From 168485d09683be0a57fabb601d892fab9d49adfa Mon Sep 17 00:00:00 2001 From: brightyi Date: Tue, 23 Jul 2024 11:26:44 +0800 Subject: [PATCH] drm/arise:add glenfly arise1 series GPU DRM kernel driver. drm: This version driver is the initial version for linux kernel 6.6, and add basic arch support for amd64/arm64/loongarch64. Test pass on deepin V23. --- drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/arise/Kconfig | 8 + drivers/gpu/drm/arise/Makefile | 83 + drivers/gpu/drm/arise/cbios/CBios.h | 2858 ++++++ .../drm/arise/cbios/Callback/CBiosCallbacks.c | 445 + .../drm/arise/cbios/Callback/CBiosCallbacks.h | 130 + drivers/gpu/drm/arise/cbios/Device/CBIOSVER.H | 85 + .../drm/arise/cbios/Device/CBiosChipShare.h | 291 + .../gpu/drm/arise/cbios/Device/CBiosCompile.h | 33 + .../gpu/drm/arise/cbios/Device/CBiosDevice.c | 919 ++ .../gpu/drm/arise/cbios/Device/CBiosDevice.h | 83 + .../drm/arise/cbios/Device/CBiosDeviceShare.c | 814 ++ .../drm/arise/cbios/Device/CBiosDeviceShare.h | 149 + drivers/gpu/drm/arise/cbios/Device/CBiosReg.h | 2629 ++++++ .../gpu/drm/arise/cbios/Device/CBiosShare.c | 389 + .../gpu/drm/arise/cbios/Device/CBiosShare.h | 245 + .../gpu/drm/arise/cbios/Device/CBiosTypes.h | 267 + .../cbios/Device/Monitor/CBiosCRTMonitor.c | 106 + .../cbios/Device/Monitor/CBiosCRTMonitor.h | 40 + .../cbios/Device/Monitor/CBiosDPMonitor.c | 2573 ++++++ .../cbios/Device/Monitor/CBiosDPMonitor.h | 155 + .../cbios/Device/Monitor/CBiosEDPPanel.c | 253 + .../cbios/Device/Monitor/CBiosEDPPanel.h | 83 + .../cbios/Device/Monitor/CBiosHDMIMonitor.c | 1621 ++++ .../cbios/Device/Monitor/CBiosHDMIMonitor.h | 345 + .../Device/Monitor/DSIPanel/CBiosDSIPanel.c | 305 + .../Device/Monitor/DSIPanel/CBiosDSIPanel.h | 185 + .../Device/Monitor/DSIPanel/CBiosHX8392A.c | 306 + .../Device/Monitor/DSIPanel/CBiosNT35595.c | 555 ++ .../Device/Monitor/DSIPanel/CBiosR63319.c | 494 ++ .../Device/Monitor/DSIPanel/CBiosR63417.c | 255 + .../Device/Monitor/EDPPanel/CBiosITN156.c | 145 + .../drm/arise/cbios/Device/Port/CBiosCRT.c | 137 + .../drm/arise/cbios/Device/Port/CBiosCRT.h | 39 + .../gpu/drm/arise/cbios/Device/Port/CBiosDP.c | 640 ++ .../gpu/drm/arise/cbios/Device/Port/CBiosDP.h | 62 + .../drm/arise/cbios/Device/Port/CBiosDSI.c | 3306 +++++++ .../drm/arise/cbios/Device/Port/CBiosDSI.h | 781 ++ .../drm/arise/cbios/Device/Port/CBiosDVO.c | 260 + .../drm/arise/cbios/Device/Port/CBiosDVO.h | 73 + .../gpu/drm/arise/cbios/Device/gcc_stdarg.h | 129 + .../arise/cbios/Display/CBiosDisplayManager.c | 780 ++ .../arise/cbios/Display/CBiosDisplayManager.h | 142 + .../gpu/drm/arise/cbios/Display/CBiosMode.c | 6148 +++++++++++++ .../gpu/drm/arise/cbios/Display/CBiosMode.h | 149 + .../arise/cbios/Display/CBiosPathManager.c | 480 + .../arise/cbios/Display/CBiosPathManager.h | 88 + .../drm/arise/cbios/Hw/Arise/CBiosVCP_Arise.c | 665 ++ .../drm/arise/cbios/Hw/Arise/CBiosVCP_Arise.h | 181 + .../drm/arise/cbios/Hw/Arise/CBios_Arise.c | 3252 +++++++ .../drm/arise/cbios/Hw/Arise/CBios_Arise.h | 121 + .../gpu/drm/arise/cbios/Hw/CBiosChipFunc.c | 332 + .../gpu/drm/arise/cbios/Hw/CBiosChipFunc.h | 140 + drivers/gpu/drm/arise/cbios/Hw/CBiosHwShare.h | 123 + .../drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.c | 396 + .../drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.h | 36 + .../drm/arise/cbios/Hw/HwBlock/CBiosDIU_CSC.c | 102 + .../drm/arise/cbios/Hw/HwBlock/CBiosDIU_CSC.h | 96 + .../drm/arise/cbios/Hw/HwBlock/CBiosDIU_DP.c | 2758 ++++++ .../drm/arise/cbios/Hw/HwBlock/CBiosDIU_DP.h | 171 + .../drm/arise/cbios/Hw/HwBlock/CBiosDIU_DVO.c | 182 + .../drm/arise/cbios/Hw/HwBlock/CBiosDIU_DVO.h | 33 + .../arise/cbios/Hw/HwBlock/CBiosDIU_HDAC.c | 966 +++ .../arise/cbios/Hw/HwBlock/CBiosDIU_HDAC.h | 70 + .../arise/cbios/Hw/HwBlock/CBiosDIU_HDCP.c | 1857 ++++ .../arise/cbios/Hw/HwBlock/CBiosDIU_HDCP.h | 153 + .../arise/cbios/Hw/HwBlock/CBiosDIU_HDMI.c | 795 ++ .../arise/cbios/Hw/HwBlock/CBiosDIU_HDMI.h | 59 + .../arise/cbios/Hw/HwBlock/CBiosDIU_HDTV.c | 283 + .../arise/cbios/Hw/HwBlock/CBiosDIU_HDTV.h | 35 + .../drm/arise/cbios/Hw/HwBlock/CBiosDIU_VIP.c | 1122 +++ .../drm/arise/cbios/Hw/HwBlock/CBiosDIU_VIP.h | 81 + .../arise/cbios/Hw/HwBlock/CBiosIGA_Timing.c | 593 ++ .../arise/cbios/Hw/HwBlock/CBiosIGA_Timing.h | 32 + .../drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.c | 1725 ++++ .../drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.h | 45 + .../drm/arise/cbios/Hw/HwBlock/CBiosScaler.c | 620 ++ .../drm/arise/cbios/Hw/HwBlock/CBiosScaler.h | 155 + .../cbios/Hw/HwCallback/CBiosCallbacksHw.c | 449 + .../cbios/Hw/HwCallback/CBiosCallbacksHw.h | 115 + .../drm/arise/cbios/Hw/HwInit/CBiosInitHw.c | 1416 +++ .../drm/arise/cbios/Hw/HwInit/CBiosInitHw.h | 30 + .../cbios/Hw/HwInterface/CBiosHwInterface.c | 1398 +++ .../cbios/Hw/HwInterface/CBiosHwInterface.h | 68 + .../gpu/drm/arise/cbios/Hw/HwUtil/CBiosI2C.c | 1751 ++++ .../gpu/drm/arise/cbios/Hw/HwUtil/CBiosI2C.h | 133 + .../drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.c | 2518 ++++++ .../drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.h | 204 + .../drm/arise/cbios/Hw/Interrupt/CBiosISR.c | 372 + .../Hw/Register/BIU_CR_C_BUS_registers.h | 1587 ++++ .../cbios/Hw/Register/BIU_HDA_registers.h | 504 ++ .../cbios/Hw/Register/BIU_MM_registers.h | 273 + .../cbios/Hw/Register/BIU_SBI_registers.h | 471 + .../cbios/Hw/Register/BIU_TSR_registers.h | 54 + .../cbios/Hw/Register/BIU_VCP_registers.h | 35 + .../cbios/Hw/Register/DIU_CR_registers.h | 2094 +++++ .../cbios/Hw/Register/DIU_MM_registers.h | 3902 +++++++++ .../Hw/Register/DIU_MM_registers_Arise.h | 7689 +++++++++++++++++ .../cbios/Hw/Register/DIU_SR_registers.h | 3090 +++++++ .../cbios/Hw/Register/DIU_vga_registers.h | 771 ++ .../Hw/Register/Monitor/CBiosDPCDRegister.h | 660 ++ .../arise/cbios/Hw/Register/pmu_registers.h | 249 + drivers/gpu/drm/arise/cbios/Init/CBiosInit.c | 208 + drivers/gpu/drm/arise/cbios/Interface/CBios.c | 1729 ++++ drivers/gpu/drm/arise/cbios/Util/CBiosEDID.c | 3044 +++++++ drivers/gpu/drm/arise/cbios/Util/CBiosEDID.h | 526 ++ drivers/gpu/drm/arise/cbios/Util/CBiosGPIO.h | 970 +++ drivers/gpu/drm/arise/cbios/Util/CBiosUtil.c | 1084 +++ drivers/gpu/drm/arise/cbios/cbios.mk | 64 + drivers/gpu/drm/arise/core/Makefile | 65 + drivers/gpu/drm/arise/core/context/context.c | 743 ++ drivers/gpu/drm/arise/core/context/context.h | 198 + .../gpu/drm/arise/core/context/di_context.c | 147 + drivers/gpu/drm/arise/core/e3k/Makefile | 38 + .../drm/arise/core/e3k/global/global_e3k.c | 28 + .../drm/arise/core/e3k/include/Chip/BlockID.h | 262 + .../e3k/include/Chip/CSP_GLOBAL_Register.h | 1549 ++++ .../arise/core/e3k/include/Chip/CSP_OPCODE.h | 1770 ++++ .../core/e3k/include/Chip/ChipRegisters.h | 24 + .../arise/core/e3k/include/Chip/EU_CS_reg.h | 505 ++ .../arise/core/e3k/include/Chip/EU_FS_reg.h | 1657 ++++ .../arise/core/e3k/include/Chip/EU_PS_reg.h | 641 ++ .../core/e3k/include/Chip/FF_registers.h | 1250 +++ .../core/e3k/include/Chip/GPCPBE_register.h | 359 + .../core/e3k/include/Chip/GPCPFE_register.h | 241 + .../drm/arise/core/e3k/include/Chip/IU_reg.h | 497 ++ .../arise/core/e3k/include/Chip/L2_Register.h | 164 + .../core/e3k/include/Chip/MMU_registers.h | 54 + .../core/e3k/include/Chip/MXU_registers.h | 541 ++ .../core/e3k/include/Chip/SPIN_register.h | 74 + .../core/e3k/include/Chip/SPOUT_register.h | 284 + .../arise/core/e3k/include/Chip/TASBE_reg.h | 87 + .../arise/core/e3k/include/Chip/TASFE_reg.h | 709 ++ .../drm/arise/core/e3k/include/Chip/TU_Reg.h | 913 ++ .../e3k/include/Chip/VCP_OPCODE_DECOUPLE.h | 611 ++ .../core/e3k/include/Chip/Vcp_Registers.h | 2421 ++++++ .../core/e3k/include/Chip/WLS_Registers.h | 363 + .../arise/core/e3k/include/Chip/registerDef.h | 100 + .../core/e3k/include/Chip/registercommands.h | 1375 +++ .../core/e3k/include/Chip/surface_format.h | 2436 ++++++ .../arise/core/e3k/include/chip_include_e3k.h | 473 + .../gpu/drm/arise/core/e3k/include/mm_e3k.h | 518 ++ .../drm/arise/core/e3k/include/register_e3k.h | 144 + .../arise/core/e3k/include/stm_context_e3k.h | 514 ++ .../arise/core/e3k/perfevent/perfevent_e3k.c | 118 + .../arise/core/e3k/vidmm/vidmm_allocate_e3k.c | 756 ++ .../e3k/vidmm/vidmm_build_page_buffer_e3k.c | 453 + .../gpu/drm/arise/core/e3k/vidmm/vidmm_e3k.c | 459 + .../core/e3k/vidmm/vidmm_gart_table_e3k.c | 306 + .../gpu/drm/arise/core/e3k/vidmm/vidmmi_e3k.h | 34 + .../arise/core/e3k/vidsch/ContextSwitch_e3k.c | 503 ++ .../arise/core/e3k/vidsch/vidsch_blt_e3k.c | 107 + .../arise/core/e3k/vidsch/vidsch_blt_e3k.h | 158 + .../vidsch/vidsch_debug_hang_compatible_e3k.c | 1004 +++ .../core/e3k/vidsch/vidsch_debug_hang_e3k.c | 1228 +++ .../core/e3k/vidsch/vidsch_debug_hang_e3k.h | 405 + .../arise/core/e3k/vidsch/vidsch_dfs_e3k.c | 171 + .../arise/core/e3k/vidsch/vidsch_dfs_e3k.h | 24 + .../core/e3k/vidsch/vidsch_dump_image_e3k.h | 36 + .../arise/core/e3k/vidsch/vidsch_engine_e3k.h | 276 + .../core/e3k/vidsch/vidsch_engine_setup_e3k.c | 1042 +++ .../e3k/vidsch/vidsch_engine_submit_e3k.c | 1053 +++ .../arise/core/e3k/vidsch/vidsch_patch_e3k.c | 205 + .../arise/core/e3k/vidsch/vidsch_render_e3k.c | 103 + .../arise/core/e3k/vidsch/vidsch_setup_e3k.c | 714 ++ drivers/gpu/drm/arise/core/global/global.c | 302 + drivers/gpu/drm/arise/core/global/global.h | 26 + .../gpu/drm/arise/core/include/core_errno.h | 33 + .../gpu/drm/arise/core/include/core_import.h | 219 + .../gpu/drm/arise/core/include/gf_adapter.h | 388 + .../gpu/drm/arise/core/include/gf_chip_id.h | 123 + .../drm/arise/core/include/kernel_import.h | 440 + .../drm/arise/core/include/kernel_interface.h | 171 + drivers/gpu/drm/arise/core/kernel_interface.c | 1387 +++ .../gpu/drm/arise/core/perfevent/perfevent.c | 1115 +++ .../gpu/drm/arise/core/perfevent/perfevent.h | 50 + .../gpu/drm/arise/core/perfevent/perfeventi.h | 108 + .../gpu/drm/arise/core/powermgr/powermgr.c | 84 + .../gpu/drm/arise/core/powermgr/powermgr.h | 21 + drivers/gpu/drm/arise/core/util/bit_op.h | 306 + .../gpu/drm/arise/core/util/handle_manager.c | 129 + .../gpu/drm/arise/core/util/handle_manager.h | 73 + .../gpu/drm/arise/core/util/heap_manager.c | 344 + .../gpu/drm/arise/core/util/heap_manager.h | 58 + drivers/gpu/drm/arise/core/util/list.h | 231 + drivers/gpu/drm/arise/core/util/queue.c | 197 + drivers/gpu/drm/arise/core/util/queue.h | 49 + drivers/gpu/drm/arise/core/util/ring_buffer.c | 101 + drivers/gpu/drm/arise/core/util/ring_buffer.h | 42 + drivers/gpu/drm/arise/core/util/util.c | 397 + drivers/gpu/drm/arise/core/util/util.h | 208 + drivers/gpu/drm/arise/core/vidmm/vidmm.c | 1325 +++ drivers/gpu/drm/arise/core/vidmm/vidmm.h | 391 + .../gpu/drm/arise/core/vidmm/vidmm_allocate.c | 1316 +++ drivers/gpu/drm/arise/core/vidmm/vidmm_lock.c | 89 + .../gpu/drm/arise/core/vidmm/vidmm_paging.c | 1023 +++ drivers/gpu/drm/arise/core/vidmm/vidmmi.h | 182 + drivers/gpu/drm/arise/core/vidsch/vidsch.c | 1322 +++ drivers/gpu/drm/arise/core/vidsch/vidsch.h | 262 + .../arise/core/vidsch/vidsch_daemon_thread.c | 233 + .../gpu/drm/arise/core/vidsch/vidsch_gating.c | 61 + .../gpu/drm/arise/core/vidsch/vidsch_render.c | 481 ++ .../gpu/drm/arise/core/vidsch/vidsch_render.h | 23 + .../gpu/drm/arise/core/vidsch/vidsch_submit.c | 954 ++ .../gpu/drm/arise/core/vidsch/vidsch_submit.h | 29 + .../gpu/drm/arise/core/vidsch/vidsch_sync.c | 1118 +++ .../gpu/drm/arise/core/vidsch/vidsch_sync.h | 165 + .../gpu/drm/arise/core/vidsch/vidsch_task.c | 823 ++ .../arise/core/vidsch/vidsch_workerthread.c | 287 + .../arise/core/vidsch/vidsch_workerthread.h | 187 + drivers/gpu/drm/arise/core/vidsch/vidschi.h | 341 + drivers/gpu/drm/arise/gf_version.h | 14 + drivers/gpu/drm/arise/linux/Makefile | 58 + drivers/gpu/drm/arise/linux/e3k/gf_irq_e3k.c | 237 + drivers/gpu/drm/arise/linux/e3k/gf_irq_e3k.h | 64 + drivers/gpu/drm/arise/linux/gf.c | 76 + drivers/gpu/drm/arise/linux/gf.h | 392 + drivers/gpu/drm/arise/linux/gf_atomic.c | 282 + drivers/gpu/drm/arise/linux/gf_atomic.h | 56 + drivers/gpu/drm/arise/linux/gf_capture_drv.c | 162 + drivers/gpu/drm/arise/linux/gf_capture_drv.h | 69 + drivers/gpu/drm/arise/linux/gf_cbios.c | 2738 ++++++ drivers/gpu/drm/arise/linux/gf_cbios.h | 168 + drivers/gpu/drm/arise/linux/gf_connector.c | 789 ++ drivers/gpu/drm/arise/linux/gf_crtc.c | 1138 +++ drivers/gpu/drm/arise/linux/gf_crtc.h | 122 + drivers/gpu/drm/arise/linux/gf_debugfs.c | 1046 +++ drivers/gpu/drm/arise/linux/gf_debugfs.h | 109 + drivers/gpu/drm/arise/linux/gf_device_debug.h | 33 + drivers/gpu/drm/arise/linux/gf_disp.c | 1896 ++++ drivers/gpu/drm/arise/linux/gf_disp.h | 400 + drivers/gpu/drm/arise/linux/gf_driver.c | 1117 +++ drivers/gpu/drm/arise/linux/gf_driver.h | 178 + drivers/gpu/drm/arise/linux/gf_drmfb.c | 104 + drivers/gpu/drm/arise/linux/gf_drmfb.h | 48 + drivers/gpu/drm/arise/linux/gf_encoder.c | 389 + drivers/gpu/drm/arise/linux/gf_fbdev.c | 358 + drivers/gpu/drm/arise/linux/gf_fbdev.h | 39 + drivers/gpu/drm/arise/linux/gf_fence.c | 604 ++ drivers/gpu/drm/arise/linux/gf_fence.h | 254 + drivers/gpu/drm/arise/linux/gf_gem.c | 1989 +++++ drivers/gpu/drm/arise/linux/gf_gem.h | 120 + drivers/gpu/drm/arise/linux/gf_gem_debug.h | 46 + drivers/gpu/drm/arise/linux/gf_gem_priv.h | 175 + drivers/gpu/drm/arise/linux/gf_hw_null.c | 156 + drivers/gpu/drm/arise/linux/gf_i2c.c | 165 + drivers/gpu/drm/arise/linux/gf_i2c.h | 28 + drivers/gpu/drm/arise/linux/gf_ioctl.c | 545 ++ drivers/gpu/drm/arise/linux/gf_ioctl.h | 145 + drivers/gpu/drm/arise/linux/gf_irq.c | 1683 ++++ drivers/gpu/drm/arise/linux/gf_irq.h | 123 + drivers/gpu/drm/arise/linux/gf_kms.h | 275 + drivers/gpu/drm/arise/linux/gf_params.c | 73 + drivers/gpu/drm/arise/linux/gf_params.h | 49 + drivers/gpu/drm/arise/linux/gf_pcie.c | 1131 +++ drivers/gpu/drm/arise/linux/gf_plane.c | 784 ++ drivers/gpu/drm/arise/linux/gf_plane.h | 110 + drivers/gpu/drm/arise/linux/gf_sink.c | 90 + drivers/gpu/drm/arise/linux/gf_sink.h | 38 + drivers/gpu/drm/arise/linux/gf_splice.c | 2540 ++++++ drivers/gpu/drm/arise/linux/gf_splice.h | 396 + drivers/gpu/drm/arise/linux/gf_sysfs.c | 820 ++ drivers/gpu/drm/arise/linux/gf_trace.h | 434 + drivers/gpu/drm/arise/linux/gf_trace_events.c | 66 + drivers/gpu/drm/arise/linux/gf_vip.c | 385 + drivers/gpu/drm/arise/linux/gf_vip.h | 70 + drivers/gpu/drm/arise/linux/gf_wb.c | 465 + drivers/gpu/drm/arise/linux/gf_wb.h | 84 + drivers/gpu/drm/arise/linux/os_interface.c | 2366 +++++ drivers/gpu/drm/arise/shared/gf_capture.h | 191 + drivers/gpu/drm/arise/shared/gf_def.h | 480 + drivers/gpu/drm/arise/shared/gf_modifies.h | 75 + drivers/gpu/drm/arise/shared/gf_perf.h | 619 ++ drivers/gpu/drm/arise/shared/gf_types.h | 561 ++ drivers/gpu/drm/arise/shared/os_interface.h | 311 + drivers/gpu/drm/arise/shared/os_shared.c | 343 + 277 files changed, 163698 insertions(+) create mode 100644 drivers/gpu/drm/arise/Kconfig create mode 100644 drivers/gpu/drm/arise/Makefile create mode 100644 drivers/gpu/drm/arise/cbios/CBios.h create mode 100644 drivers/gpu/drm/arise/cbios/Callback/CBiosCallbacks.c create mode 100644 drivers/gpu/drm/arise/cbios/Callback/CBiosCallbacks.h create mode 100755 drivers/gpu/drm/arise/cbios/Device/CBIOSVER.H create mode 100644 drivers/gpu/drm/arise/cbios/Device/CBiosChipShare.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/CBiosCompile.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/CBiosDevice.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/CBiosDevice.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/CBiosDeviceShare.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/CBiosDeviceShare.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/CBiosReg.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/CBiosShare.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/CBiosShare.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/CBiosTypes.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosDPMonitor.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosDPMonitor.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosEDPPanel.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosEDPPanel.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosDSIPanel.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosDSIPanel.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosHX8392A.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosNT35595.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosR63319.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosR63417.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Monitor/EDPPanel/CBiosITN156.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Port/CBiosCRT.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Port/CBiosCRT.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/Port/CBiosDP.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Port/CBiosDP.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/Port/CBiosDSI.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Port/CBiosDSI.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/Port/CBiosDVO.c create mode 100644 drivers/gpu/drm/arise/cbios/Device/Port/CBiosDVO.h create mode 100644 drivers/gpu/drm/arise/cbios/Device/gcc_stdarg.h create mode 100644 drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.c create mode 100644 drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.h create mode 100644 drivers/gpu/drm/arise/cbios/Display/CBiosMode.c create mode 100644 drivers/gpu/drm/arise/cbios/Display/CBiosMode.h create mode 100644 drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.c create mode 100644 drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Arise/CBiosVCP_Arise.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Arise/CBiosVCP_Arise.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Arise/CBios_Arise.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Arise/CBios_Arise.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/CBiosChipFunc.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/CBiosChipFunc.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/CBiosHwShare.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CSC.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CSC.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DP.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DP.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DVO.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DVO.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDAC.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDAC.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDCP.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDCP.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDMI.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDMI.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDTV.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDTV.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_VIP.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_VIP.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosIGA_Timing.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosIGA_Timing.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosScaler.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosScaler.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwCallback/CBiosCallbacksHw.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwCallback/CBiosCallbacksHw.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwInit/CBiosInitHw.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwInit/CBiosInitHw.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwInterface/CBiosHwInterface.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwInterface/CBiosHwInterface.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosI2C.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosI2C.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Interrupt/CBiosISR.c create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/BIU_CR_C_BUS_registers.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/BIU_HDA_registers.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/BIU_MM_registers.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/BIU_SBI_registers.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/BIU_TSR_registers.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/BIU_VCP_registers.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/DIU_CR_registers.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/DIU_MM_registers.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/DIU_MM_registers_Arise.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/DIU_SR_registers.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/DIU_vga_registers.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/Monitor/CBiosDPCDRegister.h create mode 100644 drivers/gpu/drm/arise/cbios/Hw/Register/pmu_registers.h create mode 100644 drivers/gpu/drm/arise/cbios/Init/CBiosInit.c create mode 100644 drivers/gpu/drm/arise/cbios/Interface/CBios.c create mode 100644 drivers/gpu/drm/arise/cbios/Util/CBiosEDID.c create mode 100644 drivers/gpu/drm/arise/cbios/Util/CBiosEDID.h create mode 100644 drivers/gpu/drm/arise/cbios/Util/CBiosGPIO.h create mode 100644 drivers/gpu/drm/arise/cbios/Util/CBiosUtil.c create mode 100644 drivers/gpu/drm/arise/cbios/cbios.mk create mode 100644 drivers/gpu/drm/arise/core/Makefile create mode 100644 drivers/gpu/drm/arise/core/context/context.c create mode 100644 drivers/gpu/drm/arise/core/context/context.h create mode 100644 drivers/gpu/drm/arise/core/context/di_context.c create mode 100644 drivers/gpu/drm/arise/core/e3k/Makefile create mode 100644 drivers/gpu/drm/arise/core/e3k/global/global_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/BlockID.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/CSP_GLOBAL_Register.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/CSP_OPCODE.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/ChipRegisters.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/EU_CS_reg.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/EU_FS_reg.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/EU_PS_reg.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/FF_registers.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/GPCPBE_register.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/GPCPFE_register.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/IU_reg.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/L2_Register.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/MMU_registers.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/MXU_registers.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/SPIN_register.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/SPOUT_register.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/TASBE_reg.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/TASFE_reg.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/TU_Reg.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/VCP_OPCODE_DECOUPLE.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/Vcp_Registers.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/WLS_Registers.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/registerDef.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/registercommands.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/Chip/surface_format.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/chip_include_e3k.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/mm_e3k.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/register_e3k.h create mode 100644 drivers/gpu/drm/arise/core/e3k/include/stm_context_e3k.h create mode 100644 drivers/gpu/drm/arise/core/e3k/perfevent/perfevent_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_allocate_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_build_page_buffer_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_gart_table_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidmm/vidmmi_e3k.h create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/ContextSwitch_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_blt_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_blt_e3k.h create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_compatible_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_e3k.h create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dfs_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dfs_e3k.h create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dump_image_e3k.h create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_e3k.h create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_setup_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_submit_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_patch_e3k.c create mode 100644 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_render_e3k.c create mode 100755 drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_setup_e3k.c create mode 100644 drivers/gpu/drm/arise/core/global/global.c create mode 100644 drivers/gpu/drm/arise/core/global/global.h create mode 100644 drivers/gpu/drm/arise/core/include/core_errno.h create mode 100644 drivers/gpu/drm/arise/core/include/core_import.h create mode 100644 drivers/gpu/drm/arise/core/include/gf_adapter.h create mode 100644 drivers/gpu/drm/arise/core/include/gf_chip_id.h create mode 100644 drivers/gpu/drm/arise/core/include/kernel_import.h create mode 100644 drivers/gpu/drm/arise/core/include/kernel_interface.h create mode 100644 drivers/gpu/drm/arise/core/kernel_interface.c create mode 100755 drivers/gpu/drm/arise/core/perfevent/perfevent.c create mode 100755 drivers/gpu/drm/arise/core/perfevent/perfevent.h create mode 100644 drivers/gpu/drm/arise/core/perfevent/perfeventi.h create mode 100644 drivers/gpu/drm/arise/core/powermgr/powermgr.c create mode 100644 drivers/gpu/drm/arise/core/powermgr/powermgr.h create mode 100644 drivers/gpu/drm/arise/core/util/bit_op.h create mode 100644 drivers/gpu/drm/arise/core/util/handle_manager.c create mode 100644 drivers/gpu/drm/arise/core/util/handle_manager.h create mode 100644 drivers/gpu/drm/arise/core/util/heap_manager.c create mode 100644 drivers/gpu/drm/arise/core/util/heap_manager.h create mode 100644 drivers/gpu/drm/arise/core/util/list.h create mode 100644 drivers/gpu/drm/arise/core/util/queue.c create mode 100644 drivers/gpu/drm/arise/core/util/queue.h create mode 100644 drivers/gpu/drm/arise/core/util/ring_buffer.c create mode 100644 drivers/gpu/drm/arise/core/util/ring_buffer.h create mode 100644 drivers/gpu/drm/arise/core/util/util.c create mode 100644 drivers/gpu/drm/arise/core/util/util.h create mode 100644 drivers/gpu/drm/arise/core/vidmm/vidmm.c create mode 100644 drivers/gpu/drm/arise/core/vidmm/vidmm.h create mode 100644 drivers/gpu/drm/arise/core/vidmm/vidmm_allocate.c create mode 100644 drivers/gpu/drm/arise/core/vidmm/vidmm_lock.c create mode 100644 drivers/gpu/drm/arise/core/vidmm/vidmm_paging.c create mode 100644 drivers/gpu/drm/arise/core/vidmm/vidmmi.h create mode 100755 drivers/gpu/drm/arise/core/vidsch/vidsch.c create mode 100644 drivers/gpu/drm/arise/core/vidsch/vidsch.h create mode 100644 drivers/gpu/drm/arise/core/vidsch/vidsch_daemon_thread.c create mode 100644 drivers/gpu/drm/arise/core/vidsch/vidsch_gating.c create mode 100644 drivers/gpu/drm/arise/core/vidsch/vidsch_render.c create mode 100644 drivers/gpu/drm/arise/core/vidsch/vidsch_render.h create mode 100644 drivers/gpu/drm/arise/core/vidsch/vidsch_submit.c create mode 100644 drivers/gpu/drm/arise/core/vidsch/vidsch_submit.h create mode 100644 drivers/gpu/drm/arise/core/vidsch/vidsch_sync.c create mode 100644 drivers/gpu/drm/arise/core/vidsch/vidsch_sync.h create mode 100755 drivers/gpu/drm/arise/core/vidsch/vidsch_task.c create mode 100755 drivers/gpu/drm/arise/core/vidsch/vidsch_workerthread.c create mode 100644 drivers/gpu/drm/arise/core/vidsch/vidsch_workerthread.h create mode 100644 drivers/gpu/drm/arise/core/vidsch/vidschi.h create mode 100644 drivers/gpu/drm/arise/gf_version.h create mode 100644 drivers/gpu/drm/arise/linux/Makefile create mode 100755 drivers/gpu/drm/arise/linux/e3k/gf_irq_e3k.c create mode 100644 drivers/gpu/drm/arise/linux/e3k/gf_irq_e3k.h create mode 100644 drivers/gpu/drm/arise/linux/gf.c create mode 100644 drivers/gpu/drm/arise/linux/gf.h create mode 100644 drivers/gpu/drm/arise/linux/gf_atomic.c create mode 100644 drivers/gpu/drm/arise/linux/gf_atomic.h create mode 100644 drivers/gpu/drm/arise/linux/gf_capture_drv.c create mode 100644 drivers/gpu/drm/arise/linux/gf_capture_drv.h create mode 100644 drivers/gpu/drm/arise/linux/gf_cbios.c create mode 100644 drivers/gpu/drm/arise/linux/gf_cbios.h create mode 100644 drivers/gpu/drm/arise/linux/gf_connector.c create mode 100644 drivers/gpu/drm/arise/linux/gf_crtc.c create mode 100644 drivers/gpu/drm/arise/linux/gf_crtc.h create mode 100644 drivers/gpu/drm/arise/linux/gf_debugfs.c create mode 100644 drivers/gpu/drm/arise/linux/gf_debugfs.h create mode 100644 drivers/gpu/drm/arise/linux/gf_device_debug.h create mode 100644 drivers/gpu/drm/arise/linux/gf_disp.c create mode 100644 drivers/gpu/drm/arise/linux/gf_disp.h create mode 100644 drivers/gpu/drm/arise/linux/gf_driver.c create mode 100644 drivers/gpu/drm/arise/linux/gf_driver.h create mode 100644 drivers/gpu/drm/arise/linux/gf_drmfb.c create mode 100644 drivers/gpu/drm/arise/linux/gf_drmfb.h create mode 100644 drivers/gpu/drm/arise/linux/gf_encoder.c create mode 100644 drivers/gpu/drm/arise/linux/gf_fbdev.c create mode 100644 drivers/gpu/drm/arise/linux/gf_fbdev.h create mode 100644 drivers/gpu/drm/arise/linux/gf_fence.c create mode 100644 drivers/gpu/drm/arise/linux/gf_fence.h create mode 100644 drivers/gpu/drm/arise/linux/gf_gem.c create mode 100644 drivers/gpu/drm/arise/linux/gf_gem.h create mode 100644 drivers/gpu/drm/arise/linux/gf_gem_debug.h create mode 100644 drivers/gpu/drm/arise/linux/gf_gem_priv.h create mode 100644 drivers/gpu/drm/arise/linux/gf_hw_null.c create mode 100644 drivers/gpu/drm/arise/linux/gf_i2c.c create mode 100644 drivers/gpu/drm/arise/linux/gf_i2c.h create mode 100644 drivers/gpu/drm/arise/linux/gf_ioctl.c create mode 100644 drivers/gpu/drm/arise/linux/gf_ioctl.h create mode 100755 drivers/gpu/drm/arise/linux/gf_irq.c create mode 100644 drivers/gpu/drm/arise/linux/gf_irq.h create mode 100644 drivers/gpu/drm/arise/linux/gf_kms.h create mode 100644 drivers/gpu/drm/arise/linux/gf_params.c create mode 100644 drivers/gpu/drm/arise/linux/gf_params.h create mode 100644 drivers/gpu/drm/arise/linux/gf_pcie.c create mode 100644 drivers/gpu/drm/arise/linux/gf_plane.c create mode 100644 drivers/gpu/drm/arise/linux/gf_plane.h create mode 100644 drivers/gpu/drm/arise/linux/gf_sink.c create mode 100644 drivers/gpu/drm/arise/linux/gf_sink.h create mode 100644 drivers/gpu/drm/arise/linux/gf_splice.c create mode 100644 drivers/gpu/drm/arise/linux/gf_splice.h create mode 100755 drivers/gpu/drm/arise/linux/gf_sysfs.c create mode 100644 drivers/gpu/drm/arise/linux/gf_trace.h create mode 100644 drivers/gpu/drm/arise/linux/gf_trace_events.c create mode 100644 drivers/gpu/drm/arise/linux/gf_vip.c create mode 100644 drivers/gpu/drm/arise/linux/gf_vip.h create mode 100644 drivers/gpu/drm/arise/linux/gf_wb.c create mode 100644 drivers/gpu/drm/arise/linux/gf_wb.h create mode 100644 drivers/gpu/drm/arise/linux/os_interface.c create mode 100644 drivers/gpu/drm/arise/shared/gf_capture.h create mode 100644 drivers/gpu/drm/arise/shared/gf_def.h create mode 100644 drivers/gpu/drm/arise/shared/gf_modifies.h create mode 100755 drivers/gpu/drm/arise/shared/gf_perf.h create mode 100644 drivers/gpu/drm/arise/shared/gf_types.h create mode 100644 drivers/gpu/drm/arise/shared/os_interface.h create mode 100644 drivers/gpu/drm/arise/shared/os_shared.c diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 95f1231985c72..13ff4f3120d0b 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -392,6 +392,8 @@ source "drivers/gpu/drm/sprd/Kconfig" source "drivers/gpu/drm/phytium/Kconfig" +source "drivers/gpu/drm/arise/Kconfig" + config DRM_HYPERV tristate "DRM Support for Hyper-V synthetic video device" depends on DRM && PCI && MMU && HYPERV diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index dfffc3deda767..00f8d2f85e1cb 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -200,3 +200,4 @@ obj-y += solomon/ obj-$(CONFIG_DRM_SPRD) += sprd/ obj-$(CONFIG_DRM_LOONGSON) += loongson/ obj-$(CONFIG_DRM_PHYTIUM) += phytium/ +obj-$(CONFIG_DRM_ARISE) += arise/ diff --git a/drivers/gpu/drm/arise/Kconfig b/drivers/gpu/drm/arise/Kconfig new file mode 100644 index 0000000000000..d804ed9f9243d --- /dev/null +++ b/drivers/gpu/drm/arise/Kconfig @@ -0,0 +1,8 @@ +config DRM_ARISE + tristate "Arise DRM" + default m + depends on DRM + select DRM_KMS_HELPER + help + Choose this option if you have an Glenfly Arise GPU. If M is selected + the module will be called arise. diff --git a/drivers/gpu/drm/arise/Makefile b/drivers/gpu/drm/arise/Makefile new file mode 100644 index 0000000000000..793986b02ddae --- /dev/null +++ b/drivers/gpu/drm/arise/Makefile @@ -0,0 +1,83 @@ +CHIP?=E3k +DRIVER_NAME?=arise +PRO_DRIVER_NAME=$(DRIVER_NAME) +TARGET_ARCH?=x86_64 +DEBUG?=0 +VIDEO_ONLY_FPGA?=0 +RUN_HW_NULL?=0 +HW_NULL?=0 +CONFIG-GFGPU=m +ifeq ("$(M)", "") +CHECK_GCC_VERSION?=0 +else +CHECK_GCC_VERSION?=1 +endif + +ccflags-y := -D__LINUX__ -DKERNEL_BUILD +ccflags-y += -Wno-undef -Wno-unused -Wno-missing-braces -Wno-missing-attributes -Wno-overflow -Wno-missing-prototypes -Wno-missing-declarations + +ifeq ($(CHECK_GCC_VERSION), 1) + +KERNEL_UNAME?=$(shell uname -r) +KERNEL_MODLIB:=/lib/modules/$(KERNEL_UNAME) +KERNEL_SOURCES:=$(shell test -d $(KERNEL_MODLIB)/source && echo $(KERNEL_MODLIB)/source || echo $(KERNEL_MODLIB)/build) +KERNEL_COMPILE_H=$(KERNEL_SOURCES)/include/generated/compile.h +KERNEL_COMPILE_H_EXIT=$(shell if [ -f $(KERNEL_COMPILE_H) ]; then echo 1; else echo 0; fi) + +ifeq ($(KERNEL_COMPILE_H_EXIT), 1) + +KERNEL_BUILT_GCC_STRING=$(shell cat ${KERNEL_COMPILE_H} | grep LINUX_COMPILER | cut -f 2 -d '"') +KERNEL_BUILT_GCC_VERSION=$(shell echo "${KERNEL_BUILT_GCC_STRING}" | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' | head -n 1) +ifeq ("$(KERNEL_BUILT_GCC_VERSION)", "") +KERNEL_BUILT_GCC_VERSION=$(shell echo "${KERNEL_BUILT_GCC_STRING}" | grep -o '[0-9]\+\.[0-9]\+' | head -n 1) +endif + +SYSTEM_GCC_VERSION=$(shell $(CC) -v 2>&1 | awk 'END{print}' | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' | head -n 1) +ifeq ("$(SYSTEM_GCC_VERSION)", "") +SYSTEM_GCC_VERSION=$(shell $(CC) -v 2>&1 | awk 'END{print}' | grep -o '[0-9]\+\.[0-9]\+' | head -n 1) +endif + +ifneq ("$(KERNEL_BUILT_GCC_VERSION)", "$(SYSTEM_GCC_VERSION)") +$(warning "Kernel Built GCC Version ($(KERNEL_BUILT_GCC_VERSION)) Are Differ From System GCC Version($(SYSTEM_GCC_VERSION))!!") +$(warning "System GCC Version Must Match To Kernel Built GCC Version!!") +$(warning "Please Check GCC Version!!") +endif + +else +$(warning "$(KERNEL_COMPILE_H) not exist,can not do gcc version check,skip") +endif + +endif + +ifeq ($(DEBUG), 1) + ccflags-y += -ggdb3 -O2 -D_DEBUG_ -DGF_TRACE_EVENT=1 +else + ccflags-y += -O2 -fno-strict-aliasing -fno-stack-protector -DGF_TRACE_EVENT=1 +endif + +ifeq ($(VIDEO_ONLY_FPGA), 1) +ccflags-y += -DVIDEO_ONLY_FPGA +endif + +ifeq ($(RUN_HW_NULL), 1) +ccflags-y += -DGF_HW_NULL +else +ccflags-y += -DGF_PCIE_BUS +endif + +ccflags-y += -I$(src) + +ifeq ("$(M)", "") +ifeq ("$(O)", "") +GFGPU_FULL_PATH=$(src) +else +GFGPU_FULL_PATH=$(srctree)/$(src) +endif +else +GFGPU_FULL_PATH=$(src) +endif + +include $(GFGPU_FULL_PATH)/core/Makefile +include $(GFGPU_FULL_PATH)/cbios/cbios.mk +include $(GFGPU_FULL_PATH)/linux/Makefile +obj-$(CONFIG_DRM_ARISE) := $(PRO_DRIVER_NAME).o diff --git a/drivers/gpu/drm/arise/cbios/CBios.h b/drivers/gpu/drm/arise/cbios/CBios.h new file mode 100644 index 0000000000000..c457b31ef7f78 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/CBios.h @@ -0,0 +1,2858 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + + +/***************************************************************************** +** DESCRIPTION: +** CBios interface function prototype and parameter definition. +** +** NOTE: +** The interface and structure SHOULD NOT be modified under normal condition. +** If the interface need modify for some special case, please make sure to +** update the code where calls this interface. +******************************************************************************/ + + +#ifndef _CBIOS_H_ +#define _CBIOS_H_ + +/***************************************************************************** +** +** CBios interface define: +** VBE defines +** Interface function prototype and parameter defines +** CBIOS_EXTENSION defines +** +******************************************************************************/ + +#define CBIOS_IN +#define CBIOS_OUT + +#define CBIOS_CHECK_HARDWARE_STATUS 1 /*flag to indicate whether do hardware status check in cbPost */ + +#define CBIOS_VBLANK_RETRIES 150000UL + +#if defined(__linux__) +#undef RegPreFix +#define RegPreFix( x ) (void *)x +#else +#define RegPreFix( x ) L ## x +#endif + + +#define KEYNAME_DW_HARDCODED_LINKSPEED RegPreFix("ZXGDW_cbHardCodedLinkSpeed") // 0 => Hard coding disabled, 1 => 1.62Gbps, 2 => 2.7Gbps, others => Hard coding disabled +#define KEYNAME_DW_HARDCODED_LANECOUNT RegPreFix("ZXGDW_cbHardCodedLaneCount") // 0 => Hard coding disabled, (1, 2, 4) => Number of lanes, others => Hard coding disabled +#define KEYNAME_DW_LINKTRAINING_METHOD RegPreFix("ZXGDW_cbLinktrainingMethod") // 0 => Hard coding disabled, 1 => Hardware Link Training, 2 => Software Link Training, others => Hard coding disabled +#define KEYNAME_DW_HARDCODED_DP1_EDID RegPreFix("ZXGDW_cbHardCodedDp1EDID") // 1=>"DELL 2408WFP" HDMI EDID; 2=>"WestingHouse LVM-37w3" HDMI EDID; 3=>EDID forced to all Zero Bytes; 4=>"HpLp2475w" DP EDID; Others=>Disable hardcoding +#define KEYNAME_DW_HARDCODED_EDID_DEVICE RegPreFix("ZXGDW_cbHardCodedEDIDDevice") // The Devices want to use the hardcoded EDID +#define KEYNAME_UC_HARDCODED_DEVICE_EDID RegPreFix("ZXGUC_cbHardCodedDeviceEDID") // The EDID buffer. If longer than 512 bytes, the remainder will be discarded. +#define KEYNAME_DW_HARDCODED_SPECIALMODE RegPreFix("ZXGDW_cbHardCodedSpecialMode") // to some 120Hz mode such as 1280*1024*120Hz for TV wall project +#define KEYNAME_DW_EDP_CP_METHOD RegPreFix("ZXGDW_cbeDPContentProtectionMethod") // 0 => Disable CP, 1 => Enable, use method 3a, 2 => Enable, use method 3b, others are reserved +#define KEYNAME_DW_DP_RUN_CTS RegPreFix("ZXGDW_cbDPRunCTS") // 0=> normal, 1 => Run DP CTS + + +#define DP_RESET_AUX_WHEN_DEFER 1 // If any defer received, reset aux channel + +/*indicate i2c data request from DDCCI or HDCP*/ +#define CBIOS_I2CDDCCI 0 +#define CBIOS_I2CHDCP 1 +#define CBIOS_I2CCAPTURE 2 +#define CBIOS_I2CNORMAL 3 + +#define CBIOS_MAX_I2CBUS 5 +#define CBIOS_MAX_CRTCS 4 + +#define CBIOSVERSION 0x00000001 + +/* Color Depth Capability */ +#define CBIOS_COLORDEPTH8 0x04 +#define CBIOS_COLORDEPTH16 0x02 +#define CBIOS_COLORDEPTH32XRGB 0x80 +#define CBIOS_COLORDEPTH32ARGB 0x01 +#define CBIOS_COLORDEPTH32ABGR 0x08 +#define CBIOS_COLORDEPTH2101010ARGB 0x10 +#define CBIOS_COLORDEPTH2101010ABGR 0x20 +#define CBIOS_COLORDEPTH16161616ABGRF 0x40 + +#define CBIOS_VIRTUAL_GPIO_FOR_DP1 8 +#define CBIOS_VIRTUAL_GPIO_FOR_DP2 9 +#define CBIOS_VIRTUAL_GPIO_FOR_MHL 8 + +/* Clock Type */ +typedef enum _CBIOS_CLOCK_TYPE +{ + CBIOS_DCLK1TYPE = 0x01, + CBIOS_DCLK2TYPE = 0x02, + CBIOS_TVCLKTYPE = 0x03, + CBIOS_ECLKTYPE = 0x04, + CBIOS_ICLKTYPE = 0x05, + CBIOS_CPUFRQTYPE = 0x06, + CBIOS_ALLCLKTYPE = 0x07, + ECLKTYPE_Post = 0x08, + ICLKTYPE_Post = 0x09, + CBIOS_VCLKTYPE = 0x0A, + CBIOS_DCLK3TYPE = 0x0B, + CBIOS_DCLK4TYPE = 0x0C, + CBIOS_MCLKTYPE = 0x0D, + CBIOS_INVALID_CLK = 0x0E, +}CBIOS_CLOCK_TYPE, *PCBIOS_CLOCK_TYPE; + +#define CBIOS_DSI_INDEX_NUM 2 + +#define CBIOS_RGBOUTPUT 1 +#define CBIOS_YCBCR422OUTPUT 2 +#define CBIOS_YCBCR444OUTPUT 4 +#define CBIOS_YCBCR420OUTPUT 8 +#define CBIOS_NONDIGITALOUTPUT 9 + + + +#ifndef CBIOS_FALSE +#define CBIOS_FALSE 0 +#endif + +#ifndef CBIOS_TRUE +#define CBIOS_TRUE 1 +#endif + +#ifndef CBIOS_NULL +#define CBIOS_NULL ((void*)0) +#endif + +typedef unsigned char CBIOS_UCHAR, *PCBIOS_UCHAR; +typedef unsigned char CBIOS_U8, *PCBIOS_U8; +typedef unsigned short CBIOS_U16, *PCBIOS_U16; +typedef unsigned int CBIOS_U32, *PCBIOS_U32; +typedef unsigned long long CBIOS_U64, *PCBIOS_U64; + +typedef char CBIOS_CHAR, *PCBIOS_CHAR; +typedef signed char CBIOS_S8, *PCBIOS_S8; +typedef signed short CBIOS_S16, *PCBIOS_S16; +typedef signed int CBIOS_S32, *PCBIOS_S32; +typedef signed int CBIOS_BOOL, *PCBIOS_BOOL; +typedef long long CBIOS_S64, *PCBIOS_S64; + +typedef void *CBIOS_HANDLE; +typedef void CBIOS_VOID, *PCBIOS_VOID; + +/*bytes unit size*/ +#define KB(n) (n)*1024 +#define MB(n) KB(n)*1024 +#define GB(n) MB(n)*1024 + + +#if defined(_WIN64) +typedef unsigned __int64 CBIOS_ULONG_PTR, *PCBIOS_ULONG_PTR; +#else +typedef unsigned long CBIOS_ULONG_PTR, *PCBIOS_ULONG_PTR; +#endif + +#define CBIOS_MAX_DEVICE_BITS 32 + +typedef enum _CBIOS_MONITOR_TYPE { + CBIOS_MONITOR_TYPE_NONE = 0x00, + CBIOS_MONITOR_TYPE_CRT = 0x01, + CBIOS_MONITOR_TYPE_TV = 0x02, + CBIOS_MONITOR_TYPE_HDTV = 0x04, + CBIOS_MONITOR_TYPE_PANEL = 0x08, + CBIOS_MONITOR_TYPE_DVI = 0x10, + CBIOS_MONITOR_TYPE_HDMI = 0x20, + CBIOS_MONITOR_TYPE_DP = 0x40, + CBIOS_MONITOR_TYPE_MHL = 0x80 +} CBIOS_MONITOR_TYPE, *PCBIOS_MONITOR_TYPE; + +typedef enum _CBIOS_PM_STATUS +{ + CBIOS_PM_ON = 0, + CBIOS_PM_STANDBY = 1, + CBIOS_PM_SUSPEND = 2, + CBIOS_PM_OFF = 4, + CBIOS_PM_INVALID = 0xFF +} CBIOS_PM_STATUS, *PCBIOS_PM_STATUS; + +/* Castlerock and Innovation */ +typedef enum +{ + CHIPID_E3K = 26, + CHIPID_ARISE1040, + CHIPID_ARISE1020, + CHIPID_ARISE1010, + CHIPID_ARISE10C0T, + CHIPID_ARISE2030, + CHIPID_ARISE2020, + CHIPID_LAST, /* Maximum number of chips supported.*/ +} CHIPID_HW; + +/******Interface function prototype and parameter defines *******/ +typedef enum _CBIOS_STATUS_tag +{ + CBIOS_OK = 0, /* 0 OK - no error */ + CBIOS_ER_INVALID_PARAMETER, /* As is */ + CBIOS_ER_NOT_YET_IMPLEMENTED, /* Feature / function not yet implemented*/ + CBIOS_ER_INTERNAL, /* internal error (should never happen) */ + CBIOS_ER_OS_ERROR, /* Error propagated up from the underlying OS */ + CBIOS_ER_BUFFER_TOO_SMALL, /* The provided Buffer is too small. */ + CBIOS_ER_HARDWARE_LIMITATION, /* Hardware limitation. */ + CBIOS_ER_DUPLICATED_REQUEST, /*Duplicated request*/ + CBIOS_ER_LB_PU1_PU2, /* PU1 and PU2 enabled */ + CBIOS_ER_LB_PU1_PS2, /* PU1 and PS2 LB share enabled */ + CBIOS_ER_LB_PS2_PU2, /* PS2 LB share and PU2 enabled */ + CBIOS_ER_LB_PU2_PS1, /* PU2 and PS1 LB share enabled */ + CBIOS_ER_LB_PS1_PU1, /* PS1 LB share and PU1 enabled */ + CBIOS_ER_VID_MEM, /* video memory can't be read or write effectively. */ + CBIOS_ER_MMIO, /* MMIO read/write error */ + CBIOS_ER_IO, /* IO read/write error */ + CBIOS_ER_STRAPPING_RESTORED, /* strapping registers were at wrong values and then restored */ + CBIOS_ER_STRAPPING_CANNOT_RESTORE, /* strapping registers are at wrong values and cannot be restored */ + CBIOS_ER_NULLPOINTER, /*null pointer is send to CBIOS interface*/ + CBIOS_ER_NO_ENOUGH_MEM, /* allocate memory fail*/ + CBIOS_ER_CHIPDISABLE, /*Chip is not enable*/ + CBIOS_ER_OPERATION_ON_NONE_DEVICE, + CBIOS_ER_INVALID_HOTPLUG, + CBIOS_ER_LANE_DECREASED, + CBIOS_ER_CLAIMEDMEMSIZE_STRAP_RESTORED, + CBIOS_ER_VBIOS_FEATURE_OFF, + CBIOS_ER_EDID_INVALID, + CBIOS_ER_LAST /* Number of error codes */ +} CBIOS_STATUS; + +typedef enum _CBIOS_IGA_INDEX +{ + IGA1 = 0, + IGA2, + IGA3, + IGA4, + CBIOS_IGACOUNTS +} CBIOS_IGA_INDEX; + +typedef enum _CBIOS_HW_BLOCK +{ + CBIOS_HW_NONE = 0, + CBIOS_HW_IGA = 0x01, +}CBIOS_HW_BLOCK; + +typedef enum _CBIOS_COUNTER_TYPE +{ + CBIOS_COUNTER_FRAME = 0, + CBIOS_COUNTER_LINE = 1, + CBIOS_COUNTER_PIXEL = 2, + CBIOS_COUNTER_NUM = 3, +}CBIOS_COUNTER_TYPE; + +typedef struct _CBIOS_GET_HW_COUNTER +{ + CBIOS_U32 IgaIndex; + CBIOS_U32 Value[CBIOS_COUNTER_NUM]; + CBIOS_BOOL bInVblank; + struct + { + CBIOS_U32 bGetFrameCnt : 1; + CBIOS_U32 bGetLineCnt : 1; + CBIOS_U32 bGetPixelCnt : 1; + CBIOS_U32 Reserved : 29; + }; +}CBIOS_GET_HW_COUNTER, *PCBIOS_GET_HW_COUNTER; + +typedef struct _CBIOS_PCI_ADDR_PARA +{ + CBIOS_U8 BusNum; + CBIOS_U8 DeviceNum;/*Bit 4-0: device number; Bit 7-5: reserved*/ + CBIOS_U8 FunctionNum;/*Bit 2-0: function number; Bit 7-3: reserved*/ +}CBIOS_PCI_ADDR_PARA, *PCBIOS_PCI_ADDR_PARA; + +typedef struct _CBIOS_PARAM_INIT +{ + CBIOS_U32 Size; + PCBIOS_VOID RomImage; + CBIOS_U32 RomImageLength; + PCBIOS_VOID pSpinLock; + PCBIOS_VOID pAuxMutex; + PCBIOS_VOID pI2CMutex[CBIOS_MAX_I2CBUS]; + PCBIOS_VOID pAdapterContext; + CBIOS_U32 MAMMPrimaryAdapter; + CBIOS_U32 GeneralChipID; + CBIOS_U32 PCIDeviceID; + CBIOS_U32 ChipID; + CBIOS_U32 ChipRevision; + CBIOS_U32 bRunOnQT; + CBIOS_U32 bDriverLoadQTiming; +} CBIOS_PARAM_INIT, *PCBIOS_PARAM_INIT; + +typedef struct _CBIOS_PARAM_SHADOWINFO{ + PCBIOS_VOID SysShadowAddr; + CBIOS_U32 SysShadowLength; +}CBIOS_PARAM_SHADOWINFO, *PCBIOS_PARAM_SHADOWINFO; + +typedef struct _CBIOS_VBIOS_DATA_PARAM +{ + CBIOS_U32 Size; + CBIOS_U32 SyncToVbios; // 1 means sync from cbios to vbios; + // 0 means sync from vbios to cbios; +}CBIOS_VBIOS_DATA_PARAM,*PCBIOS_VBIOS_DATA_PARAM; + +typedef struct _CBIOS_PARAM_CHECK_CHIPENABLE { + CBIOS_U32 Size; + CBIOS_BOOL IsChipEnable; +}CBIOS_PARAM_CHECK_CHIPENABLE, *PCBIOS_PARAM_CHECK_CHIPENABLE; + +typedef struct _CBIOS_PARAM_DUMP_REG { + CBIOS_U32 Size; + CBIOS_U32 DumpType; /* by index or by group */ + CBIOS_U32 RegGroupID; /* or Reg Index */ + CBIOS_U32 RegBufferLen; /*for validate buffer size for group dump*/ + CBIOS_UCHAR* RegBuffer; +} CBIOS_PARAM_DUMP_REG, *PCBIOS_PARAM_DUMP_REG; + +typedef struct _CBIOS_PARAM_GET_EDID { + CBIOS_U32 Size; + CBIOS_UCHAR PortNumber; /* Edid port number */ + CBIOS_UCHAR* EdidBuffer; + CBIOS_U32 EdidBufferLen; /* Edid buffer size */ + CBIOS_U32 DeviceId; /* Device Bitfiled */ + CBIOS_U32 Flag; /* Flag to tell CBios use device bitfield or PortNumber to get Edid: 0: use port number, 1: use device bit field */ + CBIOS_U32 Reserved; +} CBIOS_PARAM_GET_EDID, *PCBIOS_PARAM_GET_EDID; + +typedef struct _CBiosCustmizedDestTiming +{ + CBIOS_U32 Size; + /*For Display Port device*/ + CBIOS_U32 LinkRate; /* 6:1.62Gbps, 0xA: 2.7Gbps, 0x14: 5.4Gbps*/ + CBIOS_U32 LaneCount; /* 1: one lane, 2: two lanes, 4: four lanes */ + CBIOS_U32 TestPattern; /* 0: No test pattern transmitted */ + /* 1: Color Ramps */ + /* 2: Black and white vertical lines */ + /* 3: color square */ + CBIOS_U32 ClockSynAsyn; /* 0: Link clock and stream clock asynchronous */ + /* 1: Link clock and stream clock synchronous*/ + CBIOS_U32 DynamicRange; /* 0: Vesa Range, 1: CEA range */ + CBIOS_U32 ColorFormat; /* 0: RGB, 1: YcbCR422, 2:YCbCr444 */ + CBIOS_U32 YCbCrCoefficients; /* 0: ITU601, 1: ITU709 */ + CBIOS_U32 EnhancedFrameMode; /* 0: normal frame mode, 1: enhanced frame mode */ + CBIOS_U32 BitDepthPerComponet; /* 0: 6 Bits */ + /* 1: 8 bits */ + /* 2: 10bits */ + /* 3: 12bits */ + /* 4: 16bits */ + /*Normal timing settings */ + CBIOS_U32 IsInterlaced; /* 0: non-interlaced, 1: interlaced */ + CBIOS_U32 HorTotal; /* Horizontal total of transmitted video stream in pixel count */ + CBIOS_U32 VerTotal; /* Vertical total of transmitted video stream in line count */ + CBIOS_U32 HorSyncStart; /* Horizontal active start from Hsync start in pixel count */ + CBIOS_U32 VerSyncStart; /* Vertical active start from Vsync start in line count */ + CBIOS_U32 HorSyncWidth; /* HSync width in pixel count */ + CBIOS_U32 VerSyncWidth; /* VSync width in line count */ + CBIOS_U32 HSyncPolarity; /* 0: Negative, 1: Positive */ + CBIOS_U32 VSyncPolarity; /* 0: Negative, 1: Positive */ + CBIOS_U32 HorWidth; /* Active video width in pixel count */ + CBIOS_U32 VerWidth; /* Active video height in line count */ + CBIOS_U32 DClk; /* DClk in Hz / 10000 */ + +}CBiosCustmizedDestTiming, *PCBiosCustmizedDestTiming; + + +typedef struct _CBIOS_PARAM_I2C_DATA { + CBIOS_U32 Size; + CBIOS_UCHAR PortNumber; /* Edid port number */ + CBIOS_UCHAR SlaveAddress; + CBIOS_UCHAR OffSet; + CBIOS_UCHAR* Buffer; + CBIOS_U32 BufferLen; /* Edid buffer size */ + CBIOS_U32 Flags; /* from OS, defined in DxgkDdiI2CReceiveDataFromDisplay in DDK*/ + CBIOS_U32 RequestType; /* CBIOS_I2CDDCCI: from DDCCI; CBIOS_I2CHDCP: from HDCP; use macro */ + CBIOS_S32 bHDCPEnable; /* indicate use DDC or HDCP */ + CBIOS_BOOL bUseDevType; /* = 1: driver send PortType, cbios will get correct I2C bus + = 0: driver send PortNumber directly, for old driver only */ + CBIOS_U32 DeviceId; + CBIOS_U32 Reserved; +} CBIOS_PARAM_I2C_DATA, *PCBIOS_PARAM_I2C_DATA; + +typedef enum _CBIOS_VIP_FORMAT +{ + CBIOS_VIP_FMT_INVALID = 0, + CBIOS_VIP_FMT_RAW_8BIT = 1, + CBIOS_VIP_FMT_RAW_10BIT = 2, + CBIOS_VIP_FMT_RAW_16BIT = 3, + CBIOS_VIP_FMT_RGB444_24BIT_SDR = 4, + CBIOS_VIP_FMT_RGB444_15BIT_DDR = 5, + CBIOS_VIP_FMT_RGB444_12BIT_DDR = 6, + CBIOS_VIP_FMT_YCBCR444_24BIT_SDR = 7, + CBIOS_VIP_FMT_YCBCR444_15BIT_DDR = 8, + CBIOS_VIP_FMT_YCBCR444_12BIT_DDR = 9, + CBIOS_VIP_FMT_YCBCR422_20BIT_SDR_ES = 10, + CBIOS_VIP_FMT_YCBCR422_20BIT_SDR_SS = 11, + CBIOS_VIP_FMT_YCBCR422_20BIT_DDR_ES = 12, + CBIOS_VIP_FMT_YCBCR422_20BIT_DDR_SS = 13, + CBIOS_VIP_FMT_YCBCR422_16BIT_SDR_ES = 14, + CBIOS_VIP_FMT_YCBCR422_16BIT_SDR_SS = 15, + CBIOS_VIP_FMT_YCBCR422_16BIT_DDR_ES = 16, + CBIOS_VIP_FMT_YCBCR422_16BIT_DDR_SS = 17, + CBIOS_VIP_FMT_YCBCR422_10BIT_SDR_ES = 18, + CBIOS_VIP_FMT_YCBCR422_10BIT_SDR_SS = 19, + CBIOS_VIP_FMT_YCBCR422_8BIT_SDR_ES = 20, + CBIOS_VIP_FMT_YCBCR422_8BIT_SDR_SS = 21, + CBIOS_VIP_FMT_YCBCR422_8BIT_DDR_ES = 22, + CBIOS_VIP_FMT_YCBCR422_8BIT_DDR_SS = 23, +}CBIOS_VIP_FORMAT, *PCBIOS_VIP_FORMAT; + +typedef enum _CBIOS_VIP_CARD +{ + CBIOS_VIP_CARD_NONE = 0, + CBIOS_VIP_CARD_AVD7611 = 1, +}CBIOS_VIP_CARD, *PCBIOS_VIP_CARD; + +typedef enum _CBIOS_VIP_CTRL_CMD +{ + CBIOS_VIP_NOP = 0, + CBIOS_VIP_SET_BUFFER, + CBIOS_VIP_SET_MODE, + CBIOS_VIP_ENABLE, + CBIOS_VIP_RESET, + CBIOS_VIP_GET_STATUS, + CBIOS_VIP_QUERY_CAPS, +}CBIOS_VIP_CTRL_CMD; + +typedef struct _CBIOS_VIP_MODE +{ + unsigned int xRes; + unsigned int yRes; + unsigned int refs; + CBIOS_VIP_FORMAT fmt; +}CBIOS_VIP_MODE; + +typedef struct _CBIOS_VIP_CTRL_DATA +{ + CBIOS_VIP_CTRL_CMD cmd; + CBIOS_U8 vip; + union + { + struct + { + CBIOS_U8 num; + CBIOS_U8 idx; + CBIOS_U64 addr; + }fbSet; + + struct + { + CBIOS_VIP_FORMAT fmt; + CBIOS_VIP_CARD vCard; + CBIOS_U32 xRes; + CBIOS_U32 yRes; + CBIOS_U32 refs; + }modeSet; + + struct + { + CBIOS_U32 supportModeNum; + CBIOS_VIP_MODE *mode; + }caps; + + CBIOS_U8 enable; + }; +}CBIOS_VIP_CTRL_DATA, *PCBIOS_VIP_CTRL_DATA; + +typedef struct _CBIOS_TIMING_ATTRIB +{ + CBIOS_U32 Size; + CBIOS_U32 FormatNum; + CBIOS_U16 XRes; + CBIOS_U16 YRes; + CBIOS_U16 RefreshRate; + CBIOS_U32 PixelClock; /* pixel clock value */ + CBIOS_UCHAR AspectRatio; /* 0 means default, 1 means 4:3, 2 means 16:9*/ + CBIOS_UCHAR HVPolarity; /* Hor/Ver Sync Polarity(MISC:11000000B)*/ + CBIOS_U16 HorTotal; /* CR5F_1-0+CR5D_0+CR0=Round(Value/8)-5 */ + CBIOS_U16 HorDisEnd; /* CR5F_3-2+CR5D_1+CR1=Round(Value/8)-1 */ + CBIOS_U16 HorBStart; /* CR5F_5-4+CR5D_2+CR2=Round(Value/8) */ + CBIOS_U16 HorBEnd; /* CR5_7+CR3_4-0 =Round(Value/8)& 0x003F*/ + CBIOS_U16 HorSyncStart; /* CR5F_7-6+CR5D_4+CR4 =Round(Value/8)*/ + CBIOS_U16 HorSyncEnd; /* CR5_B4-0 =Round(Value/8) & 0x001F*/ + CBIOS_U16 VerTotal; /* CR5E_0+CR7_5+CR7_0+CR6=Value-2 */ + CBIOS_U16 VerDisEnd; /* CR5E_1+CR7_6+CR7_1+CR12=Value-1 */ + CBIOS_U16 VerBStart; /* CR5E_2+CR9_5+CR7_3+CR15=Value-1 */ + CBIOS_U16 VerBEnd; /* CR16 */ + CBIOS_U16 VerSyncStart; /* CR5E_4+CR7_7+CR7_2+CR10 */ + CBIOS_U16 VerSyncEnd; /* CR11_3-0 */ + CBIOS_U32 PLLClock; /* DIU PLL value */ +}CBIOS_TIMING_ATTRIB, *PCBIOS_TIMING_ATTRIB; + +typedef struct _CBIOS_I2CCONTROL /*For DDC-CI */ +{ + CBIOS_U32 Size; + CBIOS_U32 Command; /* I2C_COMMAND_* */ + CBIOS_U32 dwCookie; /* Context identifier returned on Open*/ + CBIOS_UCHAR Data; /* Data to write, or returned byte */ + CBIOS_UCHAR Reserved[3]; /* Filler */ + CBIOS_U32 Flags; /* I2C_FLAGS_* */ + CBIOS_U32 Status; /* I2C_STATUS_* */ + CBIOS_U32 ClockRate; /* Bus clockrate in Hz.*/ +}CBIOS_I2CCONTROL, *PCBIOS_I2CCONTROL; + +/* The following structure is for new setting mode logic */ + + +typedef struct _CBios_Mode_Info_Ext +{ + CBIOS_U32 Size; + CBIOS_U32 XRes; + CBIOS_U32 YRes; + CBIOS_U32 RefreshRate; + CBIOS_U32 InterlaceProgressiveCaps; /* Bit0: Progressive Caps Bit1:Interlace Caps */ + CBIOS_U32 AdapterDeviceFlags; /* 0: Means adapter mode, 1:Means device mode */ + CBIOS_U32 DeviceFlags; /* Bit definition same as device bit definitions */ + CBIOS_U32 ColorDepthCaps; /* Bit0: 32Bits ARGB color depth capability*/ + /* Bit1: 16Bits color depth capability*/ + /* Bit2: 8Bits color depth capability*/ + /* Bit3: ABGR888 capability */ + /* Bit4: ARGB 2101010 capability */ + /* Bit5: ABGR 2101010 capability */ + CBIOS_U32 AspectRatioCaps; /* Bit0: 4:3 capability */ + /* Bit1: 16:9 capability */ + CBIOS_U32 NativeModeFlags; /* =0: Means normal mode */ + /* =1: Means native mode */ + union + { + CBIOS_U32 ModeFlags; + struct + { + CBIOS_U32 isCEAMode :1; /* Bit0 = 1, Means is a CE mode */ + /* = 0, Means is a PC normal mode */ + CBIOS_U32 isAddedDevMode :1; /* Bit1 = 1, Means is a added device mode */ + /* In modes whose XRes x YRes is 1920x1080, 1280x720, or 720x480, we should make */ + /* mode having RefreshRate 6000(3000) and mode having RefreshRate between 5900(2900) and */ + /* 5999(2999) paried with each other */ + /* = 0, Means is a normal mode */ + /* Bit2:15 14 bits for different timing types, 5 types at present*/ + CBIOS_U32 isEstablishedTiming :1; /* bit2 = 1, the mode is from Established timing block */ + CBIOS_U32 isStandardTiming :1; /* bit3 = 1, the mode is from Standard timing block */ + CBIOS_U32 isDetailedTiming :1; /* bit4 = 1, the mode is from Detailed timing block */ + CBIOS_U32 isSVDTiming :1; /* bit5 = 1, the mode is from Short Video Descriptor */ + CBIOS_U32 isDTDTiming :1; /* bit6 = 1, the mode is from Detailed Timing Descriptor */ + CBIOS_U32 RsvdModeType :9; /* bit7:15 for future mode types use */ + CBIOS_U32 Reserved :2; /* Bit 17-16 2 bits reserved */ + CBIOS_U32 isPreferredMode :1; /* Bit 18: Preferred mode flag*/ + /* bit18 = 1: preferred mode*/ + /* bit18 = 0: not preferred mode*/ + CBIOS_U32 RsvdModeFlags :13;/* Other bits reserved for future use */ + + }; + }; +} CBiosModeInfoExt, *PCBiosModeInfoExt; + +typedef enum _CBIOS_HDMI_AUDIO_FORMAT_TYPE { + CBIOS_AUDIO_FORMAT_REFER_TO_STREAM_HEADER, + CBIOS_AUDIO_FORMAT_LPCM, + CBIOS_AUDIO_FORMAT_AC_3, + CBIOS_AUDIO_FORMAT_MPEG_1, + CBIOS_AUDIO_FORMAT_MP3, + CBIOS_AUDIO_FORMAT_MPEG_2, + CBIOS_AUDIO_FORMAT_AAC_LC, + CBIOS_AUDIO_FORMAT_DTS, + CBIOS_AUDIO_FORMAT_ATRAC, + CBIOS_AUDIO_FORMAT_DSD, + CBIOS_AUDIO_FORMAT_E_AC_3, + CBIOS_AUDIO_FORMAT_DTS_HD, + CBIOS_AUDIO_FORMAT_MLP, + CBIOS_AUDIO_FORMAT_DST, + CBIOS_AUDIO_FORMAT_WMA_PRO, + CBIOS_AUDIO_FORMAT_HE_AAC, + CBIOS_AUDIO_FORMAT_HE_AAC_V2, + CBIOS_AUDIO_FORMAT_MPEG_SURROUND +}CBIOS_HDMI_AUDIO_FORMAT_TYPE, *PCBIOS_HDMI_AUDIO_FORMAT_TYPE; + +typedef struct _CBIOS_HDMI_AUDIO_FORMAT +{ + CBIOS_U32 Size; + CBIOS_HDMI_AUDIO_FORMAT_TYPE Format; + CBIOS_U32 MaxChannelNum; + union + { + struct + { + CBIOS_U32 SR_32kHz :1; /* Bit0 = 1, support sample rate of 32kHz */ + CBIOS_U32 SR_44_1kHz :1; /* Bit1 = 1, support sample rate of 44.1kHz */ + CBIOS_U32 SR_48kHz :1; /* Bit2 = 1, support sample rate of 48kHz */ + CBIOS_U32 SR_88_2kHz :1; /* Bit3 = 1, support sample rate of 88.2kHz */ + CBIOS_U32 SR_96kHz :1; /* Bit4 = 1, support sample rate of 96kHz */ + CBIOS_U32 SR_176_4kHz :1; /* Bit5 = 1, support sample rate of 176.4kHz */ + CBIOS_U32 SR_192kHz :1; /* Bit6 = 1, support sample rate of 192kHz */ + CBIOS_U32 Reserved :25; + }SampleRate; + + CBIOS_U32 SampleRateUnit; + }; + + union + { + CBIOS_U32 Unit; + + // for audio format: LPCM + struct + { + CBIOS_U32 BD_16bit :1; /* Bit0 = 1, support bit depth of 16 bits */ + CBIOS_U32 BD_20bit :1; /* Bit1 = 1, support bit depth of 20 bits */ + CBIOS_U32 BD_24bit :1; /* Bit2 = 1, support bit depth of 24 bits */ + CBIOS_U32 Reserved :29; + }BitDepth; + + // for audio format: AC-3, MPEG-1, MP3, MPED-2, AAC LC, DTS, ATRAC + CBIOS_U32 MaxBitRate; // unit: kHz + + // for audio format: DSD, E-AC-3, DTS-HD, MLP, DST + CBIOS_U32 AudioFormatDependValue; /* for these audio formats, this value is defined in + it's corresponding format-specific documents*/ + + // for audio format: WMA Pro + struct + { + CBIOS_U32 Value :3; + CBIOS_U32 Reserved :29; + }Profile; + }; +}CBiosHDMIAudioFormat, *PCBiosHDMIAudioFormat; + +typedef struct _CBios_Source_Mode_Params +{ + CBIOS_U32 Size; + CBIOS_U32 XRes; + CBIOS_U32 YRes; +}CBiosSourceModeParams, *PCBiosSourceModeParams; + + +typedef struct _CBios_Dest_Mode_Params +{ + CBIOS_U32 Size; + CBIOS_U32 XRes; + CBIOS_U32 YRes; + CBIOS_U32 RefreshRate; + CBIOS_U32 InterlaceFlag; /* =0, Set noninterlace mode; = 1, Set interlace mode; */ + CBIOS_U32 AspectRatioFlag; /* =0, Default aspect ratio */ + /* =1, 4:3 aspect ratio*/ + /* =2, 16:9 aspect ratio */ + CBIOS_U32 OutputSignal; /* =0x1; RGB signal */ + /* =0x2; YCbCr422 signal */ + /* =0x4; YCbCr444 signal */ + /* DP device will also use this attribute, and is called Color format */ +}CBiosDestModeParams, *PCBiosDestModeParams; + +typedef struct _CBios_ScalerSize_Params +{ + CBIOS_U32 Size; + CBIOS_U32 XRes; + CBIOS_U32 YRes; +}CBiosScalerSizeParams, *PCBiosScalerSizeParams; + +typedef struct _CBios_GetClock_Params +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_OUT CBIOS_U32 *ClockFreq; /* CBIOS_IN: this pointer must be defined */ + CBIOS_IN CBIOS_U32 ClockType; /* CBIOS_MCLKTYPE and so on*/ +}CBios_GetClock_Params, *PCBios_GetClock_Params; + +typedef struct _CBios_SetClock_Params +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 ClockFreq; + CBIOS_IN CBIOS_U32 ClockType; // CBIOS_ICLKTYPE and CBIOS_VCLKTYPE +}CBios_SetClock_Params, *PCBios_SetClock_Params; + +typedef struct _CBios_VoltageSetting_Params +{ + CBIOS_U32 Size; /*struct size, used for future revsion contol*/ + CBIOS_UCHAR IsVoltageScalingSupported; /*where the card supported Voltage Scaling*/ + CBIOS_S32 FunctionNO; /*1-Get Voltage Params and current Volage, 2-Set Voltage value,4-query is voltage scale support */ + CBIOS_UCHAR method; /*0-I2c,1-GPIO*/ + CBIOS_UCHAR I2CValueNumber; /*used for I2C,indicate support how much value levell */ + CBIOS_UCHAR DefaultVoltageValue;/*VBIOS post VoltageValue*/ + CBIOS_UCHAR CurrentVoltageValue;/*current VoltageValue*/ + CBIOS_UCHAR ExpectedValue; /*driver set ,for I2c, just use the value level,I2CValueNumber-1 indicates the highest level, + the lowest level is 0 + for GPIO,1- high level,0 -low level*/ + +}CBiosVoltageSettingParams, *PCBiosVoltageSettingParams; + +typedef struct _CBIOS_SUPPORT_BPC_FLAGS +{ + CBIOS_U32 IsSupport6BPC :1; + CBIOS_U32 IsSupport8BPC :1; + CBIOS_U32 IsSupport10BPC :1; + CBIOS_U32 IsSupport12BPC :1; + CBIOS_U32 IsSupport14BPC :1; + CBIOS_U32 IsSupport16BPC :1; + CBIOS_U32 RservedBPC :26; +}CBIOS_SUPPORT_BPC_FLAGS, *PCBIOS_SUPPORT_BPC_FLAGS; + +typedef struct _CBiosMonitorAttribute +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 ActiveDevId; /*Encoder or legacy active_type*/ + CBIOS_OUT CBIOS_MONITOR_TYPE MonitorType; //if current port is split, this variable stores the monitor type of Y channel + //if current port is not split, this variable stores the monitor type of this port + CBIOS_OUT CBIOS_UCHAR MonitorID[8]; + CBIOS_OUT CBIOS_U32 MonitorCaps; /*bit[0]=1: device support CEA861*/ + /*bit[1]=1: RGB support*/ + /*bit[2]=1: YCrCr4:2:2 support*/ + /*bit[3]=1: YCbCr4:4:4 support*/ + CBIOS_OUT CBIOS_SUPPORT_BPC_FLAGS SupportBPC; + CBIOS_OUT CBIOS_U16 MonitorHorSize; //Monitor screen image horizontal size in millimeter(mm), if calculate DPI should convert it to inch, 1 inch = 25.4 mm + CBIOS_OUT CBIOS_U16 MonitorVerSize; //Monitor screen image vertical size in millimeter(mm), if calculate DPI should convert it to inch, 1 inch = 25.4 mm + CBIOS_OUT CBIOS_BOOL bSupportHDAudio; // Encoder and HDMI monitor both support audio + + struct + { + CBIOS_OUT CBIOS_BOOL bSupportBLCtrl; // monitor support backlight control or not + CBIOS_OUT CBIOS_U32 MaxBLLevel; + CBIOS_OUT CBIOS_U32 MinBLLevel; + }; +}CBiosMonitorAttribute, *PCBiosMonitorAttribute; + +typedef struct _CBiosContentProtectionOnOffParams +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DevicesId; + CBIOS_IN CBIOS_U32 bHdcpStatus; +}CBiosContentProtectionOnOffParams, *PCBiosContentProtectionOnOffParams; + +typedef struct _CBiosAccessDpcdDataParams +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 ReadWriteFlag; /* 0: Means read, 1: Means write.*/ + CBIOS_IN CBIOS_U32 RequestConnectedDevId; /*Encoder or legacy active_type*/ + CBIOS_IN CBIOS_U32 StartingAddress; + CBIOS_IN CBIOS_U32 NumOfBytes; + CBIOS_IN CBIOS_OUT CBIOS_UCHAR *pOutBuffer; +}CBiosAccessDpcdDataParams, *PCBiosAccessDpcdDataParams; + +typedef struct _CBiosSpecifyDstTimingSrc +{ + CBIOS_U32 Size; + CBIOS_U32 Flag; /* 0: Use CBIOS default method to select where timing come from*/ + /* 1: Use user input customized timing, if this value is set, pUserCustDestTiming can not be CBIOS_NULL*/ + /* 2: Use automated test DPCD timing*/ + /* other value: reserved */ + CBiosCustmizedDestTiming UserCustDestTiming; /* If Flag is set to 1, this structure is the user defined timing buffer*/ +}CBiosSpecifyDstTimingSrc, *PCBiosSpecifyDstTimingSrc; + +#define CB_SET_MODE_PS_SS_SEPARATE_FLAG BIT3 +#define CB_SET_MODE_DIU_PS_ENABLE_COMPRESSION_FLAG BIT4 +#define CB_SET_MODE_DIU_SS_ENABLE_COMPRESSION_FLAG BIT5 + +typedef enum _CBIOS_3D_STRUCTURE +{ + FRAME_PACKING = 0x00, + FIELD_ALTERNATIVE, + LINE_ALTERNATIVE, + SIDE_BY_SIDE_FULL, + L_DEPTH, + L_DEPTH_GRAPHICS, + TOP_AND_BOTTOM, + RESERVED_3D_STRUCTURE, + SIDE_BY_SIDE_HALF, + NOT_IN_USE_3D_STRUCTURE = 0x0F, +}CBIOS_3D_STRUCTURE, *PCBIOS_3D_STRUCTURE; + +typedef enum _CBIOS_3D_VIEW_DEPENDENCY +{ + VIEW_DEPENDENCY_NO_INDICATION = 0, + VIEW_DEPENDENCY_RIGHT, + VIEW_DEPENDENCY_LEFT, + VIEW_DEPENDENCY_BOTH, +}CBIOS_3D_VIEW_DEPENDENCY; + +typedef enum _CBIOS_3D_PREFERRED_2D_VIEW +{ + PREFERRED_2D_VIEW_NO_INDICATION = 0, + PREFERRED_2D_VIEW_RIGHT, + PREFERRED_2D_VIEW_LEFT, + PREFERRED_2D_VIEW_NOT_CARE, +}CBIOS_3D_PREFERRED_2D_VIEW; + +typedef struct _CBIOS_3D_INDEPENDENT_VIEW +{ + CBIOS_3D_VIEW_DEPENDENCY Dependency; + CBIOS_3D_PREFERRED_2D_VIEW Preferred2D; +}CBIOS_3D_INDEPENDENT_VIEW, *PCBIOS_3D_INDEPENDENT_VIEW; + +typedef struct _CBIOS_3D_DISPARITY_PARA +{ + CBIOS_U8 Version; + CBIOS_U8 DisparityLength; + CBIOS_U8 DisplarityData[255]; +}CBIOS_3D_DISPARITY_PARA, *PCBIOS_3D_DISPARITY_PARA; + +typedef enum _CBIOS_FORMAT +{ + CBIOS_FMT_INVALID = 0x0000, + CBIOS_FMT_P8 = 0x0001, + CBIOS_FMT_R5G6B5 = 0x0002, + CBIOS_FMT_A1R5G5B5 = 0x0004, + CBIOS_FMT_A8R8G8B8 = 0x0008, + CBIOS_FMT_A8B8G8R8 = 0x0010, + CBIOS_FMT_X8R8G8B8 = 0x0020, + CBIOS_FMT_X8B8G8R8 = 0x0040, + CBIOS_FMT_A2R10G10B10 = 0x0080, + CBIOS_FMT_A2B10G10R10 = 0x0100, + CBIOS_FMT_CRYCBY422_16BIT = 0x0200, + CBIOS_FMT_YCRYCB422_16BIT = 0x0400, + CBIOS_FMT_CRYCBY422_32BIT = 0x0800, + CBIOS_FMT_YCRYCB422_32BIT = 0x1000, + CBIOS_FMT_YCBCR8888_32BIT = 0x2000, + CBIOS_FMT_YCBCR2101010_32BIT = 0x4000, + CBIOS_FMT_CRYCB8888_32BIT = 0x8000, + CBIOS_FMT_CRYCB2101010_32BIT = 0x10000, +}CBIOS_FORMAT, *PCBIOS_FORMAT; + +typedef enum _CBIOS_RANGE_TYPE +{ + CBIOS_RANGE_OFF = 0, + CBIOS_RGBAX8888_TILE = 1, + CBIOS_RGBAX8888_LINEAR = 2, + CBIOS_XARGB8888_TILE =3, + CBIOS_XARGB8888_LINEAR =4, + CBIOS_R10G10B10A2_LINEAR = 5, + CBIOS_A2B10G10R10_LINEAR = 6, + CBIOS_R11G11B10_LINEAR =7, + CBIOS_R5G6B5_TILE = 8, + CBIOS_YUYV_LINEAR = 10, + CBIOS_UYVY_LINEAR = 11, +}CBIOS_RANGE_TYPE,*PCBIOS_RANGE_TYPE; + +typedef struct _CBios_Setting_Mode_Params +{ + CBIOS_U32 Size; + CBIOS_U32 ulCBiosVersion; + CBiosSourceModeParams SourcModeParams; + CBiosDestModeParams DestModeParams; + CBiosScalerSizeParams ScalerSizeParams; + CBIOS_U32 IGAIndex; /* Specify which IGA need to be set mode, this can not be 0. */ + CBiosSpecifyDstTimingSrc SpecifyTiming; /* CustDestTiming structure value to set destination timing*/ + /* Normally this structure is useless, if driver do not want to specified the dest timing*/ + /* Notices, in this case, the other member parameter still need be set right */ + struct + { + CBIOS_U32 Is3DVideoMode :1; /* = 1: 3D Video mode, and 3D format is in Video3DFormat; = 0: normal 2D mode*/ + CBIOS_U32 IsSingleBuffer :1; /* = 1: 3D video data is in a single buffer; =0: 3D video data is in separate two buffers */ + CBIOS_U32 SkipIgaMode :1; + CBIOS_U32 SkipDeviceMode :1; + CBIOS_U32 Reserved :28;/* Reserved for future use*/ + }; + CBIOS_3D_STRUCTURE Video3DStruct; + CBIOS_U32 BitPerComponent; +}CBiosSettingModeParams,*PCBiosSettingModeParams; + +typedef enum _CBIOS_STREAM_TP +{ + CBIOS_STREAM_PS = 0, + CBIOS_STREAM_SS = 1, + CBIOS_STREAM_TS = 2, + CBIOS_STREAM_FS = 3, + STREAM_NUM_E3K = 4, +} CBIOS_STREAM_TP, *PCBIOS_STREAM_TP; + +typedef enum _CBIOS_OVL_TP +{ + CBIOS_OVERLAY0 = 0, + CBIOS_OVERLAY1 = 1, + CBIOS_OVERLAY2 = 2, + CBIOS_OVERLAY3 = 3, + OVL_NUM_E3K = 4, +} CBIOS_OVL_TP, *PCBIOS_OVL_TP; + +#define PLANE_NUM_E3K OVL_NUM_E3K +#define CBIOS_MAX_PLANE_CNT PLANE_NUM_E3K + +typedef enum _CBIOS_OVERLAY_MODE +{ + CBIOS_INVALID_KEYING_MODE = 0x00, + CBIOS_WINDOW_KEY = 0x01, + CBIOS_ALPHA_KEY = 0x02, + CBIOS_COLOR_KEY = 0x03, + CBIOS_ALPHA_BLENDING = 0x04, + CBIOS_CONSTANT_ALPHA = 0x05, + CBIOS_CHROMA_KEY = 0x06, +}CBIOS_OVERLAY_MODE, *PCBIOS_OVERLAY_MODE; + +typedef enum _CBIOS_MIX_ALPHA_TYPE +{ + CBIOS_MIX_ALPHA_A_B = 0x00, + CBIOS_MIX_ALPHA_A = 0x01, + CBIOS_MIX_ALPHA_B = 0x02, +}CBIOS_MIX_ALPHA_TYPE, *PCBIOS_MIX_ALPHA_TYPE; + +typedef enum _CBIOS_COLOR_KEY_TYPE +{ + CBIOS_COLOR_KEY_A_OR_B = 0x00, + CBIOS_COLOR_KEY_A = 0x01, + CBIOS_COLOR_KEY_B = 0x02, +}CBIOS_COLOR_KEY_TYPE, *PCBIOS_COLOR_KEY_TYPE; + +typedef enum _CBIOS_PLANE_FLIP_MODE +{ + CBIOS_PLANE_INVALID_FLIP = 0, + CBIOS_PLANE_FLIP_ONLY = 1, + CBIOS_PLANE_FLIP_WITH_ENABLE = 2, + CBIOS_PLANE_FLIP_WITH_DISABLE = 3, +}CBIOS_PLANE_FLIP_MODE, *PCBIOS_PLANE_FLIP_MODE; + +typedef struct _CBIOS_OVERLAY_INFO +{ + CBIOS_OVERLAY_MODE KeyMode; + union + { + struct + { + CBIOS_U8 Ka; //for SS overlay, is coefficient of PS, for TS overlay, is coefficient of (PS+SS) + CBIOS_U8 Kb; //for SS overlay, is coefficient of SS, for TS overlay, is coefficient of TS. + }WindowKey; + + struct + { + CBIOS_U8 Ka; + CBIOS_U8 Kb; + struct + { + CBIOS_U16 bAOverB :1; //for SS overlay, 0 is SS over PS, 1 is PS over SS, + CBIOS_U16 Reserved :15; //for TS overlay, 0 is TS over (PS+SS), 1 is (PS+SS) over TS + }; + }AlphaKey; + + struct + { + CBIOS_U8 ColorKeyType; + struct + { + CBIOS_U8 bAOverB :1; + CBIOS_U8 b10bitColor :1; //control the color format of (PS+SS) + CBIOS_U8 Reserved :6; + }; + }ColorKey; + + struct + { + CBIOS_U8 ConstantAlpha; + CBIOS_U8 PlaneValue; + struct + { + CBIOS_U16 bInvertAlpha :1; + CBIOS_U16 bUsePlaneAlpha :1; + CBIOS_U16 Reserved :14; + }; + }ConstantAlphaBlending; + + struct + { + CBIOS_U8 PlaneValue; + CBIOS_U8 AlphaMixType; + struct + { + CBIOS_U16 bUsePlaneAlpha :1; + CBIOS_U16 bUseAAlpha :1; //for SS, 0 is SS alpha blending, 1 is PS alpha blending + CBIOS_U16 bPremulBlend :1; //0, (1-alpha1)*PS+alpha1*SS, 1, (1-alpha1)*PS+1*SS + CBIOS_U16 bInvertAlpha :1; + CBIOS_U16 Reserved :12; + }; + }AlphaBlending; + CBIOS_U32 Value; + }; +}CBIOS_OVERLAY_INFO, *PCBIOS_OVERLAY_INFO; + +typedef enum _CSC_FORMAT +{ + CSC_FMT_RGB = 0x00, + CSC_FMT_LIMITED_RGB, + CSC_FMT_YUV601, + CSC_FMT_YUV709, + CSC_FMT_YCBCR601, + CSC_FMT_YCBCR709, + CSC_FMT_YCBCR2020, + CSC_FMT_YUV2020, +}CSC_FORMAT; + +typedef enum _CSC_INDEX +{ + CSC_INDEX_CRT = 0, + CSC_INDEX_DP1 = 1, + CSC_INDEX_DP2 = 2, + CSC_INDEX_DP3 = 3, + CSC_INDEX_DP4 = 4, +}CSC_INDEX; + +typedef struct _CBIOS_CSC_ADJUST_PARA +{ + CSC_FORMAT InputFormat; + CSC_FORMAT OutputFormat; + CBIOS_U32 IGAIndex; + CBIOS_S32 Contrast; + CBIOS_S32 Saturation; + CBIOS_S32 Hue; + CBIOS_S32 Bright; + struct + { + CBIOS_U32 bProgrammable :1; + CBIOS_U32 Reserved :31; + }Flag; +}CBIOS_CSC_ADJUST_PARA,*PCBIOS_CSC_ADJUST_PARA; + +typedef struct _CBIOS_STREAM_CSC_PARA +{ + CSC_FORMAT InputFormat; + CSC_FORMAT OutputFormat; + CBIOS_U32 IGAIndex; + CBIOS_S32 Contrast; + CBIOS_S32 Saturation; + CBIOS_S32 Hue; + CBIOS_S32 Bright; + struct + { + CBIOS_U32 bProgrammable :1; + CBIOS_U32 Reserved :31; + }Flag; + CBIOS_U32 StreamType; +}CBIOS_STREAM_CSC_PARA,*PCBIOS_STREAM_CSC_PARA; + +typedef struct _CBIOS_3D_SURFACE_PARA +{ + CBIOS_U32 RightFrameOffset; + CBIOS_3D_STRUCTURE Video3DStruct; +}CBIOS_3D_SURFACE_PARA, *PCBIOS_3D_SURFACE_PARA; + +typedef struct _CBIOS_SURFACE_ATTRIB +{ + CBIOS_U64 StartAddr; + CBIOS_FORMAT SurfaceFmt; + CBIOS_U32 SurfaceSize; // w | (h << 16) + CBIOS_U32 Pitch; + CBIOS_3D_SURFACE_PARA Surface3DPara; + CBIOS_U32 BLIndex; + CBIOS_U32 Range_Type; + + struct + { + CBIOS_U32 bCompress :1; + CBIOS_U32 b3DMode :1; + CBIOS_U32 Reserved :30; + }; +}CBIOS_SURFACE_ATTRIB, *PCBIOS_SURFACE_ATTRIB; + +typedef struct _CBIOS_WINDOW_PARA +{ + CBIOS_U32 Position; //from 0 to SourceSizeX-1, x | (y << 16) + CBIOS_U32 WinSize; +}CBIOS_WINDOW_PARA, *PCBIOS_WINDOW_PARA; + +typedef struct _CBIOS_STREAM_PARA +{ + CBIOS_SURFACE_ATTRIB SurfaceAttrib; + CBIOS_WINDOW_PARA DispWindow; + CBIOS_WINDOW_PARA SrcWindow; +}CBIOS_STREAM_PARA, *PCBIOS_STREAM_PARA; + +typedef union _CBIOS_FLIP_MODE +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FlipType : 3; + CBIOS_U32 FlipImme : 1; + CBIOS_U32 Reserved : 28; + }; +}CBIOS_FLIP_MODE, *PCBIOS_FLIP_MODE; + +typedef union _CBIOS_TRIG_MODE +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TrigPlane : 3; + CBIOS_U32 OneShotTrig : 1; + CBIOS_U32 Reserved : 28; + }; +}CBIOS_TRIG_MODE, *PCBIOS_TRIG_MODE; + +typedef enum _CBIOS_OVL_KEY_TYPE +{ + CBIOS_OVL_KEY_TYPE_INVALID = 0x00, + CBIOS_OVL_KEY_TYPE_ALPHA = 0x01, + CBIOS_OVL_KEY_TYPE_COLOR = 0x02, + CBIOS_OVL_KEY_TYPE_CHROME = 0x03, +}CBIOS_OVL_KEY_TYPE; + +typedef struct _CBIOS_OVL_KEY_INFO +{ + /* + * CBIOS_OVL_KEY_TYPE + */ + CBIOS_U32 Type; + CBIOS_U32 Index; + + union + { + CBIOS_U8 AlphaKey; + CBIOS_U32 ColorKey; + struct + { + CBIOS_U32 LowColor; + CBIOS_U32 UpColor; + }ChromeKey; + }; +}CBIOS_OVL_KEY_INFO, *PCBIOS_OVL_KEY_INFO; + +typedef struct _CBIOS_PLANE_PARA +{ + CBIOS_U32 PlaneIndex; + CBIOS_STREAM_TP StreamType; + PCBIOS_OVERLAY_INFO pOverlayInfo; + PCBIOS_STREAM_PARA pInputStream; + PCBIOS_OVL_KEY_INFO pOVLKeyInfo; + CBIOS_FLIP_MODE FlipMode; +}CBIOS_PLANE_PARA, *PCBIOS_PLANE_PARA; + +typedef struct _CBIOS_UPDATE_FRAME_PARA +{ + CBIOS_U32 Size; + CBIOS_U32 IGAIndex; + PCBIOS_PLANE_PARA pPlanePara[CBIOS_MAX_PLANE_CNT]; + CBIOS_TRIG_MODE TrigMode; +}CBIOS_UPDATE_FRAME_PARA, *PCBIOS_UPDATE_FRAME_PARA; + +typedef struct _CBIOS_GET_DISP_RESOURCE +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_OUT CBIOS_U32 CrtcNum; + CBIOS_OUT CBIOS_U32 PlaneNum[CBIOS_IGACOUNTS]; +}CBIOS_GET_DISP_RESOURCE, *PCBIOS_GET_DISP_RESOURCE; + + +typedef struct _CBIOS_DISPLAY_CAPS +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_OUT CBIOS_U32 SuppCrtcUpScale; + CBIOS_OUT CBIOS_U32 SuppCrtcDownScale; + CBIOS_OUT CBIOS_U32* pUpScalePlaneMask; + CBIOS_OUT CBIOS_U32* pDownScalePlaneMask; +}CBIOS_DISPLAY_CAPS, *PCBIOS_DISPLAY_CAPS; + +typedef struct _CBIOS_GET_DISP_ADDR +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 IGAIndex; + CBIOS_IN CBIOS_STREAM_TP StreamType; + CBIOS_OUT CBIOS_U64 DispAddr; +}CBIOS_GET_DISP_ADDR, *PCBIOS_GET_DISP_ADDR; + +typedef struct _CBIOS_CHECK_SURFACE_ON_DISP +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 IGAIndex; + CBIOS_IN CBIOS_BOOL bChkAfterEnable; + CBIOS_IN CBIOS_STREAM_TP StreamType; + CBIOS_IN PCBIOS_SURFACE_ATTRIB pSurfaceAttr; + CBIOS_IN PCBIOS_WINDOW_PARA pSrcWindow; + CBIOS_OUT CBIOS_BOOL bOnDisplay; +}CBIOS_CHECK_SURFACE_ON_DISP, *PCBIOS_CHECK_SURFACE_ON_DISP; + +typedef struct _CBios_Setting_Downscaler_Params +{ + CBIOS_U32 Size; + CBIOS_U32 DownscalerDestinationBase; + CBIOS_U32 SourceModeXResolution; + CBIOS_U32 SourceModeYResolution; + CBIOS_U32 DownscalerDestinationPitch; + CBIOS_BOOL bDisableDownscaler; +}CBiosSettingDownscalerParams,*PCBiosSettingDownscalerParams; + +typedef enum _CBIOS_WB_MODE +{ + CBIOS_WB_P2P = 0x00, + CBIOS_WB_P2I = 0x01, + CBIOS_WB_I2P = 0x02, + CBIOS_WB_I2I = 0x03, +}CBIOS_WB_MODE; + +typedef struct _CBIOS_WB_PARA +{ + CBIOS_IN CBIOS_U8 IGAIndex; + CBIOS_IN CBIOS_U64 DstBaseAddr; + CBIOS_IN CBIOS_U32 SrcSize; // X | (Y << 16) + CBIOS_IN CBIOS_U32 SrcFmt; + CBIOS_IN CBIOS_U32 CscOutFmt; + + struct + { + CBIOS_IN CBIOS_U32 DstSize; + CBIOS_IN CBIOS_U8 Mode; //CBIOS_WB_MODE + + struct + { + //when mode is CBIOS_WB_P2P, bDoubleBuffer should be set + CBIOS_IN CBIOS_U8 bDoubleBuffer:1; + CBIOS_IN CBIOS_U8 Reserved :7; + }; + }DSCL; + + struct + { + CBIOS_IN CBIOS_U8 bByPass :1; + CBIOS_IN CBIOS_U8 bEnable :1; + CBIOS_OUT CBIOS_U8 bNotSupport :1; + CBIOS_IN CBIOS_U8 bUpdateImme :1; + CBIOS_IN CBIOS_U8 Reserved :4; + }; + union + { + CBIOS_IN CBIOS_U8 Flags; + struct + { + CBIOS_IN CBIOS_U8 bEnableOP :1; + CBIOS_IN CBIOS_U8 bSetAddrOP :1; + CBIOS_IN CBIOS_U8 bSetModeOP :1; + CBIOS_IN CBIOS_U8 Reserved1 :5; + }; + }; +}CBIOS_WB_PARA, *PCBIOS_WB_PARA; + +typedef enum _CBIOS_CURSOR_SIZE_TYPE +{ + CBIOS_CURSOR_SIZE_64x64 = 0x00, + CBIOS_CURSOR_SIZE_64x128 = 0x01, + CBIOS_CURSOR_SIZE_128x64 = 0x02, + CBIOS_CURSOR_SIZE_128x128 = 0x03, + CBIOS_CURSOR_SIZE_INVALID = 0xFF, +}CBIOS_CURSOR_SIZE_TYPE; + +// cursor parameters +typedef enum _CBIOS_CURSOR_TYPE +{ + CBIOS_MONO_CURSOR = 0x00, + CBIOS_COLOR_CURSOR, + CBIOS_PREMULT_CURSOR, + CBIOS_COVERAGE_CURSOR, +}CBIOS_CURSOR_TYPE; + +typedef struct _CBIOS_CURSOR_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 IGAIndex; + + struct + { + CBIOS_IN CBIOS_S32 PositionX; + CBIOS_IN CBIOS_S32 PositionY; + CBIOS_IN CBIOS_CURSOR_SIZE_TYPE CursorSize; + }Position; + + struct + { + CBIOS_IN CBIOS_CURSOR_TYPE Type; + CBIOS_IN CBIOS_U32 CurAddr; + struct + { + CBIOS_IN CBIOS_U32 BackGround; + CBIOS_IN CBIOS_U32 ForeGround; + }Color; + }CursorAttrib; + + union + { + CBIOS_IN CBIOS_U8 Flags; + struct + { + CBIOS_IN CBIOS_U8 bDisable :1; + CBIOS_IN CBIOS_U8 bhMirror :1; + CBIOS_IN CBIOS_U8 bvMirror :1; + CBIOS_IN CBIOS_U8 Reserved :5; + }; + }; +}CBIOS_CURSOR_PARA, *PCBIOS_CURSOR_PARA; + +typedef struct _CBIOS_VERSION +{ + CBIOS_U16 MajorVersionNumber; /* Big structure refine if change. */ + CBIOS_U16 ChipID; /* For which chip. 0 means general version for all chip. */ + CBIOS_U16 ChipRevID; /* For which revision chip. 0 means no revision need to differ */ + CBIOS_U16 BranchDriverNumber; /* Branch code number, 0 means trunk code. */ + CBIOS_U16 MediumVersionNumber; /* Little improvement, Add new feature */ + CBIOS_U16 MinorVersionNumber; /* Minor fix improvement, mainly focus on bug fix. */ +}CBIOS_VERSION,*PCBIOS_VERSION; + +typedef struct _CBREGISTER +{ + CBIOS_UCHAR type; + CBIOS_UCHAR mask; + CBIOS_UCHAR index; + CBIOS_UCHAR value; +} CBREGISTER, *PCBREGISTER; + +typedef enum _CBIOS_REGISTER_BLOCK_TYPE +{ + CBIOS_REGISTER_MMIO = 0, + CBIOS_REGISTER_PMU, + CBIOS_REGISTER_GPIO, + CBIOS_REGISTER_PMC +}CBIOS_REGISTER_BLOCK_TYPE; + +typedef struct _CBIOS_REGISTER32 +{ + CBIOS_REGISTER_BLOCK_TYPE type; + CBIOS_U32 mask; + CBIOS_U32 index; + CBIOS_U32 value; +} CBIOS_REGISTER32, *PCBIOS_REGISTER32; + +typedef struct _CBREGISTER_IDX +{ + CBIOS_U16 type_index; + CBIOS_UCHAR mask; +} CBREGISTER_IDX, *PCBREGISTER_IDX; + +typedef struct _CBIOS_CALLBACK_FUNCTIONS +{ + CBIOS_U32 Size; + CBIOS_VOID* pFnDbgPrint; + CBIOS_VOID* pFnDelayMicroSeconds; + CBIOS_VOID* pFnReadUchar; + CBIOS_VOID* pFnReadUshort; + CBIOS_VOID* pFnReadUlong; + CBIOS_VOID* pFnWriteUchar; + CBIOS_VOID* pFnWriteUshort; + CBIOS_VOID* pFnWriteUlong; + CBIOS_VOID* pFnQuerySystemTime; + CBIOS_VOID* pFnAllocateNonpagedMemory; + CBIOS_VOID* pFnAllocatePagedMemory; + CBIOS_VOID* pFnFreePool; + CBIOS_VOID* pFnAcquireSpinLock; + CBIOS_VOID* pFnReleaseSpinLock; + CBIOS_VOID* pFnAcquireMutex; + CBIOS_VOID* pFnReleaseMutex; + CBIOS_VOID* pFnReadPortUchar; + CBIOS_VOID* pFnWritePortUchar; + CBIOS_VOID* pFnGetRegistryParameters; + CBIOS_VOID* pFnSetRegistryParameters; + CBIOS_VOID* pFnStrcmp; + CBIOS_VOID* pFnStrcpy; + CBIOS_VOID* pFnStrncmp; + CBIOS_VOID* pFnMemset; + CBIOS_VOID* pFnMemcpy; + CBIOS_VOID* pFnMemcmp; + CBIOS_VOID* pFnDodiv; + CBIOS_VOID* pFnVsprintf; + CBIOS_VOID* pFnWriteRegisterU32; + CBIOS_VOID* pFnReadRegisterU32; + CBIOS_VOID* pFnDbgPrintToFile; + CBIOS_VOID* pFnVsnprintf; + //gpio + CBIOS_VOID* pFnGpioGetValue; + CBIOS_VOID* pFnGpioSetValue; + CBIOS_VOID* pFnGpioRequest; + CBIOS_VOID* pFnGpioFree; + CBIOS_VOID* pFnGpioDirectionInput; + CBIOS_VOID* pFnGpioDirectionOutput; + CBIOS_VOID* pFnGetPlatformConfigU32; + //regulator + CBIOS_VOID* pFnRegulatorGet; + CBIOS_VOID* pFnRegulatorEnable; + CBIOS_VOID* pFnRegulatorDisable; + CBIOS_VOID* pFnRegulatorIsEnabled; + CBIOS_VOID* pFnRegulatorGetVoltage; + CBIOS_VOID* pFnRegulatorSetVoltage; + CBIOS_VOID* pFnRegulatorPut; +}CBIOS_CALLBACK_FUNCTIONS, *PCBIOS_CALLBACK_FUNCTIONS; + +typedef struct _CBios_IGA_Mode_Params +{ + CBIOS_U32 Size; + CBIOS_U32 DeviceId; + CBIOS_U32 IGAIndex; + CBiosSourceModeParams SourcModeParams; + CBiosDestModeParams DestModeParams; + CBiosScalerSizeParams ScalerSizeParams; + CBIOS_U32 BitPerComponent; +}CBiosIGAModeParams,*PCBiosIGAModeParams; + +typedef struct _CBIOS_VCP_DATA_ADDR_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 VCPBaseAddr; +}CBIOS_VCP_DATA_ADDR_PARA, *PCBIOS_VCP_DATA_ADDR_PARA; + +typedef struct _CBIOS_CHIP_ID +{ + CBIOS_U32 Size; + CBIOS_U32 GenericChipID; + CBIOS_U32 ChipID; +}CBIOS_CHIP_ID,*PCBIOS_CHIP_ID; + +typedef struct _CBIOS_PARAM_SET_EDID{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DeviceId; /* Device Bitfiled */ + CBIOS_IN PCBIOS_UCHAR EdidBuffer; /* When ==NULL, CBIOS will unlock the EDID and + Driver must do device detect to get the real EDID + */ + CBIOS_IN CBIOS_U32 EdidBufferLen; /* Edid buffer size */ +} CBIOS_PARAM_SET_EDID, *PCBIOS_PARAM_SET_EDID; + +typedef enum _CBIOS_TIMING_TYPE{ //can extend to support 14 different types + CBIOS_NONEDID_TIMING = 0x0000, //The mode is not from EDID + CBIOS_EST_TIMING = 0x0001, + CBIOS_STD_TIMING = 0x0002, + CBIOS_DTL_TIMING = 0x0004, + CBIOS_DTD_TIMING = 0x0008, //Detailed timing descriptor + CBIOS_SVD_TIMING = 0x0010 //CBIOS_S16 video descriptor +}CBIOS_TIMING_TYPE, *PCBIOS_TIMING_TYPE; + + +typedef struct _CBIOS_GET_MODE_TIMING_PARAM +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DeviceId; + CBIOS_IN PCBiosModeInfoExt pMode; + CBIOS_IN CBIOS_OUT PCBIOS_TIMING_ATTRIB pTiming; +}CBIOS_GET_MODE_TIMING_PARAM, *PCBIOS_GET_MODE_TIMING_PARAM; + +#pragma pack (1) + +/* + * The ELD Memory Structure + * + * Header Block of ELD Memory Structure + * --------------------------------------------------------------- + * Byte offset | bit | + * -------------------------------------------------------------- + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * -------------------------------------------------------------- + * 0 | ELD_Ver | Reserved | + * -------------------------------------------------------------- + * 1 | Reserved | + * -------------------------------------------------------------- + * 2 | BaseLine_ELD_Len | + * -------------------------------------------------------------- + * 3 | Reserved | + * -------------------------------------------------------------- + * + * + * Baseline block ELD Memory Structure fo ELD_Ver = 00010b + * -------------------------------------------------------------- + * Byte offset | bit | + * -------------------------------------------------------------- + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * -------------------------------------------------------------- + * 4 | CEA_EDI_Ver | MNL | + * -------------------------------------------------------------- + * 5 | SAD_Count | Conn_Type | S_AI |HDCP| + * -------------------------------------------------------------- + * 6 | Aud_Synch_Delay | + * -------------------------------------------------------------- + * 7 | Rsvd| RLRC| FLRC| RC | RLR | FC | LFE | FLR | + * -------------------------------------------------------------- + * 8-15 | Port_ID | + * -------------------------------------------------------------- + * 16-17 | Maufacturer Name | + * -------------------------------------------------------------- + * 18-19 | Product Code | + * -------------------------------------------------------------- + * 20 | | + * 20 + MNL - 1 | Monitor_Name_String | + * -------------------------------------------------------------- + * 20 + MNL | | + * len1 | CEA_SADs | + * -------------------------------------------------------------- + * len1 + 1 | | + * len2 | Reserved | + * -------------------------------------------------------------- + * + * + * notes: + * Len1 = 20+MNL+ (3*SAD_Count)-1; + * len2 = 4 + BaseLine_ELD_Len *4 -1; + * + * */ + +enum eld_versions { + ELD_VER_CEA_861D = 2, + ELD_VER_PARTIAL = 31, +}; + +#define ELD_MAX_SIZE 256 + +typedef struct _CBIOS_ELD_MEM_STRUCT +{ + CBIOS_U32 Size; /* Header size 4 btyes + (Baseline_ELD_Len * 4bytes) */ + + union + { + struct + { + /* Header block */ + CBIOS_U8 Reserved0 : 3; /* reserved bit set to zero. */ + CBIOS_U8 ELD_Ver : 5; + CBIOS_U8 Reserved1; + CBIOS_U8 BaseLine_Eld_len; /* Baseline block size */ + CBIOS_U8 Reserved2; + + /* BaseLineBlock */ + CBIOS_U8 MNL :5; /* Monitor_Name_String Length, Max 16 bytes, */ + CBIOS_U8 CEA_EDID_Ver :3; /* Version number of the HDMI sink Device supports. */ + + CBIOS_U8 HDCP :1; /* value 1 means the receiver supports HDCP over the digital display sink */ + CBIOS_U8 S_AI :1; /* Supports_AI capability in the HDMI */ + CBIOS_U8 Conn_Type :2; /* 00b: HDMI, 01b: Display Port */ + CBIOS_U8 SAD_Count :4; /* CEA SAD number following the Monitor_Name_String, Max 15 SADs */ + + CBIOS_U8 Aud_Synch_Delay; + + /* speaker allocation */ + CBIOS_U8 FLR :1; /* value 1: means the presence of front left and right transmission channels */ + CBIOS_U8 LFE :1; /* a Low Frequency Effect transmission channel */ + CBIOS_U8 FC :1; /* a Center Front transmission channel */ + CBIOS_U8 RLR :1; /* Rear left and right transmission channels */ + CBIOS_U8 RC :1; /* a Center Rear transmission channel */ + CBIOS_U8 FLRC :1; /* Front Left and Right of center transmission channels */ + CBIOS_U8 RLRC :1; /* Rear Left and Right of center transmission channels */ + CBIOS_U8 Rsvd :1; + + /* 8 bytes port identification value, for compatible for win7 */ + struct { + CBIOS_U32 LowPart; + CBIOS_U32 HighPart; + }Port_ID; + + CBIOS_U8 ManufactureName[2]; /* 2 byte Maufacturer Name ID from the sink device Base EDID */ + CBIOS_U8 ProductCode[2]; /* 2 byte Product Code ID from the sink device Base EDID */ + + /* + * @private_data: There are two remaining members of the _CBIOS_ELD_MEM_STRUCT: + * @ Monitor_Name_String: + * variable size, Max 16 bytes + * @ CEA_SADs: + * indicates up to 15 entries of 3-byte CEA-861 Short Audio Descriptor reported by the sink device + * + * As the Monitor_Name_String and CEA_SADs are all variable size. + * So we use a pointer to point the first byte of the two members. + * + */ + CBIOS_U8 private_data[1]; + + }ELD_Data; + + CBIOS_U8 Data[ELD_MAX_SIZE]; /* Max Length is 256 byte */ + }; + +}CBIOS_ELD_MEM_STRUCT,*PCBIOS_ELD_MEM_STRUCT; + +#pragma pack () + +typedef struct _CBIOS_GET_ELD_PARAM +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DeviceId; + CBIOS_IN CBIOS_OUT PCBIOS_ELD_MEM_STRUCT pELDMemData; +}CBIOS_GET_ELD_PARAM, *PCBIOS_GET_ELD_PARAM; + +typedef struct _PCBIOS_VBINFO_PARAM +{ + CBIOS_U32 Size; + CBIOS_U32 BiosVersion; //Vbios version + struct + { + CBIOS_U32 MCKTuneMethod :1; //Mclk tune method, 0:software, 1:hardware + CBIOS_U32 ECKTuneMethod :1; //Eclk tune method, 0:software, 1:hardware + CBIOS_U32 ICKTuneMethod :1; //Iclk tune method, 0:software, 1:hardware + CBIOS_U32 bNoHDCPSupport :1; //strapping CR56[2] + CBIOS_U32 Reserved :28; + }; + CBIOS_U32 DeviceID; //Chip Device ID + CBIOS_U32 RevisionID; //Chip revision ID + CBIOS_U32 SupportDev; //VBIOS supported devices + CBIOS_U32 PortSplitSupport; //bit definition is the same as CBIOS_ACTIVE_TYPE, + //1:corresponding device port can be split + //0: corresponding device port can not be split + CBIOS_U32 HPDBitMask; + CBIOS_U32 HPDDevicesMask; + CBIOS_U32 BootDevInCMOS; //for GOP + CBIOS_U32 PollingDevMask; + CBIOS_U32 LowTopAddress; + CBIOS_U32 FBSize; + + struct + { + CBIOS_U32 SnoopOnly :1; + CBIOS_U32 HdaudioToLocal :1; + CBIOS_U32 NonSimulChip :1; + CBIOS_U32 Reserved1 :29; + }; + + CBIOS_U32 MemChNum; // Miu channel number + CBIOS_U32 AvalMemSize; // available memory size, unit MB + CBIOS_U32 TotalMemSize; // total memory size, unit MB + CBIOS_UCHAR PMPVer[64]; // PMP info,include version and build time + CBIOS_U32 FwVersion; // Firmware version + CBIOS_UCHAR FwName[10]; // Firmware name + +}CBIOS_VBINFO_PARAM, *PCBIOS_VBINFO_PARAM; + +typedef struct _CBIOS_PERIPHERAL_TYPE +{ + CBIOS_U32 GPUFan :1; + CBIOS_U32 ExtPower :1; + CBIOS_U32 Reserved :30; //Reserved for new peripherals +}CBIOS_PERIPHERAL_TYPE, *PCBIOS_PERIPHERAL_TYPE; + +typedef struct _CBIOS_PERIPHERAL_STATUS_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_PERIPHERAL_TYPE Peripherals; //the peripherals that driver wants to query + CBIOS_IN CBIOS_BOOL bQuerySupportCaps; //= true: query whether the given peripherals state can be checked. + //= false: check the given peripherals' state. + //Driver should check whether a peripheral's status can be checked first. + CBIOS_OUT CBIOS_PERIPHERAL_TYPE Result; //same bit definition with Peripherals. + //If bQuerySupportCaps = true: + // = 1: current peripheral's state can be checked + // = 0: current peripheral's state can NOT be checked + //If bQuerySupportCaps = false: + // = 1: current peripheral is working normally + // = 0: current peripheral is in an abnormal state +}CBIOS_PERIPHERAL_STATUS_PARA, *PCBIOS_PERIPHERAL_STATUS_PARA; + +typedef struct _HDMI_3D_STUCTURE_ALL +{ + CBIOS_U16 FramePacking :1; + CBIOS_U16 FieldAlternative :1; + CBIOS_U16 LineAlternative :1; + CBIOS_U16 SideBySideFull :1; + CBIOS_U16 LDepth :1; + CBIOS_U16 LDepthGraphics :1; + CBIOS_U16 TopAndBottom :1; + CBIOS_U16 RsvdBits0 :1; + CBIOS_U16 SideBySideHalf :1; + CBIOS_U16 RsvdBits1 :6; + CBIOS_U16 NotInUse :1; +}HDMI_3D_STUCTURE_ALL, *PHDMI_3D_STUCTURE_ALL; + +typedef struct _CBIOS_3D_VIDEO_MODE_LIST +{ + CBIOS_U32 Size; + CBIOS_U32 XRes; + CBIOS_U32 YRes; + CBIOS_U32 RefreshRate; //refresh rate * 100 + CBIOS_BOOL bIsInterlace; + union + { + HDMI_3D_STUCTURE_ALL SupportStructures; + CBIOS_U16 SupportCaps; + }; + + struct + { + CBIOS_U16 IsSupport3DOSDDisparity :1; + CBIOS_U16 IsSupport3DDualView :1; + CBIOS_U16 IsSupport3DIndependentView :1; + CBIOS_U16 Reserved :13; + }; +}CBIOS_3D_VIDEO_MODE_LIST, *PCBIOS_3D_VIDEO_MODE_LIST; + +typedef enum _CBIOS_STEREO_VIEW +{ + FIELD_SEQ_RIGHT = 0x1, // Field sequential stereo, right image when stereo sync signal = 1 + FIELD_SEQ_LEFT, // Field sequential stereo, left image when stereo sync signal = 1 + TWO_WAY_RIGHT, // 2-way interleaved stereo, right image on even lines + TWO_WAY_LEFT, // 2-way interleaved stereo, left image on even lines + FOUR_WAY, // 4-way interleaved stereo + SIDE_BY_SIDE_INTERLEAVE // Side-by-Side interleaved stereo +}CBIOS_STEREO_VIEW; + +typedef struct _CBIOS_MONITOR_3D_CAPABILITY_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DeviceId; + CBIOS_OUT CBIOS_BOOL bIsSupport3DVideo; // for both HDMI 1.4 3D and row-interlace 3D monitor + CBIOS_OUT CBIOS_U32 Monitor3DModeNum; // HDMI 1.4 3D + CBIOS_OUT PCBIOS_3D_VIDEO_MODE_LIST pMonitor3DModeList; //If pMonitor3DModeList = NULL, means query monitor capability and buffer size + //If pMonitor3DModeList != NULL, cbios will copy mode list to this buffer + CBIOS_OUT CBIOS_BOOL bStereoViewSupport; // stereo Viewing Support for row-interlace + CBIOS_OUT CBIOS_STEREO_VIEW StereoViewType; // stereo view type +}CBIOS_MONITOR_3D_CAPABILITY_PARA, *PCBIOS_MONITOR_3D_CAPABILITY_PARA; + +typedef struct _CBIOS_HDAC_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DeviceId; + CBIOS_IN CBIOS_BOOL bPresent; + CBIOS_IN CBIOS_BOOL bEldValid; + CBIOS_IN CBIOS_U64 PortId; + CBIOS_IN CBIOS_U16 ManufacturerName; + CBIOS_IN CBIOS_U16 ProductCode; +}CBIOS_HDAC_PARA, *PCBIOS_HDAC_PARA; + +//for CEC +typedef enum _CBIOS_CEC_INDEX +{ + CBIOS_CEC_INDEX1 = 0, + CBIOS_CEC_INDEX2, + CBIOS_CEC_INDEX3, + CBIOS_CEC_INDEX4, + CBIOS_CEC_INDEX_COUNT +}CBIOS_CEC_INDEX; +typedef struct _CBIOS_CEC_ENABLE_DISABLE_PARA +{ + CBIOS_IN CBIOS_U32 Size; // Size of CBIOS_CEC_ENABLE_DISABLE_PARA + CBIOS_IN CBIOS_BOOL bEnableCEC; // = CBIOS_TRUE: enable CEC; = CBIOS_FALSE: Disable CEC + CBIOS_IN CBIOS_CEC_INDEX CECIndex; // = 0: CEC1; = 1: CEC2; Other values are reserved +}CBIOS_CEC_ENABLE_DISABLE_PARA, *PCBIOS_CEC_ENABLE_DISABLE_PARA; + +typedef struct _CBIOS_CEC_TRANSIMIT_MESSAGE_PARA +{ + CBIOS_IN CBIOS_U32 Size; // Size of CBIOS_CEC_TRANSIMIT_MESSAGE_PARA + CBIOS_IN CBIOS_CEC_INDEX CECIndex; // CEC index + CBIOS_IN CBIOS_U8 DestAddr; // CEC Initiator command destination address + CBIOS_IN CBIOS_U32 CmdLen; // CEC Initiator command length. The valid value is [0:16] + CBIOS_IN CBIOS_U8 Command[16]; // Initiator Command sent by CEC + CBIOS_IN CBIOS_BOOL bBroadcast; // = TRUE: broadcast; = FALSE: direct access + CBIOS_IN CBIOS_U8 RetryCnt; // CEC Initiator Retry times. Valid values must be 1 to 5. +}CBIOS_CEC_TRANSIMIT_MESSAGE_PARA, *PCBIOS_CEC_TRANSIMIT_MESSAGE_PARA; + +typedef struct _CBIOS_CEC_RECEIVE_MESSAGE_PARA +{ + CBIOS_IN CBIOS_U32 Size; // Size of CBIOS_CEC_RECEIVE_MESSAGE_PARA + CBIOS_IN CBIOS_CEC_INDEX CECIndex; // CEC index + CBIOS_OUT CBIOS_U8 SourceAddr; // CEC Follower received source address + CBIOS_OUT CBIOS_U32 CmdLen; // CEC Follower command length. The valid value is [0:16] + CBIOS_OUT CBIOS_U8 Command[16]; // Follower received command + CBIOS_OUT CBIOS_BOOL bBroadcast; // = TRUE: broadcast; = FALSE: direct access +}CBIOS_CEC_RECEIVE_MESSAGE_PARA, *PCBIOS_CEC_RECEIVE_MESSAGE_PARA; + +typedef struct _CBIOS_CEC_INFO +{ + CBIOS_IN CBIOS_U32 Size; // Size of CBIOS_CEC_INFO + CBIOS_IN CBIOS_CEC_INDEX CECIndex; // CEC index + CBIOS_OUT CBIOS_U16 PhysicalAddr; // CEC physical address + CBIOS_OUT CBIOS_U8 LogicalAddr; // logical address of our board +}CBIOS_CEC_INFO, *PCBIOS_CEC_INFO; + +typedef enum _CBIOS_CEC_INTERRUPT_TYPE +{ + INVALID_CEC_INTERRUPT = 0, + NORMAL_CEC_INTERRUPT +}CBIOS_CEC_INTERRUPT_TYPE; + +typedef struct _CBIOS_CEC_INTERRUPT_INFO +{ + CBIOS_IN CBIOS_U32 Size; // Size of CBIOS_CEC_INTERRUPT_INFO + CBIOS_IN CBIOS_U32 InterruptBitMask; // Value of mm8504 + CBIOS_OUT CBIOS_CEC_INTERRUPT_TYPE InterruptType; // Interrupt type + CBIOS_OUT CBIOS_U32 CEC1MsgReceived :1; // = TRUE: CEC1 module received a message + CBIOS_OUT CBIOS_U32 CEC2MsgReceived :1; // = TRUE: CEC2 module received a message + CBIOS_OUT CBIOS_U32 CEC3MsgReceived :1; // = TRUE: CEC3 module received a message + CBIOS_OUT CBIOS_U32 CEC4MsgReceived :1; // = TRUE: CEC4 module received a message + CBIOS_OUT CBIOS_U32 RsvdBits :28; +}CBIOS_CEC_INTERRUPT_INFO, *PCBIOS_CEC_INTERRUPT_INFO; + +typedef struct _CBIOS_INIT_CHIP_PARA +{ + CBIOS_IN CBIOS_U32 Size; +}CBIOS_INIT_CHIP_PARA, *PCBIOS_INIT_CHIP_PARA; + +typedef struct _CBIOS_QUERY_MONITOR_TYPE_PER_PORT +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 ActiveDevId; + CBIOS_IN CBIOS_BOOL bConnected; + CBIOS_OUT CBIOS_MONITOR_TYPE MonitorType; +}CBIOS_QUERY_MONITOR_TYPE_PER_PORT, *PCBIOS_QUERY_MONITOR_TYPE_PER_PORT; + +typedef struct _CBIOS_DEVICE_COMB +{ + CBIOS_IN CBIOS_U32 Devices; + CBIOS_OUT CBIOS_U32 Iga1Dev; + CBIOS_OUT CBIOS_U32 Iga2Dev; + CBIOS_OUT CBIOS_U32 Iga3Dev; + CBIOS_OUT CBIOS_U32 Iga4Dev; +}CBIOS_DEVICE_COMB, *PCBIOS_DEVICE_COMB; + +typedef struct _CBIOS_GET_DEV_COMB +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_OUT PCBIOS_DEVICE_COMB pDeviceComb; + CBIOS_OUT CBIOS_U32 bSupported; +}CBIOS_GET_DEV_COMB, *PCBIOS_GET_DEV_COMB; + +typedef struct _CBIOS_GET_IGA_MASK +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DeviceId; + CBIOS_OUT CBIOS_U32 IgaMask; +}CBIOS_GET_IGA_MASK, *PCBIOS_GET_IGA_MASK; + +typedef struct _CBIOS_GET_DEVICE_NAME +{ + CBIOS_U32 Size; + CBIOS_U32 DeviceId; + PCBIOS_CHAR pDeviceName; +}CBIOS_GET_DEVICE_NAME, *PCBIOS_GET_DEVICE_NAME; + +typedef enum +{ + CBIOS_HDCP_AUTH_DISABLE = 0, // HDCP disabled + CBIOS_HDCP_AUTH_ENABLE = 1, // HDCP enabled to do authentication + CBIOS_HDCP_AUTH_BKSV = 2, // BKSV of receiver/repeater is in FIFO + CBIOS_HDCP_AUTH_BKSV_VERIF_DONE = 3, + CBIOS_HDCP_AUTH_BKSV_LIST = 4, // BKSV list of repeater is in FIFO + CBIOS_HDCP_AUTH_BKSV_LIST_VERIF_DONE = 5, + CBIOS_HDCP_AUTH_PASS = 6, // authentication pass + CBIOS_HDCP_AUTH_FAIL = 7, // authentication fail + CBIOS_HDCP_AUTH_REAUTH_REQ = 8, // sink request to do re-authentication + CBIOS_HDCP_AUTH_HW_REAUTH = 9, + CBIOS_HDCP_AUTH_TIMEOUT = 10, // authentication timeout without corresponding interrupt +}CBIOS_HDCP_AUTHENTICATION_STATUS; + +typedef struct _CBIOS_HDCP_WORK_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DevicesId; +}CBIOS_HDCP_WORK_PARA, *PCBIOS_HDCP_WORK_PARA; + +typedef struct _CBIOS_HDCP_STATUS_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DevicesId; + CBIOS_OUT CBIOS_HDCP_AUTHENTICATION_STATUS HdcpStatus; + CBIOS_OUT CBIOS_U8 BKsv[5]; + CBIOS_OUT CBIOS_BOOL bRepeater; +}CBIOS_HDCP_STATUS_PARA, *PCBIOS_HDCP_STATUS_PARA; + +typedef struct _CBIOS_HDCP_ISR_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DevicesId; + CBIOS_IN CBIOS_U32 InterruptType; +}CBIOS_HDCP_ISR_PARA, *PCBIOS_HDCP_ISR_PARA; + +typedef struct _CBIOS_HDCP_INFO_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 IntDevicesId; + CBIOS_IN CBIOS_U32 InterruptType; +}CBIOS_HDCP_INFO_PARA, *PCBIOS_HDCP_INFO_PARA; + +typedef struct _CBIOS_HDAC_INFO_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 IntDevicesId; + CBIOS_IN CBIOS_U32 InterruptType; +}CBIOS_HDAC_INFO_PARA, *PCBIOS_HDAC_INFO_PARA; + +typedef enum _CBIOS_DSI_PACKET_TYPE +{ + CBIOS_DSI_SHORT_PACKET = 0x00, + CBIOS_DSI_LONG_PACKET, +}CBIOS_DSI_PACKET_TYPE; + +typedef enum _CBIOS_DSI_CONTENT_TYPE +{ + CBIOS_DSI_CONTENT_DCS = 0x00, + CBIOS_DSI_CONTENT_GEN, +}CBIOS_DSI_CONTENT_TYPE; + +typedef struct _CBIOS_DSI_WRITE_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DSIIndex; // 0: DSI-1, 1:DSI-2 + CBIOS_IN CBIOS_U8 VirtualCh; // refer MIPI-DSI spec 4.2.3 + CBIOS_IN CBIOS_DSI_PACKET_TYPE PacketType; // 0: short packet, 1: long packet + CBIOS_IN CBIOS_DSI_CONTENT_TYPE ContentType; // 0: DCS write cmd, 1: generic write cmd + CBIOS_IN CBIOS_U16 DataLen; + CBIOS_IN PCBIOS_U8 pDataBuf; + union + { + CBIOS_IN CBIOS_U32 DSIWriteFlags; + struct + { + CBIOS_IN CBIOS_U32 bNeedAck :1; // 1: the cmd need acknowledge, 0: no need + CBIOS_IN CBIOS_U32 bHSModeOnly :1; // 1: the cmd can be transferred in hs mode only, 0: both LP and HS mode + CBIOS_IN CBIOS_U32 Reserved :30; + }; + }; +}CBIOS_DSI_WRITE_PARA, *PCBIOS_DSI_WRITE_PARA; + +typedef struct _CBIOS_DSI_READ_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DSIIndex; // 0: DSI-1, 1:DSI-2 + CBIOS_IN CBIOS_U8 VirtualCh; // refer MIPI-DSI spec 4.2.3 + CBIOS_IN CBIOS_DSI_CONTENT_TYPE ContentType; // 0: DCS read cmd, 1: generic read cmd + CBIOS_IN CBIOS_U8 DataLen; + CBIOS_IN PCBIOS_U8 pDataBuf; + CBIOS_OUT CBIOS_U8 ReceivedPayloadBuf[16]; // The buffer to store the receive payload + CBIOS_OUT CBIOS_U16 ReceivedPayloadLen; // The length of response payload after the DCS read cmd + union + { + CBIOS_IN CBIOS_U32 DSIReadFlags; + struct + { + CBIOS_IN CBIOS_U32 bHSModeOnly :1; // 1: the cmd can be transferred in hs mode only, 0: both LP and HS mode + CBIOS_IN CBIOS_U32 Reserved :30; + }; + }; +}CBIOS_DSI_READ_PARA, *PCBIOS_DSI_READ_PARA; + +typedef struct _CBIOS_DSI_PANELUPDATE_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 PanelClumnAlign; + CBIOS_IN CBIOS_U32 PanelRowAlign; + CBIOS_IN CBIOS_U32 PanelWidthAlign; + CBIOS_IN CBIOS_U32 PanelHeightAlign; +}CBIOS_DSI_PANELUPDATE_PARA, *PCBIOS_DSI_PANELUPDATE_PARA; + +typedef struct _CBIOS_DSI_WINDOW +{ + CBIOS_U16 XStart; /* window horizontal start position */ + CBIOS_U16 YStart; /* window vertical start position */ + CBIOS_U16 WinWidth; /* window width*/ + CBIOS_U16 WinHeight; /* window height */ +}CBIOS_DSI_WINDOW, *PCBIOS_DSI_WINDOW; + +typedef struct _CBIOS_DSI_HOSTUPDATE_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_DSI_WINDOW HostUpdateWindow[CBIOS_DSI_INDEX_NUM]; + CBIOS_IN CBIOS_DSI_PANELUPDATE_PARA PanelUpdatePara; + CBIOS_IN CBIOS_BOOL isEnablePartialUpdate; + CBIOS_IN CBIOS_BOOL isEnterHS; /* 0: Enter LP mode between lines; 1: HS mode between lines by using null packet */ +}CBIOS_DSI_HOSTUPDATE_PARA, *PCBIOS_DSI_HOSTUPDATE_PARA; + +typedef struct _CBIOS_DSI_DMAUPDATE_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_DSI_WINDOW DMAUpdateWindow; + CBIOS_IN CBIOS_U32 DMABaseAddr; + CBIOS_IN CBIOS_U32 DMAStride; + CBIOS_IN CBIOS_BOOL isDMAAligned; +}CBIOS_DSI_DMAUPDATE_PARA, *PCBIOS_DSI_DMAUPDATE_PARA; + +typedef struct _CBIOS_DSI_UPDATE_CONFIG +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DMABaseAddr; + CBIOS_IN CBIOS_U32 DMAStride; + CBIOS_IN CBIOS_BOOL bDMAUpdate; + CBIOS_IN CBIOS_BOOL bDMAAligned; + CBIOS_IN CBIOS_BOOL bEnablePartialUpdate; + CBIOS_IN CBIOS_BOOL bEnterHS; /* 0: Enter LP mode between lines; 1: HS mode between lines by using null packet */ +}CBIOS_DSI_UPDATE_CONFIG, *PCBIOS_DSI_UPDATE_CONFIG; + +typedef struct _CBIOS_DSI_UPDATE_PARA +{ + CBIOS_IN CBIOS_U32 Size; // Size of CBIOS_DSI_UPDATE_PARA + CBIOS_IN CBIOS_DSI_WINDOW UpdateWindow; + CBIOS_IN CBIOS_DSI_UPDATE_CONFIG DSIUpdateConfig; +}CBIOS_DSI_UPDATE_PARA, *PCBIOS_DSI_UPDATE_PARA; + +typedef struct _CBIOS_DSI_BACKLIGHT_PARA +{ + CBIOS_IN CBIOS_U32 Size; // Size of CBIOS_DSI_BACKLIGHT_PARA + CBIOS_IN CBIOS_U32 BacklightValue; +}CBIOS_DSI_BACKLIGHT_PARA, *PCBIOS_DSI_BACKLIGHT_PARA; + +typedef struct _CBIOS_DSI_CABC_PARA +{ + CBIOS_IN CBIOS_U32 Size; // Size of CBIOS_DSI_CABC_PARA + CBIOS_IN CBIOS_U32 CabcValue; +}CBIOS_DSI_CABC_PARA, *PCBIOS_DSI_CABC_PARA; + +typedef struct _CBIOS_DBG_LEVEL_CTRL +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_BOOL bGetValue; + CBIOS_IN CBIOS_OUT CBIOS_U32 DbgLevel; +}CBIOS_DBG_LEVEL_CTRL, *PCBIOS_DBG_LEVEL_CTRL; + +typedef struct _CBIOS_DSI_CONFIG_PARA +{ + CBIOS_IN CBIOS_U32 Size; // Size of CBIOS_DSI_CONFIG_PARA + CBIOS_IN CBIOS_U32 DSIMode; + CBIOS_IN CBIOS_U32 DSIPanelID; +}CBIOS_DSI_CONFIG_PARA, *PCBIOS_DSI_CONFIG_PARA; + +typedef struct _CBIOS_DSI_DATA_ADDR_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 BaseAddr; +}CBIOS_DSI_DATA_ADDR_PARA, *PCBIOS_DSI_DATA_ADDR_PARA; + +// The interrupt definition are in MM8504 +typedef enum _CBIOS_INTERRUPT_TYPE +{ + CBIOS_VSYNC_1_INT = 0x01, + CBIOS_ENGINE_BUSY_INT = 0x02, + CBIOS_VSYNC_2_INT = 0x04, + CBIOS_VSYNC_3_INT = 0x08, + CBIOS_VSYNC_4_INT = 0x010, + CBIOS_ENGINE_IDLE_INT = 0x20, + CBIOS_CEC_INT = 0x40, + CBIOS_DP_1_INT = 0x80, + CBIOS_DP_2_INT = 0x100, + CBIOS_DP_3_INT = 0x10000, + CBIOS_DP_4_INT = 0x20000, + CBIOS_CSP_TIMEOUT_INT = 0x100, + CBIOS_CORRECTABLE_ERR_INT = 0x800, + CBIOS_NON_FATAL_ERR_INT = 0x1000, + CBIOS_FATAL_ERR_INT = 0x2000, + CBIOS_UNSUPPORTED_ERR_INT = 0x4000, + CBIOS_INVALID_CPURW_INT = 0x8000, + CBIOS_VPP_TIMEOUT_INT = 0x10000, + CBIOS_SP_TIMEOUT_INT = 0x20000, + CBIOS_HDCP_INT = 0x400000, + CBIOS_CHIP_IDLE_INT = 0x800000, + CBIOS_PECTL_TIMEOUT_INT = 0x1000000, + CBIOS_HDA_CODEC_INT = 0x4000000, + CBIOS_VCP_TIMEOUT_INT = 0x8000000, + CBIOS_MSVD_TIMEOUT_INT = 0x10000000, + CBIOS_HDA_AUDIO_INT = 0x20000000, +}CBIOS_INTERRUPT_TYPE; + +// The interrupt definition are in MM8548 +typedef enum _CBIOS_ADVANCED_INTERRUPT_TYPE +{ + CBIOS_MSVD_INT = 0x01, + CBIOS_SURFACE_FAULT_INT = 0x02, + CBIOS_PAGE_FAULT_INT = 0x04, + CBIOS_MXU_INVALID_ADDR_FAULT_INT = 0x08, + CBIOS_HANG_INT = 0x10, + CBIOS_FENCE_INT = 0x8000000, + CBIOS_MSVD0_INT = 0x800, + CBIOS_MSVD1_INT = 0x1000, + CBIOS_FLIP_INT = 0x2000, +}CBIOS_ADVANCED_INTERRUPT_TYPE; + +typedef struct _CBIOS_INT_ENABLE_DISABLE_PARA +{ + CBIOS_IN CBIOS_U32 Size; // Size of CBIOS_INTERRUPT_ENABLE_DISABLE_PARA + CBIOS_IN CBIOS_BOOL bEnableInt; + CBIOS_IN CBIOS_INTERRUPT_TYPE IntFlags; + CBIOS_IN CBIOS_ADVANCED_INTERRUPT_TYPE AdvancedIntFlags; + struct + { + CBIOS_IN CBIOS_U32 bUpdAllInt : 1; + CBIOS_IN CBIOS_U32 bUpdAllAdvInt : 1; + CBIOS_IN CBIOS_U32 Reserved : 30; + }; +}CBIOS_INT_ENABLE_DISABLE_PARA, *PCBIOS_INT_ENABLE_DISABLE_PARA; + +typedef struct _CBIOS_INTERRUPT_INFO +{ + CBIOS_IN CBIOS_U32 Size; // Size of CBIOS_INTERRUPT_INFO + CBIOS_OUT CBIOS_INTERRUPT_TYPE InterruptType; + CBIOS_OUT CBIOS_ADVANCED_INTERRUPT_TYPE AdvancedIntType; +}CBIOS_INTERRUPT_INFO, *PCBIOS_INTERRUPT_INFO; + +typedef struct _CIP_ACTIVE_DEVICES +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_OUT CBIOS_U32 DeviceId[CBIOS_MAX_CRTCS]; +}CIP_ACTIVE_DEVICES, *PCIP_ACTIVE_DEVICES; + +typedef enum _CBIOS_DP_INT_TYPE +{ + CBIOS_DP_INT_STATUS_NO_INT = 0x0, + CBIOS_DP_INT_STATUS_IN, + CBIOS_DP_INT_STATUS_HDMI_OUT, + CBIOS_DP_INT_STATUS_DP_OUT, + CBIOS_DP_INT_IRQ, +}CBIOS_DP_INT_TYPE; + +typedef struct _CBIOS_DP_HANDLE_IRQ_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DeviceId; + CBIOS_IN CBIOS_DP_INT_TYPE IntType; + CBIOS_OUT CBIOS_BOOL bNeedDetect; + CBIOS_OUT CBIOS_BOOL bNeedCompEdid; +} CBIOS_DP_HANDLE_IRQ_PARA, *PCBIOS_DP_HANDLE_IRQ_PARA; + +typedef struct _CIP_DEVICES_DETECT_PARAM +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DevicesToDetect; + CBIOS_OUT CBIOS_U32 DetectedDevices; + CBIOS_IN CBIOS_U32 FullDetect; +}CIP_DEVICES_DETECT_PARAM, *PCIP_DEVICES_DETECT_PARAM; + +typedef enum _CBIOS_DUMP_TYPE { + CBIOS_DUMP_NONE = 0x00, + CBIOS_DUMP_CR_REG = 0x01, + CBIOS_DUMP_SR_REG = 0x02, + CBIOS_DUMP_PMU_REG = 0x04, + CBIOS_DUMP_TIMING_REG = 0x08, + CBIOS_DUMP_DSI0_REG = 0x10, + CBIOS_DUMP_DSI1_REG = 0x20, + CBIOS_DUMP_MHL_REG = 0x40, + CBIOS_DUMP_DP_REG = 0x80, + CBIOS_DUMP_HDMI_REG = 0x100, + CBIOS_DUMP_PS1_REG = 0x200, + CBIOS_DUMP_PS2_REG = 0x400, + CBIOS_DUMP_SS1_REG = 0x800, + CBIOS_DUMP_SS2_REG = 0x1000, + CBIOS_DUMP_TS1_REG = 0x2000, + CBIOS_DUMP_TS2_REG = 0x4000, + CBIOS_DUMP_HDAUDIO_REG = 0x8000, + CBIOS_DUMP_VCP_INFO = 0x10000, + CBIOS_DUMP_MODE_INFO = 0x20000, + CBIOS_DUMP_CLOCK_INFO = 0x40000, + CBIOS_DUMP_SCALER = 0x80000, + CBIOS_DUMP_CURSOR = 0x100000, + CBIOS_DUMP_TVSCALER = 0x200000, + CBIOS_DUMP_CSC = 0x400000, + CBIOS_DUMP_TYPE_MASK = 0XFFFFFF, + +}CBIOS_DUMP_TYPE; + +typedef struct _CBIOS_DUMP_PARA +{ + CBIOS_U32 Size; + CBIOS_DUMP_TYPE DumpType; +}CBIOS_DUMP_PARA, *PCBIOS_DUMP_PARA; + +typedef enum _CBIOS_GAMMA_STREAM_TYPE +{ + CBIOS_GAMMA_STREAM_TYPE_PS = 0x01, + CBIOS_GAMMA_STREAM_TYPE_SS = 0x02, +}CBIOS_GAMMA_STREAM_TYPE, *PCBIOS_GAMMA_STREAM_TYPE; + +typedef struct _CBIOS_CLUT_DATA +{ + CBIOS_U8 Blue; + CBIOS_U8 Green; + CBIOS_U8 Red; + CBIOS_U8 Unused; +}CBIOS_CLUT_DATA, *PCBIOS_CLUT_DATA; + +typedef union _CBIOS_LUT +{ + CBIOS_CLUT_DATA RgbArray; + CBIOS_U32 RgbLong; +}CBIOS_LUT, *PCBIOS_LUT; + +typedef struct _CBIOS_GAMMA_PARA +{ + CBIOS_IN CBIOS_OUT PCBIOS_VOID pGammaTable; + CBIOS_IN CBIOS_U32 EntryNum; + CBIOS_IN CBIOS_U32 FisrtEntryIndex; + CBIOS_IN CBIOS_U32 IGAIndex; + union + { + CBIOS_IN CBIOS_U8 Value; + struct + { + CBIOS_IN CBIOS_U8 bDisableGamma :1; + CBIOS_IN CBIOS_U8 bConfigGamma :1; + CBIOS_IN CBIOS_U8 bSetLUT :1; + CBIOS_IN CBIOS_U8 bGetLUT :1; + CBIOS_IN CBIOS_U8 bInterpolation :1; + CBIOS_IN CBIOS_U8 bUseIO :1; //use mmio or IO to update lut + CBIOS_IN CBIOS_U8 Reserved :2; + }Flags; + }; +}CBIOS_GAMMA_PARA, *PCBIOS_GAMMA_PARA; + +////// ========== DP start===================== + +typedef struct _CBIOS_DP_ISR_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DeviceId; + CBIOS_IN CBIOS_U32 InterruptMask; +} CBIOS_DP_ISR_PARA, *PCBIOS_DP_ISR_PARA; + +typedef struct _CBIOS_DP_WORKTHREAD_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DeviceId; +} CBIOS_DP_WORKTHREAD_PARA, *PCBIOS_DP_WORKTHREAD_PARA; + +typedef enum _CBIOS_DP_EVENT_CODE +{ + // available eventCode in CBIOS_DP_NOTIFY_EVENT_PARA + CBIOS_DP_EVENT_NONE = 0, // Should not happend + CBIOS_DP_EVENT_DP_HOTPLUG_OUT, // DP hotplug out detected + CBIOS_DP_EVENT_HDMI_HOTPLUG_OUT, // HDMI hotplug out detected + CBIOS_DP_EVENT_DP_HOTPLUG_IN, // DP hotplug in detected + CBIOS_DP_EVENT_HDMI_HOTPLUG_IN, // HDMI hotplug in detected + CBIOS_DP_EVENT_TEST_PATTERN, // used in DP Link Layer CTS + CBIOS_DP_EVENT_TEST_EDID, // used in DP Link Layer CTS +} CBIOS_DP_EVENT_CODE; + +typedef struct _CBIOS_DP_INT_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DeviceId; + CBIOS_OUT CBIOS_DP_INT_TYPE IntType; +} CBIOS_DP_INT_PARA, *PCBIOS_DP_INT_PARA; + +typedef struct _CBIOS_DP_NOTIFY_EVENT_PARA +{ + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_U32 DeviceId; + CBIOS_IN CBIOS_U8 EventCode; + CBIOS_IN CBIOS_U8 EventParam; + CBIOS_IN PCBIOS_U8 pExtension; +} CBIOS_DP_NOTIFY_EVENT_PARA, *PCBIOS_DP_NOTIFY_EVENT_PARA; + +typedef CBIOS_VOID +(*PFN_CbiosNotifyDPEvent) (CBIOS_IN PCBIOS_VOID Private, CBIOS_IN PCBIOS_DP_NOTIFY_EVENT_PARA pNotifyPara); + +typedef struct _CBIOS_DP_NOTIFICATIONS +{ + CBIOS_U32 Size; + CBIOS_U32 DeviceId; + PCBIOS_VOID Private; + PFN_CbiosNotifyDPEvent NotifyDPEvent; +} CBIOS_DP_NOTIFICATIONS, *PCBIOS_DP_NOTIFICATIONS; + +typedef struct _CBIOS_DP_CUSTOMIZED_TIMING +{ + CBIOS_U32 Size; + CBIOS_U32 DeviceId; + CBiosCustmizedDestTiming CustmizedTiming; +} CBIOS_DP_CUSTOMIZED_TIMING, *PCBIOS_DP_CUSTOMIZED_TIMING; + +////// ========== DP end===================== + +/* CBIOS interfaces begins */ +#ifdef DOSDLL +#define DLLEXPORTS __declspec(dllexport) +#define DLLIMPORT __declspec(dllimport) +#else +#define DLLEXPORTS +#define DLLIMPORT +#endif + +/*This function pointer definition is for driver reference how to define the interface,*/ + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETVERSION)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_OUT PCBIOS_VERSION pCbiosVersion); + +typedef CBIOS_STATUS +(*PCBIOSDDI_INITHW)(CBIOS_IN PCBIOS_VOID pvcbe); + +typedef CBIOS_STATUS +(*PCBIOSDDI_DETECTATTACHEDDISPLAYDEVICES)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCIP_DEVICES_DETECT_PARAM pDevicesDetectParam); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETDEVICEMODELISTBUFFERSIZE)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_U32 DeviceId, + CBIOS_OUT PCBIOS_U32 pBufferSize); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETDEVICEMODELIST)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_U32 DeviceId, + CBIOS_OUT PCBiosModeInfoExt pModeList, + CBIOS_IN CBIOS_OUT PCBIOS_U32 pBufferSize); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETADAPTERMODELISTBUFFERSIZE)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_OUT PCBIOS_U32 pBufferSize); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETADAPTERMODELIST)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_OUT PCBiosModeInfoExt pModeList, + CBIOS_IN CBIOS_OUT PCBIOS_U32 pBufferSize); + +typedef CBIOS_STATUS +(*PCBIOSDDI_SETMODETOIGA)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBiosSettingModeParams pSettingModeParams); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETMODEFROMIGA)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_OUT PCBiosSettingModeParams pModeParams); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETMODETIMING)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_GET_MODE_TIMING_PARAM pGetModeTiming); + +typedef CBIOS_STATUS +(*PCBIOSDDI_SETSCREENONOFF)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_S32 status, + CBIOS_IN CBIOS_UCHAR IGAIndex); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETDEVICEPOWERSTATE)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_U32 DevicesId, + CBIOS_OUT PCBIOS_PM_STATUS pPMState); + +typedef CBIOS_STATUS +(*PCBIOSDDI_SETDEVICEPOWERSTATE)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_U32 DevicesId, + CBIOS_IN CBIOS_PM_STATUS PMState); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETEDID)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_PARAM_GET_EDID pCBParamGetEdid); + +typedef CBIOS_STATUS +(*PCBIOSDDI_SETEDID)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_PARAM_SET_EDID pCBParamSetEdid); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETCLOCK)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBios_GetClock_Params pCBiosGetClockParams); + +typedef CBIOS_STATUS +(*PCBIOSDDI_SETCLOCK)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBios_SetClock_Params pCBiosSetClockParams); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETACTIVEDEVICE)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_OUT PCIP_ACTIVE_DEVICES pActiveDevices); + +typedef CBIOS_STATUS +(*PCBIOSDDI_SETACTIVEDEVICE)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_OUT PCIP_ACTIVE_DEVICES pActiveDevices); + +typedef CBIOS_STATUS +(*PCBIOSDDI_SYNCDATAWITHVBIOS)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_VBIOS_DATA_PARAM pDataParam); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETVBIOSINFO)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_VBINFO_PARAM pVbiosInfo); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETMONITORTYPEPERPORT)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_QUERY_MONITOR_TYPE_PER_PORT pCBiosQueryMonitorTypePerPort); + +typedef CBIOS_STATUS +(*PCBIOSDDI_QUERYMONITORATTRIBUTE)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_OUT PCBiosMonitorAttribute pMonitorAttribute); + +typedef CBIOS_STATUS +(*PCBIOSDDI_QUERYMONITOR3DCAPABILITY)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_MONITOR_3D_CAPABILITY_PARA p3DCapability); + +typedef CBIOS_STATUS +(*PCBIOSDDI_I2CDATAREAD)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_PARAM_I2C_DATA pCBParamI2CData); + +typedef CBIOS_STATUS +(*PCBIOSDDI_I2CDATAWRITE)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_PARAM_I2C_DATA pCBParamI2CData); + +typedef CBIOS_STATUS +(*PCBIOSDDI_DDCCII2COPEN)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_S32 bOpen, + CBIOS_IN CBIOS_OUT PCBIOS_I2CCONTROL pI2CControl, + CBIOS_IN CBIOS_UCHAR I2CBUSNum); + +typedef CBIOS_STATUS +(*PCBIOSDDI_DDCCII2CACCESS)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_I2CCONTROL pI2CControl, + CBIOS_IN CBIOS_UCHAR I2CBUSNum); + +typedef CBIOS_STATUS +(*PCBIOSDDI_READREG)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_UCHAR type, + CBIOS_IN CBIOS_UCHAR index, + CBIOS_OUT PCBIOS_UCHAR result); + +typedef CBIOS_STATUS +(*PCBIOSDDI_WRITEREG)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_UCHAR type, + CBIOS_IN CBIOS_UCHAR index, + CBIOS_IN CBIOS_UCHAR value, + CBIOS_IN CBIOS_UCHAR mask); + +typedef CBIOS_STATUS +(*PCBIOSDDI_SETHDACODECPARA)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_HDAC_PARA pCbiosHDACPara); + +typedef CBIOS_STATUS +(*PCBIOSDDI_SETHDACCONNECTSTATUS)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_HDAC_PARA pCbiosHDACPara); + +typedef CBIOS_STATUS +(*PCBIOSDDI_ACCESSDPCDDATA)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBiosAccessDpcdDataParams pAccessDpcdDataParams); + +#ifndef UEFI_DIAGTOOL +typedef CBIOS_STATUS +(*PCBIOSDDI_CONTENTPROTECTIONONOFF)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBiosContentProtectionOnOffParams pContentProtectionOnOffParams); +#else +typedef CBIOS_STATUS +(*PCBIOSDDI_CONTENTPROTECTIONONOFF)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBiosContentProtectionOnOffParams pContentProtectionOnOffParams, CBIOS_U16 hdcpVer); +#endif + + +typedef CBIOS_STATUS +(*PCBIOSDDI_HDCPIsr)(PCBIOS_VOID pvcbe, PCBIOS_HDCP_ISR_PARA pHdcpIsrParam); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GetHDCPInterruptInfo)(PCBIOS_VOID pvcbe, PCBIOS_HDCP_INFO_PARA pHdcpInfoParam); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GetHDCPStatus)(PCBIOS_VOID pvcbe, PCBIOS_HDCP_STATUS_PARA pCBiosHdcpStatusParams); + +typedef CBIOS_STATUS +(*PCBIOSDDI_HDCPWorkThread)(PCBIOS_VOID pvcbe, PCBIOS_HDCP_WORK_PARA pCBiosHdcpWorkParams); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GetHDACInterruptInfo)(PCBIOS_VOID pvcbe, PCBIOS_HDAC_INFO_PARA pHdacInfoParam); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETDEVCOMB)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_GET_DEV_COMB pGetDevComb); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETIGAMASK)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_GET_IGA_MASK pGetIgaMask); + +typedef CBIOS_STATUS +(*PCBIOSDDI_INTERRUPTENABLEDISABLE)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_INT_ENABLE_DISABLE_PARA pIntPara); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETINTERRUPTINFO)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_INTERRUPT_INFO pIntInfo); + +typedef CBIOS_STATUS +(*PCBIOSDDI_SETCURSOR)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_CURSOR_PARA pSetCursor); + +typedef CBIOS_STATUS +(*PCBIOSDDI_RESETHWBLOCK)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_HW_BLOCK HWBlock); + +typedef CBIOS_STATUS +(*PCBIOSDDI_UNLOAD)(CBIOS_IN PCBIOS_VOID pvcbe); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GETDISPADDR)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_GET_DISP_ADDR pGetDispAddr); + +typedef CBIOS_STATUS +(*PCBIOSDDI_UPDATEFRAME)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_UPDATE_FRAME_PARA pUpdateFrame); + +typedef CBIOS_STATUS +(*PCBIOSDDI_SETGAMMA)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_GAMMA_PARA pGammaParam); + +typedef CBIOS_STATUS +(*PCBIOSDDI_DPIsr)(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_DP_ISR_PARA pDPIsrPara); + +typedef CBIOS_BOOL +(*PCBIOSDDI_DPWorkThreadMainFunc)(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_WORKTHREAD_PARA pDPWorkThreadPara); + +typedef CBIOS_STATUS +(*PCBIOSDDI_DPSetNotifications)(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_NOTIFICATIONS pDPNotifications); + +typedef CBIOS_STATUS +(*PCBIOSDDI_HandleDPIrq)(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_HANDLE_IRQ_PARA pDPHandleIrqPara); + +typedef CBIOS_STATUS +(*PCBIOSDDI_DPGetCustomizedTiming)(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_CUSTOMIZED_TIMING pDPCustomizedTiming); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GetDPIntType)(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_INT_PARA pDPIntPara); + +typedef CBIOS_STATUS +(*PCBIOSDDI_WaitVBlank)(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN CBIOS_U32 IGAIndex); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GetSliceNum)(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_OUT PCBIOS_U8 pSliceNum, CBIOS_OUT PCBIOS_U32 pGPCReg); + +typedef CBIOS_STATUS +(*PCBIOSDDI_GetHwCounter)(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_GET_HW_COUNTER pGetCounter); + + +typedef struct _CBIOS_INTERFACES { + CBIOS_U32 Size; + CBIOS_U32 Version; + PCBIOSDDI_GETVERSION CBiosDdiGetVersion; + PCBIOSDDI_INITHW CBiosDdiInitHW; + PCBIOSDDI_DETECTATTACHEDDISPLAYDEVICES CBiosDdiDetectAttachedDisplayDevices; + PCBIOSDDI_GETDEVICEMODELISTBUFFERSIZE CBiosDdiGetDeviceModeListBufferSize; + PCBIOSDDI_GETDEVICEMODELIST CBiosDdiGetDeviceModeList; + PCBIOSDDI_GETADAPTERMODELISTBUFFERSIZE CBiosDdiGetAdapterModeListBufferSize; + PCBIOSDDI_GETADAPTERMODELIST CBiosDdiGetAdapterModeList; + PCBIOSDDI_SETMODETOIGA CBiosDdiSetModeToIGA; + PCBIOSDDI_GETMODEFROMIGA CBiosDdiGetModeFromIGA; + PCBIOSDDI_GETMODETIMING CBiosDdiGetModeTiming; + PCBIOSDDI_SETSCREENONOFF CBiosDdiSetScreenOnOff; + PCBIOSDDI_GETDEVICEPOWERSTATE CBiosDdiGetDevicePowerState; + PCBIOSDDI_SETDEVICEPOWERSTATE CBiosDdiSetDevicePowerState; + PCBIOSDDI_GETEDID CBiosDdiGetEdid; + PCBIOSDDI_SETEDID CBiosDdiSetEdid; + PCBIOSDDI_GETCLOCK CBiosDdiGetClock; + PCBIOSDDI_SETCLOCK CBiosDdiSetClock; + PCBIOSDDI_GETACTIVEDEVICE CBiosDdiGetActiveDevice; + PCBIOSDDI_SETACTIVEDEVICE CBiosDdiSetActiveDevice; + PCBIOSDDI_SYNCDATAWITHVBIOS CBiosDdiSyncDataWithVBios; + PCBIOSDDI_GETVBIOSINFO CBiosDdiGetVBiosInfo; + PCBIOSDDI_GETMONITORTYPEPERPORT CBiosDdiGetMonitorTypePerPort; + PCBIOSDDI_QUERYMONITORATTRIBUTE CBiosDdiQueryMonitorAttribute; + PCBIOSDDI_QUERYMONITOR3DCAPABILITY CBiosDdiQueryMonitor3DCapability; + PCBIOSDDI_I2CDATAREAD CBiosDdiI2CDataRead; + PCBIOSDDI_I2CDATAWRITE CBiosDdiI2CDataWrite; + PCBIOSDDI_DDCCII2COPEN CBiosDdiDDCCII2COpen; + PCBIOSDDI_DDCCII2CACCESS CBiosDdiDDCCII2CAccess; + PCBIOSDDI_READREG CBiosDdiReadReg; + PCBIOSDDI_WRITEREG CBiosDdiWriteReg; + PCBIOSDDI_SETHDACODECPARA CBiosDdiSetHDACodecPara; + PCBIOSDDI_SETHDACCONNECTSTATUS CBiosDdiSetHDACConnectStatus; + PCBIOSDDI_ACCESSDPCDDATA CBiosDdiAccessDpcdData; + PCBIOSDDI_CONTENTPROTECTIONONOFF CBiosDdiContentProtectionOnOff; + PCBIOSDDI_GETDEVCOMB CBiosDdiGetDevComb; + PCBIOSDDI_GETIGAMASK CBiosDdiGetIgaMask; + PCBIOSDDI_INTERRUPTENABLEDISABLE CBiosDdiInterruptEnableDisable; + PCBIOSDDI_GETINTERRUPTINFO CBiosDdiGetInterruptInfo; + PCBIOSDDI_SETCURSOR CBiosDdiSetCursor; + PCBIOSDDI_RESETHWBLOCK CBiosDdiResetHWBlock; + PCBIOSDDI_UNLOAD CBiosDdiUnload; + PCBIOSDDI_GETDISPADDR CBiosDdiGetDispAddr; + PCBIOSDDI_UPDATEFRAME CBiosDdiUpdateFrame; + PCBIOSDDI_SETGAMMA CBiosDdiSetGamma; + PCBIOSDDI_DPIsr CBiosDdiDPIsr; + PCBIOSDDI_DPWorkThreadMainFunc CBiosDdiDPWorkThreadMainFunc; + PCBIOSDDI_GetDPIntType CBiosDdiGetDPIntType; + PCBIOSDDI_HandleDPIrq CBiosDdiHandleDPIrq; + PCBIOSDDI_DPGetCustomizedTiming CBiosDdiDPGetCustomizedTiming; + PCBIOSDDI_DPSetNotifications CBiosDdiDPSetNotifications; + PCBIOSDDI_HDCPIsr CBiosDdiHDCPIsr; + PCBIOSDDI_GetHDCPInterruptInfo CBiosDdiGetHDCPInterruptInfo; + PCBIOSDDI_GetHDCPStatus CBiosDdiGetHDCPStatus; + PCBIOSDDI_HDCPWorkThread CBiosDdiHDCPWorkThread; + PCBIOSDDI_GetHDACInterruptInfo CBiosDdiGetHDACInterruptInfo; + PCBIOSDDI_WaitVBlank CBiosDdiWaitVBlank; + PCBIOSDDI_GetSliceNum CBiosDdiGetSliceNum; + PCBIOSDDI_GetHwCounter CBiosDdiGetHwCounter; +}CBIOS_INTERFACES, *PCBIOS_INTERFACES; + + +typedef struct _CBIOS_INITIALIZATION_PARA { + CBIOS_IN CBIOS_U32 Size; + CBIOS_IN CBIOS_PARAM_INIT CBiosParamInit; + CBIOS_IN CBIOS_CALLBACK_FUNCTIONS CBiosCallbacks; + CBIOS_OUT CBIOS_INTERFACES CBiosInterfaces; + CBIOS_OUT PCBIOS_VOID pCBiosExtension; +}CBIOS_INITIALIZATION_PARA, *PCBIOS_INITIALIZATION_PARA; + + +//============================================================================= + + + +/*CBios external interface definiton.*/ +#ifdef __cplusplus +extern "C" { +#endif + +DLLEXPORTS CBIOS_STATUS +CBiosGetExtensionSize(PCBIOS_CHIP_ID pCBChipId, CBIOS_U32 *pulExtensionSize); + +DLLEXPORTS CBIOS_STATUS +CBiosInit(CBIOS_VOID* pcbe, PCBIOS_PARAM_INIT pCBParamInit); + +DLLEXPORTS CBIOS_STATUS +CBiosInitialize(CBIOS_IN CBIOS_OUT PCBIOS_INITIALIZATION_PARA pCBiosInitPara); + +DLLEXPORTS CBIOS_STATUS +CBiosGetVersion(CBIOS_VOID* pcbe, PCBIOS_VERSION pCbiosVersion); + +DLLEXPORTS CBIOS_STATUS +CBiosSetCallBackFunctions(PCBIOS_CALLBACK_FUNCTIONS pFnCallBack); + +DLLEXPORTS CBIOS_STATUS +CBiosDetectAttachedDisplayDevices(PCBIOS_VOID pvcbe, PCIP_DEVICES_DETECT_PARAM pDevicesDetectParam); + +DLLEXPORTS CBIOS_STATUS +CBiosInitHW(CBIOS_VOID* pcbe); + +DLLEXPORTS CBIOS_STATUS +CBiosIsChipEnable(PCBIOS_VOID pvcbe, PCBIOS_PARAM_CHECK_CHIPENABLE pCBParamCheckChipenable); + +DLLEXPORTS CBIOS_STATUS +CBiosDumpReg(CBIOS_VOID* pcbe, PCBIOS_PARAM_DUMP_REG pCBParamDumpReg); + +DLLEXPORTS CBIOS_STATUS +CBiosGetEdid(CBIOS_VOID* pcbe, PCBIOS_PARAM_GET_EDID pCBParamGetEdid); + +DLLEXPORTS CBIOS_STATUS +CBiosI2CDataRead(CBIOS_VOID* pcbe, PCBIOS_PARAM_I2C_DATA pCBParamI2CData); + +DLLEXPORTS CBIOS_STATUS +CBiosI2CDataWrite(CBIOS_VOID* pcbe, PCBIOS_PARAM_I2C_DATA pCBParamI2CData); + +DLLEXPORTS CBIOS_STATUS +CBiosGetClock(CBIOS_VOID* pcbe, PCBios_GetClock_Params pCBiosGetClockParams); + +DLLEXPORTS CBIOS_STATUS +CBiosSetClock(CBIOS_VOID* pcbe, PCBios_SetClock_Params pCBiosSetClockParams); + +DLLEXPORTS CBIOS_STATUS +CBiosUnload(CBIOS_VOID* pcbe); + +DLLEXPORTS CBIOS_STATUS +CBiosReadReg(CBIOS_VOID* pcbe, CBIOS_UCHAR type, CBIOS_UCHAR index,CBIOS_UCHAR *result); + +DLLEXPORTS CBIOS_STATUS +CBiosWriteReg(CBIOS_VOID* pcbe, CBIOS_UCHAR type, CBIOS_UCHAR index, CBIOS_UCHAR value, CBIOS_UCHAR mask); + +DLLEXPORTS CBIOS_STATUS +CBiosDDCCII2COpen(CBIOS_VOID* pcbe, CBIOS_S32 bOpen, PCBIOS_I2CCONTROL pI2CControl, CBIOS_UCHAR I2CBUSNum); + +DLLEXPORTS CBIOS_STATUS +CBiosDDCCII2CAccess(CBIOS_VOID* pcbe, PCBIOS_I2CCONTROL pI2CControl, CBIOS_UCHAR I2CBUSNum); + +DLLEXPORTS CBIOS_STATUS +CBiosSetIgaScreenOnOffState(CBIOS_VOID* pcbe, CBIOS_S32 status, CBIOS_UCHAR IGAIndex); + +DLLEXPORTS CBIOS_STATUS +CBiosSetDisplayDevicePowerState(CBIOS_VOID* pcbe, CBIOS_U32 DevicesId, CBIOS_PM_STATUS PMState); + +DLLEXPORTS CBIOS_STATUS +CBiosGetDisplayDevicePowerState(CBIOS_VOID* pcbe, CBIOS_U32 DevicesId, PCBIOS_PM_STATUS pPMState); + +/* The following function is for new setting mode logic */ +DLLEXPORTS CBIOS_STATUS +CBiosGetDeviceModeListBufferSize(CBIOS_IN CBIOS_VOID* pvcbe, + CBIOS_IN CBIOS_U32 DeviceId, + CBIOS_OUT CBIOS_U32 * pBufferSize); +DLLEXPORTS CBIOS_STATUS +CBiosGetDeviceModeList(CBIOS_IN CBIOS_VOID* pcbe, + CBIOS_IN CBIOS_U32 DeviceId, + CBIOS_OUT PCBiosModeInfoExt pModeList, + CBIOS_IN CBIOS_OUT CBIOS_U32 * pBufferSize); +DLLEXPORTS CBIOS_STATUS +CBiosGetAdapterModeListBufferSize(CBIOS_IN CBIOS_VOID* pcbe, + CBIOS_OUT CBIOS_U32 * pBufferSize); + +DLLEXPORTS CBIOS_STATUS +CBiosGetAdapterModeList(CBIOS_IN CBIOS_VOID* pcbe, + CBIOS_OUT PCBiosModeInfoExt pModeList, + CBIOS_IN CBIOS_OUT CBIOS_U32 * pBufferSize); + +DLLEXPORTS CBIOS_STATUS +CBiosGetHDMIAudioFomatList(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_U32 DeviceId, + CBIOS_OUT PCBiosHDMIAudioFormat pAudioFormatList, + CBIOS_IN CBIOS_OUT CBIOS_U32 *pBufferSize); + +DLLEXPORTS CBIOS_STATUS +CBiosGetHDMIAudioFomatListBufferSize(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_U32 DeviceId, + CBIOS_OUT CBIOS_U32 *pBufferSize); + +DLLEXPORTS CBIOS_STATUS +CBiosSetModeToIGA(CBIOS_IN CBIOS_VOID* pcbe, + CBIOS_IN PCBiosSettingModeParams pSettingModeParams); + +DLLEXPORTS CBIOS_STATUS +CBiosGetModeFromIGA(CBIOS_IN CBIOS_VOID* pcbe, + CBIOS_IN PCBiosSettingModeParams pModeParams); + +DLLEXPORTS CBIOS_STATUS +CBiosGetModeFromReg(CBIOS_IN CBIOS_VOID* pvcbe, + CBIOS_IN CBIOS_OUT PCBiosSettingModeParams pModeParams); + +DLLEXPORTS CBIOS_STATUS +CBiosUpdateFrame(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_UPDATE_FRAME_PARA pUpdateFrame); + +DLLEXPORTS CBIOS_STATUS +CBiosGetHwCounter(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_GET_HW_COUNTER pGetCounter); + +DLLEXPORTS CBIOS_STATUS +CBiosDoCSCAdjust(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_CSC_ADJUST_PARA pCSCAdjustPara); + +DLLEXPORTS CBIOS_STATUS +CBiosAdjustStreamCSC(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_STREAM_CSC_PARA pCSCAdjustPara); + +DLLEXPORTS CBIOS_STATUS +CBiosGetDispResource(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_GET_DISP_RESOURCE pGetDispRes); + +DLLEXPORTS CBIOS_STATUS +CBiosGetDisplayCaps(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_DISPLAY_CAPS pDispCaps); + +DLLEXPORTS CBIOS_STATUS +CBiosSetCursor(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_CURSOR_PARA pSetCursor); + +DLLEXPORTS CBIOS_STATUS +CBiosCheckSurfaceOnDisplay(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_CHECK_SURFACE_ON_DISP pChkSurfacePara); + +DLLEXPORTS CBIOS_STATUS +CBiosGetDisplayAddr(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_GET_DISP_ADDR pGetDispAddr); + +DLLEXPORTS CBIOS_STATUS +CBiosQueryMonitorAttribute(CBIOS_IN CBIOS_VOID* pvcbe, + CBIOS_OUT PCBiosMonitorAttribute pMonitorAttribute); +#ifndef UEFI_DIAGTOOL +DLLEXPORTS CBIOS_STATUS +CBiosContentProtectionOnOff(CBIOS_IN CBIOS_VOID* pvcbe, + CBIOS_IN PCBiosContentProtectionOnOffParams pContentProtectionOnOffParams); +#else +DLLEXPORTS CBIOS_STATUS +CBiosContentProtectionOnOff(CBIOS_IN CBIOS_VOID* pvcbe, + CBIOS_IN PCBiosContentProtectionOnOffParams pContentProtectionOnOffParams, CBIOS_U16 hdcpVer); +#endif + +DLLEXPORTS CBIOS_STATUS +CBiosAccessDpcdData(CBIOS_VOID* pcbe, + PCBiosAccessDpcdDataParams pAccessDpcdDataParams); + +DLLEXPORTS CBIOS_STATUS +CBiosResetHWBlock(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN CBIOS_HW_BLOCK HWBlock); + +DLLEXPORTS CBIOS_STATUS +CBiosSetEdid(CBIOS_IN CBIOS_VOID* pvcbe, + CBIOS_IN PCBIOS_PARAM_SET_EDID pCBParamSetEdid); + +DLLEXPORTS CBIOS_STATUS +CBiosSetGamma(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_GAMMA_PARA pGammaParam); + +DLLEXPORTS CBIOS_STATUS +CBiosGetModeTiming(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_GET_MODE_TIMING_PARAM pGetModeTiming); + +DLLEXPORTS CBIOS_STATUS +CBiosGetVBiosInfo(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_VBINFO_PARAM pVbiosInfo); + +DLLEXPORTS CBIOS_STATUS +CBiosSetMmioEndianMode(CBIOS_IN CBIOS_VOID* pAdapterContext); + +DLLEXPORTS CBIOS_STATUS +CBiosQueryMonitor3DCapability(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_MONITOR_3D_CAPABILITY_PARA p3DCapability); + +DLLEXPORTS CBIOS_STATUS +CBiosSetHDACodecPara(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_HDAC_PARA pCbiosHDACPara); + +DLLEXPORTS CBIOS_STATUS +CBiosSetHDACConnectStatus(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_HDAC_PARA pCbiosHDACPara); + +DLLEXPORTS CBIOS_STATUS +CBiosCECEnableDisable(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_CEC_ENABLE_DISABLE_PARA pCECEnableDisablePara); + +DLLEXPORTS CBIOS_STATUS +CBiosCECTransmitMessage(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_CEC_TRANSIMIT_MESSAGE_PARA pCECPara); + +DLLEXPORTS CBIOS_STATUS +CBiosCECReceiveMessage(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_CEC_RECEIVE_MESSAGE_PARA pCECPara); + +DLLEXPORTS CBIOS_STATUS +CBiosCECGetInfo(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_OUT PCBIOS_CEC_INFO pCECInfo); + +DLLEXPORTS CBIOS_STATUS +CBiosGetCECInterruptInfo(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_CEC_INTERRUPT_INFO pCECIntInfo); + +DLLEXPORTS CBIOS_STATUS +CBiosGetMonitorTypePerPort(CBIOS_IN CBIOS_VOID* pvcbe,CBIOS_IN CBIOS_OUT PCBIOS_QUERY_MONITOR_TYPE_PER_PORT pCBiosQueryMonitorTypePerPort); + +DLLEXPORTS CBIOS_STATUS +CBiosGetActiveDevice(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_OUT PCIP_ACTIVE_DEVICES pActiveDevices); + +DLLEXPORTS CBIOS_STATUS +CBiosSetActiveDevice(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_OUT PCIP_ACTIVE_DEVICES pActiveDevices); + +DLLEXPORTS CBIOS_STATUS +CBiosGetDevComb(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_GET_DEV_COMB pGetDevComb); + +DLLEXPORTS CBIOS_STATUS +CBiosGetIgaMask(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_GET_IGA_MASK pGetIgaMask); + +DLLEXPORTS CBIOS_STATUS +CBiosGetDeviceName(PCBIOS_VOID pvcbe, PCBIOS_GET_DEVICE_NAME pGetName); + +DLLEXPORTS CBIOS_STATUS +CBiosSetWriteback(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_WB_PARA pSettingDownscalerParams); + +DLLEXPORTS CBIOS_STATUS +CBiosGetHDCPStatus(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_HDCP_STATUS_PARA pCBiosHdcpStatusParams); + +DLLEXPORTS CBIOS_STATUS +CBiosHDCPWorkThread(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_HDCP_WORK_PARA pCBiosHdcpWorkParams); + +DLLEXPORTS CBIOS_STATUS +CBiosHDCPIsr(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_HDCP_ISR_PARA pHdcpIsrParam); + +DLLEXPORTS CBIOS_STATUS +CBiosGetHDCPInterruptInfo(PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_HDCP_INFO_PARA pHdcpInfoParam); + +DLLEXPORTS CBIOS_STATUS +CBiosGetHDACInterruptInfo(PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_HDAC_INFO_PARA pHdacInfoParam); + +DLLEXPORTS CBIOS_STATUS +CBiosDbgLevelCtl(PCBIOS_DBG_LEVEL_CTRL pDbgLevelCtl); + +DLLEXPORTS CBIOS_STATUS +CBiosInterruptEnableDisable(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_INT_ENABLE_DISABLE_PARA pIntPara); + +DLLEXPORTS CBIOS_STATUS +CBiosGetInterruptInfo(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_INTERRUPT_INFO pIntInfo); + +DLLEXPORTS CBIOS_STATUS +CBiosSyncDataWithVbios(PCBIOS_VOID pvcbe, PCBIOS_VBIOS_DATA_PARAM pDataParam); + +DLLEXPORTS CBIOS_STATUS +CBiosGetDPIntType(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_INT_PARA pDPIntPara); + +DLLEXPORTS CBIOS_STATUS +CBiosHandleDPIrq(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_HANDLE_IRQ_PARA pDPHandleIrqPara); + +DLLEXPORTS CBIOS_STATUS +CBiosDPIsr(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_ISR_PARA pDPIsrPara) ; + +DLLEXPORTS CBIOS_BOOL +CBiosDPWorkThreadMainFunc(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_WORKTHREAD_PARA pDPWorkThreadPara) ; + +DLLEXPORTS CBIOS_STATUS +CBiosDPSetNotifications(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_NOTIFICATIONS pDPNotifications); + +DLLEXPORTS CBIOS_STATUS +CBiosDPGetCustomizedTiming(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_CUSTOMIZED_TIMING pDPCustomizedTiming); + +DLLEXPORTS CBIOS_STATUS +CBiosWaitVBlank(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN CBIOS_U32 IGAIndex); + +DLLEXPORTS CBIOS_STATUS +CBiosDumpInfo(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DUMP_PARA pDumpPara); + +DLLEXPORTS CBIOS_STATUS +CBiosVIPCtl(PCBIOS_VOID pvcbe, PCBIOS_VIP_CTRL_DATA pCbiosVIPCtlData); + +DLLEXPORTS CBIOS_STATUS +CBiosGetSliceNum(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_OUT PCBIOS_U8 pSliceNum, CBIOS_OUT PCBIOS_U32 pGPCReg); + +/*When need add new interface, please add this from this position.*/ +#ifdef __cplusplus +} +#endif +/* CBIOS interfaces ends */ + + +#endif /*_CBIOS_H_ */ + + diff --git a/drivers/gpu/drm/arise/cbios/Callback/CBiosCallbacks.c b/drivers/gpu/drm/arise/cbios/Callback/CBiosCallbacks.c new file mode 100644 index 0000000000000..dd927a5d528fe --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Callback/CBiosCallbacks.c @@ -0,0 +1,445 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios hw independent callback function implementation. +** +** NOTE: +** The hw dependent callback function SHOULD NOT be added to this file. +******************************************************************************/ + + +#include "CBiosCallbacks.h" +#include "../Device/CBiosChipShare.h" + +CALLBACK_cbVsprintf cbVsprintf = CBIOS_NULL; +CALLBACK_cbVsnprintf cbVsnprintf = CBIOS_NULL; + +CBIOS_CALLBACK_FUNCTIONS FnCallback = {0}; + +CBIOS_STATUS cbSetCallBackFunctions(PCBIOS_CALLBACK_FUNCTIONS pFnCallBack) +{ + if(pFnCallBack == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + +#ifndef UEFI_DIAGTOOL + if((pFnCallBack->pFnDelayMicroSeconds == CBIOS_NULL)|| + (pFnCallBack->pFnQuerySystemTime == CBIOS_NULL)|| + (pFnCallBack->pFnAllocateNonpagedMemory == CBIOS_NULL)|| + (pFnCallBack->pFnAllocatePagedMemory == CBIOS_NULL)|| + (pFnCallBack->pFnFreePool == CBIOS_NULL)|| + (pFnCallBack->pFnAcquireSpinLock == CBIOS_NULL)|| + (pFnCallBack->pFnReleaseSpinLock == CBIOS_NULL)) +#else + if((pFnCallBack->pFnDelayMicroSeconds == CBIOS_NULL)|| + (pFnCallBack->pFnAllocateNonpagedMemory == CBIOS_NULL)|| + (pFnCallBack->pFnAllocatePagedMemory == CBIOS_NULL)|| + (pFnCallBack->pFnFreePool == CBIOS_NULL)) +#endif + { + return CBIOS_ER_INVALID_PARAMETER; + } + + // remove PrintToFile function for android 4.4 resume hang issue + + pFnCallBack->pFnDbgPrintToFile = CBIOS_NULL; + + cbVsprintf = pFnCallBack->pFnVsprintf; + + cbVsnprintf = pFnCallBack->pFnVsnprintf; + + //FnCallback = *pFnCallBack; + FnCallback.Size=pFnCallBack->Size; + FnCallback.pFnDbgPrint=pFnCallBack->pFnDbgPrint; + FnCallback.pFnDelayMicroSeconds=pFnCallBack->pFnDelayMicroSeconds; + FnCallback.pFnReadUchar=pFnCallBack->pFnReadUchar; + FnCallback.pFnReadUshort=pFnCallBack->pFnReadUshort; + FnCallback.pFnReadUlong=pFnCallBack->pFnReadUlong; + FnCallback.pFnWriteUchar=pFnCallBack->pFnWriteUchar; + FnCallback.pFnWriteUshort=pFnCallBack->pFnWriteUshort; + FnCallback.pFnWriteUlong=pFnCallBack->pFnWriteUlong; + FnCallback.pFnQuerySystemTime=pFnCallBack->pFnQuerySystemTime; + FnCallback.pFnAllocateNonpagedMemory=pFnCallBack->pFnAllocateNonpagedMemory; + FnCallback.pFnAllocatePagedMemory=pFnCallBack->pFnAllocatePagedMemory; + FnCallback.pFnFreePool=pFnCallBack->pFnFreePool; + FnCallback.pFnAcquireSpinLock=pFnCallBack->pFnAcquireSpinLock; + FnCallback.pFnReleaseSpinLock=pFnCallBack->pFnReleaseSpinLock; + FnCallback.pFnAcquireMutex=pFnCallBack->pFnAcquireMutex; + FnCallback.pFnReleaseMutex=pFnCallBack->pFnReleaseMutex; + FnCallback.pFnReadPortUchar=pFnCallBack->pFnReadPortUchar; + FnCallback.pFnWritePortUchar=pFnCallBack->pFnWritePortUchar; + FnCallback.pFnGetRegistryParameters=pFnCallBack->pFnGetRegistryParameters; + FnCallback.pFnSetRegistryParameters=pFnCallBack->pFnSetRegistryParameters; + FnCallback.pFnStrcmp=pFnCallBack->pFnStrcmp; + FnCallback.pFnStrcpy=pFnCallBack->pFnStrcpy; + FnCallback.pFnStrncmp=pFnCallBack->pFnStrncmp; + FnCallback.pFnMemset=pFnCallBack->pFnMemset; + FnCallback.pFnMemcpy=pFnCallBack->pFnMemcpy; + FnCallback.pFnMemcmp=pFnCallBack->pFnMemcmp; + FnCallback.pFnDodiv=pFnCallBack->pFnDodiv; + FnCallback.pFnVsprintf=pFnCallBack->pFnVsprintf; + FnCallback.pFnWriteRegisterU32=pFnCallBack->pFnWriteRegisterU32; + FnCallback.pFnReadRegisterU32=pFnCallBack->pFnReadRegisterU32; + FnCallback.pFnDbgPrintToFile=pFnCallBack->pFnDbgPrintToFile; + FnCallback.pFnVsnprintf=pFnCallBack->pFnVsnprintf; + + FnCallback.pFnGpioGetValue=pFnCallBack->pFnGpioGetValue; + FnCallback.pFnGpioSetValue=pFnCallBack->pFnGpioSetValue; + FnCallback.pFnGpioRequest=pFnCallBack->pFnGpioRequest; + FnCallback.pFnGpioFree=pFnCallBack->pFnGpioFree; + FnCallback.pFnGpioDirectionInput=pFnCallBack->pFnGpioDirectionInput; + FnCallback.pFnGpioDirectionOutput=pFnCallBack->pFnGpioDirectionOutput; + FnCallback.pFnGetPlatformConfigU32=pFnCallBack->pFnGetPlatformConfigU32; + + FnCallback.pFnRegulatorGet=pFnCallBack->pFnRegulatorGet; + FnCallback.pFnRegulatorEnable=pFnCallBack->pFnRegulatorEnable; + FnCallback.pFnRegulatorDisable=pFnCallBack->pFnRegulatorDisable; + FnCallback.pFnRegulatorIsEnabled=pFnCallBack->pFnRegulatorIsEnabled; + FnCallback.pFnRegulatorGetVoltage=pFnCallBack->pFnRegulatorGetVoltage; + FnCallback.pFnRegulatorSetVoltage=pFnCallBack->pFnRegulatorSetVoltage; + FnCallback.pFnRegulatorPut=pFnCallBack->pFnRegulatorPut; + return CBIOS_OK; +} + +CBIOS_VOID cb_DbgPrint(CBIOS_U32 DebugPrintLevel, PCBIOS_UCHAR DebugMessage) +{ + if (FnCallback.pFnDbgPrint != CBIOS_NULL) + { + ((CALLBACK_cbDbgPrint)FnCallback.pFnDbgPrint)(DebugPrintLevel,DebugMessage); + } + else + { + return; + } +} + +CBIOS_VOID cb_DelayMicroSeconds(CBIOS_U32 Microseconds) +{ + if (FnCallback.pFnDelayMicroSeconds != CBIOS_NULL) + { + ((CALLBACK_cbDelayMicroSeconds)FnCallback.pFnDelayMicroSeconds)(Microseconds); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } +} + +CBIOS_U64 cb_QuerySystemTime(void) +{ + CBIOS_U64 time = 0; + + if (FnCallback.pFnQuerySystemTime != CBIOS_NULL) + { + ((CALLBACK_cbQuerySystemTime)FnCallback.pFnQuerySystemTime)(&time); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + + return time; +} + +// memory allocation and free function stub +PCBIOS_VOID cb_AllocateNonpagedPool(CBIOS_U32 NumberOfBytes) +{ + PCBIOS_VOID Ret = CBIOS_NULL; + + if (FnCallback.pFnAllocateNonpagedMemory != CBIOS_NULL) + { + Ret = ((CALLBACK_cbAllocateNonpagedPool)FnCallback.pFnAllocateNonpagedMemory)(NumberOfBytes); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + return Ret; +} + +PCBIOS_VOID cb_AllocatePagedPool(CBIOS_U32 NumberOfBytes) +{ + PCBIOS_VOID Ret = CBIOS_NULL; + + if (FnCallback.pFnAllocatePagedMemory != CBIOS_NULL) + { + Ret = ((CALLBACK_cbAllocatePagedPool)FnCallback.pFnAllocatePagedMemory)(NumberOfBytes); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + return Ret; +} + +CBIOS_VOID cb_FreePool(PCBIOS_VOID pPoolMem) +{ + if (FnCallback.pFnFreePool != CBIOS_NULL) + { + ((CALLBACK_cbFreePool)FnCallback.pFnFreePool)(pPoolMem); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } +} + +CBIOS_U64 cb_AcquireSpinLock(PCBIOS_VOID pvSpinLock) +{ + CBIOS_U64 ret = 0; + + if (FnCallback.pFnAcquireSpinLock != CBIOS_NULL) + { + ret = ((CALLBACK_cbAcquireSpinLock)FnCallback.pFnAcquireSpinLock)(pvSpinLock); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + return ret; +} + +CBIOS_VOID cb_ReleaseSpinLock(PCBIOS_VOID pvSpinLock, CBIOS_U64 NewIrql) +{ + if (FnCallback.pFnReleaseSpinLock != CBIOS_NULL) + { + ((CALLBACK_cbReleaseSpinLock)FnCallback.pFnReleaseSpinLock)(pvSpinLock, NewIrql); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } +} + +CBIOS_VOID cb_AcquireMutex(PCBIOS_VOID pvMutex) +{ + if (FnCallback.pFnAcquireMutex != CBIOS_NULL) + { + ((CALLBACK_cbAcquireMutex)FnCallback.pFnAcquireMutex)(pvMutex); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } +} + +CBIOS_VOID cb_ReleaseMutex(PCBIOS_VOID pvMutex) +{ + if (FnCallback.pFnReleaseMutex != CBIOS_NULL) + { + ((CALLBACK_cbReleaseMutex)FnCallback.pFnReleaseMutex)(pvMutex); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } +} + +CBIOS_S32 cb_GetRegistryParameters(PCBIOS_VOID pAdapterContext, PWSTR ParameterName, CBIOS_UCHAR IsParameterFileName, PCBIOS_VOID Context) +{ + CBIOS_S32 Ret = 0; + +#ifndef __LINUX__ + if (FnCallback.pFnGetRegistryParameters != CBIOS_NULL) + { + Ret = ((CALLBACK_cbGetRegistryParameters)FnCallback.pFnGetRegistryParameters)(pAdapterContext, ParameterName,IsParameterFileName,Context); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),("cb_GetRegistryParameters is CBIOS_NULL!\n"))); + } +#endif + + return Ret; +} + +CBIOS_S32 cb_SetRegistryParameters(PCBIOS_VOID pAdapterContext, PWSTR ValueName, PCBIOS_VOID ValueData, CBIOS_U32 ValueLength) +{ + CBIOS_S32 Ret = 0; + +#ifndef __LINUX__ + if (FnCallback.pFnSetRegistryParameters != CBIOS_NULL) + { + Ret = ((CALLBACK_cbSetRegistryParameters)FnCallback.pFnSetRegistryParameters)(pAdapterContext, ValueName,ValueData,ValueLength); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),("cb_SetRegistryParameters is CBIOS_NULL!\n"))); + } +#endif + + return Ret; + +} + +CBIOS_S32 cb_strcmp(PCBIOS_UCHAR s1, const CBIOS_UCHAR* s2) +{ + CBIOS_S32 Ret = 0; + + if (FnCallback.pFnStrcmp != CBIOS_NULL) + { + //new driver has the callback function + Ret = ((CALLBACK_cbStrCmp)FnCallback.pFnStrcmp)(s1, s2); + } + else + { + //old driver has no callback function, then use standard lib function + Ret = cbstrcmp(s1, s2); + } + + return Ret; +} + +PCBIOS_CHAR cb_strcpy(PCBIOS_CHAR s1, PCBIOS_CHAR s2) +{ + PCBIOS_CHAR Ret = CBIOS_NULL; + + if (FnCallback.pFnStrcpy!= CBIOS_NULL) + { + //new driver has the callback function + Ret = ((CALLBACK_cbStrCpy)FnCallback.pFnStrcpy)(s1, s2); + } + else + { + //old driver has no callback function, then use standard lib function + Ret = cbstrcpy(s1, s2); + } + + return Ret; +} + +CBIOS_S32 cb_strncmp(PCBIOS_UCHAR s1, PCBIOS_UCHAR s2, CBIOS_U32 length) +{ + CBIOS_S32 Ret = 0; + + if (FnCallback.pFnStrncmp != CBIOS_NULL) + { + //new driver has the callback function + Ret = ((CALLBACK_cbStrNCmp)FnCallback.pFnStrncmp)(s1, s2, length); + } + else + { + //old driver has no callback function, then use standard lib function + Ret = cbstrncmp(s1, s2, length); + } + + return Ret; +} + +PCBIOS_VOID cb_memset(PCBIOS_VOID pBuf, CBIOS_S32 value, CBIOS_U32 length) +{ + PCBIOS_VOID Ret = CBIOS_NULL; + + if (FnCallback.pFnMemset != CBIOS_NULL) + { + //new driver has the callback function + Ret = ((CALLBACK_cbMemSet)FnCallback.pFnMemset)(pBuf, value, length); + } + else + { + //old driver has no callback function, then use standard lib function + Ret = cbmemset(pBuf, value, length); + } + + return Ret; +} + +PCBIOS_VOID cb_memcpy(PCBIOS_VOID pBuf1, PCBIOS_VOID pBuf2, CBIOS_U32 length) +{ + PCBIOS_VOID Ret = CBIOS_NULL; + + if (FnCallback.pFnMemcpy!= CBIOS_NULL) + { + //new driver has the callback function + Ret = ((CALLBACK_cbMemCpy)FnCallback.pFnMemcpy)(pBuf1, pBuf2, length); + } + else + { + //old driver has no callback function, then use standard lib function + Ret = cbmemcpy(pBuf1, pBuf2, length); + } + + return Ret; +} + +CBIOS_S32 cb_memcmp(PCBIOS_VOID pBuf1, PCBIOS_VOID pBuf2, CBIOS_U32 length) +{ + CBIOS_S32 Ret = 0; + + if (FnCallback.pFnMemcmp != CBIOS_NULL) + { + //new driver has the callback function + Ret = ((CALLBACK_cbMemCmp)FnCallback.pFnMemcmp)(pBuf1, pBuf2, length); + } + else + { + //old driver has no callback function, then use standard lib function + Ret = cbmemcmp(pBuf1, pBuf2, length); + } + + return Ret; +} + + +CBIOS_U64 cb_do_div(CBIOS_U64 a, CBIOS_U64 b) +{ + CBIOS_U64 Ret = 0; + + if (FnCallback.pFnDodiv != CBIOS_NULL) + + { + //new driver has the callback function + Ret = ((CALLBACK_cbDoDiv)FnCallback.pFnDodiv)(a, b); + } + else + { + Ret = cbdo_div(a, b); + } + + return Ret; +} + +CBIOS_VOID cbPrintMsgToFile(CBIOS_U32 DebugPrintLevel, PCBIOS_CHAR DebugMessage, PCBIOS_VOID pBuffer, CBIOS_U32 Size) +{ + if (FnCallback.pFnDbgPrintToFile != CBIOS_NULL) + { + ((CALLBACK_cbDbgPrintToFile)FnCallback.pFnDbgPrintToFile)(DebugPrintLevel, DebugMessage, pBuffer, Size); + } + + return; +} + +CBIOS_BOOL cbGetPlatformConfigurationU32(PCBIOS_VOID pvcbe, CBIOS_U8 *pName, CBIOS_U32 *pBuffer, CBIOS_U32 Length) +{ + + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + CBIOS_BOOL bRet = CBIOS_FALSE; + + if (FnCallback.pFnGetPlatformConfigU32 != CBIOS_NULL) + { + bRet = ((CALLBACK_cbGetPlatformConfigU32)FnCallback.pFnGetPlatformConfigU32)(pcbe->pAdapterContext, pName, pBuffer, Length); + } + else + { + bRet = CBIOS_FALSE; + } + + return bRet; +} + diff --git a/drivers/gpu/drm/arise/cbios/Callback/CBiosCallbacks.h b/drivers/gpu/drm/arise/cbios/Callback/CBiosCallbacks.h new file mode 100644 index 0000000000000..92dfbaf4a860b --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Callback/CBiosCallbacks.h @@ -0,0 +1,130 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios hw independent callback function prototype. +** +** NOTE: +** The hw dependent callback function SHOULD NOT be added to this file. +******************************************************************************/ + +#ifndef _CBIOS_CALLBACKS_H_ +#define _CBIOS_CALLBACKS_H_ + +#include "../Device/CBiosShare.h" + +#define CBIOS_DBG_PRINT 1 + +#if CBIOS_DBG_PRINT +#ifdef __LINUX__ +#define cbDebugPrint1(DebugCtlFlag, DebugMessage, args...) \ + do{ \ + CBIOS_UCHAR* pDbgBuff = cbGetDebugBuffer(DebugCtlFlag); \ + if(pDbgBuff != CBIOS_NULL && cbVsnprintf != CBIOS_NULL) \ + { \ + CBIOS_U32 preLen = cbAddPrefix(DebugCtlFlag, pDbgBuff); \ + cbVsnprintf(pDbgBuff + preLen, CBIOSDEBUGMESSAGEMAXBYTES-preLen-1, DebugMessage, ##args); \ + cbPrintWithDbgFlag(DebugCtlFlag, pDbgBuff);\ + } \ + }while(0) +#define cbDebugPrint(arg) cbDebugPrint1 arg +#else +#define cbDebugPrint(arg) cbPrintMessage arg +#endif +#else /*else DBG*/ +#define cbDebugPrint(arg) +#endif + +#ifndef WCHAR +typedef unsigned short WCHAR; // wc, 16-bit UNICODE character +typedef WCHAR *NWPSTR, *LPWSTR, *PWSTR; +#endif + +/******Call Back function *********/ +//******** Debug Print functions ******************************* +typedef CBIOS_VOID (*CALLBACK_cbDbgPrint)(CBIOS_U32 DebugPrintLevel, PCBIOS_UCHAR DebugMessage); + +//******** Get Registry Parameters ******************************** +typedef CBIOS_S32 (*CALLBACK_cbGetRegistryParameters)(PCBIOS_VOID pAdapterContext, PWSTR ParameterName, CBIOS_UCHAR IsParameterFileName, PCBIOS_VOID Context); +typedef CBIOS_S32 (*CALLBACK_cbSetRegistryParameters)(PCBIOS_VOID pAdapterContext, PWSTR ValueName, PCBIOS_VOID ValueData, CBIOS_U32 ValueLength); + +//******** time delay functions ******************************** +typedef CBIOS_VOID (*CALLBACK_cbDelayMicroSeconds)(CBIOS_U32 Microseconds); + +////////////////////////////////////////////////////////////////////////////// +typedef CBIOS_VOID (*CALLBACK_cbQuerySystemTime)(CBIOS_U64* LiTime); +///////////////////////////////////////////////////////////////////////////// +// memory allocation and free function stub +typedef PCBIOS_VOID (*CALLBACK_cbAllocateNonpagedPool)(CBIOS_U32 NumberOfBytes); +typedef PCBIOS_VOID (*CALLBACK_cbAllocatePagedPool)(CBIOS_U32 NumberOfBytes); +typedef CBIOS_VOID (*CALLBACK_cbFreePool)(PCBIOS_VOID pPoolMem); +typedef CBIOS_U64 (*CALLBACK_cbAcquireSpinLock)(PCBIOS_VOID pvSpinLock); +typedef CBIOS_VOID (*CALLBACK_cbReleaseSpinLock)(PCBIOS_VOID pvSpinLock, CBIOS_U64 IrqlStatus); +typedef CBIOS_VOID (*CALLBACK_cbAcquireMutex)(PCBIOS_VOID pvMutex); +typedef CBIOS_VOID (*CALLBACK_cbReleaseMutex)(PCBIOS_VOID pvMutex); + +//CBIOS_VOID cbQuerySystemTime(LARGE_INTEGER* LiTime); +typedef CBIOS_S32 (*CALLBACK_cbStrCmp)(PCBIOS_UCHAR s1, const CBIOS_UCHAR* s2); +typedef PCBIOS_CHAR (*CALLBACK_cbStrCpy)(PCBIOS_CHAR s1, PCBIOS_CHAR s2); +typedef CBIOS_S32 (*CALLBACK_cbStrNCmp)(PCBIOS_UCHAR s1, PCBIOS_UCHAR s2, CBIOS_U32 length); +typedef PCBIOS_VOID (*CALLBACK_cbMemSet)(PCBIOS_VOID pBuf, CBIOS_S32 value, CBIOS_U32 length); +typedef PCBIOS_VOID (*CALLBACK_cbMemCpy)(PCBIOS_VOID pBuf1, PCBIOS_VOID pBuf2, CBIOS_U32 length); +typedef CBIOS_S32 (*CALLBACK_cbMemCmp)(PCBIOS_VOID pBuf1, PCBIOS_VOID pBuf2, CBIOS_U32 length); +typedef CBIOS_U64 (*CALLBACK_cbDoDiv)(CBIOS_U64 a, CBIOS_U64 b); +#ifdef __LINUX__ +typedef CBIOS_S32 (*CALLBACK_cbVsprintf)(PCBIOS_UCHAR buf, PCBIOS_CHAR fmt, ...); +typedef CBIOS_S32 (*CALLBACK_cbVsnprintf)(PCBIOS_UCHAR buf, CBIOS_U32 size, PCBIOS_CHAR fmt, ...); +#else +typedef CBIOS_S32 (*CALLBACK_cbVsprintf)(PCBIOS_UCHAR buf, PCBIOS_CHAR fmt, va_list args); +typedef CBIOS_S32 (*CALLBACK_cbVsnprintf)(PCBIOS_UCHAR buf, CBIOS_U32 size, PCBIOS_CHAR fmt, va_list args); +#endif + +extern CALLBACK_cbVsprintf cbVsprintf; +extern CALLBACK_cbVsnprintf cbVsnprintf; + +CBIOS_STATUS cbSetCallBackFunctions(PCBIOS_CALLBACK_FUNCTIONS pFnCallBack); + +//******** Debug Print functions ******************************* +CBIOS_VOID cb_DbgPrint(CBIOS_U32 DebugPrintLevel, PCBIOS_UCHAR DebugMessage); + +//******** time delay functions ******************************** +CBIOS_VOID cb_DelayMicroSeconds(CBIOS_U32 Microseconds); + +CBIOS_U64 cb_QuerySystemTime(void); + +PCBIOS_VOID cb_AllocateNonpagedPool(CBIOS_U32 NumberOfBytes); +PCBIOS_VOID cb_AllocatePagedPool(CBIOS_U32 NumberOfBytes); +CBIOS_VOID cb_FreePool(PCBIOS_VOID pPoolMem); +CBIOS_U64 cb_AcquireSpinLock(PCBIOS_VOID pvSpinLock); +CBIOS_VOID cb_ReleaseSpinLock(PCBIOS_VOID pvSpinLock, CBIOS_U64 NewIrql); +CBIOS_VOID cb_AcquireMutex(PCBIOS_VOID pvMutex); +CBIOS_VOID cb_ReleaseMutex(PCBIOS_VOID pvMutex); + +//******** Get Registry Parameters ******************************** +CBIOS_S32 cb_GetRegistryParameters(PCBIOS_VOID pAdapterContext, PWSTR ParameterName, CBIOS_UCHAR IsParameterFileName, PCBIOS_VOID Context); +CBIOS_S32 cb_SetRegistryParameters(PCBIOS_VOID pAdapterContext, PWSTR ValueName, PCBIOS_VOID ValueData, CBIOS_U32 ValueLength); + +CBIOS_S32 cb_strcmp(PCBIOS_UCHAR s1, const CBIOS_UCHAR* s2); +PCBIOS_CHAR cb_strcpy(PCBIOS_CHAR s1, PCBIOS_CHAR s2); +CBIOS_S32 cb_strncmp(PCBIOS_UCHAR s1, PCBIOS_UCHAR s2, CBIOS_U32 length); +PCBIOS_VOID cb_memset(PCBIOS_VOID pBuf, CBIOS_S32 value, CBIOS_U32 length); +PCBIOS_VOID cb_memcpy(PCBIOS_VOID pBuf1, PCBIOS_VOID pBuf2, CBIOS_U32 length); +CBIOS_S32 cb_memcmp(PCBIOS_VOID pBuf1, PCBIOS_VOID pBuf2, CBIOS_U32 length); +CBIOS_U64 cb_do_div(CBIOS_U64 a, CBIOS_U64 b); +CBIOS_VOID cbPrintMsgToFile(CBIOS_U32 DebugPrintLevel, PCBIOS_CHAR DebugMessage, PCBIOS_VOID pBuffer, CBIOS_U32 Size); +CBIOS_BOOL cbGetPlatformConfigurationU32(PCBIOS_VOID pvcbe, CBIOS_U8 *pName, CBIOS_U32 *pBuffer, CBIOS_U32 Length); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Device/CBIOSVER.H b/drivers/gpu/drm/arise/cbios/Device/CBIOSVER.H new file mode 100755 index 0000000000000..ba3661170da3e --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/CBIOSVER.H @@ -0,0 +1,85 @@ +/* +* Copyright 2019-2020 Shanghai Zhaoxin Semiconductor Co., Ltd. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sub license, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial portions +* of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +* THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + + +// +// ZXG_MAJOR_VERSION and ZXG_MINOR_VERSION are used to define DRIVER_VERSION +// which is used in the .rc files. +// +// Please keep the ZXG_MINOR_VERSION to 4 decimal digits +// +// +// DX_DRIVER_PREFIX_VERSION is the number specified in the DriverVer +// directive of the .INF file, and indicates operating system and +// the driver's level of DirectX support. E.g. 5.12.01.xxxx is an +// NT5 (Win2000) DX7 driver. The last four digits are for driver use. +// The entire number (DX prefix + driver number) must be unique among +// WHQL submissions. +// + +// +// WARNING: Do NOT use leading zeroes in the ZXG_MINOR_VERSION_NUM! +// Or you'll find that '08' gets treated as an octal signal! +// + + +#define CBIOS_VERSION_MAJOR 10 /* Branch CBios code */ +#define CBIOS_VERSION_BRANCH 17 /* Big change such as structure modification */ +#define CBIOS_VERSION_FEATURE 22 /* Version Number High Byte */ +#define CBIOS_VERSION_MINOR 0000 /* Version Number Low Byte */ +#define CBIOS_PREFIX_VERSION_STR "10.17.22.0000" +#define CBIOS_INTERNAL_PRODUCTVERSION_STR "42.00.00.00" + + +#define CBIOS_PREFIX_VERSION CBIOS_VERSION_MAJOR,CBIOS_VERSION_BRANCH,CBIOS_VERSION_FEATURE,CBIOS_VERSION_MINOR + + +// +// These undefines are used to replace with ZXG version specific definitions +// below, or in the modules that include this header file. +// +#undef VER_PRODUCTNAME_STR +#undef VER_COMPANYNAME_STR +#undef VER_PRODUCTVERSION +#undef VER_PRODUCTVERSION_STR + +#define VER_LEGALCOPYRIGHT_YEARS "2024" +#define VER_LEGALCOPYRIGHT_STR VER_LEGALCOPYRIGHT_YEARS " " VER_COMPANYNAME_STR + +#define VER_COMPANYNAME_STR "Glenfly Tech Co., Ltd." +#define CBIOS_EXPORT_DRIVER_FILEDESC_STR L"Glenfly CBIOS Export Driver" + +#ifndef __LINUX__ + #if defined (_WIN64) + #define CBIOS_EXPORT_DRIVER_NAME L"arisebios_64.sys" + #else + #define CBIOS_EXPORT_DRIVER_NAME L"arisebios_32.sys" + #endif +#endif + +#define VER_PRODUCTVERSION CBIOS_PREFIX_VERSION +#define VER_FILEVERSION_STR CBIOS_PREFIX_VERSION_STR +#define VER_PRODUCTVERSION_STR CBIOS_PREFIX_VERSION_STR "-" CBIOS_INTERNAL_PRODUCTVERSION_STR + +#define VER_PRODUCTNAME_STR CBIOS_EXPORT_DRIVER_NAME + diff --git a/drivers/gpu/drm/arise/cbios/Device/CBiosChipShare.h b/drivers/gpu/drm/arise/cbios/Device/CBiosChipShare.h new file mode 100644 index 0000000000000..17e4e908ca2b6 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/CBiosChipShare.h @@ -0,0 +1,291 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios function prototypes in Init/Utility files +** Defines CBIOS_EXTENSION_COMMON and VCP_INFO +** Defines macro for sharing used. +** +** NOTE: +** The sharing used structure is SUGGESTED to be add to CBiosTypes.h +******************************************************************************/ + +#ifndef _CBIOS_CHIPSHARE_H_ +#define _CBIOS_CHIPSHARE_H_ + +#include "CBiosTypes.h" +#include "CBiosShare.h" +#include "CBiosReg.h" +#include "../Callback/CBiosCallbacks.h" +#include "../Display/CBiosDisplayManager.h" +#include "../Display/CBiosPathManager.h" +#include "../Util/CBiosEDID.h" +#include "CBiosDevice.h" +#include "Port/CBiosDVO.h" +#include "Monitor/CBiosHDMIMonitor.h" +#include "Monitor/CBiosDPMonitor.h" +#include "CBiosCompile.h" +#include "Port/CBiosDSI.h" +#include "Port/CBiosCRT.h" +#include "Port/CBiosDP.h" +#include "../Hw/HwInterface/CBiosHwInterface.h" +#include "../Hw/HwBlock/CBiosDIU_CSC.h" + + +#define CBIOS_NOIGAENCODERINDEX 0xFF + +// I2C +#define I2C_DELAY_DEFAULT 20 //default I2C delay time, 8us, I2C speed up to 125kbps +#define I2CBUSMASK 0x07 +#define I2CBUS_INVALID 0xFF + + +//for Debug Chip Enable/Disable +#define CHECK_CHIPENABLE 1 + +//for HPD +#define HPDPORT_MASK 0x07 +#define CBIOS_ANALOG_HPD_VIRTUAL_GPIO 10 + +// for invalid GPIO +#define INVALID_GPIO 0x07 + +// clock reference frequency +#define RefFreq24 240000 +#define RefFreq27 270000 + +#define ZXG_POST_TYPE_MASK 0x7F +#define MAPMASK_EXIT 0xE000 + +// the max size of data dump to log file +#define CBIOS_MAX_DUMP_DATA_SIZE 2 * 1024 + +// VCP define +#define VCP_OFFSET 0x30 +#define VCP_TAG 0x66BB +#define VBIOS_IMAGE_SIZE 0x10000 + +// for memory type definition +#define Default_Mem_Type 0x00 + +// MACRO for set mode invalid flags +#define SKIP_MODE_REG_SETTING 0x8000 + +#define AUTO_TIMING_PAL 20 +#define AUTO_TIMING_NTSC 21 + +// For calculate the mode timing according to CVT algrithm +#define CPRIME 30 +#define CLOCKSTEP 25 /* Muliplied by 100 */ +#define HSYNCPERCENT 8 +#define MPRIME 300 +#define MINVFPORCH 3 +#define MINVBPORCH 6 +#define MINVBLANKINGPERIOD 550 /* unit is us */ +#define CELLGRAN 8 + +#define SEQREGSNUM 256 +#define CRTCREGSNUM 256 + +// callback return status +#define NO_ERROR 0L // dderror +#define ERROR_INVALID_PARAMETER 87L // dderror + +// H/V sync Polarity +#define HorNEGATIVE 0x40 +#define HorPOSITIVE 0x00 +#define VerNEGATIVE 0x80 +#define VerPOSITIVE 0x00 + +// Hotplug port, defined in CBIOS. +#define CBIOS_GPIO0 0 +#define CBIOS_GPIO1 1 +#define CBIOS_GPIO2 2 +#define CBIOS_GPIO3 3 +#define CBIOS_GPIO4 4 +#define CBIOS_GPIO5 5 + +// MM8504's interrupt bits +#define CBIOS_GPIO0_BIT_MASK (BIT18) +#define CBIOS_GPIO1_BIT_MASK (BIT21) + +// MM8504's interrupt bits +#define CBIOS_GPIO3_BIT_MASK (BIT20) +#define CBIOS_GPIO4_BIT_MASK (BIT19) + +#define cb_max(a,b) (((a) > (b)) ? (a) : (b)) +#define cb_min(a,b) (((a) < (b)) ? (a) : (b)) + +#define IS_ONE_BIT(N) ((((N)-1)&(N))==0) +#define GET_LAST_BIT(N) ((~((N)-1))&(N)) + +typedef struct _CBIOS_HDMI_FORMAT_MTX +{ + CBIOS_U16 FormatNum; + CBIOS_U16 XRes; + CBIOS_U16 YRes; + CBIOS_UCHAR Interlace; + CBIOS_U16 RefRate[2]; + CBIOS_UCHAR AspectRatio; + CBIOS_UCHAR DefaultRefRateIndex; + CBIOS_U32 PixelClock; + /*CBIOS_U32 IsRealHDMIDevice; */ /* Evevy bit relate with device bit is used to judge if it a read HDMI device.*/ +}CBIOS_HDMI_FORMAT_MTX, *PCBIOS_HDMI_FORMAT_MTX; + +typedef struct _CBIOS_EXTENSION_COMMON +{ + /* driver&hardware info */ + PCBIOS_VOID pAdapterContext; + CBIOS_S32 bMAMMPrimaryAdapter; + CBIOS_U32 PCIDeviceID; + CBIOS_U32 ChipID; + CBIOS_U32 ChipRevision; + CBIOS_BOARD_VERSION BoardVersion; + + CBIOS_U32 bRunOnQT; + CBIOS_U32 bDriverLoadQTiming; + //--------------------------------------------------- + // CBIOS Chip Related Speciality + //-------------------------------------------------- + struct { + CBIOS_U32 bNoMemoryControl :1; + CBIOS_U32 IsSupportUpScaling :1; + CBIOS_U32 Is24MReferenceClock :1; + CBIOS_U32 IsSupport3DVideo :1; + CBIOS_U32 IsSupportDeepColor :1; + CBIOS_U32 IsSupportCEC :1; + CBIOS_U32 bSupportConfigEclkByEfuse :1; + CBIOS_U32 bSupportScrambling :1; //HDMI scrambling + CBIOS_U32 bSupportReadRequest :1; //HDMI read request + CBIOS_U32 reserved :23; + } ChipCaps; + struct { + //for scaler + //upscaler + CBIOS_U32 ulMaxPUHorSrc; + CBIOS_U32 ulMaxPUHorDst; + CBIOS_U32 ulMaxPUVerSrc; + CBIOS_U32 ulMaxPUVerDst; + //HDMI + CBIOS_U32 ulMaxHDMIClock; + //MHL + CBIOS_U32 ulMaxMHLClock; + CBIOS_U32 ulMaxIGAClock; + }ChipLimits; + + /* from VCP */ + CBIOS_BOOL bUseVCP; //whether we use VCP or not + CBIOS_U32 BiosVersion; + CBIOS_U32 EClock; + CBIOS_U32 EVcoLow; + CBIOS_U32 DVcoLow; + CBIOS_U32 sizeofBootDevPriority; + PCBIOS_U16 pBootDevPriority; + CBIOS_FEATURE_SWITCH FeatureSwitch; + + CBIOS_UCHAR PMPVer[64]; + CBIOS_U8 SliceNum; + CBIOS_U32 FwVersion; + CBIOS_UCHAR FwName[10]; + + /* data tables */ + PCBIOS_HDMI_FORMAT_MTX pHDMIFormatTable; + CBIOS_BOOL* pHDMISupportedFormatTable; + + CBIOS_UCHAR SavedReg[128]; + + CBIOS_POST_REGISTER_TABLE PostRegTable[POST_TABLE_MAX]; + CBIOS_POST_TABLE_TYPE PostTableId; + + PCBIOS_VOID pSpinLock; + + PCBIOS_VOID pAuxMutex; + + PCBIOS_VOID pI2CMutex[CBIOS_MAX_I2CBUS]; + + CBIOS_U32 HPDDeviceMasks; + + CBiosSpecifyDstTimingSrc SpecifyDestTimingSrc[CBIOS_IGACOUNTS]; + + CBIOS_U32 CbiosFlags; + + Shadow_Info SysBiosInfo; + + CBIOS_UCHAR EdidFromRegistry[CBIOS_EDIDDATABYTE]; + CBIOS_ACTIVE_TYPE DevicesHardcodedEdid; + CBIOS_U8 MemoryType; + + CBIOS_U32 PortSplitSupport;//bit definition is the same as CBIOS_ACTIVE_TYPE, + //:corresponding device port can be split + //0: corresponding device port can not be split + + CBIOS_BOOL bFilterUnsupportedModeFunction; + CBIOS_U8 FilterUnsupportedModeCount; + + CBIOS_U8 I2CDelay; + + CBIOS_CHIP_FUNC_TABLE ChipFuncTbl; + + //For CEC + CBIOS_CEC_PARA CECPara[CBIOS_CEC_INDEX_COUNT]; + + // Buffer for debug data dump to a log file + CBIOS_U32 DbgDataToFile[CBIOS_MAX_DUMP_DATA_SIZE]; + + // Flag to indicate whether use default VCP data or the VCP get from uboot + CBIOS_BOOL bUseDefaultVCP; + + CBIOS_U32 RomImageLength; + + CBIOS_DEVICE_MANAGER DeviceMgr; + + CBIOS_DISPLAY_MANAGER DispMgr; + +} CBIOS_EXTENSION_COMMON, *PCBIOS_EXTENSION_COMMON; + + +//************************* CBios sw utility functions ***************************// +CBIOS_BOOL cbCalcCustomizedTiming(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 XRes, CBIOS_U32 YRes, CBIOS_U32 RefreshRate, PCBIOS_TIMING_ATTRIB pTimingReg); +CBIOS_VOID cbConvertEdidTimingToTableTiming(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODE_INFO_EXT* pEDIDDetailTiming, PCBIOS_TIMING_ATTRIB pTimingReg); +CBIOS_U32 cbConvertCBiosDevBit2VBiosDevBit(CBIOS_U32 CBiosDevices); +CBIOS_U32 cbConvertVBiosDevBit2CBiosDevBit(CBIOS_U32 VBiosDevices); +CBIOS_U16 cbCalcRefreshRate(CBIOS_U32 PixelClock, CBIOS_U16 HActive, CBIOS_U16 HBlank, CBIOS_U16 VActive, CBIOS_U16 VBlank); +CBIOS_U32 cbGetHwDacMode(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_FORMAT Format); +CBIOS_U32 cbGetHw3DVideoMode(CBIOS_3D_STRUCTURE VideoFormat); +CBIOS_VOID cbGetStreamAttribute(PCBIOS_STREAM_ATTRIBUTE pStreamAttr); +CBIOS_VOID cbMulti_Matrix_CSC(CBIOS_S64 Multi_A[][3],CBIOS_S64 Multi_B[][3],CBIOS_S64 Multi_C[][3]); +CBIOS_U32 cbTran_CSCm_to_coef_fx(CBIOS_S64 coefX); +CBIOS_BOOL cbGetCscCoefMatrix(PCBIOS_CSC_ADJUST_PARA pAdajust,CBIOS_U32 informat, CBIOS_U32 outformat,CBIOS_S64 CSCm[][3]); +CBIOS_U32 cbGetHwColorKey(PCBIOS_OVERLAY_INFO pOverlayInfo, PCBIOS_U8 pKs, PCBIOS_U8 pKp); +CBIOS_BOOL cbCECAllocateLogicalAddr(PCBIOS_VOID pvcbe, CBIOS_CEC_INDEX CECIndex); +CBIOS_U32 cbConvertDeviceBit2Index(CBIOS_U32 DeviceBit); +CBIOS_U8 cbGetBitsNum(CBIOS_U32 N); +CBIOS_U32 cbGetLastBitIndex(CBIOS_U32 i); +CBIOS_VOID cbDumpBuffer(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 Buffer[], CBIOS_U32 ulLen); +CBIOS_BOOL cbIsSameMonitor(CBIOS_U8 *pCurDeviceEDID, CBIOS_U8 *pMonitorID); +CBIOS_BOOL cbPrintU8String(CBIOS_U8 *Src,CBIOS_U32 Len,CBIOS_U16 Start); +CBIOS_BOOL cbPrintU32String(CBIOS_U32 *Src,CBIOS_U32 Len,CBIOS_U16 Start); +CBIOS_VOID cbDbgPrintNull(CBIOS_U32 DebugPrintLevel, PCBIOS_CHAR DebugMessage, ...); +CBIOS_STATUS cbGetVersion(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_VERSION pCbiosVersion); +CBIOS_BOOL cbGetFakeEdidFlag(PCBIOS_VOID pvcbe); +//************************* End sw utility functions ***************************// + + +//************************* CBios sw Init functions ***************************// +CBIOS_BOOL cbInitialize(PCBIOS_VOID pvcbe, PCBIOS_PARAM_INIT pCBParamInit); +//************************* End sw Init functions ***************************// + +#endif //_CBIOS_CHIPSHARE_H_ diff --git a/drivers/gpu/drm/arise/cbios/Device/CBiosCompile.h b/drivers/gpu/drm/arise/cbios/Device/CBiosCompile.h new file mode 100644 index 0000000000000..7851ca1b1c940 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/CBiosCompile.h @@ -0,0 +1,33 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + + +/***************************************************************************** +** DESCRIPTION: +** CBios compile switch for some monitor, port or feature supported. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_COMPILE_H_ +#define _CBIOS_COMPILE_H_ + +#define LCD_MONITOR_SUPPORT 1 +#define DP_MONITOR_SUPPORT 1 +#define DVO_PORT_SUPPORT 1 +#define HDCP_ENABLE 1 + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Device/CBiosDevice.c b/drivers/gpu/drm/arise/cbios/Device/CBiosDevice.c new file mode 100644 index 0000000000000..299da5aea8f81 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/CBiosDevice.c @@ -0,0 +1,919 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios general device port functions. Call different port or monitor interface. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "../Hw/HwBlock/CBiosDIU_DP.h" +#include "../Hw/HwBlock/CBiosDIU_HDAC.h" +#include "../Hw/HwBlock/CBiosDIU_HDCP.h" + +static CBIOS_U32 DevPriorityTbl[]= +{ + CBIOS_TYPE_DP1, + CBIOS_TYPE_DP2, + CBIOS_TYPE_DP3, + CBIOS_TYPE_DP4, + CBIOS_TYPE_DVO, + CBIOS_TYPE_CRT, +}; + +CBIOS_VOID cbDevDeviceHwInit(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + if (pDevCommon->pfncbDeviceHwInit) + { + pDevCommon->pfncbDeviceHwInit(pcbe, pDevCommon); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "%s: current device: 0x%x has no hw init func.\n", FUNCTION_NAME, pDevCommon->DeviceType)); + } +} + +CBIOS_VOID cbInitDeviceArray(PCBIOS_VOID pvcbe, PVCP_INFO pVCP) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 TmpDev = pcbe->DeviceMgr.SupportDevices; + CBIOS_ACTIVE_TYPE CurDevice = CBIOS_TYPE_NONE; + PCBIOS_DEVICE_COMMON *ppDeviceCommon = CBIOS_NULL; + + while (TmpDev) + { + CurDevice = GET_LAST_BIT(TmpDev); + ppDeviceCommon = &(cbGetDeviceCommon(&pcbe->DeviceMgr, CurDevice)); + + switch (CurDevice) + { + case CBIOS_TYPE_CRT: + *ppDeviceCommon = cbCRTPort_Init(pcbe, pVCP, CBIOS_TYPE_CRT); + break; + case CBIOS_TYPE_DVO: + *ppDeviceCommon = cbDVOPort_Init(pcbe, pVCP, CBIOS_TYPE_DVO); + break; + case CBIOS_TYPE_DP1: + case CBIOS_TYPE_DP2: + case CBIOS_TYPE_DP3: + case CBIOS_TYPE_DP4: + *ppDeviceCommon = cbDPPort_Init(pcbe, pVCP, CurDevice); + break; + default: + break; + } + + TmpDev &= (~CurDevice); + } +} + +CBIOS_VOID cbDeInitDeviceArray(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_ACTIVE_TYPE CurDevice = CBIOS_TYPE_NONE; + CBIOS_U32 i = 0; + + for (i = 0; i < CBIOS_MAX_DISPLAY_DEVICES_NUM; i++) + { + if (pcbe->DeviceMgr.pDeviceArray[i] != CBIOS_NULL) + { + CurDevice = pcbe->DeviceMgr.pDeviceArray[i]->DeviceType; + switch (CurDevice) + { + case CBIOS_TYPE_CRT: + cbCRTPort_DeInit(pcbe, pcbe->DeviceMgr.pDeviceArray[i]); + break; + case CBIOS_TYPE_DVO: + cbDVOPort_DeInit(pcbe, pcbe->DeviceMgr.pDeviceArray[i]); + break; + case CBIOS_TYPE_DP1: + case CBIOS_TYPE_DP2: + case CBIOS_TYPE_DP3: + case CBIOS_TYPE_DP4: + cbDPPort_DeInit(pcbe, pcbe->DeviceMgr.pDeviceArray[i]); + break; + default: + break; + } + + pcbe->DeviceMgr.pDeviceArray[i] = CBIOS_NULL; + } + } +} + +CBIOS_U32 cbDevGetPrimaryDevice(CBIOS_U32 Device) +{ + CBIOS_U8 NumOfBit1; + CBIOS_U32 i; + + NumOfBit1 = cbGetBitsNum(Device); + if(NumOfBit1 == 1) //only one device + { + return Device; + } + else if(NumOfBit1 >= 2) //two devices + { + for(i = 0; i < sizeofarray(DevPriorityTbl); i++) + { + if(Device & DevPriorityTbl[i]) + { + return DevPriorityTbl[i]; + } + } + } + + return 0; +} + +CBIOS_VOID cbDevUpdateDeviceModeInfo(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + if (pDevCommon->pfncbUpdateDeviceModeInfo) + { + pDevCommon->pfncbUpdateDeviceModeInfo(pcbe, pDevCommon, pModeParams); + } +} + +CBIOS_VOID cbDevSetModeToDevice(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + if (pDevCommon->pfncbDeviceSetMode) + { + pDevCommon->pfncbDeviceSetMode(pcbe, pDevCommon, pModeParams); + } +} + +CBIOS_STATUS cbDevGetModeTiming(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_GET_MODE_TIMING_PARAM pGetModeTiming) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBiosDestModeParams pDestModeParams = CBIOS_NULL; + PCBIOS_TIMING_ATTRIB pTiming = CBIOS_NULL; + CBIOS_STATUS Status = CBIOS_ER_INTERNAL; + + if(CBIOS_NULL == pGetModeTiming) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pGetModeTiming is CBIOS_NULL!\n", FUNCTION_NAME)); + Status = CBIOS_ER_NULLPOINTER; + goto END; + } + pTiming = pGetModeTiming->pTiming; + if(CBIOS_NULL == pGetModeTiming->pMode || CBIOS_NULL == pGetModeTiming->pTiming) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pGetModeTiming->pMode or pGetModeTiming->pTiming is CBIOS_NULL!\n", FUNCTION_NAME)); + Status = CBIOS_ER_INVALID_PARAMETER; + goto END; + } + + pDestModeParams = cb_AllocatePagedPool(sizeof(CBiosDestModeParams)); + if(CBIOS_NULL == pDestModeParams) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: Allocat pDestModeParams fail!\n", FUNCTION_NAME)); + Status = CBIOS_ER_INTERNAL; + goto END; + } + + cb_memset(pTiming, 0, sizeof(CBIOS_TIMING_ATTRIB)); + + // 1. cbMode_GetHVTiming only use XRes, YRes, InterlaceFlag and RefreshRate to look for the detail timing. + // Therefore we init others items to 0 + pDestModeParams->Size = sizeof(CBiosDestModeParams); + pDestModeParams->XRes = pGetModeTiming->pMode->XRes; + pDestModeParams->YRes = pGetModeTiming->pMode->YRes; + pDestModeParams->RefreshRate = pGetModeTiming->pMode->RefreshRate; + pDestModeParams->InterlaceFlag = (pGetModeTiming->pMode->InterlaceProgressiveCaps & 0x2) ? 1 : 0; + + // 2. Get detail timing + cbMode_GetHVTiming(pcbe, + pDestModeParams->XRes, + pDestModeParams->YRes, + pDestModeParams->RefreshRate, + pDestModeParams->InterlaceFlag, + pGetModeTiming->DeviceId, + pTiming); + + Status = CBIOS_OK; + +END: + if(pDestModeParams != CBIOS_NULL) + { + cb_FreePool(pDestModeParams); + pDestModeParams = CBIOS_NULL; + } + + return Status; +} + +CBIOS_STATUS cbDevGetModeFromReg(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_GETTING_MODE_PARAMS pModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS csRet = CBIOS_OK; + CBIOS_U32 IGAIndex = IGA1; + CBIOS_TIMING_ATTRIB timing_reg = {0}; + CBIOS_TIMING_FLAGS flags = {0}; + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + { + csRet = CBIOS_ER_CHIPDISABLE; + return csRet; + } +#endif + + cbGetModeInfoFromReg(pcbe, pModeParams->Device, &timing_reg, &flags, IGAIndex, TIMING_REG_TYPE_CR); + + pModeParams->IGAIndex = IGAIndex; + pModeParams->DestModeParams.XRes = timing_reg.XRes; + pModeParams->DestModeParams.YRes = timing_reg.YRes; + pModeParams->DestModeParams.RefreshRate = timing_reg.RefreshRate; + pModeParams->DestModeParams.InterlaceFlag = (flags.IsInterlace == 0) ? 0 : 1; + + cb_memcpy(&(pModeParams->DetailedTiming), &timing_reg, sizeof(CBIOS_TIMING_ATTRIB)); + return csRet; +} + +CBIOS_U32 cbDevNonDestructiveDeviceDetectByEdid(PCBIOS_VOID pvcbe, PCBIOS_UCHAR pEDIDData, CBIOS_U32 EdidBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 DeviceSupported, Devices = 0; + CBIOS_ACTIVE_TYPE DeviceType = CBIOS_TYPE_NONE; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + DeviceSupported = pcbe->DeviceMgr.SupportDevices; + + if (DeviceSupported & CBIOS_TYPE_CRT) + { + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_CRT); + + if ((*(pEDIDData+EDID_VIDEO_INPUT_DEF_BYTE_OFFSET)) & EDID_VIDEO_INPUT_DEF_DIGITAL) + { + pDevCommon->CurrentMonitorType &= ~CBIOS_MONITOR_TYPE_CRT; + cb_memset(pDevCommon->EdidData, 0, CBIOS_EDIDDATABYTE); + pDevCommon->isFakeEdid = CBIOS_FALSE; + } + else + { + cb_memcpy(pDevCommon->EdidData, pEDIDData, EdidBufferSize); + Devices |= CBIOS_TYPE_CRT; + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_CRT; + pDevCommon->DeviceType = CBIOS_TYPE_CRT; + pDevCommon->isFakeEdid = CBIOS_TRUE; + } + } + + if (DeviceSupported & CBIOS_TYPE_MHL) + { + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_MHL); + + cb_memcpy(pDevCommon->EdidData, pEDIDData, EdidBufferSize); + Devices |= CBIOS_TYPE_MHL; + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_MHL; + pDevCommon->DeviceType = CBIOS_TYPE_MHL; + pDevCommon->isFakeEdid = CBIOS_TRUE; + } + + if (DeviceSupported & CBIOS_TYPE_DVO) + { + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DVO); + DeviceType = CBIOS_TYPE_DVO; + + if (!((*(pEDIDData+EDID_VIDEO_INPUT_DEF_BYTE_OFFSET)) & EDID_VIDEO_INPUT_DEF_DIGITAL)) + { + //analog monitor, reset buffers + pDevCommon->CurrentMonitorType &= (~(CBIOS_MONITOR_TYPE_DVI | CBIOS_MONITOR_TYPE_HDMI)); + cb_memset(pDevCommon->EdidData, 0, CBIOS_EDIDDATABYTE); + pDevCommon->isFakeEdid = CBIOS_FALSE; + } + else + { + cb_memcpy(pDevCommon->EdidData, pEDIDData, EdidBufferSize); + if (pDevCommon->EdidStruct.Attribute.IsCEA861HDMI) + { + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_HDMI; + } + else + { + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_DVI; + } + + //update monitor type + if (!(pDevCommon->CurrentMonitorType & cbGetSupportMonitorType(pcbe, DeviceType))) + { + pDevCommon->CurrentMonitorType = cbGetSupportMonitorType(pcbe, DeviceType); + } + + pDevCommon->DeviceType = CBIOS_TYPE_DVO; + pDevCommon->isFakeEdid = CBIOS_TRUE; + + Devices |= DeviceType; + } + } + + if(Devices == 0) + { + // Clear signature to make sure IsDeviceChanged return CBIOS_TRUE if a device with EDID is connected. + cb_memset(&pDevCommon->ConnectedDevSignature, 0, sizeof(CBIOS_DEVICE_SIGNATURE)); + } + + return Devices; +} + +CBIOS_BOOL cbDevDeviceDetect(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bHardcodeDetect, CBIOS_U32 FullDetect) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bConnected = CBIOS_FALSE; + + if (!pDevCommon->pfncbDeviceDetect) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "%s: current device: 0x%x has no detect func.\n", FUNCTION_NAME, pDevCommon->DeviceType)); + } + else + { + bConnected = pDevCommon->pfncbDeviceDetect(pcbe, pDevCommon, bHardcodeDetect, FullDetect); + } + + return bConnected; +} + +CBIOS_STATUS cbDevGetEdidFromBuffer(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_PARAM_GET_EDID pCBParamGetEdid) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8* EdidBuffer = CBIOS_NULL, *pEdidData = CBIOS_NULL; + CBIOS_U32 CopySize = 0, EdidSize = 0; + CBIOS_STATUS bRetStatus = CBIOS_ER_INTERNAL; + CBIOS_ACTIVE_TYPE Device = pCBParamGetEdid->DeviceId; + + CopySize = pCBParamGetEdid->EdidBufferLen; + EdidBuffer = pCBParamGetEdid->EdidBuffer; + + //check hardcoded EDID + if (pcbe->DevicesHardcodedEdid & Device) + { + pEdidData = pcbe->EdidFromRegistry; + EdidSize = CBIOS_EDIDDATABYTE; + } + //not hardcoded, get EDID from buffer, do not read EDID again to prevent I2C bus re-enter + else + { + pEdidData = pDevCommon->EdidData; + EdidSize = CBIOS_EDIDDATABYTE; + } + + if(cbEDIDModule_IsEDIDValid(pEdidData) && CopySize <= EdidSize) + { + cb_memcpy(EdidBuffer, pEdidData, CopySize); + bRetStatus = CBIOS_OK; + } + else + { + bRetStatus = CBIOS_ER_EDID_INVALID; + if(pDevCommon->DeviceType != CBIOS_TYPE_CRT) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "Can't get valid EDID for device 0x%x!\n", pDevCommon->DeviceType)); + } + } + + return bRetStatus; +} + +CBIOS_STATUS cbDevSetEdid(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_PARAM_SET_EDID pCBParamSetEdid) +{ + PCBIOS_UCHAR pEDIDData = CBIOS_NULL; + CBIOS_STATUS status = CBIOS_OK; + + pEDIDData = pDevCommon->EdidData; + + // When the EdidBuffer == NULL, we unlock the Edid buffer in CBIOS + if((pCBParamSetEdid->EdidBuffer == CBIOS_NULL) || (pCBParamSetEdid->EdidBufferLen == 0)) + { + cb_memset(pEDIDData, 0, CBIOS_EDIDDATABYTE); + cb_memset(&(pDevCommon->ConnectedDevSignature), 0, sizeof(CBIOS_DEVICE_SIGNATURE)); + pDevCommon->isFakeEdid = CBIOS_FALSE; + return CBIOS_OK; + } + + if(pCBParamSetEdid->EdidBufferLen <= CBIOS_EDIDDATABYTE) + { + if(!cbEDIDModule_IsEDIDValid(pCBParamSetEdid->EdidBuffer)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: EDID is invalid\n", FUNCTION_NAME)); + status = CBIOS_ER_INVALID_PARAMETER; + } + else + { + cb_memset(pEDIDData, 0, CBIOS_EDIDDATABYTE); + cb_memset(&(pDevCommon->ConnectedDevSignature), 0, sizeof(CBIOS_DEVICE_SIGNATURE)); + + cb_memcpy(pEDIDData, pCBParamSetEdid->EdidBuffer, pCBParamSetEdid->EdidBufferLen); + pDevCommon->isFakeEdid = CBIOS_TRUE; + } + } + else + { + status = CBIOS_ER_INVALID_PARAMETER; + } + + return status; +} + +CBIOS_STATUS cbDevGetSupportedMonitorType(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_QUERY_MONITOR_TYPE_PER_PORT pCBiosQueryMonitorTypePerPort) +{ + if(pCBiosQueryMonitorTypePerPort->bConnected) + { + pCBiosQueryMonitorTypePerPort->MonitorType = pDevCommon->CurrentMonitorType; + } + else + { + pCBiosQueryMonitorTypePerPort->MonitorType = pDevCommon->SupportMonitorType; + } + return CBIOS_OK; +} + +CBIOS_STATUS cbDevQueryMonitorAttribute(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBiosMonitorAttribute pMonitorAttribute) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + /* + ** 1. get basic monitor attributes + */ + pMonitorAttribute->MonitorType = pDevCommon->CurrentMonitorType; + pMonitorAttribute->MonitorCaps = pDevCommon->EdidStruct.Attribute.CEA861MonitorCaps; + pMonitorAttribute->bSupportBLCtrl = CBIOS_FALSE; + pMonitorAttribute->bSupportHDAudio = pDevCommon->EdidStruct.Attribute.IsCEA861Audio; +#ifndef __LINUX__ + // if Arise10C0, force to set bSupportHDAudio = 0 in windows + if((pcbe->ChipID == CHIPID_E3K) || (pcbe->ChipID == CHIPID_ARISE10C0T)) + { + pMonitorAttribute->bSupportHDAudio = CBIOS_FALSE; + } +#endif + pMonitorAttribute->SupportBPC.IsSupport8BPC = CBIOS_TRUE; + // get monitor screen image size + pMonitorAttribute->MonitorHorSize = pDevCommon->EdidStruct.Attribute.MonitorHorSize; + pMonitorAttribute->MonitorVerSize = pDevCommon->EdidStruct.Attribute.MonitorVerSize; + if (cbEDIDModule_IsEDIDValid(pDevCommon->EdidData)) + { + cbEDIDModule_GetMonitorID(pDevCommon->EdidData, pMonitorAttribute->MonitorID); + } + + /* + ** 2. get special monitor attributes + */ + if (pDevCommon->pfncbQueryMonitorAttribute) + { + pDevCommon->pfncbQueryMonitorAttribute(pcbe, pDevCommon, pMonitorAttribute); + } + return CBIOS_OK; +} + +CBIOS_STATUS cbDevQueryMonitor3DCapability(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_MONITOR_3D_CAPABILITY_PARA p3DCapability) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Status = CBIOS_OK; + + Status = cbEDIDModule_GetMonitor3DCaps(&(pDevCommon->EdidStruct), p3DCapability, pcbe->ChipCaps.IsSupport3DVideo); + return Status; +} + +CBIOS_STATUS cbGetDeviceName(PCBIOS_VOID pvcbe, PCBIOS_GET_DEVICE_NAME pGetName) +{ + CBIOS_U32 Status = CBIOS_OK; + CBIOS_ACTIVE_TYPE DeviceType = (CBIOS_ACTIVE_TYPE)pGetName->DeviceId; + + switch(DeviceType) + { + case CBIOS_TYPE_CRT: + pGetName->pDeviceName = "CRT1"; + break; + case CBIOS_TYPE_TV: + pGetName->pDeviceName = "TV"; + break; + case CBIOS_TYPE_HDTV: + pGetName->pDeviceName = "HDTV"; + break; + case CBIOS_TYPE_DP1: + pGetName->pDeviceName = "DP1"; + break; + case CBIOS_TYPE_DP2: + pGetName->pDeviceName = "DP2"; + break; + case CBIOS_TYPE_DP3: + pGetName->pDeviceName = "DP3"; + break; + case CBIOS_TYPE_DP4: + pGetName->pDeviceName = "DP4"; + break; + case CBIOS_TYPE_DVO: + pGetName->pDeviceName = "DVO"; + break; + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "Invalid device type 0x%x in query name.\n", DeviceType)); + pGetName->pDeviceName = "NONE"; + break; + } + + return Status; +} + +CBIOS_STATUS cbDevGetDeviceModeList(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBiosModeInfoExt pModeList, CBIOS_U32 *pBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 ulModeNum; + CBIOS_MODE_FILTER_PARA ModeFilter = {0}; + + cbMode_GetFilterPara(pcbe, pDevCommon->DeviceType, &ModeFilter); + + ulModeNum = cbMode_GetDeviceModeList(pcbe, + pDevCommon->DeviceType, + pModeList, + pBufferSize, + &ModeFilter); + + if(ulModeNum == 0) + { + ulModeNum = cbMode_GetDefaultModeList(pcbe, pModeList, pDevCommon->DeviceType); + } + + *pBufferSize = ulModeNum*sizeof(CBiosModeInfoExt); + + return CBIOS_OK; +} + +CBIOS_STATUS cbDevGetDeviceModeListBufferSize(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U32 *pBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 ulNumOfMode = 0; + CBIOS_MODE_FILTER_PARA ModeFilter = {0}; + + cbMode_GetFilterPara(pcbe, pDevCommon->DeviceType, &ModeFilter); + + ulNumOfMode = cbMode_GetDeviceModeList(pcbe, + pDevCommon->DeviceType, + CBIOS_NULL, + CBIOS_NULL, + &ModeFilter); + + if(ulNumOfMode == 0) + { + ulNumOfMode = cbMode_GetDefaultModeList(pcbe, CBIOS_NULL, pDevCommon->DeviceType); + } + + *pBufferSize = ulNumOfMode * sizeof(CBiosModeInfoExt); + + return CBIOS_OK; +} + +CBIOS_U32 cbDevGetHDAFormatList(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_HDMI_AUDIO_INFO pHDAFormatList) +{ + CBIOS_U32 HDAFormatNum = 0; + + if ((pDevCommon->EdidStruct.Attribute.IsCEA861Audio) || (pDevCommon->EdidStruct.TotalHDMIAudioFormatNum != 0)) + { + HDAFormatNum = pDevCommon->EdidStruct.TotalHDMIAudioFormatNum; + if (pHDAFormatList != CBIOS_NULL) + { + cb_memcpy(pHDAFormatList, pDevCommon->EdidStruct.HDMIAudioFormat, HDAFormatNum * sizeof(CBIOS_HDMI_AUDIO_INFO)); + } + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "%s: Device:0x%x doesn't support HD audio!\n", FUNCTION_NAME, pDevCommon->DeviceType)); + HDAFormatNum = 0; + } + + return HDAFormatNum; +} + +CBIOS_STATUS cbDevSetDisplayDevicePowerState(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_PM_STATUS PMState) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bTurnOn = CBIOS_FALSE; + CBIOS_STATUS Status = CBIOS_OK; + + if(PMState == CBIOS_PM_ON) + { + bTurnOn = CBIOS_TRUE; + } + else + { + bTurnOn = CBIOS_FALSE; + } + + if (pDevCommon->pfncbDeviceOnOff) + { + pDevCommon->pfncbDeviceOnOff(pcbe, pDevCommon, bTurnOn); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "%s: current device: 0x%x has no func to turn on/off.\n", FUNCTION_NAME, pDevCommon->DeviceType)); + } + + if (bTurnOn) + { +#if DVO_PORT_SUPPORT + if (pDevCommon->DeviceType & CBIOS_TYPE_DVO) + { + + } +#endif + } + + return Status; +} + +CBIOS_STATUS cbDevGetDisplayDevicePowerState(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_PM_STATUS pPMState) +{ + //Assume invalid parameter + *pPMState = CBIOS_PM_INVALID; + + *pPMState = pDevCommon->PowerState; + + if((*pPMState) == CBIOS_PM_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: PM State is Invalid!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + else + { + return CBIOS_OK; + } +} + +CBIOS_STATUS cbDevDSISendWriteCmd(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DSI_WRITE_PARA_INTERNAL pDSIWriteParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + return cbDSI_SendWriteCmd(pcbe, pDSIWriteParams); +} + +CBIOS_STATUS cbDevDSISendReadCmd(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DSI_READ_PARA_INTERNAL pDSIReadParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + return cbDSI_SendReadCmd(pcbe, pDSIReadParams); +} + +CBIOS_STATUS cbDevDSIDisplayUpdate(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DSI_UPDATE_PARA pDSIUpdatePara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + return cbDSI_DisplayUpdate(pcbe, pDSIUpdatePara); +} + +CBIOS_STATUS cbDevDSIPanelSetCabc(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U32 CabcValue) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DSI_PANEL_DESC pDSIPanelDesc = &(pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc); + + return cbDSIPanel_SetCabc(pcbe, CabcValue, pDSIPanelDesc); +} + +CBIOS_STATUS cbDevDSIPanelSetBacklight(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U32 BacklightValue) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DSI_PANEL_DESC pDSIPanelDesc = &(pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc); + + return cbDSIPanel_SetBacklight(pcbe, BacklightValue, pDSIPanelDesc); +} + +CBIOS_STATUS cbDevDSIPanelGetBacklight(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U32 *pBacklightValue) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DSI_PANEL_DESC pDSIPanelDesc = &(pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc); + + return cbDSIPanel_GetBacklight(pcbe, pBacklightValue, pDSIPanelDesc); +} + +CBIOS_STATUS cbDevSetHDACodecPara(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_HDAC_PARA pCbiosHDACPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + cbDIU_HDAC_SetHDACodecPara(pcbe, pCbiosHDACPara); + + return CBIOS_OK; +} + +CBIOS_STATUS cbDevSetHDACConnectStatus(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_HDAC_PARA pCbiosHDACPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + cbDIU_HDAC_SetConnectStatus(pcbe, pCbiosHDACPara); + + return CBIOS_OK; +} + +CBIOS_STATUS cbDevAccessDpcdData(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBiosAccessDpcdDataParams pAccessDpcdDataParams) +{ +#if DP_MONITOR_SUPPORT + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 offset, BufferSize, i; + CBIOS_UCHAR *DataBuffer = CBIOS_NULL; + CBIOS_MODULE_INDEX DPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + AUX_CONTROL AUX = {0}; + + offset = pAccessDpcdDataParams->StartingAddress; + DataBuffer = pAccessDpcdDataParams->pOutBuffer; + BufferSize = pAccessDpcdDataParams->NumOfBytes; + + DPModuleIndex = cbGetModuleIndex(pcbe, pAccessDpcdDataParams->RequestConnectedDevId, CBIOS_MODULE_TYPE_DP); + if (DPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + return CBIOS_ER_CHIPDISABLE; +#endif + if(pAccessDpcdDataParams->pOutBuffer == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: Data output buffer pointer is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + if (pAccessDpcdDataParams->ReadWriteFlag == 0) + { + for (i=0; iReadWriteFlag == 1) + { + for (i=0; iDevicesId, CBIOS_MODULE_TYPE_HDCP); + if (HDCPModuleIndex != CBIOS_MODULE_INDEX_INVALID) + { +#ifndef UEFI_DIAGTOOL + cbHDCP_OnOff(pcbe, pContentProtectionOnOffParams->DevicesId, IGAIndex, pContentProtectionOnOffParams->bHdcpStatus); +#else + cbHDCP_OnOff(pcbe, pContentProtectionOnOffParams->DevicesId, IGAIndex, pContentProtectionOnOffParams->bHdcpStatus, hdcpVer); +#endif + Status = CBIOS_OK; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + Status = CBIOS_ER_INVALID_PARAMETER; + } + return Status; +} + +CBIOS_STATUS cbDevGetHDCPStatus(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_HDCP_STATUS_PARA pCBiosHdcpStatusParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_ER_INVALID_PARAMETER; + CBIOS_MODULE_INDEX HDCPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + + HDCPModuleIndex = cbGetModuleIndex(pcbe, pCBiosHdcpStatusParams->DevicesId, CBIOS_MODULE_TYPE_HDCP); + if (HDCPModuleIndex != CBIOS_MODULE_INDEX_INVALID) + { + pCBiosHdcpStatusParams->HdcpStatus = cbHDCP_GetStatus(pcbe, pCBiosHdcpStatusParams->DevicesId); + cbHDCP_GetHDCPBKsv(pcbe, pCBiosHdcpStatusParams->DevicesId, pCBiosHdcpStatusParams->BKsv, &pCBiosHdcpStatusParams->bRepeater); + Status = CBIOS_OK; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: device:0x%x doesn't support HDCP!\n", FUNCTION_NAME, pCBiosHdcpStatusParams->DevicesId)); + Status = CBIOS_ER_INVALID_PARAMETER; + } + return Status; +} + +CBIOS_STATUS cbDevHDCPWorkThread(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U8 IGAIndex, PCBIOS_HDCP_WORK_PARA pCBiosHdcpWorkParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_ER_INVALID_PARAMETER; + CBIOS_MODULE_INDEX HDCPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + + HDCPModuleIndex = cbGetModuleIndex(pcbe, pCBiosHdcpWorkParams->DevicesId, CBIOS_MODULE_TYPE_HDCP); + if (HDCPModuleIndex != CBIOS_MODULE_INDEX_INVALID) + { + cbHDCP_WorkThread(pcbe, pCBiosHdcpWorkParams->DevicesId, IGAIndex); + Status = CBIOS_OK; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: device:0x%x doesn't support HDCP!\n", FUNCTION_NAME, pCBiosHdcpWorkParams->DevicesId)); + Status = CBIOS_ER_INVALID_PARAMETER; + } + return Status; +} + +CBIOS_STATUS cbDevHDCPIsr(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_HDCP_ISR_PARA pHdcpIsrParam) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_ER_INVALID_PARAMETER; + CBIOS_MODULE_INDEX HDCPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + + HDCPModuleIndex = cbGetModuleIndex(pcbe, pHdcpIsrParam->DevicesId, CBIOS_MODULE_TYPE_HDCP); + if (HDCPModuleIndex != CBIOS_MODULE_INDEX_INVALID) + { + cbHDCP_Isr(pcbe, pHdcpIsrParam->DevicesId); + Status = CBIOS_OK; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: device:0x%x doesn't support HDCP!\n", FUNCTION_NAME, pHdcpIsrParam->DevicesId)); + Status = CBIOS_ER_INVALID_PARAMETER; + } + return Status; +} + +CBIOS_BOOL cbDevHdmiSCDCWorkThreadMainFunc(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + CBIOS_BOOL bRet = CBIOS_FALSE; + + bRet = cbHDMIMonitor_SCDC_Handler(pvcbe, pDevCommon); + + return bRet; +} + +CBIOS_STATUS cbDevDPIsr(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_ISR_PARA pDPIsrPara) +{ + return cbDPPort_Isr(pvcbe, pDevCommon, pDPIsrPara); +} + +CBIOS_BOOL cbDevDPWorkThreadMainFunc(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_WORKTHREAD_PARA pDPWorkThreadPara) +{ + return cbDPPort_WorkThreadMainFunc(pvcbe, pDevCommon, pDPWorkThreadPara); +} + +CBIOS_STATUS cbDevDPSetNotifications(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_NOTIFICATIONS pDPNotifications) +{ + return cbDPPort_SetNotifications(pvcbe, pDevCommon, pDPNotifications); +} + +CBIOS_STATUS cbDevGetDPIntType(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_INT_PARA pDpIntPara) +{ + return cbDPPort_GetInt(pvcbe, pDevCommon, pDpIntPara); +} + +CBIOS_STATUS cbDevDPHandleIrq(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_HANDLE_IRQ_PARA pDPHandleIrqPara) +{ + return cbDPPort_HandleIrq(pvcbe, pDevCommon, pDPHandleIrqPara); +} + +CBIOS_STATUS cbDevDPGetCustomizedTiming(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_CUSTOMIZED_TIMING pDPCustomizedTiming) +{ + return cbDPPort_GetCustomizedTiming(pvcbe, pDevCommon, pDPCustomizedTiming); +} diff --git a/drivers/gpu/drm/arise/cbios/Device/CBiosDevice.h b/drivers/gpu/drm/arise/cbios/Device/CBiosDevice.h new file mode 100644 index 0000000000000..47cdbf6358494 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/CBiosDevice.h @@ -0,0 +1,83 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios general device port functions prototype. +** +** NOTE: +** The hw dependent function or structure SHOULD NOT be added to this file. +******************************************************************************/ + +#ifndef _CBIOS_DEVICE_H_ +#define _CBIOS_DEVICE_H_ + +#include "CBiosDeviceShare.h" + +CBIOS_VOID cbInitDeviceArray(PCBIOS_VOID pvcbe, PVCP_INFO pVCP); +CBIOS_VOID cbDeInitDeviceArray(PCBIOS_VOID pvcbe); +CBIOS_VOID cbDevDeviceHwInit(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +CBIOS_U32 cbDevGetPrimaryDevice(CBIOS_U32 Device); +CBIOS_VOID cbDevUpdateDeviceModeInfo(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DISP_MODE_PARAMS pModeParams); +CBIOS_VOID cbDevSetModeToDevice(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DISP_MODE_PARAMS pModeParams); + +CBIOS_STATUS cbDevGetModeTiming(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_GET_MODE_TIMING_PARAM pGetModeTiming); +CBIOS_STATUS cbDevGetModeFromReg(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_GETTING_MODE_PARAMS pModeParams); +CBIOS_STATUS cbDevGetEdidFromBuffer(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_PARAM_GET_EDID pCBParamGetEdid); +CBIOS_STATUS cbDevSetEdid(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_PARAM_SET_EDID pCBParamSetEdid); +CBIOS_STATUS cbDevGetSupportedMonitorType(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_QUERY_MONITOR_TYPE_PER_PORT pCBiosQueryMonitorTypePerPort); +CBIOS_STATUS cbDevQueryMonitorAttribute(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBiosMonitorAttribute pMonitorAttribute); +CBIOS_STATUS cbDevQueryMonitor3DCapability(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_MONITOR_3D_CAPABILITY_PARA p3DCapability); +CBIOS_STATUS cbDevGetDeviceModeList(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBiosModeInfoExt pModeList, CBIOS_U32 *pBufferSize); +CBIOS_STATUS cbDevGetDeviceModeListBufferSize(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U32 *pBufferSize); +CBIOS_STATUS cbGetDeviceName(PCBIOS_VOID pvcbe, PCBIOS_GET_DEVICE_NAME pGetName); +CBIOS_BOOL cbDevDeviceDetect(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bHardcodeDetect, CBIOS_U32 FullDetect); +CBIOS_U32 cbDevNonDestructiveDeviceDetectByEdid(PCBIOS_VOID pvcbe, PCBIOS_UCHAR pEDIDData, CBIOS_U32 EdidBufferSize); +CBIOS_STATUS cbDevSetDisplayDevicePowerState(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_PM_STATUS PMState); +CBIOS_STATUS cbDevGetDisplayDevicePowerState(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_PM_STATUS pPMState); + +// DP only interfaces +CBIOS_STATUS cbDevAccessDpcdData(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBiosAccessDpcdDataParams pAccessDpcdDataParams); + +// HD audio +CBIOS_STATUS cbDevSetHDACodecPara(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_HDAC_PARA pCbiosHDACPara); +CBIOS_STATUS cbDevSetHDACConnectStatus(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_HDAC_PARA pCbiosHDACPara); +CBIOS_U32 cbDevGetHDAFormatList(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_HDMI_AUDIO_INFO pHDAFormatList); + +// DSI only interfaces +CBIOS_STATUS cbDevDSISendWriteCmd(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DSI_WRITE_PARA_INTERNAL pDSIWriteParams); +CBIOS_STATUS cbDevDSISendReadCmd(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DSI_READ_PARA_INTERNAL pDSIReadParams); +CBIOS_STATUS cbDevDSIDisplayUpdate(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DSI_UPDATE_PARA pDSIUpdatePara); +CBIOS_STATUS cbDevDSIPanelSetCabc(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U32 CabcValue); +CBIOS_STATUS cbDevDSIPanelSetBacklight(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U32 BacklightValue); +CBIOS_STATUS cbDevDSIPanelGetBacklight(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U32 *pBacklightValue); + +#ifndef UEFI_DIAGTOOL +CBIOS_STATUS cbDevContentProtectionOnOff(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U8 IGAIndex, PCBiosContentProtectionOnOffParams pContentProtectionOnOffParams); +#else +CBIOS_STATUS cbDevContentProtectionOnOff(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U8 IGAIndex, PCBiosContentProtectionOnOffParams pContentProtectionOnOffParams, CBIOS_U16 hdcpVer); +#endif +CBIOS_STATUS cbDevGetHDCPStatus(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_HDCP_STATUS_PARA pCBiosHdcpStatusParams); +CBIOS_STATUS cbDevHDCPWorkThread(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U8 IGAIndex, PCBIOS_HDCP_WORK_PARA pCBiosHdcpWorkParams); +CBIOS_STATUS cbDevHDCPIsr(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_HDCP_ISR_PARA pHdcpIsrParam); +CBIOS_STATUS cbDevDPIsr(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_ISR_PARA pDPIsrPara); +CBIOS_BOOL cbDevDPWorkThreadMainFunc(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_WORKTHREAD_PARA pDPWorkThreadPara); +CBIOS_STATUS cbDevDPSetNotifications(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_NOTIFICATIONS pDPNotifications); +CBIOS_BOOL cbDevHdmiSCDCWorkThreadMainFunc(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); + +CBIOS_STATUS cbDevGetDPIntType(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_INT_PARA pDpIntPara); +CBIOS_STATUS cbDevDPHandleIrq(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_HANDLE_IRQ_PARA pDPHandleIrqPara); +CBIOS_STATUS cbDevDPGetCustomizedTiming(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_CUSTOMIZED_TIMING pDPCustomizedTiming); +#endif diff --git a/drivers/gpu/drm/arise/cbios/Device/CBiosDeviceShare.c b/drivers/gpu/drm/arise/cbios/Device/CBiosDeviceShare.c new file mode 100644 index 0000000000000..a1514e0f062df --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/CBiosDeviceShare.c @@ -0,0 +1,814 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** Device port sharing function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosDeviceShare.h" +#include "CBiosChipShare.h" + +CBIOS_U8 FPGAHDMIEdid[256] = +{ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x21, 0x34, 0x03, 0x7D, 0x43, 0x41, 0x32, 0x01, + 0x1E, 0x11, 0x01, 0x03, 0x80, 0x34, 0x20, 0x64, 0x0A, 0xEF, 0x95, 0xA3, 0x54, 0x4C, 0x9B, 0x26, + 0x0F, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5, 0x09, 0x80, 0xA0, 0x20, 0xE0, 0x2D, 0x10, 0x10, 0x60, + 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x01, 0x1D, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20, + 0x6E, 0x28, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, + 0x2D, 0x40, 0x58, 0x2C, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, + 0x00, 0x57, 0x32, 0x34, 0x30, 0x44, 0x20, 0x44, 0x56, 0x49, 0x0A, 0x20, 0x20, 0x20, 0x01, 0xFB, + 0x02, 0x03, 0x1C, 0x71, 0x23, 0x09, 0x07, 0x07, 0x49, 0x90, 0x14, 0x13, 0x12, 0x05, 0x04, 0x03, + 0x02, 0x01, 0x65, 0x03, 0x0C, 0x00, 0x10, 0x00, 0x83, 0x01, 0x00, 0x00, 0x8C, 0x0A, 0xD0, 0x90, + 0x20, 0x40, 0x31, 0x20, 0x0C, 0x40, 0x55, 0x00, 0x13, 0x8E, 0x21, 0x00, 0x00, 0x18, 0x01, 0x1D, + 0x80, 0x18, 0x71, 0x1C, 0x16, 0x20, 0x58, 0x2C, 0x25, 0x00, 0xC4, 0x8E, 0x21, 0x00, 0x00, 0x9E, + 0x01, 0x1D, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20, 0x6E, 0x28, 0x55, 0x00, 0xC4, 0x8E, 0x21, 0x00, + 0x00, 0x1E, 0x8C, 0x0A, 0xD0, 0x8A, 0x20, 0xE0, 0x2D, 0x10, 0x10, 0x3E, 0x96, 0x00, 0xC4, 0x8E, + 0x21, 0x00, 0x00, 0x18, 0x8C, 0x0A, 0xD0, 0x8A, 0x20, 0xE0, 0x2D, 0x10, 0x10, 0x3E, 0x96, 0x00, + 0x13, 0x8E, 0x21, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, +}; + + +#if IS_SUPPORT_4K_MODE +CBIOS_U8 Fake4KEdid[256] = +{ + 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x36, 0x74, 0x30, 0x0, 0x1, 0x0, 0x0, 0x0, + 0xA, 0x16, 0x1, 0x3, 0x80, 0x73, 0x41, 0x78, 0xA, 0xCF, 0x74, 0xA3, 0x57, 0x4C, 0xB0, 0x23, + 0x9, 0x48, 0x4C, 0x21, 0x8, 0x0, 0x81, 0x80, 0x45, 0x40, 0x61, 0x40, 0x95, 0x0, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C, + 0x45, 0x0, 0xC4, 0x8E, 0x21, 0x0, 0x0, 0x1E, 0x66, 0x21, 0x50, 0xB0, 0x51, 0x0, 0x1B, 0x30, + 0x40, 0x70, 0x36, 0x0, 0xC4, 0x8E, 0x21, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0xFC, 0x0, 0x4D, + 0x53, 0x74, 0x61, 0x72, 0x20, 0x44, 0x65, 0x6D, 0x6F, 0xA, 0x20, 0x20, 0x0, 0x0, 0x0, 0xFD, + 0x0, 0x32, 0x4B, 0x1E, 0x50, 0x17, 0x0, 0xA, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1, 0xF1, + 0x2, 0x3, 0x30, 0xF2, 0x4D, 0x1, 0x3, 0x4, 0x5, 0x7, 0x90, 0x12, 0x13, 0x14, 0x16, 0x9F, + 0x20, 0x22, 0x26, 0x9, 0x7, 0x7, 0x11, 0x17, 0x50, 0x83, 0x1, 0x0, 0x0, 0x72, 0x3, 0xC, + 0x0, 0x40, 0x0, 0xB8, 0x44, 0x20, 0xC0, 0x84, 0x1, 0x2, 0x3, 0x4, 0x1, 0x41, 0x0, 0x0, + 0x8C, 0xA, 0xD0, 0x8A, 0x20, 0xE0, 0x2D, 0x10, 0x10, 0x3E, 0x96, 0x0, 0xC4, 0x8E, 0x21, 0x0, + 0x0, 0x18, 0x8C, 0xA, 0xD0, 0x90, 0x20, 0x40, 0x31, 0x20, 0xC, 0x40, 0x55, 0x0, 0xC4, 0x8E, + 0x21, 0x0, 0x0, 0x18, 0x1, 0x1D, 0x0, 0xBC, 0x52, 0xD0, 0x1E, 0x20, 0xB8, 0x28, 0x55, 0x40, + 0xC4, 0x8E, 0x21, 0x0, 0x0, 0x1E, 0x1, 0x1D, 0x80, 0xD0, 0x72, 0x1C, 0x16, 0x20, 0x10, 0x2C, + 0x25, 0x80, 0xC4, 0x8E, 0x21, 0x0, 0x0, 0x9E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, +}; +#endif + + +static CBIOS_BOOL cbGetEDID(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U8 EDIDData[], CBIOS_U32 ulReadEdidOffset, CBIOS_U32 ulBufferSize) +{ + //CBIOS_U8 edid_address[] = {0xA0,0x00,0xA2,0x20,0xA6,0x20}; + CBIOS_U8 byTemp; + CBIOS_U8 I2CBUSNum = (CBIOS_U8)pDevCommon->I2CBus; + CBIOS_U8 i = 0; + CBIOS_U32 j; + CBIOS_BOOL bRet = CBIOS_FALSE; + CBIOS_U32 BlockSize = 128; + CBIOS_U32 ExtBlockCount = 0; + CBIOS_U16 DCLK = 0, XResolution = 0, YResolution = 0; + CBIOS_U32 ulEDIDLen; + PCBIOS_VOID pDPMonitorContext = CBIOS_NULL; + CBIOS_BOOL bDPMode = CBIOS_FALSE; + CBIOS_ACTIVE_TYPE Device = pDevCommon->DeviceType; + + if(ulBufferSize == 0) + return CBIOS_FALSE; + + cb_memset(EDIDData, 0, ulBufferSize); + + if (Device & ALL_DP_TYPES) + { + if (!cbDPPort_IsDeviceInDpMode(pcbe, pDevCommon))//dual mode + { + bDPMode = CBIOS_FALSE; + I2CBUSNum = (CBIOS_U8)pDevCommon->I2CBus; + } + else//DP mode + { + pDPMonitorContext = cbGetDPMonitorContext(pcbe, pDevCommon); + bDPMode = CBIOS_TRUE; + } + } + else + { + bDPMode = CBIOS_FALSE; + } + + //deal with special request, offset is not 0, read count is not times of 1 block. + if((ulReadEdidOffset != 0) || (ulBufferSize % 128 != 0)) + { + if (bDPMode) + { + #if DP_MONITOR_SUPPORT + if (pDPMonitorContext) + { + bRet = cbDPMonitor_AuxReadEDIDOffset(pcbe, pDPMonitorContext, EDIDData, ulBufferSize, ulReadEdidOffset); + } + #endif + } + else + { + bRet = cbHWReadEDID(pcbe, I2CBUSNum, EDIDData, ulReadEdidOffset, ulBufferSize, 0); + } + + } + else//read full EDID + { + if (bDPMode)//DP + { + #if DP_MONITOR_SUPPORT + if (pDPMonitorContext) + { + bRet = cbDPMonitor_AuxReadEDID(pcbe, pDPMonitorContext, EDIDData, ulBufferSize); + } + #endif + } + else//Non DP devices + { + // Get block 0 + bRet = cbHWReadEDID(pcbe, I2CBUSNum, EDIDData, 0, BlockSize, 0); + + if (bRet == CBIOS_FALSE || !cbEDIDModule_IsEDIDHeaderValid(EDIDData, BlockSize)) + { + bRet = CBIOS_FALSE; + goto Exit; + } + + // Get block 1 + if (EDIDData[0x7E] && (ulBufferSize >= 256)) + { + bRet = cbHWReadEDID(pcbe, I2CBUSNum, EDIDData+BlockSize, 128, BlockSize, 0); + } + + if (EDIDData[0x7E] && ((EDIDData[0x84]&0xE0) == 0xE0) && (EDIDData[0x85] == 0x78)) // HDMI2.1 EEODB + { + ExtBlockCount = EDIDData[0x86]; + } + else + { + ExtBlockCount = EDIDData[0x7E]; + } + + if(ExtBlockCount > CBIOS_EDIDMAXBLOCKCOUNT - 1) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbGetEDID: ExtBlockCount > 7, need refine!\n")); + ExtBlockCount = CBIOS_EDIDMAXBLOCKCOUNT - 1; + //ASSERT(CBIOS_FALSE); + } + + pDevCommon->TotalBlockNum = ExtBlockCount + 1; + + // Get block 2 ~ n + for ( i = 2; i <= ExtBlockCount; i++) + { + bRet = cbHWReadEDID(pcbe, I2CBUSNum, &EDIDData[i*BlockSize], (i-2)*128, BlockSize, i/2); + } + +Exit: + + if (bRet && (ulBufferSize % 128) == 0) + { +#if 0 + //cbDumpBuffer(pcbe, EDIDData, ulBufferSize); + cbDumpBuffer(pcbe, EDIDData, (ExtBlockCount+1)*128); + +#endif + + byTemp = 0; // Check checksum + ulEDIDLen = EDID_BLOCK_SIZE_SPEC; // just check first 128 bytes + for (j = 0; j < ulEDIDLen; j ++) + { + byTemp += EDIDData[j]; + } + + if (byTemp != 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING),"cbGetEDID: EDID is got, but check sum error, check detailed timming!\n")); + DCLK = EDIDData[0x37]; //check DCLK and X/Y Resolution + DCLK = DCLK << 8; + DCLK |= EDIDData[0x36]; + + XResolution = EDIDData[0x3A] & 0xF0; + XResolution = XResolution << 4; + XResolution |= EDIDData[0x38]; + + YResolution = EDIDData[0x3D] & 0xF0; + YResolution = YResolution << 4; + YResolution |= EDIDData[0x3B]; + + if((DCLK > 0)&&(XResolution > 0)&&(YResolution > 0)) + { + //Set checksum to the correct value + EDIDData[ulEDIDLen - 1] = (EDIDData[ulEDIDLen - 1] + 0xFF - byTemp + 1) & 0xFF; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbGetEDID: Detailed timming is invalid, zero it!\n")); + bRet = CBIOS_FALSE; + } + } + } + } + + if (!bRet) + { + cb_memset(EDIDData, 0, ulBufferSize); + } + } + + return bRet; +} + +static CBIOS_BOOL cbGetDeviceSignature(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DEVICE_SIGNATURE pDevSignatre) +{ + CBIOS_U32 i = 0; + CBIOS_BOOL bResult = CBIOS_FALSE; + CBIOS_U32 EDIDBlockNum = 0; + + if(CBIOS_NULL == pDevSignatre) + { + bResult = CBIOS_FALSE; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbGetDeviceSignature: the 3rd param is a NULL pointer\n")); + } + else + { + cb_memset(pDevSignatre, 0, sizeof(CBIOS_DEVICE_SIGNATURE)); + + // get the monitor ID + if(cbGetEDID(pcbe, pDevCommon, pDevSignatre->MonitorID, MONITORIDINDEX, MONITORIDLENGTH)) + { + // get the flag of checksum in block 0 + if(cbGetEDID(pcbe, pDevCommon, pDevSignatre->ExtFlagChecksum[0], EXTFLAGCHECKSUMINDEX, EXTFLAGCHECKSUMLENTH)) + { + EDIDBlockNum = (CBIOS_U32)pDevSignatre->ExtFlagChecksum[0][0]; + + if (0 == EDIDBlockNum) // if EDIDBlockNum = 0, just return + { + bResult = CBIOS_TRUE; + } + else + { + // get the flag of checksum in the remaining blocks + if (EDIDBlockNum > CBIOS_EDIDMAXBLOCKCOUNT - 1) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),"cbGetDeviceSignature: EDIDBlockNum > 7, here read the first 8 blocks!\n")); + EDIDBlockNum = CBIOS_EDIDMAXBLOCKCOUNT - 1; + } + + for (i = 1; i < EDIDBlockNum + 1; i++) + { + if(!cbGetEDID(pcbe, pDevCommon, pDevSignatre->ExtFlagChecksum[i], EDID_BLOCK_SIZE_SPEC * i + EXTFLAGCHECKSUMINDEX, EXTFLAGCHECKSUMLENTH)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbGetDeviceSignature: cannot read the checksum flag in EDID block %x\n", i)); + bResult = CBIOS_FALSE; + break; + } + else + { + bResult = CBIOS_TRUE; + } + } + } + } + else + { + bResult = CBIOS_FALSE; + } + } + else + { + bResult = CBIOS_FALSE; + } + } + + return bResult; +} + +//if the monitor serial number is not the same as the pcbe, the device is changed. +//return: CBIOS_TRUE - device changed +static CBIOS_BOOL cbIsDeviceChanged(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + CBIOS_DEVICE_SIGNATURE DeviceSignature; + CBIOS_BOOL bResult = CBIOS_TRUE; + CBIOS_U32 i = 0; + CBIOS_S32 ChecksumFlagChanged = 0; + + //If we can not get the signature from the edid, we consider that the device is changed + if(cbEDIDModule_IsEDIDValid(pDevCommon->EdidData)) + { + // If the new device has not edid, clear device signature + if (!cbGetDeviceSignature(pcbe, pDevCommon, &DeviceSignature)) + { + cb_memset(&DeviceSignature, 0, sizeof(CBIOS_DEVICE_SIGNATURE)); + } + + //Compare the signature--checksum + for (i = 0; i < CBIOS_EDIDMAXBLOCKCOUNT; i++) + { + ChecksumFlagChanged = cb_memcmp(pDevCommon->ConnectedDevSignature.ExtFlagChecksum[i], DeviceSignature.ExtFlagChecksum[i], EXTFLAGCHECKSUMLENTH); + if (0 != ChecksumFlagChanged) + { + bResult = CBIOS_TRUE; + break; + } + else + { + bResult = CBIOS_FALSE; + } + } + + //Compare the signature--monitor ID + if ((0 == ChecksumFlagChanged) && (0 == cb_memcmp(pDevCommon->ConnectedDevSignature.MonitorID, DeviceSignature.MonitorID, MONITORIDLENGTH))) + { + bResult = CBIOS_FALSE; + } + else + { + bResult = CBIOS_TRUE; + } + } + else + { + bResult = CBIOS_TRUE; + } + return bResult; +} + +CBIOS_BOOL cbGetDeviceEDID(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL *pIsDevChanged, CBIOS_U32 FullDetect) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bGotEDID = CBIOS_FALSE; + CBIOS_BOOL bNeedUpdateSignature = CBIOS_FALSE; + CBIOS_UCHAR *pEdidBuffer = CBIOS_NULL; + const CBIOS_U32 EdidBufferSize = CBIOS_EDIDDATABYTE; + + if (pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDevCommon is NULL!\n", FUNCTION_NAME)); + return bGotEDID; + } + + // check if use hardcode EDID + if (pcbe->DevicesHardcodedEdid & pDevCommon->DeviceType) + { + bGotEDID = CBIOS_TRUE; + bNeedUpdateSignature= CBIOS_TRUE; + *pIsDevChanged = CBIOS_TRUE; + cb_memcpy(pDevCommon->EdidData, pcbe->EdidFromRegistry, EdidBufferSize); + } + // check if use faked edid sending from the upper layer + else if ((pDevCommon->isFakeEdid) && (cbEDIDModule_IsEDIDValid(pDevCommon->EdidData))) + { + bGotEDID = CBIOS_TRUE; + bNeedUpdateSignature = CBIOS_TRUE; + *pIsDevChanged = CBIOS_TRUE; + } + // read EDID from the monitor side + else + { + + pEdidBuffer = cb_AllocateNonpagedPool(EdidBufferSize); + if(pEdidBuffer == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pEdidBuffer allocate error.\n", FUNCTION_NAME)); + bGotEDID = CBIOS_FALSE; + return bGotEDID; + } + + //some hdmi cts items like HF1-23 need read full edid when monitor issue a hotplug + if(FullDetect) + { + if (cbGetEDID(pcbe, pDevCommon, pEdidBuffer, 0, EdidBufferSize) && cbEDIDModule_IsEDIDValid(pEdidBuffer)) + { + if(cbIsDeviceChangedByEdid(pcbe, pDevCommon, pEdidBuffer)) + { + *pIsDevChanged = CBIOS_TRUE; + bNeedUpdateSignature = CBIOS_TRUE; + bGotEDID = CBIOS_TRUE; + cb_memcpy(pDevCommon->EdidData, pEdidBuffer, EdidBufferSize); + } + else + { + *pIsDevChanged = CBIOS_FALSE; + bNeedUpdateSignature = CBIOS_FALSE; + bGotEDID = CBIOS_TRUE; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "%s: cannot get edid or edid is invalid.\n", FUNCTION_NAME)); + bGotEDID = CBIOS_FALSE; + } + } + else + { + if (cbIsDeviceChanged(pcbe, pDevCommon)) + { + if (cbGetEDID(pcbe, pDevCommon, pEdidBuffer, 0, EdidBufferSize) && cbEDIDModule_IsEDIDValid(pEdidBuffer)) + { + bNeedUpdateSignature = CBIOS_TRUE; + *pIsDevChanged = CBIOS_TRUE; + bGotEDID = CBIOS_TRUE; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "%s: cannot get edid or edid is invalid.\n", FUNCTION_NAME)); + bGotEDID = CBIOS_FALSE; + } + + if (bGotEDID) + { + cb_memcpy(pDevCommon->EdidData, pEdidBuffer, EdidBufferSize); + } + } + else + { + *pIsDevChanged = CBIOS_FALSE; + bNeedUpdateSignature = CBIOS_FALSE; + bGotEDID = CBIOS_TRUE; + } + } + + if (pEdidBuffer) + { + cb_FreePool(pEdidBuffer); + } + + + } + + // update the signature + if (bNeedUpdateSignature) + { + cbUpdateDeviceSignature(pcbe, pDevCommon); + } + + return bGotEDID; +} + +CBIOS_BOOL cbIsDeviceChangedByEdid(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_UCHAR pEDIDData) +{ + CBIOS_BOOL bRet = CBIOS_TRUE; + CBIOS_S32 result = 0; + CBIOS_S32 i = 0; + CBIOS_S32 ChecksumFlagChanged = 0; + + if (CBIOS_NULL == pEDIDData) + { + bRet = CBIOS_TRUE; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is a NULL pointer\n", FUNCTION_NAME)); + } + else + { + result = cb_memcmp(pDevCommon->ConnectedDevSignature.MonitorID, + &pEDIDData[MONITORIDINDEX], MONITORIDLENGTH); + if(result == 0) + { + for (i = 0; i < CBIOS_EDIDMAXBLOCKCOUNT; i++) + { + ChecksumFlagChanged = cb_memcmp(pDevCommon->ConnectedDevSignature.ExtFlagChecksum[i], + &pEDIDData[i * EDID_BLOCK_SIZE_SPEC + EXTFLAGCHECKSUMINDEX], EXTFLAGCHECKSUMLENTH); + if (0 != ChecksumFlagChanged) + { + bRet = CBIOS_TRUE; + break; + } + else + { + bRet = CBIOS_FALSE; + } + } + } + else + { + bRet = CBIOS_TRUE; + } + } + return bRet; +} + +CBIOS_BOOL cbUpdateDeviceSignature(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + CBIOS_U32 EDIDBlockNum = 0, i = 0; + CBIOS_UCHAR *pEDID = CBIOS_NULL; + + if (pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + pEDID = pDevCommon->EdidData; + + cb_memset(&pDevCommon->ConnectedDevSignature, 0, sizeof(CBIOS_DEVICE_SIGNATURE)); + cb_memcpy(pDevCommon->ConnectedDevSignature.MonitorID, &pEDID[MONITORIDINDEX], MONITORIDLENGTH); + // copy the flag of checksum in block 0 + cb_memcpy(pDevCommon->ConnectedDevSignature.ExtFlagChecksum[0], + &pEDID[EXTFLAGCHECKSUMINDEX], EXTFLAGCHECKSUMLENTH); + EDIDBlockNum = (CBIOS_U32)pDevCommon->ConnectedDevSignature.ExtFlagChecksum[0][0]; + if (0 < EDIDBlockNum) + { + // get the flag of checksum in the remaining blocks + if (EDIDBlockNum > CBIOS_EDIDMAXBLOCKCOUNT - 1) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING),"%s: EDIDBlockNum > 3, here copy the first 4 blocks!\n", FUNCTION_NAME)); + EDIDBlockNum = CBIOS_EDIDMAXBLOCKCOUNT - 1; + } + + // copy the flag of checksum in remaining blocks + for (i = 1; i < EDIDBlockNum + 1; i++) + { + cb_memcpy(pDevCommon->ConnectedDevSignature.ExtFlagChecksum[i], + &pEDID[i * EDID_BLOCK_SIZE_SPEC + EXTFLAGCHECKSUMINDEX], EXTFLAGCHECKSUMLENTH); + } + } + + return CBIOS_TRUE; +} + +CBIOS_MONITOR_TYPE cbGetSupportMonitorType(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE devices) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MONITOR_TYPE MonitorType = CBIOS_MONITOR_TYPE_NONE; + + if(devices & CBIOS_TYPE_CRT) + { + MonitorType |= CBIOS_MONITOR_TYPE_CRT; + } + + if(devices & CBIOS_TYPE_TV) + { + MonitorType |= CBIOS_MONITOR_TYPE_TV; + } + + if(devices & CBIOS_TYPE_HDTV) + { + MonitorType |= CBIOS_MONITOR_TYPE_HDTV; + } + + if(devices & CBIOS_TYPE_DSI) + { + MonitorType |= CBIOS_MONITOR_TYPE_PANEL; + } + + if(devices & CBIOS_TYPE_DP1) + { + if (pcbe->FeatureSwitch.IsEDP1Enabled) + { + MonitorType |= CBIOS_MONITOR_TYPE_PANEL; + } + else + { + MonitorType |= CBIOS_MONITOR_TYPE_CRT | CBIOS_MONITOR_TYPE_DP | CBIOS_MONITOR_TYPE_DVI | CBIOS_MONITOR_TYPE_HDMI; + } + } + + if(devices & CBIOS_TYPE_DP2) + { + if (pcbe->FeatureSwitch.IsEDP2Enabled) + { + MonitorType |= CBIOS_MONITOR_TYPE_PANEL; + } + else + { + MonitorType |= CBIOS_MONITOR_TYPE_CRT | CBIOS_MONITOR_TYPE_DP | CBIOS_MONITOR_TYPE_DVI | CBIOS_MONITOR_TYPE_HDMI; + } + } + + if(devices & CBIOS_TYPE_DP3) + { + if (pcbe->FeatureSwitch.IsEDP3Enabled) + { + MonitorType |= CBIOS_MONITOR_TYPE_PANEL; + } + else + { + MonitorType |= CBIOS_MONITOR_TYPE_CRT | CBIOS_MONITOR_TYPE_DP | CBIOS_MONITOR_TYPE_DVI | CBIOS_MONITOR_TYPE_HDMI; + } + } + + if(devices & CBIOS_TYPE_DP4) + { + if (pcbe->FeatureSwitch.IsEDP4Enabled) + { + MonitorType |= CBIOS_MONITOR_TYPE_PANEL; + } + else + { + MonitorType |= CBIOS_MONITOR_TYPE_CRT | CBIOS_MONITOR_TYPE_DP | CBIOS_MONITOR_TYPE_DVI | CBIOS_MONITOR_TYPE_HDMI; + } + } + + if(devices & CBIOS_TYPE_DVO) + { + cbDVOPort_GetSupportMonitorType(pcbe, &MonitorType); + } + + /* + if(devices & CBIOS_TYPE_MHL) + { + if (pcbe->FeatureSwitch.IsCfgMHLMode) + { + MonitorType |= CBIOS_MONITOR_TYPE_MHL; + } + else + { + MonitorType |= CBIOS_MONITOR_TYPE_HDMI | CBIOS_MONITOR_TYPE_DVI; + } + } + */ + + if(devices & CBIOS_TYPE_DSI) + { + MonitorType |= CBIOS_MONITOR_TYPE_PANEL; + } + + if(MonitorType == CBIOS_MONITOR_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "%s: invalid device type 0x%x!\n", FUNCTION_NAME, devices)); + } + + return MonitorType; +} + +CBIOS_VOID cbClearEdidRelatedData(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + if (pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return; + } + + //reset buffers + if(cbEDIDModule_IsEDIDValid(pDevCommon->EdidData)) + { + cb_memset(pDevCommon->EdidData, 0, CBIOS_EDIDDATABYTE); + } + + cb_memset(&pDevCommon->ConnectedDevSignature, 0, sizeof(CBIOS_DEVICE_SIGNATURE)); + //cb_memset(&pDevCommon->EdidStruct, 0, sizeof(CBIOS_EDID_STRUCTURE_DATA)); + + pDevCommon->isFakeEdid = CBIOS_FALSE; +} + + + +CBIOS_BOOL cbDualModeDetect(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 byI2CBus = (CBIOS_U8)pDevCommon->I2CBus; + CBIOS_BOOL bIsDualMode = CBIOS_FALSE; + CBIOS_U8 byData = 0; + + //using DP dual mode char byte to see HDMI or DP + if (cbHWReadEDID(pcbe, byI2CBus, &byData, 0x00, 1, 0)) + { + bIsDualMode = CBIOS_TRUE; + } + else + { + bIsDualMode = CBIOS_FALSE; + } + return bIsDualMode; +} + +PCBIOS_VOID cbGetDPMonitorContext(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_VOID pDPMonitorContext = CBIOS_NULL; + + if (pDevCommon->DeviceType & ALL_DP_TYPES) + { + pDPMonitorContext = cbDPPort_GetDPMonitorContext(pvcbe, pDevCommon); + } + + return pDPMonitorContext; +} + +PCBIOS_VOID cbGetHDMIMonitorContext(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_VOID pHDMIMonitorContext = CBIOS_NULL; + + if (pDevCommon->DeviceType & ALL_DP_TYPES) + { + pHDMIMonitorContext = cbDPPort_GetHDMIMonitorContext(pvcbe, pDevCommon); + } + + return pHDMIMonitorContext; +} + + +#define GET_BIT(val, bit) ((val & (1 << bit)) >> bit) +/* ELD: EDID-Like Data, for passing sink device's audio EDID info to audio software */ +CBIOS_STATUS cbGetDeviceELD(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE DeviceType, PCBIOS_ELD_MEM_STRUCT pELD) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, DeviceType); + PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttrib = &(pDevCommon->EdidStruct.Attribute); + CBIOS_U8 *pEldPayLoad = CBIOS_NULL; + CBIOS_U32 Length = 0; + CBIOS_U32 i = 0; + + cb_memset(pELD, 0, sizeof(CBIOS_ELD_MEM_STRUCT)); + + pELD->ELD_Data.HDCP = 1; + pELD->ELD_Data.S_AI = 0; + pELD->ELD_Data.ELD_Ver = ELD_VER_CEA_861D; + + cb_memcpy(pELD->ELD_Data.ManufactureName, pMonitorAttrib->ManufactureName, 0x02); /* Manufacture name */ + cb_memcpy(pELD->ELD_Data.ProductCode, pMonitorAttrib->ProductCode, 0x02); /* ProductCode */ + + pEldPayLoad = pELD->ELD_Data.private_data; + while (i < 16 && (pMonitorAttrib->MonitorName[i] != 0x00)) + { + *(pEldPayLoad++) = pMonitorAttrib->MonitorName[i]; /* Monitor Name */ + Length++; + i++; + } + pELD->ELD_Data.MNL = (CBIOS_U8)Length; /* Monitor Name Length */ + + if (pDevCommon->CurrentMonitorType & (CBIOS_MONITOR_TYPE_DP | CBIOS_MONITOR_TYPE_PANEL)) + { + pELD->ELD_Data.Conn_Type = 0x01; // connect type is DP + } + else + { + pELD->ELD_Data.Conn_Type = 0; // HDMI + } + + if (pMonitorAttrib->IsCEA861Monitor) + { + pELD->ELD_Data.CEA_EDID_Ver = pMonitorAttrib->RevisionNumber; + + if (!pMonitorAttrib->IsCEA861Audio) + { + cbDebugPrint((MAKE_LEVEL(HDMI, INFO), "%s: Not support basic audio!\n", FUNCTION_NAME)); + } + + pELD->ELD_Data.SAD_Count = pMonitorAttrib->SAD_Count; + if (pELD->ELD_Data.SAD_Count != 0x00) + { + for (i = 0; i < pELD->ELD_Data.SAD_Count; i++) + { + *(pEldPayLoad++) = pMonitorAttrib->CEA_SADs[i][0]; + *(pEldPayLoad++) = pMonitorAttrib->CEA_SADs[i][1]; + *(pEldPayLoad++) = pMonitorAttrib->CEA_SADs[i][2]; + Length += 3; + } + } + else + { + /* + * From High-Definitiddon Multimedia Interface Specification Version 1.4b 7.3(Page 125): + * + * For CEA-861-D references to Sources: + * "Basic Audio" is defined as two channel L-PCM audio at sample rates of 32kHZ,44.1Khz, or 48kHZ, + * With a sample size of at least 16 bits + * + * CEA short Audio Descriptor for audio code = 1(LPCM) + * -------------------------------------------------------------------------------- + * Byte offset | BIts | + * ------------------------------------------------------------------------------- + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * ------------------------------------------------------------------------------- + * 1 | F17=0 | Audio Format Code = 0001 | Max_num_channels - 1 | + * ------------------------------------------------------------------------------- + * 2 | F27=0 |192kHz |176.4kHz|96kHz |88.2kHz| 48kHz | 44.1kHz| 32kHz | + * ------------------------------------------------------------------------------- + * 3 | F37=0 | F36=0 | F35=0 | F34=0| F33=0 | 24bit | 20bit | 16bit | + * ----------------------------------------------------------------------------- + */ + pELD->ELD_Data.SAD_Count = 1; + *(pEldPayLoad++) = 0x9; //Linear PCM + *(pEldPayLoad++) = 0x7; //48kHZ, 44.1Khz, 32kHZ + *(pEldPayLoad++) = 0x3; //20 bit, 16 bit + Length += 3; + } + + pELD->ELD_Data.BaseLine_Eld_len = (16 + Length + 3) / 4; + pELD->Size = pELD->ELD_Data.BaseLine_Eld_len * 4 + 4; + + pELD->ELD_Data.FLR = GET_BIT(pMonitorAttrib->SpeakerAllocationData, 0); + pELD->ELD_Data.LFE = GET_BIT(pMonitorAttrib->SpeakerAllocationData, 1); + pELD->ELD_Data.FC = GET_BIT(pMonitorAttrib->SpeakerAllocationData, 2); + pELD->ELD_Data.RLR = GET_BIT(pMonitorAttrib->SpeakerAllocationData, 3); + pELD->ELD_Data.RC = GET_BIT(pMonitorAttrib->SpeakerAllocationData, 4); + pELD->ELD_Data.FLRC = GET_BIT(pMonitorAttrib->SpeakerAllocationData, 5); + pELD->ELD_Data.RLRC = GET_BIT(pMonitorAttrib->SpeakerAllocationData, 6); + } + + return CBIOS_OK; +} + diff --git a/drivers/gpu/drm/arise/cbios/Device/CBiosDeviceShare.h b/drivers/gpu/drm/arise/cbios/Device/CBiosDeviceShare.h new file mode 100644 index 0000000000000..ffce6bdd5d837 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/CBiosDeviceShare.h @@ -0,0 +1,149 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** Defines common function pointer for each device port. +** Defines CBIOS_DEVICE_COMMON. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_DEVICE_SHARE_H_ +#define _CBIOS_DEVICE_SHARE_H_ + +#include "CBiosShare.h" +#include "../Display/CBiosMode.h" +#include "../Util/CBiosEDID.h" +#include "Port/CBiosDSI.h" +#include "../Display/CBiosPathManager.h" +#include "Monitor/CBiosEDPPanel.h" + +#define CBIOS_MAX_DISPLAY_DEVICES_NUM 32 + +typedef CBIOS_VOID +(*PFN_cbDeviceHwInit)(PCBIOS_VOID pvcbe, PCBIOS_VOID pDevCommon); + +typedef CBIOS_BOOL +(*PFN_cbDeviceDetect)(PCBIOS_VOID pvcbe, PCBIOS_VOID pDevCommon, CBIOS_BOOL bHardcodeDetected, CBIOS_U32 FullDetect); + +typedef CBIOS_VOID +(*PFN_cbDeviceOnOff)(PCBIOS_VOID pvcbe, PCBIOS_VOID pDevCommon, CBIOS_BOOL bOn); + +typedef CBIOS_VOID +(*PFN_cbQueryMonitorAttribute)(PCBIOS_VOID pvcbe, PCBIOS_VOID pDevCommon, PCBiosMonitorAttribute pMonitorAttribute); + +typedef CBIOS_VOID +(*PFN_cbUpdateDeviceModeInfo)(PCBIOS_VOID pvcbe, PCBIOS_VOID pDevCommon, PCBIOS_VOID pModeParams); + +typedef CBIOS_VOID +(*PFN_cbDeviceSetMode)(PCBIOS_VOID pvcbe, PCBIOS_VOID pDevCommon, PCBIOS_VOID pModeParams); + +typedef struct _CBIOS_DEVICE_SIGNATURE +{ + CBIOS_U8 MonitorID[MONITORIDLENGTH]; + CBIOS_U8 ExtFlagChecksum[CBIOS_EDIDMAXBLOCKCOUNT][EXTFLAGCHECKSUMLENTH]; +}CBIOS_DEVICE_SIGNATURE, *PCBIOS_DEVICE_SIGNATURE; + +typedef struct _CBIOS_DEVICE_COMMON +{ + //Common attribute with fixed value + struct + { + CBIOS_ACTIVE_TYPE DeviceType; + CBIOS_MONITOR_TYPE SupportMonitorType; + CBIOS_U32 I2CBus; // real I2C bus used to read EDID from monitor + CBIOS_U8 HPDPin; + PCBIOS_VOID pHDCPContext; + }; + + //Common attribute with variable value + struct + { + CBIOS_MONITOR_TYPE CurrentMonitorType; + CBIOS_U8 PowerState; + CBIOS_UCHAR EdidData[CBIOS_EDIDDATABYTE]; + CBIOS_U32 TotalBlockNum; + CBIOS_EDID_STRUCTURE_DATA EdidStruct; + CBIOS_DEVICE_SIGNATURE ConnectedDevSignature; // stores the signature of real device. + CBIOS_DISPLAY_SOURCE DispSource; + CBIOS_BOOL isFakeEdid; + CBIOS_MAX_RES_CONFIG MaxResConfig; + }; + + union + { + CBIOS_DSI_PARAMS DSIDevice; + CBIOS_EDPPanel_PARAMS EDPPanelDevice; + }DeviceParas; + + //common funcs for each device port + struct + { + PFN_cbDeviceHwInit pfncbDeviceHwInit; + PFN_cbDeviceDetect pfncbDeviceDetect; + PFN_cbDeviceOnOff pfncbDeviceOnOff; + PFN_cbDeviceSetMode pfncbDeviceSetMode; + + PFN_cbQueryMonitorAttribute pfncbQueryMonitorAttribute; + PFN_cbUpdateDeviceModeInfo pfncbUpdateDeviceModeInfo; + }; +}CBIOS_DEVICE_COMMON, *PCBIOS_DEVICE_COMMON; + +typedef struct _CBIOS_DEVICE_MANAGER +{ + CBIOS_ACTIVE_TYPE SupportDevices; + CBIOS_U32 ConnectedDevices; + PCBIOS_DEVICE_COMMON pDeviceArray[CBIOS_MAX_DISPLAY_DEVICES_NUM]; +}CBIOS_DEVICE_MANAGER, *PCBIOS_DEVICE_MANAGER; + +#define cbGetDeviceCommon(pDevMgr, Device) ((pDevMgr)->pDeviceArray[cbConvertDeviceBit2Index(Device)]) + +static inline void cbInitialModuleList(PCBIOS_MODULE_LIST pModuleList) +{ + pModuleList->DPModule.Type = CBIOS_MODULE_TYPE_DP; + pModuleList->DPModule.Index = CBIOS_MODULE_INDEX_INVALID; + pModuleList->MHLModule.Type = CBIOS_MODULE_TYPE_MHL; + pModuleList->MHLModule.Index = CBIOS_MODULE_INDEX_INVALID; + pModuleList->HDCPModule.Type = CBIOS_MODULE_TYPE_HDCP; + pModuleList->HDCPModule.Index = CBIOS_MODULE_INDEX_INVALID; + pModuleList->HDMIModule.Type = CBIOS_MODULE_TYPE_HDMI; + pModuleList->HDMIModule.Index = CBIOS_MODULE_INDEX_INVALID; + pModuleList->HDTVModule.Type = CBIOS_MODULE_TYPE_HDTV; + pModuleList->HDACModule.Index = CBIOS_MODULE_INDEX_INVALID; + pModuleList->HDACModule.Type = CBIOS_MODULE_TYPE_HDAC; + pModuleList->HDTVModule.Index = CBIOS_MODULE_INDEX_INVALID; + pModuleList->IGAModule.Type = CBIOS_MODULE_TYPE_IGA; + pModuleList->IGAModule.Index = CBIOS_MODULE_INDEX_INVALID; +} + +#define IS_SUPPORT_4K_MODE 1 + +extern CBIOS_U8 FPGAHDMIEdid[256]; +#if IS_SUPPORT_4K_MODE +extern CBIOS_U8 Fake4KEdid[256]; +#endif + +CBIOS_BOOL cbGetDeviceEDID(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL *pIsDevChanged, CBIOS_U32 FullDetect); +CBIOS_BOOL cbIsDeviceChangedByEdid(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_UCHAR pEDIDData); +CBIOS_BOOL cbUpdateDeviceSignature(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +CBIOS_MONITOR_TYPE cbGetSupportMonitorType(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE devices); +CBIOS_VOID cbClearEdidRelatedData(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +CBIOS_BOOL cbDualModeDetect(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +PCBIOS_VOID cbGetDPMonitorContext(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +PCBIOS_VOID cbGetHDMIMonitorContext(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +CBIOS_STATUS cbGetDeviceELD(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE DeviceType, PCBIOS_ELD_MEM_STRUCT pELD); +#endif diff --git a/drivers/gpu/drm/arise/cbios/Device/CBiosReg.h b/drivers/gpu/drm/arise/cbios/Device/CBiosReg.h new file mode 100644 index 0000000000000..508e35615a40a --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/CBiosReg.h @@ -0,0 +1,2629 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios CR, SR groups register macro definition +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_REG_H_ +#define _CBIOS_REG_H_ + +typedef enum _CBIOS_REGISTER_TYPE +{ + CR=0, /*CR registers */ + SR, /*SR registers */ + AR, + GR, + MISC, + CR_B, /* B-set of CR */ + CR_C, /* C-set of CR */ + CR_D, /* D-set of CR */ + CR_T, /* CR on IGA3 */ + SR_T, /* SR on IGA3 */ + SR_B, + CR_D_0, + CR_D_1, + CR_D_2, + CR_D_3, + CR_F, + SR_F, + RESERVED=0xFF +} CBIOS_REGISTER_TYPE; + +typedef struct _CBIOS_PARALLEL_REGISTER +{ + const CBIOS_U32 RegNameIndex; + CBIOS_U32 RegIndex[4]; +} CBIOS_PARALLEL_REGISTER, *PCBIOS_PARALLEL_REGISTER; + +#define CR_00 (CR<<8)|0x00 +#define CR_01 (CR<<8)|0x01 +#define CR_02 (CR<<8)|0x02 +#define CR_03 (CR<<8)|0x03 +#define CR_04 (CR<<8)|0x04 +#define CR_05 (CR<<8)|0x05 +#define CR_06 (CR<<8)|0x06 +#define CR_07 (CR<<8)|0x07 +#define CR_08 (CR<<8)|0x08 +#define CR_09 (CR<<8)|0x09 +#define CR_0A (CR<<8)|0x0A +#define CR_0B (CR<<8)|0x0B +#define CR_0C (CR<<8)|0x0C +#define CR_0D (CR<<8)|0x0D +#define CR_0E (CR<<8)|0x0E +#define CR_0F (CR<<8)|0x0F +#define CR_10 (CR<<8)|0x10 +#define CR_11 (CR<<8)|0x11 +#define CR_12 (CR<<8)|0x12 +#define CR_13 (CR<<8)|0x13 +#define CR_14 (CR<<8)|0x14 +#define CR_15 (CR<<8)|0x15 +#define CR_16 (CR<<8)|0x16 +#define CR_17 (CR<<8)|0x17 +#define CR_18 (CR<<8)|0x18 +#define CR_19 (CR<<8)|0x19 +#define CR_1A (CR<<8)|0x1A +#define CR_1B (CR<<8)|0x1B +#define CR_1C (CR<<8)|0x1C +#define CR_1D (CR<<8)|0x1D +#define CR_1E (CR<<8)|0x1E +#define CR_1F (CR<<8)|0x1F +#define CR_20 (CR<<8)|0x20 +#define CR_21 (CR<<8)|0x21 +#define CR_22 (CR<<8)|0x22 +#define CR_23 (CR<<8)|0x23 +#define CR_24 (CR<<8)|0x24 +#define CR_25 (CR<<8)|0x25 +#define CR_26 (CR<<8)|0x26 +#define CR_27 (CR<<8)|0x27 +#define CR_28 (CR<<8)|0x28 +#define CR_29 (CR<<8)|0x29 +#define CR_2A (CR<<8)|0x2A +#define CR_2B (CR<<8)|0x2B +#define CR_2C (CR<<8)|0x2C +#define CR_2D (CR<<8)|0x2D +#define CR_2E (CR<<8)|0x2E +#define CR_2F (CR<<8)|0x2F +#define CR_30 (CR<<8)|0x30 +#define CR_31 (CR<<8)|0x31 +#define CR_32 (CR<<8)|0x32 +#define CR_33 (CR<<8)|0x33 +#define CR_34 (CR<<8)|0x34 +#define CR_35 (CR<<8)|0x35 +#define CR_36 (CR<<8)|0x36 +#define CR_37 (CR<<8)|0x37 +#define CR_38 (CR<<8)|0x38 +#define CR_39 (CR<<8)|0x39 +#define CR_3A (CR<<8)|0x3A +#define CR_3B (CR<<8)|0x3B +#define CR_3C (CR<<8)|0x3C +#define CR_3D (CR<<8)|0x3D +#define CR_3E (CR<<8)|0x3E +#define CR_3F (CR<<8)|0x3F +#define CR_40 (CR<<8)|0x40 +#define CR_41 (CR<<8)|0x41 +#define CR_42 (CR<<8)|0x42 +#define CR_43 (CR<<8)|0x43 +#define CR_44 (CR<<8)|0x44 +#define CR_45 (CR<<8)|0x45 +#define CR_46 (CR<<8)|0x46 +#define CR_47 (CR<<8)|0x47 +#define CR_48 (CR<<8)|0x48 +#define CR_49 (CR<<8)|0x49 +#define CR_4A (CR<<8)|0x4A +#define CR_4B (CR<<8)|0x4B +#define CR_4C (CR<<8)|0x4C +#define CR_4D (CR<<8)|0x4D +#define CR_4E (CR<<8)|0x4E +#define CR_4F (CR<<8)|0x4F +#define CR_50 (CR<<8)|0x50 +#define CR_51 (CR<<8)|0x51 +#define CR_52 (CR<<8)|0x52 +#define CR_53 (CR<<8)|0x53 +#define CR_54 (CR<<8)|0x54 +#define CR_55 (CR<<8)|0x55 +#define CR_56 (CR<<8)|0x56 +#define CR_57 (CR<<8)|0x57 +#define CR_58 (CR<<8)|0x58 +#define CR_59 (CR<<8)|0x59 +#define CR_5A (CR<<8)|0x5A +#define CR_5B (CR<<8)|0x5B +#define CR_5C (CR<<8)|0x5C +#define CR_5D (CR<<8)|0x5D +#define CR_5E (CR<<8)|0x5E +#define CR_5F (CR<<8)|0x5F +#define CR_60 (CR<<8)|0x60 +#define CR_61 (CR<<8)|0x61 +#define CR_62 (CR<<8)|0x62 +#define CR_63 (CR<<8)|0x63 +#define CR_64 (CR<<8)|0x64 +#define CR_65 (CR<<8)|0x65 +#define CR_66 (CR<<8)|0x66 +#define CR_67 (CR<<8)|0x67 +#define CR_68 (CR<<8)|0x68 +#define CR_69 (CR<<8)|0x69 +#define CR_6A (CR<<8)|0x6A +#define CR_6B (CR<<8)|0x6B +#define CR_6C (CR<<8)|0x6C +#define CR_6D (CR<<8)|0x6D +#define CR_6E (CR<<8)|0x6E +#define CR_6F (CR<<8)|0x6F +#define CR_70 (CR<<8)|0x70 +#define CR_71 (CR<<8)|0x71 +#define CR_72 (CR<<8)|0x72 +#define CR_73 (CR<<8)|0x73 +#define CR_74 (CR<<8)|0x74 +#define CR_75 (CR<<8)|0x75 +#define CR_76 (CR<<8)|0x76 +#define CR_77 (CR<<8)|0x77 +#define CR_78 (CR<<8)|0x78 +#define CR_79 (CR<<8)|0x79 +#define CR_7A (CR<<8)|0x7A +#define CR_7B (CR<<8)|0x7B +#define CR_7C (CR<<8)|0x7C +#define CR_7D (CR<<8)|0x7D +#define CR_7E (CR<<8)|0x7E +#define CR_7F (CR<<8)|0x7F +#define CR_80 (CR<<8)|0x80 +#define CR_81 (CR<<8)|0x81 +#define CR_82 (CR<<8)|0x82 +#define CR_83 (CR<<8)|0x83 +#define CR_84 (CR<<8)|0x84 +#define CR_85 (CR<<8)|0x85 +#define CR_86 (CR<<8)|0x86 +#define CR_87 (CR<<8)|0x87 +#define CR_88 (CR<<8)|0x88 +#define CR_89 (CR<<8)|0x89 +#define CR_8A (CR<<8)|0x8A +#define CR_8B (CR<<8)|0x8B +#define CR_8C (CR<<8)|0x8C +#define CR_8D (CR<<8)|0x8D +#define CR_8E (CR<<8)|0x8E +#define CR_8F (CR<<8)|0x8F +#define CR_90 (CR<<8)|0x90 +#define CR_91 (CR<<8)|0x91 +#define CR_92 (CR<<8)|0x92 +#define CR_93 (CR<<8)|0x93 +#define CR_94 (CR<<8)|0x94 +#define CR_95 (CR<<8)|0x95 +#define CR_96 (CR<<8)|0x96 +#define CR_97 (CR<<8)|0x97 +#define CR_98 (CR<<8)|0x98 +#define CR_99 (CR<<8)|0x99 +#define CR_9A (CR<<8)|0x9A +#define CR_9B (CR<<8)|0x9B +#define CR_9C (CR<<8)|0x9C +#define CR_9D (CR<<8)|0x9D +#define CR_9E (CR<<8)|0x9E +#define CR_9F (CR<<8)|0x9F +#define CR_A0 (CR<<8)|0xA0 +#define CR_A1 (CR<<8)|0xA1 +#define CR_A2 (CR<<8)|0xA2 +#define CR_A3 (CR<<8)|0xA3 +#define CR_A4 (CR<<8)|0xA4 +#define CR_A5 (CR<<8)|0xA5 +#define CR_A6 (CR<<8)|0xA6 +#define CR_A7 (CR<<8)|0xA7 +#define CR_A8 (CR<<8)|0xA8 +#define CR_A9 (CR<<8)|0xA9 +#define CR_AA (CR<<8)|0xAA +#define CR_AB (CR<<8)|0xAB +#define CR_AC (CR<<8)|0xAC +#define CR_AD (CR<<8)|0xAD +#define CR_AE (CR<<8)|0xAE +#define CR_AF (CR<<8)|0xAF +#define CR_B0 (CR<<8)|0xB0 +#define CR_B1 (CR<<8)|0xB1 +#define CR_B2 (CR<<8)|0xB2 +#define CR_B3 (CR<<8)|0xB3 +#define CR_B4 (CR<<8)|0xB4 +#define CR_B5 (CR<<8)|0xB5 +#define CR_B6 (CR<<8)|0xB6 +#define CR_B7 (CR<<8)|0xB7 +#define CR_B8 (CR<<8)|0xB8 +#define CR_B9 (CR<<8)|0xB9 +#define CR_BA (CR<<8)|0xBA +#define CR_BB (CR<<8)|0xBB +#define CR_BC (CR<<8)|0xBC +#define CR_BD (CR<<8)|0xBD +#define CR_BE (CR<<8)|0xBE +#define CR_BF (CR<<8)|0xBF +#define CR_C0 (CR<<8)|0xC0 +#define CR_C1 (CR<<8)|0xC1 +#define CR_C2 (CR<<8)|0xC2 +#define CR_C3 (CR<<8)|0xC3 +#define CR_C4 (CR<<8)|0xC4 +#define CR_C5 (CR<<8)|0xC5 +#define CR_C6 (CR<<8)|0xC6 +#define CR_C7 (CR<<8)|0xC7 +#define CR_C8 (CR<<8)|0xC8 +#define CR_C9 (CR<<8)|0xC9 +#define CR_CA (CR<<8)|0xCA +#define CR_CB (CR<<8)|0xCB +#define CR_CC (CR<<8)|0xCC +#define CR_CD (CR<<8)|0xCD +#define CR_CE (CR<<8)|0xCE +#define CR_CF (CR<<8)|0xCF +#define CR_D0 (CR<<8)|0xD0 +#define CR_D1 (CR<<8)|0xD1 +#define CR_D2 (CR<<8)|0xD2 +#define CR_D3 (CR<<8)|0xD3 +#define CR_D4 (CR<<8)|0xD4 +#define CR_D5 (CR<<8)|0xD5 +#define CR_D6 (CR<<8)|0xD6 +#define CR_D7 (CR<<8)|0xD7 +#define CR_D8 (CR<<8)|0xD8 +#define CR_D9 (CR<<8)|0xD9 +#define CR_DA (CR<<8)|0xDA +#define CR_DB (CR<<8)|0xDB +#define CR_DC (CR<<8)|0xDC +#define CR_DD (CR<<8)|0xDD +#define CR_DE (CR<<8)|0xDE +#define CR_DF (CR<<8)|0xDF +#define CR_E0 (CR<<8)|0xE0 +#define CR_E1 (CR<<8)|0xE1 +#define CR_E2 (CR<<8)|0xE2 +#define CR_E3 (CR<<8)|0xE3 +#define CR_E4 (CR<<8)|0xE4 +#define CR_E5 (CR<<8)|0xE5 +#define CR_E6 (CR<<8)|0xE6 +#define CR_E7 (CR<<8)|0xE7 +#define CR_E8 (CR<<8)|0xE8 +#define CR_E9 (CR<<8)|0xE9 +#define CR_EA (CR<<8)|0xEA +#define CR_EB (CR<<8)|0xEB +#define CR_EC (CR<<8)|0xEC +#define CR_ED (CR<<8)|0xED +#define CR_EE (CR<<8)|0xEE +#define CR_EF (CR<<8)|0xEF +#define CR_F0 (CR<<8)|0xF0 +#define CR_F1 (CR<<8)|0xF1 +#define CR_F2 (CR<<8)|0xF2 +#define CR_F3 (CR<<8)|0xF3 +#define CR_F4 (CR<<8)|0xF4 +#define CR_F5 (CR<<8)|0xF5 +#define CR_F6 (CR<<8)|0xF6 +#define CR_F7 (CR<<8)|0xF7 +#define CR_F8 (CR<<8)|0xF8 +#define CR_F9 (CR<<8)|0xF9 +#define CR_FA (CR<<8)|0xFA +#define CR_FB (CR<<8)|0xFB +#define CR_FC (CR<<8)|0xFC +#define CR_FD (CR<<8)|0xFD +#define CR_FE (CR<<8)|0xFE +#define CR_FF (CR<<8)|0xFF + +#define SR_00 (SR<<8)|0x00 +#define SR_01 (SR<<8)|0x01 +#define SR_02 (SR<<8)|0x02 +#define SR_03 (SR<<8)|0x03 +#define SR_04 (SR<<8)|0x04 +#define SR_05 (SR<<8)|0x05 +#define SR_06 (SR<<8)|0x06 +#define SR_07 (SR<<8)|0x07 +#define SR_08 (SR<<8)|0x08 +#define SR_09 (SR<<8)|0x09 +#define SR_0A (SR<<8)|0x0A +#define SR_0B (SR<<8)|0x0B +#define SR_0C (SR<<8)|0x0C +#define SR_0D (SR<<8)|0x0D +#define SR_0E (SR<<8)|0x0E +#define SR_0F (SR<<8)|0x0F +#define SR_10 (SR<<8)|0x10 +#define SR_11 (SR<<8)|0x11 +#define SR_12 (SR<<8)|0x12 +#define SR_13 (SR<<8)|0x13 +#define SR_14 (SR<<8)|0x14 +#define SR_15 (SR<<8)|0x15 +#define SR_16 (SR<<8)|0x16 +#define SR_17 (SR<<8)|0x17 +#define SR_18 (SR<<8)|0x18 +#define SR_19 (SR<<8)|0x19 +#define SR_1A (SR<<8)|0x1A +#define SR_1B (SR<<8)|0x1B +#define SR_1C (SR<<8)|0x1C +#define SR_1D (SR<<8)|0x1D +#define SR_1E (SR<<8)|0x1E +#define SR_1F (SR<<8)|0x1F +#define SR_20 (SR<<8)|0x20 +#define SR_21 (SR<<8)|0x21 +#define SR_22 (SR<<8)|0x22 +#define SR_23 (SR<<8)|0x23 +#define SR_24 (SR<<8)|0x24 +#define SR_25 (SR<<8)|0x25 +#define SR_26 (SR<<8)|0x26 +#define SR_27 (SR<<8)|0x27 +#define SR_28 (SR<<8)|0x28 +#define SR_29 (SR<<8)|0x29 +#define SR_2A (SR<<8)|0x2A +#define SR_2B (SR<<8)|0x2B +#define SR_2C (SR<<8)|0x2C +#define SR_2D (SR<<8)|0x2D +#define SR_2E (SR<<8)|0x2E +#define SR_2F (SR<<8)|0x2F +#define SR_30 (SR<<8)|0x30 +#define SR_31 (SR<<8)|0x31 +#define SR_32 (SR<<8)|0x32 +#define SR_33 (SR<<8)|0x33 +#define SR_34 (SR<<8)|0x34 +#define SR_35 (SR<<8)|0x35 +#define SR_36 (SR<<8)|0x36 +#define SR_37 (SR<<8)|0x37 +#define SR_38 (SR<<8)|0x38 +#define SR_39 (SR<<8)|0x39 +#define SR_3A (SR<<8)|0x3A +#define SR_3B (SR<<8)|0x3B +#define SR_3C (SR<<8)|0x3C +#define SR_3D (SR<<8)|0x3D +#define SR_3E (SR<<8)|0x3E +#define SR_3F (SR<<8)|0x3F +#define SR_40 (SR<<8)|0x40 +#define SR_41 (SR<<8)|0x41 +#define SR_42 (SR<<8)|0x42 +#define SR_43 (SR<<8)|0x43 +#define SR_44 (SR<<8)|0x44 +#define SR_45 (SR<<8)|0x45 +#define SR_46 (SR<<8)|0x46 +#define SR_47 (SR<<8)|0x47 +#define SR_48 (SR<<8)|0x48 +#define SR_49 (SR<<8)|0x49 +#define SR_4A (SR<<8)|0x4A +#define SR_4B (SR<<8)|0x4B +#define SR_4C (SR<<8)|0x4C +#define SR_4D (SR<<8)|0x4D +#define SR_4E (SR<<8)|0x4E +#define SR_4F (SR<<8)|0x4F +#define SR_50 (SR<<8)|0x50 +#define SR_51 (SR<<8)|0x51 +#define SR_52 (SR<<8)|0x52 +#define SR_53 (SR<<8)|0x53 +#define SR_54 (SR<<8)|0x54 +#define SR_55 (SR<<8)|0x55 +#define SR_56 (SR<<8)|0x56 +#define SR_57 (SR<<8)|0x57 +#define SR_58 (SR<<8)|0x58 +#define SR_59 (SR<<8)|0x59 +#define SR_5A (SR<<8)|0x5A +#define SR_5B (SR<<8)|0x5B +#define SR_5C (SR<<8)|0x5C +#define SR_5D (SR<<8)|0x5D +#define SR_5E (SR<<8)|0x5E +#define SR_5F (SR<<8)|0x5F +#define SR_60 (SR<<8)|0x60 +#define SR_61 (SR<<8)|0x61 +#define SR_62 (SR<<8)|0x62 +#define SR_63 (SR<<8)|0x63 +#define SR_64 (SR<<8)|0x64 +#define SR_65 (SR<<8)|0x65 +#define SR_66 (SR<<8)|0x66 +#define SR_67 (SR<<8)|0x67 +#define SR_68 (SR<<8)|0x68 +#define SR_69 (SR<<8)|0x69 +#define SR_6A (SR<<8)|0x6A +#define SR_6B (SR<<8)|0x6B +#define SR_6C (SR<<8)|0x6C +#define SR_6D (SR<<8)|0x6D +#define SR_6E (SR<<8)|0x6E +#define SR_6F (SR<<8)|0x6F +#define SR_70 (SR<<8)|0x70 +#define SR_71 (SR<<8)|0x71 +#define SR_72 (SR<<8)|0x72 +#define SR_73 (SR<<8)|0x73 +#define SR_74 (SR<<8)|0x74 +#define SR_75 (SR<<8)|0x75 +#define SR_76 (SR<<8)|0x76 +#define SR_77 (SR<<8)|0x77 +#define SR_78 (SR<<8)|0x78 +#define SR_79 (SR<<8)|0x79 +#define SR_7A (SR<<8)|0x7A +#define SR_7B (SR<<8)|0x7B +#define SR_7C (SR<<8)|0x7C +#define SR_7D (SR<<8)|0x7D +#define SR_7E (SR<<8)|0x7E +#define SR_7F (SR<<8)|0x7F +#define SR_80 (SR<<8)|0x80 +#define SR_81 (SR<<8)|0x81 +#define SR_82 (SR<<8)|0x82 +#define SR_83 (SR<<8)|0x83 +#define SR_84 (SR<<8)|0x84 +#define SR_85 (SR<<8)|0x85 +#define SR_86 (SR<<8)|0x86 +#define SR_87 (SR<<8)|0x87 +#define SR_88 (SR<<8)|0x88 +#define SR_89 (SR<<8)|0x89 +#define SR_8A (SR<<8)|0x8A +#define SR_8B (SR<<8)|0x8B +#define SR_8C (SR<<8)|0x8C +#define SR_8D (SR<<8)|0x8D +#define SR_8E (SR<<8)|0x8E +#define SR_8F (SR<<8)|0x8F +#define SR_90 (SR<<8)|0x90 +#define SR_91 (SR<<8)|0x91 +#define SR_92 (SR<<8)|0x92 +#define SR_93 (SR<<8)|0x93 +#define SR_94 (SR<<8)|0x94 +#define SR_95 (SR<<8)|0x95 +#define SR_96 (SR<<8)|0x96 +#define SR_97 (SR<<8)|0x97 +#define SR_98 (SR<<8)|0x98 +#define SR_99 (SR<<8)|0x99 +#define SR_9A (SR<<8)|0x9A +#define SR_9B (SR<<8)|0x9B +#define SR_9C (SR<<8)|0x9C +#define SR_9D (SR<<8)|0x9D +#define SR_9E (SR<<8)|0x9E +#define SR_9F (SR<<8)|0x9F +#define SR_A0 (SR<<8)|0xA0 +#define SR_A1 (SR<<8)|0xA1 +#define SR_A2 (SR<<8)|0xA2 +#define SR_A3 (SR<<8)|0xA3 +#define SR_A4 (SR<<8)|0xA4 +#define SR_A5 (SR<<8)|0xA5 +#define SR_A6 (SR<<8)|0xA6 +#define SR_A7 (SR<<8)|0xA7 +#define SR_A8 (SR<<8)|0xA8 +#define SR_A9 (SR<<8)|0xA9 +#define SR_AA (SR<<8)|0xAA +#define SR_AB (SR<<8)|0xAB +#define SR_AC (SR<<8)|0xAC +#define SR_AD (SR<<8)|0xAD +#define SR_AE (SR<<8)|0xAE +#define SR_AF (SR<<8)|0xAF +#define SR_B0 (SR<<8)|0xB0 +#define SR_B1 (SR<<8)|0xB1 +#define SR_B2 (SR<<8)|0xB2 +#define SR_B3 (SR<<8)|0xB3 +#define SR_B4 (SR<<8)|0xB4 +#define SR_B5 (SR<<8)|0xB5 +#define SR_B6 (SR<<8)|0xB6 +#define SR_B7 (SR<<8)|0xB7 +#define SR_B8 (SR<<8)|0xB8 +#define SR_B9 (SR<<8)|0xB9 +#define SR_BA (SR<<8)|0xBA +#define SR_BB (SR<<8)|0xBB +#define SR_BC (SR<<8)|0xBC +#define SR_BD (SR<<8)|0xBD +#define SR_BE (SR<<8)|0xBE +#define SR_BF (SR<<8)|0xBF +#define SR_C0 (SR<<8)|0xC0 +#define SR_C1 (SR<<8)|0xC1 +#define SR_C2 (SR<<8)|0xC2 +#define SR_C3 (SR<<8)|0xC3 +#define SR_C4 (SR<<8)|0xC4 +#define SR_C5 (SR<<8)|0xC5 +#define SR_C6 (SR<<8)|0xC6 +#define SR_C7 (SR<<8)|0xC7 +#define SR_C8 (SR<<8)|0xC8 +#define SR_C9 (SR<<8)|0xC9 +#define SR_CA (SR<<8)|0xCA +#define SR_CB (SR<<8)|0xCB +#define SR_CC (SR<<8)|0xCC +#define SR_CD (SR<<8)|0xCD +#define SR_CE (SR<<8)|0xCE +#define SR_CF (SR<<8)|0xCF +#define SR_D0 (SR<<8)|0xD0 +#define SR_D1 (SR<<8)|0xD1 +#define SR_D2 (SR<<8)|0xD2 +#define SR_D3 (SR<<8)|0xD3 +#define SR_D4 (SR<<8)|0xD4 +#define SR_D5 (SR<<8)|0xD5 +#define SR_D6 (SR<<8)|0xD6 +#define SR_D7 (SR<<8)|0xD7 +#define SR_D8 (SR<<8)|0xD8 +#define SR_D9 (SR<<8)|0xD9 +#define SR_DA (SR<<8)|0xDA +#define SR_DB (SR<<8)|0xDB +#define SR_DC (SR<<8)|0xDC +#define SR_DD (SR<<8)|0xDD +#define SR_DE (SR<<8)|0xDE +#define SR_DF (SR<<8)|0xDF +#define SR_E0 (SR<<8)|0xE0 +#define SR_E1 (SR<<8)|0xE1 +#define SR_E2 (SR<<8)|0xE2 +#define SR_E3 (SR<<8)|0xE3 +#define SR_E4 (SR<<8)|0xE4 +#define SR_E5 (SR<<8)|0xE5 +#define SR_E6 (SR<<8)|0xE6 +#define SR_E7 (SR<<8)|0xE7 +#define SR_E8 (SR<<8)|0xE8 +#define SR_E9 (SR<<8)|0xE9 +#define SR_EA (SR<<8)|0xEA +#define SR_EB (SR<<8)|0xEB +#define SR_EC (SR<<8)|0xEC +#define SR_ED (SR<<8)|0xED +#define SR_EE (SR<<8)|0xEE +#define SR_EF (SR<<8)|0xEF +#define SR_F0 (SR<<8)|0xF0 +#define SR_F1 (SR<<8)|0xF1 +#define SR_F2 (SR<<8)|0xF2 +#define SR_F3 (SR<<8)|0xF3 +#define SR_F4 (SR<<8)|0xF4 +#define SR_F5 (SR<<8)|0xF5 +#define SR_F6 (SR<<8)|0xF6 +#define SR_F7 (SR<<8)|0xF7 +#define SR_F8 (SR<<8)|0xF8 +#define SR_F9 (SR<<8)|0xF9 +#define SR_FA (SR<<8)|0xFA +#define SR_FB (SR<<8)|0xFB +#define SR_FC (SR<<8)|0xFC +#define SR_FD (SR<<8)|0xFD +#define SR_FE (SR<<8)|0xFE +#define SR_FF (SR<<8)|0xFF + +#define SR_T_00 (SR_T<<8)|0x00 +#define SR_T_01 (SR_T<<8)|0x01 +#define SR_T_02 (SR_T<<8)|0x02 +#define SR_T_03 (SR_T<<8)|0x03 +#define SR_T_04 (SR_T<<8)|0x04 +#define SR_T_05 (SR_T<<8)|0x05 +#define SR_T_06 (SR_T<<8)|0x06 +#define SR_T_07 (SR_T<<8)|0x07 +#define SR_T_08 (SR_T<<8)|0x08 +#define SR_T_09 (SR_T<<8)|0x09 +#define SR_T_0A (SR_T<<8)|0x0A +#define SR_T_0B (SR_T<<8)|0x0B +#define SR_T_0C (SR_T<<8)|0x0C +#define SR_T_0D (SR_T<<8)|0x0D +#define SR_T_0E (SR_T<<8)|0x0E +#define SR_T_0F (SR_T<<8)|0x0F +#define SR_T_10 (SR_T<<8)|0x10 +#define SR_T_11 (SR_T<<8)|0x11 +#define SR_T_12 (SR_T<<8)|0x12 +#define SR_T_13 (SR_T<<8)|0x13 +#define SR_T_14 (SR_T<<8)|0x14 +#define SR_T_15 (SR_T<<8)|0x15 +#define SR_T_16 (SR_T<<8)|0x16 +#define SR_T_17 (SR_T<<8)|0x17 +#define SR_T_18 (SR_T<<8)|0x18 +#define SR_T_19 (SR_T<<8)|0x19 +#define SR_T_1A (SR_T<<8)|0x1A +#define SR_T_1B (SR_T<<8)|0x1B +#define SR_T_1C (SR_T<<8)|0x1C +#define SR_T_1D (SR_T<<8)|0x1D +#define SR_T_1E (SR_T<<8)|0x1E +#define SR_T_1F (SR_T<<8)|0x1F +#define SR_T_20 (SR_T<<8)|0x20 +#define SR_T_21 (SR_T<<8)|0x21 +#define SR_T_22 (SR_T<<8)|0x22 +#define SR_T_23 (SR_T<<8)|0x23 +#define SR_T_24 (SR_T<<8)|0x24 +#define SR_T_25 (SR_T<<8)|0x25 +#define SR_T_26 (SR_T<<8)|0x26 +#define SR_T_27 (SR_T<<8)|0x27 +#define SR_T_28 (SR_T<<8)|0x28 +#define SR_T_29 (SR_T<<8)|0x29 +#define SR_T_2A (SR_T<<8)|0x2A +#define SR_T_2B (SR_T<<8)|0x2B +#define SR_T_2C (SR_T<<8)|0x2C +#define SR_T_2D (SR_T<<8)|0x2D +#define SR_T_2E (SR_T<<8)|0x2E +#define SR_T_2F (SR_T<<8)|0x2F +#define SR_T_30 (SR_T<<8)|0x30 +#define SR_T_31 (SR_T<<8)|0x31 +#define SR_T_32 (SR_T<<8)|0x32 +#define SR_T_33 (SR_T<<8)|0x33 +#define SR_T_34 (SR_T<<8)|0x34 +#define SR_T_35 (SR_T<<8)|0x35 +#define SR_T_36 (SR_T<<8)|0x36 +#define SR_T_37 (SR_T<<8)|0x37 +#define SR_T_38 (SR_T<<8)|0x38 +#define SR_T_39 (SR_T<<8)|0x39 +#define SR_T_3A (SR_T<<8)|0x3A +#define SR_T_3B (SR_T<<8)|0x3B +#define SR_T_3C (SR_T<<8)|0x3C +#define SR_T_3D (SR_T<<8)|0x3D +#define SR_T_3E (SR_T<<8)|0x3E +#define SR_T_3F (SR_T<<8)|0x3F +#define SR_T_40 (SR_T<<8)|0x40 +#define SR_T_41 (SR_T<<8)|0x41 +#define SR_T_42 (SR_T<<8)|0x42 +#define SR_T_43 (SR_T<<8)|0x43 +#define SR_T_44 (SR_T<<8)|0x44 +#define SR_T_45 (SR_T<<8)|0x45 +#define SR_T_46 (SR_T<<8)|0x46 +#define SR_T_47 (SR_T<<8)|0x47 +#define SR_T_48 (SR_T<<8)|0x48 +#define SR_T_49 (SR_T<<8)|0x49 +#define SR_T_4A (SR_T<<8)|0x4A +#define SR_T_4B (SR_T<<8)|0x4B +#define SR_T_4C (SR_T<<8)|0x4C +#define SR_T_4D (SR_T<<8)|0x4D +#define SR_T_4E (SR_T<<8)|0x4E +#define SR_T_4F (SR_T<<8)|0x4F +#define SR_T_50 (SR_T<<8)|0x50 +#define SR_T_51 (SR_T<<8)|0x51 +#define SR_T_52 (SR_T<<8)|0x52 +#define SR_T_53 (SR_T<<8)|0x53 +#define SR_T_54 (SR_T<<8)|0x54 +#define SR_T_55 (SR_T<<8)|0x55 +#define SR_T_56 (SR_T<<8)|0x56 +#define SR_T_57 (SR_T<<8)|0x57 +#define SR_T_58 (SR_T<<8)|0x58 +#define SR_T_59 (SR_T<<8)|0x59 +#define SR_T_5A (SR_T<<8)|0x5A +#define SR_T_5B (SR_T<<8)|0x5B +#define SR_T_5C (SR_T<<8)|0x5C +#define SR_T_5D (SR_T<<8)|0x5D +#define SR_T_5E (SR_T<<8)|0x5E +#define SR_T_5F (SR_T<<8)|0x5F +#define SR_T_60 (SR_T<<8)|0x60 +#define SR_T_61 (SR_T<<8)|0x61 +#define SR_T_62 (SR_T<<8)|0x62 +#define SR_T_63 (SR_T<<8)|0x63 +#define SR_T_64 (SR_T<<8)|0x64 +#define SR_T_65 (SR_T<<8)|0x65 +#define SR_T_66 (SR_T<<8)|0x66 +#define SR_T_67 (SR_T<<8)|0x67 +#define SR_T_68 (SR_T<<8)|0x68 +#define SR_T_69 (SR_T<<8)|0x69 +#define SR_T_6A (SR_T<<8)|0x6A +#define SR_T_6B (SR_T<<8)|0x6B +#define SR_T_6C (SR_T<<8)|0x6C +#define SR_T_6D (SR_T<<8)|0x6D +#define SR_T_6E (SR_T<<8)|0x6E +#define SR_T_6F (SR_T<<8)|0x6F +#define SR_T_70 (SR_T<<8)|0x70 +#define SR_T_71 (SR_T<<8)|0x71 +#define SR_T_72 (SR_T<<8)|0x72 +#define SR_T_73 (SR_T<<8)|0x73 +#define SR_T_74 (SR_T<<8)|0x74 +#define SR_T_75 (SR_T<<8)|0x75 +#define SR_T_76 (SR_T<<8)|0x76 +#define SR_T_77 (SR_T<<8)|0x77 +#define SR_T_78 (SR_T<<8)|0x78 +#define SR_T_79 (SR_T<<8)|0x79 +#define SR_T_7A (SR_T<<8)|0x7A +#define SR_T_7B (SR_T<<8)|0x7B +#define SR_T_7C (SR_T<<8)|0x7C +#define SR_T_7D (SR_T<<8)|0x7D +#define SR_T_7E (SR_T<<8)|0x7E +#define SR_T_7F (SR_T<<8)|0x7F +#define SR_T_80 (SR_T<<8)|0x80 +#define SR_T_81 (SR_T<<8)|0x81 +#define SR_T_82 (SR_T<<8)|0x82 +#define SR_T_83 (SR_T<<8)|0x83 +#define SR_T_84 (SR_T<<8)|0x84 +#define SR_T_85 (SR_T<<8)|0x85 +#define SR_T_86 (SR_T<<8)|0x86 +#define SR_T_87 (SR_T<<8)|0x87 +#define SR_T_88 (SR_T<<8)|0x88 +#define SR_T_89 (SR_T<<8)|0x89 +#define SR_T_8A (SR_T<<8)|0x8A +#define SR_T_8B (SR_T<<8)|0x8B +#define SR_T_8C (SR_T<<8)|0x8C +#define SR_T_8D (SR_T<<8)|0x8D +#define SR_T_8E (SR_T<<8)|0x8E +#define SR_T_8F (SR_T<<8)|0x8F +#define SR_T_90 (SR_T<<8)|0x90 +#define SR_T_91 (SR_T<<8)|0x91 +#define SR_T_92 (SR_T<<8)|0x92 +#define SR_T_93 (SR_T<<8)|0x93 +#define SR_T_94 (SR_T<<8)|0x94 +#define SR_T_95 (SR_T<<8)|0x95 +#define SR_T_96 (SR_T<<8)|0x96 +#define SR_T_97 (SR_T<<8)|0x97 +#define SR_T_98 (SR_T<<8)|0x98 +#define SR_T_99 (SR_T<<8)|0x99 +#define SR_T_9A (SR_T<<8)|0x9A +#define SR_T_9B (SR_T<<8)|0x9B +#define SR_T_9C (SR_T<<8)|0x9C +#define SR_T_9D (SR_T<<8)|0x9D +#define SR_T_9E (SR_T<<8)|0x9E +#define SR_T_9F (SR_T<<8)|0x9F +#define SR_T_A0 (SR_T<<8)|0xA0 +#define SR_T_A1 (SR_T<<8)|0xA1 +#define SR_T_A2 (SR_T<<8)|0xA2 +#define SR_T_A3 (SR_T<<8)|0xA3 +#define SR_T_A4 (SR_T<<8)|0xA4 +#define SR_T_A5 (SR_T<<8)|0xA5 +#define SR_T_A6 (SR_T<<8)|0xA6 +#define SR_T_A7 (SR_T<<8)|0xA7 +#define SR_T_A8 (SR_T<<8)|0xA8 +#define SR_T_A9 (SR_T<<8)|0xA9 +#define SR_T_AA (SR_T<<8)|0xAA +#define SR_T_AB (SR_T<<8)|0xAB +#define SR_T_AC (SR_T<<8)|0xAC +#define SR_T_AD (SR_T<<8)|0xAD +#define SR_T_AE (SR_T<<8)|0xAE +#define SR_T_AF (SR_T<<8)|0xAF +#define SR_T_B0 (SR_T<<8)|0xB0 +#define SR_T_B1 (SR_T<<8)|0xB1 +#define SR_T_B2 (SR_T<<8)|0xB2 +#define SR_T_B3 (SR_T<<8)|0xB3 +#define SR_T_B4 (SR_T<<8)|0xB4 +#define SR_T_B5 (SR_T<<8)|0xB5 +#define SR_T_B6 (SR_T<<8)|0xB6 +#define SR_T_B7 (SR_T<<8)|0xB7 +#define SR_T_B8 (SR_T<<8)|0xB8 +#define SR_T_B9 (SR_T<<8)|0xB9 +#define SR_T_BA (SR_T<<8)|0xBA +#define SR_T_BB (SR_T<<8)|0xBB +#define SR_T_BC (SR_T<<8)|0xBC +#define SR_T_BD (SR_T<<8)|0xBD +#define SR_T_BE (SR_T<<8)|0xBE +#define SR_T_BF (SR_T<<8)|0xBF +#define SR_T_C0 (SR_T<<8)|0xC0 +#define SR_T_C1 (SR_T<<8)|0xC1 +#define SR_T_C2 (SR_T<<8)|0xC2 +#define SR_T_C3 (SR_T<<8)|0xC3 +#define SR_T_C4 (SR_T<<8)|0xC4 +#define SR_T_C5 (SR_T<<8)|0xC5 +#define SR_T_C6 (SR_T<<8)|0xC6 +#define SR_T_C7 (SR_T<<8)|0xC7 +#define SR_T_C8 (SR_T<<8)|0xC8 +#define SR_T_C9 (SR_T<<8)|0xC9 +#define SR_T_CA (SR_T<<8)|0xCA +#define SR_T_CB (SR_T<<8)|0xCB +#define SR_T_CC (SR_T<<8)|0xCC +#define SR_T_CD (SR_T<<8)|0xCD +#define SR_T_CE (SR_T<<8)|0xCE +#define SR_T_CF (SR_T<<8)|0xCF +#define SR_T_D0 (SR_T<<8)|0xD0 +#define SR_T_D1 (SR_T<<8)|0xD1 +#define SR_T_D2 (SR_T<<8)|0xD2 +#define SR_T_D3 (SR_T<<8)|0xD3 +#define SR_T_D4 (SR_T<<8)|0xD4 +#define SR_T_D5 (SR_T<<8)|0xD5 +#define SR_T_D6 (SR_T<<8)|0xD6 +#define SR_T_D7 (SR_T<<8)|0xD7 +#define SR_T_D8 (SR_T<<8)|0xD8 +#define SR_T_D9 (SR_T<<8)|0xD9 +#define SR_T_DA (SR_T<<8)|0xDA +#define SR_T_DB (SR_T<<8)|0xDB +#define SR_T_DC (SR_T<<8)|0xDC +#define SR_T_DD (SR_T<<8)|0xDD +#define SR_T_DE (SR_T<<8)|0xDE +#define SR_T_DF (SR_T<<8)|0xDF +#define SR_T_E0 (SR_T<<8)|0xE0 +#define SR_T_E1 (SR_T<<8)|0xE1 +#define SR_T_E2 (SR_T<<8)|0xE2 +#define SR_T_E3 (SR_T<<8)|0xE3 +#define SR_T_E4 (SR_T<<8)|0xE4 +#define SR_T_E5 (SR_T<<8)|0xE5 +#define SR_T_E6 (SR_T<<8)|0xE6 +#define SR_T_E7 (SR_T<<8)|0xE7 +#define SR_T_E8 (SR_T<<8)|0xE8 +#define SR_T_E9 (SR_T<<8)|0xE9 +#define SR_T_EA (SR_T<<8)|0xEA +#define SR_T_EB (SR_T<<8)|0xEB +#define SR_T_EC (SR_T<<8)|0xEC +#define SR_T_ED (SR_T<<8)|0xED +#define SR_T_EE (SR_T<<8)|0xEE +#define SR_T_EF (SR_T<<8)|0xEF +#define SR_T_F0 (SR_T<<8)|0xF0 +#define SR_T_F1 (SR_T<<8)|0xF1 +#define SR_T_F2 (SR_T<<8)|0xF2 +#define SR_T_F3 (SR_T<<8)|0xF3 +#define SR_T_F4 (SR_T<<8)|0xF4 +#define SR_T_F5 (SR_T<<8)|0xF5 +#define SR_T_F6 (SR_T<<8)|0xF6 +#define SR_T_F7 (SR_T<<8)|0xF7 +#define SR_T_F8 (SR_T<<8)|0xF8 +#define SR_T_F9 (SR_T<<8)|0xF9 +#define SR_T_FA (SR_T<<8)|0xFA +#define SR_T_FB (SR_T<<8)|0xFB +#define SR_T_FC (SR_T<<8)|0xFC +#define SR_T_FD (SR_T<<8)|0xFD +#define SR_T_FE (SR_T<<8)|0xFE +#define SR_T_FF (SR_T<<8)|0xFF + +#define CR_B_00 (CR_B<<8)|0x00 +#define CR_B_01 (CR_B<<8)|0x01 +#define CR_B_02 (CR_B<<8)|0x02 +#define CR_B_03 (CR_B<<8)|0x03 +#define CR_B_04 (CR_B<<8)|0x04 +#define CR_B_05 (CR_B<<8)|0x05 +#define CR_B_06 (CR_B<<8)|0x06 +#define CR_B_07 (CR_B<<8)|0x07 +#define CR_B_08 (CR_B<<8)|0x08 +#define CR_B_09 (CR_B<<8)|0x09 +#define CR_B_0A (CR_B<<8)|0x0A +#define CR_B_0B (CR_B<<8)|0x0B +#define CR_B_0C (CR_B<<8)|0x0C +#define CR_B_0D (CR_B<<8)|0x0D +#define CR_B_0E (CR_B<<8)|0x0E +#define CR_B_0F (CR_B<<8)|0x0F +#define CR_B_10 (CR_B<<8)|0x10 +#define CR_B_11 (CR_B<<8)|0x11 +#define CR_B_12 (CR_B<<8)|0x12 +#define CR_B_13 (CR_B<<8)|0x13 +#define CR_B_14 (CR_B<<8)|0x14 +#define CR_B_15 (CR_B<<8)|0x15 +#define CR_B_16 (CR_B<<8)|0x16 +#define CR_B_17 (CR_B<<8)|0x17 +#define CR_B_18 (CR_B<<8)|0x18 +#define CR_B_19 (CR_B<<8)|0x19 +#define CR_B_1A (CR_B<<8)|0x1A +#define CR_B_1B (CR_B<<8)|0x1B +#define CR_B_1C (CR_B<<8)|0x1C +#define CR_B_1D (CR_B<<8)|0x1D +#define CR_B_1E (CR_B<<8)|0x1E +#define CR_B_1F (CR_B<<8)|0x1F +#define CR_B_20 (CR_B<<8)|0x20 +#define CR_B_21 (CR_B<<8)|0x21 +#define CR_B_22 (CR_B<<8)|0x22 +#define CR_B_23 (CR_B<<8)|0x23 +#define CR_B_24 (CR_B<<8)|0x24 +#define CR_B_25 (CR_B<<8)|0x25 +#define CR_B_26 (CR_B<<8)|0x26 +#define CR_B_27 (CR_B<<8)|0x27 +#define CR_B_28 (CR_B<<8)|0x28 +#define CR_B_29 (CR_B<<8)|0x29 +#define CR_B_2A (CR_B<<8)|0x2A +#define CR_B_2B (CR_B<<8)|0x2B +#define CR_B_2C (CR_B<<8)|0x2C +#define CR_B_2D (CR_B<<8)|0x2D +#define CR_B_2E (CR_B<<8)|0x2E +#define CR_B_2F (CR_B<<8)|0x2F +#define CR_B_30 (CR_B<<8)|0x30 +#define CR_B_31 (CR_B<<8)|0x31 +#define CR_B_32 (CR_B<<8)|0x32 +#define CR_B_33 (CR_B<<8)|0x33 +#define CR_B_34 (CR_B<<8)|0x34 +#define CR_B_35 (CR_B<<8)|0x35 +#define CR_B_36 (CR_B<<8)|0x36 +#define CR_B_37 (CR_B<<8)|0x37 +#define CR_B_38 (CR_B<<8)|0x38 +#define CR_B_39 (CR_B<<8)|0x39 +#define CR_B_3A (CR_B<<8)|0x3A +#define CR_B_3B (CR_B<<8)|0x3B +#define CR_B_3C (CR_B<<8)|0x3C +#define CR_B_3D (CR_B<<8)|0x3D +#define CR_B_3E (CR_B<<8)|0x3E +#define CR_B_3F (CR_B<<8)|0x3F +#define CR_B_40 (CR_B<<8)|0x40 +#define CR_B_41 (CR_B<<8)|0x41 +#define CR_B_42 (CR_B<<8)|0x42 +#define CR_B_43 (CR_B<<8)|0x43 +#define CR_B_44 (CR_B<<8)|0x44 +#define CR_B_45 (CR_B<<8)|0x45 +#define CR_B_46 (CR_B<<8)|0x46 +#define CR_B_47 (CR_B<<8)|0x47 +#define CR_B_48 (CR_B<<8)|0x48 +#define CR_B_49 (CR_B<<8)|0x49 +#define CR_B_4A (CR_B<<8)|0x4A +#define CR_B_4B (CR_B<<8)|0x4B +#define CR_B_4C (CR_B<<8)|0x4C +#define CR_B_4D (CR_B<<8)|0x4D +#define CR_B_4E (CR_B<<8)|0x4E +#define CR_B_4F (CR_B<<8)|0x4F +#define CR_B_50 (CR_B<<8)|0x50 +#define CR_B_51 (CR_B<<8)|0x51 +#define CR_B_52 (CR_B<<8)|0x52 +#define CR_B_53 (CR_B<<8)|0x53 +#define CR_B_54 (CR_B<<8)|0x54 +#define CR_B_55 (CR_B<<8)|0x55 +#define CR_B_56 (CR_B<<8)|0x56 +#define CR_B_57 (CR_B<<8)|0x57 +#define CR_B_58 (CR_B<<8)|0x58 +#define CR_B_59 (CR_B<<8)|0x59 +#define CR_B_5A (CR_B<<8)|0x5A +#define CR_B_5B (CR_B<<8)|0x5B +#define CR_B_5C (CR_B<<8)|0x5C +#define CR_B_5D (CR_B<<8)|0x5D +#define CR_B_5E (CR_B<<8)|0x5E +#define CR_B_5F (CR_B<<8)|0x5F +#define CR_B_60 (CR_B<<8)|0x60 +#define CR_B_61 (CR_B<<8)|0x61 +#define CR_B_62 (CR_B<<8)|0x62 +#define CR_B_63 (CR_B<<8)|0x63 +#define CR_B_64 (CR_B<<8)|0x64 +#define CR_B_65 (CR_B<<8)|0x65 +#define CR_B_66 (CR_B<<8)|0x66 +#define CR_B_67 (CR_B<<8)|0x67 +#define CR_B_68 (CR_B<<8)|0x68 +#define CR_B_69 (CR_B<<8)|0x69 +#define CR_B_6A (CR_B<<8)|0x6A +#define CR_B_6B (CR_B<<8)|0x6B +#define CR_B_6C (CR_B<<8)|0x6C +#define CR_B_6D (CR_B<<8)|0x6D +#define CR_B_6E (CR_B<<8)|0x6E +#define CR_B_6F (CR_B<<8)|0x6F +#define CR_B_70 (CR_B<<8)|0x70 +#define CR_B_71 (CR_B<<8)|0x71 +#define CR_B_72 (CR_B<<8)|0x72 +#define CR_B_73 (CR_B<<8)|0x73 +#define CR_B_74 (CR_B<<8)|0x74 +#define CR_B_75 (CR_B<<8)|0x75 +#define CR_B_76 (CR_B<<8)|0x76 +#define CR_B_77 (CR_B<<8)|0x77 +#define CR_B_78 (CR_B<<8)|0x78 +#define CR_B_79 (CR_B<<8)|0x79 +#define CR_B_7A (CR_B<<8)|0x7A +#define CR_B_7B (CR_B<<8)|0x7B +#define CR_B_7C (CR_B<<8)|0x7C +#define CR_B_7D (CR_B<<8)|0x7D +#define CR_B_7E (CR_B<<8)|0x7E +#define CR_B_7F (CR_B<<8)|0x7F +#define CR_B_80 (CR_B<<8)|0x80 +#define CR_B_81 (CR_B<<8)|0x81 +#define CR_B_82 (CR_B<<8)|0x82 +#define CR_B_83 (CR_B<<8)|0x83 +#define CR_B_84 (CR_B<<8)|0x84 +#define CR_B_85 (CR_B<<8)|0x85 +#define CR_B_86 (CR_B<<8)|0x86 +#define CR_B_87 (CR_B<<8)|0x87 +#define CR_B_88 (CR_B<<8)|0x88 +#define CR_B_89 (CR_B<<8)|0x89 +#define CR_B_8A (CR_B<<8)|0x8A +#define CR_B_8B (CR_B<<8)|0x8B +#define CR_B_8C (CR_B<<8)|0x8C +#define CR_B_8D (CR_B<<8)|0x8D +#define CR_B_8E (CR_B<<8)|0x8E +#define CR_B_8F (CR_B<<8)|0x8F +#define CR_B_90 (CR_B<<8)|0x90 +#define CR_B_91 (CR_B<<8)|0x91 +#define CR_B_92 (CR_B<<8)|0x92 +#define CR_B_93 (CR_B<<8)|0x93 +#define CR_B_94 (CR_B<<8)|0x94 +#define CR_B_95 (CR_B<<8)|0x95 +#define CR_B_96 (CR_B<<8)|0x96 +#define CR_B_97 (CR_B<<8)|0x97 +#define CR_B_98 (CR_B<<8)|0x98 +#define CR_B_99 (CR_B<<8)|0x99 +#define CR_B_9A (CR_B<<8)|0x9A +#define CR_B_9B (CR_B<<8)|0x9B +#define CR_B_9C (CR_B<<8)|0x9C +#define CR_B_9D (CR_B<<8)|0x9D +#define CR_B_9E (CR_B<<8)|0x9E +#define CR_B_9F (CR_B<<8)|0x9F +#define CR_B_A0 (CR_B<<8)|0xA0 +#define CR_B_A1 (CR_B<<8)|0xA1 +#define CR_B_A2 (CR_B<<8)|0xA2 +#define CR_B_A3 (CR_B<<8)|0xA3 +#define CR_B_A4 (CR_B<<8)|0xA4 +#define CR_B_A5 (CR_B<<8)|0xA5 +#define CR_B_A6 (CR_B<<8)|0xA6 +#define CR_B_A7 (CR_B<<8)|0xA7 +#define CR_B_A8 (CR_B<<8)|0xA8 +#define CR_B_A9 (CR_B<<8)|0xA9 +#define CR_B_AA (CR_B<<8)|0xAA +#define CR_B_AB (CR_B<<8)|0xAB +#define CR_B_AC (CR_B<<8)|0xAC +#define CR_B_AD (CR_B<<8)|0xAD +#define CR_B_AE (CR_B<<8)|0xAE +#define CR_B_AF (CR_B<<8)|0xAF +#define CR_B_B0 (CR_B<<8)|0xB0 +#define CR_B_B1 (CR_B<<8)|0xB1 +#define CR_B_B2 (CR_B<<8)|0xB2 +#define CR_B_B3 (CR_B<<8)|0xB3 +#define CR_B_B4 (CR_B<<8)|0xB4 +#define CR_B_B5 (CR_B<<8)|0xB5 +#define CR_B_B6 (CR_B<<8)|0xB6 +#define CR_B_B7 (CR_B<<8)|0xB7 +#define CR_B_B8 (CR_B<<8)|0xB8 +#define CR_B_B9 (CR_B<<8)|0xB9 +#define CR_B_BA (CR_B<<8)|0xBA +#define CR_B_BB (CR_B<<8)|0xBB +#define CR_B_BC (CR_B<<8)|0xBC +#define CR_B_BD (CR_B<<8)|0xBD +#define CR_B_BE (CR_B<<8)|0xBE +#define CR_B_BF (CR_B<<8)|0xBF +#define CR_B_C0 (CR_B<<8)|0xC0 +#define CR_B_C1 (CR_B<<8)|0xC1 +#define CR_B_C2 (CR_B<<8)|0xC2 +#define CR_B_C3 (CR_B<<8)|0xC3 +#define CR_B_C4 (CR_B<<8)|0xC4 +#define CR_B_C5 (CR_B<<8)|0xC5 +#define CR_B_C6 (CR_B<<8)|0xC6 +#define CR_B_C7 (CR_B<<8)|0xC7 +#define CR_B_C8 (CR_B<<8)|0xC8 +#define CR_B_C9 (CR_B<<8)|0xC9 +#define CR_B_CA (CR_B<<8)|0xCA +#define CR_B_CB (CR_B<<8)|0xCB +#define CR_B_CC (CR_B<<8)|0xCC +#define CR_B_CD (CR_B<<8)|0xCD +#define CR_B_CE (CR_B<<8)|0xCE +#define CR_B_CF (CR_B<<8)|0xCF +#define CR_B_D0 (CR_B<<8)|0xD0 +#define CR_B_D1 (CR_B<<8)|0xD1 +#define CR_B_D2 (CR_B<<8)|0xD2 +#define CR_B_D3 (CR_B<<8)|0xD3 +#define CR_B_D4 (CR_B<<8)|0xD4 +#define CR_B_D5 (CR_B<<8)|0xD5 +#define CR_B_D6 (CR_B<<8)|0xD6 +#define CR_B_D7 (CR_B<<8)|0xD7 +#define CR_B_D8 (CR_B<<8)|0xD8 +#define CR_B_D9 (CR_B<<8)|0xD9 +#define CR_B_DA (CR_B<<8)|0xDA +#define CR_B_DB (CR_B<<8)|0xDB +#define CR_B_DC (CR_B<<8)|0xDC +#define CR_B_DD (CR_B<<8)|0xDD +#define CR_B_DE (CR_B<<8)|0xDE +#define CR_B_DF (CR_B<<8)|0xDF +#define CR_B_E0 (CR_B<<8)|0xE0 +#define CR_B_E1 (CR_B<<8)|0xE1 +#define CR_B_E2 (CR_B<<8)|0xE2 +#define CR_B_E3 (CR_B<<8)|0xE3 +#define CR_B_E4 (CR_B<<8)|0xE4 +#define CR_B_E5 (CR_B<<8)|0xE5 +#define CR_B_E6 (CR_B<<8)|0xE6 +#define CR_B_E7 (CR_B<<8)|0xE7 +#define CR_B_E8 (CR_B<<8)|0xE8 +#define CR_B_E9 (CR_B<<8)|0xE9 +#define CR_B_EA (CR_B<<8)|0xEA +#define CR_B_EB (CR_B<<8)|0xEB +#define CR_B_EC (CR_B<<8)|0xEC +#define CR_B_ED (CR_B<<8)|0xED +#define CR_B_EE (CR_B<<8)|0xEE +#define CR_B_EF (CR_B<<8)|0xEF +#define CR_B_F0 (CR_B<<8)|0xF0 +#define CR_B_F1 (CR_B<<8)|0xF1 +#define CR_B_F2 (CR_B<<8)|0xF2 +#define CR_B_F3 (CR_B<<8)|0xF3 +#define CR_B_F4 (CR_B<<8)|0xF4 +#define CR_B_F5 (CR_B<<8)|0xF5 +#define CR_B_F6 (CR_B<<8)|0xF6 +#define CR_B_F7 (CR_B<<8)|0xF7 +#define CR_B_F8 (CR_B<<8)|0xF8 +#define CR_B_F9 (CR_B<<8)|0xF9 +#define CR_B_FA (CR_B<<8)|0xFA +#define CR_B_FB (CR_B<<8)|0xFB +#define CR_B_FC (CR_B<<8)|0xFC +#define CR_B_FD (CR_B<<8)|0xFD +#define CR_B_FE (CR_B<<8)|0xFE +#define CR_B_FF (CR_B<<8)|0xFF + +#define SR_B_00 (SR_B<<8)|0x00 +#define SR_B_01 (SR_B<<8)|0x01 +#define SR_B_02 (SR_B<<8)|0x02 +#define SR_B_03 (SR_B<<8)|0x03 +#define SR_B_04 (SR_B<<8)|0x04 +#define SR_B_05 (SR_B<<8)|0x05 +#define SR_B_06 (SR_B<<8)|0x06 +#define SR_B_07 (SR_B<<8)|0x07 +#define SR_B_08 (SR_B<<8)|0x08 +#define SR_B_09 (SR_B<<8)|0x09 +#define SR_B_0A (SR_B<<8)|0x0A +#define SR_B_0B (SR_B<<8)|0x0B +#define SR_B_0C (SR_B<<8)|0x0C +#define SR_B_0D (SR_B<<8)|0x0D +#define SR_B_0E (SR_B<<8)|0x0E +#define SR_B_0F (SR_B<<8)|0x0F +#define SR_B_10 (SR_B<<8)|0x10 +#define SR_B_11 (SR_B<<8)|0x11 +#define SR_B_12 (SR_B<<8)|0x12 +#define SR_B_13 (SR_B<<8)|0x13 +#define SR_B_14 (SR_B<<8)|0x14 +#define SR_B_15 (SR_B<<8)|0x15 +#define SR_B_16 (SR_B<<8)|0x16 +#define SR_B_17 (SR_B<<8)|0x17 +#define SR_B_18 (SR_B<<8)|0x18 +#define SR_B_19 (SR_B<<8)|0x19 +#define SR_B_1A (SR_B<<8)|0x1A +#define SR_B_1B (SR_B<<8)|0x1B +#define SR_B_1C (SR_B<<8)|0x1C +#define SR_B_1D (SR_B<<8)|0x1D +#define SR_B_1E (SR_B<<8)|0x1E +#define SR_B_1F (SR_B<<8)|0x1F +#define SR_B_20 (SR_B<<8)|0x20 +#define SR_B_21 (SR_B<<8)|0x21 +#define SR_B_22 (SR_B<<8)|0x22 +#define SR_B_23 (SR_B<<8)|0x23 +#define SR_B_24 (SR_B<<8)|0x24 +#define SR_B_25 (SR_B<<8)|0x25 +#define SR_B_26 (SR_B<<8)|0x26 +#define SR_B_27 (SR_B<<8)|0x27 +#define SR_B_28 (SR_B<<8)|0x28 +#define SR_B_29 (SR_B<<8)|0x29 +#define SR_B_2A (SR_B<<8)|0x2A +#define SR_B_2B (SR_B<<8)|0x2B +#define SR_B_2C (SR_B<<8)|0x2C +#define SR_B_2D (SR_B<<8)|0x2D +#define SR_B_2E (SR_B<<8)|0x2E +#define SR_B_2F (SR_B<<8)|0x2F +#define SR_B_30 (SR_B<<8)|0x30 +#define SR_B_31 (SR_B<<8)|0x31 +#define SR_B_32 (SR_B<<8)|0x32 +#define SR_B_33 (SR_B<<8)|0x33 +#define SR_B_34 (SR_B<<8)|0x34 +#define SR_B_35 (SR_B<<8)|0x35 +#define SR_B_36 (SR_B<<8)|0x36 +#define SR_B_37 (SR_B<<8)|0x37 +#define SR_B_38 (SR_B<<8)|0x38 +#define SR_B_39 (SR_B<<8)|0x39 +#define SR_B_3A (SR_B<<8)|0x3A +#define SR_B_3B (SR_B<<8)|0x3B +#define SR_B_3C (SR_B<<8)|0x3C +#define SR_B_3D (SR_B<<8)|0x3D +#define SR_B_3E (SR_B<<8)|0x3E +#define SR_B_3F (SR_B<<8)|0x3F +#define SR_B_40 (SR_B<<8)|0x40 +#define SR_B_41 (SR_B<<8)|0x41 +#define SR_B_42 (SR_B<<8)|0x42 +#define SR_B_43 (SR_B<<8)|0x43 +#define SR_B_44 (SR_B<<8)|0x44 +#define SR_B_45 (SR_B<<8)|0x45 +#define SR_B_46 (SR_B<<8)|0x46 +#define SR_B_47 (SR_B<<8)|0x47 +#define SR_B_48 (SR_B<<8)|0x48 +#define SR_B_49 (SR_B<<8)|0x49 +#define SR_B_4A (SR_B<<8)|0x4A +#define SR_B_4B (SR_B<<8)|0x4B +#define SR_B_4C (SR_B<<8)|0x4C +#define SR_B_4D (SR_B<<8)|0x4D +#define SR_B_4E (SR_B<<8)|0x4E +#define SR_B_4F (SR_B<<8)|0x4F +#define SR_B_50 (SR_B<<8)|0x50 +#define SR_B_51 (SR_B<<8)|0x51 +#define SR_B_52 (SR_B<<8)|0x52 +#define SR_B_53 (SR_B<<8)|0x53 +#define SR_B_54 (SR_B<<8)|0x54 +#define SR_B_55 (SR_B<<8)|0x55 +#define SR_B_56 (SR_B<<8)|0x56 +#define SR_B_57 (SR_B<<8)|0x57 +#define SR_B_58 (SR_B<<8)|0x58 +#define SR_B_59 (SR_B<<8)|0x59 +#define SR_B_5A (SR_B<<8)|0x5A +#define SR_B_5B (SR_B<<8)|0x5B +#define SR_B_5C (SR_B<<8)|0x5C +#define SR_B_5D (SR_B<<8)|0x5D +#define SR_B_5E (SR_B<<8)|0x5E +#define SR_B_5F (SR_B<<8)|0x5F +#define SR_B_60 (SR_B<<8)|0x60 +#define SR_B_61 (SR_B<<8)|0x61 +#define SR_B_62 (SR_B<<8)|0x62 +#define SR_B_63 (SR_B<<8)|0x63 +#define SR_B_64 (SR_B<<8)|0x64 +#define SR_B_65 (SR_B<<8)|0x65 +#define SR_B_66 (SR_B<<8)|0x66 +#define SR_B_67 (SR_B<<8)|0x67 +#define SR_B_68 (SR_B<<8)|0x68 +#define SR_B_69 (SR_B<<8)|0x69 +#define SR_B_6A (SR_B<<8)|0x6A +#define SR_B_6B (SR_B<<8)|0x6B +#define SR_B_6C (SR_B<<8)|0x6C +#define SR_B_6D (SR_B<<8)|0x6D +#define SR_B_6E (SR_B<<8)|0x6E +#define SR_B_6F (SR_B<<8)|0x6F +#define SR_B_70 (SR_B<<8)|0x70 +#define SR_B_71 (SR_B<<8)|0x71 +#define SR_B_72 (SR_B<<8)|0x72 +#define SR_B_73 (SR_B<<8)|0x73 +#define SR_B_74 (SR_B<<8)|0x74 +#define SR_B_75 (SR_B<<8)|0x75 +#define SR_B_76 (SR_B<<8)|0x76 +#define SR_B_77 (SR_B<<8)|0x77 +#define SR_B_78 (SR_B<<8)|0x78 +#define SR_B_79 (SR_B<<8)|0x79 +#define SR_B_7A (SR_B<<8)|0x7A +#define SR_B_7B (SR_B<<8)|0x7B +#define SR_B_7C (SR_B<<8)|0x7C +#define SR_B_7D (SR_B<<8)|0x7D +#define SR_B_7E (SR_B<<8)|0x7E +#define SR_B_7F (SR_B<<8)|0x7F +#define SR_B_80 (SR_B<<8)|0x80 +#define SR_B_81 (SR_B<<8)|0x81 +#define SR_B_82 (SR_B<<8)|0x82 +#define SR_B_83 (SR_B<<8)|0x83 +#define SR_B_84 (SR_B<<8)|0x84 +#define SR_B_85 (SR_B<<8)|0x85 +#define SR_B_86 (SR_B<<8)|0x86 +#define SR_B_87 (SR_B<<8)|0x87 +#define SR_B_88 (SR_B<<8)|0x88 +#define SR_B_89 (SR_B<<8)|0x89 +#define SR_B_8A (SR_B<<8)|0x8A +#define SR_B_8B (SR_B<<8)|0x8B +#define SR_B_8C (SR_B<<8)|0x8C +#define SR_B_8D (SR_B<<8)|0x8D +#define SR_B_8E (SR_B<<8)|0x8E +#define SR_B_8F (SR_B<<8)|0x8F +#define SR_B_90 (SR_B<<8)|0x90 +#define SR_B_91 (SR_B<<8)|0x91 +#define SR_B_92 (SR_B<<8)|0x92 +#define SR_B_93 (SR_B<<8)|0x93 +#define SR_B_94 (SR_B<<8)|0x94 +#define SR_B_95 (SR_B<<8)|0x95 +#define SR_B_96 (SR_B<<8)|0x96 +#define SR_B_97 (SR_B<<8)|0x97 +#define SR_B_98 (SR_B<<8)|0x98 +#define SR_B_99 (SR_B<<8)|0x99 +#define SR_B_9A (SR_B<<8)|0x9A +#define SR_B_9B (SR_B<<8)|0x9B +#define SR_B_9C (SR_B<<8)|0x9C +#define SR_B_9D (SR_B<<8)|0x9D +#define SR_B_9E (SR_B<<8)|0x9E +#define SR_B_9F (SR_B<<8)|0x9F +#define SR_B_A0 (SR_B<<8)|0xA0 +#define SR_B_A1 (SR_B<<8)|0xA1 +#define SR_B_A2 (SR_B<<8)|0xA2 +#define SR_B_A3 (SR_B<<8)|0xA3 +#define SR_B_A4 (SR_B<<8)|0xA4 +#define SR_B_A5 (SR_B<<8)|0xA5 +#define SR_B_A6 (SR_B<<8)|0xA6 +#define SR_B_A7 (SR_B<<8)|0xA7 +#define SR_B_A8 (SR_B<<8)|0xA8 +#define SR_B_A9 (SR_B<<8)|0xA9 +#define SR_B_AA (SR_B<<8)|0xAA +#define SR_B_AB (SR_B<<8)|0xAB +#define SR_B_AC (SR_B<<8)|0xAC +#define SR_B_AD (SR_B<<8)|0xAD +#define SR_B_AE (SR_B<<8)|0xAE +#define SR_B_AF (SR_B<<8)|0xAF +#define SR_B_B0 (SR_B<<8)|0xB0 +#define SR_B_B1 (SR_B<<8)|0xB1 +#define SR_B_B2 (SR_B<<8)|0xB2 +#define SR_B_B3 (SR_B<<8)|0xB3 +#define SR_B_B4 (SR_B<<8)|0xB4 +#define SR_B_B5 (SR_B<<8)|0xB5 +#define SR_B_B6 (SR_B<<8)|0xB6 +#define SR_B_B7 (SR_B<<8)|0xB7 +#define SR_B_B8 (SR_B<<8)|0xB8 +#define SR_B_B9 (SR_B<<8)|0xB9 +#define SR_B_BA (SR_B<<8)|0xBA +#define SR_B_BB (SR_B<<8)|0xBB +#define SR_B_BC (SR_B<<8)|0xBC +#define SR_B_BD (SR_B<<8)|0xBD +#define SR_B_BE (SR_B<<8)|0xBE +#define SR_B_BF (SR_B<<8)|0xBF +#define SR_B_C0 (SR_B<<8)|0xC0 +#define SR_B_C1 (SR_B<<8)|0xC1 +#define SR_B_C2 (SR_B<<8)|0xC2 +#define SR_B_C3 (SR_B<<8)|0xC3 +#define SR_B_C4 (SR_B<<8)|0xC4 +#define SR_B_C5 (SR_B<<8)|0xC5 +#define SR_B_C6 (SR_B<<8)|0xC6 +#define SR_B_C7 (SR_B<<8)|0xC7 +#define SR_B_C8 (SR_B<<8)|0xC8 +#define SR_B_C9 (SR_B<<8)|0xC9 +#define SR_B_CA (SR_B<<8)|0xCA +#define SR_B_CB (SR_B<<8)|0xCB +#define SR_B_CC (SR_B<<8)|0xCC +#define SR_B_CD (SR_B<<8)|0xCD +#define SR_B_CE (SR_B<<8)|0xCE +#define SR_B_CF (SR_B<<8)|0xCF +#define SR_B_D0 (SR_B<<8)|0xD0 +#define SR_B_D1 (SR_B<<8)|0xD1 +#define SR_B_D2 (SR_B<<8)|0xD2 +#define SR_B_D3 (SR_B<<8)|0xD3 +#define SR_B_D4 (SR_B<<8)|0xD4 +#define SR_B_D5 (SR_B<<8)|0xD5 +#define SR_B_D6 (SR_B<<8)|0xD6 +#define SR_B_D7 (SR_B<<8)|0xD7 +#define SR_B_D8 (SR_B<<8)|0xD8 +#define SR_B_D9 (SR_B<<8)|0xD9 +#define SR_B_DA (SR_B<<8)|0xDA +#define SR_B_DB (SR_B<<8)|0xDB +#define SR_B_DC (SR_B<<8)|0xDC +#define SR_B_DD (SR_B<<8)|0xDD +#define SR_B_DE (SR_B<<8)|0xDE +#define SR_B_DF (SR_B<<8)|0xDF +#define SR_B_E0 (SR_B<<8)|0xE0 +#define SR_B_E1 (SR_B<<8)|0xE1 +#define SR_B_E2 (SR_B<<8)|0xE2 +#define SR_B_E3 (SR_B<<8)|0xE3 +#define SR_B_E4 (SR_B<<8)|0xE4 +#define SR_B_E5 (SR_B<<8)|0xE5 +#define SR_B_E6 (SR_B<<8)|0xE6 +#define SR_B_E7 (SR_B<<8)|0xE7 +#define SR_B_E8 (SR_B<<8)|0xE8 +#define SR_B_E9 (SR_B<<8)|0xE9 +#define SR_B_EA (SR_B<<8)|0xEA +#define SR_B_EB (SR_B<<8)|0xEB +#define SR_B_EC (SR_B<<8)|0xEC +#define SR_B_ED (SR_B<<8)|0xED +#define SR_B_EE (SR_B<<8)|0xEE +#define SR_B_EF (SR_B<<8)|0xEF +#define SR_B_F0 (SR_B<<8)|0xF0 +#define SR_B_F1 (SR_B<<8)|0xF1 +#define SR_B_F2 (SR_B<<8)|0xF2 +#define SR_B_F3 (SR_B<<8)|0xF3 +#define SR_B_F4 (SR_B<<8)|0xF4 +#define SR_B_F5 (SR_B<<8)|0xF5 +#define SR_B_F6 (SR_B<<8)|0xF6 +#define SR_B_F7 (SR_B<<8)|0xF7 +#define SR_B_F8 (SR_B<<8)|0xF8 +#define SR_B_F9 (SR_B<<8)|0xF9 +#define SR_B_FA (SR_B<<8)|0xFA +#define SR_B_FB (SR_B<<8)|0xFB +#define SR_B_FC (SR_B<<8)|0xFC +#define SR_B_FD (SR_B<<8)|0xFD +#define SR_B_FE (SR_B<<8)|0xFE +#define SR_B_FF (SR_B<<8)|0xFF + +#define CR_D_00 (CR_D<<8)|0x00 +#define CR_D_01 (CR_D<<8)|0x01 +#define CR_D_02 (CR_D<<8)|0x02 +#define CR_D_03 (CR_D<<8)|0x03 +#define CR_D_04 (CR_D<<8)|0x04 +#define CR_D_05 (CR_D<<8)|0x05 +#define CR_D_06 (CR_D<<8)|0x06 +#define CR_D_07 (CR_D<<8)|0x07 +#define CR_D_08 (CR_D<<8)|0x08 +#define CR_D_09 (CR_D<<8)|0x09 +#define CR_D_0A (CR_D<<8)|0x0A +#define CR_D_0B (CR_D<<8)|0x0B +#define CR_D_0C (CR_D<<8)|0x0C +#define CR_D_0D (CR_D<<8)|0x0D +#define CR_D_0E (CR_D<<8)|0x0E +#define CR_D_0F (CR_D<<8)|0x0F +#define CR_D_10 (CR_D<<8)|0x10 +#define CR_D_11 (CR_D<<8)|0x11 +#define CR_D_12 (CR_D<<8)|0x12 +#define CR_D_13 (CR_D<<8)|0x13 +#define CR_D_14 (CR_D<<8)|0x14 +#define CR_D_15 (CR_D<<8)|0x15 +#define CR_D_16 (CR_D<<8)|0x16 +#define CR_D_17 (CR_D<<8)|0x17 +#define CR_D_18 (CR_D<<8)|0x18 +#define CR_D_19 (CR_D<<8)|0x19 +#define CR_D_1A (CR_D<<8)|0x1A +#define CR_D_1B (CR_D<<8)|0x1B +#define CR_D_1C (CR_D<<8)|0x1C +#define CR_D_1D (CR_D<<8)|0x1D +#define CR_D_1E (CR_D<<8)|0x1E +#define CR_D_1F (CR_D<<8)|0x1F +#define CR_D_20 (CR_D<<8)|0x20 +#define CR_D_21 (CR_D<<8)|0x21 +#define CR_D_22 (CR_D<<8)|0x22 +#define CR_D_23 (CR_D<<8)|0x23 +#define CR_D_24 (CR_D<<8)|0x24 +#define CR_D_25 (CR_D<<8)|0x25 +#define CR_D_26 (CR_D<<8)|0x26 +#define CR_D_27 (CR_D<<8)|0x27 +#define CR_D_28 (CR_D<<8)|0x28 +#define CR_D_29 (CR_D<<8)|0x29 +#define CR_D_2A (CR_D<<8)|0x2A +#define CR_D_2B (CR_D<<8)|0x2B +#define CR_D_2C (CR_D<<8)|0x2C +#define CR_D_2D (CR_D<<8)|0x2D +#define CR_D_2E (CR_D<<8)|0x2E +#define CR_D_2F (CR_D<<8)|0x2F +#define CR_D_30 (CR_D<<8)|0x30 +#define CR_D_31 (CR_D<<8)|0x31 +#define CR_D_32 (CR_D<<8)|0x32 +#define CR_D_33 (CR_D<<8)|0x33 +#define CR_D_34 (CR_D<<8)|0x34 +#define CR_D_35 (CR_D<<8)|0x35 +#define CR_D_36 (CR_D<<8)|0x36 +#define CR_D_37 (CR_D<<8)|0x37 +#define CR_D_38 (CR_D<<8)|0x38 +#define CR_D_39 (CR_D<<8)|0x39 +#define CR_D_3A (CR_D<<8)|0x3A +#define CR_D_3B (CR_D<<8)|0x3B +#define CR_D_3C (CR_D<<8)|0x3C +#define CR_D_3D (CR_D<<8)|0x3D +#define CR_D_3E (CR_D<<8)|0x3E +#define CR_D_3F (CR_D<<8)|0x3F +#define CR_D_40 (CR_D<<8)|0x40 +#define CR_D_41 (CR_D<<8)|0x41 +#define CR_D_42 (CR_D<<8)|0x42 +#define CR_D_43 (CR_D<<8)|0x43 +#define CR_D_44 (CR_D<<8)|0x44 +#define CR_D_45 (CR_D<<8)|0x45 +#define CR_D_46 (CR_D<<8)|0x46 +#define CR_D_47 (CR_D<<8)|0x47 +#define CR_D_48 (CR_D<<8)|0x48 +#define CR_D_49 (CR_D<<8)|0x49 +#define CR_D_4A (CR_D<<8)|0x4A +#define CR_D_4B (CR_D<<8)|0x4B +#define CR_D_4C (CR_D<<8)|0x4C +#define CR_D_4D (CR_D<<8)|0x4D +#define CR_D_4E (CR_D<<8)|0x4E +#define CR_D_4F (CR_D<<8)|0x4F +#define CR_D_50 (CR_D<<8)|0x50 +#define CR_D_51 (CR_D<<8)|0x51 +#define CR_D_52 (CR_D<<8)|0x52 +#define CR_D_53 (CR_D<<8)|0x53 +#define CR_D_54 (CR_D<<8)|0x54 +#define CR_D_55 (CR_D<<8)|0x55 +#define CR_D_56 (CR_D<<8)|0x56 +#define CR_D_57 (CR_D<<8)|0x57 +#define CR_D_58 (CR_D<<8)|0x58 +#define CR_D_59 (CR_D<<8)|0x59 +#define CR_D_5A (CR_D<<8)|0x5A +#define CR_D_5B (CR_D<<8)|0x5B +#define CR_D_5C (CR_D<<8)|0x5C +#define CR_D_5D (CR_D<<8)|0x5D +#define CR_D_5E (CR_D<<8)|0x5E +#define CR_D_5F (CR_D<<8)|0x5F +#define CR_D_60 (CR_D<<8)|0x60 +#define CR_D_61 (CR_D<<8)|0x61 +#define CR_D_62 (CR_D<<8)|0x62 +#define CR_D_63 (CR_D<<8)|0x63 +#define CR_D_64 (CR_D<<8)|0x64 +#define CR_D_65 (CR_D<<8)|0x65 +#define CR_D_66 (CR_D<<8)|0x66 +#define CR_D_67 (CR_D<<8)|0x67 +#define CR_D_68 (CR_D<<8)|0x68 +#define CR_D_69 (CR_D<<8)|0x69 +#define CR_D_6A (CR_D<<8)|0x6A +#define CR_D_6B (CR_D<<8)|0x6B +#define CR_D_6C (CR_D<<8)|0x6C +#define CR_D_6D (CR_D<<8)|0x6D +#define CR_D_6E (CR_D<<8)|0x6E +#define CR_D_6F (CR_D<<8)|0x6F +#define CR_D_70 (CR_D<<8)|0x70 +#define CR_D_71 (CR_D<<8)|0x71 +#define CR_D_72 (CR_D<<8)|0x72 +#define CR_D_73 (CR_D<<8)|0x73 +#define CR_D_74 (CR_D<<8)|0x74 +#define CR_D_75 (CR_D<<8)|0x75 +#define CR_D_76 (CR_D<<8)|0x76 +#define CR_D_77 (CR_D<<8)|0x77 +#define CR_D_78 (CR_D<<8)|0x78 +#define CR_D_79 (CR_D<<8)|0x79 +#define CR_D_7A (CR_D<<8)|0x7A +#define CR_D_7B (CR_D<<8)|0x7B +#define CR_D_7C (CR_D<<8)|0x7C +#define CR_D_7D (CR_D<<8)|0x7D +#define CR_D_7E (CR_D<<8)|0x7E +#define CR_D_7F (CR_D<<8)|0x7F +#define CR_D_80 (CR_D<<8)|0x80 +#define CR_D_81 (CR_D<<8)|0x81 +#define CR_D_82 (CR_D<<8)|0x82 +#define CR_D_83 (CR_D<<8)|0x83 +#define CR_D_84 (CR_D<<8)|0x84 +#define CR_D_85 (CR_D<<8)|0x85 +#define CR_D_86 (CR_D<<8)|0x86 +#define CR_D_87 (CR_D<<8)|0x87 +#define CR_D_88 (CR_D<<8)|0x88 +#define CR_D_89 (CR_D<<8)|0x89 +#define CR_D_8A (CR_D<<8)|0x8A +#define CR_D_8B (CR_D<<8)|0x8B +#define CR_D_8C (CR_D<<8)|0x8C +#define CR_D_8D (CR_D<<8)|0x8D +#define CR_D_8E (CR_D<<8)|0x8E +#define CR_D_8F (CR_D<<8)|0x8F +#define CR_D_90 (CR_D<<8)|0x90 +#define CR_D_91 (CR_D<<8)|0x91 +#define CR_D_92 (CR_D<<8)|0x92 +#define CR_D_93 (CR_D<<8)|0x93 +#define CR_D_94 (CR_D<<8)|0x94 +#define CR_D_95 (CR_D<<8)|0x95 +#define CR_D_96 (CR_D<<8)|0x96 +#define CR_D_97 (CR_D<<8)|0x97 +#define CR_D_98 (CR_D<<8)|0x98 +#define CR_D_99 (CR_D<<8)|0x99 +#define CR_D_9A (CR_D<<8)|0x9A +#define CR_D_9B (CR_D<<8)|0x9B +#define CR_D_9C (CR_D<<8)|0x9C +#define CR_D_9D (CR_D<<8)|0x9D +#define CR_D_9E (CR_D<<8)|0x9E +#define CR_D_9F (CR_D<<8)|0x9F +#define CR_D_A0 (CR_D<<8)|0xA0 +#define CR_D_A1 (CR_D<<8)|0xA1 +#define CR_D_A2 (CR_D<<8)|0xA2 +#define CR_D_A3 (CR_D<<8)|0xA3 +#define CR_D_A4 (CR_D<<8)|0xA4 +#define CR_D_A5 (CR_D<<8)|0xA5 +#define CR_D_A6 (CR_D<<8)|0xA6 +#define CR_D_A7 (CR_D<<8)|0xA7 +#define CR_D_A8 (CR_D<<8)|0xA8 +#define CR_D_A9 (CR_D<<8)|0xA9 +#define CR_D_AA (CR_D<<8)|0xAA +#define CR_D_AB (CR_D<<8)|0xAB +#define CR_D_AC (CR_D<<8)|0xAC +#define CR_D_AD (CR_D<<8)|0xAD +#define CR_D_AE (CR_D<<8)|0xAE +#define CR_D_AF (CR_D<<8)|0xAF +#define CR_D_B0 (CR_D<<8)|0xB0 +#define CR_D_B1 (CR_D<<8)|0xB1 +#define CR_D_B2 (CR_D<<8)|0xB2 +#define CR_D_B3 (CR_D<<8)|0xB3 +#define CR_D_B4 (CR_D<<8)|0xB4 +#define CR_D_B5 (CR_D<<8)|0xB5 +#define CR_D_B6 (CR_D<<8)|0xB6 +#define CR_D_B7 (CR_D<<8)|0xB7 +#define CR_D_B8 (CR_D<<8)|0xB8 +#define CR_D_B9 (CR_D<<8)|0xB9 +#define CR_D_BA (CR_D<<8)|0xBA +#define CR_D_BB (CR_D<<8)|0xBB +#define CR_D_BC (CR_D<<8)|0xBC +#define CR_D_BD (CR_D<<8)|0xBD +#define CR_D_BE (CR_D<<8)|0xBE +#define CR_D_BF (CR_D<<8)|0xBF +#define CR_D_C0 (CR_D<<8)|0xC0 +#define CR_D_C1 (CR_D<<8)|0xC1 +#define CR_D_C2 (CR_D<<8)|0xC2 +#define CR_D_C3 (CR_D<<8)|0xC3 +#define CR_D_C4 (CR_D<<8)|0xC4 +#define CR_D_C5 (CR_D<<8)|0xC5 +#define CR_D_C6 (CR_D<<8)|0xC6 +#define CR_D_C7 (CR_D<<8)|0xC7 +#define CR_D_C8 (CR_D<<8)|0xC8 +#define CR_D_C9 (CR_D<<8)|0xC9 +#define CR_D_CA (CR_D<<8)|0xCA +#define CR_D_CB (CR_D<<8)|0xCB +#define CR_D_CC (CR_D<<8)|0xCC +#define CR_D_CD (CR_D<<8)|0xCD +#define CR_D_CE (CR_D<<8)|0xCE +#define CR_D_CF (CR_D<<8)|0xCF +#define CR_D_D0 (CR_D<<8)|0xD0 +#define CR_D_D1 (CR_D<<8)|0xD1 +#define CR_D_D2 (CR_D<<8)|0xD2 +#define CR_D_D3 (CR_D<<8)|0xD3 +#define CR_D_D4 (CR_D<<8)|0xD4 +#define CR_D_D5 (CR_D<<8)|0xD5 +#define CR_D_D6 (CR_D<<8)|0xD6 +#define CR_D_D7 (CR_D<<8)|0xD7 +#define CR_D_D8 (CR_D<<8)|0xD8 +#define CR_D_D9 (CR_D<<8)|0xD9 +#define CR_D_DA (CR_D<<8)|0xDA +#define CR_D_DB (CR_D<<8)|0xDB +#define CR_D_DC (CR_D<<8)|0xDC +#define CR_D_DD (CR_D<<8)|0xDD +#define CR_D_DE (CR_D<<8)|0xDE +#define CR_D_DF (CR_D<<8)|0xDF +#define CR_D_E0 (CR_D<<8)|0xE0 +#define CR_D_E1 (CR_D<<8)|0xE1 +#define CR_D_E2 (CR_D<<8)|0xE2 +#define CR_D_E3 (CR_D<<8)|0xE3 +#define CR_D_E4 (CR_D<<8)|0xE4 +#define CR_D_E5 (CR_D<<8)|0xE5 +#define CR_D_E6 (CR_D<<8)|0xE6 +#define CR_D_E7 (CR_D<<8)|0xE7 +#define CR_D_E8 (CR_D<<8)|0xE8 +#define CR_D_E9 (CR_D<<8)|0xE9 +#define CR_D_EA (CR_D<<8)|0xEA +#define CR_D_EB (CR_D<<8)|0xEB +#define CR_D_EC (CR_D<<8)|0xEC +#define CR_D_ED (CR_D<<8)|0xED +#define CR_D_EE (CR_D<<8)|0xEE +#define CR_D_EF (CR_D<<8)|0xEF +#define CR_D_F0 (CR_D<<8)|0xF0 +#define CR_D_F1 (CR_D<<8)|0xF1 +#define CR_D_F2 (CR_D<<8)|0xF2 +#define CR_D_F3 (CR_D<<8)|0xF3 +#define CR_D_F4 (CR_D<<8)|0xF4 +#define CR_D_F5 (CR_D<<8)|0xF5 +#define CR_D_F6 (CR_D<<8)|0xF6 +#define CR_D_F7 (CR_D<<8)|0xF7 +#define CR_D_F8 (CR_D<<8)|0xF8 +#define CR_D_F9 (CR_D<<8)|0xF9 +#define CR_D_FA (CR_D<<8)|0xFA +#define CR_D_FB (CR_D<<8)|0xFB +#define CR_D_FC (CR_D<<8)|0xFC +#define CR_D_FD (CR_D<<8)|0xFD +#define CR_D_FE (CR_D<<8)|0xFE +#define CR_D_FF (CR_D<<8)|0xFF + +#define CR_T_00 (CR_T<<8)|0x00 +#define CR_T_01 (CR_T<<8)|0x01 +#define CR_T_02 (CR_T<<8)|0x02 +#define CR_T_03 (CR_T<<8)|0x03 +#define CR_T_04 (CR_T<<8)|0x04 +#define CR_T_05 (CR_T<<8)|0x05 +#define CR_T_06 (CR_T<<8)|0x06 +#define CR_T_07 (CR_T<<8)|0x07 +#define CR_T_08 (CR_T<<8)|0x08 +#define CR_T_09 (CR_T<<8)|0x09 +#define CR_T_0A (CR_T<<8)|0x0A +#define CR_T_0B (CR_T<<8)|0x0B +#define CR_T_0C (CR_T<<8)|0x0C +#define CR_T_0D (CR_T<<8)|0x0D +#define CR_T_0E (CR_T<<8)|0x0E +#define CR_T_0F (CR_T<<8)|0x0F +#define CR_T_10 (CR_T<<8)|0x10 +#define CR_T_11 (CR_T<<8)|0x11 +#define CR_T_12 (CR_T<<8)|0x12 +#define CR_T_13 (CR_T<<8)|0x13 +#define CR_T_14 (CR_T<<8)|0x14 +#define CR_T_15 (CR_T<<8)|0x15 +#define CR_T_16 (CR_T<<8)|0x16 +#define CR_T_17 (CR_T<<8)|0x17 +#define CR_T_18 (CR_T<<8)|0x18 +#define CR_T_19 (CR_T<<8)|0x19 +#define CR_T_1A (CR_T<<8)|0x1A +#define CR_T_1B (CR_T<<8)|0x1B +#define CR_T_1C (CR_T<<8)|0x1C +#define CR_T_1D (CR_T<<8)|0x1D +#define CR_T_1E (CR_T<<8)|0x1E +#define CR_T_1F (CR_T<<8)|0x1F +#define CR_T_20 (CR_T<<8)|0x20 +#define CR_T_21 (CR_T<<8)|0x21 +#define CR_T_22 (CR_T<<8)|0x22 +#define CR_T_23 (CR_T<<8)|0x23 +#define CR_T_24 (CR_T<<8)|0x24 +#define CR_T_25 (CR_T<<8)|0x25 +#define CR_T_26 (CR_T<<8)|0x26 +#define CR_T_27 (CR_T<<8)|0x27 +#define CR_T_28 (CR_T<<8)|0x28 +#define CR_T_29 (CR_T<<8)|0x29 +#define CR_T_2A (CR_T<<8)|0x2A +#define CR_T_2B (CR_T<<8)|0x2B +#define CR_T_2C (CR_T<<8)|0x2C +#define CR_T_2D (CR_T<<8)|0x2D +#define CR_T_2E (CR_T<<8)|0x2E +#define CR_T_2F (CR_T<<8)|0x2F +#define CR_T_30 (CR_T<<8)|0x30 +#define CR_T_31 (CR_T<<8)|0x31 +#define CR_T_32 (CR_T<<8)|0x32 +#define CR_T_33 (CR_T<<8)|0x33 +#define CR_T_34 (CR_T<<8)|0x34 +#define CR_T_35 (CR_T<<8)|0x35 +#define CR_T_36 (CR_T<<8)|0x36 +#define CR_T_37 (CR_T<<8)|0x37 +#define CR_T_38 (CR_T<<8)|0x38 +#define CR_T_39 (CR_T<<8)|0x39 +#define CR_T_3A (CR_T<<8)|0x3A +#define CR_T_3B (CR_T<<8)|0x3B +#define CR_T_3C (CR_T<<8)|0x3C +#define CR_T_3D (CR_T<<8)|0x3D +#define CR_T_3E (CR_T<<8)|0x3E +#define CR_T_3F (CR_T<<8)|0x3F +#define CR_T_40 (CR_T<<8)|0x40 +#define CR_T_41 (CR_T<<8)|0x41 +#define CR_T_42 (CR_T<<8)|0x42 +#define CR_T_43 (CR_T<<8)|0x43 +#define CR_T_44 (CR_T<<8)|0x44 +#define CR_T_45 (CR_T<<8)|0x45 +#define CR_T_46 (CR_T<<8)|0x46 +#define CR_T_47 (CR_T<<8)|0x47 +#define CR_T_48 (CR_T<<8)|0x48 +#define CR_T_49 (CR_T<<8)|0x49 +#define CR_T_4A (CR_T<<8)|0x4A +#define CR_T_4B (CR_T<<8)|0x4B +#define CR_T_4C (CR_T<<8)|0x4C +#define CR_T_4D (CR_T<<8)|0x4D +#define CR_T_4E (CR_T<<8)|0x4E +#define CR_T_4F (CR_T<<8)|0x4F +#define CR_T_50 (CR_T<<8)|0x50 +#define CR_T_51 (CR_T<<8)|0x51 +#define CR_T_52 (CR_T<<8)|0x52 +#define CR_T_53 (CR_T<<8)|0x53 +#define CR_T_54 (CR_T<<8)|0x54 +#define CR_T_55 (CR_T<<8)|0x55 +#define CR_T_56 (CR_T<<8)|0x56 +#define CR_T_57 (CR_T<<8)|0x57 +#define CR_T_58 (CR_T<<8)|0x58 +#define CR_T_59 (CR_T<<8)|0x59 +#define CR_T_5A (CR_T<<8)|0x5A +#define CR_T_5B (CR_T<<8)|0x5B +#define CR_T_5C (CR_T<<8)|0x5C +#define CR_T_5D (CR_T<<8)|0x5D +#define CR_T_5E (CR_T<<8)|0x5E +#define CR_T_5F (CR_T<<8)|0x5F +#define CR_T_60 (CR_T<<8)|0x60 +#define CR_T_61 (CR_T<<8)|0x61 +#define CR_T_62 (CR_T<<8)|0x62 +#define CR_T_63 (CR_T<<8)|0x63 +#define CR_T_64 (CR_T<<8)|0x64 +#define CR_T_65 (CR_T<<8)|0x65 +#define CR_T_66 (CR_T<<8)|0x66 +#define CR_T_67 (CR_T<<8)|0x67 +#define CR_T_68 (CR_T<<8)|0x68 +#define CR_T_69 (CR_T<<8)|0x69 +#define CR_T_6A (CR_T<<8)|0x6A +#define CR_T_6B (CR_T<<8)|0x6B +#define CR_T_6C (CR_T<<8)|0x6C +#define CR_T_6D (CR_T<<8)|0x6D +#define CR_T_6E (CR_T<<8)|0x6E +#define CR_T_6F (CR_T<<8)|0x6F +#define CR_T_70 (CR_T<<8)|0x70 +#define CR_T_71 (CR_T<<8)|0x71 +#define CR_T_72 (CR_T<<8)|0x72 +#define CR_T_73 (CR_T<<8)|0x73 +#define CR_T_74 (CR_T<<8)|0x74 +#define CR_T_75 (CR_T<<8)|0x75 +#define CR_T_76 (CR_T<<8)|0x76 +#define CR_T_77 (CR_T<<8)|0x77 +#define CR_T_78 (CR_T<<8)|0x78 +#define CR_T_79 (CR_T<<8)|0x79 +#define CR_T_7A (CR_T<<8)|0x7A +#define CR_T_7B (CR_T<<8)|0x7B +#define CR_T_7C (CR_T<<8)|0x7C +#define CR_T_7D (CR_T<<8)|0x7D +#define CR_T_7E (CR_T<<8)|0x7E +#define CR_T_7F (CR_T<<8)|0x7F +#define CR_T_80 (CR_T<<8)|0x80 +#define CR_T_81 (CR_T<<8)|0x81 +#define CR_T_82 (CR_T<<8)|0x82 +#define CR_T_83 (CR_T<<8)|0x83 +#define CR_T_84 (CR_T<<8)|0x84 +#define CR_T_85 (CR_T<<8)|0x85 +#define CR_T_86 (CR_T<<8)|0x86 +#define CR_T_87 (CR_T<<8)|0x87 +#define CR_T_88 (CR_T<<8)|0x88 +#define CR_T_89 (CR_T<<8)|0x89 +#define CR_T_8A (CR_T<<8)|0x8A +#define CR_T_8B (CR_T<<8)|0x8B +#define CR_T_8C (CR_T<<8)|0x8C +#define CR_T_8D (CR_T<<8)|0x8D +#define CR_T_8E (CR_T<<8)|0x8E +#define CR_T_8F (CR_T<<8)|0x8F +#define CR_T_90 (CR_T<<8)|0x90 +#define CR_T_91 (CR_T<<8)|0x91 +#define CR_T_92 (CR_T<<8)|0x92 +#define CR_T_93 (CR_T<<8)|0x93 +#define CR_T_94 (CR_T<<8)|0x94 +#define CR_T_95 (CR_T<<8)|0x95 +#define CR_T_96 (CR_T<<8)|0x96 +#define CR_T_97 (CR_T<<8)|0x97 +#define CR_T_98 (CR_T<<8)|0x98 +#define CR_T_99 (CR_T<<8)|0x99 +#define CR_T_9A (CR_T<<8)|0x9A +#define CR_T_9B (CR_T<<8)|0x9B +#define CR_T_9C (CR_T<<8)|0x9C +#define CR_T_9D (CR_T<<8)|0x9D +#define CR_T_9E (CR_T<<8)|0x9E +#define CR_T_9F (CR_T<<8)|0x9F +#define CR_T_A0 (CR_T<<8)|0xA0 +#define CR_T_A1 (CR_T<<8)|0xA1 +#define CR_T_A2 (CR_T<<8)|0xA2 +#define CR_T_A3 (CR_T<<8)|0xA3 +#define CR_T_A4 (CR_T<<8)|0xA4 +#define CR_T_A5 (CR_T<<8)|0xA5 +#define CR_T_A6 (CR_T<<8)|0xA6 +#define CR_T_A7 (CR_T<<8)|0xA7 +#define CR_T_A8 (CR_T<<8)|0xA8 +#define CR_T_A9 (CR_T<<8)|0xA9 +#define CR_T_AA (CR_T<<8)|0xAA +#define CR_T_AB (CR_T<<8)|0xAB +#define CR_T_AC (CR_T<<8)|0xAC +#define CR_T_AD (CR_T<<8)|0xAD +#define CR_T_AE (CR_T<<8)|0xAE +#define CR_T_AF (CR_T<<8)|0xAF +#define CR_T_B0 (CR_T<<8)|0xB0 +#define CR_T_B1 (CR_T<<8)|0xB1 +#define CR_T_B2 (CR_T<<8)|0xB2 +#define CR_T_B3 (CR_T<<8)|0xB3 +#define CR_T_B4 (CR_T<<8)|0xB4 +#define CR_T_B5 (CR_T<<8)|0xB5 +#define CR_T_B6 (CR_T<<8)|0xB6 +#define CR_T_B7 (CR_T<<8)|0xB7 +#define CR_T_B8 (CR_T<<8)|0xB8 +#define CR_T_B9 (CR_T<<8)|0xB9 +#define CR_T_BA (CR_T<<8)|0xBA +#define CR_T_BB (CR_T<<8)|0xBB +#define CR_T_BC (CR_T<<8)|0xBC +#define CR_T_BD (CR_T<<8)|0xBD +#define CR_T_BE (CR_T<<8)|0xBE +#define CR_T_BF (CR_T<<8)|0xBF +#define CR_T_C0 (CR_T<<8)|0xC0 +#define CR_T_C1 (CR_T<<8)|0xC1 +#define CR_T_C2 (CR_T<<8)|0xC2 +#define CR_T_C3 (CR_T<<8)|0xC3 +#define CR_T_C4 (CR_T<<8)|0xC4 +#define CR_T_C5 (CR_T<<8)|0xC5 +#define CR_T_C6 (CR_T<<8)|0xC6 +#define CR_T_C7 (CR_T<<8)|0xC7 +#define CR_T_C8 (CR_T<<8)|0xC8 +#define CR_T_C9 (CR_T<<8)|0xC9 +#define CR_T_CA (CR_T<<8)|0xCA +#define CR_T_CB (CR_T<<8)|0xCB +#define CR_T_CC (CR_T<<8)|0xCC +#define CR_T_CD (CR_T<<8)|0xCD +#define CR_T_CE (CR_T<<8)|0xCE +#define CR_T_CF (CR_T<<8)|0xCF +#define CR_T_D0 (CR_T<<8)|0xD0 +#define CR_T_D1 (CR_T<<8)|0xD1 +#define CR_T_D2 (CR_T<<8)|0xD2 +#define CR_T_D3 (CR_T<<8)|0xD3 +#define CR_T_D4 (CR_T<<8)|0xD4 +#define CR_T_D5 (CR_T<<8)|0xD5 +#define CR_T_D6 (CR_T<<8)|0xD6 +#define CR_T_D7 (CR_T<<8)|0xD7 +#define CR_T_D8 (CR_T<<8)|0xD8 +#define CR_T_D9 (CR_T<<8)|0xD9 +#define CR_T_DA (CR_T<<8)|0xDA +#define CR_T_DB (CR_T<<8)|0xDB +#define CR_T_DC (CR_T<<8)|0xDC +#define CR_T_DD (CR_T<<8)|0xDD +#define CR_T_DE (CR_T<<8)|0xDE +#define CR_T_DF (CR_T<<8)|0xDF +#define CR_T_E0 (CR_T<<8)|0xE0 +#define CR_T_E1 (CR_T<<8)|0xE1 +#define CR_T_E2 (CR_T<<8)|0xE2 +#define CR_T_E3 (CR_T<<8)|0xE3 +#define CR_T_E4 (CR_T<<8)|0xE4 +#define CR_T_E5 (CR_T<<8)|0xE5 +#define CR_T_E6 (CR_T<<8)|0xE6 +#define CR_T_E7 (CR_T<<8)|0xE7 +#define CR_T_E8 (CR_T<<8)|0xE8 +#define CR_T_E9 (CR_T<<8)|0xE9 +#define CR_T_EA (CR_T<<8)|0xEA +#define CR_T_EB (CR_T<<8)|0xEB +#define CR_T_EC (CR_T<<8)|0xEC +#define CR_T_ED (CR_T<<8)|0xED +#define CR_T_EE (CR_T<<8)|0xEE +#define CR_T_EF (CR_T<<8)|0xEF +#define CR_T_F0 (CR_T<<8)|0xF0 +#define CR_T_F1 (CR_T<<8)|0xF1 +#define CR_T_F2 (CR_T<<8)|0xF2 +#define CR_T_F3 (CR_T<<8)|0xF3 +#define CR_T_F4 (CR_T<<8)|0xF4 +#define CR_T_F5 (CR_T<<8)|0xF5 +#define CR_T_F6 (CR_T<<8)|0xF6 +#define CR_T_F7 (CR_T<<8)|0xF7 +#define CR_T_F8 (CR_T<<8)|0xF8 +#define CR_T_F9 (CR_T<<8)|0xF9 +#define CR_T_FA (CR_T<<8)|0xFA +#define CR_T_FB (CR_T<<8)|0xFB +#define CR_T_FC (CR_T<<8)|0xFC +#define CR_T_FD (CR_T<<8)|0xFD +#define CR_T_FE (CR_T<<8)|0xFE +#define CR_T_FF (CR_T<<8)|0xFF + +#define CR_F_11 (CR_F<<8)|0x11 +#define CR_F_35 (CR_F<<8)|0x35 + +#define CR_C_00 (CR_C<<8)|0x00 +#define CR_C_01 (CR_C<<8)|0x01 +#define CR_C_02 (CR_C<<8)|0x02 +#define CR_C_03 (CR_C<<8)|0x03 +#define CR_C_04 (CR_C<<8)|0x04 +#define CR_C_05 (CR_C<<8)|0x05 +#define CR_C_06 (CR_C<<8)|0x06 +#define CR_C_07 (CR_C<<8)|0x07 +#define CR_C_08 (CR_C<<8)|0x08 +#define CR_C_09 (CR_C<<8)|0x09 +#define CR_C_0A (CR_C<<8)|0x0A +#define CR_C_0B (CR_C<<8)|0x0B +#define CR_C_0C (CR_C<<8)|0x0C +#define CR_C_0D (CR_C<<8)|0x0D +#define CR_C_0E (CR_C<<8)|0x0E +#define CR_C_0F (CR_C<<8)|0x0F +#define CR_C_10 (CR_C<<8)|0x10 +#define CR_C_11 (CR_C<<8)|0x11 +#define CR_C_12 (CR_C<<8)|0x12 +#define CR_C_13 (CR_C<<8)|0x13 +#define CR_C_14 (CR_C<<8)|0x14 +#define CR_C_15 (CR_C<<8)|0x15 +#define CR_C_16 (CR_C<<8)|0x16 +#define CR_C_17 (CR_C<<8)|0x17 +#define CR_C_18 (CR_C<<8)|0x18 +#define CR_C_19 (CR_C<<8)|0x19 +#define CR_C_1A (CR_C<<8)|0x1A +#define CR_C_1B (CR_C<<8)|0x1B +#define CR_C_1C (CR_C<<8)|0x1C +#define CR_C_1D (CR_C<<8)|0x1D +#define CR_C_1E (CR_C<<8)|0x1E +#define CR_C_1F (CR_C<<8)|0x1F +#define CR_C_20 (CR_C<<8)|0x20 +#define CR_C_21 (CR_C<<8)|0x21 +#define CR_C_22 (CR_C<<8)|0x22 +#define CR_C_23 (CR_C<<8)|0x23 +#define CR_C_24 (CR_C<<8)|0x24 +#define CR_C_25 (CR_C<<8)|0x25 +#define CR_C_26 (CR_C<<8)|0x26 +#define CR_C_27 (CR_C<<8)|0x27 +#define CR_C_28 (CR_C<<8)|0x28 +#define CR_C_29 (CR_C<<8)|0x29 +#define CR_C_2A (CR_C<<8)|0x2A +#define CR_C_2B (CR_C<<8)|0x2B +#define CR_C_2C (CR_C<<8)|0x2C +#define CR_C_2D (CR_C<<8)|0x2D +#define CR_C_2E (CR_C<<8)|0x2E +#define CR_C_2F (CR_C<<8)|0x2F +#define CR_C_30 (CR_C<<8)|0x30 +#define CR_C_31 (CR_C<<8)|0x31 +#define CR_C_32 (CR_C<<8)|0x32 +#define CR_C_33 (CR_C<<8)|0x33 +#define CR_C_34 (CR_C<<8)|0x34 +#define CR_C_35 (CR_C<<8)|0x35 +#define CR_C_36 (CR_C<<8)|0x36 +#define CR_C_37 (CR_C<<8)|0x37 +#define CR_C_38 (CR_C<<8)|0x38 +#define CR_C_39 (CR_C<<8)|0x39 +#define CR_C_3A (CR_C<<8)|0x3A +#define CR_C_3B (CR_C<<8)|0x3B +#define CR_C_3C (CR_C<<8)|0x3C +#define CR_C_3D (CR_C<<8)|0x3D +#define CR_C_3E (CR_C<<8)|0x3E +#define CR_C_3F (CR_C<<8)|0x3F +#define CR_C_40 (CR_C<<8)|0x40 +#define CR_C_41 (CR_C<<8)|0x41 +#define CR_C_42 (CR_C<<8)|0x42 +#define CR_C_43 (CR_C<<8)|0x43 +#define CR_C_44 (CR_C<<8)|0x44 +#define CR_C_45 (CR_C<<8)|0x45 +#define CR_C_46 (CR_C<<8)|0x46 +#define CR_C_47 (CR_C<<8)|0x47 +#define CR_C_48 (CR_C<<8)|0x48 +#define CR_C_49 (CR_C<<8)|0x49 +#define CR_C_4A (CR_C<<8)|0x4A +#define CR_C_4B (CR_C<<8)|0x4B +#define CR_C_4C (CR_C<<8)|0x4C +#define CR_C_4D (CR_C<<8)|0x4D +#define CR_C_4E (CR_C<<8)|0x4E +#define CR_C_4F (CR_C<<8)|0x4F +#define CR_C_50 (CR_C<<8)|0x50 +#define CR_C_51 (CR_C<<8)|0x51 +#define CR_C_52 (CR_C<<8)|0x52 +#define CR_C_53 (CR_C<<8)|0x53 +#define CR_C_54 (CR_C<<8)|0x54 +#define CR_C_55 (CR_C<<8)|0x55 +#define CR_C_56 (CR_C<<8)|0x56 +#define CR_C_57 (CR_C<<8)|0x57 +#define CR_C_58 (CR_C<<8)|0x58 +#define CR_C_59 (CR_C<<8)|0x59 +#define CR_C_5A (CR_C<<8)|0x5A +#define CR_C_5B (CR_C<<8)|0x5B +#define CR_C_5C (CR_C<<8)|0x5C +#define CR_C_5D (CR_C<<8)|0x5D +#define CR_C_5E (CR_C<<8)|0x5E +#define CR_C_5F (CR_C<<8)|0x5F +#define CR_C_60 (CR_C<<8)|0x60 +#define CR_C_61 (CR_C<<8)|0x61 +#define CR_C_62 (CR_C<<8)|0x62 +#define CR_C_63 (CR_C<<8)|0x63 +#define CR_C_64 (CR_C<<8)|0x64 +#define CR_C_65 (CR_C<<8)|0x65 +#define CR_C_66 (CR_C<<8)|0x66 +#define CR_C_67 (CR_C<<8)|0x67 +#define CR_C_68 (CR_C<<8)|0x68 +#define CR_C_69 (CR_C<<8)|0x69 +#define CR_C_6A (CR_C<<8)|0x6A +#define CR_C_6B (CR_C<<8)|0x6B +#define CR_C_6C (CR_C<<8)|0x6C +#define CR_C_6D (CR_C<<8)|0x6D +#define CR_C_6E (CR_C<<8)|0x6E +#define CR_C_6F (CR_C<<8)|0x6F +#define CR_C_70 (CR_C<<8)|0x70 +#define CR_C_71 (CR_C<<8)|0x71 +#define CR_C_72 (CR_C<<8)|0x72 +#define CR_C_73 (CR_C<<8)|0x73 +#define CR_C_74 (CR_C<<8)|0x74 +#define CR_C_75 (CR_C<<8)|0x75 +#define CR_C_76 (CR_C<<8)|0x76 +#define CR_C_77 (CR_C<<8)|0x77 +#define CR_C_78 (CR_C<<8)|0x78 +#define CR_C_79 (CR_C<<8)|0x79 +#define CR_C_7A (CR_C<<8)|0x7A +#define CR_C_7B (CR_C<<8)|0x7B +#define CR_C_7C (CR_C<<8)|0x7C +#define CR_C_7D (CR_C<<8)|0x7D +#define CR_C_7E (CR_C<<8)|0x7E +#define CR_C_7F (CR_C<<8)|0x7F +#define CR_C_80 (CR_C<<8)|0x80 +#define CR_C_81 (CR_C<<8)|0x81 +#define CR_C_82 (CR_C<<8)|0x82 +#define CR_C_83 (CR_C<<8)|0x83 +#define CR_C_84 (CR_C<<8)|0x84 +#define CR_C_85 (CR_C<<8)|0x85 +#define CR_C_86 (CR_C<<8)|0x86 +#define CR_C_87 (CR_C<<8)|0x87 +#define CR_C_88 (CR_C<<8)|0x88 +#define CR_C_89 (CR_C<<8)|0x89 +#define CR_C_8A (CR_C<<8)|0x8A +#define CR_C_8B (CR_C<<8)|0x8B +#define CR_C_8C (CR_C<<8)|0x8C +#define CR_C_8D (CR_C<<8)|0x8D +#define CR_C_8E (CR_C<<8)|0x8E +#define CR_C_8F (CR_C<<8)|0x8F +#define CR_C_90 (CR_C<<8)|0x90 +#define CR_C_91 (CR_C<<8)|0x91 +#define CR_C_92 (CR_C<<8)|0x92 +#define CR_C_93 (CR_C<<8)|0x93 +#define CR_C_94 (CR_C<<8)|0x94 +#define CR_C_95 (CR_C<<8)|0x95 +#define CR_C_96 (CR_C<<8)|0x96 +#define CR_C_97 (CR_C<<8)|0x97 +#define CR_C_98 (CR_C<<8)|0x98 +#define CR_C_99 (CR_C<<8)|0x99 +#define CR_C_9A (CR_C<<8)|0x9A +#define CR_C_9B (CR_C<<8)|0x9B +#define CR_C_9C (CR_C<<8)|0x9C +#define CR_C_9D (CR_C<<8)|0x9D +#define CR_C_9E (CR_C<<8)|0x9E +#define CR_C_9F (CR_C<<8)|0x9F +#define CR_C_A0 (CR_C<<8)|0xA0 +#define CR_C_A1 (CR_C<<8)|0xA1 +#define CR_C_A2 (CR_C<<8)|0xA2 +#define CR_C_A3 (CR_C<<8)|0xA3 +#define CR_C_A4 (CR_C<<8)|0xA4 +#define CR_C_A5 (CR_C<<8)|0xA5 +#define CR_C_A6 (CR_C<<8)|0xA6 +#define CR_C_A7 (CR_C<<8)|0xA7 +#define CR_C_A8 (CR_C<<8)|0xA8 +#define CR_C_A9 (CR_C<<8)|0xA9 +#define CR_C_AA (CR_C<<8)|0xAA +#define CR_C_AB (CR_C<<8)|0xAB +#define CR_C_AC (CR_C<<8)|0xAC +#define CR_C_AD (CR_C<<8)|0xAD +#define CR_C_AE (CR_C<<8)|0xAE +#define CR_C_AF (CR_C<<8)|0xAF +#define CR_C_B0 (CR_C<<8)|0xB0 +#define CR_C_B1 (CR_C<<8)|0xB1 +#define CR_C_B2 (CR_C<<8)|0xB2 +#define CR_C_B3 (CR_C<<8)|0xB3 +#define CR_C_B4 (CR_C<<8)|0xB4 +#define CR_C_B5 (CR_C<<8)|0xB5 +#define CR_C_B6 (CR_C<<8)|0xB6 +#define CR_C_B7 (CR_C<<8)|0xB7 +#define CR_C_B8 (CR_C<<8)|0xB8 +#define CR_C_B9 (CR_C<<8)|0xB9 +#define CR_C_BA (CR_C<<8)|0xBA +#define CR_C_BB (CR_C<<8)|0xBB +#define CR_C_BC (CR_C<<8)|0xBC +#define CR_C_BD (CR_C<<8)|0xBD +#define CR_C_BE (CR_C<<8)|0xBE +#define CR_C_BF (CR_C<<8)|0xBF +#define CR_C_C0 (CR_C<<8)|0xC0 +#define CR_C_C1 (CR_C<<8)|0xC1 +#define CR_C_C2 (CR_C<<8)|0xC2 +#define CR_C_C3 (CR_C<<8)|0xC3 +#define CR_C_C4 (CR_C<<8)|0xC4 +#define CR_C_C5 (CR_C<<8)|0xC5 +#define CR_C_C6 (CR_C<<8)|0xC6 +#define CR_C_C7 (CR_C<<8)|0xC7 +#define CR_C_C8 (CR_C<<8)|0xC8 +#define CR_C_C9 (CR_C<<8)|0xC9 +#define CR_C_CA (CR_C<<8)|0xCA +#define CR_C_CB (CR_C<<8)|0xCB +#define CR_C_CC (CR_C<<8)|0xCC +#define CR_C_CD (CR_C<<8)|0xCD +#define CR_C_CE (CR_C<<8)|0xCE +#define CR_C_CF (CR_C<<8)|0xCF +#define CR_C_D0 (CR_C<<8)|0xD0 +#define CR_C_D1 (CR_C<<8)|0xD1 +#define CR_C_D2 (CR_C<<8)|0xD2 +#define CR_C_D3 (CR_C<<8)|0xD3 +#define CR_C_D4 (CR_C<<8)|0xD4 +#define CR_C_D5 (CR_C<<8)|0xD5 +#define CR_C_D6 (CR_C<<8)|0xD6 +#define CR_C_D7 (CR_C<<8)|0xD7 +#define CR_C_D8 (CR_C<<8)|0xD8 +#define CR_C_D9 (CR_C<<8)|0xD9 +#define CR_C_DA (CR_C<<8)|0xDA +#define CR_C_DB (CR_C<<8)|0xDB +#define CR_C_DC (CR_C<<8)|0xDC +#define CR_C_DD (CR_C<<8)|0xDD +#define CR_C_DE (CR_C<<8)|0xDE +#define CR_C_DF (CR_C<<8)|0xDF +#define CR_C_E0 (CR_C<<8)|0xE0 +#define CR_C_E1 (CR_C<<8)|0xE1 +#define CR_C_E2 (CR_C<<8)|0xE2 +#define CR_C_E3 (CR_C<<8)|0xE3 +#define CR_C_E4 (CR_C<<8)|0xE4 +#define CR_C_E5 (CR_C<<8)|0xE5 +#define CR_C_E6 (CR_C<<8)|0xE6 +#define CR_C_E7 (CR_C<<8)|0xE7 +#define CR_C_E8 (CR_C<<8)|0xE8 +#define CR_C_E9 (CR_C<<8)|0xE9 +#define CR_C_EA (CR_C<<8)|0xEA +#define CR_C_EB (CR_C<<8)|0xEB +#define CR_C_EC (CR_C<<8)|0xEC +#define CR_C_ED (CR_C<<8)|0xED +#define CR_C_EE (CR_C<<8)|0xEE +#define CR_C_EF (CR_C<<8)|0xEF +#define CR_C_F0 (CR_C<<8)|0xF0 +#define CR_C_F1 (CR_C<<8)|0xF1 +#define CR_C_F2 (CR_C<<8)|0xF2 +#define CR_C_F3 (CR_C<<8)|0xF3 +#define CR_C_F4 (CR_C<<8)|0xF4 +#define CR_C_F5 (CR_C<<8)|0xF5 +#define CR_C_F6 (CR_C<<8)|0xF6 +#define CR_C_F7 (CR_C<<8)|0xF7 +#define CR_C_F8 (CR_C<<8)|0xF8 +#define CR_C_F9 (CR_C<<8)|0xF9 +#define CR_C_FA (CR_C<<8)|0xFA +#define CR_C_FB (CR_C<<8)|0xFB +#define CR_C_FC (CR_C<<8)|0xFC +#define CR_C_FD (CR_C<<8)|0xFD +#define CR_C_FE (CR_C<<8)|0xFE +#define CR_C_FF (CR_C<<8)|0xFF + +#define CR_D_1_00 (CR_D_1<<8)|0x00 +#define CR_D_1_01 (CR_D_1<<8)|0x01 +#define CR_D_1_02 (CR_D_1<<8)|0x02 +#define CR_D_1_03 (CR_D_1<<8)|0x03 +#define CR_D_1_04 (CR_D_1<<8)|0x04 +#define CR_D_1_05 (CR_D_1<<8)|0x05 +#define CR_D_1_06 (CR_D_1<<8)|0x06 +#define CR_D_1_07 (CR_D_1<<8)|0x07 +#define CR_D_1_08 (CR_D_1<<8)|0x08 +#define CR_D_1_09 (CR_D_1<<8)|0x09 +#define CR_D_1_0A (CR_D_1<<8)|0x0A +#define CR_D_1_0B (CR_D_1<<8)|0x0B +#define CR_D_1_0C (CR_D_1<<8)|0x0C +#define CR_D_1_0D (CR_D_1<<8)|0x0D +#define CR_D_1_0E (CR_D_1<<8)|0x0E +#define CR_D_1_0F (CR_D_1<<8)|0x0F +#define CR_D_1_10 (CR_D_1<<8)|0x10 +#define CR_D_1_11 (CR_D_1<<8)|0x11 +#define CR_D_1_12 (CR_D_1<<8)|0x12 +#define CR_D_1_13 (CR_D_1<<8)|0x13 +#define CR_D_1_14 (CR_D_1<<8)|0x14 +#define CR_D_1_15 (CR_D_1<<8)|0x15 +#define CR_D_1_16 (CR_D_1<<8)|0x16 +#define CR_D_1_17 (CR_D_1<<8)|0x17 +#define CR_D_1_18 (CR_D_1<<8)|0x18 +#define CR_D_1_19 (CR_D_1<<8)|0x19 +#define CR_D_1_1A (CR_D_1<<8)|0x1A +#define CR_D_1_1B (CR_D_1<<8)|0x1B +#define CR_D_1_1C (CR_D_1<<8)|0x1C +#define CR_D_1_1D (CR_D_1<<8)|0x1D +#define CR_D_1_1E (CR_D_1<<8)|0x1E +#define CR_D_1_1F (CR_D_1<<8)|0x1F +#define CR_D_1_20 (CR_D_1<<8)|0x20 +#define CR_D_1_21 (CR_D_1<<8)|0x21 +#define CR_D_1_22 (CR_D_1<<8)|0x22 +#define CR_D_1_23 (CR_D_1<<8)|0x23 +#define CR_D_1_24 (CR_D_1<<8)|0x24 +#define CR_D_1_25 (CR_D_1<<8)|0x25 +#define CR_D_1_26 (CR_D_1<<8)|0x26 +#define CR_D_1_27 (CR_D_1<<8)|0x27 +#define CR_D_1_28 (CR_D_1<<8)|0x28 +#define CR_D_1_29 (CR_D_1<<8)|0x29 +#define CR_D_1_2A (CR_D_1<<8)|0x2A +#define CR_D_1_2B (CR_D_1<<8)|0x2B +#define CR_D_1_2C (CR_D_1<<8)|0x2C +#define CR_D_1_2D (CR_D_1<<8)|0x2D +#define CR_D_1_2E (CR_D_1<<8)|0x2E +#define CR_D_1_2F (CR_D_1<<8)|0x2F +#define CR_D_1_30 (CR_D_1<<8)|0x30 +#define CR_D_1_31 (CR_D_1<<8)|0x31 +#define CR_D_1_32 (CR_D_1<<8)|0x32 +#define CR_D_1_33 (CR_D_1<<8)|0x33 +#define CR_D_1_34 (CR_D_1<<8)|0x34 +#define CR_D_1_35 (CR_D_1<<8)|0x35 +#define CR_D_1_36 (CR_D_1<<8)|0x36 +#define CR_D_1_37 (CR_D_1<<8)|0x37 +#define CR_D_1_38 (CR_D_1<<8)|0x38 +#define CR_D_1_39 (CR_D_1<<8)|0x39 +#define CR_D_1_3A (CR_D_1<<8)|0x3A +#define CR_D_1_3B (CR_D_1<<8)|0x3B +#define CR_D_1_3C (CR_D_1<<8)|0x3C +#define CR_D_1_3D (CR_D_1<<8)|0x3D +#define CR_D_1_3E (CR_D_1<<8)|0x3E +#define CR_D_1_3F (CR_D_1<<8)|0x3F +#define CR_D_1_40 (CR_D_1<<8)|0x40 +#define CR_D_1_41 (CR_D_1<<8)|0x41 +#define CR_D_1_42 (CR_D_1<<8)|0x42 +#define CR_D_1_43 (CR_D_1<<8)|0x43 +#define CR_D_1_44 (CR_D_1<<8)|0x44 +#define CR_D_1_45 (CR_D_1<<8)|0x45 +#define CR_D_1_46 (CR_D_1<<8)|0x46 +#define CR_D_1_47 (CR_D_1<<8)|0x47 +#define CR_D_1_48 (CR_D_1<<8)|0x48 +#define CR_D_1_49 (CR_D_1<<8)|0x49 +#define CR_D_1_4A (CR_D_1<<8)|0x4A +#define CR_D_1_4B (CR_D_1<<8)|0x4B +#define CR_D_1_4C (CR_D_1<<8)|0x4C +#define CR_D_1_4D (CR_D_1<<8)|0x4D +#define CR_D_1_4E (CR_D_1<<8)|0x4E +#define CR_D_1_4F (CR_D_1<<8)|0x4F +#define CR_D_1_50 (CR_D_1<<8)|0x50 +#define CR_D_1_51 (CR_D_1<<8)|0x51 +#define CR_D_1_52 (CR_D_1<<8)|0x52 +#define CR_D_1_53 (CR_D_1<<8)|0x53 +#define CR_D_1_54 (CR_D_1<<8)|0x54 +#define CR_D_1_55 (CR_D_1<<8)|0x55 +#define CR_D_1_56 (CR_D_1<<8)|0x56 +#define CR_D_1_57 (CR_D_1<<8)|0x57 +#define CR_D_1_58 (CR_D_1<<8)|0x58 +#define CR_D_1_59 (CR_D_1<<8)|0x59 +#define CR_D_1_5A (CR_D_1<<8)|0x5A +#define CR_D_1_5B (CR_D_1<<8)|0x5B +#define CR_D_1_5C (CR_D_1<<8)|0x5C +#define CR_D_1_5D (CR_D_1<<8)|0x5D +#define CR_D_1_5E (CR_D_1<<8)|0x5E +#define CR_D_1_5F (CR_D_1<<8)|0x5F +#define CR_D_1_60 (CR_D_1<<8)|0x60 +#define CR_D_1_61 (CR_D_1<<8)|0x61 +#define CR_D_1_62 (CR_D_1<<8)|0x62 +#define CR_D_1_63 (CR_D_1<<8)|0x63 +#define CR_D_1_64 (CR_D_1<<8)|0x64 +#define CR_D_1_65 (CR_D_1<<8)|0x65 +#define CR_D_1_66 (CR_D_1<<8)|0x66 +#define CR_D_1_67 (CR_D_1<<8)|0x67 +#define CR_D_1_68 (CR_D_1<<8)|0x68 +#define CR_D_1_69 (CR_D_1<<8)|0x69 +#define CR_D_1_6A (CR_D_1<<8)|0x6A +#define CR_D_1_6B (CR_D_1<<8)|0x6B +#define CR_D_1_6C (CR_D_1<<8)|0x6C +#define CR_D_1_6D (CR_D_1<<8)|0x6D +#define CR_D_1_6E (CR_D_1<<8)|0x6E +#define CR_D_1_6F (CR_D_1<<8)|0x6F +#define CR_D_1_70 (CR_D_1<<8)|0x70 +#define CR_D_1_71 (CR_D_1<<8)|0x71 +#define CR_D_1_72 (CR_D_1<<8)|0x72 +#define CR_D_1_73 (CR_D_1<<8)|0x73 +#define CR_D_1_74 (CR_D_1<<8)|0x74 +#define CR_D_1_75 (CR_D_1<<8)|0x75 +#define CR_D_1_76 (CR_D_1<<8)|0x76 +#define CR_D_1_77 (CR_D_1<<8)|0x77 +#define CR_D_1_78 (CR_D_1<<8)|0x78 +#define CR_D_1_79 (CR_D_1<<8)|0x79 +#define CR_D_1_7A (CR_D_1<<8)|0x7A +#define CR_D_1_7B (CR_D_1<<8)|0x7B +#define CR_D_1_7C (CR_D_1<<8)|0x7C +#define CR_D_1_7D (CR_D_1<<8)|0x7D +#define CR_D_1_7E (CR_D_1<<8)|0x7E +#define CR_D_1_7F (CR_D_1<<8)|0x7F +#define CR_D_1_80 (CR_D_1<<8)|0x80 +#define CR_D_1_81 (CR_D_1<<8)|0x81 +#define CR_D_1_82 (CR_D_1<<8)|0x82 +#define CR_D_1_83 (CR_D_1<<8)|0x83 +#define CR_D_1_84 (CR_D_1<<8)|0x84 +#define CR_D_1_85 (CR_D_1<<8)|0x85 +#define CR_D_1_86 (CR_D_1<<8)|0x86 +#define CR_D_1_87 (CR_D_1<<8)|0x87 +#define CR_D_1_88 (CR_D_1<<8)|0x88 +#define CR_D_1_89 (CR_D_1<<8)|0x89 +#define CR_D_1_8A (CR_D_1<<8)|0x8A +#define CR_D_1_8B (CR_D_1<<8)|0x8B +#define CR_D_1_8C (CR_D_1<<8)|0x8C +#define CR_D_1_8D (CR_D_1<<8)|0x8D +#define CR_D_1_8E (CR_D_1<<8)|0x8E +#define CR_D_1_8F (CR_D_1<<8)|0x8F +#define CR_D_1_90 (CR_D_1<<8)|0x90 +#define CR_D_1_91 (CR_D_1<<8)|0x91 +#define CR_D_1_92 (CR_D_1<<8)|0x92 +#define CR_D_1_93 (CR_D_1<<8)|0x93 +#define CR_D_1_94 (CR_D_1<<8)|0x94 +#define CR_D_1_95 (CR_D_1<<8)|0x95 +#define CR_D_1_96 (CR_D_1<<8)|0x96 +#define CR_D_1_97 (CR_D_1<<8)|0x97 +#define CR_D_1_98 (CR_D_1<<8)|0x98 +#define CR_D_1_99 (CR_D_1<<8)|0x99 +#define CR_D_1_9A (CR_D_1<<8)|0x9A +#define CR_D_1_9B (CR_D_1<<8)|0x9B +#define CR_D_1_9C (CR_D_1<<8)|0x9C +#define CR_D_1_9D (CR_D_1<<8)|0x9D +#define CR_D_1_9E (CR_D_1<<8)|0x9E +#define CR_D_1_9F (CR_D_1<<8)|0x9F +#define CR_D_1_A0 (CR_D_1<<8)|0xA0 +#define CR_D_1_A1 (CR_D_1<<8)|0xA1 +#define CR_D_1_A2 (CR_D_1<<8)|0xA2 +#define CR_D_1_A3 (CR_D_1<<8)|0xA3 +#define CR_D_1_A4 (CR_D_1<<8)|0xA4 +#define CR_D_1_A5 (CR_D_1<<8)|0xA5 +#define CR_D_1_A6 (CR_D_1<<8)|0xA6 +#define CR_D_1_A7 (CR_D_1<<8)|0xA7 +#define CR_D_1_A8 (CR_D_1<<8)|0xA8 +#define CR_D_1_A9 (CR_D_1<<8)|0xA9 +#define CR_D_1_AA (CR_D_1<<8)|0xAA +#define CR_D_1_AB (CR_D_1<<8)|0xAB +#define CR_D_1_AC (CR_D_1<<8)|0xAC +#define CR_D_1_AD (CR_D_1<<8)|0xAD +#define CR_D_1_AE (CR_D_1<<8)|0xAE +#define CR_D_1_AF (CR_D_1<<8)|0xAF +#define CR_D_1_B0 (CR_D_1<<8)|0xB0 +#define CR_D_1_B1 (CR_D_1<<8)|0xB1 +#define CR_D_1_B2 (CR_D_1<<8)|0xB2 +#define CR_D_1_B3 (CR_D_1<<8)|0xB3 +#define CR_D_1_B4 (CR_D_1<<8)|0xB4 +#define CR_D_1_B5 (CR_D_1<<8)|0xB5 +#define CR_D_1_B6 (CR_D_1<<8)|0xB6 +#define CR_D_1_B7 (CR_D_1<<8)|0xB7 +#define CR_D_1_B8 (CR_D_1<<8)|0xB8 +#define CR_D_1_B9 (CR_D_1<<8)|0xB9 +#define CR_D_1_BA (CR_D_1<<8)|0xBA +#define CR_D_1_BB (CR_D_1<<8)|0xBB +#define CR_D_1_BC (CR_D_1<<8)|0xBC +#define CR_D_1_BD (CR_D_1<<8)|0xBD +#define CR_D_1_BE (CR_D_1<<8)|0xBE +#define CR_D_1_BF (CR_D_1<<8)|0xBF +#define CR_D_1_C0 (CR_D_1<<8)|0xC0 +#define CR_D_1_C1 (CR_D_1<<8)|0xC1 +#define CR_D_1_C2 (CR_D_1<<8)|0xC2 +#define CR_D_1_C3 (CR_D_1<<8)|0xC3 +#define CR_D_1_C4 (CR_D_1<<8)|0xC4 +#define CR_D_1_C5 (CR_D_1<<8)|0xC5 +#define CR_D_1_C6 (CR_D_1<<8)|0xC6 +#define CR_D_1_C7 (CR_D_1<<8)|0xC7 +#define CR_D_1_C8 (CR_D_1<<8)|0xC8 +#define CR_D_1_C9 (CR_D_1<<8)|0xC9 +#define CR_D_1_CA (CR_D_1<<8)|0xCA +#define CR_D_1_CB (CR_D_1<<8)|0xCB +#define CR_D_1_CC (CR_D_1<<8)|0xCC +#define CR_D_1_CD (CR_D_1<<8)|0xCD +#define CR_D_1_CE (CR_D_1<<8)|0xCE +#define CR_D_1_CF (CR_D_1<<8)|0xCF +#define CR_D_1_D0 (CR_D_1<<8)|0xD0 +#define CR_D_1_D1 (CR_D_1<<8)|0xD1 +#define CR_D_1_D2 (CR_D_1<<8)|0xD2 +#define CR_D_1_D3 (CR_D_1<<8)|0xD3 +#define CR_D_1_D4 (CR_D_1<<8)|0xD4 +#define CR_D_1_D5 (CR_D_1<<8)|0xD5 +#define CR_D_1_D6 (CR_D_1<<8)|0xD6 +#define CR_D_1_D7 (CR_D_1<<8)|0xD7 +#define CR_D_1_D8 (CR_D_1<<8)|0xD8 +#define CR_D_1_D9 (CR_D_1<<8)|0xD9 +#define CR_D_1_DA (CR_D_1<<8)|0xDA +#define CR_D_1_DB (CR_D_1<<8)|0xDB +#define CR_D_1_DC (CR_D_1<<8)|0xDC +#define CR_D_1_DD (CR_D_1<<8)|0xDD +#define CR_D_1_DE (CR_D_1<<8)|0xDE +#define CR_D_1_DF (CR_D_1<<8)|0xDF +#define CR_D_1_E0 (CR_D_1<<8)|0xE0 +#define CR_D_1_E1 (CR_D_1<<8)|0xE1 +#define CR_D_1_E2 (CR_D_1<<8)|0xE2 +#define CR_D_1_E3 (CR_D_1<<8)|0xE3 +#define CR_D_1_E4 (CR_D_1<<8)|0xE4 +#define CR_D_1_E5 (CR_D_1<<8)|0xE5 +#define CR_D_1_E6 (CR_D_1<<8)|0xE6 +#define CR_D_1_E7 (CR_D_1<<8)|0xE7 +#define CR_D_1_E8 (CR_D_1<<8)|0xE8 +#define CR_D_1_E9 (CR_D_1<<8)|0xE9 +#define CR_D_1_EA (CR_D_1<<8)|0xEA +#define CR_D_1_EB (CR_D_1<<8)|0xEB +#define CR_D_1_EC (CR_D_1<<8)|0xEC +#define CR_D_1_ED (CR_D_1<<8)|0xED +#define CR_D_1_EE (CR_D_1<<8)|0xEE +#define CR_D_1_EF (CR_D_1<<8)|0xEF +#define CR_D_1_F0 (CR_D_1<<8)|0xF0 +#define CR_D_1_F1 (CR_D_1<<8)|0xF1 +#define CR_D_1_F2 (CR_D_1<<8)|0xF2 +#define CR_D_1_F3 (CR_D_1<<8)|0xF3 +#define CR_D_1_F4 (CR_D_1<<8)|0xF4 +#define CR_D_1_F5 (CR_D_1<<8)|0xF5 +#define CR_D_1_F6 (CR_D_1<<8)|0xF6 +#define CR_D_1_F7 (CR_D_1<<8)|0xF7 +#define CR_D_1_F8 (CR_D_1<<8)|0xF8 +#define CR_D_1_F9 (CR_D_1<<8)|0xF9 +#define CR_D_1_FA (CR_D_1<<8)|0xFA +#define CR_D_1_FB (CR_D_1<<8)|0xFB +#define CR_D_1_FC (CR_D_1<<8)|0xFC +#define CR_D_1_FD (CR_D_1<<8)|0xFD +#define CR_D_1_FE (CR_D_1<<8)|0xFE +#define CR_D_1_FF (CR_D_1<<8)|0xFF + +#define CR_D_2_00 (CR_D_2<<8)|0x00 +#define CR_D_2_01 (CR_D_2<<8)|0x01 +#define CR_D_2_02 (CR_D_2<<8)|0x02 +#define CR_D_2_03 (CR_D_2<<8)|0x03 +#define CR_D_2_04 (CR_D_2<<8)|0x04 +#define CR_D_2_05 (CR_D_2<<8)|0x05 +#define CR_D_2_06 (CR_D_2<<8)|0x06 +#define CR_D_2_07 (CR_D_2<<8)|0x07 +#define CR_D_2_08 (CR_D_2<<8)|0x08 +#define CR_D_2_09 (CR_D_2<<8)|0x09 +#define CR_D_2_0A (CR_D_2<<8)|0x0A +#define CR_D_2_0B (CR_D_2<<8)|0x0B +#define CR_D_2_0C (CR_D_2<<8)|0x0C +#define CR_D_2_0D (CR_D_2<<8)|0x0D +#define CR_D_2_0E (CR_D_2<<8)|0x0E +#define CR_D_2_0F (CR_D_2<<8)|0x0F +#define CR_D_2_10 (CR_D_2<<8)|0x10 +#define CR_D_2_11 (CR_D_2<<8)|0x11 +#define CR_D_2_12 (CR_D_2<<8)|0x12 +#define CR_D_2_13 (CR_D_2<<8)|0x13 +#define CR_D_2_14 (CR_D_2<<8)|0x14 +#define CR_D_2_15 (CR_D_2<<8)|0x15 +#define CR_D_2_16 (CR_D_2<<8)|0x16 +#define CR_D_2_17 (CR_D_2<<8)|0x17 +#define CR_D_2_18 (CR_D_2<<8)|0x18 +#define CR_D_2_19 (CR_D_2<<8)|0x19 +#define CR_D_2_1A (CR_D_2<<8)|0x1A +#define CR_D_2_1B (CR_D_2<<8)|0x1B +#define CR_D_2_1C (CR_D_2<<8)|0x1C +#define CR_D_2_1D (CR_D_2<<8)|0x1D +#define CR_D_2_1E (CR_D_2<<8)|0x1E +#define CR_D_2_1F (CR_D_2<<8)|0x1F +#define CR_D_2_20 (CR_D_2<<8)|0x20 +#define CR_D_2_21 (CR_D_2<<8)|0x21 +#define CR_D_2_22 (CR_D_2<<8)|0x22 +#define CR_D_2_23 (CR_D_2<<8)|0x23 +#define CR_D_2_24 (CR_D_2<<8)|0x24 +#define CR_D_2_25 (CR_D_2<<8)|0x25 +#define CR_D_2_26 (CR_D_2<<8)|0x26 +#define CR_D_2_27 (CR_D_2<<8)|0x27 +#define CR_D_2_28 (CR_D_2<<8)|0x28 +#define CR_D_2_29 (CR_D_2<<8)|0x29 +#define CR_D_2_2A (CR_D_2<<8)|0x2A +#define CR_D_2_2B (CR_D_2<<8)|0x2B +#define CR_D_2_2C (CR_D_2<<8)|0x2C +#define CR_D_2_2D (CR_D_2<<8)|0x2D +#define CR_D_2_2E (CR_D_2<<8)|0x2E +#define CR_D_2_2F (CR_D_2<<8)|0x2F +#define CR_D_2_30 (CR_D_2<<8)|0x30 +#define CR_D_2_31 (CR_D_2<<8)|0x31 +#define CR_D_2_32 (CR_D_2<<8)|0x32 +#define CR_D_2_33 (CR_D_2<<8)|0x33 +#define CR_D_2_34 (CR_D_2<<8)|0x34 +#define CR_D_2_35 (CR_D_2<<8)|0x35 +#define CR_D_2_36 (CR_D_2<<8)|0x36 +#define CR_D_2_37 (CR_D_2<<8)|0x37 +#define CR_D_2_38 (CR_D_2<<8)|0x38 +#define CR_D_2_39 (CR_D_2<<8)|0x39 +#define CR_D_2_3A (CR_D_2<<8)|0x3A +#define CR_D_2_3B (CR_D_2<<8)|0x3B +#define CR_D_2_3C (CR_D_2<<8)|0x3C +#define CR_D_2_3D (CR_D_2<<8)|0x3D +#define CR_D_2_3E (CR_D_2<<8)|0x3E +#define CR_D_2_3F (CR_D_2<<8)|0x3F +#define CR_D_2_40 (CR_D_2<<8)|0x40 +#define CR_D_2_41 (CR_D_2<<8)|0x41 +#define CR_D_2_42 (CR_D_2<<8)|0x42 +#define CR_D_2_43 (CR_D_2<<8)|0x43 +#define CR_D_2_44 (CR_D_2<<8)|0x44 +#define CR_D_2_45 (CR_D_2<<8)|0x45 +#define CR_D_2_46 (CR_D_2<<8)|0x46 +#define CR_D_2_47 (CR_D_2<<8)|0x47 +#define CR_D_2_48 (CR_D_2<<8)|0x48 +#define CR_D_2_49 (CR_D_2<<8)|0x49 +#define CR_D_2_4A (CR_D_2<<8)|0x4A +#define CR_D_2_4B (CR_D_2<<8)|0x4B +#define CR_D_2_4C (CR_D_2<<8)|0x4C +#define CR_D_2_4D (CR_D_2<<8)|0x4D +#define CR_D_2_4E (CR_D_2<<8)|0x4E +#define CR_D_2_4F (CR_D_2<<8)|0x4F +#define CR_D_2_50 (CR_D_2<<8)|0x50 +#define CR_D_2_51 (CR_D_2<<8)|0x51 +#define CR_D_2_52 (CR_D_2<<8)|0x52 +#define CR_D_2_53 (CR_D_2<<8)|0x53 +#define CR_D_2_54 (CR_D_2<<8)|0x54 +#define CR_D_2_55 (CR_D_2<<8)|0x55 +#define CR_D_2_56 (CR_D_2<<8)|0x56 +#define CR_D_2_57 (CR_D_2<<8)|0x57 +#define CR_D_2_58 (CR_D_2<<8)|0x58 +#define CR_D_2_59 (CR_D_2<<8)|0x59 +#define CR_D_2_5A (CR_D_2<<8)|0x5A +#define CR_D_2_5B (CR_D_2<<8)|0x5B +#define CR_D_2_5C (CR_D_2<<8)|0x5C +#define CR_D_2_5D (CR_D_2<<8)|0x5D +#define CR_D_2_5E (CR_D_2<<8)|0x5E +#define CR_D_2_5F (CR_D_2<<8)|0x5F +#define CR_D_2_60 (CR_D_2<<8)|0x60 +#define CR_D_2_61 (CR_D_2<<8)|0x61 +#define CR_D_2_62 (CR_D_2<<8)|0x62 +#define CR_D_2_63 (CR_D_2<<8)|0x63 +#define CR_D_2_64 (CR_D_2<<8)|0x64 +#define CR_D_2_65 (CR_D_2<<8)|0x65 +#define CR_D_2_66 (CR_D_2<<8)|0x66 +#define CR_D_2_67 (CR_D_2<<8)|0x67 +#define CR_D_2_68 (CR_D_2<<8)|0x68 +#define CR_D_2_69 (CR_D_2<<8)|0x69 +#define CR_D_2_6A (CR_D_2<<8)|0x6A +#define CR_D_2_6B (CR_D_2<<8)|0x6B +#define CR_D_2_6C (CR_D_2<<8)|0x6C +#define CR_D_2_6D (CR_D_2<<8)|0x6D +#define CR_D_2_6E (CR_D_2<<8)|0x6E +#define CR_D_2_6F (CR_D_2<<8)|0x6F +#define CR_D_2_70 (CR_D_2<<8)|0x70 +#define CR_D_2_71 (CR_D_2<<8)|0x71 +#define CR_D_2_72 (CR_D_2<<8)|0x72 +#define CR_D_2_73 (CR_D_2<<8)|0x73 +#define CR_D_2_74 (CR_D_2<<8)|0x74 +#define CR_D_2_75 (CR_D_2<<8)|0x75 +#define CR_D_2_76 (CR_D_2<<8)|0x76 +#define CR_D_2_77 (CR_D_2<<8)|0x77 +#define CR_D_2_78 (CR_D_2<<8)|0x78 +#define CR_D_2_79 (CR_D_2<<8)|0x79 +#define CR_D_2_7A (CR_D_2<<8)|0x7A +#define CR_D_2_7B (CR_D_2<<8)|0x7B +#define CR_D_2_7C (CR_D_2<<8)|0x7C +#define CR_D_2_7D (CR_D_2<<8)|0x7D +#define CR_D_2_7E (CR_D_2<<8)|0x7E +#define CR_D_2_7F (CR_D_2<<8)|0x7F +#define CR_D_2_80 (CR_D_2<<8)|0x80 +#define CR_D_2_81 (CR_D_2<<8)|0x81 +#define CR_D_2_82 (CR_D_2<<8)|0x82 +#define CR_D_2_83 (CR_D_2<<8)|0x83 +#define CR_D_2_84 (CR_D_2<<8)|0x84 +#define CR_D_2_85 (CR_D_2<<8)|0x85 +#define CR_D_2_86 (CR_D_2<<8)|0x86 +#define CR_D_2_87 (CR_D_2<<8)|0x87 +#define CR_D_2_88 (CR_D_2<<8)|0x88 +#define CR_D_2_89 (CR_D_2<<8)|0x89 +#define CR_D_2_8A (CR_D_2<<8)|0x8A +#define CR_D_2_8B (CR_D_2<<8)|0x8B +#define CR_D_2_8C (CR_D_2<<8)|0x8C +#define CR_D_2_8D (CR_D_2<<8)|0x8D +#define CR_D_2_8E (CR_D_2<<8)|0x8E +#define CR_D_2_8F (CR_D_2<<8)|0x8F +#define CR_D_2_90 (CR_D_2<<8)|0x90 +#define CR_D_2_91 (CR_D_2<<8)|0x91 +#define CR_D_2_92 (CR_D_2<<8)|0x92 +#define CR_D_2_93 (CR_D_2<<8)|0x93 +#define CR_D_2_94 (CR_D_2<<8)|0x94 +#define CR_D_2_95 (CR_D_2<<8)|0x95 +#define CR_D_2_96 (CR_D_2<<8)|0x96 +#define CR_D_2_97 (CR_D_2<<8)|0x97 +#define CR_D_2_98 (CR_D_2<<8)|0x98 +#define CR_D_2_99 (CR_D_2<<8)|0x99 +#define CR_D_2_9A (CR_D_2<<8)|0x9A +#define CR_D_2_9B (CR_D_2<<8)|0x9B +#define CR_D_2_9C (CR_D_2<<8)|0x9C +#define CR_D_2_9D (CR_D_2<<8)|0x9D +#define CR_D_2_9E (CR_D_2<<8)|0x9E +#define CR_D_2_9F (CR_D_2<<8)|0x9F +#define CR_D_2_A0 (CR_D_2<<8)|0xA0 +#define CR_D_2_A1 (CR_D_2<<8)|0xA1 +#define CR_D_2_A2 (CR_D_2<<8)|0xA2 +#define CR_D_2_A3 (CR_D_2<<8)|0xA3 +#define CR_D_2_A4 (CR_D_2<<8)|0xA4 +#define CR_D_2_A5 (CR_D_2<<8)|0xA5 +#define CR_D_2_A6 (CR_D_2<<8)|0xA6 +#define CR_D_2_A7 (CR_D_2<<8)|0xA7 +#define CR_D_2_A8 (CR_D_2<<8)|0xA8 +#define CR_D_2_A9 (CR_D_2<<8)|0xA9 +#define CR_D_2_AA (CR_D_2<<8)|0xAA +#define CR_D_2_AB (CR_D_2<<8)|0xAB +#define CR_D_2_AC (CR_D_2<<8)|0xAC +#define CR_D_2_AD (CR_D_2<<8)|0xAD +#define CR_D_2_AE (CR_D_2<<8)|0xAE +#define CR_D_2_AF (CR_D_2<<8)|0xAF +#define CR_D_2_B0 (CR_D_2<<8)|0xB0 +#define CR_D_2_B1 (CR_D_2<<8)|0xB1 +#define CR_D_2_B2 (CR_D_2<<8)|0xB2 +#define CR_D_2_B3 (CR_D_2<<8)|0xB3 +#define CR_D_2_B4 (CR_D_2<<8)|0xB4 +#define CR_D_2_B5 (CR_D_2<<8)|0xB5 +#define CR_D_2_B6 (CR_D_2<<8)|0xB6 +#define CR_D_2_B7 (CR_D_2<<8)|0xB7 +#define CR_D_2_B8 (CR_D_2<<8)|0xB8 +#define CR_D_2_B9 (CR_D_2<<8)|0xB9 +#define CR_D_2_BA (CR_D_2<<8)|0xBA +#define CR_D_2_BB (CR_D_2<<8)|0xBB +#define CR_D_2_BC (CR_D_2<<8)|0xBC +#define CR_D_2_BD (CR_D_2<<8)|0xBD +#define CR_D_2_BE (CR_D_2<<8)|0xBE +#define CR_D_2_BF (CR_D_2<<8)|0xBF +#define CR_D_2_C0 (CR_D_2<<8)|0xC0 +#define CR_D_2_C1 (CR_D_2<<8)|0xC1 +#define CR_D_2_C2 (CR_D_2<<8)|0xC2 +#define CR_D_2_C3 (CR_D_2<<8)|0xC3 +#define CR_D_2_C4 (CR_D_2<<8)|0xC4 +#define CR_D_2_C5 (CR_D_2<<8)|0xC5 +#define CR_D_2_C6 (CR_D_2<<8)|0xC6 +#define CR_D_2_C7 (CR_D_2<<8)|0xC7 +#define CR_D_2_C8 (CR_D_2<<8)|0xC8 +#define CR_D_2_C9 (CR_D_2<<8)|0xC9 +#define CR_D_2_CA (CR_D_2<<8)|0xCA +#define CR_D_2_CB (CR_D_2<<8)|0xCB +#define CR_D_2_CC (CR_D_2<<8)|0xCC +#define CR_D_2_CD (CR_D_2<<8)|0xCD +#define CR_D_2_CE (CR_D_2<<8)|0xCE +#define CR_D_2_CF (CR_D_2<<8)|0xCF +#define CR_D_2_D0 (CR_D_2<<8)|0xD0 +#define CR_D_2_D1 (CR_D_2<<8)|0xD1 +#define CR_D_2_D2 (CR_D_2<<8)|0xD2 +#define CR_D_2_D3 (CR_D_2<<8)|0xD3 +#define CR_D_2_D4 (CR_D_2<<8)|0xD4 +#define CR_D_2_D5 (CR_D_2<<8)|0xD5 +#define CR_D_2_D6 (CR_D_2<<8)|0xD6 +#define CR_D_2_D7 (CR_D_2<<8)|0xD7 +#define CR_D_2_D8 (CR_D_2<<8)|0xD8 +#define CR_D_2_D9 (CR_D_2<<8)|0xD9 +#define CR_D_2_DA (CR_D_2<<8)|0xDA +#define CR_D_2_DB (CR_D_2<<8)|0xDB +#define CR_D_2_DC (CR_D_2<<8)|0xDC +#define CR_D_2_DD (CR_D_2<<8)|0xDD +#define CR_D_2_DE (CR_D_2<<8)|0xDE +#define CR_D_2_DF (CR_D_2<<8)|0xDF +#define CR_D_2_E0 (CR_D_2<<8)|0xE0 +#define CR_D_2_E1 (CR_D_2<<8)|0xE1 +#define CR_D_2_E2 (CR_D_2<<8)|0xE2 +#define CR_D_2_E3 (CR_D_2<<8)|0xE3 +#define CR_D_2_E4 (CR_D_2<<8)|0xE4 +#define CR_D_2_E5 (CR_D_2<<8)|0xE5 +#define CR_D_2_E6 (CR_D_2<<8)|0xE6 +#define CR_D_2_E7 (CR_D_2<<8)|0xE7 +#define CR_D_2_E8 (CR_D_2<<8)|0xE8 +#define CR_D_2_E9 (CR_D_2<<8)|0xE9 +#define CR_D_2_EA (CR_D_2<<8)|0xEA +#define CR_D_2_EB (CR_D_2<<8)|0xEB +#define CR_D_2_EC (CR_D_2<<8)|0xEC +#define CR_D_2_ED (CR_D_2<<8)|0xED +#define CR_D_2_EE (CR_D_2<<8)|0xEE +#define CR_D_2_EF (CR_D_2<<8)|0xEF +#define CR_D_2_F0 (CR_D_2<<8)|0xF0 +#define CR_D_2_F1 (CR_D_2<<8)|0xF1 +#define CR_D_2_F2 (CR_D_2<<8)|0xF2 +#define CR_D_2_F3 (CR_D_2<<8)|0xF3 +#define CR_D_2_F4 (CR_D_2<<8)|0xF4 +#define CR_D_2_F5 (CR_D_2<<8)|0xF5 +#define CR_D_2_F6 (CR_D_2<<8)|0xF6 +#define CR_D_2_F7 (CR_D_2<<8)|0xF7 +#define CR_D_2_F8 (CR_D_2<<8)|0xF8 +#define CR_D_2_F9 (CR_D_2<<8)|0xF9 +#define CR_D_2_FA (CR_D_2<<8)|0xFA +#define CR_D_2_FB (CR_D_2<<8)|0xFB +#define CR_D_2_FC (CR_D_2<<8)|0xFC +#define CR_D_2_FD (CR_D_2<<8)|0xFD +#define CR_D_2_FE (CR_D_2<<8)|0xFE +#define CR_D_2_FF (CR_D_2<<8)|0xFF + +#endif /* _CBIOS_REG_H_ */ + diff --git a/drivers/gpu/drm/arise/cbios/Device/CBiosShare.c b/drivers/gpu/drm/arise/cbios/Device/CBiosShare.c new file mode 100644 index 0000000000000..433305e941d9d --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/CBiosShare.c @@ -0,0 +1,389 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** Hw independent and chip independent functions. +** +** NOTE: +** The function in this file WOULD BETTER not use CBIOS_EXTENSION_COMMON. +******************************************************************************/ + +#include "CBiosShare.h" +#include "CBiosChipShare.h" + +#define BACK_BUFFER_COUNT 64 + +static CBIOS_U32 ModuleMask = 0; +static CBIOS_U32 MaxDbgLevel = 2; +static CBIOS_U32 ModuleMaskLevel = 0x3; +static CBIOS_UCHAR* pDebugBuf = CBIOS_NULL; +static CBIOS_UCHAR* pBackBuf = CBIOS_NULL; +static CBIOS_BOOL bEnableBackOutput = CBIOS_FALSE; +static CBIOS_U32 TimeStamp = 0; +static CBIOS_U32 BackBufIndex = 0; + +CBIOS_UCHAR* ModuleName[] = +{ + (CBIOS_UCHAR*)"[DISP] General ", + (CBIOS_UCHAR*)"[DISP] MHL ", + (CBIOS_UCHAR*)"[DISP] DSI ", + (CBIOS_UCHAR*)"[DISP] HDMI ", + (CBIOS_UCHAR*)"[DISP] DP ", +}; + +CBIOS_UCHAR* DebugLevelName[] = +{ + (CBIOS_UCHAR*)"Error: ", + (CBIOS_UCHAR*)"Warning: ", + (CBIOS_UCHAR*)"Info: ", + (CBIOS_UCHAR*)"Debug: ", + (CBIOS_UCHAR*)"Trace: ", +}; + + +#ifndef __LINUX__ +CBIOS_VOID cbPrintMessage(CBIOS_U32 DebugPrintLevel, CBIOS_CHAR *DebugMessage, ...) +{ + va_list args; + CBIOS_UCHAR *pDebugString; + CBIOS_BOOL isSkipPrint = CBIOS_TRUE; + CBIOS_U32 preLen = 0; + + if(((DebugPrintLevel & 0xFF) <= MaxDbgLevel) || ((DebugPrintLevel & ModuleMask) &&((DebugPrintLevel & 0xFF) <= ModuleMaskLevel ))) + { + isSkipPrint = CBIOS_FALSE; + } + + if (isSkipPrint) + { + return; + } + + pDebugString = cbGetDebugBuffer(DebugPrintLevel & 0xFFFF); + + if(pDebugString == CBIOS_NULL) + { + return; + } + + preLen = cbAddPrefix(DebugPrintLevel, pDebugString); + + va_start(args, DebugMessage); + + if (cbVsprintf != CBIOS_NULL) + { + //new driver has the callback function + cbVsprintf(pDebugString + preLen, DebugMessage, args); + } + else + { + + //old driver has no callback function, then use standard lib function + vsprintf(pDebugString + preLen, DebugMessage, args); + + } + + va_end(args); + + cb_DbgPrint((DebugPrintLevel & 0xFF), pDebugString); + + return; +} +#endif + +CBIOS_VOID cbDelayMilliSeconds(CBIOS_U32 Milliseconds) +{ + cb_DelayMicroSeconds(1000*Milliseconds); +} + +CBIOS_U32 cbAddPrefix(CBIOS_U32 Level, CBIOS_UCHAR* pBuffer) +{ + CBIOS_U32 index = 0; + pBuffer[0] = '\0'; + +#ifdef __LINUX__ + if((Level & 0xFF000000) == BACK_OUTPUT && cbVsnprintf != CBIOS_NULL) + { + cbVsnprintf(pBuffer, CBIOSDEBUGMESSAGEMAXBYTES, "%d.", TimeStamp); + TimeStamp++; + } +#endif + + Level &= 0xFFFF; + if(Level >> 8) + { + index = cbGetLastBitIndex(Level >> 8); + } + + if (index < sizeofarray(ModuleName)) + { + cbStrCat(pBuffer, ModuleName[index]); + } + + index = Level & 0xff; + if (index < sizeofarray(DebugLevelName)) + { + cbStrCat(pBuffer, DebugLevelName[index]); + } + + return cbStrLen(pBuffer); +} + +CBIOS_VOID cbPrintWithDbgFlag(CBIOS_U32 DbgFlag, CBIOS_UCHAR* pBuffer) +{ + if((DbgFlag & 0xFF000000) == BACK_OUTPUT) + { + return; + } + + if(((DbgFlag & 0xFF) <= MaxDbgLevel) || ((DbgFlag & ModuleMask) &&((DbgFlag & 0xFF) <= ModuleMaskLevel ))) + { + if(pBuffer != CBIOS_NULL) + { + cb_DbgPrint(0, pBuffer); + } + } +} + +CBIOS_STATUS cbDbgLevelCtl(PCBIOS_DBG_LEVEL_CTRL pDbgLevelCtl) +{ + CBIOS_U32 BackBufCtrl = 0; + if(pDbgLevelCtl->bGetValue) + { + pDbgLevelCtl->DbgLevel = MaxDbgLevel | ModuleMask | (ModuleMaskLevel << 16); + pDbgLevelCtl->DbgLevel |= ((bEnableBackOutput)? 1 : 0) << 24; + } + else + { + ModuleMaskLevel = (pDbgLevelCtl->DbgLevel >> 16) & 0xFF; + ModuleMask = pDbgLevelCtl->DbgLevel & 0xFF00; + MaxDbgLevel = pDbgLevelCtl->DbgLevel & 0xFF; + BackBufCtrl = pDbgLevelCtl->DbgLevel >> 24; + bEnableBackOutput = (BackBufCtrl && BackBufCtrl != 0xFF)? CBIOS_TRUE : CBIOS_FALSE; + if(BackBufCtrl == 0xFF) + { + CBIOS_U32 Index = 0; + CBIOS_UCHAR* pBuffer = CBIOS_NULL; + if(pBackBuf) + { + for(Index = 0; Index < BACK_BUFFER_COUNT; Index++) + { + pBuffer = pBackBuf + Index * CBIOSDEBUGMESSAGEMAXBYTES; + cb_DbgPrint(0, pBuffer); + } + cb_FreePool(pBackBuf); + pBackBuf = CBIOS_NULL; + } + } + } + return CBIOS_OK; +} + +CBIOS_UCHAR* cbGetDebugBuffer(CBIOS_U32 DbgFlag) +{ + CBIOS_UCHAR* pBuffer = CBIOS_NULL; + if((DbgFlag & 0xFF000000) == BACK_OUTPUT) + { + if(bEnableBackOutput) + { + if(pBackBuf == CBIOS_NULL) + { + pBackBuf = (CBIOS_UCHAR*)cb_AllocateNonpagedPool(CBIOSDEBUGMESSAGEMAXBYTES * BACK_BUFFER_COUNT); + BackBufIndex = 0; + TimeStamp = 0; + } + pBuffer = pBackBuf + BackBufIndex * CBIOSDEBUGMESSAGEMAXBYTES; + BackBufIndex = (BackBufIndex+1) % BACK_BUFFER_COUNT; + } + } + else + { + if(pDebugBuf == CBIOS_NULL) + { + pDebugBuf = (CBIOS_UCHAR*)cb_AllocateNonpagedPool(CBIOSDEBUGMESSAGEMAXBYTES); + } + pBuffer = pDebugBuf; + } + return pBuffer; +} + +CBIOS_VOID cbReleaseDebugBuffer(CBIOS_VOID) +{ + if(pDebugBuf != CBIOS_NULL) + { + cb_FreePool(pDebugBuf); + pDebugBuf = CBIOS_NULL; + } + if(pBackBuf != CBIOS_NULL) + { + cb_FreePool(pBackBuf); + pBackBuf = CBIOS_NULL; + } +} + +CBIOS_BOARD_VERSION cbGetBoardVersion(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOARD_VERSION BoardVersion = CBIOS_BOARD_VERSION_DEFAULT; + + if (cbGetPlatformConfigurationU32(pcbe, (CBIOS_UCHAR*)"board_version", (CBIOS_U32*)&BoardVersion, 1)) + { + if (BoardVersion >= CBIOS_BOARD_VERSION_MAX) + { + BoardVersion = CBIOS_BOARD_VERSION_DEFAULT; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "Invalid board version, use default version!\n")); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Current board version: %d\n", BoardVersion)); + } + } + else + { + BoardVersion = CBIOS_BOARD_VERSION_DEFAULT; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "Can't get board version, use default version: %d!\n", BoardVersion)); + } + + return BoardVersion; +} + + +//ulLength: the number of characters after translated. +//If current number has more bits than ulLenght, the upper bits will not be translated. +//If current number has less bits than ulLengh, this function will fill '0' to upper bits. +//If ulLenght == 0, do not care about string length, just send out the real number of characters. +CBIOS_BOOL cbItoA(CBIOS_U32 ulValue, CBIOS_U8 *pStr, CBIOS_U8 byRadix, CBIOS_U32 ulLength) +{ + CBIOS_U8 index[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + CBIOS_U32 i = 0, j = 0; + CBIOS_U8 ulTmp = 0; + + if (pStr == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbItoA: pStr is null!\n")); + return CBIOS_FALSE; + } + + if ((byRadix < 2) || (byRadix > 36)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbItoA: Invalid radix!\n")); + return CBIOS_FALSE; + } + + i = 0; + do + { + pStr[i++] = index[ulValue % byRadix]; + ulValue /= byRadix; + }while(ulValue && ((i < ulLength) || (ulLength == 0))); + + //Fill 0 to upper bits + if (i < ulLength) + { + do + { + pStr[i++] = '0'; + }while(i < ulLength); + } + pStr[i] = '\0'; + + + for (j = 0; j < i / 2; j++) + { + ulTmp = pStr[j]; + pStr[j] = pStr[i - j - 1]; + pStr[i - j - 1] = ulTmp; + } + + return CBIOS_TRUE; + + +} + +CBIOS_U32 cbStrLen(CBIOS_UCHAR * pStrSrc) +{ + CBIOS_U32 strLen = 0, i = 0; + if(pStrSrc) + { + while(pStrSrc[i++] != '\0') + { + strLen++; + } + } + return strLen; +} + +PCBIOS_UCHAR cbStrCat(CBIOS_UCHAR *pStrDst, CBIOS_UCHAR * pStrSrc) +{ + CBIOS_UCHAR *pTmp = pStrDst; + + while (*pTmp) + { + pTmp++; + } + + while (*pStrSrc) + { + *pTmp = *pStrSrc; + pTmp++; + pStrSrc++; + } + + *pTmp = '\0'; + + return pStrDst; +} + +CBIOS_U32 cbRound(CBIOS_U32 Dividend, CBIOS_U32 Divisor, CBIOS_ROUND_METHOD RoundMethod) +{ + CBIOS_U32 ulRet = 0; + CBIOS_U32 ulRemainder = 0; + + if (Divisor == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbRound: fata error -- divisor is ZERO!!!\n")); + return 0; + } + + ulRemainder = Dividend % Divisor; + ulRet = Dividend / Divisor; + + switch (RoundMethod) + { + case ROUND_UP: + if (ulRemainder != 0) + { + ulRet++; + } + break; + case ROUND_NEAREST: + if ((ulRemainder * 2) >= Divisor) + { + ulRet++; + } + break; + case ROUND_DOWN: + break; + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbRound: invalid round type, round down by default!\n")); + break; + } + + return ulRet; + +} + + diff --git a/drivers/gpu/drm/arise/cbios/Device/CBiosShare.h b/drivers/gpu/drm/arise/cbios/Device/CBiosShare.h new file mode 100644 index 0000000000000..01f806f596009 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/CBiosShare.h @@ -0,0 +1,245 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** Hw independent and chip independent functions and parameters. +** +** NOTE: +** All outside head files should be included here. +******************************************************************************/ + +#ifndef _CBIOS_SHARE_H_ +#define _CBIOS_SHARE_H_ + +#ifdef __LINUX__ +#define GCC_BUILD_CBIOS 1 +#endif + +#ifndef GCC_BUILD_CBIOS +#include +#include +#include +#pragma warning(disable:4311) +#ifndef inline +#define inline __inline +#endif +#ifndef __func__ +#define __func__ __FUNCTION__ +#endif +#else +#ifndef __LINUX__ +#include "gcc_stdarg.h" +#endif +#endif + +#include "../CBios.h" + +#include "CBiosTypes.h" +#include "CBIOSVER.H" + +#ifdef __LINUX__ +#define FUNCTION_NAME __func__ +#else +#define FUNCTION_NAME __FUNCTION__ +#endif + +#ifdef __LINUX__ +#define LINE_NUM __LINE__ +#else +#define LINE_NUM __LINE__ +#endif + +#ifndef ASSERT +#if defined(DBG) && defined(WIN32) +#define ASSERT(x) if(!(x)) __debugbreak() +#else +#define ASSERT(a) +#endif +#endif + +typedef enum _CBIOS_BOARD_VERSION +{ + CBIOS_BOARD_VERSION_0 = 0, + CBIOS_BOARD_VERSION_1 = 1, + CBIOS_BOARD_VERSION_2 = 2, + CBIOS_BOARD_VERSION_EVT = 3, + CBIOS_BOARD_VERSION_MAX, +}CBIOS_BOARD_VERSION; + +typedef enum _CBIOS_ACTIVE_TYPE { + CBIOS_TYPE_NONE = 0x00, + CBIOS_TYPE_CRT = 0x01, + CBIOS_TYPE_PANEL = 0x02, + CBIOS_TYPE_TV = 0x04, + CBIOS_TYPE_HDTV = 0x08, + CBIOS_TYPE_DVO = 0x20, + CBIOS_TYPE_DUOVIEW = 0x80, + CBIOS_TYPE_DSI = 0x1000, + CBIOS_TYPE_MHL = 0x2000, + CBIOS_TYPE_DP1 = 0x8000, + CBIOS_TYPE_DP2 = 0x10000, + CBIOS_TYPE_DP3 = 0x20000, + CBIOS_TYPE_DP4 = 0x40000, +} CBIOS_ACTIVE_TYPE, *PCBIOS_ACTIVE_TYPE; + +#define ALL_DP_TYPES (CBIOS_TYPE_DP1 | CBIOS_TYPE_DP2 | CBIOS_TYPE_DP3 | CBIOS_TYPE_DP4) + +#define CBIOS_BOARD_VERSION_DEFAULT CBIOS_BOARD_VERSION_1 + +#ifndef CBIOSDEBUGMESSAGEMAXBYTES +#define CBIOSDEBUGMESSAGEMAXBYTES 256 +#endif + +#define ELT2K_HARDCODE_DP5 0 +#define ELT2K_HARDCODE_DSI_CMDMODE 0 +#define ELT2K_HARDCODE_DSI_MHL 0 + +/******* these functions must be implemented outside *******/ +/* debug print function */ + +#define DBG_LEVEL_ERROR 0 +#define DBG_LEVEL_WARNING 1 +#define DBG_LEVEL_INFO 2 +#define DBG_LEVEL_DEBUG 3 +#define DBG_LEVEL_TRACE 4 + +#define GENERIC_MODULE (1 << 8) +#define MHL_MODULE (2 << 8) +#define DSI_MODULE (4 << 8) +#define HDMI_MODULE (8 << 8) +#define DP_MODULE (16 << 8) + +#define STD_OUTPUT (0 << 24) +#define BACK_OUTPUT (1<< 24) + +#define MAKE_LEVEL(Module, Level) (Module##_MODULE + DBG_LEVEL_##Level) +#define MAKE_LEVEL_EX(Out, Module, Level) (Out##_OUTPUT + Module##_MODULE + DBG_LEVEL_##Level) + +#define cbTraceEnter(Module) cbDebugPrint((MAKE_LEVEL(Module, TRACE), "%s: Enter\n", __func__)) +#define cbTraceExit(Module) cbDebugPrint((MAKE_LEVEL(Module, TRACE), "%s: Exit\n", __func__)) + +//debug print level +#ifdef __LINUX__ +#define DBG_LEVEL_ERROR_MSG 2 +#define DBG_LEVEL_CHIP_INFO 0 +#define DBG_LEVEL_BIOS_VERSION 0 +#define DBG_LEVEL_MODE_INFO 0 +#define DBG_LEVEL_DEVICE_INFO 0 +#define DBG_LEVEL_DEBUG_MSG 1 +#else +#define DBG_LEVEL_ERROR_MSG 0 +#define DBG_LEVEL_CHIP_INFO 0 +#define DBG_LEVEL_BIOS_VERSION 0 +#define DBG_LEVEL_MODE_INFO 0 +#define DBG_LEVEL_DEVICE_INFO 0 +#define DBG_LEVEL_DEBUG_MSG 1 +#endif + +#define sizeofarray(a) (sizeof(a)/sizeof(a[0])) +#define SIZEOF_STRUCT_TILL_MEMBER(MY_STRUCT_VAR, MY_MEMBER_VAR)\ + ((CBIOS_U32)((PCBIOS_CHAR)(&(MY_STRUCT_VAR->MY_MEMBER_VAR)) - (PCBIOS_CHAR)(((MY_STRUCT_VAR))) + (sizeof(MY_STRUCT_VAR->MY_MEMBER_VAR)))) + +#define container_of(ptr, sample, member) \ + (((PCBIOS_CHAR)(ptr) == CBIOS_NULL) ? CBIOS_NULL : (PCBIOS_VOID)((PCBIOS_CHAR)(ptr) - ((PCBIOS_CHAR)(&(((sample)(0))->member)) - (PCBIOS_CHAR)(0)))) + +#ifndef MORE_THAN_1BIT +#define MORE_THAN_1BIT(x) ( (CBIOS_BOOL)( ((x) - 1) & (x) ) ) +#endif + +#ifndef LOW_WORD +#define LOW_WORD(x) ( (x) & 0xffff ) +#endif + +#ifndef HIGH_WORD +#define HIGH_WORD(x) ( ((x) >> 16 ) & 0xffff ) +#endif + +#ifndef WORD_CAT +#define WORD_CAT(low, high) ( ( (low) & 0xffff ) | (( (high) & 0xffff ) << 16) ) +#endif + +typedef enum _CBIOS_ROUND_METHOD +{ + ROUND_DOWN = 0, + ROUND_UP, + ROUND_NEAREST +}CBIOS_ROUND_METHOD; + +#ifndef __LINUX__ +CBIOS_VOID cbPrintMessage(CBIOS_U32 DebugPrintLevel, CBIOS_CHAR *DebugMessage, ...); +#endif + +CBIOS_U32 cbAddPrefix(CBIOS_U32 Level, CBIOS_UCHAR* pBuffer); +CBIOS_VOID cbPrintWithDbgFlag(CBIOS_U32 DbgFlag, CBIOS_UCHAR* pBuffer); +CBIOS_STATUS cbDbgLevelCtl(PCBIOS_DBG_LEVEL_CTRL pDbgLevelCtl); +CBIOS_UCHAR* cbGetDebugBuffer(CBIOS_U32 DbgFlag); +CBIOS_VOID cbReleaseDebugBuffer(CBIOS_VOID); +CBIOS_VOID cbDelayMilliSeconds(CBIOS_U32 Milliseconds); +CBIOS_BOOL cbItoA(CBIOS_U32 ulValue, CBIOS_U8 *pStr, CBIOS_U8 byRadix, CBIOS_U32 ulLength); +CBIOS_U32 cbStrLen(CBIOS_UCHAR * pStrSrc); +PCBIOS_UCHAR cbStrCat(CBIOS_UCHAR *pStrDst, CBIOS_UCHAR * pStrSrc); +CBIOS_U32 cbRound(CBIOS_U32 Dividend, CBIOS_U32 Divisor, CBIOS_ROUND_METHOD RoundMethod); +CBIOS_BOARD_VERSION cbGetBoardVersion(PCBIOS_VOID pvcbe); +CBIOS_STATUS cbGetExtensionSize(CBIOS_U32 *pulExtensionSize); + +#ifdef __BIG_ENDIAN__ +static inline CBIOS_U16 cb_swab16(CBIOS_U16 x) +{ + CBIOS_U16 temp = ((x & 0x00ffu) << 8) | + ((x & 0xff00u) >> 8); + return temp; +} + +static inline CBIOS_U32 cb_swab32(CBIOS_U32 x) +{ + CBIOS_U32 temp = ((x & 0x000000ff) << 24) | + ((x & 0x0000ff00) << 8) | + ((x & 0x00ff0000) >> 8) | + ((x & 0xff000000) >> 24); + return temp; +} +#else +#define cb_swab16(x) x +#define cb_swab32(x) x +#endif + +#ifdef __LINUX__ + +#define cbstrcmp(s1, s2) 0 +#define cbstrcpy(s1, s2) CBIOS_NULL +#define cbstrncmp(s1, s2, n) 0 +#define cbmemset(s1, v, n) CBIOS_NULL +#define cbmemcpy(s1, s2, n) CBIOS_NULL +#define cbmemcmp(s1, s2, n) 0 +#define cbdo_div(a, b) ((a)/(b)) +#define cbvsprintf(s, f, ...) 0 + +#else + +#define cbstrcmp strcmp +#define cbstrcpy strcpy +#define cbstrncmp strncmp +#define cbmemset memset +#define cbmemcpy memcpy +#define cbmemcmp memcmp +#define cbdo_div(a, b) ((a)/(b)) + +#define cbvsprintf vsprintf + +#endif + +#endif /* _CBIOS_SHARE_H_ */ + diff --git a/drivers/gpu/drm/arise/cbios/Device/CBiosTypes.h b/drivers/gpu/drm/arise/cbios/Device/CBiosTypes.h new file mode 100644 index 0000000000000..2a6595337e2a8 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/CBiosTypes.h @@ -0,0 +1,267 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios sharing used structures definition. +** +** NOTE: +** The hw only used structure SHOULD be add to hw layer. +******************************************************************************/ + +#ifndef _CBIOS_TYPES_H_ +#define _CBIOS_TYPES_H_ + +/* from CBios.h */ +#include "../CBios.h" + +// +// General BITx usage definition +// +#define __BIT(n) (1 << (n)) + +#ifndef BIT0 +#define BIT0 __BIT(0 ) +#define BIT1 __BIT(1 ) +#define BIT2 __BIT(2 ) +#define BIT3 __BIT(3 ) +#define BIT4 __BIT(4 ) +#define BIT5 __BIT(5 ) +#define BIT6 __BIT(6 ) +#define BIT7 __BIT(7 ) +#define BIT8 __BIT(8 ) +#define BIT9 __BIT(9 ) +#define BIT10 __BIT(10) +#define BIT11 __BIT(11) +#define BIT12 __BIT(12) +#define BIT13 __BIT(13) +#define BIT14 __BIT(14) +#define BIT15 __BIT(15) +#define BIT16 __BIT(16) +#define BIT17 __BIT(17) +#define BIT18 __BIT(18) +#define BIT19 __BIT(19) +#define BIT20 __BIT(20) +#define BIT21 __BIT(21) +#define BIT22 __BIT(22) +#define BIT23 __BIT(23) +#define BIT24 __BIT(24) +#define BIT25 __BIT(25) +#define BIT26 __BIT(26) +#define BIT27 __BIT(27) +#define BIT28 __BIT(28) +#define BIT29 __BIT(29) +#define BIT30 __BIT(30) +#define BIT31 __BIT(31) +#endif + +// VCP table size +#define VCP_MAX_REG_TABLE_SIZE 100 +#define MAX_DVO_DEVICES_NUM 2 + +typedef struct _MMIOREGISTER +{ + CBIOS_U32 index; + CBIOS_U32 value; + CBIOS_U32 length; +} MMIOREGISTER, *PMMIOREGISTER; + +typedef struct _CBIOS_AUTO_TIMING_PARA +{ + CBIOS_U16 XRes; + CBIOS_U16 YRes; + CBIOS_U16 RefreshRate; + CBIOS_BOOL IsInterlace; + CBIOS_U8 AutoTimingIndex; +}CBIOS_AUTO_TIMING_PARA, *PCBIOS_AUTO_TIMING_PARA; + +typedef struct _CBIOS_TIMING_FLAGS +{ + CBIOS_U8 IsUseAutoTiming :1; + CBIOS_U8 IsPAL :1; + CBIOS_U8 IsNTSC :1; + CBIOS_U8 IsInterlace :1; + CBIOS_U8 IsDSICmdMode :1; +}CBIOS_TIMING_FLAGS, *PCBIOS_TIMING_FLAGS; + +typedef struct _CBIOS_STREAM_ATTRIBUTE +{ + CBIOS_IN PCBIOS_SURFACE_ATTRIB pSurfaceAttr; + CBIOS_IN PCBIOS_WINDOW_PARA pSrcWinPara; + CBIOS_OUT CBIOS_U32 dwStride; + CBIOS_OUT CBIOS_U32 dwBaseOffset; + CBIOS_OUT CBIOS_U32 PixelOffset; +}CBIOS_STREAM_ATTRIBUTE, *PCBIOS_STREAM_ATTRIBUTE; + +//clock defines +typedef struct _CBIOS_CLOCK_INFO +{ + CBIOS_U16 Integer; + CBIOS_U32 Fraction; + CBIOS_U16 R; + CBIOS_U16 CP; + CBIOS_U16 PLLDiv; //R has only 2 bits, need div again for small clk +}CBIOS_CLOCK_INFO ,*PCBIOS_CLOCK_INFO; + + +typedef struct _CBIOS_GETTING_MODE_PARAMS +{ + CBIOS_IN CBIOS_U32 Device; + CBIOS_OUT CBIOS_U32 IGAIndex; + CBIOS_OUT CBiosDestModeParams DestModeParams; + CBIOS_OUT CBIOS_TIMING_ATTRIB DetailedTiming; +}CBIOS_GETTING_MODE_PARAMS,*PCBIOS_GETTING_MODE_PARAMS; + + +typedef struct _CBIOS_DVO_DEV_CONFIG +{ + CBIOS_U8 DVOTxType; + CBIOS_U8 DVOSlaveAddr; +} CBIOS_DVO_DEV_CONFIG, *PCBIOS_DVO_DEV_CONFIG; + +typedef struct _CBIOS_POST_REGISTER_TABLE +{ + CBREGISTER* pCRDefault; + CBREGISTER* pSRDefault; + CBREGISTER* pModeExtRegDefault_TBL; + + CBIOS_U32 sizeofCRDefault; + CBIOS_U32 sizeofSRDefault; + CBIOS_U32 sizeofModeExtRegDefault_TBL; +} CBIOS_POST_REGISTER_TABLE; + +typedef enum _CBIOS_POST_TABLE_TYPE +{ + VCP_TABLE, + INIT_TABLE, + RESTORE_TABLE, + POST_TABLE_MAX +} CBIOS_POST_TABLE_TYPE; + +//This definition should keep identical with VBIOS +typedef enum _VBIOS_ACTIVE_TYPE{ + VBIOS_TYPE_NONE = 0x00, + VBIOS_TYPE_CRT = 0x01, + VBIOS_TYPE_PANEL = 0x02, + VBIOS_TYPE_DVO = 0x20, + VBIOS_TYPE_DUOVIEW = 0x80, + VBIOS_TYPE_DP1 = 0x8000, + VBIOS_TYPE_DP2 = 0x200, + VBIOS_TYPE_DP3 = 0x400, + VBIOS_TYPE_DP4 = 0x800, +} VBIOS_ACTIVE_TYPE, *PVBIOS_ACTIVE_TYPE; + +typedef struct _Shadow_Info +{ + CBIOS_BOOL bSysBiosInfoValid; + CBIOS_U32 HDTV_TV_Config; + CBIOS_U32 FBStartingAddr; + CBIOS_U8 LCDPanelID; + CBIOS_U8 FBSize; + CBIOS_U8 DRAMDataRateIdx; + CBIOS_U8 DRAMMode; + CBIOS_U32 AlwaysLightOnDev; + CBIOS_U32 AlwaysLightOnDevMask; + CBIOS_U32 EngineClockModify; + CBIOS_U8 LCD2PanelID; + CBIOS_U8 TVLayOut; + CBIOS_U16 SSCCtrl; + CBIOS_U16 ChipCapability; + CBIOS_U16 LowTopAddress; + CBIOS_U32 BootUpDev; + CBIOS_U32 DetalBootUpDev; + struct + { + CBIOS_U32 SnoopOnly :1; + CBIOS_U32 Reserved :31; + }; + CBIOS_U32 ECLK; + CBIOS_U32 VCLK; + CBIOS_U32 ICLK; +}Shadow_Info,*PShadow_Info; + +typedef struct _CBIOS_FEATURE_SWITCH +{ + CBIOS_U32 IsEDP1Enabled :1; + CBIOS_U32 IsEDP2Enabled :1; + CBIOS_U32 IsDisableCodec1 :1; + CBIOS_U32 IsDisableCodec2 :1; + CBIOS_U32 IsEclkConfigEnable :1; + CBIOS_U32 IsEDP3Enabled :1; + CBIOS_U32 IsEDP4Enabled :1; + CBIOS_U32 HPDActiveHighEnable :1; + CBIOS_U32 BIUBackdoorEnable :1; + CBIOS_U32 bNonSimulChip :1; + CBIOS_U32 RsvdFeatureSwitch :22; +}CBIOS_FEATURE_SWITCH, *PCBIOS_FEATURE_SWITCH; + +typedef struct _CBIOS_MAX_RES_CONFIG +{ + CBIOS_U16 MaxXRes; + CBIOS_U16 MaxYRes; + CBIOS_U16 MaxRefresh; // unit Hz * 100 +}CBIOS_MAX_RES_CONFIG, *PCBIOS_MAX_RES_CONFIG; + +typedef struct _VCP_INFO +{ + CBIOS_BOOL bUseVCP; //whether we use VCP or not + CBIOS_U8 Version; + CBIOS_U16 VCPlength; + CBIOS_U32 BiosVersion; + CBIOS_U16 SubVendorID; + CBIOS_U16 SubSystemID; + CBIOS_U32 SupportDevices; + CBIOS_U16 BootDevPriority[16]; + + CBIOS_FEATURE_SWITCH FeatureSwitch; + + CBIOS_U8 CRTCharByte; + CBIOS_U8 DP1DualModeCharByte; + CBIOS_U8 DP2DualModeCharByte; + CBIOS_U8 DP3DualModeCharByte; + CBIOS_U8 DP4DualModeCharByte; + CBIOS_U8 DVOCharByte; + + CBIOS_U8 CRTInterruptPort; + CBIOS_U8 DVOInterruptPort; + CBIOS_U8 GpioForEDP1Power; + CBIOS_U8 GpioForEDP1BackLight; + CBIOS_U8 GpioForEDP2Power; + CBIOS_U8 GpioForEDP2BackLight; + + CBIOS_U32 EClock; + CBIOS_U32 EVcoLow; + CBIOS_U32 DVcoLow; + CBIOS_U32 VClock; + + CBIOS_U8 SupportedDVODevice; + CBIOS_DVO_DEV_CONFIG DVODevConfig[MAX_DVO_DEVICES_NUM]; + + CBIOS_U32 sizeofBootDevPriority; + CBIOS_U32 sizeofCR_DEFAULT_TABLE; + CBIOS_U32 sizeofSR_DEFAULT_TABLE; + + CBREGISTER* pCR_DEFAULT_TABLE; + CBREGISTER* pSR_DEFAULT_TABLE; + + CBIOS_MAX_RES_CONFIG DPMaxResConfig[4]; + CBIOS_U8 SliceNum; + CBIOS_U32 FwVersion; // firmware version backup + CBIOS_U8 SignOnMsg[80]; // 70 bytes defined in vbios. reserve some bytes for string operation. + CBIOS_U8 VBiosEditTime[20]; //14 bytes defined in vbios. reserve some bytes for string operation. + CBIOS_U8 FwName[10]; //8 bytes defined in vbios. reserve some bytes for string operation. +}VCP_INFO, *PVCP_INFO; +#endif /* _CBIOS_TYPES_H_ */ + diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.c new file mode 100644 index 0000000000000..d0452a209b185 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.c @@ -0,0 +1,106 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CRT monitor interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "CBiosCRTMonitor.h" +#include "../../Hw/HwBlock/CBiosDIU_CRT.h" + +CBIOS_BOOL cbCRTMonitor_Detect(PCBIOS_VOID pvcbe, PCBIOS_CRT_MONITOR_CONTEXT pCrtMonitorContext, CBIOS_BOOL bHardcodeDetected, CBIOS_U32 FullDetect) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = pCrtMonitorContext->pDevCommon; + CBIOS_BOOL bGotEdid = CBIOS_FALSE; + CBIOS_BOOL IsDevChanged = CBIOS_FALSE; + CBIOS_BOOL bConnected = CBIOS_FALSE; + CBIOS_BOOL bPrevEdidValid = CBIOS_FALSE; + + if (bHardcodeDetected) + { + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_CRT; + bConnected = CBIOS_TRUE; + goto EXIT; + } + + bPrevEdidValid = cbEDIDModule_IsEDIDValid(pDevCommon->EdidData); + + bGotEdid = cbGetDeviceEDID(pcbe, pDevCommon, &IsDevChanged, FullDetect); + + if ((*(pDevCommon->EdidData + EDID_VIDEO_INPUT_DEF_BYTE_OFFSET)) & EDID_VIDEO_INPUT_DEF_DIGITAL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: why come here??? Current device should be a CRT monitor!\n", FUNCTION_NAME)); + bGotEdid = CBIOS_FALSE; + } + + if (bGotEdid) + { + if (IsDevChanged) + { + cbEDIDModule_ParseEDID(pDevCommon->EdidData, &pDevCommon->EdidStruct, CBIOS_EDIDDATABYTE); + } + + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_CRT; + pDevCommon->isFakeEdid = CBIOS_FALSE; + bConnected = CBIOS_TRUE; + } + else + { + //for the case:if plugout monitor before suspend,and then plugin hdmi monitor before resume,after resume,4k@60 can't be lighted. + //rootcause:if plugout monitor,hpd thread will detect no device,so some attributes stored in pDevCommon will be cleared, + //plugin monitor before resume,os will do nothing,so it will not update attributes stored in pDevCommon + //then after resume,driver will not enter some hdmi module related codes,so monitor can't light + //so not memset pDevCommon->EdidStruct when device is not connected + cbClearEdidRelatedData(pcbe, pDevCommon); + + if(cbDIU_CRT_DACSense(pcbe, pDevCommon, bPrevEdidValid)) + { + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_CRT; + bConnected = CBIOS_TRUE; + } + else + { + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_NONE; + bConnected = CBIOS_FALSE; + } + } + +EXIT: + return bConnected; +} + +CBIOS_VOID cbCRTMonitor_SetMode(PCBIOS_VOID pvcbe, PCBIOS_CRT_MONITOR_CONTEXT pCrtMonitorContext, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + CBIOS_U8 HVPolarity = pModeParams->TargetTiming.HVPolarity; + CBIOS_U8 IGAIndex = (CBIOS_U8)pModeParams->IGAIndex; + + cbDIU_CRT_SetHVSync(pvcbe, HVPolarity, IGAIndex); + + cbDIU_CRT_SetDacCsc(pvcbe, CSC_FMT_RGB, pModeParams->IGAOutColorSpace); +} + +CBIOS_VOID cbCRTMonitor_OnOff(PCBIOS_VOID pvcbe, PCBIOS_CRT_MONITOR_CONTEXT pCrtMonitorContext, CBIOS_BOOL bOn, CBIOS_U8 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + cbDIU_CRT_DACOnOff(pcbe, bOn, IGAIndex); + cbDIU_CRT_SyncOnOff(pcbe, bOn); +} diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.h b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.h new file mode 100644 index 0000000000000..d6b997c36a99c --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.h @@ -0,0 +1,40 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CRT monitor interface function prototype and parameter definition. +** +** NOTE: +** CRT monitor ONLY parameters SHOULD be added to CBIOS_CRT_MONITOR_CONTEXT. +******************************************************************************/ + +#ifndef _CBIOS_CRT_MONITOR_H_ +#define _CBIOS_CRT_MONITOR_H_ + +#include "../../Display/CBiosDisplayManager.h" +#include "../CBiosDeviceShare.h" + +typedef struct _CBIOS_CRT_MONITOR_CONTEXT +{ + PCBIOS_DEVICE_COMMON pDevCommon; +}CBIOS_CRT_MONITOR_CONTEXT, *PCBIOS_CRT_MONITOR_CONTEXT; + +CBIOS_BOOL cbCRTMonitor_Detect(PCBIOS_VOID pvcbe, PCBIOS_CRT_MONITOR_CONTEXT pCrtMonitorContext, CBIOS_BOOL bHardcodeDetected, CBIOS_U32 FullDetect); +CBIOS_VOID cbCRTMonitor_SetMode(PCBIOS_VOID pvcbe, PCBIOS_CRT_MONITOR_CONTEXT pCrtMonitorContext, PCBIOS_DISP_MODE_PARAMS pModeParams); +CBIOS_VOID cbCRTMonitor_OnOff(PCBIOS_VOID pvcbe, PCBIOS_CRT_MONITOR_CONTEXT pCrtMonitorContext, CBIOS_BOOL bOn, CBIOS_U8 IGAIndex); + +#endif + diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosDPMonitor.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosDPMonitor.c new file mode 100644 index 0000000000000..bada9f0fac72e --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosDPMonitor.c @@ -0,0 +1,2573 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DP monitor interface function implementation. +** +** NOTE: +** DP monitor ONLY characters like link training, DPCD, Aux read/write, SHOULD add to this file. +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "../../Hw/HwBlock/CBiosDIU_DP.h" +#include "../../Hw/CBiosHwShare.h" +#include "../../Hw/HwBlock/CBiosDIU_HDCP.h" + +#if DP_MONITOR_SUPPORT + +static CBIOS_U8 DPFailSafeModeEdid[] = +{ + //For DP EDID corruption issue, set fail-safe mode: 640x480@60Hz, bpc=6 + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x43, 0x14, 0x81, 0x89, 0xDA, 0x07, 0x00, + 0x0A, 0x12, 0x01, 0x04, 0x95, 0x41, 0x29, 0x78, 0xE2, 0x8F, 0x95, 0xAD, 0x4F, 0x32, 0xB2, 0x25, + 0x0F, 0x50, 0x54, 0x20, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xD6, 0x09, 0x80, 0xA0, 0x20, 0xE0, 0x2D, 0x10, 0x10, 0x60, + 0xA2, 0x00, 0x8A, 0x9A, 0x21, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x44, 0x50, 0x31, + 0x39, 0x30, 0x35, 0x32, 0x38, 0x38, 0x37, 0x45, 0x54, 0x0A, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x41, + 0x42, 0x43, 0x20, 0x33, 0x30, 0x32, 0x30, 0x30, 0x38, 0x57, 0x53, 0x0A, 0x00, 0x00, 0x00, 0xFD, + 0x00, 0x31, 0x56, 0x1D, 0x71, 0x1C, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xF5, + 0x70, 0x10, 0x18, 0x03, 0x00, 0x01, 0x00, 0x0C, 0x8A, 0x02, 0x9A, 0x01, 0x00, 0x0A, 0x40, 0x06, + 0x18, 0x78, 0x3C, 0x75, 0x0D, 0x00, 0x06, 0x88, 0x20, 0x20, 0x40, 0x20, 0x20, 0xB5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, +}; + +static CBIOS_BOOL cbDPMonitor_IsEDPSupported(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + return (((DPModuleIndex == CBIOS_MODULE_INDEX1) && (pcbe->FeatureSwitch.IsEDP1Enabled)) + || ((DPModuleIndex == CBIOS_MODULE_INDEX2) && (pcbe->FeatureSwitch.IsEDP2Enabled))); +} + +static CBIOS_BOOL cbDPMonitor_EDPAuxPowerSeqCtrl(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL bOn) +{ + if (bOn) + { + // eDP power sequence on for aux channel operation + // 1. enable vdd + cbDIU_EDP_ControlVDDSignal(pcbe, pDPMonitorContext, DPModuleIndex, CBIOS_TRUE); + // 2. wait for HDP from sink, timeout is 200ms + if (!cbDIU_EDP_WaitforSinkHPDSignal(pcbe, DPModuleIndex, 200)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: can't wait HPD high from sink\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + } + else + { + // eDP power sequence off for aux channel operation + // disable vdd + cbDIU_EDP_ControlVDDSignal(pcbe, pDPMonitorContext, DPModuleIndex, CBIOS_FALSE); + } + return CBIOS_TRUE; +} + +static CBIOS_BOOL cbDPMonitor_LinkTrainingHw(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_LINK_TRAINING_PARAMS LinkTrainingParams = {0}; + CBIOS_BOOL bStatus = CBIOS_FALSE; + CBIOS_EDP_CP_METHOD CPMethod = CBIOS_EDP_CP_DISABLE; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + + cbTraceEnter(DP); + + LinkTrainingParams.bEDP = CBIOS_FALSE; + LinkTrainingParams.MaxLaneCount = pDPMonitorContext->LaneNumberToUse; + LinkTrainingParams.MaxLinkSpeed = pDPMonitorContext->LinkSpeedToUse; + LinkTrainingParams.DpSinkVersion = pDPMonitorContext->DpSinkVersion; + LinkTrainingParams.TrainingAuxRdInterval = pDPMonitorContext->TrainingAuxRdInterval; + LinkTrainingParams.bEnableTPS3 = pDPMonitorContext->bEnableTPS3; + + //check CP method + if (cbDPMonitor_IsEDPSupported(pcbe, DPModuleIndex)) + { + LinkTrainingParams.bEDP = CBIOS_TRUE; + + if (pcbe->CbiosFlags & DISABLE_EDP_CONTENT_PROTECTION) + { + CPMethod = CBIOS_EDP_CP_DISABLE; + } + else if (pDPMonitorContext->bSupportASSR && pDPMonitorContext->bSupportAF) + { + if (pcbe->CbiosFlags & DEFAULT_USE_EDP_CP_METHOD_3A_ASSR) + { + CPMethod = CBIOS_EDP_CP_ASSR; + } + else if (pcbe->CbiosFlags & DEFAULT_USE_EDP_CP_METHOD_3B_AF) + { + CPMethod = CBIOS_EDP_CP_AF; + } + } + else if (pDPMonitorContext->bSupportASSR) + { + CPMethod = CBIOS_EDP_CP_ASSR; + } + else if (pDPMonitorContext->bSupportAF) + { + CPMethod = CBIOS_EDP_CP_AF; + } + else + { + CPMethod = CBIOS_EDP_CP_DISABLE; + } + } + else + { + LinkTrainingParams.bEDP = CBIOS_FALSE; + CPMethod = CBIOS_EDP_CP_DISABLE; + } + + LinkTrainingParams.CPMethod = CPMethod; + LinkTrainingParams.bEnhancedMode = pDPMonitorContext->EnhancedMode; + + bStatus = cbDIU_DP_LinkTrainingHw(pcbe, DPModuleIndex, &LinkTrainingParams); + if (bStatus) + { + pDPMonitorContext->LinkSpeedToUse = LinkTrainingParams.CurrLinkSpeed; + pDPMonitorContext->LaneNumberToUse = LinkTrainingParams.CurrLaneCount; + } + + cbTraceExit(DP); + + return bStatus; +} + +static CBIOS_BOOL cbDPMonitor_GetAutoTestDpcdData(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + AUX_CONTROL AUX; + DPCD_REG_00219 DPCD_00219; + DPCD_REG_00220 DPCD_00220; + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x219; + AUX.Length = 1; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Can not get the auto test DPCD link rate data!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + DPCD_00219.Value = AUX.Data[0] & 0x000000FF; + if (DPCD_00219.TEST_LINK_RATE == CBIOS_DPCD_LINK_RATE_5400Mbps) + { + pDPMonitorContext->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_5400Mbps; + } + else if (DPCD_00219.TEST_LINK_RATE == CBIOS_DPCD_LINK_RATE_2700Mbps) + { + pDPMonitorContext->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_2700Mbps; + } + else + { + pDPMonitorContext->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_1620Mbps; + } + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x220; + AUX.Length = 1; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Can not get the auto test DPCD lane count data!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + DPCD_00220.Value = AUX.Data[0] & 0x000000FF; + if ((DPCD_00220.TEST_LANE_COUNT == 0x01) || (DPCD_00220.TEST_LANE_COUNT == 0x02) || (DPCD_00220.TEST_LANE_COUNT == 0x04)) + { + pDPMonitorContext->LaneNumberToUse = DPCD_00220.TEST_LANE_COUNT; + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: Invalid lane count:%d!\n", FUNCTION_NAME, DPCD_00220.TEST_LANE_COUNT)); + } + + return CBIOS_TRUE; +} + +static CBIOS_BOOL cbDPMonitor_GetSinkCapsFromSpecificPlace(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_U8 IGAIndex) +{ + PCBiosCustmizedDestTiming pUserTiming = CBIOS_NULL; + + if(pcbe->SpecifyDestTimingSrc[IGAIndex].Flag == 1) + { + pUserTiming = &pcbe->SpecifyDestTimingSrc[IGAIndex].UserCustDestTiming; + } + else if(pcbe->SpecifyDestTimingSrc[IGAIndex].Flag == 2) + { + pUserTiming = &pDPMonitorContext->TestDpcdDataTiming; + } + else + { + if (pDPMonitorContext->LaneNumberToUse > 4) + { + pDPMonitorContext->LaneNumberToUse = 4; // Default use 4 lanes + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Use default 4 lanes!\n", FUNCTION_NAME)); + } + + if ((pDPMonitorContext->LinkSpeedToUse != CBIOS_DP_LINK_SPEED_1620Mbps) && + (pDPMonitorContext->LinkSpeedToUse != CBIOS_DP_LINK_SPEED_2700Mbps) && + (pDPMonitorContext->LinkSpeedToUse != CBIOS_DP_LINK_SPEED_5400Mbps)) + { + pDPMonitorContext->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_1620Mbps; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG),"%s: Use default 1.62Gbps!\n", FUNCTION_NAME)); + } + pDPMonitorContext->EnhancedMode = pDPMonitorContext->bSupportEnhanceMode; + pDPMonitorContext->AsyncMode = 0x01; + pDPMonitorContext->DynamicRange = 0; + pDPMonitorContext->YCbCrCoefficients = 0; + pDPMonitorContext->TUSize = DP_Default_TUSize; + + return CBIOS_FALSE; + } + + if ((pUserTiming->LinkRate == CBIOS_DPCD_LINK_RATE_5400Mbps) || + (pUserTiming->LinkRate == CBIOS_DPCD_LINK_RATE_2700Mbps) || + (pUserTiming->LinkRate == CBIOS_DPCD_LINK_RATE_1620Mbps)) + { + pDPMonitorContext->LaneNumberToUse = pUserTiming->LaneCount; + if(pUserTiming->LinkRate == CBIOS_DPCD_LINK_RATE_5400Mbps) + { + pDPMonitorContext->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_5400Mbps; + } + else if(pUserTiming->LinkRate == CBIOS_DPCD_LINK_RATE_2700Mbps) + { + pDPMonitorContext->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_2700Mbps; + } + else + { + pDPMonitorContext->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_1620Mbps; + } + + pDPMonitorContext->bpc = pUserTiming->BitDepthPerComponet; + + pDPMonitorContext->AsyncMode = (pUserTiming->ClockSynAsyn == 0) ? 1 : 0; + pDPMonitorContext->ColorFormat = pUserTiming->ColorFormat; + pDPMonitorContext->DynamicRange = pUserTiming->DynamicRange; + pDPMonitorContext->YCbCrCoefficients = pUserTiming->YCbCrCoefficients; + pDPMonitorContext->EnhancedMode = pUserTiming->EnhancedFrameMode; + + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: LinkRate = %d, LaneCount = %d, bpc = %d, Async = %d\n", FUNCTION_NAME, + pDPMonitorContext->LinkSpeedToUse, pDPMonitorContext->LaneNumberToUse, pDPMonitorContext->bpc, pDPMonitorContext->AsyncMode)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: ColorFormat = %d, DynamicRange = %d, YCbCrCoefficients = %d, EnhancedMode = %d\n", FUNCTION_NAME, + pDPMonitorContext->ColorFormat,pDPMonitorContext->DynamicRange, pDPMonitorContext->YCbCrCoefficients, pDPMonitorContext->EnhancedMode)); + + return CBIOS_TRUE; + } + else + { + return CBIOS_FALSE; + } +} + +static CBIOS_VOID cbDPMonitor_DetermineLinkTrainingPara(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_BOOL isAutoTest) +{ + CBIOS_U32 MaxSupportClock_2700Mbps = 0, MaxSupportClock_1620Mbps = 0, MaxClockForCurrentLinkSpeed = 0; + CBIOS_U8 IGAIndex = 0; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + PCBIOS_DP_CONTEXT pDpContext = container_of(pDPMonitorContext->pDevCommon, PCBIOS_DP_CONTEXT, Common); + PCBIOS_EDPPanel_PARAMS pEDPPanelDevice = &(pDPMonitorContext->pDevCommon->DeviceParas.EDPPanelDevice); + CBIOS_BOOL bUsingSinkMax = CBIOS_FALSE; + + IGAIndex = DPModuleIndex; + + //for dp cts, if set registry for dp cts, Flag = 2, but some test of DPR120's dpcd timing is invalid. + + if(pDpContext->DPPortParams.bRunCTS) + { + pcbe->SpecifyDestTimingSrc[IGAIndex].Flag = 2; + } + + if((pcbe->SpecifyDestTimingSrc[IGAIndex].Flag == 2) && (pDPMonitorContext->TestDpcdDataTiming.DClk == 0)) + { + pcbe->SpecifyDestTimingSrc[IGAIndex].Flag = 0; + bUsingSinkMax = CBIOS_TRUE; + } + + if (isAutoTest) + { + cbDPMonitor_GetAutoTestDpcdData(pcbe, pDPMonitorContext); + } + else if (pcbe->SpecifyDestTimingSrc[IGAIndex].Flag & 0x03) + { + cbDPMonitor_GetSinkCapsFromSpecificPlace(pcbe, pDPMonitorContext, IGAIndex); + + /*In order to pass dp cts on unigraf DPR-120, use max link rate and max lane count, + because dpcd timing perhaps don't update, but these two params update everytime. + */ + if(pcbe->SpecifyDestTimingSrc[IGAIndex].Flag == 2) + { + pDPMonitorContext->LinkSpeedToUse = pDPMonitorContext->SinkMaxLinkSpeed; + pDPMonitorContext->LaneNumberToUse = pDPMonitorContext->SinkMaxLaneCount; + } + } + else + { + if(pDPMonitorContext->bpc > DP_Default_bpc) + { + pDPMonitorContext->bpc = DP_Default_bpc; + } + + pDPMonitorContext->LaneNumberToUse = pDPMonitorContext->SinkMaxLaneCount; + + // choose Link Speed according to current mode's pixel clock + MaxSupportClock_2700Mbps = (CBIOS_DP_LINK_SPEED_2700Mbps / (pDPMonitorContext->bpc * 3)) + * pDPMonitorContext->LaneNumberToUse * 8; + MaxSupportClock_1620Mbps = (CBIOS_DP_LINK_SPEED_1620Mbps / (pDPMonitorContext->bpc * 3)) + * pDPMonitorContext->LaneNumberToUse * 8; + if (pDPMonitorContext->TargetTiming.PixelClock < MaxSupportClock_1620Mbps) + { + pDPMonitorContext->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_1620Mbps; + } + else if (pDPMonitorContext->TargetTiming.PixelClock < MaxSupportClock_2700Mbps) + { + pDPMonitorContext->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_2700Mbps; + } + else + { + pDPMonitorContext->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_5400Mbps; + } + + if (pDPMonitorContext->LinkSpeedToUse > pDPMonitorContext->SinkMaxLinkSpeed) + { + pDPMonitorContext->LinkSpeedToUse = pDPMonitorContext->SinkMaxLinkSpeed; + } + + if(bUsingSinkMax)//for dp cts + { + pDPMonitorContext->LinkSpeedToUse = pDPMonitorContext->SinkMaxLinkSpeed; + pDPMonitorContext->LaneNumberToUse = pDPMonitorContext->SinkMaxLaneCount; + } + + if(cbDPMonitor_IsEDPSupported(pcbe, DPModuleIndex)) + { + if(pEDPPanelDevice &&pEDPPanelDevice->EDPPanelDesc.EDPCaps.isHardcodeLinkPara) + { + pDPMonitorContext->LinkSpeedToUse = pEDPPanelDevice->EDPPanelDesc.EDPCaps.LinkSpeed; + pDPMonitorContext->LaneNumberToUse = pEDPPanelDevice->EDPPanelDesc.EDPCaps.LaneNum; + } + else + { + pDPMonitorContext->LinkSpeedToUse = pDPMonitorContext->SinkMaxLinkSpeed; + pDPMonitorContext->LaneNumberToUse = pDPMonitorContext->SinkMaxLaneCount; + } + } + + /* To avoid exceeding max clock when lighten 10bpc or higher, use default bpc*/ + MaxClockForCurrentLinkSpeed = (pDPMonitorContext->LinkSpeedToUse / (pDPMonitorContext->bpc * 3)) + * pDPMonitorContext->LaneNumberToUse * 8; + if(pDPMonitorContext->TargetTiming.PixelClock > MaxClockForCurrentLinkSpeed) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: Current link speed(%d) can't lighten to PixelClock(%d) with %d bit, use default bpc\n", + FUNCTION_NAME, pDPMonitorContext->LinkSpeedToUse, pDPMonitorContext->TargetTiming.PixelClock, + pDPMonitorContext->bpc)); + + pDPMonitorContext->bpc = DP_Default_bpc; + } + } + + // determine final link training params according to Source's caps + if (pDPMonitorContext->LaneNumberToUse > pDPMonitorContext->SourceMaxLaneCount) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: source only supports lane count = %d\n", + FUNCTION_NAME, pDPMonitorContext->SourceMaxLaneCount)); + pDPMonitorContext->LaneNumberToUse = pDPMonitorContext->SourceMaxLaneCount; + } + + if (pDPMonitorContext->LinkSpeedToUse > pDPMonitorContext->SourceMaxLinkSpeed) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: source only supports link speed = %d\n", + FUNCTION_NAME, pDPMonitorContext->SourceMaxLinkSpeed)); + pDPMonitorContext->LinkSpeedToUse = pDPMonitorContext->SourceMaxLinkSpeed; + } + + if (pDPMonitorContext->bSourceSupportTPS3) + { + pDPMonitorContext->bEnableTPS3 = pDPMonitorContext->bSupportTPS3; + } + else + { + if (pDPMonitorContext->bSupportTPS3) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: source doesn't support TPS3\n", FUNCTION_NAME)); + } + pDPMonitorContext->bEnableTPS3 = 0; + } +} + +CBIOS_BOOL cbDPMonitor_SetUpMainLink(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bStatus = CBIOS_FALSE; + PCBIOS_TIMING_ATTRIB pTiming = &pDPMonitorContext->TargetTiming; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + CBIOS_MODULE_INDEX HDTVModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_HDTV); + CBIOS_MAIN_LINK_PARAMS MainLinkParams = {0}; + + cbTraceEnter(DP); + + pTiming->XRes *= pDPMonitorContext->PixelRepetition; + pTiming->HorTotal *= pDPMonitorContext->PixelRepetition; + pTiming->HorDisEnd *= pDPMonitorContext->PixelRepetition; + pTiming->HorBStart *= pDPMonitorContext->PixelRepetition; + pTiming->HorBEnd *= pDPMonitorContext->PixelRepetition; + pTiming->HorSyncStart *= pDPMonitorContext->PixelRepetition; + pTiming->HorSyncEnd *= pDPMonitorContext->PixelRepetition; + + if(pDPMonitorContext->bInterlace) + { + // HDTV module is used to transfer P -> i, so pixel clock need to be divided by 2 + if (HDTVModuleIndex != CBIOS_MODULE_INDEX_INVALID) + { + pTiming->PixelClock /= 2; + } + pTiming->YRes /= 2; + pTiming->VerTotal /= 2; + pTiming->VerDisEnd /= 2; + pTiming->VerBStart /= 2; + pTiming->VerBEnd /= 2; + pTiming->VerSyncStart /= 2; + pTiming->VerSyncEnd /= 2; + } + + MainLinkParams.pTiming = pTiming; + MainLinkParams.LaneNumberToUse = pDPMonitorContext->LaneNumberToUse; + MainLinkParams.LinkSpeedToUse = pDPMonitorContext->LinkSpeedToUse; + MainLinkParams.bpc = pDPMonitorContext->bpc; + MainLinkParams.TUSize = pDPMonitorContext->TUSize; + MainLinkParams.AsyncMode = pDPMonitorContext->AsyncMode; + MainLinkParams.ColorFormat = pDPMonitorContext->ColorFormat; + MainLinkParams.DynamicRange = pDPMonitorContext->DynamicRange; + MainLinkParams.YCbCrCoefficients = pDPMonitorContext->YCbCrCoefficients; + + bStatus = cbDIU_DP_SetUpMainLink(pcbe, DPModuleIndex, &MainLinkParams); + + cbTraceExit(DP); + + return bStatus; +} + +CBIOS_BOOL cbDPMonitor_LinkTraining(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_BOOL isAutoTest) +{ + CBIOS_BOOL bStatus = CBIOS_FALSE; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pvcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + + cbTraceEnter(DP); + + if (pDPMonitorContext->DpAuxWorkingStatus & AUX_WORKING_STATUS_LINKTRAINING) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: this routine re-rentered!!!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + else if (pDPMonitorContext->DpAuxWorkingStatus & AUX_WORKING_STATUS_EDID_READING) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s:AUX CHANNEL IS BUSY READING EDID!!!\n", FUNCTION_NAME)); + } + + //Get the specified link training parameters + cbDPMonitor_DetermineLinkTrainingPara(pcbe, pDPMonitorContext, isAutoTest); + + pDPMonitorContext->DpAuxWorkingStatus |= AUX_WORKING_STATUS_LINKTRAINING; + + cbPHY_DP_InitEPHY(pcbe, DPModuleIndex); + + bStatus = cbDPMonitor_LinkTrainingHw(pcbe, pDPMonitorContext); + + if (bStatus) + { + pDPMonitorContext->LT_Status = 1; + } + pDPMonitorContext->DpAuxWorkingStatus &= ~AUX_WORKING_STATUS_LINKTRAINING; + + cbTraceExit(DP); + return bStatus; +} + +CBIOS_BOOL cbDPMonitor_GetTrainingData(PCBIOS_VOID pvcbe, + CBIOS_MODULE_INDEX DPModuleIndex, + CBIOS_U32 ulLaneNum, + CBIOS_U32 *DPCD202_205, + CBIOS_U32 RequestVoltage[4], + CBIOS_U32 RequestPreEmph[4]) +{ + CBIOS_U32 i, DPCD206_207 = 0; + AUX_CONTROL AUX; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x202; + AUX.Length = 6; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: failed!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + *DPCD202_205 = AUX.Data[0]; + DPCD206_207 = AUX.Data[1] & 0x0000FFFF; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: DPCD_207_202: 0x%04x%08x!\n", FUNCTION_NAME, DPCD206_207, *DPCD202_205)); + + for (i = 0; i < ulLaneNum; i++) + { + RequestVoltage[i] = (DPCD206_207 >> (i * 4)) & 0x00000003; + RequestPreEmph[i] = (DPCD206_207 >> (2 + i * 4)) & 0x00000003; + + //Verify ulTemp not indicate illegal voltage swing / pre-emphasis combinations + while ((RequestVoltage[i] + RequestPreEmph[i]) > 3) + { + RequestPreEmph[i]--; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: RequestVoltage+PreEmph >= 3, lower RequestPreEmph!\n", FUNCTION_NAME)); + } + } + + return CBIOS_TRUE; +} + +CBIOS_BOOL cbDPMonitor_AuxReadEDID(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_UCHAR pEDIDBuffer, + CBIOS_U32 ulBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bStatus = CBIOS_FALSE; + CBIOS_U32 i, j; + CBIOS_U32 dTemp; + CBIOS_UCHAR ucChecksum; + CBIOS_U32 ulEdidLength = 0; + PCBIOS_UCHAR pHardcodedEdidBuffer = CBIOS_NULL; + CBIOS_ACTIVE_TYPE Device = pDPMonitorContext->pDevCommon->DeviceType; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_DP); + + cbTraceEnter(DP); + + if (pDPMonitorContext->DpAuxWorkingStatus & AUX_WORKING_STATUS_EDID_READING) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: this routine re-rentered!!!", FUNCTION_NAME)); + return CBIOS_FALSE; + } + else if (pDPMonitorContext->DpAuxWorkingStatus & AUX_WORKING_STATUS_LINKTRAINING) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: AUX CHANNEL IS BUSY LINKTRAINING!!!", FUNCTION_NAME)); + } + + pDPMonitorContext->DpAuxWorkingStatus |= AUX_WORKING_STATUS_EDID_READING; + + cb_memset(pEDIDBuffer, 0, ulBufferSize); + + // check if use hardcode EDID + if (pcbe->DevicesHardcodedEdid & Device) + { + pHardcodedEdidBuffer = pcbe->EdidFromRegistry; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: EDID is hardcoded to read from registry!\n", FUNCTION_NAME)); + } + // check if use faked edid sending from the upper layer + else if (pDPMonitorContext->pDevCommon->isFakeEdid) + { + pHardcodedEdidBuffer = pDPMonitorContext->pDevCommon->EdidData; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: EDID is hardcoded to faked edid\n", FUNCTION_NAME)); + } + + if (pHardcodedEdidBuffer == CBIOS_NULL) + { + ulEdidLength = cbDIU_DP_AuxReadEDID(pcbe, DPModuleIndex, pEDIDBuffer, ulBufferSize); + if (ulEdidLength == 0) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: read EDID fail through aux channel!!\n", FUNCTION_NAME)); + + bStatus = CBIOS_FALSE; + goto exitAuxReadEDID; + } + else + { + bStatus = CBIOS_TRUE; + } + } + else + { + ucChecksum = 0; + for (i = 0; i < ulBufferSize / 128; i++) + { + for (j = 0; j < 128 / 2; j ++) + { + dTemp = ((PCBIOS_U16)(pHardcodedEdidBuffer))[(i * 128 + j * 2) / 2]; + + ucChecksum += pEDIDBuffer[i * 128 + j * 2 + 0] = (CBIOS_U8) (dTemp >> 0); + ucChecksum += pEDIDBuffer[i * 128 + j * 2 + 1] = (CBIOS_U8) (dTemp >> 8); + } + + ulEdidLength = i * 128 + 128; + + // Must check checksum before check extension flag in case EDID is corrupted + if (ucChecksum == 0) + { + if (ulEdidLength == (pEDIDBuffer[0x7E] + 1) * 128) // Extension flag + { + bStatus = CBIOS_TRUE; + break; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: checksum == 0x%02x, wrong!!\n", FUNCTION_NAME, ucChecksum)); + + bStatus = CBIOS_FALSE; + goto exitAuxReadEDID; + } + } + } + + if (!cbEDIDModule_IsEDIDHeaderValid(pEDIDBuffer, ulEdidLength)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: EDID header is wrong!!\n", FUNCTION_NAME)); + + bStatus = CBIOS_FALSE; + goto exitAuxReadEDID; + } + + if ((pEDIDBuffer[0x7E] + 1) * 128 > CBIOS_EDIDDATABYTE) // Longer than buffer + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: EDID length exceeds code limitation, discard remaider!\n", FUNCTION_NAME)); + ASSERT(CBIOS_FALSE); + } + +exitAuxReadEDID: + pDPMonitorContext->DpAuxWorkingStatus &= ~AUX_WORKING_STATUS_EDID_READING; + if (!bStatus) + { + // Corrupted EDID, zero it to avoid be analyzed elsewhere without check corruption. + cbDumpBuffer(pcbe, pEDIDBuffer, ulBufferSize); + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: Corrupted EDID, zero entire EDID buffer!\n", FUNCTION_NAME)); + cb_memset(pEDIDBuffer, 0, ulBufferSize); + } + + cbTraceExit(DP); + return bStatus; +} + +CBIOS_BOOL cbDPMonitor_AuxReadEDIDOffset(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_UCHAR pEDIDBuffer, + CBIOS_U32 ulBufferSize, CBIOS_U32 ulReadEdidOffset) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bStatus = CBIOS_FALSE; + PCBIOS_UCHAR pHardcodedEdidBuffer = CBIOS_NULL; + CBIOS_ACTIVE_TYPE Device = pDPMonitorContext->pDevCommon->DeviceType; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_DP); + + if ((DPModuleIndex != CBIOS_MODULE_INDEX1) && (DPModuleIndex != CBIOS_MODULE_INDEX2)&& + (DPModuleIndex != CBIOS_MODULE_INDEX3) && (DPModuleIndex != CBIOS_MODULE_INDEX4)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Invalid DP index!!!", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + if (pDPMonitorContext->DpAuxWorkingStatus & AUX_WORKING_STATUS_EDID_READING) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: this routine re-rentered!!!", FUNCTION_NAME)); + return CBIOS_FALSE; + } + else if (pDPMonitorContext->DpAuxWorkingStatus & AUX_WORKING_STATUS_LINKTRAINING) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: AUX CHANNEL IS BUSY LINKTRAINING!!!", FUNCTION_NAME)); + } + + pDPMonitorContext->DpAuxWorkingStatus |= AUX_WORKING_STATUS_EDID_READING; + + cb_memset(pEDIDBuffer, 0, ulBufferSize); + + if (DPModuleIndex == CBIOS_MODULE_INDEX1) + { + //check hardcoded EDID + if (pcbe->DevicesHardcodedEdid & CBIOS_TYPE_DP1) + { + pHardcodedEdidBuffer = pcbe->EdidFromRegistry; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: DP1 EDID is hardcoded to read from registry!\n", FUNCTION_NAME)); + } + else if (pcbe->CbiosFlags & HARDCODE_DP1_EDID_ALL_ZERO_BYTES) + { + // Already zero the buffer, return CBIOS_FALSE diretly. + pDPMonitorContext->DpAuxWorkingStatus &= ~AUX_WORKING_STATUS_EDID_READING; + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: DP1 EDID is hardcoded to all zero bytes!\n", FUNCTION_NAME)); + bStatus = CBIOS_FALSE; + goto ExitFunc; + } + } + else if (DPModuleIndex == CBIOS_MODULE_INDEX2) + { + //check hardcoded EDID + if (pcbe->DevicesHardcodedEdid & CBIOS_TYPE_DP2) + { + pHardcodedEdidBuffer = pcbe->EdidFromRegistry; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: DP2 EDID is hardcoded to read from registry!\n", FUNCTION_NAME)); + } + } + else if (DPModuleIndex == CBIOS_MODULE_INDEX3) + { + //check hardcoded EDID + if (pcbe->DevicesHardcodedEdid & CBIOS_TYPE_DP3) + { + pHardcodedEdidBuffer = pcbe->EdidFromRegistry; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: DP3 EDID is hardcoded to read from registry!\n", FUNCTION_NAME)); + } + } + else if (DPModuleIndex == CBIOS_MODULE_INDEX4) + { + //check hardcoded EDID + if (pcbe->DevicesHardcodedEdid & CBIOS_TYPE_DP4) + { + pHardcodedEdidBuffer = pcbe->EdidFromRegistry; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: DP4 EDID is hardcoded to read from registry!\n", FUNCTION_NAME)); + } + } + + + if (pHardcodedEdidBuffer != CBIOS_NULL) + { + cb_memcpy(pEDIDBuffer, pHardcodedEdidBuffer + ulReadEdidOffset, ulBufferSize); + bStatus = CBIOS_TRUE; + } + else + { + bStatus = cbDIU_DP_AuxReadEDIDOffset(pcbe, DPModuleIndex, pEDIDBuffer, ulBufferSize, ulReadEdidOffset); + } + +ExitFunc: + + pDPMonitorContext->DpAuxWorkingStatus &= ~AUX_WORKING_STATUS_EDID_READING; + + return bStatus; +} + +static CBIOS_BOOL cbDPMonitor_GetDPCDVersion(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + CBIOS_BOOL bStatus = CBIOS_FALSE; + AUX_CONTROL AUX; + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0; + AUX.Length = 0x1; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX) == CBIOS_TRUE) + { + pDPMonitorContext->DpSinkVersion = AUX.Data[0] & 0xFF; + bStatus = CBIOS_TRUE; + } + + return bStatus; +} + +static CBIOS_BOOL cbDPMonitor_HDCP_ReadBKsv(CBIOS_VOID* pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_U8 pBksv, PCBIOS_BOOL bRepeater) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + CBIOS_BOOL bRet = CBIOS_TRUE; + CBIOS_U8 BCaps = 0; + AUX_CONTROL AUX; + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x68000; + AUX.Length = 0x5; + bRet = cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX); + if(bRet) + { + cb_memcpy(pBksv, (PCBIOS_U8)AUX.Data, 5); + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: Read BKsv failed!\n", FUNCTION_NAME)); + + return bRet; + } + + AUX.Offset = 0x68028; + AUX.Length = 0x1; + bRet = cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX); + if(bRet) + { + BCaps = AUX.Data[0] & 0xFF; + *bRepeater = BCaps & 0x2; + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: Read BCaps failed!\n", FUNCTION_NAME)); + } + + return bRet; +} + +static CBIOS_VOID cbDPMonitor_SetSinkPowerState(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL bPowerOn) +{ + AUX_CONTROL AUX = {0}; + DPCD_REG_00600 DPCD00600; + REG_MM8330 DPAuxTimerRegValue; + CBIOS_U8 counter = 0, plugin = 0; + + cbTraceEnter(DP); + + for(counter = 0; counter < 5; counter++) + { + DPAuxTimerRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_TIMER[DPModuleIndex]); + if((DPAuxTimerRegValue.HPD_Status == 1) || (DPAuxTimerRegValue.HPD_Status == 3)) // plugin + { + plugin = 1; + break; + } + cb_DelayMicroSeconds(200); // delay 200us + } + if(!plugin) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Aux can't work when DP is unplugged, mm%x==%08x!!!\n", + FUNCTION_NAME, DP_REG_AUX_TIMER[DPModuleIndex], DPAuxTimerRegValue.Value)); + + return; + } + + DPCD00600.Value = 0; + if (bPowerOn) + { + DPCD00600.SET_POWER = 1; // normal operation mode + } + else + { + DPCD00600.SET_POWER = 2; // power down mode + } + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x600; + AUX.Length = 0x1; + AUX.Data[0] = DPCD00600.Value; + + if(bPowerOn) + { + // Source must try at least 3 times if no reply/response from Sink + // Not all Sink device implemented this feature, so can't exit here + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDelayMilliSeconds(10); + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDelayMilliSeconds(20); + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + // 20090331_BC For DP compliance test 4.4.3 + // QuantumData 882 won't ACK this power on request even after 3 attempts + // But if we started link training too early, the test failed + // The test checks by monitoring the link training registers for certain period + // so put in some delay here. Do not reduce this number (40ms). + // Note that this would not affect normal operation since the Sink would usually + // respond to the very first power on request already + cbDelayMilliSeconds(40); + } + } + } + } + else + { + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Write DPCD power state D3 error!\n", FUNCTION_NAME)); + } + } + cbTraceExit(DP); +} + +static CBIOS_BOOL cbDPMonitor_GetSinkCaps(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + CBIOS_BOOL bStatus = CBIOS_FALSE; + AUX_CONTROL AUX; + DPCD_REG_00001 DPCD_00001 = {0}; + DPCD_REG_00002 DPCD_00002 = {0}; + DPCD_REG_00005 DPCD_00005 = {0}; + DPCD_REG_00007 DPCD_00007 = {0}; + DPCD_REG_0000D DPCD_0000D = {0}; + DPCD_REG_0000E DPCD_0000E = {0}; + DPCD_REG_00200 DPCD_00200 = {0}; + CBIOS_U32 SinkCount = 0; + + cbTraceEnter(DP); + + // Read DP monitor Caps + // In order to meet CTS item: 4.2.2.2, read 16 bytes although some of them are needless here. + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0; + AUX.Length = 16; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD_00001.Value = (AUX.Data[0] >> 8) & 0x000000FF; + if (DPCD_00001.MAX_LINK_RATE >= CBIOS_DPCD_LINK_RATE_5400Mbps) + { + // MAX_LANE_RATE 0x14 ought to be 5.4Gbps. + pDPMonitorContext->SinkMaxLinkSpeed = CBIOS_DP_LINK_SPEED_5400Mbps; + + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: link speed DP Sink max supports is 5.4Gpbs\n", FUNCTION_NAME)); + } + else if (DPCD_00001.MAX_LINK_RATE == CBIOS_DPCD_LINK_RATE_2700Mbps) + { + pDPMonitorContext->SinkMaxLinkSpeed = CBIOS_DP_LINK_SPEED_2700Mbps; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: link speed DP Sink max supports is 2.7Gpbs\n", FUNCTION_NAME)); + } + else + { + pDPMonitorContext->SinkMaxLinkSpeed = CBIOS_DP_LINK_SPEED_1620Mbps; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: link speed DP Sink max supports is 1.62Gpbs\n", FUNCTION_NAME)); + } + + // Check if anyone want to over write link speed in Registry. + if (pcbe->CbiosFlags & HARDCODE_DP1_MAX_LINKSPEED_1620) + { + pDPMonitorContext->SinkMaxLinkSpeed = CBIOS_DP_LINK_SPEED_1620Mbps; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: link speed is hardcoded to 1.62Gpbs\n", FUNCTION_NAME)); + } + else if (pcbe->CbiosFlags & HARDCODE_DP1_MAX_LINKSPEED_2700) + { + pDPMonitorContext->SinkMaxLinkSpeed = CBIOS_DP_LINK_SPEED_2700Mbps; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: link speed is hardcoded to 2.7Gbps\n", FUNCTION_NAME)); + } + else if (pcbe->CbiosFlags & HARDCODE_DP1_MAX_LINKSPEED_5400) + { + pDPMonitorContext->SinkMaxLinkSpeed = CBIOS_DP_LINK_SPEED_5400Mbps; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: link speed is hardcoded to 5.4Gbps\n", FUNCTION_NAME)); + } + + DPCD_00002.Value = (AUX.Data[0] >> 16) & 0x000000FF; + if ((DPCD_00002.MAX_LANE_COUNT == 0x01) || (DPCD_00002.MAX_LANE_COUNT == 0x02) || (DPCD_00002.MAX_LANE_COUNT == 0x04)) + { + pDPMonitorContext->SinkMaxLaneCount= DPCD_00002.MAX_LANE_COUNT; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: lane count DP Sink max supports is %d\n", FUNCTION_NAME, DPCD_00002.MAX_LANE_COUNT)); + } + else + { + pDPMonitorContext->SinkMaxLaneCount = 4; + } + + // DP 1.2 + if (pDPMonitorContext->DpSinkVersion >= 0x12) + { + pDPMonitorContext->bSupportTPS3 = DPCD_00002.TPS3_SUPPORTED; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: bSupportTPS3 = %d\n", + FUNCTION_NAME, pDPMonitorContext->bSupportTPS3)); + } + else + { + pDPMonitorContext->bSupportTPS3 = CBIOS_FALSE; + } + + // DP 1.1 + if (pDPMonitorContext->DpSinkVersion >= 0x11) + { + pDPMonitorContext->bSupportEnhanceMode = DPCD_00002.ENHANCED_FRAME_CAP; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: bSupportEnhanceMode = %d\n", + FUNCTION_NAME, pDPMonitorContext->bSupportEnhanceMode)); + } + else + { + pDPMonitorContext->bSupportEnhanceMode = CBIOS_FALSE; + } + + // Check if anyone want to over write lane count in Registry. + if (pcbe->CbiosFlags & HARDCODE_DP1_LANECOUNT_1) + { + pDPMonitorContext->SinkMaxLaneCount = 1; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: lane count is hardcoded to 1!\n", FUNCTION_NAME)); + } + else if (pcbe->CbiosFlags & HARDCODE_DP1_LANECOUNT_2) + { + pDPMonitorContext->SinkMaxLaneCount = 2; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: lane count is hardcoded to 2!\n", FUNCTION_NAME)); + } + else if (pcbe->CbiosFlags & HARDCODE_DP1_LANECOUNT_4) + { + pDPMonitorContext->SinkMaxLaneCount = 4; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: lane count is hardcoded to 4!\n", FUNCTION_NAME)); + } + + // check eDP content protection + DPCD_0000D.Value = (AUX.Data[3] >> 8) & 0x000000FF; + //it's BIT0 listed in DP 1.2 draft and eDP 1.2 draft. But bit4 in eDP 1.3. Need confirm + if (DPCD_0000D.ALTERNATE_SCRAMBLER_RESET_CAPABLE) + { + pDPMonitorContext->bSupportASSR = CBIOS_TRUE; + } + else + { + pDPMonitorContext->bSupportASSR = CBIOS_FALSE; + } + + if (DPCD_0000D.FRAMING_CHANGE_CAPABLE) + { + pDPMonitorContext->bSupportAF = CBIOS_TRUE; + } + else + { + pDPMonitorContext->bSupportAF = CBIOS_FALSE; + } + + // DP 1.2 + if (pDPMonitorContext->DpSinkVersion >= 0x12) + { + DPCD_0000E.Value = (AUX.Data[3] >> 16) & 0x000000FF; + pDPMonitorContext->TrainingAuxRdInterval = DPCD_0000E.TRAINING_AUX_RD_INTERVAL; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: TrainingAuxRdInterval = %d\n", FUNCTION_NAME, pDPMonitorContext->TrainingAuxRdInterval)); + } + + // CTS: 4.2.2.7 + DPCD_00005.Value = (AUX.Data[1] >> 8) & 0x000000FF; + DPCD_00007.Value = (AUX.Data[1] >> 24) & 0x000000FF; + if (DPCD_00005.DWN_STRM_PORT_PRESENT) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: downstream port count = %d\n", FUNCTION_NAME, DPCD_00007.DWN_STRM_PORT_COUNT)); + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x200; + AUX.Length = 1; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD_00200.Value = AUX.Data[0] & 0x000000FF; + SinkCount = (DPCD_00200.SINK_COUNT_6 << 6) + DPCD_00200.SINK_COUNT_5_0; + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: SinkCount = %d\n", FUNCTION_NAME, SinkCount)); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: cannot get DPCD(offset = 0x%x, len = %d)\n", + FUNCTION_NAME, AUX.Offset, AUX.Length)); + } + } + bStatus = CBIOS_TRUE; + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: cannot get sink caps through aux channel!\n", FUNCTION_NAME)); + } + + //for DP1.4 CTS 4.2.2.7 and 4.2.2.8, need read extended capability + if(DPCD_0000E.EXTENDED_RECEIVER_CAPABILITY_FIELD_PRESENT) + { + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x2200; + AUX.Length = 16; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + bStatus = CBIOS_TRUE; + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: cannot get sink extended caps through aux channel!\n", FUNCTION_NAME)); + } + } + + //initialize current link speed and lane count to max value + pDPMonitorContext->LinkSpeedToUse = pDPMonitorContext->SinkMaxLinkSpeed; + pDPMonitorContext->LaneNumberToUse = pDPMonitorContext->SinkMaxLaneCount; + + pDPMonitorContext->bpc = DP_Default_bpc; + pDPMonitorContext->EnhancedMode = 0x01; + pDPMonitorContext->AsyncMode = 0x01; + pDPMonitorContext->ColorFormat = 0; + pDPMonitorContext->DynamicRange = 0; + pDPMonitorContext->YCbCrCoefficients = 0; + pDPMonitorContext->TUSize = DP_Default_TUSize; + pDPMonitorContext->LT_Status = 0; + + cbTraceExit(DP); + return bStatus; +} + +CBIOS_U32 cbDPMonitor_GetMaxSupportedDclk(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_U32 MaxDclk = 0; + CBIOS_U32 Bpc = DP_Default_bpc; + + if (pDPMonitorContext == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid\n", FUNCTION_NAME)); + return 0; + } + + if(pDPMonitorContext->bpc > DP_Default_bpc) + { + Bpc = DP_Default_bpc; + } + else + { + Bpc = pDPMonitorContext->bpc; + } + + MaxDclk = (pDPMonitorContext->SinkMaxLinkSpeed / (Bpc * 3)) + * pDPMonitorContext->SinkMaxLaneCount * 8; + + return MaxDclk; +} + +CBIOS_VOID cbDPMonitor_GetMonitorParamsFromEdid(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_BOOL IsUpdateDevSignature) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = pDPMonitorContext->pDevCommon; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + CBIOS_BOOL IsEDP = CBIOS_FALSE; + PCBIOS_U8 pEdidBuffer = pDevCommon->EdidData; + + if (IsUpdateDevSignature) + { + cbUpdateDeviceSignature(pcbe, pDevCommon); + pDevCommon->isFakeEdid = CBIOS_FALSE; + } + + if(cbDPMonitor_IsEDPSupported(pcbe, DPModuleIndex)) + { + IsEDP = CBIOS_TRUE; + } + + if(IsEDP) + { + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_PANEL; + } + else + { + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_DP; + } + + // Check if HDMI + if (pDevCommon->EdidStruct.Attribute.IsCEA861HDMI) + { + cbDebugPrint((MAKE_LEVEL(DP, INFO), "%s: HDMI device on dual mode DP port!\n", FUNCTION_NAME)); + } + + pDPMonitorContext->bpc = DP_Default_bpc; + //: Should check EDID 1.4 here since majority of DP monitors don't have extended EDID block + if((pEdidBuffer[0x12] == 0x01) && (pEdidBuffer[0x13] == 0x04)) + { + if (pEdidBuffer[0x14] & 0x80) + { + if((pEdidBuffer[0x14] & 0x70) == 0x10) + { + pDPMonitorContext->bpc = 6; + } + else if((pEdidBuffer[0x14] & 0x70) == 0x20) + { + pDPMonitorContext->bpc = 8; + } + else if((pEdidBuffer[0x14] & 0x70) == 0x30) + { + pDPMonitorContext->bpc = 10; + } + else if((pEdidBuffer[0x14] & 0x70) == 0x40) + { + pDPMonitorContext->bpc = 12; + } + else if((pEdidBuffer[0x14] & 0x70) == 0x50) + { + pDPMonitorContext->bpc = 14; + } + else if((pEdidBuffer[0x14] & 0x70) == 0x60) + { + pDPMonitorContext->bpc = 16; + } + } + } + + cbDebugPrint((MAKE_LEVEL(DP, INFO), "%s: DP monitor supported bpc = %d\n", FUNCTION_NAME, pDPMonitorContext->bpc)); +} + +CBIOS_BOOL cbDPMonitor_Detect(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_BOOL bHardcodeDetected, CBIOS_U32 FullDetect) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bConnected = CBIOS_FALSE; + CBIOS_BOOL IsDevChanged = CBIOS_FALSE; + REG_MM8340 DPEphyMpllRegValue; + REG_MM8348 DPEphyMiscRegValue; + CBIOS_U8 AuxReadEDIDTime; + CBIOS_BOOL bGetEDID = CBIOS_FALSE; + PCBIOS_DEVICE_COMMON pDevCommon = pDPMonitorContext->pDevCommon; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + PCBIOS_EDP_PANEL_DESC pPanelDesc = &(pDevCommon->DeviceParas.EDPPanelDevice.EDPPanelDesc); + + cb_AcquireMutex(pcbe->pAuxMutex); + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + bConnected = CBIOS_FALSE; + goto EXIT; + } + + //save mm8340 value + DPEphyMpllRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_EPHY_MPLL[DPModuleIndex]); + // save mm8348 value + DPEphyMiscRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_EPHY_MISC[DPModuleIndex]); + + if(cbDPMonitor_IsEDPSupported(pcbe, DPModuleIndex)) + { + cbEDPPanel_PreInit(pcbe); + } + + cbPHY_DP_AuxPowerOn(pcbe, DPModuleIndex); + + cbDIU_DP_ResetAUX(pcbe, DPModuleIndex); + + if(cbDPMonitor_IsEDPSupported(pcbe, DPModuleIndex)) + { + if (pDevCommon->PowerState != CBIOS_PM_ON) //if eDP already power on, skip aux power sequence + { + cbDPMonitor_EDPAuxPowerSeqCtrl(pcbe, pDPMonitorContext, DPModuleIndex, CBIOS_TRUE); + } + } + + //DP LinkCompTest 4.4.3, "Sink shall not respond to any AUX requests + //prior to initial power save mode exit request." + //So, we must set sink device to D0 state, otherwise, any AUX requests + //may fail. + cbDPMonitor_SetSinkPowerState(pcbe, DPModuleIndex, CBIOS_TRUE); + + if (cbDPMonitor_GetDPCDVersion(pcbe, pDPMonitorContext)) + { + bConnected = CBIOS_TRUE; + + cbDPMonitor_GetSinkCaps(pcbe, pDPMonitorContext); + + //Following is patch for the cbDPMonitor_AuxReadEDID fail due to the conflict usage of Aux Channel between Reading EDID and sending CP_IRQ signal , + //which causes the EDID process being interrupted and fail. + for (AuxReadEDIDTime = 0; AuxReadEDIDTime < 3; AuxReadEDIDTime++) + { + bGetEDID = cbGetDeviceEDID(pcbe, pDevCommon, &IsDevChanged, FullDetect); + if (bGetEDID) + { + break; + } + } + if(!bGetEDID) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: Can't get EDID of DP single mode device!\n", FUNCTION_NAME)); + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: Use fail-safe EDID!\n", FUNCTION_NAME)); + + cb_memcpy(pDevCommon->EdidData, DPFailSafeModeEdid, sizeof(DPFailSafeModeEdid)); + IsDevChanged = CBIOS_TRUE; + } + } + else + { + bConnected = CBIOS_FALSE; + } + + if(cbDPMonitor_IsEDPSupported(pcbe, DPModuleIndex)) + { + if (pDevCommon->PowerState != CBIOS_PM_ON) + { + cbDPMonitor_EDPAuxPowerSeqCtrl(pcbe, pDPMonitorContext, DPModuleIndex, CBIOS_FALSE); + } + } + + if(bConnected) + { + if (IsDevChanged) + { + cbEDIDModule_ParseEDID(pDevCommon->EdidData, &(pDevCommon->EdidStruct), CBIOS_EDIDDATABYTE); + cbEDIDModule_SADPatch(&(pDevCommon->EdidStruct)); + cbDPMonitor_HDCP_ReadBKsv(pcbe, pDevCommon, ((PCBIOS_HDCP_CONTEXT)pDevCommon->pHDCPContext)->BKsv, + &(((PCBIOS_HDCP_CONTEXT)pDevCommon->pHDCPContext)->bRepeater)); + } + cbDPMonitor_GetMonitorParamsFromEdid(pcbe, pDPMonitorContext, IsDevChanged); + } + else + { + //for the case:if plugout monitor before suspend,and then plugin hdmi monitor before resume,after resume,4k@60 can't be lighted. + //rootcause:if plugout monitor,hpd thread will detect no device,so some attributes stored in pDevCommon will be cleared, + //plugin monitor before resume,os will do nothing,so it will not update attributes stored in pDevCommon + //then after resume,driver will not enter some hdmi module related codes,so monitor can't light + //so not memset pDevCommon->EdidStruct when device is not connected + cbClearEdidRelatedData(pcbe, pDevCommon); + cb_memset(((PCBIOS_HDCP_CONTEXT)pDevCommon->pHDCPContext)->BKsv, 0, sizeof(((PCBIOS_HDCP_CONTEXT)pDevCommon->pHDCPContext)->BKsv)); + } + + //restore mm 8340 value + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, 0); + // restore mm8348 value + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, 0); + // HW uses AUX + cbDIU_DP_HWUseAuxChannel(pcbe, DPModuleIndex); + + if(bConnected && cbDPMonitor_IsEDPSupported(pcbe, DPModuleIndex)) + { + if(cbEDPPanel_GetPanelDescriptor(pcbe, pDevCommon->EdidData) != CBIOS_NULL) + { + cb_memcpy(pPanelDesc, cbEDPPanel_GetPanelDescriptor(pcbe, pDevCommon->EdidData), sizeof(CBIOS_EDP_PANEL_DESC)); + cbEDPPanel_Init(pcbe, pPanelDesc); + } + } +EXIT: + + cb_ReleaseMutex(pcbe->pAuxMutex); + + return bConnected; +} + +CBIOS_VOID cbDPMonitor_UpdateModeInfo(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 IGAIndex = pModeParams->IGAIndex; + + if (0 == pcbe->SpecifyDestTimingSrc[IGAIndex].Flag) + { + if (CBIOS_RGBOUTPUT == pModeParams->TargetModePara.OutputSignal) + { + pDPMonitorContext->ColorFormat = 0; + } + else if(CBIOS_YCBCR422OUTPUT == pModeParams->TargetModePara.OutputSignal) + { + pDPMonitorContext->ColorFormat = 1; + } + else if(CBIOS_YCBCR444OUTPUT == pModeParams->TargetModePara.OutputSignal) + { + pDPMonitorContext->ColorFormat = 2; + } + // YUV420 -- may be need to change here in future + else if(CBIOS_YCBCR420OUTPUT == pModeParams->TargetModePara.OutputSignal) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: DP doesn't support YUV420 output up to DP1.2\n", FUNCTION_NAME)); + pDPMonitorContext->ColorFormat = 0; + } + } + + // save timing and interlace flag to DP monitor context for link training used + cb_memcpy(&(pDPMonitorContext->TargetTiming), &(pModeParams->TargetTiming), sizeof(CBIOS_TIMING_ATTRIB)); + pDPMonitorContext->bInterlace = pModeParams->TargetModePara.bInterlace; + pDPMonitorContext->PixelRepetition = pModeParams->PixelRepitition; +} + +CBIOS_VOID cbDPMonitor_SetMode(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = pDPMonitorContext->pDevCommon; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + CBIOS_U8 HVPolarity = pModeParams->TargetTiming.HVPolarity; + + if (DPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + cbDIU_DP_SetHVSync(pcbe, DPModuleIndex, HVPolarity); +} + +CBIOS_VOID cbDPMonitor_QueryAttribute(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBiosMonitorAttribute pMonitorAttribute) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_EDP_PANEL_DESC pEDPPanelDesc = &(pDPMonitorContext->pDevCommon->DeviceParas.EDPPanelDevice.EDPPanelDesc); + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + + if (pDPMonitorContext->bpc == 6) + { + pMonitorAttribute->SupportBPC.IsSupport6BPC = CBIOS_TRUE; + } + else if (pDPMonitorContext->bpc == 8) + { + pMonitorAttribute->SupportBPC.IsSupport8BPC = CBIOS_TRUE; + } + else if (pDPMonitorContext->bpc == 10) + { + pMonitorAttribute->SupportBPC.IsSupport10BPC = CBIOS_TRUE; + } + else if (pDPMonitorContext->bpc == 12) + { + pMonitorAttribute->SupportBPC.IsSupport12BPC = CBIOS_TRUE; + } + else if (pDPMonitorContext->bpc == 14) + { + pMonitorAttribute->SupportBPC.IsSupport14BPC = CBIOS_TRUE; + } + else if (pDPMonitorContext->bpc == 16) + { + pMonitorAttribute->SupportBPC.IsSupport16BPC = CBIOS_TRUE; + } + + if(cbDPMonitor_IsEDPSupported(pcbe, DPModuleIndex) && pEDPPanelDesc) + { + pMonitorAttribute->bSupportBLCtrl = pEDPPanelDesc->EDPCaps.isBLCtrlSupport; + } +} + +CBIOS_VOID cbDPMonitor_OnOff(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_BOOL bOn) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = pDPMonitorContext->pDevCommon; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + PCBIOS_EDP_PANEL_DESC pEDPPanelDesc = &(pDevCommon->DeviceParas.EDPPanelDevice.EDPPanelDesc); + CBIOS_BOOL bEDPMode = cbDPMonitor_IsEDPSupported(pcbe, DPModuleIndex); + + cb_AcquireMutex(pcbe->pAuxMutex); + + if (bOn) + { + cbDPMonitor_SetDither(pcbe, pDPMonitorContext->bpc, CBIOS_TRUE, DPModuleIndex); + // 1. start EDP panel power supply + if (bEDPMode) + { + cbDPMonitor_EDPAuxPowerSeqCtrl(pcbe, pDPMonitorContext, DPModuleIndex, bOn); + } + + // 2. turn on DP EPHY + cbPHY_DP_DPModeOnOff(pcbe, DPModuleIndex, pDPMonitorContext->LinkSpeedToUse, bOn); + + // 3. Set Sink device to D0(normal operation mode) state + cbDPMonitor_SetSinkPowerState(pcbe, DPModuleIndex, CBIOS_TRUE); + cbDelayMilliSeconds(2); + + // 4. turn off DP video before Link Training + cbDIU_DP_VideoOnOff(pcbe, DPModuleIndex, CBIOS_FALSE); + + // 5. do Link Training + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: ON. Need to do Link Training !\n", FUNCTION_NAME)); + if (cbDPMonitor_LinkTraining(pcbe, pDPMonitorContext, CBIOS_FALSE)) + { + CBIOS_BOOL status; + status = cbDPMonitor_SetUpMainLink(pcbe, pDPMonitorContext); + if(!status) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING),"%s: setting up Main Link failed!\n", FUNCTION_NAME)); + } + } + else + { + // Even if link training failed, still need to set correct DP path since sink would try to request link training again via hot IRQ. + cbDebugPrint((MAKE_LEVEL(DP, WARNING),"%s: skip setting up Main Link because Link Training failed!\n", FUNCTION_NAME)); + } + + cbDelayMilliSeconds(2); + + // 6. turn on DP video after Link Training + cbDIU_DP_EnableVideoAudio(pcbe, DPModuleIndex); + + // 7. turn on EDP panel back light + if (bEDPMode) + { + cbEDPPanel_OnOff(pcbe, bOn, pEDPPanelDesc); + } + } + else + { + // 1. turn off EDP panel back light + if (bEDPMode) + { + cbEDPPanel_OnOff(pcbe, bOn, pEDPPanelDesc); + cbDIU_EDP_ControlVEESignal(pcbe, pDPMonitorContext, DPModuleIndex, bOn); + cbDelayMilliSeconds(2); + } + + //disable both Video and Audio during link training + cbDIU_DP_DisableVideoAudio(pcbe, DPModuleIndex); + + // 2. reset Link Training + cbDIU_DP_ResetLinkTraining(pcbe, DPModuleIndex); + pDPMonitorContext->LT_Status = 0; + + // 3. Set Sink device to D3 (power saving) state + cbDPMonitor_SetSinkPowerState(pcbe, DPModuleIndex, CBIOS_FALSE); + + // 4. turn off DP EPHY + cbPHY_DP_DPModeOnOff(pcbe, DPModuleIndex, pDPMonitorContext->LinkSpeedToUse, bOn); + + // 5. reset AUX + cbDIU_DP_ResetAUX(pcbe, DPModuleIndex); + + // 6. stop EDP panel power supply + if (bEDPMode) + { + cbDPMonitor_EDPAuxPowerSeqCtrl(pcbe, pDPMonitorContext, DPModuleIndex, bOn); + } + + cbDPMonitor_SetDither(pcbe, pDPMonitorContext->bpc, CBIOS_FALSE, DPModuleIndex); + } + + cb_ReleaseMutex(pcbe->pAuxMutex); +} + +static CBIOS_BOOL cbDPMonitor_ProcTestEdidRead(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + AUX_CONTROL AUX = {0}; + DPCD_REG_00260 DPCD00260; + CBIOS_BOOL bStatus = CBIOS_TRUE; + PCBIOS_U8 pEDIDData = CBIOS_NULL; + + // Write Ack to test response fields of DPCD + DPCD00260.Value = 0; + DPCD00260.TEST_ACK = 1; + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x260; + AUX.Length = 1; + AUX.Data[0] = DPCD00260.Value; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Write ack to TEST_RESPONSE fields of DPCD!\n", FUNCTION_NAME)); + bStatus = CBIOS_FALSE; + } + + // 4.2.2.3 + // 4.2.2.4 + // 4.2.2.5 + pEDIDData = cb_AllocateNonpagedPool(CBIOS_EDIDDATABYTE); + if(pEDIDData == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: pEDIDData allocate error.\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + if(cbDPMonitor_AuxReadEDID(pcbe, pDPMonitorContext, pEDIDData, CBIOS_EDIDDATABYTE)) + { + cb_memcpy(pDPMonitorContext->pDevCommon->EdidData, pEDIDData, CBIOS_EDIDDATABYTE); + } + else + { + // CTS item: 4.2.2.4 + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: Automated Test: EDID Corruption Test, use fake safe-mode EDID.\n", FUNCTION_NAME)); + cb_memcpy(pDPMonitorContext->pDevCommon->EdidData, DPFailSafeModeEdid, sizeof(DPFailSafeModeEdid)); + } + + pDPMonitorContext->pDevCommon->isFakeEdid = CBIOS_TRUE; + + cb_FreePool(pEDIDData); + + return bStatus; +} + +static CBIOS_BOOL cbDPMonitor_ProcTestLinkTraining(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + AUX_CONTROL AUX = {0}; + DPCD_REG_00260 DPCD00260; + CBIOS_BOOL bStatus = CBIOS_TRUE; + + // Write Ack to test response fields of DPCD + DPCD00260.Value = 0; + DPCD00260.TEST_ACK = 1; + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x260; + AUX.Length = 1; + AUX.Data[0] = DPCD00260.Value; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Write ack to TEST_RESPONSE fields of DPCD!\n", FUNCTION_NAME)); + bStatus = CBIOS_FALSE; + } + //4.3.1.2 + //4.3.1.3 + //4.3.1.4 + //4.3.1.5 + //4.3.1.6 + //4.3.1.7 + //4.3.1.8 + //4.3.1.9 + //4.3.1.10 + //4.3.1.11 + //4.3.1.12 + + cbDPMonitor_LinkTraining(pcbe, pDPMonitorContext, CBIOS_TRUE); + + pDPMonitorContext->LT_Status = 1; + + return bStatus; +} + +static CBIOS_BOOL cbDPMonitor_GetAutoTestDpcdTiming(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + AUX_CONTROL AUX = {0}; + DPCD_REG_00219 DPCD00219; + DPCD_REG_00220 DPCD00220; + DPCD_REG_00221 DPCD00221; + DPCD_REG_00222 DPCD00222; + DPCD_REG_00223 DPCD00223; + DPCD_REG_00224 DPCD00224; + DPCD_REG_00225 DPCD00225; + DPCD_REG_00226 DPCD00226; + DPCD_REG_00227 DPCD00227; + DPCD_REG_00228 DPCD00228; + DPCD_REG_00229 DPCD00229; + DPCD_REG_0022A DPCD0022A; + DPCD_REG_0022B DPCD0022B; + DPCD_REG_0022C DPCD0022C; + DPCD_REG_0022D DPCD0022D; + DPCD_REG_0022E DPCD0022E; + DPCD_REG_0022F DPCD0022F; + DPCD_REG_00230 DPCD00230; + DPCD_REG_00231 DPCD00231; + DPCD_REG_00232 DPCD00232; + DPCD_REG_00233 DPCD00233; + DPCD_REG_00234 DPCD00234; + CBIOS_U32 RefreshRate = 0; + CBIOS_BOOL bStatus = CBIOS_TRUE; + + cb_memset(&pDPMonitorContext->TestDpcdDataTiming, 0, sizeof(CBiosCustmizedDestTiming)); + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x219; + AUX.Length = 1; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD00219.Value = AUX.Data[0] & 0x000000FF; + pDPMonitorContext->TestDpcdDataTiming.LinkRate = DPCD00219.TEST_LINK_RATE; + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s(%d): read DPCD reg(Offset = 0x%x, len = %d) fail?\n", + FUNCTION_NAME, LINE_NUM, AUX.Offset, AUX.Length)); + bStatus = CBIOS_FALSE; + } + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x220; + AUX.Length = 16; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD00220.Value = (AUX.Data[0] & 0x000000FF) >> 0; + DPCD00221.Value = (AUX.Data[0] & 0x0000FF00) >> 8; + DPCD00222.Value = (AUX.Data[0] & 0x00FF0000) >> 16; + DPCD00223.Value = (AUX.Data[0] & 0xFF000000) >> 24; + DPCD00224.Value = (AUX.Data[1] & 0x000000FF) >> 0; + DPCD00225.Value = (AUX.Data[1] & 0x0000FF00) >> 8; + DPCD00226.Value = (AUX.Data[1] & 0x00FF0000) >> 16; + DPCD00227.Value = (AUX.Data[1] & 0xFF000000) >> 24; + DPCD00228.Value = (AUX.Data[2] & 0x000000FF) >> 0; + DPCD00229.Value = (AUX.Data[2] & 0x0000FF00) >> 8; + DPCD0022A.Value = (AUX.Data[2] & 0x00FF0000) >> 16; + DPCD0022B.Value = (AUX.Data[2] & 0xFF000000) >> 24; + DPCD0022C.Value = (AUX.Data[3] & 0x000000FF) >> 0; + DPCD0022D.Value = (AUX.Data[3] & 0x0000FF00) >> 8; + DPCD0022E.Value = (AUX.Data[3] & 0x00FF0000) >> 16; + DPCD0022F.Value = (AUX.Data[3] & 0xFF000000) >> 24; + + pDPMonitorContext->TestDpcdDataTiming.LaneCount = DPCD00220.TEST_LANE_COUNT; + pDPMonitorContext->TestDpcdDataTiming.TestPattern = DPCD00221.TEST_PATTERN; + pDPMonitorContext->TestDpcdDataTiming.HorTotal = (DPCD00222.TEST_H_TOTAL_15_8 << 8) + DPCD00223.TEST_H_TOTAL_7_0; + pDPMonitorContext->TestDpcdDataTiming.VerTotal = (DPCD00224.TEST_V_TOTAL_15_8 << 8) + DPCD00225.TEST_V_TOTAL_7_0; + pDPMonitorContext->TestDpcdDataTiming.HorSyncStart = (DPCD00226.TEST_H_START_15_8 << 8) + DPCD00227.TEST_H_START_7_0; + pDPMonitorContext->TestDpcdDataTiming.VerSyncStart = (DPCD00228.TEST_V_START_15_8 << 8) + DPCD00229.TEST_V_START_7_0; + pDPMonitorContext->TestDpcdDataTiming.HSyncPolarity = DPCD0022A.TEST_HSYNC_POLARITY; + pDPMonitorContext->TestDpcdDataTiming.HorSyncWidth = (DPCD0022A.TEST_HSYNC_WIDTH_14_8 << 8) + DPCD0022B.TEST_HSYNC_WIDTH_7_0; + pDPMonitorContext->TestDpcdDataTiming.VSyncPolarity = DPCD0022C.TEST_VSYNC_POLARITY; + pDPMonitorContext->TestDpcdDataTiming.VerSyncWidth = (DPCD0022C.TEST_VSYNC_WIDTH_14_8 << 8) + DPCD0022D.TEST_VSYNC_WIDTH_7_0; + pDPMonitorContext->TestDpcdDataTiming.HorWidth = (DPCD0022E.TEST_H_WIDTH_15_8 << 8) + DPCD0022F.TEST_H_WIDTH_7_0; + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s(%d): read DPCD reg(Offset = 0x%x, len = %d) fail\n", + FUNCTION_NAME, LINE_NUM, AUX.Offset, AUX.Length)); + bStatus = CBIOS_FALSE; + } + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x230; + AUX.Length = 5; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD00230.Value = (AUX.Data[0] & 0x000000FF) >> 0; + DPCD00231.Value = (AUX.Data[0] & 0x0000FF00) >> 8; + DPCD00232.Value = (AUX.Data[0] & 0x00FF0000) >> 16; + DPCD00233.Value = (AUX.Data[0] & 0xFF000000) >> 24; + DPCD00234.Value = (AUX.Data[1] & 0x000000FF) >> 0; + + pDPMonitorContext->TestDpcdDataTiming.VerWidth = (DPCD00230.TEST_V_WIDTH_15_8 << 8) + DPCD00231.TEST_V_WIDTH_7_0; + pDPMonitorContext->TestDpcdDataTiming.ClockSynAsyn = DPCD00232.TEST_SYNCHRONOUS_CLOCK; + pDPMonitorContext->TestDpcdDataTiming.ColorFormat = DPCD00232.TEST_COLOR_FORMAT; + pDPMonitorContext->TestDpcdDataTiming.DynamicRange = DPCD00232.TEST_DYNAMIC_RANGE; + pDPMonitorContext->TestDpcdDataTiming.YCbCrCoefficients = DPCD00232.TEST_YCBCR_COEFFICIENTS; + if (DPCD00232.TEST_BIT_DEPTH == 0) + { + pDPMonitorContext->TestDpcdDataTiming.BitDepthPerComponet = 6; + } + else if (DPCD00232.TEST_BIT_DEPTH == 1) + { + pDPMonitorContext->TestDpcdDataTiming.BitDepthPerComponet = 8; + } + else if (DPCD00232.TEST_BIT_DEPTH == 2) + { + pDPMonitorContext->TestDpcdDataTiming.BitDepthPerComponet = 10; + } + else if (DPCD00232.TEST_BIT_DEPTH == 3) + { + pDPMonitorContext->TestDpcdDataTiming.BitDepthPerComponet = 12; + } + else if (DPCD00232.TEST_BIT_DEPTH == 4) + { + pDPMonitorContext->TestDpcdDataTiming.BitDepthPerComponet = 16; + } + pDPMonitorContext->TestDpcdDataTiming.IsInterlaced = DPCD00233.TEST_INTERLACED; + RefreshRate = DPCD00234.TEST_REFRESH_RATE_NUMERATOR; + pDPMonitorContext->TestDpcdDataTiming.DClk = pDPMonitorContext->TestDpcdDataTiming.HorTotal * pDPMonitorContext->TestDpcdDataTiming.VerTotal + * RefreshRate / 100; + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s(%d): read DPCD reg(Offset = 0x%x, len = %d) fail?\n", + FUNCTION_NAME, LINE_NUM, AUX.Offset, AUX.Length)); + bStatus = CBIOS_FALSE; + } + + // Enhanced Frame Mode supported flag cannot be gotten from DPCD Test Request Field + pDPMonitorContext->TestDpcdDataTiming.EnhancedFrameMode = pDPMonitorContext->bSupportEnhanceMode; + + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: LinkRate = 0x%x\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.LinkRate)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: LaneCount = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.LaneCount)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: TestPattern = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.TestPattern)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: ClockSynAsyn = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.ClockSynAsyn)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: DynamicRange = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.DynamicRange)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: ColorFormat = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.ColorFormat)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: YCbCrCoefficients = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.YCbCrCoefficients)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: EnhancedFrameMode = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.EnhancedFrameMode)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: BitDepthPerComponet = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.BitDepthPerComponet)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: IsInterlaced = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.IsInterlaced)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: HorTotal = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.HorTotal)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: HorWidth = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.HorWidth)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: HorSyncStart = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.HorSyncStart)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: HorSyncWidth = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.HorSyncWidth)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: HSyncPolarity = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.HSyncPolarity)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: VerTotal = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.VerTotal)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: VerWidth = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.VerWidth)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: VerSyncStart = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.VerSyncStart)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: VerSyncWidth = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.VerSyncWidth)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: VSyncPolarity = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.VSyncPolarity)); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: DClk = %d\n", FUNCTION_NAME, pDPMonitorContext->TestDpcdDataTiming.DClk)); + + return bStatus; +} + +static CBIOS_BOOL cbDPMonitor_ProcTestPattern(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + AUX_CONTROL AUX = {0}; + DPCD_REG_00260 DPCD00260; + CBIOS_BOOL bStatus = CBIOS_FALSE; + + //4.4.1.1 + //4.4.1.2 + //4.4.1.3 + //4.4.2 + // Currently not support automated test for pattern test + // Clear TRAINING_PATTERN_SET byte + // Write NACK to test response fields of DPCD. + DPCD00260.Value = 0; + DPCD00260.TEST_NACK = 1; + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x260; + AUX.Length = 1; + AUX.Data[0] = DPCD00260.Value; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Write no ack to TEST_RESPONSE fields of DPCD!\n", FUNCTION_NAME)); + bStatus = CBIOS_FALSE; + } + + //Currently we can not support automation test for pattern test. + //If we support this feature, the following code path should be went through. + if(!cbDPMonitor_GetAutoTestDpcdTiming(pcbe, pDPMonitorContext)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Can not get request pattern fields of DPCD!\n", FUNCTION_NAME)); + bStatus = CBIOS_FALSE; + } + else + { + bStatus = CBIOS_TRUE; + } + + return bStatus; +} + +static CBIOS_BOOL cbDPMonitor_HandleTestRequest(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_HANDLE_IRQ_PARA pDPHandleIrqPara) +{ + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + AUX_CONTROL AUX = {0}; + DPCD_REG_00218 DPCD00218; + CBIOS_BOOL bStatus = CBIOS_TRUE; + + // Read Automated detail request. + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x218; + AUX.Length = 1; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD00218.Value = AUX.Data[0] & 0x000000FF; + + if(DPCD00218.TEST_EDID_READ) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Test Edid Read.\n", FUNCTION_NAME)); + if(cbDPMonitor_ProcTestEdidRead(pcbe, pDPMonitorContext)) + { + pDPHandleIrqPara->bNeedDetect = 1; + pDPHandleIrqPara->bNeedCompEdid = 1; + } + } + + if(DPCD00218.TEST_LINK_TRAINING) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Test Link Training.\n", FUNCTION_NAME)); + cbDPMonitor_ProcTestLinkTraining(pcbe, pDPMonitorContext); + } + + if(DPCD00218.TEST_PATTERN) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Test Pattern.\n", FUNCTION_NAME)); + if(cbDPMonitor_ProcTestPattern(pcbe, pDPMonitorContext)) + { + if (cbDPMonitor_LinkTraining(pcbe, pDPMonitorContext, CBIOS_FALSE)) + { + cbDPMonitor_SetUpMainLink(pcbe, pDPMonitorContext); + } + pDPHandleIrqPara->bNeedDetect = 1; + pDPHandleIrqPara->bNeedCompEdid = 1; + } + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s(%d): why read DPCD reg TEST_REQUEST fail?\n", FUNCTION_NAME, LINE_NUM)); + bStatus = CBIOS_FALSE; + } + + return bStatus; +} + +static CBIOS_BOOL cbDPMonitor_PutNextCBusRecvEvent_locked(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, DP_RECV_EVENT *pRecvEvent) +{ + CBIOS_BOOL bRet = CBIOS_TRUE; + CBIOS_U64 oldIrql = 0; + + oldIrql = cb_AcquireSpinLock(pcbe->pSpinLock); + + if (!QUEUE_FULL(pDPMonitorContext->RecvQueue)) + { + if (pRecvEvent != CBIOS_NULL) + { + pDPMonitorContext->RecvQueue.Queue[pDPMonitorContext->RecvQueue.Tail] = *pRecvEvent; + ADVANCE_QUEUE_TAIL(pDPMonitorContext->RecvQueue); + } + + bRet = CBIOS_TRUE; + } + else + { + //queue is full + bRet = CBIOS_FALSE; + } + + cb_ReleaseSpinLock(pcbe->pSpinLock, oldIrql); + return bRet; +} + +static CBIOS_BOOL cbDPMonitor_IsRecvEventQueueEmpty_locked(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_BOOL bRet = CBIOS_TRUE; + CBIOS_U64 oldIrql = cb_AcquireSpinLock(pcbe->pSpinLock); + + if (QUEUE_EMPTY(pDPMonitorContext->RecvQueue)) + { + bRet = CBIOS_TRUE; + } + else + { + bRet = CBIOS_FALSE; + } + + cb_ReleaseSpinLock(pcbe->pSpinLock, oldIrql); + return bRet; +} + +static CBIOS_BOOL cbDPMonitor_GetNextCBusRecvEvent_locked(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, DP_RECV_EVENT *pRecvEvent) +{ + CBIOS_BOOL bRet = CBIOS_TRUE; + CBIOS_U64 oldIrql = cb_AcquireSpinLock(pcbe->pSpinLock); + + if (QUEUE_EMPTY(pDPMonitorContext->RecvQueue)) + { + bRet = CBIOS_FALSE; + } + else + { + cb_memcpy(pRecvEvent, &(pDPMonitorContext->RecvQueue.Queue[pDPMonitorContext->RecvQueue.Head]), sizeof(DP_RECV_EVENT)); + ADVANCE_QUEUE_HEAD(pDPMonitorContext->RecvQueue) + } + + cb_ReleaseSpinLock(pcbe->pSpinLock, oldIrql); + return bRet; +} + +static CBIOS_VOID cbDPMonitor_NotifyDPEvent(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_U8 EventCode, CBIOS_U8 EventParam) +{ + CBIOS_DP_NOTIFY_EVENT_PARA NotifyPara; + NotifyPara.Size = sizeof(CBIOS_DP_NOTIFY_EVENT_PARA); + NotifyPara.DeviceId = pDPMonitorContext->pDevCommon->DeviceType; + NotifyPara.EventCode = EventCode; + NotifyPara.EventParam = EventParam; + + cbTraceEnter(DP); + + if (pDPMonitorContext->Notifications.NotifyDPEvent != CBIOS_NULL) + { + pDPMonitorContext->Notifications.NotifyDPEvent(pDPMonitorContext->Notifications.Private, &NotifyPara); + } + + cbTraceExit(DP); +} + + +static CBIOS_BOOL cbDPMonitor_ProcAutomatedTestRequest(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + AUX_CONTROL AUX = {0}; + DPCD_REG_00218 DPCD00218; + CBIOS_BOOL bStatus = CBIOS_TRUE; + + // Read Automated detail request. + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x218; + AUX.Length = 1; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD00218.Value = AUX.Data[0] & 0x000000FF; + + if(DPCD00218.TEST_EDID_READ) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Test Edid Read.\n", FUNCTION_NAME)); + if(cbDPMonitor_ProcTestEdidRead(pcbe, pDPMonitorContext)) + { + cbDPMonitor_NotifyDPEvent(pcbe, pDPMonitorContext, CBIOS_DP_EVENT_TEST_EDID, 0); + } + } + + if(DPCD00218.TEST_LINK_TRAINING) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Test Link Training.\n", FUNCTION_NAME)); + cbDPMonitor_ProcTestLinkTraining(pcbe, pDPMonitorContext); + } + + if(DPCD00218.TEST_PATTERN) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Test Pattern.\n", FUNCTION_NAME)); + if(cbDPMonitor_ProcTestPattern(pcbe, pDPMonitorContext)) + { + if (cbDPMonitor_LinkTraining(pcbe, pDPMonitorContext, CBIOS_FALSE)) + { + cbDPMonitor_SetUpMainLink(pcbe, pDPMonitorContext); + } + cbDPMonitor_NotifyDPEvent(pcbe, pDPMonitorContext, CBIOS_DP_EVENT_TEST_PATTERN, 0); + } + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s(%d): why read DPCD reg TEST_REQUEST fail?\n", FUNCTION_NAME, LINE_NUM)); + bStatus = CBIOS_FALSE; + } + + return bStatus; +} + + +static CBIOS_BOOL cbDPMonitor_ProcLinkStatusCheck(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + AUX_CONTROL AUX = {0}; + CBIOS_U32 ulLaneNum, i; + CBIOS_BOOL bNeedRetraining = CBIOS_FALSE; + DPCD_REG_00202 DPCD_00202; + DPCD_REG_00203 DPCD_00203; + DPCD_REG_00204 DPCD_00204; + //DPCD_REG_00205 DPCD_00205; + CBIOS_BOOL bStatus = CBIOS_TRUE; + + //4.3.2.1 + //4.3.2.2 + //4.3.2.3 + //4.3.2.4 + + // Link maintenance hot IRQ signal, need to check link/sink status field of DPCD. + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Not a automated test IRQ, Link maitanance IRQ!\n", FUNCTION_NAME)); + ulLaneNum = pDPMonitorContext->LaneNumberToUse; + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x202; + AUX.Length = 4; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD_00202.Value = (AUX.Data[0] & 0x000000FF) >> 0; + DPCD_00203.Value = (AUX.Data[0] & 0x0000FF00) >> 8; + DPCD_00204.Value = (AUX.Data[0] & 0x00FF0000) >> 16; + //DPCD_00205.Value = (AUX.Data[0] & 0xFF000000) >> 24; + + // 20090317_BC Don't rely on register 204[7] because it's cleared once read, and + // we have no idea whether here is the first read instance + //if(DPCD_00204.LINK_STATUS_UPDATED) // Link status and Adjust request updated since the last read. + if(pDPMonitorContext->pDevCommon->PowerState == CBIOS_PM_ON) + { + for (i = 0; i < ulLaneNum; i++) + { + if ((i == 0) && (!DPCD_00202.LANE0_CR_DONE || !DPCD_00202.LANE0_CHANNEL_EQ_DONE || !DPCD_00202.LANE0_SYMBOL_LOCKED)) + { + bNeedRetraining = CBIOS_TRUE; + break; + } + else if ((i == 1) && (!DPCD_00202.LANE1_CR_DONE || !DPCD_00202.LANE1_CHANNEL_EQ_DONE || !DPCD_00202.LANE1_SYMBOL_LOCKED)) + { + bNeedRetraining = CBIOS_TRUE; + break; + } + else if ((i == 2) && (!DPCD_00203.LANE2_CR_DONE || !DPCD_00203.LANE2_CHANNEL_EQ_DONE || !DPCD_00203.LANE2_SYMBOL_LOCKED)) + { + bNeedRetraining = CBIOS_TRUE; + break; + } + else if ((i == 3) && (!DPCD_00203.LANE3_CR_DONE || !DPCD_00203.LANE3_CHANNEL_EQ_DONE || !DPCD_00203.LANE3_SYMBOL_LOCKED)) + { + bNeedRetraining = CBIOS_TRUE; + break; + } + } + + if(!bNeedRetraining) + { + // Check lane align status + if(!DPCD_00204.INTERLANE_ALIGN_DONE) + { + bNeedRetraining = CBIOS_TRUE; + } + /*// check receive port status + else if(!DPCD_00205.RECEIVE_PORT_0_STATUS) + { + bNeedRetraining = CBIOS_TRUE; + } + else if(!DPCD_00205.RECEIVE_PORT_1_STATUS) + { + bNeedRetraining = CBIOS_TRUE; + }*/ + } + + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: bNeedRetraining: %d.\n", FUNCTION_NAME, bNeedRetraining)); + + if(bNeedRetraining) + { + if (cbDPMonitor_LinkTraining(pcbe, pDPMonitorContext, CBIOS_FALSE)) + { + CBIOS_BOOL status; + status = cbDPMonitor_SetUpMainLink(pcbe, pDPMonitorContext); + if(!status) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING),"%s: setting up Main Link failed!\n", FUNCTION_NAME)); + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: skip Setting Up MainLink because Link Training failed!\n", FUNCTION_NAME)); + } + + pDPMonitorContext->LT_Status = 0; + } + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Can not get sink link status!\n", FUNCTION_NAME)); + bStatus = CBIOS_FALSE; + } + + return bStatus; +} + +static CBIOS_BOOL cbDPMonitor_ProcRecvEvents_Int(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, const PDP_RECV_EVENT pRecvEvent) +{ + CBIOS_BOOL bRet = CBIOS_TRUE; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + const DP_RECV_EVENT RecvEvent = *pRecvEvent; + AUX_CONTROL AUX = {0}; + DPCD_REG_00201 DPCD00201; + + cbTraceEnter(DP); + + switch (RecvEvent.HpdStatus) + { + case 1: + { + if(cbDualModeDetect(pcbe, pDPMonitorContext->pDevCommon)) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: HDMI monitor hotplug in!\n", FUNCTION_NAME)); + cbDPMonitor_NotifyDPEvent(pcbe, pDPMonitorContext, CBIOS_DP_EVENT_HDMI_HOTPLUG_IN, 0); + } + else + { + // power on aux channel + cbPHY_DP_SelectEphyMode(pcbe, DPModuleIndex, DP_EPHY_DP_MODE); + cbPHY_DP_AuxPowerOn(pcbe, DPModuleIndex); + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x201; + AUX.Length = 1; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD00201.Value = AUX.Data[0] & 0x000000FF; + if(DPCD00201.AUTOMATED_TEST_REQUEST) + { + // clear AUTOMATED_TEST_REQUEST bit + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x201; + AUX.Length = 1; + AUX.Data[0] = DPCD00201.Value; + cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX); + + cbDPMonitor_ProcAutomatedTestRequest(pcbe, pDPMonitorContext); + } + // normal hotplug event + else + { + cbDPMonitor_NotifyDPEvent(pcbe, pDPMonitorContext, CBIOS_DP_EVENT_DP_HOTPLUG_IN, 0); + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: I2C and Aux all fail, regard it as HDMI monitor hotplug in!\n", FUNCTION_NAME)); + cbDPMonitor_NotifyDPEvent(pcbe, pDPMonitorContext, CBIOS_DP_EVENT_HDMI_HOTPLUG_IN, 0); + } + } + } + break; + + case 2: + { + if(cbDPPort_IsDeviceInDpMode(pcbe, pDPMonitorContext->pDevCommon)) + { + cbDPMonitor_NotifyDPEvent(pcbe, pDPMonitorContext, CBIOS_DP_EVENT_DP_HOTPLUG_OUT, 0); + } + else + { + cbDPMonitor_NotifyDPEvent(pcbe, pDPMonitorContext, CBIOS_DP_EVENT_HDMI_HOTPLUG_OUT, 0); + } + } + break; + + case 3: + { + // power on aux channel + cbPHY_DP_SelectEphyMode(pcbe, DPModuleIndex, DP_EPHY_DP_MODE); + cbPHY_DP_AuxPowerOn(pcbe, DPModuleIndex); + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x200; + AUX.Length = 2; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD00201.Value = (AUX.Data[0] & 0x0000FF00) >> 8; + if(DPCD00201.AUTOMATED_TEST_REQUEST) + { + // clear AUTOMATED_TEST_REQUEST bit + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x201; + AUX.Length = 1; + AUX.Data[0] = DPCD00201.Value; + cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX); + + cbDPMonitor_ProcAutomatedTestRequest(pcbe, pDPMonitorContext); + } + else + { + cbDPMonitor_ProcLinkStatusCheck(pcbe, pDPMonitorContext); + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s(%d): read DPCD reg(Offset = 0x%x, len = %d) fail?\n", + FUNCTION_NAME, LINE_NUM, AUX.Offset, AUX.Length)); + bRet = CBIOS_FALSE; + } + } + break; + + default: + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "## unkown RecvEvent.HpdStatus = %d\n", RecvEvent.HpdStatus)); + bRet = CBIOS_FALSE; + break; + } + + cbTraceExit(DP); + return bRet; +} + +static CBIOS_BOOL cbDPMonitor_ProcRecvEvents(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext) +{ + CBIOS_BOOL bRet = CBIOS_TRUE; + DP_RECV_EVENT RecvEvent; + + cbTraceEnter(DP); + cb_AcquireMutex(pcbe->pAuxMutex); + + if(cbDPMonitor_GetNextCBusRecvEvent_locked(pcbe, pDPMonitorContext, &RecvEvent) == CBIOS_TRUE) + { + switch (RecvEvent.EventType) + { + case 0: + { + cbDPMonitor_ProcRecvEvents_Int(pcbe, pDPMonitorContext, &RecvEvent); + } + break; + + default: + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "unkown RecvEvent.EventType\n")); + break; + } + } + else + { + // empty queue + bRet = CBIOS_FALSE; + } + + cb_ReleaseMutex(pcbe->pAuxMutex); + + cbTraceExit(DP); + return bRet; +} + +CBIOS_STATUS cbDPMonitor_Isr(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_ISR_PARA pDPIsrPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + DP_RECV_EVENT RecvEvent; + CBIOS_U32 HPDStatus = 0; + REG_MM8330 DPAuxTimerRegValue; + + if (DPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_ER_INTERNAL; + } + cb_memset(&RecvEvent, 0, sizeof(DP_RECV_EVENT)); + + DPAuxTimerRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_TIMER[DPModuleIndex]); + HPDStatus = DPAuxTimerRegValue.HPD_Status; + + if (HPDStatus == 0) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s(%d): why got HPD status: %d\n", FUNCTION_NAME, LINE_NUM, HPDStatus)); + } + else if ((HPDStatus == 1) || (HPDStatus == 2) || (HPDStatus == 3)) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s(%d): HPD status: %d\n", FUNCTION_NAME, LINE_NUM, HPDStatus)); + + RecvEvent.EventType = 0; + RecvEvent.HpdStatus = HPDStatus; + + if(!cbDPMonitor_PutNextCBusRecvEvent_locked(pcbe, pDPMonitorContext, &RecvEvent)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s(%d): Recv Queue is Full\n", FUNCTION_NAME, LINE_NUM)); + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s(%d): unknown HPD status: %d\n", FUNCTION_NAME, LINE_NUM, HPDStatus)); + } + + return Status; +} + +CBIOS_BOOL cbDPMonitor_WorkThreadMainFunc(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_WORKTHREAD_PARA pDPWorkThreadPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bWorkThreadBusy = CBIOS_FALSE; + + cbTraceEnter(DP); + + if (!cbDPMonitor_IsRecvEventQueueEmpty_locked(pcbe, pDPMonitorContext)) + { + bWorkThreadBusy = CBIOS_TRUE; + } + else + { + goto Exit; + } + + while (cbDPMonitor_ProcRecvEvents(pcbe, pDPMonitorContext)); + + cbTraceExit(DP); + +Exit: + return bWorkThreadBusy; +} + +CBIOS_STATUS cbDPMonitor_SetNotifications(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_NOTIFICATIONS pDPNotifications) +{ + CBIOS_STATUS Status = CBIOS_OK; + + cbTraceEnter(DP); + + pDPMonitorContext->Notifications.Size = pDPNotifications->Size; + pDPMonitorContext->Notifications.DeviceId = pDPNotifications->DeviceId; + pDPMonitorContext->Notifications.Private = pDPNotifications->Private; + pDPMonitorContext->Notifications.NotifyDPEvent = pDPNotifications->NotifyDPEvent; + + cbTraceExit(DP); + return Status; +} + +CBIOS_STATUS cbDPMonitor_GetInt(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_INT_PARA pDPIntPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + CBIOS_U32 HPDStatus = 0; + REG_MM8330 DPAuxTimerRegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + return CBIOS_ER_INTERNAL; + } + + pDPIntPara->IntType = CBIOS_DP_INT_STATUS_NO_INT; + + DPAuxTimerRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_TIMER[DPModuleIndex]); + HPDStatus = DPAuxTimerRegValue.HPD_Status; + + if (HPDStatus == 1) + { + pDPIntPara->IntType = CBIOS_DP_INT_STATUS_IN; + } + else if (HPDStatus == 2) + { + if(cbDPPort_IsDeviceInDpMode(pcbe, pDPMonitorContext->pDevCommon)) + { + pDPIntPara->IntType = CBIOS_DP_INT_STATUS_DP_OUT; + } + else + { + pDPIntPara->IntType = CBIOS_DP_INT_STATUS_HDMI_OUT; + } + } + else if(HPDStatus == 3) + { + pDPIntPara->IntType = CBIOS_DP_INT_IRQ; + } + + return CBIOS_OK; +} + +CBIOS_STATUS cbDPMonitor_HandleIrq(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_HANDLE_IRQ_PARA pDPHandleIrqPara) +{ + CBIOS_STATUS Ret = CBIOS_OK; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, pDPMonitorContext->pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + CBIOS_DP_INT_TYPE int_type = pDPHandleIrqPara->IntType; + AUX_CONTROL AUX = {0}; + DPCD_REG_00201 DPCD00201; + DP_EPHY_MODE Mode; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_ER_INTERNAL; + } + + pDPHandleIrqPara->bNeedDetect = 0; + pDPHandleIrqPara->bNeedCompEdid = 0; + + switch (int_type) + { + case CBIOS_DP_INT_STATUS_IN: + { + if(cbDualModeDetect(pcbe, pDPMonitorContext->pDevCommon)) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: HDMI monitor hotplug in!\n", FUNCTION_NAME)); + pDPHandleIrqPara->bNeedDetect = 1; + pDPHandleIrqPara->bNeedCompEdid = 1; + } + else + { + cb_AcquireMutex(pcbe->pAuxMutex); + Mode = cbPHY_DP_GetEphyMode(pcbe, DPModuleIndex); //save ephy mode + // power on aux channel + cbPHY_DP_SelectEphyMode(pcbe, DPModuleIndex, DP_EPHY_DP_MODE); + cbPHY_DP_AuxPowerOn(pcbe, DPModuleIndex); + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x201; + AUX.Length = 1; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD00201.Value = AUX.Data[0] & 0x000000FF; + if(DPCD00201.AUTOMATED_TEST_REQUEST) + { + // clear AUTOMATED_TEST_REQUEST bit + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x201; + AUX.Length = 1; + AUX.Data[0] = DPCD00201.Value; + cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX); + + cbDPMonitor_HandleTestRequest(pcbe, pDPMonitorContext, pDPHandleIrqPara); + } + // normal hotplug event + else + { + pDPHandleIrqPara->bNeedDetect = 1; + pDPHandleIrqPara->bNeedCompEdid = 1; + } + } + else + { + pDPHandleIrqPara->bNeedDetect = 1; + pDPHandleIrqPara->bNeedCompEdid = 1; + } + + cbPHY_DP_SelectEphyMode(pcbe, DPModuleIndex, Mode); //restore ephy mode + cb_ReleaseMutex(pcbe->pAuxMutex); + } + } + break; + case CBIOS_DP_INT_IRQ: + { + cb_AcquireMutex(pcbe->pAuxMutex); + + // power on aux channel + cbPHY_DP_SelectEphyMode(pcbe, DPModuleIndex, DP_EPHY_DP_MODE); + cbPHY_DP_AuxPowerOn(pcbe, DPModuleIndex); + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x200; + AUX.Length = 2; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD00201.Value = (AUX.Data[0] & 0x0000FF00) >> 8; + if(DPCD00201.AUTOMATED_TEST_REQUEST) + { + // clear AUTOMATED_TEST_REQUEST bit + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x201; + AUX.Length = 1; + AUX.Data[0] = DPCD00201.Value; + cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX); + + cbDPMonitor_HandleTestRequest(pcbe, pDPMonitorContext, pDPHandleIrqPara); + } + else + { + cbDPMonitor_ProcLinkStatusCheck(pcbe, pDPMonitorContext); + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s(%d): read DPCD reg(Offset = 0x%x, len = %d) fail?\n", + FUNCTION_NAME, LINE_NUM, AUX.Offset, AUX.Length)); + Ret = CBIOS_ER_INTERNAL; + } + + cb_ReleaseMutex(pcbe->pAuxMutex); + } + break; + default: + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "## unkown RecvEvent.HpdStatus = %d\n", int_type)); + Ret = CBIOS_ER_INVALID_HOTPLUG; + break; + } + + return Ret; +} + +CBIOS_STATUS cbDPMonitor_GetCustomizedTiming(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_CUSTOMIZED_TIMING pDPCustomizedTiming) +{ + CBIOS_STATUS Status = CBIOS_OK; + PCBiosCustmizedDestTiming pCustomizedTiming = &pDPMonitorContext->TestDpcdDataTiming; + + cbTraceEnter(DP); + + if (pCustomizedTiming->HorWidth && pCustomizedTiming->VerWidth) + { + cb_memcpy(&pDPCustomizedTiming->CustmizedTiming, pCustomizedTiming, sizeof(CBiosCustmizedDestTiming)); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid Customized Timing\n", FUNCTION_NAME)); + Status = CBIOS_ER_INTERNAL; + } + + cbTraceExit(DP); + return Status; +} + +CBIOS_VOID cbDPMonitor_SetDither(PCBIOS_VOID pvcbe, CBIOS_U32 bpc, CBIOS_BOOL bOn, CBIOS_MODULE_INDEX DPModuleIndex ) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_SR36 SR36_value, SR36_mask; + + if(bOn) + { + switch(bpc) + { + case 5: + SR36_value.Value = 0; + SR36_value.Dither_Pattern_Select = 1; + SR36_value.Dither_EN = 1; + SR36_value.Dither_Bit_Select = 3; + break; + + case 6: + SR36_value.Value = 0; + SR36_value.Dither_Pattern_Select = 1; + SR36_value.Dither_EN = 1; + SR36_value.Dither_Bit_Select = 4; + break; + + case 7: + SR36_value.Value = 0; + SR36_value.Dither_Pattern_Select = 1; + SR36_value.Dither_EN = 1; + SR36_value.Dither_Bit_Select = 5; + break; + + case 8: + SR36_value.Value = 0; + SR36_value.Dither_Pattern_Select = 1; + SR36_value.Dither_EN = 1; + SR36_value.Dither_Bit_Select = 6; + break; + + case 9: + SR36_value.Value = 0; + SR36_value.Dither_Pattern_Select = 1; + SR36_value.Dither_EN = 1; + SR36_value.Dither_Bit_Select = 7; + break; + + default: + SR36_value.Value = 0; + break; + } + } + else + { + SR36_value.Value = 0; + } + + SR36_mask.Value = 0xFF; + SR36_mask.Dither_Pattern_Select = 0; + SR36_mask.Dither_EN = 0; + SR36_mask.Dither_Bit_Select = 0; + + if(DPModuleIndex == CBIOS_MODULE_INDEX2) + { + cbMMIOWriteReg(pcbe,SR_B_36, SR36_value.Value, SR36_mask.Value); + } + else + { + cbMMIOWriteReg(pcbe,SR_36, SR36_value.Value, SR36_mask.Value); + } +} + +#endif + diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosDPMonitor.h b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosDPMonitor.h new file mode 100644 index 0000000000000..fdcff60841708 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosDPMonitor.h @@ -0,0 +1,155 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DP monitor interface function prototype and parameter definition. +** +** NOTE: +** DP monitor ONLY parameters SHOULD be added to CBIOS_DP_MONITOR_CONTEXT. +******************************************************************************/ + +#ifndef _CBIOS_DP_MONITOR_H_ +#define _CBIOS_DP_MONITOR_H_ + +#include "../CBiosDeviceShare.h" + +#define HARDCODE_DP1_MAX_LINKSPEED_1620 0x00000001 +#define HARDCODE_DP1_MAX_LINKSPEED_2700 0x00000002 +#define HARDCODE_DP1_MAX_LINKSPEED_5400 0x00008000 +#define HARDCODE_DP1_LANECOUNT_1 0x00000004 +#define HARDCODE_DP1_LANECOUNT_2 0x00000008 +#define HARDCODE_DP1_LANECOUNT_4 0x00000010 +#define HARDCODE_DP1_EDID_ALL_ZERO_BYTES 0x00000100 +#define DISABLE_EDP_CONTENT_PROTECTION 0x00001000 +#define DEFAULT_USE_EDP_CP_METHOD_3A_ASSR 0x00002000 +#define DEFAULT_USE_EDP_CP_METHOD_3B_AF 0x00004000 + +#define DP_Default_bpc 8 +#define DP_Default_TUSize 48 +#define DP_Min_bpc 6 + +typedef enum _AUX_WORKING_STATUS +{ + AUX_WORKING_STATUS_IDLE = 0x00, + AUX_WORKING_STATUS_LINKTRAINING = 0x01, + AUX_WORKING_STATUS_EDID_READING = 0x02, +}AUX_WORKING_STATUS; + +typedef struct +{ + CBIOS_U32 EventType; + CBIOS_U64 Timestamp; + union + { + CBIOS_U32 HpdStatus; + }; +} DP_RECV_EVENT, *PDP_RECV_EVENT; + +#define MAX_DP_RECV_QUEUE_EVENTS 64 +typedef struct +{ + CBIOS_U32 Head; + CBIOS_U32 Tail; + DP_RECV_EVENT Queue[MAX_DP_RECV_QUEUE_EVENTS]; +} DP_RECV_QUEUE, *PDP_RECV_QUEUE; + +#define QUEUE_SIZE(x) (sizeof(x.Queue)/sizeof(x.Queue[0])) +#define MAX_QUEUE_DEPTH(x) (QUEUE_SIZE(x) -1) +#define QUEUE_DEPTH(x) ((x.Head <= x.Tail)?(x.Tail-x.Head):(QUEUE_SIZE(x)-x.Head+x.Tail)) +#define QUEUE_FULL(x) (QUEUE_DEPTH(x) >= MAX_QUEUE_DEPTH(x)) +#define QUEUE_EMPTY(x) (QUEUE_DEPTH(x) == 0) +#define ADVANCE_QUEUE_HEAD(x) { x.Head = (x.Head < MAX_QUEUE_DEPTH(x))?(x.Head+1):0; } +#define ADVANCE_QUEUE_TAIL(x) { x.Tail = (x.Tail < MAX_QUEUE_DEPTH(x))?(x.Tail+1):0; } +#define LAST_ITEM_INDEX(x) (x.Tail == 0)?(QUEUE_SIZE(x) -1):(x.Tail-1) +#define RESET_QUEUE(x) { do {x.Head = 0; x.Tail = 0;} while(0); } + +typedef struct _CBIOS_DP_MONITOR_CONTEXT +{ + PCBIOS_DEVICE_COMMON pDevCommon; + + // monitor caps + struct + { + CBIOS_U32 DpSinkVersion; // sink version + CBIOS_U32 SinkMaxLaneCount; // max lane count supported by sink + CBIOS_U32 SinkMaxLinkSpeed; // max link speed supported by sink + CBIOS_BOOL bSupportASSR; // Support content protection method 3a, ASSR + CBIOS_BOOL bSupportAF; // Support content protection method 3b, AF + CBIOS_BOOL bSupportEnhanceMode; // Support enhanced framing symbol sequence for BS, SR, CPBS and CPSR + CBIOS_BOOL bSupportTPS3; // Support Training Pattern 3(5.4Gbps) + }; + + // source caps + struct + { + CBIOS_U32 SourceMaxLaneCount; // max lane count supported by Source + CBIOS_U32 SourceMaxLinkSpeed; // max link speed supported by Source + CBIOS_BOOL bSourceSupportTPS3; // Support Training Pattern 3(5.4Gbps) + }; + + // control params + struct + { + CBIOS_U32 LaneNumberToUse; // 1 ~ 4 lanes + CBIOS_U32 LinkSpeedToUse; // 1.62Gbps, 2.7 Gbps or 5.4 Gbps + CBIOS_U32 bpc; // bit per channel + CBIOS_U32 TUSize; // 32 ~ 64, default to 48 + CBIOS_BOOL EnhancedMode; // 1 (yes) to support HDCP + CBIOS_BOOL AsyncMode; // 1 (yes), asynchronous mode + CBIOS_U32 ColorFormat; // 0: RGB, 1:YCbCr422, 2:YCbCr444 + CBIOS_U32 DynamicRange; // 0: VESA range, 1:CEA range + CBIOS_U32 YCbCrCoefficients; // 0: ITU601, 1: ITU709 + CBIOS_BOOL LT_Status; // 0:not yet link trainning (to save LT in DP ON/OFF function) + CBIOS_U32 DpAuxWorkingStatus; // To detect/record any simultaneous work(s) via AUX channel. + CBiosCustmizedDestTiming TestDpcdDataTiming; //This is only for DP automation test. + CBIOS_TIMING_ATTRIB TargetTiming; + CBIOS_BOOL bInterlace; + CBIOS_U32 TrainingAuxRdInterval; // Link Status/Adjust Request read interval during Main Link Training + // 0: 100us; 1: 4ms; 2: 8ms; 3: 12ms; 4: 16ms. + CBIOS_U8 PixelRepetition; + CBIOS_BOOL bEnableTPS3; // 1: transmit Training Pattern 3 during Link Training + }; + + // eDP GPIO + CBIOS_U8 GpioForEDP1Power; + CBIOS_U8 GpioForEDP1BackLight; + CBIOS_U8 GpioForEDP2Power; + CBIOS_U8 GpioForEDP2BackLight; + + struct + { + // protected by spinLock between threads + DP_RECV_QUEUE RecvQueue; + CBIOS_DP_NOTIFICATIONS Notifications; + }; +}CBIOS_DP_MONITOR_CONTEXT, *PCBIOS_DP_MONITOR_CONTEXT; + +CBIOS_BOOL cbDPMonitor_AuxReadEDID(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_UCHAR pEDIDBuffer, CBIOS_U32 ulBufferSize); +CBIOS_BOOL cbDPMonitor_AuxReadEDIDOffset(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_UCHAR pEDIDBuffer, CBIOS_U32 ulBufferSize, CBIOS_U32 ulReadEdidOffset); +CBIOS_STATUS cbDPMonitor_GetCustomizedTiming(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_CUSTOMIZED_TIMING pDPCustomizedTiming); +CBIOS_STATUS cbDPMonitor_Isr(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_ISR_PARA pDPIsrPara); +CBIOS_BOOL cbDPMonitor_WorkThreadMainFunc(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_WORKTHREAD_PARA pDPWorkThreadPara); +CBIOS_STATUS cbDPMonitor_SetNotifications(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_NOTIFICATIONS pDPNotifications); +CBIOS_STATUS cbDPMonitor_GetInt(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_INT_PARA pDPIntPara); +CBIOS_STATUS cbDPMonitor_HandleIrq(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DP_HANDLE_IRQ_PARA pDPHandleIrqPara); +CBIOS_U32 cbDPMonitor_GetMaxSupportedDclk(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext); +CBIOS_BOOL cbDPMonitor_Detect(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_BOOL bHardcodeDetected, CBIOS_U32 FullDetect); +CBIOS_VOID cbDPMonitor_SetMode(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DISP_MODE_PARAMS pModeParams); +CBIOS_VOID cbDPMonitor_UpdateModeInfo(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBIOS_DISP_MODE_PARAMS pModeParams); +CBIOS_VOID cbDPMonitor_QueryAttribute(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, PCBiosMonitorAttribute pMonitorAttribute); +CBIOS_VOID cbDPMonitor_OnOff(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_BOOL bOn); +CBIOS_VOID cbDPMonitor_SetDither(PCBIOS_VOID pvcbe, CBIOS_U32 bpc, CBIOS_BOOL bOn, CBIOS_MODULE_INDEX DPModuleIndex); +#endif diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosEDPPanel.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosEDPPanel.c new file mode 100644 index 0000000000000..3abf0d6bab37c --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosEDPPanel.c @@ -0,0 +1,253 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +#include "CBiosChipShare.h" +#include "CBiosEDPPanel.h" + +extern CBIOS_EDP_PANEL_DESC ITN156_Panel_Desc; + +#define DEFAULT_EDP_PANEL_INDEX 0 +#define ITN156_PANEL_INDEX 0 + +static PCBIOS_EDP_PANEL_DESC EDPPanelDescTbl[] = +{ + &ITN156_Panel_Desc, +}; + +static CBIOS_BOOL cbEDPPanel_GetMonitorID(CBIOS_U8 *pEDID, CBIOS_U8 *pMnitorID) +{ + CBIOS_U8 index[32] = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]^_"; + CBIOS_U8 ProductID[3] = {0}; + CBIOS_BOOL bRet = CBIOS_FALSE; + CBIOS_U8 *pMonitorIDinEDID = pEDID + 0x08; + + if ((pMonitorIDinEDID == CBIOS_NULL) || (pMnitorID == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbEDPPanel_GetMonitorID: input buffer is null!\n")); + return CBIOS_FALSE; + } + + //get manufacturer ID + pMnitorID[0] = index[(pMonitorIDinEDID[0] >> 2) & 0x1F]; + pMnitorID[1] = index[((pMonitorIDinEDID[1] >> 5) & 0x07) | ((pMonitorIDinEDID[0] << 3) & 0x18)]; + pMnitorID[2] = index[pMonitorIDinEDID[1] & 0x1F]; + pMnitorID[3] = '\0'; + + if (cbItoA((CBIOS_U32)pMonitorIDinEDID[3], ProductID, 16, 2)) + { + cbStrCat(pMnitorID, ProductID); + if (cbItoA((CBIOS_U32)pMonitorIDinEDID[2], ProductID, 16, 2)) + { + cbStrCat(pMnitorID, ProductID); + bRet = CBIOS_TRUE; + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Monitor ID is: %s\n", pMnitorID)); + } + } + + return bRet; + +} + +PCBIOS_EDP_PANEL_DESC cbEDPPanel_GetPanelDescriptor(PCBIOS_VOID pvcbe, PCBIOS_U8 pEdidData) +{ + PCBIOS_EDP_PANEL_DESC pPanelDesc = CBIOS_NULL; + CBIOS_UCHAR MonitorID[8]; + CBIOS_U32 i = 0; + + if (cbEDPPanel_GetMonitorID(pEdidData, MonitorID))// use monitor ID to get desc temporary,need sync with sysinfo + { + for (i = 0; i < sizeofarray(EDPPanelDescTbl); i++) + { + if (cb_strcmp(MonitorID, EDPPanelDescTbl[i]->MonitorID) == 0) + { + pPanelDesc = EDPPanelDescTbl[i]; + break; + } + } + } + + if (pPanelDesc == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DP, INFO), "Can't get panel descriptor for eDP list. Treat it as DP.\n")); + } + + return pPanelDesc; +} + +CBIOS_STATUS cbEDPPanel_PreInit(PCBIOS_VOID pvcbe) +{ + PCBIOS_EDP_PANEL_DESC pPanelDesc = CBIOS_NULL; + CBIOS_U32 i = 0; + + for (i = 0; i < sizeofarray(EDPPanelDescTbl); i++) + { + pPanelDesc = EDPPanelDescTbl[i]; + if (pPanelDesc->EDPPreCaps.IsNeedPreInit) + { + if(pPanelDesc->EDPPreCaps.pFnEDPPanelPreInit != CBIOS_NULL) + { + pPanelDesc->EDPPreCaps.pFnEDPPanelPreInit(pvcbe); + } + } + } + + return CBIOS_OK; +} + +CBIOS_STATUS cbEDPPanel_Init(PCBIOS_VOID pvcbe, PCBIOS_EDP_PANEL_DESC pPanelDesc) +{ + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pPanelDesc != CBIOS_NULL) + { + if (pPanelDesc->pFnEDPPanelInit != CBIOS_NULL) + { + Status = pPanelDesc->pFnEDPPanelInit(pvcbe); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "function %s not implemented.\n", FUNCTION_NAME)); + } + Status = CBIOS_OK; + + } + else + { + Status = CBIOS_ER_NULLPOINTER; + } + + + return Status; +} + + +CBIOS_STATUS cbEDPPanel_DeInit(PCBIOS_VOID pvcbe, PCBIOS_EDP_PANEL_DESC pPanelDesc) +{ + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pPanelDesc != CBIOS_NULL) + { + if (pPanelDesc->pFnEDPPanelDeInit != CBIOS_NULL) + { + Status = pPanelDesc->pFnEDPPanelDeInit(pvcbe); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "function %s not implemented.\n", FUNCTION_NAME)); + } + Status = CBIOS_OK; + + } + else + { + Status = CBIOS_ER_NULLPOINTER; + } + + + return Status; +} + + +CBIOS_STATUS cbEDPPanel_OnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn, PCBIOS_EDP_PANEL_DESC pPanelDesc) +{ + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pPanelDesc != CBIOS_NULL) + { + if (pPanelDesc->pFnEDPPanelOnOff != CBIOS_NULL) + { + Status = pPanelDesc->pFnEDPPanelOnOff(pvcbe, bTurnOn); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "function %s not implemented.\n", FUNCTION_NAME)); + } + Status = CBIOS_OK; + } + else + { + Status = CBIOS_ER_NULLPOINTER; + } + + + return Status; +} + + +CBIOS_STATUS cbEDPPanel_SetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 BacklightValue, PCBIOS_EDP_PANEL_DESC pPanelDesc) +{ + PCBIOS_EDP_CAPS pEDPCaps = CBIOS_NULL; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 BlValue = 0; + + if (pPanelDesc != CBIOS_NULL) + { + if (pPanelDesc->pFnEDPPanelSetBacklight!= CBIOS_NULL) + { + BlValue = BacklightValue; + pEDPCaps = &(pPanelDesc->EDPCaps); + if (BacklightValue < pEDPCaps->BacklightMin) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: backlight value: %d is smaller than the min backlight value, use the min.\n", FUNCTION_NAME, BacklightValue)); + BlValue = pEDPCaps->BacklightMin; + } + if (BacklightValue > pEDPCaps->BacklightMax) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: backlight value: %d is greater than the max backlight value, use the max.\n", FUNCTION_NAME, BacklightValue)); + BlValue = pEDPCaps->BacklightMax; + } + + Status = pPanelDesc->pFnEDPPanelSetBacklight(pvcbe, BlValue); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "function %s not implemented. use default command list\n", FUNCTION_NAME)); + } + } + else + { + Status = CBIOS_ER_NULLPOINTER; + } + + return Status; +} + +CBIOS_STATUS cbEDPPanel_GetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 *pBacklightValue, PCBIOS_EDP_PANEL_DESC pPanelDesc) +{ + CBIOS_STATUS Status = CBIOS_OK; + + if (pPanelDesc != CBIOS_NULL) + { + + if (pPanelDesc->pFnEDPPanelGetBacklight!= CBIOS_NULL) + { + Status = pPanelDesc->pFnEDPPanelGetBacklight(pvcbe, pBacklightValue); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "function %s not implemented. \n", FUNCTION_NAME)); + + *pBacklightValue = 0; + } + } + else + { + Status = CBIOS_ER_NULLPOINTER; + } + + + return Status; +} + diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosEDPPanel.h b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosEDPPanel.h new file mode 100644 index 0000000000000..db35bc5b0d21f --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosEDPPanel.h @@ -0,0 +1,83 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +#ifndef _CBIOS_EDP_PANEL_H_ +#define _CBIOS_EDP_PANEL_H_ + +#include "../CBiosShare.h" + +#define CBIOS_EDP_VERSION 0x01 + +typedef struct _CBIOS_EDP_CAPS +{ + CBIOS_U32 LinkSpeed; // 270 MHz is 2700000 + CBIOS_U32 LaneNum; + CBIOS_U32 BacklightMax; + CBIOS_U32 BacklightMin; + + union + { + struct + { + CBIOS_U32 isBLCtrlSupport :1; + CBIOS_U32 isHardcodeLinkPara :1; // 1: use the LinkSpeed and LaneNum given in CBIOS_EDP_CAPS + CBIOS_U32 Reserved :30; + }; + CBIOS_U32 Flags; + }; +}CBIOS_EDP_CAPS, *PCBIOS_EDP_CAPS; + +typedef CBIOS_STATUS (*PFN_cbEDPPanel_PreInit)(PCBIOS_VOID pvcbe); +typedef CBIOS_STATUS (*PFN_cbEDPPanel_Init)(PCBIOS_VOID pvcbe); +typedef CBIOS_STATUS (*PFN_cbEDPPanel_DeInit)(PCBIOS_VOID pvcbe); +typedef CBIOS_STATUS (*PFN_cbEDPPanel_PowerOnOff)(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn); +typedef CBIOS_STATUS (*PFN_cbEDPPanel_SetBacklight)(PCBIOS_VOID pvcbe, CBIOS_U32 BrightnessValue); +typedef CBIOS_STATUS (*PFN_cbEDPPanel_GetBacklight)(PCBIOS_VOID pvcbe, CBIOS_U32 *pBrightnessValue); + +typedef struct _CBIOS_EDP_PREPARE_CAPS +{ + CBIOS_BOOL IsNeedPreInit; + PFN_cbEDPPanel_PreInit pFnEDPPanelPreInit; +}CBIOS_EDP_PREPARE_CAPS, *PCBIOS_EDP_PREPARE_CAPS; + +typedef struct _CBIOS_EDP_PANEL_DESC +{ + CBIOS_U32 VersionNum; + CBIOS_UCHAR MonitorID[8]; + CBIOS_EDP_PREPARE_CAPS EDPPreCaps; + CBIOS_EDP_CAPS EDPCaps; + PFN_cbEDPPanel_Init pFnEDPPanelInit; + PFN_cbEDPPanel_DeInit pFnEDPPanelDeInit; + PFN_cbEDPPanel_PowerOnOff pFnEDPPanelOnOff; + PFN_cbEDPPanel_SetBacklight pFnEDPPanelSetBacklight; + PFN_cbEDPPanel_GetBacklight pFnEDPPanelGetBacklight; +}CBIOS_EDP_PANEL_DESC, *PCBIOS_EDP_PANEL_DESC; + +typedef struct _CBIOS_EDP_PARA +{ + CBIOS_EDP_PANEL_DESC EDPPanelDesc; +}CBIOS_EDPPanel_PARAMS, *PCBIOS_EDPPanel_PARAMS; + +PCBIOS_EDP_PANEL_DESC cbEDPPanel_GetPanelDescriptor(PCBIOS_VOID pvcbe, PCBIOS_U8 pEdidData); +CBIOS_STATUS cbEDPPanel_PreInit(PCBIOS_VOID pvcbe); +CBIOS_STATUS cbEDPPanel_Init(PCBIOS_VOID pvcbe, PCBIOS_EDP_PANEL_DESC pPanelDesc); +CBIOS_STATUS cbEDPPanel_DeInit(PCBIOS_VOID pvcbe, PCBIOS_EDP_PANEL_DESC pPanelDesc); +CBIOS_STATUS cbEDPPanel_OnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn, PCBIOS_EDP_PANEL_DESC pPanelDesc); +CBIOS_STATUS cbEDPPanel_SetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 BacklightValue, PCBIOS_EDP_PANEL_DESC pPanelDesc); +CBIOS_STATUS cbEDPPanel_GetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 *pBacklightValue, PCBIOS_EDP_PANEL_DESC pPanelDesc); +CBIOS_STATUS cbEDPPanel_DisplayOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn, PCBIOS_EDP_PANEL_DESC pPanelDesc); + +#endif + diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.c new file mode 100644 index 0000000000000..8faef9ec22e3f --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.c @@ -0,0 +1,1621 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** HDMI monitor interface function implementation. +** +** NOTE: +** HDMI monitor related function SHOULD be added to this file, +** no matter the monitor is on DP port or MHL port. +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "../../Hw/HwBlock/CBiosDIU_HDMI.h" +#include "../../Hw/HwBlock/CBiosDIU_HDAC.h" +#include "../../Hw/HwBlock/CBiosDIU_HDCP.h" +#include "../../Hw/CBiosHwShare.h" + + static CBIOS_U8 cbHDMIMonitor_HDACGetCAValue(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_ACTIVE_TYPE DeviceType) + { + CBIOS_U8 CA_Value = 0; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, DeviceType); + PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttrib = &(pDevCommon->EdidStruct.Attribute); + + //pMonitorAttrib->SpeakerAllocationData + // bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 + //------------------------------------------------- + // | FLR | LFE | FC | RLR | RC | FLRC| RLRC + + if(pMonitorAttrib->IsCEA861Monitor) + { + // refer to CEA-861D table 20 + if(pMonitorAttrib->SpeakerAllocationData & 0x02) // Lower Frequency Effect + CA_Value |= BIT0; + + if(pMonitorAttrib->SpeakerAllocationData & 0x04) // Front Center + CA_Value |= BIT1; + + if((pMonitorAttrib->SpeakerAllocationData & 0x60) == 0) + { + if(pMonitorAttrib->SpeakerAllocationData & 0x10) // Rear Center + CA_Value |= BIT2; + + if(pMonitorAttrib->SpeakerAllocationData & 0x08) // Rear Left/Rear Right + CA_Value |= BIT3; + } + + if((pMonitorAttrib->SpeakerAllocationData & 0x40) && (pMonitorAttrib->SpeakerAllocationData & 0x08)) + CA_Value |= BIT4; + + if(pMonitorAttrib->SpeakerAllocationData & 0x20) // Front Left Center/Front Right Center + { + CA_Value |= BIT4; + if(pMonitorAttrib->SpeakerAllocationData & 0x10) + CA_Value |= BIT3; + + if(pMonitorAttrib->SpeakerAllocationData & 0x08) + CA_Value |= (BIT2 | BIT3); + } + } + + return CA_Value; + } + +static CBIOS_VOID cbHDMIMonitor_GenerateAVIInfoFrameData(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams, PCBIOS_AVI_INFO_FRAME_DATA pAVIInfoFrameData) +{ + CBIOS_U8 VICCode = pModeParams->VICCode; + PCBIOS_HDMI_FORMAT_MTX pCurrentFormat = CBIOS_NULL; + CBIOS_BOOL bIsCEAMode = CBIOS_FALSE; + + cb_memset(pAVIInfoFrameData, 0, sizeof(CBIOS_AVI_INFO_FRAME_DATA)); + + if ((VICCode > 0) && (VICCode <= CBIOS_HDMIFORMATCOUNTS)) + { + bIsCEAMode = CBIOS_TRUE; + pCurrentFormat = &(pcbe->pHDMIFormatTable[VICCode - 1]); + } + else + { + bIsCEAMode = CBIOS_FALSE; + } + + + //See CEA-861-F Table 9 + // S1 S0 | Scan Information + // ----------------------------- + // 0 0 | No Data + // 0 1 | Overscan + // 1 0 | Underscan + // 1 1 | Reserved + pAVIInfoFrameData->ScanInfo = 2; //hardcode to underscan + + + // B1 B0 | Bar Info + // --------------------------------- + // 0 0 | Bar data not valid + // 0 1 | Vert. Bar info valid + // 1 0 | Hor. Bar Info valid + // 1 1 | V & H Bar Info valid + pAVIInfoFrameData->BarInfo = 0; //Bar data not valid + + + //aspect ratio related + + // M1 M0 | Picture Aspect Ratio + // --------------------------------- + // 0 0 | No Data + // 0 1 | 4:3 + // 1 0 | 16:9 + // 1 1 | Reserved + if ((bIsCEAMode) && (pCurrentFormat->AspectRatio >= 0) && (pCurrentFormat->AspectRatio <= 2)) + { + pAVIInfoFrameData->PictureAspectRatio = pCurrentFormat->AspectRatio; + } + else + { + pAVIInfoFrameData->PictureAspectRatio = 0; + } + + // A0 | Active Format Info Present + //------------------------------------ + // 0 | No Data + // 1 | R0...R3 valid + pAVIInfoFrameData->ActFormatInfoPreset = 0; //active format info not valid + + //Effective only when ActFormatInfoPreset = 1 + // R3 R2 R1 R0 | Active Format Aspect Ratio + //------------------------------------------------- + // 1 0 0 0 | Same as picture aspect ratio + // 1 0 0 1 | 4:3 (Center) + // 1 0 1 0 | 16:9 (Center) + // 1 0 1 1 | 14:9 (Center) + // Other Values | Per DVB AFD active_format + // | field in ETSI + pAVIInfoFrameData->ActFormatAspectRatio = 0x08; //Same as picture aspect ratio + + + //Color format related + + // Y2 Y1 Y0 | RGB or YCbCr + // -------------------------- + // 0 0 0 | RGB + // 0 0 1 | YCbCr 4:2:2 + // 0 1 0 | YCbCr 4:4:4 + // 0 1 1 | YCbCr 4:2:0 + // 1 0 0 | Reserved + // 1 0 1 | Reserved + // 1 1 0 | Reserved + // 1 1 1 | IDO-Defined + if (pModeParams->TargetModePara.OutputSignal == CBIOS_YCBCR422OUTPUT) + { + pAVIInfoFrameData->ColorFormat = 1; + } + else if (pModeParams->TargetModePara.OutputSignal == CBIOS_YCBCR444OUTPUT) + { + pAVIInfoFrameData->ColorFormat = 2; + } + else if (pModeParams->TargetModePara.OutputSignal == CBIOS_YCBCR420OUTPUT) + { + pAVIInfoFrameData->ColorFormat = 3; + } + else + { + pAVIInfoFrameData->ColorFormat = 0;//set to RGB by default + } + + // C1 C0 | Colorimetry + //----------------------------------- + // 0 0 | No Data + // 0 1 | ITU-601 + // 1 0 | ITU-709 + // 1 1 | Ext colorimetry valid + // | See EC2...EC0 + + // EC2 EC1 EC0 | Extended Colorimetry + //------------------------------------------- + // 0 0 0 | xvYCC601 + // 0 0 1 | xvYCC709 + // 0 1 0 | sYCC601 + // 0 1 1 | AdobeYCC601 + // 1 0 0 | AdobeRGB + // 1 0 1 | ITU-R BT.2020 Y'cC'bcC'rc + // 1 1 0 | ITU-R BT.2020 R'G'B' or Y'C'bC'r + // 1 1 1 | Reserved + + if(bIsCEAMode && VICCode > 1) + { + if((pAVIInfoFrameData->ColorFormat == 0))//RGB + { + if((pModeParams->IsAdobe) && pModeParams->ColorimetryCaps.IsSupportAdobeRGB) + { + pAVIInfoFrameData->Colorimetry = 0x03; //use extended colorimetry + pAVIInfoFrameData->ExtendedColorimetry = 0x04; //AdobeRGB + } + else if((pModeParams->IsBT2020) && pModeParams->ColorimetryCaps.IsSupportBT2020RGB) + { + pAVIInfoFrameData->Colorimetry = 0x03; //use extended colorimetry + pAVIInfoFrameData->ExtendedColorimetry = 0x06; //BT2020RGB + } + else + { + pAVIInfoFrameData->Colorimetry = 0; + pAVIInfoFrameData->ExtendedColorimetry = 0; + } + } + else if(((pAVIInfoFrameData->ColorFormat == 1) || //YCbCr422 + (pAVIInfoFrameData->ColorFormat == 2) || //YCbCr444 + (pAVIInfoFrameData->ColorFormat == 3))) //YCbCr420 + { + if(pModeParams->IsxvYCC) + { + if(pCurrentFormat->YRes < 720 && pModeParams->ColorimetryCaps.IsSupportxvYCC601) //SDTV, use BT601 + { + pAVIInfoFrameData->Colorimetry = 0x03; + pAVIInfoFrameData->ExtendedColorimetry = 0x00; //xvYCC601 + } + else if(pCurrentFormat->YRes >= 720 && pModeParams->ColorimetryCaps.IsSupportxvYCC709) + { + pAVIInfoFrameData->Colorimetry = 0x03; + pAVIInfoFrameData->ExtendedColorimetry = 0x01; //xvYCC709 + } + else + { + pAVIInfoFrameData->Colorimetry = 0; + pAVIInfoFrameData->ExtendedColorimetry = 0; + } + } + else if(pModeParams->IsAdobe) + { + if(pModeParams->ColorimetryCaps.IsSupportAdobeYCC601) + { + pAVIInfoFrameData->Colorimetry = 0x03; + pAVIInfoFrameData->ExtendedColorimetry = 0x03; //AdobeYCC601 + } + else + { + pAVIInfoFrameData->Colorimetry = 0; + pAVIInfoFrameData->ExtendedColorimetry = 0; + } + } + else if((pModeParams->IsBT2020) && pModeParams->ColorimetryCaps.IsSupportBT2020YCC) + { + pAVIInfoFrameData->Colorimetry = 0x03; + pAVIInfoFrameData->ExtendedColorimetry = 0x06; //BT2020Y'C'bC'r + } + else + { + pAVIInfoFrameData->Colorimetry = 0; + pAVIInfoFrameData->ExtendedColorimetry = 0; + } + } + else + { + pAVIInfoFrameData->Colorimetry = 0; + pAVIInfoFrameData->ExtendedColorimetry = 0; + } + + pAVIInfoFrameData->RGBQuantRange = 1; //RGB range is limited during CEA mode + } + else + { + //Colorimetry = 0: use default Colorimetry + //720 and above: BT709 + //576 and below: BT601 + pAVIInfoFrameData->Colorimetry = 0; + pAVIInfoFrameData->ExtendedColorimetry = 0; + + //Quant range + // Q1 Q0 | RGB Quant Range + //------------------------------ + // 0 0 | Default + // 0 1 | Limited range + // 1 0 | Full Range + // 1 1 | Reserved + pAVIInfoFrameData->RGBQuantRange = 0; //depends on video format + } + + //If a Sink declares a selectable RGB Quantization Range (QS=1) in EDID VCDB + //It shall expect Limited Range values if it receives Q=1 and it shall expect Full Range values if it receives Q=2 + //Here,we set Q=2 to send Full Range pixel values + if(pModeParams->VideoCapability.bRGBQuantRange) + { + pAVIInfoFrameData->RGBQuantRange = 2; + } + + //hardcode here + // SC1 SC0 | Non-Uniform Picture Scaling + //------------------------------------------ + // 0 0 | No known non-uniform scaling + // 0 1 | Scaled horizontally + // 1 0 | Scaled vertically + // 1 1 | Scaled both H & V + pAVIInfoFrameData->NonUniformScaling = 0; + + + // ITC | IT Content + //-------------------- + // 0 | No Data + // 1 | IT Content + pAVIInfoFrameData->ITContent = 1; + + // ITC | CN1 CN0 | Content Type + //------------------------------------- + // 0 | 0 0 | No Data + // 1 | 0 0 | Graphics + // X | 0 1 | Photo + // X | 1 0 | Cinema + // X | 1 1 | Game + //"X" denotes don't care. + pAVIInfoFrameData->ContentType = 0; //set to graphics by default + + + //VIC + if ((VICCode > 0) && (VICCode <= CBIOS_HDMI_NORMAL_VIC_COUNTS)) + { + pAVIInfoFrameData->VICCode = VICCode; + } + else if(pModeParams->IsEnable3DVideo)//extended formats and 3D video, the source shall set AVI infoframe VIC with the corresponding "Equivalent CEA-861-F VIC" + { + if((VICCode - CBIOS_HDMI_NORMAL_VIC_COUNTS) == 1) + { + pAVIInfoFrameData->VICCode = 95; + } + else if((VICCode - CBIOS_HDMI_NORMAL_VIC_COUNTS) == 2) + { + pAVIInfoFrameData->VICCode = 94; + } + else if((VICCode - CBIOS_HDMI_NORMAL_VIC_COUNTS) == 3) + { + pAVIInfoFrameData->VICCode = 93; + } + else if((VICCode - CBIOS_HDMI_NORMAL_VIC_COUNTS) == 4) + { + pAVIInfoFrameData->VICCode = 98; + } + } + else//none-CEA mode or extended formats, set VIC to 0 here, extended VIC will be programmed in VSIF + { + pAVIInfoFrameData->VICCode = 0; + } + + //pixel repetition factor + //now we only support repeat once + // PR3 PR2 PR1 PR0 | Pixel Repeat Factor + //------------------------------------------ + // 0 0 0 0 | No Repetition + // Other values | Repeat times + if (bIsCEAMode) + { + pAVIInfoFrameData->PixelRepeatFactor = pModeParams->PixelRepitition - 1; + } + else + { + pAVIInfoFrameData->PixelRepeatFactor = 0;//no repeat + } + + + // YQ1 YQ0 | YCbCr Quant Range + //---------------------------------- + // 0 0 | Limited Range + // 0 1 | Full Range + // Other | Reserved + pAVIInfoFrameData->YCCQuantRange = 0; +} + +//Test only +CBIOS_U8 GBDRangeData[6] = +{ + 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF +}; + +static CBIOS_VOID cbHDMIMonitor_GenerateInfoFrameData(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext, + PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_HDMI_INFO_FRAME_DATA pInfoFrameData = &pHDMIMonitorContext->HDMIInfoFrame; + CBIOS_U32 HBlank = 0, HDMIMaxPacketNum = 2; + + //fill AVI infoframe data bytes + cbHDMIMonitor_GenerateAVIInfoFrameData(pcbe, pModeParams, &pInfoFrameData->AVIInfoFrameData); + + //fill HF-VSIF when enable 3D OSD Disparity, Dual View or Independent View + if(pModeParams->IsEnable3DOSDDisparity || pModeParams->IsEnable3DDualView || pModeParams->IsEnable3DIndependentView) + { + pInfoFrameData->HFVSIFPara.Valid3D = CBIOS_TRUE; + pInfoFrameData->HFVSIFPara.Video3DFStruct = pModeParams->Video3DStruct; + if(pModeParams->IsEnable3DOSDDisparity) + { + pInfoFrameData->HFVSIFPara.IsEnable3DOSDDisparity = CBIOS_TRUE; + cb_memcpy(&pInfoFrameData->HFVSIFPara.DisparityPara, &pModeParams->Video3DDisparity, sizeof(pModeParams->Video3DDisparity)); + } + + if(pModeParams->IsEnable3DDualView) + { + pInfoFrameData->HFVSIFPara.IsEnable3DDualView = CBIOS_TRUE; + } + + if(pModeParams->IsEnable3DIndependentView) + { + pInfoFrameData->HFVSIFPara.IsEnable3DIndependentView = CBIOS_TRUE; + pInfoFrameData->HFVSIFPara.IndependentViewPara.Dependency = pModeParams->Viedo3DIndependentCaps.Dependency; + pInfoFrameData->HFVSIFPara.IndependentViewPara.Preferred2D = pModeParams->Viedo3DIndependentCaps.Preferred2D; + } + } + else if ((pModeParams->IsEnable3DVideo) ||(pModeParams->VICCode > CBIOS_HDMI_NORMAL_VIC_COUNTS)) + { + //fill VSIF data when enable 3D video or for extended VICs + if (pModeParams->IsEnable3DVideo) + { + pInfoFrameData->VSIFPara.VSIFVideoFormat = VSIF_3D_FORMAT_INDICATION_PRESENT; + pInfoFrameData->VSIFPara.VSIF3DFormatPara.Video3DStruct = pModeParams->Video3DStruct; + } + else if (pModeParams->VICCode > CBIOS_HDMI_NORMAL_VIC_COUNTS) + { + pInfoFrameData->VSIFPara.VSIFVideoFormat = VSIF_EXTENDED_FORMAT_PRESENT; + pInfoFrameData->VSIFPara.VSIFExtFormatPara.VICCode = pModeParams->VICCode - CBIOS_HDMI_NORMAL_VIC_COUNTS; + } + } + else + { + pInfoFrameData->VSIFPara.VSIFVideoFormat = VSIF_NO_ADDITIONAL_PRESENT; + } + + //xvYCC + if (pModeParams->IsxvYCC) + { + //hardcode here, for test only + pInfoFrameData->GamutMetadata.FormatFlag = RANGE_GBD_STRUCT; + pInfoFrameData->GamutMetadata.GBDColorPrecision = 8; + + if (pModeParams->TargetModePara.YRes >= 720) + { + pInfoFrameData->GamutMetadata.GBDData.RangeGBD.ColorSpace = GBD_RANGE_COLOR_SPACE_XVYCC_709; + } + else + { + pInfoFrameData->GamutMetadata.GBDData.RangeGBD.ColorSpace = GBD_RANGE_COLOR_SPACE_XVYCC_601; + } + pInfoFrameData->GamutMetadata.GBDData.RangeGBD.pRangeData = GBDRangeData; + pInfoFrameData->GamutMetadata.GBDData.RangeGBD.RangeDataSize = sizeof(GBDRangeData); + } + + // Calculate MAX packets in H balnk + HBlank = pModeParams->TargetTiming.HorBEnd - pModeParams->TargetTiming.HorBStart; + HBlank *= pModeParams->PixelRepitition; + + HDMIMaxPacketNum = (HBlank - HDMI_DELAY_FOR_HDCP - HDMI_LEADING_GUARD_BAND_PERIOD - + HDMI_MIN_CTL_PERIOD - HDMI_TRAILING_GUARD_BAND_PERIOD) / 32; + pInfoFrameData->HDMIMaxPacketNum = cb_min(HDMIMaxPacketNum, 15); + + cbDebugPrint((MAKE_LEVEL(HDMI, INFO), "VICCode=%d.\n", pModeParams->VICCode)); + if ((pModeParams->VICCode > 0) && (pModeParams->VICCode <= CBIOS_HDMIFORMATCOUNTS)) + { + pInfoFrameData->bIsCEAMode = CBIOS_TRUE; + } + else + { + pInfoFrameData->bIsCEAMode = CBIOS_FALSE; + } + +} + + +static CBIOS_VOID cbHDMIMonitor_SetAVIInfoFrame(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_AVI_INFO_FRAME_DATA pAVIInfoFrameData, CBIOS_ACTIVE_TYPE DeviceType, PCBIOS_U8 FIFOIndex) +{ + CBIOS_U8 ucAVIData[32], i = 0, checksum = 0; + CBIOS_U32 DataLen = 0; + CBIOS_U32 Version = 0x2; + + cb_memset(ucAVIData, 0, 32); + + /* + According to CEA-861-F 6.4 + A version 3 AVI InfoFrame is only used when either of the most-significant bits Y2 or VIC7 are set to '1' + + Note for HDMI Specification Version 2.0: + it is always the case that Y2=0 (see previous bullet). + Also, no VIC codes above 107 have been defined in CEA-861-F (thus VIC7=0). + Therefore, the "version 3" AVI InfoFrame is not applicable for Source Devices + built according to This Specification, and Source Devices + shall always transmit a "version 2" AVI InfoFrame. + */ + if((pAVIInfoFrameData->ColorFormat > 3) || (pAVIInfoFrameData->VICCode > 127)) + { + Version = 0x3; // Version = 0x03 + } + else + { + Version = 0x2; // Version = 0x02 + } + + ucAVIData[0] = 0x82; // Packet Type = 0x82 + ucAVIData[1] = (CBIOS_U8)Version; + ucAVIData[2] = 0x0D; // Length = 0x0D + + DataLen = cb_min(CBIOS_AVI_INFO_FRAME_LEN, sizeof(CBIOS_AVI_INFO_FRAME_DATA)); + cb_memcpy(&ucAVIData[4], pAVIInfoFrameData, DataLen); + + // count check sum + for(i = 0; i < 32; i++) + { + checksum += ucAVIData[i]; + } + + ucAVIData[3] = 0x100 - checksum; + + cbDIU_HDMI_WriteFIFO(pcbe, DeviceType, *FIFOIndex, ucAVIData, 32); + (*FIFOIndex)++; +} + +static CBIOS_VOID cbHDMIMonitor_SetAudioInfoFrame(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_ACTIVE_TYPE DeviceType, PCBIOS_U8 FIFOIndex) +{ + CBIOS_MODULE_INDEX HDACModuleIndex = CBIOS_MODULE_INDEX_INVALID; + CBIOS_U8 ucAAIData[32], i = 0, checksum = 0; + CBIOS_U32 NumofChannels = 0; + + cb_memset(ucAAIData, 0, 32); + + HDACModuleIndex = cbGetModuleIndex(pcbe, DeviceType, CBIOS_MODULE_TYPE_HDAC); + if (HDACModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDAC module index!\n", FUNCTION_NAME)); + return; + } + + NumofChannels = cbDIU_HDAC_GetChannelNums(pcbe, HDACModuleIndex); + + ucAAIData[0] = 0x84; // Packet Type = 0x84 + ucAAIData[1] = 0x01; // Version number = 0x01 + ucAAIData[2] = 0x0A; // Length = 0x0A + + // CC2 CC1 CC0 | Audio Channel Count + // --------------------------------------- + // 0 0 0 | Refer to Stream Header + // 0 0 1 | 2ch + // 0 1 0 | 3ch + // 0 1 1 | 4ch + // 1 0 0 | 5ch + // 1 0 1 | 6ch + // 1 1 0 | 7ch + // 1 1 1 | 8ch + ucAAIData[4] |= NumofChannels; + + // CT3 CT2 CT1 CT0 | Audio Coding Type + // ------------------------------------------- + // 0 0 0 0 | Refer to Stream Header + // 0 0 0 1 | IEC 60958 PCM[30,31] + // 0 0 1 0 | AC-3 + // 0 0 1 1 | MPEG1 (Layer 1 & 2) + ucAAIData[4] |= 0x00; + + // SS1 SS0 | Sample Size + // -------------------------- + // 0 0 | Refer to Stream Header + // 0 1 | 16 bit + // 1 0 | 20 bit + // 1 1 | 24 bit + ucAAIData[5] |= 0x00; + + // SF2 SF1 SF0 | Sampling Frequency + // --------------------------------------- + // 0 0 0 | Refer to Stream Header + // 0 0 1 | 32 kHz + // 0 1 0 | 44.1 kHz(CD) + // 0 1 1 | 48 kHz + // 1 0 0 | 88.2 kHz + // 1 0 1 | 96 kHz + // 1 1 0 | 176.4 kHz + // 1 1 1 | 192 kHz + ucAAIData[5] |= 0x00; + + ucAAIData[6] = 0x00; + + // CA + if(NumofChannels == 1) + { + ucAAIData[7] = 0; + } + else + { + ucAAIData[7] = cbHDMIMonitor_HDACGetCAValue(pcbe, DeviceType); + } + ucAAIData[8] = 0x00; + + //all others are 0 + + // count check sum + for(i = 0; i < 32; i++) + checksum += ucAAIData[i]; + + ucAAIData[3] = 0x100 - checksum; + + cbDIU_HDMI_WriteFIFO(pcbe, DeviceType, *FIFOIndex, ucAAIData, 32); + (*FIFOIndex)++; + +} + +static CBIOS_VOID cbHDMIMonitor_SetHFVendorSpecificInfoFrame(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_ACTIVE_TYPE DeviceType, PCBIOS_HF_VENDOR_SPECIFIC_INFOFRAME_PARA pHFVSIFPara, +PCBIOS_U8 FIFOIndex) +{ + CBIOS_U8 VSInfoFrame[32]; + CBIOS_U32 i = 0; + CBIOS_U32 Length = 0; + CBIOS_U8 Checksum = 0; + CBIOS_U8 *pHFVSIFPayLoad = CBIOS_NULL; + + cb_memset(VSInfoFrame, 0, sizeof(VSInfoFrame)); + + //Packet Header + + //Packet Type + VSInfoFrame[0] = 0x81; + + //Version + VSInfoFrame[1] = 0x01; + + //Length should be programed later + + //Checksum will be programmed later + + //Packet content begin + Length = 0; + pHFVSIFPayLoad = &(VSInfoFrame[4]); + + //24bit IEEE Registration identifier + *(pHFVSIFPayLoad++) = 0xD8; + *(pHFVSIFPayLoad++) = 0x5D; + *(pHFVSIFPayLoad++) = 0xC4; + Length += 3; + + //Version + *(pHFVSIFPayLoad++) = 0x1; + Length++; + + //3D_Valid + *(pHFVSIFPayLoad++) = pHFVSIFPara->Valid3D; + Length++; + + if(pHFVSIFPara->Valid3D) + { + CBIOS_U8 Data = 0; + + //3D_F_STRUCTURE + Data |= (pHFVSIFPara->Video3DFStruct & 0xF) << 4; + + if(pHFVSIFPara->IsEnable3DDualView || pHFVSIFPara->IsEnable3DIndependentView) + { + //3D AddtionalInfo_Present + Data |= (1 << 3); + } + + if(pHFVSIFPara->IsEnable3DOSDDisparity && (pHFVSIFPara->DisparityPara.DisparityLength > 0)) + { + //3D_DisparityData_Present + Data |= (1 << 2); + } + + //Assume 3D_Meta_present = 0 + Data |= (0 << 1); + + *(pHFVSIFPayLoad++) = Data; + Length++; + + //3D_F_Ext_Data + if (pHFVSIFPara->Video3DFStruct == 8) + { + *(pHFVSIFPayLoad++) = (0x00 << 4) & 0xF0; + Length++; + } + else if (pHFVSIFPara->Video3DFStruct > 8) + { + //now hardcode here first, it should be read from VSDB + *(pHFVSIFPayLoad++) = (0x04 << 4) & 0xF0; + Length++; + } + + if(pHFVSIFPara->IsEnable3DDualView || pHFVSIFPara->IsEnable3DIndependentView) + { + Data = 0; + + //3D Dual_View + if(pHFVSIFPara->IsEnable3DDualView) + { + Data |= (1 << 4); + } + + //Independent View + if(pHFVSIFPara->IsEnable3DIndependentView) + { + Data |= ((pHFVSIFPara->IndependentViewPara.Dependency & 0x3) << 2); + Data |= (pHFVSIFPara->IndependentViewPara.Preferred2D & 0x3); + } + + *(pHFVSIFPayLoad++) = Data; + Length++; + } + + if(pHFVSIFPara->IsEnable3DOSDDisparity && (pHFVSIFPara->DisparityPara.DisparityLength > 0)) + { + Data = 0; + + //3D_DisparityData_Version + Data |= ((pHFVSIFPara->DisparityPara.Version & 0x7) << 5); + Data |= ((pHFVSIFPara->DisparityPara.DisparityLength & 0x1F) << 5); + *(pHFVSIFPayLoad++) = Data; + Length++; + + //Disparity Data + cb_memcpy(pHFVSIFPayLoad, &pHFVSIFPara->DisparityPara.DisplarityData[0], pHFVSIFPara->DisparityPara.DisparityLength); + Length += pHFVSIFPara->DisparityPara.DisparityLength; + pHFVSIFPayLoad += pHFVSIFPara->DisparityPara.DisparityLength; + } + } + + //Length + VSInfoFrame[2] = Length & 0x1F; + + //Checksum + for (i = 0; i < 32; i++) + { + Checksum += VSInfoFrame[i]; + } + VSInfoFrame[3] = 0xFF - Checksum + 1; + + cbDIU_HDMI_WriteFIFO(pcbe, DeviceType, *FIFOIndex, VSInfoFrame, 32); + (*FIFOIndex)++; +} + +static CBIOS_VOID cbHDMIMonitor_SetVendorSpecificInfoFrame(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_ACTIVE_TYPE DeviceType, PCBIOS_VENDOR_SPECIFIC_INFOFRAME_PARA pVSIFPara, +PCBIOS_U8 FIFOIndex) +{ + CBIOS_U8 VSInfoFrame[32]; + CBIOS_U32 i = 0; + CBIOS_U32 Length = 0; + CBIOS_U8 Checksum = 0; + CBIOS_U8 *pVSIFPayLoad = CBIOS_NULL; + + cb_memset(VSInfoFrame, 0, sizeof(VSInfoFrame)); + + //Packet Header + + //Packet Type + VSInfoFrame[0] = 0x81; + + //Version + VSInfoFrame[1] = 0x01; + + //Length should be programed later + + //Checksum will be programmed later + + //Packet content begin + Length = 0; + pVSIFPayLoad = &(VSInfoFrame[4]); + + //24bit IEEE Registration identifier + *(pVSIFPayLoad++) = 0x03; + *(pVSIFPayLoad++) = 0x0C; + *(pVSIFPayLoad++) = 0x00; + Length += 3; + + // PB4[7-5] | HDMI_Video_Format + //---------------------------------------------------- + // 0 0 0 | No Additional info + // 0 0 1 | Extended resolution format present + // 0 1 0 | 3D format indication present + *(pVSIFPayLoad++) = (pVSIFPara->VSIFVideoFormat << 5) & 0xE0; + Length++; + + if (pVSIFPara->VSIFVideoFormat == VSIF_3D_FORMAT_INDICATION_PRESENT) + { + + //3D structure, 3D_Meta_present + //Assume 3D_Meta_present = 0 + *(pVSIFPayLoad++) = (pVSIFPara->VSIF3DFormatPara.Video3DStruct << 4) & 0xF0; + Length++; + + if (pVSIFPara->VSIF3DFormatPara.Video3DStruct == 8) + { + *(pVSIFPayLoad++) = (0x00 << 4) & 0xF0; + Length++; + } + else if (pVSIFPara->VSIF3DFormatPara.Video3DStruct > 8) + { + //now hardcode here first, it should be read from VSDB + *(pVSIFPayLoad++) = (0x04 << 4) & 0xF0; + Length++; + } + + //3D_Metadata + //TBD + } + else if (pVSIFPara->VSIFVideoFormat == VSIF_EXTENDED_FORMAT_PRESENT) + { + //VIC + *(pVSIFPayLoad++) = pVSIFPara->VSIFExtFormatPara.VICCode; + Length++; + } + else + { + //HDMI_Video_Format: no additional info + } + + //Length + VSInfoFrame[2] = Length & 0x1F; + + //Checksum + for (i = 0; i < 32; i++) + { + Checksum += VSInfoFrame[i]; + } + VSInfoFrame[3] = 0xFF - Checksum + 1; + + cbDIU_HDMI_WriteFIFO(pcbe, DeviceType, *FIFOIndex, VSInfoFrame, 32); + (*FIFOIndex)++; +} + + +static CBIOS_VOID cbHDMIMonitor_SetGamutMetadataPacket(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_ACTIVE_TYPE DeviceType, PCBIOS_GAMUT_METADATA_PARA pGamutMetadata, PCBIOS_U8 FIFOIndex) +{ + CBIOS_U8 GamutMetadataPacket[32]; + CBIOS_U8 ColorPrecision = 0; + + cb_memset(GamutMetadataPacket, 0, sizeof(GamutMetadataPacket)); + + //get ColorPrecision + if (pGamutMetadata->GBDColorPrecision == 10) + { + ColorPrecision = 0x01; + } + else if (pGamutMetadata->GBDColorPrecision == 12) + { + ColorPrecision = 0x02; + } + else//set to 8 bit by default + { + ColorPrecision = 0x00; + } + + //haeder byte 0, packet type + GamutMetadataPacket[0] = 0x0A; + + //haeder byte 1 + //Next_Field, GBD_Profile, Affected_Gamut_Seq_Num + //now hardcode here + GamutMetadataPacket[1] = 0x80; + + //haeder byte 2 + //No_Crnt_GBD, Packet_Seq, Current_Gamut_Seq_Num + //now hardcode here + GamutMetadataPacket[2] = 0x30; + + //Packet body. P0 only now + if (pGamutMetadata->FormatFlag == VERTICES_FACETS_GBD_STRUCT) + { + PCBIOS_VERTICES_GBD_PARA pGBDPara = &(pGamutMetadata->GBDData.VerticesGBD); + CBIOS_U32 VerticesSize = 0; + + //byte 0 + GamutMetadataPacket[3] = ((pGBDPara->ColorSpace & 0x07) + | ((ColorPrecision << 3) & 0x18) + | ((pGamutMetadata->FormatFlag << 7) & 0x80)); + + //byte 1, Number_Vertices_H + GamutMetadataPacket[4] = (CBIOS_U8)((pGBDPara->VerticesNum >> 8) & 0xff); + + //byte 2, Number_Vertices_L + GamutMetadataPacket[5] = (CBIOS_U8)(pGBDPara->VerticesNum & 0xff); + + //byte 3 ... VSIZE+2: Packed_GBD_Vertices_Data[0...VSIZE-1] + VerticesSize = cbRound(3 * pGBDPara->VerticesNum * pGamutMetadata->GBDColorPrecision, 8, ROUND_UP); + VerticesSize = cb_min(VerticesSize, pGBDPara->VerticesDataSize); + cb_memcpy(&(GamutMetadataPacket[6]), pGBDPara->pVerticesData, VerticesSize); + + if (pGBDPara->bFacetMode) + { + //byte VSIZE+5 ... VSIZE+FSIZE+4, Packed_GBD_Facets_Data[0...FSIZE - 1] + //not defined yet + } + + } + else if (pGamutMetadata->FormatFlag == RANGE_GBD_STRUCT) + { + PCBIOS_RANGE_GBD_PARA pGBDPara = &(pGamutMetadata->GBDData.RangeGBD); + CBIOS_U32 DataSize = 0; + + //byte 0 + GamutMetadataPacket[3] = ((pGBDPara->ColorSpace & 0x07) + | ((ColorPrecision << 3) & 0x18) + | ((pGamutMetadata->FormatFlag << 7) & 0x80)); + + //byte 1...N, Packed_Range_Data + DataSize = cbRound(pGamutMetadata->GBDColorPrecision * 3 * 2, 8, ROUND_UP); + DataSize = cb_min(DataSize, pGBDPara->RangeDataSize); + cb_memcpy(&(GamutMetadataPacket[4]), pGBDPara->pRangeData, DataSize); + } + + cbDIU_HDMI_WriteFIFO(pcbe, DeviceType, *FIFOIndex, GamutMetadataPacket, 32); + (*FIFOIndex)++; +} + +#if 0 +static CBIOS_BOOL cbHDMIMonitor_HDCP_ReadData(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U8* Buffer, CBIOS_U8 Offset, CBIOS_U32 Num) +{ + CBIOS_PARAM_I2C_DATA I2CParams; + CBIOS_U8 I2CBUSNum = (CBIOS_U8)pDevCommon->I2CBus; + CBIOS_BOOL bRet = CBIOS_FALSE; + + cb_memset(&I2CParams, 0, sizeof(CBIOS_PARAM_I2C_DATA)); + + cb_AcquireMutex(pcbe->pI2CMutex[I2CBUSNum]); + + I2CParams.RequestType = 0xFF; + I2CParams.PortNumber = I2CBUSNum; + I2CParams.SlaveAddress = 0x74; + I2CParams.Buffer = Buffer; + I2CParams.BufferLen = Num; + I2CParams.OffSet = Offset; + I2CParams.bHDCPEnable = 1; + + bRet = cbHWI2CDataRead(pcbe, &I2CParams); + + cb_ReleaseMutex(pcbe->pI2CMutex[I2CBUSNum]); + + if(bRet != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: HDCP read failed!\n", FUNCTION_NAME)); + + return CBIOS_FALSE; + } + + return CBIOS_TRUE; +} + +static CBIOS_BOOL cbHDMIMonitor_HDCP_ReadBKsv(CBIOS_VOID* pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_U8 pBksv, PCBIOS_BOOL bRepeater) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bRet = CBIOS_TRUE; + CBIOS_U8 BCaps = 0; + + bRet = cbHDMIMonitor_HDCP_ReadData(pcbe, pDevCommon, pBksv, 0, 5); + if(!bRet) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: Read BKsv failed!\n", FUNCTION_NAME)); + + return bRet; + } + + bRet = cbHDMIMonitor_HDCP_ReadData(pcbe, pDevCommon, &BCaps, 0x40, 1); + + if(!bRet) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: Read BCaps failed!\n", FUNCTION_NAME)); + } + else + { + *bRepeater = BCaps & 0x40; + } + + return bRet; +} +#endif + +static CBIOS_BOOL cbHDMIMonitor_SCDC_ReadData(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U8* Buffer, CBIOS_U8 Offset, CBIOS_U32 Num) +{ + CBIOS_PARAM_I2C_DATA I2CParams; + CBIOS_U8 I2CBUSNum = (CBIOS_U8)pDevCommon->I2CBus; + CBIOS_BOOL bRet = CBIOS_FALSE; + + cb_memset(&I2CParams, 0, sizeof(CBIOS_PARAM_I2C_DATA)); + + cb_AcquireMutex(pcbe->pI2CMutex[I2CBUSNum]); + + I2CParams.RequestType = 0xFF; + I2CParams.PortNumber = I2CBUSNum; + I2CParams.SlaveAddress = 0xA8; + I2CParams.Buffer = Buffer; + I2CParams.BufferLen = Num; + I2CParams.OffSet = Offset; + I2CParams.bHDCPEnable = 1; + + bRet = cbHWI2CDataRead(pcbe, &I2CParams); + + cb_ReleaseMutex(pcbe->pI2CMutex[I2CBUSNum]); + + if(bRet != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: SCDC read failed!\n", FUNCTION_NAME)); + + return CBIOS_FALSE; + } + + return CBIOS_TRUE; +} + +static CBIOS_BOOL cbHDMIMonitor_SCDC_WriteData(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U8* Buffer, CBIOS_U8 Offset, CBIOS_U32 Num) +{ + CBIOS_PARAM_I2C_DATA I2CParams; + CBIOS_U8 I2CBUSNum = (CBIOS_U8)pDevCommon->I2CBus; + CBIOS_BOOL bRet = CBIOS_FALSE; + + cb_memset(&I2CParams, 0, sizeof(CBIOS_PARAM_I2C_DATA)); + + cb_AcquireMutex(pcbe->pI2CMutex[I2CBUSNum]); + + I2CParams.RequestType = 0xFF; + I2CParams.PortNumber = I2CBUSNum; + I2CParams.SlaveAddress = 0xA8; + I2CParams.Buffer = Buffer; + I2CParams.BufferLen = Num; + I2CParams.OffSet = Offset; + I2CParams.bHDCPEnable = 1; + + bRet = cbHWI2CDataWrite(pcbe, &I2CParams); + + cb_ReleaseMutex(pcbe->pI2CMutex[I2CBUSNum]); + + if(bRet != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: SCDC write failed!\n", FUNCTION_NAME)); + + return CBIOS_FALSE; + } + + return CBIOS_TRUE; +} + +static CBIOS_BOOL cbHDMIMonitor_SCDC_ReadUpdateFlags(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_SCDC_UPDATE_FLAGS pUpdateFlags) +{ + CBIOS_BOOL bRet = CBIOS_FALSE; + + pUpdateFlags->UpdateFlags = 0; + bRet = cbHDMIMonitor_SCDC_ReadData(pcbe, pDevCommon, (CBIOS_U8*)(&(pUpdateFlags->UpdateFlags)), 0x10, 0x2);//Offset = 0x10:Update_0, Offset = 0x11:Update_1 + + if(pUpdateFlags->UpdateFlags != 0) + { + //write 1 to clear corresponding bits + cbHDMIMonitor_SCDC_WriteData(pcbe, pDevCommon, (CBIOS_U8*)(&(pUpdateFlags->UpdateFlags)), 0x10, 0x2); + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG), "Clear SCDC corresponding Update Flags bits\n")); + } + + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG), "SCDC Update Flags: 0x%04X, Status_Update: %X, CED_Update: %X, RR_Test: %X!\n", + pUpdateFlags->UpdateFlags, pUpdateFlags->Update_0.StatusUpdate, pUpdateFlags->Update_0.CEDUpdate, pUpdateFlags->Update_0.RRTest)); + + return bRet; +} + +static CBIOS_BOOL cbHDMIMonitor_SCDC_ReadStatusFlags(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_SCDC_STATUS_FLAGS pStatusFlags) +{ + CBIOS_BOOL bRet = CBIOS_FALSE; + + pStatusFlags->Status_Flags = 0; + bRet = cbHDMIMonitor_SCDC_ReadData(pcbe, pDevCommon, &(pStatusFlags->ScramblerStatus), 0x21, 0x1);//Offset = 0x40:Status_0, Offset = 0x41:Status_1 + + if(!bRet) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: SCDC read data failed !\n", FUNCTION_NAME)); + + return CBIOS_FALSE; + } + + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG), "SCDC Scrambler Status: 0x%02X, Scrambling Status: %1X !\n", + pStatusFlags->ScramblerStatus, pStatusFlags->Scrambling_Status)); + + bRet = cbHDMIMonitor_SCDC_ReadData(pcbe, pDevCommon, (CBIOS_U8*)(&(pStatusFlags->Status_Flags)), 0x40, 0x2);//Offset = 0x40:Status_0, Offset = 0x41:Status_1 + + if(!bRet) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: SCDC read data failed !\n", FUNCTION_NAME)); + + return CBIOS_FALSE; + } + + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG), "SCDC Status Flags: 0x%04X, Clock_Detected: %X, Ch0_Locked: %X, Ch1_Locked: %X, Ch2_Locked: %X!\n", + pStatusFlags->Status_Flags, pStatusFlags->Status_Flags_0.ClockDetected, pStatusFlags->Status_Flags_0.Ch0_Locked, + pStatusFlags->Status_Flags_0.Ch1_Locked, pStatusFlags->Status_Flags_0.Ch2_Locked)); + + return bRet; +} + +static CBIOS_BOOL cbHDMIMonitor_SCDC_ReadCEDData(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_SCDC_CED_DATA pCEDData) +{ + CBIOS_BOOL bRet = CBIOS_FALSE; + + bRet = cbHDMIMonitor_SCDC_ReadData(pcbe, pDevCommon, (CBIOS_U8*)pCEDData, 0x50, 0x7);//Offset = 0x50:Character Error Detection start offset + + cbDebugPrint((MAKE_LEVEL(HDMI, INFO), "Ch0_Valid:%X, Ch0_ERR_Counter:%d, Ch1_Valid:%X, Ch1_ERR_Counter:%d, Ch2_Valid:%X, Ch2_ERR_Counter:%d !\n", + pCEDData->Ch0_Valid, (((pCEDData->Ch0_Err_CountBits14To8 << 8) | pCEDData->Ch0_Err_CountBits7To0) & 0x7FFF), + pCEDData->Ch1_Valid, (((pCEDData->Ch1_Err_CountBits14To8 << 8) | pCEDData->Ch1_Err_CountBits7To0) & 0x7FFF), + pCEDData->Ch2_Valid, (((pCEDData->Ch2_Err_CountBits14To8 << 8) | pCEDData->Ch2_Err_CountBits7To0) & 0x7FFF))); + + return bRet; +} + +CBIOS_BOOL cbHDMIMonitor_SCDC_Handler(CBIOS_VOID* pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_SCDC_UPDATE_FLAGS UpdateFlags; + CBIOS_BOOL bRet = CBIOS_FALSE; + + if(pDevCommon->EdidStruct.Attribute.HFVSDBData.IsSCDCPresent) + { + cb_memset(&UpdateFlags, 0, sizeof(UpdateFlags)); + bRet = cbHDMIMonitor_SCDC_ReadUpdateFlags(pcbe, pDevCommon, &UpdateFlags); + + if(UpdateFlags.Update_0.StatusUpdate) + { + CBIOS_SCDC_STATUS_FLAGS StatusFlags; + + cb_memset(&StatusFlags, 0, sizeof(StatusFlags)); + bRet = cbHDMIMonitor_SCDC_ReadStatusFlags(pcbe, pDevCommon, &StatusFlags); + } + + if(UpdateFlags.Update_0.CEDUpdate) + { + CBIOS_SCDC_CED_DATA CEDData; + + cb_memset(&CEDData, 0, sizeof(CEDData)); + bRet = cbHDMIMonitor_SCDC_ReadCEDData(pcbe, pDevCommon, &CEDData); + } + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "SCDC is not present!\n")); + } + + return bRet; +} + +static CBIOS_VOID cbHDMIMonitor_SCDC_Configure(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext) +{ + CBIOS_U8 Data = 0; + CBIOS_U8 ReadBackData = 0; + CBIOS_BOOL bRet = CBIOS_FALSE; + PCBIOS_DEVICE_COMMON pDevCommon = pHDMIMonitorContext->pDevCommon; + + //Offset = 0x1: Sink Version + bRet = cbHDMIMonitor_SCDC_ReadData(pcbe, pDevCommon, &Data, 0x1, 0x1); + + if(!bRet) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: SCDC read Sink Version failed!\n", FUNCTION_NAME)); + return; + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG), "Sink Version %X\n", Data)); + } + + Data = 1;// Version 1 + + //Offset = 0x2: Source Version + bRet = cbHDMIMonitor_SCDC_WriteData(pcbe, pDevCommon, &Data, 0x2, 0x1); + ReadBackData = 0; + bRet = cbHDMIMonitor_SCDC_ReadData(pcbe, pDevCommon, &ReadBackData, 0x2, 0x1); + + if(bRet && (Data == ReadBackData)) + { + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG), "SCDC write Source Version successfully!\n")); + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: SCDC write Source Version failed!\n", FUNCTION_NAME)); + } + + Data = 0; + if(pHDMIMonitorContext->ScramblingEnable) + { + Data |= (1 << 0); + } + if(pHDMIMonitorContext->TMDSBitClockRatio) + { + Data |= (1 << 1); + } + + //Offset = 0x20: SCDC TMDS_Config + cb_DelayMicroSeconds(20000);//add a delay here to wait sink status stable + bRet = cbHDMIMonitor_SCDC_WriteData(pcbe, pDevCommon, &Data, 0x20, 0x1); + //per HDMI2.0 spec, need wait 1-100ms before send TMDS signal + cb_DelayMicroSeconds(20000); + ReadBackData = 0; + bRet = cbHDMIMonitor_SCDC_ReadData(pcbe, pDevCommon, &ReadBackData, 0x20, 0x1); + + if(bRet && (Data == ReadBackData)) + { + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG), "SCDC write TMDS_Config successfully!\n")); + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: SCDC write TMDS_Config failed!\n", FUNCTION_NAME)); + } + + // We write SCDC config 0x30 here, VBIOS clear SCDC config 0x20 when reboot os, + //The ViewSonic VP2780 monitor will show ViewSonic logo. To fix bug 6231. +/* + Data = 0; + if(pHDMIMonitorContext->ReadRequestEnable) + { + Data |= (1 << 0); + } + + //Offset = 0x30: SCDC Config_0 + bRet = cbHDMIMonitor_SCDC_WriteData(pcbe, pDevCommon, &Data, 0x30, 0x1); + ReadBackData = 0; + bRet = cbHDMIMonitor_SCDC_ReadData(pcbe, pDevCommon, &ReadBackData, 0x30, 0x1); + + if(bRet && (Data == ReadBackData)) + { + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG), "SCDC write Config_0 successfully!\n")); + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: SCDC write Config_0 failed!\n", FUNCTION_NAME)); + } +*/ +} + + +CBIOS_VOID cbHDMIMonitor_SetInfoFrame(PCBIOS_VOID pvcbe, PCBIOS_HDMI_INFO_FRAME_DATA pInfoFrameData, CBIOS_ACTIVE_TYPE DeviceType) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 FIFOIndex = 0; + + // AVI InfoFrame + cbHDMIMonitor_SetAVIInfoFrame(pcbe, &(pInfoFrameData->AVIInfoFrameData), DeviceType, &FIFOIndex); + + // Audio InfoFrame + cbHDMIMonitor_SetAudioInfoFrame(pcbe, DeviceType, &FIFOIndex); + + /* + 3D OSD Disparity Indication + 3D Dual-View Signaling + 3d Independent View Signaling + */ + if(pInfoFrameData->HFVSIFPara.IsEnable3DOSDDisparity || pInfoFrameData->HFVSIFPara.IsEnable3DDualView || pInfoFrameData->HFVSIFPara.IsEnable3DIndependentView) + { + cbHDMIMonitor_SetHFVendorSpecificInfoFrame(pcbe, DeviceType, &(pInfoFrameData->HFVSIFPara), &FIFOIndex); + } + else + { + //if don't send HF-VSIF, always send VSIF + cbHDMIMonitor_SetVendorSpecificInfoFrame(pcbe, DeviceType, &(pInfoFrameData->VSIFPara), &FIFOIndex); + } + + //xvYCC + if (pInfoFrameData->GamutMetadata.FormatFlag) + { + cbHDMIMonitor_SetGamutMetadataPacket(pcbe, DeviceType, &(pInfoFrameData->GamutMetadata), &FIFOIndex); + } + + //Send + cbDIU_HDMI_SendInfoFrame(pcbe, pInfoFrameData->HDMIMaxPacketNum, DeviceType, FIFOIndex); +} + +CBIOS_BOOL cbHDMIMonitor_Detect(PCBIOS_VOID pvcbe, PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext, CBIOS_BOOL bHardcodeDetected, CBIOS_U32 FullDetect) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bConnected = CBIOS_FALSE; + CBIOS_BOOL IsDevChanged = CBIOS_FALSE; + PCBIOS_DEVICE_COMMON pDevCommon = pHDMIMonitorContext->pDevCommon; + PCBIOS_UCHAR pEDIDData = pDevCommon->EdidData; + PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttrib = &(pDevCommon->EdidStruct.Attribute); + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + CBIOS_MODULE_INDEX HDMIModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_HDMI); + CBIOS_SCDC_STATUS_FLAGS SCDCStatusFlags; + + /* + ** 1. get EDID data + */ + if (bHardcodeDetected) + { + // use hardcoded EDID data instead of reading from monitor side +#if IS_SUPPORT_4K_MODE + cb_memcpy(pDevCommon->EdidData, Fake4KEdid, sizeof(Fake4KEdid)); +#else + cb_memcpy(pDevCommon->EdidData, FPGAHDMIEdid, sizeof(FPGAHDMIEdid)); +#endif + IsDevChanged = CBIOS_TRUE; + bConnected = CBIOS_TRUE; + } + + if ((!bConnected) && (cbGetDeviceEDID(pcbe, pDevCommon, &IsDevChanged, FullDetect))) + { + bConnected = CBIOS_TRUE; + } + + /* + ** 2. parse EDID data + */ + if(bConnected) + { + if (IsDevChanged) + { + cbEDIDModule_ParseEDID(pDevCommon->EdidData, &(pDevCommon->EdidStruct), EDID_BLOCK_SIZE_SPEC * pDevCommon->TotalBlockNum); + cbEDIDModule_SADPatch(&(pDevCommon->EdidStruct)); + cbUpdateDeviceSignature(pcbe, pDevCommon); + pDevCommon->isFakeEdid = CBIOS_FALSE; + } + + if (FullDetect && HDMIModuleIndex != CBIOS_MODULE_INDEX_INVALID + && pDevCommon->PowerState == CBIOS_PM_ON + && (pcbe->DeviceMgr.ConnectedDevices & pDevCommon->DeviceType)) + { + //NOTE: fix issue13048, as the client will not set mode when hotplug bettween two monitors which has the same mode and one support + // scramble while the other does not. + //Some monitor support 4K@60 but not set IsSupportLTE340McscScramble, the sramble will be disable, add patch here to check clock. + if(pHDMIMonitorContext->HDMIClock > 3400000) + { + pHDMIMonitorContext->ScramblingEnable = CBIOS_TRUE;//enable scrambling if both source and sink device support scrambling + } + else + { + pHDMIMonitorContext->ScramblingEnable = CBIOS_FALSE; + } + cbDIU_HDMI_ConfigScrambling(pcbe, HDMIModuleIndex, pHDMIMonitorContext->ScramblingEnable); + + if(pDevCommon->EdidStruct.Attribute.HFVSDBData.IsSCDCPresent) + { + SCDCStatusFlags.ScramblerStatus = 0; + if(cbHDMIMonitor_SCDC_ReadData(pcbe, pDevCommon, &(SCDCStatusFlags.ScramblerStatus), 0x21, 0x1)) + { + //if scramble was enabled, but scramble_status is not 1, should reconfig SCDC + if((pHDMIMonitorContext->ScramblingEnable && !SCDCStatusFlags.Scrambling_Status) + || (!pHDMIMonitorContext->ScramblingEnable && SCDCStatusFlags.Scrambling_Status)) + { + //per HDMI2.0 spec,before write TMDS config,source should suspend transmission of TMDS clock and data + cbPHY_DP_DualModeOnOff(pcbe, HDMIModuleIndex, pDpContext->HDMIMonitorContext.HDMIClock, 0); + cbHDMIMonitor_SCDC_Configure(pcbe, pHDMIMonitorContext); + cbPHY_DP_DualModeOnOff(pcbe, HDMIModuleIndex, pDpContext->HDMIMonitorContext.HDMIClock, 1); + } + } + } + } + + if (!(pEDIDData[EDID_VIDEO_INPUT_DEF_BYTE_OFFSET] & EDID_VIDEO_INPUT_DEF_DIGITAL)) + { + cbDebugPrint((MAKE_LEVEL(HDMI, WARNING), "%s: why come here??? Current device is a CRT monitor according to EDID!\n", FUNCTION_NAME)); + } + + // Check if HDMI + if (pMonitorAttrib->IsCEA861HDMI) + { + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_HDMI; + } + else + { + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_DVI; + } + + if (!bHardcodeDetected) + { + if ((pDevCommon->CurrentMonitorType == CBIOS_MONITOR_TYPE_HDMI) && + (pMonitorAttrib->VSDBData.VSDBHeader.SourcePhyAddr != CEC_INVALID_PHYSICAL_ADDR)) + { + CBIOS_CEC_INDEX CECIndex = CBIOS_CEC_INDEX1; + + CECIndex = CBIOS_CEC_INDEX1; + + //get physical address + pcbe->CECPara[CECIndex].PhysicalAddr = pMonitorAttrib->VSDBData.VSDBHeader.SourcePhyAddr; + + if (pcbe->CECPara[CECIndex].CECEnable) + { + //allocate logical address + cbCECAllocateLogicalAddr(pcbe, CECIndex); + } + } + } + } + else + { + //for the case:if plugout monitor before suspend,and then plugin hdmi monitor before resume,after resume,4k@60 can't be lighted. + //rootcause:if plugout monitor,hpd thread will detect no device,so some attributes stored in pDevCommon will be cleared, + //plugin monitor before resume,os will do nothing,so it will not update attributes stored in pDevCommon + //then after resume,driver will not enter some hdmi module related codes,so monitor can't light + //so not memset pDevCommon->EdidStruct when device is not connected + cbClearEdidRelatedData(pcbe, pDevCommon); + cb_memset(((PCBIOS_HDCP_CONTEXT)pDevCommon->pHDCPContext)->BKsv, 0, sizeof(((PCBIOS_HDCP_CONTEXT)pDevCommon->pHDCPContext)->BKsv)); + } + + return bConnected; +} + +CBIOS_VOID cbHDMIMonitor_UpdateModeInfo(PCBIOS_VOID pvcbe, PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = pHDMIMonitorContext->pDevCommon; + CBIOS_U32 ClockFreq = pHDMIMonitorContext->HDMIClock; + + cbHDMIMonitor_GenerateInfoFrameData(pcbe, pHDMIMonitorContext, pModeParams); + + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG), "%s: CharR = %d.%d Mcsc!\n", FUNCTION_NAME, ClockFreq /10000, ClockFreq % 10000 / 1000)); + + if(ClockFreq > 3400000) + { + pHDMIMonitorContext->TMDSBitClockRatio = 1;//1:40 + + //When the TMDS Bit Rate is greater than 3.4Gbps, scrambling shall be enabled by the Source + pHDMIMonitorContext->ScramblingEnable = CBIOS_TRUE; + } + else + { + pHDMIMonitorContext->TMDSBitClockRatio = 0;//1:10 + + pHDMIMonitorContext->ScramblingEnable = CBIOS_FALSE; + } + + if(pcbe->ChipCaps.bSupportReadRequest) + { + pHDMIMonitorContext->ReadRequestEnable = CBIOS_TRUE; + } + else + { + pHDMIMonitorContext->ReadRequestEnable = CBIOS_FALSE; + } +} + + +CBIOS_VOID cbHDMIMonitor_SetMode(PCBIOS_VOID pvcbe, PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = pHDMIMonitorContext->pDevCommon; + CBIOS_MODULE_INDEX HDMIModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_HDMI); + CBIOS_U8 HVPolarity = pModeParams->TargetTiming.HVPolarity; + CBIOS_BOOL bHDMIDevice = pDevCommon->EdidStruct.Attribute.IsCEA861HDMI; + CBIOS_U32 ClockFreq = pHDMIMonitorContext->HDMIClock; + CBIOS_BOOL bHDCPCapable = CBIOS_TRUE; + + if (HDMIModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + cbDIU_HDMI_SetHVSync(pcbe, HDMIModuleIndex, HVPolarity); + + if (bHDMIDevice) + { + // avoid HBlank being too small to not transmit any packet(32 bytes). + if (pModeParams->TargetTiming.HorBEnd - pModeParams->TargetTiming.HorBStart < + HDMI_DELAY_FOR_HDCP + HDMI_LEADING_GUARD_BAND_PERIOD + HDMI_MIN_CTL_PERIOD + HDMI_TRAILING_GUARD_BAND_PERIOD + 32) + { + bHDCPCapable = CBIOS_FALSE; + } + cbDIU_HDMI_SetHDCPDelay(pcbe, HDMIModuleIndex, bHDCPCapable); + cbDIU_HDMI_SetPixelFormat(pcbe, HDMIModuleIndex, pModeParams->TargetModePara.OutputSignal); + cbDIU_HDMI_SetColorDepth(pcbe, HDMIModuleIndex, pModeParams->BitPerComponent * 3); + + //HDMI CLK LANE is used for PHY to generate 1/4 TMDS Clock Rate when TMDS Character Rates above 340Mcsc + if(ClockFreq > 3400000) + { + cbDIU_HDMI_EnableClkLane(pcbe, HDMIModuleIndex, CBIOS_TRUE); + } + else + { + cbDIU_HDMI_EnableClkLane(pcbe, HDMIModuleIndex, CBIOS_FALSE); + } + } + else + { + cbDIU_HDMI_EnableClkLane(pcbe, HDMIModuleIndex, CBIOS_FALSE); + } +} + +CBIOS_VOID cbHDMIMonitor_OnOff(PCBIOS_VOID pvcbe, PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext, CBIOS_BOOL bOn) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + //CBIOS_HDAC_PARA HDACPara = {0}; + PCBIOS_DEVICE_COMMON pDevCommon = pHDMIMonitorContext->pDevCommon; + CBIOS_MODULE_INDEX HDMIModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_HDMI); + CBIOS_MODULE_INDEX IGAIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_IGA); + PCBIOS_DISP_MODE_PARAMS pModeParams = CBIOS_NULL; + CBIOS_BOOL bHDMIDevice = pDevCommon->EdidStruct.Attribute.IsCEA861HDMI; + CBIOS_BOOL bSCDCPresent = pDevCommon->EdidStruct.Attribute.HFVSDBData.IsSCDCPresent; + PCBIOS_CEA_EXTENED_BLOCK pCEAExtData = &pDevCommon->EdidStruct.Attribute.ExtDataBlock[VIDEO_CAPABILITY_DATA_BLOCK_TAG]; + CBIOS_BOOL bQS = pCEAExtData->VideoCapabilityData.bRGBQuantRange; + CBIOS_CSC_ADJUST_PARA CSCAdjustPara = {0}; + + if (HDMIModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + if (bOn) + { + cbDIU_HDMI_SetModuleMode(pcbe, HDMIModuleIndex, bHDMIDevice); + + if (bHDMIDevice) + { + //HDACPara.DeviceId = pDevCommon->DeviceType; + //HDACPara.Size = sizeof(CBIOS_HDAC_PARA); + //HDACPara.bPresent = CBIOS_TRUE; + //HDACPara.bEldValid = CBIOS_TRUE; + + cbHDMIMonitor_SetInfoFrame(pcbe, &pHDMIMonitorContext->HDMIInfoFrame, pDevCommon->DeviceType); + //cbHDMIMonitor_SetHDACConnectStatus(pcbe, &HDACPara); + + if(bSCDCPresent) + { + cbHDMIMonitor_SCDC_Configure(pcbe, pHDMIMonitorContext); + } + + if(pcbe->ChipCaps.bSupportScrambling) + { + cbDIU_HDMI_ConfigScrambling(pcbe, HDMIModuleIndex, pHDMIMonitorContext->ScramblingEnable); + } + + if(pcbe->ChipCaps.bSupportReadRequest) + { + cbDIU_HDMI_EnableReadRequest(pcbe, HDMIModuleIndex, pHDMIMonitorContext->ReadRequestEnable); + } + } + + if (IGAIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid IGA module index!\n", FUNCTION_NAME)); + return; + } + pModeParams = pcbe->DispMgr.pModeParams[IGAIndex]; + + CSCAdjustPara.InputFormat = pModeParams->TargetModePara.DevInColorSpace; + if(pModeParams->TargetModePara.OutputSignal != CBIOS_RGBOUTPUT) + { + if(pModeParams->TargetModePara.YRes >= 720) + { + CSCAdjustPara.OutputFormat = CSC_FMT_YCBCR709; + } + else + { + CSCAdjustPara.OutputFormat = CSC_FMT_YCBCR601; + } + } + else + { + //If a Sink declares a selectable RGB Quantization Range (QS=1) in EDID VCDB + //It supports the reception of either type of RGB Quantization Range(Limited Range and Full Range) + //Here, we set CSC_FMT_RGB to send Full Range pixel values + if(bQS) + { + CSCAdjustPara.OutputFormat = CSC_FMT_RGB; + } + else + { + if((pHDMIMonitorContext->HDMIInfoFrame.bIsCEAMode == CBIOS_TRUE) && (pModeParams->VICCode > 1)) + { + CSCAdjustPara.OutputFormat = CSC_FMT_LIMITED_RGB; + } + else + { + CSCAdjustPara.OutputFormat = CSC_FMT_RGB; + } + } + } + CSCAdjustPara.Flag.bProgrammable = 0; + cbDoCSCAdjust(pcbe, pDevCommon->DeviceType, &CSCAdjustPara); + + cbDIU_HDMI_EnableVideoAudio(pcbe, HDMIModuleIndex); + } + else + { + //Wait vblank before turning off device to avoid flashing white lines + cbWaitVBlank(pcbe, IGAIndex); + + cbDIU_HDMI_DisableVideoAudio(pcbe, HDMIModuleIndex); + + if(pcbe->ChipCaps.bSupportScrambling) + { + cbDIU_HDMI_ConfigScrambling(pcbe, HDMIModuleIndex, CBIOS_FALSE); + } + + if(pcbe->ChipCaps.bSupportReadRequest) + { + cbDIU_HDMI_EnableReadRequest(pcbe, HDMIModuleIndex, CBIOS_FALSE); + } + + } + +} + +CBIOS_VOID cbHDMIMonitor_QueryAttribute(PCBIOS_VOID pvcbe, PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext, PCBiosMonitorAttribute pMonitorAttribute) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = pHDMIMonitorContext->pDevCommon; + PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttrib = &(pDevCommon->EdidStruct.Attribute); + + cbTraceEnter(HDMI); + + if ((pDevCommon->CurrentMonitorType == CBIOS_MONITOR_TYPE_HDMI) && (pcbe->ChipCaps.IsSupportDeepColor)) + { + if (pMonitorAttrib->VSDBData.IsSupport30Bit) + { + pMonitorAttribute->SupportBPC.IsSupport10BPC = CBIOS_TRUE; + } + + if (pMonitorAttrib->VSDBData.IsSupport36Bit) + { + pMonitorAttribute->SupportBPC.IsSupport12BPC = CBIOS_TRUE; + } + + if (pMonitorAttrib->VSDBData.IsSupport48Bit) + { + pMonitorAttribute->SupportBPC.IsSupport16BPC = CBIOS_TRUE; + } + } + + cbTraceExit(HDMI); +} + diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.h b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.h new file mode 100644 index 0000000000000..86d20f0accca1 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.h @@ -0,0 +1,345 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** HDMI monitor interface function prototype and parameter definition. +** +** NOTE: +** HDMI monitor ONLY parameters SHOULD be added to CBIOS_HDMI_MONITOR_CONTEXT., +** no matter the monitor is on DP port or MHL port. +******************************************************************************/ + +#ifndef _CBIOS_HDMI_MONITOR_H_ +#define _CBIOS_HDMI_MONITOR_H_ + +#include "../CBiosDeviceShare.h" + +#define CBIOS_AVI_INFO_FRAME_LEN 13 + +//************************************************************************************* +// MACROs for CEC +//************************************************************************************/ +#define CEC_UNREGISTERED_DEVICE 0x0F +#define CEC_BROADCAST_ADDRESS 0x0F +#define CEC_INVALID_PHYSICAL_ADDR 0xFFFF + +typedef enum _CBIOS_CEC_FEATURE_OPCODE +{ + CEC_FEATURE_ABORT = 0x00, + CEC_IMAGE_VIEW_ON = 0x04, + CEC_TEXT_VIEW_ON = 0x0D, + CEC_ACTIVE_SOURCE = 0x82, + CEC_GIVE_PHYSICAL_ADDR = 0x83, + CEC_REPORT_PHYSCAL_ADDR = 0x84, + CEC_REPORT_VENDOR_ID = 0x87, + CEC_GIVE_VENDOR_ID = 0x8C, + CEC_GIVE_POWER_STATUS = 0x8F, + CEC_REPORT_POWER_STATUS = 0x90, + CEC_REPORT_CEC_VERSION = 0x9E, + CEC_GET_CEC_VERSION = 0x9F, +}CBIOS_CEC_FEATURE_OPCODE; + +typedef enum _CBIOS_VSIF_HDMI_VIDEO_FORMAT +{ + VSIF_NO_ADDITIONAL_PRESENT = 0, + VSIF_EXTENDED_FORMAT_PRESENT, + VSIF_3D_FORMAT_INDICATION_PRESENT, + VSIF_VIDEO_FORMAT_LAST +}CBIOS_VSIF_HDMI_VIDEO_FORMAT; + + +typedef struct _CBIOS_VENDOR_SPECIFIC_INFOFRAME_PARA +{ + CBIOS_VSIF_HDMI_VIDEO_FORMAT VSIFVideoFormat; + union + { + struct + { + CBIOS_U8 VICCode; + }VSIFExtFormatPara; + struct + { + CBIOS_3D_STRUCTURE Video3DStruct; + }VSIF3DFormatPara; + }; +}CBIOS_VENDOR_SPECIFIC_INFOFRAME_PARA, *PCBIOS_VENDOR_SPECIFIC_INFOFRAME_PARA; + +typedef enum _CBIOS_HF_VSIF_3D_VIEW_DEPENDENCY +{ + HF_VSIF_3D_VIEW_DEPENDENCY_NO_INDICATION = 0, + HF_VSIF_3D_VIEW_DEPENDENCY_RIGHT, + HF_VSIF_3D_VIEW_DEPENDENCY_LEFT, + HF_VSIF_3D_VIEW_DEPENDENCY_BOTH, +}CBIOS_HF_VSIF_3D_VIEW_DEPENDENCY; + +typedef enum _CBIOS_HF_VSIF_3D_PREFERRED_2D_VIEW +{ + HF_VSIF_3D_PREFERRED_2D_VIEW_NO_INDICATION = 0, + HF_VSIF_3D_PREFERRED_2D_VIEW_RIGHT, + HF_VSIF_3D_PREFERRED_2D_VIEW_LEFT, + HF_VSIF_3D_PREFERRED_2D_VIEW_NOT_CARE, +}CBIOS_HF_VSIF_3D_PREFERRED_2D_VIEW; + +typedef struct _CBIOS_HF_VENDOR_SPECIFIC_INFOFRAME_PARA +{ + struct + { + CBIOS_U8 Valid3D :1; + CBIOS_U8 IsEnable3DOSDDisparity :1; + CBIOS_U8 IsEnable3DDualView :1; + CBIOS_U8 IsEnable3DIndependentView :1; + }; + CBIOS_3D_STRUCTURE Video3DFStruct; + CBIOS_3D_DISPARITY_PARA DisparityPara; + CBIOS_3D_INDEPENDENT_VIEW IndependentViewPara; +}CBIOS_HF_VENDOR_SPECIFIC_INFOFRAME_PARA, *PCBIOS_HF_VENDOR_SPECIFIC_INFOFRAME_PARA; + + +typedef enum _CBIOS_GBD_FORMAT +{ + VERTICES_FACETS_GBD_STRUCT = 0, + RANGE_GBD_STRUCT +}CBIOS_GBD_FORMAT; + +typedef enum _CBIOS_VERTICES_GBD_COLOR_SPACE +{ + GBD_VERTICES_COLOR_SPACE_BT709 = 0, + GBD_VERTICES_COLOR_SPACE_XVYCC_601, + GBD_VERTICES_COLOR_SPACE_XVYCC_709, + GBD_VERTICES_COLOR_SPACE_XYZ +}CBIOS_VERTICES_GBD_COLOR_SPACE; + +typedef enum _CBIOS_RANGE_GBD_COLOR_SPACE +{ + GBD_RANGE_COLOR_SPACE_RSVD = 0, + GBD_RANGE_COLOR_SPACE_XVYCC_601, + GBD_RANGE_COLOR_SPACE_XVYCC_709 +}CBIOS_RANGE_GBD_COLOR_SPACE; + +//CEA-861-F Table 5 +typedef enum _CBIOS_INFO_FRAME_TYPE +{ + RESERVED_INFO_FRAME_TYPE = 0, + VENDOR_SPECIFIC_INFO_FRAME_TYPE, + AVI_INFO_FRAME_TYPE, + SOURCE_PRODUCT_DESCRIPTION_INFO_FRAME_TYPE, + AUDIO_INFO_FRAME_TYPE, + MPEG_SOURCE_INFO_FRAME_TYPE, + NTSC_VBI_INFO_FRAME_TYPE, + //0x07-0x1F reserved for future use + //0x20-0xFF Forbidden +}CBIO_INFO_FRAME_TYPE; + + +typedef struct _CBIOS_VERTICES_GBD_PARA +{ + CBIOS_VERTICES_GBD_COLOR_SPACE ColorSpace; + CBIOS_U16 VerticesNum; + CBIOS_BOOL bFacetMode; + CBIOS_U16 FacetsNum; + CBIOS_U8 *pVerticesData; + CBIOS_U32 VerticesDataSize; + CBIOS_U8 *pFacetsData; + CBIOS_U32 FacetsDataSize; +}CBIOS_VERTICES_GBD_PARA, *PCBIOS_VERTICES_GBD_PARA; + +typedef struct _CBIOS_RANGE_GBD_PARA +{ + CBIOS_RANGE_GBD_COLOR_SPACE ColorSpace; + CBIOS_U8 *pRangeData; + CBIOS_U32 RangeDataSize; +}CBIOS_RANGE_GBD_PARA, *PCBIOS_RANGE_GBD_PARA; + +typedef union _CBIOS_GBD_DATA +{ + CBIOS_VERTICES_GBD_PARA VerticesGBD; + CBIOS_RANGE_GBD_PARA RangeGBD; +}CBIOS_GBD_DATA, *PCBIOS_GBD_DATA; + +typedef struct _CBIOS_GAMUT_METADATA_PARA +{ + CBIOS_GBD_FORMAT FormatFlag; + CBIOS_U8 GBDColorPrecision; + CBIOS_GBD_DATA GBDData; +}CBIOS_GAMUT_METADATA_PARA, *PCBIOS_GAMUT_METADATA_PARA; + +typedef struct _CBIOS_AVI_INFO_FRAME_DATA +{ + //Data Byte 1 + CBIOS_U8 ScanInfo :2; + CBIOS_U8 BarInfo :2; + CBIOS_U8 ActFormatInfoPreset :1; + CBIOS_U8 ColorFormat :3; // CEA-861-F Version 3 [3 bits] + //Data Byte 2 + CBIOS_U8 ActFormatAspectRatio :4; + CBIOS_U8 PictureAspectRatio :2; + CBIOS_U8 Colorimetry :2; + //Data Byte 3 + CBIOS_U8 NonUniformScaling :2; + CBIOS_U8 RGBQuantRange :2; + CBIOS_U8 ExtendedColorimetry :3; + CBIOS_U8 ITContent :1; + //Data Byte 4 + CBIOS_U8 VICCode :8; // CEA-861-F Version 3 [8 bits] + //Data Byte 5 + CBIOS_U8 PixelRepeatFactor :4; + CBIOS_U8 ContentType :2; + CBIOS_U8 YCCQuantRange :2; + //Data Byte 6-13, bar info + CBIOS_U8 EndTopBarLineL; //Line Number of End of Top Bar (lower 8 bits) + CBIOS_U8 EndTopBarLineH; //Line Number of End of Top Bar (upper 8 bits) + CBIOS_U8 StartBottomBarLineL; //Line Number of Start of Bottom Bar (lower 8 bits) + CBIOS_U8 StartBottomBarLineH; //Line Number of Start of Bottom Bar (upper 8 bits) + CBIOS_U8 EndLeftBarPixelL; //Pixel Number of End of Left Bar (lower 8 bits) + CBIOS_U8 EndLeftBarPixelH; //Pixel Number of End of Left Bar (upper 8 bits) + CBIOS_U8 StartRightBarPixelL; //Pixel Number of Start of Right Bar (lower 8 bits) + CBIOS_U8 StartRightBarPixelH; //Pixel Number of Start of Right Bar (upper 8 bits) +}CBIOS_AVI_INFO_FRAME_DATA, *PCBIOS_AVI_INFO_FRAME_DATA; + +typedef struct _CBIOS_AUDIO_INFO_FRAME_DATA +{ + //Data Byte 1 + CBIOS_U8 ChannelCount :3; + CBIOS_U8 Rsvd1 :1; + CBIOS_U8 CodingType :4; + //Data Byte 2 + CBIOS_U8 SampleSize :2; + CBIOS_U8 SampleFrequency :3; + CBIOS_U8 Rsvd2 :3; + //Data Byte 3 + CBIOS_U8 Format; + //Data Byte 4 + CBIOS_U8 ChannelAllocation; + //Data Byte 5 + CBIOS_U8 LEFPlaybackLevel :2; + CBIOS_U8 Rsvd3 :1; + CBIOS_U8 LevelShiftValue :4; + CBIOS_U8 DownmixInhibit :1; +}CBIOS_AUDIO_INFO_FRAME_DATA, *PCBIOS_AUDIO_INFO_FRAME_DATA; + +typedef struct _CBIOS_HDMI_INFO_FRAME_DATA +{ + CBIOS_VENDOR_SPECIFIC_INFOFRAME_PARA VSIFPara; + CBIOS_HF_VENDOR_SPECIFIC_INFOFRAME_PARA HFVSIFPara; + CBIOS_GAMUT_METADATA_PARA GamutMetadata; + CBIOS_AVI_INFO_FRAME_DATA AVIInfoFrameData; + CBIOS_U32 HDMIMaxPacketNum; + CBIOS_BOOL bIsCEAMode; +}CBIOS_HDMI_INFO_FRAME_DATA, *PCBIOS_HDMI_INFO_FRAME_DATA; + +typedef struct _CBIOS_CEC_MESSAGE +{ + CBIOS_U8 SourceAddr; // Initiator Logical Address + CBIOS_U8 DestAddr; // Destination Logical Address + CBIOS_U32 CmdLen; // CEC Initiator command length. The valid value is [0:16] + CBIOS_U8 Command[16]; // Initiator Command sent by CEC + CBIOS_BOOL bBroadcast; // = TRUE: broadcast; = FALSE: direct access + CBIOS_U8 RetryCnt; // CEC Initiator Retry times. Valid values must be 1 to 5. +}CBIOS_CEC_MESSAGE, *PCBIOS_CEC_MESSAGE; + +typedef struct _CBIOS_CEC_PARA +{ + CBIOS_BOOL CECEnable; // =TRUE: CEC is enabled; = FALSE: CEC is disabled + CBIOS_U16 PhysicalAddr; // physical address of our board + CBIOS_U8 LogicalAddr; // logical address of our board +}CBIOS_CEC_PARA, *PCBIOS_CEC_PARA; + +typedef struct _CBIOS_SCDC_UPDATE_FLAGS +{ + union + { + struct + { + struct + { + CBIOS_U8 StatusUpdate :1; + CBIOS_U8 CEDUpdate :1; + CBIOS_U8 RRTest :1; + CBIOS_U8 Rsvd :5; + }Update_0; + struct + { + CBIOS_U8 Rsvd :8; + }Update_1; + }; + CBIOS_U16 UpdateFlags; + }; +}CBIOS_SCDC_UPDATE_FLAGS,*PCBIOS_SCDC_UPDATE_FLAGS; + +typedef struct _CBIOS_SCDC_STATUS_FLAGS +{ + union + { + struct + { + CBIOS_U8 Scrambling_Status :1; + CBIOS_U8 Rsvd :7; + }; + CBIOS_U8 ScramblerStatus; + }; + union + { + struct + { + struct + { + CBIOS_U8 ClockDetected :1; + CBIOS_U8 Ch0_Locked :1; + CBIOS_U8 Ch1_Locked :1; + CBIOS_U8 Ch2_Locked :1; + CBIOS_U8 Rsvd :4; + }Status_Flags_0; + struct + { + CBIOS_U8 Rsvd :8; + }Status_Flags_1; + }; + CBIOS_U16 Status_Flags; + }; +}CBIOS_SCDC_STATUS_FLAGS,*PCBIOS_SCDC_STATUS_FLAGS; + +typedef struct _CBIOS_SCDC_CED_DATA +{ + CBIOS_U8 Ch0_Err_CountBits7To0 :8; + CBIOS_U8 Ch0_Err_CountBits14To8 :7; + CBIOS_U8 Ch0_Valid :1; + CBIOS_U8 Ch1_Err_CountBits7To0 :8; + CBIOS_U8 Ch1_Err_CountBits14To8 :7; + CBIOS_U8 Ch1_Valid :1; + CBIOS_U8 Ch2_Err_CountBits7To0 :8; + CBIOS_U8 Ch2_Err_CountBits14To8 :7; + CBIOS_U8 Ch2_Valid :1; + CBIOS_U8 CHECKSUM :8; +}CBIOS_SCDC_CED_DATA,*PCBIOS_SCDC_CED_DATA; + +typedef struct _CBIOS_HDMI_MONITOR_CONTEXT +{ + PCBIOS_DEVICE_COMMON pDevCommon; + CBIOS_HDMI_INFO_FRAME_DATA HDMIInfoFrame; + CBIOS_U8 TMDSBitClockRatio;// =0 means 1:10, =1 means 1:40 + CBIOS_U32 HDMIClock; // HDMI clock + CBIOS_BOOL ReadRequestEnable; + CBIOS_BOOL ScramblingEnable; +}CBIOS_HDMI_MONITOR_CONTEXT, *PCBIOS_HDMI_MONITOR_CONTEXT; + +CBIOS_BOOL cbHDMIMonitor_Detect(PCBIOS_VOID pvcbe, PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext, CBIOS_BOOL bHardcodeDetected, CBIOS_U32 FullDetect); +CBIOS_VOID cbHDMIMonitor_UpdateModeInfo(PCBIOS_VOID pvcbe, PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext, PCBIOS_DISP_MODE_PARAMS pModeParams); +CBIOS_VOID cbHDMIMonitor_SetMode(PCBIOS_VOID pvcbe, PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext, PCBIOS_DISP_MODE_PARAMS pModeParams); +CBIOS_VOID cbHDMIMonitor_OnOff(PCBIOS_VOID pvcbe, PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext, CBIOS_BOOL bOn); +CBIOS_VOID cbHDMIMonitor_QueryAttribute(PCBIOS_VOID pvcbe, PCBIOS_HDMI_MONITOR_CONTEXT pHDMIMonitorContext, PCBiosMonitorAttribute pMonitorAttribute); +CBIOS_BOOL cbHDMIMonitor_SCDC_Handler(CBIOS_VOID* pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosDSIPanel.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosDSIPanel.c new file mode 100644 index 0000000000000..02726cdf505e3 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosDSIPanel.c @@ -0,0 +1,305 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DSI panel interface function implementation. +** +** NOTE: +** +******************************************************************************/ + + +#include "CBiosDSI.h" +#include "CBiosDSIPanel.h" + + +extern CBIOS_DSI_PANEL_DESC HX8392A_Panel_Desc; +extern CBIOS_DSI_PANEL_DESC R63417_Panel_Desc; +extern CBIOS_DSI_PANEL_DESC NT35595_Panel_Desc; +extern CBIOS_DSI_PANEL_DESC R63319_Panel_Desc; + +#define DEFAULT_PANEL_INDEX 3 + +#define HX8392A_PANEL_INDEX 0 +#define NT35595_PANEL_INDEX 2 + +static PCBIOS_DSI_PANEL_DESC DSIPanelDescTbl[] = +{ + &HX8392A_Panel_Desc, + &R63417_Panel_Desc, + &NT35595_Panel_Desc, + &R63319_Panel_Desc, +}; + + +PCBIOS_DSI_PANEL_DESC cbDSIPanel_GetPanelDescriptor(PCBIOS_VOID pvcbe) +{ + PCBIOS_DSI_PANEL_DESC pPanelDesc = CBIOS_NULL; + CBIOS_U32 PanelIndex = DEFAULT_PANEL_INDEX; + + if (cbGetPlatformConfigurationU32(pvcbe, (CBIOS_UCHAR*)"panel_index", &PanelIndex, 1)) + { + if (PanelIndex >= sizeofarray(DSIPanelDescTbl)) + { + PanelIndex = DEFAULT_PANEL_INDEX; + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "Invalid panel index, use default index!\n")); + } + } + else + { + PanelIndex = DEFAULT_PANEL_INDEX; + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "Can't get panel index, use default index!\n")); + } + +#if ELT2K_HARDCODE_DSI_CMDMODE + PanelIndex = HX8392A_PANEL_INDEX; +#endif + + pPanelDesc = DSIPanelDescTbl[PanelIndex]; + + if (pPanelDesc == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "Can't get panel descriptor!\n")); + } + + return pPanelDesc; +} + +CBIOS_STATUS cbDSIPanel_Init(PCBIOS_VOID pvcbe, PCBIOS_DSI_PANEL_DESC pPanelDesc) +{ + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pPanelDesc != CBIOS_NULL) + { + if (pPanelDesc->pFnDSIPanelInit != CBIOS_NULL) + { + Status = pPanelDesc->pFnDSIPanelInit(pvcbe); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "function %s not implemented. use default command list\n", FUNCTION_NAME)); + } + Status = CBIOS_OK; + + } + else + { + Status = CBIOS_ER_NULLPOINTER; + } + + + return Status; +} + + +CBIOS_STATUS cbDSIPanel_DeInit(PCBIOS_VOID pvcbe, PCBIOS_DSI_PANEL_DESC pPanelDesc) +{ + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pPanelDesc != CBIOS_NULL) + { + if (pPanelDesc->pFnDSIPanelDeInit != CBIOS_NULL) + { + Status = pPanelDesc->pFnDSIPanelDeInit(pvcbe); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "function %s not implemented. use default command list\n", FUNCTION_NAME)); + } + Status = CBIOS_OK; + + } + else + { + Status = CBIOS_ER_NULLPOINTER; + } + + + return Status; +} + + +CBIOS_STATUS cbDSIPanel_OnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn, PCBIOS_DSI_PANEL_DESC pPanelDesc) +{ + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pPanelDesc != CBIOS_NULL) + { + if (pPanelDesc->pFnDSIPanelOnOff != CBIOS_NULL) + { + Status = pPanelDesc->pFnDSIPanelOnOff(pvcbe, bTurnOn); + } + else + { + if (bTurnOn) + { + /** + IOVDD ON + >0ms + cbDelayMilliSeconds(1); + AVDD ON + >2ms + cbDelayMilliSeconds(3); + DCDC_EN ON + >2ms + cbDelayMilliSeconds(3); + RESX + >5ms + cbDelayMilliSeconds(6); + **/ + cbDSI_SendCmdList(pvcbe, pPanelDesc->pPowerOnCmdList, pPanelDesc->PowerOnCmdListSize); + } + else + { + cbDSI_SendCmdList(pvcbe, pPanelDesc->pPowerOffCmdList, pPanelDesc->PowerOffCmdListSize); + /** + DCDC_EN OFF + >1ms + cbDelayMilliSeconds(2); + AVDD OFF + >0ms + cbDelayMilliSeconds(1); + IOVDD OFF + **/ + } + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "function %s not implemented. use default command list\n", FUNCTION_NAME)); + } + Status = CBIOS_OK; + } + else + { + Status = CBIOS_ER_NULLPOINTER; + } + + + return Status; +} + +CBIOS_STATUS cbDSIPanel_DisplayOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn, PCBIOS_DSI_PANEL_DESC pPanelDesc) +{ + CBIOS_STATUS Status = CBIOS_OK; + if (bTurnOn) + { + cbDSI_SendCmdList(pvcbe, pPanelDesc->pDisplayOnCmdList, pPanelDesc->DisplayOnCmdListSize); + } + else + { + cbDSI_SendCmdList(pvcbe, pPanelDesc->pDisplayOffCmdList, pPanelDesc->DisplayOffCmdListSize); + } + + return Status; +} + +CBIOS_STATUS cbDSIPanel_SetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 BacklightValue, PCBIOS_DSI_PANEL_DESC pPanelDesc) +{ + PCBIOS_DSI_CONFIG pDSIConfig = CBIOS_NULL; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U8 BlValue = 0; + PCBIOS_U8 pBlDataBuf = CBIOS_NULL; + + if (pPanelDesc != CBIOS_NULL) + { + + if (pPanelDesc->pFnDSIPanelSetBacklight!= CBIOS_NULL) + { + Status = pPanelDesc->pFnDSIPanelSetBacklight(pvcbe, BacklightValue); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "function %s not implemented. use default command list\n", FUNCTION_NAME)); + BlValue = (CBIOS_U8)BacklightValue; + pDSIConfig = &(pPanelDesc->DSIConfig); + if (BacklightValue < pDSIConfig->BacklightMin) + { + BlValue = (CBIOS_U8)pDSIConfig->BacklightMin; + } + if (BacklightValue > pDSIConfig->BacklightMax) + { + BlValue = (CBIOS_U8)pDSIConfig->BacklightMax; + } + + BlValue = (CBIOS_U8)BlValue * (pDSIConfig->BacklightMax - pDSIConfig->BacklightMin + 1) / 256 + pDSIConfig->BacklightMin; + + pBlDataBuf = pPanelDesc->pBacklightCmdList[0].pDataBuf; + pBlDataBuf[1] = BlValue; + + Status = cbDSI_SendCmdList(pvcbe, pPanelDesc->pBacklightCmdList, pPanelDesc->BacklightCmdListSize); + + } + } + else + { + Status = CBIOS_ER_NULLPOINTER; + } + + return Status; +} + +CBIOS_STATUS cbDSIPanel_GetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 *pBacklightValue, PCBIOS_DSI_PANEL_DESC pPanelDesc) +{ + CBIOS_STATUS Status = CBIOS_OK; + + if (pPanelDesc != CBIOS_NULL) + { + + if (pPanelDesc->pFnDSIPanelGetBacklight!= CBIOS_NULL) + { + Status = pPanelDesc->pFnDSIPanelGetBacklight(pvcbe, pBacklightValue); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "function %s not implemented. \n", FUNCTION_NAME)); + + *pBacklightValue = 0; + } + } + else + { + Status = CBIOS_ER_NULLPOINTER; + } + + + return Status; +} + + +CBIOS_STATUS cbDSIPanel_SetCabc(PCBIOS_VOID pvcbe, CBIOS_U32 CabcValue, PCBIOS_DSI_PANEL_DESC pPanelDesc) +{ + CBIOS_STATUS Status = CBIOS_OK; + + if (pPanelDesc != CBIOS_NULL) + { + + if (pPanelDesc->pFnDSIPanelSetCABC!= CBIOS_NULL) + { + Status = pPanelDesc->pFnDSIPanelSetCABC(pvcbe, CabcValue); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "function %s not implemented. \n", FUNCTION_NAME)); + } + } + else + { + Status = CBIOS_ER_NULLPOINTER; + } + + return Status; +} + + + + diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosDSIPanel.h b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosDSIPanel.h new file mode 100644 index 0000000000000..14ceb76f4f59f --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosDSIPanel.h @@ -0,0 +1,185 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + + +/***************************************************************************** +** DESCRIPTION: +** DSI panel interface function prototype and parameter definition. +** +** NOTE: +*** +******************************************************************************/ + +#ifndef _CBIOS_DSI_PANEL_H_ +#define _CBIOS_DSI_PANEL_H_ + + +#include "../../CBiosShare.h" +#include "../../../Callback/CBiosCallbacks.h" +#include "../../../Hw/HwCallback/CBiosCallbacksHw.h" + + +typedef struct _GPIO_PORT +{ + CBIOS_GPIO_TYPE GPIOType; + CBIOS_U32 GPIOIndex; +}GPIO_PORT, *PGPIO_PORT; + +typedef enum _CBIOS_DSI_MODE +{ + CBIOS_DSI_VIDEOMODE = 0x01, + CBIOS_DSI_CMDMODE = 0x02 +}CBIOS_DSI_MODE; + +typedef enum _CBIOS_DSI_SYNC_PACKET_TYPE +{ + CBIOS_DSI_SYNC_PULSE = 0x01, + CBIOS_DSI_SYNC_EVENT = 0x02, +}CBIOS_DSI_SYNC_PACKET_TYPE; + +typedef enum _CBIOS_DSI_TE_TYPE +{ + CBIOS_DSI_TE_TRIGGER = 0x01, + CBIOS_DSI_TE_PAD = 0x02, +}CBIOS_DSI_TE_TYPE; + +typedef enum _CBIOS_DSI_CLK_LANE_MODE +{ + CBIOS_DSI_CLK_LANE_SOFTWARE_CTL = 0x01, + CBIOS_DSI_CLK_LANE_HARDWARE_CTL = 0x02, +}CBIOS_DSI_CLK_LANE_MODE; + +typedef struct _CBIOS_DSI_CONFIG +{ + CBIOS_DSI_MODE DSIMode; /* 1: video mode; 2: command mode */ + CBIOS_DSI_CLK_LANE_MODE ClkLaneMode; /* 1: software control; 2: hardware control */ + CBIOS_DSI_SYNC_PACKET_TYPE SyncPacketType; /* 1: sync pulse; 2: sync event */ + CBIOS_DSI_TE_TYPE TEType; /* 1: trigger; 2: pad */ + CBIOS_U32 TurnAroundTimeout; /* unit: tBClk */ + CBIOS_U32 HS_TXTimeout; /* unit: tBClk */ + CBIOS_U32 LP_RXTimeout; /* unit: tBClk */ + CBIOS_U32 DMAThreshold; + CBIOS_U32 BacklightMax; + CBIOS_U32 BacklightMin; + + union + { + CBIOS_U32 ConfigFlags; + struct + { + CBIOS_U32 isEnableEoTp :1; + CBIOS_U32 isHFPEnterLP :1; + CBIOS_U32 isHSAEnterLP :1; + CBIOS_U32 isHBPEnterLP :1; + CBIOS_U32 isBLCtrlSupport :1; + CBIOS_U32 isDualChannel :1; + CBIOS_U32 Reserved :26; + }; + }; +}CBIOS_DSI_CONFIG, *PCBIOS_DSI_CONFIG; + +typedef struct _CBIOS_DSI_TIMING +{ + CBIOS_U32 XResolution; + CBIOS_U32 YResolution; + CBIOS_U32 DCLK; + CBIOS_U32 HorTotal; + CBIOS_U32 HorDisEnd; + CBIOS_U32 HorBStart; + CBIOS_U32 HorBEnd; + CBIOS_U32 HorSyncStart; + CBIOS_U32 HorSyncEnd; + CBIOS_U32 VerTotal; + CBIOS_U32 VerDisEnd; + CBIOS_U32 VerBStart; + CBIOS_U32 VerBEnd; + CBIOS_U32 VerSyncStart; + CBIOS_U32 VerSyncEnd; + CBIOS_U32 HVPolarity; +}CBIOS_DSI_TIMING, *PCBIOS_DSI_TIMING; + +typedef struct _CBIOS_DSI_PANEL_TABLE +{ + CBIOS_U32 LaneNum; + CBIOS_U32 OutBpp; + CBIOS_DSI_TIMING PanelTiming; +} CBIOS_DSI_PANEL_TABLE, *PCBIOS_DSI_PANEL_TABLE; + +typedef struct _CBIOS_DSI_CMD_DESC +{ + CBIOS_U32 DSIIndex; // 0: DSI-1, 1:DSI-2 + CBIOS_U32 VirtualCh; // refer MIPI-DSI spec 4.2.3 + CBIOS_U32 PacketType; // 0: short packet, 1: long packet + CBIOS_U32 ContentType; // 0: DCS write cmd, 1: generic write cmd + CBIOS_U32 WaitTime; // unit: ms + CBIOS_U32 DataLen; + PCBIOS_U8 pDataBuf; + union + { + CBIOS_U32 DSIFlags; + struct + { + CBIOS_U32 bNeedAck :1; // 1: the cmd need acknowledge, 0: no need + CBIOS_U32 bHSModeOnly :1; // 1: the cmd can be transferred in hs mode only, 0: both LP and HS mode + CBIOS_U32 Reserved :6; + }; + }; +}CBIOS_DSI_CMD_DESC, *PCBIOS_DSI_CMD_DESC; + +/*It's for environment initial and can be called only once.*/ +typedef CBIOS_STATUS (*PFN_cbDSIPanel_Init)(PCBIOS_VOID pvcbe); + + + +typedef CBIOS_STATUS (*PFN_cbDSIPanel_DeInit)(PCBIOS_VOID pvcbe); +typedef CBIOS_STATUS (*PFN_cbDSIPanel_PowerOnOff)(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn); +typedef CBIOS_STATUS (*PFN_cbDSIPanel_SetBacklight)(PCBIOS_VOID pvcbe, CBIOS_U32 BrightnessValue); +typedef CBIOS_STATUS (*PFN_cbDSIPanel_GetBacklight)(PCBIOS_VOID pvcbe, CBIOS_U32 *pBrightnessValue); +typedef CBIOS_STATUS (*PFN_cbDSIPanel_SetCabc)(PCBIOS_VOID pvcbe,CBIOS_U32 CabcValue); + + +typedef struct _CBIOS_DSI_PANEL_DESC +{ + CBIOS_U32 VersionNum; + CBIOS_DSI_CONFIG DSIConfig; + CBIOS_DSI_PANEL_TABLE DSIPanelTbl; + CBIOS_U32 PowerOnCmdListSize; + CBIOS_U32 PowerOffCmdListSize; + CBIOS_U32 DisplayOnCmdListSize; + CBIOS_U32 DisplayOffCmdListSize; + CBIOS_U32 BacklightCmdListSize; + PCBIOS_DSI_CMD_DESC pPowerOnCmdList; + PCBIOS_DSI_CMD_DESC pPowerOffCmdList; + PCBIOS_DSI_CMD_DESC pDisplayOnCmdList; + PCBIOS_DSI_CMD_DESC pDisplayOffCmdList; + PCBIOS_DSI_CMD_DESC pBacklightCmdList; + PFN_cbDSIPanel_PowerOnOff pFnDSIPanelOnOff; + PFN_cbDSIPanel_SetBacklight pFnDSIPanelSetBacklight; + PFN_cbDSIPanel_GetBacklight pFnDSIPanelGetBacklight; + PFN_cbDSIPanel_SetCabc pFnDSIPanelSetCABC; + PFN_cbDSIPanel_Init pFnDSIPanelInit; + PFN_cbDSIPanel_DeInit pFnDSIPanelDeInit; +}CBIOS_DSI_PANEL_DESC, *PCBIOS_DSI_PANEL_DESC; + +PCBIOS_DSI_PANEL_DESC cbDSIPanel_GetPanelDescriptor(PCBIOS_VOID pvcbe); +CBIOS_STATUS cbDSIPanel_Init(PCBIOS_VOID pvcbe, PCBIOS_DSI_PANEL_DESC pPanelDesc); +CBIOS_STATUS cbDSIPanel_DeInit(PCBIOS_VOID pvcbe, PCBIOS_DSI_PANEL_DESC pPanelDesc); +CBIOS_STATUS cbDSIPanel_OnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn, PCBIOS_DSI_PANEL_DESC pPanelDesc); +CBIOS_STATUS cbDSIPanel_SetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 BacklightValue, PCBIOS_DSI_PANEL_DESC pPanelDesc); +CBIOS_STATUS cbDSIPanel_GetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 *pBacklightValue, PCBIOS_DSI_PANEL_DESC pPanelDesc); +CBIOS_STATUS cbDSIPanel_DisplayOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn, PCBIOS_DSI_PANEL_DESC pPanelDesc); +CBIOS_STATUS cbDSIPanel_SetCabc(PCBIOS_VOID pvcbe, CBIOS_U32 CabcValue, PCBIOS_DSI_PANEL_DESC pPanelDesc); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosHX8392A.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosHX8392A.c new file mode 100644 index 0000000000000..a185ca514905a --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosHX8392A.c @@ -0,0 +1,306 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** HX8392A type DSI panel descriptor definition, +** which contains panel config and command lists. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosDSIPanel.h" +#include "CBiosDSI.h" + +static CBIOS_U8 PasswordBuf[0x4] = +{ + 0xB9, 0xFF, 0x83, 0x92 +}; + +static CBIOS_U8 PowerBuf[0x0E] = +{ + 0xB1, 0x7C, 0x00, 0x44, + 0x14, 0x00, 0x11, 0x11, + 0x24, 0x2C, 0x3F, 0x3F, + 0x42, 0x72 +}; + +static CBIOS_U8 MpuBuf[0x18] = +{ + 0xB4, 0x00, 0x00, 0x05, + 0x00, 0xA0, 0x05, 0x16, + 0x9D, 0x30, 0x03, 0x16, + 0x00, 0x03, 0x03, 0x00, + 0x1B, 0x04, 0x07, 0x07, + 0x01, 0x00, 0x1A, 0x77 +}; + +static CBIOS_U8 DrivingBuf[0x18] = +{ + 0xD8, 0x00, 0x00, 0x04, + 0x00, 0xA0, 0x04, 0x16, + 0x9D, 0x30, 0x03, 0x16, + 0x00, 0x03, 0x03, 0x00, + 0x1B, 0x04, 0x07, 0x07, + 0x01, 0x00, 0x1A, 0x77 +}; + +static CBIOS_U8 DisplayBuf[0x0D] = +{ + 0xB2, 0x08, 0xC8, 0x05, + 0x0F, 0x08, 0x44, 0x00, + 0xFF, 0x05, 0x0F, 0x04, + 0x20 +}; + +static CBIOS_U8 VcomBuf[0x02] = +{ + 0xB6, 0x70 +}; + +static CBIOS_U8 GammaRBuf[0x23] = +{ + 0xE0, 0x03, 0x1B, 0x22, + 0x3B, 0x3B, 0x3F, 0x2B, + 0x47, 0x05, 0x0B, 0x0E, + 0x10, 0x13, 0x11, 0x12, + 0x11, 0x1A, 0x03, 0x1B, + 0x22, 0x3B, 0x3B, 0x3F, + 0x2B, 0x47, 0x05, 0x0B, + 0x0E, 0x10, 0x13, 0x11, + 0x12, 0x11, 0x1A +}; + +static CBIOS_U8 GammaGBuf[0x23] = +{ + 0xE1, 0x03, 0x1B, 0x22, + 0x3B, 0x3B, 0x3F, 0x2B, + 0x47, 0x05, 0x0B, 0x0E, + 0x10, 0x13, 0x11, 0x12, + 0x11, 0x1A, 0x03, 0x1B, + 0x22, 0x3B, 0x3B, 0x3F, + 0x2B, 0x47, 0x05, 0x0B, + 0x0E, 0x10, 0x13, 0x11, + 0x12, 0x11, 0x1A +}; + +static CBIOS_U8 GammaBBuf[0x23] = +{ + 0xE2, 0x03, 0x1B, 0x22, + 0x3B, 0x3B, 0x3F, 0x2B, + 0x47, 0x05, 0x0B, 0x0E, + 0x10, 0x13, 0x11, 0x12, + 0x11, 0x1A, 0x03, 0x1B, + 0x22, 0x3B, 0x3B, 0x3F, + 0x2B, 0x47, 0x05, 0x0B, + 0x0E, 0x10, 0x13, 0x11, + 0x12, 0x11, 0x1A +}; + +static CBIOS_U8 PixelFormatBuf[0x02] = +{ + 0x3A, 0x77 +}; + +static CBIOS_U8 MIPIBuf[0x03] = +{ + 0xBA, 0x13, 0x83 //0xBA, 0x13, 0x83 +}; + +static CBIOS_U8 DisplayModeBuf[0x02] = +{ + 0xC2, 0x08 //panel display mode: +}; + +static CBIOS_U8 InterPowerBuf[0x05] = +{ + 0xBF, 0x05, 0xE0, 0x02, + 0x00 +}; + +static CBIOS_U8 TConBuf[0x03] = +{ + 0xC7, 0x00, 0x40 +}; + +static CBIOS_U8 PanelBuf[0x02] = +{ + 0xCC, 0x08 +}; + +static CBIOS_U8 EqBuf[0x02] = +{ + 0xD4, 0x0C +}; + +static CBIOS_U8 GckEqBuf[0x16] = +{ + 0xD5, 0x00, 0x08, 0x08, + 0x00, 0x44, 0x55, 0x66, + 0x77, 0xCC, 0xCC, 0xCC, + 0xCC, 0x00, 0x77, 0x66, + 0x55, 0x44, 0xCC, 0xCC, + 0xCC, 0xCC +}; + +static CBIOS_U8 C0Buf[0x03] = +{ + 0xC0, 0x01, 0x94 +}; + +static CBIOS_U8 C6Buf[0x05] = +{ + 0xC6, 0x45, 0x02, 0x10, + 0x04 +}; + +static CBIOS_U8 EnterSleepBuf[0x01] = +{ + 0x10 +}; + +static CBIOS_U8 ExitSleepBuf[0x01] = +{ + 0x11 +}; + + +static CBIOS_U8 DisplayOffBuf[0x01] = +{ + 0x28 +}; + +static CBIOS_U8 DisplayOnBuf[0x01] = +{ + 0x29 +}; + +static CBIOS_U8 BacklightBuf[0x02] = +{ + 0x51, 0xFF +}; +static CBIOS_U8 TEEnable[0x02] = +{ + 0x35, 0x00 +}; + +static CBIOS_DSI_CMD_DESC HX8392A_PowerOn_CmdList[] = +{ + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(PasswordBuf), PasswordBuf, {0}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 120, sizeof(ExitSleepBuf), ExitSleepBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(PowerBuf), PowerBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MpuBuf), MpuBuf, {0}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(VcomBuf), VcomBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MIPIBuf), MIPIBuf, {0}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DisplayModeBuf), DisplayModeBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(InterPowerBuf), InterPowerBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(C0Buf), C0Buf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(C6Buf), C6Buf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(TConBuf), TConBuf, {0}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(PanelBuf), PanelBuf, {0}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EqBuf), EqBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(GckEqBuf), GckEqBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DrivingBuf), DrivingBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(GammaRBuf), GammaRBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(GammaGBuf), GammaGBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(GammaBBuf), GammaBBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(DisplayBuf), DisplayBuf, {0}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(PixelFormatBuf), PixelFormatBuf, {0}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DisplayOnBuf), DisplayOnBuf, {0}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(TEEnable), TEEnable, {0}}, +}; + + +static CBIOS_DSI_CMD_DESC HX8392A_PowerOff_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DisplayOffBuf), DisplayOffBuf, {0}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 120, sizeof(EnterSleepBuf), EnterSleepBuf, {0}}, +}; + +static CBIOS_DSI_CMD_DESC HX8392A_DisplayOn_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 10, sizeof(DisplayOnBuf), DisplayOnBuf, {0}}, +}; + +static CBIOS_DSI_CMD_DESC HX8392A_DisplayOff_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 10, sizeof(DisplayOffBuf), DisplayOffBuf, {0}}, +}; + +static CBIOS_DSI_CMD_DESC HX8392A_Backlight_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(BacklightBuf), BacklightBuf, {0}}, +}; + +CBIOS_DSI_PANEL_DESC HX8392A_Panel_Desc = +{ + /*.VersionNum = */CBIOS_DSI_VERSION, + /*.DSIConfig =*/ + { + /*.DSIMode = */CBIOS_DSI_CMDMODE, + /*.ClkLaneMode = */CBIOS_DSI_CLK_LANE_HARDWARE_CTL, + /*.SyncPacketType = */CBIOS_DSI_SYNC_PULSE, + /*.TEType = */CBIOS_DSI_TE_PAD, + /*.TurnAroundTimeout = */0x1000000, + /*.HS_TXTimeout = */0x1000000, + /*.LP_RXTimeout = */0x1000000, + /*.DMAThreshold = */0x400, + /*.BacklightMax = */255, + /*.BacklightMin = */0, + /*.ConfigFlags = */{0x1F,}, + }, + /*.DSIPanelTbl =*/ + { + /*.LaneNum = */4, + /*.OutBpp = */24, + /*.PanelTiming =*/ + { + /*.XResolution = */720, + /*.YResolution = */1280, + /*.DCLK = */5775, + /*.HorTotal = */880, + /*.HorDisEnd = */720, + /*.HorBStart = */720, + /*.HorBEnd = */880, + /*.HorSyncStart = */(720+64), + /*.HorSyncEnd = */(720+64+32), + /*.VerTotal = */1312, + /*.VerDisEnd = */1280, + /*.VerBStart = */1280, + /*.VerBEnd = */1312, + /*.VerSyncStart = */(1280+16), + /*.VerSyncEnd = */(1280+16+4), + /*.HVPolarity = */DSI_VNEGATIVE + DSI_HNEGATIVE, + }, + }, + /*.PowerOnCmdListSize = */sizeofarray(HX8392A_PowerOn_CmdList), + /*.PowerOffCmdListSize = */sizeofarray(HX8392A_PowerOff_CmdList), + /*.DisplayOnCmdListSize = */sizeofarray(HX8392A_DisplayOn_CmdList), + /*.DisplayOffCmdListSize = */sizeofarray(HX8392A_DisplayOff_CmdList), + /*.BacklightCmdListSize = */sizeofarray(HX8392A_Backlight_CmdList), + /*.pPowerOnCmdList = */HX8392A_PowerOn_CmdList, + /*.pPowerOffCmdList = */HX8392A_PowerOff_CmdList, + /*.pDisplayOnCmdList = */HX8392A_DisplayOn_CmdList, + /*.pDisplayOffCmdList = */HX8392A_DisplayOff_CmdList, + /*.pBacklightCmdList = */HX8392A_Backlight_CmdList, + /*.pFnDSIPanelOnOff = */CBIOS_NULL, + /*.pFnDSIPanelSetBacklight = */CBIOS_NULL, + /*.pFnDSIPanelGetBacklight = */CBIOS_NULL, + /*.pFnDSIPanelSetCABC = */CBIOS_NULL, + /*.pFnDSIPanelInit = */CBIOS_NULL, + /*.pFnDSIPanelDeInit = */CBIOS_NULL, +}; + diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosNT35595.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosNT35595.c new file mode 100644 index 0000000000000..97aed0cc3c80d --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosNT35595.c @@ -0,0 +1,555 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + + +/***************************************************************************** +** DESCRIPTION: +** NT35595 type DSI panel descriptor definition, +** which contains panel config and command lists. +** +** NOTE: +** +******************************************************************************/ + + +#include "CBiosDSIPanel.h" +#include "CBiosDSI.h" + + +static CBIOS_U8 EnterSleepBuf[0x01] = +{ + 0x10 +}; + +static CBIOS_U8 DisplayOffBuf[0x01] = +{ + 0x28 +}; + +static CBIOS_U8 DisplayOnBuf[0x01] = +{ + 0x29 +}; + +static CBIOS_U8 BacklightBuf[0x02] = +{ + 0x51, 0xFF +}; + +static CBIOS_U8 MipiCmdModeBuf[0x02] = {0xBB,0x10}; +static CBIOS_U8 EnterC2P3Buf[0x02] = {0xFF, 0x23}; +static CBIOS_U8 DmctCtlBuf[0x02] = {0x00, 0x02}; +static CBIOS_U8 CabcDimBuf[0x02] = {0x01, 0x84}; +static CBIOS_U8 DimStepBuf[0x02] ={0x05, 0x22}; +static CBIOS_U8 PwmFreqBuf[0x02] = {0x08, 0x04}; +static CBIOS_U8 DutyCntBuf[0x02] ={0x46, 0x00}; +static CBIOS_U8 StillModeGBuf0[0x02] ={0x17, 0xFF}; +static CBIOS_U8 StillModeGBuf1[0x02] ={0x18, 0xFA}; +static CBIOS_U8 StillModeGBuf2[0x02] ={0x19, 0xF8}; +static CBIOS_U8 StillModeGBuf3[0x02] ={0x1A, 0xF5}; +static CBIOS_U8 StillModeGBuf4[0x02] = {0x1B, 0xEE}; +static CBIOS_U8 StillModeGBuf5[0x02] = {0x1C, 0xE1}; +static CBIOS_U8 StillModeGBuf6[0x02] = {0x1D, 0xD5}; +static CBIOS_U8 StillModeGBuf7[0x02] = {0x1E, 0xCD}; +static CBIOS_U8 StillModeGBuf8[0x02] = {0x1F, 0xB9}; +static CBIOS_U8 StillModeGBuf9[0x02] = {0x20, 0xB4}; +static CBIOS_U8 MovieModeGBuf0[0x02] ={0x21, 0xFF}; +static CBIOS_U8 MovieModeGBuf1[0x02] ={0x22, 0xFA,}; +static CBIOS_U8 MovieModeGBuf2[0x02] ={0x23, 0xF5}; +static CBIOS_U8 MovieModeGBuf3[0x02] ={0x24, 0xEB}; +static CBIOS_U8 MovieModeGBuf4[0x02] ={0x25, 0xE1}; +static CBIOS_U8 MovieModeGBuf5[0x02] ={0x26, 0xC8}; +static CBIOS_U8 MovieModeGBuf6[0x02] ={0x27, 0xAA}; +static CBIOS_U8 MovieModeGBuf7[0x02] ={0x28, 0x96}; +static CBIOS_U8 MovieModeGBuf8[0x02] ={0x29, 0x73}; +static CBIOS_U8 MovieModeGBuf9[0x02] ={0x2A, 0x66}; +static CBIOS_U8 StillModeGamBuf0[0x02] = {0x09, 0x02}; +static CBIOS_U8 StillModeGamBuf1[0x02] = {0x0A, 0x06}; +static CBIOS_U8 StillModeGamBuf2[0x02] = {0x0B, 0x07}; +static CBIOS_U8 StillModeGamBuf3[0x02] = {0x0C, 0x08}; +static CBIOS_U8 StillModeGamBuf4[0x02] = {0x0D, 0x09}; +static CBIOS_U8 StillModeGamBuf5[0x02] = {0x0E, 0x0B}; +static CBIOS_U8 StillModeGamBuf6[0x02] = {0x0F, 0x0D}; +static CBIOS_U8 StillModeGamBuf7[0x02] = {0x10, 0x0D}; +static CBIOS_U8 StillModeGamBuf8[0x02] = {0x11, 0x12}; +static CBIOS_U8 StillModeGamBuf9[0x02] = {0x12, 0x20}; +static CBIOS_U8 MovieModeGamBuf[0x02] = {0x33, 0x0C}; +static CBIOS_U8 MtpReloadCtlBuf[0x02] = {0xFB, 0x01}; +static CBIOS_U8 EnterC2P2Buf[0x02] = {0xFF, 0x22}; +static CBIOS_U8 AdjustSatuBuf0[0x02] = {0x00, 0x00}; +static CBIOS_U8 AdjustSatuBuf1[0x02] = {0x01, 0x04}; +static CBIOS_U8 AdjustSatuBuf2[0x02] = {0x02, 0x08}; +static CBIOS_U8 AdjustSatuBuf3[0x02] = {0x03, 0x0C}; +static CBIOS_U8 AdjustSatuBuf4[0x02] = {0x04, 0x10}; +static CBIOS_U8 AdjustSatuBuf5[0x02] = {0x05, 0x14}; +static CBIOS_U8 AdjustSatuBuf6[0x02] = {0x06, 0x18}; +static CBIOS_U8 AdjustSatuBuf7[0x02] = {0x07, 0x20}; +static CBIOS_U8 AdjustSatuBuf8[0x02] = {0x08, 0x24}; +static CBIOS_U8 AdjustSatuBuf9[0x02] = {0x09, 0x28}; +static CBIOS_U8 AdjustSatuBufA[0x02] = {0x0A, 0x30}; +static CBIOS_U8 AdjustSatuBufB[0x02] = {0x0B, 0x38}; +static CBIOS_U8 AdjustSatuBufC[0x02] = {0x0C, 0x38}; +static CBIOS_U8 AdjustSatuBufD[0x02] = {0x0D, 0x30}; +static CBIOS_U8 AdjustSatuBufE[0x02] = {0x0E, 0x28}; +static CBIOS_U8 AdjustSatuBufF[0x02] = {0x0F, 0x20}; +static CBIOS_U8 AdjustSatuBuf10[0x02] = {0x10, 0x10}; +static CBIOS_U8 AdjustSatuBuf11[0x02] = {0x11, 0x00}; +static CBIOS_U8 AdjustSatuBuf12[0x02] = {0x12, 0x00}; +static CBIOS_U8 AdjustSatuBuf13[0x02] = {0x13, 0x00}; +static CBIOS_U8 HueDegBuf0[0x02] = {0x32, 0x10}; +static CBIOS_U8 HueDegBuf1[0x02] = {0x33, 0x10}; +static CBIOS_U8 HueDegBuf2[0x02] = {0x34, 0x10}; +static CBIOS_U8 HueDegBuf3[0x02] = {0x35, 0x10}; +static CBIOS_U8 HueDegBuf4[0x02] = {0x36, 0x10}; +static CBIOS_U8 HueDegBuf5[0x02] = {0x37, 0x10}; +static CBIOS_U8 HueDegBuf6[0x02] = {0x38, 0x10}; +static CBIOS_U8 HueDegBuf7[0x02] = {0x39, 0x10}; +static CBIOS_U8 HueDegBuf8[0x02] = {0x3A, 0x10}; +static CBIOS_U8 HueDegBuf9[0x02] = {0x3B, 0x10}; +static CBIOS_U8 HueDegBufA[0x02] = {0x3F, 0x10}; +static CBIOS_U8 HueDegBufB[0x02] = {0x40, 0x10}; +static CBIOS_U8 HueDegBufC[0x02] = {0x41, 0x10}; +static CBIOS_U8 HueDegBufD[0x02] = {0x42, 0x10}; +static CBIOS_U8 HueDegBufE[0x02] = {0x43, 0x10}; +static CBIOS_U8 HueDegBufF[0x02] = {0x44, 0x10}; +static CBIOS_U8 HueDegBuf10[0x02] = {0x45, 0x10}; +static CBIOS_U8 HueDegBuf11[0x02] = {0x46, 0x10}; +static CBIOS_U8 HueDegBuf12[0x02] = {0x47, 0x10}; +static CBIOS_U8 HueDegBuf13[0x02] = {0x48, 0x10}; +static CBIOS_U8 HueDegBuf14[0x02] = {0x49, 0x10}; +static CBIOS_U8 HueDegBuf15[0x02] = {0x4A, 0x10}; +static CBIOS_U8 HueDegBuf16[0x02] = {0x4B, 0x10}; +static CBIOS_U8 HueDegBuf17[0x02] = {0x4C, 0x10}; +static CBIOS_U8 DisableViBuf[0x02] = {0x1A, 0x00}; +static CBIOS_U8 EnableSmartBuf[0x02] = {0x53, 0x01}; +static CBIOS_U8 DisableSkinBuf[0x02] = {0x54, 0x00}; +static CBIOS_U8 DisableOverBuf[0x02] = {0x55, 0x00}; +static CBIOS_U8 EnableSmtCotra[0x02] = {0x56, 0x01}; +static CBIOS_U8 EnableEdgeBuf[0x02] = {0x68, 0x01}; +static CBIOS_U8 SmtClrGrBuf[0x02] = {0x4D, 0x0E}; +static CBIOS_U8 SmtCotraDppBuf[0x02] = {0x58, 0x0E}; +static CBIOS_U8 SmtCotraLppBuf[0x02] = {0x59, 0x14}; +static CBIOS_U8 TurnOffSmtBuf[0x02] = {0x64, 0x20}; +static CBIOS_U8 EdgeLevel2Buf[0x02] = {0x65, 0x02}; +static CBIOS_U8 EdgeThdL0Buf[0x02] = {0x69, 0x02}; +static CBIOS_U8 MtpRelCmdBuf[0x02] = {0xFB, 0x01}; +static CBIOS_U8 EnterCmd1Buf[0x02] = {0xFF, 0x10}; +static CBIOS_U8 EnableISCMBuf[0x02] = {0x55, 0x82}; +static CBIOS_U8 EnableCmdFunBuf[0x02] = {0x5E, 0x14}; +static CBIOS_U8 LcdSleepCmd[0x02] = {0x11, 0x00}; +static CBIOS_U8 EnterCmd24Buf[0x02] = {0xFF, 0x24}; +static CBIOS_U8 OutputHTHBuf[0x02] = {0xC6, 0x09}; +static CBIOS_U8 NoMtpRelBuf[0x02] = {0xFB, 0x01}; +static CBIOS_U8 TurnOnTEBuf[0x02] = {0x35, 0x00}; +static CBIOS_U8 NoNameFuncBuf[0x02] = {0x51, 0xff}; +static CBIOS_U8 LcdDispOnBuf[0x02] = {0x29, 0x00}; +static CBIOS_U8 EnableBlBuf[0x02] = {0x53, 0x24}; + +static CBIOS_DSI_CMD_DESC NT35595_PowerOn_CmdList[] = +{ + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MipiCmdModeBuf), MipiCmdModeBuf, {0}}, //MIPI CMD mode + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EnterC2P3Buf), EnterC2P3Buf, {0}}, //Enter CMD2 page3 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DmctCtlBuf), DmctCtlBuf, {0}}, //DMCT = 1, Select the enable / disable mechanism for CABC and Manual dimming functions. + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(CabcDimBuf), CabcDimBuf, {0}}, //Enable CABC dimmin and Gamma Dimming + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DimStepBuf), DimStepBuf, {0}}, //Moving mode dimming 32step, still mode 8step + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(PwmFreqBuf), PwmFreqBuf, {0}}, //PWMDIV[7:0] for PWM frequency + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DutyCntBuf), DutyCntBuf, {0}}, //PWM duty count for 42.96kHZ + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGBuf0), StillModeGBuf0, {0}}, //CABC still mode PWM - gray 240-255 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGBuf1), StillModeGBuf1, {0}}, //CABC still mode PWM - gray 224-239 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGBuf2), StillModeGBuf2, {0}}, //CABC still mode PWM - gray 208-223 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGBuf3), StillModeGBuf3, {0}}, //CABC still mode PWM - gray 192-207 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGBuf4), StillModeGBuf4, {0}}, //CABC still mode PWM - gray 160-191 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGBuf5), StillModeGBuf5, {0}}, //CABC still mode PWM - gray 128-159 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGBuf6), StillModeGBuf6, {0}}, //CABC still mode PWM - gray 112-127 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGBuf7), StillModeGBuf7, {0}}, //CABC still mode PWM - gray 64-111 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGBuf8), StillModeGBuf8, {0}}, //CABC still mode PWM - gray 16-63 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGBuf9), StillModeGBuf9, {0}}, //CABC still mode PWM - gray 0-15 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MovieModeGBuf0), MovieModeGBuf0, {0}}, //CABC movie mode PWM - gray 240-255 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MovieModeGBuf1), MovieModeGBuf1, {0}}, //CABC movie mode PWM - gray 224-239 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MovieModeGBuf2), MovieModeGBuf2, {0}}, //CABC movie mode PWM - gray 208-223 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MovieModeGBuf3), MovieModeGBuf3, {0}}, //CABC movie mode PWM -gray 192-207 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MovieModeGBuf4), MovieModeGBuf4, {0}}, //CABC movie mode PWM - gray 160-191 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MovieModeGBuf5), MovieModeGBuf5, {0}}, //CABC movie mode PWM - gray 128-159 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MovieModeGBuf6), MovieModeGBuf6, {0}}, //CABC movie mode PWM - gray 112-127 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MovieModeGBuf7), MovieModeGBuf7, {0}}, //CABC movie mode PWM- gray 64-111 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MovieModeGBuf8), MovieModeGBuf8, {0}}, //CABC movie mode PWM - gray 16-63 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MovieModeGBuf9), MovieModeGBuf9, {0}}, //CABC movie mode PWM - gray 0-15 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGamBuf0), StillModeGamBuf0, {0}}, //CABC still mode Gamma curve compensation - gray 240-255 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGamBuf1), StillModeGamBuf1, {0}}, //CABC still mode Gamma curve compensation - gray 224-239 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGamBuf2), StillModeGamBuf2, {0}}, //CABC still mode Gamma curve compensation - gray 208-223 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGamBuf3), StillModeGamBuf3, {0}}, //CABC still mode Gamma curve compensation - gray 192-207 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGamBuf4), StillModeGamBuf4, {0}}, //CABC still mode Gamma curve compensation - gray 160-191 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGamBuf5), StillModeGamBuf5, {0}}, //CABC still mode Gamma curve compensation - gray 128-159 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGamBuf6), StillModeGamBuf6, {0}}, //CABC still mode Gamma curve compensation - gray 112-127 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGamBuf7), StillModeGamBuf7, {0}}, //CABC still mode Gamma curve compensation - gray 64-111 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGamBuf8), StillModeGamBuf8, {0}}, //CABC still mode Gamma curve compensation - gray 16-63 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(StillModeGamBuf9), StillModeGamBuf9, {0}}, //CABC still mode Gamma curve compensation - gray 0-15 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MovieModeGamBuf), MovieModeGamBuf, {0}}, //CABC Movie mode Gamma curve compensation + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MtpReloadCtlBuf), MtpReloadCtlBuf, {0}}, //MTP do not reload CMD2 P3 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EnterC2P2Buf), EnterC2P2Buf, {0}}, //Enter CMD2 page2 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf0), AdjustSatuBuf0, {0}}, //parameter to adjust saturation > 0.98 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf1), AdjustSatuBuf1, {0}}, //parameter to adjustsaturation 0.95~0.98 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf2), AdjustSatuBuf2, {0}}, //parameter to adjustsaturation 0.91~0.95 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf3), AdjustSatuBuf3, {0}}, //parameter to adjustsaturation 0.88~0.91 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf4), AdjustSatuBuf4, {0}}, //parameter to adjustsaturation 0.85~0.88 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf5), AdjustSatuBuf5, {0}}, //parameter to adjustsaturation 0.82~0.85 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf6), AdjustSatuBuf6, {0}}, //parameter to adjustsaturation 0.79~0.82 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf7), AdjustSatuBuf7, {0}}, //parameter to adjustsaturation 0.76~0.79 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf8), AdjustSatuBuf8, {0}}, //parameter to adjustsaturation 0.73~0.76 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf9), AdjustSatuBuf9, {0}}, //parameter to adjustsaturation 0.7~0.73 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBufA), AdjustSatuBufA, {0}}, //parameter to adjustsaturation 0.66~0.7 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBufB), AdjustSatuBufB, {0}}, //parameter to adjustsaturation 0.6~0.66 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBufC), AdjustSatuBufC, {0}}, //parameter to adjustsaturation 0.54~0.6 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBufD), AdjustSatuBufD, {0}}, //parameter to adjustsaturation 0.48~0.54 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBufE), AdjustSatuBufE, {0}}, //parameter to adjustsaturation 0.41~0.48 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBufF), AdjustSatuBufF, {0}}, //parameter to adjustsaturation 0.35~0.41 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf10), AdjustSatuBuf10, {0}}, //parameter to adjustsaturation 0.26~0.35 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf11), AdjustSatuBuf11, {0}}, //parameter to adjustsaturation 0.16~0.26 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf12), AdjustSatuBuf12, {0}}, //parameter to adjustsaturation 0.07~0.16 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(AdjustSatuBuf13), AdjustSatuBuf13, {0}}, //parameter to adjustsaturation < 0.07 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf0), HueDegBuf0, {0}}, //HUE 0~15 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf1), HueDegBuf1, {0}}, //HUE 15~30 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf2), HueDegBuf2, {0}}, //HUE 30~45 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf3), HueDegBuf3, {0}}, //HUE 45~60 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf4), HueDegBuf4, {0}}, //HUE 60~75 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf5), HueDegBuf5, {0}}, //HUE 75~90 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf6), HueDegBuf6, {0}}, //HUE 90~105 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf7), HueDegBuf7, {0}}, //HUE 105~120 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf8), HueDegBuf8, {0}}, //HUE 120~135 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf9), HueDegBuf9, {0}}, //HUE 135~150 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBufA), HueDegBufA, {0}}, //HUE 150~165 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBufB), HueDegBufB, {0}}, //HUE 165~180 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBufC), HueDegBufC, {0}}, //HUE 180~195 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBufD), HueDegBufD, {0}}, //HUE 195~210 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBufE), HueDegBufE, {0}}, //HUE 210~225 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBufF), HueDegBufF, {0}}, //HUE 225~240 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf10), HueDegBuf10, {0}}, //HUE 240~255 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf11), HueDegBuf11, {0}}, //HUE 255~270 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf12), HueDegBuf12, {0}}, //HUE 270~285 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf13), HueDegBuf13, {0}}, //HUE 285~300 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf14), HueDegBuf14, {0}}, //HUE 300~315 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf15), HueDegBuf15, {0}}, //HUE 315~330 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf16), HueDegBuf16, {0}}, //HUE 330~345 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(HueDegBuf17), HueDegBuf17, {0}}, //HUE 345~360 degree + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DisableViBuf), DisableViBuf, {0}}, //Disable Vivid Color + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EnableSmartBuf), EnableSmartBuf, {0}}, //Enable Smart Color + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DisableSkinBuf), DisableSkinBuf, {0}}, //Disable SKIN_KEEP + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DisableOverBuf), DisableOverBuf, {0}}, //Disable Over-Saturation protection + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EnableSmtCotra), EnableSmtCotra, {0}}, //Enable Smart Contrast + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EnableEdgeBuf), EnableEdgeBuf, {0}}, //Enable Edge Enhancement + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(SmtClrGrBuf), SmtClrGrBuf, {0}}, //Smart Color global ratio + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(SmtCotraDppBuf), SmtCotraDppBuf, {0}}, //Smart Contrast Dark part parameter 14 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(SmtCotraLppBuf), SmtCotraLppBuf, {0}}, //Smart Contrast Light part parameter 20 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(TurnOffSmtBuf), TurnOffSmtBuf, {0}}, //Turn off Smart Contrast local reference + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EdgeLevel2Buf), EdgeLevel2Buf, {0}}, //Edge level 2 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EdgeThdL0Buf), EdgeThdL0Buf, {0}}, //Edge THD level 0 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(MtpRelCmdBuf), MtpRelCmdBuf, {0}}, //MTP do not reload CMD2 P2 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EnterCmd1Buf), EnterCmd1Buf, {0}}, //Enter CMD1 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EnableISCMBuf), EnableISCMBuf, {0}}, //Enable IE slight level and CABC still mode + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EnableCmdFunBuf), EnableCmdFunBuf, {0}}, //Enable CMB function + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 120, sizeof(LcdSleepCmd), LcdSleepCmd, {0}}, //LCD Sleep out command + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EnterCmd24Buf), EnterCmd24Buf, {0}}, //Enter CMD24 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(OutputHTHBuf), OutputHTHBuf, {0}}, //output Hsync to HSOUT + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(NoMtpRelBuf), NoMtpRelBuf, {0}}, //No MTP reload at CMD2 P4 + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(TurnOnTEBuf), TurnOnTEBuf, {0}}, //Turn on TE (TEE/ TE H/W pin) function + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(NoNameFuncBuf), NoNameFuncBuf, {0}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(LcdDispOnBuf), LcdDispOnBuf, {0}}, //LCD Display on + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(EnableBlBuf), EnableBlBuf, {0}}, //Enable BL +}; + + +static CBIOS_DSI_CMD_DESC NT35595_PowerOff_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DisplayOffBuf), DisplayOffBuf, {0}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 120, sizeof(EnterSleepBuf), EnterSleepBuf, {0}}, +}; + +static CBIOS_DSI_CMD_DESC NT35595_DisplayOn_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 10, sizeof(DisplayOnBuf), DisplayOnBuf, {0}}, +}; + +static CBIOS_DSI_CMD_DESC NT35595_DisplayOff_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 10, sizeof(DisplayOffBuf), DisplayOffBuf, {0}}, +}; + +static CBIOS_DSI_CMD_DESC NT35595_Backlight_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(BacklightBuf), BacklightBuf, {0}}, +}; + +#define NT35595_INDEX_IOVDD 0 +#define NT35595_INDEX_AVDDP 1 +#define NT35595_INDEX_AVDDN 2 +#define NT35595_INDEX_RESX 3 +#define NT35595_INDEX_BLEN 4 + +// GPIO PORTS for board version A0 & A1 +GPIO_PORT NT35595_GPIO_PORTS_A1[] = +{ + {CBIOS_GPIO_AUD, 18}, //IOVDD + {CBIOS_GPIO_VSOC, 57}, //AVDDP + {CBIOS_GPIO_VSOC, 58}, //AVDDN + {CBIOS_GPIO_GFX, 10}, //RESX + {CBIOS_GPIO_VSUS, 46}, //DSI_BLEN +}; + +// GPIO PORTS for board version A2 & A3 +GPIO_PORT NT35595_GPIO_PORTS_A2[] = +{ + {CBIOS_GPIO_VSUS, 48}, //IOVDD + {CBIOS_GPIO_VSOC, 57}, //AVDD+ + {CBIOS_GPIO_VSOC, 58}, //AVDD- + {CBIOS_GPIO_VSUS, 33}, //RESX + {CBIOS_GPIO_VSUS, 46}, //DSI_BLEN +}; + +extern CBIOS_DSI_PANEL_DESC NT35595_Panel_Desc; + +static CBIOS_STATUS cbNT35595_GetGpioPorts(PCBIOS_VOID pvcbe, PGPIO_PORT *pGpioPorts, CBIOS_U32 *pNumPorts) +{ + CBIOS_BOARD_VERSION BoardVersion = cbGetBoardVersion(pvcbe); + CBIOS_STATUS Status = CBIOS_OK; + + *pGpioPorts = CBIOS_NULL; + *pNumPorts = 0; + if (BoardVersion <= CBIOS_BOARD_VERSION_1) + { + *pGpioPorts = NT35595_GPIO_PORTS_A1; + *pNumPorts = sizeofarray(NT35595_GPIO_PORTS_A1); + } + else if (BoardVersion == CBIOS_BOARD_VERSION_2) + { + *pGpioPorts = NT35595_GPIO_PORTS_A2; + *pNumPorts = sizeofarray(NT35595_GPIO_PORTS_A2); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: invalid board version: 0x%x!\n", FUNCTION_NAME, BoardVersion)); + Status = CBIOS_ER_INTERNAL; + } + + return Status; +} + +CBIOS_STATUS cbNT35595_Init(PCBIOS_VOID pvcbe) +{ + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 Requested = 0, i = 0, NumPorts = 0; + PGPIO_PORT pNT35595GpioPorts = CBIOS_NULL; + + cbNT35595_GetGpioPorts(pvcbe, &pNT35595GpioPorts, &NumPorts); + + for (i = 0; i < NumPorts; i++) + { + if (cbRequestGPIO(pvcbe, pNT35595GpioPorts[i].GPIOType, pNT35595GpioPorts[i].GPIOIndex) == CBIOS_OK) + { + cbSetGPIODirectionOutput(pvcbe, pNT35595GpioPorts[i].GPIOType, pNT35595GpioPorts[i].GPIOIndex, 0); + Requested |= (1 << i); + Status = CBIOS_OK; + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "Request GPIO fail! Type: %x, Index: %d\n", pNT35595GpioPorts[i].GPIOType, pNT35595GpioPorts[i].GPIOIndex)); + Status = CBIOS_ER_INTERNAL; + break; + } + } + + if (Status != CBIOS_OK)//request fail, free requested GPIOs + { + for (i = 0; i < NumPorts; i++) + { + if (i & Requested) + { + cbFreeGPIO(pvcbe, pNT35595GpioPorts[i].GPIOType, pNT35595GpioPorts[i].GPIOIndex); + } + } + } + + return Status; +} + +CBIOS_STATUS cbNT35595_DeInit(PCBIOS_VOID pvcbe) +{ + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 i = 0, NumPorts = 0; + PGPIO_PORT pNT35595GpioPorts = CBIOS_NULL; + + cbNT35595_GetGpioPorts(pvcbe, &pNT35595GpioPorts, &NumPorts); + + if (pNT35595GpioPorts == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: cannot get GPIO ports for NT35595\n", FUNCTION_NAME)); + Status = CBIOS_ER_INTERNAL; + return Status; + } + + for (i = 0; i < NumPorts; i++) + { + cbFreeGPIO(pvcbe, pNT35595GpioPorts[i].GPIOType, pNT35595GpioPorts[i].GPIOIndex); + } + + return Status; +} + +CBIOS_STATUS cbNT35595_PanelPowerOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn) +{ + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 NumPorts = 0; + PGPIO_PORT pNT35595GpioPorts = CBIOS_NULL; + + cbNT35595_GetGpioPorts(pvcbe, &pNT35595GpioPorts, &NumPorts); + + if (pNT35595GpioPorts == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: cannot get GPIO ports for NT35595\n", FUNCTION_NAME)); + Status = CBIOS_ER_INTERNAL; + return Status; + } + + if(bTurnOn) + { + //XRES=L + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_RESX].GPIOType, pNT35595GpioPorts[NT35595_INDEX_RESX].GPIOIndex, 0); + cbDelayMilliSeconds(1); + + //IOVDD On --config 1.8v + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_IOVDD].GPIOType, pNT35595GpioPorts[NT35595_INDEX_IOVDD].GPIOIndex, 1); + cbDelayMilliSeconds(2); + + //DSI_BL_EN + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_BLEN].GPIOType, pNT35595GpioPorts[NT35595_INDEX_BLEN].GPIOIndex, 1); + cbDelayMilliSeconds(2); + + //AVDD+ ON + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_AVDDP].GPIOType, pNT35595GpioPorts[NT35595_INDEX_AVDDP].GPIOIndex, 1); + cbDelayMilliSeconds(1); + + //AVDD- ON + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_AVDDN].GPIOType, pNT35595GpioPorts[NT35595_INDEX_AVDDN].GPIOIndex, 1); + cbDelayMilliSeconds(15); + + //XRES=H + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_RESX].GPIOType, pNT35595GpioPorts[NT35595_INDEX_RESX].GPIOIndex, 1); + cbDelayMilliSeconds(1); + + //XRES=L + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_RESX].GPIOType, pNT35595GpioPorts[NT35595_INDEX_RESX].GPIOIndex, 0); + cbDelayMilliSeconds(1); + + //XRES=H + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_RESX].GPIOType, pNT35595GpioPorts[NT35595_INDEX_RESX].GPIOIndex, 1); + cbDelayMilliSeconds(15); + + + + Status = cbDSI_SendCmdList(pvcbe, NT35595_PowerOn_CmdList, sizeofarray(NT35595_PowerOn_CmdList)); + } + else + { + Status = cbDSI_SendCmdList(pvcbe, NT35595_PowerOff_CmdList, sizeofarray(NT35595_PowerOff_CmdList)); + + cbDelayMilliSeconds(10); + + //DSI_BL_EN OFF + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_BLEN].GPIOType, pNT35595GpioPorts[NT35595_INDEX_BLEN].GPIOIndex, 0); + + //AVDD- OFF + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_AVDDN].GPIOType, pNT35595GpioPorts[NT35595_INDEX_AVDDN].GPIOIndex, 0); + cbDelayMilliSeconds(1); + + //AVDD+ OFF + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_AVDDP].GPIOType, pNT35595GpioPorts[NT35595_INDEX_AVDDP].GPIOIndex, 0); + cbDelayMilliSeconds(1); + + //XRES=L + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_RESX].GPIOType, pNT35595GpioPorts[NT35595_INDEX_RESX].GPIOIndex, 0); + cbDelayMilliSeconds(1); + + //config 1.8v -- IOVDD OFF + cbWriteGPIO(pvcbe, pNT35595GpioPorts[NT35595_INDEX_IOVDD].GPIOType, pNT35595GpioPorts[NT35595_INDEX_IOVDD].GPIOIndex, 0); + } + + return Status; +} + +CBIOS_DSI_PANEL_DESC NT35595_Panel_Desc = +{ + /*.VersionNum = */CBIOS_DSI_VERSION, + /*.DSIConfig =*/ + { + /*.DSIMode = */CBIOS_DSI_CMDMODE, + /*.ClkLaneMode = */CBIOS_DSI_CLK_LANE_HARDWARE_CTL, + /*.SyncPacketType = */CBIOS_DSI_SYNC_PULSE, +#ifdef ELT2K_DIU_FPGA + /*.TEType = */CBIOS_DSI_TE_PAD, +#else + /*.TEType = */CBIOS_DSI_TE_PAD, +#endif + /*.TurnAroundTimeout = */0x1000000, + /*.HS_TXTimeout = */0x1000000, + /*.LP_RXTimeout = */0x1000000, + /*.DMAThreshold = */0x400, + /*.BacklightMax =*/ 255, + /*.BacklightMin = */0, + /*.ConfigFlags = */{0x10,}, + }, + /*.DSIPanelTbl = */ + { + /*.LaneNum = */4, + /*.OutBpp = */24, + /*.PanelTiming = */ + { + /*.XResolution = */1080, + /*.YResolution = */1920, +#ifdef ELT2K_DIU_FPGA + /*.DCLK = */5400, +#else + /*.DCLK = */15550, //14040, +#endif + /*.HorTotal = */1200 + 128, + /*.HorDisEnd = */1080, + /*.HorBStart = */1080, + /*.HorBEnd = */1200 + 128, + /*.HorSyncStart = */(1080+64 ) + 32, + /*.HorSyncEnd = */(1080+64+32) + 64, + /*.VerTotal = */1950, + /*.VerDisEnd = */1920, + /*.VerBStart = */1920, + /*.VerBEnd = */1950, + /*.VerSyncStart = */(1920+16), + /*.VerSyncEnd = */(1920+16+2), + /*.HVPolarity = */DSI_VNEGATIVE + DSI_HNEGATIVE, + }, + }, + /*.PowerOnCmdListSize = */sizeofarray(NT35595_PowerOn_CmdList), + /*.PowerOffCmdListSize = */sizeofarray(NT35595_PowerOff_CmdList), + /*.DisplayOnCmdListSize = */sizeofarray(NT35595_DisplayOn_CmdList), + /*.DisplayOffCmdListSize = */sizeofarray(NT35595_DisplayOff_CmdList), + /*.BacklightCmdListSize = */sizeofarray(NT35595_Backlight_CmdList), + /*.pPowerOnCmdList = */NT35595_PowerOn_CmdList, + /*.pPowerOffCmdList = */NT35595_PowerOff_CmdList, + /*.pDisplayOnCmdList = */NT35595_DisplayOn_CmdList, + /*.pDisplayOffCmdList = */NT35595_DisplayOff_CmdList, + /*.pBacklightCmdList = */NT35595_Backlight_CmdList, + /*.pFnDSIPanelOnOff = */cbNT35595_PanelPowerOnOff, + /*.pFnDSIPanelSetBacklight = */CBIOS_NULL, + /*.pFnDSIPanelGetBacklight = */CBIOS_NULL, + /*.pFnDSIPanelSetCABC = */CBIOS_NULL, + /*.pFnDSIPanelInit = */cbNT35595_Init, + /*.pFnDSIPanelDeInit = */CBIOS_NULL, +}; diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosR63319.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosR63319.c new file mode 100644 index 0000000000000..e63bf199c6acc --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosR63319.c @@ -0,0 +1,494 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** R63319 type DSI panel descriptor definition, +** which contains panel config and command lists. +** +** NOTE: +** +******************************************************************************/ + + +#include "CBiosDSIPanel.h" +#include "CBiosDSI.h" + +static CBIOS_U8 EnterSleepBuf[0x01] = +{ + 0x10 +}; + +static CBIOS_U8 ExitSleepBuf[0x01] = +{ + 0x11 +}; + + +static CBIOS_U8 DisplayOffBuf[0x01] = +{ + 0x28 +}; + +static CBIOS_U8 DisplayOnBuf[0x01] = +{ + 0x29 +}; + + +static CBIOS_U8 SetBacklightBuf[0x02] = +{ + 0x51, 0xFF +}; +static CBIOS_U8 GetBacklightBuf[0x01] = +{ + 0x52 +}; + +static CBIOS_U8 PanelAddrMode[0x02] = +{ + 0x36, 0x40 +}; + + +static CBIOS_U8 PWMBuf[0x2] = +{ + 0x53, 0x24 +}; + + +static CBIOS_U8 BrightnessCtrlBuf[0x2] = +{ + 0x55, 0x00 +}; + + +static CBIOS_U8 TEEnable[0x02] = +{ + 0x35, 0x00 +}; + + +static CBIOS_DSI_CMD_DESC R63319_PowerOn_CmdList[] = +{ + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 120, sizeof(ExitSleepBuf), ExitSleepBuf, {0}}, + + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(PWMBuf), PWMBuf, {0}}, + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(BrightnessCtrlBuf), BrightnessCtrlBuf, {0}}, + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(TEEnable), TEEnable, {0}}, + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(PanelAddrMode),PanelAddrMode, {0}}, + + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DisplayOnBuf), DisplayOnBuf, {0}}, + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(SetBacklightBuf), SetBacklightBuf, {0}}, +}; + +static CBIOS_DSI_CMD_DESC R63319_PowerOff_CmdList[] = +{ + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DisplayOffBuf), DisplayOffBuf, {0}}, + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 120, sizeof(EnterSleepBuf), EnterSleepBuf, {0}}, +}; + +static CBIOS_DSI_CMD_DESC R63319_DisplayOn_CmdList[] = +{ + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 10, sizeof(DisplayOnBuf), DisplayOnBuf, {0}}, +}; + +static CBIOS_DSI_CMD_DESC R63319_DisplayOff_CmdList[] = +{ + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 10, sizeof(DisplayOffBuf), DisplayOffBuf, {0}}, +}; + +static CBIOS_DSI_CMD_DESC R63319_Backlight_CmdList[] = +{ + {1, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(SetBacklightBuf), SetBacklightBuf, {0}}, +}; + +// important note: +// These are indexes of below gpio ports table with corresponding usage. So they must keep synchronization with blow +// gpio ports table. If gpio ports table changes with usage, these indexes must be changed too. +#define R63319_INDEX_IOVDD 0 +#define R63319_INDEX_DCDCEN 1 +#define R63319_INDEX_RESX 2 +#define R63319_INDEX_AVDD 3 + +// GPIO PORTS for board version A0 & A1 +GPIO_PORT R63319_GPIO_PORTS_A1[] = +{ + {CBIOS_GPIO_AUD, 18}, //IOVDD + {CBIOS_GPIO_GFX, 3}, //DCDC_EN + {CBIOS_GPIO_GFX, 10}, //RESX + {CBIOS_GPIO_GFX, 11}, //AVDD +}; + +// GPIO PORTS for board version A2 +GPIO_PORT R63319_GPIO_PORTS_A2[] = +{ + {CBIOS_GPIO_VSUS, 48}, //IOVDD + {CBIOS_GPIO_GFX, 2}, //DCDC_EN + {CBIOS_GPIO_VSUS, 33}, //RESX + {CBIOS_GPIO_GFX, 1}, //AVDD +}; + + +GPIO_PORT R63319_GPIO_PORTS_EVT[] = +{ + {CBIOS_GPIO_VSUS, 47}, //IOVDD + {CBIOS_GPIO_GFX, 2}, //DCDC_EN + {CBIOS_GPIO_VSUS, 33}, //RESX + {CBIOS_GPIO_GFX, 1}, //AVDD +}; + + +extern CBIOS_DSI_PANEL_DESC R63319_Panel_Desc; + +static CBIOS_STATUS cbR63319_GetGpioPorts(PCBIOS_VOID pvcbe, PGPIO_PORT *pGpioPorts, CBIOS_U32 *pNumPorts) +{ + CBIOS_BOARD_VERSION BoardVersion = cbGetBoardVersion(pvcbe); + CBIOS_STATUS Status = CBIOS_OK; + + *pGpioPorts = CBIOS_NULL; + *pNumPorts = 0; + if (BoardVersion <= CBIOS_BOARD_VERSION_1) + { + *pGpioPorts = R63319_GPIO_PORTS_A1; + *pNumPorts = sizeofarray(R63319_GPIO_PORTS_A1); + } + else if (BoardVersion == CBIOS_BOARD_VERSION_2) + { + *pGpioPorts = R63319_GPIO_PORTS_A2; + *pNumPorts = sizeofarray(R63319_GPIO_PORTS_A2); + } + else if(BoardVersion == CBIOS_BOARD_VERSION_EVT) + { + *pGpioPorts = R63319_GPIO_PORTS_EVT; + *pNumPorts = sizeofarray(R63319_GPIO_PORTS_EVT); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: invalid board version: 0x%x!\n", FUNCTION_NAME, BoardVersion)); + Status = CBIOS_ER_INTERNAL; + } + + return Status; +} + +CBIOS_STATUS cbR63319_SetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 BrightnessValue) +{ + PCBIOS_DSI_CONFIG pDSIConfig = &(R63319_Panel_Desc.DSIConfig); + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U8* pDataBuffer = CBIOS_NULL; + CBIOS_U8 BlValue = (CBIOS_U8)BrightnessValue; + + if (BrightnessValue < pDSIConfig->BacklightMin) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "DSI panel backlight value is smaller than min value! \n")); + BlValue = (CBIOS_U8)pDSIConfig->BacklightMin; + } + + if (BrightnessValue > pDSIConfig->BacklightMax) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "DSI panel backlight value is greater than max value! \n")); + BlValue = (CBIOS_U8)pDSIConfig->BacklightMax; + } + + pDataBuffer = R63319_Backlight_CmdList[0].pDataBuf; + pDataBuffer[1] = BlValue; + Status = cbDSI_SendCmdList(pvcbe, R63319_Backlight_CmdList, sizeofarray(R63319_Backlight_CmdList)); + + return Status; +} + + +CBIOS_STATUS cbR63319_GetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 *pBrightnessValue) +{ + CBIOS_DSI_READ_PARA_INTERNAL DSIReadPara = {0}; + CBIOS_U32 BacklightValue = 0; + CBIOS_U32 Status; + + DSIReadPara.DSIIndex = DSI_INDEX1; + DSIReadPara.VirtualCh = 0; + DSIReadPara.ContentType = 0; + DSIReadPara.DataLen = sizeof(GetBacklightBuf); + DSIReadPara.pDataBuf = GetBacklightBuf; + DSIReadPara.pReceivedPayloadBuf = (CBIOS_U8 *)&BacklightValue; + DSIReadPara.ReceivedPayloadLen = sizeof(BacklightValue); + DSIReadPara.bHSModeOnly = 0; + + Status = cbDSI_SendReadCmd(pvcbe, &DSIReadPara); + + if (Status == CBIOS_OK) + { + *pBrightnessValue = BacklightValue; + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "Can't get backlight value! \n")); + } + + return Status; +} + +CBIOS_STATUS cbR63319_PanelPowerOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn) +{ + CBIOS_BOARD_VERSION BoardVersion = CBIOS_BOARD_VERSION_MAX; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 NumPorts = 0; + PGPIO_PORT pR63319GpioPorts = CBIOS_NULL; + + + cbR63319_GetGpioPorts(pvcbe, &pR63319GpioPorts, &NumPorts); + + if (pR63319GpioPorts == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: cannot get GPIO ports for R63319\n", FUNCTION_NAME)); + Status = CBIOS_ER_INTERNAL; + return Status; + } + + BoardVersion = cbGetBoardVersion(pvcbe); + + if(BoardVersion == CBIOS_BOARD_VERSION_EVT) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "-------board version: EVT-------\n")); + if(bTurnOn) + { + //IOVDD high + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_IOVDD].GPIOType, pR63319GpioPorts[R63319_INDEX_IOVDD].GPIOIndex, 1); + //IOVDD high --> AVDD high > 0ms + cbDelayMilliSeconds(2); + //AVDD high + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_AVDD].GPIOType, pR63319GpioPorts[R63319_INDEX_AVDD].GPIOIndex, 1); + //AVDD high --> DCDC_EN > 2ms + cbDelayMilliSeconds(6); + //DCDC_EN, GFX_GPIO3 + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_DCDCEN].GPIOType, pR63319GpioPorts[R63319_INDEX_DCDCEN].GPIOIndex, 1); + //DCDC_EN --> RESX > 2ms + cbDelayMilliSeconds(6); + //RESX, GFX_GPIO10 + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_RESX].GPIOType, pR63319GpioPorts[R63319_INDEX_RESX].GPIOIndex, 1); + //RSP LCD driver status reset> 5ms + cbDelayMilliSeconds(12); + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_RESX].GPIOType, pR63319GpioPorts[R63319_INDEX_RESX].GPIOIndex, 0); + //RSP LCD driver status reset> 5ms + cbDelayMilliSeconds(12); + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_RESX].GPIOType, pR63319GpioPorts[R63319_INDEX_RESX].GPIOIndex, 1); + //RSP LCD driver status reset> 5ms + cbDelayMilliSeconds(12); + + Status = cbDSI_SendCmdList(pvcbe, R63319_PowerOn_CmdList, sizeofarray(R63319_PowerOn_CmdList)); + } + else + { + Status = cbDSI_SendCmdList(pvcbe, R63319_PowerOff_CmdList, sizeofarray(R63319_PowerOff_CmdList)); + + //DCDC_EN low + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_DCDCEN].GPIOType, pR63319GpioPorts[R63319_INDEX_DCDCEN].GPIOIndex, 0); + //DCDC_EN low --> AVDD low > 1ms + cbDelayMilliSeconds(4); + //AVDD low, GFX_GPIO11 + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_AVDD].GPIOType, pR63319GpioPorts[R63319_INDEX_AVDD].GPIOIndex, 0); + //AVDD low --> IOVDD low > 0ms + cbDelayMilliSeconds(2); + //IOVDD low + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_IOVDD].GPIOType, pR63319GpioPorts[R63319_INDEX_IOVDD].GPIOIndex, 0); + } + } + + else + { + if(bTurnOn) + { + //IOVDD high + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_IOVDD].GPIOType, pR63319GpioPorts[R63319_INDEX_IOVDD].GPIOIndex, 1); + //IOVDD high --> AVDD high > 0ms + cbDelayMilliSeconds(1); + //AVDD high + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_AVDD].GPIOType, pR63319GpioPorts[R63319_INDEX_AVDD].GPIOIndex, 1); + //AVDD high --> DCDC_EN > 2ms + cbDelayMilliSeconds(3); + //DCDC_EN, GFX_GPIO3 + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_DCDCEN].GPIOType, pR63319GpioPorts[R63319_INDEX_DCDCEN].GPIOIndex, 1); + //DCDC_EN --> RESX > 2ms + cbDelayMilliSeconds(3); + //RESX, GFX_GPIO10 + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_RESX].GPIOType, pR63319GpioPorts[R63319_INDEX_RESX].GPIOIndex, 1); + //RSP LCD driver status reset> 5ms + cbDelayMilliSeconds(6); + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_RESX].GPIOType, pR63319GpioPorts[R63319_INDEX_RESX].GPIOIndex, 0); + //RSP LCD driver status reset> 5ms + cbDelayMilliSeconds(6); + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_RESX].GPIOType, pR63319GpioPorts[R63319_INDEX_RESX].GPIOIndex, 1); + //RSP LCD driver status reset> 5ms + cbDelayMilliSeconds(6); + + Status = cbDSI_SendCmdList(pvcbe, R63319_PowerOn_CmdList, sizeofarray(R63319_PowerOn_CmdList)); + } + else + { + Status = cbDSI_SendCmdList(pvcbe, R63319_PowerOff_CmdList, sizeofarray(R63319_PowerOff_CmdList)); + + //DCDC_EN low + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_DCDCEN].GPIOType, pR63319GpioPorts[R63319_INDEX_DCDCEN].GPIOIndex, 0); + //DCDC_EN low --> AVDD low > 1ms + cbDelayMilliSeconds(2); + //AVDD low, GFX_GPIO11 + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_AVDD].GPIOType, pR63319GpioPorts[R63319_INDEX_AVDD].GPIOIndex, 0); + //AVDD low --> IOVDD low > 0ms + cbDelayMilliSeconds(1); + //IOVDD low + cbWriteGPIO(pvcbe, pR63319GpioPorts[R63319_INDEX_IOVDD].GPIOType, pR63319GpioPorts[R63319_INDEX_IOVDD].GPIOIndex, 0); + + } + } + return Status; +} + +CBIOS_STATUS cbR63319_SetCABC(PCBIOS_VOID pvcbe,CBIOS_U32 CabcValue) +{ + + return CBIOS_OK; +} + +CBIOS_STATUS cbR63319_Init(PCBIOS_VOID pvcbe) +{ + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 Requested = 0, i = 0, NumPorts = 0; + PGPIO_PORT pR63319GpioPorts = CBIOS_NULL; + + cbR63319_GetGpioPorts(pvcbe, &pR63319GpioPorts, &NumPorts); + + if (pR63319GpioPorts == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: cannot get GPIO ports for R63319\n", FUNCTION_NAME)); + Status = CBIOS_ER_INTERNAL; + return Status; + } + + for (i = 0; i < NumPorts; i++) + { + if (cbRequestGPIO(pvcbe, pR63319GpioPorts[i].GPIOType, pR63319GpioPorts[i].GPIOIndex) == CBIOS_OK) + { + cbSetGPIODirectionOutput(pvcbe, pR63319GpioPorts[i].GPIOType, pR63319GpioPorts[i].GPIOIndex, 0); + Requested |= (1 << i); + Status = CBIOS_OK; + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "Request GPIO fail! Type: %x, Index: %d\n", pR63319GpioPorts[i].GPIOType, pR63319GpioPorts[i].GPIOIndex)); + Status = CBIOS_ER_INTERNAL; + break; + } + } + + if (Status != CBIOS_OK)//request fail, free requested GPIOs + { + for (i = 0; i < NumPorts; i++) + { + if (i & Requested) + { + cbFreeGPIO(pvcbe, pR63319GpioPorts[i].GPIOType, pR63319GpioPorts[i].GPIOIndex); + } + } + } + + return Status; +} + +CBIOS_STATUS cbR63319_DeInit(PCBIOS_VOID pvcbe) +{ + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 i = 0, NumPorts = 0; + PGPIO_PORT pR63319GpioPorts = CBIOS_NULL; + + cbR63319_GetGpioPorts(pvcbe, &pR63319GpioPorts, &NumPorts); + + if (pR63319GpioPorts == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: cannot get GPIO ports for R63319\n", FUNCTION_NAME)); + Status = CBIOS_ER_INTERNAL; + return Status; + } + + for (i = 0; i < NumPorts; i++) + { + cbFreeGPIO(pvcbe, pR63319GpioPorts[i].GPIOType, pR63319GpioPorts[i].GPIOIndex); + } + + return Status; +} + +CBIOS_DSI_PANEL_DESC R63319_Panel_Desc = +{ + /*.VersionNum = */CBIOS_DSI_VERSION, + /*.DSIConfig =*/ + { + /*.DSIMode = */CBIOS_DSI_VIDEOMODE, + /*.ClkLaneMode = */CBIOS_DSI_CLK_LANE_HARDWARE_CTL, + /*.SyncPacketType = */CBIOS_DSI_SYNC_EVENT, + /*.TEType = */CBIOS_DSI_TE_TRIGGER, + /*.TurnAroundTimeout = */0x1000000, + /*.HS_TXTimeout = */0x1000000, + /*.LP_RXTimeout = */0x1000000, + /*.DMAThreshold = */0x400, + /*.BacklightMax = */255, + /*.BacklightMin = */0, + /*.ConfigFlags =*/ {0x3E,}, + }, + /*.DSIPanelTbl =*/ + { + /*.LaneNum = */4, + /*.OutBpp = */24, + /*.PanelTiming =*/ + { + /*.XResolution = */1536, + /*.YResolution = */2048, +#ifdef ELT2K_DIU_FPGA + /*.DCLK = */5400, //540000, 54MHz +#else + + /*.DCLK = */24775, // 247.75MHz +#endif + /*.HorTotal = */1536 + 300 + 76 + 80, + /*.HorDisEnd = */1536, + /*.HorBStart = */1536, + /*.HorBEnd = */1992, + /*.HorSyncStart = */(1536 + 300), + /*.HorSyncEnd = */(1536 + 300 + 76), + /*.VerTotal = */2048 + 12 + 4 + 4, + /*.VerDisEnd = */2048, + /*.VerBStart = */2048, + /*.VerBEnd = */2068, + /*.VerSyncStart = */(2048 + 12), + /*.VerSyncEnd = */(2048 + 12 + 4), + /*.HVPolarity = */DSI_HPOSITIVE + DSI_VPOSITIVE, + }, + }, + /*.PowerOnCmdListSize = */sizeofarray(R63319_PowerOn_CmdList), + /*.PowerOffCmdListSize = */sizeofarray(R63319_PowerOff_CmdList), + /*.DisplayOnCmdListSize = */sizeofarray(R63319_DisplayOn_CmdList), + /*.DisplayOffCmdListSize = */sizeofarray(R63319_DisplayOff_CmdList), + /*.BacklightCmdListSize = */sizeofarray(R63319_Backlight_CmdList), + /*.pPowerOnCmdList = */R63319_PowerOn_CmdList, + /*.pPowerOffCmdList = */R63319_PowerOff_CmdList, + /*.pDisplayOnCmdList = */R63319_DisplayOn_CmdList, + /*.pDisplayOffCmdList = */R63319_DisplayOff_CmdList, + /*.pBacklightCmdList = */R63319_Backlight_CmdList, + /*.pFnDSIPanelOnOff = */cbR63319_PanelPowerOnOff, + /*.pFnDSIPanelSetBacklight = */cbR63319_SetBacklight, + /*.pFnDSIPanelGetBacklight = */cbR63319_GetBacklight, + /*.pFnDSIPanelSetCABC = */cbR63319_SetCABC, + /*.pFnDSIPanelInit = */cbR63319_Init, + /*.pFnDSIPanelDeInit = */cbR63319_DeInit, +}; diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosR63417.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosR63417.c new file mode 100644 index 0000000000000..4309fdc6e9d15 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/DSIPanel/CBiosR63417.c @@ -0,0 +1,255 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** R63417 type DSI panel descriptor definition, +** which contains panel config and command lists. +** +** NOTE: +** +******************************************************************************/ + + +#include "CBiosDSIPanel.h" +#include "CBiosDSI.h" + +static CBIOS_U8 PasswordBuf[0x2] = +{ + 0xB0, 0x00 +}; + +static CBIOS_U8 RemoveNVMBuf[0x2] = +{ + 0xD6, 0x01 +}; + +static CBIOS_U8 CommonSetBuf[0x18] = +{ + 0xCE, 0x6C, 0x40, 0x43, + 0x49, 0x55, 0x62, 0x71, + 0x82, 0x94, 0xA8, 0xB9, + 0xCB, 0xDB, 0xE9, 0xF5, + 0xFC, 0xFF, 0x04, 0xD3, + 0x00, 0x00, 0x54, 0x24 +}; + +static CBIOS_U8 CABCStillBuf[0x07] = +{ + 0xB9, 0x03, 0x82, 0x3C, + 0x10, 0x3C, 0x87 +}; + +static CBIOS_U8 CABCMovieBuf[0x07] = +{ + 0xBA, 0x03, 0x78, 0x64, + 0x10, 0x64, 0xB4 +}; + +static CBIOS_U8 SREManual0Buf[0x04] = +{ + 0xBB, 0x01, 0x00, 0x00 +}; + +static CBIOS_U8 M7ColorEnhanceBuf[0x21] = +{ + 0xCA, 0x01, 0x02, 0x9A, + 0xA4, 0xB8, 0xB4, 0xB0, + 0xA4, 0x08, 0x28, 0x05, + 0x87, 0xB0, 0x50, 0x01, + 0xFF, 0x05, 0xF8, 0x0C, + 0x0C, 0x50, 0x40, 0x13, + 0x13, 0xF0, 0x08, 0x10, + 0x10, 0x3F, 0x3F, 0x3F, + 0x3F +}; + +static CBIOS_U8 BrightnessCtrlBuf[0x2] = +{ + 0x55, 0x42 +}; + +static CBIOS_U8 PWMBuf[0x2] = +{ + 0x53, 0x0C +}; + +static CBIOS_U8 BlueShiftBuf1[0x1F] = +{ + 0xC7, 0x01, 0x0B, 0x12, + 0x1B, 0x2A, 0x3A, 0x45, + 0x56, 0x3A, 0x42, 0x4E, + 0x5B, 0x64, 0x6C, 0x75, + 0x01, 0x0B, 0x12, 0x1A, + 0x29, 0x37, 0x41, 0x52, + 0x36, 0x3F, 0x4C, 0x59, + 0x62, 0x6A, 0x74 +}; + +static CBIOS_U8 BlueShiftBuf2[0x14] = +{ + 0xC8, 0x01, 0x00, 0xF4, + 0x00, 0x00, 0xFC, 0x00, + 0x00, 0xF7, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFC, 0x0F +}; + +static CBIOS_U8 SourceTimingBuf[0x17]= +{ + 0xC4, 0x70, 0x0C, 0x0C, + 0x55, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x05, + 0x00, 0x0C, 0x0C, 0x55, + 0x55, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x05 +}; + +static CBIOS_U8 LockBuf[0x02] = +{ + 0xB0, 0x03 +}; + +static CBIOS_U8 NopBuf[0x02] = +{ + 0x00, 0x00 +}; + +static CBIOS_U8 EnterSleepBuf[0x01] = +{ + 0x10 +}; + +static CBIOS_U8 ExitSleepBuf[0x01] = +{ + 0x11 +}; + +static CBIOS_U8 DisplayOffBuf[0x01] = +{ + 0x28 +}; + +static CBIOS_U8 DisplayOnBuf[0x01] = +{ + 0x29 +}; + +static CBIOS_U8 BacklightBuf[0x02] = +{ + 0x51, 0xFF +}; + + +static CBIOS_DSI_CMD_DESC R63417_PowerOn_CmdList[] = +{ + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(PasswordBuf), PasswordBuf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(RemoveNVMBuf), RemoveNVMBuf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(CommonSetBuf), CommonSetBuf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(CABCStillBuf), CABCStillBuf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(CABCMovieBuf), CABCMovieBuf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(SREManual0Buf), SREManual0Buf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(M7ColorEnhanceBuf), M7ColorEnhanceBuf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(BrightnessCtrlBuf), BrightnessCtrlBuf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(PWMBuf), PWMBuf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(BlueShiftBuf1), BlueShiftBuf1, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(BlueShiftBuf2), BlueShiftBuf2, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(SourceTimingBuf), SourceTimingBuf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_GEN, 0, sizeof(LockBuf), LockBuf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(NopBuf), NopBuf, {1}}, + {0, 0, CBIOS_DSI_LONG_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(NopBuf), NopBuf, {1}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 120, sizeof(ExitSleepBuf), ExitSleepBuf, {1}}, +}; + +static CBIOS_DSI_CMD_DESC R63417_PowerOff_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(DisplayOffBuf), DisplayOffBuf, {1}}, + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 120, sizeof(EnterSleepBuf), EnterSleepBuf, {1}}, +}; + +static CBIOS_DSI_CMD_DESC R63417_DisplayOn_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 10, sizeof(DisplayOnBuf), DisplayOnBuf, {1}}, +}; + +static CBIOS_DSI_CMD_DESC R63417_DisplayOff_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 10, sizeof(DisplayOffBuf), DisplayOffBuf, {1}}, +}; + +static CBIOS_DSI_CMD_DESC R63417_Backlight_CmdList[] = +{ + {0, 0, CBIOS_DSI_SHORT_PACKET, CBIOS_DSI_CONTENT_DCS, 0, sizeof(BacklightBuf), BacklightBuf, {1}}, +}; + +CBIOS_DSI_PANEL_DESC R63417_Panel_Desc = +{ + /*.VersionNum = */CBIOS_DSI_VERSION, + /*.DSIConfig = */ + { + /*.DSIMode = */CBIOS_DSI_CMDMODE, + /*.ClkLaneMode = */CBIOS_DSI_CLK_LANE_HARDWARE_CTL, + /*.SyncPacketType = */CBIOS_DSI_SYNC_PULSE, + /*.TEType = */CBIOS_DSI_TE_TRIGGER, + /*.TurnAroundTimeout = */0x1000000, + /*.HS_TXTimeout = */0x1000000, + /*.LP_RXTimeout = */0x1000000, + /*.DMAThreshold = */0x400, + /*.BacklightMax = */255, + /*.BacklightMin = */0, + /*.ConfigFlags = */{0x10,}, + }, + /*.DSIPanelTbl = */ + { + /*.LaneNum = */4, + /*.OutBpp = */24, + /*.PanelTiming = */ + { + /*.XResolution = */1080, + /*.YResolution = */1920, + /*.DCLK = */14040, + /*.HorTotal = */1200, + /*.HorDisEnd = */1080, + /*.HorBStart = */1080, + /*.HorBEnd = */1200, + /*.HorSyncStart = */(1080+64), + /*.HorSyncEnd = */(1080+64+8), + /*.VerTotal = */1950, + /*.VerDisEnd = */1920, + /*.VerBStart = */1920, + /*.VerBEnd = */1950, + /*.VerSyncStart = */(1920+16), + /*.VerSyncEnd = */(1920+16+2), + /*.HVPolarity = */DSI_VNEGATIVE + DSI_HNEGATIVE, + }, + }, + /*.PowerOnCmdListSize = */sizeofarray(R63417_PowerOn_CmdList), + /*.PowerOffCmdListSize = */sizeofarray(R63417_PowerOff_CmdList), + /*.DisplayOnCmdListSize = */sizeofarray(R63417_DisplayOn_CmdList), + /*.DisplayOffCmdListSize = */sizeofarray(R63417_DisplayOff_CmdList), + /*.BacklightCmdListSize = */sizeofarray(R63417_Backlight_CmdList), + /*.pPowerOnCmdList = */R63417_PowerOn_CmdList, + /*.pPowerOffCmdList = */R63417_PowerOff_CmdList, + /*.pDisplayOnCmdList = */R63417_DisplayOn_CmdList, + /*.pDisplayOffCmdList = */R63417_DisplayOff_CmdList, + /*.pBacklightCmdList = */R63417_Backlight_CmdList, + /*.pFnDSIPanelOnOff = */CBIOS_NULL, + /*.pFnDSIPanelSetBacklight = */CBIOS_NULL, + /*.pFnDSIPanelGetBacklight = */CBIOS_NULL, + /*.pFnDSIPanelSetCABC = */CBIOS_NULL, + /*.pFnDSIPanelInit = */CBIOS_NULL, + /*.pFnDSIPanelDeInit = */CBIOS_NULL, +}; + diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/EDPPanel/CBiosITN156.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/EDPPanel/CBiosITN156.c new file mode 100644 index 0000000000000..03a29aadf8775 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/EDPPanel/CBiosITN156.c @@ -0,0 +1,145 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +#include "../../../Hw/HwCallback/CBiosCallbacksHw.h" +#include "../CBiosEDPPanel.h" + +// eDP panel pre-initialization, if something must be done before detecting, do here, and set ITN156_Panel_Desc.EDPPreCaps.IsNeedPreInit = CBIOS_TRUE. +CBIOS_STATUS INT156_PreInit(PCBIOS_VOID pvcbe) +{ + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + // use cbRequestGPIO to request GPIO + // use cbSetGPIODirectionOutput to set GPIO direction + + return Status; +} + + +// eDP panel initialization +CBIOS_STATUS INT156_Init(PCBIOS_VOID pvcbe) +{ + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + // use cbRequestGPIO to request GPIO + // use cbSetGPIODirectionOutput to set GPIO direction + + return Status; +} + + +CBIOS_STATUS INT156_DeInit(PCBIOS_VOID pvcbe) +{ + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + // use cbFreeGPIO to free GPIO + + return Status; +} + + +// set panel backlight +CBIOS_STATUS INT156_SetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 BacklightValue) +{ + CBIOS_U16 PwmFrequencyCounter = 0xff; //frequency = 27Mhz / PwmFrequencyCounter:about 105khz + CBIOS_U16 DutyCycle = (CBIOS_U16)BacklightValue; // 0 ~ 255 means:0% ~ 100% + CBIOS_U32 RegValue = 0; + + RegValue = 0; // PWM pulse value is mm346c[15:0] + cbWriteRegisterU32WithMask(pvcbe, CBIOS_REGISTER_MMIO, 0x8180, RegValue, 0); + + //set PWM frequency counter + RegValue = PwmFrequencyCounter << 16; //mm346c[31:16]:PwmFrequencyCounter + cbWriteRegisterU32WithMask(pvcbe, CBIOS_REGISTER_MMIO, 0x346C, RegValue, 0x0000FFFF); + + //duty cycle + RegValue = 8 << 4; // mm3470[7:4] = 4'b1000: pwm_duty = {8'b0, mm346c[15:8]} + cbWriteRegisterU32WithMask(pvcbe, CBIOS_REGISTER_MMIO, 0x3470, RegValue, 0xFFFFFF0F); + + RegValue = ((CBIOS_U16)DutyCycle) << 8;//mm346c[15:0] : PWM pulse value + cbWriteRegisterU32WithMask(pvcbe, CBIOS_REGISTER_MMIO, 0x346C, RegValue, 0xFFFF0000); + + RegValue = cbReadRegisterU32(pvcbe, CBIOS_REGISTER_MMIO, 0x3470); + if(!(RegValue & 0x1)) //if pwm is not enabled, enable it. mm346c[0]:enable/disable pwm + { + RegValue = 0x1; + cbWriteRegisterU32WithMask(pvcbe, CBIOS_REGISTER_MMIO, 0x3470, RegValue, 0xFFFFFFFE); + } + + return CBIOS_OK; +} + +// get panel backlight +CBIOS_STATUS INT156_GetBacklight(PCBIOS_VOID pvcbe, CBIOS_U32 *pBacklightValue) +{ + CBIOS_U16 DutyCycle = 0; + CBIOS_U32 RegValue = 0; + + RegValue = cbReadRegisterU32(pvcbe, CBIOS_REGISTER_MMIO, 0x346C); + + DutyCycle = (CBIOS_U16)(RegValue & 0xFFFF); //mm346c[15:0] + + //reflect it to 0~255 + *pBacklightValue = (CBIOS_U8)(DutyCycle >> 8); + + return CBIOS_OK; +} + +// eDP panel power & diaplay onoff +CBIOS_STATUS INT156_OnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn) +{ + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + // use cbWriteGPIO to write GPIO + // use cbDelayMilliSeconds to delay + + if(bTurnOn) + { + INT156_SetBacklight(pvcbe, 255); //set max backlight when turn on + } + else + { + INT156_SetBacklight(pvcbe, 0); //set min backlight when turn off + } + + return Status; +} + + +CBIOS_EDP_PANEL_DESC ITN156_Panel_Desc = +{ + /*.VersionNum = */CBIOS_EDP_VERSION, + /*.MonitorID = */"SDC4852", + /*.EDPPreCaps =*/ + { + /*.IsNeedPreInit = */CBIOS_TRUE, + /*.pFnEDPPanelPreInit =*/ INT156_PreInit, + }, + /*.EDPCaps = */ + { + /*.LinkSpeed = */2700000, + /*.LaneNum = */4, + /*.BacklightMax = */255, + /*.BacklightMin = */0, + /*.Flags = */0x2,//backlight control = 0, use hard code link para + }, + /*.pFnEDPPanelInit = */INT156_Init, + /*.pFnEDPPanelDeInit = */INT156_DeInit, + /*.pFnEDPPanelOnOff = */INT156_OnOff, + /*.pFnEDPPanelSetBacklight = */INT156_SetBacklight, + /*.pFnEDPPanelGetBacklight = */INT156_GetBacklight, +}; + + diff --git a/drivers/gpu/drm/arise/cbios/Device/Port/CBiosCRT.c b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosCRT.c new file mode 100644 index 0000000000000..62dffd3ec8556 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosCRT.c @@ -0,0 +1,137 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CRT port interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "CBiosCRT.h" + +static CBIOS_BOOL cbCRTPort_DeviceDetect(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bHardcodeDetected, CBIOS_U32 FullDetect) +{ + PCBIOS_CRT_CONTEXT pCrtContext = container_of(pDevCommon, PCBIOS_CRT_CONTEXT, Common); + CBIOS_BOOL bConnected = CBIOS_FALSE; + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_CRT))) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return bConnected; + } + + if ((!bConnected) && (pCrtContext->Common.SupportMonitorType & CBIOS_MONITOR_TYPE_CRT)) + { + bConnected = cbCRTMonitor_Detect(pcbe, &pCrtContext->CRTMonitorContext, bHardcodeDetected, FullDetect); + } + + return bConnected; +} + +static CBIOS_VOID cbCRTPort_OnOff(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bOn) +{ + PCBIOS_CRT_CONTEXT pCrtContext = container_of(pDevCommon, PCBIOS_CRT_CONTEXT, Common); + CBIOS_U32 IGAIndex = CBIOS_MODULE_INDEX_INVALID; + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_CRT))) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Invalid Para, will skip CRT ON_OFF!\n", FUNCTION_NAME)); + return; + } + + IGAIndex = pDevCommon->DispSource.ModuleList.IGAModule.Index; + + cbCRTMonitor_OnOff(pcbe, &pCrtContext->CRTMonitorContext, bOn, (CBIOS_U8)IGAIndex); + + pDevCommon->PowerState = (bOn)? CBIOS_PM_ON : CBIOS_PM_OFF; + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO),"%s: status = %s.\n", FUNCTION_NAME, (bOn)? "On" : "Off")); +} + +static CBIOS_VOID cbCRTPort_SetMode(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_CRT_CONTEXT pCrtContext = container_of(pDevCommon, PCBIOS_CRT_CONTEXT, Common); + CBIOS_MONITOR_TYPE MonitorType = CBIOS_MONITOR_TYPE_NONE; + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_CRT))) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return ; + } + + MonitorType = pDevCommon->CurrentMonitorType; + + if (MonitorType == CBIOS_MONITOR_TYPE_CRT) + { + cbCRTMonitor_SetMode(pcbe, &pCrtContext->CRTMonitorContext, pModeParams); + } +} + +PCBIOS_DEVICE_COMMON cbCRTPort_Init(PCBIOS_VOID pvcbe, PVCP_INFO pVCP, CBIOS_ACTIVE_TYPE DeviceType) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CRT_CONTEXT pCrtContext = CBIOS_NULL; + PCBIOS_DEVICE_COMMON pDeviceCommon = CBIOS_NULL; + + if(DeviceType & ~CBIOS_TYPE_CRT) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: unsupported device type!!!\n", FUNCTION_NAME)); + return CBIOS_NULL; + } + + pCrtContext = cb_AllocateNonpagedPool(sizeof(CBIOS_CRT_CONTEXT)); + + if(pCrtContext == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: pCrtContext allocate error!!!\n", FUNCTION_NAME)); + return CBIOS_NULL; + } + + pDeviceCommon = &pCrtContext->Common; + pDeviceCommon->DeviceType = DeviceType; + pDeviceCommon->SupportMonitorType = cbGetSupportMonitorType(pcbe, DeviceType); + pDeviceCommon->I2CBus = pVCP->CRTCharByte & I2CBUSMASK; + pDeviceCommon->HPDPin = pVCP->CRTInterruptPort & HPDPORT_MASK; + pDeviceCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_NONE; + pDeviceCommon->PowerState = CBIOS_PM_INVALID; + + cbInitialModuleList(&pDeviceCommon->DispSource.ModuleList); + + pDeviceCommon->pfncbDeviceDetect = (PFN_cbDeviceDetect)cbCRTPort_DeviceDetect; + pDeviceCommon->pfncbDeviceOnOff = (PFN_cbDeviceOnOff)cbCRTPort_OnOff; + pDeviceCommon->pfncbDeviceSetMode = (PFN_cbDeviceSetMode)cbCRTPort_SetMode; + + pCrtContext->CRTMonitorContext.pDevCommon = pDeviceCommon; + + return pDeviceCommon; +} + +CBIOS_VOID cbCRTPort_DeInit(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_CRT_CONTEXT pCrtContext = container_of(pDevCommon, PCBIOS_CRT_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_CRT))) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return; + } + + cb_FreePool(pCrtContext); + pCrtContext = CBIOS_NULL; + +} diff --git a/drivers/gpu/drm/arise/cbios/Device/Port/CBiosCRT.h b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosCRT.h new file mode 100644 index 0000000000000..20baf6acb3596 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosCRT.h @@ -0,0 +1,39 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CRT port interface function prototype and CBIOS_CRT_CONTEXT definition. +** +** NOTE: +** CRT port ONLY parameters SHOULD be added to CBIOS_CRT_CONTEXT. +******************************************************************************/ + +#ifndef _CBIOS_CRT_H_ +#define _CBIOS_CRT_H_ + +#include "../Monitor/CBiosCRTMonitor.h" + +typedef struct _CBIOS_CRT_CONTEXT +{ + CBIOS_DEVICE_COMMON Common; + + // monitor contexts + CBIOS_CRT_MONITOR_CONTEXT CRTMonitorContext; +}CBIOS_CRT_CONTEXT, *PCBIOS_CRT_CONTEXT; + +PCBIOS_DEVICE_COMMON cbCRTPort_Init(PCBIOS_VOID pvcbe, PVCP_INFO pVCP, CBIOS_ACTIVE_TYPE DeviceType); +CBIOS_VOID cbCRTPort_DeInit(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +#endif diff --git a/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDP.c b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDP.c new file mode 100644 index 0000000000000..6f58c8fcc9f93 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDP.c @@ -0,0 +1,640 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DP port interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "CBiosDP.h" +#include "../../Hw/HwBlock/CBiosDIU_DP.h" +#include "../../Hw/HwBlock/CBiosDIU_HDCP.h" +#include "../../Hw/HwBlock/CBiosDIU_HDMI.h" +#include "../../Hw/CBiosHwShare.h" + +PCBIOS_VOID cbDPPort_GetDPMonitorContext(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return CBIOS_NULL; + } + if (pDpContext->Common.SupportMonitorType & (CBIOS_MONITOR_TYPE_DP | CBIOS_MONITOR_TYPE_PANEL)) + { + return &(pDpContext->DPMonitorContext); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: wrong support monitor type 0x%x\n", FUNCTION_NAME, pDpContext->Common.SupportMonitorType)); + return CBIOS_NULL; + } +} + +PCBIOS_VOID cbDPPort_GetHDMIMonitorContext(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return CBIOS_NULL; + } + if ((pDpContext->Common.CurrentMonitorType == CBIOS_MONITOR_TYPE_HDMI) || (pDpContext->Common.CurrentMonitorType == CBIOS_MONITOR_TYPE_DVI)) + { + return &(pDpContext->HDMIMonitorContext); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: wrong monitor type 0x%x\n", FUNCTION_NAME, pDpContext->Common.CurrentMonitorType)); + return CBIOS_NULL; + } +} + +CBIOS_BOOL cbDPPort_IsDeviceInDpMode(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + CBIOS_BOOL isDpMode = CBIOS_FALSE; + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + if (pDevCommon->DeviceType & ALL_DP_TYPES) + { + isDpMode = !pDpContext->DPPortParams.bDualMode; + } + else + { + isDpMode = CBIOS_FALSE; + } + + return isDpMode; +} + +CBIOS_STATUS cbDPPort_Isr(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_ISR_PARA pDPIsrPara) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDPMonitor_Isr(pvcbe, &pDpContext->DPMonitorContext, pDPIsrPara); +} + +CBIOS_BOOL cbDPPort_WorkThreadMainFunc(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_WORKTHREAD_PARA pDPWorkThreadPara) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + return cbDPMonitor_WorkThreadMainFunc(pvcbe, &pDpContext->DPMonitorContext, pDPWorkThreadPara); +} + +CBIOS_STATUS cbDPPort_SetNotifications(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_NOTIFICATIONS pDPNotifications) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDPMonitor_SetNotifications(pvcbe, &pDpContext->DPMonitorContext, pDPNotifications); +} + +CBIOS_STATUS cbDPPort_GetInt(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_INT_PARA pDPIntPara) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDPMonitor_GetInt(pvcbe, &pDpContext->DPMonitorContext, pDPIntPara); +} + +CBIOS_STATUS cbDPPort_HandleIrq(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_HANDLE_IRQ_PARA pDPHandleIrqPara) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDPMonitor_HandleIrq(pvcbe, &pDpContext->DPMonitorContext, pDPHandleIrqPara); +} + +CBIOS_STATUS cbDPPort_GetCustomizedTiming(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_CUSTOMIZED_TIMING pDPCustomizedTiming) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDPMonitor_GetCustomizedTiming(pvcbe, &pDpContext->DPMonitorContext, pDPCustomizedTiming); +} + +static CBIOS_VOID cbDPPort_HwInit(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + CBIOS_MODULE_INDEX DPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return; + } + DPModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + + if(!(cbDIU_DP_IsOn(pcbe, DPModuleIndex) || cbDIU_HDMI_IsOn(pcbe, DPModuleIndex))) + { + cbPHY_DP_InitEPHY(pcbe, DPModuleIndex); + cbPHY_DP_DeInitEPHY(pcbe, DPModuleIndex); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: EPHY has been initialized for 0x%x!\n", FUNCTION_NAME, pDevCommon->DeviceType)); + } +} + +static CBIOS_BOOL cbDPPort_DeviceDetect(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bHardcodeDetected, CBIOS_U32 FullDetect) +{ + CBIOS_BOOL bConnected = CBIOS_FALSE; + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + CBIOS_MODULE_INDEX DPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + CBIOS_MODULE_INDEX HDMIModuleIndex = CBIOS_MODULE_INDEX_INVALID; + DP_EPHY_MODE Mode; + + cbTraceEnter(DP); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + bConnected = CBIOS_FALSE; + goto EXIT; + } + + DPModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + HDMIModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_HDMI); + Mode = cbPHY_DP_GetEphyMode(pcbe, DPModuleIndex); + + pDpContext->DPPortParams.bDualMode = cbDualModeDetect(pcbe, pDevCommon); + //Some monitors(like samsung UA40) can't get EDID by I2C after change brightness through DDX, and bDualMode is FALSE + //So it has no chance to enter cbHDMIMonitor_Detect function to handle scramble, just clear it here when found bDualMode is FALSE + if (!pDpContext->DPPortParams.bDualMode) + { + pDpContext->HDMIMonitorContext.ScramblingEnable = CBIOS_FALSE; + cbDIU_HDMI_ConfigScrambling(pcbe, HDMIModuleIndex, pDpContext->HDMIMonitorContext.ScramblingEnable); + } + + if ((!bConnected) && (pDpContext->DPPortParams.bDualMode) + && (pDpContext->Common.SupportMonitorType & (CBIOS_MONITOR_TYPE_HDMI | CBIOS_MONITOR_TYPE_DVI))) + { + bConnected = cbHDMIMonitor_Detect(pcbe, &pDpContext->HDMIMonitorContext, bHardcodeDetected, FullDetect); + if (bConnected) + { + cbPHY_DP_SelectEphyMode(pcbe, DPModuleIndex, DP_EPHY_TMDS_MODE); + pDpContext->DPPortParams.DPEphyMode = DP_EPHY_TMDS_MODE; + cbDIU_DP_SetInterruptMode(pcbe, DPModuleIndex, CBIOS_FALSE); + } + } + +#if DP_MONITOR_SUPPORT + if ((!bConnected) && (!pDpContext->DPPortParams.bDualMode) + && (pDpContext->Common.SupportMonitorType & (CBIOS_MONITOR_TYPE_DP | CBIOS_MONITOR_TYPE_PANEL))) + { + pDpContext->DPPortParams.bDualMode = CBIOS_FALSE; + + cbPHY_DP_SelectEphyMode(pcbe, DPModuleIndex, DP_EPHY_DP_MODE); + + bConnected = cbDPMonitor_Detect(pcbe, &pDpContext->DPMonitorContext, bHardcodeDetected, FullDetect); + if (bConnected) + { + pDpContext->DPPortParams.DPEphyMode = DP_EPHY_DP_MODE; + cbDIU_DP_SetInterruptMode(pcbe, DPModuleIndex, CBIOS_TRUE); + } + } +#endif + + if(!bConnected) + { + cbPHY_DP_SelectEphyMode(pcbe, DPModuleIndex, Mode); + } + + if(bConnected) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Monitor(0x%x) on Device(0x%x) is detected!\n", + FUNCTION_NAME, pDevCommon->CurrentMonitorType, pDevCommon->DeviceType)); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Device(0x%x) is not detected!\n", + FUNCTION_NAME, pDevCommon->DeviceType)); + } + +EXIT: + cbTraceExit(DP); + return bConnected; +} + +static CBIOS_VOID cbDPPort_OnOff(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bOn) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + CBIOS_MODULE_INDEX DPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + CBIOS_DISPLAY_SOURCE *pSource = CBIOS_NULL; + CBIOS_BOOL bDPMode = 0; + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return; + } + + DPModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_DP); + bDPMode = (pDpContext->DPPortParams.DPEphyMode == DP_EPHY_DP_MODE) ? CBIOS_TRUE : CBIOS_FALSE; + pSource = &(pDevCommon->DispSource); + + if (pSource->bIsSrcChanged) + { + cbPHY_DP_SelectPhySource(pcbe, pDpContext->DPPortParams.DPEphyMode, pSource, pDpContext->Common.CurrentMonitorType); + cbPathMgrSelectDIUSource(pcbe, pSource); + + // source select done, clear flag + pSource->bIsSrcChanged = CBIOS_FALSE; + } + + if(bOn) + { + cbPathMgrModuleOnOff(pcbe, pSource->ModulePath, CBIOS_TRUE); + cbDIU_DP_DPModeEnable(pcbe, DPModuleIndex, bDPMode); + } + + if(bDPMode) + { + if(bOn) + { + if ((pDpContext->Common.CurrentMonitorType == CBIOS_MONITOR_TYPE_DP) || (pDpContext->Common.CurrentMonitorType == CBIOS_MONITOR_TYPE_PANEL)) + { + #if DP_MONITOR_SUPPORT + cbPHY_DP_InitEPHY(pcbe, DPModuleIndex); + cbDPMonitor_OnOff(pcbe, &pDpContext->DPMonitorContext, bOn); + #endif + } + } + else + { + if ((pDpContext->Common.CurrentMonitorType == CBIOS_MONITOR_TYPE_DP) || (pDpContext->Common.CurrentMonitorType == CBIOS_MONITOR_TYPE_PANEL)) + { + #if DP_MONITOR_SUPPORT + cbDPMonitor_OnOff(pcbe, &pDpContext->DPMonitorContext, bOn); + #endif + } + } + } + else + { + if(bOn) + { + if ((pDpContext->Common.CurrentMonitorType == CBIOS_MONITOR_TYPE_HDMI) || (pDpContext->Common.CurrentMonitorType == CBIOS_MONITOR_TYPE_DVI)) + { + cbHDMIMonitor_OnOff(pcbe, &pDpContext->HDMIMonitorContext, bOn); + cbPHY_DP_InitEPHY(pcbe, DPModuleIndex); + cbPHY_DP_DualModeOnOff(pcbe, DPModuleIndex, pDpContext->HDMIMonitorContext.HDMIClock, bOn); + } + } + else + { + if ((pDpContext->Common.CurrentMonitorType == CBIOS_MONITOR_TYPE_HDMI) || (pDpContext->Common.CurrentMonitorType == CBIOS_MONITOR_TYPE_DVI)) + { + cbHDMIMonitor_OnOff(pcbe, &pDpContext->HDMIMonitorContext, bOn); + cbPHY_DP_DualModeOnOff(pcbe, DPModuleIndex, pDpContext->HDMIMonitorContext.HDMIClock, bOn); + } + } + } + + if(!bOn) + { + cbPathMgrModuleOnOff(pcbe, pSource->ModulePath, CBIOS_FALSE); + } + + pDevCommon->PowerState = bOn ? CBIOS_PM_ON : CBIOS_PM_OFF; + + cbDebugPrint((MAKE_LEVEL(DP, INFO),"%s: status = %s.\n", FUNCTION_NAME, (bOn)? "On" : "Off")); +} + +static CBIOS_VOID cbDPPort_QueryMonitorAttribute(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBiosMonitorAttribute pMonitorAttribute) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + + cbTraceEnter(DP); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return ; + } + + if (pDpContext->Common.CurrentMonitorType & (CBIOS_MONITOR_TYPE_HDMI | CBIOS_MONITOR_TYPE_DVI)) + { + cbHDMIMonitor_QueryAttribute(pcbe, &pDpContext->HDMIMonitorContext, pMonitorAttribute); + } + else if (pDpContext->Common.CurrentMonitorType & (CBIOS_MONITOR_TYPE_DP | CBIOS_MONITOR_TYPE_PANEL)) + { + cbDPMonitor_QueryAttribute(pcbe, &pDpContext->DPMonitorContext, pMonitorAttribute); + } + + cbTraceExit(DP); +} + +static CBIOS_VOID cbDPPort_UpdateModeInfo(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + CBIOS_U32 PixelRepitition = pModeParams->PixelRepitition; + CBIOS_U32 DiuPLLClock = 0; + CBIOS_MODULE_INDEX HDTVModuleIndex = CBIOS_MODULE_INDEX_INVALID; + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return ; + } + + HDTVModuleIndex = cbGetModuleIndex(pcbe, pDpContext->Common.DeviceType, CBIOS_MODULE_TYPE_HDTV); + if (pDpContext->Common.CurrentMonitorType & (CBIOS_MONITOR_TYPE_DP | CBIOS_MONITOR_TYPE_PANEL)) + { + if ((HDTVModuleIndex != CBIOS_MODULE_INDEX_INVALID) && (pModeParams->TargetModePara.bInterlace)) + { + pModeParams->TargetTiming.PixelClock *= 2; + } + DiuPLLClock = pModeParams->TargetTiming.PixelClock; + pModeParams->TargetTiming.PLLClock = DiuPLLClock; + + cbDPMonitor_UpdateModeInfo(pcbe, &pDpContext->DPMonitorContext, pModeParams); + } + + if (pDpContext->Common.CurrentMonitorType & (CBIOS_MONITOR_TYPE_HDMI | CBIOS_MONITOR_TYPE_DVI)) + { + // patch to 1080i don't bypass HDTV module + if ((HDTVModuleIndex != CBIOS_MODULE_INDEX_INVALID) && (pModeParams->TargetModePara.bInterlace)) + { + if((pModeParams->TargetModePara.XRes == 1920) && (pModeParams->TargetModePara.YRes == 1080)) + { + pModeParams->TargetTiming.PixelClock *= 2; + } + } + // determine DIU PLL clock + DiuPLLClock = pModeParams->TargetTiming.PixelClock; + + if (pModeParams->BitPerComponent == 8) // 24bit + { + if (PixelRepitition == 1) + { + DiuPLLClock *= 1; + } + else if (PixelRepitition == 2) + { + DiuPLLClock *= 2; + } + else if (PixelRepitition == 4) + { + DiuPLLClock *= 4; + } + pDpContext->HDMIMonitorContext.HDMIClock = DiuPLLClock; + } + else if (pModeParams->BitPerComponent == 10) // 30bit + { + if (PixelRepitition == 1) + { + DiuPLLClock = (DiuPLLClock * 5)/2; + } + else if (PixelRepitition == 2) + { + DiuPLLClock *= 5; + } + else if (PixelRepitition == 4) + { + DiuPLLClock *= 10; + } + pDpContext->HDMIMonitorContext.HDMIClock = DiuPLLClock/2; + } + else if (pModeParams->BitPerComponent == 12) // 36bit + { + if (PixelRepitition == 1) + { + DiuPLLClock *= 3; + pDpContext->HDMIMonitorContext.HDMIClock = DiuPLLClock/2; + } + else if (PixelRepitition == 2) + { + DiuPLLClock *= 3; + pDpContext->HDMIMonitorContext.HDMIClock = DiuPLLClock; + } + else if (PixelRepitition == 4) + { + DiuPLLClock *= 6; + pDpContext->HDMIMonitorContext.HDMIClock = DiuPLLClock; + } + } + + if (HDTVModuleIndex != CBIOS_MODULE_INDEX_INVALID && (pModeParams->TargetModePara.bInterlace)) + { + pDpContext->HDMIMonitorContext.HDMIClock /= 2; + } + + if(CBIOS_YCBCR420OUTPUT == pModeParams->TargetModePara.OutputSignal) + { + pDpContext->HDMIMonitorContext.HDMIClock /= 2; + } + pModeParams->TargetTiming.PLLClock = DiuPLLClock; + + cbHDMIMonitor_UpdateModeInfo(pcbe, &pDpContext->HDMIMonitorContext, pModeParams); + + } + +} + +static CBIOS_VOID cbDPPort_SetMode(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + CBIOS_MONITOR_TYPE MonitorType = CBIOS_MONITOR_TYPE_NONE; + CBIOS_MODULE_INDEX HDTVModuleIndex = CBIOS_MODULE_INDEX_INVALID; + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return ; + } + + MonitorType = pDevCommon->CurrentMonitorType; + HDTVModuleIndex = cbGetModuleIndex(pcbe, pDevCommon->DeviceType, CBIOS_MODULE_TYPE_HDTV); + + if (HDTVModuleIndex != CBIOS_MODULE_INDEX_INVALID) + { + // Enable HDTV block function. + cbDoHDTVFuncSetting(pcbe, pModeParams, pModeParams->IGAIndex, pDevCommon->DeviceType); + } + + if ((MonitorType == CBIOS_MONITOR_TYPE_HDMI) || (MonitorType == CBIOS_MONITOR_TYPE_DVI)) + { + cbHDMIMonitor_SetMode(pcbe, &pDpContext->HDMIMonitorContext, pModeParams); + } + else if ((MonitorType == CBIOS_MONITOR_TYPE_DP) || (MonitorType == CBIOS_MONITOR_TYPE_PANEL)) + { + cbDPMonitor_SetMode(pcbe, &pDpContext->DPMonitorContext, pModeParams); + } +} + +PCBIOS_DEVICE_COMMON cbDPPort_Init(PCBIOS_VOID pvcbe, PVCP_INFO pVCP, CBIOS_ACTIVE_TYPE DeviceType) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DP_CONTEXT pDpContext = CBIOS_NULL; + PCBIOS_DEVICE_COMMON pDeviceCommon = CBIOS_NULL; + CBIOS_MODULE_INDEX DPIndex; + CBIOS_U32 ulTemp = 0; + + if(!(DeviceType & ALL_DP_TYPES)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: unsupported device type!!!\n", FUNCTION_NAME)); + return CBIOS_NULL; + } + + pDpContext = cb_AllocateNonpagedPool(sizeof(CBIOS_DP_CONTEXT)); + if(pDpContext == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: pDpContext allocate error!!!\n", FUNCTION_NAME)); + return CBIOS_NULL; + } + + pDeviceCommon = &pDpContext->Common; + + pDeviceCommon->DeviceType = DeviceType; + pDeviceCommon->SupportMonitorType = cbGetSupportMonitorType(pcbe, DeviceType); + pDeviceCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_NONE; + pDeviceCommon->PowerState = CBIOS_PM_INVALID; + cbHDCP_Init(pvcbe, &pDeviceCommon->pHDCPContext); + + cbInitialModuleList(&pDeviceCommon->DispSource.ModuleList); + + pDeviceCommon->pfncbDeviceHwInit = (PFN_cbDeviceHwInit)cbDPPort_HwInit; + pDeviceCommon->pfncbUpdateDeviceModeInfo = (PFN_cbUpdateDeviceModeInfo)cbDPPort_UpdateModeInfo; + pDeviceCommon->pfncbQueryMonitorAttribute = (PFN_cbQueryMonitorAttribute)cbDPPort_QueryMonitorAttribute; + pDeviceCommon->pfncbDeviceDetect = (PFN_cbDeviceDetect)cbDPPort_DeviceDetect; + pDeviceCommon->pfncbDeviceOnOff = (PFN_cbDeviceOnOff)cbDPPort_OnOff; + pDeviceCommon->pfncbDeviceSetMode = (PFN_cbDeviceSetMode)cbDPPort_SetMode; + + if (DeviceType == CBIOS_TYPE_DP1) + { + pDeviceCommon->I2CBus = pVCP->DP1DualModeCharByte & I2CBUSMASK; + pDeviceCommon->HPDPin = CBIOS_VIRTUAL_GPIO_FOR_DP1; + pDeviceCommon->DispSource.ModuleList.DPModule.Index = CBIOS_MODULE_INDEX1; + pDeviceCommon->DispSource.ModuleList.HDMIModule.Index = CBIOS_MODULE_INDEX1; + pDeviceCommon->DispSource.ModuleList.HDCPModule.Index = CBIOS_MODULE_INDEX1; + pDeviceCommon->DispSource.ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX1; + } + else if (DeviceType == CBIOS_TYPE_DP2) + { + pDeviceCommon->I2CBus = pVCP->DP2DualModeCharByte & I2CBUSMASK; + pDeviceCommon->HPDPin = CBIOS_VIRTUAL_GPIO_FOR_DP2; + pDeviceCommon->DispSource.ModuleList.DPModule.Index = CBIOS_MODULE_INDEX2; + pDeviceCommon->DispSource.ModuleList.HDMIModule.Index = CBIOS_MODULE_INDEX2; + pDeviceCommon->DispSource.ModuleList.HDCPModule.Index = CBIOS_MODULE_INDEX2; + pDeviceCommon->DispSource.ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX2; + } + else if (DeviceType == CBIOS_TYPE_DP3) + { + pDeviceCommon->I2CBus = pVCP->DP3DualModeCharByte & I2CBUSMASK; + pDeviceCommon->DispSource.ModuleList.DPModule.Index = CBIOS_MODULE_INDEX3; + pDeviceCommon->DispSource.ModuleList.HDMIModule.Index = CBIOS_MODULE_INDEX3; + pDeviceCommon->DispSource.ModuleList.HDCPModule.Index = CBIOS_MODULE_INDEX3; + pDeviceCommon->DispSource.ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX_INVALID; + } + else if (DeviceType == CBIOS_TYPE_DP4) + { + pDeviceCommon->I2CBus = pVCP->DP4DualModeCharByte & I2CBUSMASK; + pDeviceCommon->DispSource.ModuleList.DPModule.Index = CBIOS_MODULE_INDEX4; + pDeviceCommon->DispSource.ModuleList.HDMIModule.Index = CBIOS_MODULE_INDEX4; + pDeviceCommon->DispSource.ModuleList.HDCPModule.Index = CBIOS_MODULE_INDEX4; + pDeviceCommon->DispSource.ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX_INVALID; + } + + pDpContext->HDMIMonitorContext.pDevCommon = pDeviceCommon; + pDpContext->DPMonitorContext.pDevCommon = pDeviceCommon; + pDpContext->DPMonitorContext.GpioForEDP1Power = pVCP->GpioForEDP1Power; + pDpContext->DPMonitorContext.GpioForEDP2Power = pVCP->GpioForEDP2Power; + pDpContext->DPMonitorContext.GpioForEDP1BackLight = pVCP->GpioForEDP1BackLight; + pDpContext->DPMonitorContext.GpioForEDP2BackLight = pVCP->GpioForEDP2BackLight; + DPIndex = pDeviceCommon->DispSource.ModuleList.DPModule.Index; + cb_memcpy(&pDeviceCommon->MaxResConfig, &pVCP->DPMaxResConfig[DPIndex], sizeof(CBIOS_MAX_RES_CONFIG)); + + pDpContext->DPMonitorContext.SourceMaxLaneCount = 4; + pDpContext->DPMonitorContext.SourceMaxLinkSpeed = CBIOS_DP_LINK_SPEED_5400Mbps; + pDpContext->DPMonitorContext.bSourceSupportTPS3 = CBIOS_TRUE; + + if (NO_ERROR == cb_GetRegistryParameters(pcbe->pAdapterContext, KEYNAME_DW_DP_RUN_CTS, CBIOS_FALSE, &ulTemp)) + { + if(ulTemp) + { + pDpContext->DPPortParams.bRunCTS = CBIOS_TRUE;//run dp cts + } + else + { + pDpContext->DPPortParams.bRunCTS = CBIOS_FALSE; + } + } + else + { + pDpContext->DPPortParams.bRunCTS = CBIOS_FALSE; + } + + return &pDpContext->Common; +} + +CBIOS_VOID cbDPPort_DeInit(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_DP_CONTEXT pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & ALL_DP_TYPES))) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return ; + } + + cbHDCP_DeInit(pvcbe, pDevCommon->DeviceType); + cb_FreePool(pDpContext); + pDpContext = CBIOS_NULL; +} + diff --git a/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDP.h b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDP.h new file mode 100644 index 0000000000000..b21d15fb455c6 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDP.h @@ -0,0 +1,62 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DP port interface function prototype and parameter definition. +** +** NOTE: +** DP port ONLY parameters SHOULD be added to CBIOS_DP_CONTEXT. +******************************************************************************/ + +#ifndef _CBIOS_DP_H_ +#define _CBIOS_DP_H_ + +#include "../CBiosDeviceShare.h" +#include "../Monitor/CBiosDPMonitor.h" +#include "../Monitor/CBiosHDMIMonitor.h" +#include "../../Hw/HwBlock/CBiosPHY_DP.h" + +typedef struct _CBIOS_DP_PORT_PARAMS +{ + CBIOS_BOOL bDualMode; // 1 (yes), connect to HDMI/DVI via a connector + + DP_EPHY_MODE DPEphyMode; + CBIOS_BOOL bRunCTS; +}CBIOS_DP_PORT_PARAMS, *PCBIOS_DP_PORT_PARAMS; + +typedef struct _CBIOS_DP_CONTEXT +{ + CBIOS_DEVICE_COMMON Common; + CBIOS_DP_PORT_PARAMS DPPortParams; + + // monitor contexts + CBIOS_DP_MONITOR_CONTEXT DPMonitorContext; + CBIOS_HDMI_MONITOR_CONTEXT HDMIMonitorContext; +}CBIOS_DP_CONTEXT, *PCBIOS_DP_CONTEXT; + + +PCBIOS_DEVICE_COMMON cbDPPort_Init(PCBIOS_VOID pvcbe, PVCP_INFO pVCP, CBIOS_ACTIVE_TYPE DeviceType); +CBIOS_VOID cbDPPort_DeInit(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +CBIOS_BOOL cbDPPort_IsDeviceInDpMode(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +PCBIOS_VOID cbDPPort_GetDPMonitorContext(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +PCBIOS_VOID cbDPPort_GetHDMIMonitorContext(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +CBIOS_STATUS cbDPPort_Isr(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_ISR_PARA pDPIsrPara); +CBIOS_BOOL cbDPPort_WorkThreadMainFunc(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_WORKTHREAD_PARA pDPWorkThreadPara); +CBIOS_STATUS cbDPPort_SetNotifications(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_NOTIFICATIONS pDPNotifications); +CBIOS_STATUS cbDPPort_GetInt(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_INT_PARA pDPIntPara); +CBIOS_STATUS cbDPPort_HandleIrq(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_HANDLE_IRQ_PARA pDPHandleIrqPara); +CBIOS_STATUS cbDPPort_GetCustomizedTiming(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DP_CUSTOMIZED_TIMING pDPCustomizedTiming); +#endif diff --git a/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDSI.c b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDSI.c new file mode 100644 index 0000000000000..9b97f19fa401e --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDSI.c @@ -0,0 +1,3306 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DSI port interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "../../Hw/CBiosHwShare.h" + +extern CBIOS_U8 DSIPanelIndex; + +static CBIOS_STATUS cbDSI_WriteCmdRawData(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 RawData, CBIOS_DSI_INDEX DSIIndex) +{ + CBIOS_U32 DataNumInFIFO, i; + REG_MM3444_MM3574 RegMM3444_MM3574Value; + REG_MM3404_MM3534 RegMM3404_MM3534Value; + REG_MM3404_MM3534 RegMM3404_MM3534Mask; + CBIOS_U32 StatusRegIndex = 0x3444, DataRegIndex = 0x3404; + CBIOS_STATUS Status; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + StatusRegIndex = 0x3444; + DataRegIndex = 0x3404; + } + else if (DSIIndex == DSI_INDEX1) + { + StatusRegIndex = 0x3574; + DataRegIndex = 0x3534; + } + + for(i = 0; i < 10; i++) + { + RegMM3444_MM3574Value.Value = cbReadRegisterU32(pcbe, CBIOS_REGISTER_MMIO, StatusRegIndex); + DataNumInFIFO = RegMM3444_MM3574Value.DSI_Command_FIFO_Status; + + if (DataNumInFIFO < CBIOS_DSI_CMD_FIFO_DEPTH) + { + break; + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "cbDSI_WriteCmdRawData: command FIFO full! \n")); + cb_DelayMicroSeconds(1000); // just copy 5850 delay time + continue; + } + } + + if (i < 10) + { + RegMM3404_MM3534Value.Value = RawData; + RegMM3404_MM3534Mask.Value = 0; + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "DSI: RegIndex: 0x%08x, Value: 0x%08x \n", DataRegIndex, RegMM3404_MM3534Value.Value)); + cbMMIOWriteReg32(pcbe, DataRegIndex, RegMM3404_MM3534Value.Value, RegMM3404_MM3534Mask.Value); + Status = CBIOS_OK; + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_WriteCmdRawData: write raw data timeout! \n")); + Status = CBIOS_ER_INTERNAL; + } + + cbTraceExit(DSI); + return Status; +} + +static CBIOS_STATUS cbDSI_SendShortPacket(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 VirtualCh, CBIOS_U8 DataType, + CBIOS_U8 Data0, CBIOS_U8 Data1, CBIOS_U8 CmdType, CBIOS_DSI_INDEX DSIIndex) +{ + CBIOS_U32 RawData; + CBIOS_U8 DataIDByte; + CBIOS_STATUS Status; + cbTraceEnter(DSI); + + DataIDByte = (VirtualCh << 6) | DataType; + RawData = (CBIOS_U32)(DataIDByte | (Data0 << 8) | (Data1 << 16) | (CmdType << 24)); + + Status = cbDSI_WriteCmdRawData(pcbe, RawData, DSIIndex); + + cbTraceExit(DSI); + return Status; +} + +static CBIOS_STATUS cbDSI_SendLongPacket(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 VirtualCh, CBIOS_U8 DataType, + CBIOS_U16 WordCount, CBIOS_U8 *pDataBuf, CBIOS_U8 CmdType, CBIOS_DSI_INDEX DSIIndex) +{ + CBIOS_U32 RawData, i, Reminder; + CBIOS_U8 DataIDByte, LowByte, HighByte; + CBIOS_STATUS Status; + cbTraceEnter(DSI); + + // send packet header first + DataIDByte = (VirtualCh << 6) | DataType; + LowByte = (CBIOS_U8)(WordCount & 0xFF); // LSB first + HighByte = (CBIOS_U8)((WordCount & 0xFF00) >> 8); + RawData = (CBIOS_U32)(DataIDByte | (LowByte << 8) | (HighByte << 16) | (CmdType << 24)); + Status = cbDSI_WriteCmdRawData(pcbe, RawData, DSIIndex); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendLongPacket: send packet header failed! \n")); + goto Exit; + } + + // send packet data + for (i = 0; i < (CBIOS_U32)(WordCount >> 2); i++) + { + RawData = (CBIOS_U32)(pDataBuf[i * 4]) | (CBIOS_U32)(pDataBuf[i * 4 + 1] << 8) + | (CBIOS_U32)(pDataBuf[i * 4 + 2] << 16) | (CBIOS_U32)(pDataBuf[i * 4 + 3] << 24); + Status = cbDSI_WriteCmdRawData(pcbe, RawData, DSIIndex); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendLongPacket: send packet data failed! \n")); + goto Exit; + } + } + + Reminder = WordCount % 4; + + if (Reminder != 0) + { + RawData = 0; + + for (i = Reminder; i > 0; i--) + { + RawData |= (CBIOS_U32)((pDataBuf[WordCount - i]) << ((Reminder - i) * 8)); + } + + Status = cbDSI_WriteCmdRawData(pcbe, RawData, DSIIndex); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendLongPacket: send packet data failed! \n")); + goto Exit; + } + } + +Exit: + cbTraceExit(DSI); + return Status; + +} + +static CBIOS_STATUS cbDSI_SendDMAPacket(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 VirtualCh, CBIOS_U8 DataType, + CBIOS_U16 WordCount, CBIOS_U8 CmdType, CBIOS_U32 DMAAddr, CBIOS_U8 DCSCommand, CBIOS_DSI_INDEX DSIIndex) +{ + CBIOS_U32 RawData = 0; + CBIOS_U8 DataIDByte = 0, LowByte = 0, HighByte = 0; + CBIOS_STATUS Status; + cbTraceEnter(DSI); + + // send packet header first + DataIDByte = (VirtualCh << 6) | DataType; + LowByte = (CBIOS_U8)(WordCount & 0xFF); // LSB first + HighByte = (CBIOS_U8)((WordCount & 0xFF00) >> 8); + CmdType |= DSI_CMD_TYPE_DMA; + RawData = (CBIOS_U32)(DataIDByte | (LowByte << 8) | (HighByte << 16) | (CmdType << 24)); + Status = cbDSI_WriteCmdRawData(pcbe, RawData, DSIIndex); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendDMAPacket: send packet header failed! \n")); + goto Exit; + } + + // send dma data address + Status = cbDSI_WriteCmdRawData(pcbe, DMAAddr, DSIIndex); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendDMAPacket: send dma data address failed! \n")); + goto Exit; + } + + //send dcs command + Status = cbDSI_WriteCmdRawData(pcbe, DCSCommand, DSIIndex); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendLongPacket: send dcs command failed! \n")); + goto Exit; + } + +Exit: + cbTraceExit(DSI); + return Status; +} + +static CBIOS_BOOL cbDSI_WaitDMAFree(PCBIOS_EXTENSION_COMMON pcbe) +{ + CBIOS_U32 busy = 1; + CBIOS_U32 i = 10000; + REG_MM3444_MM3574 RegMM3444_MM3574Value; + cbTraceEnter(DSI); + + while(i--) + { + RegMM3444_MM3574Value.Value = cbReadRegisterU32(pcbe, CBIOS_REGISTER_MMIO, 0x3444); + busy = RegMM3444_MM3574Value.DSI_Command_DMA_Busy_Status; + + if(!busy) + { + break; + } + } + + cbTraceExit(DSI); + return busy == 0 ? CBIOS_TRUE : CBIOS_FALSE; +} + +static CBIOS_VOID cbDSI_SelectMode(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_DSI_MODE Mode, CBIOS_DSI_INDEX DSIIndex) +{ + REG_MM3408_MM3538 RegMM3408_MM3538Value; + REG_MM3408_MM3538 RegMM3408_MM3538Mask; + CBIOS_U32 CtrlRegIndex = 0x3408; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + CtrlRegIndex = 0x3408; + } + else if (DSIIndex == DSI_INDEX1) + { + CtrlRegIndex = 0x3538; + } + + RegMM3408_MM3538Value.Value = 0; + RegMM3408_MM3538Mask.Value = 0xFFFFFFFF; + RegMM3408_MM3538Value.DSI_Mode = (Mode == CBIOS_DSI_CMDMODE) ? 1 : 0; + RegMM3408_MM3538Mask.DSI_Mode = 0; + cbMMIOWriteReg32(pcbe, CtrlRegIndex, RegMM3408_MM3538Value.Value, RegMM3408_MM3538Mask.Value); + + cbTraceExit(DSI); +} + +static CBIOS_VOID cbDSI_SetOutBpp(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 OutBpp, CBIOS_DSI_INDEX DSIIndex) +{ + CBIOS_U32 val = 0; + REG_MM3408_MM3538 RegMM3408_MM3538Value; + REG_MM3408_MM3538 RegMM3408_MM3538Mask; + CBIOS_U32 CtrlRegIndex = 0x3408; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + CtrlRegIndex = 0x3408; + } + else if (DSIIndex == DSI_INDEX1) + { + CtrlRegIndex = 0x3538; + } + + if (OutBpp == 16) + { + val = 1; + } + else if (OutBpp == 18) + { + val = 2; + } + else if (OutBpp == 24) + { + val = 0; + } + + RegMM3408_MM3538Value.Value = 0; + RegMM3408_MM3538Mask.Value = 0xFFFFFFFF; + RegMM3408_MM3538Value.DSI_Video_Mode_Ouput_Pixel_Format = val; + RegMM3408_MM3538Mask.DSI_Video_Mode_Ouput_Pixel_Format = 0; + cbMMIOWriteReg32(pcbe, CtrlRegIndex, RegMM3408_MM3538Value.Value, RegMM3408_MM3538Mask.Value); + + cbTraceExit(DSI); +} + +static CBIOS_VOID cbDSI_EoTpEnableDisable(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DSI_CONFIG pDSIConfig, CBIOS_DSI_INDEX DSIIndex) +{ + REG_MM3408_MM3538 RegMM3408_MM3538Value; + REG_MM3408_MM3538 RegMM3408_MM3538Mask; + REG_MM345C_MM358C RegMM345C_MM358CValue; + REG_MM345C_MM358C RegMM345C_MM358CMask; + CBIOS_U32 CtrlRegIndex = 0x3408, VideoRegIndex = 0x345C; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + CtrlRegIndex = 0x3408; + VideoRegIndex = 0x345C; + } + else if (DSIIndex == DSI_INDEX1) + { + CtrlRegIndex = 0x3538; + VideoRegIndex = 0x358C; + } + + RegMM3408_MM3538Value.Value = 0; + RegMM3408_MM3538Mask.Value = 0xFFFFFFFF; + RegMM345C_MM358CValue.Value = 0; + RegMM345C_MM358CMask.Value = 0xFFFFFFFF; + + if (pDSIConfig->DSIMode == CBIOS_DSI_CMDMODE) + { + if (pDSIConfig->isEnableEoTp) + { + RegMM3408_MM3538Value.Enable_Command_EoTp_End_of_Transmission_packet = 1; + } + else + { + RegMM3408_MM3538Value.Enable_Command_EoTp_End_of_Transmission_packet = 0; + } + + RegMM3408_MM3538Mask.Enable_Command_EoTp_End_of_Transmission_packet = 0; + cbMMIOWriteReg32(pcbe, CtrlRegIndex, RegMM3408_MM3538Value.Value, RegMM3408_MM3538Mask.Value); + } + else if (pDSIConfig->DSIMode == CBIOS_DSI_VIDEOMODE) + { + if (pDSIConfig->isEnableEoTp) + { + RegMM345C_MM358CValue.DSI_Video_Mode_EoTp_Packet_Enable = 1; + } + else + { + RegMM345C_MM358CValue.DSI_Video_Mode_EoTp_Packet_Enable = 0; + } + + RegMM345C_MM358CMask.DSI_Video_Mode_EoTp_Packet_Enable = 0; + cbMMIOWriteReg32(pcbe, VideoRegIndex, RegMM345C_MM358CValue.Value, RegMM345C_MM358CMask.Value); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_EoTpEnableDisable: wrong dsi mode! \n")); + } + + cbTraceExit(DSI); +} + +static CBIOS_VOID cbDSI_SetDataLaneNum(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 DataLaneNum, CBIOS_DSI_INDEX DSIIndex) +{ + REG_MM340C_MM353C RegMM340C_MM353CValue; + REG_MM340C_MM353C RegMM340C_MM353CMask; + CBIOS_U32 PhyRegIndex = 0x340C; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + PhyRegIndex = 0x340C; + } + else if (DSIIndex == DSI_INDEX1) + { + PhyRegIndex = 0x353C; + } + + + RegMM340C_MM353CValue.Value = 0; + RegMM340C_MM353CMask.Value = 0xFFFFFFFF; + RegMM340C_MM353CValue.DSI_Data_Lane_Number = (DataLaneNum - 1); + RegMM340C_MM353CMask.DSI_Data_Lane_Number = 0; + cbMMIOWriteReg32(pcbe, PhyRegIndex, RegMM340C_MM353CValue.Value, RegMM340C_MM353CMask.Value); + + cbTraceExit(DSI); +} + +static CBIOS_VOID cbDSI_SetClkLaneMode(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_DSI_CLK_LANE_MODE ClkLaneMode, CBIOS_DSI_INDEX DSIIndex) +{ + REG_MM340C_MM353C RegMM340C_MM353CValue; + REG_MM340C_MM353C RegMM340C_MM353CMask; + CBIOS_U32 PhyRegIndex = 0x340C; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + PhyRegIndex = 0x340C; + } + else if (DSIIndex == DSI_INDEX1) + { + PhyRegIndex = 0x353C; + } + + RegMM340C_MM353CValue.Value = 0; + RegMM340C_MM353CMask.Value = 0xFFFFFFFF; + + if (ClkLaneMode == CBIOS_DSI_CLK_LANE_SOFTWARE_CTL) + { + RegMM340C_MM353CValue.Clock_Lane_Control_Mode = 0; + } + else + { + RegMM340C_MM353CValue.Clock_Lane_Control_Mode = 1; + } + + RegMM340C_MM353CMask.Clock_Lane_Control_Mode = 0; + cbMMIOWriteReg32(pcbe, PhyRegIndex, RegMM340C_MM353CValue.Value, RegMM340C_MM353CMask.Value); + + cbTraceExit(DSI); +} + +static CBIOS_VOID cbDSI_ClkLaneHSEnableDisable(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_BOOL isEnable, CBIOS_DSI_INDEX DSIIndex) +{ + REG_MM3410_MM3540 RegMM3410_MM3540Value; + REG_MM3410_MM3540 RegMM3410_MM3540Mask; + CBIOS_U32 LPhyRegIndex = 0x3410; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + LPhyRegIndex = 0x3410; + } + else if (DSIIndex == DSI_INDEX1) + { + LPhyRegIndex = 0x3540; + } + + RegMM3410_MM3540Value.Value = 0; + RegMM3410_MM3540Mask.Value = 0xFFFFFFFF; + + if (isEnable) + { + RegMM3410_MM3540Value.Enable_Clock_lane_high_speed_clock = 1; + } + else + { + RegMM3410_MM3540Value.Enable_Clock_lane_high_speed_clock = 0; + } + + RegMM3410_MM3540Mask.Enable_Clock_lane_high_speed_clock = 0; + cbMMIOWriteReg32(pcbe, LPhyRegIndex, RegMM3410_MM3540Value.Value, RegMM3410_MM3540Mask.Value); + + cbTraceExit(DSI); +} + +static CBIOS_VOID cbDSI_SyncEndEnableDisable(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DSI_CONFIG pDSIConfig, CBIOS_DSI_INDEX DSIIndex) +{ + REG_MM345C_MM358C RegMM345C_MM358CValue; + REG_MM345C_MM358C RegMM345C_MM358CMask; + CBIOS_U32 VideoRegIndex = 0x345C; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + VideoRegIndex = 0x345C; + } + else if (DSIIndex == DSI_INDEX1) + { + VideoRegIndex = 0x358C; + } + + RegMM345C_MM358CValue.Value = 0; + RegMM345C_MM358CMask.Value = 0xFFFFFFFF; + + RegMM345C_MM358CValue.HSS_EN = 1; + RegMM345C_MM358CValue.VSS_EN = 1; + + if (pDSIConfig->SyncPacketType == CBIOS_DSI_SYNC_PULSE) + { + RegMM345C_MM358CValue.HSE_EN = 1; + RegMM345C_MM358CValue.VSE_EN = 1; + } + else + { + RegMM345C_MM358CValue.HSE_EN = 0; + RegMM345C_MM358CValue.VSE_EN = 0; + } + + RegMM345C_MM358CMask.HSS_EN = 0; + RegMM345C_MM358CMask.HSE_EN = 0; + RegMM345C_MM358CMask.VSS_EN = 0; + RegMM345C_MM358CMask.VSE_EN = 0; + cbMMIOWriteReg32(pcbe, VideoRegIndex, RegMM345C_MM358CValue.Value, RegMM345C_MM358CMask.Value); + + cbTraceExit(DSI); +} + +static CBIOS_VOID cbDSI_SetTimeOut(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DSI_CONFIG pDSIConfig, CBIOS_DSI_INDEX DSIIndex) +{ + REG_MM342C_MM355C RegMM342C_MM355CValue; + REG_MM342C_MM355C RegMM342C_MM355CMask; + REG_MM3430_MM3560 RegMM3430_MM3560Value; + REG_MM3430_MM3560 RegMM3430_MM3560Mask; + REG_MM3434_MM3564 RegMM3434_MM3564Value; + REG_MM3434_MM3564 RegMM3434_MM3564Mask; + CBIOS_U32 TARegIndex = 0x342C, HsTxRegIndex = 0x3430, LpRxRegIndex = 0x3434; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + TARegIndex = 0x342C; + HsTxRegIndex = 0x3430; + LpRxRegIndex = 0x3434; + } + else if (DSIIndex == DSI_INDEX1) + { + TARegIndex = 0x355C; + HsTxRegIndex = 0x3560; + LpRxRegIndex = 0x3564; + } + + + RegMM342C_MM355CValue.DSI_TurnAround_Timeout_Period = pDSIConfig->TurnAroundTimeout; + RegMM342C_MM355CMask.DSI_TurnAround_Timeout_Period = 0; + RegMM3430_MM3560Value.DSI_HS_TX_Timeout_Period = pDSIConfig->HS_TXTimeout; + RegMM3430_MM3560Mask.DSI_HS_TX_Timeout_Period = 0; + RegMM3434_MM3564Value.DSI_LP_RX_Timeout_Period = pDSIConfig->LP_RXTimeout; + RegMM3434_MM3564Mask.DSI_LP_RX_Timeout_Period = 0; + + cbMMIOWriteReg32(pcbe, TARegIndex, RegMM342C_MM355CValue.Value, RegMM342C_MM355CMask.Value); + cbMMIOWriteReg32(pcbe, HsTxRegIndex, RegMM3430_MM3560Value.Value, RegMM3430_MM3560Mask.Value); + cbMMIOWriteReg32(pcbe, LpRxRegIndex, RegMM3434_MM3564Value.Value, RegMM3434_MM3564Mask.Value); + + cbTraceExit(DSI); +} + +static CBIOS_VOID cbDSI_SetPhyParams(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DSI_PARAMS pDSIParams, CBIOS_U32 IGAIndex, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_DSI_PHY_PARAMS pPhyParams = &pDSIParams->PhyParams; + PCBIOS_DSI_CONFIG pDSIConfig = &(pDSIParams->DSIPanelDesc.DSIConfig); + PCBIOS_DSI_PANEL_TABLE pDSIPanelTbl = &(pDSIParams->DSIPanelDesc.DSIPanelTbl); + CBIOS_U32 tDclk, tBclk, tEclk, tUI; + CBIOS_S32 value; + REG_MM3414_MM3544 RegMM3414_MM3544Value; + REG_MM3414_MM3544 RegMM3414_MM3544Mask; + REG_MM3418_MM3548 RegMM3418_MM3548Value; + REG_MM3418_MM3548 RegMM3418_MM3548Mask; + REG_MM341C_MM354C RegMM341C_MM354CValue; + REG_MM341C_MM354C RegMM341C_MM354CMask; + REG_MM3420_MM3550 RegMM3420_MM3550Value; + REG_MM3420_MM3550 RegMM3420_MM3550Mask; + REG_MM3424_MM3554 RegMM3424_MM3554Value; + REG_MM3424_MM3554 RegMM3424_MM3554Mask; + REG_MM3428_MM3558 RegMM3428_MM3558Value; + REG_MM3428_MM3558 RegMM3428_MM3558Mask; + REG_MM3448_MM3578 RegMM3448_MM3578Value; + REG_MM3448_MM3578 RegMM3448_MM3578Mask; + CBIOS_U32 LpxTaRegIndex = 0x3414, GoSureRegIndex = 0x3418, WakeUpRegIndex = 0x341C; + CBIOS_U32 PreZeroRegIndex = 0x3420, TrailRegIndex = 0x3424, ExitRegIndex = 0x3428; + CBIOS_U32 EphyCtrlRegIndex = 0x3448, EphyTunRegIndex = 0x344C, EphyMiscRegIndex = 0x3450; + cbTraceEnter(DSI); + + cb_memset(pPhyParams, 0 , sizeof(CBIOS_DSI_PHY_PARAMS)); + + if (DSIIndex == DSI_INDEX0) + { + LpxTaRegIndex = 0x3414; + GoSureRegIndex = 0x3418; + WakeUpRegIndex = 0x341C; + PreZeroRegIndex = 0x3420; + TrailRegIndex = 0x3424; + ExitRegIndex = 0x3428; + EphyCtrlRegIndex = 0x3448; + EphyTunRegIndex = 0x344C; + EphyMiscRegIndex = 0x3450; + } + else if (DSIIndex == DSI_INDEX1) + { + LpxTaRegIndex = 0x3544; + GoSureRegIndex = 0x3548; + WakeUpRegIndex = 0x354C; + PreZeroRegIndex = 0x3550; + TrailRegIndex = 0x3554; + ExitRegIndex = 0x3558; + EphyCtrlRegIndex = 0x3578; + EphyTunRegIndex = 0x357C; + EphyMiscRegIndex = 0x3580; + } + + tDclk = khz2ps(pDSIPanelTbl->PanelTiming.DCLK * 10); // unit: ps, 1ns = 1000ps + if (pDSIConfig->isDualChannel) + { + tDclk *= 2; + } + tEclk = khz2ps(1700000 / 10); // unit: ps, 1ns = 1000ps + tBclk = tDclk * pDSIPanelTbl->LaneNum * 8 / pDSIPanelTbl->OutBpp; + tUI = tBclk / 8; + cbDebugPrint((MAKE_LEVEL(DSI, INFO), "cbDSI_SetPhyParams, pDSIPanelTbl->PanelTiming.DCLK: %d \n", pDSIPanelTbl->PanelTiming.DCLK)); + cbDebugPrint((MAKE_LEVEL(DSI, INFO), "cbDSI_SetPhyParams, tDclk: %d \n", tDclk)); + cbDebugPrint((MAKE_LEVEL(DSI, INFO), "cbDSI_SetPhyParams, tEclk: %d \n", tEclk)); + cbDebugPrint((MAKE_LEVEL(DSI, INFO), "cbDSI_SetPhyParams, tBclk: %d \n", tBclk)); + cbDebugPrint((MAKE_LEVEL(DSI, INFO), "cbDSI_SetPhyParams, tUI: %d \n", tUI)); + + pPhyParams->LPX = 1000 * (pPhyParams->LPX ? pPhyParams->LPX : 60); + pPhyParams->HS_PREPARE = pPhyParams->HS_PREPARE ? (1000 * pPhyParams->HS_PREPARE) : (1000 * 50 + 6 * tUI); + pPhyParams->HS_PREPARE_ZERO = pPhyParams->HS_PREPARE_ZERO ? (1000 * pPhyParams->HS_PREPARE_ZERO) : (1000 * 145 + 10 * tUI); + pPhyParams->HS_TRAIL = pPhyParams->HS_TRAIL ? (1000 * pPhyParams->HS_TRAIL) : (cb_max(8 * tUI, 1000 * 60 + 4 * tUI)); + pPhyParams->HS_EXIT = 1000 * (pPhyParams->HS_EXIT ? pPhyParams->HS_EXIT : 110); + pPhyParams->CLK_PREPARE = 1000 * (pPhyParams->CLK_PREPARE ? pPhyParams->CLK_PREPARE : 50); + pPhyParams->CLK_PREPARE_ZERO = 1000 * (pPhyParams->CLK_PREPARE_ZERO ? pPhyParams->CLK_PREPARE_ZERO : 350); + pPhyParams->CLK_POST = pPhyParams->CLK_POST ? (1000 * pPhyParams->CLK_POST) : (1000 * 70 + 52 * tUI); + pPhyParams->CLK_PRE = pPhyParams->CLK_PRE ? (1000 * pPhyParams->CLK_PRE) : (8 * tUI); + pPhyParams->CLK_TRAIL = 1000 * (pPhyParams->CLK_TRAIL ? pPhyParams->CLK_TRAIL : 70); + pPhyParams->TA_GET = pPhyParams->TA_GET ? (1000 * pPhyParams->TA_GET) : (5 * pPhyParams->LPX); + pPhyParams->TA_GO = pPhyParams->TA_GO ? (1000 * pPhyParams->TA_GO) : (4 * pPhyParams->LPX); + pPhyParams->TA_SURE = pPhyParams->TA_SURE ? (1000 * pPhyParams->TA_SURE) : (pPhyParams->LPX); + pPhyParams->WakeUp = 1000 * (pPhyParams->WakeUp ? pPhyParams->WakeUp : 110000); + + //LPHY_LPX_and_TA-GET_Period_Register + value = ceil(pPhyParams->LPX, tBclk) - 1; + RegMM3414_MM3544Value.LPX_Period = value < 0 ? 0 : value; + pPhyParams->LPX = (value + 1) * tBclk; + pPhyParams->LPX = ceil(pPhyParams->LPX , 1000); + + value = ceil(2 * pPhyParams->TA_GET - 9 * tBclk , 2 * tEclk) - 1; + RegMM3414_MM3544Value.TA_GET_Period = value < 0 ? 0 : value; + pPhyParams->TA_GET = 2 * (value + 1) * tEclk + 9 * tBclk; + pPhyParams->TA_GET = ceil(pPhyParams->TA_GET, 2000); + RegMM3414_MM3544Mask.Value = 0; + cbMMIOWriteReg32(pcbe, LpxTaRegIndex, RegMM3414_MM3544Value.Value, RegMM3414_MM3544Mask.Value); + + //LPHY_TA-GO_and_TA-SURE_Period_Register + value = ceil(2 * pPhyParams->TA_GO - 3 * tBclk , 2 * tEclk) - 2; + RegMM3418_MM3548Value.TA_GO_Period = value < 0 ? 0 : value; + pPhyParams->TA_GO = 2 * (value + 5) * tEclk + 3 * tBclk; + pPhyParams->TA_GO = ceil(pPhyParams->TA_GO, 2000); + + value = ceil(pPhyParams->TA_SURE, tEclk) - 4; + RegMM3418_MM3548Value.TA_SURE_Period = value < 0 ? 0 : value; + pPhyParams->TA_SURE = (value + 4) * tEclk; + pPhyParams->TA_SURE = ceil(pPhyParams->TA_SURE, 1000); + RegMM3418_MM3548Mask.Value = 0; + cbMMIOWriteReg32(pcbe, GoSureRegIndex, RegMM3418_MM3548Value.Value, RegMM3418_MM3548Mask.Value); + + //LPHY_Wake_Up_Period_Register + value = ceil(pPhyParams->WakeUp, tBclk) - 1; + RegMM341C_MM354CValue.Wake_Up_Period = value < 0 ? 0 : value; + pPhyParams->WakeUp = (value + 1) * tBclk; + pPhyParams->WakeUp = ceil(pPhyParams->WakeUp, 1000); + RegMM341C_MM354CMask.Value = 0; + cbMMIOWriteReg32(pcbe, WakeUpRegIndex, RegMM341C_MM354CValue.Value, RegMM341C_MM354CMask.Value); + + //LPHY_Data/Clock_Lane_HS_Prepare_Period_Register + value = ceil(pPhyParams->HS_PREPARE_ZERO, tBclk) - 3; + RegMM3420_MM3550Value.HS_PREPARE_and_HS_ZERO_Period = value < 0 ? 0 : value; + pPhyParams->HS_PREPARE_ZERO = (value + 3) * tBclk; + pPhyParams->HS_PREPARE_ZERO = ceil(pPhyParams->HS_PREPARE_ZERO, 1000); + + value = ceil(pPhyParams->CLK_PREPARE_ZERO, tBclk) - 1; + RegMM3420_MM3550Value.CLK_PREPARE_and_CLK_ZERO_Period = value < 0 ? 0 : value; + pPhyParams->CLK_PREPARE_ZERO = (value + 3) * tBclk; + pPhyParams->CLK_PREPARE_ZERO = ceil(pPhyParams->CLK_PREPARE_ZERO, 1000); + RegMM3420_MM3550Mask.Value = 0; + cbMMIOWriteReg32(pcbe, PreZeroRegIndex, RegMM3420_MM3550Value.Value, RegMM3420_MM3550Mask.Value); + + //LPHY_Data/Clock_Lane_HS_Trail_Period_Register + value = ceil(pPhyParams->HS_TRAIL, tBclk) - 1; + RegMM3424_MM3554Value.HS_TRAIL_Period = value < 0 ? 0 : value; + pPhyParams->HS_TRAIL = (value + 1) * tBclk; + pPhyParams->HS_TRAIL = ceil(pPhyParams->HS_TRAIL, 1000); + + value = ceil(pPhyParams->CLK_TRAIL, tBclk) - 1; + RegMM3424_MM3554Value.CLK_TRAIL_Period = value < 0 ? 0 : value; + pPhyParams->CLK_TRAIL = (value + 1) * tBclk; + pPhyParams->CLK_TRAIL = ceil(pPhyParams->CLK_TRAIL, 1000); + + value = ceil(pPhyParams->CLK_POST, tBclk) - 1; + RegMM3424_MM3554Value.CLK_POST_Period = value < 0 ? 0 : value; + pPhyParams->CLK_POST = (value + 1) * tBclk; + pPhyParams->CLK_POST = ceil(pPhyParams->CLK_POST, 1000); + + value = ceil(pPhyParams->CLK_PRE, tBclk) - 1; + RegMM3424_MM3554Value.CLK_PRE_Period = value < 0 ? 0 : value; + pPhyParams->CLK_PRE = (value + 1) * tBclk; + pPhyParams->CLK_PRE = ceil(pPhyParams->CLK_PRE, 1000); + + RegMM3424_MM3554Mask.Value = 0; + cbMMIOWriteReg32(pcbe, TrailRegIndex, RegMM3424_MM3554Value.Value, RegMM3424_MM3554Mask.Value); + + //LPHY_HS-EXIT_Period_Register + value = ceil(pPhyParams->HS_EXIT, tBclk) - 1; + RegMM3428_MM3558Value.Value = 0; + RegMM3428_MM3558Value.HS_EXIT_Period = value < 0 ? 0 : value; + pPhyParams->HS_EXIT = (value + 1) * tBclk; + pPhyParams->HS_EXIT = ceil(pPhyParams->HS_EXIT, 1000); + RegMM3428_MM3558Mask.Value = 0xFFFFFFFF; + RegMM3428_MM3558Mask.HS_EXIT_Period = 0; + cbMMIOWriteReg32(pcbe, ExitRegIndex, RegMM3428_MM3558Value.Value, RegMM3428_MM3558Mask.Value); + + //set MM342C, MM3430, MM3434 + //TODO + + //DSI_EPHY_Control_Register + RegMM3448_MM3578Value.Value = 0; + RegMM3448_MM3578Mask.Value = 0xFFFFFFFF; + value = ceil(pPhyParams->HS_PREPARE, (2 * tUI)); + RegMM3448_MM3578Value.THS_PREPARE = value < 0 ? 0 : value; + RegMM3448_MM3578Mask.THS_PREPARE = 0; + pPhyParams->HS_PREPARE = value * 2 * tUI; + pPhyParams->HS_PREPARE = ceil(pPhyParams->HS_PREPARE, 1000); + + value = ceil(pPhyParams->CLK_PREPARE, (2 * tUI)); + RegMM3448_MM3578Value.TCLK_PREPARE = value < 0 ? 0 : value; + RegMM3448_MM3578Mask.TCLK_PREPARE = 0; + pPhyParams->CLK_PREPARE = value * 2 * tUI; + pPhyParams->CLK_PREPARE = ceil(pPhyParams->CLK_PREPARE, 1000); + + RegMM3448_MM3578Value.Power_down_PLL = 1; // power on EPHY PLL + RegMM3448_MM3578Mask.Power_down_PLL = 0; + RegMM3448_MM3578Value.Clock_Lane_Power_Down = 1; // power on clock lane + RegMM3448_MM3578Mask.Clock_Lane_Power_Down = 0; + RegMM3448_MM3578Value.Power_Down_Data_Lane_0 = 1; // power on data lane + RegMM3448_MM3578Mask.Power_Down_Data_Lane_0 = 0; + + if (pDSIPanelTbl->LaneNum > 1) + { + RegMM3448_MM3578Value.Power_Down_Data_Lane_1 = 1; + RegMM3448_MM3578Mask.Power_Down_Data_Lane_1 = 0; + } + + if (pDSIPanelTbl->LaneNum > 2) + { + RegMM3448_MM3578Value.Power_Down_Data_Lane_2 = 1; + RegMM3448_MM3578Mask.Power_Down_Data_Lane_2 = 0; + } + + if (pDSIPanelTbl->LaneNum > 3) + { + RegMM3448_MM3578Value.Power_Down_Data_Lane_3 = 1; + RegMM3448_MM3578Mask.Power_Down_Data_Lane_3 = 0; + } + + RegMM3448_MM3578Value.Power_Down_LP_RX = 1; // power on lp-rx + RegMM3448_MM3578Mask.Power_Down_LP_RX = 0; + //cbMMIOWriteReg32(pcbe, EPhyRegIndex, RegMM3448_MM3578Value.Value, RegMM3448_MM3578Mask.Value); + + if (pDSIConfig->ClkLaneMode == CBIOS_DSI_CLK_LANE_HARDWARE_CTL) // hardware control + { + pPhyParams->tLP2HS = pPhyParams->LPX + \ + pPhyParams->LPX + \ + pPhyParams->CLK_PREPARE_ZERO + \ + pPhyParams->CLK_PRE + \ + pPhyParams->LPX + \ + pPhyParams->LPX + \ + pPhyParams->HS_PREPARE_ZERO + \ + tBclk / 1000 + \ + ceil(3 * tBclk , 1000) + \ + ceil(2 * tBclk , 1000) + \ + pPhyParams->LPX; + + pPhyParams->tHS2LP = pPhyParams->HS_TRAIL + \ + pPhyParams->HS_EXIT + \ + pPhyParams->LPX + \ + pPhyParams->CLK_POST + \ + pPhyParams->CLK_TRAIL + \ + pPhyParams->HS_EXIT + \ + pPhyParams->LPX + \ + 4 * tBclk / 1000 + \ + 3 * tBclk / 1000 + \ + 2 * tBclk / 1000 + \ + pPhyParams->LPX; + } + else // software control + { + pPhyParams->tLP2HS = pPhyParams->LPX + \ + pPhyParams->LPX + \ + pPhyParams->HS_PREPARE_ZERO + \ + tBclk / 1000 + \ + 3 * tBclk / 1000 + \ + 2 * tBclk / 1000 + \ + pPhyParams->LPX; + + pPhyParams->tHS2LP = pPhyParams->HS_TRAIL + \ + pPhyParams->HS_EXIT + \ + pPhyParams->LPX + \ + 4 * tBclk / 1000 + \ + 3 * tBclk / 1000 + \ + 2 * tBclk / 1000 + \ + pPhyParams->LPX; + } + //set Ephy parameter + cbMMIOWriteReg32(pcbe, EphyCtrlRegIndex, 0x09df3101, 0x0); + cbMMIOWriteReg32(pcbe, EphyTunRegIndex, 0xe4030802, 0x0); + cbMMIOWriteReg32(pcbe, EphyMiscRegIndex, 0x00008000, 0x0); + + cbTraceExit(DSI); +} + +static CBIOS_VOID cbDSI_IrqEnableDisable(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 BitMask, CBIOS_BOOL bEnable, CBIOS_DSI_INDEX DSIIndex) +{ + REG_MM3408_MM3538 RegMM3408_MM3538Value; + REG_MM3408_MM3538 RegMM3408_MM3538Mask; + REG_MM340C_MM353C RegMM340C_MM353CValue; + REG_MM340C_MM353C RegMM340C_MM353CMask; + REG_MM3438_MM3568 RegMM3438_MM3568Value; + REG_MM3438_MM3568 RegMM3438_MM3568Mask; + CBIOS_U32 CtrlRegIndex = 0x3408, PhyRegIndex = 0x340C, IntRegIndex = 0x3438; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + CtrlRegIndex = 0x3408; + PhyRegIndex = 0x340C; + IntRegIndex = 0x3438; + } + else if (DSIIndex == DSI_INDEX1) + { + CtrlRegIndex = 0x3538; + PhyRegIndex = 0x353C; + IntRegIndex = 0x3568; + } + + RegMM3408_MM3538Value.Value = 0; + RegMM3408_MM3538Mask.Value = 0xFFFFFFFF; + RegMM340C_MM353CValue.Value = 0; + RegMM340C_MM353CMask.Value = 0xFFFFFFFF; + RegMM3438_MM3568Value.Value = 0; + RegMM3438_MM3568Mask.Value = 0xFFFFFFFF; + + // trigger + if (BitMask & (DSI_IRQ_ULPS_TRIGGER | DSI_IRQ_RESET_TRIGGER | DSI_IRQ_TE_TRIGGER | DSI_IRQ_OTHER_TRIGGER)) + { + if (bEnable) + { + RegMM340C_MM353CValue.Receive_Trigger_Message_Interrupt_Enable = 1; + RegMM3408_MM3538Value.DSI_Read_Data_Ready_Interrupt_Enable = 1; + } + else + { + RegMM340C_MM353CValue.Receive_Trigger_Message_Interrupt_Enable = 0; + RegMM3408_MM3538Value.DSI_Read_Data_Ready_Interrupt_Enable = 0; + } + + RegMM340C_MM353CMask.Receive_Trigger_Message_Interrupt_Enable = 0; + RegMM3408_MM3538Mask.DSI_Read_Data_Ready_Interrupt_Enable = 0; + cbMMIOWriteReg32(pcbe, PhyRegIndex, RegMM340C_MM353CValue.Value, RegMM340C_MM353CMask.Value); + cbMMIOWriteReg32(pcbe, CtrlRegIndex, RegMM3408_MM3538Value.Value, RegMM3408_MM3538Mask.Value); + + // clear the interrupt status + if (BitMask & DSI_IRQ_ULPS_TRIGGER) + { + RegMM3438_MM3568Value.Receive_ULPS_Trigger_Interrupt_Status = 1; + RegMM3438_MM3568Mask.Receive_ULPS_Trigger_Interrupt_Status = 0; + } + + if (BitMask & DSI_IRQ_RESET_TRIGGER) + { + RegMM3438_MM3568Value.Receive_Reset_Trigger_Interrupt_Status = 1; + RegMM3438_MM3568Mask.Receive_Reset_Trigger_Interrupt_Status = 0; + } + + if (BitMask & DSI_IRQ_TE_TRIGGER) + { + RegMM3438_MM3568Value.Receive_TE_Trigger_Interrupt_Status = 1; + RegMM3438_MM3568Mask.Receive_TE_Trigger_Interrupt_Status = 0; + } + + if (BitMask & DSI_IRQ_OTHER_TRIGGER) + { + RegMM3438_MM3568Value.Receive_Other_Trigger_or_Unrecognized_Stauts = 1; + RegMM3438_MM3568Mask.Receive_Other_Trigger_or_Unrecognized_Stauts = 0; + } + + cbMMIOWriteReg32(pcbe, IntRegIndex, RegMM3438_MM3568Value.Value, RegMM3438_MM3568Mask.Value); + } + + // read back data + if (BitMask & DSI_IRQ_DSI_READBACK) + { + if (bEnable) + { + RegMM3408_MM3538Value.DSI_Read_Data_Ready_Interrupt_Enable = 1; + } + else + { + RegMM3408_MM3538Value.DSI_Read_Data_Ready_Interrupt_Enable = 0; + } + + RegMM3408_MM3538Mask.DSI_Read_Data_Ready_Interrupt_Enable = 0; + cbMMIOWriteReg32(pcbe, CtrlRegIndex, RegMM3408_MM3538Value.Value, RegMM3408_MM3538Mask.Value); + + // clear the status + RegMM3438_MM3568Value.DSI_Read_Back_Data_Interrupt_Status = 1; + RegMM3438_MM3568Mask.DSI_Read_Back_Data_Interrupt_Status = 0; + cbMMIOWriteReg32(pcbe, IntRegIndex, RegMM3438_MM3568Value.Value, RegMM3438_MM3568Mask.Value); + } + cbTraceExit(DSI); +} + +static CBIOS_STATUS cbDSI_SendOneFrameData(PCBIOS_VOID pvcbe, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status; + CBIOS_U8 CmdType = DSI_CMD_TYPE_VIDEO | DSI_CMD_TYPE_LAST_GROUP; + CBIOS_U8 DataType = DSI_DCS_LONG_WRITE; + cbTraceEnter(DSI); + + Status = cbDSI_SendShortPacket(pcbe, 0, DataType, DSI_DCS_WRITE_MEMORY_START, DSI_DCS_WRITE_MEMORY_CONTINUE, CmdType, DSIIndex); + + cbTraceExit(DSI); + return Status; +} + +static CBIOS_STATUS cbDSI_SetPXL_WC(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 OutBpp, CBIOS_U32 HorDispWidth, CBIOS_DSI_INDEX DSIIndex) +{ + CBIOS_U32 PXL_WC = 0; + CBIOS_STATUS Status = CBIOS_OK; + REG_MM345C_MM358C RegMM345C_MM358CValue; + REG_MM345C_MM358C RegMM345C_MM358CMask; + CBIOS_U32 VideoRegIndex = 0x345C; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + VideoRegIndex = 0x345C; + } + else if (DSIIndex == DSI_INDEX1) + { + VideoRegIndex = 0x358C; + } + + if (OutBpp == 16) + { + PXL_WC = 2 * HorDispWidth; + } + else if (OutBpp == 18) + { + if (HorDispWidth % 4 == 0) + { + PXL_WC = HorDispWidth * 18 / 8; + } + else + { + PXL_WC = (HorDispWidth + 4 - (HorDispWidth % 4)) * 18 / 8; + } + } + else if (OutBpp == 24) + { + PXL_WC = 3 * HorDispWidth; + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_PartialUpdate: Unsupport DSI out bpp!\n")); + Status = CBIOS_ER_INVALID_PARAMETER; + } + + RegMM345C_MM358CValue.Value = 0; + RegMM345C_MM358CMask.Value = 0xFFFFFFFF; + RegMM345C_MM358CValue.PXL_WC = PXL_WC; + RegMM345C_MM358CMask.PXL_WC = 0; + cbMMIOWriteReg32(pcbe, VideoRegIndex, RegMM345C_MM358CValue.Value, RegMM345C_MM358CMask.Value); + + cbTraceExit(DSI); + return Status; +} + +#if 0 +// ref to MIPI-DCS 1.02.00 spec section 6.24 for Address mode definition +static CBIOS_STATUS cbDSI_SetAddrMode(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 AddrMode, CBIOS_DSI_INDEX DSIIndex) +{ + CBIOS_STATUS Status; + CBIOS_U8 Buf[2] = {0}; + CBIOS_DSI_WRITE_PARA_INTERNAL DSIWriteParams; + cbTraceEnter(DSI); + + cb_memset(&DSIWriteParams, 0, sizeof(CBIOS_DSI_WRITE_PARA_INTERNAL)); + DSIWriteParams.DSIIndex = DSIIndex; + DSIWriteParams.VirtualCh = 0; + DSIWriteParams.PacketType = CBIOS_DSI_SHORT_PACKET; + DSIWriteParams.ContentType = CBIOS_DSI_CONTENT_DCS; + DSIWriteParams.pDataBuf = Buf; + DSIWriteParams.DataLen = 0x02; + DSIWriteParams.bNeedAck = CBIOS_TRUE; + DSIWriteParams.bHSModeOnly = CBIOS_FALSE; + + Buf[0] = DSI_DCS_SET_ADDRESS_MODE; + Buf[1] = AddrMode; + + Status = cbDSI_SendWriteCmd(pcbe, &DSIWriteParams); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SetAddrMode failed!\n")); + } + + cbTraceExit(DSI); + return Status; +} +#endif + +// ref to MIPI-DCS 1.02.00 spec section 6.25 +static CBIOS_STATUS cbDSI_SetColumnAddr(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U16 StartCol, CBIOS_U16 EndCol, CBIOS_DSI_INDEX DSIIndex) +{ + CBIOS_STATUS Status; + CBIOS_U8 Buf[5] = {0}; + CBIOS_DSI_WRITE_PARA_INTERNAL DSIWriteParams; + cbTraceEnter(DSI); + + cb_memset(&DSIWriteParams, 0, sizeof(CBIOS_DSI_WRITE_PARA_INTERNAL)); + DSIWriteParams.DSIIndex = DSIIndex; + DSIWriteParams.VirtualCh = 0; + DSIWriteParams.PacketType = CBIOS_DSI_LONG_PACKET; + DSIWriteParams.ContentType = CBIOS_DSI_CONTENT_DCS; + DSIWriteParams.pDataBuf = Buf; + DSIWriteParams.DataLen = 0x05; + DSIWriteParams.bNeedAck = CBIOS_FALSE; + DSIWriteParams.bHSModeOnly = CBIOS_FALSE; + + Buf[0] = DSI_DCS_SET_COLUMN_ADDRESS; + Buf[1] = (CBIOS_U8)((StartCol & 0xFF00) >> 8); + Buf[2] = (CBIOS_U8)(StartCol & 0x00FF); + Buf[3] = (CBIOS_U8)((EndCol & 0xFF00) >> 8); + Buf[4] = (CBIOS_U8)(EndCol & 0x00FF); + + Status = cbDSI_SendWriteCmd(pcbe, &DSIWriteParams); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SetColumnAddr failed!\n")); + } + + cbTraceExit(DSI); + return Status; +} + +// ref to MIPI-DCS 1.02.00 spec section 6.29 +static CBIOS_STATUS cbDSI_SetPageAddr(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U16 StartPage, CBIOS_U16 EndPage, CBIOS_DSI_INDEX DSIIndex) +{ + CBIOS_STATUS Status; + CBIOS_U8 Buf[5] = {0}; + CBIOS_DSI_WRITE_PARA_INTERNAL DSIWriteParams; + cbTraceEnter(DSI); + + cb_memset(&DSIWriteParams, 0, sizeof(CBIOS_DSI_WRITE_PARA_INTERNAL)); + DSIWriteParams.DSIIndex = DSIIndex; + DSIWriteParams.VirtualCh = 0; + DSIWriteParams.PacketType = CBIOS_DSI_LONG_PACKET; + DSIWriteParams.ContentType = CBIOS_DSI_CONTENT_DCS; + DSIWriteParams.pDataBuf = Buf; + DSIWriteParams.DataLen = 0x05; + DSIWriteParams.bNeedAck = CBIOS_FALSE; + DSIWriteParams.bHSModeOnly = CBIOS_FALSE; + + Buf[0] = DSI_DCS_SET_PAGE_ADDRESS; + Buf[1] = (CBIOS_U8)((StartPage & 0xFF00) >> 8); + Buf[2] = (CBIOS_U8)(StartPage & 0x00FF); + Buf[3] = (CBIOS_U8)((EndPage & 0xFF00) >> 8); + Buf[4] = (CBIOS_U8)(EndPage & 0x00FF); + + Status = cbDSI_SendWriteCmd(pcbe, &DSIWriteParams); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SetPageAddr failed!\n")); + } + + cbTraceExit(DSI); + return Status; +} + +#if 0 +// ref to MIPI-DCS 1.02.00 spec section 6.35-6.37 +static CBIOS_STATUS cbDSI_EnableDisableTE(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn, CBIOS_U16 Scanline, CBIOS_U8 TearMode, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_DSI_WRITE_PARA_INTERNAL DSIWriteParams; + CBIOS_U8 Buf[3] = {0}; + CBIOS_STATUS Status; + cbTraceEnter(DSI); + + cb_memset(&DSIWriteParams, 0, sizeof(CBIOS_DSI_WRITE_PARA_INTERNAL)); + DSIWriteParams.DSIIndex = DSIIndex; + DSIWriteParams.VirtualCh = 0; + DSIWriteParams.ContentType = CBIOS_DSI_CONTENT_DCS; + DSIWriteParams.pDataBuf = Buf; + DSIWriteParams.bNeedAck = CBIOS_TRUE; + DSIWriteParams.bHSModeOnly = CBIOS_FALSE; + + if (!bTurnOn) // disable TE function + { + Buf[0] = DSI_DCS_SET_TEAR_OFF; + DSIWriteParams.DataLen = 0x01; + DSIWriteParams.PacketType = CBIOS_DSI_SHORT_PACKET; + Status = cbDSI_SendWriteCmd(pcbe, &DSIWriteParams); + } + else // enable TE + { + if (Scanline > 0) + { + Buf[0] = DSI_DCS_SET_TEAR_SCANLINE; + Buf[1] = (CBIOS_U8)(Scanline & 0xFF); + Buf[2] = (CBIOS_U8)(Scanline >> 8) & 0xFF; + DSIWriteParams.DataLen = 0x03; + DSIWriteParams.PacketType = CBIOS_DSI_LONG_PACKET; + Status = cbDSI_SendWriteCmd(pcbe, &DSIWriteParams); + } + else + { + Buf[0] = DSI_DCS_SET_TEAR_ON; + Buf[1] = TearMode; // TearMode == 0: VSYNC, TearMode == 1: VSYNC+HSYNC + DSIWriteParams.DataLen = 0x02; + DSIWriteParams.PacketType = CBIOS_DSI_SHORT_PACKET; + Status = cbDSI_SendWriteCmd(pcbe, &DSIWriteParams); + } + } + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_EnableDisableTE failed!\n")); + } + + cbTraceExit(DSI); + return Status; +} +#endif + +// This function is not really send DCS set_tear_on cmd, it just send a TE BTA to panel, so that host can receive TE signal from panel +CBIOS_STATUS cbDSI_SetTE_BTA(PCBIOS_VOID pvcbe, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status; + // when we set DSI_CMD_TYPE_TE flag, we should also set DSI_CMD_TYPE_NEED_ACK, that hw can know we want to send TE BTA + CBIOS_U8 CmdType = 0; + CBIOS_U8 DataBuf[3] = {0}; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DSI); + CBIOS_U16 ScanLine = (CBIOS_U16)pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc.DSIPanelTbl.PanelTiming.YResolution; + cbTraceEnter(DSI); + + //set TE on + CmdType = DSI_CMD_TYPE_LAST_GROUP | DSI_CMD_TYPE_LP; + Status = cbDSI_SendShortPacket(pcbe, 0, DSI_DCS_SHORT_WRITE_PARAM, DSI_DCS_SET_TEAR_ON, 0, CmdType, DSIIndex); + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "Set tear on without BTA failed!\n")); + } + + //set TE scan line + CmdType = DSI_CMD_TYPE_LAST_GROUP | DSI_CMD_TYPE_LP; + DataBuf[0] = DSI_DCS_SET_TEAR_SCANLINE; + DataBuf[1] = (ScanLine >> 8) & 0xff; + DataBuf[2] = ScanLine & 0xff; + Status = cbDSI_SendLongPacket(pcbe, 0, DSI_DCS_LONG_WRITE, 3, DataBuf, CmdType, DSIIndex); + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "Set tear scanline failed!\n")); + } + + //set BTA + CmdType = DSI_CMD_TYPE_LAST_GROUP | DSI_CMD_TYPE_LP | DSI_CMD_TYPE_TE | DSI_CMD_TYPE_NEED_ACK; + Status = cbDSI_SendShortPacket(pcbe, 0, DSI_DCS_SHORT_WRITE_PARAM, DSI_DCS_SET_TEAR_ON, 0, CmdType, DSIIndex); + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "Set tear on with BTA failed!\n")); + } + + cbTraceExit(DSI); + return Status; +} + +#if 0 +// ref to MIPI-DSI spec 8.8.10 +static CBIOS_STATUS cbDSI_SetMaxReturnSize(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U16 MaxSize, CBIOS_DSI_INDEX DSIIndex) +{ + CBIOS_STATUS Status; + CBIOS_U8 CmdType = DSI_CMD_TYPE_LAST_GROUP | DSI_CMD_TYPE_LP | DSI_CMD_TYPE_NEED_ACK; + CBIOS_U8 Buf[2] = {0}; + cbTraceEnter(DSI); + + // LS byte first + Buf[0] = (CBIOS_U8)(MaxSize & 0xFF); + Buf[1] = (CBIOS_U8)((MaxSize >> 8) & 0xFF); + + Status = cbDSI_SendShortPacket(pcbe, 0, DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, Buf[0], Buf[1], CmdType, DSIIndex); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SetMaxReturnSize failed!\n")); + } + + cbTraceExit(DSI); + return Status; +} +#endif + +static CBIOS_STATUS cbDSI_GetReceivedPayload(PCBIOS_VOID pvcbe, CBIOS_U8 *pDataBuf, CBIOS_U16 *pBufLen, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U8 DataType; + CBIOS_U16 WordCount; + CBIOS_U32 RawData, i, Reminder; + CBIOS_U32 DataRegIndex = 0x3404; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + DataRegIndex = 0x3404; + } + else if (DSIIndex == DSI_INDEX1) + { + DataRegIndex = 0x3534; + } + + if ((pDataBuf == CBIOS_NULL) || (pBufLen == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_ReadBackData: data buffer or buffer length is null! \n")); + Status = CBIOS_ER_NULLPOINTER; + goto Exit; + } + + // first parse the data type + RawData = cbReadRegisterU32(pcbe, CBIOS_REGISTER_MMIO, DataRegIndex); + DataType = (CBIOS_U8)(RawData & 0x3F); + + if ((DataType == DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE) || (DataType == DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE)) + { + pDataBuf[0] = (CBIOS_U8)((RawData & 0xFF00) >> 8); + *pBufLen = 1; + goto Exit; + } + else if ((DataType == DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE) || (DataType == DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE)) + { + pDataBuf[0] = (CBIOS_U8)((RawData & 0xFF00) >> 8); + pDataBuf[1] = (CBIOS_U8)((RawData & 0xFF0000) >> 16); + *pBufLen = 2; + goto Exit; + } + else if ((DataType == DSI_RX_DCS_LONG_READ_RESPONSE) || (DataType == DSI_RX_GENERIC_LONG_READ_RESPONSE)) + { + WordCount = (CBIOS_U16)((RawData & 0xFFFF00) >> 8); // get the wordcount + + for (i = 0; i < (CBIOS_U32)(WordCount >> 2); i++) + { + *((CBIOS_U32 *)(pDataBuf + i * 4)) = cbReadRegisterU32(pcbe, CBIOS_REGISTER_MMIO, DataRegIndex); + } + + Reminder = WordCount % 4; + + if (Reminder != 0) + { + RawData = cbReadRegisterU32(pcbe, CBIOS_REGISTER_MMIO, DataRegIndex); + + for (i = Reminder; i > 0; i--) + { + *((CBIOS_U8 *)(pDataBuf + WordCount - i)) = (CBIOS_U8)((RawData >> (Reminder - i) * 8) & 0xFF); + } + } + + *pBufLen = WordCount; + } + +Exit: + cbTraceExit(DSI); + return Status; +} + +static CBIOS_VOID cbDSI_ClearReadFIFO(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_DSI_INDEX DSIIndex) +{ + CBIOS_U32 ReadDataNum, i; + REG_MM3444_MM3574 RegMM3444_MM3574Value; + REG_MM3404_MM3534 RegMM3404_MM3534Value; + CBIOS_U32 StatusRegIndex = 0x3444, DataRegIndex = 0x3404; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + StatusRegIndex = 0x3444; + DataRegIndex = 0x3404; + } + else if (DSIIndex == DSI_INDEX1) + { + StatusRegIndex = 0x3574; + DataRegIndex = 0x3534; + } + + RegMM3444_MM3574Value.Value = cbReadRegisterU32(pcbe, CBIOS_REGISTER_MMIO, StatusRegIndex); + ReadDataNum = RegMM3444_MM3574Value.DSI_Read_Back_Data_Number; + + for(i = 0; i < ReadDataNum; i+=4) + { + RegMM3404_MM3534Value.Value = cbReadRegisterU32(pcbe, CBIOS_REGISTER_MMIO, DataRegIndex); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "cbDSI_ClearReadFIFO: uncaught read data: 0x%08x! \n", RegMM3404_MM3534Value.Value)); + } + + cbTraceExit(DSI); +} + +/* DCS command interfaces start */ + +CBIOS_STATUS cbDSI_SendWriteCmd(PCBIOS_VOID pvcbe, PCBIOS_DSI_WRITE_PARA_INTERNAL pDSIWriteParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status; + CBIOS_U8 DataType; + CBIOS_U32 i; + CBIOS_BOOL bReceiveACK; + CBIOS_DSI_INDEX DSIIndex = pDSIWriteParams->DSIIndex; + CBIOS_U16 DataLen = pDSIWriteParams->DataLen; + PCBIOS_U8 pDataBuf = pDSIWriteParams->pDataBuf; + CBIOS_U8 VirtualCh = pDSIWriteParams->VirtualCh; + CBIOS_U8 CmdType = DSI_CMD_TYPE_LAST_GROUP; + REG_MM3438_MM3568 RegMM3438_MM3568Value; + REG_MM3438_MM3568 RegMM3438_MM3568Mask; + CBIOS_U32 IntRegIndex = 0x3438; + cbTraceEnter(DSI); + + cbDSI_ClearReadFIFO(pcbe, DSIIndex); + + if (DSIIndex == DSI_INDEX0) + { + IntRegIndex = 0x3438; + } + else if (DSIIndex == DSI_INDEX1) + { + IntRegIndex = 0x3568; + } + + if (pDSIWriteParams->bNeedAck) + { + CmdType |= DSI_CMD_TYPE_NEED_ACK; + } + + if (!pDSIWriteParams->bHSModeOnly) + { + CmdType |= DSI_CMD_TYPE_LP; + } + + if (pDSIWriteParams->PacketType == CBIOS_DSI_SHORT_PACKET) + { + if (pDSIWriteParams->ContentType == CBIOS_DSI_CONTENT_DCS) + { + if (DataLen == 1) + { + DataType = DSI_DCS_SHORT_WRITE; + Status = cbDSI_SendShortPacket(pcbe, VirtualCh, DataType, pDataBuf[0], 0, CmdType, DSIIndex); + } + else if (DataLen == 2) + { + DataType = DSI_DCS_SHORT_WRITE_PARAM; + Status = cbDSI_SendShortPacket(pcbe, VirtualCh, DataType, pDataBuf[0], pDataBuf[1], CmdType, DSIIndex); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendWriteCmd: Data length is invaild for DCS write short packet! \n")); + Status = CBIOS_ER_INVALID_PARAMETER; + goto Exit; + } + } + else if (pDSIWriteParams->ContentType == CBIOS_DSI_CONTENT_GEN) + { + if (DataLen == 0) + { + DataType = DSI_GENERIC_SHORT_WRITE_0_PARAM; + Status = cbDSI_SendShortPacket(pcbe, VirtualCh, DataType, 0, 0, CmdType, DSIIndex); + } + else if (DataLen == 1) + { + DataType = DSI_GENERIC_SHORT_WRITE_1_PARAM; + Status = cbDSI_SendShortPacket(pcbe, VirtualCh, DataType, pDataBuf[0], 0, CmdType, DSIIndex); + } + else if (DataLen == 2) + { + DataType = DSI_GENERIC_SHORT_WRITE_2_PARAM; + Status = cbDSI_SendShortPacket(pcbe, VirtualCh, DataType, pDataBuf[0], pDataBuf[1], CmdType, DSIIndex); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendWriteCmd: Data length is invaild for GEN write short packet! \n")); + Status = CBIOS_ER_INVALID_PARAMETER; + goto Exit; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendWriteCmd: ContentType is invaild! \n")); + Status = CBIOS_ER_INVALID_PARAMETER; + goto Exit; + } + } + else if (pDSIWriteParams->PacketType == CBIOS_DSI_LONG_PACKET) + { + if (pDSIWriteParams->ContentType == CBIOS_DSI_CONTENT_DCS) + { + DataType = DSI_DCS_LONG_WRITE; + Status = cbDSI_SendLongPacket(pcbe, VirtualCh, DataType, DataLen, pDataBuf, CmdType, DSIIndex); + } + else if (pDSIWriteParams->ContentType == CBIOS_DSI_CONTENT_GEN) + { + DataType = DSI_GENERIC_LONG_WRITE; + Status = cbDSI_SendLongPacket(pcbe, VirtualCh, DataType, DataLen, pDataBuf, CmdType, DSIIndex); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendWriteCmd: ContentType is invaild! \n")); + Status = CBIOS_ER_INVALID_PARAMETER; + goto Exit; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendWriteCmd: PacketType is invaild! \n")); + Status = CBIOS_ER_INVALID_PARAMETER; + goto Exit; + } + + if (pDSIWriteParams->bNeedAck) + { + //wait for ACK + // Fix me: the delay time may be not correct + bReceiveACK = CBIOS_FALSE; + + for (i = 0; i < CBIOS_DSI_POLLING_TIMEOUT; i++) + { + RegMM3438_MM3568Value.Value = cbReadRegisterU32(pcbe, CBIOS_REGISTER_MMIO, IntRegIndex); + + if (RegMM3438_MM3568Value.Receive_Other_Trigger_or_Unrecognized_Stauts) + { + if (RegMM3438_MM3568Value.Receive_Trigger_Data == DSI_TRIGGER_MSG_ACK) + { + bReceiveACK = CBIOS_TRUE; + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "cbDSI_SendWriteCmd: Receive the ACK success! \n")); + Status = CBIOS_OK; + // clear the status + RegMM3438_MM3568Value.Value = 0; + RegMM3438_MM3568Mask.Value = 0xFFFFFFFF; + RegMM3438_MM3568Value.Receive_Other_Trigger_or_Unrecognized_Stauts = 1; + RegMM3438_MM3568Mask.Receive_Other_Trigger_or_Unrecognized_Stauts = 0; + cbMMIOWriteReg32(pcbe, IntRegIndex, RegMM3438_MM3568Value.Value, RegMM3438_MM3568Mask.Value); + break; + } + } + else + { + cbDelayMilliSeconds(1); + } + } + + if (!bReceiveACK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendWriteCmd: Receive the ACK failed! \n")); + Status = CBIOS_ER_INTERNAL; + } + } + +Exit: + cbTraceExit(DSI); + return Status; +} + + +CBIOS_STATUS cbDSI_SendReadCmd(PCBIOS_VOID pvcbe, PCBIOS_DSI_READ_PARA_INTERNAL pDSIReadParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_DSI_INDEX DSIIndex = pDSIReadParams->DSIIndex; + CBIOS_U16 DataLen = pDSIReadParams->DataLen; + PCBIOS_U8 pDataBuf = pDSIReadParams->pDataBuf; + CBIOS_U8 VirtualCh = pDSIReadParams->VirtualCh; + CBIOS_U8 CmdType = DSI_CMD_TYPE_LAST_GROUP | DSI_CMD_TYPE_NEED_ACK; + CBIOS_U8 DataType; + CBIOS_STATUS Status; + CBIOS_BOOL bGetResponse = CBIOS_FALSE; + CBIOS_U32 i; + REG_MM3438_MM3568 RegMM3438_MM3568Value; + REG_MM3438_MM3568 RegMM3438_MM3568Mask; + CBIOS_U32 IntRegIndex = 0x3438; + cbTraceEnter(DSI); + + cbDSI_ClearReadFIFO(pcbe, DSIIndex); + + if (DSIIndex == DSI_INDEX0) + { + IntRegIndex = 0x3438; + } + else if (DSIIndex == DSI_INDEX1) + { + IntRegIndex = 0x3568; + } + + if (!pDSIReadParams->bHSModeOnly) + { + CmdType |= DSI_CMD_TYPE_LP; + } + + // clear read back data interrupt status + RegMM3438_MM3568Value.Value = 0; + RegMM3438_MM3568Mask.Value = 0xFFFFFFFF; + RegMM3438_MM3568Value.DSI_Read_Back_Data_Interrupt_Status = 1; + RegMM3438_MM3568Mask.DSI_Read_Back_Data_Interrupt_Status = 0; + cbMMIOWriteReg32(pcbe, IntRegIndex, RegMM3438_MM3568Value.Value, RegMM3438_MM3568Mask.Value); + + // send read cmd + if (pDSIReadParams->ContentType == CBIOS_DSI_CONTENT_DCS) + { + DataType = DSI_DCS_READ; + Status = cbDSI_SendShortPacket(pcbe, VirtualCh, DataType, pDataBuf[0], 0, CmdType, DSIIndex); + } + else if (pDSIReadParams->ContentType == CBIOS_DSI_CONTENT_GEN) + { + if (DataLen == 0) + { + DataType = DSI_GENERIC_READ_REQUEST_0_PARAM; + Status = cbDSI_SendShortPacket(pcbe, VirtualCh, DataType, 0, 0, CmdType, DSIIndex); + } + else if (DataLen == 1) + { + DataType = DSI_GENERIC_READ_REQUEST_1_PARAM; + Status = cbDSI_SendShortPacket(pcbe, VirtualCh, DataType, pDataBuf[0], 0, CmdType, DSIIndex); + } + else if (DataLen == 2) + { + DataType = DSI_GENERIC_READ_REQUEST_2_PARAM; + Status = cbDSI_SendShortPacket(pcbe, VirtualCh, DataType, pDataBuf[0], pDataBuf[1], CmdType, DSIIndex); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendGenReadCmd: Data length is invaild for generic read short packet! \n")); + Status = CBIOS_ER_INVALID_PARAMETER; + goto Exit; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendReadCmd: ContentType is invaild! \n")); + Status = CBIOS_ER_INVALID_PARAMETER; + goto Exit; + } + + // get read back payload + if (Status == CBIOS_OK) + { + for (i = 0; i < CBIOS_DSI_POLLING_TIMEOUT; i++) + { + RegMM3438_MM3568Value.Value = cbReadRegisterU32(pcbe, CBIOS_REGISTER_MMIO, IntRegIndex); + + if (RegMM3438_MM3568Value.DSI_Read_Back_Data_Interrupt_Status) + { + bGetResponse = CBIOS_TRUE; + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "cbDSI_SendReadCmd: Receive the read back data! \n")); + // clear the status + RegMM3438_MM3568Value.DSI_Read_Back_Data_Interrupt_Status = 1; + RegMM3438_MM3568Mask.DSI_Read_Back_Data_Interrupt_Status = 0; + cbMMIOWriteReg32(pcbe, IntRegIndex, RegMM3438_MM3568Value.Value, RegMM3438_MM3568Mask.Value); + break; + } + else + { + cbDelayMilliSeconds(1); + } + } + + if (bGetResponse) + { + Status = cbDSI_GetReceivedPayload(pcbe, pDSIReadParams->pReceivedPayloadBuf, &(pDSIReadParams->ReceivedPayloadLen), DSIIndex); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendReadCmd: get read back data failed! \n")); + Status = CBIOS_ER_INTERNAL; + goto Exit; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SendReadCmd: send read cmd failed! \n")); + } + +Exit: + cbTraceExit(DSI); + return Status; +} + + +CBIOS_STATUS cbDSI_SetDisplayOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status; + CBIOS_U8 Buf[0x01] = {DSI_DCS_SET_DISPLAY_ON}; + CBIOS_DSI_WRITE_PARA_INTERNAL DSIWriteParams; + cbTraceEnter(DSI); + + cb_memset(&DSIWriteParams, 0, sizeof(CBIOS_DSI_WRITE_PARA_INTERNAL)); + DSIWriteParams.DSIIndex = DSIIndex; + DSIWriteParams.VirtualCh = 0; + DSIWriteParams.PacketType = CBIOS_DSI_SHORT_PACKET; + DSIWriteParams.ContentType = CBIOS_DSI_CONTENT_DCS; + DSIWriteParams.pDataBuf = Buf; + DSIWriteParams.DataLen = 0x01; + DSIWriteParams.bNeedAck = CBIOS_FALSE; + DSIWriteParams.bHSModeOnly = CBIOS_FALSE; + + if (bTurnOn) + { + Buf[0] = DSI_DCS_SET_DISPLAY_ON; + } + else + { + Buf[0] = DSI_DCS_SET_DISPLAY_OFF; + } + + Status = cbDSI_SendWriteCmd(pcbe, &DSIWriteParams); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SetDisplayOnOff failed!\n")); + } + + cbTraceExit(DSI); + return Status; +} + +CBIOS_STATUS cbDSI_PanelSoftReset(PCBIOS_VOID pvcbe, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U8 Buf[0x01] = {DSI_DCS_SOFT_RESET}; + CBIOS_DSI_WRITE_PARA_INTERNAL DSIWriteParams; + cbTraceEnter(DSI); + + cb_memset(&DSIWriteParams, 0, sizeof(CBIOS_DSI_WRITE_PARA_INTERNAL)); + DSIWriteParams.DSIIndex = DSIIndex; + DSIWriteParams.VirtualCh = 0; + DSIWriteParams.PacketType = CBIOS_DSI_SHORT_PACKET; + DSIWriteParams.ContentType = CBIOS_DSI_CONTENT_DCS; + DSIWriteParams.pDataBuf = Buf; + DSIWriteParams.DataLen = 0x01; + DSIWriteParams.bNeedAck = CBIOS_FALSE; + DSIWriteParams.bHSModeOnly = CBIOS_FALSE; + + Status = cbDSI_SendWriteCmd(pcbe, &DSIWriteParams); + + if (Status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_PanelSoftReset failed!\n")); + } + + cbTraceExit(DSI); + return Status; +} + +/* Switch the display module between the idle, invert, normal, partial and sleep mode described in MIPI-DCS spec*/ +static CBIOS_STATUS cbDSI_DCSSwitchMode(PCBIOS_VOID pvcbe, CBIOS_DSI_DCS_MODE Mode, CBIOS_BOOL bEnter, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status; + CBIOS_U8 Buf[1] = {0}; + CBIOS_DSI_WRITE_PARA_INTERNAL DSIWriteParams; + cbTraceEnter(DSI); + + cb_memset(&DSIWriteParams, 0, sizeof(CBIOS_DSI_WRITE_PARA_INTERNAL)); + DSIWriteParams.DSIIndex = DSIIndex; + DSIWriteParams.VirtualCh = 0; + DSIWriteParams.PacketType = CBIOS_DSI_SHORT_PACKET; + DSIWriteParams.ContentType = CBIOS_DSI_CONTENT_DCS; + DSIWriteParams.pDataBuf = Buf; + DSIWriteParams.DataLen = 0x01; + DSIWriteParams.bNeedAck = CBIOS_FALSE; + DSIWriteParams.bHSModeOnly = CBIOS_FALSE; + + switch (Mode) + { + case CBIOS_DSI_DCS_IDLE_MODE: + if (bEnter) + { + Buf[0] = DSI_DCS_ENTER_IDLE_MODE; + } + else + { + Buf[0] = DSI_DCS_EXIT_IDLE_MODE; + } + + break; + + case CBIOS_DSI_DCS_INVERT_MODE: + if (bEnter) + { + Buf[0] = DSI_DCS_ENTER_INVERT_MODE; + } + else + { + Buf[0] = DSI_DCS_EXIT_INVERT_MODE; + } + + break; + + case CBIOS_DSI_DCS_NORMAL_MODE: + if (bEnter) + { + Buf[0] = DSI_DCS_ENTER_NORMAL_MODE; + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "cbDSI_DCSSwitchMode: there is no exit_normal_mode cmd, send nop instead! \n")); + Buf[0] = DSI_DCS_NOP; + } + + break; + + case CBIOS_DSI_DCS_PARTIAL_MODE: + if (bEnter) + { + Buf[0] = DSI_DCS_ENTER_PARTIAL_MODE; + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "cbDSI_DCSSwitchMode: there is no exit_partial_mode cmd, send nop instead! \n")); + Buf[0] = DSI_DCS_NOP; + } + + break; + + case CBIOS_DSI_DCS_SLEEP_MODE: + if (bEnter) + { + Buf[0] = DSI_DCS_ENTER_SLEEP_MODE; + } + else + { + Buf[0] = DSI_DCS_EXIT_SLEEP_MODE; + } + + break; + } + + Status = cbDSI_SendWriteCmd(pcbe, &DSIWriteParams); + + cbTraceExit(DSI); + return Status; +} + +static CBIOS_VOID cbDSI_SetDSITimingHW(PCBIOS_VOID pvcbe, PCBIOS_DSI_PARAMS pDSIParams, PCBIOS_TIMING_ATTRIB pTiming, CBIOS_U32 IGAIndex, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 tDclk, tBclk; + CBIOS_BOOL isHFPEnterLP, isHSAEnterLP, isHBPEnterLP; + CBIOS_U16 HorFrontPorch, HorSyncAct, HorBackPorch; + CBIOS_DSI_VIDEO_TIMING_REG DSITimingReg; + PCBIOS_DSI_PHY_PARAMS pPhyParams; + PCBIOS_DSI_CONFIG pDSIConfig = &(pDSIParams->DSIPanelDesc.DSIConfig); + PCBIOS_DSI_PANEL_TABLE pDSIPanelTbl = &(pDSIParams->DSIPanelDesc.DSIPanelTbl); + PCBIOS_TIMING_ATTRIB pTimingAttrib; + REG_MM345C_MM358C RegMM345C_MM358CValue; + REG_MM345C_MM358C RegMM345C_MM358CMask; + REG_MM3460_MM3590 RegMM3460_MM3590Value; + REG_MM3460_MM3590 RegMM3460_MM3590Mask; + REG_MM3464_MM3594 RegMM3464_MM3594Value; + REG_MM3464_MM3594 RegMM3464_MM3594Mask; + REG_MM3468_MM3598 RegMM3468_MM3598Value; + REG_MM3468_MM3598 RegMM3468_MM3598Mask; + REG_MM34C0_MM34C8 RegMM34C0_MM34C8Value; + REG_MM34C0_MM34C8 RegMM34C0_MM34C8Mask; + CBIOS_U32 VideoReg1Index = 0x345C, VideoReg2Index = 0x3460; + CBIOS_U32 VideoReg3Index = 0x3464, VideoReg4Index = 0x3468; + CBIOS_U32 VideoReg5Index = 0x34c0; + CBIOS_TIMING_ATTRIB TimingAttrib = {0}; + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + VideoReg1Index = 0x345C; + VideoReg2Index = 0x3460; + VideoReg3Index = 0x3464; + VideoReg4Index = 0x3468; + VideoReg5Index = 0x34c0; + } + else if (DSIIndex == DSI_INDEX1) + { + VideoReg1Index = 0x358C; + VideoReg2Index = 0x3590; + VideoReg3Index = 0x3594; + VideoReg4Index = 0x3598; + VideoReg5Index = 0x34c8; + } + + cb_memset(&DSITimingReg, 0, sizeof(CBIOS_DSI_VIDEO_TIMING_REG)); + pPhyParams = &(pDSIParams->PhyParams); + pTimingAttrib = &TimingAttrib; + cb_memcpy(pTimingAttrib, pTiming, sizeof(CBIOS_TIMING_ATTRIB)); + if (pDSIConfig->isDualChannel) + { + pTimingAttrib->PixelClock /= 2; + pTimingAttrib->HorTotal /= 2; + pTimingAttrib->HorDisEnd /= 2; + pTimingAttrib->HorBStart /= 2; + pTimingAttrib->HorBEnd /= 2; + pTimingAttrib->HorSyncStart /= 2; + pTimingAttrib->HorSyncEnd /= 2; + } + tDclk = 10000000 / (pTimingAttrib->PixelClock) * 1000; // unit: ps, 1ns = 1000ps + tBclk = tDclk * pDSIPanelTbl->LaneNum * 8 / pDSIPanelTbl->OutBpp; // unit: ps, 1ns = 1000ps + + + HorFrontPorch = pTimingAttrib->HorSyncStart - pTimingAttrib->HorBStart; + HorSyncAct = pTimingAttrib->HorSyncEnd - pTimingAttrib->HorSyncStart; + HorBackPorch = pTimingAttrib->HorBEnd - pTimingAttrib->HorSyncEnd; + + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "%s: HorFrontPorch: %d\n ", FUNCTION_NAME, HorFrontPorch)); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "%s: HorSyncAct: %d\n ", FUNCTION_NAME, HorSyncAct)); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "%s: HorBackPorch: %d\n ", FUNCTION_NAME, HorBackPorch)); + + // calc *_WC + if (pDSIPanelTbl->OutBpp == 16) + { + DSITimingReg.PXL_WC = 2 * pTimingAttrib->HorDisEnd; + DSITimingReg.HFP_WC = 2 * HorFrontPorch - 11; + DSITimingReg.HSA_WC = 2 * HorSyncAct - 10; + + if (pDSIConfig->SyncPacketType == CBIOS_DSI_SYNC_PULSE) + { + DSITimingReg.HBP_WC = 2 * pTimingAttrib->HorTotal - DSITimingReg.PXL_WC - DSITimingReg.HFP_WC - DSITimingReg.HSA_WC - 32; + } + else + { + DSITimingReg.HBP_WC = 2 * pTimingAttrib->HorTotal - DSITimingReg.PXL_WC - DSITimingReg.HFP_WC - 22; + } + } + else if (pDSIPanelTbl->OutBpp == 18) + { + if (pTimingAttrib->HorDisEnd % 4 == 0) + { + DSITimingReg.PXL_WC = pTimingAttrib->HorDisEnd * 18 / 8; + } + else + { + DSITimingReg.PXL_WC = (pTimingAttrib->HorDisEnd + 4 - (pTimingAttrib->HorDisEnd % 4)) * 18 / 8; + } + + DSITimingReg.HFP_WC = cbRound(HorFrontPorch * 18, 8, ROUND_UP) - 11; + DSITimingReg.HSA_WC = cbRound(HorSyncAct * 18, 8, ROUND_UP) - 10; + + if (pDSIConfig->SyncPacketType == CBIOS_DSI_SYNC_PULSE) + { + DSITimingReg.HBP_WC = pTimingAttrib->HorTotal * 18 / 8 - DSITimingReg.PXL_WC - DSITimingReg.HFP_WC - DSITimingReg.HSA_WC - 32; + } + else + { + DSITimingReg.HBP_WC = pTimingAttrib->HorTotal * 18 / 8 - DSITimingReg.PXL_WC - DSITimingReg.HFP_WC - 22; + } + } + else if (pDSIPanelTbl->OutBpp == 24) + { + DSITimingReg.PXL_WC = 3 * pTimingAttrib->HorDisEnd; + DSITimingReg.HFP_WC = 3 * HorFrontPorch - 11; + DSITimingReg.HSA_WC = 3 * HorSyncAct - 10; + + if (pDSIConfig->SyncPacketType == CBIOS_DSI_SYNC_PULSE) + { + DSITimingReg.HBP_WC = pTimingAttrib->HorTotal * 3 - DSITimingReg.PXL_WC - DSITimingReg.HFP_WC - DSITimingReg.HSA_WC - 32; + } + else + { + DSITimingReg.HBP_WC = pTimingAttrib->HorTotal * 3 - DSITimingReg.PXL_WC - DSITimingReg.HFP_WC - 22; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "cbDSI_SetVideoModeTiming: Unsupport DSI video mode bpp!\n")); + } + + // calc *LP2HS + DSITimingReg.HSS_LP2HS = (CBIOS_S32)(pTimingAttrib->HorSyncStart * tDclk - 1000 * pPhyParams->tLP2HS); + DSITimingReg.HSE_LP2HS = (CBIOS_S32)(pTimingAttrib->HorSyncEnd * tDclk - 1000 * pPhyParams->tLP2HS); + DSITimingReg.PXL_LP2HS = (CBIOS_S32)(pTimingAttrib->HorBEnd * tDclk - 1000 * pPhyParams->tLP2HS); + + if ((DSITimingReg.HSS_LP2HS <= 0) || (DSITimingReg.HSE_LP2HS <= 0) || (DSITimingReg.PXL_LP2HS <= 0)) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_SetVideoModeTiming: Error: *LP2HS is negative!\n")); + } + + DSITimingReg.HSS_LP2HS = ceil(DSITimingReg.HSS_LP2HS, tBclk); + DSITimingReg.HSE_LP2HS = ceil(DSITimingReg.HSE_LP2HS, tBclk); + DSITimingReg.PXL_LP2HS = ceil(DSITimingReg.PXL_LP2HS, tBclk); + + // set DSI timing registers + RegMM345C_MM358CValue.Value = 0; + RegMM345C_MM358CMask.Value = 0xFFFFFFFF; + RegMM345C_MM358CValue.PXL_WC = DSITimingReg.PXL_WC; + RegMM345C_MM358CMask.PXL_WC = 0; + cbMMIOWriteReg32(pcbe, VideoReg1Index, RegMM345C_MM358CValue.Value, RegMM345C_MM358CMask.Value); + + RegMM3460_MM3590Value.HFP_WC = DSITimingReg.HFP_WC; + RegMM3460_MM3590Value.HSA_WC = DSITimingReg.HSA_WC; + RegMM3460_MM3590Mask.Value = 0; + cbMMIOWriteReg32(pcbe, VideoReg2Index, RegMM3460_MM3590Value.Value, RegMM3460_MM3590Mask.Value); + + RegMM3464_MM3594Value.HBP_WC = DSITimingReg.HBP_WC; + RegMM3464_MM3594Value.HSS_LP2HS = DSITimingReg.HSS_LP2HS; + RegMM3464_MM3594Mask.Value = 0; + cbMMIOWriteReg32(pcbe, VideoReg3Index, RegMM3464_MM3594Value.Value, RegMM3464_MM3594Mask.Value); + + RegMM3468_MM3598Value.HSE_LP2HS = DSITimingReg.HSE_LP2HS; + RegMM3468_MM3598Value.PXL_LP2HS = DSITimingReg.PXL_LP2HS; + RegMM3468_MM3598Mask.Value = 0; + cbMMIOWriteReg32(pcbe, VideoReg4Index, RegMM3468_MM3598Value.Value, RegMM3468_MM3598Mask.Value); + + // set video mode lp + if (pDSIConfig->DSIMode == CBIOS_DSI_VIDEOMODE) + { + isHFPEnterLP = pDSIConfig->isHFPEnterLP; + isHSAEnterLP = pDSIConfig->isHSAEnterLP; + isHBPEnterLP = pDSIConfig->isHBPEnterLP; + + if ((HorFrontPorch * tDclk) <= (pPhyParams->tHS2LP + pPhyParams->tLP2HS) * 1000) + { + isHFPEnterLP = CBIOS_FALSE; + } + + if (pDSIConfig->SyncPacketType == CBIOS_DSI_SYNC_PULSE) + { + if ((HorSyncAct * tDclk) <= (pPhyParams->tHS2LP + pPhyParams->tLP2HS) * 1000) + { + isHSAEnterLP = CBIOS_FALSE; + } + } + + if (pDSIConfig->SyncPacketType == CBIOS_DSI_SYNC_PULSE) + { + if ((HorBackPorch * tDclk) <= (pPhyParams->tHS2LP + pPhyParams->tLP2HS) * 1000) + { + isHBPEnterLP = CBIOS_FALSE; + } + } + else + { + if ((HorSyncAct + HorBackPorch) * tDclk <= (pPhyParams->tHS2LP + pPhyParams->tLP2HS) * 1000) + { + isHBPEnterLP = CBIOS_FALSE; + } + } + } + else + { + isHFPEnterLP = CBIOS_FALSE; + isHSAEnterLP = CBIOS_FALSE; + isHBPEnterLP = CBIOS_FALSE; + } + + RegMM345C_MM358CValue.HFP_LP = isHFPEnterLP; + RegMM345C_MM358CValue.HSA_LP = isHSAEnterLP; + RegMM345C_MM358CValue.HBP_LP = isHBPEnterLP; + RegMM345C_MM358CValue.DSI_Video_Mode_Enable = 1; + RegMM345C_MM358CMask.HFP_LP = 0; + RegMM345C_MM358CMask.HSA_LP = 0; + RegMM345C_MM358CMask.HBP_LP = 0; + RegMM345C_MM358CMask.DSI_Video_Mode_Enable = 0; + cbMMIOWriteReg32(pcbe, VideoReg1Index, RegMM345C_MM358CValue.Value, RegMM345C_MM358CMask.Value); + + if (pDSIConfig->DSIMode == CBIOS_DSI_CMDMODE) + { + RegMM34C0_MM34C8Value.Value = 0; + RegMM34C0_MM34C8Value.DSI_CMD_Mode_Enable = 1; + RegMM34C0_MM34C8Mask.Value = 0xFFFFFFFF; + RegMM34C0_MM34C8Mask.DSI_CMD_Mode_Enable = 0; + cbMMIOWriteReg32(pcbe, VideoReg5Index, RegMM34C0_MM34C8Value.Value, RegMM34C0_MM34C8Mask.Value); + } + else + { + RegMM34C0_MM34C8Value.Value = 0; + RegMM34C0_MM34C8Value.DSI_CMD_Mode_Enable = 0; + RegMM34C0_MM34C8Mask.Value = 0xFFFFFFFF; + RegMM34C0_MM34C8Mask.DSI_CMD_Mode_Enable = 0; + cbMMIOWriteReg32(pcbe, VideoReg5Index, RegMM34C0_MM34C8Value.Value, RegMM34C0_MM34C8Mask.Value); + } + cbTraceExit(DSI); +} + +CBIOS_VOID cbDSI_ControllerInit(PCBIOS_VOID pvcbe, CBIOS_U32 IGAIndex, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM3400_MM3530 RegMM3400_MM3530Value; + REG_MM3400_MM3530 RegMM3400_MM3530Mask; + REG_MM3408_MM3538 RegMM3408_MM3538Value; + REG_MM3408_MM3538 RegMM3408_MM3538Mask; + REG_MM34A0 RegMM34A0Value; + REG_MM34A0 RegMM34A0Mask; + PCBIOS_DSI_CONFIG pDSIConfig = CBIOS_NULL; + PCBIOS_DSI_PANEL_TABLE pDSIPanelTbl = CBIOS_NULL; + PCBIOS_DSI_PARAMS pDSIParams = CBIOS_NULL; + CBIOS_U32 IrqBitMask = DSI_IRQ_TE_TRIGGER | DSI_IRQ_OTHER_TRIGGER | DSI_IRQ_DSI_READBACK; + CBIOS_U32 DMARegIndex = 0x3400, CtrlRegIndex = 0x3408; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DSI); + cbTraceEnter(DSI); + + pDSIParams = &(pDevCommon->DeviceParas.DSIDevice); + pDSIConfig = &(pDSIParams->DSIPanelDesc.DSIConfig); + pDSIPanelTbl = &(pDSIParams->DSIPanelDesc.DSIPanelTbl); + + + if (DSIIndex == DSI_INDEX0) + { + DMARegIndex = 0x3400; + CtrlRegIndex = 0x3408; + } + else if (DSIIndex == DSI_INDEX1) + { + DMARegIndex = 0x3530; + CtrlRegIndex = 0x3538; + } + + RegMM3400_MM3530Value.Value = 0; + RegMM3400_MM3530Mask.Value = 0xFFFFFFFF; + RegMM3408_MM3538Value.Value = 0; + RegMM3408_MM3538Mask.Value = 0xFFFFFFFF; + + //DSI clock Enable + RegMM34A0Value.Value = 0; + RegMM34A0Value.DSI_Clock_Enable = 1; + RegMM34A0Mask.Value = 0xFFFFFFFF; + RegMM34A0Mask.DSI_Clock_Enable = 0; + cbMMIOWriteReg32(pcbe, 0x34a0, RegMM34A0Value.Value, RegMM34A0Mask.Value); + + // first set DSI mode bit load control bit + RegMM3408_MM3538Value.DSI_Mode_Bit_Load_Control = 1; // directly load + RegMM3408_MM3538Value.IGA_VSYNC_Previous_Signal_Select = 2; + RegMM3408_MM3538Value.IGA_VSYNC_Previous_Time = 7; + RegMM3408_MM3538Mask.DSI_Mode_Bit_Load_Control = 0; + RegMM3408_MM3538Mask.IGA_VSYNC_Previous_Signal_Select = 0; + RegMM3408_MM3538Mask.IGA_VSYNC_Previous_Time = 0; + cbMMIOWriteReg32(pcbe, CtrlRegIndex, RegMM3408_MM3538Value.Value, RegMM3408_MM3538Mask.Value); + + // set data lane num, clock lane mode and turn on clk lane high speed + cbDSI_SetDataLaneNum(pcbe, pDSIPanelTbl->LaneNum, DSIIndex); + cbDSI_SetClkLaneMode(pcbe, pDSIConfig->ClkLaneMode, DSIIndex); + + // turn on clk lane high speed + cbDSI_ClkLaneHSEnableDisable(pcbe, CBIOS_TRUE, DSIIndex); + + cbDSI_EoTpEnableDisable(pcbe, pDSIConfig, DSIIndex); + cbDSI_SetTimeOut(pcbe, pDSIConfig, DSIIndex); + + // still need to set DMA threshold? + RegMM3400_MM3530Value.DMA_FIFO_Threshold = pDSIConfig->DMAThreshold; + RegMM3400_MM3530Mask.DMA_FIFO_Threshold = 0; + cbMMIOWriteReg32(pcbe, DMARegIndex, RegMM3400_MM3530Value.Value, RegMM3400_MM3530Mask.Value); + + cbDSI_SetOutBpp(pcbe, pDSIPanelTbl->OutBpp, DSIIndex); + + // init phy + cbDSI_SetPhyParams(pcbe, pDSIParams, IGAIndex, DSIIndex); + + if (pDSIConfig->DSIMode == CBIOS_DSI_VIDEOMODE) + { + cbDSI_SyncEndEnableDisable(pcbe, pDSIConfig, DSIIndex); + } + + // enable irq + cbDSI_IrqEnableDisable(pcbe, IrqBitMask, CBIOS_TRUE, DSIIndex); + + RegMM3408_MM3538Value.Value = 0; + RegMM3408_MM3538Value.DSI_Output_Enable = 1; + RegMM3408_MM3538Mask.Value = 0xFFFFFFFF; + RegMM3408_MM3538Mask.DSI_Output_Enable = 0; + cbMMIOWriteReg32(pcbe, CtrlRegIndex, RegMM3408_MM3538Value.Value, RegMM3408_MM3538Mask.Value); + + //cbDSI_SetAddrMode(pcbe, 0, DSIIndex); + + cbDSI_SelectMode(pcbe, pDSIConfig->DSIMode, DSIIndex); + + //cbDSI_SetMaxReturnSize(pcbe, CBIOS_DSI_MAX_RETURN_PACKET_SIZE, DSIIndex); + + //cbDSI_EnableDisableTE(pcbe, CBIOS_TRUE, 0, 0, DSIIndex); + + cbTraceExit(DSI); +} + +CBIOS_VOID cbDSI_Init(PCBIOS_VOID pvcbe, CBIOS_U32 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DSI); + PCBIOS_DSI_PANEL_DESC pPanelDesc = &pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc; + cbTraceEnter(DSI); + + cbDSI_ControllerInit(pcbe, IGA1, DSI_INDEX0); + + if(pPanelDesc->DSIConfig.isDualChannel) + { + cbDSI_ControllerInit(pcbe, IGA1, DSI_INDEX1); + } + + if((pPanelDesc->DSIConfig.DSIMode == CBIOS_DSI_CMDMODE) && (pPanelDesc->DSIConfig.TEType == CBIOS_DSI_TE_PAD)) + { + REG_MM349C RegMM349CValue; + REG_MM349C RegMM349CMask; + //detect whether GFX GPIO6 used as GPIO mode or TE Pad mode + //For GFX GPIO6 we will only read/write through 0xd8110052; not by SR_4A[6:5] + // we won't force exec cbFreeGPIO(pvcbe, CBIOS_GPIO_GFX, 6); only detect and report this fatal error + //temporary skip this judgement + /* + dwGP18EnableReg = cbReadRegisterU32(pcbe, CBIOS_REGISTER_GPIO, 0x0050); + if(dwGP18EnableReg & BIT19) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_Init: Detect GFX GPIO6 already enabled as GPIO Mode!\n")); + } + */ + RegMM349CValue.Value = 0; + RegMM349CValue.DSI_TE_IEN = 1; + RegMM349CMask.Value = 0xFFFFFFFF; + RegMM349CMask.DSI_TE_IEN = 0; + cbMMIOWriteReg32(pcbe, 0x349c, RegMM349CValue.Value, RegMM349CMask.Value); + } + if(pPanelDesc->DSIConfig.DSIMode == CBIOS_DSI_CMDMODE) + { + REG_MM3294_MM32AC RegMM3294Value; + REG_MM3294_MM32AC RegMM3294Mask; + + RegMM3294Value.Value = 0; + RegMM3294Value.Vcnt_Reset_Value_Sel = 1; + RegMM3294Mask.Value = 0xFFFFFFFF; + RegMM3294Mask.Vcnt_Reset_Value_Sel = 0; + cbMMIOWriteReg32(pcbe, 0x3294, RegMM3294Value.Value, RegMM3294Mask.Value); + } + + cbTraceExit(DSI); +} + + +CBIOS_VOID cbDSI_ControllerOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bTurnOn, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM3408_MM3538 RegMM3408_MM3538Value; + REG_MM3408_MM3538 RegMM3408_MM3538Mask; + REG_MM345C_MM358C RegMM345C_MM358CValue; + REG_MM345C_MM358C RegMM345C_MM358CMask; + REG_MM3448_MM3578 RegMM3448_MM3578Value; + REG_MM3448_MM3578 RegMM3448_MM3578Mask; + REG_MM34C0_MM34C8 RegMM34C0_MM34C8Value; + REG_MM34C0_MM34C8 RegMM34C0_MM34C8Mask; + PCBIOS_DSI_PARAMS pDSIParams = CBIOS_NULL; + PCBIOS_DSI_CONFIG pDSIConfig = CBIOS_NULL; + PCBIOS_DSI_PANEL_TABLE pDSIPanelTbl = CBIOS_NULL; + CBIOS_U32 CtrlRegIndex = 0x3408, VideoRegIndex = 0x345C, EPhyRegIndex = 0x3448, VideoReg5Index = 0x34C0; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DSI); + cbTraceEnter(DSI); + + if (DSIIndex == DSI_INDEX0) + { + CtrlRegIndex = 0x3408; + VideoRegIndex = 0x345C; + EPhyRegIndex = 0x3448; + VideoReg5Index = 0x34C0; + } + else if (DSIIndex == DSI_INDEX1) + { + CtrlRegIndex = 0x3538; + VideoRegIndex = 0x358C; + EPhyRegIndex = 0x3578; + VideoReg5Index = 0x34C8; + } + + RegMM3408_MM3538Value.Value = 0; + RegMM3408_MM3538Mask.Value = 0xFFFFFFFF; + RegMM345C_MM358CValue.Value = 0; + RegMM345C_MM358CMask.Value = 0xFFFFFFFF; + RegMM3448_MM3578Value.Value = 0; + RegMM3448_MM3578Mask.Value = 0xFFFFFFFF; + RegMM34C0_MM34C8Value.Value = 0; + RegMM34C0_MM34C8Mask.Value = 0xFFFFFFFF; + pDSIParams = &(pDevCommon->DeviceParas.DSIDevice); + pDSIConfig = &(pDSIParams->DSIPanelDesc.DSIConfig); + pDSIPanelTbl = &(pDSIParams->DSIPanelDesc.DSIPanelTbl); + + if (bTurnOn) + { + + RegMM3408_MM3538Value.DSI_Output_Enable = 1; + RegMM3408_MM3538Mask.DSI_Output_Enable = 0; + + if (pDSIConfig->DSIMode == CBIOS_DSI_VIDEOMODE) + { + RegMM345C_MM358CValue.DSI_Video_Mode_Enable = 1; + RegMM345C_MM358CMask.DSI_Video_Mode_Enable = 0; + RegMM34C0_MM34C8Value.DSI_CMD_Mode_Enable = 0; + RegMM34C0_MM34C8Mask.DSI_CMD_Mode_Enable = 0; + } + else if (pDSIConfig->DSIMode == CBIOS_DSI_CMDMODE) + { + RegMM345C_MM358CValue.DSI_Video_Mode_Enable = 0; + RegMM345C_MM358CMask.DSI_Video_Mode_Enable = 0; + RegMM34C0_MM34C8Value.DSI_CMD_Mode_Enable = 1; + RegMM34C0_MM34C8Mask.DSI_CMD_Mode_Enable = 0; + } + + cbMMIOWriteReg32(pcbe, CtrlRegIndex, RegMM3408_MM3538Value.Value, RegMM3408_MM3538Mask.Value); + cbMMIOWriteReg32(pcbe, VideoRegIndex, RegMM345C_MM358CValue.Value, RegMM345C_MM358CMask.Value); + cbMMIOWriteReg32(pcbe, VideoReg5Index, RegMM34C0_MM34C8Value.Value, RegMM34C0_MM34C8Mask.Value); + + } + else // turn off + { + + RegMM3408_MM3538Value.DSI_Output_Enable = 0; + RegMM3408_MM3538Mask.DSI_Output_Enable = 0; + + if (pDSIConfig->DSIMode == CBIOS_DSI_VIDEOMODE) + { + RegMM345C_MM358CValue.DSI_Video_Mode_Enable = 0; + RegMM345C_MM358CMask.DSI_Video_Mode_Enable = 0; + } + else if (pDSIConfig->DSIMode == CBIOS_DSI_CMDMODE) + { + RegMM34C0_MM34C8Value.DSI_CMD_Mode_Enable = 0; + RegMM34C0_MM34C8Mask.DSI_CMD_Mode_Enable = 0; + } + + RegMM3448_MM3578Value.Power_down_PLL = 0; // power off EPHY PLL + RegMM3448_MM3578Mask.Power_down_PLL = 0; + RegMM3448_MM3578Value.Clock_Lane_Power_Down = 0; // power off clock lane + RegMM3448_MM3578Mask.Clock_Lane_Power_Down = 0; + RegMM3448_MM3578Value.Power_Down_Data_Lane_0 = 0; // power off data lane 0 + RegMM3448_MM3578Mask.Power_Down_Data_Lane_0 = 0; + + if (pDSIPanelTbl->LaneNum > 1) + { + RegMM3448_MM3578Value.Power_Down_Data_Lane_1 = 0; + RegMM3448_MM3578Mask.Power_Down_Data_Lane_1 = 0; + } + + if (pDSIPanelTbl->LaneNum > 2) + { + RegMM3448_MM3578Value.Power_Down_Data_Lane_2 = 0; + RegMM3448_MM3578Mask.Power_Down_Data_Lane_2 = 0; + } + + if (pDSIPanelTbl->LaneNum > 3) + { + RegMM3448_MM3578Value.Power_Down_Data_Lane_3 = 0; + RegMM3448_MM3578Mask.Power_Down_Data_Lane_3 = 0; + } + + RegMM3448_MM3578Value.Power_Down_LP_RX = 0; // power off lp-rx + RegMM3448_MM3578Mask.Power_Down_LP_RX = 0; + cbMMIOWriteReg32(pcbe, CtrlRegIndex, RegMM3408_MM3538Value.Value, RegMM3408_MM3538Mask.Value); + cbMMIOWriteReg32(pcbe, VideoRegIndex, RegMM345C_MM358CValue.Value, RegMM345C_MM358CMask.Value); + cbMMIOWriteReg32(pcbe, VideoReg5Index, RegMM34C0_MM34C8Value.Value, RegMM34C0_MM34C8Mask.Value); + cbMMIOWriteReg32(pcbe, EPhyRegIndex, RegMM3448_MM3578Value.Value, RegMM3448_MM3578Mask.Value); + } + + cbTraceExit(DSI); +} + +static CBIOS_STATUS cbDSI_DisplayUpdateByDMA(PCBIOS_VOID pvcbe, PCBIOS_DSI_DMAUPDATE_PARA pUpdateParams, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 UpdateSize = 0, WriteStride = 0, FetchStride = 0, StartSize = 0, Counter = 0; + CBIOS_U8 CmdType = 0, DCSCmd = 0, DataId = 0; + PCBIOS_DSI_WINDOW pUpdateWin = CBIOS_NULL; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DSI); + CBIOS_U8 OutBpp = (CBIOS_U8)pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc.DSIPanelTbl.OutBpp; + CBIOS_U32 XRes = pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc.DSIPanelTbl.PanelTiming.XResolution; + CBIOS_U32 AlignedXRes = 0; + CBIOS_U8 VirtualCh = 0; //might need fix + CBIOS_U32 FBAddr = pUpdateParams->DMABaseAddr; + CBIOS_U32 StartCol = 0, EndCol = 0, StartRow = 0, EndRow = 0; + CBIOS_U32 i = 0; + REG_MM3440_MM3570 RegMM3440Value, RegMM3440Mask; + REG_MM3480 RegMM3480Value, RegMM3480Mask; + cbTraceEnter(DSI); + + pUpdateWin = &(pUpdateParams->DMAUpdateWindow); + + // set the updated window on Panel + StartCol = pUpdateWin->XStart; + EndCol = pUpdateWin->XStart + pUpdateWin->WinWidth - 1; + StartRow = pUpdateWin->YStart; + EndRow = pUpdateWin->YStart + pUpdateWin->WinHeight - 1; + + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "cbDSI_DisplayUpdateByDMA: pUpdateWin->XStart: %d \n", pUpdateWin->XStart)); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "cbDSI_DisplayUpdateByDMA: pUpdateWin->YStart: %d \n", pUpdateWin->YStart)); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "cbDSI_DisplayUpdateByDMA: pUpdateWin->WinWidth: %d \n", pUpdateWin->WinWidth)); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "cbDSI_DisplayUpdateByDMA: pUpdateWin->WinHeight: %d \n", pUpdateWin->WinHeight)); + + cbDSI_SetColumnAddr(pcbe, (CBIOS_U16)StartCol, (CBIOS_U16)EndCol, DSIIndex); + cbDSI_SetPageAddr(pcbe, (CBIOS_U16)StartRow, (CBIOS_U16)EndRow, DSIIndex); + + //select DMA FIFO: DSI1 share SS1 FIFO; DSI2 share TS1 FIFO + RegMM3480Value.Value = 0; + RegMM3480Mask.Value = 0xFFFFFFFF; + + if (DSIIndex == DSI_INDEX0) + { + RegMM3480Value.SS_DMA1_SEL = 1; + RegMM3480Mask.SS_DMA1_SEL = 0; + } + else + { + RegMM3480Value.TS_DMA2_SEL = 1; + RegMM3480Mask.TS_DMA2_SEL = 0; + } + + cbMMIOWriteReg32(pcbe, 0x3480, RegMM3480Value.Value, RegMM3480Mask.Value); + + + //set DMA bits + RegMM3440Value.Value = 0; + RegMM3440Mask.Value = 0xFFFFFFFF; + + //As OutBpp in Our code only include the RGB data, for DMA fetch pixel ought to add the Alpha + if(OutBpp == 24) + { + OutBpp = 32; + } + + if (OutBpp == 32) + { + RegMM3440Value.DMA_Pixel_Dataformat_32bpp = 1; + RegMM3440Mask.DMA_Pixel_Dataformat_32bpp = 0; + cbMMIOWriteReg32(pcbe, 0x3440, RegMM3440Value.Value, RegMM3440Mask.Value); + } + else if (OutBpp == 16) + { + RegMM3440Value.DMA_Pixel_Dataformat_16bpp = 1; + RegMM3440Mask.DMA_Pixel_Dataformat_16bpp = 0; + cbMMIOWriteReg32(pcbe, 0x3440, RegMM3440Value.Value, RegMM3440Mask.Value); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_DisplayUpdateByDMA: Wrong OutBpp for DMA test! OutBpp: %d \n", OutBpp)); + } + + if(pUpdateParams->isDMAAligned) + { + UpdateSize = pUpdateParams->DMAStride * pUpdateWin->WinHeight * OutBpp / 8; + + if(UpdateSize % 2) + { + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "cbDSI_DisplayUpdateByDMA: ought to be 2 pixel data aligned \n")); + } + + WriteStride = pUpdateWin->WinWidth * OutBpp / 8; + FetchStride = (XRes * OutBpp / 8 + 256 - 1) & ~(256 - 1); + AlignedXRes = FetchStride / (OutBpp / 8); + FBAddr = pUpdateParams->DMABaseAddr + (pUpdateWin->YStart * AlignedXRes + pUpdateWin->XStart ) * OutBpp / 8; + + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "cbDSI_DisplayUpdateByDMA: UpdateSize: %d, WriteStride: %d (Byte)\n", UpdateSize, WriteStride )); + + for(i = 0; i < pUpdateWin->WinHeight; i++) + { + if (i == 0) + { + DCSCmd = DSI_DCS_WRITE_MEMORY_START; + } + else + { + DCSCmd = DSI_DCS_WRITE_MEMORY_CONTINUE; + } + + CmdType = DSI_CMD_TYPE_DMA | DSI_CMD_TYPE_LAST_GROUP ; + DataId = DSI_DCS_LONG_WRITE; + + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "DMA, i: %d \n", i)); + + cbDSI_SendDMAPacket(pcbe, VirtualCh, DataId, (CBIOS_U16)WriteStride, CmdType, FBAddr, DCSCmd, DSIIndex); + FBAddr += FetchStride; + } + } + else + { + UpdateSize = pUpdateWin->WinWidth * pUpdateWin->WinHeight * OutBpp / 8; + + if(UpdateSize % 2) + { + cbDebugPrint((MAKE_LEVEL(DSI, WARNING), "cbDSI_DisplayUpdateByDMA: ought to be 2 pixel data aligned \n")); + } + + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "cbDSI_DisplayUpdateByDMA: UpdateSize: %d, WriteStride: %d (Byte)\n", UpdateSize, pUpdateParams->DMAStride)); + + FBAddr = pUpdateParams->DMABaseAddr; + WriteStride = pUpdateParams->DMAStride; + + if(UpdateSize < WriteStride) + { + StartSize = UpdateSize; + } + else + { + StartSize = WriteStride; + } + + UpdateSize = UpdateSize - StartSize; + CmdType = DSI_CMD_TYPE_DMA | DSI_CMD_TYPE_LAST_GROUP ; + DataId = DSI_DCS_LONG_WRITE; + DCSCmd = DSI_DCS_WRITE_MEMORY_START; + cbDSI_SendDMAPacket(pcbe, VirtualCh, DataId, (CBIOS_U16)StartSize, CmdType, FBAddr, DCSCmd, DSIIndex); + + DCSCmd = DSI_DCS_WRITE_MEMORY_CONTINUE; + + while(UpdateSize > 0) + { + FBAddr += StartSize; + + if(UpdateSize < WriteStride) + { + StartSize = UpdateSize; + } + else + { + StartSize = WriteStride; + } + + UpdateSize = UpdateSize - StartSize; + + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "DMA Counter: %d \n", Counter++)); + cbDSI_SendDMAPacket(pcbe, VirtualCh, DataId, (CBIOS_U16)StartSize, CmdType, FBAddr, DCSCmd, DSIIndex); + } + } + + //check DMA Bit + Status = cbDSI_WaitDMAFree(pcbe); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "cbDSI_DisplayUpdateByDMA: DMAStatus: %d \n", Status)); + + cbTraceExit(DSI); + return Status; +} + +static CBIOS_STATUS cbDSI_DisplayPartialUpdate(PCBIOS_VOID pvcbe, PCBIOS_DSI_HOSTUPDATE_PARA pUpdateParams, CBIOS_BOOL bPartial, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + PCBIOS_DSI_WINDOW pUpdateWin = CBIOS_NULL, pLastUpdateWin = CBIOS_NULL; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DSI); + PCBIOS_DSI_PANEL_DESC pPanelDesc = &pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc; + CBIOS_U16 StartCol, EndCol, StartRow, EndRow; + REG_MM3408_MM3538 RegMM3408_MM3538Value, RegMM3408_MM3538Mask; + REG_MM34BC_MM35EC RegMM34BC_MM35ECValue, RegMM34BC_MM35ECMask; + REG_MM34C0_MM34C8 RegMM34C0_MM34C8Value, RegMM34C0_MM34C8Mask; + REG_MM34C4_MM34CC RegMM34C4_MM34CCValue, RegMM34C4_MM34CCMask; + CBIOS_U32 MiscRegIndex = 0x34BC, CtrlRegIndex = 0x3408, PosRegIndex = 0x34C0, SizeRegIndex = 0x34C4; + PCBIOS_TIMING_ATTRIB pTargetTiming = &(pDevCommon->DeviceParas.DSIDevice.TargetTiming); + CBIOS_U32 MaxWidth = pTargetTiming->XRes; + CBIOS_U32 MaxHeight = pTargetTiming->YRes; + cbTraceEnter(DSI); + + if (pPanelDesc->DSIConfig.isDualChannel) + { + MaxWidth /= 2; + } + + pUpdateWin = &(pUpdateParams->HostUpdateWindow[DSIIndex]); + pLastUpdateWin = &(pDevCommon->DeviceParas.DSIDevice.HostUpdatePara.HostUpdateWindow[DSIIndex]); + + if (DSIIndex == DSI_INDEX0) + { + MiscRegIndex = 0x34BC; + CtrlRegIndex = 0x3408; + PosRegIndex = 0x34C0; + SizeRegIndex = 0x34C4; + } + else if (DSIIndex == DSI_INDEX1) + { + MiscRegIndex = 0x35EC; + CtrlRegIndex = 0x3538; + PosRegIndex = 0x34C8; + SizeRegIndex = 0x34CC; + } + + if (bPartial) // 1: normal->partial mode; 2.partial mode, update para changed + { + // IGA programming + RegMM34BC_MM35ECValue.Value = 0; + RegMM34BC_MM35ECMask.Value = 0xFFFFFFFF; + RegMM34BC_MM35ECValue.DSI_Partial_Timing_Enable = 1; + RegMM34BC_MM35ECMask.DSI_Partial_Timing_Enable = 0; + RegMM34BC_MM35ECValue.Y_START = pUpdateWin->YStart; + RegMM34BC_MM35ECMask.Y_START = 0; + RegMM34BC_MM35ECValue.Y_HEIGHT = pUpdateWin->WinHeight; + RegMM34BC_MM35ECMask.Y_HEIGHT = 0; + cbMMIOWriteReg32(pcbe, MiscRegIndex, RegMM34BC_MM35ECValue.Value, RegMM34BC_MM35ECMask.Value); + + // DSI programming + RegMM34C0_MM34C8Value.Value = 0; + RegMM34C0_MM34C8Mask.Value = 0xFFFFFFFF; + RegMM34C0_MM34C8Value.X_START = pUpdateWin->XStart; + RegMM34C0_MM34C8Mask.X_START = 0; + RegMM34C0_MM34C8Value.Y_START = pUpdateWin->YStart; + RegMM34C0_MM34C8Mask.Y_START = 0; + cbMMIOWriteReg32(pcbe, PosRegIndex, RegMM34C0_MM34C8Value.Value, RegMM34C0_MM34C8Mask.Value); + + RegMM34C4_MM34CCValue.Value = 0; + RegMM34C4_MM34CCMask.Value = 0xFFFFFFFF; + RegMM34C4_MM34CCValue.Width = pUpdateWin->WinWidth; + RegMM34C4_MM34CCMask.Width = 0; + RegMM34C4_MM34CCValue.Height = pUpdateWin->WinHeight; + RegMM34C4_MM34CCMask.Height = 0; + cbMMIOWriteReg32(pcbe, SizeRegIndex, RegMM34C4_MM34CCValue.Value, RegMM34C4_MM34CCMask.Value); + + Status = cbDSI_SetPXL_WC(pcbe, pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc.DSIPanelTbl.OutBpp, pUpdateWin->WinWidth, DSIIndex); + + + RegMM3408_MM3538Value.Value = 0; + RegMM3408_MM3538Mask.Value = 0xFFFFFFFF; + RegMM3408_MM3538Value.DCS_DSI_16BPP = 0; + RegMM3408_MM3538Mask.DCS_DSI_16BPP = 0; + RegMM3408_MM3538Value.ENTER_HS = pUpdateParams->isEnterHS; + RegMM3408_MM3538Mask.ENTER_HS = 0; + cbMMIOWriteReg32(pcbe, CtrlRegIndex, RegMM3408_MM3538Value.Value, RegMM3408_MM3538Mask.Value); + + + // enter partial mode and send frame data + StartCol = pUpdateWin->XStart; + EndCol = StartCol + pUpdateWin->WinWidth - 1; + StartRow = pUpdateWin->YStart; + EndRow = StartRow + pUpdateWin->WinHeight - 1; + + cbDSI_SetColumnAddr(pcbe, StartCol, EndCol, DSIIndex); + cbDSI_SetPageAddr(pcbe, StartRow, EndRow, DSIIndex); + //cbDSI_DCSSwitchMode(pcbe, CBIOS_DSI_DCS_PARTIAL_MODE, CBIOS_TRUE, DSIIndex); //not applied for NT35595 + + // save update window paras to pcbe + cb_memcpy(pLastUpdateWin, pUpdateWin, sizeof(CBIOS_DSI_WINDOW)); + + } + else // 1: partial->normal mode; + { + // IGA programming + RegMM34BC_MM35ECValue.Value = 0; + RegMM34BC_MM35ECMask.Value = 0xFFFFFFFF; + RegMM34BC_MM35ECValue.DSI_Partial_Timing_Enable = 0; + RegMM34BC_MM35ECMask.DSI_Partial_Timing_Enable = 0; + RegMM34BC_MM35ECValue.Y_START = 0; + RegMM34BC_MM35ECMask.Y_START = 0; + RegMM34BC_MM35ECValue.Y_HEIGHT = 0; + RegMM34BC_MM35ECMask.Y_HEIGHT = 0; + cbMMIOWriteReg32(pcbe, 0x34BC, RegMM34BC_MM35ECValue.Value, RegMM34BC_MM35ECMask.Value); + + // DSI programming + RegMM34C0_MM34C8Value.Value = 0; + RegMM34C0_MM34C8Mask.Value = 0xFFFFFFFF; + RegMM34C0_MM34C8Value.X_START = 0; + RegMM34C0_MM34C8Mask.X_START = 0; + RegMM34C0_MM34C8Value.Y_START = 0; + RegMM34C0_MM34C8Mask.Y_START = 0; + cbMMIOWriteReg32(pcbe, PosRegIndex, RegMM34C0_MM34C8Value.Value, RegMM34C0_MM34C8Mask.Value); + + RegMM34C4_MM34CCValue.Value = 0; + RegMM34C4_MM34CCMask.Value = 0xFFFFFFFF; + RegMM34C4_MM34CCValue.Width = 0; + RegMM34C4_MM34CCMask.Width = 0; + RegMM34C4_MM34CCValue.Height = 0; + RegMM34C4_MM34CCMask.Height = 0; + cbMMIOWriteReg32(pcbe, SizeRegIndex, RegMM34C4_MM34CCValue.Value, RegMM34C4_MM34CCMask.Value); + + Status = cbDSI_SetPXL_WC(pcbe, pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc.DSIPanelTbl.OutBpp, pTargetTiming->HorDisEnd, DSIIndex); + + // save update window paras to pcbe + cb_memcpy(pLastUpdateWin, pUpdateWin, sizeof(CBIOS_DSI_WINDOW)); + + //enter normal mode and send frame data + StartCol = 0; + EndCol = MaxWidth - 1; + StartRow = 0; + EndRow = MaxHeight - 1; + cbDSI_SetColumnAddr(pcbe, StartCol, EndCol, DSIIndex); + cbDSI_SetPageAddr(pcbe, StartRow, EndRow, DSIIndex); + cbDSI_DCSSwitchMode(pcbe, CBIOS_DSI_DCS_NORMAL_MODE, CBIOS_TRUE, DSIIndex); + } + + cbTraceExit(DSI); + return Status; +} + +static CBIOS_STATUS cbDSI_DisplayUpdateByHost(PCBIOS_VOID pvcbe, PCBIOS_DSI_HOSTUPDATE_PARA pUpdateParams, CBIOS_DSI_INDEX DSIIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_BOOL isPartialUpdate, isWindowChanged; + PCBIOS_DSI_WINDOW pUpdateWin = CBIOS_NULL, pLastUpdateWin = CBIOS_NULL; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DSI); + PCBIOS_TIMING_ATTRIB pTargetTiming = &(pDevCommon->DeviceParas.DSIDevice.TargetTiming); + cbTraceEnter(DSI); + + pUpdateWin = &(pUpdateParams->HostUpdateWindow[DSIIndex]); + pLastUpdateWin = &(pDevCommon->DeviceParas.DSIDevice.HostUpdatePara.HostUpdateWindow[DSIIndex]); + + // first judge is partial update or normal update + if ((pUpdateWin->XStart == 0) && (pUpdateWin->YStart == 0) + && (pUpdateWin->WinWidth == pTargetTiming->XRes) + && (pUpdateWin->WinHeight == pTargetTiming->YRes)) + { + isPartialUpdate = CBIOS_FALSE; + } + else + { + isPartialUpdate = CBIOS_TRUE; + } + + // then judge whether the window changed + if ((pUpdateWin->XStart == pLastUpdateWin->XStart) + && (pUpdateWin->YStart == pLastUpdateWin->YStart) + && (pUpdateWin->WinWidth == pLastUpdateWin->WinWidth) + && (pUpdateWin->WinHeight == pLastUpdateWin->WinHeight)) + { + isWindowChanged = CBIOS_FALSE; + } + else + { + isWindowChanged = CBIOS_TRUE; + } + + if ((pUpdateWin->XStart == 0) && (pUpdateWin->YStart == 0) + && (pUpdateWin->WinWidth == 0) && (pUpdateWin->WinHeight == 0)) + { + isWindowChanged = CBIOS_FALSE; + } + + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "pUpdateWin->XStart : %d \n", pUpdateWin->XStart )); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "pUpdateWin->YStart: %d \n", pUpdateWin->YStart)); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "pUpdateWin->WinWidth: %d \n", pUpdateWin->WinWidth)); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "pUpdateWin->WinHeight: %d \n", pUpdateWin->WinHeight)); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "isWindowChanged: %d \n", isWindowChanged)); + cbDebugPrint((MAKE_LEVEL(DSI, DEBUG), "isPartialUpdate: %d \n", isPartialUpdate)); + + if ((pUpdateParams->isEnablePartialUpdate) && (isWindowChanged)) + { + cbDSI_DisplayPartialUpdate(pcbe, pUpdateParams, isPartialUpdate, DSIIndex); + } + + cbDSI_SendOneFrameData(pcbe, DSIIndex); + + cbTraceExit(DSI); + return Status; +} + +static CBIOS_STATUS cbDSI_GetPanelUpdatePara(PCBIOS_VOID pvcbe, PCBIOS_DSI_PANELUPDATE_PARA pPanelUpdateParams) +{ + CBIOS_STATUS Status = CBIOS_OK; + pPanelUpdateParams->Size = sizeof(CBIOS_DSI_PANELUPDATE_PARA); + pPanelUpdateParams->PanelClumnAlign = 2; //clumn start align + pPanelUpdateParams->PanelRowAlign = 2; //page addr start align + pPanelUpdateParams->PanelWidthAlign = 2; //window width need to be divisible by 2 + pPanelUpdateParams->PanelHeightAlign = 2; //window height need to be divisible by 2 + + return Status; +} + +static CBIOS_STATUS cbDSI_AdjustPanelUpdateWindow(PCBIOS_VOID pvcbe, PCBIOS_DSI_PANELUPDATE_PARA pPanelUpdateParams, PCBIOS_DSI_WINDOW pUpdateWin) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DSI); + PCBIOS_DSI_PANEL_DESC pPanelDesc = &pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc; + PCBIOS_TIMING_ATTRIB pTargetTiming = &(pDevCommon->DeviceParas.DSIDevice.TargetTiming); + CBIOS_U32 MaxWidth = pTargetTiming->XRes; + CBIOS_U32 MaxHeight = pTargetTiming->YRes; + + if (pPanelDesc->DSIConfig.isDualChannel) + { + MaxWidth /= 2; + } + + if(pPanelUpdateParams && pUpdateWin) + { + //check UpdateWindow Para + if(pUpdateWin->XStart > MaxWidth) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_AdjustPanelUpdateWindow Invalid pUpdateWin->XStart! \n")); + Status = CBIOS_ER_INVALID_PARAMETER; + } + if(pUpdateWin->YStart > MaxHeight) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_AdjustPanelUpdateWindow Invalid pUpdateWin->YStart! \n")); + Status = CBIOS_ER_INVALID_PARAMETER; + } + if((CBIOS_U32)(pUpdateWin->XStart + pUpdateWin->WinWidth) > MaxWidth) + { + pUpdateWin->WinWidth = MaxWidth - pUpdateWin->XStart; + } + if((CBIOS_U32)(pUpdateWin->YStart + pUpdateWin->WinHeight) > MaxHeight) + { + pUpdateWin->WinHeight = MaxHeight - pUpdateWin->YStart; + } + + //check UpdateWindow according to Panel Parital Update Align requirement + if(pUpdateWin->XStart % pPanelUpdateParams->PanelClumnAlign) + { + pUpdateWin->WinWidth += (pUpdateWin->XStart % pPanelUpdateParams->PanelClumnAlign); + pUpdateWin->XStart -= (pUpdateWin->XStart % pPanelUpdateParams->PanelClumnAlign); + } + if(pUpdateWin->WinWidth % pPanelUpdateParams->PanelWidthAlign) + { + pUpdateWin->WinWidth += (pPanelUpdateParams->PanelWidthAlign - (pUpdateWin->WinWidth % pPanelUpdateParams->PanelWidthAlign)); + } + if(pUpdateWin->YStart % pPanelUpdateParams->PanelRowAlign) + { + pUpdateWin->WinHeight += (pUpdateWin->YStart % pPanelUpdateParams->PanelRowAlign); + pUpdateWin->YStart -= (pUpdateWin->YStart % pPanelUpdateParams->PanelRowAlign); + } + if(pUpdateWin->WinHeight % pPanelUpdateParams->PanelHeightAlign) + { + pUpdateWin->WinHeight += (pPanelUpdateParams->PanelHeightAlign - (pUpdateWin->WinHeight % pPanelUpdateParams->PanelHeightAlign)); + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_AdjustPanelUpdateWindow Invalid parameter! \n")); + Status = CBIOS_ER_INVALID_PARAMETER; + } + + return Status; +} + +static CBIOS_STATUS cbDSI_GetHostUpdatePara(PCBIOS_VOID pvcbe, PCBIOS_DSI_HOSTUPDATE_PARA pHostUpdateParams, PCBIOS_DSI_UPDATE_PARA pUpdateParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DSI); + PCBIOS_DSI_PANEL_DESC pPanelDesc = &pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc; + PCBIOS_TIMING_ATTRIB pTargetTiming = &(pDevCommon->DeviceParas.DSIDevice.TargetTiming); + PCBIOS_DSI_WINDOW pUpdateWin = CBIOS_NULL; + + pHostUpdateParams->Size = sizeof(CBIOS_DSI_HOSTUPDATE_PARA); + pHostUpdateParams->isEnablePartialUpdate = pUpdateParams->DSIUpdateConfig.bEnablePartialUpdate; + pHostUpdateParams->isEnterHS = pUpdateParams->DSIUpdateConfig.bEnterHS; + + cbDSI_GetPanelUpdatePara(pcbe, &(pHostUpdateParams->PanelUpdatePara)); + + if (pPanelDesc->DSIConfig.isDualChannel) + { + //only in left part + if((pUpdateParams->UpdateWindow.XStart + pUpdateParams->UpdateWindow.WinWidth) < (pTargetTiming->XRes / 2)) + { + pUpdateWin = &(pHostUpdateParams->HostUpdateWindow[DSI_INDEX0]); + cbmemcpy(pUpdateWin, &(pUpdateParams->UpdateWindow), sizeof(CBIOS_DSI_WINDOW)); + cbDSI_AdjustPanelUpdateWindow(pcbe, &(pHostUpdateParams->PanelUpdatePara), pUpdateWin); + } + else if (pUpdateParams->UpdateWindow.XStart >= (pTargetTiming->XRes / 2)) //only in right part + { + pUpdateWin = &(pHostUpdateParams->HostUpdateWindow[DSI_INDEX1]); + pUpdateWin->XStart = pUpdateParams->UpdateWindow.XStart - pTargetTiming->XRes / 2 ; + pUpdateWin->YStart = pUpdateParams->UpdateWindow.YStart; + pUpdateWin->WinWidth = pUpdateParams->UpdateWindow.WinWidth; + pUpdateWin->WinHeight = pUpdateParams->UpdateWindow.WinHeight; + cbDSI_AdjustPanelUpdateWindow(pcbe, &(pHostUpdateParams->PanelUpdatePara), pUpdateWin); + } + else //both in left part and right part + { + pUpdateWin = &(pHostUpdateParams->HostUpdateWindow[DSI_INDEX0]); + pUpdateWin->XStart = pUpdateParams->UpdateWindow.XStart; + pUpdateWin->YStart = pUpdateParams->UpdateWindow.YStart; + pUpdateWin->WinWidth = (pTargetTiming->XRes / 2 - 1) - pUpdateParams->UpdateWindow.XStart + 1; + pUpdateWin->WinHeight = pUpdateParams->UpdateWindow.WinHeight; + cbDSI_AdjustPanelUpdateWindow(pcbe, &(pHostUpdateParams->PanelUpdatePara), pUpdateWin); + + pUpdateWin = &(pHostUpdateParams->HostUpdateWindow[DSI_INDEX1]); + pUpdateWin->XStart = 0; //pTargetTiming->XRes / 2 ; + pUpdateWin->YStart = pUpdateParams->UpdateWindow.YStart; + pUpdateWin->WinWidth = (pUpdateParams->UpdateWindow.WinWidth) - (pTargetTiming->XRes / 2) + pUpdateParams->UpdateWindow.XStart; + pUpdateWin->WinHeight = pUpdateParams->UpdateWindow.WinHeight; + cbDSI_AdjustPanelUpdateWindow(pcbe, &(pHostUpdateParams->PanelUpdatePara), pUpdateWin); + } + + } + else + { + pUpdateWin = &(pHostUpdateParams->HostUpdateWindow[DSI_INDEX0]); + cb_memcpy(pUpdateWin, &(pUpdateParams->UpdateWindow), sizeof(CBIOS_DSI_WINDOW)); + + cbDSI_AdjustPanelUpdateWindow(pcbe, &(pHostUpdateParams->PanelUpdatePara), pUpdateWin); + } + + return Status; +} + +static CBIOS_VOID cbDSI_WaitForFlip(PCBIOS_EXTENSION_COMMON pcbe) +{ + CBIOS_U8 uCR3A_before = 0, uCR3E_before = 0; + CBIOS_U8 uCR3A_after = 0, uCR3E_after = 0; + CBIOS_U32 TryTimes = 0; + + while(TryTimes < 20) + { + uCR3A_before = cbMMIOReadReg(pcbe, CR_3A); + uCR3E_before=cbMMIOReadReg(pcbe, CR_3E); + + cbDelayMilliSeconds(1); + + uCR3A_after = cbMMIOReadReg(pcbe, CR_3A); + uCR3E_after=cbMMIOReadReg(pcbe, CR_3E); + if((uCR3A_after != uCR3A_before) || (uCR3E_after != uCR3E_before)) + { + TryTimes++; + } + else + { + break; + } + } + + return; +} + +static CBIOS_STATUS cbDSI_GetDMAUpdatePara(PCBIOS_VOID pvcbe, PCBIOS_DSI_DMAUPDATE_PARA pDMAUpdateParams, PCBIOS_DSI_UPDATE_PARA pUpdateParams) +{ + CBIOS_STATUS Status = CBIOS_OK; + if(pDMAUpdateParams && pUpdateParams) + { + pDMAUpdateParams->Size = sizeof(CBIOS_DSI_DMAUPDATE_PARA); + pDMAUpdateParams->DMABaseAddr = pUpdateParams->DSIUpdateConfig.DMABaseAddr; + pDMAUpdateParams->DMAStride = pUpdateParams->DSIUpdateConfig.DMAStride; + pDMAUpdateParams->isDMAAligned = pUpdateParams->DSIUpdateConfig.bDMAAligned; + cbmemcpy(&(pDMAUpdateParams->DMAUpdateWindow), &(pUpdateParams->UpdateWindow), sizeof(CBIOS_DSI_WINDOW)); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "cbDSI_GetDMAUpdatePara Invalid parameter! \n")); + Status = CBIOS_ER_INVALID_PARAMETER; + } + return Status; +} + +CBIOS_STATUS cbDSI_DisplayUpdate(PCBIOS_VOID pvcbe, PCBIOS_DSI_UPDATE_PARA pUpdateParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DSI); + PCBIOS_DSI_PANEL_DESC pPanelDesc = &pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc; + CBIOS_DSI_INDEX DSIIndex = DSI_INDEX0, MaxDSIIndex = DSI_INDEX0; + CBIOS_BOOL bDMAUpdate = pUpdateParams->DSIUpdateConfig.bDMAUpdate; + CBIOS_DSI_HOSTUPDATE_PARA DSIHostUpdatePara = {0}; + CBIOS_DSI_DMAUPDATE_PARA DSIDMAUpdatePara = {0}; + cbTraceEnter(DSI); + + if(bDMAUpdate) + { + Status = cbDSI_GetDMAUpdatePara(pcbe, &DSIDMAUpdatePara, pUpdateParams); + } + else + { + Status = cbDSI_GetHostUpdatePara(pcbe, &DSIHostUpdatePara, pUpdateParams); + } + + if (pPanelDesc->DSIConfig.isDualChannel) + { + MaxDSIIndex = DSI_INDEX1; + } + + cbDSI_WaitForFlip(pcbe); + + for (DSIIndex = DSI_INDEX0; DSIIndex <= MaxDSIIndex; DSIIndex++) + { + if(bDMAUpdate) + { + Status = cbDSI_DisplayUpdateByDMA(pcbe, &DSIDMAUpdatePara, DSIIndex); + } + else + { + Status = cbDSI_DisplayUpdateByHost(pcbe, &DSIHostUpdatePara, DSIIndex); + } + + } + + cbTraceExit(DSI); + return Status; +} + +CBIOS_STATUS cbDSI_SendCmdList(PCBIOS_VOID pvcbe, PCBIOS_DSI_CMD_DESC pCmdList, CBIOS_U32 CmdCount) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_DSI_WRITE_PARA_INTERNAL DSIWriteParams; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 i = 0; + cbTraceEnter(DSI); + + for (i = 0; i < CmdCount; i++) + { + cb_memset(&DSIWriteParams, 0, sizeof(CBIOS_DSI_WRITE_PARA_INTERNAL)); + DSIWriteParams.DSIIndex = pCmdList[i].DSIIndex; + DSIWriteParams.VirtualCh = (CBIOS_U8)pCmdList[i].VirtualCh; + DSIWriteParams.PacketType = pCmdList[i].PacketType; + DSIWriteParams.ContentType = pCmdList[i].ContentType; + DSIWriteParams.DataLen = (CBIOS_U16)pCmdList[i].DataLen; + DSIWriteParams.DSIFlags = pCmdList[i].DSIFlags; + DSIWriteParams.pDataBuf = pCmdList[i].pDataBuf; + + Status = cbDSI_SendWriteCmd(pcbe, &DSIWriteParams); + + if (pCmdList[i].WaitTime != 0) + { + cbDelayMilliSeconds(pCmdList[i].WaitTime); + } + } + + cbTraceExit(DSI); + return Status; +} + +#define POLL_PANEL_STATE_NUM 20 +#define CLK_CTRL_EXCH_NUM 10 +CBIOS_VOID cbDSI_R63319Patch(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DSI); + PCBIOS_DSI_PANEL_DESC pPanelDesc = &pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc; + REG_MM3444_MM3574 RegMM3444_MM3574Value; + REG_MM3404_MM3534 RegMM3404_MM3534Value; + REG_MM3438_MM3568 RegMM3438_MM3568Value; + CBIOS_U32 i = 0, j = 0; + CBIOS_BOOL bResult = CBIOS_FALSE; + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "enter cbDSIPanel_R63319Patch!\n")); + cbDSIPanel_DisplayOnOff(pcbe, CBIOS_FALSE, pPanelDesc); + + for(i = 0; i < CLK_CTRL_EXCH_NUM; i++) + { + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "i: %d \n", i)); + bResult = CBIOS_FALSE; + + cbWaitForActive(pcbe); + cbDSI_SetClkLaneMode(pcbe, CBIOS_DSI_CLK_LANE_SOFTWARE_CTL, DSI_INDEX1); + cbDSI_SetClkLaneMode(pcbe, CBIOS_DSI_CLK_LANE_SOFTWARE_CTL, DSI_INDEX0); + + + cbDSI_ClearReadFIFO(pcbe, DSI_INDEX1); + + for(j = 0; j < POLL_PANEL_STATE_NUM; j++ ) + { + cbMMIOWriteReg32(pcbe, 0x3534, 0x16000005, 0x0); + cbDelayMilliSeconds(50); + RegMM3438_MM3568Value.Value = cb_ReadU32(pcbe->pAdapterContext,0x3568); + RegMM3444_MM3574Value.Value = cb_ReadU32(pcbe->pAdapterContext,0x3574); + RegMM3404_MM3534Value.Value = cb_ReadU32(pcbe->pAdapterContext,0x3534); + cbMMIOWriteReg32(pcbe, 0x3568, RegMM3438_MM3568Value.Value, 0x0); + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "RegMM3438_MM3568Value: 0x%08x\n", RegMM3438_MM3568Value.Value)); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "RegMM3444_MM3574Value: 0x%08x\n", RegMM3444_MM3574Value.Value)); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "RegMM3404_MM3534Value: 0x%08x\n", RegMM3404_MM3534Value.Value)); + + if(RegMM3438_MM3568Value.Receive_Other_Trigger_or_Unrecognized_Stauts) + { + bResult = CBIOS_FALSE; + break; + } + else + { + cbDSI_ClearReadFIFO(pcbe, DSI_INDEX1); + } + } + + if(j >= POLL_PANEL_STATE_NUM) + { + bResult = CBIOS_TRUE; + } + + if(bResult) + { + break; + } + else + { + cbDSI_SetClkLaneMode(pcbe, CBIOS_DSI_CLK_LANE_HARDWARE_CTL, DSI_INDEX1); + cbDSI_SetClkLaneMode(pcbe, CBIOS_DSI_CLK_LANE_HARDWARE_CTL, DSI_INDEX0); + } + + cbDelayMilliSeconds(10); + + } + + cbDSIPanel_DisplayOnOff(pcbe, CBIOS_TRUE, pPanelDesc); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Exit cbDSIPanel_R63319Patch, bResult: %d\n", bResult)); +} + +static CBIOS_BOOL cbDSIPort_PanelDetect(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_U8 pEdid = pDevCommon->EdidData; + CBIOS_FAKE_EDID_PARAMS FakeEdidParams = {0}; + CBIOS_BOOL bConnected = CBIOS_FALSE; + PCBIOS_DSI_PARAMS pDSIParams = CBIOS_NULL; + PCBIOS_DSI_PANEL_TABLE pDSIPanelTbl = CBIOS_NULL; + + if(!(pcbe->DeviceMgr.SupportDevices & pDevCommon->DeviceType)) + { + //Not support, then return not connected + return CBIOS_FALSE; + } + + //check EDID + if (!cbEDIDModule_IsEDIDHeaderValid(pEdid, CBIOS_EDIDDATABYTE)) + { + //Integrated panel, use fake EDID + cbDebugPrint((MAKE_LEVEL(DSI, INFO),(" Use FakeEDID\n"))); + + cb_memset(pEdid, 0, CBIOS_EDIDDATABYTE); + + pDSIParams = &(pDevCommon->DeviceParas.DSIDevice); + pDSIPanelTbl = &(pDSIParams->DSIPanelDesc.DSIPanelTbl); + + FakeEdidParams.bProvideDtlTimingEDID = CBIOS_FALSE; + FakeEdidParams.DtlTiming.PixelClock = pDSIPanelTbl->PanelTiming.DCLK; + FakeEdidParams.DtlTiming.HActive = (CBIOS_U16)pDSIPanelTbl->PanelTiming.HorDisEnd; + FakeEdidParams.DtlTiming.VActive = (CBIOS_U16)pDSIPanelTbl->PanelTiming.VerDisEnd; + FakeEdidParams.DtlTiming.HBlank = pDSIPanelTbl->PanelTiming.HorBEnd - pDSIPanelTbl->PanelTiming.HorBStart; + FakeEdidParams.DtlTiming.VBlank = pDSIPanelTbl->PanelTiming.VerBEnd - pDSIPanelTbl->PanelTiming.VerBStart; + FakeEdidParams.DtlTiming.HSyncOffset = pDSIPanelTbl->PanelTiming.HorSyncStart - pDSIPanelTbl->PanelTiming.HorBStart; + FakeEdidParams.DtlTiming.HSyncPulseWidth = pDSIPanelTbl->PanelTiming.HorSyncEnd - pDSIPanelTbl->PanelTiming.HorSyncStart; + FakeEdidParams.DtlTiming.VSyncOffset = pDSIPanelTbl->PanelTiming.VerSyncStart - pDSIPanelTbl->PanelTiming.VerBStart; + FakeEdidParams.DtlTiming.VSyncPulseWidth = pDSIPanelTbl->PanelTiming.VerSyncEnd - pDSIPanelTbl->PanelTiming.VerSyncStart; + if (pDSIPanelTbl->PanelTiming.HVPolarity & DSI_HPOSITIVE) + { + FakeEdidParams.DtlTiming.HSync = HorPOSITIVE; + } + else + { + FakeEdidParams.DtlTiming.HSync = HorNEGATIVE; + } + if (pDSIPanelTbl->PanelTiming.HVPolarity & DSI_VPOSITIVE) + { + FakeEdidParams.DtlTiming.VSync = VerPOSITIVE; + } + else + { + FakeEdidParams.DtlTiming.VSync = VerNEGATIVE; + } + + cbEDIDModule_FakePanelEDID(&FakeEdidParams, pEdid, 128); + cbEDIDModule_ParseEDID(pEdid, &(pDevCommon->EdidStruct), CBIOS_EDIDDATABYTE); + + pDevCommon->isFakeEdid = CBIOS_TRUE; + pDevCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_PANEL; + } + + bConnected = CBIOS_TRUE; + return bConnected; +} + +CBIOS_VOID cbDSIPort_HwInit(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_DSI_PANEL_DESC pPanelDesc = CBIOS_NULL; + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_DSI))) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return; + } + + pPanelDesc = &pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc; + + if (!pDevCommon->DeviceParas.DSIDevice.bInitialized) + { + cb_memcpy(pPanelDesc, cbDSIPanel_GetPanelDescriptor(pcbe), sizeof(CBIOS_DSI_PANEL_DESC)); + cbDSIPanel_Init(pcbe, pPanelDesc); + pDevCommon->DeviceParas.DSIDevice.bInitialized = CBIOS_TRUE; + } + + if(cbDSIPort_PanelDetect(pcbe, pDevCommon)) + { + cbDSI_Init(pcbe, IGA1); + } + else + { + cbDebugPrint((MAKE_LEVEL(DSI, INFO), "%s: can't detect DSI panel, remove DSI from support devices!\n", FUNCTION_NAME)); + pcbe->DeviceMgr.SupportDevices &= ~(CBIOS_TYPE_DSI); + } +} + +CBIOS_VOID cbDSIPort_QueryMonitorAttribute(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBiosMonitorAttribute pMonitorAttribute) +{ + cbTraceEnter(DSI); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_DSI))) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return; + } + + pMonitorAttribute->bSupportBLCtrl = pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc.DSIConfig.isBLCtrlSupport; + pMonitorAttribute->MaxBLLevel = pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc.DSIConfig.BacklightMax; + pMonitorAttribute->MinBLLevel = pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc.DSIConfig.BacklightMin; + + cbTraceExit(DSI); +} + + +static CBIOS_VOID cbDSIPort_HW_SetMode(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_DSI_PARAMS pDSIParams = CBIOS_NULL; + PCBIOS_DSI_CONFIG pDSIConfig = CBIOS_NULL; + PCBIOS_TIMING_ATTRIB pTiming = &(pModeParams->TargetTiming); + + pDSIParams = &(pDevCommon->DeviceParas.DSIDevice); + pDSIConfig = &(pDSIParams->DSIPanelDesc.DSIConfig); + + if(pDSIConfig->isDualChannel) + { + cbDSI_SetDSITimingHW(pcbe, pDSIParams, pTiming, IGA1, DSI_INDEX0); + cbDSI_SetDSITimingHW(pcbe, pDSIParams, pTiming, IGA1, DSI_INDEX1); + + //enable dual-dsi timing + } + else + { + cbDSI_SetDSITimingHW(pcbe, pDSIParams, pTiming, IGA1, DSI_INDEX0); + //disable dual-dsi timing + } + +} + +static CBIOS_U32 cbDSIPort_CalPLLCLK(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_U32 PixelClock) +{ + PCBIOS_DSI_PANEL_DESC pPanelDesc = &pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc; + CBIOS_U32 PLLClk = 0; + if(pPanelDesc->DSIPanelTbl.OutBpp == 24) + { + switch(pPanelDesc->DSIPanelTbl.LaneNum ) + { + case 3: + PLLClk = PixelClock; + break; + case 1: + case 2: + case 4: + PLLClk = PixelClock * 3; + break; + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbDSIPort_CalPLLCLK: Wrong LaneNum \n")); + break; + } + } + else if (pPanelDesc->DSIPanelTbl.OutBpp == 16) + { + switch(pPanelDesc->DSIPanelTbl.LaneNum ) + { + case 1: + case 3: + PLLClk = PixelClock * 2; + break; + case 2: + case 4: + PLLClk = PixelClock ; + break; + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbDSIPort_CalPLLCLK: Wrong LaneNum \n")); + break; + } + } + else if (pPanelDesc->DSIPanelTbl.OutBpp == 18) + { + switch(pPanelDesc->DSIPanelTbl.LaneNum ) + { + case 3: + PLLClk = PixelClock * 3; + break; + case 1: + case 2: + case 4: + PLLClk = PixelClock * 9; + break; + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbDSIPort_CalPLLCLK: Wrong LaneNum \n")); + break; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbDSIPort_CalPLLCLK: Wrong OutBpp \n")); + } + + return PLLClk; +} + +static CBIOS_VOID cbDSIPort_UpdateModeInfo(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_DSI_PARAMS pDSIParams = CBIOS_NULL; + PCBIOS_TIMING_ATTRIB pTiming = &(pModeParams->TargetTiming); + + cbTraceEnter(DSI); + + pDSIParams = &(pDevCommon->DeviceParas.DSIDevice); + pTiming->PLLClock = cbDSIPort_CalPLLCLK(pcbe, pDevCommon, pTiming->PixelClock); + // save target timing + cb_memcpy(&(pDSIParams->TargetTiming), pTiming, sizeof(CBIOS_TIMING_ATTRIB)); + + cbTraceExit(DSI); +} + +static CBIOS_VOID cbDSIPort_SetMode(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + cbTraceEnter(DSI); + + cbDSIPort_HW_SetMode(pcbe, pDevCommon, pModeParams); + + cbTraceExit(DSI); +} + +CBIOS_BOOL cbDSIPort_DeviceDetect(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bHardcodeDetected, CBIOS_U32 FullDetect) +{ + CBIOS_BOOL bConnected = CBIOS_FALSE; + + cbTraceEnter(DSI); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_DSI))) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return bConnected; + } + + bConnected = cbDSIPort_PanelDetect(pcbe, pDevCommon); + + cbTraceExit(DSI); + + return bConnected; +} + +CBIOS_VOID cbDSIPort_OnOff(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bOn) +{ + PCBIOS_DSI_PANEL_DESC pPanelDesc = CBIOS_NULL; + cbTraceEnter(DSI); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_DSI))) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return; + } + + pPanelDesc = &pDevCommon->DeviceParas.DSIDevice.DSIPanelDesc; + + if (bOn) + { + cbDSI_ControllerInit(pcbe, IGA1, DSI_INDEX0); + cbDSI_ControllerOnOff(pcbe, CBIOS_TRUE, DSI_INDEX0); + + if(pPanelDesc->DSIConfig.isDualChannel) + { + cbDSI_ControllerInit(pcbe, IGA1, DSI_INDEX1); + cbDSI_ControllerOnOff(pcbe, CBIOS_TRUE, DSI_INDEX1); + } + + cbDSIPanel_OnOff(pcbe, CBIOS_TRUE, pPanelDesc); + + pDevCommon->PowerState = CBIOS_PM_ON; + } + else // turn off + { + // panel turn off + cbDSIPanel_OnOff(pcbe, CBIOS_FALSE, pPanelDesc); + + cbDSI_ControllerOnOff(pcbe, CBIOS_FALSE, DSI_INDEX0); + if(pPanelDesc->DSIConfig.isDualChannel) + { + cbDSI_ControllerOnOff(pcbe, CBIOS_FALSE, DSI_INDEX1); + } + pDevCommon->PowerState = CBIOS_PM_OFF; + } + + cbTraceExit(DSI); +} + +PCBIOS_DEVICE_COMMON cbDSIPort_Init(PCBIOS_VOID pvcbe, PVCP_INFO pVCP, CBIOS_ACTIVE_TYPE DeviceType) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDeviceCommon = CBIOS_NULL; + + if(DeviceType & ~CBIOS_TYPE_DSI) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: unsupported device type!!!\n", FUNCTION_NAME)); + return CBIOS_NULL; + } + + pDeviceCommon = cb_AllocateNonpagedPool(sizeof(CBIOS_DEVICE_COMMON)); + if(pDeviceCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: pDeviceCommon allocate error!!!\n", FUNCTION_NAME)); + return CBIOS_NULL; + } + + pDeviceCommon->DeviceType = DeviceType; + pDeviceCommon->SupportMonitorType = cbGetSupportMonitorType(pcbe, DeviceType); + pDeviceCommon->I2CBus = I2CBUS_INVALID; + pDeviceCommon->HPDPin = 0; + pDeviceCommon->CurrentMonitorType = CBIOS_MONITOR_TYPE_NONE; + pDeviceCommon->PowerState = CBIOS_PM_INVALID; + + cbInitialModuleList(&pDeviceCommon->DispSource.ModuleList); + + pDeviceCommon->pfncbDeviceHwInit = (PFN_cbDeviceHwInit)cbDSIPort_HwInit; + pDeviceCommon->pfncbQueryMonitorAttribute = (PFN_cbQueryMonitorAttribute)cbDSIPort_QueryMonitorAttribute; + pDeviceCommon->pfncbDeviceDetect = (PFN_cbDeviceDetect)cbDSIPort_DeviceDetect; + pDeviceCommon->pfncbDeviceOnOff = (PFN_cbDeviceOnOff)cbDSIPort_OnOff; + pDeviceCommon->pfncbUpdateDeviceModeInfo = (PFN_cbUpdateDeviceModeInfo)cbDSIPort_UpdateModeInfo; + pDeviceCommon->pfncbDeviceSetMode = (PFN_cbDeviceSetMode)cbDSIPort_SetMode; + + return pDeviceCommon; +} + +CBIOS_VOID cbDSIPort_DeInit(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_DSI_PARAMS pDSIParams = CBIOS_NULL; + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_DSI))) + { + cbDebugPrint((MAKE_LEVEL(DSI, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return; + } + + pDSIParams = &(pDevCommon->DeviceParas.DSIDevice); + + if (pDSIParams->pPanelDataBuf != CBIOS_NULL) + { + cb_FreePool(pDSIParams->pPanelDataBuf); + pDSIParams->pPanelDataBuf = CBIOS_NULL; + } + + cb_FreePool(pDevCommon); +} diff --git a/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDSI.h b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDSI.h new file mode 100644 index 0000000000000..bd6011d723003 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDSI.h @@ -0,0 +1,781 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DSI port interface function prototype and parameter definition. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_DSI_H_ +#define _CBIOS_DSI_H_ + +#include "../Monitor/DSIPanel/CBiosDSIPanel.h" + +#define CBIOS_DSI_VERSION 0x01 +#define CBIOS_DSI_PANEL_TAG 0x445349 // ASCII code of 'DSI' +#define CBIOS_DSI_CMD_FIFO_DEPTH 63 +#define CBIOS_DSI_POLLING_TIMEOUT 1000 // ms +#define CBIOS_DSI_MAX_RETURN_PACKET_SIZE 16 // byte + +#define khz2ps(khz) (1000000000 /(khz)) + +#define ceil(x, y) (((unsigned long)(x) + (unsigned long)(y) - 1) / (y)) + +// these cmd types are defined by hw design, not DSI spec +#define DSI_CMD_TYPE_DMA (1 << 0) // 1: DMA cmd, 0: non DMA cmd +#define DSI_CMD_TYPE_LAST_GROUP (1 << 1) // 1: last cmd of a transaction group, 0: is not +#define DSI_CMD_TYPE_NEED_ACK (1 << 2) // 1: the cmd need acknowledge, 0: no need +#define DSI_CMD_TYPE_FOLLOW_INTERV (1 << 3) // 1: next cmd should not be transferred until a configured interval has passed +#define DSI_CMD_TYPE_LP (1 << 4) // 1: the cmd can be transferred in LP mode, 0: the cmd can only be transferred in HS mode +#define DSI_CMD_TYPE_TE (1 << 5) // 1: the cmd is a TE BTA, 0: is not +#define DSI_CMD_TYPE_VIDEO (1 << 6) // 1: video cmd, 0: non video cmd + +#define DSI_TRIGGER_MSG_ACK 0x21 +#define DSI_TRIGGER_MSG_RESET 0x62 +#define DSI_TRIGGER_MSG_TE 0x5D + +// the interrupt status defined in register MM3438 +#define DSI_IRQ_DSI_READBACK (1 << 2) +#define DSI_IRQ_EPHY_LPP_HFAULT (1 << 3) +#define DSI_IRQ_EPHY_LPN_HFAULT (1 << 4) +#define DSI_IRQ_EPHY_LPP_LFAULT (1 << 5) +#define DSI_IRQ_EPHY_LPN_LFAULT (1 << 6) +#define DSI_IRQ_LPRX_TIMEOUT (1 << 7) +#define DSI_IRQ_HSTX_TIMEOUT (1 << 8) +#define DSI_IRQ_BTA_TIMEOUT (1 << 9) +#define DSI_IRQ_LPDATA_SYNC_ERR (1 << 10) +#define DSI_IRQ_INCRRECT_LINE_STATE (1 << 11) +#define DSI_IRQ_ULPS_TRIGGER (1 << 12) +#define DSI_IRQ_RESET_TRIGGER (1 << 13) +#define DSI_IRQ_TE_TRIGGER (1 << 14) +#define DSI_IRQ_OTHER_TRIGGER (1 << 15) +#define DSI_IRQ_HOST_BUS_TIMEOUT (1 << 24) + +// the Hsync Vsync signal polarity +#define DSI_HPOSITIVE 0x02 +#define DSI_HNEGATIVE 0x00 +#define DSI_VPOSITIVE 0x04 +#define DSI_VNEGATIVE 0x00 + +/* DSI Registers Begin */ +typedef union _REG_MM3294_MM32AC +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 IGA_VSync_Beg :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 IGA_VSync_End :4; + CBIOS_U32 Reserved_1 :11; + CBIOS_U32 Vcnt_Reset_Value_Sel :1; + }; +} REG_MM3294_MM32AC; + +typedef union _REG_MM3400_MM3530 //DSI_DMA_Time_Out_Register +{ + struct + { + CBIOS_U32 DMA_FIFO_Time_Out : 7; + CBIOS_U32 Reserved : 1; + CBIOS_U32 DMA_FIFO_Threshold : 16; + CBIOS_U32 Wait_interval_between_two_command_group : 8; + }; + CBIOS_U32 Value; +} REG_MM3400_MM3530; + +typedef union _REG_MM3404_MM3534 //DSI_Command_Data_Register +{ + struct + { + CBIOS_U32 DSI_Command_Data : 32; + }; + CBIOS_U32 Value; +} REG_MM3404_MM3534; + +typedef union _REG_MM3408_MM3538 //DSI_General_Control_Register +{ + struct + { + CBIOS_U32 DSI_Video_Mode_Software_Reset : 1; + CBIOS_U32 DSI_Output_Enable : 1; + CBIOS_U32 DSI_Mode : 1; + CBIOS_U32 DSI_Video_Mode_Pixel_End_Position : 1; + CBIOS_U32 DSI_Virtual_Channel : 2; + CBIOS_U32 Enable_Command_EoTp_End_of_Transmission_packet : 1; + CBIOS_U32 DSI_Video_Mode_Ouput_Pixel_Format : 2; + CBIOS_U32 DSI_Read_Data_Ready_Interrupt_Enable : 1; + CBIOS_U32 Reserved : 4; + CBIOS_U32 DCS_DSI_16BPP : 1; + CBIOS_U32 ENTER_HS : 1; + CBIOS_U32 IGA_VSYNC_Previous_Signal_Select : 2; + CBIOS_U32 IGA_VSYNC_Previous_Time : 13; + CBIOS_U32 DSI_Mode_Bit_Load_Control : 1; + }; + CBIOS_U32 Value; +} REG_MM3408_MM3538; + +typedef union _REG_MM340C_MM353C //DSI_Logical_PHY_Mode_Control_Register +{ + struct + { + CBIOS_U32 DSI_Data_Lane_Number : 2; + CBIOS_U32 Data_Lane_0_Bi_directional_or_Unidirectional : 1; + CBIOS_U32 Clock_Lane_Control_Mode : 1; + CBIOS_U32 Reserved_0 : 3; + CBIOS_U32 Enable_Turn_Around_Timeout_Check : 1; + CBIOS_U32 Enable_HS_TX_Timeout_Check : 1; + CBIOS_U32 Enable_LP_RX_Timeout_Check : 1; + CBIOS_U32 Contention_Detected_Sample_Select : 1; + CBIOS_U32 Reserved_1 : 1; + CBIOS_U32 LPP_High_Fault_Contention_Interrupt_Enable : 1; + CBIOS_U32 LPN_High_Fault_Contention_Interrupt_Enable : 1; + CBIOS_U32 LPP_Low_Fault_Contention_Interrupt_Enable : 1; + CBIOS_U32 LPN_Low_Fault_Contention_Interrupt_Enable : 1; + CBIOS_U32 LP_RX_Timeout_Interrupt_Enable : 1; + CBIOS_U32 Turn_Around_Timeout_Interrupt_Enable : 1; + CBIOS_U32 HS_TX_Timeout_Interrupt_Enable : 1; + CBIOS_U32 Low_Power_Data_Transmission_Synchronization_Error_Interrupt_Enable : 1; + CBIOS_U32 Incorrect_Line_State_Detected_Interrupt_Enable : 1; + CBIOS_U32 Receive_Trigger_Message_Interrupt_Enable : 1; + CBIOS_U32 Contention_Detected_LPP_TX_State_Delay_Select : 2; + CBIOS_U32 DSI_TE_from_Pad_interrupt_Enable : 1; + CBIOS_U32 DSI_TE_from_Pad_interrupt_set_select : 1; + CBIOS_U32 Reserved_2 : 6; + }; + CBIOS_U32 Value; +} REG_MM340C_MM353C; + +typedef union _REG_MM3410_MM3540 //LPHY_Real-Time_Control_Register +{ + struct + { + CBIOS_U32 LPHY_Software_Reset : 1; + CBIOS_U32 Data_Lane_Ultra_Low_Power_State_Control : 1; + CBIOS_U32 Enable_Clock_lane_high_speed_clock : 1; + CBIOS_U32 Clock_Lane_Ultra_Low_Power_State_Control : 1; + CBIOS_U32 Reserved_0 : 2; + CBIOS_U32 Driver_Send_Trigger_Message : 1; + CBIOS_U32 Driver_Send_Trigger_Message_in_Process : 1; + CBIOS_U32 Driver_Send_Trigger_Message_Data : 8; + CBIOS_U32 Reserved_1 : 16; + }; + CBIOS_U32 Value; +} REG_MM3410_MM3540; + +typedef union _REG_MM3414_MM3544 //LPHY_LPX_and_TA-GET_Period_Register +{ + struct + { + CBIOS_U32 LPX_Period : 16; + CBIOS_U32 TA_GET_Period : 16; + }; + CBIOS_U32 Value; +} REG_MM3414_MM3544; + + +typedef union _REG_MM3418_MM3548 //LPHY_TA-GO_and_TA-SURE_Period_Register +{ + struct + { + CBIOS_U32 TA_GO_Period : 16; + CBIOS_U32 TA_SURE_Period : 16; + }; + CBIOS_U32 Value; +} REG_MM3418_MM3548; + + +typedef union _REG_MM341C_MM354C //LPHY_Wake_Up_Period_Register +{ + struct + { + CBIOS_U32 Wake_Up_Period : 32; + }; + CBIOS_U32 Value; +} REG_MM341C_MM354C; + + +typedef union _REG_MM3420_MM3550 //LPHY_Data/Clock_Lane_HS_Prepare_Period_Register +{ + struct + { + CBIOS_U32 HS_PREPARE_and_HS_ZERO_Period : 16; + CBIOS_U32 CLK_PREPARE_and_CLK_ZERO_Period : 16; + }; + CBIOS_U32 Value; +} REG_MM3420_MM3550; + + +typedef union _REG_MM3424_MM3554 //LPHY_Data/Clock_Lane_HS_Trail_Period_Register +{ + struct + { + CBIOS_U32 HS_TRAIL_Period : 8; + CBIOS_U32 CLK_TRAIL_Period : 8; + CBIOS_U32 CLK_POST_Period : 8; + CBIOS_U32 CLK_PRE_Period : 8; + }; + CBIOS_U32 Value; +} REG_MM3424_MM3554; + + +typedef union _REG_MM3428_MM3558 //LPHY_HS-EXIT_Period_Register +{ + struct + { + CBIOS_U32 HS_EXIT_Period : 8; + CBIOS_U32 Reserved : 24; + }; + CBIOS_U32 Value; +} REG_MM3428_MM3558; + +typedef union _REG_MM342C_MM355C //DSI_TurnAround_Timeout_Period_Register +{ + struct + { + CBIOS_U32 DSI_TurnAround_Timeout_Period : 32; + }; + CBIOS_U32 Value; +} REG_MM342C_MM355C; + + +typedef union _REG_MM3430_MM3560 //DSI_HS-TX_Timeout_Period_Register +{ + struct + { + CBIOS_U32 DSI_HS_TX_Timeout_Period : 32; + }; + CBIOS_U32 Value; +} REG_MM3430_MM3560; + + +typedef union _REG_MM3434_MM3564 //DSI_LP-RX_Timeout_Period_Register +{ + struct + { + CBIOS_U32 DSI_LP_RX_Timeout_Period : 32; + }; + CBIOS_U32 Value; +} REG_MM3434_MM3564; + +typedef union _REG_MM3440_MM3570 //DSI Command Group Wait Control register +{ + struct + { + CBIOS_U32 DSI_Command_Group_Wait_Time : 8; + CBIOS_U32 DSI_Command_Group_Wait_Enable : 1; + CBIOS_U32 DIU_HostBus_Timeout_Interrupt_Enable : 1; + CBIOS_U32 Reserved_1 : 6; + CBIOS_U32 DSI_Command_DMA_Request_Threshold : 8; + CBIOS_U32 DMA_Pixel_Dataformat_32bpp : 1; + CBIOS_U32 DMA_Pixel_Dataformat_16bpp : 1; + CBIOS_U32 Switch_R_B_32bpp : 1; + CBIOS_U32 Switch_R_B_16bpp : 1; + CBIOS_U32 Special_Switch_R_B_16bpp : 1; + CBIOS_U32 Reserved_2 : 3; + }; + CBIOS_U32 Value; +} REG_MM3440_MM3570; + +typedef union _REG_MM3444_MM3574 //DSI_Command_Mode_Status_Register +{ + struct + { + CBIOS_U32 Reserved_0 : 6; + CBIOS_U32 DSI_Command_Busy_Status : 1; + CBIOS_U32 DSI_Command_DMA_Busy_Status : 1; + CBIOS_U32 DSI_Read_Back_Data_Number : 8; + CBIOS_U32 DSI_Command_FIFO_Status :10; + CBIOS_U32 Reserved_1 : 6; + }; + CBIOS_U32 Value; +} REG_MM3444_MM3574; + +typedef union _REG_MM3438_MM3568 //LPHY_Interrupt_Status_Register +{ + struct + { + CBIOS_U32 IGA1_Vertical_Interrupt_Stauts : 1; + CBIOS_U32 IGA2_Vertical_Interrupt_Stauts : 1; + CBIOS_U32 DSI_Read_Back_Data_Interrupt_Status : 1; + CBIOS_U32 EPHY_LPP_High_Fault_Interrupt_Status : 1; + CBIOS_U32 EPHY_LPN_High_Fault_Interrupt_Status : 1; + CBIOS_U32 EPHY_LPP_Low_Fault_Interrupt_Status : 1; + CBIOS_U32 EPHY_LPN_Low_Fault_Interrupt_Status : 1; + CBIOS_U32 LP_RX_Timer_Timeout_Interrupt_Status : 1; + CBIOS_U32 HS_TX_Timer_Timeout_Interrupt_Status : 1; + CBIOS_U32 Turnaround_Timer_Timeout_Interrupt_Status : 1; + CBIOS_U32 Low_Power_Data_Transmission_Synchronization_Error_Interrupt_Status : 1; + CBIOS_U32 Incorrect_Line_State_Detected_Interrupt_Status : 1; + CBIOS_U32 Receive_ULPS_Trigger_Interrupt_Status : 1; + CBIOS_U32 Receive_Reset_Trigger_Interrupt_Status : 1; + CBIOS_U32 Receive_TE_Trigger_Interrupt_Status : 1; + CBIOS_U32 Receive_Other_Trigger_or_Unrecognized_Stauts : 1; + CBIOS_U32 Receive_Trigger_Data : 8; + CBIOS_U32 DIU_host_bus_timeout_interrupt_status : 1; + CBIOS_U32 DSI_TE_from_PAD_Interrupt_status : 1; + CBIOS_U32 Reserved : 6; + }; + CBIOS_U32 Value; +} REG_MM3438_MM3568; + +typedef union _REG_MM3448_MM3578 //DSI_EPHY_Control_Register +{ + struct + { + CBIOS_U32 Power_down_PLL : 1; + CBIOS_U32 PLL_charge_pump_current_control : 3; + CBIOS_U32 PLL_filter_C_control : 2; + CBIOS_U32 PLL_filter_R_control : 2; + CBIOS_U32 Clock_Lane_Power_Down : 1; + CBIOS_U32 TCLK_PREPARE : 6; + CBIOS_U32 Clock_Lane_Boost : 1; + CBIOS_U32 Power_Down_Data_Lane_0 : 1; + CBIOS_U32 Power_Down_Data_Lane_1 : 1; + CBIOS_U32 Power_Down_Data_Lane_2 : 1; + CBIOS_U32 Power_Down_Data_Lane_3 : 1; + CBIOS_U32 THS_PREPARE : 6; + CBIOS_U32 Data_Lane_Boost : 1; + CBIOS_U32 Power_Down_LP_RX : 1; + CBIOS_U32 Reserved : 4; + }; + CBIOS_U32 Value; +} REG_MM3448_MM3578; + +typedef union _REG_MM344C_MM357C //DSI_EPHY_Control_Register +{ + struct + { + CBIOS_U32 RTNSWX : 1; + CBIOS_U32 RTNEN : 1; + CBIOS_U32 RTNSETEN : 1; + CBIOS_U32 RTNSET : 4; + CBIOS_U32 RTNCMSET : 4; + CBIOS_U32 RTNRSTB : 1; + CBIOS_U32 RTNOUT : 4; + CBIOS_U32 EPHY_HS_Drive_Amplitude_Select : 4; + CBIOS_U32 EPHY_LP_Drivers_Slew_Rate_Control : 4; + CBIOS_U32 EPHY_Bandgap_Reference_Voltage_Select : 3; + CBIOS_U32 EPHY_Input_Data_Hold_Time_Select : 4; + CBIOS_U32 EPHY_Current_Reference_Resistor_Select : 1; + + }; + CBIOS_U32 Value; +} REG_MM344C_MM357C; + +typedef union _REG_MM3450_MM3580 //DSI_EPHY_Control_Register +{ + struct + { + CBIOS_U32 EPHY_CHY : 8 ; + CBIOS_U32 EPHY_CHX :8 ; + CBIOS_U32 EPHY_REFS : 4 ; + CBIOS_U32 Reserved : 12 ; + }; + CBIOS_U32 Value; +} REG_MM3450_MM3580; + + +typedef union _REG_MM345C_MM358C //DSI_Video_Mode_Register_1 +{ + struct + { + CBIOS_U32 DSI_Video_Mode_EoTp_Packet_Enable : 1; + CBIOS_U32 Reserved : 6; + CBIOS_U32 HFP_LP : 1; + CBIOS_U32 HSA_LP : 1; + CBIOS_U32 HBP_LP : 1; + CBIOS_U32 HSS_EN : 1; + CBIOS_U32 HSE_EN : 1; + CBIOS_U32 VSS_EN : 1; + CBIOS_U32 VSE_EN : 1; + CBIOS_U32 DSI_Video_Mode_Enable : 1; + CBIOS_U32 DSI_Video_Mode_Enable_Flip_Control : 1; + CBIOS_U32 PXL_WC : 16; + }; + CBIOS_U32 Value; +} REG_MM345C_MM358C; + + +typedef union _REG_MM3460_MM3590 //DSI_Video_Mode_Register_2 +{ + struct + { + CBIOS_U32 HFP_WC : 16; + CBIOS_U32 HSA_WC : 16; + }; + CBIOS_U32 Value; +} REG_MM3460_MM3590; + + +typedef union _REG_MM3464_MM3594 //DSI_Video_Mode_Register_3 +{ + struct + { + CBIOS_U32 HBP_WC : 16; + CBIOS_U32 HSS_LP2HS : 16; + }; + CBIOS_U32 Value; +} REG_MM3464_MM3594; + + +typedef union _REG_MM3468_MM3598 //DSI_Video_Mode_Register_4 +{ + struct + { + CBIOS_U32 HSE_LP2HS : 16; + CBIOS_U32 PXL_LP2HS : 16; + }; + CBIOS_U32 Value; +} REG_MM3468_MM3598; + +typedef union _REG_MM346C //backlight adjustment +{ + struct + { + CBIOS_U32 reg_backlight_factor : 16; + CBIOS_U32 pwm_frequency_counter : 16; + }; + CBIOS_U32 Value; +} REG_MM346C; + +typedef union _REG_MM3470 //backlight adjustment +{ + struct + { + CBIOS_U32 pwm_enable : 1; + CBIOS_U32 Reserved_0 : 3; + CBIOS_U32 reg_pwm_control : 4; + CBIOS_U32 Reserved_1 : 24; + }; + CBIOS_U32 Value; +} REG_MM3470; + +typedef union _REG_MM3480 //MDI misc registers +{ + struct + { + CBIOS_U32 ONE_CHANNEL : 1; + CBIOS_U32 LCH_EN : 1; + CBIOS_U32 LCH_MODE : 2; + CBIOS_U32 SS_DMA1_SEL : 1; + CBIOS_U32 TS_DMA2_SEL : 1; + CBIOS_U32 PS1_FF_DEEPTH : 3; + CBIOS_U32 PS2_FF_DEEPTH : 3; + CBIOS_U32 CHANNEL_SIZE : 3; + CBIOS_U32 MIU_BANK_NUM : 1; + CBIOS_U32 MIU_PAGE_SIZE : 2; + CBIOS_U32 AUD_LCH_EN : 1; + CBIOS_U32 IDLE_ROUND_EN : 1; + CBIOS_U32 RDATA_FF_LEFT : 4; + CBIOS_U32 RDATA_FF_THRESHOLD : 8; + }; + CBIOS_U32 Value; +} REG_MM3480; + +typedef union _REG_MM349C //Pad Control +{ + struct + { + CBIOS_U32 GPIO3_REN: 1; + CBIOS_U32 GPIO4_REN: 1; + CBIOS_U32 GPIO5_REN: 1; + CBIOS_U32 GPIO6_REN: 1; + CBIOS_U32 GPIO7_REN: 1; + CBIOS_U32 GPIO8_REN: 1; + CBIOS_U32 GPIO9_REN: 1; + CBIOS_U32 ENVDD_REN: 1; + CBIOS_U32 ENVEE_REN: 1; + CBIOS_U32 DSI_TE_IEN: 1; + CBIOS_U32 MHLSWT_OEN: 1; + CBIOS_U32 ENVDD_ENVEE_OEN: 1; + CBIOS_U32 Reserved: 20; + }; + CBIOS_U32 Value; +} REG_MM349C; + +typedef union _REG_MM34A0 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DSI_Clock_Enable :1; + CBIOS_U32 MHL_Enable :1; + CBIOS_U32 MHL_Mode :1; //0: MHL normal mode, 1: MHL packed mode + CBIOS_U32 Reserved :29; + }; +} REG_MM34A0; + +typedef union _REG_MM34BC_MM35EC // +{ + struct + { + CBIOS_U32 Y_START : 12; + CBIOS_U32 Reserved_0 : 4; + CBIOS_U32 Y_HEIGHT : 12; + CBIOS_U32 Reserved_1 : 3; + CBIOS_U32 DSI_Partial_Timing_Enable : 1; + }; + CBIOS_U32 Value; +} REG_MM34BC_MM35EC; + +typedef union _REG_MM34C0_MM34C8 // +{ + struct + { + CBIOS_U32 X_START : 13; + CBIOS_U32 Y_START : 12; + CBIOS_U32 Reserved : 6; + CBIOS_U32 DSI_CMD_Mode_Enable : 1; + }; + CBIOS_U32 Value; +} REG_MM34C0_MM34C8; + +typedef union _REG_MM34C4_MM34CC // +{ + struct + { + CBIOS_U32 Width : 13; + CBIOS_U32 Height : 12; + CBIOS_U32 Reserved : 7; + }; + CBIOS_U32 Value; +} REG_MM34C4_MM34CC; + +/* DSI Registers End */ + +/* MIPI DSI Processor-to-Peripheral transaction packet data types */ +typedef enum _CBIOS_DSI_PROCESSOR_DATA_TYPE +{ + DSI_V_SYNC_START = 0x01, + DSI_V_SYNC_END = 0x11, + DSI_H_SYNC_START = 0x21, + DSI_H_SYNC_END = 0x31, + DSI_END_OF_TRANSMISSION = 0x08, + DSI_COLOR_MODE_OFF = 0x02, + DSI_COLOR_MODE_ON = 0x12, + DSI_SHUTDOWN_PERIPHERAL = 0x22, + DSI_TURN_ON_PERIPHERAL = 0x32, + DSI_GENERIC_SHORT_WRITE_0_PARAM = 0x03, + DSI_GENERIC_SHORT_WRITE_1_PARAM = 0x13, + DSI_GENERIC_SHORT_WRITE_2_PARAM = 0x23, + DSI_GENERIC_READ_REQUEST_0_PARAM = 0x04, + DSI_GENERIC_READ_REQUEST_1_PARAM = 0x14, + DSI_GENERIC_READ_REQUEST_2_PARAM = 0x24, + DSI_DCS_SHORT_WRITE = 0x05, + DSI_DCS_SHORT_WRITE_PARAM = 0x15, + DSI_DCS_READ = 0x06, + DSI_SET_MAXIMUM_RETURN_PACKET_SIZE = 0x37, + DSI_NULL_PACKET = 0x09, + DSI_BLANKING_PACKET = 0x19, + DSI_GENERIC_LONG_WRITE = 0x29, + DSI_DCS_LONG_WRITE = 0x39, + DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 = 0x0c, + DSI_PACKED_PIXEL_STREAM_YCBCR24 = 0x1c, + DSI_PACKED_PIXEL_STREAM_YCBCR16 = 0x2c, + DSI_PACKED_PIXEL_STREAM_30 = 0x0d, + DSI_PACKED_PIXEL_STREAM_36 = 0x1d, + DSI_PACKED_PIXEL_STREAM_YCBCR12 = 0x3d, + DSI_PACKED_PIXEL_STREAM_16 = 0x0e, + DSI_PACKED_PIXEL_STREAM_18 = 0x1e, + DSI_PIXEL_STREAM_3BYTE_18 = 0x2e, + DSI_PACKED_PIXEL_STREAM_24 = 0x3e, +} CBIOS_DSI_PROCESSOR_DATA_TYPE; + +/* MIPI DSI Peripheral-to-Processor transaction packet data types */ +typedef enum _CBIOS_DSI_PERIPHERAL_DATA_TYPE +{ + DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT = 0x02, + DSI_RX_END_OF_TRANSMISSION = 0x08, + DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE = 0x11, + DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE = 0x12, + DSI_RX_GENERIC_LONG_READ_RESPONSE = 0x1a, + DSI_RX_DCS_LONG_READ_RESPONSE = 0x1c, + DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE = 0x21, + DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE = 0x22, +} CBIOS_DSI_PERIPHERAL_DATA_TYPE; + + +/* MIPI DCS commands */ +typedef enum _CBIOS_DSI_DCS_COMMAND +{ + DSI_DCS_NOP = 0x00, + DSI_DCS_SOFT_RESET = 0x01, + DSI_DCS_GET_DISPLAY_ID = 0x04, + DSI_DCS_GET_RED_CHANNEL = 0x06, + DSI_DCS_GET_GREEN_CHANNEL = 0x07, + DSI_DCS_GET_BLUE_CHANNEL = 0x08, + DSI_DCS_GET_DISPLAY_STATUS = 0x09, + DSI_DCS_GET_POWER_MODE = 0x0A, + DSI_DCS_GET_ADDRESS_MODE = 0x0B, + DSI_DCS_GET_PIXEL_FORMAT = 0x0C, + DSI_DCS_GET_DISPLAY_MODE = 0x0D, + DSI_DCS_GET_SIGNAL_MODE = 0x0E, + DSI_DCS_GET_DIAGNOSTIC_RESULT = 0x0F, + DSI_DCS_ENTER_SLEEP_MODE = 0x10, + DSI_DCS_EXIT_SLEEP_MODE = 0x11, + DSI_DCS_ENTER_PARTIAL_MODE = 0x12, + DSI_DCS_ENTER_NORMAL_MODE = 0x13, + DSI_DCS_EXIT_INVERT_MODE = 0x20, + DSI_DCS_ENTER_INVERT_MODE = 0x21, + DSI_DCS_SET_GAMMA_CURVE = 0x26, + DSI_DCS_SET_DISPLAY_OFF = 0x28, + DSI_DCS_SET_DISPLAY_ON = 0x29, + DSI_DCS_SET_COLUMN_ADDRESS = 0x2A, + DSI_DCS_SET_PAGE_ADDRESS = 0x2B, + DSI_DCS_WRITE_MEMORY_START = 0x2C, + DSI_DCS_WRITE_LUT = 0x2D, + DSI_DCS_READ_MEMORY_START = 0x2E, + DSI_DCS_SET_PARTIAL_ROWS = 0x30, + DSI_DCS_SET_PARTIAL_COLUMNS = 0x31, + DSI_DCS_SET_SCROLL_AREA = 0x33, + DSI_DCS_SET_TEAR_OFF = 0x34, + DSI_DCS_SET_TEAR_ON = 0x35, + DSI_DCS_SET_ADDRESS_MODE = 0x36, + DSI_DCS_SET_SCROLL_START = 0x37, + DSI_DCS_EXIT_IDLE_MODE = 0x38, + DSI_DCS_ENTER_IDLE_MODE = 0x39, + DSI_DCS_SET_PIXEL_FORMAT = 0x3A, + DSI_DCS_WRITE_MEMORY_CONTINUE = 0x3C, + DSI_DCS_READ_MEMORY_CONTINUE = 0x3E, + DSI_DCS_SET_TEAR_SCANLINE = 0x44, + DSI_DCS_GET_SCANLINE = 0x45, + DSI_DCS_READ_DDB_START = 0xA1, + DSI_DCS_READ_DDB_CONTINUE = 0xA8, +} CBIOS_DSI_DCS_COMMAND; + +typedef enum _CBIOS_DSI_PANELID +{ + DSI_PANELID_HX8369A = 0, + DSI_PANELID_HX8392A = 1, + DSI_PANELID_R63417 = 2 +} CBIOS_DSI_PANELID; + +typedef enum _CBIOS_DSI_INDEX +{ + DSI_INDEX0 = 0, + DSI_INDEX1 = 1 +} CBIOS_DSI_INDEX; + +typedef enum _CBIOS_DSI_DCS_MODE +{ + CBIOS_DSI_DCS_IDLE_MODE = 0x00, + CBIOS_DSI_DCS_INVERT_MODE, + CBIOS_DSI_DCS_NORMAL_MODE, + CBIOS_DSI_DCS_PARTIAL_MODE, + CBIOS_DSI_DCS_SLEEP_MODE, +} CBIOS_DSI_DCS_MODE; + +typedef struct _CBIOS_DSI_PHY_PARAMS +{ + CBIOS_U32 LPX; + CBIOS_U32 HS_PREPARE; + CBIOS_U32 HS_PREPARE_ZERO; + CBIOS_U32 HS_TRAIL; + CBIOS_U32 HS_EXIT; + CBIOS_U32 CLK_PRE; + CBIOS_U32 CLK_PREPARE; + CBIOS_U32 CLK_PREPARE_ZERO; + CBIOS_U32 CLK_POST; + CBIOS_U32 CLK_TRAIL; + CBIOS_U32 TA_GET; + CBIOS_U32 TA_GO; + CBIOS_U32 TA_SURE; + CBIOS_U32 WakeUp; + + CBIOS_U32 tLP2HS; + CBIOS_U32 tHS2LP; +} CBIOS_DSI_PHY_PARAMS, *PCBIOS_DSI_PHY_PARAMS; + + + + + +typedef struct _CBIOS_DSI_VIDEO_TIMING_REG +{ + CBIOS_U32 PXL_WC; + CBIOS_U32 HFP_WC; + CBIOS_U32 HSA_WC; + CBIOS_U32 HBP_WC; + CBIOS_U32 HSS_LP2HS; + CBIOS_U32 HSE_LP2HS; + CBIOS_U32 PXL_LP2HS; +} CBIOS_DSI_VIDEO_TIMING_REG, *PCBIOS_DSI_VIDEO_TIMING_REG; + +// CBIOS_DSI_WRITE_PARA is for CBIOS interface use, and CBIOS_DSI_WRITE_PARA_INTERNAL is for CBIOS internal use +typedef struct _CBIOS_DSI_WRITE_PARA_INTERNAL +{ + CBIOS_U32 DSIIndex; // 0: DSI-1, 1:DSI-2 + CBIOS_U8 VirtualCh; // refer MIPI-DSI spec 4.2.3 + CBIOS_DSI_PACKET_TYPE PacketType; // 0: short packet, 1: long packet + CBIOS_DSI_CONTENT_TYPE ContentType; // 0: DCS write cmd, 1: generic write cmd + CBIOS_U16 DataLen; + PCBIOS_U8 pDataBuf; + union + { + CBIOS_U32 DSIFlags; + struct + { + CBIOS_U32 bNeedAck : 1; // 1: the cmd need acknowledge, 0: no need + CBIOS_U32 bHSModeOnly : 1; // 1: the cmd can be transferred in hs mode only, 0: both LP and HS mode + CBIOS_U32 Reserved : 30; + }; + }; +} CBIOS_DSI_WRITE_PARA_INTERNAL, *PCBIOS_DSI_WRITE_PARA_INTERNAL; + +// CBIOS_DSI_READ_PARA is for CBIOS interface use, and CBIOS_DSI_READ_PARA_INTERNAL is for CBIOS internal use +typedef struct _CBIOS_DSI_READ_PARA_INTERNAL +{ + CBIOS_U32 Size; + CBIOS_U32 DSIIndex; // 0: DSI-1, 1:DSI-2 + CBIOS_U8 VirtualCh; // refer MIPI-DSI spec 4.2.3 + CBIOS_DSI_CONTENT_TYPE ContentType; // 0: DCS read cmd, 1: generic read cmd + CBIOS_U8 DataLen; + PCBIOS_U8 pDataBuf; + PCBIOS_U8 pReceivedPayloadBuf; // The buffer to store the receive payload + CBIOS_U16 ReceivedPayloadLen; // The length of response payload after the DCS read cmd + union + { + CBIOS_U32 DSIReadFlags; + struct + { + CBIOS_U32 bHSModeOnly : 1; // 1: the cmd can be transferred in hs mode only, 0: both LP and HS mode + CBIOS_U32 Reserved : 31; + }; + }; +} CBIOS_DSI_READ_PARA_INTERNAL, *PCBIOS_DSI_READ_PARA_INTERNAL; + + +typedef struct _CBIOS_DSI_PARAMS +{ + CBIOS_DSI_PANEL_DESC DSIPanelDesc; + CBIOS_DSI_PHY_PARAMS PhyParams; + CBIOS_DSI_UPDATE_PARA UpdatePara; + CBIOS_DSI_HOSTUPDATE_PARA HostUpdatePara; + CBIOS_TIMING_ATTRIB TargetTiming; + PCBIOS_U8 pPanelDataBuf; + CBIOS_BOOL bInitialized; +} CBIOS_DSI_PARAMS, *PCBIOS_DSI_PARAMS; + + +CBIOS_STATUS cbDSI_SendWriteCmd(PCBIOS_VOID pvcbe, PCBIOS_DSI_WRITE_PARA_INTERNAL pDSIWriteParams); +CBIOS_STATUS cbDSI_SendReadCmd(PCBIOS_VOID pvcbe, PCBIOS_DSI_READ_PARA_INTERNAL pDSIReadParams); +CBIOS_STATUS cbDSI_SendCmdList(PCBIOS_VOID pvcbe, PCBIOS_DSI_CMD_DESC pCmdList, CBIOS_U32 CmdCount); +CBIOS_STATUS cbDSI_DisplayUpdate(PCBIOS_VOID pvcbe, PCBIOS_DSI_UPDATE_PARA pUpdatePara); +CBIOS_STATUS cbDSI_SetTE_BTA(PCBIOS_VOID pvcbe, CBIOS_DSI_INDEX DSIIndex); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDVO.c b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDVO.c new file mode 100644 index 0000000000000..695ff093ab658 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDVO.c @@ -0,0 +1,260 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DVO port interface function implementation. +** +** NOTE: +** DVO port ONLY parameters SHOULD be added to CBIOS_DVO_CONTEXT. +** The daughter card's function and parameter SHOULD be added to corresponding monitor file. +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "../../Hw/HwBlock/CBiosDIU_DVO.h" + +#if DVO_PORT_SUPPORT + +CBIOS_VOID cbDVOPort_GetSupportMonitorType(PCBIOS_VOID pvcbe, PCBIOS_MONITOR_TYPE pMonitorType) +{ + //PCBIOS_EXTENSION_COMMON pcbe=(PCBIOS_EXTENSION_COMMON)pvcbe; + //PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DVO); + + /*if (pDvoContext->DVODevice.DVOTxType == TX_ADV7511) + { + (*pMonitorType) |= CBIOS_MONITOR_TYPE_HDMI | CBIOS_MONITOR_TYPE_DVI; + }*/ +} + +//------------------------------------------------------------------- +//cbDVOPort_InitTX +// initialize TX HW on DVO port +// +//------------------------------------------------------------------- +static CBIOS_BOOL cbDVOPort_InitTX(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DVO_CONTEXT pDvoContext) +{ + CBIOS_BOOL status = CBIOS_TRUE; + + switch (pDvoContext->DVODevice.DVOTxType) + { + /*case TX_ADV7511: + status = cbADV7511_Init(pcbe); + break;*/ + default: + status = CBIOS_FALSE; + break; + } + + return status; +} + + +static CBIOS_VOID cbDVOPort_OnOff(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bOn) +{ + PCBIOS_DVO_CONTEXT pDvoContext = container_of(pDevCommon, PCBIOS_DVO_CONTEXT, Common); + CBIOS_U32 IGAIndex = CBIOS_MODULE_INDEX_INVALID; + + cbTraceEnter(GENERIC); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_DVO))) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return; + } + + IGAIndex = pDevCommon->DispSource.ModuleList.IGAModule.Index; + + if(bOn) + { + cbDIU_DVO_VideoOnOff(pcbe, bOn, (CBIOS_U8)IGAIndex); + + switch(pDvoContext->DVODevice.DVOTxType) + { + /*case TX_ADV7511: + cbADV7511_OnOff(pcbe, CBIOS_TRUE, IGAIndex); + break;*/ + + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING),"%s: unknown DVO daughter card type!\n", FUNCTION_NAME)); + break; + } + + pDevCommon->PowerState = CBIOS_PM_ON; + } + else + { + switch(pDvoContext->DVODevice.DVOTxType) + { + /*case TX_ADV7511: + cbADV7511_OnOff(pcbe, CBIOS_FALSE, IGAIndex); + break;*/ + + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING),"%s: unknown DVO daughter card type!\n", FUNCTION_NAME)); + break; + } + + cbDIU_DVO_VideoOnOff(pcbe, bOn, (CBIOS_U8)IGAIndex); + + pDevCommon->PowerState = CBIOS_PM_OFF; + } + + cbTraceExit(GENERIC); +} + +static CBIOS_VOID cbDVOPort_HW_SetMode(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + CBIOS_U8 HVPolarity = pModeParams->TargetTiming.HVPolarity; + + cbDIU_DVO_SetHVSync(pcbe, HVPolarity); +} + +static CBIOS_VOID cbDVOPort_SetMode(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + cbDVOPort_HW_SetMode(pcbe, pModeParams); +} + +static CBIOS_VOID cbDVOPort_HwInit(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_DVO_CONTEXT pDvoContext = container_of(pDevCommon, PCBIOS_DVO_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_DVO))) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return; + } + + cbDVOPort_InitTX(pcbe, pDvoContext); +} + +static CBIOS_BOOL cbDVOPort_DeviceDetect(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bHardcodeDetected, CBIOS_U32 FullDetect) +{ + CBIOS_BOOL bGotEdid = CBIOS_FALSE; + CBIOS_BOOL IsDevChanged = 0; + CBIOS_BOOL bConnected = CBIOS_FALSE; + PCBIOS_DVO_CONTEXT pDvoContext = container_of(pDevCommon, PCBIOS_DVO_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_DVO))) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return bConnected; + } +/* //for ADV7511 , config the EDID slaveaddr (0x43) as a0 + if(pDvoContext->DvoDevice.DVOTxType == TX_ADV7511) + { + cbADV7511_PreDetect(pvcbe); + }*/ + + bGotEdid = cbGetDeviceEDID(pcbe, &pDvoContext->Common, &IsDevChanged, FullDetect); + + if (!((*(pDvoContext->Common.EdidData + EDID_VIDEO_INPUT_DEF_BYTE_OFFSET)) & EDID_VIDEO_INPUT_DEF_DIGITAL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: why come here??? Current device is a CRT monitor according to EDID!\n", FUNCTION_NAME)); + bGotEdid = CBIOS_FALSE; + } + + if (bGotEdid) + { + if (IsDevChanged) + { + cbEDIDModule_ParseEDID(pDvoContext->Common.EdidData, &(pDvoContext->Common.EdidStruct), CBIOS_EDIDDATABYTE); + } + + if (pDvoContext->Common.EdidStruct.Attribute.IsCEA861HDMI) + { + pDvoContext->Common.CurrentMonitorType = CBIOS_MONITOR_TYPE_HDMI; + } + else + { + pDvoContext->Common.CurrentMonitorType = CBIOS_MONITOR_TYPE_DVI; + } + + //update monitor type + if (!(pDvoContext->Common.CurrentMonitorType & cbGetSupportMonitorType(pcbe, pDevCommon->DeviceType))) + { + pDvoContext->Common.CurrentMonitorType = cbGetSupportMonitorType(pcbe, pDevCommon->DeviceType); + } + + pDvoContext->Common.isFakeEdid = CBIOS_FALSE; + bConnected = CBIOS_TRUE; + } + else + { + //for the case:if plugout monitor before suspend,and then plugin hdmi monitor before resume,after resume,4k@60 can't be lighted. + //rootcause:if plugout monitor,hpd thread will detect no device,so some attributes stored in pDevCommon will be cleared, + //plugin monitor before resume,os will do nothing,so it will not update attributes stored in pDevCommon + //then after resume,driver will not enter some hdmi module related codes,so monitor can't light + //so not memset pDevCommon->EdidStruct when device is not connected + cbClearEdidRelatedData(pcbe, &pDvoContext->Common); + } + + return bConnected; +} + +PCBIOS_DEVICE_COMMON cbDVOPort_Init(PCBIOS_VOID pvcbe, PVCP_INFO pVCP, CBIOS_ACTIVE_TYPE DeviceType) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DVO_CONTEXT pDvoContext = CBIOS_NULL; + + if(DeviceType & ~CBIOS_TYPE_DVO) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: unsupported device type!!!\n", FUNCTION_NAME)); + return CBIOS_NULL; + } + + pDvoContext = cb_AllocateNonpagedPool(sizeof(CBIOS_DVO_CONTEXT)); + if(pDvoContext == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: pDvoContext allocate error!!!\n", FUNCTION_NAME)); + return CBIOS_NULL; + } + + pDvoContext->Common.DeviceType = DeviceType; + pDvoContext->Common.SupportMonitorType = CBIOS_MONITOR_TYPE_NONE; + pDvoContext->Common.I2CBus = pVCP->DVOCharByte & I2CBUSMASK; + pDvoContext->Common.HPDPin = pVCP->DVOInterruptPort & HPDPORT_MASK; + pDvoContext->Common.CurrentMonitorType = CBIOS_MONITOR_TYPE_NONE; + pDvoContext->Common.PowerState = CBIOS_PM_INVALID; + + cbInitialModuleList(&pDvoContext->Common.DispSource.ModuleList); + + pDvoContext->Common.pfncbDeviceHwInit = (PFN_cbDeviceHwInit)cbDVOPort_HwInit; + pDvoContext->Common.pfncbDeviceDetect = (PFN_cbDeviceDetect)cbDVOPort_DeviceDetect; + pDvoContext->Common.pfncbDeviceOnOff = (PFN_cbDeviceOnOff)cbDVOPort_OnOff; + pDvoContext->Common.pfncbDeviceSetMode = (PFN_cbDeviceSetMode)cbDVOPort_SetMode; + + // pre check if DVO daughter card exists + cbDIU_DVO_CheckDaughterCardType(pcbe, pVCP, pDvoContext); + + return &pDvoContext->Common; +} + +CBIOS_VOID cbDVOPort_DeInit(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon) +{ + PCBIOS_DVO_CONTEXT pDvoContext = container_of(pDevCommon, PCBIOS_DVO_CONTEXT, Common); + + if ((pDevCommon == CBIOS_NULL) || (!(pDevCommon->DeviceType & CBIOS_TYPE_DVO))) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is invalid!\n", FUNCTION_NAME)); + return ; + } + + cb_FreePool(pDvoContext); + pDvoContext = CBIOS_NULL; + +} + +#endif + diff --git a/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDVO.h b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDVO.h new file mode 100644 index 0000000000000..4f01744f114f0 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/Port/CBiosDVO.h @@ -0,0 +1,73 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + + +/***************************************************************************** +** DESCRIPTION: +** DVO port interface function prototype and parameter definition. +** +** NOTE: +** The daughter card's function and parameter SHOULD be added to corresponding monitor file. +******************************************************************************/ + +#ifndef _CBIOS_DVO_H_ +#define _CBIOS_DVO_H_ + +#include "../CBiosDeviceShare.h" + +#define SUPPORTDVODEVICE TX_NONE + + +//Hardcode DVO SlaveAddress +#define VT1636_SLAVE_ADDRESS 0x80 +#define CH7301_SLAVE_ADDRESS 0xEC +#define VT1632_SLAVE_ADDRESS 0x10 +#define AD9389_SLAVE_ADDRESS 0x72 +#define CH7305_SLAVE_ADDRESS 0xEA + +typedef struct _TXRegType +{ + CBIOS_U8 index; + CBIOS_U8 mask; + CBIOS_U8 data; +}TXRegType, *PTXRegType; + +typedef enum TX_TYPE +{ + TX_NONE = 0, // No transmitter and without LCD function + TX_VT1636 = 0x01, + TX_CH7301C = 0x02, + TX_VT1632 = 0x04, + TX_AD9389B = 0x08, + TX_CH7305 = 0x10, +} TX_TYPE; + +typedef struct _DVO_CARD_ID_PARA +{ + TX_TYPE DVOCardType; + CBIOS_U8 DVOCardIDOffset; + CBIOS_U8 DVOCardIDValue; +} DVO_CARD_ID_PARA; + +typedef struct _CBIOS_DVO_CONTEXT +{ + CBIOS_DEVICE_COMMON Common; + CBIOS_DVO_DEV_CONFIG DVODevice; +}CBIOS_DVO_CONTEXT, *PCBIOS_DVO_CONTEXT; + +CBIOS_VOID cbDVOPort_GetSupportMonitorType(PCBIOS_VOID pvcbe, PCBIOS_MONITOR_TYPE pMonitorType); +PCBIOS_DEVICE_COMMON cbDVOPort_Init(PCBIOS_VOID pvcbe, PVCP_INFO pVCP, CBIOS_ACTIVE_TYPE DeviceType); +CBIOS_VOID cbDVOPort_DeInit(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon); +#endif diff --git a/drivers/gpu/drm/arise/cbios/Device/gcc_stdarg.h b/drivers/gpu/drm/arise/cbios/Device/gcc_stdarg.h new file mode 100644 index 0000000000000..39153e2d87f53 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Device/gcc_stdarg.h @@ -0,0 +1,129 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* + * ISO C Standard: 7.15 Variable arguments + */ + +#ifndef _STDARG_H +#ifndef _ANSI_STDARG_H_ +#ifndef __need___va_list +#define _STDARG_H +#define _ANSI_STDARG_H_ +#endif /* not __need___va_list */ +#undef __need___va_list + +/* Define __gnuc_va_list. */ + +#ifndef __GNUC_VA_LIST +#define __GNUC_VA_LIST +typedef __builtin_va_list __gnuc_va_list; +#endif + +/* Define the standard macros for the user, + if this invocation was from the user program. */ +#ifdef _STDARG_H + +#define va_start(v,l) __builtin_va_start(v,l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v,l) __builtin_va_arg(v,l) +#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L +#define va_copy(d,s) __builtin_va_copy(d,s) +#endif +#define __va_copy(d,s) __builtin_va_copy(d,s) + +/* Define va_list, if desired, from __gnuc_va_list. */ +/* We deliberately do not define va_list when called from + stdio.h, because ANSI C says that stdio.h is not supposed to define + va_list. stdio.h needs to have access to that data type, + but must not use that name. It should use the name __gnuc_va_list, + which is safe because it is reserved for the implementation. */ + +#ifdef _HIDDEN_VA_LIST /* On OSF1, this means varargs.h is "half-loaded". */ +#undef _VA_LIST +#endif + +#ifdef _BSD_VA_LIST +#undef _BSD_VA_LIST +#endif + +#if defined(__svr4__) || (defined(_SCO_DS) && !defined(__VA_LIST)) +/* SVR4.2 uses _VA_LIST for an internal alias for va_list, + so we must avoid testing it and setting it here. + SVR4 uses _VA_LIST as a flag in stdarg.h, but we should + have no conflict with that. */ +#ifndef _VA_LIST_ +#define _VA_LIST_ +#ifdef __i860__ +#ifndef _VA_LIST +#define _VA_LIST va_list +#endif +#endif /* __i860__ */ +typedef __gnuc_va_list va_list; +#ifdef _SCO_DS +#define __VA_LIST +#endif +#endif /* _VA_LIST_ */ +#else /* not __svr4__ || _SCO_DS */ + +/* The macro _VA_LIST_ is the same thing used by this file in Ultrix. + But on BSD NET2 we must not test or define or undef it. + (Note that the comments in NET 2's ansi.h + are incorrect for _VA_LIST_--see stdio.h!) */ +#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT) +/* The macro _VA_LIST_DEFINED is used in Windows NT 3.5 */ +#ifndef _VA_LIST_DEFINED +/* The macro _VA_LIST is used in SCO Unix 3.2. */ +#ifndef _VA_LIST +/* The macro _VA_LIST_T_H is used in the Bull dpx2 */ +#ifndef _VA_LIST_T_H +/* The macro __va_list__ is used by BeOS. */ +#ifndef __va_list__ +typedef __gnuc_va_list va_list; +#endif /* not __va_list__ */ +#endif /* not _VA_LIST_T_H */ +#endif /* not _VA_LIST */ +#endif /* not _VA_LIST_DEFINED */ +#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__)) +#define _VA_LIST_ +#endif +#ifndef _VA_LIST +#define _VA_LIST +#endif +#ifndef _VA_LIST_DEFINED +#define _VA_LIST_DEFINED +#endif +#ifndef _VA_LIST_T_H +#define _VA_LIST_T_H +#endif +#ifndef __va_list__ +#define __va_list__ +#endif + +#endif /* not _VA_LIST_, except on certain systems */ + +#endif /* not __svr4__ */ + +#endif /* _STDARG_H */ + +#endif /* not _ANSI_STDARG_H_ */ +#endif /* not _STDARG_H */ diff --git a/drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.c b/drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.c new file mode 100644 index 0000000000000..f1787bba3fe77 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.c @@ -0,0 +1,780 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios display manager functions. +** Mainly take charge of set mode, active devices and stream update. +** +** NOTE: +** The hw dependent function or structure SHOULD NOT be added to this file. +******************************************************************************/ + + +#include "CBiosDisplayManager.h" +#include "CBiosChipShare.h" + +static CBIOS_STATUS cbValidateSettingModeParam(PCBIOS_VOID pvcbe, PCBIOS_DISP_MODE_PARAMS pModeParams, PCBiosSettingModeParams pSettingModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS csRet = CBIOS_OK; + //CBIOS_U32 DispDev; + CBIOS_U32 IGAIndex = pSettingModeParams->IGAIndex; + CBiosSettingModeParams SetModePara; + CBIOS_SCALER_STATUS ScalerStatusToUse = DISABLE_SCALER; + CBIOS_BOOL bIsEnable3DVideo; + CBIOS_U16 HDMI3DStructure; + + //DispDev = pcbe->DispMgr.ActiveDevices[IGAIndex]; + + cb_memcpy(&(SetModePara.SourcModeParams), &(pSettingModeParams->SourcModeParams), sizeof(CBiosSourceModeParams)); + cb_memcpy(&(SetModePara.DestModeParams), &(pSettingModeParams->DestModeParams), sizeof(CBiosDestModeParams)); + cb_memcpy(&(SetModePara.ScalerSizeParams), &(pSettingModeParams->ScalerSizeParams), sizeof(CBiosScalerSizeParams)); + + + if ((SetModePara.SourcModeParams.XRes == 0) ||(SetModePara.SourcModeParams.YRes == 0) || + (SetModePara.DestModeParams.XRes == 0) ||(SetModePara.DestModeParams.YRes == 0) || + (SetModePara.ScalerSizeParams.XRes == 0) ||(SetModePara.ScalerSizeParams.YRes == 0) || + (SetModePara.DestModeParams.RefreshRate == 0)) + { + csRet = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbValidateSettingModeParam: Mode para is ZERO!\n")); + } + else if ((SetModePara.DestModeParams.XRes < SetModePara.ScalerSizeParams.XRes) + || (SetModePara.DestModeParams.YRes < SetModePara.ScalerSizeParams.YRes)) + { + //dest mode should always bigger than or equal to scaler size, otherwise we will see panning + csRet = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbValidateSettingModeParam: Dest mode is smaller than scaler size!\n")); + } + else if ((SetModePara.ScalerSizeParams.XRes == SetModePara.SourcModeParams.XRes) + && (SetModePara.ScalerSizeParams.YRes == SetModePara.SourcModeParams.YRes)) + { + //source mode equal to dest mode, do not need scaler + csRet = CBIOS_OK; + ScalerStatusToUse = DISABLE_SCALER; + } + else if (((SetModePara.ScalerSizeParams.XRes <= SetModePara.SourcModeParams.XRes) && + (SetModePara.ScalerSizeParams.YRes < SetModePara.SourcModeParams.YRes)) + || ((SetModePara.ScalerSizeParams.XRes < SetModePara.SourcModeParams.XRes) && + (SetModePara.ScalerSizeParams.YRes <= SetModePara.SourcModeParams.YRes))) + { + csRet = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbValidateSettingModeParam: Can't support downscaling!\n")); + } + else if (((SetModePara.ScalerSizeParams.XRes >= SetModePara.SourcModeParams.XRes)&& + (SetModePara.ScalerSizeParams.YRes > SetModePara.SourcModeParams.YRes)) + || ((SetModePara.ScalerSizeParams.XRes > SetModePara.SourcModeParams.XRes)&& + (SetModePara.ScalerSizeParams.YRes >= SetModePara.SourcModeParams.YRes))) + { + if ((SetModePara.SourcModeParams.XRes > pcbe->ChipLimits.ulMaxPUHorSrc) + || (SetModePara.SourcModeParams.YRes > pcbe->ChipLimits.ulMaxPUVerSrc) + || (SetModePara.ScalerSizeParams.XRes > pcbe->ChipLimits.ulMaxPUHorDst) + || (SetModePara.ScalerSizeParams.YRes > pcbe->ChipLimits.ulMaxPUVerDst) + || !pcbe->ChipCaps.IsSupportUpScaling) + { + csRet = CBIOS_ER_HARDWARE_LIMITATION; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbValidateSettingModeParam: Scaler size exceeds hardware limit!\n")); + } + else + { + //upscaling + csRet = CBIOS_OK; + ScalerStatusToUse = ENABLE_UPSCALER; + } + } + else + { + csRet = CBIOS_ER_HARDWARE_LIMITATION; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbValidateSettingModeParam: Invalid scaler size!\n")); + } + + // Validate if user specified timing is OK. + // Inorder to compatible with old driver, need to check struct size to avoid overflow to write. + if (pSettingModeParams->SpecifyTiming.Flag) + { + cb_memcpy(&pcbe->SpecifyDestTimingSrc[IGAIndex], &pSettingModeParams->SpecifyTiming, sizeof(CBiosSpecifyDstTimingSrc)); + } + else + { + cb_memset(&pcbe->SpecifyDestTimingSrc[IGAIndex], 0, sizeof(CBiosSpecifyDstTimingSrc)); + } + + // Validate 3D video + if (csRet == CBIOS_OK) + { + bIsEnable3DVideo = pSettingModeParams->Is3DVideoMode; + HDMI3DStructure = pSettingModeParams->Video3DStruct; + + if (bIsEnable3DVideo) + { + if ((!pcbe->ChipCaps.IsSupport3DVideo) && (HDMI3DStructure != 0)) + { + csRet = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbValidateSettingModeParam: Invalid 3D video parameter!\n")); + } + else if (ScalerStatusToUse != DISABLE_SCALER) + { + csRet = CBIOS_ER_HARDWARE_LIMITATION; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbValidateSettingModeParam: HW limitation, can't support PU/PD when enable 3D video!\n")); + } + else + { + csRet = CBIOS_OK; + } + } + else + { + csRet = CBIOS_OK; + } + } + + if (csRet == CBIOS_OK) + { + pModeParams->ScalerStatusToUse = ScalerStatusToUse; + pModeParams->IsEnable3DVideo = bIsEnable3DVideo; + pModeParams->IsSingleBuffer = pSettingModeParams->IsSingleBuffer; + pModeParams->Video3DStruct = pSettingModeParams->Video3DStruct; + } + + return csRet; +} + +#define cbGetDiff(a, b) ((a) > (b) ? (a - b) : (b - a)) + +static CBIOS_BOOL cbHDMIFormatTableSetRefRateIndex(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U16 RefRate, + CBIOS_U32 FormatIndex, + CBIOS_U8 *pIndex) +{ + CBIOS_BOOL bStatus = CBIOS_FALSE; + CBIOS_U32 Difference = 0; + CBIOS_U16 NearestRefRate = 0, LeftRefRate = 0, RightRefRate = 0; + + if (FormatIndex >= CBIOS_HDMIFORMATCOUNTS) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR),"cbHDMIFormatTableSetRefRateIndex: invalid format!\n")); + bStatus = CBIOS_FALSE; + } + else + { + LeftRefRate = pcbe->pHDMIFormatTable[FormatIndex].RefRate[1]; + RightRefRate = pcbe->pHDMIFormatTable[FormatIndex].RefRate[0]; + + if ((LeftRefRate == 0) || (RefRate > ((LeftRefRate + RightRefRate) / 2))) + { + NearestRefRate = RightRefRate; + } + else + { + NearestRefRate = LeftRefRate; + } + + Difference = cbGetDiff(RefRate, NearestRefRate); + + if ((Difference * 1000 / NearestRefRate) <= 5)//0.5% + { + *pIndex = (NearestRefRate == RightRefRate) ? 0 : 1; + + bStatus = CBIOS_TRUE; + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG),"cbHDMIFormatTableSetRefRateIndex: RefreshRate is invalid!\n")); + bStatus = CBIOS_FALSE; + } + } + + return bStatus; +} + +static CBIOS_VOID cbDetermineModeVICCode(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams, CBIOS_U32 IGAIndex) +{ + PCBIOS_MODE_TARGET_PARA pTargetModePara = CBIOS_NULL; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_U8 RefRateIndex = 0; + CBIOS_U32 Device = 0, i = 0; + CBIOS_BOOL bHDMIDevice = CBIOS_FALSE; + + Device = cbDevGetPrimaryDevice((CBIOS_U32)pcbe->DispMgr.ActiveDevices[IGAIndex]); + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + bHDMIDevice = pDevCommon->EdidStruct.Attribute.IsCEA861HDMI; + + if(bHDMIDevice) + { + pModeParams->VICCode = 0; + pTargetModePara = &(pModeParams->TargetModePara); + for(i = 0; i < CBIOS_HDMI_NORMAL_VIC_COUNTS; i++) + { + if((pTargetModePara->XRes == pcbe->pHDMIFormatTable[i].XRes) && + (pTargetModePara->YRes == pcbe->pHDMIFormatTable[i].YRes) && + (pTargetModePara->bInterlace == (CBIOS_BOOL)pcbe->pHDMIFormatTable[i].Interlace)) + { + //check refresh rate + if (cbHDMIFormatTableSetRefRateIndex(pcbe, (CBIOS_U16)pTargetModePara->RefRate, i, &RefRateIndex)) + { + //check aspect ratio + if ((pTargetModePara->AspectRatioFlag == 0) || + (pTargetModePara->AspectRatioFlag == pcbe->pHDMIFormatTable[i].AspectRatio)) + { + pModeParams->VICCode = (CBIOS_U8)pcbe->pHDMIFormatTable[i].FormatNum; + break; + } + } + } + } + + if (pDevCommon->EdidStruct.Attribute.VSDBData.HDMIVICLen > 0) + { + for(i = CBIOS_HDMI_NORMAL_VIC_COUNTS; i < CBIOS_HDMIFORMATCOUNTS; i++) + { + if((pTargetModePara->XRes == pcbe->pHDMIFormatTable[i].XRes) && + (pTargetModePara->YRes == pcbe->pHDMIFormatTable[i].YRes) && + (pTargetModePara->bInterlace== (CBIOS_BOOL)pcbe->pHDMIFormatTable[i].Interlace) && + pDevCommon->EdidStruct.HDMIFormat[i].IsSupported) + { + //check refresh rate + if (cbHDMIFormatTableSetRefRateIndex(pcbe, (CBIOS_U16)pTargetModePara->RefRate, i, &RefRateIndex)) + { + //check aspect ratio + if ((pTargetModePara->AspectRatioFlag == 0) || + (pTargetModePara->AspectRatioFlag == pcbe->pHDMIFormatTable[i].AspectRatio)) + { + pModeParams->VICCode = (CBIOS_U8)pcbe->pHDMIFormatTable[i].FormatNum; + break; + } + } + } + } + } + } +} + + +static CBIOS_VOID cb3DVideoTimingAdjust(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_3D_STRUCTURE Video3DStruct, PCBIOS_TIMING_ATTRIB pTiming) +{ + switch (Video3DStruct) + { + case FRAME_PACKING: + case L_DEPTH: + pTiming->PixelClock *= 2; + break; + case LINE_ALTERNATIVE: + pTiming->PixelClock *= 2; + pTiming->VerTotal *= 2; + pTiming->VerDisEnd *= 2; + pTiming->VerBStart *= 2; + pTiming->VerBEnd*= 2; + pTiming->VerSyncStart *= 2; + pTiming->VerSyncEnd *= 2; + break; + case SIDE_BY_SIDE_FULL: + pTiming->PixelClock *= 2; + pTiming->HorDisEnd *= 2; + pTiming->HorBStart *= 2; + pTiming->HorBEnd *= 2; + pTiming->HorSyncStart *= 2; + pTiming->HorSyncEnd *= 2; + break; + case SIDE_BY_SIDE_HALF: + case TOP_AND_BOTTOM: + default: + break; + } +} + +static CBIOS_STATUS cbUpdateIGAModeInfo(PCBIOS_VOID pvcbe, PCBIOS_DISP_MODE_PARAMS pModeParams, PCBiosSettingModeParams pSettingModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 IGAIndex = pSettingModeParams->IGAIndex; + CBIOS_TIMING_ATTRIB Timing = {0}; + CBIOS_U32 Device = 0; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttr = CBIOS_NULL; + + Device = pcbe->DispMgr.ActiveDevices[IGAIndex]; + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + pMonitorAttr = &(pDevCommon->EdidStruct.Attribute); + + //check bpc + if ((pcbe->ChipCaps.IsSupportDeepColor) && (pMonitorAttr->IsCEA861HDMI)) + { + pModeParams->BitPerComponent = pSettingModeParams->BitPerComponent; + } + else + { + //do not support deep color + pModeParams->BitPerComponent = 8; + } + + pModeParams->IGAIndex = pSettingModeParams->IGAIndex; + + pModeParams->SrcModePara.XRes = pSettingModeParams->SourcModeParams.XRes; + pModeParams->SrcModePara.YRes = pSettingModeParams->SourcModeParams.YRes; + + pModeParams->TargetModePara.XRes = pSettingModeParams->DestModeParams.XRes; + pModeParams->TargetModePara.YRes = pSettingModeParams->DestModeParams.YRes; + + pModeParams->ScalerPara.XRes = pSettingModeParams->ScalerSizeParams.XRes; + pModeParams->ScalerPara.YRes = pSettingModeParams->ScalerSizeParams.YRes; + + // Update refresh rate setting + if(pSettingModeParams->DestModeParams.RefreshRate == 1) + { + pModeParams->TargetModePara.RefRate = 6000; + } + else if(pSettingModeParams->DestModeParams.RefreshRate != 0) + { + pModeParams->TargetModePara.RefRate = pSettingModeParams->DestModeParams.RefreshRate; + } + + pModeParams->TargetModePara.bInterlace = pSettingModeParams->DestModeParams.InterlaceFlag; + pModeParams->TargetModePara.AspectRatioFlag = pSettingModeParams->DestModeParams.AspectRatioFlag; + if (pSettingModeParams->DestModeParams.OutputSignal) + { + pModeParams->TargetModePara.OutputSignal = pSettingModeParams->DestModeParams.OutputSignal; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "no output signal type assigned, default to RGB\n")); + pModeParams->TargetModePara.OutputSignal = CBIOS_RGBOUTPUT; + } + + pModeParams->IGAOutColorSpace = CSC_FMT_RGB;//hardcode IGA output color space to RGB + + pModeParams->TargetModePara.DevInColorSpace = pModeParams->IGAOutColorSpace; + + cbDetermineModeVICCode(pcbe, pModeParams, IGAIndex); + + if(pModeParams->VICCode != 0)//convert output signal to YCbCr420 for 420 only mode + { + if(pDevCommon->EdidStruct.HDMIFormat[pModeParams->VICCode - 1].IsSupportYCbCr420 && + !pDevCommon->EdidStruct.HDMIFormat[pModeParams->VICCode - 1].IsSupportOtherFormats) + { + pModeParams->TargetModePara.OutputSignal = CBIOS_YCBCR420OUTPUT; + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "convert output signal to YCbCr420 as %s only support YCbCr420 for %d x %d @ %d\n", + pMonitorAttr->MonitorName, pSettingModeParams->DestModeParams.XRes, pSettingModeParams->DestModeParams.YRes, + pSettingModeParams->DestModeParams.RefreshRate)); + } + } + + cb_memcpy(&pModeParams->ColorimetryCaps, &pMonitorAttr->ExtDataBlock[COLORIMETRY_DATA_BLOCK_TAG].ColorimetryData, + sizeof(CBIOS_COLORIMETRY_DATA)); + cb_memcpy(&pModeParams->VideoCapability, &pMonitorAttr->ExtDataBlock[VIDEO_CAPABILITY_DATA_BLOCK_TAG].VideoCapabilityData, + sizeof(CBIOS_VIDEO_CAPABILITY_DATA)); + + cbMode_GetHVTiming(pcbe, + pModeParams->TargetModePara.XRes, + pModeParams->TargetModePara.YRes, + pModeParams->TargetModePara.RefRate, + pModeParams->TargetModePara.bInterlace, + Device, + &Timing); + //pcbe->SpecifyDestTimingSrc[IGAIndex].Flag = 0; + + if (pModeParams->IsEnable3DVideo) + { + cb3DVideoTimingAdjust(pcbe, pModeParams->Video3DStruct, &Timing); + } + + //check pixel repetition + pModeParams->PixelRepitition = 1; + if(((pModeParams->TargetModePara.bInterlace) && ((Timing.YRes == 576) || (Timing.YRes == 480))) + || (!(pModeParams->TargetModePara.bInterlace) && ((Timing.YRes == 288) || (Timing.YRes == 240)))) + { + pModeParams->PixelRepitition = 2; + } + + Timing.PLLClock = Timing.PixelClock; + + cb_memcpy(&(pModeParams->TargetTiming), &Timing, sizeof(CBIOS_TIMING_ATTRIB)); + + return CBIOS_OK; +} + + +static CBIOS_STATUS cbDispMgrPrepareToSetMode(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DEVICE_MANAGER pDevMgr, + PCBIOS_DISPLAY_MANAGER pDispMgr, PCBiosSettingModeParams pSettingModeParams) +{ + CBIOS_U32 IGAIndex = pSettingModeParams->IGAIndex; + CBIOS_ACTIVE_TYPE Device = pDispMgr->ActiveDevices[IGAIndex]; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(pDevMgr, Device); + PCBIOS_DISP_MODE_PARAMS pModeParams = pDispMgr->pModeParams[IGAIndex]; + CBIOS_STATUS csRet = CBIOS_OK; + PCBIOS_MONITOR_MISC_ATTRIB pAttribute = &pDevCommon->EdidStruct.Attribute; + CBIOS_BOOL bForceHDTV = CBIOS_FALSE; + + if(pSettingModeParams->SkipIgaMode == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "SourceMode: %d x %d!\n", pSettingModeParams->SourcModeParams.XRes, pSettingModeParams->SourcModeParams.YRes)); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "DestMode: %d x %d @ %d!\n", pSettingModeParams->DestModeParams.XRes, pSettingModeParams->DestModeParams.YRes, + pSettingModeParams->DestModeParams.RefreshRate)); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "ScalerMode: %d x %d!\n", pSettingModeParams->ScalerSizeParams.XRes, pSettingModeParams->ScalerSizeParams.YRes)); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Interlace=%d, Signal=%d, AsRatio=%d, Bpc=%d!\n", pSettingModeParams->DestModeParams.InterlaceFlag, + pSettingModeParams->DestModeParams.OutputSignal, pSettingModeParams->DestModeParams.AspectRatioFlag, pSettingModeParams->BitPerComponent)); + } + + // Validate the input parameter. + csRet = cbValidateSettingModeParam(pcbe, pModeParams, pSettingModeParams); + if (csRet != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: mode parameters are invalid!\n", FUNCTION_NAME)); + return csRet; + } + + cbUpdateIGAModeInfo(pcbe, pModeParams, pSettingModeParams); + // patch for a handwriting screen's 800x1280 mode(HBack=20). when HBack is smaller 24, HDisEnd and HBack is not right. So use HDTV module. + if (!cb_memcmp(pAttribute->MonitorName, "HDMI", 5) + && !cb_memcmp(pAttribute->ManufactureName, "\xff\xff", 2) + && (pModeParams->TargetTiming.XRes == 800) + && (pModeParams->TargetTiming.YRes == 1280) + && (pModeParams->TargetTiming.HorBEnd - pModeParams->TargetTiming.HorSyncEnd == 20)) + { + bForceHDTV = CBIOS_TRUE; + } + cbPathMgrSelectDIUPath(pcbe, pDevCommon->DeviceType, pModeParams->IGAIndex, &pSettingModeParams->DestModeParams, bForceHDTV); + + cbDevUpdateDeviceModeInfo(pcbe, pDevCommon, pModeParams); + + return csRet; +} + +static CBIOS_U32 cbDispMgrGetIgaCnt(PCBIOS_EXTENSION_COMMON pcbe) +{ + CBIOS_U32 Count = 0; + + switch(pcbe->ChipID) + { + case CHIPID_ARISE1040: + case CHIPID_ARISE1010: + Count = 2; + break; + case CHIPID_ARISE1020: + Count = (pcbe->FeatureSwitch.bNonSimulChip)? 2 : 4; + break; + case CHIPID_ARISE2030: + case CHIPID_ARISE2020: + Count = 3; + break; + case CHIPID_E3K: + case CHIPID_ARISE10C0T: + Count = 4; + break; + default: + Count = 2; + break; + } + + return Count; +} + +CBIOS_STATUS cbDispMgrInit(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DISPLAY_MANAGER pDispMgr = &(pcbe->DispMgr); + CBIOS_U32 i = 0, j = 0; + + pDispMgr->IgaCount = cbDispMgrGetIgaCnt(pcbe); + + for (i = IGA1; i < pDispMgr->IgaCount; i++) + { + pDispMgr->ActiveDevices[i] = CBIOS_TYPE_NONE; + pDispMgr->pModeParams[i] = cb_AllocateNonpagedPool(sizeof(CBIOS_DISP_MODE_PARAMS)); + if(pDispMgr->pModeParams[i] == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: pModeParams for IGA%d allocate error!\n", FUNCTION_NAME, i)); + goto Fail; + } + + pDispMgr->pModeParams[i]->IGAIndex = i; + + pDispMgr->IgaUpScale = (pcbe->ChipCaps.IsSupportUpScaling)? 1 : 0; + + pDispMgr->IgaDownScale = 0; + + pDispMgr->StreamCount[i] = STREAM_NUM_E3K; + + for(j = 0; j < pDispMgr->StreamCount[i]; j++) + { + pDispMgr->DownScaleStreamMask[i] |= 0; + pDispMgr->UpScaleStreamMask[i] |= (1 << j); + } + } + + return CBIOS_OK; + +Fail: + + for (i = IGA1; i < pDispMgr->IgaCount; i++) + { + if(pDispMgr->pModeParams[i]) + { + cb_FreePool(pDispMgr->pModeParams[i]); + pDispMgr->pModeParams[i] = CBIOS_NULL; + } + } + + return CBIOS_ER_NO_ENOUGH_MEM; +} + + +CBIOS_STATUS cbDispMgrGetActiveDevice(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr, PCIP_ACTIVE_DEVICES pActiveDevices) +{ + CBIOS_STATUS status = CBIOS_ER_INVALID_PARAMETER; + CBIOS_U32 i = 0; + + if(pDispMgr) + { + for (i = IGA1; i < pDispMgr->IgaCount; i++) + { + pActiveDevices->DeviceId[i] = pDispMgr->ActiveDevices[i]; + status = CBIOS_OK; + } + } + + return status; +} + + +CBIOS_STATUS cbDispMgrSetActiveDevice(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr, PCIP_ACTIVE_DEVICES pActiveDevices) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 i = 0; + + cbTraceEnter(GENERIC); + + for (i = IGA1; i < pDispMgr->IgaCount; i++) + { + pDispMgr->ActiveDevices[i] = pActiveDevices->DeviceId[i]; + } + + // If Both IGA device equal zero, we should not update register value. + // Or else, VBIOS will have no device to light. + if((pDispMgr->ActiveDevices[IGA1] != 0) || (pDispMgr->ActiveDevices[IGA2] != 0) || \ + (pDispMgr->ActiveDevices[IGA3] != 0) || (pDispMgr->ActiveDevices[IGA4] != 0)) + { + // Update the CR6b and CR6C register for compatible with VBIOS, and for Dos full screen. + cbHwUpdateActDeviceToReg(pcbe, pDispMgr); + } + + cbTraceExit(GENERIC); + + return Status; +} + + +CBIOS_STATUS cbDispMgrGetMode(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr, PCBiosSettingModeParams pModeParams) +{ + CBIOS_U32 IGAIndex = pModeParams->IGAIndex; + PCBIOS_DISP_MODE_PARAMS pDispModeParams = pDispMgr->pModeParams[IGAIndex]; + //source mode + pModeParams->SourcModeParams.XRes = pDispModeParams->SrcModePara.XRes; + pModeParams->SourcModeParams.YRes = pDispModeParams->SrcModePara.YRes; + //target mode + pModeParams->DestModeParams.XRes = pDispModeParams->TargetModePara.XRes; + pModeParams->DestModeParams.YRes = pDispModeParams->TargetModePara.YRes; + pModeParams->DestModeParams.RefreshRate = pDispModeParams->TargetModePara.RefRate; + pModeParams->DestModeParams.OutputSignal = pDispModeParams->TargetModePara.OutputSignal; + pModeParams->DestModeParams.InterlaceFlag = pDispModeParams->TargetModePara.bInterlace; + pModeParams->DestModeParams.AspectRatioFlag = pDispModeParams->TargetModePara.AspectRatioFlag; + //scaler size + pModeParams->ScalerSizeParams.XRes = pDispModeParams->ScalerPara.XRes; + pModeParams->ScalerSizeParams.YRes = pDispModeParams->ScalerPara.YRes; + + return CBIOS_OK; +} + +CBIOS_STATUS cbDispMgrGetHwCounter(PCBIOS_VOID pvcbe, PCBIOS_GET_HW_COUNTER pGetCounter) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + return cbHwGetCounter(pcbe, pGetCounter); +} + +CBIOS_STATUS cbDispMgrGetModeFromReg(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr, PCBiosSettingModeParams pModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 IGAIndex = pModeParams->IGAIndex; + CBIOS_ACTIVE_TYPE ActiveDevice = pDispMgr->ActiveDevices[IGAIndex]; + CBIOS_TIMING_ATTRIB SourceTimingAttr = {0}; + CBIOS_TIMING_ATTRIB TargetTimingAttr = {0}; + CBIOS_TIMING_FLAGS Flags = {0}; + + cbGetModeInfoFromReg(pcbe, ActiveDevice, &SourceTimingAttr, &Flags, IGAIndex, TIMING_REG_TYPE_CR); + cbGetModeInfoFromReg(pcbe, ActiveDevice, &TargetTimingAttr, &Flags, IGAIndex, TIMING_REG_TYPE_SR); + + //source mode + pModeParams->SourcModeParams.XRes = SourceTimingAttr.XRes; + pModeParams->SourcModeParams.YRes = SourceTimingAttr.YRes; + //target mode + pModeParams->DestModeParams.XRes = TargetTimingAttr.XRes; + pModeParams->DestModeParams.YRes = TargetTimingAttr.YRes; + pModeParams->DestModeParams.RefreshRate = TargetTimingAttr.RefreshRate; + pModeParams->DestModeParams.InterlaceFlag = Flags.IsInterlace; + //scaler size + pModeParams->ScalerSizeParams.XRes = TargetTimingAttr.XRes; + pModeParams->ScalerSizeParams.YRes = TargetTimingAttr.YRes; + + return CBIOS_OK; +} + +CBIOS_STATUS cbDispMgrSetMode(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_MANAGER pDevMgr, PCBIOS_DISPLAY_MANAGER pDispMgr, PCBiosSettingModeParams pSettingModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS csRet = CBIOS_OK; + CBIOS_U32 IGAIndex = pSettingModeParams->IGAIndex; + CBIOS_ACTIVE_TYPE Device = pDispMgr->ActiveDevices[IGAIndex]; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(pDevMgr, Device); + PCBIOS_DISP_MODE_PARAMS pModeParams = pDispMgr->pModeParams[IGAIndex]; + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + return CBIOS_ER_CHIPDISABLE; +#endif + + cbTraceEnter(GENERIC); + + if(!Device || !pDevCommon) + { + return CBIOS_ER_OPERATION_ON_NONE_DEVICE; + } + + csRet = cbDispMgrPrepareToSetMode(pcbe, pDevMgr, pDispMgr, pSettingModeParams); + if (csRet != CBIOS_OK) + { + return csRet; + } + + if(!pSettingModeParams->SkipIgaMode) + { + cbHwSetModeToIGA(pcbe, pModeParams); + } + + if(!pSettingModeParams->SkipDeviceMode) + { + cbDevSetModeToDevice(pcbe, pDevCommon, pModeParams); + } + + cbTraceExit(GENERIC); + return csRet; +} + +CBIOS_STATUS cbDispMgrGetDispResource(PCBIOS_VOID pvcbe, PCBIOS_GET_DISP_RESOURCE pGetDispRes) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DISPLAY_MANAGER pDispMgr = &pcbe->DispMgr; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 i = 0; + + pGetDispRes->CrtcNum = pDispMgr->IgaCount; + + for(i = 0; i < pGetDispRes->CrtcNum; i++) + { + pGetDispRes->PlaneNum[i] = pDispMgr->StreamCount[i]; + } + + return Status; +} + +CBIOS_STATUS cbDispMgrGetDisplayCaps(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_CAPS pDispCaps) +{ + CBIOS_STATUS Status = CBIOS_OK; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DISPLAY_MANAGER pDispMgr = &pcbe->DispMgr; + CBIOS_U32 i = 0; + + pDispCaps->SuppCrtcUpScale = pDispMgr->IgaUpScale; + pDispCaps->SuppCrtcDownScale = pDispMgr->IgaDownScale; + + if(pDispCaps->pUpScalePlaneMask) + { + for(i = 0; i < pDispMgr->IgaCount; i++) + { + pDispCaps->pUpScalePlaneMask[i] = pDispMgr->UpScaleStreamMask[i]; + } + } + + if(pDispCaps->pDownScalePlaneMask) + { + for(i = 0; i < pDispMgr->IgaCount; i++) + { + pDispCaps->pDownScalePlaneMask[i] = pDispMgr->DownScaleStreamMask[i]; + } + } + return Status; +} + +CBIOS_STATUS cbDispMgrUpdateFrame(PCBIOS_VOID pvcbe, PCBIOS_UPDATE_FRAME_PARA pUpdateFrame) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + return cbUpdateFrame(pcbe, pUpdateFrame); +} + +CBIOS_STATUS cbDispMgrDoCSCAdjust(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr, PCBIOS_CSC_ADJUST_PARA pCSCAdjustPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 IGAIndex = pCSCAdjustPara->IGAIndex; + CBIOS_ACTIVE_TYPE Device = pDispMgr->ActiveDevices[IGAIndex]; + + return cbDoCSCAdjust(pcbe, Device, pCSCAdjustPara); +} + +CBIOS_STATUS cbDispMgrAdjustStreamCSC(PCBIOS_VOID pvcbe, PCBIOS_STREAM_CSC_PARA pCSCAdjustPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + return cbAdjustStreamCSC(pcbe, pCSCAdjustPara); +} + +CBIOS_STATUS cbDispMgrCheckSurfaceOnDisplay(PCBIOS_VOID pvcbe, PCBIOS_CHECK_SURFACE_ON_DISP pChkSurfacePara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + return cbCheckSurfaceOnDisplay(pcbe, pChkSurfacePara); +} + +CBIOS_STATUS cbDispMgrGetDispAddr(PCBIOS_VOID pvcbe, PCBIOS_GET_DISP_ADDR pGetDispAddr) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + return cbGetDispAddr(pcbe, pGetDispAddr); +} + +CBIOS_STATUS cbDispMgrSetHwCursor(PCBIOS_VOID pvcbe, PCBIOS_CURSOR_PARA pSetCursor) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + return cbSetHwCursor(pcbe, pSetCursor); +} + +CBIOS_STATUS cbDispMgrDeInit(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DISPLAY_MANAGER pDispMgr = &(pcbe->DispMgr); + CBIOS_U32 i = 0; + + for (i = IGA1; i < pDispMgr->IgaCount; i++) + { + if(pDispMgr->pModeParams[i]) + { + cb_FreePool(pDispMgr->pModeParams[i]); + pDispMgr->pModeParams[i] = CBIOS_NULL; + } + } + + return CBIOS_OK; +} diff --git a/drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.h b/drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.h new file mode 100644 index 0000000000000..a6187badce427 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.h @@ -0,0 +1,142 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios display manager interface prototype and parameter define. +** +** NOTE: +** The hw dependent function or structure SHOULD NOT be added to this file. +******************************************************************************/ + +#ifndef _CBIOS_DISPLAY_MANAGER_H_ +#define _CBIOS_DISPLAY_MANAGER_H_ + +#include "../Device/CBiosDeviceShare.h" + +#define CBIOS_STREAM_16BPP_FMTS (CBIOS_FMT_R5G6B5 | CBIOS_FMT_A1R5G5B5 | CBIOS_FMT_CRYCBY422_16BIT | CBIOS_FMT_YCRYCB422_16BIT) + +#define CBIOS_STREAM_32BPP_FMTS (CBIOS_FMT_A8R8G8B8 | CBIOS_FMT_A8B8G8R8 | \ + CBIOS_FMT_A2R10G10B10 | CBIOS_FMT_A2B10G10R10 | \ + CBIOS_FMT_CRYCBY422_32BIT | CBIOS_FMT_YCRYCB422_32BIT | \ + CBIOS_FMT_YCBCR8888_32BIT | CBIOS_FMT_YCBCR2101010_32BIT) + +#define CBIOS_STREAM_FMT_YUV_SPACE (CBIOS_FMT_CRYCBY422_32BIT | CBIOS_FMT_YCRYCB422_32BIT | \ + CBIOS_FMT_YCBCR8888_32BIT | CBIOS_FMT_YCBCR2101010_32BIT | \ + CBIOS_FMT_CRYCBY422_16BIT | CBIOS_FMT_YCRYCB422_16BIT | \ + CBIOS_FMT_CRYCB8888_32BIT | CBIOS_FMT_CRYCB2101010_32BIT) + +typedef enum _CBIOS_TIMING_REG_TYPE { + TIMING_REG_TYPE_CR = 0, + TIMING_REG_TYPE_SR, + TIMING_REG_TYPE_MMIO, +} CBIOS_TIMING_REG_TYPE; + +typedef struct _CBIOS_MODE_SRC_PARA{ + CBIOS_U32 XRes; + CBIOS_U32 YRes; +}CBIOS_MODE_SRC_PARA, *PCBIOS_MODE_SRC_PARA; + +typedef struct _CBIOS_MODE_TARGET_PARA{ + CBIOS_U32 XRes; + CBIOS_U32 YRes; + CBIOS_U32 RefRate; + CBIOS_U32 bInterlace; /* =0, Set noninterlace mode; = 1, Set interlace mode; */ + CBIOS_U32 AspectRatioFlag; /* =0, Default aspect ratio */ + /* =1, 4:3 aspect ratio*/ + /* =2, 16:9 aspect ratio */ + CSC_FORMAT DevInColorSpace; /* device csc input color sapce*/ + CBIOS_U32 OutputSignal; /* =0x1; RGB signal */ + /* =0x2; YCbCr422 signal */ + /* =0x4; YCbCr444 signal */ + /* DP device will also use this attribute, and is called Color format */ +}CBIOS_MODE_TARGET_PARA, *PCBIOS_MODE_TARGET_PARA; + +typedef struct _CBIOS_MODE_SCALER_PARA{ + CBIOS_U32 XRes; + CBIOS_U32 YRes; +}CBIOS_MODE_SCALER_PARA, *PCBIOS_MODE_SCALER_PARA; + +typedef enum _CBIOS_SCALER_STATUS +{ + DISABLE_SCALER = 0, + ENABLE_UPSCALER, + ENABLE_DOWNSCALER, + INVALID_SCALER_SETTING +}CBIOS_SCALER_STATUS; + +typedef struct _CBIOS_DISP_MODE_PARAMS +{ + CBIOS_U32 IGAIndex; + CBIOS_MODE_SRC_PARA SrcModePara; + CBIOS_MODE_TARGET_PARA TargetModePara; + CBIOS_MODE_SCALER_PARA ScalerPara; + CBIOS_SCALER_STATUS ScalerStatusToUse; + CBIOS_TIMING_ATTRIB TargetTiming; + CSC_FORMAT IGAOutColorSpace; + struct + { + CBIOS_U32 IsEnable3DVideo :1; // = 1: enable 3D video, = 0: normal 2D mode + CBIOS_U32 IsxvYCC :1; + CBIOS_U32 IsAdobe :1; + CBIOS_U32 IsBT2020 :1; + CBIOS_U32 IsSingleBuffer :1; /* = 1: 3D video data is in a single buffer; =0: 3D video data is in separate two buffers */ + CBIOS_U32 IsEnable3DOSDDisparity :1; // = 1: 3D OSD Disparity data present + CBIOS_U32 IsEnable3DDualView :1; + CBIOS_U32 IsEnable3DIndependentView :1; + CBIOS_U32 Reserved :24; // Reserved for futrue use + }; + + //for HDMI + CBIOS_3D_STRUCTURE Video3DStruct; + CBIOS_3D_DISPARITY_PARA Video3DDisparity; + CBIOS_3D_INDEPENDENT_VIEW Viedo3DIndependentCaps; + CBIOS_U8 VICCode; + CBIOS_U8 PixelRepitition; + CBIOS_U32 BitPerComponent; + CBIOS_COLORIMETRY_DATA ColorimetryCaps; + CBIOS_VIDEO_CAPABILITY_DATA VideoCapability; +}CBIOS_DISP_MODE_PARAMS, *PCBIOS_DISP_MODE_PARAMS; + +typedef struct _CBIOS_DISPLAY_MANAGER +{ + CBIOS_U32 IgaCount; + CBIOS_U32 IgaUpScale; + CBIOS_U32 IgaDownScale; + CBIOS_U32 StreamCount[CBIOS_IGACOUNTS]; + CBIOS_U32 UpScaleStreamMask[CBIOS_IGACOUNTS]; + CBIOS_U32 DownScaleStreamMask[CBIOS_IGACOUNTS]; + CBIOS_ACTIVE_TYPE ActiveDevices[CBIOS_IGACOUNTS]; + PCBIOS_DISP_MODE_PARAMS pModeParams[CBIOS_IGACOUNTS]; +}CBIOS_DISPLAY_MANAGER, *PCBIOS_DISPLAY_MANAGER; + +CBIOS_STATUS cbDispMgrInit(PCBIOS_VOID pvcbe); +CBIOS_STATUS cbDispMgrGetActiveDevice(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr, PCIP_ACTIVE_DEVICES pActiveDevices); +CBIOS_STATUS cbDispMgrSetActiveDevice(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr, PCIP_ACTIVE_DEVICES pActiveDevices); +CBIOS_STATUS cbDispMgrGetMode(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr, PCBiosSettingModeParams pModeParams); +CBIOS_STATUS cbDispMgrGetHwCounter(PCBIOS_VOID pvcbe, PCBIOS_GET_HW_COUNTER pGetCounter); +CBIOS_STATUS cbDispMgrGetModeFromReg(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr, PCBiosSettingModeParams pModeParams); +CBIOS_STATUS cbDispMgrSetMode(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_MANAGER pDevMgr, PCBIOS_DISPLAY_MANAGER pDispMgr, PCBiosSettingModeParams pSettingModeParams); +CBIOS_STATUS cbDispMgrGetDispResource(PCBIOS_VOID pvcbe, PCBIOS_GET_DISP_RESOURCE pGetDispRes); +CBIOS_STATUS cbDispMgrGetDisplayCaps(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_CAPS pDispCaps); +CBIOS_STATUS cbDispMgrUpdateFrame(PCBIOS_VOID pvcbe, PCBIOS_UPDATE_FRAME_PARA pUpdateFrame); +CBIOS_STATUS cbDispMgrDoCSCAdjust(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr, PCBIOS_CSC_ADJUST_PARA pCSCAdjustPara); +CBIOS_STATUS cbDispMgrAdjustStreamCSC(PCBIOS_VOID pvcbe, PCBIOS_STREAM_CSC_PARA pCSCAdjustPara); +CBIOS_STATUS cbDispMgrCheckSurfaceOnDisplay(PCBIOS_VOID pvcbe, PCBIOS_CHECK_SURFACE_ON_DISP pChkSurfacePara); +CBIOS_STATUS cbDispMgrGetDispAddr(PCBIOS_VOID pvcbe, PCBIOS_GET_DISP_ADDR pGetDispAddr); +CBIOS_STATUS cbDispMgrSetHwCursor(PCBIOS_VOID pvcbe, PCBIOS_CURSOR_PARA pSetCursor); +CBIOS_STATUS cbDispMgrDeInit(PCBIOS_VOID pvcbe); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Display/CBiosMode.c b/drivers/gpu/drm/arise/cbios/Display/CBiosMode.c new file mode 100644 index 0000000000000..d8be23b67a230 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Display/CBiosMode.c @@ -0,0 +1,6148 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios mode related functions. Generate mode list from EDID data. Search timing from EDID and +** timing table. +** +** NOTE: +** The hw dependent function or structure SHOULD NOT be added to this file. +******************************************************************************/ + +#include "CBiosChipShare.h" + +#define MODE_COLOR_DEPTH_CAPS CBIOS_COLORDEPTH8 | CBIOS_COLORDEPTH16 | CBIOS_COLORDEPTH32XRGB | \ + CBIOS_COLORDEPTH32ARGB | CBIOS_COLORDEPTH32ABGR | CBIOS_COLORDEPTH2101010ARGB | \ + CBIOS_COLORDEPTH2101010ABGR | CBIOS_COLORDEPTH16161616ABGRF +#define MODE_INFO_EXT_SIZE sizeof(CBiosModeInfoExt) +#define TIMING_ATTRIB_SIZE sizeof(CBIOS_TIMING_ATTRIB) + +CBIOS_U8 KortekMonitorID[MONITORIDLENGTH] = +{ + 0x2E, 0x8C, 0x19, 0x00 +}; + +static CBIOS_BOOL EstModeSupportTbl[] = { + CBIOS_TRUE, // EDID23h[0]: 800x600@60Hz + CBIOS_FALSE, // EDID23h[1]: 800x600@56Hz + CBIOS_TRUE, // EDID23h[2]: 640x480@75Hz + CBIOS_TRUE, // EDID23h[3]: 640x480@72Hz + CBIOS_FALSE, // EDID23h[4]: 640x480@67Hz + CBIOS_TRUE, // EDID23h[5]: 640x480@60Hz + CBIOS_FALSE, // EDID23h[6]: 720x400@88Hz + CBIOS_FALSE, // EDID23h[7]: 720x400@70Hz + CBIOS_TRUE, // EDID24h[0]: 1280x1024@75Hz + CBIOS_TRUE, // EDID24h[1]: 1024x768@75Hz + CBIOS_TRUE, // EDID24h[2]: 1024x768@70Hz + CBIOS_TRUE, // EDID24h[3]: 1024x768@60Hz + CBIOS_FALSE, // EDID24h[4]: 1024x768@87HzInterlace + CBIOS_FALSE, // EDID24h[5]: 832x624@75Hz + CBIOS_TRUE, // EDID24h[6]: 800x600@75Hz + CBIOS_TRUE, // EDID24h[7]: 800x600@72Hz + CBIOS_FALSE, // EDID25h[7]: 1152x870@75Hz +}; + + +// This table is for new CBIOS setting mode logic. +// When add item to this table, must notice: +// 1. Can't repeat the item in current table. +// 2. Must stored by sort. +static CBIOS_TIMING_ATTRIB AdapterTimingTbl[] = +{ +{ + TIMING_ATTRIB_SIZE, + 0, + 640,350, + 8500, + 315000, + 0, + VerNEGATIVE + HorPOSITIVE, + 832, /*Hor Total Time*/ + 640, /*Hor Display End*/ + 640, /*Hor Blank Start*/ + 640 + 192, /*Hor Blank End*/ + 640 + 32, /*Hor Sync Start*/ + 640 + 32 + 64, /*Hor Sync End*/ + 445, /*Ver Total Time*/ + 350, /*Ver Display End*/ + 350, /*Ver Blank Start*/ + 350 + 95, /*Ver Blank End*/ + 350 + 32, /*Ver Sync Start*/ + 350 + 32 + 3, /*Ver Sync End*/ +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 640,400, + 8500, + 315000, + 0, + VerPOSITIVE + HorNEGATIVE, + 832, + 640, + 640, + 640 + 192, + 640 + 32, + 640 + 32 + 64, + 445, + 400, + 400, + 400 + 45, + 400 + 1, + 400 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 720,400, + 8500, + 355000, + 0, + VerPOSITIVE + HorNEGATIVE, + 936, + 720, + 720, + 720 + 216, + 720 + 36, + 720 + 36 + 72, + 446, + 400, + 400, + 400 + 46, + 400 + 1, + 400 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 640,480, + 6000, + 251750, + 0, + VerNEGATIVE+HorNEGATIVE, + 100*8, + 80*8, + 81*8, + (100-1)*8 , + 82*8, + (82+12)*8 , + 525, + 480, + 488+1, + 488+29, + 490, + 490+2, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 640,480, + 7200, + 315000, + 0, + VerNEGATIVE+HorNEGATIVE, + 104*8, + 80*8, + 81*8, + (81+22)*8, + 83*8, + (83+5) *8, + 520, + 480, + 488, + 488+24, + 489, + 489+3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 640,480, + 7500, + 315000, + 0, + VerNEGATIVE+HorNEGATIVE, + 105*8, + 80*8, + 80*8, + (80+25)*8, + 82*8, + (82+8) *8, + 500, + 480, + 480, + 480+20, + 481, + 481+3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 640,480, + 8500, + 360000, + 0, + VerNEGATIVE+HorNEGATIVE, + 104*8, + 80*8, + 80*8, + (80+24) *8, + 87*8, + (87+7) *8, + 509, + 480, + 480, + 480+29, + 481, + 481+3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 800,600, + 5600, + 360000, + 0, + VerPOSITIVE+HorPOSITIVE, + 1024, + 800, + 800, + 800 + 224, + 800 + 24, + 800 + 24 + 72, + 625, + 600, + 600, + 600 + 25, + 600 + 1, + 600 + 1 + 2, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 800,600, + 6000, + 400000, + 0, + VerPOSITIVE+HorPOSITIVE, + 132*8, + 100*8, + 100*8, + (100+32) *8, + 105*8, + (105+16) *8, + 628, + 600, + 600, + 600+28, + 601, + 601+4, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 800,600, + 7200, + 500000, + 0, + VerPOSITIVE+HorPOSITIVE, + 130*8, + 100*8, + 100*8, + (100+30)*8, + 107*8, + (107+15)*8, + 666, + 600, + 600, + 600+66, + 637, + 637+6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 800,600, + 7500, + 495000, + 0, + VerPOSITIVE+HorPOSITIVE, + 132*8, + 100*8, + 100*8, + (100+32) *8, + 102*8, + (102+10) *8, + 625, + 600, + 600, + 600+25, + 601, + 601+3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 800,600, + 8500, + 562500, + 0, + VerPOSITIVE+HorPOSITIVE, + 131*8, + 100*8, + 100*8, + (100+31)*8, + 104*8, + (104+8) *8, + 631, + 600, + 600, + 600+31, + 601, + 601+3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 800,600, + 10000, + 672500, + 0, + VerPOSITIVE+HorNEGATIVE, + 132*8, + 100*8, + 100*8, + (100+32) *8, + 106*8, + (106+10) *8, + 639, + 600, + 600, + 600+39, + 603, + 603+4, +}, +/** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 800,600, + 12000, + 732500, + 0, + VerNEGATIVE + HorPOSITIVE, + 960, + 800, + 800, + 800 + 160, + 800 + 48, + 800 + 48 + 32, + 636, + 600, + 600, + 600 + 36, + 600 + 3, + 600 + 3 + 4, +}, +********************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 848,480, + 6000, + 337500, + 0, + VerPOSITIVE + HorPOSITIVE, + 1088, + 848, + 848, + 848 + 240, + 848 + 16, + 848 + 16 +112, + 517, + 480, + 480, + 480 + 37, + 480 + 6, + 480 + 6 +8, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1024,768, + 6000, + 650000, + 0, + VerNEGATIVE+HorNEGATIVE, + 168*8, + 128*8, + 128*8, + (128+40) *8, + 131*8, + (131+17) *8, + 806, + 768, + 768, + 768+38, + 771, + 771+6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1024,768, + 7000, + 750000, + 0, + VerNEGATIVE+HorNEGATIVE, + 166*8, + 128*8, + 128*8, + (128+38) *8, + 131*8, + (131+17) *8, + 806, + 768, + 768, + 768+38, + 771, + 771+6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1024,768, + 7500, + 787500, + 0, + VerPOSITIVE+HorPOSITIVE, + 164*8, + 128*8, + 128*8, + (128+36)*8, + 130*8, + (130+12) *8, + 800, + 768, + 768, + 768+32, + 769, + 769+3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1024,768, + 8500, + 945000, + 0, + VerPOSITIVE+HorPOSITIVE, + 172*8, + 128*8, + 128*8, + (128+44)*8, + 134*8, + (134+12) *8, + 808, + 768, + 768, + 768+40, + 769, + 769+3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1024,768, + 10000, + 1122500, + 0, + VerPOSITIVE+HorNEGATIVE, + 172*8, + 128*8, + 128*8, + (128+44) *8, + 137*8, + (137+13-1) *8, + 816, + 768, + 768, + 768+48, + 771, + 771+4, +}, +/** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1024,768, + 12000, + 1155000, + 0, + VerNEGATIVE + HorPOSITIVE, + 1184, + 1024, + 1024, + 1024 + 160, + 1024 + 48, + 1024 + 48 + 32, + 813, + 768, + 768, + 768 + 45, + 768 + 3, + 768 + 3 + 4, +}, +*******************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1024,768, + 12000, + 1390000, + 0, + VerPOSITIVE+HorNEGATIVE, + 176*8, + 128*8, + 128*8, + (128+48) *8, + 138*8, + (138+14) *8, + 823, + 768, + 768, + 768+55, + 769, + 769+3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1152,864, + 7500, + 1080000, + 0, + VerPOSITIVE + HorPOSITIVE, + 1600, + 1152, + 1152, + 1152 + 448, + 1152 + 64, + 1152 + 64 + 128, + 900, + 864, + 864, + 864 + 36, + 864 + 1, + 864 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,720, + 5000, + 742500, + 0, + VerPOSITIVE+HorPOSITIVE, + 1980, + 1280, + 1280, + 1980, + 1280+440, + (1280+440+40) , + 750, + 720, + 720, + 720+30, + 725, + 725+5, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,720, + 6000, + 742500, + 0, + VerPOSITIVE+HorPOSITIVE, + 1650, + 1280, + 1280, + 1650 , + 1280+110, + (1280+110+40) , + 750, + 720, + 720, + 720+30, + 725, + 725+5, +}, +/** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,768, + 6000, + 682500, + 0, + VerNEGATIVE + HorPOSITIVE, + 1440, + 1280, + 1280, + 1280 + 160, + 1280 + 48, + 1280 + 48 + 32, + 790, + 768, + 768, + 768 + 22, + 768 + 3, + 768 + 3 + 7, +}, +*******************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,768, + 6000, + 795000, + 0, + VerPOSITIVE + HorNEGATIVE, + 1664, + 1280, + 1280, + 1280 + 384, + 1280 + 64, + 1280 + 64 + 128, + 798, + 768, + 768, + 768 + 30, + 768 + 3, + 768 + 3 + 7, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,768, + 7500, + 1022500, + 0, + VerPOSITIVE + HorNEGATIVE, + 1696, + 1280, + 1280, + 1280 + 416, + 1280 + 80, + 1280 + 80 + 128, + 805, + 768, + 768, + 768 + 37, + 768 + 3, + 768 + 3 + 7, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,768, + 8500, + 1175000, + 0, + VerPOSITIVE + HorNEGATIVE, + 1712, + 1280, + 1280, + 1280 + 432, + 1280 + 80, + 1280 + 80 + 136, + 809, + 768, + 768, + 768 + 41, + 768 + 3, + 768 + 3 + 7, +}, +/** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,768, + 12000, + 1402500, + 0, + VerNEGATIVE + HorPOSITIVE, + 1440, + 1280, + 1280, + 1280 + 160, + 1280 + 48, + 1280 + 48 + 32, + 813, + 768, + 768, + 768 + 45, + 768 + 3, + 768 + 3 + 7, +}, +*********************/ +/** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,800, + 6000, + 710000, + 0, + VerNEGATIVE + HorPOSITIVE, + 1440, + 1280, + 1280, + 1280 + 160, + 1280 + 48, + 1280 + 48 + 32, + 823, + 800, + 800, + 800 + 23, + 800 + 3, + 800 + 3 + 6, +}, +*****************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,800, + 6000, + 835000, + 0, + VerPOSITIVE + HorNEGATIVE, + 1680, + 1280, + 1280, + 1280 + 400, + 1280 + 72, + 1280 + 72 + 128, + 831, + 800, + 800, + 800 + 31, + 800 + 3, + 800 + 3 + 6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,800, + 7500, + 1065000, + 0, + VerPOSITIVE + HorNEGATIVE, + 1696, + 1280, + 1280, + 1280 + 416, + 1280 + 80, + 1280 + 80 + 128, + 838, + 800, + 800, + 800 + 38, + 800 + 3, + 800 + 3 + 6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,800, + 8500, + 1225000, + 0, + VerPOSITIVE + HorNEGATIVE, + 1712, + 1280, + 1280, + 1280 + 432, + 1280 + 80, + 1280 + 80 + 136, + 843, + 800, + 800, + 800 + 43, + 800 + 3, + 800 + 3 + 6, +}, +/** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,800, + 12000, + 1462500, + 0, + VerNEGATIVE + HorPOSITIVE, + 1440, + 1280, + 1280, + 1280 + 160, + 1280 + 48, + 1280 + 48 + 32, + 847, + 800, + 800, + 800 + 47, + 800 + 3, + 800 + 3 + 6, +}, +******************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,960, + 6000, + 1080000, + 0, + VerPOSITIVE + HorPOSITIVE, + 1800, + 1280, + 1280, + 1280 + 520, + 1280 + 96, + 1280 + 96 + 112, + 1000, + 960, + 960, + 960 + 40, + 960 + 1, + 960 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,960, + 8500, + 1485000, + 0, + VerPOSITIVE + HorPOSITIVE, + 1728, + 1280, + 1280, + 1280 + 448, + 1280 + 64, + 1280 + 64 + 160, + 1011, + 960, + 960, + 960 + 51, + 960 + 1, + 960 + 1 + 3, +}, +/*** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,960, + 12000, + 1755000, + 0, + VerNEGATIVE + HorPOSITIVE, + 1440, + 1280, + 1280, + 1280 + 160, + 1280 + 48, + 1280 + 48 + 32, + 1017, + 960, + 960, + 960 + 57, + 960 + 3, + 960 + 3 + 4, +}, +*********************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,1024, + 6000, + 1080000, + 0, + VerPOSITIVE+HorPOSITIVE, + 211*8, + 160*8, + 160*8, + (160+51)*8, + 166*8, + (166+14) *8, + 1066, + 1024, + 1024, + 1024+42, + 1025, + 1025+3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,1024, + 7500, + 1350000, + 0, + VerPOSITIVE+HorPOSITIVE, + 211*8, + 160*8, + 160*8, + (160+51) *8, + 162*8, + (162+18) *8, + 1066, + 1024, + 1024, + 1024+42, + 1025, + 1025+3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,1024, + 8500, + 1575000, + 0, + VerPOSITIVE+HorPOSITIVE, + 1728, + 1280, + 1280, + 1280 + 448, + 1280 + 64, + 1280 + 64 + 160, + 1072, + 1024, + 1024, + 1024 + 48, + 1024 + 1, + 1024 + 1 + 3, +}, +/*** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1280,1024, + 12000, + 1872500, + 0, + VerNEGATIVE + HorPOSITIVE, + 1440, + 1280, + 1280, + 1280 + 160, + 1280 + 48, + 1280 + 48 + 32, + 1084, + 1024, + 1024, + 1024 + 60, + 1024 + 3, + 1024 + 3 + 7, +}, +**********************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1360,768, + 6000, + 855000, + 0, + VerPOSITIVE+HorPOSITIVE, + 1792, + 1360, + 1360, + 1360 + 432, + 1360 + 64, + 1360 + 64 + 112, + 795, + 768, + 768, + 768 + 27, + 768 + 3, + 768 + 3 + 6, +}, +/*** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1360,768, + 12000, + 1482500, + 0, + VerNEGATIVE + HorPOSITIVE, + 1520, + 1360, + 1360, + 1360 + 160, + 1360 + 48, + 1360 + 48 + 32, + 813, + 768, + 768, + 768 + 45, + 768 + 3, + 768 + 3 + 5, +}, +*********************/ +/*** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1366,768, + 6000, + 720000, + 0, + VerPOSITIVE+HorPOSITIVE, + 1500, + 1366, + 1366, + 1366 + 134, + 1366 + 14, + 1366 + 14 + 56, + 800, + 768, + 768, + 768 + 32, + 768 + 1, + 768 + 1 + 3, +}, +******************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1366,768, + 6000, + 855000, + 0, + VerPOSITIVE+HorPOSITIVE, + 1792, + 1366, + 1366, + 1366 + 426, + 1366 + 70, + 1366 + 70 + 143, + 798, + 768, + 768, + 768 + 30, + 768 + 3, + 768 + 3 + 3, +}, +/***** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1400,1050, + 6000, + 1010000, + 0, + VerNEGATIVE + HorPOSITIVE, + 1560, + 1400, + 1400, + 1400 + 160, + 1400 + 48, + 1400 + 48 + 32, + 1080, + 1050, + 1050, + 1050 + 30, + 1050 + 3, + 1050 + 3 + 4, +}, +*********************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1400,1050, + 6000, + 1217500, + 0, + VerPOSITIVE + HorNEGATIVE, + 1864, + 1400, + 1400, + 1400 + 464, + 1400 + 88, + 1400 + 88 + 144, + 1089, + 1050, + 1050, + 1050 + 39, + 1050 + 3, + 1050 + 3 + 4, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1400,1050, + 7500, + 1560000, + 0, + VerPOSITIVE + HorNEGATIVE, + 1896, + 1400, + 1400, + 1400 + 496, + 1400 + 104, + 1400 + 104 + 144, + 1099, + 1050, + 1050, + 1050 + 49, + 1050 + 3, + 1050 + 3 + 4, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1400,1050, + 8500, + 1795000, + 0, + VerPOSITIVE + HorNEGATIVE, + 1912, + 1400, + 1400, + 1400 + 512, + 1400 + 104, + 1400 + 104 + 152, + 1105, + 1050, + 1050, + 1050 + 55, + 1050 + 3, + 1050 + 3 + 4, +}, +/******* Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1400,1050, + 12000, + 2080000, + 0, + VerNEGATIVE + HorPOSITIVE, + 1560, + 1400, + 1400, + 1400 + 160, + 1400 + 48, + 1400 + 48 + 32, + 1112, + 1050, + 1050, + 1050 + 62, + 1050 + 3, + 1050 + 3 + 4, +}, +***********************/ + +/****** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1440,900, + 6000, + 887500, + 0, + VerNEGATIVE + HorPOSITIVE, + 1600, + 1440, + 1440, + 1440 + 160, + 1440 + 48, + 1440 + 48 + 32, + 926, + 900, + 900, + 900 + 26, + 900 + 3, + 900 + 3 + 6, +}, +**********************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1440,900, + 6000, + 1065000, + 0, + VerPOSITIVE + HorNEGATIVE, + 1904, + 1440, + 1440, + 1440 + 464, + 1440 + 80, + 1440 + 80 + 152, + 934, + 900, + 900, + 900 + 34, + 900 + 3, + 900 + 3 + 6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1440,900, + 7500, + 1367500, + 0, + VerPOSITIVE + HorNEGATIVE, + 1936, + 1440, + 1440, + 1440 + 496, + 1440 + 96, + 1440 + 96 + 152, + 942, + 900, + 900, + 900 + 42, + 900 + 3, + 900 + 3 + 6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1440,900, + 8500, + 1570000, + 0, + VerPOSITIVE + HorNEGATIVE, + 1952, + 1440, + 1440, + 1440 + 512, + 1440 + 104, + 1440 + 104 + 152, + 948, + 900, + 900, + 900 + 48, + 900 + 3, + 900 + 3 + 6, +}, +/***** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1440,900, + 12000, + 1827500, + 0, + VerNEGATIVE + HorPOSITIVE, + 1600, + 1440, + 1440, + 1440 + 160, + 1440 + 48, + 1440 + 48 + 32, + 953, + 900, + 900, + 900 + 53, + 900 + 3, + 900 + 3 + 6, +}, +*********************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1600,900, + 6000, + 1080000, + 0, + VerPOSITIVE+HorPOSITIVE, + 1800, + 1600, + 1600, + 1600 + 200, + 1600 + 24, + 1600 + 24 + 80, + 1000, + 900, + 900, + 900 + 100, + 900 + 1, + 900 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1600,1200, + 6000, + 1620000, + 0, + VerPOSITIVE+HorPOSITIVE, + 2160, + 1600, + 1600, + 1600 + 560, + 1600 + 64, + 1600 + 64 + 192, + 1250, + 1200, + 1200, + 1200 + 50, + 1200 + 1, + 1200 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1600,1200, + 6500, + 1755000, + 0, + VerPOSITIVE+HorPOSITIVE, + 2160, + 1600, + 1600, + 1600 + 560, + 1600 + 64, + 1600 + 64 + 192, + 1250, + 1200, + 1200, + 1200 + 50, + 1200 + 1, + 1200 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1600,1200, + 7000, + 1890000, + 0, + VerPOSITIVE+HorPOSITIVE, + 2160, + 1600, + 1600, + 1600 + 560, + 1600 + 64, + 1600 + 64 + 192, + 1250, + 1200, + 1200, + 1200 + 50, + 1200 + 1, + 1200 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1600,1200, + 7500, + 2025000, + 0, + VerPOSITIVE+HorPOSITIVE, + 2160, + 1600, + 1600, + 1600 + 560, + 1600 + 64, + 1600 + 64 + 192, + 1250, + 1200, + 1200, + 1200 + 50, + 1200 + 1, + 1200 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1600,1200, + 8500, + 2295000, + 0, + VerPOSITIVE+HorPOSITIVE, + 2160, + 1600, + 1600, + 1600 + 560, + 1600 + 64, + 1600 + 64 + 192, + 1250, + 1200, + 1200, + 1200 + 50, + 1200 + 1, + 1200 + 1 + 3, +}, +/***** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1600,1200, + 12000, + 2682500, + 0, + VerNEGATIVE + HorPOSITIVE, + 1760, + 1600, + 1600, + 1600 + 160, + 1600 + 48, + 1600 + 48 + 32, + 1271, + 1200, + 1200, + 1200 + 71, + 1200 + 3, + 1200 + 3 + 4, +}, +********************/ +/***** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1680,1050, + 6000, + 1190000, + 0, + VerNEGATIVE + HorPOSITIVE, + 1840, + 1680, + 1680, + 1680 + 160, + 1680 + 48, + 1680 + 48 + 32, + 1080, + 1050, + 1050, + 1050 + 30, + 1050 + 3, + 1050 + 3 + 6, +}, +******************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1680,1050, + 6000, + 1462500, + 0, + VerPOSITIVE + HorNEGATIVE, + 2240, + 1680, + 1680, + 1680 + 560, + 1680 + 104, + 1680 + 104 + 176, + 1089, + 1050, + 1050, + 1050 + 39, + 1050 + 3, + 1050 + 3 + 6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1680,1050, + 7500, + 1870000, + 0, + VerPOSITIVE + HorNEGATIVE, + 2272, + 1680, + 1680, + 1680 + 592, + 1680 + 120, + 1680 + 120 + 176, + 1099, + 1050, + 1050, + 1050 + 49, + 1050 + 3, + 1050 + 3 + 6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1680,1050, + 8500, + 2147500, + 0, + VerPOSITIVE + HorNEGATIVE, + 2288, + 1680, + 1680, + 1680 + 608, + 1680 + 128, + 1680 + 128 + 176, + 1105, + 1050, + 1050, + 1050 + 55, + 1050 + 3, + 1050 + 3 + 6, +}, +/***** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1680,1050, + 12000, + 2455000, + 0, + VerNEGATIVE + HorPOSITIVE, + 1840, + 1680, + 1680, + 1680 + 160, + 1680 + 48, + 1680 + 48 + 32, + 1112, + 1050, + 1050, + 1050 + 62, + 1050 + 3, + 1050 + 3 + 6, +}, +*********************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1792,1344, + 6000, + 2047500, + 0, + VerPOSITIVE + HorNEGATIVE, + 2448, + 1792, + 1792, + 1792 + 656, + 1792 + 128, + 1792 + 128 + 200, + 1394, + 1344, + 1344, + 1344 + 50, + 1344 + 1, + 1344 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1792,1344, + 7500, + 2610000, + 0, + VerPOSITIVE + HorNEGATIVE, + 2456, + 1792, + 1792, + 1792 + 664, + 1792 + 96, + 1792 + 96 + 216, + 1417, + 1344, + 1344, + 1344 + 73, + 1344 + 1, + 1344 + 1 + 3, +}, +/*** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1792,1344, + 12000, + 3332500, + 0, + VerNEGATIVE + HorPOSITIVE, + 1952, + 1792, + 1792, + 1792 + 160, + 1792 + 48, + 1792 + 48 + 32, + 1423, + 1344, + 1344, + 1344 + 79, + 1344 + 3, + 1344 + 3 + 4, +}, +****************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1856,1392, + 6000, + 2182500, + 0, + VerPOSITIVE + HorNEGATIVE, + 2528, + 1856, + 1856, + 1856 + 672, + 1856 + 96, + 1856 + 96 + 224, + 1439, + 1392, + 1392, + 1392 + 47, + 1392 + 1, + 1392 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1856,1392, + 7500, + 2880000, + 0, + VerPOSITIVE + HorNEGATIVE, + 2560, + 1856, + 1856, + 1856 + 704, + 1856 + 128, + 1856 + 128 + 224, + 1500, + 1392, + 1392, + 1392 + 108, + 1392 + 1, + 1392 + 1 + 3, +}, +/**** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1856,1392, + 12000, + 3565000, + 0, + VerNEGATIVE + HorPOSITIVE, + 2016, + 1856, + 1856, + 1856 + 160, + 1856 + 48, + 1856 + 48 + 32, + 1474, + 1392, + 1392, + 1392 + 82, + 1392 + 3, + 1392 + 3 + 4, +}, +****************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1920,1080, + 5000, + 1485000, + 0, + VerPOSITIVE+HorPOSITIVE, + 2640, + 1920, + 1920, + 2640, + 1920+528, + (1920+528+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1920,1080, + 6000, + 1485000, + 0, + VerPOSITIVE+HorPOSITIVE, + 2200, + 1920, + 1920, + 2200 , + 1920+88, + (1920+88+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +/*{ + TIMING_ATTRIB_SIZE, + 0, + 1920,1080, + 12000, + 3687000, + 0, + VerPOSITIVE+HorNEGATIVE, + 332*8, + 240*8, + 240*8, + (240+92) *8, + 259*8, + (259+27) *8, + 1157, + 1080, + 1080, + 1080+77, + 1081, + 1081+3, +},*/ +/*** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1920,1200, + 6000, + 1540000, + 0, + VerNEGATIVE + HorPOSITIVE, + 2080, + 1920, + 1920, + 1920 + 160, + 1920 + 48, + 1920 + 48 + 32, + 1235, + 1200, + 1200, + 1200 + 35, + 1200 + 3, + 1200 + 3 + 6, +}, +**************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1920,1200, + 6000, + 1932500, + 0, + VerPOSITIVE+HorNEGATIVE, + 2592, + 1920, + 1920, + 1920 + 672, + 1920 + 136, + 1920 + 136 + 200, + 1245, + 1200, + 1200, + 1200 + 45, + 1200 + 3, + 1200 + 3 + 6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1920,1200, + 7500, + 2452500, + 0, + VerPOSITIVE+HorNEGATIVE, + 2608, + 1920, + 1920, + 1920 + 688, + 1920 + 136, + 1920 + 136 + 208, + 1255, + 1200, + 1200, + 1200 + 55, + 1200 + 3, + 1200 + 3 + 6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1920,1200, + 8500, + 2812500, + 0, + VerPOSITIVE+HorNEGATIVE, + 2624, + 1920, + 1920, + 1920 + 704, + 1920 + 144, + 1920 + 144 + 208, + 1262, + 1200, + 1200, + 1200 + 62, + 1200 + 3, + 1200 + 3 + 6, +}, +/**** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1920,1200, + 12000, + 3170000, + 0, + VerNEGATIVE + HorPOSITIVE, + 2080, + 1920, + 1920, + 1920 + 160, + 1920 + 48, + 1920 + 48 + 32, + 1271, + 1200, + 1200, + 1200 + 71, + 1200 + 3, + 1200 + 3 + 6, +}, +**********************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 1920,1440, + 6000, + 2340000, + 0, + VerPOSITIVE+HorNEGATIVE, + 2600, + 1920, + 1920, + 1920 + 680, + 1920 + 128, + 1920 + 128 + 208, + 1500, + 1440, + 1440, + 1440 + 60, + 1440 + 1, + 1440 + 1 + 3, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 1920,1440, + 7500, + 2970000, + 0, + VerPOSITIVE+HorNEGATIVE, + 2640, + 1920, + 1920, + 1920 + 720, + 1920 + 144, + 1920 + 144 + 224, + 1500, + 1440, + 1440, + 1440 + 60, + 1440 + 1, + 1440 + 1 + 3, +}, +/*** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 1920,1440, + 12000, + 3805000, + 0, + VerNEGATIVE + HorPOSITIVE, + 2080, + 1920, + 1920, + 1920 + 160, + 1920 + 48, + 1920 + 48 + 32, + 1525, + 1440, + 1440, + 1440 + 85, + 1440 + 3, + 1440 + 3 + 4, +}, +******************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 2048,1152, + 6000, + 1620000, + 0, + VerPOSITIVE+HorPOSITIVE, + 2250, + 2048, + 2048, + 2048 + 202, + 2048 + 26, + 2048 + 26 + 80, + 1200, + 1152, + 1152, + 1152 + 48, + 1152 + 1, + 1152 + 1 + 3, +}, +/*** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 2560,1600, + 6000, + 2685000, + 0, + VerNEGATIVE + HorPOSITIVE, + 2720, + 2560, + 2560, + 2560 + 160, + 2560 + 48, + 2560 + 48 + 32, + 1646, + 1600, + 1600, + 1600 + 46, + 1600 + 3, + 1600 + 3 + 6, +}, +****************/ +{ + TIMING_ATTRIB_SIZE, + 0, + 2560,1600, + 6000, + 3485000, + 0, + VerPOSITIVE+HorNEGATIVE, + 3504, + 2560, + 2560, + 2560 + 944, + 2560 + 192, + 2560 + 192 + 280, + 1658, + 1600, + 1600, + 1600 + 58, + 1600 + 3, + 1600 + 3 + 6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 2560,1600, + 7500, + 4432500, + 0, + VerPOSITIVE+HorNEGATIVE, + 3536, + 2560, + 2560, + 2560 + 976, + 2560 + 208, + 2560 + 208 + 280, + 1672, + 1600, + 1600, + 1600 + 72, + 1600 + 3, + 1600 + 3 + 6, +}, +{ + TIMING_ATTRIB_SIZE, + 0, + 2560,1600, + 8500, + 5052500, + 0, + VerPOSITIVE+HorNEGATIVE, + 3536, + 2560, + 2560, + 2560 + 976, + 2560 + 208, + 2560 + 208 + 280, + 1682, + 1600, + 1600, + 1600 + 82, + 1600 + 3, + 1600 + 3 + 6, +} +/** Reduced Blanking +{ + TIMING_ATTRIB_SIZE, + 0, + 2560,1600, + 12000, + 5527500, + 0, + VerNEGATIVE + HorPOSITIVE, + 2720, + 2560, + 2560, + 2560 + 160, + 2560 + 48, + 2560 + 48 + 32, + 1694, + 1600, + 1600, + 1600 + 94, + 1600 + 3, + 1600 + 3 + 6, +}, +***************/ +}; + +static CBiosModeInfoExt AdapterModeList[] = +{ +{ + MODE_INFO_EXT_SIZE, + 640, + 480, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_ADAPTERMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 800, + 600, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_ADAPTERMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 1024, + 768, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_ADAPTERMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 1280, + 720, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_ADAPTERMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 1280, + 800, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_ADAPTERMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + 0, +}, +{ + MODE_INFO_EXT_SIZE, + 1280, + 1024, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_ADAPTERMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 1366, + 768, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_ADAPTERMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + 0, +}, +{ + MODE_INFO_EXT_SIZE, + 1440, + 900, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_ADAPTERMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + 0, +}, +{ + MODE_INFO_EXT_SIZE, + 1680, + 1050, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_ADAPTERMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + 0, +}, +{ + MODE_INFO_EXT_SIZE, + 1920, + 1080, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_ADAPTERMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +}; + + +static CBIOS_TIMING_ATTRIB HDMIFormatTimingTbl[] = +{ +//normal VIC begin +//if new VICs are added, make sure to update CBIOS_HDMI_NORMAL_VIC_COUNTS +//1 +{ + TIMING_ATTRIB_SIZE, + 1, + 640,480, //XResolution, YResolution + 6000, //RefreshRate + 252000, //DCLK + 1, + VerNEGATIVE+HorNEGATIVE, //HVPolarity: Hor/Ver Sync Polarity(MISC:11000000B) + 800, //HorTotal: SR66_0+SR60=Round(Value/8)-5 + 640, //HorDisEnd: SR66_1+SR61=Round(Value/8)-1 + 640, //HorBStart: SR66_2+SR62=Round(Value/8) + 800 , //HorBEnd: SR66[3]+SR65[7]+SR63[0-4]=Round(Value/8)& 0x003F*/ + 656, //HorSyncStart: SR66[4]+SR64=Round(Value/8) + (656+96) , //HorSyncEnd: SR66[5]+SR65[0-4] =Round(Value/8) & 0x001F*/ + 525, //VerTotal: SR6E[0-3]+SR68=Value-2 + 480, //VerDisEnd: SR6E[4-7]+SR69=Value-1 + 480, //VerBStart: SR6F[0-3]+SR6A=Value + 525, //VerBEnd: SR6B + 490, //VerSyncStart: SR6F[4-7]+SR6C + 490+2, //VerSyncEnd: SR6B +}, +//2 +{ + TIMING_ATTRIB_SIZE, + 2, + 720,480, + 6000, + 270270, + 1, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858 , + 736, + (736+62) , + 525, + 480, + 480, + 525, + 489, + 489+6, +}, +//3 +{ + TIMING_ATTRIB_SIZE, + 3, + 720,480, + 6000, + 270270, + 2, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858 , + 736, + (736+62) , + 525, + 480, + 480, + 525, + 489, + 489+6, +}, +//4 +{ + TIMING_ATTRIB_SIZE, + 4, + 1280,720, + 6000, + 742500, + 2, + VerPOSITIVE+HorPOSITIVE, + 1650, + 1280, + 1280, + 1650 , + 1280+110, + (1280+110+40) , + 750, + 720, + 720, + 720+30, + 725, + 725+5, +}, +//5 +{ + TIMING_ATTRIB_SIZE, + 5, + 1920,1080, + 6000, + 742500, + 2, + VerPOSITIVE+HorPOSITIVE, + 2200, + 1920, + 1920, + 2200 , + 1920+88, + (1920+88+44) , + 1125, + 1080, + 1080, + 1080+22+23, + 1084, + 1084+10, +}, +//6 +{ + TIMING_ATTRIB_SIZE, + 6, + 720,480, + 6000, + 270270, + 1, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858 , + 720+38/2, + 720+38/2+124/2 , + 525, + 480, + 480, + 525, + 489-1, //adjust to correct 480i timing + 489-1+6, +}, +//7 +{ + TIMING_ATTRIB_SIZE, + 7, + 720,480, + 6000, + 270270, + 2, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858, + 720+38/2, + 720+38/2+124/2 , + 525, + 480, + 480, + 525, + 489-1, //adjust to correct 480i timing + 489-1+6, +}, +//8 +{ + TIMING_ATTRIB_SIZE, + 8, + 720,240, + 6000, + 270270, + 1, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 858, + 858, + 720+38/2, + 720+38/2+124/2, + 262, + 240, + 240, + 240+22, + 244, + 244+3, +}, +//9 +{ + TIMING_ATTRIB_SIZE, + 9, + 720,240, + 6000, + 270270, + 2, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 858, + 858, + 720+38/2, + 720+38/2+124/2, + 262, + 240, + 240, + 240+22, + 244, + 244+3, +}, +//10 +{ + TIMING_ATTRIB_SIZE, + 10, + 2880,480, + 6000, + 540540, + 1, + VerNEGATIVE+HorNEGATIVE, + 3432, + 2880, + 2880, + 3432 , + 2880+76, + (2880+76+248) , + 525, + 480, + 480, + 525, + 488, + 488+6, +}, +//11 +{ + TIMING_ATTRIB_SIZE, + 11, + 2880,480, + 6000, + 540540, + 2, + VerNEGATIVE+HorNEGATIVE, + 3432, + 2880, + 2880, + 3432, + 2880+76, + (2880+76+248) , + 525, + 480, + 480, + 525, + 488, + 488+6, +}, +//12 +{ + TIMING_ATTRIB_SIZE, + 12, + 2880,240, + 6000, + 540540, + 1, + VerNEGATIVE+HorNEGATIVE, + 3432, + 2880, + 2880, + 3432, + 2880+76, + (2880+76+248) , + 262, + 240, + 240, + 240+22, + 244, + 244+3, +}, +//13 +{ + TIMING_ATTRIB_SIZE, + 13, + 2880,240, + 6000, + 540540, + 2, + VerNEGATIVE+HorNEGATIVE, + 3432, + 2880, + 2880, + 3432 , + 2880+76, + (2880+76+248) , + 263, + 240, + 240, + 240+23, + 245, + 245+3, +}, +//14 +{ + TIMING_ATTRIB_SIZE, + 14, + 1440,480, + 6000, + 540540, + 1, + VerNEGATIVE+HorNEGATIVE, + 1716, + 1440, + 1440, + 1716, + 1472, + (1472+124) , + 525, + 480, + 480, + 480+45, + 490, + 490+6, +}, +//15 +{ + TIMING_ATTRIB_SIZE, + 15, + 1440,480, + 6000, + 540540, + 2, + VerNEGATIVE+HorNEGATIVE, + 1716, + 1440, + 1440, + 1716, + 1472, + (1472+124) , + 525, + 480, + 480, + 480+45, + 490, + 490+6, +}, +//16 +{ + TIMING_ATTRIB_SIZE, + 16, + 1920,1080, + 6000, + 1485000, + 2, + VerPOSITIVE+HorPOSITIVE, + 2200, + 1920, + 1920, + 2200 , + 1920+88, + (1920+88+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +//17 +{ + TIMING_ATTRIB_SIZE, + 17, + 720,576, + 5000, + 270000, + 1, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 732, + (732+64) , + 625, + 576, + 576, + 625, + 581, + 581+5, +}, +//18 +{ + TIMING_ATTRIB_SIZE, + 18, + 720,576, + 5000, + 270000, + 2, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864 , + 732, + (732+64) , + 625, + 576, + 576, + 625, + 581, + 581+5, +}, +//19 +{ + TIMING_ATTRIB_SIZE, + 19, + 1280,720, + 5000, + 742500, + 2, + VerPOSITIVE+HorPOSITIVE, + 1980, + 1280, + 1280, + 1980, + 1280+440, + (1280+440+40) , + 750, + 720, + 720, + 720+30, + 725, + 725+5, +}, +//20 +{ + TIMING_ATTRIB_SIZE, + 20, + 1920,1080, + 5000, + 742500, + 2, + VerPOSITIVE+HorPOSITIVE, + 2640, + 1920, + 1920, + 2640, + 1920+528, + (1920+528+44) , + 1125, + 1080, + 1080, + 1080+22+23, + 1084, + 1084+10, +}, +//21 +{ + TIMING_ATTRIB_SIZE, + 21, + 720,576, + 5000, + 270000, + 1, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 732, + (732+63) , + 625, + 576, + 576, + 625, + 580, //adjust to correct 576i timing + 580+6, +}, +//22 +{ + TIMING_ATTRIB_SIZE, + 22, + 720,576, + 5000, + 270000, + 2, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864 , + 732, + (732+63) , + 625, + 576, + 576, + 625, + 580,//adjust to correct 576i timing + 580+6, +}, +//23 +{ + TIMING_ATTRIB_SIZE, + 23, + 720,288, + 5000, + 270000, + 1, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 732, + (732+63) , + 312, + 288, + 288, + 312, + 290, + 290+3, +}, +//24 +{ + TIMING_ATTRIB_SIZE, + 24, + 720,288, + 5000, + 270000, + 2, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 732, + (732+63) , + 312, + 288, + 288, + 312, + 290, + 290+3, +}, +//25 +{ + TIMING_ATTRIB_SIZE, + 25, + 2880,576, + 5000, + 540000, + 1, + VerNEGATIVE+HorNEGATIVE, + 3456, + 2880, + 2880, + 3456, + 2880+48, + (2880+48+252) , + 625, + 576, + 576, + 625, + 580, + 580+6, +}, +//26 +{ + TIMING_ATTRIB_SIZE, + 26, + 2880,576, + 5000, + 540000, + 2, + VerNEGATIVE+HorNEGATIVE, + 3456, + 2880, + 2880, + 3456, + 2880+48, + (2880+48+252) , + 625, + 576, + 576, + 625, + 580, + 580+6, +}, +//27 +{ + TIMING_ATTRIB_SIZE, + 27, + 2880,288, + 5000, + 540000, + 1, + VerNEGATIVE+HorNEGATIVE, + 3456, + 2880, + 2880, + 3456, + 2880+48, + (2880+48+252) , + 312, + 288, + 288, + 312, + 290, + 290+3, +}, +//28 +{ + TIMING_ATTRIB_SIZE, + 28, + 2880,288, + 5000, + 540000, + 2, + VerNEGATIVE+HorNEGATIVE, + 3456, + 2880, + 2880, + 3456, + 2880+48, + (2880+48+252) , + 313, + 288, + 288, + 313, + 291, + 291+3, +}, +//29 +{ + TIMING_ATTRIB_SIZE, + 29, + 1440,576, + 5000, + 540000, + 1, + VerNEGATIVE+HorNEGATIVE, + 1728, + 1440, + 1440, + 1728, + 1440+24, + (1440+24+128) , + 625, + 576, + 576, + 625, + 581, + 581+5, +}, +//30 +{ + TIMING_ATTRIB_SIZE, + 30, + 1440,576, + 5000, + 540000, + 2, + VerNEGATIVE+HorNEGATIVE, + 1728, + 1440, + 1440, + 1728, + 1440+24, + (1440+24+128) , + 625, + 576, + 576, + 625, + 581, + 581+ 5, +}, +//31 +{ + TIMING_ATTRIB_SIZE, + 31, + 1920,1080, + 5000, + 1485000, + 2, + VerPOSITIVE+HorPOSITIVE, + 2640, + 1920, + 1920, + 2640, + 1920+528, + (1920+528+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +//32 +{ + TIMING_ATTRIB_SIZE, + 32, + 1920,1080, + 2397, + 742500, + 2, + VerPOSITIVE+HorPOSITIVE, + 2750, + 1920, + 1920, + 2750, + 1920+638, + (1920+638+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +//33 +{ + TIMING_ATTRIB_SIZE, + 33, + 1920,1080, + 2500, + 742500, + 2, + VerPOSITIVE+HorPOSITIVE, + 2640, + 1920, + 1920, + 2640, + 1920+528, + (1920+528+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +//34 +{ + TIMING_ATTRIB_SIZE, + 34, + 1920,1080, + 3000, + 742500, + 2, + VerPOSITIVE+HorPOSITIVE, + 2200,//2640-5*8, + 1920, + 1920, + 2200, + 1920+88, + (1920+88+44),//(1920+528+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +//35 2880x480p@60Hz 4:3 +{ + TIMING_ATTRIB_SIZE, + 35, + 2880, 480, + 6000, + 1081080, + 1, + VerNEGATIVE+HorNEGATIVE, + 3432, + 2880, + 2880, + 3432, + 2880+64, + 2880+64+248, + 525, + 480, + 480, + 525, + 480+9, + 480+9+6, +}, +//36 2880x480p@60Hz 16:9 +{ + TIMING_ATTRIB_SIZE, + 36, + 2880, 480, + 6000, + 1081080, + 2, + VerNEGATIVE+HorNEGATIVE, + 3432, + 2880, + 2880, + 3432, + 2880+64, + 2880+64+248, + 525, + 480, + 480, + 525, + 480+9, + 480+9+6, +}, +//37 2880x576p@50Hz 4:3 +{ + TIMING_ATTRIB_SIZE, + 37, + 2880, 576, + 5000, + 1080000, + 1, + VerNEGATIVE+HorNEGATIVE, + 3456, + 2880, + 2880, + 3456, + 2880+48, + 2880+48+256, + 625, + 576, + 576, + 625, + 576+5, + 576+5+5, +}, +//38 2880x576p@50Hz 16:9 +{ + TIMING_ATTRIB_SIZE, + 38, + 2880, 576, + 5000, + 1080000, + 2, + VerNEGATIVE+HorNEGATIVE, + 3456, + 2880, + 2880, + 3456, + 2880+48, + 2880+48+256, + 625, + 576, + 576, + 625, + 576+5, + 576+5+5, +}, +//39 1920x1080i@50Hz 16:9 +{ + TIMING_ATTRIB_SIZE, + 39, + 1920, 1080, + 5000, + 720000, + 2, + VerPOSITIVE+HorPOSITIVE, + 2304, + 1920, + 1920, + 2304, + 1920+32, + 1920+32+168, + 1250, + 1080, + 1080, + 1250, + 1080+46, + 1080+46+10, +}, +//40 1920x1080i@100Hz 16:9 +{ + TIMING_ATTRIB_SIZE, + 40, + 1920, 1080, + 10000, + 1485000, + 2, + VerPOSITIVE+HorPOSITIVE, + 2640, + 1920, + 1920, + 2640, + 1920+528, + 1920+528+44, + 1125, + 1080, + 1080, + 1125, + 1080+4, + 1080+4+10, +}, +//41 1280x720p@100Hz 16:9 +{ + TIMING_ATTRIB_SIZE, + 41, + 1280, 720, + 10000, + 1485000, + 2, + VerPOSITIVE+HorPOSITIVE, + 1980, + 1280, + 1280, + 1980, + 1280+440, + 1280+440+40, + 750, + 720, + 720, + 750, + 720+5, + 720+5+5, +}, +//42 720*576p@100Hz 4:3 +{ + TIMING_ATTRIB_SIZE, + 42, + 720, 576, + 10000, + 540000, + 1, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 720+12, + 720+12+64, + 625, + 576, + 576, + 625, + 576+5, + 576+5+5, +}, + +//43 720*576p@100Hz 16:9 +{ + TIMING_ATTRIB_SIZE, + 43, + 720, 576, + 10000, + 540000, + 2, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 720+12, + 720+12+64, + 625, + 576, + 576, + 625, + 576+5, + 576+5+5, +}, +//44 720(1440)*576i@100Hz 4:3 +{ + TIMING_ATTRIB_SIZE, + 44, + 720, 576, + 10000, + 540000, + 1, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 720+12, + 720+12+63, + 625, + 576, + 576, + 625, + 576+5-1, + 576+5+5, +}, +//45 720(1440)*576i@100Hz 16:9 +{ + TIMING_ATTRIB_SIZE, + 45, + 720, 576, + 10000, + 540000, + 2, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 720+12, + 720+12+63, + 625, + 576, + 576, + 625, + 576+5-1, + 576+5+5, +}, +//46 1920x1080i@120Hz 16:9 +{ + TIMING_ATTRIB_SIZE, + 46, + 1920, 1080, + 10000, + 1485000, + 2, + VerPOSITIVE+HorPOSITIVE, + 2200, + 1920, + 1920, + 2200, + 1920+88, + 1920+88+44, + 1125, + 1080, + 1080, + 1125, + 1080+4, + 1080+4+10, +}, +//47 1280x720p@120Hz 16:9 +{ + TIMING_ATTRIB_SIZE, + 47, + 1280,720, + 12000, + 1485000, + 2, + VerPOSITIVE+HorPOSITIVE, + 1650, + 1280, + 1280, + 1650 , + 1280+110, + (1280+110+40) , + 750, + 720, + 720, + 720+30, + 725, + 725+5, +}, +//48 720x480p@120Hz 4:3 +{ + TIMING_ATTRIB_SIZE, + 48, + 720,480, + 12000, + 540540, + 1, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858 , + 736, + (736+62) , + 525, + 480, + 480, + 525, + 489, + 489+6, +}, +//49 720x480p@120Hz 16:9 +{ + TIMING_ATTRIB_SIZE, + 49, + 720,480, + 12000, + 540540, + 2, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858 , + 736, + (736+62) , + 525, + 480, + 480, + 525, + 489, + 489+6, +}, +//50 720(1440)x480i@120Hz 4:3 +{ + TIMING_ATTRIB_SIZE, + 50, + 720,480, + 12000, + 540540, + 1, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858 , + 720+38/2, + 720+38/2+124/2, + 525, + 480, + 480, + 525, + 489-1, + 489-1+6, +}, +//51 720(1440)x480i@120Hz 16:9 +{ + TIMING_ATTRIB_SIZE, + 51, + 720,480, + 12000, + 540540, + 2, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858 , + 720+38/2, + 720+38/2+124/2, + 525, + 480, + 480, + 525, + 489-1, + 489-1+6, +}, +//52 720x576p@200Hz, 4:3 +{ + TIMING_ATTRIB_SIZE, + 52, + 720,576, + 20000, + 1080000, + 1, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 732, + (732+64) , + 625, + 576, + 576, + 625, + 581, + 581+5, +}, +//53 720x576p@200Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 53, + 720,576, + 20000, + 1080000, + 2, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 732, + (732+64) , + 625, + 576, + 576, + 625, + 581, + 581+5, +}, +//54 720(1440)x576i@200Hz, 4:3 +{ + TIMING_ATTRIB_SIZE, + 54, + 720,576, + 20000, + 1080000, + 1, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 732, + (732+63) , + 625, + 576, + 576, + 625, + 581-1, + 581+5, +}, +//55 720(1440)x576i@200Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 55, + 720,576, + 20000, + 1080000, + 2, + VerNEGATIVE+HorNEGATIVE, + 864, + 720, + 720, + 864, + 732, + (732+63) , + 625, + 576, + 576, + 625, + 581-1, + 581+5, +}, +//56 720x480p@240Hz, 4:3 +{ + TIMING_ATTRIB_SIZE, + 56, + 720,480, + 24000, + 1081080, + 1, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858, + 736, + (736+62) , + 525, + 480, + 480, + 525, + 480+9, + 480+9+6, +}, +//57 720x480p@240Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 57, + 720,480, + 24000, + 1081080, + 2, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858, + 736, + (736+62) , + 525, + 480, + 480, + 525, + 480+9, + 480+9+6, +}, +//58 720(1440)x480i@240Hz, 4:3 +{ + TIMING_ATTRIB_SIZE, + 58, + 720,480, + 24000, + 1081080, + 1, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858, + 720+19, + (720+19+62) , + 525, + 480, + 480, + 525, + 480+9-1, + 480+9-1+6, +}, +//59 720(1440)x480i@240Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 59, + 720,480, + 24000, + 1081080, + 2, + VerNEGATIVE+HorNEGATIVE, + 858, + 720, + 720, + 858, + 720+19, + (720+19+62) , + 525, + 480, + 480, + 525, + 480+9-1, + 480+9-1+6, +}, +//60 1280x720p@24Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 60, + 1280,720, + 2400, + 594000, + 2, + VerPOSITIVE+HorPOSITIVE, + 3300, + 1280, + 1280, + 3300, + 1280+1760, + 1280+1760+40, + 750, + 720, + 720, + 750, + 725, + 725+5, +}, +//61 1280x720p@25Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 61, + 1280,720, + 2500, + 742500, + 2, + VerPOSITIVE+HorPOSITIVE, + 3960, + 1280, + 1280, + 3960, + 1280+2420, + 1280+2420+40, + 750, + 720, + 720, + 750, + 725, + 725+5, +}, +//62 1280x720p@30Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 62, + 1280,720, + 3000, + 742500, + 2, + VerPOSITIVE+HorPOSITIVE, + 3300, + 1280, + 1280, + 3300, + 1280+1760, + 1280+1760+40, + 750, + 720, + 720, + 750, + 725, + 725+5, +}, +//63 1920x1080p@120Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 63, + 1920,1080, + 12000, + 2970000, + 2, + VerPOSITIVE+HorPOSITIVE, + 2200, + 1920, + 1920, + 2200, + 1920+88, + 1920+88+44, + 1125, + 1080, + 1080, + 1125, + 1080+4, + 1084+5, +}, +//64 1920x1080p@100Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 64, + 1920,1080, + 10000, + 2970000, + 2, + VerPOSITIVE+HorPOSITIVE, + 2640, + 1920, + 1920, + 2640, + 1920+528, + 1920+528+44, + 1125, + 1080, + 1080, + 1125, + 1080+4, + 1084+5, +}, + +// CEA-861-F +//65 1280x720p@24Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 65, + 1280,720, + 2400, + 594000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3300, + 1280, + 1280, + 3300, + 1280+1760, + 1280+1760+40, + 750, + 720, + 720, + 750, + 725, + 725+5, +}, +//66 1280x720p@25Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 66, + 1280,720, + 2500, + 742500, + 3, + VerPOSITIVE+HorPOSITIVE, + 3960, + 1280, + 1280, + 3960, + 1280+2420, + 1280+2420+40, + 750, + 720, + 720, + 750, + 725, + 725+5, +}, +//67 1280x720p@30Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 67, + 1280,720, + 3000, + 742500, + 3, + VerPOSITIVE+HorPOSITIVE, + 3300, + 1280, + 1280, + 3300, + 1280+1760, + 1280+1760+40, + 750, + 720, + 720, + 750, + 725, + 725+5, +}, +//68 1280x720p@50Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 68, + 1280,720, + 5000, + 742500, + 3, + VerPOSITIVE+HorPOSITIVE, + 1980, + 1280, + 1280, + 1980, + 1280+440, + (1280+440+40) , + 750, + 720, + 720, + 720+30, + 725, + 725+5, +}, +//69 1280x720p@60Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 69, + 1280,720, + 6000, + 742500, + 3, + VerPOSITIVE+HorPOSITIVE, + 1650, + 1280, + 1280, + 1650 , + 1280+110, + (1280+110+40) , + 750, + 720, + 720, + 720+30, + 725, + 725+5, +}, +//70 1280x720p@100Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 70, + 1280, 720, + 10000, + 1485000, + 3, + VerPOSITIVE+HorPOSITIVE, + 1980, + 1280, + 1280, + 1980, + 1280+440, + 1280+440+40, + 750, + 720, + 720, + 750, + 720+5, + 720+5+5, +}, +//71 1280x720p@120Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 71, + 1280,720, + 12000, + 1485000, + 3, + VerPOSITIVE+HorPOSITIVE, + 1650, + 1280, + 1280, + 1650 , + 1280+110, + (1280+110+40) , + 750, + 720, + 720, + 720+30, + 725, + 725+5, +}, +//72 1920x1080p@24Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 72, + 1920,1080, + 2397, + 742500, + 3, + VerPOSITIVE+HorPOSITIVE, + 2750, + 1920, + 1920, + 2750, + 1920+638, + (1920+638+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +//73 1920x1080p@25Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 73, + 1920,1080, + 2500, + 742500, + 3, + VerPOSITIVE+HorPOSITIVE, + 2640, + 1920, + 1920, + 2640, + 1920+528, + (1920+528+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +//74 1920x1080p@30Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 74, + 1920,1080, + 3000, + 741760, + 3, + VerPOSITIVE+HorPOSITIVE, + 2200,//2640-5*8, + 1920, + 1920, + 2200, + 1920+88, + (1920+88+44),//(1920+528+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +//75 1920x1080p@50Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 75, + 1920,1080, + 5000, + 1485000, + 3, + VerPOSITIVE+HorPOSITIVE, + 2640, + 1920, + 1920, + 2640, + 1920+528, + (1920+528+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +//76 1920x1080p@60Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 76, + 1920,1080, + 6000, + 1485000, + 3, + VerPOSITIVE+HorPOSITIVE, + 2200, + 1920, + 1920, + 2200 , + 1920+88, + (1920+88+44) , + 1125, + 1080, + 1080, + 1080+45, + 1084, + 1084+5, +}, +//77 1920x1080p@100Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 77, + 1920,1080, + 10000, + 2970000, + 3, + VerPOSITIVE+HorPOSITIVE, + 2640, + 1920, + 1920, + 2640, + 1920+528, + 1920+528+44, + 1125, + 1080, + 1080, + 1125, + 1080+4, + 1084+5, +}, +//78 1920x1080p@120Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 78, + 1920,1080, + 12000, + 2970000, + 3, + VerPOSITIVE+HorPOSITIVE, + 2200, + 1920, + 1920, + 2200, + 1920+88, + 1920+88+44, + 1125, + 1080, + 1080, + 1125, + 1080+4, + 1084+5, +}, +//79 1680x720p@24Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 79, + 1680,720, + 2400, + 594000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3300, + 1680, + 1680, + 3300, + 1680+1360, + 1680+1360+40, + 750, + 720, + 720, + 750, + 720+5, + 720+5+5, +}, +//80 1680x720p@25Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 80, + 1680,720, + 2500, + 594000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3168, + 1680, + 1680, + 3168, + 1680+1228, + 1680+1228+40, + 750, + 720, + 720, + 750, + 720+5, + 720+5+5, +}, +//81 1680x720p@30Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 81, + 1680,720, + 3000, + 594000, + 3, + VerPOSITIVE+HorPOSITIVE, + 2640, + 1680, + 1680, + 2640, + 1680+700, + 1680+700+40, + 750, + 720, + 720, + 750, + 720+5, + 720+5+5, +}, +//82 1680x720p@50Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 82, + 1680,720, + 5000, + 825000, + 3, + VerPOSITIVE+HorPOSITIVE, + 2200, + 1680, + 1680, + 2200, + 1680+260, + 1680+260+40, + 750, + 720, + 720, + 750, + 720+5, + 720+5+5, +}, +//83 1680x720p@60Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 83, + 1680,720, + 6000, + 990000, + 3, + VerPOSITIVE+HorPOSITIVE, + 2200, + 1680, + 1680, + 2200, + 1680+260, + 1680+260+40, + 750, + 720, + 720, + 750, + 720+5, + 720+5+5, +}, +//84 1680x720p@100Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 84, + 1680,720, + 10000, + 1650000, + 3, + VerPOSITIVE+HorPOSITIVE, + 2000, + 1680, + 1680, + 2000, + 1680+60, + 1680+60+40, + 825, + 720, + 720, + 825, + 720+5, + 720+5+5, +}, +//85 1680x720p@120Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 85, + 1680,720, + 12000, + 1980000, + 3, + VerPOSITIVE+HorPOSITIVE, + 2000, + 1680, + 1680, + 2000, + 1680+60, + 1680+60+40, + 825, + 720, + 720, + 825, + 720+5, + 720+5+5, +}, +//86 2560x1080p@24Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 86, + 2560,1080, + 2400, + 990000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3750, + 2560, + 2560, + 3750, + 2560+998, + 2560+998+44, + 1100, + 1080, + 1080, + 1100, + 1080+4, + 1080+4+5, +}, +//87 2560x1080p@25Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 87, + 2560,1080, + 2500, + 900000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3200, + 2560, + 2560, + 3200, + 2560+448, + 2560+448+44, + 1125, + 1080, + 1080, + 1125, + 1080+4, + 1080+4+5, +}, +//88 2560x1080p@30Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 88, + 2560,1080, + 3000, + 1188000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3520, + 2560, + 2560, + 3520, + 2560+768, + 2560+768+44, + 1125, + 1080, + 1080, + 1125, + 1080+4, + 1080+4+5, +}, +//89 2560x1080p@50Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 89, + 2560,1080, + 5000, + 1856250, + 3, + VerPOSITIVE+HorPOSITIVE, + 3300, + 2560, + 2560, + 3300, + 2560+548, + 2560+548+44, + 1125, + 1080, + 1080, + 1125, + 1080+4, + 1080+4+5, +}, +//90 2560x1080p@60Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 90, + 2560,1080, + 6000, + 1980000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3000, + 2560, + 2560, + 3000, + 2560+248, + 2560+248+44, + 1100, + 1080, + 1080, + 1100, + 1080+4, + 1080+4+5, +}, +//91 2560x1080p@100Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 91, + 2560,1080, + 10000, + 3712500, + 3, + VerPOSITIVE+HorPOSITIVE, + 2970, + 2560, + 2560, + 2970, + 2560+218, + 2560+218+44, + 1250, + 1080, + 1080, + 1250, + 1080+4, + 1080+4+5, +}, +//92 2560x1080p@120Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 92, + 2560,1080, + 12000, + 4950000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3300, + 2560, + 2560, + 3300, + 2560+548, + 2560+548+44, + 1250, + 1080, + 1080, + 1250, + 1080+4, + 1080+4+5, +}, +//93 3840x2160p@24Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 93, + 3840, 2160, + 2400, + 2970000, + 2, + VerPOSITIVE+HorPOSITIVE, + 3840+1660, + 3840, + 3840, + 3840+1660, + 3840+1276, + 3840+1276+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//94 3840x2160p@25Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 94, + 3840, 2160, + 2500, + 2970000, + 2, + VerPOSITIVE+HorPOSITIVE, + 3840+1440, + 3840, + 3840, + 3840+1440, + 3840+1056, + 3840+1056+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//95 3840x2160p@30Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 95, + 3840, 2160, + 3000, + 2970000, + 2, + VerPOSITIVE+HorPOSITIVE, + 3840+560, + 3840, + 3840, + 3840+560, + 3840+176, + 3840+176+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//96 3840x2160p@50Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 96, + 3840, 2160, + 5000, + 5940000, + 2, + VerPOSITIVE+HorPOSITIVE, + 3840+1440, + 3840, + 3840, + 3840+1440, + 3840+1056, + 3840+1056+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//97 3840x2160p@60Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 97, + 3840, 2160, + 6000, + 5940000, + 2, + VerPOSITIVE+HorPOSITIVE, + 3840+560, + 3840, + 3840, + 3840+560, + 3840+176, + 3840+176+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//98 4096x2160p@24Hz, 256:135 +{ + TIMING_ATTRIB_SIZE, + 98, + 4096, 2160, + 2400, + 2970000, + 4, + VerPOSITIVE+HorPOSITIVE, + 4096+1404, + 4096, + 4096, + 4096+1404, + 4096+1020, + 4096+1020+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//99 4096x2160p@25Hz, 256:135 +{ + TIMING_ATTRIB_SIZE, + 99, + 4096, 2160, + 2500, + 2970000, + 4, + VerPOSITIVE+HorPOSITIVE, + 5280, + 4096, + 4096, + 5280, + 4096+968, + 4096+968+88, + 2250, + 2160, + 2160, + 2250, + 2160+8, + 2160+8+10 +}, +//100 4096x2160p@30Hz, 256:135 +{ + TIMING_ATTRIB_SIZE, + 100, + 4096, 2160, + 3000, + 2970000, + 4, + VerPOSITIVE+HorPOSITIVE, + 4400, + 4096, + 4096, + 4400, + 4096+88, + 4096+88+88, + 2250, + 2160, + 2160, + 2250, + 2160+8, + 2160+8+10 +}, +//101 4096x2160p@50Hz, 256:135 +{ + TIMING_ATTRIB_SIZE, + 101, + 4096, 2160, + 5000, + 5940000, + 4, + VerPOSITIVE+HorPOSITIVE, + 5280, + 4096, + 4096, + 5280, + 4096+968, + 4096+968+88, + 2250, + 2160, + 2160, + 2250, + 2160+8, + 2160+8+10 +}, +//102 4096x2160p@60Hz, 256:135 +{ + TIMING_ATTRIB_SIZE, + 102, + 4096, 2160, + 6000, + 5940000, + 4, + VerPOSITIVE+HorPOSITIVE, + 4400, + 4096, + 4096, + 4400, + 4096+88, + 4096+88+88, + 2250, + 2160, + 2160, + 2250, + 2160+8, + 2160+8+10 +}, +//103 3840x2160p@24Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 103, + 3840, 2160, + 2400, + 2970000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3840+1660, + 3840, + 3840, + 3840+1660, + 3840+1276, + 3840+1276+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//104 3840x2160p@25Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 104, + 3840, 2160, + 2500, + 2970000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3840+1440, + 3840, + 3840, + 3840+1440, + 3840+1056, + 3840+1056+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//105 3840x2160p@30Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 105, + 3840, 2160, + 3000, + 2970000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3840+560, + 3840, + 3840, + 3840+560, + 3840+176, + 3840+176+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//106 3840x2160p@50Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 106, + 3840, 2160, + 5000, + 5940000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3840+1440, + 3840, + 3840, + 3840+1440, + 3840+1056, + 3840+1056+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//107 3840x2160p@60Hz, 64:27 +{ + TIMING_ATTRIB_SIZE, + 107, + 3840, 2160, + 6000, + 5940000, + 3, + VerPOSITIVE+HorPOSITIVE, + 3840+560, + 3840, + 3840, + 3840+560, + 3840+176, + 3840+176+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//normal VIC end +//extended resolution begin +//3840x2160p@30Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 108, + 3840, 2160, + 3000, + 2970000, + 2, + VerPOSITIVE+HorPOSITIVE, + 3840+560, + 3840, + 3840, + 3840+560, + 3840+176, + 3840+176+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//3840x2160p@25Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 109, + 3840, 2160, + 2500, + 2970000, + 2, + VerPOSITIVE+HorPOSITIVE, + 3840+1440, + 3840, + 3840, + 3840+1440, + 3840+1056, + 3840+1056+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//3840x2160p@24Hz, 16:9 +{ + TIMING_ATTRIB_SIZE, + 110, + 3840, 2160, + 2400, + 2970000, + 2, + VerPOSITIVE+HorPOSITIVE, + 3840+1660, + 3840, + 3840, + 3840+1660, + 3840+1276, + 3840+1276+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +//4096x2160p@24Hz, 16:9(SMPTE) +{ + TIMING_ATTRIB_SIZE, + 111, + 4096, 2160, + 2400, + 2970000, + 2, + VerPOSITIVE+HorPOSITIVE, + 4096+1404, + 4096, + 4096, + 4096+1404, + 4096+1020, + 4096+1020+88, + 2160+90, + 2160, + 2160, + 2160+90, + 2160+8, + 2160+8+10 +}, +}; + +static CBiosModeInfoExt TV_DefaultModeList[] = +{ +{ + MODE_INFO_EXT_SIZE, + 704, + 576, + 5000, + CBIOS_INTERLACECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_TV, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +}; + +static CBiosModeInfoExt HDTV_DefaultModeList[] = +{ +{ + MODE_INFO_EXT_SIZE, + 720, + 576, + 5000, + CBIOS_PROGRESSIVECAP|CBIOS_INTERLACECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_HDTV, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +{ + MODE_INFO_EXT_SIZE, + 1280, + 720, + 5000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_HDTV, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +{ + MODE_INFO_EXT_SIZE, + 1920, + 1080, + 5000, + CBIOS_PROGRESSIVECAP|CBIOS_INTERLACECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_HDTV, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +}; + +static CBiosModeInfoExt DSI_DefaultModeList[] = +{ +{ + MODE_INFO_EXT_SIZE, + 640, + 480, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_DSI, + MODE_COLOR_DEPTH_CAPS, + 0, + CBIOS_NATIVEMODE, + {(CBIOS_DTL_TIMING << 2)}, +}, +}; + +static CBiosModeInfoExt DP_DefaultModeList[] = +{ +{ + MODE_INFO_EXT_SIZE, + 640, + 480, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_DP1, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +{ + MODE_INFO_EXT_SIZE, + 720, + 480, + 5994, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_DP1, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +{ + MODE_INFO_EXT_SIZE, + 720, + 480, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_DP1, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +{ + MODE_INFO_EXT_SIZE, + 720, + 576, + 5000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_DP1, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +{ + MODE_INFO_EXT_SIZE, + 1280, + 720, + 5000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_DP1, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +{ + MODE_INFO_EXT_SIZE, + 1280, + 720, + 5994, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_DP1, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +{ + MODE_INFO_EXT_SIZE, + 1280, + 720, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_DP1, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +{ + MODE_INFO_EXT_SIZE, + 1920, + 1080, + 5000, + CBIOS_INTERLACECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_DP1, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +{ + MODE_INFO_EXT_SIZE, + 1920, + 1080, + 5994, + CBIOS_INTERLACECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_DP1, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +{ + MODE_INFO_EXT_SIZE, + 1920, + 1080, + 6000, + CBIOS_INTERLACECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_DP1, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {1}, +}, +}; + +static CBiosModeInfoExt MHL_DefaultModeList[] = +{ +{ + MODE_INFO_EXT_SIZE, + 640, + 480, + 5994, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_MHL, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 640, + 480, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_MHL, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 720, + 480, + 5994, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_MHL, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 720, + 480, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_MHL, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 720, + 576, + 5000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_MHL, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 1280, + 720, + 5994, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_MHL, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 1280, + 720, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_MHL, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +{ + MODE_INFO_EXT_SIZE, + 1280, + 720, + 5000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_MHL, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {0}, +}, +}; + +static CBiosModeInfoExt Device_DefaultModeList[] = +{ +{ + MODE_INFO_EXT_SIZE, + 640, + 480, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {(CBIOS_MODE_STD_TIMING << 2)}, +}, +{ + MODE_INFO_EXT_SIZE, + 800, + 600, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {(CBIOS_MODE_STD_TIMING << 2)}, +}, +{ + MODE_INFO_EXT_SIZE, + 1024, + 768, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {(CBIOS_MODE_STD_TIMING << 2)}, +}, +{ + MODE_INFO_EXT_SIZE, + 1280, + 1024, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {(CBIOS_MODE_STD_TIMING << 2)}, +}, +{ + MODE_INFO_EXT_SIZE, + 1920, + 1080, + 6000, + CBIOS_PROGRESSIVECAP, + CBIOS_DEVICEMODE, + CBIOS_TYPE_NONE, + MODE_COLOR_DEPTH_CAPS, + 0, + 0, + {((CBIOS_MODE_DTL_TIMING << 2) | (1 << 18))}, +} +}; + + +static CBiosEquivalentDeviceMode Equivalent_DeviceMode_Table[] = +{ + {720, 480, {5900, 6000-1}, 6000}, + {720, 480, {6000, 6000}, 5994}, + {1280, 720, {5900, 6000-1}, 6000}, + {1280, 720, {6000, 6000}, 5994}, + {1920, 1080, {2900, 3000-1}, 3000}, + {1920, 1080, {3000, 3000}, 2997}, + {1920, 1080, {5900, 6000-1}, 6000}, + {1920, 1080, {6000, 6000}, 5994}, +}; + +/*************************************************************** +Function: cbMode_CompareMode + +Description: Compare two mode XRes, YRes, Refresh Rate and Interlace/Progress + +Input: pMode1, pMode2: two modes need to compare + +Output: + +Return: Positive: if Mode1 > Mode2 + Zero : if Mode1 == Mode2 + Negative: if Mode1 < Mode2 +***************************************************************/ +static CBIOS_S32 cbMode_CompareMode(PCBIOS_MODE_INFO_EXT pMode1, PCBIOS_MODE_INFO_EXT pMode2) +{ + CBIOS_S32 retValue; + + if ((pMode1->XResolution > pMode2->XResolution)|| + ((pMode1->XResolution == pMode2->XResolution)&& + (pMode1->YResolution > pMode2->YResolution))|| + ((pMode1->XResolution == pMode2->XResolution)&& + (pMode1->YResolution == pMode2->YResolution)&& + (pMode1->Refreshrate > pMode2->Refreshrate))) + { + retValue = 1; + } + else if ((pMode1->XResolution == pMode2->XResolution)&& + (pMode1->YResolution == pMode2->YResolution)&& + (pMode1->Refreshrate == pMode2->Refreshrate)) + { + if (pMode1->InterLaced == pMode2->InterLaced) + { + retValue = 0; + } + else if ((pMode1->InterLaced == CBIOS_FALSE)&& + (pMode2->InterLaced == CBIOS_TRUE)) + { + retValue = 1; + } + else + { + retValue = -1; + } + } + else + { + retValue = -1; + } + + return retValue; +} + +static CBIOS_BOOL cbMode_AddMode(PCBiosModeInfoExt pModeList, PCBiosModeInfoExt pMode, CBIOS_U32 CurrentModeNum, CBIOS_ACTIVE_TYPE Device) +{ + CBIOS_MODE_INFO_EXT ModeList, ModeInsert; + CBIOS_BOOL bRet = CBIOS_FALSE; + CBIOS_U32 index = 0xFFFFFFFF, i = 0; + CBIOS_S32 sCmp; + + cb_memset(&ModeList, 0, sizeof(CBIOS_MODE_INFO_EXT)); + cb_memset(&ModeInsert, 0, sizeof(CBIOS_MODE_INFO_EXT)); + + pMode->DeviceFlags = Device; + + ModeInsert.XResolution = (CBIOS_U16)pMode->XRes; + ModeInsert.YResolution = (CBIOS_U16)pMode->YRes; + ModeInsert.Refreshrate = (CBIOS_U16)pMode->RefreshRate; + ModeInsert.InterLaced = (pMode->InterlaceProgressiveCaps & 0x2) ? CBIOS_TRUE : CBIOS_FALSE; + + + for(i = 0; i< CurrentModeNum; i++) + { + ModeList.XResolution = (CBIOS_U16)pModeList[i].XRes; + ModeList.YResolution = (CBIOS_U16)pModeList[i].YRes; + ModeList.Refreshrate = (CBIOS_U16)pModeList[i].RefreshRate; + ModeList.InterLaced = (pModeList[i].InterlaceProgressiveCaps & 0x2) ? CBIOS_TRUE : CBIOS_FALSE; + sCmp = cbMode_CompareMode(&ModeList, &ModeInsert); + if (sCmp <= 0) + { + break; + } + } + if(i == CurrentModeNum) + { + cb_memcpy(&pModeList[i], pMode, sizeof(CBiosModeInfoExt)); + bRet = CBIOS_TRUE; + } + else + { + if (sCmp < 0) + { + // insert mode to modelist + for(index = CurrentModeNum; index > i; index--) + { + cb_memcpy(&pModeList[index], &pModeList[index - 1], sizeof(CBiosModeInfoExt)); + } + cb_memcpy(&pModeList[i], pMode, sizeof(CBiosModeInfoExt)); + bRet = CBIOS_TRUE; + } + else if (sCmp == 0) + { + // added mode already exists in modelist, only merge mode flags + pModeList[i].InterlaceProgressiveCaps |= pMode->InterlaceProgressiveCaps; + pModeList[i].AdapterDeviceFlags |= pMode->AdapterDeviceFlags; + pModeList[i].DeviceFlags |= pMode->DeviceFlags; + pModeList[i].ColorDepthCaps |= pMode->ColorDepthCaps; + pModeList[i].AspectRatioCaps |= pMode->AspectRatioCaps; + pModeList[i].NativeModeFlags |= pMode->NativeModeFlags; + pModeList[i].ModeFlags |= pMode->ModeFlags; + bRet= CBIOS_FALSE; + } + } + + return bRet; +} + +#if 0 +static CBIOS_BOOL cbMode_DeleteMode(PCBiosModeInfoExt pModeList, CBIOS_U16 XRes, CBIOS_U16 YRes, CBIOS_U16 RefRate, CBIOS_BOOL isInterlace) +{ + CBIOS_BOOL bFound = CBIOS_FALSE; + CBIOS_U32 index = 0, i = 0; + + while(pModeList[i].XRes) + { + if ((pModeList[i].XRes == XRes) && + (pModeList[i].YRes == YRes) && + (pModeList[i].RefreshRate == RefRate)) + { + if (((pModeList[i].InterlaceProgressiveCaps == CBIOS_INTERLACECAP) && isInterlace) || + ((pModeList[i].InterlaceProgressiveCaps == CBIOS_PROGRESSIVECAP) && (!isInterlace))) + { + index = i; + bFound = CBIOS_TRUE; + break; + } + else + { + i++; + continue; + } + } + else + { + i++; + continue; + } + } + + if (bFound) + { + if (pModeList[index+1].XRes) + { + do + { + cb_memcpy(&pModeList[i], &pModeList[i+1], sizeof(CBiosModeInfoExt)); + i++; + }while(pModeList[i+1].XRes); + cb_memset(&pModeList[i], 0, sizeof(CBiosModeInfoExt)); + } + else + { + cb_memset(&pModeList[index], 0, sizeof(CBiosModeInfoExt)); + } + + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "cbMode_DeleteMode: Delete mode not found in modelist!\n")); + } + + return bFound; +} +#endif + +static CBIOS_BOOL cbMode_FindModeInModeList(PCBiosModeInfoExt pModeList, CBIOS_U32 ModeNum, CBIOS_U32 XRes, CBIOS_U32 YRes, CBIOS_U32 RefRate, CBIOS_U32 InterlaceProgressiveCaps, PCBIOS_U32 pIndex) +{ + CBIOS_BOOL bRet = CBIOS_FALSE; + CBIOS_U32 index = 0; + + for(index = 0; index < ModeNum; index++) + { + if((pModeList[index].XRes == XRes) && (pModeList[index].YRes == YRes) && (pModeList[index].RefreshRate == RefRate) && (pModeList[index].InterlaceProgressiveCaps == InterlaceProgressiveCaps)) + { + if(pIndex) + { + *pIndex = index; + } + bRet = CBIOS_TRUE; + } + } + + return bRet; +} + + +/********* + +per CEA861-F spec +if A Video Timing with a vertical frequency that is an integer multiple of 6.00 Hz +(i.e., 24.00, 30.00, 60.00, 120.00 or 240.00 Hz) is considered to be the same as a +Video Timing with the equivalent detailed timing information but where the vertical +frequency is adjusted by a factor of 1000/1001 + +here Add 5994(6000) for 720X480, add 5994(6000) for 1280X720, add 5994(6000) and 2997(3000) for 1920X1080 mode + +*********/ + + +CBIOS_VOID cbMode_AddEquivalentDeviceMode(PCBiosModeInfoExt pModeList, PCBIOS_U32 pModeNum, PCBiosModeInfoExt pDeviceMode, CBIOS_ACTIVE_TYPE Device, CBIOS_U32 MaxMode) +{ + CBiosModeInfoExt ModeToInsert = {0}; + CBIOS_U32 XRes, YRes, MinRefreshRate, MaxRefreshRate; + CBIOS_U32 OriginModeNum = *pModeNum; + CBIOS_U32 ModeNum = OriginModeNum; + CBIOS_BOOL found = CBIOS_FALSE; + CBIOS_U32 index = 0; + + + for(index = 0; index < (sizeof(Equivalent_DeviceMode_Table)/sizeof(Equivalent_DeviceMode_Table[0])); index++) + { + XRes = Equivalent_DeviceMode_Table[index].XRes; + YRes = Equivalent_DeviceMode_Table[index].YRes; + MinRefreshRate = Equivalent_DeviceMode_Table[index].RefRateRange[0]; + MaxRefreshRate = Equivalent_DeviceMode_Table[index].RefRateRange[1]; + if((pDeviceMode->XRes == XRes) && (pDeviceMode->YRes == YRes) && (pDeviceMode->RefreshRate >= MinRefreshRate) && (pDeviceMode->RefreshRate <= MaxRefreshRate)) + { + found = CBIOS_TRUE; + ModeNum++; + break; + } + + } + + if(found && pModeList && (MaxMode >= ModeNum) && (index < sizeof(Equivalent_DeviceMode_Table)/sizeof(Equivalent_DeviceMode_Table[0]))) + { + cb_memcpy(&ModeToInsert, pDeviceMode, sizeof(CBiosModeInfoExt)); + ModeToInsert.RefreshRate = Equivalent_DeviceMode_Table[index].RefRateToAdd; + ModeToInsert.ModeFlags |= 0x2; + if(cbMode_FindModeInModeList(pModeList, OriginModeNum, ModeToInsert.XRes, ModeToInsert.YRes, ModeToInsert.RefreshRate, ModeToInsert.InterlaceProgressiveCaps, CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbMode_AddEquivalentDeviceMode: add mode failed! this mode already exists!\n")); + ModeNum--; + } + else if(!cbMode_AddMode(pModeList, &ModeToInsert, OriginModeNum, Device)) + { + ModeNum--; + } + } + + *pModeNum = ModeNum; + + return; +} + + +static CBIOS_VOID cbMode_FillAdapterModeBuffer(PCBIOS_EXTENSION_COMMON pcbe, + PCBiosModeInfoExt pModeList, + CBIOS_U32 XRes, + CBIOS_U32 YRes, + CBIOS_U32 RefRate) +{ + if(pModeList != CBIOS_NULL) + { + pModeList->XRes = XRes; + pModeList->YRes = YRes; + pModeList->RefreshRate = RefRate; + pModeList->InterlaceProgressiveCaps = CBIOS_PROGRESSIVECAP; + + pModeList->AdapterDeviceFlags = CBIOS_ADAPTERMODE; + //pModeList->DeviceFlags = + pModeList->ColorDepthCaps = CBIOS_COLORDEPTH16 | + CBIOS_COLORDEPTH32XRGB | + CBIOS_COLORDEPTH32ARGB | + CBIOS_COLORDEPTH32ABGR | + CBIOS_COLORDEPTH2101010ARGB | + CBIOS_COLORDEPTH2101010ABGR | + CBIOS_COLORDEPTH16161616ABGRF; + //pModeList->AspectRatioCaps = + //pModeList->NativeModeFlags + //pModeList->ModeFlags + } +} + + + +// All timing value is progressive, even though request is interlace mode. +CBIOS_BOOL cbMode_GetHVTiming(PCBIOS_VOID pvcbe, + CBIOS_U32 XRes, + CBIOS_U32 YRes, + CBIOS_U32 Refresh, + CBIOS_U32 isInterlace, + CBIOS_ACTIVE_TYPE Device, + PCBIOS_TIMING_ATTRIB pTiming) + +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + PCBIOS_EDID_STRUCTURE_DATA pEdidStruct = CBIOS_NULL; + PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttr = CBIOS_NULL; + PCBIOS_MODE_INFO_EXT pModeInfo = CBIOS_NULL; + PCBIOS_TIMING_ATTRIB pTimingTbl = CBIOS_NULL; + CBIOS_U32 ulTimingBlock = 0, ulTmIdx = 0; + CBIOS_U32 NumOfTimings = 0, i; + CBIOS_BOOL bFound = CBIOS_FALSE; + + cbTraceEnter(GENERIC); + + pEdidStruct = &(pDevCommon->EdidStruct); + pMonitorAttr = &(pEdidStruct->Attribute); + + // Set the default refresh rate to 60Hz. + if((Refresh == 0) || (Refresh == 1)) + { + Refresh = 6000; + } + + // first find timing in EDID + if((cbEDIDModule_IsEDIDValid(pDevCommon->EdidData))&& + (cbEDIDModule_SearchTmInEdidStruct(XRes, YRes, Refresh, isInterlace, + pEdidStruct, &ulTimingBlock, &ulTmIdx))) + { + if(ulTimingBlock == 3) // Means CEA861B format block + { + CBIOS_BOOL byRefIndex = 0; + byRefIndex = pEdidStruct->HDMIFormat[ulTmIdx].RefreshIndex; + + cb_memcpy(pTiming, &HDMIFormatTimingTbl[ulTmIdx], sizeof(CBIOS_TIMING_ATTRIB)); + + if (byRefIndex == 1) + { + pTiming->PixelClock = pTiming->PixelClock / 1001UL * 1000UL; + pTiming->RefreshRate = (CBIOS_U16)((CBIOS_U32)pTiming->RefreshRate * 1000 / 1001); + } + bFound = CBIOS_TRUE; + } + else if (ulTimingBlock == 4)//DTD + { + pModeInfo = &(pDevCommon->EdidStruct.DTDTimings[ulTmIdx]); + cbConvertEdidTimingToTableTiming(pcbe, pModeInfo, pTiming); + bFound = CBIOS_TRUE; + } + else if(ulTimingBlock == 2) // Means Detailed timing block. + { + //Patch for DFI: Kortek monitor, for 1280x1024 mode, use VESA timing instead of detailed timing + if (cbIsSameMonitor(pDevCommon->EdidData, KortekMonitorID) + && (XRes == 1280) && (YRes == 1024)) + { + bFound = CBIOS_FALSE; + } + else + { + pModeInfo = &(pDevCommon->EdidStruct.DtlTimings[ulTmIdx]); + cbConvertEdidTimingToTableTiming(pcbe, pModeInfo, pTiming); + bFound = CBIOS_TRUE; + } + } + else if(ulTimingBlock == 5) + { + pModeInfo = &(pDevCommon->EdidStruct.DisplayID_TYPE1_Timings[ulTmIdx]); + cbConvertEdidTimingToTableTiming(pcbe, pModeInfo, pTiming); + bFound = CBIOS_TRUE; + } + } + + if(!bFound) + { + pTimingTbl = AdapterTimingTbl; + NumOfTimings = sizeofarray(AdapterTimingTbl); + + //patch for HDMI 640*480@60HZ timing.When set 640*480 of DP and HDMI device,use HDMI timing table + //since AdapterTiming also have this mode + if((XRes== 640) && (YRes == 480) && (Refresh == 6000) + && (pMonitorAttr->IsCEA861HDMI)) + { + pTimingTbl = HDMIFormatTimingTbl; + NumOfTimings = sizeofarray(HDMIFormatTimingTbl); + } + } + + + if((!bFound)&& + (pTimingTbl != CBIOS_NULL)) + { + + for(i=0; ipHDMIFormatTable[i].Interlace == isInterlace)) + { + if (Refresh == 0) //default refrate + { + RefRateIndex = pcbe->pHDMIFormatTable[i].DefaultRefRateIndex; + bFound = CBIOS_TRUE; + } + else + { + for (RefRateIndex = 0; RefRateIndex < 2; RefRateIndex++) + { + RefRate = pcbe->pHDMIFormatTable[i].RefRate[RefRateIndex]; + if ((RefRate / 100) == (Refresh / 100)) + { + bFound = CBIOS_TRUE; + break; + } + } + } + + if (bFound) + { + break; //for (i = 0; i < NumOfTimings; i++) + } + }//if((pTiming[i].XResolution == pTmParam->XRes)... + }//for (i = 0; i < NumOfTimings; i++) + + if (bFound) + { + cb_memcpy(pTiming, &pTimingTbl[i], sizeof(CBIOS_TIMING_ATTRIB)); + + if ((RefRateIndex % 2) == 1)//fractional refreshrate + { + pTiming->PixelClock = pTiming->PixelClock / 1001UL * 1000UL; + pTiming->RefreshRate = (CBIOS_U16)((CBIOS_U32)pTiming->RefreshRate * 1000 / 1001); + } + } + } + + } + } + + if((!bFound) && (XRes != 0) && (YRes != 0) && (Refresh != 0)) + { + //Customize timing not support interlace mode. + //Timing value has no difference between interlace mode and non-interlace mode. + cbCalcCustomizedTiming(pcbe, XRes, YRes, Refresh, pTiming); + bFound = CBIOS_TRUE; + } + + if(!bFound) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbMode_GetHVTiming:Funtion failure!\n")); + } + + cbTraceExit(GENERIC); + + return bFound; +} + + +CBIOS_U32 cbMode_GetDefaultModeList(PCBIOS_VOID pvcbe, PCBiosModeInfoExt pModeList, CBIOS_ACTIVE_TYPE Device) +{ + CBIOS_U32 ulModeNum = 0; + CBIOS_U32 i = 0; + + switch(Device) + { + case CBIOS_TYPE_TV: + ulModeNum = sizeofarray(TV_DefaultModeList); + if (pModeList != CBIOS_NULL) + { + for (i = 0; i < ulModeNum; i++) + { + cbMode_AddMode(pModeList, &(TV_DefaultModeList[i]), i, Device); + } + } + break; + + case CBIOS_TYPE_HDTV: + ulModeNum = sizeofarray(HDTV_DefaultModeList); + if (pModeList != CBIOS_NULL) + { + for (i = 0; i < ulModeNum; i++) + { + cbMode_AddMode(pModeList, &(HDTV_DefaultModeList[i]), i, Device); + } + } + break; + + case CBIOS_TYPE_DSI: + ulModeNum = sizeofarray(DSI_DefaultModeList); + if (pModeList != CBIOS_NULL) + { + for (i = 0; i < ulModeNum; i++) + { + cbMode_AddMode(pModeList, &(DSI_DefaultModeList[i]), i, Device); + } + } + break; + + case CBIOS_TYPE_DP1: + case CBIOS_TYPE_DP2: + case CBIOS_TYPE_DP3: + case CBIOS_TYPE_DP4: + ulModeNum = sizeofarray(DP_DefaultModeList); + if (pModeList != CBIOS_NULL) + { + for (i = 0; i < ulModeNum; i++) + { + cbMode_AddMode(pModeList, &(DP_DefaultModeList[i]), i, Device); + } + } + break; + + case CBIOS_TYPE_MHL: + ulModeNum = sizeofarray(MHL_DefaultModeList); + if (pModeList != CBIOS_NULL) + { + for (i = 0; i < ulModeNum; i++) + { + cbMode_AddMode(pModeList, &(MHL_DefaultModeList[i]), i, Device); + } + } + break; + + case CBIOS_TYPE_DVO: + case CBIOS_TYPE_CRT: + default: + ulModeNum = sizeofarray(Device_DefaultModeList); + if (pModeList != CBIOS_NULL) + { + for (i = 0; i < ulModeNum; i++) + { + cbMode_AddMode(pModeList, &(Device_DefaultModeList[i]), i, Device); + } + } + break; + } + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbMode_GetDefaultModeList: Total mode num is %d!\n", ulModeNum)); + return ulModeNum; +} + + +// Get the mode counts from new CBIOS adapter mode timing table. +// This mode list does not include the interlace mode. +CBIOS_VOID cbMode_GetAdapterModeNum(PCBIOS_VOID pvcbe, CBIOS_U32* AdapterModeNum) +{ + CBIOS_U32 ulModeCount = sizeofarray(AdapterModeList); + + *AdapterModeNum = ulModeCount; + + return; +} + +CBIOS_STATUS cbMode_FillAdapterModeList(PCBIOS_VOID pvcbe, PCBiosModeInfoExt pModeList, CBIOS_U32 *pBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 ulAdapterModeCount = sizeofarray(AdapterModeList); + PCBiosModeInfoExt pAdapterModeList = AdapterModeList; + + CBIOS_U32 ulModeCount = 0, i = 0; + CBIOS_U32 XRes = 0, YRes = 0, RefRate = 0; + CBIOS_U32 ulTemp; + + if (pModeList == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbMode_FillAdapterModeList: pModeList is null.\n")); + return CBIOS_ER_NULLPOINTER; + } + + cb_memset(pModeList, 0, *pBufferSize); + + for (i = 0; i < ulAdapterModeCount; i++) + { + XRes = pAdapterModeList[i].XRes; + YRes = pAdapterModeList[i].YRes; + RefRate = pAdapterModeList[i].RefreshRate; + + // add registry to control some 120Hz modes + //such as 1024*768, 1280*1024, 1600*1200, 1920*1080 + if(pAdapterModeList[i].RefreshRate == 12000) + { + if (NO_ERROR == cb_GetRegistryParameters(pcbe->pAdapterContext, KEYNAME_DW_HARDCODED_SPECIALMODE, CBIOS_FALSE, &ulTemp)) + { + if(!ulTemp) + { + continue; + } + } + else + { + continue; + } + } + + cbMode_FillAdapterModeBuffer(pcbe, &pModeList[ulModeCount], XRes, YRes, RefRate); + ulModeCount++; + } + + *pBufferSize = ulModeCount*sizeof(CBiosModeInfoExt); + return CBIOS_OK; +} + + +CBIOS_VOID cbMode_GetFilterPara(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, PCBIOS_MODE_FILTER_PARA pFilter) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MONITOR_TYPE MonitorType = CBIOS_MONITOR_TYPE_NONE; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + PCBIOS_VOID pDPMonitorContext = CBIOS_NULL; + + + MonitorType = pDevCommon->CurrentMonitorType; + + switch(MonitorType) + { + case CBIOS_MONITOR_TYPE_DVI: + pFilter->MaxDclk = 1650000; + break; + case CBIOS_MONITOR_TYPE_HDMI: + pFilter->MaxDclk = pcbe->ChipLimits.ulMaxHDMIClock; + break; + case CBIOS_MONITOR_TYPE_MHL: + pFilter->MaxDclk = pcbe->ChipLimits.ulMaxMHLClock; + break; + case CBIOS_MONITOR_TYPE_DP: + pDPMonitorContext = cbGetDPMonitorContext(pcbe, pDevCommon); + pFilter->MaxDclk = cbDPMonitor_GetMaxSupportedDclk(pcbe, pDPMonitorContext); + break; + case CBIOS_MONITOR_TYPE_CRT: + pFilter->MaxDclk = 4000000; + break; + default: + pFilter->MaxDclk = 3300000; + break; + } + + if(pFilter->MaxDclk > pcbe->ChipLimits.ulMaxIGAClock) + { + pFilter->MaxDclk = pcbe->ChipLimits.ulMaxIGAClock; + } + + pFilter->bFilterInterlace = CBIOS_TRUE; +} + + +CBIOS_U32 cbMode_GetDeviceModeList(PCBIOS_VOID pvcbe, + CBIOS_ACTIVE_TYPE Device, + PCBiosModeInfoExt pModeList, + CBIOS_U32 *pBufferSize, + PCBIOS_MODE_FILTER_PARA pFilter) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + PCBIOS_EDID_STRUCTURE_DATA pEdidStruct = &(pDevCommon->EdidStruct); + + CBIOS_U32 i = 0; + CBIOS_U32 EstIndex = 0, StdIndex = 0, DtlIndex = 0, CEAIndex = 0, DTDIndex = 0, DIDT1Index = 0; + CBIOS_U32 ulModeNum = 0, MaxModeNum = 0, TotalModeCount = 0; + CBIOS_U8 byRefRateIndex = 0; + + CBIOS_U32 AspectRatioCaps = 0; + CBIOS_U32 IntProgCaps = 0; + CBIOS_U32 NativeModeFlags = 0; + CBIOS_U32 IsCEAMode = 0; + CBIOS_U32 PreferredModeFlags = 0; + + CBIOS_BOOL *pbModeUsed; + CBIOS_BOOL *pbEstModeUsed; + CBIOS_BOOL *pbStdModeUsed; + CBIOS_BOOL *pbDtlModeUsed; + CBIOS_BOOL *pbHDMIFormatUsed; + CBIOS_BOOL *pbDTDModeUsed; + CBIOS_BOOL *pbDisplayIDT1ModeUsed; + CBIOS_BOOL bFilterThisMode = CBIOS_FALSE; + + CBIOS_MODE_INFO_EXT MaxMode, tempBuffer,SupportedMaxMode = {0}; + CBiosModeInfoExt ModeToInsert = {0}; + CBIOS_TIMING_ATTRIB Timing = {0}; + CBIOS_MODE_TIMING_TYPE TimingType = CBIOS_MODE_NONEDID_TIMING, tempType, curType; + + if ((pModeList != CBIOS_NULL) && (pBufferSize != CBIOS_NULL)) + { + // calculate the mode num of buffer can contain + MaxModeNum = (*pBufferSize) / sizeof(CBiosModeInfoExt); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),"cbMode_GetDeviceModeList: BufferSize = %d. MaxModeNum = %d\n", *pBufferSize, MaxModeNum)); + } + + TotalModeCount = CBIOS_ESTABLISHMODECOUNT+CBIOS_STDMODECOUNT+CBIOS_DTLMODECOUNT+CBIOS_HDMIFORMATCOUNTS+CBIOS_DTDTIMINGCOUNTS+CBIOS_DISPLAYID_TYPE1_MODECOUNT; + pbModeUsed = cb_AllocateNonpagedPool(TotalModeCount*sizeof(CBIOS_BOOL)); + if(pbModeUsed == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"pbModeUsed allocate error.\n")); + return ulModeNum; + } + + for(i = 0; i < TotalModeCount; i++) + { + *(pbModeUsed+i) = CBIOS_FALSE; + } + pbEstModeUsed = pbModeUsed; + pbStdModeUsed = pbEstModeUsed + CBIOS_ESTABLISHMODECOUNT; + pbDtlModeUsed = pbStdModeUsed + CBIOS_STDMODECOUNT; + pbHDMIFormatUsed = pbDtlModeUsed + CBIOS_DTLMODECOUNT; + pbDTDModeUsed = pbHDMIFormatUsed + CBIOS_HDMIFORMATCOUNTS; + pbDisplayIDT1ModeUsed= pbDTDModeUsed + CBIOS_DTDTIMINGCOUNTS; + + SupportedMaxMode.XResolution = pDevCommon->MaxResConfig.MaxXRes; + SupportedMaxMode.YResolution = pDevCommon->MaxResConfig.MaxYRes; + SupportedMaxMode.Refreshrate = pDevCommon->MaxResConfig.MaxRefresh; + + ulModeNum = 0; + + while(CBIOS_TRUE) + { + EstIndex = 0xFF; + StdIndex = 0xFF; + DtlIndex = 0xFF; + CEAIndex = 0xFF; + DTDIndex = 0xFF; + DIDT1Index = 0xFF; + NativeModeFlags = CBIOS_NONNATIVEMODE; + PreferredModeFlags = CBIOS_NONPERFERREDMODE; + AspectRatioCaps = CBIOS_DEFAULTRATIO; + TimingType = CBIOS_MODE_NONEDID_TIMING; + IsCEAMode = 0; + bFilterThisMode = CBIOS_FALSE; + cb_memset(&MaxMode, 0, sizeof(CBIOS_MODE_INFO_EXT)); + cb_memset(&tempBuffer, 0, sizeof(CBIOS_MODE_INFO_EXT)); + + // Get the maximum mode sorted by X, Y, Refrsh Rate. + for(i=0; iEstTimings[i].Valid) && (EstModeSupportTbl[i]) && (!(*(pbEstModeUsed+i)))) + { + tempBuffer.XResolution = pEdidStruct->EstTimings[i].XResolution; + tempBuffer.YResolution = pEdidStruct->EstTimings[i].YResolution; + tempBuffer.Refreshrate = pEdidStruct->EstTimings[i].Refreshrate; + tempBuffer.InterLaced = CBIOS_FALSE; + + if ((cbMode_CompareMode(&tempBuffer, &MaxMode)) > 0) + { + MaxMode.XResolution = tempBuffer.XResolution; + MaxMode.YResolution = tempBuffer.YResolution; + MaxMode.Refreshrate = tempBuffer.Refreshrate; + MaxMode.InterLaced = tempBuffer.InterLaced; + cbMode_GetHVTiming(pcbe, + MaxMode.XResolution, + MaxMode.YResolution, + MaxMode.Refreshrate, + MaxMode.InterLaced, + Device, + &Timing); + MaxMode.PixelClock = Timing.PixelClock; + EstIndex = i; + TimingType = CBIOS_MODE_EST_TIMING; + } + } + } + for(i=0; iStdTimings[i].Valid) && (!(*(pbStdModeUsed+i)))) + { + tempBuffer.XResolution = pEdidStruct->StdTimings[i].XResolution; + tempBuffer.YResolution = pEdidStruct->StdTimings[i].YResolution; + tempBuffer.Refreshrate = pEdidStruct->StdTimings[i].Refreshrate; + tempBuffer.InterLaced = CBIOS_FALSE; + + if ((cbMode_CompareMode(&tempBuffer, &MaxMode)) > 0) + { + MaxMode.XResolution = tempBuffer.XResolution; + MaxMode.YResolution = tempBuffer.YResolution; + MaxMode.Refreshrate = tempBuffer.Refreshrate; + MaxMode.InterLaced = tempBuffer.InterLaced; + cbMode_GetHVTiming(pcbe, + MaxMode.XResolution, + MaxMode.YResolution, + MaxMode.Refreshrate, + MaxMode.InterLaced, + Device, + &Timing); + MaxMode.PixelClock = Timing.PixelClock; + StdIndex = i; + TimingType = CBIOS_MODE_STD_TIMING; + } + else if ((cbMode_CompareMode(&tempBuffer, &MaxMode)) == 0) + { + StdIndex = i; + TimingType |= CBIOS_MODE_STD_TIMING; + } + } + } + for(i=0; iDtlTimings[i].Valid)&&(!(*(pbDtlModeUsed + i)))) + { + if ((cbMode_CompareMode(&(pEdidStruct->DtlTimings[i]), &MaxMode)) > 0) + { + MaxMode.XResolution = pEdidStruct->DtlTimings[i].XResolution; + MaxMode.YResolution = pEdidStruct->DtlTimings[i].YResolution; + MaxMode.Refreshrate = pEdidStruct->DtlTimings[i].Refreshrate; + MaxMode.InterLaced = pEdidStruct->DtlTimings[i].InterLaced; + MaxMode.PixelClock = pEdidStruct->DtlTimings[i].PixelClock; + DtlIndex = i; + TimingType = CBIOS_MODE_DTL_TIMING; + } + else if ((cbMode_CompareMode(&(pEdidStruct->DtlTimings[i]), &MaxMode)) == 0) + { + DtlIndex = i; + TimingType |= CBIOS_MODE_DTL_TIMING; + } + } + } + if((pEdidStruct->Attribute.IsCEA861Monitor)|| + (pEdidStruct->Attribute.IsCEA861HDMI)) + { + for(i=0; iHDMIFormat[i].IsSupported) && + (pcbe->pHDMISupportedFormatTable[i]) && (!(*(pbHDMIFormatUsed+i)))) + { + byRefRateIndex = pEdidStruct->HDMIFormat[i].RefreshIndex % 2; + tempBuffer.XResolution = pcbe->pHDMIFormatTable[i].XRes; + tempBuffer.YResolution = pcbe->pHDMIFormatTable[i].YRes; + tempBuffer.Refreshrate = pcbe->pHDMIFormatTable[i].RefRate[byRefRateIndex]; + tempBuffer.InterLaced = pcbe->pHDMIFormatTable[i].Interlace; + + if ((cbMode_CompareMode(&tempBuffer, &MaxMode)) > 0) + { + MaxMode.XResolution = tempBuffer.XResolution; + MaxMode.YResolution = tempBuffer.YResolution; + MaxMode.Refreshrate = tempBuffer.Refreshrate; + MaxMode.InterLaced = tempBuffer.InterLaced; + cbMode_GetHVTiming(pcbe, + MaxMode.XResolution, + MaxMode.YResolution, + MaxMode.Refreshrate, + MaxMode.InterLaced, + Device, + &Timing); + MaxMode.PixelClock = Timing.PixelClock; + CEAIndex = i; + TimingType = CBIOS_MODE_SVD_TIMING; + } + else if((cbMode_CompareMode(&tempBuffer, &MaxMode)) == 0) + { + CEAIndex = i; + TimingType |= CBIOS_MODE_SVD_TIMING; + } + } + } + for (i = 0; i < CBIOS_DTDTIMINGCOUNTS; i++) + { + if((pEdidStruct->DTDTimings[i].Valid)&&(!(*(pbDTDModeUsed+i)))) + { + if ((cbMode_CompareMode(&(pEdidStruct->DTDTimings[i]), &MaxMode)) > 0) + { + MaxMode.XResolution = pEdidStruct->DTDTimings[i].XResolution; + MaxMode.YResolution = pEdidStruct->DTDTimings[i].YResolution; + MaxMode.Refreshrate = pEdidStruct->DTDTimings[i].Refreshrate; + MaxMode.InterLaced = pEdidStruct->DTDTimings[i].InterLaced; + MaxMode.PixelClock = pEdidStruct->DTDTimings[i].PixelClock; + DTDIndex = i; + TimingType = CBIOS_MODE_DTD_TIMING; + } + else if ((cbMode_CompareMode(&(pEdidStruct->DTDTimings[i]), &MaxMode)) == 0) + { + DTDIndex = i; + TimingType |= CBIOS_MODE_DTD_TIMING; + } + } + } + } + + for (i = 0; i < CBIOS_DISPLAYID_TYPE1_MODECOUNT; i++) + { + if((pEdidStruct->DisplayID_TYPE1_Timings[i].Valid)&&(!(*(pbDisplayIDT1ModeUsed+i)))) + { + if ((cbMode_CompareMode(&(pEdidStruct->DisplayID_TYPE1_Timings[i]), &MaxMode)) > 0) + { + MaxMode.XResolution = pEdidStruct->DisplayID_TYPE1_Timings[i].XResolution; + MaxMode.YResolution = pEdidStruct->DisplayID_TYPE1_Timings[i].YResolution; + MaxMode.Refreshrate = pEdidStruct->DisplayID_TYPE1_Timings[i].Refreshrate; + MaxMode.InterLaced = pEdidStruct->DisplayID_TYPE1_Timings[i].InterLaced; + MaxMode.PixelClock = pEdidStruct->DisplayID_TYPE1_Timings[i].PixelClock; + DIDT1Index = i; + TimingType = CBIOS_MODE_DISPLAYID_TYPE1_TIMING; + } + else if ((cbMode_CompareMode(&(pEdidStruct->DisplayID_TYPE1_Timings[i]), &MaxMode)) == 0) + { + DIDT1Index = i; + TimingType |= CBIOS_MODE_DISPLAYID_TYPE1_TIMING; + } + } + } + + if (MaxMode.InterLaced == CBIOS_TRUE) + { + IntProgCaps = CBIOS_INTERLACECAP; + } + else + { + IntProgCaps = CBIOS_PROGRESSIVECAP; + } + + tempType = TimingType; + while(tempType) + { + curType = GET_LAST_BIT(tempType); + switch (curType) + { + case CBIOS_MODE_DTD_TIMING: + + if (DTDIndex != 0xFF) + { + if (pEdidStruct->DTDTimings[DTDIndex].IsNativeMode) + { + NativeModeFlags |= CBIOS_NATIVEMODE; + } + + *(pbDTDModeUsed + DTDIndex) = CBIOS_TRUE; + } + tempType &= (~curType); + break; + + case CBIOS_MODE_SVD_TIMING: + + if (CEAIndex != 0xFF) + { + NativeModeFlags |= pEdidStruct->HDMIFormat[CEAIndex].IsNative; + + IsCEAMode = 1; //Means is a CE mode. + + if(pcbe->pHDMIFormatTable[CEAIndex].AspectRatio == 1) + { + AspectRatioCaps = CBIOS_ASPECTRATIOCAP4B3; + } + else if(pcbe->pHDMIFormatTable[CEAIndex].AspectRatio == 3) + { + AspectRatioCaps = CBIOS_ASPECTRATIOCAP64B27; + } + else if(pcbe->pHDMIFormatTable[CEAIndex].AspectRatio == 4) + { + AspectRatioCaps = CBIOS_ASPECTRATIOCAP256B135; + } + else + { + AspectRatioCaps = CBIOS_ASPECTRATIOCAP16B9; + } + *(pbHDMIFormatUsed+CEAIndex) = CBIOS_TRUE; + } + tempType &= (~curType); + break; + + case CBIOS_MODE_DTL_TIMING: + + if (DtlIndex != 0xFF) + { + if (pEdidStruct->DtlTimings[DtlIndex].IsNativeMode) + { + NativeModeFlags |= CBIOS_NATIVEMODE; + } + + if (DtlIndex == 0) + { + PreferredModeFlags = CBIOS_PERFERREDMODE; + } + + *(pbDtlModeUsed+DtlIndex) = CBIOS_TRUE; + } + tempType &= (~curType); + break; + + case CBIOS_MODE_STD_TIMING: + + if (StdIndex != 0xFF) + { + *(pbStdModeUsed+StdIndex) = CBIOS_TRUE; + } + tempType &= (~curType); + break; + + case CBIOS_MODE_EST_TIMING: + + if (EstIndex != 0xFF) + { + *(pbEstModeUsed+EstIndex) = CBIOS_TRUE; + } + tempType &= (~curType); + break; + + case CBIOS_MODE_DISPLAYID_TYPE1_TIMING: + + if(DIDT1Index != 0xFF) + { + *(pbDisplayIDT1ModeUsed + DIDT1Index) = CBIOS_TRUE; + } + tempType &= (~curType); + break; + + default: + tempType &= (~curType); + break; + } + } + + if ((DTDIndex == 0xFF) && + (CEAIndex == 0xFF) && + (DtlIndex == 0xFF) && + (StdIndex == 0xFF) && + (EstIndex == 0xFF) && + (DIDT1Index == 0xFF)) + { + break; + } + + // check whether to filter the mode + if ((pFilter->bFilterInterlace) && (MaxMode.InterLaced)) + { + bFilterThisMode = CBIOS_TRUE; + } + if (MaxMode.PixelClock > pFilter->MaxDclk) + { + bFilterThisMode = CBIOS_TRUE; + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "----Mode pixel clk(%d) greater than the max DClk(%d), filter this mode-----\n", + MaxMode.PixelClock, pFilter->MaxDclk)); + } + + if ((SupportedMaxMode.XResolution) && (SupportedMaxMode.YResolution) && (SupportedMaxMode.Refreshrate)) + { + if((MaxMode.XResolution > SupportedMaxMode.XResolution) || (MaxMode.YResolution > SupportedMaxMode.YResolution)) + { + bFilterThisMode = CBIOS_TRUE; + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),"cbMode_GetDeviceModeList: Filter mode %d x %d @ %d as it is greater than config max mode.\n", + MaxMode.XResolution, MaxMode.YResolution, MaxMode.Refreshrate)); + } + + if((MaxMode.XResolution == SupportedMaxMode.XResolution) && (MaxMode.YResolution == SupportedMaxMode.YResolution)) + { + if(MaxMode.Refreshrate > SupportedMaxMode.Refreshrate) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),"cbMode_GetDeviceModeList: Filter mode %d x %d @ %d as it is greater than config max mode.\n", + MaxMode.XResolution, MaxMode.YResolution, MaxMode.Refreshrate)); + bFilterThisMode = CBIOS_TRUE; + } + } + } + + if (!bFilterThisMode) + { + ulModeNum++; + ModeToInsert.XRes = MaxMode.XResolution; + ModeToInsert.YRes = MaxMode.YResolution; + ModeToInsert.RefreshRate = MaxMode.Refreshrate; + ModeToInsert.InterlaceProgressiveCaps = IntProgCaps; + ModeToInsert.AdapterDeviceFlags = CBIOS_DEVICEMODE; + ModeToInsert.DeviceFlags = Device; + ModeToInsert.ColorDepthCaps = CBIOS_COLORDEPTH16 | + CBIOS_COLORDEPTH32XRGB | + CBIOS_COLORDEPTH32ARGB | + CBIOS_COLORDEPTH32ABGR | + CBIOS_COLORDEPTH2101010ARGB | + CBIOS_COLORDEPTH2101010ABGR | + CBIOS_COLORDEPTH16161616ABGRF; + ModeToInsert.AspectRatioCaps = AspectRatioCaps; + ModeToInsert.NativeModeFlags = NativeModeFlags; + ModeToInsert.ModeFlags = IsCEAMode; + ModeToInsert.ModeFlags |= PreferredModeFlags; + ModeToInsert.ModeFlags |= (TimingType << 2); + + if (pModeList != CBIOS_NULL) // insert mode + { + // if space is enough, insert a item to mode list. + if( ulModeNum <= MaxModeNum) + { + if (!cbMode_AddMode(pModeList, &ModeToInsert, ulModeNum - 1, Device)) + { + //insert mode fail, decrease mode num + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbMode_GetDeviceModeList: add mode failed!\n")); + ulModeNum--; + } + + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbMode_GetDeviceModeList: buffer size for mode list is not enough!\n ulModeNum = %d MaxModeNum = %d\n", ulModeNum, MaxModeNum)); + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "DTDIndex = %d CEAIndex = %d DtlIndex = %d StdIndex = %d EstIndex = %d DIDT1Index = %d\n ", DTDIndex, CEAIndex, DtlIndex, StdIndex, EstIndex,DIDT1Index)); + ulModeNum--; + break; + } + } + + /********* + per CEA861-F spec + if A Video Timing with a vertical frequency that is an integer multiple of 6.00 Hz + (i.e., 24.00, 30.00, 60.00, 120.00 or 240.00 Hz) is considered to be the same as a + Video Timing with the equivalent detailed timing information but where the vertical + frequency is adjusted by a factor of 1000/1001 + + here Add 5994(6000) for 720X480, add 5994(6000) for 1280X720, add 5994(6000) and 2997(3000) for 1920X1080 mode + *********/ + if(Device & ALL_DP_TYPES) + { + cbMode_AddEquivalentDeviceMode(pModeList, &ulModeNum, &ModeToInsert, Device, MaxModeNum); + } + } + } + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbMode_GetDeviceModeList: Total mode num is %d!\n", ulModeNum)); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "pbModeUsed = 0x%08X\n", pbModeUsed)); + + cb_FreePool(pbModeUsed); + return ulModeNum; +} + + diff --git a/drivers/gpu/drm/arise/cbios/Display/CBiosMode.h b/drivers/gpu/drm/arise/cbios/Display/CBiosMode.h new file mode 100644 index 0000000000000..1f7e7e01b4211 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Display/CBiosMode.h @@ -0,0 +1,149 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + + +/***************************************************************************** +** DESCRIPTION: +** CBios mode module interface prototype and parameter definition. +** +** NOTE: +** The hw dependent function or structure SHOULD NOT be added to this file. +******************************************************************************/ + +#ifndef _CBIOS_MODE_H_ +#define _CBIOS_MODE_H_ + +#define CBIOS_PROGRESSIVECAP 0x01 +#define CBIOS_INTERLACECAP 0x02 +#define CBIOS_PROGRESSIVEVALUE 0x01 +#define CBIOS_INTERLACEVALUE 0x00 + +#define CBIOS_ADAPTERMODE 0 +#define CBIOS_DEVICEMODE 1 + +#define CBIOS_ASPECTRATIOCAP4B3 0x01 +#define CBIOS_ASPECTRATIOCAP16B9 0x02 +#define CBIOS_ASPECTRATIOCAP64B27 0x03 +#define CBIOS_ASPECTRATIOCAP256B135 0x04 +#define CBIOS_DEFAULTRATIO 0x00 + +#define CBIOS_NATIVEMODE 1 +#define CBIOS_NONNATIVEMODE 0 + +#define CBIOS_PERFERREDMODE BIT18 +#define CBIOS_NONPERFERREDMODE 0 + +typedef enum _CBIOS_MODE_TIMING_TYPE{ //can extend to support 14 different types + CBIOS_MODE_NONEDID_TIMING = 0x0000, //The mode is not from EDID + CBIOS_MODE_EST_TIMING = 0x0001, + CBIOS_MODE_STD_TIMING = 0x0002, + CBIOS_MODE_DTL_TIMING = 0x0004, + CBIOS_MODE_SVD_TIMING = 0x0008, //Detailed timing descriptor + CBIOS_MODE_DTD_TIMING = 0x0010, //CBIOS_S16 video descriptor + CBIOS_MODE_DISPLAYID_TYPE1_TIMING = 0x0020 +}CBIOS_MODE_TIMING_TYPE, *PCBIOS_MODE_TIMING_TYPE; + +typedef struct _CBIOS_MODE_INFO { + union { + struct { +#ifdef __BIG_ENDIAN__ + CBIOS_U16 XResolution; + CBIOS_U16 YResolution; +#else + CBIOS_U16 YResolution; + CBIOS_U16 XResolution; +#endif + }; + CBIOS_U32 XYResolution; + }; + CBIOS_U16 Refreshrate; + CBIOS_BOOL Valid; +}CBIOS_MODE_INFO, *PCBIOS_MODE_INFO; + +typedef struct _CBIOS_MODE_INFO_EXT { + union{ + struct{ +#ifdef __BIG_ENDIAN__ + union{ + CBIOS_U16 XResolution; + CBIOS_U16 HActive; + }; + union{ + CBIOS_U16 YResolution; + CBIOS_U16 VActive; + }; +#else + union{ + CBIOS_U16 YResolution; + CBIOS_U16 VActive; + }; + union{ + CBIOS_U16 XResolution; + CBIOS_U16 HActive; + }; +#endif + }; + CBIOS_U32 XYResolution; + }; + CBIOS_U16 HBlank; + CBIOS_U16 HSyncOffset; + CBIOS_U16 HSyncPulseWidth; + CBIOS_U16 VBlank; + CBIOS_U16 VSyncOffset; + CBIOS_U16 VSyncPulseWidth; + CBIOS_U16 HImageSize; + CBIOS_U16 VImageSize; + CBIOS_U32 PixelClock; + CBIOS_U16 Refreshrate; + CBIOS_BOOL Valid; + CBIOS_U8 InterLaced; + CBIOS_U8 VSync; + CBIOS_U8 HSync; + CBIOS_U8 AspectRatio; /* 0 means default, 1 means 4:3, 2 means 16:9 */ + CBIOS_U8 IsNativeMode; +}CBIOS_MODE_INFO_EXT, *PCBIOS_MODE_INFO_EXT; + +typedef struct _CBios_Equivalent_Device_Mode +{ + CBIOS_U32 XRes; + CBIOS_U32 YRes; + CBIOS_U32 RefRateRange[2]; + CBIOS_U32 RefRateToAdd; +}CBiosEquivalentDeviceMode, PCBiosEquivalentDeviceMode; + +typedef struct _CBIOS_MODE_FILTER_PARA{ + CBIOS_BOOL bFilterInterlace; + CBIOS_U32 MaxDclk; +}CBIOS_MODE_FILTER_PARA, *PCBIOS_MODE_FILTER_PARA; + + +CBIOS_BOOL cbMode_GetHVTiming(PCBIOS_VOID pvcbe, + CBIOS_U32 XRes, + CBIOS_U32 YRes, + CBIOS_U32 Refresh, + CBIOS_U32 isInterlace, + CBIOS_ACTIVE_TYPE Device, + PCBIOS_TIMING_ATTRIB pTiming); +CBIOS_U32 cbMode_GetDefaultModeList(PCBIOS_VOID pvcbe, PCBiosModeInfoExt pModeList, CBIOS_ACTIVE_TYPE Device); +CBIOS_VOID cbMode_GetAdapterModeNum(PCBIOS_VOID pvcbe, CBIOS_U32* AdapterModeNum); +CBIOS_STATUS cbMode_FillAdapterModeList(PCBIOS_VOID pvcbe, PCBiosModeInfoExt pModeList, CBIOS_U32 *pBufferSize); +CBIOS_VOID cbMode_GetFilterPara(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, PCBIOS_MODE_FILTER_PARA pFilter); +CBIOS_U32 cbMode_GetDeviceModeList(PCBIOS_VOID pvcbe, + CBIOS_ACTIVE_TYPE Device, + PCBiosModeInfoExt pModeList, + CBIOS_U32 *pBufferSize, + PCBIOS_MODE_FILTER_PARA pFilter); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.c b/drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.c new file mode 100644 index 0000000000000..8b9279ba34650 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.c @@ -0,0 +1,480 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios path manager interface function implementation. +** Generate display source path, DIU module index and devices combination. +** +** NOTE: +**The hw dependent function or structure SHOULD NOT be added to this file. +******************************************************************************/ + +#include "CBiosPathManager.h" +#include "CBiosChipShare.h" +#include "../Hw/HwBlock/CBiosDIU_HDCP.h" +#include "../Hw/HwBlock/CBiosDIU_HDTV.h" +#include "../Hw/HwBlock/CBiosDIU_HDMI.h" + + +CBIOS_STATUS cbPathMgrGetDevComb(PCBIOS_VOID pvcbe, PCBIOS_GET_DEV_COMB pDevComb) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMB pDeviceComb = pDevComb->pDeviceComb; + CBIOS_ACTIVE_TYPE Devices = pDeviceComb->Devices; + CBIOS_ACTIVE_TYPE TempDev = CBIOS_TYPE_NONE; + CBIOS_GET_IGA_MASK GetIgaMask = {0}; + CBIOS_U32 IgaMask = 0, IgaIndex = 0; + CBIOS_U32 DevOnIga[CBIOS_IGACOUNTS] = {0}; + CBIOS_BOOL bAssigned = CBIOS_FALSE; + + if (Devices == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Devices is NONE ! \n", FUNCTION_NAME)); + return CBIOS_OK; + } + + if (pcbe->bRunOnQT) + { + pDeviceComb->Iga1Dev = CBIOS_TYPE_CRT; + pDevComb->bSupported = CBIOS_TRUE; + + return CBIOS_OK; + } + + if ((cbGetBitsNum(Devices) > pcbe->DispMgr.IgaCount) || (Devices & ~(pcbe->DeviceMgr.SupportDevices))) + { + pDevComb->bSupported = CBIOS_FALSE; + return CBIOS_ER_INVALID_PARAMETER; + } + + GetIgaMask.Size = sizeof(CBIOS_GET_IGA_MASK); + while(Devices) + { + bAssigned = CBIOS_FALSE; + + //select a high priority device if more than one device + TempDev = cbDevGetPrimaryDevice(Devices); + Devices &= ~TempDev; + GetIgaMask.DeviceId = (CBIOS_U32)TempDev; + cbPathMgrGetIgaMask(pcbe, &GetIgaMask); + + IgaMask = GetIgaMask.IgaMask; + while(IgaMask) + { + IgaIndex = cbGetLastBitIndex(IgaMask); + IgaMask &= ~(1 << IgaIndex); + if(DevOnIga[IgaIndex] == CBIOS_TYPE_NONE) + { + DevOnIga[IgaIndex] = TempDev; + bAssigned = CBIOS_TRUE; + break; + } + } + + if (!bAssigned) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: Can't assign IGA for device: 0x%x\n", FUNCTION_NAME, TempDev)); + break; + } + } + + if(bAssigned) + { + pDeviceComb->Iga1Dev = DevOnIga[IGA1]; + pDeviceComb->Iga2Dev = DevOnIga[IGA2]; + pDeviceComb->Iga3Dev = DevOnIga[IGA3]; + pDeviceComb->Iga4Dev = DevOnIga[IGA4]; + pDevComb->bSupported = CBIOS_TRUE; + + return CBIOS_OK; + } + else + { + pDevComb->bSupported = CBIOS_FALSE; + return CBIOS_ER_INVALID_PARAMETER; + } + +} + +CBIOS_STATUS cbPathMgrGetIgaMask(PCBIOS_VOID pvcbe, PCBIOS_GET_IGA_MASK pGetIgaMask) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + if (pcbe->bRunOnQT) + { + pGetIgaMask->IgaMask = 1 << IGA1; + return CBIOS_OK; + } + + switch(pGetIgaMask->DeviceId) + { + case CBIOS_TYPE_DP1: + pGetIgaMask->IgaMask = 1 << IGA1; + break; + case CBIOS_TYPE_DP2: + pGetIgaMask->IgaMask = 1 << IGA2; + break; + case CBIOS_TYPE_DP3: + pGetIgaMask->IgaMask = 1 << IGA3; + break; + case CBIOS_TYPE_DP4: + pGetIgaMask->IgaMask = 1 << IGA4; + break; + case CBIOS_TYPE_CRT: + if(pcbe->DispMgr.IgaCount == 4) + { + pGetIgaMask->IgaMask = 1 << IGA4; + } + else if(pcbe->DispMgr.IgaCount == 3) + { + pGetIgaMask->IgaMask = 1 << IGA3; + } + else + { + pGetIgaMask->IgaMask = 1 << IGA2; + } + break; + default: + pGetIgaMask->IgaMask = (1 << IGA1) | (1 << IGA2) | (1 << IGA3) | (1 << IGA4); + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "%s: invalid device: 0x%x.\n", FUNCTION_NAME, pGetIgaMask->DeviceId)); + break; + } + + return CBIOS_OK; +} + + +static CBIOS_VOID cbPathMgrGeneratePath(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_DISPLAY_SOURCE *pSource) +{ + CBIOS_MODULE_LIST *pModuleList = CBIOS_NULL; + CBIOS_U32 index = 0; + + if (pSource == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return; + } + + pModuleList = &pSource->ModuleList; + + cb_memset(pSource->ModulePath, 0, sizeof(CBIOS_MODULE*) * CBIOS_MAX_MODULE_NUM); + if (pModuleList->HDCPModule.Index != CBIOS_MODULE_INDEX_INVALID) + { + pSource->ModulePath[index] = &pModuleList->HDCPModule; + index++; + } + + if (pModuleList->HDMIModule.Index != CBIOS_MODULE_INDEX_INVALID) + { + pSource->ModulePath[index] = &pModuleList->HDMIModule; + index++; + } + + if (pModuleList->HDTVModule.Index != CBIOS_MODULE_INDEX_INVALID) + { + pSource->ModulePath[index] = &pModuleList->HDTVModule; + index++; + } + + if (pModuleList->IGAModule.Index != CBIOS_MODULE_INDEX_INVALID) + { + pSource->ModulePath[index] = &pModuleList->IGAModule; + index++; + } +} + +CBIOS_VOID cbPathMgrSelectDIUPath(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U32 IGAIndex, PCBiosDestModeParams pDestModeParams, CBIOS_BOOL bForceHDTV) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_DISPLAY_SOURCE *pSrc = CBIOS_NULL; + CBIOS_BOOL isHDMIDevice = CBIOS_FALSE; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + CBIOS_U32 bInterlace = pDestModeParams->InterlaceFlag; + CBIOS_MODULE_INDEX ModuleIndex = CBIOS_MODULE_INDEX_INVALID; + pSrc = &(pDevCommon->DispSource); + + isHDMIDevice = pDevCommon->EdidStruct.Attribute.IsCEA861HDMI; + + if (IGAIndex == IGA1) + { + pSrc->ModuleList.IGAModule.Index = CBIOS_MODULE_INDEX1; + } + else if (IGAIndex == IGA2) + { + pSrc->ModuleList.IGAModule.Index = CBIOS_MODULE_INDEX2; + } + else if (IGAIndex == IGA3) + { + pSrc->ModuleList.IGAModule.Index = CBIOS_MODULE_INDEX3; + } + else if(IGAIndex == IGA4) + { + pSrc->ModuleList.IGAModule.Index = CBIOS_MODULE_INDEX4; + } + else + { + pSrc->ModuleList.IGAModule.Index = CBIOS_MODULE_INDEX_INVALID; + } + + switch (Device) + { + case CBIOS_TYPE_DP1: // currently DVI mode doesn't support interlaced timing + case CBIOS_TYPE_DP2: + case CBIOS_TYPE_DP3: + case CBIOS_TYPE_DP4: + ModuleIndex = CBIOS_MODULE_INDEX_INVALID; + if (Device == CBIOS_TYPE_DP1) + { + ModuleIndex = CBIOS_MODULE_INDEX1; + } + else if (Device == CBIOS_TYPE_DP2) + { + ModuleIndex = CBIOS_MODULE_INDEX2; + } + else if (Device == CBIOS_TYPE_DP3) + { + ModuleIndex = CBIOS_MODULE_INDEX3; + } + else if (Device == CBIOS_TYPE_DP4) + { + ModuleIndex = CBIOS_MODULE_INDEX4; + } + + pSrc->ModuleList.HDTVModule.Index = CBIOS_MODULE_INDEX_INVALID; + if (pDevCommon->CurrentMonitorType & (CBIOS_MONITOR_TYPE_HDMI | CBIOS_MONITOR_TYPE_DVI)) + { + if (isHDMIDevice) + { + pSrc->ModuleList.HDMIModule.Index = ModuleIndex; + if (Device == CBIOS_TYPE_DP1) + { + pSrc->ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX1; + } + else if (Device == CBIOS_TYPE_DP2) + { + pSrc->ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX2; + } + else + { + pSrc->ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX_INVALID; + } + + if(bForceHDTV || bInterlace || ((pDestModeParams->XRes == 720) && (pDestModeParams->YRes == 576))) + { + pSrc->ModuleList.HDTVModule.Index = ModuleIndex; + } + } + else + { + pSrc->ModuleList.HDMIModule.Index = ModuleIndex; + pSrc->ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX_INVALID; + } + } + else + { + pSrc->ModuleList.HDMIModule.Index = CBIOS_MODULE_INDEX_INVALID; + if (Device == CBIOS_TYPE_DP1) + { + pSrc->ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX1; + } + else if (Device == CBIOS_TYPE_DP2) + { + pSrc->ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX2; + } + else + { + pSrc->ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX_INVALID; + } + + if(bForceHDTV || bInterlace || ((pDestModeParams->XRes == 720) && (pDestModeParams->YRes == 576))) + { + pSrc->ModuleList.HDTVModule.Index = ModuleIndex; + } + } + cbPathMgrGeneratePath(pcbe, pSrc); + break; + case CBIOS_TYPE_MHL: // currently DVI mode doesn't support interlaced timing + pSrc->ModuleList.HDCPModule.Index = CBIOS_MODULE_INDEX1; + pSrc->ModuleList.HDTVModule.Index = CBIOS_MODULE_INDEX_INVALID; + + if (isHDMIDevice) + { + pSrc->ModuleList.HDMIModule.Index = CBIOS_MODULE_INDEX1; + pSrc->ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX1; + } + else + { + pSrc->ModuleList.HDMIModule.Index = CBIOS_MODULE_INDEX_INVALID; + pSrc->ModuleList.HDACModule.Index = CBIOS_MODULE_INDEX_INVALID; + } + + cbPathMgrGeneratePath(pcbe, pSrc); + break; + case CBIOS_TYPE_CRT: + case CBIOS_TYPE_DVO: + case CBIOS_TYPE_DSI: + cbPathMgrGeneratePath(pcbe, pSrc); + break; + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: invalid device type: 0x%x.\n", FUNCTION_NAME, Device)); + return; + } + + pSrc->bIsSrcChanged = CBIOS_TRUE; +} + + +CBIOS_MODULE_INDEX cbGetModuleIndex(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_MODULE_TYPE ModuleType) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MODULE_INDEX ModuleIndex = CBIOS_MODULE_INDEX_INVALID; + CBIOS_DISPLAY_SOURCE *pSource = CBIOS_NULL; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + + if (pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDevCommon is NULL!\n", FUNCTION_NAME)); + return ModuleIndex; + } + + pSource = &(pDevCommon->DispSource); + + switch (ModuleType) + { + case CBIOS_MODULE_TYPE_DP: + ModuleIndex = pSource->ModuleList.DPModule.Index; + break; + case CBIOS_MODULE_TYPE_MHL: + ModuleIndex = pSource->ModuleList.MHLModule.Index; + break; + case CBIOS_MODULE_TYPE_HDMI: + ModuleIndex = pSource->ModuleList.HDMIModule.Index; + break; + case CBIOS_MODULE_TYPE_HDTV: + ModuleIndex = pSource->ModuleList.HDTVModule.Index; + break; + case CBIOS_MODULE_TYPE_HDCP: + ModuleIndex = pSource->ModuleList.HDCPModule.Index; + break; + case CBIOS_MODULE_TYPE_HDAC: + ModuleIndex = pSource->ModuleList.HDACModule.Index; + break; + case CBIOS_MODULE_TYPE_IGA: + ModuleIndex = pSource->ModuleList.IGAModule.Index; + break; + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid module type: %d!\n", FUNCTION_NAME, ModuleType)); + break; + } + + if (ModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "%s: invalid module index of module: %d!\n", FUNCTION_NAME, ModuleType)); + } + + return ModuleIndex; +} + + +CBIOS_BOOL cbPathMgrModuleOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE **pModulePath, CBIOS_BOOL bTurnOn) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 i = 0; + + if ((pModulePath == CBIOS_NULL) || (*pModulePath == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: the 2nd param is null!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + if (bTurnOn) + { + while (pModulePath[i]) + { + ++i; + } + --i; + } + + while (pModulePath[i]) + { + switch (pModulePath[i]->Type) + { + case CBIOS_MODULE_TYPE_HDMI: + cbDIU_HDMI_ModuleOnOff(pcbe, pModulePath[i]->Index, bTurnOn); + break; + case CBIOS_MODULE_TYPE_HDTV: + cbDIU_HDTV_ModuleOnOff(pcbe, pModulePath[i]->Index, bTurnOn); + break; + case CBIOS_MODULE_TYPE_HDCP: + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "%s: module %d does not need to be on/ff here!\n", FUNCTION_NAME, pModulePath[i]->Index)); + break; + } + + if (bTurnOn) + { + if (i) + { + --i; + } + else + { + break; + } + } + else + { + ++i; + } + } + return CBIOS_TRUE; +} + +CBIOS_BOOL cbPathMgrSelectDIUSource(PCBIOS_VOID pvcbe, CBIOS_DISPLAY_SOURCE *pSource) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MODULE *pCurModule = CBIOS_NULL; + CBIOS_MODULE *pNextModule = CBIOS_NULL; + CBIOS_U32 i = 0; + + if (pSource == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is null!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + while (pSource->ModulePath[i]) + { + pCurModule = pSource->ModulePath[i]; + pNextModule = pSource->ModulePath[i + 1]; + + switch (pCurModule->Type) + { + case CBIOS_MODULE_TYPE_HDMI: + cbDIU_HDMI_SelectSource(pcbe, pCurModule, pNextModule); + break; + case CBIOS_MODULE_TYPE_HDCP: + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "%s: module %d does not need to select source here!\n", FUNCTION_NAME, pCurModule->Index)); + break; + } + i++; + } + + return CBIOS_TRUE; +} + diff --git a/drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.h b/drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.h new file mode 100644 index 0000000000000..a27d2d6e634d3 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.h @@ -0,0 +1,88 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios path manager interface function prototype. +** +** NOTE: +**The hw dependent function or structure SHOULD NOT be added to this file. +******************************************************************************/ + +#ifndef _CBIOS_PATH_MANAGER_H_ +#define _CBIOS_PATH_MANAGER_H_ + +#include "../Device/CBiosShare.h" + +//*************************************************************** +// DIU module definition +//*************************************************************** +#define CBIOS_MAX_MODULE_NUM 16 + +typedef enum _CBIOS_MODULE_TYPE +{ + CBIOS_MODULE_TYPE_NONE, + CBIOS_MODULE_TYPE_DP, + CBIOS_MODULE_TYPE_MHL, + CBIOS_MODULE_TYPE_HDMI, + CBIOS_MODULE_TYPE_HDTV, + CBIOS_MODULE_TYPE_HDCP, + CBIOS_MODULE_TYPE_HDAC, + CBIOS_MODULE_TYPE_IGA +}CBIOS_MODULE_TYPE, *PCBIOS_MODULE_TYPE; + +typedef enum _CBIOS_MODULE_INDEX +{ + CBIOS_MODULE_INDEX1, + CBIOS_MODULE_INDEX2, + CBIOS_MODULE_INDEX3, + CBIOS_MODULE_INDEX4, + CBIOS_MODULE_NUM, + CBIOS_MODULE_INDEX_INVALID = 0xFF +}CBIOS_MODULE_INDEX, *PCBIOS_MODULE_INDEX; + +typedef struct _CBIOS_MODULE +{ + CBIOS_MODULE_TYPE Type; + CBIOS_MODULE_INDEX Index; +}CBIOS_MODULE, *PCBIOS_MODULE; + +typedef struct _CBIOS_MODULE_LIST +{ + CBIOS_MODULE DPModule; + CBIOS_MODULE MHLModule; + + CBIOS_MODULE HDCPModule; + CBIOS_MODULE HDMIModule; + CBIOS_MODULE HDACModule; + CBIOS_MODULE HDTVModule; + CBIOS_MODULE IGAModule; +}CBIOS_MODULE_LIST, *PCBIOS_MODULE_LIST; + +typedef struct _CBIOS_DISPLAY_SOURCE +{ + CBIOS_MODULE_LIST ModuleList; + CBIOS_MODULE *ModulePath[CBIOS_MAX_MODULE_NUM]; // Link modules from PHY module to IGA module + CBIOS_BOOL bIsSrcChanged; // If any parameters listed above changes, this variable must be set to CBIOS_TRUE + // When source is updated, this variable will be set to CBIOS_FALSE +}CBIOS_DISPLAY_SOURCE, *PCBIOS_DISPLAY_SOURCE; + +CBIOS_STATUS cbPathMgrGetDevComb(PCBIOS_VOID pvcbe, PCBIOS_GET_DEV_COMB pDevComb); +CBIOS_STATUS cbPathMgrGetIgaMask(PCBIOS_VOID pvcbe, PCBIOS_GET_IGA_MASK pGetIgaMask); +CBIOS_VOID cbPathMgrSelectDIUPath(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U32 IGAIndex, PCBiosDestModeParams pDestModeParams, CBIOS_BOOL bForceHDTV); +CBIOS_MODULE_INDEX cbGetModuleIndex(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_MODULE_TYPE ModuleType); +CBIOS_BOOL cbPathMgrSelectDIUSource(PCBIOS_VOID pvcbe, CBIOS_DISPLAY_SOURCE *pSource); +CBIOS_BOOL cbPathMgrModuleOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE **pModulePath, CBIOS_BOOL bTurnOn); +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/Arise/CBiosVCP_Arise.c b/drivers/gpu/drm/arise/cbios/Hw/Arise/CBiosVCP_Arise.c new file mode 100644 index 0000000000000..2b7c9cb1005bd --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Arise/CBiosVCP_Arise.c @@ -0,0 +1,665 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** VCP functions implementation. Initailize VCP structure. +** +** NOTE: +** The functions in this file are hw layer internal functions, +** CAN ONLY be called by files under Hw folder. +******************************************************************************/ + +#include "CBios_Arise.h" +#include "CBiosVCP_Arise.h" + +// these macro start with 'VBIOS_' should consistent with VBIOS code +#define VBIOS_TBL_REGMASK 0x0F +#define VBIOS_TBL_BITMASK 0x40 +#define VBIOS_TBL_INITDATA 0x20 +#define VBIOS_TBL_TABLINK 0x10 +#define VBIOS_CR_REG 0x0 +#define VBIOS_SR_REG 0x1 +#define VBIOS_GR_REG 0x2 +#define VBIOS_MISC_REG 0x3 +#define VBIOS_AR_REG 0x4 +#define VBIOS_CR_P_REG 0x5 +#define VBIOS_SR_P_REG 0x6 +#define VBIOS_CR_B_REG 0x7 +#define VBIOS_CR_C_REG 0x8 +#define VBIOS_CR_D_REG 0x0B +#define VBIOS_SR_B_REG VBIOS_SR_P_REG + +#define VCP_CRT_CHAR_BYTE 0x04 +#define VCP_DP1_DUAL_MODE_CHAR_BYTE 0x00 +#define VCP_DP2_DUAL_MODE_CHAR_BYTE 0x01 +#define VCP_DP3_DUAL_MODE_CHAR_BYTE 0x02 // need refine +#define VCP_DP4_DUAL_MODE_CHAR_BYTE 0x03 // need refine +#define VCP_DVO_CHAR_BYTE 0x0C + +#define VCP_CRT_CHAR_BYTE_E2 0x00 +#define VCP_DP5_DUAL_MODE_CHAR_BYTE_E2 0x02 +#define VCP_DP6_DUAL_MODE_CHAR_BYTE_E2 0x03 +#define VCP_DVO_CHAR_BYTE_E2 0x0C + +static CBIOS_U16 VCP_Length = 0x100; +static CBIOS_U32 VCP_BiosVersion = 0x1A110000; +static CBIOS_U8 VCP_Version = 0x00; +static CBIOS_U16 VCP_SubVendorID = 0x6766; +static CBIOS_U16 VCP_SubSystemID = 0x3D02; +static CBIOS_U32 VCP_SupportDevices = CBIOS_TYPE_DP1 | CBIOS_TYPE_CRT; +static CBIOS_FEATURE_SWITCH VCP_FeatureSwitch = {0}; +static CBIOS_U8 VCP_CRTInterruptPort = 0x0F; +static CBIOS_U8 VCP_DVOInterruptPort = 0x0F; +static CBIOS_U8 VCP_GpioForEDP1Power = 0x0F; +static CBIOS_U8 VCP_GpioForEDP1BackLight = 0x0F; +static CBIOS_U8 VCP_GpioForEDP2Power = 0x0F; +static CBIOS_U8 VCP_GpioForEDP2BackLight = 0x0F; +static CBIOS_U32 VCP_EClock = 5000000; +static CBIOS_U32 VCP_EVcoLow = 12000000; +static CBIOS_U32 VCP_DVcoLow = 12000000; +static CBIOS_U8 VCP_SLICE_NUM = 2; + +//variable VCP data region start, add variable VCP data below +CBIOS_U16 VCP_BOOT_DEVICES_PRIORITY[] = +{ + VBIOS_TYPE_DP1, + VBIOS_TYPE_DP2, + VBIOS_TYPE_DVO, + VBIOS_TYPE_CRT, + 0xFFFF, +}; + +CBREGISTER VCP_CR_DEFAULT_TABLE[] = +{ + {CR, (CBIOS_U8)~0xFF, 0x45, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0x52, 0x00}, + {CR, (CBIOS_U8)~0xD8, 0x63, 0x00}, + {CR, (CBIOS_U8)~0x06, 0x67, 0x02}, + {CR, (CBIOS_U8)~0xFF, 0x6D, 0x33}, + {CR, (CBIOS_U8)~0xFF, 0x6E, 0x00}, + {CR, (CBIOS_U8)~0x22, 0x71, 0x22}, + {CR, (CBIOS_U8)~0xFF, 0x86, 0xA8}, + {CR, (CBIOS_U8)~0xFF, 0x87, 0x68}, + {CR, (CBIOS_U8)~0xFF, 0x88, 0x20}, + {CR, (CBIOS_U8)~0xFF, 0x89, 0xE0}, + {CR, (CBIOS_U8)~0xFF, 0x8D, 0x68}, + {CR, (CBIOS_U8)~0xFF, 0xBC, 0x20}, + {CR, (CBIOS_U8)~0xFF, 0xBD, 0xA8}, + {CR, (CBIOS_U8)~0xFF, 0xBE, 0x08}, + {CR, (CBIOS_U8)~0xFF, 0xC0, 0x24}, + {CR_B, (CBIOS_U8)~0x22, 0x71, 0x22}, + {CR_B, (CBIOS_U8)~0xFF, 0x45, 0x00}, + {CR_B, (CBIOS_U8)~0xFF, 0xC0, 0x7F}, + {CR_B, (CBIOS_U8)~0xFF, 0xC1, 0x7F}, + {CR_B, (CBIOS_U8)~0xFF, 0xC4, 0x00}, + {CR_B, (CBIOS_U8)~0xFF, 0xF5, 0x00}, + {CR_B, (CBIOS_U8)~0xFF, 0xF6, 0x00}, + {CR_B, (CBIOS_U8)~0xFF, 0xFC, 0x00}, + {CR_C, (CBIOS_U8)~0xFF, 0x4F, 0xFF}, + {CR_C, (CBIOS_U8)~0x04, 0x53, 0x04}, + {CR_C, (CBIOS_U8)~0xFF, 0x72, 0x20}, + {CR_C, (CBIOS_U8)~0x0F, 0x88, 0x00}, + {CR_C, (CBIOS_U8)~0x04, 0x9D, 0x04}, + {CR_C, (CBIOS_U8)~0x1F, 0xA0, 0x00}, + {CR_C, (CBIOS_U8)~0xC3, 0xA3, 0x00}, + {CR_C, (CBIOS_U8)~0x80, 0xA4, 0x00}, + {CR_C, (CBIOS_U8)~0xF0, 0xA5, 0x00}, + {CR_C, (CBIOS_U8)~0x1E, 0xC2, 0x00}, + {CR_C, (CBIOS_U8)~0x08, 0x70, 0x08}, + {0xFF}, +}; + + +CBREGISTER VCP_SR_DEFAULT_TABLE[] = +{ + {SR, (CBIOS_U8)~0xE0, 0x09, 0x60}, + {SR, (CBIOS_U8)~0x8D, 0x0B, 0x00}, + {SR, (CBIOS_U8)~0xF7, 0x0D, 0x50}, + {SR, (CBIOS_U8)~0xFF, 0x0E, 0xC1}, + {SR, (CBIOS_U8)~0xFF, 0x0F, 0x6B}, + {SR, (CBIOS_U8)~0xDF, 0x14, 0x00}, + {SR, (CBIOS_U8)~0x6E, 0x15, 0x4A}, + {SR, (CBIOS_U8)~0x20, 0x18, 0x20}, + {SR, (CBIOS_U8)~0xFF, 0x19, 0x31}, + {SR, (CBIOS_U8)~0x67, 0x1D, 0x67}, + {SR, (CBIOS_U8)~0x67, 0x1E, 0x00}, + {SR, (CBIOS_U8)~0x01, 0x1F, 0x00}, + {SR, (CBIOS_U8)~0xFF, 0x20, 0x7F}, + {SR, (CBIOS_U8)~0xFF, 0x21, 0xCE}, + {SR, (CBIOS_U8)~0xE7, 0x10, 0x84}, + {SR, (CBIOS_U8)~0x7F, 0x22, 0x0E}, + {SR, (CBIOS_U8)~0xFF, 0x23, 0xE8}, + {SR, (CBIOS_U8)~0xFF, 0x24, 0x10}, + {SR, (CBIOS_U8)~0xFF, 0x25, 0xC8}, + {SR, (CBIOS_U8)~0x80, 0x26, 0x00}, + {SR, (CBIOS_U8)~0xFF, 0x27, 0xB3}, + {SR, (CBIOS_U8)~0xFF, 0x29, 0x00}, + {SR, (CBIOS_U8)~0xFF, 0x2B, 0x00}, + {SR, (CBIOS_U8)~0xD0, 0x2D, 0x00}, + {SR, (CBIOS_U8)~0x3F, 0x30, 0x01}, + {SR, (CBIOS_U8)~0x01, 0x32, 0x00}, + {SR, (CBIOS_U8)~0x80, 0x33, 0x80}, + {SR, (CBIOS_U8)~0xF0, 0x39, 0x30}, + {SR, (CBIOS_U8)~0x18, 0x3C, 0x18}, + {SR, (CBIOS_U8)~0xE4, 0x31, 0x00}, + {SR, (CBIOS_U8)~0x3F, 0x3F, 0x00}, + {SR, (CBIOS_U8)~0xFF, 0x42, 0x01}, + {SR, (CBIOS_U8)~0xFF, 0x43, 0x01}, + {SR, (CBIOS_U8)~0x88, 0x44, 0x80}, + {SR, (CBIOS_U8)~0x1B, 0x45, 0x00}, + {SR, (CBIOS_U8)~0xFF, 0x47, 0x01}, + {0xFF}, +}; + + + +#ifndef _CBIOS_BUILD_VCP_BIN_FILE + +CBIOS_U32 cbGetDefaultRegTblSize(CBREGISTER* pRegTable) +{ + CBIOS_U32 Table_Size = 0, i = 0; + CBREGISTER* pReg = pRegTable; + + for (i = 0; i < VCP_MAX_REG_TABLE_SIZE ; i++) + { + if (pReg->type != 0xFF) + { + Table_Size++; + pReg++; + } + else + { + break; + } + } + + return Table_Size; +} + +CBIOS_U32 cbGetBootDevPrioritySize(PCBIOS_U16 pVCPBootDevPriority) +{ + CBIOS_U32 Size = 0; + while((*pVCPBootDevPriority) != 0xFFFF) + { + Size ++; + pVCPBootDevPriority ++; + + if (Size >= 16) + break; + } + return Size; +} + + +//----------------------------------------------------------------------// +// CBIOS_U32 cbGetVCPRegTbl_dst( ) +// +// Convert BIOS VCP ROM image to our register table +// 1) Get the number of register lenght +// 2) Copy the register value over to our reg table +// +//-----------------------------------------------------------------------// +CBIOS_U32 cbGetRomRegTbl(PCBIOS_VOID VCPBase, CBIOS_U16 TblOffset, CBREGISTER** pRegTable) +{ + CBIOS_U8* pVCPTblBase; + CBIOS_U8* pBYTE; + CBIOS_U8* pHead; + CBIOS_U32 RegCounter = 0; + CBIOS_U32 ItemLength = 0; + CBIOS_U32 i,Count; + CBIOS_U8 regtype = 0; + CBREGISTER* pReg; + + pVCPTblBase = (PCBIOS_U8)VCPBase + TblOffset - VCP_OFFSET; + + // 1.scan table to get memory size. + pBYTE = pVCPTblBase; + do{ + // BIOS table format + // flags in head(REGTYPE + BITMASK + INITDATA + TABLINK) + pHead = pBYTE; + + ItemLength = 1; //always has index + if(*pHead & VBIOS_TBL_BITMASK) //include Mask + ItemLength++; + if(*pHead & VBIOS_TBL_INITDATA) //include value + ItemLength++; + + // The next member will indicate the # of registers + // number of regs in this table + Count = *(pHead + 1); + RegCounter += Count; //total regs + + //point to next table + pBYTE += 1 + 1 + ItemLength*Count; //head+count+regs + }while(*pHead & VBIOS_TBL_TABLINK); + + // 2. Allocate memory + if(RegCounter == 0) + return RegCounter; + pReg = *pRegTable = cb_AllocateNonpagedPool(RegCounter * sizeof(CBREGISTER)); + if(pReg == CBIOS_NULL) + { + cbDebugPrint((1,"pRegTable allocate error!\n")); + return 0; + } + + // 3. Fill reg table + pBYTE = pVCPTblBase; + + do{ + pHead = pBYTE; + + switch(*pHead & VBIOS_TBL_REGMASK) + { + case VBIOS_CR_REG: + regtype = CR; + break; + case VBIOS_SR_REG: + regtype = SR; + break; + case VBIOS_GR_REG: + regtype = GR; + break; + case VBIOS_MISC_REG: + regtype = MISC; + break; + case VBIOS_AR_REG: + regtype = AR; + break; + case VBIOS_CR_P_REG: + case VBIOS_CR_B_REG: + regtype = CR_B; + break; + case VBIOS_SR_B_REG: + regtype = SR_B; + break; + case VBIOS_CR_C_REG: + regtype = CR_C; + break; + case VBIOS_CR_D_REG: + regtype = CR_D; + break; + } + + pBYTE++; + + Count = *(pBYTE++); + + for(i = 0;itype = regtype; + + pReg->index = *(pBYTE++); + + if(*pHead & VBIOS_TBL_BITMASK) + pReg->mask = ~(*(pBYTE++)); + else + pReg->mask = 0x00; + + if(*pHead & VBIOS_TBL_INITDATA) + pReg->value = *(pBYTE++); + else + pReg->value = 0x00; + + pReg++; + } + + }while(*pHead & VBIOS_TBL_TABLINK); + + return RegCounter; +} + +CBIOS_VOID cbLoadDefaultVCPData(PVCP_INFO pVCP, CBIOS_U32 rom_len) +{ + pVCP->VCPlength = VCP_Length; + pVCP->BiosVersion = VCP_BiosVersion; + pVCP->Version = VCP_Version; + pVCP->SubVendorID = VCP_SubVendorID; + pVCP->SubSystemID = VCP_SubSystemID; + pVCP->SupportDevices = VCP_SupportDevices; + + cb_memcpy(&pVCP->FeatureSwitch, &VCP_FeatureSwitch, sizeof(CBIOS_FEATURE_SWITCH)); + + pVCP->CRTCharByte = (CBIOS_U8)VCP_CRT_CHAR_BYTE; + pVCP->DP1DualModeCharByte = (CBIOS_U8)VCP_DP1_DUAL_MODE_CHAR_BYTE; + pVCP->DP2DualModeCharByte = (CBIOS_U8)VCP_DP2_DUAL_MODE_CHAR_BYTE; + pVCP->DP3DualModeCharByte = (CBIOS_U8)VCP_DP3_DUAL_MODE_CHAR_BYTE; + pVCP->DP4DualModeCharByte = (CBIOS_U8)VCP_DP4_DUAL_MODE_CHAR_BYTE; + pVCP->DVOCharByte = (CBIOS_U8)VCP_DVO_CHAR_BYTE; + + pVCP->CRTInterruptPort = VCP_CRTInterruptPort; + pVCP->DVOInterruptPort = VCP_DVOInterruptPort; + pVCP->GpioForEDP1Power = VCP_GpioForEDP1Power; + pVCP->GpioForEDP1BackLight = VCP_GpioForEDP1BackLight; + pVCP->GpioForEDP2Power = VCP_GpioForEDP2Power; + pVCP->GpioForEDP2BackLight = VCP_GpioForEDP2BackLight; + + pVCP->EClock = VCP_EClock; + pVCP->EVcoLow = VCP_EVcoLow; + pVCP->DVcoLow = VCP_DVcoLow; + + pVCP->SliceNum = VCP_SLICE_NUM; + + pVCP->sizeofBootDevPriority = cbGetBootDevPrioritySize(VCP_BOOT_DEVICES_PRIORITY); + pVCP->sizeofCR_DEFAULT_TABLE = cbGetDefaultRegTblSize(VCP_CR_DEFAULT_TABLE); + pVCP->sizeofSR_DEFAULT_TABLE = cbGetDefaultRegTblSize(VCP_SR_DEFAULT_TABLE); + pVCP->pCR_DEFAULT_TABLE = cb_AllocateNonpagedPool(sizeof(VCP_CR_DEFAULT_TABLE)); + pVCP->pSR_DEFAULT_TABLE = cb_AllocateNonpagedPool(sizeof(VCP_SR_DEFAULT_TABLE)); + cb_memcpy(pVCP->pCR_DEFAULT_TABLE, VCP_CR_DEFAULT_TABLE, sizeof(VCP_CR_DEFAULT_TABLE)); + cb_memcpy(pVCP->pSR_DEFAULT_TABLE, VCP_SR_DEFAULT_TABLE, sizeof(VCP_SR_DEFAULT_TABLE)); + + //Note: temp fix for arise1020 can not get the rom image + if (0x100000 == rom_len) + { + pVCP->FeatureSwitch.bNonSimulChip = 1; + pVCP->FeatureSwitch.IsDisableCodec2 = 1; + pVCP->FeatureSwitch.IsEclkConfigEnable = 1; + } + +} + + +CBIOS_VOID cbParseVCPInfo(PCBIOS_EXTENSION_COMMON pcbe, PVCP_INFO pVCP, PVCP_INIT_DATA pVCPInitData, PCBIOS_VOID VCPBase, CBIOS_U32 RomLength) +{ + CBIOS_U32 i = 0; + PCBIOS_U16 pVCP_BootDevPriorityAddr = CBIOS_NULL; + PCBIOS_U8 pByte = CBIOS_NULL; + VCP_FEATURESWITCH FeatureSwitch = {0}; + VCP_EDP_POWERCONFIG eDPPowerConfig = {0}; + + pVCP->Version = pVCPInitData->VCP_Version; + pVCP->VCPlength = cb_swab16(pVCPInitData->VCP_Length); + pVCP->BiosVersion = cb_swab32(pVCPInitData->VCP_BiosVersion); + pVCP->SubVendorID = cb_swab16(pVCPInitData->VCP_SubVendorID); + pVCP->SubSystemID = cb_swab16(pVCPInitData->VCP_SubSystemID); + pVCP->SupportDevices = cb_swab16(pVCPInitData->VCP_SupportDevices); + pVCP->SupportDevices = cbConvertVBiosDevBit2CBiosDevBit(pVCP->SupportDevices); + + // feature switch + FeatureSwitch = cb_swab32(pVCPInitData->VCP_FeatureSwitch); + pVCP->FeatureSwitch.IsEDP1Enabled = FeatureSwitch.IsEDP1Enabled; + pVCP->FeatureSwitch.IsEDP2Enabled = FeatureSwitch.IsEDP2Enabled; + pVCP->FeatureSwitch.IsDisableCodec1 = FeatureSwitch.IsDisableCodec1; + pVCP->FeatureSwitch.IsDisableCodec2 = FeatureSwitch.IsDisableCodec2; + pVCP->FeatureSwitch.HPDActiveHighEnable = FeatureSwitch.HPDActiveHighEnable; + pVCP->FeatureSwitch.BIUBackdoorEnable = FeatureSwitch.IsBIUBackdoorEnable; + pVCP->FeatureSwitch.bNonSimulChip = FeatureSwitch.NonSimulateChip; + + eDPPowerConfig = cb_swab32(pVCPInitData->VCP_EDPPowerConfig); + pVCP->GpioForEDP1Power = eDPPowerConfig.eDP1PowerCtrlGPIO; + pVCP->GpioForEDP2Power = eDPPowerConfig.eDP2PowerCtrlGPIO; + pVCP->GpioForEDP1BackLight = eDPPowerConfig.eDP1BackLightGPIO; + pVCP->GpioForEDP2BackLight = eDPPowerConfig.eDP2BackLightGPIO; + + pVCP->CRTCharByte = (CBIOS_U8)(pVCPInitData->VCP_PortConfig.DACCharByte); + if (pVCP->CRTCharByte == 0x0F) + { + pVCP->CRTCharByte = I2CBUS_INVALID; + } + + pVCP->DP1DualModeCharByte = (CBIOS_U8)(pVCPInitData->VCP_PortConfig.DP1DualModeCharByte); + if (pVCP->DP1DualModeCharByte == 0x0F) + { + pVCP->DP1DualModeCharByte = I2CBUS_INVALID; + } + + pVCP->DP2DualModeCharByte = (CBIOS_U8)(pVCPInitData->VCP_PortConfig.DP2DualModeCharByte); + if (pVCP->DP2DualModeCharByte == 0x0F) + { + pVCP->DP2DualModeCharByte = I2CBUS_INVALID; + } + + pVCP->DP3DualModeCharByte = (CBIOS_U8)(pVCPInitData->VCP_PortConfig.DP3DualModeCharByte); + if (pVCP->DP3DualModeCharByte == 0x0F) + { + pVCP->DP3DualModeCharByte = I2CBUS_INVALID; + } + + pVCP->DP4DualModeCharByte = (CBIOS_U8)(pVCPInitData->VCP_PortConfig.DP4DualModeCharByte); + if (pVCP->DP4DualModeCharByte == 0x0F) + { + pVCP->DP4DualModeCharByte = I2CBUS_INVALID; + } + + pVCP->DVOCharByte = (CBIOS_U8)(pVCPInitData->VCP_PortConfig.DVOCharByte); + if (pVCP->DVOCharByte == 0x0F) + { + pVCP->DVOCharByte = I2CBUS_INVALID; + } + + pVCP->CRTInterruptPort = (CBIOS_U8)(pVCPInitData->VCP_PortConfig.DACGPIOByte); + if (pVCP->CRTInterruptPort == 0x0F) + { + pVCP->CRTInterruptPort = INVALID_GPIO; + } + + pVCP->DVOInterruptPort = (CBIOS_U8)(pVCPInitData->VCP_PortConfig.DVOGPIOByte); + if (pVCP->DVOInterruptPort == 0x0F) + { + pVCP->DVOInterruptPort = INVALID_GPIO; + } + + pVCP->EClock = cb_swab32(pVCPInitData->VCP_ChipClock.EClock); + pVCP->EVcoLow = cb_swab32(pVCPInitData->VCP_ChipClock.EVcoLow); + pVCP->DVcoLow = cb_swab32(pVCPInitData->VCP_ChipClock.DVcoLow); + + if (RomLength < VBIOS_IMAGE_SIZE) + { + pVCP->sizeofCR_DEFAULT_TABLE = cbGetDefaultRegTblSize(VCP_CR_DEFAULT_TABLE); + pVCP->sizeofSR_DEFAULT_TABLE = cbGetDefaultRegTblSize(VCP_SR_DEFAULT_TABLE); + pVCP->pCR_DEFAULT_TABLE = cb_AllocateNonpagedPool(sizeof(VCP_CR_DEFAULT_TABLE)); + pVCP->pSR_DEFAULT_TABLE = cb_AllocateNonpagedPool(sizeof(VCP_SR_DEFAULT_TABLE)); + cb_memcpy(pVCP->pCR_DEFAULT_TABLE, VCP_CR_DEFAULT_TABLE, sizeof(VCP_CR_DEFAULT_TABLE)); + cb_memcpy(pVCP->pSR_DEFAULT_TABLE, VCP_SR_DEFAULT_TABLE, sizeof(VCP_SR_DEFAULT_TABLE)); + } + else + { + pVCP->sizeofCR_DEFAULT_TABLE = cbGetRomRegTbl(VCPBase, cb_swab16(pVCPInitData->VCP_CRDefaultTableOffset), &pVCP->pCR_DEFAULT_TABLE); + pVCP->sizeofSR_DEFAULT_TABLE = cbGetRomRegTbl(VCPBase, cb_swab16(pVCPInitData->VCP_SRDefaultTableOffset), &pVCP->pSR_DEFAULT_TABLE); + + pVCP_BootDevPriorityAddr = (PCBIOS_U16)((PCBIOS_U8)VCPBase + cb_swab16(pVCPInitData->VCP_BootDevPriorityOffset) - VCP_OFFSET); + pVCP->sizeofBootDevPriority = cb_min(cbGetBootDevPrioritySize(pVCP_BootDevPriorityAddr), 16); + for(i = 0; i < (pVCP->sizeofBootDevPriority); i++) + { + pVCP->BootDevPriority[i] = cb_swab16(pVCP_BootDevPriorityAddr[i]); + } + + if (pVCPInitData->VCP_DVOConfig.DVODeviceType.ActVT1636) + { + pVCP->SupportedDVODevice |= TX_VT1636; + } + if (pVCPInitData->VCP_DVOConfig.DVODeviceType.ActCH7301C) + { + pVCP->SupportedDVODevice |= TX_CH7301C; + } + if (pVCPInitData->VCP_DVOConfig.DVODeviceType.ActVT1632A) + { + pVCP->SupportedDVODevice |= TX_VT1632; + } + if (pVCPInitData->VCP_DVOConfig.DVODeviceType.ActAD9389B) + { + pVCP->SupportedDVODevice |= TX_AD9389B; + } + if (pVCPInitData->VCP_DVOConfig.DVODeviceType.ActCH7305) + { + pVCP->SupportedDVODevice |= TX_CH7305; + } + + //Get all DVO Device Slave Address from VCP + cb_memset(pVCP->DVODevConfig, 0, MAX_DVO_DEVICES_NUM * sizeof(CBIOS_DVO_DEV_CONFIG)); + pByte = (PCBIOS_U8)(VCPBase) + pVCPInitData->VCP_DVODevConfigOffset; + for(i = 0; i < MAX_DVO_DEVICES_NUM; i++) + { + switch(*(PCBIOS_U8)(pByte++)) + { + case 0x01: + pVCP->DVODevConfig[i].DVOTxType = TX_VT1636; + break; + case 0x02: + pVCP->DVODevConfig[i].DVOTxType = TX_CH7301C; + break; + case 0x04: + pVCP->DVODevConfig[i].DVOTxType = TX_VT1632; + break; + case 0x08: + pVCP->DVODevConfig[i].DVOTxType = TX_AD9389B; + break; + case 0x10: + pVCP->DVODevConfig[i].DVOTxType = TX_CH7305; + break; + default: + pVCP->DVODevConfig[i].DVOTxType = TX_NONE; + } + + pVCP->DVODevConfig[i].DVOSlaveAddr = *(PCBIOS_U8)(pByte++); + } + } + + // Get Max Resolution configs for 4 DP ports from VCP + if (pVCPInitData->VCP_Version > 0x06) + { + for (i = 0; i < 4; i++) + { + pVCP->DPMaxResConfig[i].MaxXRes = cb_swab16(pVCPInitData->VCP_DPMaxResConfig[i].MaxXRes); + pVCP->DPMaxResConfig[i].MaxYRes = cb_swab16(pVCPInitData->VCP_DPMaxResConfig[i].MaxYRes); + pVCP->DPMaxResConfig[i].MaxRefresh = cb_swab16(pVCPInitData->VCP_DPMaxResConfig[i].MaxRefresh) * 100; + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),"cbParseVCPInfo: Get port %d res config = %d x %d @ %d.\n", + i, pVCP->DPMaxResConfig[i].MaxXRes, pVCP->DPMaxResConfig[i].MaxYRes, pVCP->DPMaxResConfig[i].MaxRefresh)); + } + + pVCP->SliceNum = pVCPInitData->VCP_SliceNum; + } + + if (pVCPInitData->VCP_Version > 0x07) + { + pVCP->FwVersion = cb_swab32(pVCPInitData->VCP_FwVersion); + cb_memset(pVCP->SignOnMsg, 0, sizeofarray(pVCP->SignOnMsg)); + cb_memcpy(pVCP->SignOnMsg, pVCPInitData->VCP_SignOnMsg, sizeofarray(pVCPInitData->VCP_SignOnMsg)); + cb_memset(pVCP->VBiosEditTime, 0, sizeofarray(pVCP->VBiosEditTime)); + cb_memcpy(pVCP->VBiosEditTime, pVCPInitData->VCP_VBiosEditTime, sizeofarray(pVCPInitData->VCP_VBiosEditTime)); + cb_memset(pVCP->FwName, 0, sizeofarray(pVCP->FwName)); + cb_memcpy(pVCP->FwName, pVCPInitData->VCP_FwName, sizeofarray(pVCPInitData->VCP_FwName)); + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO),"Firmware version: %08x \n", pVCP->FwVersion)); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO),"Firmware name: %s \n", pVCP->FwName)); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO),"Firmware SignOnMsg: %s \n", pVCP->SignOnMsg)); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO),"Firmware modified time (mm/dd/yy hr:mi): %s \n", pVCP->VBiosEditTime)); + } +} + + +CBIOS_BOOL cbCalculateCheckSumOfVCP(PVCP_INIT_DATA pVCPInitData) +{ + CBIOS_U32 i = 0; + CBIOS_U32 result = 0; + PCBIOS_U32 pDWORD = (PCBIOS_U32)pVCPInitData; + CBIOS_U32 lenth = *(pDWORD + 2); + CBIOS_U32 version = *(pDWORD + 1); + CBIOS_U32 num = lenth/sizeof(CBIOS_U32); + if(version > 0x0D) + { + for(i = 0; i < num; i++) + { + result += pDWORD[i]; + } + if(result == 0) + { + return CBIOS_TRUE; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "CheckSum is not correct! \n")); + return CBIOS_FALSE; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "no CheckSum, default correct! \n")); + return CBIOS_TRUE; + } +} + +CBIOS_BOOL cbInitVCP_Arise(PCBIOS_EXTENSION_COMMON pcbe, PVCP_INFO pVCP, PCBIOS_VOID pRomBase) +{ + PVCP_INIT_DATA pVCPInitData; + PCBIOS_VOID pRomVCPBase = (PCBIOS_VOID)((PCBIOS_CHAR)pRomBase + VCP_OFFSET); + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "vcp_init_data size = %ld\n", sizeof(VCP_INIT_DATA))); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "pRomBase addr = %x\n", (PCBIOS_CHAR)(pRomBase))); + + if((pRomBase != CBIOS_NULL) && (cb_swab16(*(CBIOS_U16*)(pRomVCPBase))== VCP_TAG)) + { + pcbe->bUseDefaultVCP = CBIOS_FALSE; + + //VCP not used by default, need discuss with Talen when it is used. + pVCP->bUseVCP = CBIOS_TRUE; + pVCPInitData = (PVCP_INIT_DATA)(pRomVCPBase); + cbParseVCPInfo(pcbe, pVCP, pVCPInitData, pRomVCPBase, pcbe->RomImageLength); + } + else + { + // load default VCP data + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "cbInitVCP: Enter! Load default VCP data\n")); + pcbe->bUseDefaultVCP = CBIOS_TRUE; + //VCP not used by default, need discuss with Talen when it is used. + pVCP->bUseVCP = CBIOS_TRUE; + cbLoadDefaultVCPData(pVCP, pcbe->RomImageLength); + } + + if(pcbe->bRunOnQT) + { + pVCP->SupportDevices = CBIOS_TYPE_CRT; + } + + if (pVCP->SupportDevices & CBIOS_TYPE_DVO) + { + pcbe->HPDDeviceMasks |= CBIOS_TYPE_DVO; + } + + if (pVCP->SupportDevices & CBIOS_TYPE_DP1) + { + pcbe->HPDDeviceMasks |= CBIOS_TYPE_DP1; + } + + if (pVCP->SupportDevices & CBIOS_TYPE_DP2) + { + pcbe->HPDDeviceMasks |= CBIOS_TYPE_DP2; + } + + if (pVCP->SupportDevices & CBIOS_TYPE_DP3) + { + pcbe->HPDDeviceMasks |= CBIOS_TYPE_DP3; + } + + if (pVCP->SupportDevices & CBIOS_TYPE_DP4) + { + pcbe->HPDDeviceMasks |= CBIOS_TYPE_DP4; + } + + pcbe->bFilterUnsupportedModeFunction = CBIOS_FALSE; + + return CBIOS_TRUE; +} + + +#else +__attribute__((section(".fakemain"))) CBIOS_VOID FakeMainForBuildVCPFile( ) +{ + return; +} +#endif + diff --git a/drivers/gpu/drm/arise/cbios/Hw/Arise/CBiosVCP_Arise.h b/drivers/gpu/drm/arise/cbios/Hw/Arise/CBiosVCP_Arise.h new file mode 100644 index 0000000000000..db8553ec1c7fa --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Arise/CBiosVCP_Arise.h @@ -0,0 +1,181 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** VCP functions prototype and raw VCP data definition. +** +** NOTE: +** This header file CAN ONLY be included by hw layer those files under Hw folder. +******************************************************************************/ + +#ifndef _CBIOS_VCP_ELT_H_ +#define _CBIOS_VCP_ELT_H_ + +/* +#ifdef __uboot__ +#define __BUILD_INTO_VCPDATA_SECTION __attribute__ ((aligned (4), section(".vcpdata"))) +#define __4_BYTE_ALIGNED __attribute__ ((aligned (4))) +#endif +*/ +#define __BUILD_INTO_VCPDATA_SECTION +#define __4_BYTE_ALIGNED + +typedef struct _VCP_PORTCONFIG +{ + CBIOS_U8 DACCharByte; + CBIOS_U8 DVOCharByte; + CBIOS_U8 DP1DualModeCharByte; + CBIOS_U8 DP2DualModeCharByte; + CBIOS_U8 DP3DualModeCharByte; + CBIOS_U8 DP4DualModeCharByte; + CBIOS_U8 DACGPIOByte; + CBIOS_U8 DVOGPIOByte; + CBIOS_U8 DP1GPIOByte; + CBIOS_U8 DP2GPIOByte; + CBIOS_U8 Reserved_2[2]; +} VCP_PORTCONFIG,*PVCP_PORTCONFIG; + +typedef struct _VCP_CHIPCLOCK +{ + CBIOS_U32 EClock; + CBIOS_U32 IClock; + CBIOS_U32 EVcoLow; + CBIOS_U32 DVcoLow; + CBIOS_U32 VClock; +} VCP_CHIPCLOCK,*PVCP_CHIPCLOCK; + +typedef struct _VCP_FEATURESWITCH +{ + CBIOS_U32 Reserved_1 :4; + CBIOS_U32 IsEDP1Enabled :1; + CBIOS_U32 IsEDP2Enabled :1; + CBIOS_U32 IsDisableCodec1 :1; + CBIOS_U32 IsDisableCodec2 :1; + CBIOS_U32 IsEclkConfigEnable :1; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 IsBIUBackdoorEnable :1; + CBIOS_U32 Reserved_3 :3; + CBIOS_U32 IsEDPPowerSeqEnable :1; + CBIOS_U32 HPDActiveHighEnable :1; + CBIOS_U32 NonSimulateChip :1; + CBIOS_U32 RsvdFeatureSwitch :15; +}VCP_FEATURESWITCH; + +typedef struct _VCP_DVOCONFIG +{ + struct + { + CBIOS_U8 ActVT1636 :1; + CBIOS_U8 ActCH7301C :1; + CBIOS_U8 ActVT1632A :1; + CBIOS_U8 ActAD9389B :1; + CBIOS_U8 ActCH7305 :1; + CBIOS_U8 RsvdDVODeviceType :3; + }DVODeviceType; + CBIOS_U8 DVOSlaveAddr; + CBIOS_U16 DVODeltaDelay; +} VCP_DVOCONFIG, *PVCP_DVOCONFIG; + +typedef struct _VCP_DVO_CARDCONFIG +{ + CBIOS_U8 DVOCardType; + CBIOS_U8 DVOCardSlaveAddr; +}VCP_DVO_CARDCONFIG, *PVCP_DVO_CARDCONFIG; + +typedef struct _VCP_EDP_POWERCONFIG +{ + struct + { + CBIOS_U8 eDP1PowerCtrlGPIO :4; + CBIOS_U8 eDP1BackLightGPIO :4; + }; + struct + { + CBIOS_U8 eDP2PowerCtrlGPIO :4; + CBIOS_U8 eDP2BackLightGPIO :4; + }; + CBIOS_U8 Positive_Delay_VDD_to_DPLane; + CBIOS_U8 Positive_Delay_DPLane_to_PWM; + CBIOS_U8 Positive_Delay_PWM_to_VEE; + CBIOS_U8 Negative_Delay_VEE_to_PWM; + CBIOS_U8 Negative_Delay_PWM_to_DPLane; + CBIOS_U8 Negative_Delay_DPLane_to_VDD; + CBIOS_U8 EDPOFFON_Delay_Negative_to_Positive; +}VCP_EDP_POWERCONFIG, *PVCP_EDP_POWERCONFIG; + +typedef struct _VCP_CBREGISTER +{ + CBIOS_U32 type; + CBIOS_U32 mask; + CBIOS_U32 index; + CBIOS_U32 value; +} VCP_CBREGISTER, *PVCP_CBREGISTER; + +typedef struct _VCP_MAX_RESCONFIG +{ + CBIOS_U16 MaxXRes; + CBIOS_U16 MaxYRes; + CBIOS_U16 MaxRefresh; // unit HZ +} VCP_MAX_RESCONFIG, *PVCP_MAX_RESCONFIG; + +#pragma pack(push, 1) +typedef struct _VCP_INIT_DATA +{ + CBIOS_U16 VCP_Tag; // 0x66BB + CBIOS_U16 VCP_Length; // 256 byte + CBIOS_U32 VCP_BiosVersion; + CBIOS_U8 VCP_Version; + CBIOS_U32 VCP_FwVersion; + CBIOS_U8 RsvdByte_1[3]; + CBIOS_U16 VCP_SubVendorID; + CBIOS_U16 VCP_SubSystemID; + CBIOS_U8 VCP_BiosName[10]; + CBIOS_U16 VCP_SupportDevices; + VCP_FEATURESWITCH VCP_FeatureSwitch; + VCP_PORTCONFIG VCP_PortConfig; + VCP_CHIPCLOCK VCP_ChipClock; + CBIOS_U8 VCP_FwName[8]; + VCP_DVOCONFIG VCP_DVOConfig; + CBIOS_U32 VCP_DP1SscConfig; + CBIOS_U32 VCP_DP2SscConfig; + VCP_EDP_POWERCONFIG VCP_EDPPowerConfig; + CBIOS_U8 RsvdByte_3[5]; + + CBIOS_U16 VCP_BootDevPriorityOffset; + CBIOS_U16 VCP_DVODevConfigOffset; + CBIOS_U16 VCP_PCIDefaultTableOffset; + CBIOS_U16 VCP_CRDefaultTableOffset; + CBIOS_U16 VCP_SRDefaultTableOffset; + CBIOS_U16 VCP_FIFODefalutTableOffset; + CBIOS_U16 VCP_PostTimeTableOffset; + CBIOS_U8 RsvdByte_4[4]; + + CBIOS_U8 VCP_SignOnMsgSetting; + CBIOS_U8 VCP_SignOnMsg[70]; + CBIOS_U8 VCP_VBiosBuildTime[14]; + CBIOS_U16 VCP_EndofBuildTime; + CBIOS_U8 VCP_VBiosEditTime[14]; + CBIOS_U16 VCP_EndofEditTime; + CBIOS_U8 RsvdByte_5[1]; + + VCP_MAX_RESCONFIG VCP_DPMaxResConfig[4]; + CBIOS_U8 VCP_SliceNum; + CBIOS_U16 VCP_CoreTempThreshold; + CBIOS_U8 RsvdByte_6[5]; +}VCP_INIT_DATA, *PVCP_INIT_DATA; +#pragma pack(pop) + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/Arise/CBios_Arise.c b/drivers/gpu/drm/arise/cbios/Hw/Arise/CBios_Arise.c new file mode 100644 index 0000000000000..da5c7f17cc8eb --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Arise/CBios_Arise.c @@ -0,0 +1,3252 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** chip functions implementation. +** +** NOTE: +** The chip functions SHOULD NOT be called by other modules directly. +** Please call the corresponding function defined in CBiosChipFunc.h. +******************************************************************************/ + +#include "CBios_Arise.h" +#include "../Register/BIU_SBI_registers.h" +#include "../Register/pmu_registers.h" +#include "../HwBlock/CBiosDIU_HDTV.h" + +CBIOS_U32 CheckCnt = 0; + +static CBIOS_U32 PSStartAddrIndex[CBIOS_IGACOUNTS] = {0x81dc, 0x33988, 0x34088, 0x34788}; +static CBIOS_U32 PSCompFifoIndex[CBIOS_IGACOUNTS] = {0x81A4, 0x33910, 0x34010, 0x34710}; +static CBIOS_U32 PSBaseOffsetIndex[CBIOS_IGACOUNTS] = {0x33700, 0x3394C, 0x3404C, 0x3474C}; +static CBIOS_U32 PSRightBaseIndex[CBIOS_IGACOUNTS] = {0x81E0, 0x3398C, 0x3408C, 0x3478C}; +static CBIOS_U32 PSVsyncOffIndex[CBIOS_IGACOUNTS] = {0x81C4, 0x33908, 0x34008, 0x34708}; +static CBIOS_U32 PSStrideIndex[CBIOS_IGACOUNTS] = {0x81C8, 0x3390C, 0x3400C, 0x3470C}; +static CBIOS_U32 PSShadowIndex[CBIOS_IGACOUNTS] = {0x81FC, 0x33924, 0x34024, 0x34724}; +//static CBIOS_U32 PSWinWIndex[CBIOS_IGACOUNTS] = {0x33290, 0x3392C, 0x3402C, 0x3472C}; +//static CBIOS_U32 PSWinHIndex[CBIOS_IGACOUNTS] = {0x33294, 0x33930, 0x34030, 0x34730}; +//static CBIOS_U32 PSScalRatWIndex[CBIOS_IGACOUNTS] = {0x33318, 0x33990, 0x34090, 0x34790}; +//static CBIOS_U32 PSScalRatHIndex[CBIOS_IGACOUNTS] = {0x3331C, 0x33994, 0x34094, 0x34794}; +//static CBIOS_U32 PSScalSrcIndex[CBIOS_IGACOUNTS] = {0x33320, 0x33998, 0x34098, 0x34798}; +static CBIOS_U32 PSCscIndex[CBIOS_IGACOUNTS] = {0x33644, 0x33944, 0x34044, 0x34744}; +static CBIOS_U32 PSCscCoef1[CBIOS_IGACOUNTS] = {0x33634, 0x33934, 0x34034, 0x34734}; +static CBIOS_U32 PSCscCoef2[CBIOS_IGACOUNTS] = {0x33638, 0x33938, 0x34038, 0x34738}; +static CBIOS_U32 PSCscCoef3[CBIOS_IGACOUNTS] = {0x3363c, 0x3393c, 0x3403c, 0x3473c}; +static CBIOS_U32 PSCscCoef4[CBIOS_IGACOUNTS] = {0x33640, 0x33940, 0x34040, 0x34740}; +static CBIOS_U32 PSBLIndex[CBIOS_IGACOUNTS] = {0x33810, 0x33E6C, 0x34574, 0x34c74}; + +static CBIOS_U32 SSStartAddrIndex[CBIOS_IGACOUNTS] = {0x81D0, 0x339D4, 0x340D4, 0x347D4}; +static CBIOS_U32 SSCompFifoIndex[CBIOS_IGACOUNTS] = {0x8198, 0x339C8, 0x340C8, 0x347C8}; +static CBIOS_U32 SSBaseOffsetIndex[CBIOS_IGACOUNTS] = {0x33708, 0x33A14, 0x34114, 0x34814}; +static CBIOS_U32 SSEnableIndex[CBIOS_IGACOUNTS] = {0x33834, 0x33E70, 0x34578, 0x34C78}; +static CBIOS_U32 SSRightBaseIndex[CBIOS_IGACOUNTS] = {0x81D4, 0x339D8, 0x340D8, 0x347D8}; +static CBIOS_U32 SSStrideIndex[CBIOS_IGACOUNTS] = {0x81D8, 0x339DC, 0x340DC, 0x347DC}; +static CBIOS_U32 SSFmtSrcWIndex[CBIOS_IGACOUNTS] = {0x8190, 0x339C0, 0x340C0, 0x347C0}; +static CBIOS_U32 SSDstWinIndex[CBIOS_IGACOUNTS] = {0x819C, 0x339CC, 0x340CC, 0x347CC}; +static CBIOS_U32 SSSrcWinHIndex[CBIOS_IGACOUNTS] = {0x81A8, 0x339D0, 0x340D0, 0x347D0}; +static CBIOS_U32 SSDstWinPosIndex[CBIOS_IGACOUNTS] = {0x81F8, 0x339E8, 0x340E8, 0x347E8}; +static CBIOS_U32 SSScalRatioHIndex[CBIOS_IGACOUNTS] = {0x332E0, 0x339F4, 0x340F4, 0x347F4}; +static CBIOS_U32 SSScalRatioVIndex[CBIOS_IGACOUNTS] = {0x332E4, 0x339F8, 0x340F8, 0x347F8}; +static CBIOS_U32 SSCscIndex[CBIOS_IGACOUNTS] = {0x3362C, 0x33A10, 0x34110, 0x34810}; +static CBIOS_U32 SSCscCoef1[CBIOS_IGACOUNTS] = {0x3361c, 0x33a00, 0x34100, 0x34800}; +static CBIOS_U32 SSCscCoef2[CBIOS_IGACOUNTS] = {0x33620, 0x33a04, 0x34104, 0x34804}; +static CBIOS_U32 SSCscCoef3[CBIOS_IGACOUNTS] = {0x33624, 0x33a08, 0x34108, 0x34808}; +static CBIOS_U32 SSCscCoef4[CBIOS_IGACOUNTS] = {0x33628, 0x33a0c, 0x3410c, 0x3480c}; +static CBIOS_U32 SSBLIndex[CBIOS_IGACOUNTS] = {0x33854, 0x33a24, 0x34124, 0x34824}; + +static CBIOS_U32 TQSStartAddrIndex[2][CBIOS_IGACOUNTS] = {{0x8430, 0x33A40, 0x34140, 0x34840}, +{0x33404, 0x33AF4, 0x341F4, 0x348F4}}; +static CBIOS_U32 TQSCompFifoIndex[2][CBIOS_IGACOUNTS] = {{0x8414, 0x33A3C, 0x3413C, 0x3483C}, +{0x33400, 0x33AF0, 0x341F0, 0x348F0}}; +static CBIOS_U32 TQSBaseOffsetIndex[2][CBIOS_IGACOUNTS] = {{0x8498, 0x33A78, 0x34178, 0x34878}, +{0x33410, 0x33B00, 0x34200, 0x34900}}; +static CBIOS_U32 TQSEnableIndex[2][CBIOS_IGACOUNTS] = {{0x8458, 0x33A5C, 0x3415C, 0x3485C}, +{0x3384C, 0x33B8C, 0x3428C, 0x3498C}}; +static CBIOS_U32 TQSRightBaseIndex[2][CBIOS_IGACOUNTS] = {{0x844C, 0x33A54, 0x34154, 0x34854}, +{0x33408, 0x33AF8, 0x341F8, 0x348F8}}; +static CBIOS_U32 TQSStrideIndex[2][CBIOS_IGACOUNTS] = {{0x8438, 0x33A44, 0x34144, 0x34844}, +{0x3340C, 0x33AFC, 0x341FC, 0x348FC}}; +static CBIOS_U32 TQSFormatIndex[2][CBIOS_IGACOUNTS] = {{0x33600, 0x33ABC, 0x341BC, 0x348BC}, +{0x33480, 0x33B64, 0x34264, 0x34964}}; +static CBIOS_U32 TQSDstWinPosIndex[2][CBIOS_IGACOUNTS] = {{0x8444, 0x33A4C, 0x3414C, 0x3484C}, +{0x33418, 0x33B08, 0x34208, 0x34908}}; +static CBIOS_U32 TQSDstWinIndex[2][CBIOS_IGACOUNTS] = {{0x8450, 0x33A58, 0x34158, 0x34858}, +{0x3341C, 0x33B0C, 0x3420C, 0x3490C}}; +static CBIOS_U32 TQSSrcWinIndex[2][CBIOS_IGACOUNTS] = {{0x8448, 0x33A50, 0x34150, 0x34850}, +{0x33414, 0x33B04, 0x34204, 0x34904}}; +static CBIOS_U32 TQSScalRatioHIndex[2][CBIOS_IGACOUNTS] = {{0x84A4, 0x33A84, 0x34184, 0x34884}, +{0x33420, 0x33B10, 0x34210, 0x34910}}; +static CBIOS_U32 TQSScalRatioVIndex[2][CBIOS_IGACOUNTS] = {{0x84A8, 0x33A88, 0x34188, 0x34888}, +{0x33424, 0x33B14, 0x34214, 0x34914}}; +static CBIOS_U32 TQSCscIndex[2][CBIOS_IGACOUNTS] = {{0x33614, 0x33AD0, 0x341D0, 0x348D0}, +{0x33494, 0x33B78, 0x34278, 0x34978}}; +static CBIOS_U32 TQSCscCoef1[2][CBIOS_IGACOUNTS] = {{0x33604, 0x33ac0, 0x341c0, 0x348c0}, +{0x33484, 0x33b68, 0x34268, 0x34968}}; +static CBIOS_U32 TQSCscCoef2[2][CBIOS_IGACOUNTS] = {{0x33608, 0x33ac4, 0x341c4, 0x348c4}, +{0x33488, 0x33b6c, 0x3426c, 0x3496c}}; +static CBIOS_U32 TQSCscCoef3[2][CBIOS_IGACOUNTS] = {{0x3360c, 0x33ac8, 0x341c8, 0x348c8}, +{0x3348c, 0x33b70, 0x34270, 0x34970}}; +static CBIOS_U32 TQSCscCoef4[2][CBIOS_IGACOUNTS] = {{0x33610, 0x33acc, 0x341cc, 0x348cc}, +{0x33490, 0x33b74, 0x34274, 0x34974}}; +static CBIOS_U32 TQSBLIndex[2][CBIOS_IGACOUNTS] = {{0x33858, 0x33ad4, 0x341d4, 0x348d4}, +{0x33860, 0x33b84, 0x34284, 0x34984}}; + + +static CBIOS_U32 BackgndColorIndex[CBIOS_IGACOUNTS] = {0x33670, 0x339A4, 0x340A4, 0x347A4}; +static CBIOS_U32 OneShotTrigIndex[CBIOS_IGACOUNTS] = {0x8200, 0x33958, 0x34058, 0x34758}; + +CBIOS_U32 OvlKeyIndex[CBIOS_IGACOUNTS][OVL_NUM_E3K] = { + {0x33840, 0x8194, 0x8410, 0x332BC}, + {0x33E80, 0x339C4, 0x33A38, 0x33AE8}, + {0x34590, 0x340C4, 0x34138, 0x341E8}, + {0x34C90, 0x347C4, 0x34838, 0x348E8}, +}; + +static CBIOS_U32 OvlPlaneAlphaIndex[CBIOS_IGACOUNTS][OVL_NUM_E3K] = { + {0x33844, 0x332A0, 0x332A4, 0x332C0}, + {0x33E84, 0x339EC, 0x33A98, 0x33AEC}, + {0x34594, 0x340EC, 0x34198, 0x341EC}, + {0x34C94, 0x347EC, 0x34898, 0x348EC}, +}; + +static CBIOS_U32 KeyHighIndex[CBIOS_IGACOUNTS][STREAM_NUM_E3K] = +{ + {0x8188, 0x332E8, 0x843C, 0x33498,}, + {0x3397C, 0x33A20, 0x33A48, 0x33B7C,}, + {0x3407C, 0x34120, 0x34148, 0x3427C,}, + {0x3477C, 0x34820, 0x34848, 0x3497C}, +}; + +static CBIOS_U32 KeyLowIndex[CBIOS_IGACOUNTS][STREAM_NUM_E3K] = +{ + {0x81AC, 0x8184, 0x8400, 0x3342C,}, + {0x33980, 0x339BC, 0x33A34, 0x33B1C,}, + {0x34080, 0x340BC, 0x34134, 0x3421C,}, + {0x34780, 0x347BC, 0x34834, 0x3491C}, +}; + +static CBIOS_U32 CursorCscIndex[CBIOS_IGACOUNTS] = {0x81e4, 0x33bb0, 0x342b0, 0x349b0}; +static CBIOS_U32 CursorControl1Index[CBIOS_IGACOUNTS] = {0x33718, 0x33bb4, 0x342b4, 0x349b4}; +static CBIOS_U32 CursorControl2Index[CBIOS_IGACOUNTS] = {0x3371c, 0x33bb8, 0x342b8, 0x349b8}; +static CBIOS_U32 CursorBaseAddrIndex[CBIOS_IGACOUNTS] = {0x33720, 0x33bbc, 0x342bc, 0x349bc}; +//static CBIOS_U32 CursorRightFrameBaseAddrIndex[CBIOS_IGACOUNTS] = {0x33724, 0x33bc0, 0x342c0, 0x349c0}; +static CBIOS_U32 CursorEndPixelIndex[CBIOS_IGACOUNTS] = {0x33728, 0x33bc4, 0x342c4, 0x349c4}; + +static CBIOS_U16 LUTBitWidthIndex[CBIOS_IGACOUNTS] = {CR_E4, CR_E5, CR_E6, CR_B_CD}; + +//HDMI support table +//CBIOS_TRUE: support, CBIOS_FALSE: not support +CBIOS_BOOL HDMIFormatSupportTable[] = +{ + CBIOS_TRUE, //640, 480, p, 5994,6000 + CBIOS_TRUE, //720, 480, p, 5994,6000 + CBIOS_TRUE, //720, 480, p, 5994,6000 + CBIOS_TRUE, //1280, 720, p, 5994,6000 + CBIOS_TRUE, //5, 1920, 1080, i, 5994,6000 + CBIOS_TRUE, //6, 720, 480, i, 5994,6000 + CBIOS_TRUE, //7, 720, 480, i, 5994,6000 + CBIOS_TRUE, //8, 720, 240, p, 5994,6000 + CBIOS_TRUE, //9, 720, 240, p, 5994,6000 + CBIOS_FALSE, //10, 2880, 480, i, 5994,6000 + CBIOS_FALSE, //11, 2880, 480, i, 5994,6000 + CBIOS_FALSE, //12, 2880, 240, p, 5994,6000 + CBIOS_FALSE, //13, 2880, 240, p, 5994,6000 + CBIOS_FALSE, //14, 1440, 480, p, 5994,6000 + CBIOS_FALSE, //15, 1440, 480, p, 5994,6000 + CBIOS_TRUE, //16, 1920, 1080, p, 5994,6000 + CBIOS_TRUE, //17, 720, 576, p, 5000,0000 + CBIOS_TRUE, //18, 720, 576, p, 5000,0000 + CBIOS_TRUE, //19, 1280, 720, p, 5000,0000 + CBIOS_TRUE, //20, 1920, 1080, i, 5000,0000 + CBIOS_TRUE, //21, 720, 576, i, 5000,0000 + CBIOS_TRUE, //22, 720, 576, i, 5000,0000 + CBIOS_TRUE, //23, 720, 288, p, 5000,0000 + CBIOS_TRUE, //24, 720, 288, p, 5000,0000 + CBIOS_FALSE, //25, 2880, 576, i, 5000,0000 + CBIOS_FALSE, //26, 2880, 576, i, 5000,0000 + CBIOS_FALSE, //27, 2880, 288, p, 5000,0000 + CBIOS_FALSE, //28, 2880, 288, p, 5000,0000 + CBIOS_FALSE, //29, 1440, 576, p, 5000,0000 + CBIOS_FALSE, //30, 1440, 576, p, 5000,0000 + CBIOS_TRUE, //31, 1920, 1080, p, 5000,0000 + CBIOS_TRUE, //32, 1920, 1080, p, 2397,2400 + CBIOS_TRUE, //33, 1920, 1080, p, 2500,0000 + CBIOS_TRUE, //34, 1920, 1080, p, 2997,3000 + CBIOS_FALSE, //35, 2880, 480, p, 5994,6000 + CBIOS_FALSE, //36, 2880, 480, p, 5994,6000 + CBIOS_FALSE, //37, 2880, 576, p, 5000,0000 + CBIOS_FALSE, //38, 2880, 576, p, 5000,0000 + CBIOS_FALSE, //39, 1920, 1080, i, 5000,0000 + CBIOS_FALSE, //40, 1920, 1080, i, 10000,0000 + CBIOS_FALSE, //41, 1280, 720, p, 10000,0000 + CBIOS_FALSE, //42, 720, 576, p, 10000,0000 + CBIOS_FALSE, //43, 720, 576, p, 10000,0000 + CBIOS_FALSE, //44, 720, 576, i, 10000,0000 + CBIOS_FALSE, //45, 720, 576, i, 10000,0000 + CBIOS_FALSE, //46, 1920, 1080, i, 11988,12000 + CBIOS_FALSE, //47, 1280, 720, p, 11988,12000 + CBIOS_FALSE, //48, 720, 480, p, 11988,12000 + CBIOS_FALSE, //49, 720, 480, p, 11988,12000 + CBIOS_FALSE, //50, 720, 480, i, 11988,12000 + CBIOS_FALSE, //51, 720, 480, i, 11988,12000 + CBIOS_FALSE, //52, 720, 576, p, 20000,0000 + CBIOS_FALSE, //53, 720, 576, p, 20000,0000 + CBIOS_FALSE, //54, 720, 576, i, 20000,0000 + CBIOS_FALSE, //55, 720, 576, i, 20000,0000 + CBIOS_FALSE, //56, 720, 480, p, 23976,24000 + CBIOS_FALSE, //57, 720, 480, p, 23976,24000 + CBIOS_FALSE, //58, 720, 480, i, 23976,24000 + CBIOS_FALSE, //59, 720, 480, i, 23976,24000 + CBIOS_FALSE, //60 1280, 720, p, 2398, 2400 + CBIOS_FALSE, //61, 1280, 720, p, 2500, 0000 + CBIOS_FALSE, //62, 1280, 720, p, 2997, 3000 + CBIOS_FALSE, //63, 1920,1080, p, 11988,12000 + CBIOS_FALSE, //64, 1920,1080, p, 10000, 0000 + CBIOS_FALSE, //65, 1280, 720, p, 2398, 2400 + CBIOS_FALSE, //66, 1280, 720, p, 2500, 0000 + CBIOS_FALSE, //67 1280, 720, p, 3000, 2997 + CBIOS_FALSE, //68, 1280, 720, p, 5000, 0000 + CBIOS_FALSE, //69, 1280, 720, p, 5994, 6000 + CBIOS_FALSE, //70, 1280, 720, p, 10000, 0000 + CBIOS_FALSE, //71, 1280, 720, p, 11988,12000 + CBIOS_FALSE, //72, 1920,1080, p, 2398, 2400 + CBIOS_FALSE, //73, 1920,1080, p, 2500, 0000 + CBIOS_FALSE, //74, 1920,1080, p, 3000, 2997 + CBIOS_FALSE, //75, 1920,1080, p, 5000, 0000 + CBIOS_FALSE, //76, 1920,1080, p, 5994, 6000 + CBIOS_FALSE, //77, 1920,1080, p, 10000, 0000 + CBIOS_FALSE, //78, 1920,1080, p, 11988,12000 + CBIOS_FALSE, //79, 1680, 720, p, 2398, 2400 + CBIOS_FALSE, //80, 1680, 720, p, 2500, 0000 + CBIOS_FALSE, //81 1680, 720, p, 3000, 2997 + CBIOS_FALSE, //82, 1680, 720, p, 5000, 0000 + CBIOS_FALSE, //83, 1680, 720, p, 5994, 6000 + CBIOS_FALSE, //84, 1680, 720, p, 10000, 0000 + CBIOS_FALSE, //85, 1680, 720, p, 11988,12000 + CBIOS_FALSE, //86, 2560,1080, p, 2398, 2400 + CBIOS_FALSE, //87, 2560,1080, p, 2500, 0000 + CBIOS_FALSE, //88, 2560,1080, p, 3000, 2997 + CBIOS_FALSE, //89, 2560,1080, p, 5000, 0000 + CBIOS_FALSE, //90, 2560,1080, p, 5994, 6000 + CBIOS_FALSE, //91, 2560,1080, p, 10000, 0000 + CBIOS_FALSE, //92, 2560,1080, p, 11988,12000 + CBIOS_TRUE, //93, 3840,2160, p, 2398, 2400 + CBIOS_TRUE, //94, 3840,2160, p, 2500, 0000 + CBIOS_TRUE, //95, 3840,2160, p, 3000, 2997 + CBIOS_TRUE, //96, 3840,2160, p, 5000, 0000 + CBIOS_TRUE, //97, 3840,2160, p, 5994, 6000 + CBIOS_TRUE, //98, 3840,2160, p, 2398, 2400 + CBIOS_TRUE, //99, 3840,2160, p, 2500, 0000 + CBIOS_TRUE, //100, 3840,2160, p, 3000, 2997 + CBIOS_TRUE, //101, 3840,2160, p, 5000, 0000 + CBIOS_TRUE, //102, 3840,2160, p, 5994, 6000 + CBIOS_TRUE, //103, 3840,2160, p, 2398, 2400 + CBIOS_TRUE, //104, 3840,2160, p, 2500, 0000 + CBIOS_TRUE, //105, 3840,2160, p, 3000, 2997 + CBIOS_TRUE, //106, 3840,2160, p, 5000, 0000 + CBIOS_TRUE, //107, 3840,2160, p, 5994, 6000 + // VSDB VIC + CBIOS_TRUE, //108, 3840,2160, p, 3000, 0000 + CBIOS_TRUE, //109, 3840,2160, p, 2500, 0000 + CBIOS_TRUE, //110, 3840,2160, p, 2400, 0000 + CBIOS_TRUE, //111, 4096,2160, p, 2400, 0000 +}; + + +/******** The following tables are for HDTV encoders ********/ +/* +static CBREGISTER_IDX TriLevelSyncWidth_INDEX[] = { + {SR_B_71,0x3F}, + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX BlankLevel_INDEX[] = { + {SR_B_72,0xFF}, + {SR_B_73,0x03}, + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX SyncDelayReg_INDEX[] = { + {SR_B_7E,0xff}, + {SR_B_7D,0x07}, + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HSyncToHActive_INDEX[] = { + {SR_B_8A,0xFF}, + {SR_B_89,0x07}, + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HSyncWidth_INDEX[] = { + {SR_B_A3, 0xFF}, + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HSyncDelay_INDEX[] = { + {SR_B_AA,0x07}, + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX BroadPulseReg_INDEX[] = { + {SR_B_D0,0x7F}, + {SR_B_D1,0xFF}, + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HalfSyncReg_INDEX[] = { + {SR_B_D2,0xFF}, + {SR_B_D3,0x07}, + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HDTVHDEReg_INDEX[] = { + {SR_B_E4,0xFF}, + {SR_B_E5,0x07}, + {MAPMASK_EXIT}, +}; +*/ +static CBREGISTER_IDX HSS2Reg_INDEX[] = { + {SR_64,0xff}, //SR64[7:0] + {SR_66,0x08}, //SR66[3] + {SR_67,0x08}, //SR67[3] + {SR_2E,0x40}, //SR2E[6] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HT2Reg_INDEX[] = { + {SR_60,0xff}, //SR60[7:0] + {SR_66,0x01}, //SR66[0] + {SR_67,0x01}, //SR67[0] + {SR_2E,0x01}, //SR2E[0] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HSE2Reg_INDEX[] = { + {SR_65,0x3f}, //SR65[5:0] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HDE2Reg_INDEX[] = { + {SR_61,0xff}, //SR61[7:0] + {SR_66,0x02}, //SR66[1] + {SR_67,0x02}, //SR67[1] + {SR_2E,0x02}, //SR2E[1] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HBS2Reg_INDEX[] = { + {SR_62,0xff}, //SR62[7:0] + {SR_66,0x04}, //SR66[2] + {SR_67,0x04}, //SR67[2] + {SR_2E,0x04}, //SR2E[2] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HBE2Reg_INDEX[] = { + {SR_63,0x7f}, //SR63[6:0] + {SR_2E,0x38}, //SR2E[5:3] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VT2Reg_INDEX[] = { + {SR_68,0xff}, //SR68[7:0] + {SR_6E,0x0f}, //SR6E[3:0] + {SR_2F,0X01}, //SR2F[0] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VDE2Reg_INDEX[] = { + {SR_69,0xff}, //SR69[7:0] + {SR_6E,0xf0}, //SR6E[7:4] + {SR_2F,0X02}, //SR2F[1] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VBS2Reg_INDEX[] = { + {SR_6A,0xFF}, //SR6A[7:0] + {SR_6F,0x0f}, //SR6F[3:0] + {SR_2F,0X04}, //SR2F[2] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VBE2Reg_INDEX[] = { + {SR_6B,0xff}, //SR6B[7:0] + {SR_2F,0X08}, //SR2F[3] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VSS2Reg_INDEX[] = { + {SR_6C,0xff}, //SR6C[7:0] + {SR_6F,0xf0}, //SR6F[7:4] + {SR_2F,0X10}, //SR2F[4] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VSE2Reg_INDEX[] = { + {SR_6D,0x0f}, //SR6D[3:0] + {SR_2F,0x60}, //SR2F[6:5] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HorSyncStartReg_INDEX[] = { + { CR_04,0xFF }, //CR04[7:0] + { CR_5D,0x10 }, //CR5D[4] + { CR_5F, 0x08 }, //CR5F[3] + { CR_74, 0x40 }, //CR74[6] + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HorTotalReg_INDEX[] = { + { CR_00, 0xFF }, //CR00[7:0] + { CR_5D, 0x01 }, //CR5D[0] + { CR_5F, 0x01 }, //CR5F[0] + { CR_74, 0x01 }, //CR74[0] + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HorSyncEndReg_INDEX[] = { + { CR_05, 0x1F }, //CR05[4:0] + { CR_5D, 0x20 }, //CR5D[5] + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HorDisEndReg_INDEX[] = { + { CR_01, 0xFF }, //CR01[7:0] + { CR_5D, 0x02 }, //CR5D[1] + { CR_5F, 0x02 }, //CR5F[1] + { CR_74, 0x02 }, //CR74[1] + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HorBStartReg_INDEX[] = { + { CR_02, 0xFF }, //CR02[7:0] + { CR_5D, 0x04 }, //CR5D[2] + { CR_5F, 0x04 }, //CR5F[2] + { CR_74, 0x04 }, //CR74[2] + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX HorBEndReg_INDEX[] = { + { CR_03, 0x1F }, //CR03[4:0] + { CR_05, 0x80 }, //CR05[7] + { CR_5D, 0x08 }, //CR5D[3] + { CR_74, 0x38 }, //CR74[5:3] + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VerTotalReg_INDEX[] = { + { CR_06, 0xFF }, //CR06[7:0] + { CR_07, 0x21 }, //CR07[0], CR07[5] + { CR_63, 0xC0 }, //CR63[7:6] + { CR_79, 0x04 }, //CR79[2] + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VerDisEndReg_INDEX[] = { + { CR_12, 0xFF }, //CR12[7:0] + { CR_07, 0x42 }, //CR07[1], CR07[6] + { CR_5E, 0x03 }, //CR5E[1:0] + { CR_79, 0x08 }, //CR79[3] + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX VerBStartReg_INDEX[] = { + { CR_15, 0xFF }, //CR15[7:0] + { CR_07, 0x08 }, //CR07[3] + { CR_09, 0x20 }, //CR09[5] + { CR_5E, 0x0C }, //CR5E[3:2] + { CR_79, 0x10 }, //CR79[4] + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VerBEndReg_INDEX[] = { + { CR_16, 0xFF }, //CR16[7:0] + { CR_79, 0x20 }, //CR79[5] + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VerSyncStartReg_INDEX[] = { + { CR_10, 0xFF }, //CR10[7:0] + { CR_07, 0x84 }, //CR07[2], CR07[7] + { CR_5E, 0x30 }, //CR5E[5:4] + { CR_79, 0x01 }, //CR79[0] + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VerSyncEndReg_INDEX[] = { + { CR_11, 0x0F }, //CR11[3:0] + { CR_79, 0x42 }, //CR79[1], CR79[6] + { MAPMASK_EXIT}, +}; + +extern CBIOS_U32 HDTV_REG_LB[4]; + +CBIOS_VOID cbInitChipAttribute_Arise(PCBIOS_EXTENSION_COMMON pcbe) +{ + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + + //init chip dependent functions + pFuncTbl->pfncbGetModeInfoFromReg = (PFN_cbGetModeInfoFromReg)cbGetModeInfoFromReg_Arise; + pFuncTbl->pfncbInitVCP = (PFN_cbInitVCP)cbInitVCP_Arise; + pFuncTbl->pfncbDoHDTVFuncSetting = (PFN_cbDoHDTVFuncSetting)cbDoHDTVFuncSetting_Arise; + pFuncTbl->pfncbLoadSSC = CBIOS_NULL; + pFuncTbl->pfncbEnableSpreadSpectrum = CBIOS_NULL; + pFuncTbl->pfncbDisableSpreadSpectrum = CBIOS_NULL; + pFuncTbl->pfncbSetGamma = (PFN_cbSetGamma)cbSetGamma_Arise; + pFuncTbl->pfncbInterruptEnableDisable = (PFN_cbInterruptEnableDisable)cbInterruptEnableDisable_Arise; + pFuncTbl->pfncbCECEnableDisable = (PFN_cbCECEnableDisable)cbCECEnableDisable_Arise; + pFuncTbl->pfncbCheckSurfaceOnDisplay = (PFN_cbCheckSurfaceOnDisplay)cbCheckSurfaceOnDisplay_Arise; + pFuncTbl->pfncbGetDispAddr = (PFN_cbGetDispAddr)cbGetDispAddr_Arise; + + pFuncTbl->pfncbSetHwCursor = (PFN_cbSetHwCursor)cbSetHwCursor_Arise; + pFuncTbl->pfncbSetCRTimingReg = (PFN_cbSetTimingReg)cbSetCRTimingReg_Arise; + pFuncTbl->pfncbSetSRTimingReg = (PFN_cbSetTimingReg)cbSetSRTimingReg_Arise; + pFuncTbl->pfncbDoCSCAdjust = (PFN_cbDoCSCAdjust)cbDoCSCAdjust_Arise; + pFuncTbl->pfncbAdjustStreamCSC = (PFN_cbAdjustStreamCSC)cbAdjustStreamCSC_Arise; + + pFuncTbl->pfncbUpdateFrame = (PFN_cbUpdateFrame)cbUpdateFrame_Arise; + pFuncTbl->pfncbDisableStream = (PFN_cbDisableStream)cbDisableStream_Arise; + //tables + pcbe->pHDMISupportedFormatTable = HDMIFormatSupportTable; +} + +CBIOS_VOID cbSetSRTimingReg_Arise(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_TIMING_ATTRIB pTiming, + CBIOS_U32 IGAIndex, + CBIOS_TIMING_FLAGS Flags) +{ + CBIOS_U32 ulBlankingTime = 0,ulSyncWidth= 0, ulBackPorchWidth = 0, ulSyncStart2BlankEnd = 0; + CBIOS_TIMING_REG_Arise TimingReg; + CBIOS_U8 Value = 0x80; + + cb_memset(&TimingReg, 0, sizeof(CBIOS_TIMING_REG_Arise)); + //================================================================// + //************Start Setting Horizontal Timing Registers***********// + //================================================================// + + //(1) Adjust (H Bottom/Right Border + H Front Porch) period: CR72[2:0] = (Hor sync start position in pixel)%8 + TimingReg.HSSRemainder = pTiming->HorSyncStart % 8; + cbBiosMMIOWriteReg(pcbe, CR_72, TimingReg.HSSRemainder, 0xF8, IGAIndex); + + //patch the timing no sync width + if(pTiming->HorSyncEnd <= pTiming->HorSyncStart) + { + pTiming->HorSyncEnd = pTiming->HorSyncStart + 1; + } + + //(2) Adjust HSYNC period: CR72[5:3] = (the number of pixel in Hor sync time)%8 + ulSyncWidth = pTiming->HorSyncEnd - pTiming->HorSyncStart; + TimingReg.HSyncRemainder = ulSyncWidth % 8; + ulSyncWidth = cbRound(ulSyncWidth, CELLGRAN, ROUND_DOWN); + cbBiosMMIOWriteReg(pcbe, CR_72, (TimingReg.HSyncRemainder) << 3, 0xC7, IGAIndex); + + //(3) Adjust (H Back Porch + H Top/Left Border) period: CR73[2:0] = (the number of pixel in (Hor back porch + H top/left border))%8 + ulBackPorchWidth = pTiming->HorTotal - pTiming->HorSyncEnd; + TimingReg.HBackPorchRemainder = ulBackPorchWidth % 8; + cbBiosMMIOWriteReg(pcbe, CR_73, TimingReg.HBackPorchRemainder, 0xF8, IGAIndex); + if((ulBackPorchWidth > 25) && (ulBackPorchWidth < 32)) + { + cbBiosMMIOWriteReg(pcbe, CR_59, 0x01, 0x0, IGAIndex);//set H DisplayShift to 1, to resolve display skew to left + cbBiosMMIOWriteReg(pcbe, CR_5B, 0x08, ~0x08, IGAIndex);//Enable Display Shift + } + + //(4) Start Horizontal Sync Position = HSync Start(in pixel)/8 + TimingReg.HorSyncStart = (CBIOS_U16)cbRound(pTiming->HorSyncStart, CELLGRAN, ROUND_DOWN); + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorSyncStart, HSS2Reg_INDEX, IGAIndex); + + //(5) Htotal = (number of character clocks in one scan line) - 5 - (CR72[2:0]+CR72[5:3]+CR73[2:0])/8 + TimingReg.HorTotal = (CBIOS_U16)cbRound(pTiming->HorTotal, CELLGRAN, ROUND_DOWN) - 5; + TimingReg.HorTotal -= (CBIOS_U16)cbRound(TimingReg.HSSRemainder + TimingReg.HSyncRemainder + + TimingReg.HBackPorchRemainder, CELLGRAN, ROUND_DOWN); + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorTotal, HT2Reg_INDEX, IGAIndex); + + //(6) End Horizontal Sync Position = {Start Horizontal Sync Position + Hsync time(in pixel)/8}[5:0] + TimingReg.HorSyncEnd = (CBIOS_U16)cbRound(pTiming->HorSyncEnd, CELLGRAN, ROUND_DOWN); + if (TimingReg.HorSyncEnd > TimingReg.HorTotal + 3) + { + TimingReg.HorSyncEnd = TimingReg.HorTotal + 3; + } + TimingReg.HorSyncEnd &= 0x1F; + if(ulSyncWidth > 32) + { + TimingReg.HorSyncEnd |= 0x20;//sr65[5]set when Hsynwidth>32char + } + else + { + TimingReg.HorSyncEnd &= ~0x20;//sr65[5]set when Hsynwidth>32char + } + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorSyncEnd, HSE2Reg_INDEX, IGAIndex); + + + //(7) Adjust HDE:CR58[2:0] = (the number of pixel for 1 line of active display)%8 - 1 + TimingReg.HDERemainder = pTiming->HorDisEnd % 8; + if (TimingReg.HDERemainder != 0) + { + TimingReg.HDERemainder = (TimingReg.HDERemainder - 1) & 0x07; + cbBiosMMIOWriteReg(pcbe, CR_58, TimingReg.HDERemainder, 0xF8, IGAIndex); + //enable HDE adjust + cbBiosMMIOWriteReg(pcbe, CR_58, 0x08, 0xF7, IGAIndex); + } + else + { + //disable HDE adjust + cbBiosMMIOWriteReg(pcbe, CR_58, 0x00, 0xF0, IGAIndex); + } + + + //(8) Horizontal Display End = (the number of pixel for 1 line of active display)/8 - 1, rounded up to the nearest integer. + TimingReg.HorDisEnd = (CBIOS_U16)cbRound(pTiming->HorDisEnd, CELLGRAN, ROUND_UP) - 1; + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorDisEnd, HDE2Reg_INDEX, IGAIndex); + + //(9) Horizontal Blank Start + TimingReg.HorBStart = (CBIOS_U16)cbRound(pTiming->HorBStart, CELLGRAN, ROUND_UP); + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorBStart, HBS2Reg_INDEX, IGAIndex); + + //(10) Horizontal Blank End + TimingReg.HorBEnd = (CBIOS_U16)cbRound(pTiming->HorBEnd, CELLGRAN, ROUND_DOWN); + if (TimingReg.HorBEnd > TimingReg.HorTotal + 3) + { + TimingReg.HorBEnd = TimingReg.HorTotal + 3; + } + + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorBEnd, HBE2Reg_INDEX, IGAIndex); + + //================================================================// + //************Start Setting Vertical Timing Registers*************// + //================================================================// + TimingReg.VerTotal = pTiming->VerTotal - 2;//VerTotalTime-2 + cbMapMaskWrite(pcbe,(CBIOS_U32) TimingReg.VerTotal,VT2Reg_INDEX, IGAIndex); + + TimingReg.VerDisEnd = pTiming->VerDisEnd - 1;//HorAddrTime-1 + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.VerDisEnd, VDE2Reg_INDEX, IGAIndex); + + TimingReg.VerBStart = pTiming->VerBStart - 1;//VerBlankStart + //According to spec, both CR15 and SR6A need -1, move the -1 patch to cbConvertVesaTimingToInternalTiming_dst + //Add this patch for HDMI to pass golden file check. Later SE will help measure the output timing for HDMI + // to see whether this patch is still needed. + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.VerBStart, VBS2Reg_INDEX, IGAIndex); + + ulBlankingTime = pTiming->VerBEnd - pTiming->VerBStart; + TimingReg.VerBEnd = TimingReg.VerBStart + ulBlankingTime;//(VerBlankStart+VerBlankTime) and 00FFh + if (TimingReg.VerBEnd > TimingReg.VerTotal) + { + TimingReg.VerBEnd = TimingReg.VerTotal; + } + + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.VerBEnd, VBE2Reg_INDEX, IGAIndex); + + //According to spec, SR6C[7-0] = [scan line counter value at which the vertical sync pulse (FLM) becomes active] -1 + //CR10 needn't -1 + TimingReg.VerSyncStart = pTiming->VerSyncStart - 1;//VerSyncStart + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.VerSyncStart, VSS2Reg_INDEX, IGAIndex); + + //patch the timing no sync width + if(pTiming->VerSyncEnd <= pTiming->VerSyncStart) + { + pTiming->VerSyncEnd = pTiming->VerSyncStart + 1; + } + + //SR6D = SR6C+VerSyncTime + ulSyncWidth = pTiming->VerSyncEnd - pTiming->VerSyncStart; + TimingReg.VerSyncEnd = TimingReg.VerSyncStart + ulSyncWidth; //(VerSyncStart+VerSyncTime) and 000Fh + if (TimingReg.VerSyncEnd > TimingReg.VerTotal) + { + TimingReg.VerSyncEnd = TimingReg.VerTotal; + } + TimingReg.VerSyncEnd &= 0x3F; + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.VerSyncEnd, VSE2Reg_INDEX, IGAIndex); + + //patch the timing which vsyncwidth add vbackporch is less than 8 + ulSyncStart2BlankEnd = pTiming->VerBEnd - pTiming->VerSyncStart; + if(ulSyncStart2BlankEnd < 8 && ulSyncStart2BlankEnd >= 4) + { + Value = 0x40; + } + else if(ulSyncStart2BlankEnd < 4) + { + Value = 0x00; + } + + if(IGAIndex == IGA1) + { + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_ADDR_REG, 0x8f); + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_DATA_REG, Value); + } + else + { + cbBiosMMIOWriteReg(pcbe, CR_8F, Value, (CBIOS_U8)~0xc0, IGAIndex); + } +} + + +CBIOS_VOID cbSetCRTimingReg_Arise(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_TIMING_ATTRIB pTiming, + CBIOS_U32 IGAIndex, + CBIOS_TIMING_FLAGS Flags) +{ + CBIOS_U32 ulBlankingTime = 0,ulSyncWidth= 0,ulBackPorchWidth = 0; + CBIOS_TIMING_REG_Arise TimingReg; + + //patch for unlocking CR: CR is locked for some reason, so unlock CR here temporarily + cbBiosMMIOWriteReg(pcbe, CR_11, 0, 0x7f, IGAIndex); + + cb_memset(&TimingReg, 0, sizeof(CBIOS_TIMING_REG_Arise)); + + //================================================================// + //************Start Setting Horizontal Timing Registers***********// + //================================================================// + + ulSyncWidth = cbRound(pTiming->HorSyncEnd - pTiming->HorSyncStart, CELLGRAN, ROUND_DOWN); + TimingReg.HorSyncStart = (CBIOS_U16)cbRound(pTiming->HorSyncStart, CELLGRAN, ROUND_UP); + + + + //=========================Set HorSyncStart: CR04, CR5D, CR5F===================// + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorSyncStart, HorSyncStartReg_INDEX, IGAIndex); + //===================================================================// + + + TimingReg.HorTotal = (CBIOS_U16)cbRound(pTiming->HorTotal, CELLGRAN, ROUND_UP) - 5; + + + //========================Set HorTotal: CR00, CR5D, CR5F=====================// + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorTotal, HorTotalReg_INDEX, IGAIndex); + //==================================================================// + + + TimingReg.HorSyncEnd = (CBIOS_U16)cbRound(pTiming->HorSyncEnd, CELLGRAN, ROUND_DOWN); + if (TimingReg.HorSyncEnd > TimingReg.HorTotal + 3) + { + TimingReg.HorSyncEnd = TimingReg.HorTotal + 3; + } + TimingReg.HorSyncEnd &= 0x1F; + if(ulSyncWidth > 32) + { + TimingReg.HorSyncEnd |= 0x20;//sr65[5]set when Hsynwidth>32char + } + else + { + TimingReg.HorSyncEnd &= ~0x20;//sr65[5]set when Hsynwidth>32char + } + + + //=============================Set HorSyncEnd: CR05, CR5D======================// + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorSyncEnd, HorSyncEndReg_INDEX, IGAIndex); + //======================================================================// + + ulBackPorchWidth = pTiming->HorTotal - pTiming->HorSyncEnd; + if ((ulBackPorchWidth < 32) && (ulBackPorchWidth % 8 != 0)) + { + TimingReg.HorDisEnd = (CBIOS_U16)cbRound(pTiming->HorDisEnd, CELLGRAN, ROUND_UP); + } + else + { + TimingReg.HorDisEnd = (CBIOS_U16)cbRound(pTiming->HorDisEnd, CELLGRAN, ROUND_UP) - 1; + } + + //=======================Set HorDisEnd: CR01, CR5D, CR5F=======================// + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorDisEnd, HorDisEndReg_INDEX, IGAIndex); + //====================================================================// + + + TimingReg.HorBStart = (CBIOS_U16)cbRound(pTiming->HorBStart, CELLGRAN, ROUND_UP); + + //=====================Set HorBStart: CR02, CR5D, CR5F========================// + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorBStart, HorBStartReg_INDEX, IGAIndex); + //===================================================================// + + TimingReg.HorBEnd = (CBIOS_U16)cbRound(pTiming->HorBEnd, CELLGRAN, ROUND_DOWN); + + if (TimingReg.HorBEnd > TimingReg.HorTotal + 3) + { + TimingReg.HorBEnd = TimingReg.HorTotal + 3; + } + TimingReg.HorBEnd &= 0x3F; + if(ulBlankingTime > 64) + { + TimingReg.HorBEnd |= 0x40; + } + else + { + TimingReg.HorBEnd &= ~0x40; + } + + //==================Set HorBEnd: CR03, CR05, CR5D=========================// + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.HorBEnd, HorBEndReg_INDEX, IGAIndex); + //================================================================// + + + + //================================================================// + //************Start Setting Vertical Timing Registers*************// + //================================================================// + TimingReg.VerTotal = pTiming->VerTotal - 2;//VerTotalTime-2 + + + //======================Set VerTotal: CR06, CR07, CR63======================// + cbMapMaskWrite(pcbe, (CBIOS_U32) TimingReg.VerTotal, VerTotalReg_INDEX, IGAIndex); + //================================================================// + + + TimingReg.VerDisEnd = pTiming->VerDisEnd - 1;//HorAddrTime-1 + + //====================Set VerDisEnd: CR12, CR07, CR5E==========================// + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.VerDisEnd, VerDisEndReg_INDEX, IGAIndex); + //====================================================================// + + + + TimingReg.VerBStart = pTiming->VerBStart - 1;//VerBlankStart + //According to spec, both CR15 and SR6A need -1, move the -1 patch to cbConvertVesaTimingToInternalTiming_dst + //Add this patch for HDMI to pass golden file check. Later SE will help measure the output timing for HDMI + // to see whether this patch is still needed. + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.VerBStart, VerBStartReg_INDEX, IGAIndex); + + ulBlankingTime = pTiming->HorBEnd - pTiming->HorBStart; + TimingReg.VerBEnd = TimingReg.VerBStart + ulBlankingTime;//(VerBlankStart+VerBlankTime) and 00FFh + if (TimingReg.VerBEnd > TimingReg.VerTotal) + { + TimingReg.VerBEnd = TimingReg.VerTotal; + } + TimingReg.VerBEnd &= 0xFF; + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.VerBEnd, VerBEndReg_INDEX, IGAIndex); + + //According to spec, SR6C[7-0] = [scan line counter value at which the vertical sync pulse (FLM) becomes active] -1 + //CR10 needn't -1 + TimingReg.VerSyncStart = pTiming->VerSyncStart;//VerSyncStart + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.VerSyncStart, VerSyncStartReg_INDEX, IGAIndex); + + //SR6D = SR6C+VerSyncTime + ulSyncWidth = pTiming->VerSyncEnd - pTiming->VerSyncStart; + TimingReg.VerSyncEnd = TimingReg.VerSyncStart + ulSyncWidth; //(VerSyncStart+VerSyncTime) and 000Fh + if (TimingReg.VerSyncEnd > TimingReg.VerTotal) + { + TimingReg.VerSyncEnd = TimingReg.VerTotal; + } + TimingReg.VerSyncEnd &= 0x3F; + cbMapMaskWrite(pcbe, (CBIOS_U32)TimingReg.VerSyncEnd, VerSyncEndReg_INDEX, IGAIndex); + +} + +CBIOS_VOID cbGetCRTimingReg_Arise(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_TIMING_ATTRIB pTiming, + CBIOS_U32 IGAIndex, + PCBIOS_TIMING_FLAGS pFlags) +{ + CBIOS_U32 temp = 0; + CBIOS_U8 ClockType = CBIOS_DCLK1TYPE; + CBIOS_U32 CurrentFreq = 0; + CBIOS_U32 remainder = 0; + + cb_memset(pTiming, 0, sizeof(CBIOS_TIMING_ATTRIB)); + cb_memset(pFlags, 0, sizeof(CBIOS_TIMING_FLAGS)); + + if(IGAIndex == IGA1) + { + ClockType = CBIOS_DCLK1TYPE; + } + else if(IGAIndex == IGA2) + { + ClockType = CBIOS_DCLK2TYPE; + } + else if(IGAIndex == IGA3) + { + ClockType = CBIOS_DCLK3TYPE; + } + else if(IGAIndex == IGA4) + { + ClockType = CBIOS_DCLK4TYPE; + } + cbGetProgClock(pcbe, &CurrentFreq, ClockType); + pTiming->PLLClock = CurrentFreq; + + //================================================================// + //************Start Getting Horizontal Timing Registers***********// + //================================================================// + pTiming->HorTotal = (CBIOS_U16)cbMapMaskRead(pcbe, HorTotalReg_INDEX, IGAIndex); //Horizontal Total + pTiming->HorTotal += 5; + pTiming->HorTotal *= 8; + + pTiming->HorDisEnd = (CBIOS_U16)cbMapMaskRead(pcbe, HorDisEndReg_INDEX, IGAIndex); //Horizontal Display End + pTiming->HorDisEnd++; + pTiming->HorDisEnd *= 8; + + pTiming->HorBStart = (CBIOS_U16)cbMapMaskRead(pcbe, HorBStartReg_INDEX, IGAIndex); //Horizontal Blank Start + pTiming->HorBStart *= 8; + + temp = cbMapMaskRead(pcbe, HorBEndReg_INDEX, IGAIndex); //Horizontal Blank End + pTiming->HorBEnd = (temp & 0x3F) | ((pTiming->HorBStart/8) & ~0x3F); + if (temp & BIT6) + { + pTiming->HorBEnd += 0x40; + } + if (pTiming->HorBEnd <= (pTiming->HorBStart/8)) + { + pTiming->HorBEnd += 0x40; + } + if (pTiming->HorBEnd >= (pTiming->HorTotal/8) - 2) + { + pTiming->HorBEnd += 2; + } + pTiming->HorBEnd *= 8; + + pTiming->HorSyncStart = (CBIOS_U16)cbMapMaskRead(pcbe, HorSyncStartReg_INDEX, IGAIndex); //Horizontal Sync Start + pTiming->HorSyncStart *= 8; + + temp = cbMapMaskRead(pcbe, HorSyncEndReg_INDEX, IGAIndex); //Horizontal Sync End + pTiming->HorSyncEnd = (temp & 0x1F) | ((pTiming->HorSyncStart/8) & ~0x1F); + if (temp & BIT5) + { + pTiming->HorSyncEnd += 0x20; + } + if (pTiming->HorSyncEnd <= (pTiming->HorSyncStart/8)) + { + pTiming->HorSyncEnd += 0x20; + } + pTiming->HorSyncEnd *= 8; + + //================================================================// + //************Start Getting Vertical Timing Registers*************// + //================================================================// + pTiming->VerTotal = (CBIOS_U16)cbMapMaskRead(pcbe, VerTotalReg_INDEX, IGAIndex); //Vertical Total + pTiming->VerTotal +=2; + + pTiming->VerDisEnd = (CBIOS_U16)cbMapMaskRead(pcbe, VerDisEndReg_INDEX, IGAIndex); //Vertical Display End + pTiming->VerDisEnd++; + + pTiming->VerBStart = (CBIOS_U16)cbMapMaskRead(pcbe, VerBStartReg_INDEX, IGAIndex); //Vertical Blank Start + pTiming->VerBStart++; + + temp = cbMapMaskRead(pcbe, VerBEndReg_INDEX, IGAIndex); //Vertical Blank End + temp++; + + pTiming->VerBEnd = (temp & 0xFF) | (pTiming->VerBStart & ~(0xFF)); + if (pTiming->VerBEnd <= pTiming->VerBStart ) + { + pTiming->VerBEnd += 0x100; + } + if(pTiming->VerBEnd >= pTiming->VerTotal - 2) + { + pTiming->VerBEnd += 1; + } + + pTiming->VerSyncStart = (CBIOS_U16)cbMapMaskRead(pcbe, VerSyncStartReg_INDEX, IGAIndex); //Vertical Sync Start + + temp = cbMapMaskRead(pcbe, VerSyncEndReg_INDEX, IGAIndex); //Vertical Sync End + pTiming->VerSyncEnd = (temp & 0x0F) | (pTiming->VerSyncStart & ~(0x0F)); + if (pTiming->VerSyncEnd <= pTiming->VerSyncStart) + { + pTiming->VerSyncEnd += 0x10; + } + + //calculate the result value + pTiming->XRes = pTiming->HorDisEnd; + pTiming->YRes = pTiming->VerDisEnd; + + temp = (CBIOS_U32)pTiming->HorTotal * (CBIOS_U32)pTiming->VerTotal; + pTiming->RefreshRate = pTiming->PLLClock * 100 / temp; + remainder = (pTiming->PLLClock * 100) % temp; + pTiming->RefreshRate = pTiming->RefreshRate * 100 + remainder * 100 / temp; +} + +CBIOS_VOID cbGetSRTimingReg_Arise(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_TIMING_ATTRIB pTiming, + CBIOS_U32 IGAIndex, + PCBIOS_TIMING_FLAGS pFlags) +{ + CBIOS_U32 temp = 0; + CBIOS_U8 ClockType = CBIOS_DCLK1TYPE; + CBIOS_U32 CurrentFreq = 0; + CBIOS_U32 remainder = 0; + CBIOS_U32 HSSRemainder = 0; + CBIOS_U32 HSyncRemainder = 0; + CBIOS_U32 HBackPorchRemainder = 0; + CBIOS_U32 HDisEndRemainder = 0; + CBIOS_U32 HorTotalReg = 0; + + cb_memset(pTiming, 0, sizeof(CBIOS_TIMING_ATTRIB)); + cb_memset(pFlags, 0, sizeof(CBIOS_TIMING_FLAGS)); + + if(IGAIndex == IGA1) + { + ClockType = CBIOS_DCLK1TYPE; + } + else if(IGAIndex == IGA2) + { + ClockType = CBIOS_DCLK2TYPE; + } + else if(IGAIndex == IGA3) + { + ClockType = CBIOS_DCLK3TYPE; + } + else if(IGAIndex == IGA4) + { + ClockType = CBIOS_DCLK4TYPE; + } + + cbGetProgClock(pcbe, &CurrentFreq, ClockType); + pTiming->PLLClock = CurrentFreq; + + //================================================================// + //************Start Getting Horizontal Timing Registers***********// + //================================================================// + HSSRemainder = cbBiosMMIOReadReg(pcbe, CR_72, IGAIndex) & 0x07; + temp = cbBiosMMIOReadReg(pcbe, CR_72, IGAIndex); + HSyncRemainder = (temp >> 3) & 0x07; + HBackPorchRemainder = cbBiosMMIOReadReg(pcbe, CR_73, IGAIndex) & 0x07; + + temp = cbBiosMMIOReadReg(pcbe, CR_58, IGAIndex); + if(temp & BIT3) + { + HDisEndRemainder = (temp & 0x07) + 1; + } + + pTiming->HorSyncStart = (CBIOS_U16)cbMapMaskRead(pcbe, HSS2Reg_INDEX, IGAIndex); //Horizontal Sync Start + pTiming->HorSyncStart *= 8; + pTiming->HorSyncStart += (CBIOS_U16)HSSRemainder; + + pTiming->HorTotal = (CBIOS_U16)cbMapMaskRead(pcbe, HT2Reg_INDEX, IGAIndex); //Horizontal Total + HorTotalReg = pTiming->HorTotal; + pTiming->HorTotal = (pTiming->HorTotal + 5) * 8 + (CBIOS_U16)(HSSRemainder + HSyncRemainder + HBackPorchRemainder); + + + temp = cbMapMaskRead(pcbe, HSE2Reg_INDEX, IGAIndex); //Horizontal Sync End + pTiming->HorSyncEnd = (temp & 0x1F) | ((pTiming->HorSyncStart/8) & ~(0x1F)); + if (temp & BIT5) + { + pTiming->HorSyncEnd += 0x20; + } + if (pTiming->HorSyncEnd <= (pTiming->HorSyncStart/8)) + { + pTiming->HorSyncEnd += 0x20; + } + pTiming->HorSyncEnd *= 8; + pTiming->HorSyncEnd += (CBIOS_U16)(HSyncRemainder + HSSRemainder); + + pTiming->HorDisEnd = (CBIOS_U16)cbMapMaskRead(pcbe, HDE2Reg_INDEX, IGAIndex); //Horizontal Display End + //rounded up to the nearest integer + if(HDisEndRemainder) + { + pTiming->HorDisEnd = pTiming->HorDisEnd * 8; + } + else + { + pTiming->HorDisEnd = (pTiming->HorDisEnd + 1) * 8; + } + pTiming->HorDisEnd += (CBIOS_U16)HDisEndRemainder; + + pTiming->HorBStart = (CBIOS_U16)cbMapMaskRead(pcbe, HBS2Reg_INDEX, IGAIndex); //Horizontal Blank Start + pTiming->HorBStart *= 8; + + pTiming->HorBEnd = (CBIOS_U16)cbMapMaskRead(pcbe, HBE2Reg_INDEX, IGAIndex); //Horizontal Blank End + if (pTiming->HorBEnd >= HorTotalReg + 3) + { + pTiming->HorBEnd += 0x02; + pTiming->HorBEnd *= 8; + pTiming->HorBEnd += (CBIOS_U16)(HSSRemainder + HSyncRemainder + HBackPorchRemainder); + } + else + { + pTiming->HorBEnd *= 8; + } + + //================================================================// + //************Start Getting Vertical Timing Registers*************// + //================================================================// + pTiming->VerTotal = (CBIOS_U16)cbMapMaskRead(pcbe, VT2Reg_INDEX, IGAIndex); //Vertical Total + pTiming->VerTotal +=2; + + pTiming->VerDisEnd = (CBIOS_U16)cbMapMaskRead(pcbe, VDE2Reg_INDEX, IGAIndex); //Vertical Display End + pTiming->VerDisEnd++; + + pTiming->VerBStart = (CBIOS_U16)cbMapMaskRead(pcbe, VBS2Reg_INDEX, IGAIndex); //Vertical Blank Start + pTiming->VerBStart++; + + temp = cbMapMaskRead(pcbe, VBE2Reg_INDEX, IGAIndex); //Vertical Blank End + temp++; + pTiming->VerBEnd = (temp & 0xFF) | (pTiming->VerBStart & ~(0xFF)); + if (pTiming->VerBEnd <= pTiming->VerBStart ) + { + pTiming->VerBEnd += 0x100; + } + if(pTiming->VerBEnd >= pTiming->VerTotal - 2) + { + pTiming->VerBEnd += 1; + } + + pTiming->VerSyncStart = (CBIOS_U16)cbMapMaskRead(pcbe, VSS2Reg_INDEX, IGAIndex); //Vertical Sync Start + pTiming->VerSyncStart++; + + temp = cbMapMaskRead(pcbe, VSE2Reg_INDEX, IGAIndex); //Vertical Sync End + temp++; + pTiming->VerSyncEnd = (temp & 0x0F) | (pTiming->VerSyncStart & ~(0x0F)); + if (pTiming->VerSyncEnd <= pTiming->VerSyncStart) + { + pTiming->VerSyncEnd += 0x10; + } + + //calculate the result value + pTiming->XRes = pTiming->HorDisEnd; + pTiming->YRes = pTiming->VerDisEnd; + + temp = (CBIOS_U32)pTiming->HorTotal * (CBIOS_U32)pTiming->VerTotal; + pTiming->RefreshRate = pTiming->PLLClock * 100 / temp; + remainder = (pTiming->PLLClock * 100) % temp; + pTiming->RefreshRate = pTiming->RefreshRate * 100 + remainder * 100 / temp; +} + + +CBIOS_VOID cbGetModeInfoFromReg_Arise(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_ACTIVE_TYPE ulDevice, + PCBIOS_TIMING_ATTRIB pTiming, + PCBIOS_TIMING_FLAGS pFlags, + CBIOS_U32 IGAIndex, + CBIOS_TIMING_REG_TYPE TimingRegType) +{ + REG_SR70_B RegSR70_BValue; + REG_MM33694 RegMM33694; + + + if(TIMING_REG_TYPE_CR == TimingRegType) + { + cbGetCRTimingReg_Arise(pcbe, pTiming, IGAIndex, pFlags); + } + else if(TIMING_REG_TYPE_SR == TimingRegType) + { + cbGetSRTimingReg_Arise(pcbe, pTiming, IGAIndex, pFlags); + } + else + { + cbGetSRTimingReg_Arise(pcbe, pTiming, IGAIndex, pFlags); + } + + // judge if timing mode is interlaced or not + switch (ulDevice) + { + case CBIOS_TYPE_CRT: + case CBIOS_TYPE_DVO: + pFlags->IsInterlace = 0; + break; + case CBIOS_TYPE_HDTV: + RegSR70_BValue.Value = 0; + RegSR70_BValue.Value = cbMMIOReadReg(pcbe, SR_B_70); + if (RegSR70_BValue.Progressive_Mode_Enable == 0) + { + pFlags->IsInterlace = 1; + } + else + { + pFlags->IsInterlace = 0; + } + break; + case CBIOS_TYPE_DP1: + case CBIOS_TYPE_DP2: + case CBIOS_TYPE_DP3: + case CBIOS_TYPE_DP4: + RegMM33694.Value = cb_ReadU32(pcbe->pAdapterContext, HDTV_REG_LB[IGAIndex]); + if (RegMM33694.LB1_BYPASS == 0) // HDTV source + { + RegSR70_BValue.Value = 0; + RegSR70_BValue.Value = cbMMIOReadReg(pcbe, SR_B_70); + if (0)//RegSR70_BValue.Progressive_Mode_Enable == 0) //can't find this define in e3k register spec, just comment interlace mode + { + pFlags->IsInterlace = 1; + } + else + { + pFlags->IsInterlace = 0; + } + } + else + { + pFlags->IsInterlace = 0; + } + break; + case CBIOS_TYPE_TV: + pFlags->IsInterlace = 1; + break; + + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "unknown device type!\n")); + return; + } +} + +CBIOS_STATUS cbInterruptEnableDisable_Arise(PCBIOS_EXTENSION_COMMON pcbe,PCBIOS_INT_ENABLE_DISABLE_PARA pIntPara) +{ + CBIOS_U32 Status = CBIOS_OK; + CBIOS_U32 RegValue = 0; + REG_MM8508 RegMM8508Value; + REG_MM8508 RegMM8508Mask; + REG_MM854C RegMM854CValue; + REG_MM854C RegMM854CMask; + + RegMM8508Value.Value = 0; + RegMM8508Mask.Value = 0xFFFFFFFF; + RegMM854CValue.Value = 0; + RegMM854CMask.Value = 0xFFFFFFFF; + + if (pIntPara->bEnableInt) + { + RegValue = 1; + } + else + { + RegValue = 0; + } + + if (pIntPara->bUpdAllInt) + { + RegMM8508Value.Value = (pIntPara->bEnableInt) ? 0xFFFFFFFF : 0; + RegMM8508Mask.Value = 0; + // Enable/Disable all BIU interrupts + cbMMIOWriteReg32(pcbe, 0x8508, RegMM8508Value.Value, RegMM8508Mask.Value); + } + else + { + if (pIntPara->IntFlags & CBIOS_VSYNC_1_INT) + { + RegMM8508Value.VSYNC1_INT_EN = RegValue; + RegMM8508Mask.VSYNC1_INT_EN = 0; + } + if (pIntPara->IntFlags & CBIOS_VSYNC_2_INT) + { + RegMM8508Value.VSYNC2_INT_EN = RegValue; + RegMM8508Mask.VSYNC2_INT_EN = 0; + } + if (pIntPara->IntFlags & CBIOS_VSYNC_3_INT) + { + RegMM8508Value.VSYNC3_INT_EN = RegValue; + RegMM8508Mask.VSYNC3_INT_EN = 0; + } + if (pIntPara->IntFlags & CBIOS_VSYNC_4_INT) + { + RegMM8508Value.VSYNC4_INT_EN = RegValue; + RegMM8508Mask.VSYNC4_INT_EN = 0; + } + if ((pIntPara->IntFlags & CBIOS_DP_1_INT) && (pcbe->DeviceMgr.SupportDevices & CBIOS_TYPE_DP1)) + { + RegMM8508Value.DP1_INT_EN = RegValue; + RegMM8508Mask.DP1_INT_EN = 0; + } + if ((pIntPara->IntFlags & CBIOS_DP_2_INT) && (pcbe->DeviceMgr.SupportDevices & CBIOS_TYPE_DP2)) + { + RegMM8508Value.DP2_INT_EN = RegValue; + RegMM8508Mask.DP2_INT_EN = 0; + } + if ((pIntPara->IntFlags & CBIOS_DP_3_INT) && (pcbe->DeviceMgr.SupportDevices & CBIOS_TYPE_DP3)) + { + RegMM8508Value.DP3_INT_EN = RegValue; + RegMM8508Mask.DP3_INT_EN = 0; + } + if ((pIntPara->IntFlags & CBIOS_DP_4_INT) && (pcbe->DeviceMgr.SupportDevices & CBIOS_TYPE_DP4)) + { + RegMM8508Value.DP4_INT_EN = RegValue; + RegMM8508Mask.DP4_INT_EN = 0; + } + if (pIntPara->IntFlags & CBIOS_HDCP_INT) + { + RegMM8508Value.HDCP_INT_EN = RegValue; + RegMM8508Mask.HDCP_INT_EN = 0; + } + if (pIntPara->IntFlags & CBIOS_HDA_CODEC_INT) + { + RegMM8508Value.INT_VIP_INT_EN = RegValue; + RegMM8508Mask.INT_VIP_INT_EN = 0; + + // Arise1020 use mb INT bit as CODEC INT + RegMM8508Value.INT_MB_INT_EN = RegValue; + RegMM8508Mask.INT_MB_INT_EN = 0; + } + /* + if (pIntPara->IntFlags & CBIOS_VCP_TIMEOUT_INT) + { + RegMM8508Value.VCP_TIMEOUT_INT_EN = RegValue; + RegMM8508Mask.VCP_TIMEOUT_INT_EN = 0; + } + if(pIntPara->IntFlags & CBIOS_MSVD_TIMEOUT_INT) + { + RegMM8508Value.MSVD_TIMEOUT_INT_EN = RegValue; + RegMM8508Mask.MSVD_TIMEOUT_INT_EN = 0; + }*/ + + // Enable/Disable specified BIU interrupts + cbMMIOWriteReg32(pcbe, 0x8508, RegMM8508Value.Value, RegMM8508Mask.Value); + } + + if (pIntPara->bUpdAllAdvInt) + { + RegMM854CValue.Value = (pIntPara->bEnableInt) ? 0xFFFFFFFF : 0; + RegMM854CMask.Value = 0; + // Enable/Disable all Advanced interrupts + cbMMIOWriteReg32(pcbe, 0x854C, RegMM854CValue.Value, RegMM854CMask.Value); + } + else + { + if (pIntPara->AdvancedIntFlags & CBIOS_FENCE_INT) + { + RegMM854CValue.FENCE_CMD_INT_EN = RegValue; + RegMM854CMask.FENCE_CMD_INT_EN = 0; + } + /* + if (pIntPara->AdvancedIntFlags & CBIOS_PAGE_FAULT_INT) + { + RegMM854CValue.Page_Fault_Int = RegValue; + RegMM854CMask.Page_Fault_Int = 0; + } + if (pIntPara->AdvancedIntFlags & CBIOS_MXU_INVALID_ADDR_FAULT_INT) + { + RegMM854CValue.MXU_Invalid_Address_Fault_Int = RegValue; + RegMM854CMask.MXU_Invalid_Address_Fault_Int = 0; + } + if (pIntPara->AdvancedIntFlags & CBIOS_MSVD0_INT) + { + RegMM854CValue.VCP_cmd_Int = RegValue; + RegMM854CMask.VCP_cmd_Int = 0; + } + if (pIntPara->AdvancedIntFlags & CBIOS_MSVD1_INT) + { + RegMM854CValue.Dump_cmd_Int = RegValue; + RegMM854CMask.Dump_cmd_Int = 0; + }*/ + + // Enable/Disable specified advanced interrupts + cbMMIOWriteReg32(pcbe, 0x854C, RegMM854CValue.Value, RegMM854CMask.Value); + } + + if(pIntPara->bEnableInt) + { + //Enable PCIE bus interrupts report. CRA0_C=0x01 + cbMMIOWriteReg(pcbe, CR_C_A0, 0x01, ~0x01); + } + else if(pIntPara->bUpdAllAdvInt && pIntPara->bUpdAllInt) + { + cbMMIOWriteReg(pcbe, CR_C_A0, 0x00, ~0x01); + } + + return Status; +} + +CBIOS_STATUS cbCheckSurfaceOnDisplay_Arise(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_CHECK_SURFACE_ON_DISP pChkSurfacePara) +{ + CBIOS_STREAM_ATTRIBUTE StreamAttr = {0}; + CBIOS_STREAM_TP StreamType = pChkSurfacePara->StreamType; + CBIOS_U32 IGAIndex = pChkSurfacePara->IGAIndex; + CBIOS_U64 PhyAddr = 0; + CBIOS_U32 BaseOffset = 0; + + CBIOS_U32 AddrRegValue = 0; + REG_MM81DC_Arise PSStartAddrValue = {0}; + REG_MM81D0_Arise SSStartAddrValue = {0}; + + CBIOS_U32 BaseOffsetRegValue = 0; + REG_MM33700_Arise PSBaseOffsetValue = {0}; + REG_MM33708_Arise SSBaseOffsetValue = {0}; + + CBIOS_BOOL bOnDisplay = CBIOS_TRUE; + + CheckCnt++; + + if(pChkSurfacePara->bChkAfterEnable) + { + StreamAttr.pSurfaceAttr = pChkSurfacePara->pSurfaceAttr; + StreamAttr.pSrcWinPara = pChkSurfacePara->pSrcWindow; + cbGetStreamAttribute(&StreamAttr); + PhyAddr = StreamAttr.pSurfaceAttr->StartAddr; + BaseOffset = StreamAttr.dwBaseOffset; + } + else + { + PhyAddr = STREAM_DISABLE_FAKE_ADDR; + BaseOffset = 0; + } + + if(StreamType == CBIOS_STREAM_PS) + { + PSStartAddrValue.Value = cb_ReadU32(pcbe->pAdapterContext, PSStartAddrIndex[IGAIndex]); + PSBaseOffsetValue.Value = cb_ReadU32(pcbe->pAdapterContext, PSBaseOffsetIndex[IGAIndex]); + AddrRegValue = PSStartAddrValue.PS1_Start_Address; + BaseOffsetRegValue = PSBaseOffsetValue.Base_Offset; + } + else if(StreamType == CBIOS_STREAM_SS) + { + SSStartAddrValue.Value = cb_ReadU32(pcbe->pAdapterContext, SSStartAddrIndex[IGAIndex]); + SSBaseOffsetValue.Value = cb_ReadU32(pcbe->pAdapterContext, SSBaseOffsetIndex[IGAIndex]); + AddrRegValue = SSStartAddrValue.SS_Start_Address0; + BaseOffsetRegValue = SSBaseOffsetValue.SS_Base_Offset; + } + else if(StreamType == CBIOS_STREAM_TS) + { + SSStartAddrValue.Value = cb_ReadU32(pcbe->pAdapterContext, TQSStartAddrIndex[0][IGAIndex]); + SSBaseOffsetValue.Value = cb_ReadU32(pcbe->pAdapterContext, TQSBaseOffsetIndex[0][IGAIndex]); + AddrRegValue = SSStartAddrValue.SS_Start_Address0; + BaseOffsetRegValue = SSBaseOffsetValue.SS_Base_Offset; + } + else + { + SSStartAddrValue.Value = cb_ReadU32(pcbe->pAdapterContext, TQSStartAddrIndex[1][IGAIndex]); + SSBaseOffsetValue.Value = cb_ReadU32(pcbe->pAdapterContext, TQSBaseOffsetIndex[1][IGAIndex]); + AddrRegValue = SSStartAddrValue.SS_Start_Address0; + BaseOffsetRegValue = SSBaseOffsetValue.SS_Base_Offset; + } + + if(AddrRegValue != (PhyAddr >> 5) || + BaseOffsetRegValue != (BaseOffset >> 5)) + { + bOnDisplay = CBIOS_FALSE; + } + + pChkSurfacePara->bOnDisplay = bOnDisplay; + + if(CheckCnt <= 6) + { + if(pChkSurfacePara->pSrcWindow) + { + cbDebugPrint((MAKE_LEVEL_EX(BACK,GENERIC,DEBUG), "Check %d: Addr=%x,Pitch=%d,FixedAddr=%x, OnDisp=%d.\n\n", + StreamType, pChkSurfacePara->pSurfaceAttr->StartAddr, pChkSurfacePara->pSurfaceAttr->Pitch, + PhyAddr, bOnDisplay)); + } + else + { + cbDebugPrint((MAKE_LEVEL_EX(BACK,GENERIC,DEBUG), "Check %d(disable): Addr=%x, OnDisp=%d.\n\n", StreamType, + pChkSurfacePara->pSurfaceAttr->StartAddr, bOnDisplay)); + } + } + + return CBIOS_OK; +} + +CBIOS_STATUS cbGetDispAddr_Arise(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_GET_DISP_ADDR pGetDispAddr) +{ + CBIOS_STREAM_TP StreamType = pGetDispAddr->StreamType; + CBIOS_U32 IGAIndex = pGetDispAddr->IGAIndex; + CBIOS_U64 AddrRegValue = 0; + REG_MM81DC_Arise PSStartAddrValue = {0}; + REG_MM81D0_Arise SSStartAddrValue = {0}; + + if(StreamType == CBIOS_STREAM_PS) + { + PSStartAddrValue.Value = cb_ReadU32(pcbe->pAdapterContext, PSStartAddrIndex[IGAIndex]); + AddrRegValue = PSStartAddrValue.PS1_Start_Address; + } + else if(StreamType == CBIOS_STREAM_SS) + { + SSStartAddrValue.Value = cb_ReadU32(pcbe->pAdapterContext, SSStartAddrIndex[IGAIndex]); + AddrRegValue = SSStartAddrValue.SS_Start_Address0; + } + else if(StreamType == CBIOS_STREAM_TS) + { + SSStartAddrValue.Value = cb_ReadU32(pcbe->pAdapterContext, TQSStartAddrIndex[0][IGAIndex]); + AddrRegValue = SSStartAddrValue.SS_Start_Address0; + } + else + { + SSStartAddrValue.Value = cb_ReadU32(pcbe->pAdapterContext, TQSStartAddrIndex[1][IGAIndex]); + AddrRegValue = SSStartAddrValue.SS_Start_Address0; + } + + pGetDispAddr->DispAddr = AddrRegValue << 5; + + + return CBIOS_OK; +} + +CBIOS_BOOL cbUpdateOverlay_Arise(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U32 IGAIndex, + CBIOS_U32 OvlIndex, + CBIOS_STREAM_TP StreamType, + PCBIOS_OVERLAY_INFO pOverlayInfo, + PCBIOS_FLIP_MODE pFlipMode) +{ + REG_MM33670_Arise BackgndValue = {0}; + REG_MM33840_Arise OvlKeyValue = {0}; + REG_MM33844_Arise OvlPlaneAlphaValue = {0}; + CBIOS_U32 KeyMode = 0; + CBIOS_U8 Kp = 0, Ks = 0; + + if(OvlIndex == CBIOS_OVERLAY0) + { + BackgndValue.Backgnd_Color_Value = 0; // black background + BackgndValue.Backgnd_Color_Ycbcr = 0; + } + + if(pFlipMode->FlipType == CBIOS_PLANE_FLIP_WITH_DISABLE) + { + KeyMode = 0; + Kp = 8; + Ks = 0; + } + else + { + KeyMode = cbGetHwColorKey(pOverlayInfo, &Ks, &Kp); + + //invert alpha + if((pOverlayInfo->KeyMode == CBIOS_CONSTANT_ALPHA && pOverlayInfo->ConstantAlphaBlending.bInvertAlpha) || + (pOverlayInfo->KeyMode == CBIOS_ALPHA_BLENDING && pOverlayInfo->AlphaBlending.bInvertAlpha)) + { + OvlKeyValue.Invert_Alpha_Or_Ka = 1; + } + + //pre-multi + if(pOverlayInfo->KeyMode == CBIOS_ALPHA_BLENDING && pOverlayInfo->AlphaBlending.bPremulBlend) + { + OvlPlaneAlphaValue.Ovl0_Alpha_Blend_Mode = 1; + } + + //plane alpha + if(pOverlayInfo->KeyMode == CBIOS_ALPHA_BLENDING) + { + OvlPlaneAlphaValue.Ovl0_Plane_Alpha = + pOverlayInfo->AlphaBlending.bUsePlaneAlpha ? pOverlayInfo->AlphaBlending.PlaneValue : 0xff; + } + if(pOverlayInfo->KeyMode == CBIOS_CONSTANT_ALPHA) + { + OvlPlaneAlphaValue.Ovl0_Plane_Alpha = + pOverlayInfo->ConstantAlphaBlending.bUsePlaneAlpha ? pOverlayInfo->ConstantAlphaBlending.PlaneValue : 0xff; + } + + //mix alpha + if(pOverlayInfo->KeyMode == CBIOS_ALPHA_BLENDING) + { + OvlKeyValue.Alpha_Select = pOverlayInfo->AlphaBlending.AlphaMixType; + } + + //color key select + if(pOverlayInfo->KeyMode == CBIOS_COLOR_KEY) + { + OvlKeyValue.Color_Key_Sel = pOverlayInfo->ColorKey.ColorKeyType; + } + } + + OvlKeyValue.Ka_3to0_Or_Ks = Ks; + OvlKeyValue.Ka_7to4_Or_Kp = Kp; + OvlKeyValue.Key_Mode = KeyMode; + OvlKeyValue.Ovl0_Input_Stream = StreamType; + + if(OvlIndex == CBIOS_OVERLAY0) + { + cbMMIOWriteReg32(pcbe, BackgndColorIndex[IGAIndex], BackgndValue.Value, 0); + } + + cbMMIOWriteReg32(pcbe, OvlKeyIndex[IGAIndex][OvlIndex], OvlKeyValue.Value, 0); + cbMMIOWriteReg32(pcbe, OvlPlaneAlphaIndex[IGAIndex][OvlIndex], OvlPlaneAlphaValue.Value, 0); + + return CBIOS_TRUE; +} + + +/* + * flip mode is set by the corresponding stream + * so flip mode is no need in the parameters' list + */ +CBIOS_BOOL cbUpdateOVLKey_Arise(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U32 IGAIndex, + CBIOS_OVL_KEY_INFO *pInfo) +{ + REG_MM8188_Arise PSKeyHighValue = {0}; + REG_MM81AC_Arise PSKeyLowValue = {0}; + + if (CBIOS_OVL_KEY_TYPE_ALPHA == pInfo->Type) + { + PSKeyLowValue.PS_B_Cb_Low_Or_Alpha_Key = pInfo->AlphaKey; + PSKeyHighValue.Value = 0; + } + else if (CBIOS_OVL_KEY_TYPE_COLOR == pInfo->Type) + { + PSKeyLowValue.Value = pInfo->ColorKey; + PSKeyHighValue.Value = 0; + } + else if (CBIOS_OVL_KEY_TYPE_CHROME == pInfo->Type) + { + PSKeyLowValue.Value = pInfo->ChromeKey.LowColor; + PSKeyHighValue.Value = pInfo->ChromeKey.UpColor; + } + else + { + return CBIOS_FALSE; + } + + cbMMIOWriteReg32(pcbe, KeyHighIndex[IGAIndex][pInfo->Index], PSKeyHighValue.Value, 0); + cbMMIOWriteReg32(pcbe, KeyLowIndex[IGAIndex][pInfo->Index], PSKeyLowValue.Value, 0); + + return CBIOS_TRUE; +} + + +CBIOS_BOOL cbUpdatePrimaryStream_Arise(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U32 IGAIndex, + PCBIOS_STREAM_PARA pStreamPara, + PCBIOS_FLIP_MODE pFlipMode) +{ + PCBIOS_SURFACE_ATTRIB pSurfaceAttrib = CBIOS_NULL; + PCBIOS_DISP_MODE_PARAMS pModeParams = pcbe->DispMgr.pModeParams[IGAIndex]; + CBIOS_U64 ullStartAddress = 0; + CBIOS_U32 dwBitCnt = 0, dwFetchCount = 0, DacColorMode = 0; + PCBIOS_WINDOW_PARA pSrcWin = CBIOS_NULL, pDstWin = CBIOS_NULL; + CBIOS_STREAM_ATTRIBUTE StreamAttr = {0}; + REG_MM81A4_Arsie PSCompFifoValue = {0}; + REG_MM81DC_Arise PSStartAddrValue = {0}; + REG_MM33700_Arise PSBaseOffsetValue = {0}; + REG_MM81C4_Arise PSVsyncOff = {0}; + REG_MM81E0_Arise PSRightBaseValue = {0}; + REG_MM81C8_Arise PSStrideValue = {0}; + REG_MM81FC_Arise PSShadowValue = {0}; + REG_MM33644_Arise PSCscValue = {0}; + REG_MM33810_Arise PS1BLIIndexValue = {0}; + REG_MM33E6C_Arise PS2BLIIndexValue = {0}; + + //use mmio + cbBiosMMIOWriteReg(pcbe, CR_67, 0x08, ~0x08, IGAIndex); + cbBiosMMIOWriteReg(pcbe, CR_64, 0x40, ~0x40, IGAIndex); + + if(pFlipMode->FlipType == CBIOS_PLANE_FLIP_WITH_DISABLE) + { + ullStartAddress = STREAM_DISABLE_FAKE_ADDR; + } + else + { + pSurfaceAttrib = &pStreamPara->SurfaceAttrib; + pSrcWin = &pStreamPara->SrcWindow; + pDstWin = &pStreamPara->DispWindow; + + StreamAttr.pSurfaceAttr = pSurfaceAttrib; + StreamAttr.pSrcWinPara = pSrcWin; + cbGetStreamAttribute(&StreamAttr); + ullStartAddress = pSurfaceAttrib->StartAddr; + } + + PSStartAddrValue.PS1_Start_Address = (CBIOS_U32)(ullStartAddress >> 5); + + if(pFlipMode->FlipType == CBIOS_PLANE_FLIP_WITH_DISABLE) + { + PSShadowValue.PS_Disable = 1; + PSBaseOffsetValue.Base_Offset = 0; + cbMMIOWriteReg32(pcbe, PSBaseOffsetIndex[IGAIndex], PSBaseOffsetValue.Value, 0); + cbMMIOWriteReg32(pcbe, PSStartAddrIndex[IGAIndex], PSStartAddrValue.Value, 0); + cbMMIOWriteReg32(pcbe, PSShadowIndex[IGAIndex], PSShadowValue.Value, 0); + return CBIOS_TRUE; + } + + PSBaseOffsetValue.Base_Offset = StreamAttr.dwBaseOffset >> 5; + PSStrideValue.PS_Pixel_Offset = StreamAttr.PixelOffset; + PSStrideValue.PS_Pixel_Offset_Bit4 = StreamAttr.PixelOffset >> 4; + PSStrideValue.PS_Stride = StreamAttr.dwStride; + + if(pSurfaceAttrib->SurfaceFmt & (CBIOS_FMT_A2B10G10R10 | CBIOS_FMT_A8B8G8R8 | CBIOS_FMT_X8B8G8R8)) + { + PSStrideValue.PS_Abgr_En = 1; //DX10 ABGR format enabled for PS1 + } + if(pSurfaceAttrib->SurfaceFmt & (CBIOS_FMT_YCRYCB422_16BIT | CBIOS_FMT_YCRYCB422_32BIT)) + { + PSStrideValue.PS_Uyvy422 = 1; + } + if(pSurfaceAttrib->SurfaceFmt & (CBIOS_FMT_YCBCR8888_32BIT | CBIOS_FMT_YCBCR2101010_32BIT)) + { + PSStrideValue.PS_Ycbcr_Mode = 1; + } + + if(pSurfaceAttrib->bCompress) + { + PSCompFifoValue.PS_Compress_Type = pSurfaceAttrib->Range_Type; + if (0 == IGAIndex) + { + PS1BLIIndexValue.PS1_BL_IDX = pSurfaceAttrib->BLIndex; + } + else + { + PS2BLIIndexValue.PS2_BL_IDX = pSurfaceAttrib->BLIndex; + } + PSShadowValue.PS_Compress_Enable = 1; + } + PSCompFifoValue.PS_Fifo_Depth = 0; //256 + if(pSrcWin->WinSize == pDstWin->WinSize) + { + PSCompFifoValue.PS_Share_Scl_Fifo = 1; + } + + DacColorMode = cbGetHwDacMode(pcbe, pSurfaceAttrib->SurfaceFmt); + + if(pSurfaceAttrib->SurfaceFmt == CBIOS_FMT_P8) + { + dwBitCnt = 8; + } + else if(pSurfaceAttrib->SurfaceFmt & CBIOS_STREAM_16BPP_FMTS) + { + dwBitCnt = 16; + } + else + { + dwBitCnt = 32; + } + + dwFetchCount = (pModeParams->SrcModePara.XRes & 0xFFFF)* dwBitCnt; + if(pSurfaceAttrib->b3DMode && pModeParams->Video3DStruct == SIDE_BY_SIDE_HALF) + { + dwFetchCount /= 2; + } + dwFetchCount = (dwFetchCount + 255) / 256; + + PSShadowValue.DAC_Color_Mode = DacColorMode; + PSShadowValue.PS_L1_10to0 = dwFetchCount & 0x7ff; + PSShadowValue.PS_L1_Bit11 = (dwFetchCount >> 11) & 0x1; + PSShadowValue.Enable_PS_L1 = 1; + PSShadowValue.PS_Read_Length = 2; + PSShadowValue.PS_Disable = 0; + if(pSurfaceAttrib->b3DMode) + { + PSShadowValue.PS_3D_Video_Mode = cbGetHw3DVideoMode(pSurfaceAttrib->Surface3DPara.Video3DStruct); + } + + if(pSurfaceAttrib->SurfaceFmt & CBIOS_STREAM_FMT_YUV_SPACE) + { + if(pModeParams->TargetModePara.YRes >= 720) + { + PSCscValue.PS_Data_In_Fmt = CSC_FMT_YCBCR709; + } + else + { + PSCscValue.PS_Data_In_Fmt = CSC_FMT_YCBCR601; + } + } + else + { + PSCscValue.PS_Data_In_Fmt = CSC_FMT_RGB; + } + PSCscValue.PS_Data_Out_Fmt = CSC_FMT_RGB; + + if(pSurfaceAttrib->b3DMode) + { + PSRightBaseValue.PS_Right_Frame_Base = ((pSurfaceAttrib->Surface3DPara.RightFrameOffset & ~0xf) >> 4); + } + + if(pFlipMode->FlipImme) + { + PSVsyncOff.VsyncOff = 1; + } + + cbMMIOWriteReg32(pcbe, PSVsyncOffIndex[IGAIndex], PSVsyncOff.Value, 0); + + cbMMIOWriteReg32(pcbe, PSCompFifoIndex[IGAIndex], PSCompFifoValue.Value, 0); + cbMMIOWriteReg32(pcbe, PSStartAddrIndex[IGAIndex], PSStartAddrValue.Value, 0); + cbMMIOWriteReg32(pcbe, PSBaseOffsetIndex[IGAIndex], PSBaseOffsetValue.Value, 0); + cbMMIOWriteReg32(pcbe, PSRightBaseIndex[IGAIndex], PSRightBaseValue.Value, 0); + cbMMIOWriteReg32(pcbe, PSStrideIndex[IGAIndex], PSStrideValue.Value, 0); + cbMMIOWriteReg32(pcbe, PSShadowIndex[IGAIndex], PSShadowValue.Value, 0); + cbMMIOWriteReg32(pcbe, PSCscIndex[IGAIndex], PSCscValue.Value, 0); + + if (0 == IGAIndex) + { + cbMMIOWriteReg32(pcbe, PSBLIndex[IGAIndex], PS1BLIIndexValue.Value, 0); + } + else + { + cbMMIOWriteReg32(pcbe, PSBLIndex[IGAIndex], PS2BLIIndexValue.Value, 0); + } + + + return CBIOS_TRUE; +} + +CBIOS_BOOL cbUpdateSecondStream_Arise(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U32 IGAIndex, + PCBIOS_STREAM_PARA pStreamPara, + PCBIOS_FLIP_MODE pFlipMode) +{ + PCBIOS_SURFACE_ATTRIB pSurfaceAttrib = CBIOS_NULL; + PCBIOS_DISP_MODE_PARAMS pModeParams = pcbe->DispMgr.pModeParams[IGAIndex]; + PCBIOS_WINDOW_PARA pSrcWin = CBIOS_NULL, pDstWin = CBIOS_NULL; + CBIOS_U64 ullStartAddress = 0; + CBIOS_STREAM_ATTRIBUTE StreamAttr = {0}; + REG_MM8198_Arise SSCompFifoValue = {0}; + REG_MM81D0_Arise SSStartAddrValue = {0}; + REG_MM33708_Arise SSBaseOffsetValue = {0}; + REG_MM33834_Arise SSEnableValue = {0}; + REG_MM81D4_Arise SSRightBaseValue = {0}; + REG_MM81D8_Arise SSStrideValue = {0}; + REG_MM8190_Arise SSFmtSrcWValue = {0}; + REG_MM819C_Arise SSDstWinValue = {0}; + REG_MM81A8_Arise SSSrcWinHValue = {0}; + REG_MM81F8_Arise SSDstWinPosValue = {0}; + REG_MM332E0_Arise SSScalRatioHValue = {0}; + REG_MM332E4_Arise SSScalRatioVValue = {0}; + REG_MM3362C_Arise SSCscValue = {0}; + REG_MM33854_Arise SSBLIndexValue = {0}; + + if(pFlipMode->FlipType == CBIOS_PLANE_FLIP_WITH_DISABLE) + { + ullStartAddress = STREAM_DISABLE_FAKE_ADDR; + } + else + { + pSurfaceAttrib = &pStreamPara->SurfaceAttrib; + pSrcWin = &pStreamPara->SrcWindow; + pDstWin = &pStreamPara->DispWindow; + + StreamAttr.pSurfaceAttr = pSurfaceAttrib; + StreamAttr.pSrcWinPara = pSrcWin; + cbGetStreamAttribute(&StreamAttr); + ullStartAddress = pSurfaceAttrib->StartAddr; + } + + SSStartAddrValue.SS_Start_Address0 = (CBIOS_U32)(ullStartAddress >> 5); + + SSEnableValue.SS_Use_Mmio_En = 1; + if(pFlipMode->FlipType == CBIOS_PLANE_FLIP_WITH_DISABLE) + { + SSEnableValue.SS_Enable = 0; + SSBaseOffsetValue.SS_Base_Offset = 0; + cbMMIOWriteReg32(pcbe, SSBaseOffsetIndex[IGAIndex], SSBaseOffsetValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSStartAddrIndex[IGAIndex], SSStartAddrValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSEnableIndex[IGAIndex], SSEnableValue.Value, 0); + return CBIOS_TRUE; + } + + SSEnableValue.SS_Enable = 1; + + SSBaseOffsetValue.SS_Base_Offset = StreamAttr.dwBaseOffset >> 5; + SSStrideValue.SS_Stride = StreamAttr.dwStride; + SSStrideValue.SS_Pixel_Offset = StreamAttr.PixelOffset; + SSStrideValue.SS_Read_Length = 3; //256 bits + if(pSurfaceAttrib->SurfaceFmt & (CBIOS_FMT_A2B10G10R10 | CBIOS_FMT_A8B8G8R8 | CBIOS_FMT_X8B8G8R8)) + { + SSStrideValue.SS_Abgr_En = 1; //DX10 ABGR format enabled for PS1 + } + + if(pSurfaceAttrib->bCompress) + { + SSCompFifoValue.SS_Comp_Mode_Enable = 1; + SSCompFifoValue.SS_Compress_Type = pSurfaceAttrib->Range_Type; + SSBLIndexValue.SS1_burst_index = pSurfaceAttrib->BLIndex; + } + SSCompFifoValue.SS_Fifo_Depth_Control = 0; //256 + if(pSrcWin->WinSize == pDstWin->WinSize) + { + SSCompFifoValue.SS_Share_Scaler_Fifo = 1; + } + + if(pSurfaceAttrib->SurfaceFmt & (CBIOS_FMT_YCRYCB422_16BIT | CBIOS_FMT_YCRYCB422_32BIT)) + { + SSFmtSrcWValue.SS_Uyvy422 = 1; + } + if(pSurfaceAttrib->SurfaceFmt & (CBIOS_FMT_YCBCR8888_32BIT | CBIOS_FMT_YCBCR2101010_32BIT)) + { + SSFmtSrcWValue.SS_YCbCr_Mode = 1; + } + SSFmtSrcWValue.SS_Input_Format = cbGetHwDacMode(pcbe, pSurfaceAttrib->SurfaceFmt); + SSFmtSrcWValue.SS_YCbCr_Mode = 0; //? + SSFmtSrcWValue.SS_Src_Line_Width = pSrcWin->WinSize & 0xFFFF; + + SSSrcWinHValue.SS_Line_Height = (pSrcWin->WinSize >> 16) & 0xFFFF; + + SSDstWinValue.SS_Dest_Width = pDstWin->WinSize & 0xFFFF; + SSDstWinValue.SS_Dest_Height = (pDstWin->WinSize >> 16) & 0xFFFF; + + SSDstWinPosValue.SS_X_Start = (pDstWin->Position & 0xFFFF) + 1; + SSDstWinPosValue.SS_Y_Start = ((pDstWin->Position >> 16) & 0xFFFF) + 1; + + if((pSrcWin->WinSize & 0xFFFF) == (pDstWin->WinSize & 0xFFFF)) + { + SSScalRatioHValue.SS_Hacc = 0x100000; + } + else + { + SSScalRatioHValue.SS_Hacc = ((1048576 * (pSrcWin->WinSize & 0xFFFF)) /(pDstWin->WinSize & 0xFFFF)) & 0x1FFFFF; + } + if((pSrcWin->WinSize & 0xFFFF0000) == (pDstWin->WinSize & 0xFFFF0000)) + { + SSScalRatioVValue.SS_Vacc = 0x100000; + } + else + { + SSScalRatioVValue.SS_Vacc = ((1048576 * ((pSrcWin->WinSize >> 16) & 0xFFFF)) /((pDstWin->WinSize >> 16) & 0xFFFF)) & 0x1FFFFF; + } + + if(pSurfaceAttrib->SurfaceFmt & CBIOS_STREAM_FMT_YUV_SPACE) + { + if(pModeParams->TargetModePara.YRes >= 720) + { + SSCscValue.SS_Data_In_Format = CSC_FMT_YCBCR709; + } + else + { + SSCscValue.SS_Data_In_Format = CSC_FMT_YCBCR601; + } + } + else + { + SSCscValue.SS_Data_In_Format = CSC_FMT_RGB; + } + SSCscValue.SS_Data_Out_Format = CSC_FMT_RGB; + + if(pSurfaceAttrib->b3DMode) + { + SSRightBaseValue.SS_Roffset = pSurfaceAttrib->Surface3DPara.RightFrameOffset; + } + + if(pFlipMode->FlipImme) + { + SSRightBaseValue.SS_Vsync_Off_Flip = 1; + } + + cbMMIOWriteReg32(pcbe, SSRightBaseIndex[IGAIndex], SSRightBaseValue.Value, 0); + + cbMMIOWriteReg32(pcbe, SSStartAddrIndex[IGAIndex], SSStartAddrValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSBaseOffsetIndex[IGAIndex], SSBaseOffsetValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSStrideIndex[IGAIndex], SSStrideValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSCompFifoIndex[IGAIndex], SSCompFifoValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSFmtSrcWIndex[IGAIndex], SSFmtSrcWValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSDstWinIndex[IGAIndex], SSDstWinValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSDstWinPosIndex[IGAIndex], SSDstWinPosValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSSrcWinHIndex[IGAIndex], SSSrcWinHValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSScalRatioHIndex[IGAIndex], SSScalRatioHValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSScalRatioVIndex[IGAIndex], SSScalRatioVValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSCscIndex[IGAIndex], SSCscValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSEnableIndex[IGAIndex], SSEnableValue.Value, 0); + cbMMIOWriteReg32(pcbe, SSBLIndex[IGAIndex], SSBLIndexValue.Value, 0); + + return CBIOS_TRUE; +} + +CBIOS_BOOL cbUpdateThdFourStream_Arise(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U32 IGAIndex, + CBIOS_STREAM_TP StreamIndex, + PCBIOS_STREAM_PARA pStreamPara, + PCBIOS_FLIP_MODE pFlipMode) +{ + PCBIOS_SURFACE_ATTRIB pSurfaceAttrib = CBIOS_NULL; + PCBIOS_DISP_MODE_PARAMS pModeParams = pcbe->DispMgr.pModeParams[IGAIndex]; + PCBIOS_WINDOW_PARA pSrcWin = CBIOS_NULL, pDstWin = CBIOS_NULL; + CBIOS_U64 ullStartAddress = 0; + CBIOS_U32 dwIndex = StreamIndex - CBIOS_STREAM_TS; + CBIOS_STREAM_ATTRIBUTE StreamAttr = {0}; + REG_MM8430_Arise TQSStartAddrValue = {0}; + REG_MM8414_Arise TQSCompFifoValue = {0}; + REG_MM8498_Arise TQSBaseOffsetValue = {0}; + REG_MM8458_Arise TQSEnableValue = {0}; + REG_MM844C_Arise TQSRightBaseValue = {0}; + REG_MM8438_Arise TQSStrideValue = {0}; + REG_MM33600_Arise TQSFormatValue = {0}; + REG_MM8444_Arise TQSDstWinPosValue = {0}; + REG_MM8450_Arise TQSDstWinValue = {0}; + REG_MM8448_Arise TQSSrcWinValue = {0}; + REG_MM84A4_Arise TQSScalRatioHValue = {0}; + REG_MM84A8_Arise TQSScalRatioVValue = {0}; + REG_MM33614_Arise TQSCscValue = {0}; + REG_MM33858_Arise TQSBLIndexValue = {0}; + + if(StreamIndex != CBIOS_STREAM_TS && StreamIndex != CBIOS_STREAM_FS) + { + return CBIOS_FALSE; + } + + //TS and QS can only use mmio + + if(pFlipMode->FlipType == CBIOS_PLANE_FLIP_WITH_DISABLE) + { + ullStartAddress = STREAM_DISABLE_FAKE_ADDR; + } + else + { + pSurfaceAttrib = &pStreamPara->SurfaceAttrib; + pSrcWin = &pStreamPara->SrcWindow; + pDstWin = &pStreamPara->DispWindow; + + StreamAttr.pSurfaceAttr = pSurfaceAttrib; + StreamAttr.pSrcWinPara = pSrcWin; + cbGetStreamAttribute(&StreamAttr); + ullStartAddress = pSurfaceAttrib->StartAddr; + } + + TQSStartAddrValue.TS_FB_Start_Address_0 = (CBIOS_U32)(ullStartAddress >> 5); + + if(pFlipMode->FlipType == CBIOS_PLANE_FLIP_WITH_DISABLE) + { + TQSEnableValue.TS_En = 0; + TQSBaseOffsetValue.TS_Win1_Base_Offset = 0; + cbMMIOWriteReg32(pcbe, TQSBaseOffsetIndex[dwIndex][IGAIndex], TQSBaseOffsetValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSStartAddrIndex[dwIndex][IGAIndex], TQSStartAddrValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSEnableIndex[dwIndex][IGAIndex], TQSEnableValue.Value, 0); + return CBIOS_TRUE; + } + + TQSEnableValue.TS_En = 1; + + TQSBaseOffsetValue.TS_Win1_Base_Offset = StreamAttr.dwBaseOffset >> 5; + TQSStrideValue.TS_Stride = StreamAttr.dwStride; + TQSStrideValue.TS_Start_Address_Byte_Offset = StreamAttr.PixelOffset; + TQSStrideValue.TS_Read_Length = 3; //256 bits + if(pSurfaceAttrib->SurfaceFmt & (CBIOS_FMT_A2B10G10R10 | CBIOS_FMT_A8B8G8R8 | CBIOS_FMT_X8B8G8R8)) + { + TQSStrideValue.TS_Abgr_En = 1; //DX10 ABGR format enabled for PS1 + } + + if(pSurfaceAttrib->bCompress) + { + TQSCompFifoValue.TS_Comp_Enable = 1; + TQSCompFifoValue.TS_Comp_Type = pSurfaceAttrib->Range_Type; + TQSBLIndexValue.TS_win1_burst_index = pSurfaceAttrib->BLIndex; + } + TQSCompFifoValue.TS_Fifo_Depth = 0; //256 + if(pSrcWin->WinSize == pDstWin->WinSize) + { + TQSCompFifoValue.TS_Share_Scaler_Fifo = 1; + } + + if(pSurfaceAttrib->SurfaceFmt & (CBIOS_FMT_YCRYCB422_16BIT | CBIOS_FMT_YCRYCB422_32BIT)) + { + TQSFormatValue.TS_YCbCr_Order = 1; + } + if(pSurfaceAttrib->SurfaceFmt & (CBIOS_FMT_YCBCR8888_32BIT | CBIOS_FMT_YCBCR2101010_32BIT)) + { + TQSFormatValue.TS_444_YCbCr_Order = 1; + } + TQSFormatValue.TS_Win1_Format = cbGetHwDacMode(pcbe, pSurfaceAttrib->SurfaceFmt); + + TQSSrcWinValue.TS_Win1_Src_W = pSrcWin->WinSize & 0xFFFF; + + TQSSrcWinValue.TS_Win1_Src_H = (pSrcWin->WinSize >> 16) & 0xFFFF; + + TQSDstWinValue.TS_Win1_Dst_W = pDstWin->WinSize & 0xFFFF; + TQSDstWinValue.TS_Win1_Dst_H = (pDstWin->WinSize >> 16) & 0xFFFF; + + TQSDstWinPosValue.TS_X_Start = (pDstWin->Position & 0xFFFF) + 1; + TQSDstWinPosValue.TS_Y_Start = ((pDstWin->Position >> 16) & 0xFFFF) + 1; + + if((pSrcWin->WinSize & 0xFFFF) == (pDstWin->WinSize & 0xFFFF)) + { + TQSScalRatioHValue.TS_Win1_Hacc = 0x100000; + } + else + { + TQSScalRatioHValue.TS_Win1_Hacc = ((1048576 * (pSrcWin->WinSize & 0xFFFF)) /(pDstWin->WinSize & 0xFFFF)) & 0x1FFFFF; + } + if((pSrcWin->WinSize & 0xFFFF0000) == (pDstWin->WinSize & 0xFFFF0000)) + { + TQSScalRatioVValue.TS_Win1_Vacc = 0x100000; + } + else + { + TQSScalRatioVValue.TS_Win1_Vacc = ((1048576 * ((pSrcWin->WinSize >> 16) & 0xFFFF)) /((pDstWin->WinSize >> 16) & 0xFFFF)) & 0x1FFFFF; + } + + if(pSurfaceAttrib->SurfaceFmt & CBIOS_STREAM_FMT_YUV_SPACE) + { + if(pModeParams->TargetModePara.YRes >= 720) + { + TQSCscValue.TS_In_Format = CSC_FMT_YCBCR709; + } + else + { + TQSCscValue.TS_In_Format = CSC_FMT_YCBCR601; + } + } + else + { + TQSCscValue.TS_In_Format = CSC_FMT_RGB; + } + TQSCscValue.TS_Out_Format = CSC_FMT_RGB; + + if(pSurfaceAttrib->b3DMode) + { + TQSRightBaseValue.TS_Win1_Roffset = pSurfaceAttrib->Surface3DPara.RightFrameOffset; + } + + if(pFlipMode->FlipImme) + { + TQSRightBaseValue.TS_Win1_Vsync_Off_Flip = 1; + } + + cbMMIOWriteReg32(pcbe, TQSRightBaseIndex[dwIndex][IGAIndex], TQSRightBaseValue.Value, 0); + + cbMMIOWriteReg32(pcbe, TQSStartAddrIndex[dwIndex][IGAIndex], TQSStartAddrValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSBaseOffsetIndex[dwIndex][IGAIndex], TQSBaseOffsetValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSStrideIndex[dwIndex][IGAIndex], TQSStrideValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSCompFifoIndex[dwIndex][IGAIndex], TQSCompFifoValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSFormatIndex[dwIndex][IGAIndex], TQSFormatValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSDstWinIndex[dwIndex][IGAIndex], TQSDstWinValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSDstWinPosIndex[dwIndex][IGAIndex], TQSDstWinPosValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSSrcWinIndex[dwIndex][IGAIndex], TQSSrcWinValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSScalRatioHIndex[dwIndex][IGAIndex], TQSScalRatioHValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSScalRatioVIndex[dwIndex][IGAIndex], TQSScalRatioVValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSCscIndex[dwIndex][IGAIndex], TQSCscValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSEnableIndex[dwIndex][IGAIndex], TQSEnableValue.Value, 0); + cbMMIOWriteReg32(pcbe, TQSBLIndex[dwIndex][IGAIndex], TQSBLIndexValue.Value, 0); + + return CBIOS_TRUE; +} + +CBIOS_STATUS cbDoCSCAdjust_Arise(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_ACTIVE_TYPE Device, PCBIOS_CSC_ADJUST_PARA pCSCAdjustPara) +{ + PCBIOS_CSC_ADJUST_PARA pAdjustPara = pCSCAdjustPara; + CBIOS_S64 CSCm[3][3]; + CSC_INDEX CSCIndex = 0; + REG_MM33698_Arise CSCCoef1RegValue = {0}, CSCCoef1RegMask = {0xffffffff}; + REG_MM3369C_Arise CSCCoef2RegValue = {0}, CSCCoef2RegMask = {0xffffffff}; + REG_MM336A0_Arise CSCCoef3RegValue = {0}, CSCCoef3RegMask = {0xffffffff}; + REG_MM336A4_Arise CSCCoef4RegValue = {0}, CSCCoef4RegMask = {0xffffffff}; + REG_MM336A8_Arise CSCCoef5RegValue = {0}, CSCCoef5RegMask = {0xffffffff}; + REG_MM33694_Arise LBCscFormatRegValue = {0}, LBCscFormatRegMask = {0xffffffff}; + REG_MM33868_Arise DACCscFormatRegValue = {0}, DACCscFormatRegMask = {0xffffffff}; + + cb_memset((PCBIOS_VOID)(CSCm), 0, sizeof(CSCm)); + + if(CBIOS_TYPE_DP1 == Device) + { + CSCIndex = CSC_INDEX_DP1; + } + else if(CBIOS_TYPE_DP2 == Device) + { + CSCIndex = CSC_INDEX_DP2; + } + else if(CBIOS_TYPE_DP3 == Device) + { + CSCIndex = CSC_INDEX_DP3; + } + else if(CBIOS_TYPE_DP4 == Device) + { + CSCIndex = CSC_INDEX_DP4; + } + else + { + CSCIndex = CSC_INDEX_CRT; + } + + LBCscFormatRegMask.Value = 0xffffffff; + DACCscFormatRegMask.Value = 0xffffffff; + + if (CSC_INDEX_CRT == CSCIndex) + { + DACCscFormatRegValue.Dac_Csc_In_Format = pAdjustPara->InputFormat; + DACCscFormatRegMask.Dac_Csc_In_Format = 0; + DACCscFormatRegValue.Dac_Csc_Out_Format = pAdjustPara->OutputFormat; + DACCscFormatRegMask.Dac_Csc_Out_Format = 0; + } + else + { + LBCscFormatRegValue.LB1_CSC_IN_FMT = pAdjustPara->InputFormat; + LBCscFormatRegMask.LB1_CSC_IN_FMT = 0; + LBCscFormatRegValue.LB1_CSC_OUT_FMT = pAdjustPara->OutputFormat; + LBCscFormatRegMask.LB1_CSC_OUT_FMT = 0; + } + + if(!pAdjustPara->Flag.bProgrammable) + { + if (CSC_INDEX_CRT == CSCIndex) + { + DACCscFormatRegValue.Dac_Csc_Program = 0; + DACCscFormatRegMask.Dac_Csc_Program = 0; + } + else + { + LBCscFormatRegValue.LB1_PROGRAMMBLE = 0; + LBCscFormatRegMask.LB1_PROGRAMMBLE = 0; + } + } + else + { + if (CSC_INDEX_CRT == CSCIndex) + { + DACCscFormatRegValue.Dac_Csc_Program = 1; + DACCscFormatRegMask.Dac_Csc_Program = 0; + } + else + { + LBCscFormatRegValue.LB1_PROGRAMMBLE = 1; + LBCscFormatRegMask.LB1_PROGRAMMBLE = 0; + } + + if(pAdjustPara->Bright > 255 || pAdjustPara->Bright < -255) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "CSC bright value should be [-255,255]!\n")); + } + else + { + if(pAdjustPara->Bright >= 0) + { + CSCCoef5RegValue.LB1_BRIGHT = pAdjustPara->Bright; + } + else + { + CSCCoef5RegValue.LB1_BRIGHT = (CBIOS_U32)(1 << CSC_BRIGHT_MODULE) + pAdjustPara->Bright; //get brightness 2's complement + } + CSCCoef5RegMask.LB1_BRIGHT = 0; + } + + if(cbGetCscCoefMatrix(pAdjustPara, + pCSCAdjustPara->InputFormat, + pCSCAdjustPara->OutputFormat, + CSCm)) + { + CSCCoef1RegValue.LB1_COEF_F1 = cbTran_CSCm_to_coef_fx(CSCm[0][0]); + CSCCoef1RegValue.LB1_COEF_F2 = cbTran_CSCm_to_coef_fx(CSCm[0][1]); + CSCCoef2RegValue.LB1_COEF_F3 = cbTran_CSCm_to_coef_fx(CSCm[0][2]); + CSCCoef2RegValue.LB1_COEF_F4 = cbTran_CSCm_to_coef_fx(CSCm[1][0]); + CSCCoef3RegValue.LB1_COEF_F5 = cbTran_CSCm_to_coef_fx(CSCm[1][1]); + CSCCoef3RegValue.LB1_COEF_F6 = cbTran_CSCm_to_coef_fx(CSCm[1][2]); + CSCCoef4RegValue.LB1_COEF_F7 = cbTran_CSCm_to_coef_fx(CSCm[2][0]); + CSCCoef4RegValue.LB1_COEF_F8 = cbTran_CSCm_to_coef_fx(CSCm[2][1]); + CSCCoef5RegValue.LB1_COEF_F9 = cbTran_CSCm_to_coef_fx(CSCm[2][2]); + + CSCCoef1RegMask.Value = 0; + CSCCoef2RegMask.Value = 0; + CSCCoef3RegMask.Value = 0; + CSCCoef4RegMask.Value = 0; + CSCCoef5RegMask.LB1_COEF_F9 = 0; + } + else // illegal para,use fixed coef do csc + { + if (CSC_INDEX_CRT == CSCIndex) + { + DACCscFormatRegValue.Dac_Csc_Program = 0; + DACCscFormatRegMask.Dac_Csc_Program = 0; + } + else + { + LBCscFormatRegValue.LB1_PROGRAMMBLE = 0; + LBCscFormatRegMask.LB1_PROGRAMMBLE = 0; + } + } + + if(CSC_INDEX_DP1 == CSCIndex) + { + cbMMIOWriteReg32(pcbe, 0x33698, CSCCoef1RegValue.Value, CSCCoef1RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x3369c, CSCCoef2RegValue.Value, CSCCoef2RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x336a0, CSCCoef3RegValue.Value, CSCCoef3RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x336a4, CSCCoef4RegValue.Value, CSCCoef4RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x336a8, CSCCoef5RegValue.Value, CSCCoef5RegMask.Value); + } + else if(CSC_INDEX_DP2 == CSCIndex) + { + cbMMIOWriteReg32(pcbe, 0x33c38, CSCCoef1RegValue.Value, CSCCoef1RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x33c3c, CSCCoef2RegValue.Value, CSCCoef2RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x33c40, CSCCoef3RegValue.Value, CSCCoef3RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x33c44, CSCCoef4RegValue.Value, CSCCoef4RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x33c48, CSCCoef5RegValue.Value, CSCCoef5RegMask.Value); + } + else if(CSC_INDEX_DP3 == CSCIndex) + { + cbMMIOWriteReg32(pcbe, 0x34338, CSCCoef1RegValue.Value, CSCCoef1RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x3433c, CSCCoef2RegValue.Value, CSCCoef2RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x34340, CSCCoef3RegValue.Value, CSCCoef3RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x34344, CSCCoef4RegValue.Value, CSCCoef4RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x34348, CSCCoef5RegValue.Value, CSCCoef5RegMask.Value); + } + else if(CSC_INDEX_DP4 == CSCIndex) + { + cbMMIOWriteReg32(pcbe, 0x34a38, CSCCoef1RegValue.Value, CSCCoef1RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x34a3c, CSCCoef2RegValue.Value, CSCCoef2RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x34a40, CSCCoef3RegValue.Value, CSCCoef3RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x34a44, CSCCoef4RegValue.Value, CSCCoef4RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x34a48, CSCCoef5RegValue.Value, CSCCoef5RegMask.Value); + } + else + { + cbMMIOWriteReg32(pcbe, 0x3386c, CSCCoef1RegValue.Value, CSCCoef1RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x33870, CSCCoef2RegValue.Value, CSCCoef2RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x33874, CSCCoef3RegValue.Value, CSCCoef3RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x33878, CSCCoef4RegValue.Value, CSCCoef4RegMask.Value); + cbMMIOWriteReg32(pcbe, 0x3387c, CSCCoef5RegValue.Value, CSCCoef5RegMask.Value); + } + } + + if(CSC_INDEX_DP1 == CSCIndex) + { + cbMMIOWriteReg32(pcbe, 0x33694, LBCscFormatRegValue.Value, LBCscFormatRegMask.Value); + } + else if(CSC_INDEX_DP2 == CSCIndex) + { + cbMMIOWriteReg32(pcbe, 0x33c34, LBCscFormatRegValue.Value, LBCscFormatRegMask.Value); + } + else if(CSC_INDEX_DP3 == CSCIndex) + { + cbMMIOWriteReg32(pcbe, 0x34334, LBCscFormatRegValue.Value, LBCscFormatRegMask.Value); + } + else if(CSC_INDEX_DP4 == CSCIndex) + { + cbMMIOWriteReg32(pcbe, 0x34a34, LBCscFormatRegValue.Value, LBCscFormatRegMask.Value); + } + else + { + cbMMIOWriteReg32(pcbe, 0x33868, DACCscFormatRegValue.Value, DACCscFormatRegMask.Value); + } + + return CBIOS_OK; +} + +CBIOS_STATUS cbAdjustStreamCSC_Arise(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_STREAM_CSC_PARA pStreamCSCPara) +{ + PCBIOS_STREAM_CSC_PARA pAdjustPara = pStreamCSCPara; + CBIOS_S64 CSCm[3][3]; + CBIOS_U32 IGAIndex = pAdjustPara->IGAIndex; + CBIOS_U32 StreamType = pAdjustPara->StreamType; + REG_MM33634_Arise CSCCoef1RegValue = {0}, CSCCoef1RegMask = {0xffffffff}; + REG_MM33638_Arise CSCCoef2RegValue = {0}, CSCCoef2RegMask = {0xffffffff}; + REG_MM3363C_Arise CSCCoef3RegValue = {0}, CSCCoef3RegMask = {0xffffffff}; + REG_MM33640_Arise CSCCoef4RegValue = {0}, CSCCoef4RegMask = {0xffffffff}; + REG_MM33644_Arise CscFormatRegValue = {0}, CscFormatRegMask = {0xffffffff}; + REG_MM8200_Arise OneShotTrigValue = {0}; + CBIOS_U32 CSCCoef1RegIndex = 0; + CBIOS_U32 CSCCoef2RegIndex = 0; + CBIOS_U32 CSCCoef3RegIndex = 0; + CBIOS_U32 CSCCoef4RegIndex = 0; + CBIOS_U32 CscFormatRegIndex = 0; + + cb_memset((PCBIOS_VOID)(CSCm), 0, sizeof(CSCm)); + + if (CBIOS_STREAM_PS == StreamType) + { + CSCCoef1RegIndex = PSCscCoef1[IGAIndex]; + CSCCoef2RegIndex = PSCscCoef2[IGAIndex]; + CSCCoef3RegIndex = PSCscCoef3[IGAIndex]; + CSCCoef4RegIndex = PSCscCoef4[IGAIndex]; + CscFormatRegIndex = PSCscIndex[IGAIndex]; + OneShotTrigValue.PS_Enable_Work = 1; + } + else if (CBIOS_STREAM_SS == StreamType) + { + CSCCoef1RegIndex = SSCscCoef1[IGAIndex]; + CSCCoef2RegIndex = SSCscCoef2[IGAIndex]; + CSCCoef3RegIndex = SSCscCoef3[IGAIndex]; + CSCCoef4RegIndex = SSCscCoef4[IGAIndex]; + CscFormatRegIndex = SSCscIndex[IGAIndex]; + OneShotTrigValue.SS_Enable_Work = 1; + } + else if (CBIOS_STREAM_TS == StreamType) + { + CSCCoef1RegIndex = TQSCscCoef1[0][IGAIndex]; + CSCCoef2RegIndex = TQSCscCoef2[0][IGAIndex]; + CSCCoef3RegIndex = TQSCscCoef3[0][IGAIndex]; + CSCCoef4RegIndex = TQSCscCoef4[0][IGAIndex]; + CscFormatRegIndex = TQSCscIndex[0][IGAIndex]; + OneShotTrigValue.TS_Enable_Work = 1; + } + else if (CBIOS_STREAM_FS == StreamType) + { + CSCCoef1RegIndex = TQSCscCoef1[1][IGAIndex]; + CSCCoef2RegIndex = TQSCscCoef2[1][IGAIndex]; + CSCCoef3RegIndex = TQSCscCoef3[1][IGAIndex]; + CSCCoef4RegIndex = TQSCscCoef4[1][IGAIndex]; + CscFormatRegIndex = TQSCscIndex[1][IGAIndex]; + OneShotTrigValue.QS_Enable_Work = 1; + } + + CscFormatRegValue.PS_Data_In_Fmt = pAdjustPara->InputFormat; + CscFormatRegMask.PS_Data_In_Fmt = 0; + CscFormatRegValue.PS_Data_Out_Fmt = pAdjustPara->OutputFormat; + CscFormatRegMask.PS_Data_Out_Fmt = 0; + + if(!pAdjustPara->Flag.bProgrammable) + { + CscFormatRegValue.PS_Program = 0; + CscFormatRegMask.PS_Program = 0; + } + else + { + + CscFormatRegValue.PS_Program = 1; + CscFormatRegMask.PS_Program = 0; + + if(pAdjustPara->Bright > 255 || pAdjustPara->Bright < -255) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "CSC bright value should be [-255,255]!\n")); + } + else + { + if(pAdjustPara->Bright >= 0) + { + CscFormatRegValue.PS_Bright = pAdjustPara->Bright; + } + else + { + CscFormatRegValue.PS_Bright = (CBIOS_U32)(1 << CSC_BRIGHT_MODULE) + pAdjustPara->Bright; //get brightness 2's complement + } + CscFormatRegMask.PS_Bright = 0; + } + + if(cbGetCscCoefMatrix((PCBIOS_CSC_ADJUST_PARA)pAdjustPara, + pAdjustPara->InputFormat, + pAdjustPara->OutputFormat, + CSCm)) + { + CSCCoef1RegValue.PS_F1 = cbTran_CSCm_to_coef_fx(CSCm[0][0]); + CSCCoef1RegValue.PS_F2 = cbTran_CSCm_to_coef_fx(CSCm[0][1]); + CSCCoef2RegValue.PS_F3 = cbTran_CSCm_to_coef_fx(CSCm[0][2]); + CSCCoef2RegValue.PS_F4 = cbTran_CSCm_to_coef_fx(CSCm[1][0]); + CSCCoef3RegValue.PS_F5 = cbTran_CSCm_to_coef_fx(CSCm[1][1]); + CSCCoef3RegValue.PS_F6 = cbTran_CSCm_to_coef_fx(CSCm[1][2]); + CSCCoef4RegValue.PS_F7 = cbTran_CSCm_to_coef_fx(CSCm[2][0]); + CSCCoef4RegValue.PS_F8 = cbTran_CSCm_to_coef_fx(CSCm[2][1]); + CscFormatRegValue.PS_F9 = cbTran_CSCm_to_coef_fx(CSCm[2][2]); + + CSCCoef1RegMask.Value = 0; + CSCCoef2RegMask.Value = 0; + CSCCoef3RegMask.Value = 0; + CSCCoef4RegMask.Value = 0; + CscFormatRegMask.PS_F9 = 0; + } + else // illegal para,use fixed coef do csc + { + CscFormatRegValue.PS_Program = 0; + CscFormatRegMask.PS_Program = 0; + } + + cbMMIOWriteReg32(pcbe, CSCCoef1RegIndex, CSCCoef1RegValue.Value, CSCCoef1RegMask.Value); + cbMMIOWriteReg32(pcbe, CSCCoef2RegIndex, CSCCoef2RegValue.Value, CSCCoef2RegMask.Value); + cbMMIOWriteReg32(pcbe, CSCCoef3RegIndex, CSCCoef3RegValue.Value, CSCCoef3RegMask.Value); + cbMMIOWriteReg32(pcbe, CSCCoef4RegIndex, CSCCoef4RegValue.Value, CSCCoef4RegMask.Value); + } + + cbMMIOWriteReg32(pcbe, CscFormatRegIndex, CscFormatRegValue.Value, CscFormatRegMask.Value); + cbMMIOWriteReg32(pcbe, OneShotTrigIndex[IGAIndex], OneShotTrigValue.Value, 0); + + return CBIOS_OK; +} + +CBIOS_VOID cbTriggerPlanes_Arise(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U32 IGAIndex, + PCBIOS_FLIP_MODE pFlipMode) +{ + PCBIOS_FLIP_MODE_EX pFlipModeEx = (PCBIOS_FLIP_MODE_EX)pFlipMode; + REG_MM8200_Arise OneShotTrigValue = {0}; + CBIOS_U32 i = 0; + + for(i = 0; i < OVL_NUM_E3K; i++) + { + if(pFlipModeEx->TrigOvlMask & (1 << i)) + { + if(i == CBIOS_OVERLAY0) + { + OneShotTrigValue.Ovl0_Enable_Work = 1; + } + else if(i == CBIOS_OVERLAY1) + { + OneShotTrigValue.Ovl1_Enable_Work = 1; + } + else if(i == CBIOS_OVERLAY2) + { + OneShotTrigValue.Ovl2_Enable_Work = 1; + } + else if(i == CBIOS_OVERLAY3) + { + OneShotTrigValue.Ovl3_Enable_Work = 1; + } + } + } + + for(i = 0; i < STREAM_NUM_E3K; i++) + { + if(pFlipModeEx->TrigStreamMask & (1 << i)) + { + if(i == CBIOS_STREAM_PS) + { + OneShotTrigValue.PS_Enable_Work = 1; + } + else if(i == CBIOS_STREAM_SS) + { + OneShotTrigValue.SS_Enable_Work = 1; + } + else if(i == CBIOS_STREAM_TS) + { + OneShotTrigValue.TS_Enable_Work = 1; + } + else if(i == CBIOS_STREAM_FS) + { + OneShotTrigValue.QS_Enable_Work = 1; + } + } + } + + cbMMIOWriteReg32(pcbe, OneShotTrigIndex[IGAIndex], OneShotTrigValue.Value, 0); +} + +CBIOS_BOOL cbUpdateOnePlane_Arise(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_PLANE_PARA pPlanePara, + CBIOS_U32 IGAIndex) +{ + CBIOS_BOOL bStatus = CBIOS_TRUE; + + if(pPlanePara->pInputStream) + { + if(pPlanePara->StreamType == CBIOS_STREAM_PS) + { + bStatus = cbUpdatePrimaryStream_Arise(pcbe, IGAIndex, pPlanePara->pInputStream, &pPlanePara->FlipMode); + } + else if(pPlanePara->StreamType == CBIOS_STREAM_SS) + { + bStatus = cbUpdateSecondStream_Arise(pcbe, IGAIndex, pPlanePara->pInputStream, &pPlanePara->FlipMode); + } + else if((pPlanePara->StreamType == CBIOS_STREAM_TS) || (pPlanePara->StreamType == CBIOS_STREAM_FS)) + { + bStatus = cbUpdateThdFourStream_Arise(pcbe, IGAIndex, pPlanePara->StreamType, + pPlanePara->pInputStream, &pPlanePara->FlipMode); + } + } + + if(pPlanePara->pOverlayInfo || (pPlanePara->FlipMode.FlipType == CBIOS_PLANE_FLIP_WITH_DISABLE)) + { + cbUpdateOverlay_Arise(pcbe, IGAIndex, pPlanePara->PlaneIndex, pPlanePara->StreamType, + pPlanePara->pOverlayInfo, &pPlanePara->FlipMode); + } + + if (pPlanePara->pOVLKeyInfo) + { + cbUpdateOVLKey_Arise(pcbe, IGAIndex, pPlanePara->pOVLKeyInfo); + } + + cbTriggerPlanes_Arise(pcbe, IGAIndex, &pPlanePara->FlipMode); + + return bStatus; +} + +CBIOS_STATUS cbUpdatePlanePerTrig_Arise(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_UPDATE_FRAME_PARA pUpdateFramePara) +{ + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 i = 0, TrigIndex = 0xFFFFFFFF, TrigOvlMask = 0, TrigStreamMask = 0; + PCBIOS_PLANE_PARA pPlane = CBIOS_NULL, *ppPlane = CBIOS_NULL; + PCBIOS_FLIP_MODE_EX pFlipModeEx = CBIOS_NULL; + + ppPlane = pUpdateFramePara->pPlanePara; + + if(pUpdateFramePara->TrigMode.OneShotTrig) + { + for(i = 0; i < PLANE_NUM_E3K; i++) + { + pPlane = ppPlane[i]; + + if(!pPlane) + { + continue; + } + + TrigOvlMask |= (1 << pPlane->PlaneIndex); + TrigStreamMask |= (1 << pPlane->StreamType); + if (pPlane->pOVLKeyInfo) + { + TrigStreamMask |= (1 << pPlane->pOVLKeyInfo->Index); + } + + pFlipModeEx = (PCBIOS_FLIP_MODE_EX)(&pPlane->FlipMode); + + if(pPlane->PlaneIndex != pUpdateFramePara->TrigMode.TrigPlane) + { + pFlipModeEx->TrigOvlMask = 0; + pFlipModeEx->TrigStreamMask = 0; + if(cbUpdateOnePlane_Arise(pcbe, pPlane, pUpdateFramePara->IGAIndex) != CBIOS_TRUE) + { + Status = CBIOS_ER_INVALID_PARAMETER; + break; + } + } + else if(pPlane->PlaneIndex == pUpdateFramePara->TrigMode.TrigPlane) + { + TrigIndex = i; + } + } + if(Status == CBIOS_OK && TrigIndex != 0xFFFFFFFF) + { + pPlane = ppPlane[TrigIndex]; + pFlipModeEx = (PCBIOS_FLIP_MODE_EX)(&pPlane->FlipMode); + pFlipModeEx->TrigOvlMask = TrigOvlMask; + pFlipModeEx->TrigStreamMask = TrigStreamMask; + if(cbUpdateOnePlane_Arise(pcbe, pPlane, pUpdateFramePara->IGAIndex) != CBIOS_TRUE) + { + Status = CBIOS_ER_INVALID_PARAMETER; + } + } + } + else + { + for(i = 0; i < PLANE_NUM_E3K; i++) + { + pPlane = ppPlane[i]; + if(pPlane) + { + pFlipModeEx = (PCBIOS_FLIP_MODE_EX)(&pPlane->FlipMode); + pFlipModeEx->TrigOvlMask = 1 << pPlane->PlaneIndex; + pFlipModeEx->TrigStreamMask = 1 << pPlane->StreamType; + if (pPlane->pOVLKeyInfo) + { + pFlipModeEx->TrigStreamMask |= (1 << pPlane->pOVLKeyInfo->Index); + } + if(cbUpdateOnePlane_Arise(pcbe, pPlane, pUpdateFramePara->IGAIndex) != CBIOS_TRUE) + { + Status = CBIOS_ER_INVALID_PARAMETER; + break; + } + } + } + } + return Status; +} + +CBIOS_STATUS cbValidatePlanePara_Arise(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_UPDATE_FRAME_PARA pUpdateFrame) +{ + CBIOS_U32 i = 0, iga = 0; + CBIOS_BOOL bPlaneValid = CBIOS_FALSE; + CBIOS_BOOL bTrigPlaneValid = CBIOS_FALSE; + PCBIOS_PLANE_PARA pPlane = CBIOS_NULL; + CBIOS_STATUS Status = CBIOS_OK; + + if(pUpdateFrame == CBIOS_NULL) + { + Status = CBIOS_ER_INVALID_PARAMETER; + goto DONE; + } + + iga = pUpdateFrame->IGAIndex; + + for(i = 0; i < PLANE_NUM_E3K; i++) + { + if(pUpdateFrame->pPlanePara[i] != CBIOS_NULL) + { + bPlaneValid = CBIOS_TRUE; + break; + } + } + + if(!bPlaneValid) + { + Status = CBIOS_ER_INVALID_PARAMETER; + goto DONE; + } + + for(i = 0; i < PLANE_NUM_E3K; i++) + { + if(pUpdateFrame->pPlanePara[i]) + { + pPlane = pUpdateFrame->pPlanePara[i]; + if(pPlane->PlaneIndex == pUpdateFrame->TrigMode.TrigPlane) + { + bTrigPlaneValid = CBIOS_TRUE; + } + if(pPlane->FlipMode.FlipType == CBIOS_PLANE_INVALID_FLIP) + { + Status = CBIOS_ER_INVALID_PARAMETER; + goto DONE; + } + if(pPlane->FlipMode.FlipImme && pUpdateFrame->TrigMode.OneShotTrig) + { + Status = CBIOS_ER_INVALID_PARAMETER; + goto DONE; + } + if((pPlane->pInputStream == CBIOS_NULL) && (pPlane->pOverlayInfo == CBIOS_NULL) + && (pPlane->FlipMode.FlipType != CBIOS_PLANE_FLIP_WITH_DISABLE)) + { + Status = CBIOS_ER_INVALID_PARAMETER; + goto DONE; + } + if(pPlane->FlipMode.FlipType == CBIOS_PLANE_INVALID_FLIP) + { + Status = CBIOS_ER_INVALID_PARAMETER; + goto DONE; + } + if(pPlane->pInputStream) + { + CBIOS_BOOL bSupportUpScale = pcbe->DispMgr.UpScaleStreamMask[iga] & (1 << i); + CBIOS_BOOL bSupportDownScale = pcbe->DispMgr.DownScaleStreamMask[iga] & (1 << i); + if(!bSupportUpScale && !bSupportDownScale && + (pPlane->pInputStream->SrcWindow.WinSize!= pPlane->pInputStream->DispWindow.WinSize)) + { + Status = CBIOS_ER_INVALID_PARAMETER; + goto DONE; + } + } + } + } + + if(pUpdateFrame->TrigMode.OneShotTrig && !bTrigPlaneValid) + { + Status = CBIOS_ER_INVALID_PARAMETER; + } + +DONE: + return Status; +} + +CBIOS_STATUS cbUpdateFrame_Arise(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_UPDATE_FRAME_PARA pUpdateFrame) +{ + CBIOS_STATUS Status = CBIOS_OK; + + if(cbValidatePlanePara_Arise(pcbe, pUpdateFrame) != CBIOS_OK) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + Status = cbUpdatePlanePerTrig_Arise(pcbe, pUpdateFrame); + + return Status; +} + +CBIOS_STATUS cbSetGamma_Arise(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_GAMMA_PARA pGammaParam) +{ + if((!pGammaParam) || (!pGammaParam->Flags.bDisableGamma && !pGammaParam->pGammaTable)) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + // always use IO path + pGammaParam->Flags.bUseIO = 1; + + if(1 == pGammaParam->Flags.bDisableGamma) + { + cbDisableGamma_Arise(pcbe, pGammaParam->IGAIndex); + } + else + { + cbWaitVBlank(pcbe, (CBIOS_U8)pGammaParam->IGAIndex); + if(pGammaParam->Flags.bConfigGamma) + { + cbDoGammaConfig_Arise(pcbe, pGammaParam); + } + + if(pGammaParam->Flags.bSetLUT) + { + cbSetLUT_Arise(pcbe, pGammaParam); + } + + if(pGammaParam->Flags.bGetLUT) + { + cbGetLUT_Arise(pcbe, pGammaParam); + } + } + + return CBIOS_OK; +} + +CBIOS_VOID cbDisableGamma_Arise(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 IGAIndex) +{ + REG_SR47 SR47Value = {0}, SR47Mask = {0xff}; + + SR47Value.SP_Gamma_Enable = 0; + SR47Mask.SP_Gamma_Enable = 0; + SR47Value.SP_LUT_Interpolation_Enable = 0; + SR47Mask.SP_LUT_Interpolation_Enable = 0; + + cbBiosMMIOWriteReg(pcbe, SR_47, SR47Value.Value, SR47Mask.Value, IGAIndex); +} + +CBIOS_VOID cbDoGammaConfig_Arise(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_GAMMA_PARA pGammaParam) +{ + REG_SR47 SR47Value = {0}, SR47Mask = {0xff}; + REG_CRE2 CRE2Value = {0}, CRE2Mask = {0xff}; + REG_CRE4 CRE4Value = {0}, CRE4Mask = {0xff}; + + SR47Value.SP_Gamma_Enable = 1; + SR47Mask.SP_Gamma_Enable = 0; + + if (pGammaParam->Flags.bInterpolation) + { + SR47Value.SP_LUT_Interpolation_Enable = 1; + SR47Mask.SP_LUT_Interpolation_Enable = 0; + } + else + { + SR47Value.SP_LUT_Interpolation_Enable = 0; + SR47Mask.SP_LUT_Interpolation_Enable = 0; + } + + if (!pGammaParam->Flags.bUseIO) + { + //use mmio to R/W LUT + CRE2Value.LUT_MMIO_EN = 1; + CRE2Mask.LUT_MMIO_EN = 0; + } + else + { + CRE2Value.LUT_MMIO_EN = 0; + CRE2Mask.LUT_MMIO_EN = 0; + + if (!pGammaParam->Flags.bInterpolation) + { + CRE4Value.LUT1_BIT_width = 2; + CRE4Mask.LUT1_BIT_width = 0; + } + else + { + CRE4Value.LUT1_BIT_width = 1; + CRE4Mask.LUT1_BIT_width = 0; + } + cbMMIOWriteReg(pcbe, LUTBitWidthIndex[pGammaParam->IGAIndex], CRE4Value.Value, CRE4Mask.Value); + } + + cbBiosMMIOWriteReg(pcbe, SR_47, SR47Value.Value, SR47Mask.Value, pGammaParam->IGAIndex); + cbMMIOWriteReg(pcbe, CR_E2, CRE2Value.Value, CRE2Mask.Value); +} + +CBIOS_VOID cbGetLUT_Arise(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_GAMMA_PARA pGammaParam) +{ + PCBIOS_LUT pGammaTable = pGammaParam->pGammaTable; + REG_MM332AC_Arise MM332ACValue = {0}, MM332ACMask = {0xff}; + CBIOS_U32 i; + + if(IGA1 == pGammaParam->IGAIndex) + { + cbMMIOWriteReg(pcbe, SR_47, 0x01, 0xF0); //LUT1 read and write + } + else if(IGA2 == pGammaParam->IGAIndex) + { + cbMMIOWriteReg(pcbe, SR_47, 0x02, 0xF0); //LUT2 read and write + } + else if(IGA3 == pGammaParam->IGAIndex) + { + cbMMIOWriteReg(pcbe, SR_47, 0x09, 0xF0); //LUT3 read and write + } + else + { + cbMMIOWriteReg(pcbe, SR_47, 0x0a, 0xF0); //LUT4 read and write + } + + if (!pGammaParam->Flags.bUseIO) + { + // set index + cbWaitVBlank(pcbe, (CBIOS_U8)pGammaParam->IGAIndex); + MM332ACValue.LUT_SSC_HDMI_INFO_DP_INFO_Read_current_index = (CBIOS_UCHAR)(pGammaParam->FisrtEntryIndex); + MM332ACMask.LUT_SSC_HDMI_INFO_DP_INFO_Read_current_index = 0; + cbMMIOWriteReg32(pcbe, 0x332ac, MM332ACValue.Value, MM332ACMask.Value); + + //read LUT + for (i = 0; i < pGammaParam->EntryNum; i++) + { + pGammaTable[i].RgbLong = cb_ReadU32(pcbe->pAdapterContext, 0x81a0); + } + } + else + { + if(!pGammaParam->Flags.bInterpolation) + { + cbWaitVBlank(pcbe, (CBIOS_U8)pGammaParam->IGAIndex); + + cb_WriteU8(pcbe->pAdapterContext, 0x83c7, (CBIOS_UCHAR)pGammaParam->FisrtEntryIndex); // index auto-increments + + for ( i = 0; i < pGammaParam->EntryNum; i++) + { + CBIOS_U8 Byte1, Byte2, Byte3, Byte4; + CBIOS_U16 R_10, G_10, B_10; + + Byte1 = cb_ReadU8(pcbe->pAdapterContext, 0x83c9); + Byte2 = cb_ReadU8(pcbe->pAdapterContext, 0x83c9); + Byte3 = cb_ReadU8(pcbe->pAdapterContext, 0x83c9); + Byte4 = cb_ReadU8(pcbe->pAdapterContext, 0x83c9); + + R_10 = ((Byte2 >> 4) & 0x0f) | ((Byte1 & 0x3f) << 4); + G_10 = ((Byte3 >> 2) & 0x3f) | ((Byte2 & 0x0f) << 6); + B_10 = Byte4 | ((Byte3 & 0x03) << 8); + + pGammaTable[i].RgbLong = (R_10 << 20) | (G_10 << 10) | B_10; + } + } + else + { + cbWaitVBlank(pcbe, (CBIOS_U8)pGammaParam->IGAIndex); + + cb_WriteU8(pcbe->pAdapterContext, 0x83c6, 0xff); + cb_WriteU8(pcbe->pAdapterContext, 0x83c7, (CBIOS_UCHAR)pGammaParam->FisrtEntryIndex); + + for ( i = 0; i < pGammaParam->EntryNum; i++) + { + pGammaTable[i].RgbArray.Red = cb_ReadU8(pcbe->pAdapterContext, 0x83c9); + pGammaTable[i].RgbArray.Green = cb_ReadU8(pcbe->pAdapterContext, 0x83c9); + pGammaTable[i].RgbArray.Blue = cb_ReadU8(pcbe->pAdapterContext, 0x83c9); + pGammaTable[i].RgbArray.Unused = 0; + } + } + } + + //restore SR_47 + cbMMIOWriteReg(pcbe, SR_47, 0x00, 0xF0); +} + +CBIOS_VOID cbSetLUT_Arise(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_GAMMA_PARA pGammaParam) +{ + REG_CR33_Pair CR33Value = {0}, CR33Mask = {0xff}; + REG_MM332AC_Arise MM332ACValue = {0}, MM332ACMask = {0xffffffff}; + PCBIOS_LUT pGammaTable = pGammaParam->pGammaTable; + CBIOS_U32 FirstEntry = pGammaParam->FisrtEntryIndex; + CBIOS_U32 i = 0; + + if(IGA1 == pGammaParam->IGAIndex) + { + cbMMIOWriteReg(pcbe, SR_47, 0x01, 0xF0); //LUT1 read and write + } + else if(IGA2 == pGammaParam->IGAIndex) + { + cbMMIOWriteReg(pcbe, SR_47, 0x02, 0xF0); //LUT2 read and write + } + else if(IGA3 == pGammaParam->IGAIndex) + { + cbMMIOWriteReg(pcbe, SR_47, 0x09, 0xF0); //LUT3 read and write + } + else + { + cbMMIOWriteReg(pcbe, SR_47, 0x0a, 0xF0); //LUT4 read and write + } + + //Clear CR33 bit4, enable DAC write. + CR33Value.Lock_DAC_Writes = 0; + CR33Mask.Lock_DAC_Writes = 0; + cbBiosMMIOWriteReg(pcbe, CR_33, CR33Value.Value, CR33Mask.Value, pGammaParam->IGAIndex); + + if (!pGammaParam->Flags.bUseIO) + { + // set index + MM332ACValue.LUT_SSC_HDMI_INFO_DP_INFO_write_current_index = (CBIOS_UCHAR)FirstEntry; + MM332ACMask.LUT_SSC_HDMI_INFO_DP_INFO_write_current_index = 0; + cbMMIOWriteReg32(pcbe, 0x332ac, MM332ACValue.Value, MM332ACMask.Value); + + //write lut + for ( i = 0; i < pGammaParam->EntryNum; i++) + { + cb_WriteU32(pcbe->pAdapterContext, 0x81a0, pGammaTable[i].RgbLong); + } + } + else + { + if(!pGammaParam->Flags.bInterpolation) + { + cb_WriteU8(pcbe->pAdapterContext, 0x83c8, (CBIOS_UCHAR)FirstEntry); // index auto-increments + + for ( i = 0; i < pGammaParam->EntryNum; i++) + { + CBIOS_U8 Byte1, Byte2, Byte3, Byte4; + CBIOS_U16 R_10, G_10, B_10; + + B_10 = (CBIOS_U16)(pGammaTable[i].RgbLong & 0x000003FF); + G_10 = (CBIOS_U16)((pGammaTable[i].RgbLong>>10) & 0x000003FF); + R_10 = (CBIOS_U16)((pGammaTable[i].RgbLong>>20) & 0x000003FF); + + Byte1 = (CBIOS_U8)((R_10 & 0x03F0) >>4) ; + Byte2 = (CBIOS_U8)(((R_10 & 0x000F)<<4) |((G_10 & 0x03C0)>>6)); + Byte3 = (CBIOS_U8)(((G_10 & 0x003F)<<2) |((B_10 & 0x0300)>>8)); + Byte4 = (CBIOS_U8)(B_10 & 0x00FF); + + cb_WriteU8(pcbe->pAdapterContext, 0x83c9, Byte1); //3C9h + cb_WriteU8(pcbe->pAdapterContext, 0x83c9, Byte2); //3C9h + cb_WriteU8(pcbe->pAdapterContext, 0x83c9, Byte3); //3C9h + cb_WriteU8(pcbe->pAdapterContext, 0x83c9, Byte4); //3C9h + } + } + else + { + cb_WriteU8(pcbe->pAdapterContext, 0x83c6, 0xff); + cb_WriteU8(pcbe->pAdapterContext, 0x83c8, (CBIOS_UCHAR)FirstEntry); + + for ( i = 0; i < pGammaParam->EntryNum; i++) + { + cb_WriteU8(pcbe->pAdapterContext, 0x83c9, pGammaTable[i].RgbArray.Red); + cb_WriteU8(pcbe->pAdapterContext, 0x83c9, pGammaTable[i].RgbArray.Green); + cb_WriteU8(pcbe->pAdapterContext, 0x83c9, pGammaTable[i].RgbArray.Blue); + } + } + } + + //restore SR_47 + cbMMIOWriteReg(pcbe, SR_47, 0x00, 0xF0); +} + +CBIOS_STATUS cbCECEnableDisable_Arise(PCBIOS_VOID pvcbe, PCBIOS_CEC_ENABLE_DISABLE_PARA pCECEnableDisablePara) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + CBIOS_U32 CECMiscReg = 0; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_CEC_INDEX CECIndex = CBIOS_CEC_INDEX1; + + if (pCECEnableDisablePara == CBIOS_NULL) + { + Status = CBIOS_ER_NULLPOINTER; + cbDebugPrint((DBG_LEVEL_ERROR_MSG, "CBiosCECEnableDisable_E3K: pCECEnableDisablePara is NULL!")); + } + else if (!pcbe->ChipCaps.IsSupportCEC) + { + Status = CBIOS_ER_HARDWARE_LIMITATION; + cbDebugPrint((DBG_LEVEL_ERROR_MSG, "CBiosCECEnableDisable_E3K: Can't support CEC!")); + } + else if (pCECEnableDisablePara->CECIndex >= CBIOS_CEC_INDEX_COUNT) + { + Status = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((DBG_LEVEL_ERROR_MSG, "CBiosCECEnableDisable_E3K: invalid CEC index!")); + } + else + { + CECIndex = pCECEnableDisablePara->CECIndex; + if (CECIndex == CBIOS_CEC_INDEX1) + { + CECMiscReg = 0x33148; + } + else if (CECIndex == CBIOS_CEC_INDEX2) + { + CECMiscReg = 0x33e34; + } + else if (CECIndex == CBIOS_CEC_INDEX3) + { + CECMiscReg = 0x34538; + } + else if (CECIndex == CBIOS_CEC_INDEX4) + { + CECMiscReg = 0X34c38; + } + + + if (pCECEnableDisablePara->bEnableCEC) + { + cbMMIOWriteReg32(pcbe, CECMiscReg, BIT18, ~BIT18); + pcbe->CECPara[CECIndex].CECEnable = CBIOS_TRUE; + //allocate logical address + cbCECAllocateLogicalAddr(pcbe, CECIndex); + } + else + { + cbMMIOWriteReg32(pcbe, CECMiscReg, 0x00000000, ~BIT18); + pcbe->CECPara[CECIndex].CECEnable = CBIOS_FALSE; + } + + Status = CBIOS_OK; + + } + + return Status; + +} + +static CBIOS_STATUS cbUpdateCursorColor_Arise(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 IGAIndex, CBIOS_U32 Bg, CBIOS_U32 Fg) +{ + CBIOS_STATUS bStatus = CBIOS_OK; + + REG_CR4A_Pair Cr4a = {0}; + REG_CR4B_Pair Cr4b = {0}; + CBIOS_U32 MmioBase = 0; + + if(IGA1 == IGAIndex) + { + MmioBase = MMIO_OFFSET_CR_GROUP_A; + } + else if(IGA2 == IGAIndex) + { + MmioBase = MMIO_OFFSET_CR_GROUP_B; + } + else if(IGA3 == IGAIndex) + { + MmioBase = MMIO_OFFSET_CR_GROUP_T; + } + else + { + MmioBase = MMIO_OFFSET_CR_GROUP_F; + } + + // foreground color + cbBiosMMIOReadReg(pcbe, CR_45, IGAIndex);//reset cr4a to '0' by reading cr45. + Cr4a.HW_Cursor_Color_Foreground_Stack = Fg & 0xff; + cb_WriteU8(pcbe->pAdapterContext, MmioBase + 0x4a, Cr4a.Value); + Cr4a.HW_Cursor_Color_Foreground_Stack = (Fg >> 8)& 0xff; + cb_WriteU8(pcbe->pAdapterContext, MmioBase + 0x4a, Cr4a.Value); + Cr4a.HW_Cursor_Color_Foreground_Stack = (Fg >> 16)& 0xff; + cb_WriteU8(pcbe->pAdapterContext, MmioBase + 0x4a, Cr4a.Value); + Cr4a.HW_Cursor_Color_Foreground_Stack = (Fg >> 24)& 0xff; + cb_WriteU8(pcbe->pAdapterContext, MmioBase + 0x4a, Cr4a.Value); + // background color + cbBiosMMIOReadReg(pcbe, CR_45, IGAIndex);//reset cr4a to '0' by reading cr45. + Cr4b.HW_Cursor_Color_Background_Stack = Bg & 0xff; + cb_WriteU8(pcbe->pAdapterContext, MmioBase + 0x4b, Cr4b.Value); + Cr4b.HW_Cursor_Color_Background_Stack = (Bg >> 8) & 0xff; + cb_WriteU8(pcbe->pAdapterContext, MmioBase + 0x4b, Cr4b.Value); + Cr4b.HW_Cursor_Color_Background_Stack = (Bg >> 16) & 0xff; + cb_WriteU8(pcbe->pAdapterContext, MmioBase + 0x4b, Cr4b.Value); + Cr4b.HW_Cursor_Color_Background_Stack = (Bg >> 24) & 0xff; + cb_WriteU8(pcbe->pAdapterContext, MmioBase + 0x4b, Cr4b.Value); + + return bStatus; +} + +CBIOS_STATUS cbSetHwCursor_Arise(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_CURSOR_PARA pSetCursor) +{ + CBIOS_STATUS bStatus = CBIOS_OK; + CBIOS_U32 IGAIndex = pSetCursor->IGAIndex; + PCBIOS_DISP_MODE_PARAMS pModeParams = pcbe->DispMgr.pModeParams[IGAIndex]; + CBIOS_U32 CursorBaseAddr = 0; + REG_MM33718_Arise CursorCtrl1RegValue = {0}; + REG_MM3371C_Arise CursorCtrl2RegValue = {0}; + REG_MM33720_Arise CursorBaseAddrRegValue = {0}; + REG_MM33728_Arise CursorEndPixelRegValue = {0}; + REG_MM81E4_Arise CursorCscRegValue = {0}; + CBIOS_U32 CursorSize = 0; + CBIOS_U8 StartX = 0; + CBIOS_U8 StartY = 0; + + CursorCtrl1RegValue.Value = 0; + + // enable MMIO setting + CursorCtrl1RegValue.Cursor_1_mmio_reg_en = 1; + + //check position + if(!pSetCursor->bDisable) + { + if(pSetCursor->Position.PositionX < 0) + { + StartX = -pSetCursor->Position.PositionX; + pSetCursor->Position.PositionX = 0; + } + if(pSetCursor->Position.PositionY < 0) + { + StartY = -pSetCursor->Position.PositionY; + pSetCursor->Position.PositionY = 0; + } + if(pSetCursor->Position.CursorSize == CBIOS_CURSOR_SIZE_64x64) + { + CursorSize = 64; + } + else + { + CursorSize = 128; + } + if(StartX >= CursorSize || StartY >= CursorSize) + { + pSetCursor->bDisable = 1; + } + } + + if(pSetCursor->bDisable) + { + CursorCtrl1RegValue.Cursor_1_Enable = 0; + CursorBaseAddrRegValue.Cursor_1_Enable_Work_Registers = 1; + cbMMIOWriteReg32(pcbe, CursorControl1Index[IGAIndex], CursorCtrl1RegValue.Value, 0); + cbMMIOWriteReg32(pcbe, CursorBaseAddrIndex[IGAIndex], CursorBaseAddrRegValue.Value, 0); + return CBIOS_OK; + } + + //enable cursor + CursorCtrl1RegValue.Cursor_1_Enable = 1; + + //position + CursorCtrl2RegValue.Cursor_1_X_Origin = pSetCursor->Position.PositionX; + CursorCtrl2RegValue.Cursor_1_Y_Origin = pSetCursor->Position.PositionY; + + //start pixel + CursorCtrl1RegValue.Cursor_1_Display_Start_X = StartX; + CursorCtrl1RegValue.Cursor_1_Display_Start_Y = StartY; + CursorEndPixelRegValue.Cursor_1_X_end = CursorSize; + CursorEndPixelRegValue.Cursor_1_Y_end = CursorSize; + + //size + CursorCtrl1RegValue.Cursor_1_Size = pSetCursor->Position.CursorSize; + + //type + CursorCtrl1RegValue.Cursor_1_Type = pSetCursor->CursorAttrib.Type; + if(pSetCursor->CursorAttrib.Type == CBIOS_MONO_CURSOR) + { + cbUpdateCursorColor_Arise(pcbe, pSetCursor->IGAIndex, pSetCursor->CursorAttrib.Color.BackGround, pSetCursor->CursorAttrib.Color.ForeGround); + } + + //address + CursorBaseAddr = (CBIOS_U32)(pSetCursor->CursorAttrib.CurAddr >> 5); + CursorBaseAddrRegValue.Cursor_1_Base_Address = CursorBaseAddr; + + //rotation + if (pSetCursor->bhMirror) + { + CursorCtrl1RegValue.Cursor_1_X_Rotation = 1; + } + if (pSetCursor->bvMirror) + { + CursorCtrl1RegValue.Cursor_1_Y_Rotation = 1; + } + + //format + CursorCscRegValue.Cursor1_Csc_output_Fmt = pModeParams->IGAOutColorSpace; + + CursorBaseAddrRegValue.Cursor_1_Enable_Work_Registers = 1; + + cbMMIOWriteReg32(pcbe, CursorCscIndex[IGAIndex], CursorCscRegValue.Value, 0); + cbMMIOWriteReg32(pcbe, CursorControl1Index[IGAIndex], CursorCtrl1RegValue.Value, 0); + cbMMIOWriteReg32(pcbe, CursorControl2Index[IGAIndex], CursorCtrl2RegValue.Value, 0); + cbMMIOWriteReg32(pcbe, CursorEndPixelIndex[IGAIndex], CursorEndPixelRegValue.Value, 0); + cbMMIOWriteReg32(pcbe, CursorBaseAddrIndex[IGAIndex], CursorBaseAddrRegValue.Value, 0); + + return bStatus; +} + +/*****************************************************************************************/ +// +//Function:cbGetSysBiosInfo +//Discription: +// This function will init pcbe scratch pad and related HW registers from system bios info +//Return: +// TRUE --- Success, init success, in system bios info valid case +// FALSE--- Fail, system bios info invalid, init fail +/*****************************************************************************************/ +CBIOS_BOOL cbGetSysBiosInfo(PCBIOS_EXTENSION_COMMON pcbe) +{ + CBIOS_BOOL status = CBIOS_TRUE; + + if(pcbe->SysBiosInfo.bSysBiosInfoValid == CBIOS_TRUE) + { + pcbe->SysBiosInfo.BootUpDev = cbConvertVBiosDevBit2CBiosDevBit(pcbe->SysBiosInfo.BootUpDev); + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "\nCBIOS:cbGetSysBiosInfo:pcbe->SysBiosInfo.BootUpDev = 0x%x!\n", pcbe->SysBiosInfo.BootUpDev)); + } + else + { + status = CBIOS_FALSE; + } + return status; +} +CBIOS_U8 cbGetCheckSum(CBIOS_U8* pByte, CBIOS_U32 uLength) +{ + CBIOS_U8 ByteVal=0; + CBIOS_U32 i; + for(i=0;iChipFuncTbl); + + if (pFuncTbl->pfncbSetCRTimingReg != CBIOS_NULL) + { + pFuncTbl->pfncbSetCRTimingReg(pcbe, pTiming, IGAIndex, Flags); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbSetCRTimingReg: function not implemented! Fatal Error\n")); + } +} + +CBIOS_VOID cbSetSRTimingReg(PCBIOS_VOID pvcbe, PCBIOS_TIMING_ATTRIB pTiming, CBIOS_U32 IGAIndex, CBIOS_TIMING_FLAGS Flags) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + + if (pFuncTbl->pfncbSetSRTimingReg != CBIOS_NULL) + { + pFuncTbl->pfncbSetSRTimingReg(pcbe, pTiming, IGAIndex, Flags); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbSetSRTimingReg: function not implemented! Fatal Error\n")); + } +} + +CBIOS_VOID cbGetModeInfoFromReg(PCBIOS_VOID pvcbe, + CBIOS_ACTIVE_TYPE ulDevice, + PCBIOS_TIMING_ATTRIB pTiming, + PCBIOS_TIMING_FLAGS pFlags, + CBIOS_U32 IGAIndex, + CBIOS_TIMING_REG_TYPE TimingRegType) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + + if (pFuncTbl->pfncbGetModeInfoFromReg != CBIOS_NULL) + { + pFuncTbl->pfncbGetModeInfoFromReg(pcbe, ulDevice, pTiming, pFlags, IGAIndex, TimingRegType); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbGetModeInfoFromReg: function not implemented!\n")); + } +} + +CBIOS_BOOL cbInitVCP(PCBIOS_VOID pvcbe, PCBIOS_VOID pVCPInfo, PCBIOS_VOID pRomBase) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PVCP_INFO pVCP = (PVCP_INFO)pVCPInfo; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + CBIOS_BOOL bStatus = CBIOS_FALSE; + + if (pFuncTbl->pfncbInitVCP != CBIOS_NULL) + { + bStatus = pFuncTbl->pfncbInitVCP(pcbe, pVCP, pRomBase); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbInitVCP: function not implemented!\n")); + bStatus = CBIOS_FALSE; + } + return bStatus; +} + +CBIOS_VOID cbDoHDTVFuncSetting(PCBIOS_VOID pvcbe, + PCBIOS_DISP_MODE_PARAMS pModeParams, + CBIOS_U32 IGAIndex, + CBIOS_ACTIVE_TYPE ulDevices) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + + if (pFuncTbl->pfncbDoHDTVFuncSetting != CBIOS_NULL) + { + pFuncTbl->pfncbDoHDTVFuncSetting(pcbe, pModeParams, IGAIndex, ulDevices); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbDoHDTVFuncSetting: function not implemented!\n")); + } +} + +CBIOS_VOID cbLoadSSC(PCBIOS_VOID pvcbe, CBIOS_U32 CenterFreq, CBIOS_U8 IGAIndex, CBIOS_ACTIVE_TYPE LCDType) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + + if (pFuncTbl->pfncbLoadSSC != CBIOS_NULL) + { + pFuncTbl->pfncbLoadSSC(pcbe, CenterFreq, IGAIndex, LCDType); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbLoadSSC: function not implemented!\n")); + } +} + +CBIOS_VOID cbEnableSpreadSpectrum(PCBIOS_VOID pvcbe, CBIOS_U8 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + + if (pFuncTbl->pfncbEnableSpreadSpectrum != CBIOS_NULL) + { + pFuncTbl->pfncbEnableSpreadSpectrum(pcbe, IGAIndex); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEnableSpreadSpectrum: function not implemented!\n")); + } +} + +CBIOS_VOID cbDisableSpreadSpectrum(PCBIOS_VOID pvcbe, CBIOS_U8 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + + if (pFuncTbl->pfncbDisableSpreadSpectrum != CBIOS_NULL) + { + pFuncTbl->pfncbDisableSpreadSpectrum(pcbe, IGAIndex); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbDisableSpreadSpectrum: function not implemented!\n")); + } +} + +CBIOS_STATUS cbInterruptEnableDisable(PCBIOS_VOID pvcbe, PCBIOS_INT_ENABLE_DISABLE_PARA pIntPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pFuncTbl->pfncbInterruptEnableDisable != CBIOS_NULL) + { + Status = pFuncTbl->pfncbInterruptEnableDisable(pcbe, pIntPara); + } + else + { + Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + } + return Status; +} + +CBIOS_STATUS cbCECEnableDisable(PCBIOS_VOID pvcbe, PCBIOS_CEC_ENABLE_DISABLE_PARA pCECEnableDisablePara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pFuncTbl->pfncbCECEnableDisable != CBIOS_NULL) + { + Status = pFuncTbl->pfncbCECEnableDisable(pcbe, pCECEnableDisablePara); + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbCECEnableDisable: function not implemented!\n")); + Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + } + return Status; +} + +CBIOS_STATUS cbSetGamma(PCBIOS_VOID pvcbe, PCBIOS_GAMMA_PARA pGammaParam) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pFuncTbl->pfncbSetGamma != CBIOS_NULL) + { + Status = pFuncTbl->pfncbSetGamma(pcbe, pGammaParam); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbSetGamma: function not implemented!\n")); + Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + } + return Status; +} + +CBIOS_STATUS cbUpdateFrame(PCBIOS_VOID pvcbe, PCBIOS_UPDATE_FRAME_PARA pUpdateFrame) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pFuncTbl->pfncbUpdateFrame != CBIOS_NULL) + { + Status = pFuncTbl->pfncbUpdateFrame(pcbe, pUpdateFrame); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbUpdateFrame: function not implemented!\n")); + Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + } + return Status; +} + +CBIOS_STATUS cbDoCSCAdjust(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, PCBIOS_CSC_ADJUST_PARA pCSCAdjustPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pFuncTbl->pfncbDoCSCAdjust != CBIOS_NULL) + { + Status = pFuncTbl->pfncbDoCSCAdjust(pcbe, Device, pCSCAdjustPara); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbDoCSCAdjust: function not implemented!\n")); + Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + } + + return Status; +} + +CBIOS_STATUS cbAdjustStreamCSC(PCBIOS_VOID pvcbe, PCBIOS_STREAM_CSC_PARA pCSCAdjustPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pFuncTbl->pfncbAdjustStreamCSC != CBIOS_NULL) + { + Status = pFuncTbl->pfncbAdjustStreamCSC(pcbe, pCSCAdjustPara); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbDoCSCAdjust: function not implemented!\n")); + Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + } + + return Status; +} + +CBIOS_STATUS cbCheckSurfaceOnDisplay(PCBIOS_VOID pvcbe, PCBIOS_CHECK_SURFACE_ON_DISP pChkSurfacePara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pFuncTbl->pfncbCheckSurfaceOnDisplay != CBIOS_NULL) + { + Status = pFuncTbl->pfncbCheckSurfaceOnDisplay(pcbe, pChkSurfacePara); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbCheckSurfaceOnDisplay: function not implemented!\n")); + Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + } + return Status; +} + +CBIOS_STATUS cbGetDispAddr(PCBIOS_VOID pvcbe, PCBIOS_GET_DISP_ADDR pGetDispAddr) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pFuncTbl->pfncbGetDispAddr != CBIOS_NULL) + { + Status = pFuncTbl->pfncbGetDispAddr(pcbe, pGetDispAddr); + } + else + { + Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + } + return Status; +} + +CBIOS_STATUS cbSetHwCursor(PCBIOS_VOID pvcbe, PCBIOS_CURSOR_PARA pSetCursor) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pFuncTbl->pfncbSetHwCursor != CBIOS_NULL) + { + Status = pFuncTbl->pfncbSetHwCursor(pcbe, pSetCursor); + } + else + { + Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + } + return Status; +} + +CBIOS_VOID cbDisableStream(PCBIOS_VOID pvcbe, CBIOS_U32 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_CHIP_FUNC_TABLE pFuncTbl = &(pcbe->ChipFuncTbl); + if(pFuncTbl->pfncbDisableStream != CBIOS_NULL) + { + pFuncTbl->pfncbDisableStream(pcbe, IGAIndex); + } +} + diff --git a/drivers/gpu/drm/arise/cbios/Hw/CBiosChipFunc.h b/drivers/gpu/drm/arise/cbios/Hw/CBiosChipFunc.h new file mode 100644 index 0000000000000..ee57cea7a4516 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/CBiosChipFunc.h @@ -0,0 +1,140 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios chip dependent function prototype. +** +** NOTE: +** This header file CAN be included by sw layer. +******************************************************************************/ + +#ifndef _CBIOS_CHIP_FUNC_H_ +#define _CBIOS_CHIP_FUNC_H_ + +#include "../CBios.h" +#include "../Device/CBiosChipShare.h" +#include "../Display/CBiosDisplayManager.h" + +typedef CBIOS_VOID +(*PFN_cbSetTimingReg)(PCBIOS_VOID pvcbe, + PCBIOS_TIMING_ATTRIB pTiming, + CBIOS_U32 IGAIndex, + CBIOS_TIMING_FLAGS Flags); + +typedef CBIOS_VOID +(*PFN_cbGetModeInfoFromReg)(PCBIOS_VOID pvcbe, + CBIOS_ACTIVE_TYPE ulDevice, + PCBIOS_TIMING_ATTRIB pTiming, + PCBIOS_TIMING_FLAGS pFlags, + CBIOS_U32 IGAIndex, + CBIOS_TIMING_REG_TYPE TimingRegType); + +typedef CBIOS_BOOL +(*PFN_cbInitVCP) (PCBIOS_VOID pvcbe, PCBIOS_VOID pVCP, PCBIOS_VOID pRomBase); + +typedef CBIOS_VOID +(*PFN_cbDoHDTVFuncSetting) (PCBIOS_VOID pvcbe, + PCBIOS_DISP_MODE_PARAMS pModeParams, + CBIOS_U32 IGAIndex, + CBIOS_ACTIVE_TYPE ulDevices); + +typedef CBIOS_VOID +(*PFN_cbLoadSSC) (PCBIOS_VOID pvcbe, CBIOS_U32 CenterFreq, CBIOS_U8 IGAIndex, CBIOS_ACTIVE_TYPE LCDType); + +typedef CBIOS_VOID +(*PFN_cbEnableSpreadSpectrum) (PCBIOS_VOID pvcbe, CBIOS_U8 IGAIndex); + +typedef CBIOS_VOID +(*PFN_cbDisableSpreadSpectrum) (PCBIOS_VOID pvcbe, CBIOS_U8 IGAIndex); + +typedef CBIOS_STATUS +(*PFN_cbUpdateFrame)(PCBIOS_VOID pvcbe, PCBIOS_UPDATE_FRAME_PARA pUpdateFrame); + +typedef CBIOS_STATUS +(*PFN_cbDoCSCAdjust)(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, PCBIOS_CSC_ADJUST_PARA pCSCAdjustPara); + +typedef CBIOS_STATUS +(*PFN_cbAdjustStreamCSC)(PCBIOS_VOID pvcbe, PCBIOS_STREAM_CSC_PARA pCSCAdjustPara); + +typedef CBIOS_STATUS +(*PFN_cbCheckSurfaceOnDisplay)(PCBIOS_VOID pvcbe, PCBIOS_CHECK_SURFACE_ON_DISP pChkSurfacePara); + +typedef CBIOS_STATUS +(*PFN_cbGetDispAddr)(PCBIOS_VOID pvcbe, PCBIOS_GET_DISP_ADDR pGetDispAddr); + +typedef CBIOS_STATUS +(*PFN_cbSetHwCursor)(PCBIOS_VOID pvcbe, PCBIOS_CURSOR_PARA pSetCursor); + +typedef CBIOS_STATUS +(*PFN_cbInterruptEnableDisable)(PCBIOS_VOID pvcbe, PCBIOS_INT_ENABLE_DISABLE_PARA pIntPara); + +typedef CBIOS_STATUS +(*PFN_cbCECEnableDisable)(PCBIOS_VOID pvcbe, PCBIOS_CEC_ENABLE_DISABLE_PARA pCECEnableDisablePara); + +typedef CBIOS_STATUS +(*PFN_cbSetGamma)(CBIOS_VOID* pvcbe, PCBIOS_GAMMA_PARA pGammaParam); + + +typedef CBIOS_VOID +(*PFN_cbDisableStream)(PCBIOS_VOID pvcbe, CBIOS_U32 IGAIndex); + +typedef struct _CBIOS_CHIP_FUNC_TABLE +{ + PFN_cbSetTimingReg pfncbSetCRTimingReg; + PFN_cbSetTimingReg pfncbSetSRTimingReg; + PFN_cbGetModeInfoFromReg pfncbGetModeInfoFromReg; + PFN_cbInitVCP pfncbInitVCP; + PFN_cbDoHDTVFuncSetting pfncbDoHDTVFuncSetting; + PFN_cbLoadSSC pfncbLoadSSC; + PFN_cbEnableSpreadSpectrum pfncbEnableSpreadSpectrum; + PFN_cbDisableSpreadSpectrum pfncbDisableSpreadSpectrum; + PFN_cbUpdateFrame pfncbUpdateFrame; + PFN_cbDoCSCAdjust pfncbDoCSCAdjust; + PFN_cbAdjustStreamCSC pfncbAdjustStreamCSC; + PFN_cbCheckSurfaceOnDisplay pfncbCheckSurfaceOnDisplay; + PFN_cbGetDispAddr pfncbGetDispAddr; + PFN_cbSetHwCursor pfncbSetHwCursor; + PFN_cbInterruptEnableDisable pfncbInterruptEnableDisable; + PFN_cbCECEnableDisable pfncbCECEnableDisable; + PFN_cbSetGamma pfncbSetGamma; + PFN_cbDisableStream pfncbDisableStream; +}CBIOS_CHIP_FUNC_TABLE, *PCBIOS_CHIP_FUNC_TABLE; + + +CBIOS_VOID cbSetCRTimingReg(PCBIOS_VOID pvcbe, PCBIOS_TIMING_ATTRIB pTiming, CBIOS_U32 IGAIndex, CBIOS_TIMING_FLAGS Flags); +CBIOS_VOID cbSetSRTimingReg(PCBIOS_VOID pvcbe, PCBIOS_TIMING_ATTRIB pTiming, CBIOS_U32 IGAIndex, CBIOS_TIMING_FLAGS Flags); +CBIOS_VOID cbGetModeInfoFromReg(PCBIOS_VOID pvcbe, + CBIOS_ACTIVE_TYPE ulDevice, + PCBIOS_TIMING_ATTRIB pTiming, + PCBIOS_TIMING_FLAGS pFlags, + CBIOS_U32 IGAIndex, + CBIOS_TIMING_REG_TYPE TimingRegType); +CBIOS_BOOL cbInitVCP(PCBIOS_VOID pvcbe, PCBIOS_VOID pVCPInfo, PCBIOS_VOID pRomBase); +CBIOS_VOID cbDoHDTVFuncSetting(PCBIOS_VOID pvcbe, PCBIOS_DISP_MODE_PARAMS pModeParams, CBIOS_U32 IGAIndex, CBIOS_ACTIVE_TYPE ulDevices); +CBIOS_VOID cbLoadSSC(PCBIOS_VOID pvcbe, CBIOS_U32 CenterFreq, CBIOS_U8 IGAIndex, CBIOS_ACTIVE_TYPE LCDType); +CBIOS_VOID cbEnableSpreadSpectrum(PCBIOS_VOID pvcbe, CBIOS_U8 IGAIndex); +CBIOS_VOID cbDisableSpreadSpectrum(PCBIOS_VOID pvcbe, CBIOS_U8 IGAIndex); +CBIOS_STATUS cbInterruptEnableDisable(PCBIOS_VOID pvcbe, PCBIOS_INT_ENABLE_DISABLE_PARA pIntPara); +CBIOS_STATUS cbCECEnableDisable(PCBIOS_VOID pvcbe, PCBIOS_CEC_ENABLE_DISABLE_PARA pCECEnableDisablePara); +CBIOS_STATUS cbSetGamma(PCBIOS_VOID pvcbe, PCBIOS_GAMMA_PARA pGammaParam); +CBIOS_STATUS cbUpdateFrame(PCBIOS_VOID pvcbe, PCBIOS_UPDATE_FRAME_PARA pUpdateFrame); +CBIOS_STATUS cbDoCSCAdjust(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, PCBIOS_CSC_ADJUST_PARA pCSCAdjustPara); +CBIOS_STATUS cbAdjustStreamCSC(PCBIOS_VOID pvcbe, PCBIOS_STREAM_CSC_PARA pCSCAdjustPara); +CBIOS_STATUS cbCheckSurfaceOnDisplay(PCBIOS_VOID pvcbe, PCBIOS_CHECK_SURFACE_ON_DISP pChkSurfacePara); +CBIOS_STATUS cbGetDispAddr(PCBIOS_VOID pvcbe, PCBIOS_GET_DISP_ADDR pGetDispAddr); +CBIOS_STATUS cbSetHwCursor(PCBIOS_VOID pvcbe, PCBIOS_CURSOR_PARA pSetCursor); +CBIOS_VOID cbDisableStream(PCBIOS_VOID pvcbe, CBIOS_U32 IGAIndex); +#endif//_CBIOS_CHIP_FUNC_H_ diff --git a/drivers/gpu/drm/arise/cbios/Hw/CBiosHwShare.h b/drivers/gpu/drm/arise/cbios/Hw/CBiosHwShare.h new file mode 100644 index 0000000000000..2d014bb30fe00 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/CBiosHwShare.h @@ -0,0 +1,123 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** Include hw layer common header files. +** +** NOTE: +** This header file CAN ONLY be included by hw layer those files under Hw folder. +******************************************************************************/ + +#ifndef _CBIOS_HW_SHARE_H_ +#define _CBIOS_HW_SHARE_H_ + +//The register header files are included here +#include "Register/BIU_CR_C_BUS_registers.h" +#include "Register/BIU_HDA_registers.h" +#include "Register/BIU_MM_registers.h" +#include "Register/BIU_TSR_registers.h" +#include "Register/BIU_VCP_registers.h" +#include "Register/DIU_CR_registers.h" +#include "Register/DIU_MM_registers.h" +#include "Register/DIU_MM_registers_Arise.h" +#include "Register/DIU_SR_registers.h" +#include "Register/DIU_vga_registers.h" +#include "Register/Monitor/CBiosDPCDRegister.h" + +#include "HwUtil/CBiosUtilHw.h" +#include "HwUtil/CBiosI2C.h" +#include "HwCallback/CBiosCallbacksHw.h" + +#define PARALLEL_TABLE_END_INDEX 0xdeadbeaf +#define PARALLEL_TABLE_MAX_SIZE 100 + +#define STREAM_DISABLE_FAKE_ADDR (0xABBCC << 2) + +typedef enum _VIP_PARALLEL_REG_INDEX +{ + VIP_REG0 = 0, + VIP_REG1, + VIP_REG2, + VIP_REG3, + VIP_REG4, + VIP_REG5, + VIP_REG6, + VIP_REG7, + VIP_REG8, + VIP_REG9, + VIP_REG10, + VIP_REG11, + VIP_REG12, +}VIP_PARALLEL_REG_INDEX, *PVIP_PARALLEL_REG_INDEX; + +typedef enum _VIP_IIC_PARALLEL_REG_INDEX +{ + VIP_IIC_RW_DATA_REG = 0, + VIP_IIC_CONTROL_REG, + VIP_IIC_IE, +}VIP_IIC_PARALLEL_REG_INDEX, *PVIP_IIC_PARALLEL_REG_INDEX; + + +typedef union _CEC_MISC_REG1 +{ + struct + { + CBIOS_U32 IniRetryCnt :3; // CEC Initiator Retry times. Valid values must be 1 to 5. + CBIOS_U32 DeviceAddr :4; // CEC Initiator/Follower device address + CBIOS_U32 IniDestAddr :4; // CEC Initiator command destination address + CBIOS_U32 IniCmdLen :5; // CEC Initiator command length. The valid value is [0:16] + CBIOS_U32 IniBroadcast :1; // = TRUE: broadcast; = FALSE: direct access + CBIOS_U32 RsvdBit17 :1; + CBIOS_U32 CECEnable :1; // = CBIOS_TRUE: enable CEC; = CBIOS_FALSE: Disable CEC + CBIOS_U32 IniCmdAvailable :1; // = 0: NOT available; = 1: CEC Initiator commands have been loaded into register. + CBIOS_U32 RsvdBit20_31 :12; + + }; + CBIOS_U32 CECMiscReg1Value; +}CEC_MISC_REG1; + +typedef union _CEC_MISC_REG2 +{ + struct + { + CBIOS_U32 IniTransFinish :1; // CEC Initiator has finished the transmission. + CBIOS_U32 IniTransSucceed :1; // CEC Initiator transmission has succeeded. + CBIOS_U32 RsvdBit2 :1; + CBIOS_U32 FolSrcAddr :4; // The source address received by CEC Follower. + CBIOS_U32 FolBroadcast :1; // Transaction type received by CEC Follower.= TRUE: broadcast; = FALSE: direct access + CBIOS_U32 FolCmdLen :5; // Command length received by CEC Follower. A valid value is between 0 and 16 + CBIOS_U32 FolReceiveReady :1; // Follower has successfully received a transaction. + CBIOS_U32 RsvdBit14_31 :18; + }; + CBIOS_U32 CECMiscReg2Value; +}CEC_MISC_REG2; + +typedef struct _CBIOS_REGISTER_RANGE +{ + CBIOS_REGISTER_BLOCK_TYPE RegType; + CBIOS_U8 RegLen; + CBIOS_U16 StartIndex; + CBIOS_U16 EndIndex; +}CBIOS_REGISTER_RANGE, *PCBIOS_REGISTER_RANGE; + +typedef struct _CBIOS_REGISTER_GROUP +{ + CBIOS_UCHAR GroupName[10]; + PCBIOS_REGISTER_RANGE pRegRange; + CBIOS_U32 RangeNum; +}CBIOS_REGISTER_GROUP, *PCBIOS_REGISTER_GROUP; +#endif /* _CBIOS_HW_SHARE_H_ */ + diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.c new file mode 100644 index 0000000000000..538fedd06a7e4 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.c @@ -0,0 +1,396 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CRT hw block interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosDIU_CRT.h" +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" + +static CBREGISTER NewCRTDetectEnv[] = { +//notes: CBE has reserved 128 Byte array:pcbe->SavedReg[128] + //Per Ping, DAC phy need clock to trigger DATA into DAC, + //thus we should enable clock before setting sense data. + //{CR_B,(CBIOS_U8)~0x01,0xFC, 0x00 }, //Turn on DCLK1 + {SR,(CBIOS_U8)~0x01,0x0B, 0x00 }, //Turn on DCLK2 + {SR,(CBIOS_U8)~0x20,0x18, 0x20 }, //Turn on CRT Dac1 + {SR,(CBIOS_U8)~0x02,0x21, 0x02 }, //Turn on CRT Dac1 Sense power + {SR,(CBIOS_U8)~0x02,0x20, 0x00 }, //CRT DAC not off in Standby mode + {SR,(CBIOS_U8)~0x4C,0x31, 0x44 }, //DAC1 Sense Data Source Select + {SR, 0x00,0x4B, 0x94 }, // R sense data + {SR, 0x00,0x4C, 0x94 }, // G sense data + {SR, 0x00,0x4D, 0x94 }, // B sense data +}; + +CBIOS_VOID cbDIU_CRT_SetDacCsc(PCBIOS_VOID pvcbe, CSC_FORMAT InFmt, CSC_FORMAT OutFmt) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM33868_Arise DacCscValue = {0}; + + DacCscValue.Dac_Csc_In_Format = InFmt; + DacCscValue.Dac_Csc_Out_Format = OutFmt; + + cbMMIOWriteReg32(pcbe, 0x3868, DacCscValue.Value, 0); +} + +CBIOS_VOID cbDIU_CRT_SetHVSync(PCBIOS_VOID pvcbe, CBIOS_U8 HVPolarity, CBIOS_U8 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_ACTIVE_TYPE DevicePort = 0; + CBIOS_U8 byTemp = 0; + + DevicePort = pcbe->DispMgr.ActiveDevices[IGAIndex]; + + if (DevicePort & (0x1 | 0x40)) + { + byTemp = 0; + + if (HVPolarity & HorNEGATIVE) + { + byTemp |= 0x40; + + } + if (HVPolarity & VerNEGATIVE) + { + byTemp |= 0x80; + } + + if(IGAIndex == IGA1) + { + cb_WriteU8(pcbe->pAdapterContext,CB_MISC_OUTPUT_WRITE_REG, + (cb_ReadU8(pcbe->pAdapterContext,CB_MISC_OUTPUT_READ_REG)& ~0xC0) | byTemp); + } + else if(IGAIndex == IGA2) + { + cbMMIOWriteReg(pcbe, CR_42, byTemp, 0x3F); + } + else if(IGAIndex == IGA3) + { + cbMMIOWriteReg(pcbe, CR_43, (byTemp >> 5), 0xF9); + } + else if(IGAIndex == IGA4) + { + cbMMIOWriteReg(pcbe, CR_55, (byTemp >> 6), 0xFC); + } + } +} + +CBIOS_VOID cbDIU_CRT_DACOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bOn, CBIOS_U8 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_SR18 RegSR18Value, RegSR18Mask; + REG_SR27 RegSR27Value, RegSR27Mask; + REG_SR31_Pair RegSR31Value, RegSR31Mask; + + RegSR18Value.Value = 0; + RegSR18Mask.Value = 0xFF; + RegSR27Value.Value = 0; + RegSR27Mask.Value = 0xFF; + RegSR31Value.Value = 0; + RegSR31Mask.Value = 0xFF; + + if(bOn) + { + RegSR27Value.DAC1_Gain_Adjust = 0x03; + RegSR27Mask.DAC1_Gain_Adjust = 0; + cbMMIOWriteReg(pcbe, SR_27, RegSR27Value.Value, RegSR27Mask.Value); + + //select DAC source + if(IGAIndex == IGA1) + { + RegSR31Value.DAC1_Source_Select = 0; + } + else if(IGAIndex == IGA2) + { + RegSR31Value.DAC1_Source_Select = 1; + } + else if(IGAIndex == IGA3) + { + RegSR31Value.DAC1_Source_Select = 2; + } + else if(IGAIndex == IGA4) + { + RegSR31Value.DAC1_Source_Select = 3; + } + RegSR31Mask.DAC1_Source_Select = 0; + cbMMIOWriteReg(pcbe, SR_31, RegSR31Value.Value, RegSR31Mask.Value); + + //power up DAC + RegSR18Value.DAC1_Power_Up = 1; + RegSR18Mask.DAC1_Power_Up = 0; + cbMMIOWriteReg(pcbe, SR_18, RegSR18Value.Value, RegSR18Mask.Value); + cbMMIOWriteReg(pcbe, SR_32, 0x40, ~0x40); + } + else + { + //power down DAC + RegSR18Value.DAC1_Power_Up = 0; + RegSR18Mask.DAC1_Power_Up = 0; + cbMMIOWriteReg(pcbe, SR_18, RegSR18Value.Value, RegSR18Mask.Value); + } +} + +CBIOS_VOID cbDIU_CRT_SyncOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bOn) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_SR0D RegSR0DValue, RegSR0DMask; + + if(bOn) + { + RegSR0DValue.Value = 0; + RegSR0DValue.CRT1_HSYNC = 0; + RegSR0DValue.CRT1_VSYNC = 0; + RegSR0DMask.Value = 0xFF; + RegSR0DMask.CRT1_HSYNC = 0; + RegSR0DMask.CRT1_VSYNC = 0; + cbMMIOWriteReg(pcbe,SR_0D, RegSR0DValue.Value, RegSR0DMask.Value); + } + else + { + RegSR0DValue.Value = 0; + RegSR0DValue.CRT1_HSYNC = 1; + RegSR0DValue.CRT1_VSYNC = 1; + RegSR0DMask.Value = 0xFF; + RegSR0DMask.CRT1_HSYNC = 0; + RegSR0DMask.CRT1_VSYNC = 0; + cbMMIOWriteReg(pcbe,SR_0D, RegSR0DValue.Value, RegSR0DMask.Value); + } +} + +typedef struct _CBIOS_DAC_SENSE_PARA +{ + CBIOS_IN CBIOS_U8 PowerState; + CBIOS_IN CBIOS_U8 PrevEdidValid; + CBIOS_OUT CBIOS_U8 Connected; // if don't need dac sense, need return connect status + CBIOS_OUT CBIOS_U8 UseNewSense; // if need dac sense, need return sense path(new or old) +}CBIOS_DAC_SENSE_PARA; + +static CBIOS_BOOL cbIsNeedDacSense(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_DAC_SENSE_PARA *pSensePara) +{ + CBIOS_BOOL bNeedSense = CBIOS_FALSE; + CBIOS_BOOL bRetConnected = CBIOS_FALSE; + CBIOS_BOOL bUseNewSense = CBIOS_FALSE; + REG_SR31_Pair RegSR31Value; + + if(!pcbe || !pSensePara) + { + return CBIOS_FALSE; + } + + pSensePara->Connected = 0; + pSensePara->UseNewSense = 0; + + if(pcbe->ChipID != CHIPID_ARISE2030 && pcbe->ChipID != CHIPID_ARISE2020) + { + pSensePara->UseNewSense = (pSensePara->PowerState == CBIOS_PM_ON)? 1 : 0; + return CBIOS_TRUE; + } + + //patch for arise2030, check CRT's power and connect status + if(pSensePara->PowerState == CBIOS_PM_ON && (pcbe->DeviceMgr.ConnectedDevices & CBIOS_TYPE_CRT)) + { + //CRT is connected and turned on, check its binded IGA + RegSR31Value.Value = cbMMIOReadReg(pcbe, SR_31); + if(RegSR31Value.DAC1_Source_Select == 0x2) //source is IGA3 + { + //It's binded to IGA3, can't do dac sense, check whether previous EDID is valid + if(pSensePara->PrevEdidValid) + { + //previous EDID is valid, and can't read current EDID, it's edid-monitor plug out case + bNeedSense = CBIOS_FALSE; + bRetConnected = CBIOS_FALSE; + } + else + { + //can't detect plug out of non-EDID-monitor + bNeedSense = CBIOS_FALSE; + bRetConnected = CBIOS_TRUE; + } + } + else + { + //not bind to IGA3, do normal new dac sense + bNeedSense = CBIOS_TRUE; + bUseNewSense = CBIOS_TRUE; + } + } + else + { + //not connected or not turned on, can switch to IGA1/IGA2 to do old dac sense + bNeedSense = CBIOS_TRUE; + bUseNewSense = CBIOS_FALSE; + } + + if(bNeedSense) + { + pSensePara->UseNewSense = (bUseNewSense)? 1 : 0; + } + else + { + pSensePara->Connected = (bRetConnected)? 1 : 0; + } + + return bNeedSense; +} + +CBIOS_BOOL cbDIU_CRT_DACSense(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bPrevEdidValid) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 IGAIndex = pDevCommon->DispSource.ModuleList.IGAModule.Index; + CBIOS_BOOL bStatus = CBIOS_FALSE; + CBIOS_U8 by3C2; + REG_SR21 RegSR21Value, RegSR21Mask; + REG_SR31_Pair RegSR31Value, RegSR31Mask; + REG_SR3F RegSR3FValue, RegSR3FMask; + REG_CR71_Pair RegCR71Value, RegCR71Mask; + CBIOS_DAC_SENSE_PARA DacSensePara = {0}; + + DacSensePara.PowerState = pDevCommon->PowerState; + DacSensePara.PrevEdidValid = (bPrevEdidValid)? 1 : 0; + + if(!cbIsNeedDacSense(pcbe, &DacSensePara)) + { + return (DacSensePara.Connected)? CBIOS_TRUE : CBIOS_FALSE; + } + + if(DacSensePara.UseNewSense) + { + //Use new DAC1 sense logic when CRT is on. + RegSR21Value.Value = 0; + RegSR21Value.DAC1_SENSE_Power_Down_Enable = 0; + RegSR21Mask.Value = 0xFF; + RegSR21Mask.DAC1_SENSE_Power_Down_Enable = 0; + cbMMIOWriteReg(pcbe,SR_21, RegSR21Value.Value, RegSR21Mask.Value); + + RegSR31Value.Value = 0; + RegSR31Value.DAC1_SENSE_Source = 0; + RegSR31Mask.Value = 0xFF; + RegSR31Mask.DAC1_SENSE_Source = 0; + cbMMIOWriteReg(pcbe,SR_31, RegSR31Value.Value, RegSR31Mask.Value); + + RegSR3FValue.Value = 0; + RegSR3FValue.SENSE_Mode = 0; + RegSR3FMask.Value = 0xFF; + RegSR3FMask.SENSE_Mode = 0; + cbMMIOWriteReg(pcbe,SR_3F, RegSR3FValue.Value, RegSR3FMask.Value); + + RegCR71Value.Value = 0; + RegCR71Value.DLYSEL = 1; + RegCR71Value.SENSEL = 0; + RegCR71Value.SENWIDTH = 3; + RegCR71Mask.Value = 0xFF; + RegCR71Mask.DLYSEL = 0; + RegCR71Mask.SENSEL = 0; + RegCR71Mask.SENWIDTH = 0; + cbMMIOWriteReg(pcbe,CR_71, RegCR71Value.Value, RegCR71Mask.Value); + + cbMMIOWriteReg(pcbe,SR_4B, 0x7A, 0x00); //R sense + cbMMIOWriteReg(pcbe,SR_4C, 0x7A, 0x00); // G sense + cbMMIOWriteReg(pcbe,SR_4D, 0x7A, 0x00); // B sense + + RegSR3FValue.Value = 0; + RegSR3FValue.B_Sense_1to0 = 3; + RegSR3FValue.G_Sense_1to0 = 3; + RegSR3FValue.R_Sense_1to0 = 3; + RegSR3FMask.Value = 0xFF; + RegSR3FMask.B_Sense_1to0 = 0; + RegSR3FMask.G_Sense_1to0 = 0; + RegSR3FMask.R_Sense_1to0 = 0; + cbMMIOWriteReg(pcbe,SR_3F, RegSR3FValue.Value, RegSR3FMask.Value); + + RegSR21Value.Value = 0; + RegSR21Value.SEN_SEL = 0; + RegSR21Mask.Value = 0xFF; + RegSR21Mask.SEN_SEL = 0; + cbMMIOWriteReg(pcbe,SR_21, RegSR21Value.Value, RegSR21Mask.Value); + + RegSR31Value.Value = 0; + RegSR31Value.DAC1_SENSE_Source = 1; + RegSR31Mask.Value = 0xFF; + RegSR31Mask.DAC1_SENSE_Source = 0; + cbMMIOWriteReg(pcbe,SR_31, RegSR31Value.Value, RegSR31Mask.Value); + + RegSR21Value.Value = 0; + RegSR21Value.DAC1_SENSE_Power_Down_Enable = 1; + RegSR21Mask.Value = 0xFF; + RegSR21Mask.DAC1_SENSE_Power_Down_Enable = 0; + cbMMIOWriteReg(pcbe,SR_21, RegSR21Value.Value, RegSR21Mask.Value); + + if (IGAIndex != CBIOS_MODULE_INDEX_INVALID) + { + cbWaitVSync(pcbe, (CBIOS_U8)IGAIndex); + } + } + else + { + //Use old DAC1 sense logic when CRT is off. Use IGA2 to sense + cbSaveRegTableU8(pcbe, NewCRTDetectEnv, sizeofarray(NewCRTDetectEnv), pcbe->SavedReg); + + RegSR21Value.Value = 0; + RegSR21Value.SEN_SEL = 0; + RegSR21Mask.Value = 0xFF; + RegSR21Mask.SEN_SEL = 0; + cbMMIOWriteReg(pcbe,SR_21, RegSR21Value.Value, RegSR21Mask.Value); + RegSR3FValue.Value = 0; + RegSR3FValue.SENSE_Mode = 1; + RegSR3FMask.Value = 0xFF; + RegSR3FMask.SENSE_Mode = 0; + cbMMIOWriteReg(pcbe,SR_3F, RegSR3FValue.Value, RegSR3FMask.Value); + + cbMMIOWriteReg(pcbe,SR_4B, 0x7A, 0x00); + cbMMIOWriteReg(pcbe,SR_4C, 0x7A, 0x00); + cbMMIOWriteReg(pcbe,SR_4D, 0x7A, 0x00); + + cb_DelayMicroSeconds(570); + } + + // Read result + by3C2 = cb_ReadU8(pcbe->pAdapterContext, CB_INPUT_STATUS_0_REG); + if((by3C2 & 0x70) != 0x70) + { + bStatus = CBIOS_TRUE; + } + + // Restore register + if(DacSensePara.UseNewSense) + { + //Use new DAC1 sense logic when CRT is on. + RegSR21Value.Value = 0; + RegSR21Value.DAC1_SENSE_Power_Down_Enable = 0; + RegSR21Mask.Value = 0xFF; + RegSR21Mask.DAC1_SENSE_Power_Down_Enable = 0; + cbMMIOWriteReg(pcbe,SR_21, RegSR21Value.Value, RegSR21Mask.Value); + RegSR31Value.Value = 0; + RegSR31Value.DAC1_SENSE_Source = 0; + RegSR31Mask.Value= 0xFF; + RegSR31Mask.DAC1_SENSE_Source = 0; + cbMMIOWriteReg(pcbe,SR_31, RegSR31Value.Value, RegSR31Mask.Value); + } + else + { + //Use old DAC1 sense logic when CRT is off. + cbRestoreRegTableU8(pcbe, NewCRTDetectEnv, sizeofarray(NewCRTDetectEnv), pcbe->SavedReg); + } + + return bStatus; +} + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.h new file mode 100644 index 0000000000000..328b9d4ec5f98 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.h @@ -0,0 +1,36 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CRT hw block interface function prototype. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_DIU_CRT_H_ +#define _CBIOS_DIU_CRT_H_ + +#include "../../Device/CBiosDeviceShare.h" +#include "../../Device/Monitor/CBiosCRTMonitor.h" + +CBIOS_VOID cbDIU_CRT_SetHVSync(PCBIOS_VOID pvcbe, CBIOS_U8 HVPolarity, CBIOS_U8 IGAIndex); +CBIOS_VOID cbDIU_CRT_SetDacCsc(PCBIOS_VOID pvcbe, CSC_FORMAT InFmt, CSC_FORMAT OutFmt); +CBIOS_VOID cbDIU_CRT_DACOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bOn, CBIOS_U8 IGAIndex); +CBIOS_VOID cbDIU_CRT_SyncOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bOn); +CBIOS_BOOL cbDIU_CRT_DACSense(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon, CBIOS_BOOL bPrevEdidValid); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CSC.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CSC.c new file mode 100644 index 0000000000000..7fc73343994bd --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CSC.c @@ -0,0 +1,102 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +#include "CBiosChipShare.h" + +CBIOS_S64 YCbCr601_fr_RGB[][3] = { {269391, 528872, 102711}, + {-155485, -305252, 460738}, + {460738, -385810, -74927}}; + +CBIOS_S64 RGB_fr_YCbCr601[][3] = { {1220356, 0, 1672876} , + {1220356, -410625, -852112}, + {1220356, 2114363, 0} }; + +CBIOS_S64 YCbCr709_fr_RGB[][3] = { {191547, 644378, 65050}, + {-105575, -355162, 460738}, + {460738, -418490, -42247}}; + +CBIOS_S64 RGB_fr_YCbCr709[][3] = { {1220356, 0 , 1879062}, + {1220356, -223516, -558569}, + {1220356, 2214115, 0} }; + +CBIOS_S64 YCbCr2020_fr_RGB[][3] = {{236686, 610861, 53428}, + {-128665, -332072, 460738}, + {460738, -423681, -37056} };// non constant luminance only + +CBIOS_S64 RGB_fr_YCbCr2020[][3] = { {1220356, 0, 1759503}, + {1220356, -196345, -681742}, + {1220356, 2244899, 0} }; + +CBIOS_S64 LimitedRGB_fr_RGB[][3] = { {900976, 0, 0}, + {0, 900976, 0}, + {0, 0, 900976} }; + +CBIOS_S64 RGB_fr_LimitedRGB[][3] = { {1220356, 0, 0}, + {0, 1220356, 0}, + {0, 0, 1220356}}; + +CBIOS_S64 YCbCr709_fr_YCbCr601[][3] = {{1048576, -120831, -217087}, + {0, 1069055, 120831}, + {0, 77824, 1075200}}; + +CBIOS_S64 YCbCr601_fr_YCbCr709[][3] = {{1048576, 104447, 200703}, + {0, 1038335, -116735}, + {0, -75776, 1030144} }; + +CBIOS_S64 Balance_Times_matrix[][3] = {{1048576, 0, 0}, + {0, 1048576, 0}, + {0, 0, 1048576}}; + +//map cosX' value (X range from -180' to 180') to CSC_cos[0 ... 360] +CBIOS_S32 CSC_cos[]={ -1048576 ,-1048416 ,-1047937 ,-1047138 ,-1046021 ,-1044585 ,-1042831 ,-1040760 ,-1038371 ,-1035666 ,-1032645 ,-1029310 ,-1025662 ,-1021701 ,-1017428 ,-1012846 ,-1007955 ,-1002758 , -997255 , -991448 , + -985339 , -978930 , -972222 , -965219 , -957921 , -950332 , -942453 , -934288 , -925837 , -917105 , -908093 , -898805 , -889242 , -879409 , -869308 , -858943 , -848315 , -837430 , -826289 , -814896 , + -803255 , -791370 , -779243 , -766879 , -754282 , -741455 , -728402 , -715127 , -701634 , -687927 , -674011 , -659890 , -645567 , -631048 , -616337 , -601438 , -586356 , -571095 , -555660 , -540056 , + -524288 , -508359 , -492276 , -476043 , -459665 , -443147 , -426494 , -409711 , -392803 , -375776 , -358634 , -341382 , -324027 , -306573 , -289026 , -271391 , -253673 , -235878 , -218011 , -200077 , + -182083 , -164033 , -145933 , -127789 , -109606 , -91389 , -73144 , -54878 , -36594 , -18300 , 0 , 18300 , 36594 , 54878 , 73144 , 91389 , 109606 , 127789 , 145933 , 164033 , + 182083 , 200077 , 218011 , 235878 , 253673 , 271391 , 289026 , 306573 , 324027 , 341382 , 358634 , 375776 , 392803 , 409711 , 426494 , 443147 , 459665 , 476043 , 492276 , 508359 , + 524287 , 540056 , 555660 , 571095 , 586356 , 601438 , 616337 , 631048 , 645567 , 659890 , 674011 , 687927 , 701634 , 715127 , 728402 , 741455 , 754282 , 766879 , 779243 , 791370 , + 803255 , 814896 , 826289 , 837430 , 848315 , 858943 , 869308 , 879409 , 889242 , 898805 , 908093 , 917105 , 925837 , 934288 , 942453 , 950332 , 957921 , 965219 , 972222 , 978930 , + 985339 , 991448 , 997255 , 1002758 , 1007955 , 1012846 , 1017428 , 1021701 , 1025662 , 1029310 , 1032645 , 1035666 , 1038371 , 1040760 , 1042831 , 1044585 , 1046021 , 1047138 , 1047937 , 1048416 , + 1048576 , 1048416 , 1047937 , 1047138 , 1046021 , 1044585 , 1042831 , 1040760 , 1038371 , 1035666 , 1032645 , 1029310 , 1025662 , 1021701 , 1017428 , 1012846 , 1007955 , 1002758 , 997255 , 991448 , + 985339 , 978930 , 972222 , 965219 , 957921 , 950332 , 942453 , 934288 , 925837 , 917105 , 908093 , 898805 , 889242 , 879409 , 869308 , 858943 , 848315 , 837430 , 826289 , 814896 , + 803255 , 791370 , 779243 , 766879 , 754282 , 741455 , 728402 , 715127 , 701634 , 687927 , 674011 , 659890 , 645567 , 631048 , 616337 , 601438 , 586356 , 571095 , 555660 , 540056 , + 524287 , 508359 , 492276 , 476043 , 459665 , 443147 , 426494 , 409711 , 392803 , 375776 , 358634 , 341382 , 324027 , 306573 , 289026 , 271391 , 253673 , 235878 , 218011 , 200077 , + 182083 , 164033 , 145933 , 127789 , 109606 , 91389 , 73144 , 54878 , 36594 , 18300 , 0 , -18300 , -36594 , -54878 , -73144 , -91389 , -109606 , -127789 , -145933 , -164033 , + -182083 , -200077 , -218011 , -235878 , -253673 , -271391 , -289026 , -306573 , -324027 , -341382 , -358634 , -375776 , -392803 , -409711 , -426494 , -443147 , -459665 , -476043 , -492276 , -508359 , + -524288 , -540056 , -555660 , -571095 , -586356 , -601438 , -616337 , -631048 , -645567 , -659890 , -674011 , -687927 , -701634 , -715127 , -728402 , -741455 , -754282 , -766879 , -779243 , -791370 , + -803255 , -814896 , -826289 , -837430 , -848315 , -858943 , -869308 , -879409 , -889242 , -898805 , -908093 , -917105 , -925837 , -934288 , -942453 , -950332 , -957921 , -965219 , -972222 , -978930 , + -985339 , -991448 , -997255 ,-1002758 ,-1007955 ,-1012846 ,-1017428 ,-1021701 ,-1025662 ,-1029310 ,-1032645 ,-1035666 ,-1038371 ,-1040760 ,-1042831 ,-1044585 ,-1046021 ,-1047138 ,-1047937 ,-1048416 , + -1048576}; +//map sinX' value (X range from -180' to 180') to CSC_sin[0 ... 360] +CBIOS_S32 CSC_sin[] = {0 , -18300 , -36594 , -54878 , -73144 , -91389 , -109606 , -127789 , -145933 , -164033 , -182083 , -200077 , -218011 , -235878 , -253673 , -271391 , -289026 , -306573 , -324027 , -341382 , + -358634 , -375776 , -392803 , -409711 , -426494 , -443147 , -459665 , -476043 , -492276 , -508359 , -524287 , -540056 , -555660 , -571095 , -586356 , -601438 , -616337 , -631048 , -645567 , -659890 , + -674011 , -687927 , -701634 , -715127 , -728402 , -741455 , -754282 , -766879 , -779243 , -791370 , -803255 , -814896 , -826289 , -837430 , -848315 , -858943 , -869308 , -879409 , -889242 , -898805 , + -908093 , -917105 , -925837 , -934288 , -942453 , -950332 , -957921 , -965219 , -972222 , -978930 , -985339 , -991448 , -997255 ,-1002758 ,-1007955 ,-1012846 ,-1017428 ,-1021701 ,-1025662 ,-1029310 , + -1032645 ,-1035666 ,-1038371 ,-1040760 ,-1042831 ,-1044585 ,-1046021 ,-1047138 ,-1047937 ,-1048416 ,-1048576 ,-1048416 ,-1047937 ,-1047138 ,-1046021 ,-1044585 ,-1042831 ,-1040760 ,-1038371 ,-1035666 , + -1032645 ,-1029310 ,-1025662 ,-1021701 ,-1017428 ,-1012846 ,-1007955 ,-1002758 , -997255 , -991448 , -985339 , -978930 , -972222 , -965219 , -957921 , -950332 , -942453 , -934288 , -925837 , -917105 , + -908093 , -898805 , -889242 , -879409 , -869308 , -858943 , -848315 , -837430 , -826289 , -814896 , -803255 , -791370 , -779243 , -766879 , -754282 , -741455 , -728402 , -715127 , -701634 , -687927 , + -674011 , -659890 , -645567 , -631048 , -616337 , -601438 , -586356 , -571095 , -555660 , -540056 , -524288 , -508359 , -492276 , -476043 , -459665 , -443147 , -426494 , -409711 , -392803 , -375776 , + -358634 , -341382 , -324027 , -306573 , -289026 , -271391 , -253673 , -235878 , -218011 , -200077 , -182083 , -164033 , -145933 , -127789 , -109606 , -91389 , -73144 , -54878 , -36594 , -18300 , + 0 , 18300 , 36594 , 54878 , 73144 , 91389 , 109606 , 127789 , 145933 , 164033 , 182083 , 200077 , 218011 , 235878 , 253673 , 271391 , 289026 , 306573 , 324027 , 341382 , + 358634 , 375776 , 392803 , 409711 , 426494 , 443147 , 459665 , 476043 , 492276 , 508359 , 524288 , 540056 , 555660 , 571095 , 586356 , 601438 , 616337 , 631048 , 645567 , 659890 , + 674011 , 687927 , 701634 , 715127 , 728402 , 741455 , 754282 , 766879 , 779243 , 791370 , 803255 , 814896 , 826289 , 837430 , 848315 , 858943 , 869308 , 879409 , 889242 , 898805 , + 908093 , 917105 , 925837 , 934288 , 942453 , 950332 , 957921 , 965219 , 972222 , 978930 , 985339 , 991448 , 997255 , 1002758 , 1007955 , 1012846 , 1017428 , 1021701 , 1025662 , 1029310 , + 1032645 , 1035666 , 1038371 , 1040760 , 1042831 , 1044585 , 1046021 , 1047138 , 1047937 , 1048416 , 1048576 , 1048416 , 1047937 , 1047138 , 1046021 , 1044585 , 1042831 , 1040760 , 1038371 , 1035666 , + 1032645 , 1029310 , 1025662 , 1021701 , 1017428 , 1012846 , 1007955 , 1002758 , 997255 , 991448 , 985339 , 978930 , 972222 , 965219 , 957921 , 950332 , 942453 , 934288 , 925837 , 917105 , + 908093 , 898805 , 889242 , 879409 , 869308 , 858943 , 848315 , 837430 , 826289 , 814896 , 803255 , 791370 , 779243 , 766879 , 754282 , 741455 , 728402 , 715127 , 701634 , 687927 , + 674011 , 659890 , 645567 , 631048 , 616337 , 601438 , 586356 , 571095 , 555660 , 540056 , 524287 , 508359 , 492276 , 476043 , 459665 , 443147 , 426494 , 409711 , 392803 , 375776 , + 358634 , 341382 , 324027 , 306573 , 289026 , 271391 , 253673 , 235878 , 218011 , 200077 , 182083 , 164033 , 145933 , 127789 , 109606 , 91389 , 73144 , 54878 , 36594 , 18300 , + 0 ,}; + diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CSC.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CSC.h new file mode 100644 index 0000000000000..6ecbd3b72f9cf --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CSC.h @@ -0,0 +1,96 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +#ifndef _CBIOSDIU_CSC_H_ +#define _CBIOSDIU_CSC_H_ + +//these maro is used for get Coefx and birghtness's 2's complement +#define CSC_COEF_MODULE 14 +#define CSC_BRIGHT_MODULE 9 + +#define CSC_MAX_CONTRAST 2 +#define CSC_MIN_CONTRAST 0 +#define CSC_DEFAULT_CONTRAST 1 + +#define CSC_MAX_SATURATION 2 +#define CSC_MIN_SATURATION 0 +#define CSC_DEFAULT_SATURATION 1 + +#define CSC_MAX_HUE 180 +#define CSC_MIN_HUE -180 +#define CSC_DEFAULT_HUE 0 + +#define CSC_HUE_MATRIX_EXPAND_TIMES 0x100000 +#define CSC_CONTRAST_MATRIX_EXPAND_TIMES 0x80 +#define CSC_SATURATION_MATRIX_EXPAND_TIMES 0x80 +#define CSC_YCBCR_RGB_MATRIX_EXPAND_TIMES 0x100000 + +#define CSC_HUE_MATRIX_SHIFT_BITS 20 +#define CSC_CONTRAST_MATRIX_SHIFT_BITS 7 +#define CSC_SATURATION_MATRIX_SHIFT_BITS 7 +#define CSC_YCBCR_RGB_MATRIX_SHIFT_BITS 20 //expand 0x100000 times,need shift 20bit + +#define CSC_TOTAL_MATRIX_EXPAND_TIMES CSC_HUE_MATRIX_EXPAND_TIMES*CSC_CONTRAST_MATRIX_EXPAND_TIMES* \ + CSC_SATURATION_MATRIX_EXPAND_TIMES*CSC_YCBCR_RGB_MATRIX_EXPAND_TIMES + +#define CSC_TOTAL_MAXTRIX_SHIFT_BITS (CSC_HUE_MATRIX_SHIFT_BITS + CSC_CONTRAST_MATRIX_SHIFT_BITS+ \ + CSC_SATURATION_MATRIX_SHIFT_BITS + CSC_YCBCR_RGB_MATRIX_SHIFT_BITS) + + +#define CSC_MODE_HASH_VALUE 7 + +//value of CSC_XXX_TO_XXX = CSC_MODE_HASH_VALUE * input format + output format +#define CSC_RGB_TO_RGB 0 +#define CSC_RGB_TO_YCBCR601 4 +#define CSC_RGB_TO_YCBCR709 5 +#define CSC_RGB_TO_YCBCR2020 6 +#define CSC_LIMITED_RGB_TO_RGB 7 +#define CSC_LIMITED_RGB_TO_LIMITED_RGB 8 +#define CSC_LIMITED_RGB_TO_YCBCR601 11 +#define CSC_LIMITED_RGB_TO_YCBCR709 12 +#define CSC_LIMITED_RGB_TO_YCBCR2020 13 +#define CSC_YCBCR601_TO_RGB 28 +#define CSC_YCBCR601_TO_LIMITED_RGB 29 +#define CSC_YCBCR601_TO_YCBCR601 32 +#define CSC_YCBCR601_TO_YCBCR709 33 +#define CSC_YCBCR601_TO_YCBCR2020 34 +#define CSC_YCBCR709_TO_RGB 35 +#define CSC_YCBCR709_TO_LIMITED_RGB 36 +#define CSC_YCBCR709_TO_YCBCR601 39 +#define CSC_YCBCR709_TO_YCBCR709 40 +#define CSC_YCBCR709_TO_YCBCR2020 41 +#define CSC_YCBCR2020_TO_RGB 42 +#define CSC_YCBCR2020_TO_LIMITED_RGB 43 +#define CSC_YCBCR2020_TO_YCBCR601 46 +#define CSC_YCBCR2020_TO_YCBCR709 47 +#define CSC_YCBCR2020_TO_YCBCR2020 48 + +extern CBIOS_S64 YCbCr601_fr_RGB[][3]; +extern CBIOS_S64 RGB_fr_YCbCr601[][3]; +extern CBIOS_S64 YCbCr709_fr_RGB[][3]; +extern CBIOS_S64 RGB_fr_YCbCr709[][3]; +extern CBIOS_S64 YCbCr2020_fr_RGB[][3];// non constant luminance only +extern CBIOS_S64 RGB_fr_YCbCr2020[][3]; +extern CBIOS_S64 LimitedRGB_fr_RGB[][3]; +extern CBIOS_S64 RGB_fr_LimitedRGB[][3]; +extern CBIOS_S64 YCbCr709_fr_YCbCr601[][3]; +extern CBIOS_S64 YCbCr601_fr_YCbCr709[][3]; +extern CBIOS_S64 Balance_Times_matrix[][3]; + +extern CBIOS_S32 CSC_cos[]; +extern CBIOS_S32 CSC_sin[]; + +#endif + diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DP.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DP.c new file mode 100644 index 0000000000000..49a6d49812fbf --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DP.c @@ -0,0 +1,2758 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DP hw block interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosDIU_DP.h" +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" + +#define MEASURE_LT_TIME_GPIO 0 + +CBIOS_U32 DP_REG_MISC1[DP_MODU_NUM] = {0x8210, 0x33CA8, 0x343A8, 0x34AA8}; +CBIOS_U32 DP_REG_LINK[DP_MODU_NUM] = {0x8214, 0x33CAC, 0x343AC, 0x34AAC}; +CBIOS_U32 DP_REG_GEN_CTRL[DP_MODU_NUM] = {0x8218, 0x33CB0, 0x343B0, 0x34AB0}; +CBIOS_U32 DP_REG_EXT_PACKET[DP_MODU_NUM] = {0x821C, 0x33CB4, 0x343B4, 0x34AB4}; +CBIOS_U32 DP_REG_ENABLE[DP_MODU_NUM] = {0x8240, 0x33CB8, 0x343B8, 0x34AB8}; +CBIOS_U32 DP_REG_HWIDTH_TU[DP_MODU_NUM] = {0x8244, 0x33CBC, 0x343BC, 0x34ABC}; +CBIOS_U32 DP_REG_HLINE_DUR[DP_MODU_NUM] = {0x8248, 0x33CC0, 0x343C0, 0x34AC0}; +CBIOS_U32 DP_REG_MISC0[DP_MODU_NUM] = {0x824C, 0x33CC4, 0x343C4, 0x34AC4}; +CBIOS_U32 DP_REG_HV_TOTAL[DP_MODU_NUM] = {0x8250, 0x33CC8, 0x343C8, 0x34AC8}; +CBIOS_U32 DP_REG_HV_START[DP_MODU_NUM] = {0x8254, 0x33CCC, 0x343CC, 0x34ACC}; +CBIOS_U32 DP_REG_HV_SYNC[DP_MODU_NUM] = {0x8258, 0x33CD0, 0x343D0, 0x34AD0}; +CBIOS_U32 DP_REG_HV_ACTIVE[DP_MODU_NUM] = {0x825C, 0x33CD4, 0x343D4, 0x34AD4}; +CBIOS_U32 DP_REG_EPHY_CTRL[DP_MODU_NUM] = {0x82CC, 0x33CD8, 0x343D8, 0x34AD8}; +CBIOS_U32 DP_REG_AUX_WRITE0[DP_MODU_NUM] = {0x8310, 0x33CDC, 0x343DC, 0x34ADC}; +CBIOS_U32 DP_REG_AUX_WRITE1[DP_MODU_NUM] = {0x8314, 0x33CE0, 0x343E0, 0x34AE0}; +CBIOS_U32 DP_REG_AUX_WRITE2[DP_MODU_NUM] = {0x8318, 0x33CE4, 0x343E4, 0x34AE4}; +CBIOS_U32 DP_REG_AUX_WRITE3[DP_MODU_NUM] = {0x831C, 0x33CE8, 0x343E8, 0x34AE8}; +CBIOS_U32 DP_REG_AUX_READ0[DP_MODU_NUM] = {0x8320, 0x33CEC, 0x343EC, 0x34AEC}; +CBIOS_U32 DP_REG_AUX_READ1[DP_MODU_NUM] = {0x8324, 0x33CF0, 0x343F0, 0x34AF0}; +CBIOS_U32 DP_REG_AUX_READ2[DP_MODU_NUM] = {0x8328, 0x33CF4, 0x343F4, 0x34AF4}; +CBIOS_U32 DP_REG_AUX_READ3[DP_MODU_NUM] = {0x832C, 0x33CF8, 0x343F8, 0x34AF8}; +CBIOS_U32 DP_REG_AUX_TIMER[DP_MODU_NUM] = {0x8330, 0x33CFC, 0x343FC, 0x34AFC}; +CBIOS_U32 DP_REG_AUX_CMD[DP_MODU_NUM] = {0x8334, 0x33D00, 0x34400, 0x34B00}; +CBIOS_U32 DP_REG_MUTE[DP_MODU_NUM] = {0x8338, 0x33D04, 0x34404, 0x34B04}; +CBIOS_U32 DP_REG_MAUD[DP_MODU_NUM] = {0x833C, 0x33D08, 0x34408, 0x34B08}; +CBIOS_U32 DP_REG_EPHY_MPLL[DP_MODU_NUM] = {0x8340, 0x33D0C, 0x3440C, 0x34B0C}; +CBIOS_U32 DP_REG_EPHY_TX[DP_MODU_NUM] = {0x8344, 0x33D10, 0x34410, 0x34B10}; +CBIOS_U32 DP_REG_EPHY_MISC[DP_MODU_NUM] = {0x8348, 0x33D14, 0x34414, 0x34B14}; +CBIOS_U32 DP_REG_SWING[DP_MODU_NUM] = {0x8368, 0x33D28, 0x34428, 0x34B28}; +CBIOS_U32 DP_REG_EPHY_STATUS[DP_MODU_NUM] = {0x836C, 0x33D2C, 0x3442C, 0x34B2C}; +CBIOS_U32 DP_REG_LINK_CTRL[DP_MODU_NUM] = {0x334C8, 0x33D3C, 0x3443C, 0x34B3C}; +CBIOS_U32 DP_REG_CTRL2[DP_MODU_NUM] = {0x334CC, 0x33D40, 0x34440, 0x34B40}; +CBIOS_U32 DP_REG_CTRL[DP_MODU_NUM] = {0x334DC, 0x33D50, 0x34450, 0x34B50}; +CBIOS_U32 DP_REG_EPHY_SETTING1[DP_MODU_NUM] = {0x334E0, 0x33D54, 0x34454, 0x34B54}; +CBIOS_U32 DP_REG_EPHY_SETTING2[DP_MODU_NUM] = {0x334E4, 0x33D58, 0x34458, 0x34B58}; + +CBIOS_VOID cbDIU_EDP_ControlVDDSignal(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL status) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_SR3C_Pair RegSR3CValue, RegSR3CMask; + REG_SR35_Pair RegSR35Value, RegSR35Mask; + + if(status) //ON + { + if(((DPModuleIndex == CBIOS_MODULE_INDEX1) && (pDPMonitorContext->GpioForEDP1Power== 0x0f)) + || ((DPModuleIndex == CBIOS_MODULE_INDEX2) && (pDPMonitorContext->GpioForEDP2Power== 0x0f))) //invalid + { + RegSR3CValue.Value = 0; + RegSR3CValue.ENVDD = 0; + RegSR3CMask.Value = 0xFF; + RegSR3CMask.ENVDD = 0; + cbMMIOWriteReg(pcbe, SR_3C, RegSR3CValue.Value, RegSR3CMask.Value); + cbDelayMilliSeconds(2); + } + else if(((DPModuleIndex == CBIOS_MODULE_INDEX1) && (pDPMonitorContext->GpioForEDP1Power== 0)) + || ((DPModuleIndex == CBIOS_MODULE_INDEX2) && (pDPMonitorContext->GpioForEDP2Power== 0))) + { + RegSR35Value.Value = 0; + RegSR35Value.GPIO0_Select = 0x1; + RegSR35Value.GPIO0_Data = 1; + RegSR35Mask.Value = 0xFF; + RegSR35Mask.GPIO0_Select = 0; + RegSR35Mask.GPIO0_Data = 0; + cbMMIOWriteReg(pcbe, SR_35, RegSR35Value.Value, RegSR35Mask.Value); + } + else + { + //TODO: GPIO control power sequence + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: invalid power gpio index!\n", FUNCTION_NAME)); + } + } + else //OFF + { + if(((DPModuleIndex == CBIOS_MODULE_INDEX1) && (pDPMonitorContext->GpioForEDP1Power== 0x0f)) + || ((DPModuleIndex == CBIOS_MODULE_INDEX2) && (pDPMonitorContext->GpioForEDP2Power== 0x0f))) //invalid + { + //cbDelayMilliSeconds(16); + RegSR3CValue.Value = 0; + RegSR3CValue.ENVDD = 1; + RegSR3CMask.Value = 0xFF; + RegSR3CMask.ENVDD = 0; + cbMMIOWriteReg(pcbe, SR_3C, RegSR3CValue.Value, RegSR3CMask.Value); + cbDelayMilliSeconds(500); + } + else if(((DPModuleIndex == CBIOS_MODULE_INDEX1) && (pDPMonitorContext->GpioForEDP1Power== 0)) + || ((DPModuleIndex == CBIOS_MODULE_INDEX2) && (pDPMonitorContext->GpioForEDP2Power== 0))) + { + RegSR35Value.Value = 0; + RegSR35Value.GPIO0_Select = 0x1; + RegSR35Value.GPIO0_Data = 0; + RegSR35Mask.Value = 0xFF; + RegSR35Mask.GPIO0_Select = 0; + RegSR35Mask.GPIO0_Data = 0; + cbMMIOWriteReg(pcbe, SR_35, RegSR35Value.Value, RegSR35Mask.Value); + cbDelayMilliSeconds(500); + } + else + { + //TODO: GPIO control power sequence + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: invalid power gpio index!\n", FUNCTION_NAME)); + } + } +} + +CBIOS_VOID cbDIU_EDP_ControlVEESignal(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL status) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_SR3C_Pair RegSR3CValue, RegSR3CMask; + REG_SR35_Pair RegSR35Value, RegSR35Mask; + + if(status) //ON + { + if(((DPModuleIndex == CBIOS_MODULE_INDEX1) && (pDPMonitorContext->GpioForEDP1BackLight== 0x0f)) + || ((DPModuleIndex == CBIOS_MODULE_INDEX2) && (pDPMonitorContext->GpioForEDP2BackLight== 0x0f))) //invalid + { + //cbDelayMilliSeconds(256); + RegSR3CValue.Value = 0; + RegSR3CValue.ENVEE = 0; + RegSR3CMask.Value = 0xFF; + RegSR3CMask.ENVEE = 0; + cbMMIOWriteReg(pcbe,SR_3C, RegSR3CValue.Value, RegSR3CMask.Value); + } + else if(((DPModuleIndex == CBIOS_MODULE_INDEX1) && (pDPMonitorContext->GpioForEDP1BackLight== 1)) + || ((DPModuleIndex == CBIOS_MODULE_INDEX2) && (pDPMonitorContext->GpioForEDP2BackLight== 1))) + { + RegSR35Value.Value = 0; + RegSR35Value.GPIO0_Select = 0x1; + RegSR35Value.GPIO0_Data = 1; + RegSR35Mask.Value = 0xFF; + RegSR35Mask.GPIO0_Select = 0; + RegSR35Mask.GPIO0_Data = 0; + cbMMIOWriteReg(pcbe, SR_B_35, RegSR35Value.Value, RegSR35Mask.Value); + } + else + { + //TODO: GPIO control power sequence + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: invalid backlignt gpio index!\n", FUNCTION_NAME)); + } + } + else //OFF + { + if(((DPModuleIndex == CBIOS_MODULE_INDEX1) && (pDPMonitorContext->GpioForEDP1BackLight== 0x0f)) + || ((DPModuleIndex == CBIOS_MODULE_INDEX2) && (pDPMonitorContext->GpioForEDP2BackLight== 0x0f))) //invalid + { + RegSR3CValue.Value = 0; + RegSR3CValue.ENVEE = 1; + RegSR3CMask.Value = 0xFF; + RegSR3CMask.ENVEE = 0; + cbMMIOWriteReg(pcbe,SR_3C, RegSR3CValue.Value, RegSR3CMask.Value); + //cbDelayMilliSeconds(256); + } + else if(((DPModuleIndex == CBIOS_MODULE_INDEX1) && (pDPMonitorContext->GpioForEDP1BackLight== 1)) + || ((DPModuleIndex == CBIOS_MODULE_INDEX2) && (pDPMonitorContext->GpioForEDP2BackLight== 1))) + { + RegSR35Value.Value = 0; + RegSR35Value.GPIO0_Select = 0x1; + RegSR35Value.GPIO0_Data = 0; + RegSR35Mask.Value = 0xFF; + RegSR35Mask.GPIO0_Select = 0; + RegSR35Mask.GPIO0_Data = 0; + cbMMIOWriteReg(pcbe, SR_B_35, RegSR35Value.Value, RegSR35Mask.Value); + } + else + { + //TODO: GPIO control power sequence + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: invalid backlignt gpio index!\n", FUNCTION_NAME)); + } + } +} + +CBIOS_BOOL cbDIU_EDP_WaitforSinkHPDSignal(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U16 timeout) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U16 counter = 0; + REG_MM8330 DPAuxTimerRegValue; + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + while (counter <= timeout) + { + //Per Sean, if mmio 8330[31:30] shows hot plugin, means a rising edge of hpd signal + //After VDD on, HPD signal will be a rising edge, and vdd off will be falling edge + DPAuxTimerRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_TIMER[DPModuleIndex]); + if (DPAuxTimerRegValue.HPD_Status == 0x01) + { + return CBIOS_TRUE; + } + cbDelayMilliSeconds(1); //query HPD status every 1ms + counter += 1; + } + + return CBIOS_FALSE; +} + +CBIOS_VOID cbDIU_DP_DPModeEnable(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL bEnable) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8240 DPEnableRegValue, DPEnableRegMask; + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return; + } + + cbTraceEnter(DP); + + DPEnableRegValue.Value = 0; + DPEnableRegValue.DP_Enable = (bEnable)? 1 : 0; + DPEnableRegMask.Value = 0xFFFFFFFF; + DPEnableRegMask.DP_Enable = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_ENABLE[DPModuleIndex], DPEnableRegValue.Value, DPEnableRegMask.Value); + + cbTraceExit(DP); +} + +CBIOS_VOID cbDIU_DP_SetInterruptMode(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL isDPMode) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM82CC DPEphyCtrlRegValue, DPEphyCtrlRegMask; + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return; + } + + DPEphyCtrlRegValue.Value = 0; + DPEphyCtrlRegValue.int_mode = (isDPMode)? 0 : 1; + DPEphyCtrlRegMask.Value = 0xFFFFFFFF; + DPEphyCtrlRegMask.int_mode = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_CTRL[DPModuleIndex], DPEphyCtrlRegValue.Value, DPEphyCtrlRegMask.Value); +} + +CBIOS_VOID cbDIU_DP_SetHVSync(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U8 HVPolarity) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8258 DPPolarityRegValue, DPPolarityRegMask; + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return; + } + + DPPolarityRegValue.Value = 0; + if (HVPolarity & HorNEGATIVE) + { + DPPolarityRegValue.HSYNC_Polarity = 1; + } + if (HVPolarity & VerNEGATIVE) + { + DPPolarityRegValue.VSYNC_Polarity = 1; + } + + DPPolarityRegMask.Value = 0xFFFFFFFF; + DPPolarityRegMask.HSYNC_Polarity = 0; + DPPolarityRegMask.VSYNC_Polarity = 0; + cbMMIOWriteReg32(pcbe, DP_REG_HV_SYNC[DPModuleIndex], DPPolarityRegValue.Value, DPPolarityRegMask.Value); +} + +CBIOS_VOID cbDIU_DP_SetMaudNaud(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U32 LinkSpeed, CBIOS_U32 StreamFormat) +{ + CBIOS_U64 Naud = 0; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8240 DPEnableRegValue, DPEnableRegMask; + REG_MM8338 DPMuteRegValue, DPMuteRegMask; + //REG_MM833C DPMaudRegValue, DPMaudRegMask; + REG_MM8218 DPCodecSelRegValue, DPCodecSelRegMask; + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return; + } + + // 1. Audio Enable + DPMuteRegValue.Value = 0; + DPMuteRegValue.Audio_Output_Enable = 1; + DPMuteRegMask.Value = 0xFFFFFFFF; + DPMuteRegMask.Audio_Output_Enable = 0; + cbMMIOWriteReg32(pcbe, DP_REG_MUTE[DPModuleIndex], DPMuteRegValue.Value, DPMuteRegMask.Value); + + DPEnableRegValue.Value = 0; + DPEnableRegValue.Enable_Audio = 1; + DPEnableRegMask.Value = 0xFFFFFFFF; + DPEnableRegMask.Enable_Audio = 0; + cbMMIOWriteReg32(pcbe, DP_REG_ENABLE[DPModuleIndex], DPEnableRegValue.Value, DPEnableRegMask.Value); + + DPCodecSelRegValue.Value = 0; + DPCodecSelRegMask.Value = 0xFFFFFFFF; + DPCodecSelRegMask.Audio_Strm_Select = 0; + if(DPModuleIndex == CBIOS_MODULE_INDEX1) + { + DPCodecSelRegValue.Audio_Strm_Select = 0; + } + else if(DPModuleIndex == CBIOS_MODULE_INDEX2) + { + DPCodecSelRegValue.Audio_Strm_Select = 1; + } + cbMMIOWriteReg32(pcbe, DP_REG_GEN_CTRL[DPModuleIndex], DPCodecSelRegValue.Value, DPCodecSelRegMask.Value); + + // 2. Calculate Naud Maud + Naud = 0x8000; // set Naud = 32768 +#if 0 // it is SW MAUD + Maud = cb_do_div((Naud * 512 * StreamFormat), (LinkSpeed * 100)); + + DPMaudRegValue.Value = 0; + DPMaudRegValue.MAUD = (CBIOS_U32)Maud; + DPMaudRegMask.Value = 0xFFFFFFFF; + DPMaudRegMask.MAUD = 0; + cbMMIOWriteReg32(pcbe, DP_REG_MAUD[DPModuleIndex], DPMaudRegValue.Value, DPMaudRegMask.Value); +#endif + DPMuteRegValue.Value = 0; + DPMuteRegValue.NAUD = (CBIOS_U32)Naud; + DPMuteRegValue.Generate_MAUD = 1; // use HW MAUD + DPMuteRegValue.Generated_MAUD_Mode = 1; // use HW MAUD + DPMuteRegMask.Value = 0xFFFFFFFF; + DPMuteRegMask.NAUD = 0; + DPMuteRegMask.Generate_MAUD = 0; + DPMuteRegMask.Generated_MAUD_Mode = 0; + cbMMIOWriteReg32(pcbe, DP_REG_MUTE[DPModuleIndex], DPMuteRegValue.Value, DPMuteRegMask.Value); +} + +CBIOS_VOID cbDIU_DP_ResetLinkTraining(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8214 DPLinkRegValue, DPLinkRegMask; + + cbTraceEnter(DP); + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return; + } + + // reset Link Training + DPLinkRegValue.Value = 0; + DPLinkRegValue.SW_Set_Link_Train_Fail = 1; + DPLinkRegMask.Value = 0xFFFFFFFF; + DPLinkRegMask.SW_Set_Link_Train_Fail = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + + DPLinkRegValue.Value = 0; + DPLinkRegValue.SW_Set_Link_Train_Fail = 0; + DPLinkRegMask.Value = 0xFFFFFFFF; + DPLinkRegMask.SW_Set_Link_Train_Fail = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + + DPLinkRegValue.Value = 0; + DPLinkRegValue.SW_Link_Train_State = 0; + DPLinkRegValue.SW_Set_Link_Train_Fail = 0; + DPLinkRegMask.Value = 0xFFFFFFFF; + DPLinkRegMask.SW_Link_Train_State = 0; + DPLinkRegMask.SW_Set_Link_Train_Fail = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + + cbTraceExit(DP); +} + +CBIOS_VOID cbDIU_DP_VideoOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL bOn) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8240 DPEnableRegValue, DPEnableRegMask; + + cbTraceEnter(DP); + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return; + } + + DPEnableRegValue.Value = 0; + DPEnableRegMask.Value = 0xFFFFFFFF; + DPEnableRegMask.Video_Enable = 0; + + if (bOn) + { + DPEnableRegValue.Video_Enable = 1; + cbMMIOWriteReg32(pcbe, DP_REG_ENABLE[DPModuleIndex], DPEnableRegValue.Value, DPEnableRegMask.Value); + } + else + { + DPEnableRegValue.Video_Enable = 0; + cbWaitVBlank(pcbe, DPModuleIndex); + cbMMIOWriteReg32(pcbe, DP_REG_ENABLE[DPModuleIndex], DPEnableRegValue.Value, DPEnableRegMask.Value); + } +} + +//We should disable both video and audio during link training. +//Disable video : MM8240[3] = 0 +//Mute by DP: MM8338[27-26] = 3; MM8240[24] = 1 +CBIOS_VOID cbDIU_DP_DisableVideoAudio(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8240 DPEnableRegValue, DPEnableRegMask; + REG_MM8338 DPMuteRegValue, DPMuteRegMask; + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return; + } + + //disable video and audio + DPMuteRegValue.Value = 0; + DPMuteRegValue.Audio_Output_Enable = 0; + DPMuteRegValue.Mute = 1; + DPMuteRegValue.Mute_Mode =1; + DPMuteRegMask.Value = 0xFFFFFFFF; + DPMuteRegMask.Audio_Output_Enable = 0; + DPMuteRegMask.Mute = 0; + DPMuteRegMask.Mute_Mode =0; + cbMMIOWriteReg32(pcbe, DP_REG_MUTE[DPModuleIndex], DPMuteRegValue.Value, DPMuteRegMask.Value); + + DPEnableRegValue.Value = 0; + DPEnableRegValue.Enable_Audio = 0; + DPEnableRegValue.Video_Enable = 0; + DPEnableRegMask.Value = 0xFFFFFFFF; + DPEnableRegMask.Enable_Audio = 0; + DPEnableRegMask.Video_Enable = 0; + cbWaitVBlank(pcbe, DPModuleIndex); + cbMMIOWriteReg32(pcbe, DP_REG_ENABLE[DPModuleIndex], DPEnableRegValue.Value, DPEnableRegMask.Value); +} + +CBIOS_VOID cbDIU_DP_EnableVideoAudio(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8240 DPEnableRegValue, DPEnableRegMask; + REG_MM8338 DPMuteRegValue, DPMuteRegMask; + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return; + } + + DPMuteRegValue.Value = 0; + DPMuteRegValue.Audio_Output_Enable = 1; + DPMuteRegValue.Mute = 0; + DPMuteRegValue.Mute_Mode = 1; + DPMuteRegMask.Value = 0xFFFFFFFF; + DPMuteRegMask.Audio_Output_Enable = 0; + DPMuteRegMask.Mute = 0; + DPMuteRegMask.Mute_Mode = 0; + cbMMIOWriteReg32(pcbe, DP_REG_MUTE[DPModuleIndex], DPMuteRegValue.Value, DPMuteRegMask.Value); + + DPEnableRegValue.Value = 0; + DPEnableRegValue.Enable_Audio = 1; + DPEnableRegValue.Video_Enable = 1; + DPEnableRegMask.Value = 0xFFFFFFFF; + DPEnableRegMask.Video_Enable = 0; + DPEnableRegMask.Enable_Audio = 0; + cbMMIOWriteReg32(pcbe, DP_REG_ENABLE[DPModuleIndex], DPEnableRegValue.Value, DPEnableRegMask.Value); +} + +/***************************************************************************************/ +/******************************* Link Training Interfaces ****************************/ +// Reset Aux, PISO, enable Scramble +static CBIOS_VOID cbDIU_DP_LinkTrainingPreset(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL bEnhancedMode) +{ + REG_MM8218 DPGenCtrlRegValue, DPGenCtrlRegMask; + REG_MM8240 DPEnableRegValue, DPEnableRegMask; + REG_MM8344 DPEphyTxRegValue, DPEphyTxRegMask; + + cbTraceEnter(DP); + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return; + } + + // Reset Aux + cbDIU_DP_ResetAUX(pcbe, DPModuleIndex); + + // Reset EPHY PISO in case of speed change + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 1; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 1; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 1; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 1; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Power_Control_Lane0 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane1 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane2 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane3 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + cb_DelayMicroSeconds(1); + + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 0; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Power_Control_Lane0 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane1 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane2 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane3 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // enable scramble + DPGenCtrlRegValue.Value = 0; + DPGenCtrlRegValue.Scramble_enable = 1; + DPGenCtrlRegValue.Switch_Idle_mode_to_video = 0; + DPGenCtrlRegValue.Idle_Pattern_Counter = 0; + DPGenCtrlRegValue.AUX_Length = 0; + DPGenCtrlRegValue.HW_Link_Train_Fail = 0; + DPGenCtrlRegMask.Value = 0xFFFFFFFF; + DPGenCtrlRegMask.Scramble_enable = 0; + DPGenCtrlRegMask.Switch_Idle_mode_to_video = 0; + DPGenCtrlRegMask.Idle_Pattern_Counter = 0; + DPGenCtrlRegMask.AUX_Length = 0; + DPGenCtrlRegMask.HW_Link_Train_Fail = 0; + cbMMIOWriteReg32(pcbe, DP_REG_GEN_CTRL[DPModuleIndex], DPGenCtrlRegValue.Value, DPGenCtrlRegMask.Value); + + DPEnableRegValue.Value = 0; + DPEnableRegValue.DP_Enable = 1; + DPEnableRegValue.Field_Invert = 0; + DPEnableRegValue.InfoFrame_FIFO_1_Ready = 0; + DPEnableRegValue.INFOFRAME_FIFO_2_READY = 0; + DPEnableRegValue.InfoFrame_FIFO_Select = 0; + DPEnableRegValue.InfoFrame_FIFO_1_Start_Address = 0; + DPEnableRegValue.InfoFrame_FIFO_2_Start_Address = 0; + DPEnableRegValue.InfoFrame_FIFO_1_Length = 0; + DPEnableRegValue.InfoFrame_FIFO_2_Length = 0; + DPEnableRegValue.Ext_Packet_Enable = 0; + DPEnableRegValue.header_of_audio_info_frame_is_from_HDAudio_codec = 0; + DPEnableRegValue.Main_Link_Status = 0; + + DPEnableRegMask.Value = 0xFFFFFFFF; + DPEnableRegMask.DP_Enable = 0; + DPEnableRegMask.Field_Invert = 0; + DPEnableRegMask.Enhanced_Framing_Mode = 0; + DPEnableRegMask.InfoFrame_FIFO_1_Ready = 0; + DPEnableRegMask.INFOFRAME_FIFO_2_READY = 0; + DPEnableRegMask.InfoFrame_FIFO_Select = 0; + DPEnableRegMask.InfoFrame_FIFO_1_Start_Address = 0; + DPEnableRegMask.InfoFrame_FIFO_2_Start_Address = 0; + DPEnableRegMask.InfoFrame_FIFO_1_Length = 0; + DPEnableRegMask.InfoFrame_FIFO_2_Length = 0; + DPEnableRegMask.Ext_Packet_Enable = 0; + DPEnableRegMask.header_of_audio_info_frame_is_from_HDAudio_codec = 0; + DPEnableRegMask.Main_Link_Status = 0; + + if (bEnhancedMode) + { + DPEnableRegValue.Enhanced_Framing_Mode = 1; + } + else + { + DPEnableRegValue.Enhanced_Framing_Mode = 0; + } + cbMMIOWriteReg32(pcbe, DP_REG_ENABLE[DPModuleIndex], DPEnableRegValue.Value, DPEnableRegMask.Value); + + cbTraceExit(DP); +} + +static CBIOS_VOID cbDIU_DP_SetDPVersion(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U32 DPVersion) +{ + REG_MM334CC DPCtrl2RegValue, DPCtrl2RegMask; + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return; + } + + DPCtrl2RegValue.Value = 0; + DPCtrl2RegValue.DP_VERSION_VALUE = DPVersion; + DPCtrl2RegMask.Value = 0xFFFFFFFF; + DPCtrl2RegMask.DP_VERSION_VALUE = 0; + cbMMIOWriteReg32(pcbe, DP_REG_CTRL2[DPModuleIndex], DPCtrl2RegValue.Value, DPCtrl2RegMask.Value); +} + +CBIOS_BOOL cbDIU_DP_LinkTrainingHw(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_LINK_TRAINING_PARAMS pLinkTrainingParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Device = CBIOS_TYPE_NONE; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + PCBIOS_DP_CONTEXT pDpContext = CBIOS_NULL; + CBIOS_BOOL bStatus = CBIOS_FALSE; + CBIOS_U32 i = 0; + CBIOS_U32 bEQFallBack = 0; + CBIOS_U32 BitRate = 0; + CBIOS_U32 ulLaneNum, MaxLaneCount = 0; + CBIOS_U32 BitRateIndex = 0, MaxBitRateIndex = 0; + AUX_CONTROL AUX; + REG_MM8214 DPLinkRegValue, DPLinkRegMask; + REG_MM8218 DPGenCtrlRegValue; + REG_MM8240 DPEnableRegValue; + REG_MM82CC DPEphyCtrlRegValue, DPEphyCtrlRegMask; + REG_MM8330 DPAuxTimerRegValue; + REG_MM8338 DPMuteRegValue, DPMuteRegMask; + REG_MM8368 DPSwingRegValue, DPSwingRegMask; + REG_MM334C8 DPLinkCtrlRegValue, DPLinkCtrlRegMask; + DPCD_REG_00100 DPCD_00100; + DPCD_REG_00101 DPCD_00101; + DPCD_REG_0010A DPCD_0010A; + DPCD_REG_00102 DPCD_00102; + + //For DP test 4.3.1.4, if use SW to try 1.62 when 2.7 fail, the ulMaxRetryCount should set to 1. + CBIOS_U32 ulRetryCount = 0, ulMaxRetryCount = 3; + + if(DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid module index in %s\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + cbTraceEnter(DP); + + switch (DPModuleIndex) + { + case CBIOS_MODULE_INDEX1: + Device = CBIOS_TYPE_DP1; + break; + case CBIOS_MODULE_INDEX2: + Device = CBIOS_TYPE_DP2; + break; + case CBIOS_MODULE_INDEX3: + Device = CBIOS_TYPE_DP3; + break; + case CBIOS_MODULE_INDEX4: + Device = CBIOS_TYPE_DP4; + break; + default: + break; + } + + if(Device == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: invalid DP module index, LT failed! \n", FUNCTION_NAME)); + return bStatus; + } + + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + pDpContext = container_of(pDevCommon, PCBIOS_DP_CONTEXT, Common); + + if(pDpContext->DPPortParams.bRunCTS) + { + ulMaxRetryCount = 1;//For DP test 4.3.1.4, if use SW to try 1.62 when 2.7 fail, the ulMaxRetryCount should set to 1. + } + + MaxLaneCount = pLinkTrainingParams->MaxLaneCount; + if (pLinkTrainingParams->MaxLinkSpeed == CBIOS_DP_LINK_SPEED_5400Mbps) + { + MaxBitRateIndex = 3; + } + else if (pLinkTrainingParams->MaxLinkSpeed == CBIOS_DP_LINK_SPEED_2700Mbps) + { + MaxBitRateIndex = 2; + } + else + { + MaxBitRateIndex = 1; + } + + // set DP version according to sink + cbDIU_DP_SetDPVersion(pcbe, DPModuleIndex, pLinkTrainingParams->DpSinkVersion); + + BitRateIndex = MaxBitRateIndex; + ulLaneNum = MaxLaneCount; + while(ulLaneNum > 0 && BitRateIndex > 0) + { + if (BitRateIndex == 3) + { + BitRate = CBIOS_DP_LINK_SPEED_5400Mbps; + } + else if (BitRateIndex == 2) + { + BitRate = CBIOS_DP_LINK_SPEED_2700Mbps; + } + else + { + BitRate = CBIOS_DP_LINK_SPEED_1620Mbps; + } + + for (ulRetryCount = 0; ulRetryCount < ulMaxRetryCount; ulRetryCount++) + { + //----------------- HW link training core:---------------------------------------- + // reset link training, MM8338[31] used for HW linktraining only. + DPMuteRegValue.Value = 0; + DPMuteRegValue.Link_Training_SW_Reset = 1; + DPMuteRegMask.Value = 0xFFFFFFFF; + DPMuteRegMask.Link_Training_SW_Reset = 0; + cbMMIOWriteReg32(pcbe, DP_REG_MUTE[DPModuleIndex], DPMuteRegValue.Value, DPMuteRegMask.Value); + + cb_DelayMicroSeconds(1000); // wait HW Link Training Module Reset to be done especially on FPGA. + + DPMuteRegValue.Value = 0; + DPMuteRegValue.Link_Training_SW_Reset = 0; + DPMuteRegMask.Value = 0xFFFFFFFF; + DPMuteRegMask.Link_Training_SW_Reset = 0; + cbMMIOWriteReg32(pcbe, DP_REG_MUTE[DPModuleIndex], DPMuteRegValue.Value, DPMuteRegMask.Value); + + // Set MM8214 + DPLinkRegValue.Value = 0; + DPLinkRegValue.Num_of_Lanes = ulLaneNum; + DPLinkRegValue.HW_Link_Training_Done = 0; + DPLinkRegValue.Max_V_swing = 3; + DPLinkRegValue.Max_Pre_emphasis = 2; + DPLinkRegValue.SW_Link_Train_Enable = 0; + DPLinkRegValue.SW_Lane0_Swing = 0; + DPLinkRegValue.SW_Lane1_Swing = 0; + DPLinkRegValue.SW_Lane2_Swing = 0; + DPLinkRegValue.SW_Lane3_Swing = 0; + DPLinkRegMask.Value = 0xFFFFFFFF; + DPLinkRegMask.Num_of_Lanes = 0; + DPLinkRegMask.HW_Link_Training_Done = 0; + DPLinkRegMask.Max_V_swing = 0; + DPLinkRegMask.Max_Pre_emphasis = 0; + DPLinkRegMask.SW_Link_Train_Enable = 0; + DPLinkRegMask.SW_Lane0_Swing = 0; + DPLinkRegMask.SW_Lane1_Swing = 0; + DPLinkRegMask.SW_Lane2_Swing = 0; + DPLinkRegMask.SW_Lane3_Swing = 0; + + DPLinkCtrlRegValue.Value = 0; + DPLinkCtrlRegMask.Value = 0xFFFFFFFF; + + DPLinkCtrlRegValue.DPCD102_B5 = 1; + DPLinkCtrlRegMask.DPCD102_B5 = 0; + + if (pLinkTrainingParams->bEnableTPS3) + { + // to support 5.4Gbps Link Rate, need to send Training Pattern 3 + DPLinkCtrlRegValue.EQ_USE_TP3 = 1; + DPLinkCtrlRegMask.EQ_USE_TP3 = 0; + } + else + { + DPLinkCtrlRegValue.EQ_USE_TP3 = 0; + DPLinkCtrlRegMask.EQ_USE_TP3 = 0; + } + + // choose HW Link Training Speed + if (BitRate == CBIOS_DP_LINK_SPEED_5400Mbps) + { + DPLinkRegValue.Start_Link_Rate_0 = 0; + DPLinkRegMask.Start_Link_Rate_0 = 0; + DPLinkCtrlRegValue.Start_LINK_RATE_1 = 1; + DPLinkCtrlRegMask.Start_LINK_RATE_1 = 0; + } + else if (BitRate == CBIOS_DP_LINK_SPEED_2700Mbps) + { + DPLinkRegValue.Start_Link_Rate_0 = 1; + DPLinkRegMask.Start_Link_Rate_0 = 0; + DPLinkCtrlRegValue.Start_LINK_RATE_1 = 0; + DPLinkCtrlRegMask.Start_LINK_RATE_1 = 0; + } + else + { + DPLinkRegValue.Start_Link_Rate_0 = 0; + DPLinkRegMask.Start_Link_Rate_0 = 0; + DPLinkCtrlRegValue.Start_LINK_RATE_1 = 0; + DPLinkCtrlRegMask.Start_LINK_RATE_1 = 0; + } + + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + cbMMIOWriteReg32(pcbe, DP_REG_LINK_CTRL[DPModuleIndex], DPLinkCtrlRegValue.Value, DPLinkCtrlRegMask.Value); + + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: { %dMbps by %dLane(s) }: initiated...\n", FUNCTION_NAME, (BitRate / 1000), ulLaneNum)); + // Reset Aux, PISO, enable Scramble + cbDIU_DP_LinkTrainingPreset(pcbe, DPModuleIndex, pLinkTrainingParams->bEnhancedMode); + + // Set DPCD + // According linklayer compliance test spec, + // Before link training pattern set, must update LINK_BW_SET and LANE_COUNT_SET fields of DPCD. + DPCD_00100.Value = 0; + if (BitRate == CBIOS_DP_LINK_SPEED_5400Mbps) + { + DPCD_00100.LINK_BW_SET = CBIOS_DPCD_LINK_RATE_5400Mbps; + } + else if (BitRate == CBIOS_DP_LINK_SPEED_2700Mbps) + { + DPCD_00100.LINK_BW_SET = CBIOS_DPCD_LINK_RATE_2700Mbps; + } + else + { + DPCD_00100.LINK_BW_SET = CBIOS_DPCD_LINK_RATE_1620Mbps; + } + + DPCD_00101.Value = 0; + DPCD_00101.LANE_COUNT_SET = (CBIOS_U8)ulLaneNum; + //enhanced mode bit. + //if eDP alternate framing is enabled, DPCD 101h enhanced frame mode should not be set + if ((pLinkTrainingParams->bEnhancedMode) && (pLinkTrainingParams->CPMethod != CBIOS_EDP_CP_AF)) + { + DPCD_00101.ENHANCED_FRAME_EN = 1; + } + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x100; + AUX.Length = 0x2; + AUX.Data[0] = (DPCD_00101.Value << 8) | DPCD_00100.Value; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Aux Error before LT!\n", FUNCTION_NAME)); + goto EndOfLinkTraining; + } + + //write eDP CP DPCD + if (pLinkTrainingParams->CPMethod == CBIOS_EDP_CP_ASSR) + { + //enable ASSR for source + DPEphyCtrlRegValue.Value = 0; + DPEphyCtrlRegValue.EDP_ASSR = 1; + DPEphyCtrlRegMask.Value = 0xFFFFFFFF; + DPEphyCtrlRegMask.EDP_ASSR = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_CTRL[DPModuleIndex], DPEphyCtrlRegValue.Value, DPEphyCtrlRegMask.Value); + + DPCD_0010A.Value = 0; + DPCD_0010A.ALTERNATE_SCRAMBER_RESET_ENABLE = 1; + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x10A; + AUX.Length = 1; + AUX.Data[0] = DPCD_0010A.Value; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Aux Error before LT!\n", FUNCTION_NAME)); + goto EndOfLinkTraining; + } + } + else if (pLinkTrainingParams->CPMethod == CBIOS_EDP_CP_AF) + { + DPCD_0010A.Value = 0; + DPCD_0010A.FRAMING_CHANGE_ENABLE = 1; + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x10A; + AUX.Length = 1; + AUX.Data[0] = DPCD_0010A.Value; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Aux Error before LT!\n", FUNCTION_NAME)); + goto EndOfLinkTraining; + } + } + else + { + //disable ASSR for source + DPEphyCtrlRegValue.Value = 0; + DPEphyCtrlRegValue.EDP_ASSR = 0; + DPEphyCtrlRegMask.Value = 0xFFFFFFFF; + DPEphyCtrlRegMask.EDP_ASSR = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_CTRL[DPModuleIndex], DPEphyCtrlRegValue.Value, DPEphyCtrlRegMask.Value); + + //disable eDP CP + DPCD_0010A.Value = 0; + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x10A; + AUX.Length = 1; + AUX.Data[0] = DPCD_0010A.Value; + cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX); + //here we don't check aux reply since for some monitors, + //DPCD 0x10A is reserved and will not send back reply + } + +#if MEASURE_LT_TIME_GPIO + // GPIO2 outputs 1 for measuring purpose + cbMMIOWriteReg(pcbe,CR_B_DA,0x30,0x8F); +#endif + + cbDIU_DP_HWUseAuxChannel(pcbe, DPModuleIndex); + + // Increase TX amplitude by 60%. + DPEphyCtrlRegValue.Value = 0; + DPEphyCtrlRegValue.DIAJ_L0 = 1; + DPEphyCtrlRegValue.DIAJ_L1 = 1; + DPEphyCtrlRegValue.DIAJ_L2 = 1; + DPEphyCtrlRegValue.DIAJ_L3 = 1; + DPEphyCtrlRegMask.Value = 0xFF000FFF; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_CTRL[DPModuleIndex], DPEphyCtrlRegValue.Value, DPEphyCtrlRegMask.Value); + + if (BitRate == CBIOS_DP_LINK_SPEED_5400Mbps) + { + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 1; + DPSwingRegValue.DP1_SW_swing = 0x09; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 5; + DPSwingRegValue.DP1_SW_swing = 0x10; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 9; + DPSwingRegValue.DP1_SW_swing = 0x17; + DPSwingRegValue.DP1_SW_pp = 0x1C; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x11; + DPSwingRegValue.DP1_SW_swing = 0x11; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x15; + DPSwingRegValue.DP1_SW_swing = 0x19; + DPSwingRegValue.DP1_SW_pp = 0x08; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x19; + DPSwingRegValue.DP1_SW_swing = 0x33; + DPSwingRegValue.DP1_SW_pp = 0x1A; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x1D; + DPSwingRegValue.DP1_SW_swing = 0x1C; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x21; + DPSwingRegValue.DP1_SW_swing = 0x14; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x25; + DPSwingRegValue.DP1_SW_swing = 0x3F; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + } + else + { + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 1; + DPSwingRegValue.DP1_SW_swing = 0x09; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 5; + DPSwingRegValue.DP1_SW_swing = 0x15; + DPSwingRegValue.DP1_SW_pp = 0x06; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 9; + DPSwingRegValue.DP1_SW_swing = 0x1D; + DPSwingRegValue.DP1_SW_pp = 0x0E; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x11; + DPSwingRegValue.DP1_SW_swing = 0x11; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x15; + DPSwingRegValue.DP1_SW_swing = 0x30; + DPSwingRegValue.DP1_SW_pp = 0x08; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x19; + DPSwingRegValue.DP1_SW_swing = 0x39; + DPSwingRegValue.DP1_SW_pp = 0x1A; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x1D; + DPSwingRegValue.DP1_SW_swing = 0x30; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x21; + DPSwingRegValue.DP1_SW_swing = 0x39; + DPSwingRegValue.DP1_SW_pp = 0xA; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 0x25; + DPSwingRegValue.DP1_SW_swing = 0x3F; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], 0x2687F8, 0xFFC00000); + } + + if (pLinkTrainingParams->DpSinkVersion >= 0x12) + { + DPSwingRegValue.Value = 0; + DPSwingRegValue.VER1P2 = 1; + DPSwingRegValue.RD_INTVAL = pLinkTrainingParams->TrainingAuxRdInterval; + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.VER1P2 = 0; + DPSwingRegMask.RD_INTVAL = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + } + + // enable HW link training + DPLinkRegValue.Value = 0; + DPLinkRegValue.Start_Link_Training = 1; + DPLinkRegMask.Value = 0xFFFFFFFF; + DPLinkRegMask.Start_Link_Training = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + + // Spec says LT should be done within 10ms. + // Here we wait 30ms. + for(i = 0; i <= 600; i++) + { + cb_DelayMicroSeconds(250); + + DPLinkRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_LINK[DPModuleIndex]); + if (DPLinkRegValue.HW_Link_Training_Done) + { + DPEnableRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_ENABLE[DPModuleIndex]); + if (DPEnableRegValue.Main_Link_Status == 3) + { + DPLinkRegValue.Value = 0; + DPLinkRegValue.Start_Link_Training = 0; + DPLinkRegValue.HW_Link_Training_Done = 0; + DPLinkRegMask.Value = 0xFFFFFFFF; + DPLinkRegMask.Start_Link_Training = 0; + DPLinkRegMask.HW_Link_Training_Done = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + bStatus = CBIOS_TRUE; + break; + } + } + } + + if (bStatus) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: { %dMbps by %dLane(s) }: Succeed!\n", FUNCTION_NAME, (BitRate / 1000), ulLaneNum)); + goto LinkTrainingDone; + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: { %dMbps by %dLane(s) }: Fail!\n", FUNCTION_NAME, (BitRate / 1000), ulLaneNum)); + + //clear last link training fail status + DPLinkRegValue.Value = 0; + DPLinkRegValue.Start_Link_Training = 0; + DPLinkRegValue.HW_Link_Training_Done = 0; + DPLinkRegMask.Value = 0xFFFFFFFF; + DPLinkRegMask.Start_Link_Training = 0; + DPLinkRegMask.HW_Link_Training_Done = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + + //clear link training pattern + DPCD_00102.Value = 0; + DPCD_00102.TRAINING_PATTERN_SELECT = 0; + DPCD_00102.SCRAMBLING_DISABLE = 0; + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x102; + AUX.Length = 0x1; + AUX.Data[0] = DPCD_00102.Value; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Aux Error before LT!\n", FUNCTION_NAME)); + goto EndOfLinkTraining; + } + + } + + }//end of retry loop + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x202; + AUX.Length = 0x2; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "AUX.Data[0] = %x\n", AUX.Data[0])); + + if(BitRateIndex == MaxBitRateIndex && ulLaneNum == MaxLaneCount) + { + if((MaxLaneCount == 4 && AUX.Data[0] == 0x1177)|| + (MaxLaneCount == 2 && ((AUX.Data[0]&0xFF) == 0x17))) + { + bEQFallBack = 1; + } + } + } + + if(bEQFallBack) + { + ulLaneNum = ulLaneNum >> 1; + if(ulLaneNum == 0 && BitRateIndex > 0) + { + ulLaneNum = MaxLaneCount; + BitRateIndex --; + if(BitRateIndex == 0) + { + ulLaneNum = 0; + } + } + } + else + { + BitRateIndex --; + if(BitRateIndex == 0 && ulLaneNum > 0) + { + BitRateIndex = MaxBitRateIndex; + ulLaneNum = ulLaneNum >> 1; + if(ulLaneNum == 0) + { + BitRateIndex = 0; + } + } + } + }//end of lane count loop + +LinkTrainingDone: + //link training succeeded, update current link speed and lane count + if (bStatus) + { + pLinkTrainingParams->CurrLinkSpeed = BitRate; + pLinkTrainingParams->CurrLaneCount = ulLaneNum; + } + + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Polling Loop Count ==: %d, equivalent time (i*50us) == %dus!\n", FUNCTION_NAME, i, (i * 50))); + +#if MEASURE_LT_TIME_GPIO + // GPIO2 outputs 0 for measuring purpose + cbMMIOWriteReg(pcbe,CR_B_DA,0x20,0x8F); +#endif +EndOfLinkTraining: + if (!bStatus) + { + DPGenCtrlRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_GEN_CTRL[DPModuleIndex]); + DPAuxTimerRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_TIMER[DPModuleIndex]); + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: LT fail: mm8218==0x%08x, mm8330==0x%08x\n", FUNCTION_NAME, DPGenCtrlRegValue.Value, DPAuxTimerRegValue.Value)); + + if (DPGenCtrlRegValue.HW_Link_Train_Fail) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: LT failed due to Aux error!\n", FUNCTION_NAME)); + + // Clear TRAINING_PATTERN_SET byte + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: write DPCD_102 0x00 to abort LT and recover Aux\n", FUNCTION_NAME)); + + DPCD_00102.Value = 0; + DPCD_00102.TRAINING_PATTERN_SELECT = 0; + DPCD_00102.SCRAMBLING_DISABLE = 0; + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x102; + AUX.Length = 0x1; + AUX.Data[0] = DPCD_00102.Value; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Write DPCD error to abort LT!\n", FUNCTION_NAME)); + bStatus = CBIOS_FALSE; + } + } + } + + cbDIU_DP_HWUseAuxChannel(pcbe, DPModuleIndex); + + cbTraceExit(DP); + + return bStatus; +} + +CBIOS_BOOL cbDIU_DP_SetUpMainLink(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_MAIN_LINK_PARAMS pMainLinkParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bStatus = CBIOS_FALSE; + PCBIOS_TIMING_ATTRIB pTiming = pMainLinkParams->pTiming; + CBIOS_U64 ulTURatio, ulTemp1, ulTemp2, ulTemp3; + REG_MM8210 DPMisc1RegValue, DPMisc1RegMask; + REG_MM8218 DPGenCtrlRegValue, DPGenCtrlRegMask; + REG_MM821C DPExtPacketRegValue, DPExtPacketRegMask; + REG_MM8240 DPEnableRegValue, DPEnableRegMask; + REG_MM8244 DPHWidthTURegValue, DPHWidthTURegMask; + REG_MM8248 DPHLineDurRegValue, DPHLineDurRegMask; + REG_MM824C DPMisc0RegValue, DPMisc0RegMask; + REG_MM8250 DPHVTotalRegValue, DPHVTotalRegMask; + REG_MM8254 DPHVStartRegValue, DPHVStartRegMask; + REG_MM8258 DPHVSyncRegValue, DPHVSyncRegMask; + REG_MM825C DPHVActiveRegValue, DPHVActiveRegMask; + REG_MM334DC DPCtrlRegValue; + REG_SR3A_Pair RegSR3AValue; + REG_SR3A_Pair RegSR3AMask; + AUX_CONTROL AUX; + DPCD_REG_00100 DPCD_0100; + + cbTraceEnter(DP); + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return bStatus; + } + + DPEnableRegValue.Value = 0; + DPEnableRegValue.Field_Invert = 0; + DPEnableRegMask.Value = 0xFFFFFFFF; + DPEnableRegMask.Field_Invert = 0; + cbMMIOWriteReg32(pcbe, DP_REG_ENABLE[DPModuleIndex], DPEnableRegValue.Value, DPEnableRegMask.Value); + + #if 1 + DPCtrlRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_CTRL[DPModuleIndex]); + if (DPCtrlRegValue.LINK_bit_rate_status_1_0 == 0) + { + if (pMainLinkParams->LinkSpeedToUse != CBIOS_DP_LINK_SPEED_1620Mbps) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: why current link speed:%d is not sync with REG:0x%x?\n", + FUNCTION_NAME, pMainLinkParams->LinkSpeedToUse, DP_REG_CTRL[DPModuleIndex])); + pMainLinkParams->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_1620Mbps; + } + } + else if (DPCtrlRegValue.LINK_bit_rate_status_1_0 == 1) + { + if (pMainLinkParams->LinkSpeedToUse != CBIOS_DP_LINK_SPEED_2700Mbps) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: why current link speed:%d is not sync with REG:0x%x?\n", + FUNCTION_NAME, pMainLinkParams->LinkSpeedToUse, DP_REG_CTRL[DPModuleIndex])); + pMainLinkParams->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_2700Mbps; + } + } + else + { + if (pMainLinkParams->LinkSpeedToUse != CBIOS_DP_LINK_SPEED_5400Mbps) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: why current link speed:%d is not sync with REG:0x%x?\n", + FUNCTION_NAME, pMainLinkParams->LinkSpeedToUse, DP_REG_CTRL[DPModuleIndex])); + pMainLinkParams->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_5400Mbps; + } + } + #endif + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_READ; + AUX.Offset = 0x100; + AUX.Length = 1; + if(cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + DPCD_0100.Value = (CBIOS_U8)AUX.Data[0]; + + switch(DPCD_0100.LINK_BW_SET) + { + case CBIOS_DPCD_LINK_RATE_1620Mbps: + if (pMainLinkParams->LinkSpeedToUse != CBIOS_DP_LINK_SPEED_1620Mbps) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: why current link speed:%d is not sync with DPCD100?\n", + FUNCTION_NAME, pMainLinkParams->LinkSpeedToUse)); + pMainLinkParams->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_1620Mbps; + } + break; + case CBIOS_DPCD_LINK_RATE_2700Mbps: + if (pMainLinkParams->LinkSpeedToUse != CBIOS_DP_LINK_SPEED_2700Mbps) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: why current link speed:%d is not sync with DPCD100?\n", + FUNCTION_NAME, pMainLinkParams->LinkSpeedToUse)); + pMainLinkParams->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_2700Mbps; + } + break; + case CBIOS_DPCD_LINK_RATE_5400Mbps: + if (pMainLinkParams->LinkSpeedToUse != CBIOS_DP_LINK_SPEED_5400Mbps) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: why current link speed:%d is not sync with DPCD100?\n", + FUNCTION_NAME, pMainLinkParams->LinkSpeedToUse)); + pMainLinkParams->LinkSpeedToUse = CBIOS_DP_LINK_SPEED_5400Mbps; + } + break; + } + } + + // TU: Transfer Unit(used to carry main video stream data during its horizontal active period). + // TU has 32 to 64 symbols per lane. Currently we default to 48. + // MM8244, H width and TU size/ratio, MM821C[30]:Bit-12 of HDisp + // TU ratio = (Dclk * bpp) * 32768 / (Ls_clk * Lane# * 8) + // bpp: bit per pixel + // bpc: bit per channel + if (pMainLinkParams->ColorFormat == 1) // YUV422 format + { + ulTemp1 = pTiming->PixelClock*2*pMainLinkParams->bpc; + } + else + { + ulTemp1 = pTiming->PixelClock*3*pMainLinkParams->bpc; + } + + ulTemp2 = pMainLinkParams->LaneNumberToUse * pMainLinkParams->LinkSpeedToUse * 8; + + if (ulTemp2 == 0) // Prevent being divided by zero + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: fata error -- LaneNumber or LinkSpeed is ZERO!!!\n", FUNCTION_NAME)); + bStatus = CBIOS_FALSE; + goto Exit; + } + ulTURatio = cb_do_div((ulTemp1<<15), ulTemp2); + + DPHWidthTURegValue.Value = 0; + if (pMainLinkParams->LaneNumberToUse == 0) // Prevent being divided by zero + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: fata error -- LaneNumber is ZERO!!!\n", FUNCTION_NAME)); + bStatus = CBIOS_FALSE; + goto Exit; + } + DPHWidthTURegValue.Horiz_Width = pTiming->HorDisEnd / pMainLinkParams->LaneNumberToUse - 1; + DPHWidthTURegValue.TU_Size = (pMainLinkParams->TUSize - 1); + DPHWidthTURegValue.TU_Ratio = (CBIOS_U32)ulTURatio; + DPHWidthTURegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_HWIDTH_TU[DPModuleIndex], DPHWidthTURegValue.Value, DPHWidthTURegMask.Value); + + DPExtPacketRegValue.Value = 0; + DPExtPacketRegValue.Horizontal_Width_bit12to11 = ((pTiming->HorDisEnd / pMainLinkParams->LaneNumberToUse - 1) >> 11); + DPExtPacketRegMask.Value = 0xFFFFFFFF; + DPExtPacketRegMask.Horizontal_Width_bit12to11 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EXT_PACKET[DPModuleIndex], DPExtPacketRegValue.Value, DPExtPacketRegMask.Value); + + // MM8248, H line duration: H * Ls_clk / Dclk + // ulTemp2 = pDevCommon->DeviceParas.DPDevice.LinkSpeed / pTiming->DCLK; + // ulTemp3 = ((ulTemp1 * ulTemp2) & 0x00000FFF ) << 15; + ulTemp1 = pTiming->HorTotal - pTiming->HorDisEnd; + + if (pTiming->PixelClock == 0) // Prevent being divided by zero + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: fata error -- PixelClock is ZERO!!!\n", FUNCTION_NAME)); + bStatus = CBIOS_FALSE; + goto Exit; + } + + /*previous setting -35, will lead to audio abnormal with some specific timing(ex. 800x600@75), change it to 64*/ + ulTemp3 = (cb_do_div(ulTemp1 * pMainLinkParams->LinkSpeedToUse, pTiming->PixelClock) & 0x00000FFF) - 64; + + ulTemp2 = pTiming->HorTotal; + ulTemp1 = cb_do_div(ulTemp2 * pMainLinkParams->LinkSpeedToUse, pTiming->PixelClock) - 64; + + DPHLineDurRegValue.Value = 0; + DPHLineDurRegValue.Horiz_Line_Duration = (CBIOS_U32)ulTemp1; + DPHLineDurRegValue.HBLANK_Duration = (CBIOS_U32)ulTemp3; + DPHLineDurRegMask.Value = 0xFFFFFFFF; + DPHLineDurRegMask.Horiz_Line_Duration = 0; + DPHLineDurRegMask.HBLANK_Duration = 0; + cbMMIOWriteReg32(pcbe, DP_REG_HLINE_DUR[DPModuleIndex], DPHLineDurRegValue.Value, DPHLineDurRegMask.Value); + + DPEnableRegValue.Value = 0; + DPEnableRegValue.Generate_MVID = pMainLinkParams->AsyncMode ? 1 : 0; + DPEnableRegMask.Value = 0xFFFFFFFF; + DPEnableRegMask.Generate_MVID = 0; + cbMMIOWriteReg32(pcbe, DP_REG_ENABLE[DPModuleIndex], DPEnableRegValue.Value, DPEnableRegMask.Value); + + // M/N = Dclk / Ls_clk, but N must be 32768 to work with Parade DP + // So, N = 32768, M = Dclk * 32768 / Ls_clk + // Mvid and Nvid are not needed if in asynchronous mode, set it anyway + if (pMainLinkParams->LinkSpeedToUse == 0) // Prevent being divided by zero + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: fata error -- LinkSpeed is ZERO!!!\n", FUNCTION_NAME)); + bStatus = CBIOS_FALSE; + goto Exit; + } + ulTemp1 = cb_do_div(32768 * ((CBIOS_U64)(pTiming->PixelClock)), pMainLinkParams->LinkSpeedToUse); // N = 32768 + + DPMisc0RegValue.Value = 0; + DPMisc0RegValue.MVID = (CBIOS_U32)ulTemp1; + + if (pMainLinkParams->bpc == 6) + DPMisc0RegValue.MISC0_Bit_depth = 0; + else if (pMainLinkParams->bpc == 8) + DPMisc0RegValue.MISC0_Bit_depth = 1; + else if (pMainLinkParams->bpc == 10) + DPMisc0RegValue.MISC0_Bit_depth = 2; + else if (pMainLinkParams->bpc == 12) + DPMisc0RegValue.MISC0_Bit_depth = 3; + else if (pMainLinkParams->bpc == 16) + DPMisc0RegValue.MISC0_Bit_depth = 4; + + DPMisc0RegValue.MISC0_Sync_Clk = pMainLinkParams->AsyncMode ? 0 : 1; + DPMisc0RegValue.MISC0_Component_Format = pMainLinkParams->ColorFormat; + + // bit[27] "VESA/CEA range" + if (pMainLinkParams->DynamicRange == 1) + { + DPMisc0RegValue.MISC0_Dynamic_Range = 1; + } + + // bit[28] "YCbCr colorimetry" ITU-R BT601-5/ITU-R BT709-5 + if (pMainLinkParams->YCbCrCoefficients == 1) + { + DPMisc0RegValue.MISC0_YCbCr_Colorimetry = 1; + } + + DPMisc0RegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_MISC0[DPModuleIndex], DPMisc0RegValue.Value, DPMisc0RegMask.Value); + + // MM8250, DP HTotal attribute data + DPHVTotalRegValue.H_Total = pTiming->HorTotal; + DPHVTotalRegValue.V_Total = pTiming->VerTotal; + DPHVTotalRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_HV_TOTAL[DPModuleIndex], DPHVTotalRegValue.Value, DPHVTotalRegMask.Value); + + // MM8254, DP H/V start attribute data (from leading edge of Sync) + DPHVStartRegValue.H_Start = (pTiming->HorTotal - pTiming->HorSyncStart); + DPHVStartRegValue.V_Start = (pTiming->VerTotal - pTiming->VerSyncStart); + DPHVStartRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_HV_START[DPModuleIndex], DPHVStartRegValue.Value, DPHVStartRegMask.Value); + + // MM8258, DP H/V Sync Polarity, Width attribute data + DPHVSyncRegValue.HSYNC_Width = (pTiming->HorSyncEnd - pTiming->HorSyncStart); + DPHVSyncRegValue.VSYNC_Width = (pTiming->VerSyncEnd - pTiming->VerSyncStart); + + RegSR3AValue.Value = 0; + RegSR3AValue.DP_PHY_Test_Mode_Select = 0; + RegSR3AValue.FP_DP_HYSNC_POL = 0; + RegSR3AValue.FP_DP_VYSNC_POL = 0; + RegSR3AMask.Value = 0x38; + cbMMIOWriteReg(pcbe, SR_3A, RegSR3AValue.Value, RegSR3AMask.Value); + + DPHVSyncRegValue.HSYNC_Polarity = 0; + DPHVSyncRegValue.VSYNC_Polarity = 0; + + if (pTiming->HVPolarity & HorNEGATIVE) + { + RegSR3AValue.Value = 0; + RegSR3AValue.DP_PHY_Test_Mode_Select = 0; + RegSR3AValue.FP_DP_HYSNC_POL = 0; + RegSR3AValue.FP_DP_VYSNC_POL = 1; + RegSR3AMask.Value = 0x38; + cbMMIOWriteReg(pcbe, SR_3A, RegSR3AValue.Value, RegSR3AMask.Value); + DPHVSyncRegValue.HSYNC_Polarity = 1; + } + if (pTiming->HVPolarity & VerNEGATIVE) + { + RegSR3AValue.Value = 0; + RegSR3AValue.DP_PHY_Test_Mode_Select = 0; + RegSR3AValue.FP_DP_HYSNC_POL = 1; + RegSR3AValue.FP_DP_VYSNC_POL = 0; + RegSR3AMask.Value = 0x38; + cbMMIOWriteReg(pcbe, SR_3A, RegSR3AValue.Value, RegSR3AMask.Value); + DPHVSyncRegValue.VSYNC_Polarity = 1; + } + DPHVSyncRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_HV_SYNC[DPModuleIndex], DPHVSyncRegValue.Value, DPHVSyncRegMask.Value); + + // MM825C, DP H/V display attribute data + DPHVActiveRegValue.Acitve_Width = pTiming->HorDisEnd; + DPHVActiveRegValue.Active_Height = pTiming->VerDisEnd; + DPHVActiveRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_HV_ACTIVE[DPModuleIndex], DPHVActiveRegValue.Value, DPHVActiveRegMask.Value); + + // MM8210, DP Nvid attribute data, N=32768 + DPMisc1RegValue.Value = 0; + DPMisc1RegValue.NVID = 0x008000; + DPMisc1RegValue.MISC1_Even = 0; + DPMisc1RegValue.MISC1_Stereo_Video = 0; + DPMisc1RegValue.MISC1_Reserved = 0; + DPMisc1RegMask.Value = 0xFFFFFFFF; + DPMisc1RegMask.NVID = 0; + DPMisc1RegMask.MISC1_Even = 0; + DPMisc1RegMask.MISC1_Stereo_Video = 0; + DPMisc1RegMask.MISC1_Reserved = 0; + cbMMIOWriteReg32(pcbe, DP_REG_MISC1[DPModuleIndex], DPMisc1RegValue.Value, DPMisc1RegMask.Value); + + // MM8218, DP input and general control + DPGenCtrlRegValue.Value = 0; + DPGenCtrlRegValue.DELAY = 0x20; + DPGenCtrlRegMask.Value = 0xFFFFFFFF; + DPGenCtrlRegMask.DELAY = 0; + cbMMIOWriteReg32(pcbe, DP_REG_GEN_CTRL[DPModuleIndex], DPGenCtrlRegValue.Value, DPGenCtrlRegMask.Value); + + bStatus = CBIOS_TRUE; + + cbTraceExit(DP); +Exit: + return bStatus; +} + +CBIOS_VOID cbDIU_DP_SendInfoFrame(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U32 Length) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 StartAddress = 0; + REG_MM8240 DPEnableInfoFrameRegValue, DPEnableInfoFrameRegMask; + REG_MM8338 DPMuteRegValue, DPMuteRegMask; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + // InfoFrame from FIFO + DPMuteRegValue.Value = 0; + DPMuteRegValue.Audio_InfoFrame = 0; + DPMuteRegMask.Value = 0xFFFFFFFF; + DPMuteRegMask.Audio_InfoFrame = 0; + cbMMIOWriteReg32(pcbe, DP_REG_MUTE[DPModuleIndex], DPMuteRegValue.Value, DPMuteRegMask.Value); + + DPEnableInfoFrameRegValue.Value = 0; + DPEnableInfoFrameRegValue.InfoFrame_FIFO_Select = 0; // select FIFO 1 + DPEnableInfoFrameRegValue.InfoFrame_FIFO_1_Ready = 1; + DPEnableInfoFrameRegValue.InfoFrame_FIFO_1_Start_Address = StartAddress; + DPEnableInfoFrameRegValue.InfoFrame_FIFO_1_Length = Length - 1; + DPEnableInfoFrameRegMask.Value = 0xFFFFFFFF; + DPEnableInfoFrameRegMask.InfoFrame_FIFO_Select = 0; + DPEnableInfoFrameRegMask.InfoFrame_FIFO_1_Ready = 0; + DPEnableInfoFrameRegMask.InfoFrame_FIFO_1_Start_Address = 0; + DPEnableInfoFrameRegMask.InfoFrame_FIFO_1_Length = 0; + cbMMIOWriteReg32(pcbe, DP_REG_ENABLE[DPModuleIndex], DPEnableInfoFrameRegValue.Value, DPEnableInfoFrameRegMask.Value); +} + +/***************************************************************************************/ +/******************************* Aux Channel Interfaces ******************************/ +CBIOS_VOID cbDIU_DP_ResetAUX(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8214 DPLinkRegValue, DPLinkRegMask; + REG_MM8338 DPMuteRegValue, DPMuteRegMask; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + DPMuteRegValue.Value = 0; + DPMuteRegMask.Value = 0xFFFFFFFF; + DPMuteRegMask.AUX_SW_Reset = 0; + + DPMuteRegValue.AUX_SW_Reset = 1; + cbMMIOWriteReg32(pcbe, DP_REG_MUTE[DPModuleIndex], DPMuteRegValue.Value, DPMuteRegMask.Value); + + cb_DelayMicroSeconds(1000); // wait AUX Reset to be done + + DPMuteRegValue.AUX_SW_Reset = 0; + cbMMIOWriteReg32(pcbe, DP_REG_MUTE[DPModuleIndex], DPMuteRegValue.Value, DPMuteRegMask.Value); + + DPLinkRegValue.Value = 0; + DPLinkRegMask.Value = 0xFFFFFFFF; + DPLinkRegMask.SW_Hpd_assert = 0; + + DPLinkRegValue.SW_Hpd_assert = 1; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + + DPLinkRegValue.SW_Hpd_assert = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + + cb_DelayMicroSeconds(200); +} + +static CBIOS_VOID cbDIU_DP_ClearAuxReadBuffer(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + REG_MM8320 DPAuxRead0RegValue; + REG_MM8324 DPAuxRead1RegValue; + REG_MM8328 DPAuxRead2RegValue; + REG_MM832C DPAuxRead3RegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + DPAuxRead0RegValue.Value = 0; + DPAuxRead0RegValue.AUX_Read_Bytes_3_0 = 0; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_READ0[DPModuleIndex], DPAuxRead0RegValue.Value); + DPAuxRead1RegValue.Value = 0; + DPAuxRead1RegValue.AUX_Read_Bytes_7_4 = 0; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_READ1[DPModuleIndex], DPAuxRead1RegValue.Value); + DPAuxRead2RegValue.Value = 0; + DPAuxRead2RegValue.AUX_Read_Bytes_11_8 = 0; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_READ2[DPModuleIndex], DPAuxRead2RegValue.Value); + DPAuxRead3RegValue.Value = 0; + DPAuxRead3RegValue.AUX_Read_Bytes_15_12 = 0; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_READ3[DPModuleIndex], DPAuxRead3RegValue.Value); +} + +static CBIOS_VOID cbDIU_DP_ClearAuxWriteBuffer(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + REG_MM8310 DPAuxWrite0RegValue; + REG_MM8314 DPAuxWrite1RegValue; + REG_MM8318 DPAuxWrite2RegValue; + REG_MM831C DPAuxWrite3RegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + DPAuxWrite0RegValue.Value = 0; + DPAuxWrite0RegValue.AUX_Write_Bytes_3_0 = 0; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE0[DPModuleIndex], DPAuxWrite0RegValue.Value); + DPAuxWrite1RegValue.Value = 0; + DPAuxWrite1RegValue.AUX_Write_Bytes_7_4 = 0; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE1[DPModuleIndex], DPAuxWrite1RegValue.Value); + DPAuxWrite2RegValue.Value = 0; + DPAuxWrite2RegValue.AUX_Write_Bytes_11_8 = 0; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE2[DPModuleIndex], DPAuxWrite2RegValue.Value); + DPAuxWrite3RegValue.Value = 0; + DPAuxWrite3RegValue.AUX_Write_Bytes_15_12 = 0; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE3[DPModuleIndex], DPAuxWrite3RegValue.Value); +} + +static CBIOS_VOID cbDIU_DP_SWAuxRequest(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + REG_MM8330 DPAuxTimerRegValue, DPAuxTimerRegMask; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + DPAuxTimerRegValue.Value = 0; + DPAuxTimerRegValue.SW_AUX = 1; + DPAuxTimerRegValue.AUX_Request = 1; + DPAuxTimerRegValue.AUX_DRDY = 0; + DPAuxTimerRegValue.AUX_Timeout = 0; + DPAuxTimerRegMask.Value = 0xFFFFFFFF; + DPAuxTimerRegMask.SW_AUX = 0; + DPAuxTimerRegMask.AUX_Request = 0; + DPAuxTimerRegMask.AUX_DRDY = 0; + DPAuxTimerRegMask.AUX_Timeout = 0; + cbMMIOWriteReg32(pcbe, DP_REG_AUX_TIMER[DPModuleIndex], DPAuxTimerRegValue.Value, DPAuxTimerRegMask.Value); +} + +CBIOS_VOID cbDIU_DP_HWUseAuxChannel(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8330 DPAuxTimerRegValue, DPAuxTimerRegMask; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + DPAuxTimerRegValue.Value = 0; + DPAuxTimerRegValue.SW_AUX = 0; + DPAuxTimerRegValue.AUX_Request = 0; + DPAuxTimerRegValue.AUX_DRDY = 0; + DPAuxTimerRegValue.AUX_Timeout = 0; + + DPAuxTimerRegMask.Value = 0xFFFFFFFF; + DPAuxTimerRegMask.SW_AUX = 0; + DPAuxTimerRegMask.AUX_Request = 0; + DPAuxTimerRegMask.AUX_DRDY = 0; + DPAuxTimerRegMask.AUX_Timeout = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_AUX_TIMER[DPModuleIndex], DPAuxTimerRegValue.Value, DPAuxTimerRegMask.Value); +} + +// IsNative = 1: native aux read/write +// IsNative = 0: I2C over aux read/write +static CBIOS_BOOL cbDIU_DP_CheckAuxReplyStatus(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL IsNative) +{ + // 20090326_BC + // 4.2.1.2 will not send AUX STOP so we won't get AUX ready usually. + // But sometimes, after ~600us, HW would set AUX ready with timeout bit. + // For the EDID read intermittent error cited below we cannot rely on timeout bit checking. + // To workaround this problem, reduce counter from 13 to 11. + // So resend the request after 550us instead of 650us. + CBIOS_U32 i, j, counter; + CBIOS_BOOL bStatus = CBIOS_FALSE; + REG_MM8330 DPAuxTimerRegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + //increase the waiting time in case EDID can't be read correctly + //now SW will resend the request after 10ms + counter = IsNative ? 10 : 100; + + for(i = 0; i < 10; i++) + { + for (j = 1; j < counter; j++) + { + cb_DelayMicroSeconds(100); + // Need to check timeout (bit 3) as well + // But when reading EDID sometime, timeout got set but the correct data did arrive, + // making us throwing away good data and end up with bad checksum. + // Going back to old method (no timeout check). + DPAuxTimerRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_TIMER[DPModuleIndex]) & 0x3C000007; + + // [29:26]: Reply AUX command status + // [3:0]: AUX command status + if (DPAuxTimerRegValue.SW_AUX && DPAuxTimerRegValue.AUX_DRDY) + { + if ((DPAuxTimerRegValue.AUX_Command == CBIOS_AUX_REPLY_ACK) || + (DPAuxTimerRegValue.AUX_Command == CBIOS_AUX_REPLY_NACK)) + { + if (DPAuxTimerRegValue.AUX_Command == CBIOS_AUX_REPLY_NACK) + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Sink send NACK reply, just abort current aux transaction\n", FUNCTION_NAME)); + } + + bStatus = CBIOS_TRUE; + break; + } + } + } + + if (bStatus) + { + break; + } + else + { + +#if DP_RESET_AUX_WHEN_DEFER + cbDIU_DP_ResetAUX(pcbe, DPModuleIndex); +#endif + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Failed! i=%d, j=%d, mm%x=0x%08x\n", FUNCTION_NAME, + i, j, DP_REG_AUX_TIMER[DPModuleIndex], DPAuxTimerRegValue.Value)); + + // I2C over AUX channel is much slower than native AUX channel transaction + // I2C R/W over AUX channel defer case + if (DPAuxTimerRegValue.AUX_Command == CBIOS_AUX_REPLY_DEFER) + { + cbDelayMilliSeconds(1); + } + + // Can satisfy 4.2.1.1 &4.2.1.2 compliance test cause 600 us has passed + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + } + } + + return bStatus; +} + +CBIOS_U32 cbDIU_DP_AuxReadEDID(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_UCHAR pEDIDBuffer, CBIOS_U32 ulBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bStatus = CBIOS_FALSE; + CBIOS_U32 i, j; + CBIOS_U32 dTemp, ulEdidLength = 0; + CBIOS_UCHAR ucChecksum; + REG_MM8334 DPAuxCmdRegValue; + AUX_CONTROL AUX; + DPCD_REG_00260 DPCD_00260; + DPCD_REG_00261 DPCD_00261; + CBIOS_U32 EdidBlockNum = 0; + const CBIOS_U32 EdidBlockBufferSize = 256; + PCBIOS_UCHAR pEdidTempBuffer = pEDIDBuffer; + + cbTraceEnter(DP); + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return 0; + } + + // AUX write, 0 byte, address 050h (A0h >> 1), address transaction only + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto exitAuxReadEDID; + + // AUX write, 1 byte, address 050h (A0h >> 1), set EDID offset 0 + cbDIU_DP_ClearAuxWriteBuffer(pcbe, DPModuleIndex); + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 1; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto exitAuxReadEDID; + + // Parade DP RX can't trasnmit more than 7 bytes at a time... Be reminded! + // AUX read, 0 byte, I2C read repeated start + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto exitAuxReadEDID; + + // AUX I2C read, 2 bytes, address 050h (A0h >> 1) + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 2; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + + ucChecksum = 0; + for (i = 0; i < EdidBlockBufferSize / 128; i++) + { + for (j = 0; j < 128 / 2; j ++) + { + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: Read EDID 0x%x failed!\n", FUNCTION_NAME, 2*j)); + } + dTemp = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ0[DPModuleIndex]); + + ucChecksum += pEDIDBuffer[i * 128 + j * 2 + 0] = (CBIOS_U8) (dTemp >> 0); + ucChecksum += pEDIDBuffer[i * 128 + j * 2 + 1] = (CBIOS_U8) (dTemp >> 8); + } + + ulEdidLength += 128; + + // Must check checksum before check extension flag in case EDID is corrupted + if (ucChecksum == 0) + { + if (ulEdidLength == (pEDIDBuffer[0x7E] + 1) * 128) // Extension flag + { + bStatus = CBIOS_TRUE; + break; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: checksum == 0x%02x, wrong!!\n", FUNCTION_NAME, ucChecksum)); + bStatus = CBIOS_FALSE; + if (ulEdidLength == (pEDIDBuffer[0x7E] + 1) * 128) // Extension flag + { + break; + } + } + } + + // AUX read, 0 byte, without MOT => I2C stop + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Send I2C STOP failed!\n", FUNCTION_NAME)); + bStatus = CBIOS_TRUE; + goto exitAuxReadEDID; + } + + // if EdidBlockNum > 2, read the rest edid data. + EdidBlockNum = pEDIDBuffer[0x7E] + 1; + pEdidTempBuffer = pEDIDBuffer + EdidBlockBufferSize; + if (EdidBlockNum > 2) + { + // AUX write, 0 byte, address 030h (60h >> 1), address transaction only + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00030; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto exitAuxReadEDID; + + // AUX write, 1 byte, address 030h (60h >> 1), set EDID segment num 1 + cbDIU_DP_ClearAuxWriteBuffer(pcbe, DPModuleIndex); + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 1; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00030; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE0[DPModuleIndex], 1); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto exitAuxReadEDID; + + // AUX write, 0 byte, address 050h (A0h >> 1), address transaction only + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto exitAuxReadEDID; + + // AUX write, 1 byte, address 050h (A0h >> 1), set EDID offset 0 + cbDIU_DP_ClearAuxWriteBuffer(pcbe, DPModuleIndex); + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 1; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto exitAuxReadEDID; + + // Parade DP RX can't trasnmit more than 7 bytes at a time... Be reminded! + // AUX read, 0 byte, I2C read repeated start + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto exitAuxReadEDID; + + // AUX I2C read, 2 bytes, address 050h (A0h >> 1) + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 2; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + + ucChecksum = 0; + for (i = 0; i < EdidBlockBufferSize / 128; i++) + { + for (j = 0; j < 128 / 2; j ++) + { + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + { + cbDebugPrint((MAKE_LEVEL(DP, WARNING), "%s: Read EDID 0x%x failed!\n", FUNCTION_NAME, 2*j)); + } + dTemp = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ0[DPModuleIndex]); + + ucChecksum += pEdidTempBuffer[i * 128 + j * 2 + 0] = (CBIOS_U8) (dTemp >> 0); + ucChecksum += pEdidTempBuffer[i * 128 + j * 2 + 1] = (CBIOS_U8) (dTemp >> 8); + } + + ulEdidLength += 128; + + // Must check checksum before check extension flag in case EDID is corrupted + if (ucChecksum == 0) + { + if (ulEdidLength == (pEDIDBuffer[0x7E] + 1) * 128) // Extension flag + { + bStatus = CBIOS_TRUE; + break; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: checksum == 0x%02x, wrong!!\n", FUNCTION_NAME, ucChecksum)); + bStatus = CBIOS_FALSE; + if (ulEdidLength == (pEDIDBuffer[0x7E] + 1) * 128) // Extension flag + { + break; + } + } + } + + // AUX read, 0 byte, without MOT => I2C stop + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Send I2C STOP failed!\n", FUNCTION_NAME)); + bStatus = CBIOS_TRUE; + goto exitAuxReadEDID; + } + } + + // For CTS EDID read test item: 4.2.2.3 + // Should always check the checksum of last edid block according to linklayer compliance test spec. + DPCD_00260.Value = 0; + DPCD_00260.TEST_EDID_CHECKSUM_WRITE = 1; + DPCD_00261.Value = 0; + DPCD_00261.TEST_EDID_CHECKSUM = pEDIDBuffer[ulEdidLength - 1]; + + AUX.Function = CBIOS_AUX_REQUEST_NATIVE_WRITE; + AUX.Offset = 0x260; + AUX.Length = 0x2; + AUX.Data[0] = (DPCD_00261.Value << 8) | DPCD_00260.Value; + if(!cbDIU_DP_AuxChRW(pcbe, DPModuleIndex, &AUX)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Write EDID checksum to TEST_RESPONSE and TEST_EDID_CHECKSUM fields of DPCD failed!\n", FUNCTION_NAME)); + } + +exitAuxReadEDID: + cbTraceExit(DP); + return bStatus ? ulEdidLength : 0; +} + +CBIOS_BOOL cbDIU_DP_AuxReadEDIDOffset(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_UCHAR pEDIDBuffer, CBIOS_U32 ulBufferSize, CBIOS_U32 ulReadEdidOffset) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bStatus = CBIOS_FALSE; + CBIOS_U32 i = 0; + REG_MM8334 DPAuxCmdRegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + //AUX write, 0 byte, address 050h (A0h >> 1), address transaction only + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT;; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + { + bStatus = CBIOS_FALSE; + goto ExitFunc; + } + + cbDIU_DP_ClearAuxWriteBuffer(pcbe, DPModuleIndex); + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 1; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE0[DPModuleIndex], ulReadEdidOffset); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + { + bStatus = CBIOS_FALSE; + goto ExitFunc; + } + + // Parade DP RX can't trasnmit more than 7 bytes at a time... Be reminded! + // AUX read, 0 byte, I2C read repeated start + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + { + bStatus = CBIOS_FALSE; + goto ExitFunc; + } + + // AUX I2C read, 1 bytes, address 050h (A0h >> 1) + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 1; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + + bStatus = CBIOS_TRUE; + for (i = 0; i < ulBufferSize; i++) + { + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Read EDID %d failed!\n", FUNCTION_NAME, i + ulReadEdidOffset)); + bStatus = CBIOS_FALSE; + // AUX read, 0 byte, without MOT => I2C stop + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + goto ExitFunc; + + } + + pEDIDBuffer[i] = (CBIOS_U8)cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ0[DPModuleIndex]); + } + + // AUX read, 0 byte, without MOT => I2C stop + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = 0x00050; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Send I2C STOP failed!\n", FUNCTION_NAME)); + bStatus = CBIOS_TRUE; + goto ExitFunc; + } + +ExitFunc: + + return bStatus; +} + +static CBIOS_BOOL cbDIU_DP_WaitAuxReady(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + CBIOS_U32 i = 0; + REG_MM8330 DPAuxTimerRegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + DPAuxTimerRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_TIMER[DPModuleIndex]); + + if ((DPAuxTimerRegValue.HPD_Status == 0) || (DPAuxTimerRegValue.HPD_Status == 2)) // unplug + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Aux can't work when DP is unplugged, mm%x==%08x!!!\n", + FUNCTION_NAME, DP_REG_AUX_TIMER[DPModuleIndex], DPAuxTimerRegValue.Value)); + + return CBIOS_FALSE; + } + + while ((DPAuxTimerRegValue.AUX_Request) || // Data not sent yet + (((DPAuxTimerRegValue.Value & 0xE) != 0x0) && (!(DPAuxTimerRegValue.Value& 0xC)))) // If not the first aux cmd, data should be ready or time out + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Aux channel is busy, mm%x==%08x, wait 100us!\n", + FUNCTION_NAME, DP_REG_AUX_TIMER[DPModuleIndex], DPAuxTimerRegValue.Value)); + i++; + if (i > 15) // 1.5ms time out + { + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: Aux channel is busy for 15ms, time out!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + cb_DelayMicroSeconds(100); + DPAuxTimerRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_TIMER[DPModuleIndex]); + } + + return CBIOS_TRUE; +} + +static CBIOS_BOOL cbDIU_DP_ReadDPCD(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 addr, CBIOS_U32 numData, CBIOS_MODULE_INDEX DPModuleIndex) +{ + CBIOS_BOOL bStatus = CBIOS_FALSE; + REG_MM8320 DPAuxRead0RegValue; + REG_MM8324 DPAuxRead1RegValue; + REG_MM8328 DPAuxRead2RegValue; + REG_MM832C DPAuxRead3RegValue; + REG_MM8334 DPAuxCmdRegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + if(!cbDIU_DP_WaitAuxReady(pcbe, DPModuleIndex)) + { + return CBIOS_FALSE; + } + + cbDIU_DP_ClearAuxReadBuffer(pcbe, DPModuleIndex); + + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_Addr = addr; + DPAuxCmdRegValue.SW_AUX_Length = numData; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_NATIVE_READ; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + bStatus = cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_TRUE); + + DPAuxRead0RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ0[DPModuleIndex]); + DPAuxRead1RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ1[DPModuleIndex]); + DPAuxRead2RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ2[DPModuleIndex]); + DPAuxRead3RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ3[DPModuleIndex]); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: addr(0x%x), numData(%d), data-3_0, data-7_4, data-11_8, data-15_12 = %08x, %08x, %08x, %08x\n", + FUNCTION_NAME, addr, numData, DPAuxRead0RegValue.Value, DPAuxRead1RegValue.Value, DPAuxRead2RegValue.Value, DPAuxRead3RegValue.Value)); + + return bStatus; +} + +static CBIOS_BOOL cbDIU_DP_WriteDPCD(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 addr, CBIOS_U32 numData, CBIOS_MODULE_INDEX DPModuleIndex) +{ + CBIOS_BOOL bStatus = CBIOS_FALSE; + REG_MM8310 DPAuxWrite0RegValue; + REG_MM8314 DPAuxWrite1RegValue; + REG_MM8334 DPAuxCmdRegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + if(!cbDIU_DP_WaitAuxReady(pcbe, DPModuleIndex)) + { + return CBIOS_FALSE; + } + + DPAuxWrite0RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE0[DPModuleIndex]); + DPAuxWrite1RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE1[DPModuleIndex]); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: addr, numData, data3_0, data7_4 = %04x, %04x, %08x, %08x!!!\n", + FUNCTION_NAME, addr, numData, DPAuxWrite0RegValue.Value, DPAuxWrite1RegValue.Value)); + + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_Addr = addr; + DPAuxCmdRegValue.SW_AUX_Length = numData; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_NATIVE_WRITE; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + bStatus = cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_TRUE); + + return bStatus; +} + +static CBIOS_VOID cbDIU_DP_SetAuxWriteBuffer(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex, PAUX_CONTROL pAUX) +{ + CBIOS_U32 i = 0; + REG_MM8310 DPAuxWrite0RegValue; + REG_MM8314 DPAuxWrite1RegValue; + REG_MM8318 DPAuxWrite2RegValue; + REG_MM831C DPAuxWrite3RegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + // first clear write buffer + cbDIU_DP_ClearAuxWriteBuffer(pcbe, DPModuleIndex); + + // Clear Data[i] over pAUX->Lenth + for(i = pAUX->Length; i < 0x10; i++) + *((PCBIOS_U8)(pAUX->Data) + i) = 0x00; + + DPAuxWrite0RegValue.Value = pAUX->Data[0]; + DPAuxWrite1RegValue.Value = pAUX->Data[1]; + DPAuxWrite2RegValue.Value = pAUX->Data[2]; + DPAuxWrite3RegValue.Value = pAUX->Data[3]; + + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE0[DPModuleIndex], DPAuxWrite0RegValue.Value); + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE1[DPModuleIndex], DPAuxWrite1RegValue.Value); + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE2[DPModuleIndex], DPAuxWrite2RegValue.Value); + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE3[DPModuleIndex], DPAuxWrite3RegValue.Value); +} + +static CBIOS_VOID cbDIU_DP_GetAuxReadBuffer(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex, PAUX_CONTROL pAUX) +{ + CBIOS_U32 i = 0; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + pAUX->Data[0] = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ0[DPModuleIndex]); + pAUX->Data[1] = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ1[DPModuleIndex]); + pAUX->Data[2] = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ2[DPModuleIndex]); + pAUX->Data[3] = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ3[DPModuleIndex]); + + // Clear Data[i] over pAUX->Lenth + for(i = pAUX->Length; i < 0x10; i++) + { + *((PCBIOS_U8)(pAUX->Data) + i) = 0x00; + } +} + +static CBIOS_BOOL cbDIU_DP_AuxReplyStatus(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + CBIOS_BOOL bStatus = CBIOS_FALSE; + REG_MM8330 DPAuxTimerRegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + DPAuxTimerRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_TIMER[DPModuleIndex]); + + if(DPAuxTimerRegValue.AUX_DRDY) + bStatus = CBIOS_TRUE; + + return bStatus; +} + +CBIOS_BOOL cbDIU_DP_AuxChRW(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PAUX_CONTROL pAUX) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bStatus = CBIOS_FALSE; + CBIOS_U32 Retry = 0, MAX_RETRY_COUNT = 8; + REG_MM82CC DPEphyCtrlRegValue; + REG_MM8334 DPAuxCmdRegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + cbTraceEnter(DP); + + if(pAUX->Length > 0x10) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s : AUX Command Length > 0x10 error!!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + DPEphyCtrlRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_EPHY_CTRL[DPModuleIndex]); + if(!DPEphyCtrlRegValue.check_sync_cnt)//check 82cc Check_Sync_Cnt bit + { + DPEphyCtrlRegValue.check_sync_cnt = 1;//HW don't check sync counter for aux receiver + cb_WriteU32(pcbe->pAdapterContext, DP_REG_EPHY_CTRL[DPModuleIndex], DPEphyCtrlRegValue.Value); + } + + cbDIU_DP_ResetAUX(pcbe, (CBIOS_U8)DPModuleIndex); + + // AUX CH as I2C transaction + if(pAUX->Function == CBIOS_AUX_REQUEST_I2C_READ || pAUX->Function == CBIOS_AUX_REQUEST_I2C_WRITE) + { + while(bStatus == CBIOS_FALSE && Retry <= MAX_RETRY_COUNT) + { + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = (pAUX->I2cPort >> 1) & 0xFF; // I2C slave address + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); // write command to command buffer + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE0[DPModuleIndex], pAUX->Offset); + + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + bStatus = cbDIU_DP_AuxReplyStatus(pcbe, DPModuleIndex); + + // write I2C offset + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; // I2C R/W command; + DPAuxCmdRegValue.SW_AUX_Length = 0x1; // I2C offset length + DPAuxCmdRegValue.SW_AUX_Addr = (pAUX->I2cPort >> 1) & 0xFF; // I2C slave address + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); // write command to command buffer + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE0[DPModuleIndex], pAUX->Offset); + + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + bStatus = cbDIU_DP_AuxReplyStatus(pcbe, DPModuleIndex); + + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = pAUX->Function; + DPAuxCmdRegValue.SW_AUX_Length = pAUX->Function; + DPAuxCmdRegValue.SW_AUX_Addr = (pAUX->I2cPort >> 1) & 0xFF; // I2C slave address + + if(pAUX->Function == CBIOS_AUX_REQUEST_I2C_WRITE) + cbDIU_DP_SetAuxWriteBuffer(pcbe, DPModuleIndex, pAUX); + + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); // write command to command buffer + + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + bStatus = cbDIU_DP_AuxReplyStatus(pcbe, DPModuleIndex); + Retry++; + } + + if(pAUX->Function == CBIOS_AUX_REQUEST_I2C_READ) + cbDIU_DP_GetAuxReadBuffer(pcbe, DPModuleIndex, pAUX); + } + else // AUX CH + { + if (pAUX->Function == CBIOS_AUX_REQUEST_NATIVE_READ) + { + bStatus = cbDIU_DP_ReadDPCD(pcbe, pAUX->Offset, pAUX->Length, DPModuleIndex); + cbDIU_DP_GetAuxReadBuffer(pcbe, DPModuleIndex, pAUX); + } + else if (pAUX->Function == CBIOS_AUX_REQUEST_NATIVE_WRITE) + { + cbDIU_DP_SetAuxWriteBuffer(pcbe, DPModuleIndex, pAUX); + bStatus = cbDIU_DP_WriteDPCD(pcbe, pAUX->Offset, pAUX->Length, DPModuleIndex); + } + } + + // return AUX CH control to HW + cbDIU_DP_HWUseAuxChannel(pcbe, DPModuleIndex); + cbTraceExit(DP); + + return bStatus; +} + +CBIOS_STATUS cbDIU_DP_ReadData(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams, CBIOS_U32 Flags, CBIOS_BOOL IsDDC) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 i, ulLength = 0; + CBIOS_STATUS bStatus = CBIOS_ER_INTERNAL; + CBIOS_U8 SlaveAddress = pCBModuleI2CParams->SlaveAddress; + CBIOS_U32 BufferLen = pCBModuleI2CParams->BufferLen; + CBIOS_U8* buffer = pCBModuleI2CParams->Buffer; + CBIOS_U32 ulReadEdidOffset = pCBModuleI2CParams->OffSet; + REG_MM8334 DPAuxCmdRegValue; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + // DP MCCS, need to follow I2C-over-AUX syntax + cbDIU_DP_ClearAuxReadBuffer(pcbe, DPModuleIndex); + SlaveAddress >>= 1; + + if(!IsDDC) + { + //AUX write, 0 byte, address 050h (A0h >> 1), address transaction only + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = SlaveAddress; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto ExitAuxDdcRead; + // Transmit + cbDIU_DP_ClearAuxWriteBuffer(pcbe, DPModuleIndex); + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 1; + DPAuxCmdRegValue.SW_AUX_Addr = SlaveAddress; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE0[DPModuleIndex], ulReadEdidOffset); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto ExitAuxDdcRead; + } + + // 1. Start, 0 byte, adress transaction only + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = SlaveAddress; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto ExitAuxDdcRead; + + // 2. Receive every Byte + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 1; + DPAuxCmdRegValue.SW_AUX_Addr = SlaveAddress; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + + for (i = 0; i < BufferLen; i++) + { + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto ExitAuxDdcRead; + buffer[i] = (CBIOS_U8)cb_ReadU32(pcbe->pAdapterContext, DP_REG_AUX_READ0[DPModuleIndex]); + + if ((i == 1) && (Flags & 0x000000001)) + { + ulLength = buffer[i] & ~0x80; + if (ulLength > (BufferLen - 3)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: Buffer is too small!\n", FUNCTION_NAME)); + bStatus = CBIOS_ER_BUFFER_TOO_SMALL; + goto ExitAuxDdcRead; + } + BufferLen = ulLength + 3; + } + } + + // 3. Stop, 0 byte, adress transaction only + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_READ; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = SlaveAddress; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto ExitAuxDdcRead; + + bStatus = CBIOS_OK; + +ExitAuxDdcRead: + cbDIU_DP_HWUseAuxChannel(pcbe, DPModuleIndex); + return bStatus; +} + +CBIOS_BOOL cbDIU_DP_WriteData(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams, CBIOS_BOOL IsDDC) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 i; + CBIOS_STATUS bStatus = CBIOS_FALSE; + CBIOS_U8 SlaveAddress = pCBModuleI2CParams->SlaveAddress; + REG_MM8334 DPAuxCmdRegValue; + CBIOS_U32 ulReadEdidOffset = pCBModuleI2CParams->OffSet; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + // DP MCCS, need to follow I2C-over-AUX syntax + cbDIU_DP_ClearAuxWriteBuffer(pcbe, DPModuleIndex); + SlaveAddress >>= 1; + + // 1. Start, 0 byte, adress transaction only + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 0; + DPAuxCmdRegValue.SW_AUX_Addr = SlaveAddress; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto ExitAuxDdcWrite; + + // 2. Transmit every Byte + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE | CBIOS_AUX_REQUEST_I2C_MOT; + DPAuxCmdRegValue.SW_AUX_Length = 1; + DPAuxCmdRegValue.SW_AUX_Addr = SlaveAddress; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + if(!IsDDC) + { + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE0[DPModuleIndex], ulReadEdidOffset); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto ExitAuxDdcWrite; + } + for (i = 0; i < pCBModuleI2CParams->BufferLen; i++) + { + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_WRITE0[DPModuleIndex], pCBModuleI2CParams->Buffer[i]); + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto ExitAuxDdcWrite; + } + + // 3. Stop, 0 byte, adress transaction only + DPAuxCmdRegValue.Value = 0; + DPAuxCmdRegValue.SW_AUX_CMD = CBIOS_AUX_REQUEST_I2C_WRITE; + DPAuxCmdRegValue.SW_AUX_Length = 1; + DPAuxCmdRegValue.SW_AUX_Addr = SlaveAddress; + cb_WriteU32(pcbe->pAdapterContext, DP_REG_AUX_CMD[DPModuleIndex], DPAuxCmdRegValue.Value); + + cbDIU_DP_SWAuxRequest(pcbe, DPModuleIndex); + if (!cbDIU_DP_CheckAuxReplyStatus(pcbe, DPModuleIndex, CBIOS_FALSE)) + goto ExitAuxDdcWrite; + + bStatus = CBIOS_TRUE; + +ExitAuxDdcWrite: + cbDIU_DP_HWUseAuxChannel(pcbe, DPModuleIndex); + return bStatus; +} + +CBIOS_BOOL cbDIU_DP_IsOn(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8240 DPEnableRegValue; + CBIOS_BOOL status = CBIOS_FALSE; + + if (DPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return status; + } + + DPEnableRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_ENABLE[DPModuleIndex]); + + if(DPEnableRegValue.DP_Enable) + { + status = CBIOS_TRUE; + } + else + { + status = CBIOS_FALSE; + } + + return status; +} diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DP.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DP.h new file mode 100644 index 0000000000000..bc9908779dcbb --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DP.h @@ -0,0 +1,171 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DP hw block interface function prototype and parameter definition. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_DIU_DP_H_ +#define _CBIOS_DIU_DP_H_ + +#include "CBiosChipShare.h" +#include "CBiosDeviceShare.h" +#include "../HwUtil/CBiosI2C.h" + +#define CBIOS_DP_LINK_SPEED_1620Mbps 1620000 +#define CBIOS_DP_LINK_SPEED_2700Mbps 2700000 +#define CBIOS_DP_LINK_SPEED_5400Mbps 5400000 + +#define DP_MODU_NUM 4 + +extern CBIOS_U32 DP_REG_MISC1[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_LINK[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_GEN_CTRL[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_EXT_PACKET[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_ENABLE[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_HWIDTH_TU[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_HLINE_DUR[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_MISC0[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_HV_TOTAL[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_HV_START[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_HV_SYNC[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_HV_ACTIVE[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_EPHY_CTRL[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_AUX_WRITE0[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_AUX_WRITE1[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_AUX_WRITE2[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_AUX_WRITE3[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_AUX_READ0[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_AUX_READ1[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_AUX_READ2[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_AUX_READ3[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_AUX_TIMER[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_AUX_CMD[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_MUTE[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_MAUD[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_EPHY_MPLL[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_EPHY_TX[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_EPHY_MISC[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_SWING[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_EPHY_STATUS[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_LINK_CTRL[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_CTRL2[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_CTRL[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_EPHY_SETTING1[DP_MODU_NUM]; +extern CBIOS_U32 DP_REG_EPHY_SETTING2[DP_MODU_NUM]; + +typedef enum _CBIOS_DPCD_LINK_RATE +{ + CBIOS_DPCD_LINK_RATE_1620Mbps = 0x6, // 1.62Gbps per lane + CBIOS_DPCD_LINK_RATE_2700Mbps = 0xA, // 2.7 Gbps per lane + CBIOS_DPCD_LINK_RATE_5400Mbps = 0x14, // 5.4 Gbps per lane +}CBIOS_DPCD_LINK_RATE; + +typedef enum _CBIOS_AUX_REQUEST_CMD +{ + CBIOS_AUX_REQUEST_I2C_WRITE = 0, + CBIOS_AUX_REQUEST_I2C_READ = 1, + CBIOS_AUX_REQUEST_I2C_MOT = 4, + CBIOS_AUX_REQUEST_NATIVE_WRITE = 8, + CBIOS_AUX_REQUEST_NATIVE_READ = 9, +}CBIOS_AUX_REQUEST_CMD; + +typedef enum _CBIOS_AUX_REPLY_CMD +{ + CBIOS_AUX_REPLY_ACK = 0, + CBIOS_AUX_REPLY_NACK = 1, + CBIOS_AUX_REPLY_DEFER = 2, // Not ready for the write/read request. A uPacket TX may retry later. + CBIOS_AUX_REPLY_RESERVED = 3, +}CBIOS_AUX_REPLY_CMD; + +typedef struct _AUX_CONTROL +{ + CBIOS_U8 I2cPort; // + CBIOS_U32 Length; + CBIOS_U32 Offset; // register index + CBIOS_U32 Data[4]; // register data + CBIOS_U8 Function; // Special I2c control flag +}AUX_CONTROL, *PAUX_CONTROL; + +typedef enum _CBIOS_EDP_CP_METHOD +{ + CBIOS_EDP_CP_DISABLE = 0, + CBIOS_EDP_CP_ASSR, + CBIOS_EDP_CP_AF +}CBIOS_EDP_CP_METHOD; + +typedef struct _CBIOS_LINK_TRAINING_PARAMS +{ + // input params + CBIOS_U32 DpSinkVersion; + CBIOS_U32 MaxLaneCount; + CBIOS_U32 MaxLinkSpeed; + CBIOS_BOOL bEnhancedMode; + CBIOS_BOOL bEDP; + CBIOS_BOOL bEnableTPS3; + CBIOS_EDP_CP_METHOD CPMethod; + CBIOS_U32 TrainingAuxRdInterval; + + // output params + CBIOS_U32 CurrLaneCount; + CBIOS_U32 CurrLinkSpeed; + +}CBIOS_LINK_TRAINING_PARAMS, *PCBIOS_LINK_TRAINING_PARAMS; + +typedef struct _CBIOS_MAIN_LINK_PARAMS +{ + CBIOS_U32 LaneNumberToUse; // 1 ~ 4 lanes + CBIOS_U32 LinkSpeedToUse; // 1.62Gbps, 2.7Gbps or 5.4Gbps + CBIOS_U32 bpc; // bit per channel + CBIOS_U32 TUSize; // 32 ~ 64, default to 48 + CBIOS_BOOL AsyncMode; // 1 (yes), asynchronous mode + CBIOS_U32 ColorFormat; // 0: RGB, 1:YCbCr422, 2:YCbCr444 + CBIOS_U32 DynamicRange; // 0: VESA range, 1:CEA range + CBIOS_U32 YCbCrCoefficients;// 0: ITU601, 1: ITU709 + PCBIOS_TIMING_ATTRIB pTiming; +}CBIOS_MAIN_LINK_PARAMS, *PCBIOS_MAIN_LINK_PARAMS; + +CBIOS_VOID cbDIU_EDP_ControlVDDSignal(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL status); +CBIOS_VOID cbDIU_EDP_ControlVEESignal(PCBIOS_VOID pvcbe, PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL status); +CBIOS_BOOL cbDIU_EDP_WaitforSinkHPDSignal(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U16 timeout); + +CBIOS_VOID cbDIU_DP_DPModeEnable(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL bEnable); +CBIOS_VOID cbDIU_DP_SetHVSync(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U8 HVPolarity); +CBIOS_VOID cbDIU_DP_SetMaudNaud(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U32 LinkSpeed, CBIOS_U32 StreamFormat); +CBIOS_VOID cbDIU_DP_ResetLinkTraining(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex); +CBIOS_VOID cbDIU_DP_VideoOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL bOn); +CBIOS_VOID cbDIU_DP_DisableVideoAudio(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex); +CBIOS_VOID cbDIU_DP_EnableVideoAudio(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex); +CBIOS_VOID cbDIU_DP_SetInterruptMode(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_BOOL isDPMode); + +CBIOS_BOOL cbDIU_DP_LinkTrainingHw(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_LINK_TRAINING_PARAMS pLinkTrainingParams); +CBIOS_BOOL cbDIU_DP_SetUpMainLink(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_MAIN_LINK_PARAMS pMainLinkParams); + +CBIOS_VOID cbDIU_DP_SendInfoFrame(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U32 Length); + +CBIOS_VOID cbDIU_DP_ResetAUX(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex); +CBIOS_BOOL cbDIU_DP_AuxChRW(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PAUX_CONTROL pAUX); +CBIOS_VOID cbDIU_DP_HWUseAuxChannel(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex); +CBIOS_U32 cbDIU_DP_AuxReadEDID(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_UCHAR pEDIDBuffer, CBIOS_U32 ulBufferSize); +CBIOS_BOOL cbDIU_DP_AuxReadEDIDOffset(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_UCHAR pEDIDBuffer, CBIOS_U32 ulBufferSize, CBIOS_U32 ulReadEdidOffset); +CBIOS_STATUS cbDIU_DP_ReadData(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams, CBIOS_U32 Flags, CBIOS_BOOL IsDDC); +CBIOS_BOOL cbDIU_DP_WriteData(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams, CBIOS_BOOL IsDDC); +CBIOS_BOOL cbDIU_DP_IsOn(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DVO.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DVO.c new file mode 100644 index 0000000000000..d35f687e0ff97 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DVO.c @@ -0,0 +1,182 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DVO hw block interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosDIU_DVO.h" +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" + +static DVO_CARD_ID_PARA DVODaughterCardIDTable[] = +{ + {TX_VT1636, 0x02, 0x45}, + {TX_CH7301C, 0x4A, 0x95}, + {TX_VT1632, 0x02, 0x92}, + {TX_AD9389B, 0x43, 0x7E}, + {TX_CH7305, 0x4A, 0x81}, +}; + +static CBIOS_VOID cbDIU_DVO_GetCardIDPara(TX_TYPE CardType, PCBIOS_U8 pCardIDOffset, PCBIOS_U8 pCardIDValue) +{ + CBIOS_U32 i; + + for (i = 0; i < MAX_DVO_DEVICES_NUM; i++) + { + if (CardType == DVODaughterCardIDTable[i].DVOCardType) + { + *pCardIDOffset = DVODaughterCardIDTable[i].DVOCardIDOffset; + *pCardIDValue = DVODaughterCardIDTable[i].DVOCardIDValue; + break; + } + } + + if ( i == MAX_DVO_DEVICES_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "%s: can't fine daughter card ID para!!\n", FUNCTION_NAME)); + } +} + +CBIOS_VOID cbDIU_DVO_SetHVSync(PCBIOS_VOID pvcbe, CBIOS_U8 HVPolarity) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 byTemp = 0; + REG_SR2D RegSR2DMask; + + // set polarity for DVO + if (HVPolarity & HorNEGATIVE) + { + byTemp |= 0x40; + + } + if (HVPolarity & VerNEGATIVE) + { + byTemp |= 0x80; + } + RegSR2DMask.Value = 0xFF; + RegSR2DMask.Invert_DVO1_HSYNC = 0; + RegSR2DMask.Invert_DVO1_VSYNC = 0; + cbMMIOWriteReg(pcbe, SR_2D, byTemp, RegSR2DMask.Value); +} + +CBIOS_VOID cbDIU_DVO_VideoOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bOn, CBIOS_U8 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_SR2B RegSR2BValue, RegSR2BMask; + REG_SR32 RegSR32Value, RegSR32Mask; + + if (bOn) + { + RegSR2BValue.Value = 0; + RegSR2BMask.Value = 0xFF; + + if (IGAIndex == IGA1) + { + RegSR2BValue.DVO1_Source_Select = 0; + RegSR2BMask.DVO1_Source_Select = 0; + } + else if (IGAIndex == IGA2) + { + RegSR2BValue.DVO1_Source_Select = 1; + RegSR2BMask.DVO1_Source_Select = 0; + } + else if (IGAIndex == IGA3) + { + RegSR2BValue.DVO1_Source_Select = 2; + RegSR2BMask.DVO1_Source_Select = 0; + } + cbMMIOWriteReg(pcbe,SR_2B, RegSR2BValue.Value, RegSR2BMask.Value); + + //Set to DVO1 only. enable pad + //DVO and UART share the same port + //if turn on DVO, we should disable UART + //otherwise will cause TDR + RegSR32Value.Value = 0; + RegSR32Value.DVO_1_DAT_Pad_Out = 1; + RegSR32Value.DVO_1_HSYNC_VSYNC_Pad_Out = 1; + RegSR32Value.DVO_1_DEN_CLK_Pad_Out = 1; + RegSR32Value.DVO_1_CLKB_Pad_Out = 1; + RegSR32Mask.Value = 0xE0; + cbMMIOWriteReg(pcbe,SR_32, RegSR32Value.Value, RegSR32Mask.Value); + } + else + { + RegSR2BValue.Value = 0; + RegSR2BValue.DVO1_Source_Select = 0; + RegSR2BValue.Reserved_7to2 = 0; + RegSR2BMask.Value = 0xF0; + cbMMIOWriteReg(pcbe,SR_2B, RegSR2BValue.Value, RegSR2BMask.Value); + + RegSR32Value.Value = 0; + RegSR32Value.DVO_1_DAT_Pad_Out = 0; + RegSR32Value.DVO_1_HSYNC_VSYNC_Pad_Out = 0; + RegSR32Value.DVO_1_DEN_CLK_Pad_Out = 0; + RegSR32Value.DVO_1_CLKB_Pad_Out = 0; + RegSR32Mask.Value = 0xE0; + cbMMIOWriteReg(pcbe,SR_32, RegSR32Value.Value, RegSR32Mask.Value); + } +} + +CBIOS_STATUS cbDIU_DVO_CheckDaughterCardType(PCBIOS_VOID pvcbe, PVCP_INFO pVCP, PCBIOS_VOID pvDvoContext) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DVO_CONTEXT pDvoContext = (PCBIOS_DVO_CONTEXT)pvDvoContext; + CBIOS_U8 i = 0; + CBIOS_U8 Result = 0; + CBIOS_U8 CardIDOffset = 0; + CBIOS_U8 CardIDValue = 0; + TX_TYPE DVOTxType = TX_NONE; + CBIOS_BOOL status = CBIOS_TRUE; + CBIOS_MODULE_I2C_PARAMS I2CParams; + + cb_memset(&I2CParams, 0, sizeof(CBIOS_MODULE_I2C_PARAMS)); + + for(i = 0; i < MAX_DVO_DEVICES_NUM; i++) + { + if (pVCP->SupportedDVODevice & pVCP->DVODevConfig[i].DVOTxType) + { + cbDIU_DVO_GetCardIDPara(pVCP->DVODevConfig[i].DVOTxType, &CardIDOffset, &CardIDValue); + + I2CParams.ConfigType = CONFIG_I2C_BY_BUSNUM; + I2CParams.I2CBusNum = (CBIOS_U8)pDvoContext->Common.I2CBus; + I2CParams.SlaveAddress = pVCP->DVODevConfig[i].DVOSlaveAddr; + I2CParams.BufferLen = 1; + I2CParams.OffSet = CardIDOffset; + I2CParams.Buffer = &Result; + status = cbI2CModule_ReadData(pcbe, &I2CParams); + if(status && (Result == CardIDValue)) + { + DVOTxType = pVCP->DVODevConfig[i].DVOTxType; + pDvoContext->Common.SupportMonitorType = cbGetSupportMonitorType(pcbe, CBIOS_TYPE_DVO); + pDvoContext->DVODevice.DVOTxType = pVCP->DVODevConfig[i].DVOTxType; + pDvoContext->DVODevice.DVOSlaveAddr = pVCP->DVODevConfig[i].DVOSlaveAddr; + break; + } + } + } + + if(DVOTxType == TX_NONE) + { + pcbe->DeviceMgr.SupportDevices &= ~CBIOS_TYPE_DVO; + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: none daughter card detected!!\n", FUNCTION_NAME)); + } + + return CBIOS_OK; +} diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DVO.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DVO.h new file mode 100644 index 0000000000000..8c890c475591b --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_DVO.h @@ -0,0 +1,33 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DVO hw block interface function prototype. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_DIU_DVO_H_ +#define _CBIOS_DIU_DVO_H_ + +#include "../../Device/CBiosDeviceShare.h" + +CBIOS_VOID cbDIU_DVO_SetHVSync(PCBIOS_VOID pvcbe, CBIOS_U8 HVPolarity); +CBIOS_VOID cbDIU_DVO_VideoOnOff(PCBIOS_VOID pvcbe, CBIOS_BOOL bOn, CBIOS_U8 IGAIndex); +CBIOS_STATUS cbDIU_DVO_CheckDaughterCardType(PCBIOS_VOID pvcbe, PVCP_INFO pVCP, PCBIOS_VOID pvDvoContext); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDAC.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDAC.c new file mode 100644 index 0000000000000..abf11ea8b7ad9 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDAC.c @@ -0,0 +1,966 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** Audio codec hw block interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosDIU_HDAC.h" +#include "CBiosDIU_HDMI.h" +#include "CBiosDIU_DP.h" +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" + +CBIOS_U32 HDAC_REG_PACKET1[HDAC_MODU_NUM] = {0x8298, 0x33DA0}; +CBIOS_U32 HDAC_REG_PACKET2[HDAC_MODU_NUM] = {0x829C, 0x33DA4}; +CBIOS_U32 HDAC_REG_MODE_RESP[HDAC_MODU_NUM] = {0x82A0, 0x33DA8}; +CBIOS_U32 HDAC_REG_SW_RESP[HDAC_MODU_NUM] = {0x82A8, 0x33DB0}; +CBIOS_U32 HDAC_REG_CHSTATUS_CTRL[HDAC_MODU_NUM] = {0x82AC, 0x33DB4}; +CBIOS_U32 HDAC_REG_SUP_PARA[HDAC_MODU_NUM] = {0x82D4, 0x33DBC}; +CBIOS_U32 HDAC_REG_SAMP_RATE[HDAC_MODU_NUM] = {0x82E0, 0x33DC8}; +CBIOS_U32 HDAC_REG_CONVERT_CAP[HDAC_MODU_NUM] = {0x82EC, 0x33DD4}; +CBIOS_U32 HDAC_REG_PIN_WIDGET_CAP[HDAC_MODU_NUM] = {0x82F0, 0x33DD8}; +CBIOS_U32 HDAC_REG_PIN_SENSE[HDAC_MODU_NUM] = {0x8308, 0x33DF0}; +CBIOS_U32 HDAC_REG_ELD_BUF[HDAC_MODU_NUM] = {0x834C, 0x33DF8}; +CBIOS_U32 HDAC_REG_CTRL_WRITE[HDAC_MODU_NUM] = {0x837C, 0x33E04}; +CBIOS_U32 HDAC_REG_READ_SEL[HDAC_MODU_NUM] = {0x8380, 0x33E08}; +CBIOS_U32 HDAC_REG_READ_OUT[HDAC_MODU_NUM] = {0x8384, 0x33E0C}; + + +static AUDIO_CLOCK_TABLE AudioClockPreGenerated[] = +{ + {44100 , 1795868992ULL}, + {48000 , 1954687338ULL}, + {22050 , 897934496ULL}, + {14700 , 598622997ULL}, + {11025 , 448967248ULL}, + {8820 , 359173798ULL}, + {7350 , 299311498ULL}, + {6300 , 256552713ULL}, + {5512 , 224463262ULL}, + {88200 , 3591737984ULL}, + {29400 , 1197245994ULL}, + {17640 , 718347596ULL}, + {12600 , 513105426ULL}, + {132300 ,5387606976ULL}, + {66150 , 2693803488ULL}, + {33075 , 1346901744ULL}, + {26460 , 1077521395ULL}, + {18900 , 769658139ULL}, + {16537 , 673430510ULL}, + {176400 ,7183475968ULL}, + {58800 , 2394491989ULL}, + {35280 , 1436695193ULL}, + {25200 , 1026210852ULL}, + {24000 , 977343669ULL}, + {16000 , 651562446ULL}, + {12000 , 488671834ULL}, + {9600 , 390937467ULL}, + {8000 , 325781223ULL}, + {6857 , 279235230ULL}, + {6000 , 244335917ULL}, + {96000 , 3909374676ULL}, + {32000 , 1303124892ULL}, + {19200 , 781874935ULL}, + {13714 , 558470461ULL}, + {144000 ,5864062014ULL}, + {72000 , 2932031007ULL}, + {36000 , 1466015503ULL}, + {28800 , 1172812402ULL}, + {20571 , 837705692ULL}, + {18000 , 733007751ULL}, + {192000 ,7818749353ULL}, + {64000 , 2606249784ULL}, + {38400 , 1563749870ULL}, + {27428 , 1116940923ULL}, +}; + +CBIOS_VOID cbDIU_HDAC_SetSnoop(PCBIOS_VOID pvcbe, HDAC_NONSNOOP_SETTING NonSnoopValue) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM336B4 RegMM336B4Value, RegMM336B4Mask; + + RegMM336B4Value.Value = 0; + if(NonSnoopValue.bStreamNonSnoop) + { + RegMM336B4Value.STRM1_SNOOP = 1; + RegMM336B4Value.STRM1_FB = 1; + RegMM336B4Value.STRM2_SNOOP = 1; + RegMM336B4Value.STRM2_FB = 1; + } + if(NonSnoopValue.bBDLNonSnoop) + { + RegMM336B4Value.STRM1_BDL_SNOOP = 1; + RegMM336B4Value.STRM1_BDL_FB = 1; + RegMM336B4Value.STRM2_BDL_SNOOP = 1; + RegMM336B4Value.STRM2_BDL_FB = 1; + } + if(NonSnoopValue.bCORBNonSnoop) + { + RegMM336B4Value.CORB_SNOOP = 1; + RegMM336B4Value.CORB_FB = 1; + } + if(NonSnoopValue.bRIRBNonSnoop) + { + RegMM336B4Value.RIRB_SNOOP = 1; + RegMM336B4Value.RIRB_FB = 1; + } + if(NonSnoopValue.bDMAPositionNonSnoop) + { + RegMM336B4Value.DMAP_DES1_SNOOP = 1; + RegMM336B4Value.DMAP_DES1_FB = 1; + RegMM336B4Value.DMAP_DES2_SNOOP = 1; + RegMM336B4Value.DMAP_DES2_FB = 1; + } + RegMM336B4Mask.Value = 0xFFFFFFFF; + RegMM336B4Mask.STRM1_SNOOP = 0; + RegMM336B4Mask.STRM1_FB = 0; + RegMM336B4Mask.STRM2_SNOOP = 0; + RegMM336B4Mask.STRM2_FB = 0; + RegMM336B4Mask.STRM1_BDL_SNOOP = 0; + RegMM336B4Mask.STRM1_BDL_FB = 0; + RegMM336B4Mask.STRM2_BDL_SNOOP = 0; + RegMM336B4Mask.STRM2_BDL_FB = 0; + RegMM336B4Mask.CORB_SNOOP = 0; + RegMM336B4Mask.CORB_FB = 0; + RegMM336B4Mask.RIRB_SNOOP = 0; + RegMM336B4Mask.RIRB_FB = 0; + RegMM336B4Mask.DMAP_DES1_SNOOP = 0; + RegMM336B4Mask.DMAP_DES1_FB = 0; + RegMM336B4Mask.DMAP_DES2_SNOOP = 0; + RegMM336B4Mask.DMAP_DES2_FB = 0; + + cbMMIOWriteReg32(pcbe, 0x336B4, RegMM336B4Value.Value, RegMM336B4Mask.Value); +} + +static CBIOS_VOID cbDIU_HDAC_SetHDACSettings(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDACModuleIndex, CBIOS_U32 StreamFormat) +{ + CBIOS_U64 AudioPacketClock = 40722; // 2^40 + CBIOS_U32 i = 0; + CBIOS_BOOL bMatchAudioClock = CBIOS_FALSE; + CBIOS_U32 HDACReadSelRegIndex; + REG_MM8298 HDACPacket1RegValue, HDACPacket1RegMask; + REG_MM829C HDACPacket2RegValue, HDACPacket2RegMask; + REG_MM82AC HDACChStatusCtrlRegValue, HDACChStatusCtrlRegMask; + REG_MM8380 HDACReadSelRegValue, HDACReadSelRegMask; + REG_MM8388 HDACWallClkLRegValue, HDACWallClkLRegMask; + REG_MM838C HDACWallClkHRegValue, HDACWallClkHRegMask; + + if (HDACModuleIndex >= HDAC_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid HDAC module index!\n", FUNCTION_NAME)); + return; + } + HDACReadSelRegIndex = 0x8380; + + // 1. Audio Packet to Clock Ratio = (Fs * 2^40)/ 27Mhz + for(i = 0; i < sizeofarray(AudioClockPreGenerated); i++) + { + if(StreamFormat == (AudioClockPreGenerated[i].StreamFormat)) + { + AudioPacketClock = AudioClockPreGenerated[i].AudioPacketClock; + bMatchAudioClock = CBIOS_TRUE; + break; + } + } + + if(!bMatchAudioClock) + { + AudioPacketClock *= StreamFormat; + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid StreamFormat, could not match the pre-computed AudioPacketClock!!\n ")); + } + + HDACPacket1RegValue.Value = (CBIOS_U32)AudioPacketClock; + HDACPacket1RegMask.Value = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_PACKET1[HDACModuleIndex], HDACPacket1RegValue.Value, HDACPacket1RegMask.Value); + + HDACPacket2RegValue.Value = 0; + HDACPacket2RegValue.CODEC1_Audio_Packet_to_DClk_Ratio_39to32 = (CBIOS_U32)((AudioPacketClock >> 32) & 0xFF); + HDACPacket2RegValue.CODEC1_MUTE_EN = 1; //for win10 mute speaker + HDACPacket2RegMask.Value = 0xFFFFFFFF; + HDACPacket2RegMask.CODEC1_Audio_Packet_to_DClk_Ratio_39to32 = 0; + HDACPacket2RegMask.CODEC1_MUTE_EN = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_PACKET2[HDACModuleIndex], HDACPacket2RegValue.Value, HDACPacket2RegMask.Value); + + // 2. Ratio_Clk_Select, using Xclock + HDACChStatusCtrlRegValue.Value = 0; + HDACChStatusCtrlRegValue.Ratio_CLK_Select = 1; + HDACChStatusCtrlRegMask.Value = 0xFFFFFFFF; + HDACChStatusCtrlRegMask.Ratio_CLK_Select = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_CHSTATUS_CTRL[HDACModuleIndex], HDACChStatusCtrlRegValue.Value, HDACChStatusCtrlRegMask.Value); + // Short Audio patch + HDACChStatusCtrlRegValue.Value = 0; +#ifdef __LINUX__ + //This patch will cause a black screen when playing audio + HDACChStatusCtrlRegValue.Always_Output_Audio = 0; +#else + HDACChStatusCtrlRegValue.Always_Output_Audio = 1; +#endif + HDACChStatusCtrlRegMask.Value = 0xFFFFFFFF; + HDACChStatusCtrlRegMask.Always_Output_Audio = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_CHSTATUS_CTRL[HDACModuleIndex], HDACChStatusCtrlRegValue.Value, HDACChStatusCtrlRegMask.Value); + + // 3.1 Sw_Strm_Fifo_Depth_Select + HDACReadSelRegValue.Value = 0; + HDACReadSelRegValue.SW_Strm1_FIFO_Depth_Select = 1; + // 3.2 Sw_Strm_Fifo_Depth + HDACReadSelRegValue.SW_Strm1_FIFO_Depth = 3; + // 3.3 Sw_Strm_Link_Position_Select + HDACReadSelRegValue.Strm1_Link_Position_Select = 1; + // 3.4 Wall_Clk_Select + HDACReadSelRegValue.HDAUDIO_Wall_Clock_Select = 0; + // 3.5 Wall_Clk_Cnt_sel + HDACReadSelRegValue.Wal_Clk_Cnt_Sel = 1; + // 3.6 Wall_Clk_Cnt_clock_Sel + HDACReadSelRegValue.Wal_Clk_Cnt_Clock_Sel1 = 0; + HDACReadSelRegValue.Wal_Clk_Cnt_Clock_Sel2 = 1; + + HDACReadSelRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, HDACReadSelRegIndex, HDACReadSelRegValue.Value, HDACReadSelRegMask.Value); + + // 4. Wall Clock Ratio / Wall clock enable + HDACWallClkLRegValue.Value = 0; + HDACWallClkLRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, 0x8388, HDACWallClkLRegValue.Value, HDACWallClkLRegMask.Value); + HDACWallClkHRegValue.Value = 0; + HDACWallClkHRegValue.Wall_clock__ratio__hi = 0; + HDACWallClkHRegValue.Wall_clock_ratio_enable = 0; + HDACWallClkHRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, 0x838C, HDACWallClkHRegValue.Value, HDACWallClkHRegMask.Value); +} + +static CBIOS_VOID cbDIU_HDAC_SetHDAudioCapability(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_ACTIVE_TYPE Device, + CBIOS_MODULE_INDEX HDACModuleIndex) +{ + CBIOS_U32 AudioFmtNum = 0, i = 0; + PCBIOS_HDMI_AUDIO_INFO pAudioInfo = CBIOS_NULL; + CBIOS_BOOL bSupportStero = CBIOS_FALSE; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + REG_MM82D4 HDACSupParaRegValue, HDACSupParaRegMask; + REG_MM82E0 HDACSampRateRegValue, HDACSampRateRegMask; + REG_MM82EC HDACConvertCapRegValue, HDACConvertCapRegMask; + REG_MM82F0 HDACPinWidgetCapRegValue, HDACPinWidgetCapRegMask; + + pAudioInfo = pDevCommon->EdidStruct.HDMIAudioFormat; + AudioFmtNum = pDevCommon->EdidStruct.TotalHDMIAudioFormatNum; + + if (HDACModuleIndex >= HDAC_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid HDAC module index!\n", FUNCTION_NAME)); + return; + } + + if(!pAudioInfo) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "Invalid audio info!")); + return; + } + + HDACSupParaRegValue.Value = 0; + HDACSupParaRegValue.PCM_Support = 0; + HDACSupParaRegValue.PCM_Float32_Only_Support = 0; + HDACSupParaRegValue.AC3_16_bit_only_Support = 0; + HDACSupParaRegValue.SuppPowerState_D1Sup = 0; + HDACSupParaRegValue.SuppPowerState_D2Sup = 0; + + HDACSupParaRegMask.Value = 0xFFFFFFFF; + HDACSupParaRegMask.PCM_Support = 0; + HDACSupParaRegMask.PCM_Float32_Only_Support = 0; + HDACSupParaRegMask.AC3_16_bit_only_Support = 0; + HDACSupParaRegMask.SuppPowerState_D1Sup = 0; + HDACSupParaRegMask.SuppPowerState_D2Sup = 0; + + HDACSampRateRegValue.Value = 0; + HDACSampRateRegValue.R1 = 0; //8kHz + HDACSampRateRegValue.R2 = 0; //11.025kHz + HDACSampRateRegValue.R3 = 0; //16kHz + HDACSampRateRegValue.R4 = 0; //22.05kHz + HDACSampRateRegValue.R7 = 1; //must support 48kHz + HDACSampRateRegValue.R12 = 0; //384kHz + HDACSampRateRegValue.B8 = 0; //8bit PCM + HDACSampRateRegValue.B32 = 0; //32bit PCM + for(i = 0; i < AudioFmtNum; i++) + { + if(pAudioInfo[i].Format == CBIOS_AUDIO_FORMAT_LPCM) + { + HDACSupParaRegValue.PCM_Support = 1; + if(pAudioInfo[i].SampleRate.SR_32kHz) + { + HDACSampRateRegValue.R5 = 1; + } + if(pAudioInfo[i].SampleRate.SR_44_1kHz) + { + HDACSampRateRegValue.R6 = 1; + } + if(pAudioInfo[i].SampleRate.SR_88_2kHz) + { + HDACSampRateRegValue.R8 = 1; + } + if(pAudioInfo[i].SampleRate.SR_96kHz) + { + HDACSampRateRegValue.R9 = 1; + } + if(pAudioInfo[i].SampleRate.SR_176_4kHz) + { + HDACSampRateRegValue.R10 = 1; + } + if(pAudioInfo[i].SampleRate.SR_192kHz) + { + HDACSampRateRegValue.R11 = 1; + } + if(pAudioInfo[i].BitDepth.BD_16bit) + { + HDACSampRateRegValue.B16 = 1; + } + if(pAudioInfo[i].BitDepth.BD_20bit) + { + HDACSampRateRegValue.B20 = 1; + } + if(pAudioInfo[i].BitDepth.BD_24bit) + { + HDACSampRateRegValue.B24 = 1; + } + } + if(pAudioInfo[i].MaxChannelNum > 1) + { + bSupportStero = CBIOS_TRUE; + } + } + HDACSampRateRegMask.Value = 0; + HDACSampRateRegMask.Reserved_15to12 = 0xF; + HDACSampRateRegMask.Reserved_31to21 = 0x7FF; + + HDACConvertCapRegValue.Value = 0; + HDACConvertCapRegValue.Stereo = bSupportStero? 1 : 0; + HDACConvertCapRegMask.Value = 0xFFFFFFFF; + HDACConvertCapRegMask.Stereo = 0; + HDACPinWidgetCapRegValue.Value = 0; + HDACPinWidgetCapRegValue.Stereo = bSupportStero? 1 : 0; + HDACPinWidgetCapRegMask.Value = 0xFFFFFFFF; + HDACPinWidgetCapRegMask.Stereo = 0; + + cbMMIOWriteReg32(pcbe, HDAC_REG_SUP_PARA[HDACModuleIndex], HDACSupParaRegValue.Value, HDACSupParaRegMask.Value); + cbMMIOWriteReg32(pcbe, HDAC_REG_SAMP_RATE[HDACModuleIndex], HDACSampRateRegValue.Value, HDACSampRateRegMask.Value); + cbMMIOWriteReg32(pcbe, HDAC_REG_CONVERT_CAP[HDACModuleIndex], HDACConvertCapRegValue.Value, HDACConvertCapRegMask.Value); + cbMMIOWriteReg32(pcbe, HDAC_REG_PIN_WIDGET_CAP[HDACModuleIndex], HDACPinWidgetCapRegValue.Value, HDACPinWidgetCapRegMask.Value); +} + +CBIOS_VOID cbDIU_HDAC_SetHDACodecPara(PCBIOS_VOID pvcbe, PCBIOS_HDAC_PARA pCbiosHDACPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 ReadOutValue = 0, StreamFormat = 0; + CBIOS_BOOL bEnableHDMI1 = CBIOS_FALSE; + CBIOS_ACTIVE_TYPE Device = (CBIOS_ACTIVE_TYPE)pCbiosHDACPara->DeviceId; + CBIOS_MODULE_INDEX HDACModuleIndex = CBIOS_MODULE_INDEX_INVALID; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + CBIOS_BOOL bHDMIDevice = (pDevCommon->CurrentMonitorType & CBIOS_MONITOR_TYPE_HDMI); + REG_MM82A0 HDACModeRespRegValue, HDACModeRespRegMask; + REG_MM82AC HDACChStatusCtrlRegValue, HDACChStatusCtrlRegMask; + REG_MM8380 HDACReadSelRegValue, HDACReadSelRegMask; + HDAC_NONSNOOP_SETTING NonSnoopValue; + + + HDACModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_HDAC); + + if (HDACModuleIndex >= HDAC_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid HDAC module index!\n", FUNCTION_NAME)); + return; + } + + if ((pDevCommon->CurrentMonitorType != CBIOS_MONITOR_TYPE_HDMI) + && (pDevCommon->CurrentMonitorType != CBIOS_MONITOR_TYPE_DP)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid monitor type 0x%x for HDAC!\n", + FUNCTION_NAME, pDevCommon->CurrentMonitorType)); + return; + } + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "codec#%d interrupt!\n", HDACModuleIndex)); + // step 0. Set Codec_Type to HDMI1 + if(cb_ReadU32(pcbe->pAdapterContext, 0x8280) & BIT1) + { + bEnableHDMI1 = CBIOS_TRUE; + } + if(bEnableHDMI1 == CBIOS_FALSE) + { + cbMMIOWriteReg32(pcbe, 0x8280, 0x2, ~0x2); + } + + //enable HDAUDIO mode + HDACModeRespRegValue.Value = 0; + HDACModeRespRegValue.HD_AUDIO_MODE_SELECT = 1; + HDACModeRespRegMask.Value = 0xFFFFFFFF; + HDACModeRespRegMask.HD_AUDIO_MODE_SELECT = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_MODE_RESP[HDACModuleIndex], HDACModeRespRegValue.Value, HDACModeRespRegMask.Value); + + // step 1. read out stream format + HDACReadSelRegValue.Value = 0; + HDACReadSelRegValue.Read_Out_Control_Select = 1; + HDACReadSelRegMask.Value = 0xFFFFFFFF; + HDACReadSelRegMask.Read_Out_Control_Select = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_READ_SEL[HDACModuleIndex], HDACReadSelRegValue.Value, HDACReadSelRegMask.Value); + ReadOutValue = cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_READ_OUT[HDACModuleIndex]); // [15:0] + + HDACReadSelRegValue.Value = 0; + HDACReadSelRegValue.Read_Out_Control_Select = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_READ_SEL[HDACModuleIndex], HDACReadSelRegValue.Value, HDACReadSelRegMask.Value); + + //step 2. decode ReadOutValue by definition + // [14] Converter_Format_Base + // BASE. Converter Format Sample Base Rate. (PCM Format structure bit 14) + // 0: 48kHz + // 1: 44.1kHz + // [13:11] Converter_Format_Mult + // MULT. Converter Format Sample Base Rate Multiple. (PCM Format structure bits 13:11) + // 000: 48kHz/ 44.1 kHz or lesss + // 001: x2 (96kHz, 88.2kHz, 32kHz) + // 010: x3 (144kHz) + // 011: x4 (192kHz, 176.4kHz) + // 100-111: Reserved + // [10:8] Converter_Format_Div + // DIV. Converter Format Sample Base Rate Divisor. (PCM Format structure bits 10:8) + // 000: Divide by 1 (48kHz, 44.1 kHz) + // 001: Divide by 2 (24kHz, 22.05kHz) + // 010: Divide by 3 (16kHz, 32kHz) + // 011: Divide by 4 (11.025kHz) + // 100: Divide by 5 (9.6kHz) + // 101: Divide by 6 (8kHz) + // 110: Divide by 7 + // 111: Divide by 8 (6kHz) + if(ReadOutValue & 0x4000) + { + StreamFormat = 44100; + } + else + { + StreamFormat = 48000; + } + + StreamFormat *= (((ReadOutValue & 0x3800) >> 11) + 1); + + StreamFormat /= (((ReadOutValue & 0x700) >> 8) + 1); + + // step 3. Audio packet clock, Wall clock ratio + cbDIU_HDAC_SetHDACSettings(pcbe, HDACModuleIndex, StreamFormat); + + // step 4. fill CTS/N for HDMI/MHL, Maud/Naud for DP + if(bHDMIDevice) + { + CBIOS_MODULE_INDEX HDMIModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_HDMI); + + cbDIU_HDMI_SetCTSN(pcbe, HDMIModuleIndex, HDACModuleIndex, StreamFormat); + } +#if DP_MONITOR_SUPPORT + else + { + PCBIOS_DP_MONITOR_CONTEXT pDPMonitorContext = cbGetDPMonitorContext(pcbe, pDevCommon); + CBIOS_MODULE_INDEX DPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_DP); + + cbDIU_DP_SetMaudNaud(pcbe, DPModuleIndex, pDPMonitorContext->LinkSpeedToUse, StreamFormat); + } +#endif + +#ifdef __LINUX__ + NonSnoopValue.NonSnoopFlags = 0; + if(cbNeedSetHdaudioToLocal(pcbe)) // if arise10C0, set Stream and BDL to non-snoop + { + NonSnoopValue.bStreamNonSnoop = 1; + NonSnoopValue.bBDLNonSnoop = 1; + } + cbDIU_HDAC_SetSnoop(pcbe, NonSnoopValue); +#else + NonSnoopValue.NonSnoopFlags = 0; + cbDIU_HDAC_SetSnoop(pcbe, NonSnoopValue); +#endif + + //step 5. set to correct source + HDACChStatusCtrlRegValue.Value = 0; + HDACChStatusCtrlRegMask.Value = 0xFFFFFFFF; + HDACChStatusCtrlRegMask.Codec_Type = 0; + + if(HDACModuleIndex == CBIOS_MODULE_INDEX1) + { + if(bHDMIDevice) + { + //codec_1 is used for HDMI1 + HDACChStatusCtrlRegValue.Codec_Type = 0; + } + else + { + //codec_2 is used for DP1 + HDACChStatusCtrlRegValue.Codec_Type = 1; + } + } + else if(HDACModuleIndex == CBIOS_MODULE_INDEX2) + { + if(bHDMIDevice) + { + //codec_2 is used for HDMI2 + HDACChStatusCtrlRegValue.Codec_Type = 3; + } + else + { + //codec_2 is used for DP2 + HDACChStatusCtrlRegValue.Codec_Type = 2; + } + } + cbMMIOWriteReg32(pcbe, HDAC_REG_CHSTATUS_CTRL[HDACModuleIndex], HDACChStatusCtrlRegValue.Value, HDACChStatusCtrlRegMask.Value); + + cbDIU_HDAC_SetHDAudioCapability(pcbe, Device, HDACModuleIndex); + + // step 6. disable HDMI1 + if(bEnableHDMI1 == CBIOS_FALSE) + { + cbMMIOWriteReg32(pcbe, 0x8280, 0x0, ~0x2); + } +} + +CBIOS_VOID cbDIU_HDAC_SetStatus(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bNeedDisableCodec1 = CBIOS_FALSE; + CBIOS_BOOL bNeedDisableCodec2 = CBIOS_FALSE; + REG_MM82A0 HDACModeRespRegValue, HDACModeRespRegMask; + HDAC_NONSNOOP_SETTING NonSnoopValue; + + + bNeedDisableCodec1 = (pcbe->FeatureSwitch.IsDisableCodec1) ? CBIOS_TRUE : CBIOS_FALSE; + bNeedDisableCodec2 = (pcbe->FeatureSwitch.IsDisableCodec2) ? CBIOS_TRUE : CBIOS_FALSE; + + cbTraceEnter(DP); + + cbMMIOWriteReg32(pcbe, HDAC_REG_PIN_WIDGET_CAP[CBIOS_MODULE_INDEX1], 0x00400381, 0); + cbMMIOWriteReg32(pcbe, 0x82F4, 0x00000094, 0); + + HDACModeRespRegValue.Value = 0; + HDACModeRespRegValue.HDAUDIO_CODEC1_Enable = (bNeedDisableCodec1)? 0 : 1; + HDACModeRespRegMask.Value = 0xFFFFFFFF; + HDACModeRespRegMask.HDAUDIO_CODEC1_Enable = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_MODE_RESP[CBIOS_MODULE_INDEX1], HDACModeRespRegValue.Value, HDACModeRespRegMask.Value); + + cbMMIOWriteReg32(pcbe, HDAC_REG_CTRL_WRITE[CBIOS_MODULE_INDEX1], 0x00000080, 0xFFFFFF7F); + cbMMIOWriteReg32(pcbe, HDAC_REG_CTRL_WRITE[CBIOS_MODULE_INDEX1], 0x00000000, 0xFFFFFF7F); + + + cbMMIOWriteReg32(pcbe, HDAC_REG_PIN_WIDGET_CAP[CBIOS_MODULE_INDEX2], 0x00400381, 0); + cbMMIOWriteReg32(pcbe, 0x33DDC, 0x00000094, 0); + + HDACModeRespRegValue.HDAUDIO_CODEC1_Enable = (bNeedDisableCodec2)? 0 : 1; + cbMMIOWriteReg32(pcbe, HDAC_REG_MODE_RESP[CBIOS_MODULE_INDEX2], HDACModeRespRegValue.Value, HDACModeRespRegMask.Value); + + cbMMIOWriteReg32(pcbe, HDAC_REG_CTRL_WRITE[CBIOS_MODULE_INDEX2], 0x00000080, 0xFFFFFF7F); + cbMMIOWriteReg32(pcbe, HDAC_REG_CTRL_WRITE[CBIOS_MODULE_INDEX2], 0x00000000, 0xFFFFFF7F); + + //As E3k DIU-MXU only has 36-bit address lines, set hdac supported address to 32bits here. + cbMMIOWriteReg32(pcbe, 0x336B4, 0x00000080, 0xFFFFFF7F); + + // Set 336B4.bit3 HW_CORB_RST_SEL = 1, don't display hdaudio CORB reset timeout. + cbMMIOWriteReg32(pcbe, 0x336B4, 0x00000008, 0xFFFFFFF7); + +#ifdef __LINUX__ + NonSnoopValue.NonSnoopFlags = 0; + if(cbNeedSetHdaudioToLocal(pcbe)) // if arise10C0, set Stream and BDL to non-snoop + { + NonSnoopValue.bStreamNonSnoop = 1; + NonSnoopValue.bBDLNonSnoop = 1; + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Set HdAudio path to local fb!\n")); + } + cbDIU_HDAC_SetSnoop(pcbe, NonSnoopValue); +#else + NonSnoopValue.NonSnoopFlags = 0; + cbDIU_HDAC_SetSnoop(pcbe, NonSnoopValue); +#endif + + cbTraceExit(DP); +} + +CBIOS_U32 cbDIU_HDAC_GetChannelNums(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDACModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 ReadOutValue = 0, NumofChannels = 0; + REG_MM82A0 HDACModeRespRegValue, HDACModeRespRegMask; + REG_MM82AC HDACChStatusCtrlRegValue, HDACChStatusCtrlRegMask; + REG_MM8380 HDACReadSelRegValue, HDACReadSelRegMask; + + if (HDACModuleIndex >= HDAC_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid HDAC module index!\n", FUNCTION_NAME)); + return 0; + } + + //enable HDAUDIO mode + HDACModeRespRegValue.Value = 0; + HDACModeRespRegValue.HD_AUDIO_MODE_SELECT = 1; + HDACModeRespRegMask.Value = 0xFFFFFFFF; + HDACModeRespRegMask.HD_AUDIO_MODE_SELECT = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_MODE_RESP[HDACModuleIndex], HDACModeRespRegValue.Value, HDACModeRespRegMask.Value); + + HDACChStatusCtrlRegValue.Value = 0; + HDACChStatusCtrlRegMask.Value = 0xFFFFFFFF; + HDACChStatusCtrlRegMask.Codec_Type = 0; + if(HDACModuleIndex == CBIOS_MODULE_INDEX1) + { + HDACChStatusCtrlRegValue.Codec_Type = 0; + } + else + { + HDACChStatusCtrlRegValue.Codec_Type = 3; + } + cbMMIOWriteReg32(pcbe, HDAC_REG_CHSTATUS_CTRL[HDACModuleIndex], HDACChStatusCtrlRegValue.Value, HDACChStatusCtrlRegMask.Value); + + // step 1. read out stream format + HDACReadSelRegValue.Value = 0; + HDACReadSelRegValue.Read_Out_Control_Select = 1; + HDACReadSelRegMask.Value = 0xFFFFFFFF; + HDACReadSelRegMask.Read_Out_Control_Select = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_READ_SEL[HDACModuleIndex], HDACReadSelRegValue.Value, HDACReadSelRegMask.Value); + + ReadOutValue = cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_READ_OUT[HDACModuleIndex]); // [15:0] + + HDACReadSelRegValue.Value = 0; + HDACReadSelRegValue.Read_Out_Control_Select = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_READ_SEL[HDACModuleIndex], HDACReadSelRegValue.Value, HDACReadSelRegMask.Value); + + //step 2. decode ReadOutValue by definition + // [3:0] Number of channels(CHAN) + NumofChannels = ReadOutValue & 0xF; + + return NumofChannels; +} + +#if 0 + +static CBIOS_VOID cbDIU_HDAC_DevicesSwitchPatched(PCBIOS_VOID pvcbe, PCBIOS_HDAC_PARA pCbiosHDACPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_ACTIVE_TYPE Device = (CBIOS_ACTIVE_TYPE)pCbiosHDACPara->DeviceId; + PCBIOS_DEVICE_COMMON pDevCommon1 = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DP1); + PCBIOS_DEVICE_COMMON pDevCommon2 = cbGetDeviceCommon(&pcbe->DeviceMgr, CBIOS_TYPE_DP2); + CBIOS_BOOL bHDMIDevice1 = (pDevCommon1->CurrentMonitorType & CBIOS_MONITOR_TYPE_HDMI); + CBIOS_BOOL bHDMIDevice2 = (pDevCommon2->CurrentMonitorType & CBIOS_MONITOR_TYPE_HDMI); + REG_MM82AC HDACChStatusCtrlRegValue, HDACChStatusCtrlRegMask; + + if((!pCbiosHDACPara->bPresent) && (Device == CBIOS_TYPE_DP1)) //DP1 is disconnected and DP2 is connected. + { + if(pDevCommon2->PowerState == CBIOS_PM_ON) + { + cb_WriteU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX1], + (cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX1]) & 0xFFFF9FFF) | (cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX2]) & 0x00006000)); + } + } + else if((!pCbiosHDACPara->bPresent) && (Device == CBIOS_TYPE_DP2)) //DP2 is disconnected and DP1 is connected. + { + if(pDevCommon1->PowerState == CBIOS_PM_ON) + { + cb_WriteU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX2], + (cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX2]) & 0xFFFF9FFF) | (cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX1]) & 0x00006000)); + } + } + else if(pCbiosHDACPara->bPresent && (Device == CBIOS_TYPE_DP1)) //DP1 is connected and DP2 is disconnected. + { + // set codec1 source + HDACChStatusCtrlRegValue.Value = 0; + if(bHDMIDevice1) + { + HDACChStatusCtrlRegValue.Codec_Type = 0; //codec_1 is used for HDMI1 + } + else + { + HDACChStatusCtrlRegValue.Codec_Type = 1; //codec_2 is used for DP1 + } + HDACChStatusCtrlRegMask.Value = 0xFFFFFFFF; + HDACChStatusCtrlRegMask.Codec_Type = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX1], HDACChStatusCtrlRegValue.Value, HDACChStatusCtrlRegMask.Value); + + if(pDevCommon2->PowerState == CBIOS_PM_OFF) + { + cb_WriteU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX2], + (cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX2]) & 0xFFFF9FFF) | (cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX1]) & 0x00006000)); + } + } + else if(pCbiosHDACPara->bPresent && (Device == CBIOS_TYPE_DP2)) //DP2 is connected and DP1 is disconnected. + { + // set codec2 source + HDACChStatusCtrlRegValue.Value = 0; + if(bHDMIDevice2) + { + HDACChStatusCtrlRegValue.Codec_Type = 3; //codec_2 is used for HDMI2 + } + else + { + HDACChStatusCtrlRegValue.Codec_Type = 2; //codec_2 is used for DP2 + } + HDACChStatusCtrlRegMask.Value = 0xFFFFFFFF; + HDACChStatusCtrlRegMask.Codec_Type = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX2], HDACChStatusCtrlRegValue.Value, HDACChStatusCtrlRegMask.Value); + + if(pDevCommon1->PowerState == CBIOS_PM_OFF) + { + cb_WriteU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX1], + (cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX1]) & 0xFFFF9FFF) | (cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_CHSTATUS_CTRL[CBIOS_MODULE_INDEX2]) & 0x00006000)); + } + } +} + +#endif + +static CBIOS_VOID cbDIU_HDAC_UpdateEldStatus(PCBIOS_VOID pvcbe, PCBIOS_HDAC_PARA pCbiosHDACPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 PinSense = 0, UnsolResponse = 0, UnsolCtl = 0, ulTemp = 0; + CBIOS_MODULE_INDEX HDACModuleIndex = CBIOS_MODULE_INDEX_INVALID; + REG_MM82A0 HDACModeRespRegValue, HDACModeRespRegMask; + REG_MM8308 HDACPinSenseRegValue, HDACPinSenseRegMask; + REG_MM837C HDACCtrlWriteRegValue, HDACCtrlWriteRegMask; + REG_MM8380 HDACReadSelRegValue, HDACReadSelRegMask; + + if((pCbiosHDACPara->bPresent == CBIOS_TRUE) + && (pCbiosHDACPara->bEldValid== CBIOS_TRUE)) + { + PinSense |= 0x80000000; + UnsolResponse |= 0x1; + PinSense |= 0x40000000; + UnsolResponse |= 0x2; + } + else if((pCbiosHDACPara->bPresent == CBIOS_TRUE) + && (pCbiosHDACPara->bEldValid == CBIOS_FALSE)) + { + PinSense |= 0x80000000; + UnsolResponse |= 0x1; + PinSense |= 0x00000000; + UnsolResponse |= 0x2; + } + + HDACModuleIndex = cbGetModuleIndex(pcbe, (CBIOS_ACTIVE_TYPE)pCbiosHDACPara->DeviceId, CBIOS_MODULE_TYPE_HDAC); + if (HDACModuleIndex >= HDAC_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid HDAC module index!\n", FUNCTION_NAME)); + return; + } + + //load PinSense + HDACPinSenseRegValue.Value = PinSense; + HDACPinSenseRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_PIN_SENSE[HDACModuleIndex], HDACPinSenseRegValue.Value, HDACPinSenseRegMask.Value); + HDACCtrlWriteRegValue.Value = 0; + HDACCtrlWriteRegValue.Load_Pinwidget1_PinSense = 1; + HDACCtrlWriteRegMask.Value = 0xFFFFFFFF; + HDACCtrlWriteRegMask.Load_Pinwidget1_PinSense = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_CTRL_WRITE[HDACModuleIndex], HDACCtrlWriteRegValue.Value, HDACCtrlWriteRegMask.Value); + + cb_DelayMicroSeconds(20); + + HDACCtrlWriteRegValue.Value = 0; + HDACCtrlWriteRegValue.Load_Pinwidget1_PinSense = 0; + HDACCtrlWriteRegMask.Value = 0xFFFFFFFF; + HDACCtrlWriteRegMask.Load_Pinwidget1_PinSense = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_CTRL_WRITE[HDACModuleIndex], HDACCtrlWriteRegValue.Value, HDACCtrlWriteRegMask.Value); + + //read out + HDACReadSelRegValue.Value = 0; + HDACReadSelRegValue.Read_Out_Control_Select = 0x06; + HDACReadSelRegMask.Value = 0xFFFFFFFF; + HDACReadSelRegMask.Read_Out_Control_Select = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_READ_SEL[HDACModuleIndex], HDACReadSelRegValue.Value, HDACReadSelRegMask.Value); + ulTemp = cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_READ_OUT[HDACModuleIndex]); + if(PinSense == ulTemp) + { + //if(bSendUnsol) + { + HDACReadSelRegValue.Value = 0; + HDACReadSelRegValue.Read_Out_Control_Select = 0x04; + HDACReadSelRegMask.Value = 0xFFFFFFFF; + HDACReadSelRegMask.Read_Out_Control_Select = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_READ_SEL[HDACModuleIndex], HDACReadSelRegValue.Value, HDACReadSelRegMask.Value); + UnsolCtl = cb_ReadU32(pcbe->pAdapterContext, HDAC_REG_READ_OUT[HDACModuleIndex]); + if(UnsolCtl & 0x80) + { // Unsolicited response enabled + UnsolResponse |= (UnsolCtl & 0x3f) << 26; + cb_WriteU32(pcbe->pAdapterContext, HDAC_REG_SW_RESP[HDACModuleIndex], UnsolResponse); + + HDACModeRespRegValue.Value = 0; + HDACModeRespRegMask.Value = 0xFFFFFFFF; + HDACModeRespRegValue.Send_UNSOLRESP = 1; + HDACModeRespRegMask.Send_UNSOLRESP = 0; + // send it 3 times to make sure it be sent out. + cbMMIOWriteReg32(pcbe, HDAC_REG_MODE_RESP[HDACModuleIndex], HDACModeRespRegValue.Value, HDACModeRespRegMask.Value); + cb_DelayMicroSeconds(20); + cbMMIOWriteReg32(pcbe, HDAC_REG_MODE_RESP[HDACModuleIndex], HDACModeRespRegValue.Value, HDACModeRespRegMask.Value); + cb_DelayMicroSeconds(20); + cbMMIOWriteReg32(pcbe, HDAC_REG_MODE_RESP[HDACModuleIndex], HDACModeRespRegValue.Value, HDACModeRespRegMask.Value); + } + } + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: Write Codec PinSense Failed!\n", FUNCTION_NAME)); + } + + HDACReadSelRegValue.Value = 0; + HDACReadSelRegValue.Read_Out_Control_Select = 0; + HDACReadSelRegMask.Value = 0xFFFFFFFF; + HDACReadSelRegMask.Read_Out_Control_Select = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_READ_SEL[HDACModuleIndex], HDACReadSelRegValue.Value, HDACReadSelRegMask.Value); +} + + +static CBIOS_VOID cbDIU_HDAC_WriteFIFO(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, PCBIOS_ELD_MEM_STRUCT pEld) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 SR47Value = 0, Data = 0, LookupTable = 0; + CBIOS_U32 index = 0, eldIndex = 0; + CBIOS_MODULE_INDEX HDACModuleIndex = CBIOS_MODULE_INDEX_INVALID; + REG_MM82AC HDACChStatusCtrlRegValue, HDACChStatusCtrlRegMask; + REG_MM834C HDACEldBufRegValue, HDACEldBufRegMask; + REG_SR47 RegSR47Value, RegSR47Mask; + + HDACModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_HDAC); + + if (HDACModuleIndex >= HDAC_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid HDAC module index!\n", FUNCTION_NAME)); + return; + } + + if(HDACModuleIndex == CBIOS_MODULE_INDEX1) // CODEC1 + { + LookupTable = 4; + } + else if(HDACModuleIndex == CBIOS_MODULE_INDEX2) // CODEC2 + { + LookupTable = 5; + } + + HDACChStatusCtrlRegValue.Value = 0; + HDACChStatusCtrlRegValue.Set_ELD_Default = 1; + HDACChStatusCtrlRegValue.ELD_Use_LUT = 1; + HDACChStatusCtrlRegMask.Value = 0xFFFFFFFF; + HDACChStatusCtrlRegMask.Set_ELD_Default = 0; + HDACChStatusCtrlRegMask.ELD_Use_LUT = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_CHSTATUS_CTRL[HDACModuleIndex], HDACChStatusCtrlRegValue.Value, HDACChStatusCtrlRegMask.Value); + + HDACEldBufRegValue.Value = 0; + HDACEldBufRegValue.Byte_Offset_into_ELD_memory = 0; + HDACEldBufRegMask.Value = 0xFFFFFFFF; + HDACEldBufRegMask.Byte_Offset_into_ELD_memory = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_ELD_BUF[HDACModuleIndex], HDACEldBufRegValue.Value, HDACEldBufRegMask.Value); + HDACEldBufRegValue.Value = 0; + HDACEldBufRegValue.ELD_Buffer_Size = (pEld->Size & 0xff); + HDACEldBufRegMask.Value = 0xFFFFFFFF; + HDACEldBufRegMask.ELD_Buffer_Size = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_ELD_BUF[HDACModuleIndex], HDACEldBufRegValue.Value, HDACEldBufRegMask.Value); + + SR47Value = cbMMIOReadReg(pcbe, SR_47); + + //select eld lookup table + RegSR47Value.Value = 0; + RegSR47Value.CLUT_Select = LookupTable; + RegSR47Mask.Value = 0xFF; + RegSR47Mask.CLUT_Select = 0; + cbMMIOWriteReg(pcbe, SR_47, RegSR47Value.Value, RegSR47Mask.Value); + + cb_WriteU8(pcbe->pAdapterContext, 0x83C8, 0); + + for(index = 0; index < ((pEld->Size + 31) / 32); index++) + { + for(eldIndex = (index + 1) * 32; eldIndex > 0; eldIndex--) + { + if(eldIndex > pEld->Size) + Data = 0; + else + Data = pEld->Data[eldIndex - 1]; + cb_WriteU8(pcbe->pAdapterContext, 0x83C9, Data); + } + } + + //clear ELD_Use_LUT as DP3/4 not bind to codec, so it can not send out info frame + HDACChStatusCtrlRegValue.Value = 0; + HDACChStatusCtrlRegValue.ELD_Use_LUT = 0; + HDACChStatusCtrlRegMask.Value = 0xFFFFFFFF; + HDACChStatusCtrlRegMask.ELD_Use_LUT = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_CHSTATUS_CTRL[HDACModuleIndex], HDACChStatusCtrlRegValue.Value, HDACChStatusCtrlRegMask.Value); + + //restore SR47 + RegSR47Value.Value = SR47Value; + RegSR47Mask.Value = 0; + cbMMIOWriteReg(pcbe, SR_47, RegSR47Value.Value, RegSR47Mask.Value); +} + + +static CBIOS_VOID cbDIU_HDAC_UpdateEldMemory(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_HDAC_PARA pCbiosHDACPara) +{ + PCBIOS_ELD_MEM_STRUCT pEld; + + pEld = cb_AllocateNonpagedPool(sizeof(CBIOS_ELD_MEM_STRUCT)); + if (pEld == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: pEld allocate error.\n", FUNCTION_NAME)); + return; + } + + /* Get ELD data from the sink device base EDID */ + cbGetDeviceELD(pcbe, pCbiosHDACPara->DeviceId, pEld); + + /* + * according to win8 spec: + * "Matching up Container ID for Audio and Video in Windows_Partner-120106.pdf" + * using PortID to group monitors embedded audio, + * + * which you can see them in: + * 'control panel'->'all control panel items'->'Devices and Printers' + */ + if ((pCbiosHDACPara->ManufacturerName == 0) && (pCbiosHDACPara->ProductCode == 0)) + { + /* for compatible for win7 */ + pEld->ELD_Data.Port_ID.HighPart = 0; /* hAdapter->AdapterLUID.HighPart; */ + pEld->ELD_Data.Port_ID.LowPart = 0; /* hAdapter->AdapterLUID.LowPart */ + } + else + { + /* for win8 which its new DDI pass one param like 'ELD Info' to cbios to overwrite hardware ELD PortID.*/ + cb_memcpy(&(pEld->ELD_Data.Port_ID), &pCbiosHDACPara->PortId, 8); + cb_memcpy(&(pEld->ELD_Data.ManufactureName), &pCbiosHDACPara->ManufacturerName, 2); + cb_memcpy(&(pEld->ELD_Data.ProductCode), &pCbiosHDACPara->ProductCode, 2); + } + + cbDIU_HDAC_WriteFIFO(pcbe, (CBIOS_ACTIVE_TYPE)pCbiosHDACPara->DeviceId, pEld); + cb_FreePool(pEld); +} + +CBIOS_VOID cbDIU_HDAC_SetConnectStatus(PCBIOS_VOID pvcbe, PCBIOS_HDAC_PARA pCbiosHDACPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + //cbDIU_HDAC_DevicesSwitchPatched(pcbe, pCbiosHDACPara); + /* + *1,use cbios macro 'SIZEOF_STRUCT_TILL_MEMBER'to avoid overborder + *2, check the value of BIT31, if it equal TRUE,and the flag of bPresent=TRUE; + * we should always update ELD Info first. + *3, set BIT31, and BIT30, according to flags 'bPresent & bEldValid' + */ + if(pCbiosHDACPara->bPresent == CBIOS_TRUE) + { + cbDIU_HDAC_UpdateEldMemory(pcbe, pCbiosHDACPara); + } + + cbDIU_HDAC_UpdateEldStatus(pcbe, pCbiosHDACPara); +} + diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDAC.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDAC.h new file mode 100644 index 0000000000000..9625e128d5672 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDAC.h @@ -0,0 +1,70 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** Audio codec hw block interface function prototype and parameter definition. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_DIU_HDAC_H_ +#define _CBIOS_DIU_HDAC_H_ + +#include "../../Device/CBiosDeviceShare.h" + +#define HDAC_MODU_NUM 2 + +extern CBIOS_U32 HDAC_REG_PACKET1[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_PACKET2[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_MODE_RESP[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_SW_RESP[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_CHSTATUS_CTRL[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_SUP_PARA[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_SAMP_RATE[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_CONVERT_CAP[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_PIN_WIDGET_CAP[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_PIN_SENSE[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_ELD_BUF[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_CTRL_WRITE[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_READ_SEL[HDAC_MODU_NUM]; +extern CBIOS_U32 HDAC_REG_READ_OUT[HDAC_MODU_NUM]; + +typedef struct _AUDIO_CLOCK_TABLE +{ + CBIOS_U32 StreamFormat; + CBIOS_U64 AudioPacketClock; +}AUDIO_CLOCK_TABLE,*PAUDIO_CLOCK_TABLE; + +typedef union _HDAC_NONSNOOP_SETTING +{ + CBIOS_U16 NonSnoopFlags; + struct + { + CBIOS_U16 bStreamNonSnoop :1; + CBIOS_U16 bBDLNonSnoop :1; + CBIOS_U16 bCORBNonSnoop :1; + CBIOS_U16 bRIRBNonSnoop :1; + CBIOS_U16 bDMAPositionNonSnoop :1; + CBIOS_U16 Reserved :11; + }; +}HDAC_NONSNOOP_SETTING,*PHDAC_NONSNOOP_SETTING; + +CBIOS_VOID cbDIU_HDAC_SetHDACodecPara(PCBIOS_VOID pvcbe, PCBIOS_HDAC_PARA pCbiosHDACPara); +CBIOS_VOID cbDIU_HDAC_SetStatus(PCBIOS_VOID pvcbe); +CBIOS_U32 cbDIU_HDAC_GetChannelNums(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDACModuleIndex); +CBIOS_VOID cbDIU_HDAC_SetConnectStatus(PCBIOS_VOID pvcbe, PCBIOS_HDAC_PARA pCbiosHDACPara); +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDCP.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDCP.c new file mode 100644 index 0000000000000..c6fa3eee9421a --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDCP.c @@ -0,0 +1,1857 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** HDCP hw block interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosDIU_HDCP.h" +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" + +// for CTS in Quantum Data 980 +CBIOS_U8 Fake_RevokedBksv[3][5] = +{ + {0x23, 0xde, 0x5c, 0x43, 0x93}, + {0x10, 0x43, 0x44, 0x4f, 0x51}, + {0x0b, 0x37, 0x21, 0xb4, 0x7d}, +}; + + +// for internal test +#define HDCP_USE_TEST_KEY 0 + +CBIOS_U32 HDCP_REG_KSV1[HDCP_MODU_NUM] = {0x82B0, 0x33C5C, 0x3435C, 0x34A5C}; +CBIOS_U32 HDCP_REG_CTRL_KSV[HDCP_MODU_NUM] = {0x82B4, 0x33C60, 0x34360, 0x34A60}; +CBIOS_U32 HDCP_REG_CTRL2[HDCP_MODU_NUM] = {0x82B8, 0x33C64, 0x34364, 0x34A64}; +CBIOS_U32 HDCP_REG_MISC1[HDCP_MODU_NUM] = {0x82C4, 0x33C6C, 0x3436C, 0x34A6C}; +CBIOS_U32 HDCP_REG_MISC2[HDCP_MODU_NUM] = {0x82C8, 0x33C70, 0x34370, 0x34A70}; +CBIOS_U32 HDCP_REG_2XHDMI_CTRL[HDCP_MODU_NUM] = {0x33680, 0x33C80, 0x34380, 0x34A80}; +CBIOS_U32 HDCP_REG_2XCTRL[HDCP_MODU_NUM] = {0x33688, 0x33C84, 0x34384, 0x34A84}; +CBIOS_U32 HDCP_REG_2XINT[HDCP_MODU_NUM] = {0x3368C, 0x33C88, 0x34388, 0x34A88}; +CBIOS_U32 HDCP_REG_DP_KSV1[HDCP_MODU_NUM] = {0x8370, 0x33C74, 0x34374, 0x34A74}; +CBIOS_U32 HDCP_REG_DP_CTRL_KSV[HDCP_MODU_NUM] = {0x8374, 0x33C78, 0x34378, 0x34A78}; +CBIOS_U32 HDCP_REG_DP_CTRL2[HDCP_MODU_NUM] = {0x8378, 0x33C7C, 0x3437C, 0x34A7C}; +CBIOS_U32 HDCP_REG_2XDP_CTRL[HDCP_MODU_NUM] = {0x33684, 0x33C90, 0x34390, 0x34A90}; + +#define GET_HDCP_CONTEXT(pvcbe, Device) cbHDCP_GetContext(pvcbe, Device) +static PCBIOS_HDCP_CONTEXT cbHDCP_GetContext(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + + return pDevCommon->pHDCPContext; +} + +static CBIOS_BOOL cbHDCP_CheckRevokedBksv(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_U8 pBksvList, CBIOS_U32 BufferSize1, + PCBIOS_U8 pRevocationList, CBIOS_U32 BufferSize2) +{ + CBIOS_BOOL bRevoked = CBIOS_FALSE; + CBIOS_U32 i, j; + + if ((pRevocationList == CBIOS_NULL) || (pBksvList == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pRevocationList or pBksvList is NULL!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + if ((BufferSize1 == 0) || (BufferSize1 % 5 != 0) || (BufferSize2 == 0) || (BufferSize2 % 5 != 0)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid buffer size!\n", FUNCTION_NAME)); + return CBIOS_TRUE; + } + + for (j = 0; j < BufferSize1/5; j++) + { + for (i = 0; i < BufferSize2/5; i++) + { + if ((pBksvList[j * 5] == pRevocationList[i * 5]) && + (pBksvList[j * 5 + 1] == pRevocationList[i * 5 + 1]) && + (pBksvList[j * 5 + 2] == pRevocationList[i * 5 + 2]) && + (pBksvList[j * 5 + 3] == pRevocationList[i * 5 + 3]) && + (pBksvList[j * 5 + 4] == pRevocationList[i * 5 + 4])) + { + bRevoked = CBIOS_TRUE; + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Bksv: 0x%02x%02x%02x%02x%02x\n", FUNCTION_NAME, + pBksvList[j * 5], pBksvList[j * 5 + 1], pBksvList[j * 5 + 2], pBksvList[j * 5 + 3], pBksvList[j * 5 + 4])); + break; + } + } + + if (i != BufferSize2/5) + { + break; + } + } + + return bRevoked; +} + +static CBIOS_VOID cbDIU_HDMI_HDCP_EncryptionEnableDisable(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_BOOL bEnable) +{ + REG_MM82C4 HDCPMisc1RegValue, HDCPMisc1RegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPMisc1RegValue.Value = 0; + HDCPMisc1RegValue.CTL = bEnable ? 9 : 1; + HDCPMisc1RegMask.Value = 0xFFFFFFFF; + HDCPMisc1RegMask.CTL = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_MISC1[HDCPModuleIndex], HDCPMisc1RegValue.Value, HDCPMisc1RegMask.Value); +} + +static CBIOS_VOID cbDIU_HDMI_HDCP_ReadBksv(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, PCBIOS_U8 pBksv) +{ + REG_MM82B0 HDCPKsv1RegValue; + REG_MM82B4 HDCPCtrlKsvRegValue; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + if (pBksv == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pBksv is NULL!\n", FUNCTION_NAME)); + return; + } + + HDCPKsv1RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_KSV1[HDCPModuleIndex]); + HDCPCtrlKsvRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_CTRL_KSV[HDCPModuleIndex]); + + pBksv[1] = (CBIOS_U8)HDCPKsv1RegValue.KSV_39to8; + pBksv[2] = (CBIOS_U8)(HDCPKsv1RegValue.KSV_39to8 >> 8); + pBksv[3] = (CBIOS_U8)(HDCPKsv1RegValue.KSV_39to8 >> 16); + pBksv[4] = (CBIOS_U8)(HDCPKsv1RegValue.KSV_39to8 >> 24); + pBksv[0] = (CBIOS_U8)HDCPCtrlKsvRegValue.KSV_7to0; + + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Bksv: 0x%08x%02x\n", FUNCTION_NAME, HDCPKsv1RegValue.KSV_39to8, HDCPCtrlKsvRegValue.KSV_7to0)); +} + +static CBIOS_BOOL cbDIU_HDMI_HDCP_IsBKSVReady(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM82B8 HDCPCtrl2RegValue; + CBIOS_U32 wait_us = 10, timeout = 250000, count = 0; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + while(1) + { + HDCPCtrl2RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_CTRL2[HDCPModuleIndex]); + if (HDCPCtrl2RegValue.KSV_Verification_Done) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "wait times %d\n", count)); + break; + } + + cb_DelayMicroSeconds(wait_us); + + count++; + if (count > timeout) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: wait time out\n", FUNCTION_NAME)); + break; + } + } + + return HDCPCtrl2RegValue.KSV_Verification_Done ? CBIOS_TRUE : CBIOS_FALSE; +} + +static CBIOS_VOID cbDIU_HDMI_HDCP_RevocationCheckDoneAck(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM82B8 HDCPCtrl2RegValue, HDCPCtrl2RegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPCtrl2RegValue.Value = 0; + HDCPCtrl2RegValue.KSV_Verification_Done = 0; + HDCPCtrl2RegMask.Value = 0xFFFFFFFF; + HDCPCtrl2RegMask.KSV_Verification_Done = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_CTRL2[HDCPModuleIndex], HDCPCtrl2RegValue.Value, HDCPCtrl2RegMask.Value); +} + +static CBIOS_VOID cbDIU_HDMI_HDCP1x_Isr(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + PCBIOS_HDCP_CONTEXT pHdcpContext = GET_HDCP_CONTEXT(pcbe, Device); + REG_MM82C4 HDCPMisc1RegValue; + CBIOS_U32 HDCPIntSource; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPMisc1RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_MISC1[HDCPModuleIndex]); + HDCPIntSource = HDCPMisc1RegValue.Interrupt_Source; + + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Interrupt_Source = %d\n", FUNCTION_NAME, HDCPIntSource)); + + switch (HDCPIntSource) + { + case CBIOS_HDMI_HDCP1x_INT_KSV_READY: + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: BKSV ready\n", FUNCTION_NAME)); + if (cbDIU_HDMI_HDCP_IsBKSVReady(pcbe, HDCPModuleIndex)) + { + cbDIU_HDMI_HDCP_ReadBksv(pcbe, HDCPModuleIndex, pHdcpContext->BKsv); + } + if(cbHDCP_CheckRevokedBksv(pcbe, pHdcpContext->BKsv, 5, + pHdcpContext->pRevocationList, pHdcpContext->RevocationListBufferSize)) + { + //cbHDCP_OnOff(pcbe, Device, IGAIndex, CBIOS_FALSE); + //pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + } + else + { + cbDIU_HDMI_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + } + break; + case CBIOS_HDMI_HDCP1x_INT_AUTH_PASS: + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: authentication pass\n", FUNCTION_NAME)); + cbDIU_HDMI_HDCP_EncryptionEnableDisable(pcbe, HDCPModuleIndex, CBIOS_TRUE); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_PASS; + break; + case CBIOS_HDMI_HDCP1x_INT_MAX_CASCADE: + case CBIOS_HDMI_HDCP1x_INT_MAX_DEVICES: + case CBIOS_HDMI_HDCP1x_INT_AUTH_FAIL: + case CBIOS_HDMI_HDCP1x_INT_Ri_VERIF_FAIL: + case CBIOS_HDMI_HDCP1x_INT_ZERO_DEVICE: + case CBIOS_HDMI_HDCP1x_INT_BKSV_INVALID: + case CBIOS_HDMI_HDCP1x_INT_V_LIST_CHECK_FAIL: + case CBIOS_HDMI_HDCP1x_INT_Ri_VERIF_TIMEOUT: + case CBIOS_HDMI_HDCP1x_INT_Pj_VERIF_FAIL: + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: %d verification fail\n", FUNCTION_NAME, HDCPIntSource)); + cbDIU_HDMI_HDCP_EncryptionEnableDisable(pcbe, HDCPModuleIndex, CBIOS_FALSE); +#ifndef UEFI_DIAGTOOL + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_FALSE); + cbDelayMilliSeconds(1500); + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_TRUE); +#else + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_FALSE, 1); + cbDelayMilliSeconds(1500); + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_TRUE, 1); +#endif + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + break; + } +} + +static CBIOS_VOID cbDIU_HDMI_HDCP1x_OnOff(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_BOOL bTurnOn) +{ + REG_MM82B4 HDCPCtrlKsvRegValue, HDCPCtrlKsvRegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPCtrlKsvRegValue.Value = 0x0; + HDCPCtrlKsvRegValue.CP_EN = bTurnOn ? 1 : 0; + HDCPCtrlKsvRegMask.Value = 0xFFFFFFFF; + HDCPCtrlKsvRegMask.CP_EN = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_CTRL_KSV[HDCPModuleIndex], HDCPCtrlKsvRegValue.Value, HDCPCtrlKsvRegMask.Value); +} + +static CBIOS_BOOL cbDIU_HDMI_HDCP1x_IsEnabled(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM82B4 HDCPCtrlKsvRegValue; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + HDCPCtrlKsvRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_CTRL_KSV[HDCPModuleIndex]); + + return HDCPCtrlKsvRegValue.CP_EN ? CBIOS_TRUE : CBIOS_FALSE; +} + +static CBIOS_VOID cbDIU_HDMI_HDCP2x_OnOff(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_BOOL bTurnOn) +{ + REG_MM33680 HDCP2xHDMICtrlRegValue, HDCP2xHDMICtrlRegMask; + REG_MM33688 HDCP2xCtrlRegValue, HDCP2xCtrlRegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + if (bTurnOn) + { + HDCP2xHDMICtrlRegValue.Value = 0; + HDCP2xHDMICtrlRegValue.STREAM_ID = 0; + HDCP2xHDMICtrlRegValue.STREAM_TYPE = 0; + HDCP2xHDMICtrlRegValue.RNG_OSC_MD = 0; + HDCP2xHDMICtrlRegValue.RNG_OSC_EN_HDCP = 1; + HDCP2xHDMICtrlRegValue.RNG_EN_HDCP = 1; + + HDCP2xHDMICtrlRegValue.HDCP22_AUTH_SEL = 0; // disable HDCP 2.2 re-authentication reattemp + HDCP2xHDMICtrlRegValue.HDCP22_AUTH_TRIG = 1; + + HDCP2xHDMICtrlRegValue.CSM_TRIGGER = 1; + HDCP2xHDMICtrlRegValue.AKE_Stored_km_DIS = 0; // enable AKE_Stored_Km + HDCP2xHDMICtrlRegValue.HDCP22_VER_RD_DIS = 0; // read HDCP 2.2 version before enable HDCP 2.2 + HDCP2xHDMICtrlRegValue.TEST_MODE = 0; + HDCP2xHDMICtrlRegValue.TEST_REPEATER = 0; + HDCP2xHDMICtrlRegValue.CONT_STREAM_EN = 1; + HDCP2xHDMICtrlRegValue.HDCP22_CP_EN = 1; + HDCP2xHDMICtrlRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_2XHDMI_CTRL[HDCPModuleIndex], HDCP2xHDMICtrlRegValue.Value, HDCP2xHDMICtrlRegMask.Value); + + // HDCP 2.2 TX must set VERSION to 0x02 + HDCP2xCtrlRegValue.Value = 0; + HDCP2xCtrlRegValue.TxCaps = 0x020000; + HDCP2xCtrlRegMask.Value = 0xFFFFFFFF; + HDCP2xCtrlRegMask.TxCaps = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_2XCTRL[HDCPModuleIndex], HDCP2xCtrlRegValue.Value, HDCP2xCtrlRegMask.Value); + } + else + { + HDCP2xHDMICtrlRegValue.Value = 0; + HDCP2xHDMICtrlRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_2XHDMI_CTRL[HDCPModuleIndex], HDCP2xHDMICtrlRegValue.Value, HDCP2xHDMICtrlRegMask.Value); + } +} + +static CBIOS_BOOL cbDIU_HDMI_HDCP2x_IsEnabled(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM33680 HDCP2xHDMICtrlRegValue; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + HDCP2xHDMICtrlRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_2XHDMI_CTRL[HDCPModuleIndex]); + + return HDCP2xHDMICtrlRegValue.HDCP22_CP_EN ? CBIOS_TRUE : CBIOS_FALSE; +} + +static CBIOS_VOID cbDIU_HDMI_HDCP_ChooseProtocol(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, + CBIOS_U8 IGAIndex, CBIOS_HDCP_VERSION HdcpVersion, CBIOS_BOOL bHDMI) +{ + REG_MM82B4 HDCPCtrlKsvRegValue, HDCPCtrlKsvRegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + // HDMI protocol + if (bHDMI) + { + HDCPCtrlKsvRegValue.Value = 0; + HDCPCtrlKsvRegValue.Source_Select = 2; // HDMI + HDCPCtrlKsvRegValue.Mode_Sel = 1; + HDCPCtrlKsvRegValue.AC_EN = 0; + HDCPCtrlKsvRegValue.Verify_Pj_Enable = 0; + HDCPCtrlKsvRegValue.EESS_Signaling_Select = 1; + HDCPCtrlKsvRegMask.Value = 0xFFFFFFFF; + HDCPCtrlKsvRegMask.Source_Select = 0; + HDCPCtrlKsvRegMask.Mode_Sel = 0; + HDCPCtrlKsvRegMask.AC_EN = 0; + HDCPCtrlKsvRegMask.Verify_Pj_Enable = 0; + HDCPCtrlKsvRegMask.EESS_Signaling_Select = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_CTRL_KSV[HDCPModuleIndex], HDCPCtrlKsvRegValue.Value, HDCPCtrlKsvRegMask.Value); + } + // DVI protocol + else + { + HDCPCtrlKsvRegValue.Value = 0; + HDCPCtrlKsvRegValue.Source_Select = 0; // SP1 + + HDCPCtrlKsvRegValue.Mode_Sel = 0; + HDCPCtrlKsvRegValue.AC_EN = 0; + HDCPCtrlKsvRegValue.Verify_Pj_Enable = 0; + if (HdcpVersion == CBIOS_HDCP_VERSION_1x) + { + HDCPCtrlKsvRegValue.EESS_Signaling_Select = 0; // OESS + } + else if (HdcpVersion == CBIOS_HDCP_VERSION_2x) + { + // NOTE: for HDCP 2.2, only support EESS for DVI + HDCPCtrlKsvRegValue.EESS_Signaling_Select = 1; // EESS + } + HDCPCtrlKsvRegMask.Value = 0xFFFFFFFF; + HDCPCtrlKsvRegMask.Source_Select = 0; + HDCPCtrlKsvRegMask.Mode_Sel = 0; + HDCPCtrlKsvRegMask.AC_EN = 0; + HDCPCtrlKsvRegMask.Verify_Pj_Enable = 0; + HDCPCtrlKsvRegMask.EESS_Signaling_Select = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_CTRL_KSV[HDCPModuleIndex], HDCPCtrlKsvRegValue.Value, HDCPCtrlKsvRegMask.Value); + } +} + +static CBIOS_VOID cbDIU_HDMI_HDCP_RevocationCheckEnableDisable(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_BOOL bEnable) +{ + REG_MM82B8 HDCPCtrl2RegValue, HDCPCtrl2RegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPCtrl2RegValue.Value = 0; + HDCPCtrl2RegValue.KSV_Revocation_List_Available = bEnable ? 1 : 0; + HDCPCtrl2RegMask.Value = 0xFFFFFFFF; + HDCPCtrl2RegMask.KSV_Revocation_List_Available = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_CTRL2[HDCPModuleIndex], HDCPCtrl2RegValue.Value, HDCPCtrl2RegMask.Value); +} + +static CBIOS_U8 cbDIU_HDMI_HDCP_GetDeviceCount(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM82C4 HDCPMisc1RegValue; + CBIOS_U8 DeviceCount = 0; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return 0; + } + + // NOTE: + // HDCP 1.4 BKSV list HW fifo is 4 * BKSV. So supports repeater with maximum 4 receivers connected. + // HDCP 2.2 BKSV list HW fifo is 31 * BKSV. So supports repeater with maximum 31 receivers connected. + HDCPMisc1RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_MISC1[HDCPModuleIndex]); + DeviceCount = (CBIOS_U8)HDCPMisc1RegValue.Device_Count; + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Device Count = %d\n", FUNCTION_NAME, DeviceCount)); + + return DeviceCount; +} + +static CBIOS_VOID cbDIU_HDMI_HDCP_ReadBksvList(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, + PCBIOS_U8 pBksvList, CBIOS_U8 DeviceCount) +{ + CBIOS_U32 i; + + if (HDCPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + if (DeviceCount == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: no receiver connected\n", FUNCTION_NAME)); + return; + } + + if (pBksvList == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pBksvList is NULL!\n", FUNCTION_NAME)); + return; + } + + for (i = 0; i < DeviceCount; i++) + { + if (cbDIU_HDMI_HDCP_IsBKSVReady(pcbe, HDCPModuleIndex)) + { + cbDIU_HDMI_HDCP_ReadBksv(pcbe, HDCPModuleIndex, pBksvList + i * 5); + cbDIU_HDMI_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + } + else + { + return; + } + } +} + +static CBIOS_BOOL cbDIU_HDMI_HDCP_CheckIfRepeater(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM82C4 HDCPMisc1RegValue; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + HDCPMisc1RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_MISC1[HDCPModuleIndex]); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: repeater = %d\n", FUNCTION_NAME, HDCPMisc1RegValue.Repeater_Flag)); + + return HDCPMisc1RegValue.Repeater_Flag ? CBIOS_TRUE : CBIOS_FALSE; +} + +static CBIOS_VOID cbDIU_HDMI_HDCP_HwI2cOnOff(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_U8 I2CBus, CBIOS_BOOL bTurnOn) +{ + CBIOS_MODULE_I2C_PARAMS I2CParams = {0}; + REG_MM82B8 HDCPCtrl2RegValue, HDCPCtrl2RegMask; + REG_MM82C4 HDCPMisc1RegValue, HDCPMisc1RegMask; + REG_CRAA RegCRAAValue, RegCRAAMask; + REG_CRC6_B RegCRC6_BValue, RegCRC6_BMask; + REG_CRF8_B RegCRF8_BValue, RegCRF8_BMask; + REG_CRC5_B RegCRC5_BValue, RegCRC5_BMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + I2CParams.ConfigType = CONFIG_I2C_BY_BUSNUM; + I2CParams.I2CBusNum = I2CBus; + + RegCRAAValue.Value = 0; + RegCRAAMask.Value = 0xFF; + RegCRC6_BValue.Value = 0; + RegCRC6_BMask.Value = 0xFF; + + // config I2C module for HDMI + if (bTurnOn) + { + // Enable I2C bus + cbI2CModule_HDCPI2CEnableDisable(pcbe, &I2CParams, CBIOS_TRUE); + + // Write I2C bus number used for HDCP + if (HDCPModuleIndex == CBIOS_MODULE_INDEX1) + { + RegCRAAValue.HDCP1_I2C_port_selection = (I2CParams.I2CBusNum & 0x03); + RegCRAAMask.HDCP1_I2C_port_selection = 0; + cbMMIOWriteReg(pcbe, CR_AA, RegCRAAValue.Value, RegCRAAMask.Value); + } + else if (HDCPModuleIndex == CBIOS_MODULE_INDEX2) + { + RegCRC6_BValue.HDCP2_I2C_port_selection = (I2CParams.I2CBusNum & 0x03); + RegCRC6_BMask.HDCP2_I2C_port_selection = 0; + cbMMIOWriteReg(pcbe, CR_B_C6, RegCRC6_BValue.Value, RegCRC6_BMask.Value); + } + else if (HDCPModuleIndex == CBIOS_MODULE_INDEX3) + { + RegCRF8_BValue.HDCP3_I2C_port_selection = (I2CParams.I2CBusNum & 0x03); + RegCRF8_BMask.HDCP3_I2C_port_selection = 0; + cbMMIOWriteReg(pcbe, CR_B_F8, RegCRF8_BValue.Value, RegCRF8_BMask.Value); + } + else if (HDCPModuleIndex == CBIOS_MODULE_INDEX4) + { + RegCRC5_BValue.HDCP4_I2C_port_selection = (I2CParams.I2CBusNum & 0x03); + RegCRC5_BMask.HDCP4_I2C_port_selection = 0; + cbMMIOWriteReg(pcbe, CR_B_C5, RegCRC5_BValue.Value, RegCRC5_BMask.Value); + } + + HDCPMisc1RegValue.Value = 0; + HDCPMisc1RegValue.I2C_Frequency_Sleect = CBIOS_HW_I2C_Freq_200kHz; + HDCPMisc1RegValue.AUTH_FAIL_INT_SEL = 1; + HDCPMisc1RegMask.Value = 0xFFFFFFFF; + HDCPMisc1RegMask.I2C_Frequency_Sleect = 0; + HDCPMisc1RegMask.AUTH_FAIL_INT_SEL = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_MISC1[HDCPModuleIndex], HDCPMisc1RegValue.Value, HDCPMisc1RegMask.Value); + + // enable HDCP I2C function. + HDCPCtrl2RegValue.Value = 0x0; + HDCPCtrl2RegValue.HDCP_I2C_Function_Enable = 1; + HDCPCtrl2RegMask.Value = 0xFFFFFFFF; + HDCPCtrl2RegMask.HDCP_I2C_Function_Enable = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_CTRL2[HDCPModuleIndex], HDCPCtrl2RegValue.Value, HDCPCtrl2RegMask.Value); + } + else + { + // disable HDCP I2C function. + HDCPCtrl2RegValue.Value = 0x0; + HDCPCtrl2RegValue.HDCP_I2C_Function_Enable = 0; + HDCPCtrl2RegMask.Value = 0xFFFFFFFF; + HDCPCtrl2RegMask.HDCP_I2C_Function_Enable = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_CTRL2[HDCPModuleIndex], HDCPCtrl2RegValue.Value, HDCPCtrl2RegMask.Value); + + cbI2CModule_HDCPI2CEnableDisable(pcbe, &I2CParams, CBIOS_FALSE); + } +} + +#if HDCP_USE_TEST_KEY +// for internal test +static CBIOS_VOID cbDIU_HDMI_HDCP_TestKeyEnableDisable(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_BOOL bEnable) +{ + REG_MM82B4 HDCPCtrlKsvRegValue, HDCPCtrlKsvRegMask; + REG_MM82C8 HDCPMisc2RegValue, HDCPMisc2RegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPMisc2RegValue.Value = 0; + HDCPMisc2RegValue.reserved = bEnable ? 1 : 0; // bit27 = 1 + HDCPMisc2RegMask.Value = 0xFFFFFFFF; + HDCPMisc2RegMask.reserved = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_MISC2[CBIOS_MODULE_INDEX1], HDCPMisc2RegValue.Value, HDCPMisc2RegMask.Value); + + HDCPCtrlKsvRegValue.Value = 0; + HDCPCtrlKsvRegValue.Test_Key_Enable = bEnable ? 1 : 0; // bit26 = 1 + HDCPCtrlKsvRegMask.Value = 0xFFFFFFFF; + HDCPCtrlKsvRegMask.Test_Key_Enable = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_CTRL_KSV[CBIOS_MODULE_INDEX1], HDCPCtrlKsvRegValue.Value, HDCPCtrlKsvRegMask.Value); +} + +#endif + +static CBIOS_VOID cbDIU_DP_HDCP_RevocationCheckEnableDisable(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_BOOL bEnable) +{ + REG_MM8374 HDCPDPCtrlKsvRegValue, HDCPDPCtrlKsvRegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPDPCtrlKsvRegValue.Value = 0x0; + HDCPDPCtrlKsvRegValue.KSV_Rev_List = bEnable ? 1 : 0; + HDCPDPCtrlKsvRegMask.Value = 0xFFFFFFFF; + HDCPDPCtrlKsvRegMask.KSV_Rev_List = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_DP_CTRL_KSV[HDCPModuleIndex], HDCPDPCtrlKsvRegValue.Value, HDCPDPCtrlKsvRegMask.Value); +} + +static CBIOS_VOID cbDIU_DP_HDCP_RevocationCheckDoneAck(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM8374 HDCPDPCtrlKsvRegValue, HDCPDPCtrlKsvRegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPDPCtrlKsvRegValue.Value = 0x0; + HDCPDPCtrlKsvRegValue.KSV_Verifcation_Done = 0; + HDCPDPCtrlKsvRegMask.Value = 0xFFFFFFFF; + HDCPDPCtrlKsvRegMask.KSV_Verifcation_Done = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_DP_CTRL_KSV[HDCPModuleIndex], HDCPDPCtrlKsvRegValue.Value, HDCPDPCtrlKsvRegMask.Value); +} + +static CBIOS_BOOL cbDIU_DP_HDCP_IsBKSVReady(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM8374 HDCPDPCtrlKsvRegValue; + CBIOS_U32 wait_us = 10, timeout = 10000, count = 0; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + while(1) + { + HDCPDPCtrlKsvRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_DP_CTRL_KSV[HDCPModuleIndex]); + if (HDCPDPCtrlKsvRegValue.KSV_Verifcation_Done) + { + break; + } + + cb_DelayMicroSeconds(wait_us); + + count++; + if (count > timeout) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: wait time out\n", FUNCTION_NAME)); + break; + } + } + + return HDCPDPCtrlKsvRegValue.KSV_Verifcation_Done ? CBIOS_TRUE : CBIOS_FALSE; +} + +static CBIOS_VOID cbDIU_DP_HDCP_ReadBksv(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, PCBIOS_U8 pBksv) +{ + REG_MM8370 HDCPDPKsv1RegValue; + REG_MM8374 HDCPDPCtrlKsvRegValue; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + if (pBksv == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pBksv is NULL!\n", FUNCTION_NAME)); + return; + } + + HDCPDPKsv1RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_DP_KSV1[HDCPModuleIndex]); + HDCPDPCtrlKsvRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_DP_CTRL_KSV[HDCPModuleIndex]); + + pBksv[1] = (CBIOS_U8)HDCPDPKsv1RegValue.KSV_39to8; + pBksv[2] = (CBIOS_U8)(HDCPDPKsv1RegValue.KSV_39to8 >> 8); + pBksv[3] = (CBIOS_U8)(HDCPDPKsv1RegValue.KSV_39to8 >> 16); + pBksv[4] = (CBIOS_U8)(HDCPDPKsv1RegValue.KSV_39to8 >> 24); + pBksv[0] = (CBIOS_U8)HDCPDPCtrlKsvRegValue.KSV_7to0; + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Bksv: 0x%08x%02x\n", FUNCTION_NAME, HDCPDPKsv1RegValue.KSV_39to8, HDCPDPCtrlKsvRegValue.KSV_7to0)); +} + +static CBIOS_VOID cbDIU_DP_HDCP_EncryptionEnableDisable(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_BOOL bEnable) +{ + REG_MM8374 HDCPDPCtrlKsvRegValue, HDCPDPCtrlKsvRegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPDPCtrlKsvRegValue.Value = 0x0; + HDCPDPCtrlKsvRegValue.Enc_Sel = 0; // when authentication fails, HW disables encryption + HDCPDPCtrlKsvRegValue.Enc_Con = bEnable ? 1 : 0; + HDCPDPCtrlKsvRegMask.Value = 0xFFFFFFFF; + HDCPDPCtrlKsvRegMask.Enc_Sel = 0; + HDCPDPCtrlKsvRegMask.Enc_Con = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_DP_CTRL_KSV[HDCPModuleIndex], HDCPDPCtrlKsvRegValue.Value, HDCPDPCtrlKsvRegMask.Value); +} + +static CBIOS_VOID cbDIU_DP_HDCP1x_Isr(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + PCBIOS_HDCP_CONTEXT pHdcpContext = GET_HDCP_CONTEXT(pcbe, Device); + REG_MM8378 HDCPDPCtrl2RegValue; + CBIOS_U32 HDCPDPIntSource; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPDPCtrl2RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_DP_CTRL2[HDCPModuleIndex]); + HDCPDPIntSource = HDCPDPCtrl2RegValue.Interrupt_Source; + + switch (HDCPDPIntSource) + { + case CBIOS_DP_HDCP1x_INT_KSV_READY: + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: BKSV ready\n", FUNCTION_NAME)); + if (cbDIU_DP_HDCP_IsBKSVReady(pcbe, HDCPModuleIndex)) + { + cbDIU_DP_HDCP_ReadBksv(pcbe, HDCPModuleIndex, pHdcpContext->BKsv); + } + if(cbHDCP_CheckRevokedBksv(pcbe, pHdcpContext->BKsv, 5, + pHdcpContext->pRevocationList, pHdcpContext->RevocationListBufferSize)) + { + //cbHDCP_OnOff(pcbe, Device, IGAIndex, CBIOS_FALSE); + //pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + } + else + { + cbDIU_DP_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + } + break; + case CBIOS_DP_HDCP1x_INT_AUTH_PASS: + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: authentication pass\n", FUNCTION_NAME)); + cbDIU_DP_HDCP_EncryptionEnableDisable(pcbe, HDCPModuleIndex, CBIOS_TRUE); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_PASS; + break; + case CBIOS_DP_HDCP1x_INT_BKSV_INVALID: + case CBIOS_DP_HDCP1x_INT_V_LIST_CHECK_FAIL: + case CBIOS_DP_HDCP1x_INT_AUTH_FAIL: + case CBIOS_DP_HDCP1x_INT_AUX_FAIL: + case CBIOS_DP_HDCP1x_INT_NOT_HDCP_CAPABLE: + case CBIOS_DP_HDCP1x_INT_RO_INVALID: + case CBIOS_DP_HDCP1x_INT_KSV_VERIF_TIMEOUT: + case CBIOS_DP_HDCP1x_INT_MAX_CASCADE: + case CBIOS_DP_HDCP1x_INT_MAX_DEVS: + case CBIOS_DP_HDCP1x_INT_ZERO_DEVS: + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: %d verification fail\n", FUNCTION_NAME, HDCPDPIntSource)); + cbDIU_DP_HDCP_EncryptionEnableDisable(pcbe, HDCPModuleIndex, CBIOS_FALSE); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + break; + } +} + +static CBIOS_VOID cbDIU_DP_HDCP1x_OnOff(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_BOOL bTurnOn) +{ + REG_MM8374 HDCPDPCtrlKsvRegValue, HDCPDPCtrlKsvRegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPDPCtrlKsvRegValue.Value = 0x0; + HDCPDPCtrlKsvRegValue.CP_EN = bTurnOn ? 1 : 0; + HDCPDPCtrlKsvRegMask.Value = 0xFFFFFFFF; + HDCPDPCtrlKsvRegMask.CP_EN = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_DP_CTRL_KSV[HDCPModuleIndex], HDCPDPCtrlKsvRegValue.Value, HDCPDPCtrlKsvRegMask.Value); +} + +static CBIOS_BOOL cbDIU_DP_HDCP1x_IsEnabled(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM8374 HDCPDPCtrlKsvRegValue; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + HDCPDPCtrlKsvRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_DP_CTRL_KSV[HDCPModuleIndex]); + + return HDCPDPCtrlKsvRegValue.CP_EN ? CBIOS_TRUE : CBIOS_FALSE; +} + +static CBIOS_VOID cbDIU_DP_HDCP2x_OnOff(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_BOOL bTurnOn) +{ + REG_MM33684 HDCP2xDPCtrlRegValue, HDCP2xDPCtrlRegMask; + REG_MM33688 HDCP2xCtrlRegValue, HDCP2xCtrlRegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + if (bTurnOn) + { + HDCP2xDPCtrlRegValue.Value = 0; + //HDCP2xDPCtrlRegValue.DPHDCP22_AUTH_SEL = 1; // disable HDCP 2.2 re-authentication reattemp + //HDCP2xDPCtrlRegValue.DPHDCP22_AUTH_TRIG = 1; + HDCP2xDPCtrlRegValue.DPHDCP22_CSM_TRIGGER = 1; + HDCP2xDPCtrlRegValue.DPHDCP22_AKE_Stored_km_DIS = 0; + HDCP2xDPCtrlRegValue.DPHDCP22_CAP_EN = 1; + HDCP2xDPCtrlRegValue.DPHDCP22_CONT_STREAM_EN = 1; + HDCP2xDPCtrlRegValue.DPHDCP22_CP_EN = 1; + HDCP2xDPCtrlRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_2XDP_CTRL[HDCPModuleIndex], HDCP2xDPCtrlRegValue.Value, HDCP2xDPCtrlRegMask.Value); + + // HDCP 2.2 TX must set VERSION to 0x02 + HDCP2xCtrlRegValue.Value = 0; + HDCP2xCtrlRegValue.TxCaps = 0x020000; + HDCP2xCtrlRegMask.Value = 0xFFFFFFFF; + HDCP2xCtrlRegMask.TxCaps = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_2XCTRL[HDCPModuleIndex], HDCP2xCtrlRegValue.Value, HDCP2xCtrlRegMask.Value); + } + else + { + HDCP2xDPCtrlRegValue.Value = 0; + HDCP2xDPCtrlRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_2XDP_CTRL[HDCPModuleIndex], HDCP2xDPCtrlRegValue.Value, HDCP2xDPCtrlRegMask.Value); + } +} + +static CBIOS_BOOL cbDIU_DP_HDCP2x_IsEnabled(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM33684 HDCP2xDPCtrlRegValue; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + HDCP2xDPCtrlRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_2XDP_CTRL[HDCPModuleIndex]); + + return HDCP2xDPCtrlRegValue.DPHDCP22_CP_EN ? CBIOS_TRUE : CBIOS_FALSE; +} + +static CBIOS_VOID cbDIU_DP_HDCP_ReadBksvList(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, + PCBIOS_U8 pBksvList, CBIOS_U8 DeviceCount) +{ + CBIOS_U32 i; + + if (HDCPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + if (DeviceCount == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: no receiver connected\n", FUNCTION_NAME)); + return; + } + + if (pBksvList == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pBksvList is NULL!\n", FUNCTION_NAME)); + return; + } + + for (i = 0; i < DeviceCount; i++) + { + if (cbDIU_DP_HDCP_IsBKSVReady(pcbe, HDCPModuleIndex)) + { + cbDIU_DP_HDCP_ReadBksv(pcbe, HDCPModuleIndex, pBksvList + i * 5); + cbDIU_DP_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + } + else + { + return; + } + } +} + +static CBIOS_BOOL cbDIU_DP_HDCP_CheckIfRepeater(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM8378 HDCPDPCtrl2RegValue; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + HDCPDPCtrl2RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_DP_CTRL2[HDCPModuleIndex]); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: repeater = %d\n", FUNCTION_NAME, HDCPDPCtrl2RegValue.Repeater_Flag)); + + return HDCPDPCtrl2RegValue.Repeater_Flag ? CBIOS_TRUE : CBIOS_FALSE; +} + +#if 0 +static CBIOS_U8 cbDIU_DP_HDCP_GetDeviceCount(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM8378 HDCPDPCtrl2RegValue; + CBIOS_U8 DeviceCount = 0; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return 0; + } + + // NOTE: + // HDCP 1.4 BKSV list HW fifo is 4 * BKSV. So supports repeater with maximum 4 receivers connected. + // HDCP 2.2 BKSV list HW fifo is 31 * BKSV. So supports repeater with maximum 31 receivers connected. + HDCPDPCtrl2RegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_DP_CTRL2[HDCPModuleIndex]); + DeviceCount = (CBIOS_U8)HDCPDPCtrl2RegValue.Device_Count; + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Device Count = %d\n", FUNCTION_NAME, DeviceCount)); + + return DeviceCount; +} +#endif + +static CBIOS_VOID cbDIU_DP_HDCP_AuxOnOff(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_BOOL bTurnOn) +{ + REG_MM8374 HDCPDPCtrlKsvRegValue, HDCPDPCtrlKsvRegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + if (bTurnOn) + { + HDCPDPCtrlKsvRegValue.Value = 0x0; + HDCPDPCtrlKsvRegValue.AUX_Fail_Config = 6; // 15 failures + HDCPDPCtrlKsvRegValue.AUX_Def_Config = 3; // 7 defers + HDCPDPCtrlKsvRegValue.Disable_AUX = 0; + HDCPDPCtrlKsvRegMask.Value = 0xFFFFFFFF; + HDCPDPCtrlKsvRegMask.AUX_Fail_Config = 0; + HDCPDPCtrlKsvRegMask.AUX_Def_Config = 0; + HDCPDPCtrlKsvRegMask.Disable_AUX = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_DP_CTRL_KSV[HDCPModuleIndex], HDCPDPCtrlKsvRegValue.Value, HDCPDPCtrlKsvRegMask.Value); + } + else + { + HDCPDPCtrlKsvRegValue.Value = 0x0; + HDCPDPCtrlKsvRegValue.Disable_AUX = 1; + HDCPDPCtrlKsvRegMask.Value = 0xFFFFFFFF; + HDCPDPCtrlKsvRegMask.Disable_AUX = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_DP_CTRL_KSV[HDCPModuleIndex], HDCPDPCtrlKsvRegValue.Value, HDCPDPCtrlKsvRegMask.Value); + } +} + +#if HDCP_USE_TEST_KEY +// for internal test +static CBIOS_VOID cbDIU_DP_HDCP_TestKeyEnableDisable(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex, CBIOS_BOOL bEnable) +{ + REG_MM8374 HDCPDPCtrlKsvRegValue, HDCPDPCtrlKsvRegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPDPCtrlKsvRegValue.Value = 0x0; + HDCPDPCtrlKsvRegValue.Test_Key_Enable = 1; + HDCPDPCtrlKsvRegValue.DPHDCP_Test_Mode_Select = 1; + HDCPDPCtrlKsvRegMask.Value = 0xFFFFFFFF; + HDCPDPCtrlKsvRegMask.Test_Key_Enable = 0; + HDCPDPCtrlKsvRegMask.DPHDCP_Test_Mode_Select = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_DP_CTRL_KSV[HDCPModuleIndex], HDCPDPCtrlKsvRegValue.Value, HDCPDPCtrlKsvRegMask.Value); +} +#endif + +#if 0 +static CBIOS_VOID cbDIU_HDCP_SwReset(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM82C4 HDCPMisc1RegValue, HDCPMisc1RegMask; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + HDCPMisc1RegValue.Value = 0; + HDCPMisc1RegValue.HDCP_SW_Reset = 1; + HDCPMisc1RegMask.Value = 0xFFFFFFFF; + HDCPMisc1RegMask.HDCP_SW_Reset = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_MISC1[CBIOS_MODULE_INDEX1], HDCPMisc1RegValue.Value, HDCPMisc1RegMask.Value); + + cb_DelayMicroSeconds(5000);//delay 5ms + + HDCPMisc1RegValue.Value = 0; + HDCPMisc1RegValue.HDCP_SW_Reset = 0; + HDCPMisc1RegMask.Value = 0xFFFFFFFF; + HDCPMisc1RegMask.HDCP_SW_Reset = 0; + cbMMIOWriteReg32(pcbe, HDCP_REG_MISC1[CBIOS_MODULE_INDEX1], HDCPMisc1RegValue.Value, HDCPMisc1RegMask.Value); +} +#endif + +static CBIOS_U32 cbDIU_HDCP2x_ReadAndClearIntStatus(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + REG_MM3368C HDCP2xIntRegValue; + + if (HDCPModuleIndex >= HDCP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return 0; + } + + HDCP2xIntRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDCP_REG_2XINT[HDCPModuleIndex]); + // clear the interrupt + cb_WriteU32(pcbe->pAdapterContext, HDCP_REG_2XINT[HDCPModuleIndex], HDCP2xIntRegValue.Value); + + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: MM%x = 0x%x\n", FUNCTION_NAME, HDCP_REG_2XINT[HDCPModuleIndex], HDCP2xIntRegValue.Value)); + + return HDCP2xIntRegValue.Value; +} + +static CBIOS_VOID cbDIU_HDCP2x_Isr(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_MODULE_INDEX HDCPModuleIndex) +{ + PCBIOS_HDCP_CONTEXT pHdcpContext = GET_HDCP_CONTEXT(pcbe, Device); + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + CBIOS_U32 IntStatus = 0; + + if (HDCPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + //init value of authstatus + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_ENABLE; + + IntStatus = cbDIU_HDCP2x_ReadAndClearIntStatus(pcbe, HDCPModuleIndex); + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_I2C_FAIL) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: I2C interaction fail\n", FUNCTION_NAME)); + } + +#ifndef UEFI_DIAGTOOL + if (IntStatus & CBIOS_HDCP2x_INT_MASK_NOT_HDCP22) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: not a HDCP 2.2 supported device\n", FUNCTION_NAME)); + // disable HDCP 2.2 and enable HDCP 1.4 + if (cbDIU_HDMI_HDCP2x_IsEnabled(pcbe, HDCPModuleIndex)) + { + cbDIU_HDMI_HDCP2x_OnOff(pcbe, HDCPModuleIndex, CBIOS_FALSE); + cbDIU_HDMI_HDCP1x_OnOff(pcbe, HDCPModuleIndex, CBIOS_TRUE); + } + + if (cbDIU_DP_HDCP2x_IsEnabled(pcbe, HDCPModuleIndex)) + { + cbDIU_DP_HDCP2x_OnOff(pcbe, HDCPModuleIndex, CBIOS_FALSE); + cbDIU_DP_HDCP1x_OnOff(pcbe, HDCPModuleIndex, CBIOS_TRUE); + } + + pHdcpContext->HdcpVersion = CBIOS_HDCP_VERSION_1x; + } +#endif + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_IS_HDCP22) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: is a HDCP 2.2 supported device\n", FUNCTION_NAME)); + pHdcpContext->HdcpVersion = CBIOS_HDCP_VERSION_2x; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_REAUTH_REQ) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: re-authentication request\n", FUNCTION_NAME)); +#ifndef UEFI_DIAGTOOL + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_FALSE); + cbDelayMilliSeconds(120); + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_TRUE); +#else + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_FALSE, 2); + cbDelayMilliSeconds(120); + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_TRUE, 2); +#endif + + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_AUTH_FAIL) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: authentication fail\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + //last ints are to repeater + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_RECID_INVALID) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: receiver id invalid\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_CERT_TIMEOUT) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: CERT timeout\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_CERT_FAIL) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: CERT fail\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_H_FAIL) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: H fail\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_H_TIMEOUT) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: H timeout\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_EKH_TIMEOUT) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: eKh timeout\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_L_FAIL) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: L fail\n", FUNCTION_NAME)); + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_LC_TIMEOUT) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: LC timeout\n", FUNCTION_NAME)); + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_LC_RETRY_NUMOUT) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: LC retry num out\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_MSG_ID) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: msg id\n", FUNCTION_NAME)); +#ifndef UEFI_DIAGTOOL + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_FALSE); + cbDelayMilliSeconds(120); + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_TRUE); +#else + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_FALSE, 2); + cbDelayMilliSeconds(120); + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_TRUE, 2); +#endif + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_GET_RECID) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: read receiver id\n", FUNCTION_NAME)); + if (pDevCommon->CurrentMonitorType == CBIOS_MONITOR_TYPE_DP) + { + if (cbDIU_DP_HDCP_IsBKSVReady(pcbe, HDCPModuleIndex)) + { + cbDIU_DP_HDCP_ReadBksv(pcbe, HDCPModuleIndex, pHdcpContext->BKsv); + } + if(cbHDCP_CheckRevokedBksv(pcbe, pHdcpContext->BKsv, 5, + pHdcpContext->pRevocationList, pHdcpContext->RevocationListBufferSize)) + { + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + else + { + cbDIU_DP_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + } + } + else + { + if (cbDIU_HDMI_HDCP_IsBKSVReady(pcbe, HDCPModuleIndex)) + { + cbDIU_HDMI_HDCP_ReadBksv(pcbe, HDCPModuleIndex, pHdcpContext->BKsv); + } + if(cbHDCP_CheckRevokedBksv(pcbe, pHdcpContext->BKsv, 5, + pHdcpContext->pRevocationList, pHdcpContext->RevocationListBufferSize)) + { + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + else + { + cbDIU_HDMI_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + } + } + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_SEQ_NUM_M_ROLLOVER) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: seq num M roll over\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + //last ints are to repeater + if (IntStatus & CBIOS_HDCP2x_INT_MASK_WAIT_RECID_TIMEOUT) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: wait receiver id timeout\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_V_FAIL) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: V fail\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_DEV_ZERO) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: zero device\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_MAX_DEVS) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: max devices\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_MAX_CAS) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: max cascade\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_NONZERO_SEQ_NUM_V) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: non-zero seq num V\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_SEQ_NUM_V_ROLLOVER) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: seq num V roll over\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_M_FAIL) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: M fail\n", FUNCTION_NAME)); + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_M_TIMEOUT) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: M timeout\n", FUNCTION_NAME)); + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_M_RETRY_NUMOUT) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: M retry num out\n", FUNCTION_NAME)); +#ifndef UEFI_DIAGTOOL + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_FALSE); + cbDelayMilliSeconds(120); + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_TRUE); +#else + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_FALSE, 2); + cbDelayMilliSeconds(120); + cbHDCP_OnOff(pcbe, Device, HDCPModuleIndex, CBIOS_TRUE, 2); +#endif + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_FAIL; + return; + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_CSM_FAIL) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: CSM fail\n", FUNCTION_NAME)); + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_CSM_PASS) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: CSM pass\n", FUNCTION_NAME)); + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_KSVFF) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: KSV fifo full\n", FUNCTION_NAME)); + } + + if (IntStatus & CBIOS_HDCP2x_INT_MASK_AUTH_PASS) + { + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: Got int: authentication pass\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_PASS; + } +} + + +static CBIOS_VOID cbHDCP_InitHdcpContext(PCBIOS_VOID pvcbe, PCBIOS_HDCP_CONTEXT pHdcpContext) +{ + if(pHdcpContext == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: pHdcpContext is NULL!\n", FUNCTION_NAME)); + return; + } + + pHdcpContext->HdcpVersion = CBIOS_HDCP_VERSION_2x; + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_DISABLE; + pHdcpContext->bRepeater = CBIOS_FALSE; + pHdcpContext->DeviceCount = 0; + pHdcpContext->bRepeaterAuthPass = CBIOS_FALSE; + pHdcpContext->HdcpReAuthTryCount = CBIOS_HDCP_REAUTH_TRY_COUNT_MAX; + + if (pHdcpContext->pBKsvList) + { + cb_FreePool(pHdcpContext->pBKsvList); + pHdcpContext->pBKsvList = CBIOS_NULL; + } + pHdcpContext->BKsvListBufferSize = 0; + + pHdcpContext->pRevocationList = (PCBIOS_U8)Fake_RevokedBksv; + pHdcpContext->RevocationListBufferSize = sizeof(Fake_RevokedBksv); +} + +#ifndef UEFI_DIAGTOOL +static CBIOS_VOID cbHDMI_HDCP_OnOff(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 IGAIndex, CBIOS_BOOL bTurnOn) +#else +static CBIOS_VOID cbHDMI_HDCP_OnOff(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 IGAIndex, CBIOS_BOOL bTurnOn, CBIOS_U16 hdcpVer) +#endif +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MODULE_INDEX HDCPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + CBIOS_BOOL bUseI2CModule = CBIOS_TRUE; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttr = CBIOS_NULL; + PCBIOS_HDCP_CONTEXT pHdcpContext = GET_HDCP_CONTEXT(pvcbe, Device); + + cbTraceEnter(GENERIC); + + HDCPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_HDCP); + if (HDCPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + pMonitorAttr = &(pDevCommon->EdidStruct.Attribute); + + if ((Device == CBIOS_TYPE_MHL) && (pDevCommon->CurrentMonitorType == CBIOS_MONITOR_TYPE_MHL)) + { + bUseI2CModule = CBIOS_FALSE; + } + + if(bUseI2CModule & bTurnOn) + { + cbDIU_HDMI_HDCP_HwI2cOnOff(pcbe, HDCPModuleIndex, (CBIOS_U8)pDevCommon->I2CBus, bTurnOn); + } + + if (bTurnOn) + { + // NOTE: HDCP enable/disable registers take effects right away instead of at vsync. + // So need to wait vblank to prevent garbage show when enable/disable HDCP. + cbWaitVBlank(pcbe, IGAIndex); + /* hdcp reset will lead to black screen, comment it. But we should call hdcp reset if run hdcp cts*/ + //cbDIU_HDCP_SwReset(pcbe, HDCPModuleIndex); + +#if HDCP_USE_TEST_KEY + cbDIU_HDMI_HDCP_TestKeyEnableDisable(pcbe, HDCPModuleIndex, CBIOS_TRUE); +#endif + + cbDIU_HDMI_HDCP_RevocationCheckEnableDisable(pcbe, HDCPModuleIndex, CBIOS_TRUE); + cbDIU_HDMI_HDCP_EncryptionEnableDisable(pcbe, HDCPModuleIndex, CBIOS_TRUE); + + if (pMonitorAttr->IsCEA861HDMI) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: choose HDMI protocol\n", FUNCTION_NAME)); + cbDIU_HDMI_HDCP_ChooseProtocol(pcbe, HDCPModuleIndex, IGAIndex, pHdcpContext->HdcpVersion, CBIOS_TRUE); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s: choose DVI protocol\n", FUNCTION_NAME)); + cbDIU_HDMI_HDCP_ChooseProtocol(pcbe, HDCPModuleIndex, IGAIndex, pHdcpContext->HdcpVersion, CBIOS_FALSE); + } + +#ifdef UEFI_DIAGTOOL + if (hdcpVer == 1) + { + pHdcpContext->HdcpVersion = CBIOS_HDCP_VERSION_1x; + cbDIU_HDMI_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + + cbDIU_HDMI_HDCP1x_OnOff(pcbe, HDCPModuleIndex, bTurnOn); + } + else + { +#endif + pHdcpContext->HdcpVersion = CBIOS_HDCP_VERSION_2x; + // clear HDCP 2.2 interrupt status before HDCP 2.2 enable + cbDIU_HDCP2x_ReadAndClearIntStatus(pcbe, HDCPModuleIndex); + // clear BKSV ready bit + cbDIU_HDMI_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + + cbDIU_HDMI_HDCP2x_OnOff(pcbe, HDCPModuleIndex, bTurnOn); + +#ifdef UEFI_DIAGTOOL + } +#endif + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_ENABLE; + } + else + { + cbDIU_HDMI_HDCP_EncryptionEnableDisable(pcbe, HDCPModuleIndex, CBIOS_FALSE); + + if (cbDIU_HDMI_HDCP1x_IsEnabled(pcbe, HDCPModuleIndex)) + { + cbDIU_HDMI_HDCP1x_OnOff(pcbe, HDCPModuleIndex, bTurnOn); + } + + if (cbDIU_HDMI_HDCP2x_IsEnabled(pcbe, HDCPModuleIndex)) + { + cbDIU_HDMI_HDCP2x_OnOff(pcbe, HDCPModuleIndex, bTurnOn); + } + + /* hdcp reset will lead to black screen, comment it. But we should call hdcp reset if run hdcp cts*/ + //cbDIU_HDCP_SwReset(pcbe, HDCPModuleIndex); + + if(bUseI2CModule) + { + cbDIU_HDMI_HDCP_HwI2cOnOff(pcbe, HDCPModuleIndex, (CBIOS_U8)pDevCommon->I2CBus, bTurnOn); + } + + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_DISABLE; + cbHDCP_InitHdcpContext(pvcbe, pHdcpContext); // reset HDCP context + } + + cbTraceExit(GENERIC); +} + +#ifndef UEFI_DIAGTOOL +CBIOS_VOID cbDP_HDCP_OnOff(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 IGAIndex, CBIOS_BOOL bTurnOn) +#else +CBIOS_VOID cbDP_HDCP_OnOff(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 IGAIndex, CBIOS_BOOL bTurnOn, CBIOS_U16 hdcpVer) +#endif +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MODULE_INDEX HDCPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + PCBIOS_HDCP_CONTEXT pHdcpContext = GET_HDCP_CONTEXT(pvcbe, Device); + + cbTraceEnter(GENERIC); + + HDCPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_HDCP); + if (HDCPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + // NOTE: HDCP enable/disable registers take effects right away instead of at vsync. + // So need to wait vblank to prevent garbage show when enable/disable HDCP. + cbWaitVBlank(pcbe, IGAIndex); + + if (bTurnOn) + { + //cbDIU_HDCP_SwReset(pcbe, HDCPModuleIndex); + + cbDIU_DP_HDCP_AuxOnOff(pcbe, HDCPModuleIndex, bTurnOn); + +#if HDCP_USE_TEST_KEY + cbDIU_DP_HDCP_TestKeyEnableDisable(pcbe, HDCPModuleIndex, CBIOS_TRUE); +#endif + + cbDIU_DP_HDCP_RevocationCheckEnableDisable(pcbe, HDCPModuleIndex, CBIOS_TRUE); + cbDIU_DP_HDCP_EncryptionEnableDisable(pcbe, HDCPModuleIndex, CBIOS_TRUE); + +#ifdef UEFI_DIAGTOOL + if (hdcpVer == 1) + { + pHdcpContext->HdcpVersion = CBIOS_HDCP_VERSION_1x; + cbDIU_DP_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + + cbDIU_DP_HDCP1x_OnOff(pcbe, HDCPModuleIndex, bTurnOn); + } + else + { +#endif + pHdcpContext->HdcpVersion = CBIOS_HDCP_VERSION_2x; + + // clear HDCP 2.2 interrupt status before HDCP 2.2 enable + cbDIU_HDCP2x_ReadAndClearIntStatus(pcbe, HDCPModuleIndex); + // clear BKSV ready bit + cbDIU_DP_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + + cbDIU_DP_HDCP2x_OnOff(pcbe, HDCPModuleIndex, bTurnOn); + +#ifdef UEFI_DIAGTOOL + } +#endif + + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_ENABLE; + } + else + { + cbDIU_DP_HDCP_EncryptionEnableDisable(pcbe, HDCPModuleIndex, CBIOS_FALSE); + + if (cbDIU_DP_HDCP1x_IsEnabled(pcbe, HDCPModuleIndex)) + { + cbDIU_DP_HDCP1x_OnOff(pcbe, HDCPModuleIndex, bTurnOn); + } + + if (cbDIU_DP_HDCP2x_IsEnabled(pcbe, HDCPModuleIndex)) + { + cbDIU_DP_HDCP2x_OnOff(pcbe, HDCPModuleIndex, bTurnOn); + } + + //cbDIU_HDCP_SwReset(pcbe, HDCPModuleIndex); + + cbDIU_DP_HDCP_AuxOnOff(pcbe, HDCPModuleIndex, bTurnOn); + + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_DISABLE; + cbHDCP_InitHdcpContext(pvcbe, pHdcpContext); // reset HDCP context + } + + cbTraceExit(GENERIC); +} + +#ifndef UEFI_DIAGTOOL +CBIOS_VOID cbHDCP_OnOff(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 IGAIndex, CBIOS_BOOL bTurnOn) +#else +CBIOS_VOID cbHDCP_OnOff(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 IGAIndex, CBIOS_BOOL bTurnOn, CBIOS_U16 hdcpVer) +#endif +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MODULE_INDEX HDCPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + CBIOS_BOOL bDPMonitor = CBIOS_FALSE; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + //PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttr = CBIOS_NULL; + + cbTraceEnter(GENERIC); + + if (pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDevCommon is NULL!\n", FUNCTION_NAME)); + return; + } + + HDCPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_HDCP); + if (HDCPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + //pMonitorAttr = &(pDevCommon->EdidStruct.Attribute); + + if (pDevCommon->CurrentMonitorType == CBIOS_MONITOR_TYPE_DP) + { + bDPMonitor = CBIOS_TRUE; + } + +#ifndef UEFI_DIAGTOOL + if (bDPMonitor) + { + cbDP_HDCP_OnOff(pcbe, Device, IGAIndex, bTurnOn); + } + else + { + cbHDMI_HDCP_OnOff(pcbe, Device, IGAIndex, bTurnOn); + } +#else + if (bDPMonitor) + { + cbDP_HDCP_OnOff(pcbe, Device, IGAIndex, bTurnOn, hdcpVer); + } + else + { + cbHDMI_HDCP_OnOff(pcbe, Device, IGAIndex, bTurnOn, hdcpVer); + } +#endif + + cbTraceExit(GENERIC); +} + +CBIOS_VOID cbHDCP_Isr(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MODULE_INDEX HDCPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + + HDCPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_HDCP); + if (HDCPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return; + } + + if (cbDIU_HDMI_HDCP1x_IsEnabled(pcbe, HDCPModuleIndex)) + { + cbDIU_HDMI_HDCP1x_Isr(pcbe, Device, HDCPModuleIndex); + } + + if (cbDIU_DP_HDCP1x_IsEnabled(pcbe, HDCPModuleIndex)) + { + cbDIU_DP_HDCP1x_Isr(pcbe, Device, HDCPModuleIndex); + } + + if (cbDIU_HDMI_HDCP2x_IsEnabled(pcbe, HDCPModuleIndex) || cbDIU_DP_HDCP2x_IsEnabled(pcbe, HDCPModuleIndex)) + { + cbDIU_HDCP2x_Isr(pcbe, Device, HDCPModuleIndex); + } +} + +CBIOS_BOOL cbHDCP_GetHDCPBKsv(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, PCBIOS_U8 pBKsv, PCBIOS_BOOL bRepeater) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_HDCP_CONTEXT pHdcpContext = GET_HDCP_CONTEXT(pcbe, Device); + + if(pHdcpContext == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: pHdcpContext is NULL!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + if(pBKsv == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: pBKsv is NULL!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + cb_memcpy(pBKsv, pHdcpContext->BKsv, sizeof(pHdcpContext->BKsv)); + *bRepeater = pHdcpContext->bRepeater; + + return CBIOS_TRUE; +} + +CBIOS_HDCP_AUTHENTICATION_STATUS cbHDCP_GetStatus(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_HDCP_CONTEXT pHdcpContext = GET_HDCP_CONTEXT(pcbe, Device); + CBIOS_MODULE_INDEX HDCPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + + if(pHdcpContext == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: pHdcpContext is NULL!\n", FUNCTION_NAME)); + return CBIOS_HDCP_AUTH_FAIL; + } + + HDCPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_HDCP); + if (HDCPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + return CBIOS_HDCP_AUTH_FAIL; + } + + return pHdcpContext->AuthStatus; +} + +CBIOS_VOID cbHDCP_WorkThread(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_HDCP_CONTEXT pHdcpContext = GET_HDCP_CONTEXT(pcbe, Device); + CBIOS_MODULE_INDEX HDCPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + CBIOS_BOOL bDPMonitor = CBIOS_FALSE; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + //PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttr = CBIOS_NULL; + + if(pHdcpContext == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: pHdcpContext is NULL!\n", FUNCTION_NAME)); + return; + } + + HDCPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_HDCP); + if (HDCPModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP module index!\n", FUNCTION_NAME)); + } + + //pMonitorAttr = &(pDevCommon->EdidStruct.Attribute); + + if (pDevCommon->CurrentMonitorType == CBIOS_MONITOR_TYPE_DP) + { + bDPMonitor = CBIOS_TRUE; + } + + if (pHdcpContext->AuthStatus == CBIOS_HDCP_AUTH_BKSV) + { + if (bDPMonitor) + { + if (cbDIU_DP_HDCP_IsBKSVReady(pcbe, HDCPModuleIndex)) + { + cbDIU_DP_HDCP_ReadBksv(pcbe, HDCPModuleIndex, pHdcpContext->BKsv); + } + } + else + { + if (cbDIU_HDMI_HDCP_IsBKSVReady(pcbe, HDCPModuleIndex)) + { + cbDIU_HDMI_HDCP_ReadBksv(pcbe, HDCPModuleIndex, pHdcpContext->BKsv); + } + } + + if(cbHDCP_CheckRevokedBksv(pcbe, pHdcpContext->BKsv, 5, + pHdcpContext->pRevocationList, pHdcpContext->RevocationListBufferSize)) + { +#ifndef UEFI_DIAGTOOL + cbHDCP_OnOff(pcbe, Device, IGAIndex, CBIOS_FALSE); +#else + cbHDCP_OnOff(pcbe, Device, IGAIndex, CBIOS_FALSE, 2); +#endif + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_DISABLE; + } + else + { + if (bDPMonitor) + { + cbDIU_DP_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + pHdcpContext->bRepeater = cbDIU_DP_HDCP_CheckIfRepeater(pcbe, HDCPModuleIndex); + } + else + { + cbDIU_HDMI_HDCP_RevocationCheckDoneAck(pcbe, HDCPModuleIndex); + pHdcpContext->bRepeater = cbDIU_HDMI_HDCP_CheckIfRepeater(pcbe, HDCPModuleIndex); + } + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_BKSV_VERIF_DONE; + } + } + else if (pHdcpContext->AuthStatus == CBIOS_HDCP_AUTH_BKSV_LIST) + { + if (pHdcpContext->bRepeater) + { + if (pHdcpContext->bRepeater) + { + pHdcpContext->DeviceCount = cbDIU_HDMI_HDCP_GetDeviceCount(pcbe, HDCPModuleIndex); + } + + if (pHdcpContext->DeviceCount > 0) + { + pHdcpContext->BKsvListBufferSize = pHdcpContext->DeviceCount * 5; + if (pHdcpContext->pBKsvList == CBIOS_NULL) + { + pHdcpContext->pBKsvList = cb_AllocateNonpagedPool(pHdcpContext->BKsvListBufferSize); + } + + if (bDPMonitor) + { + cbDIU_DP_HDCP_ReadBksvList(pcbe, HDCPModuleIndex, pHdcpContext->pBKsvList, pHdcpContext->DeviceCount); + } + else + { + cbDIU_HDMI_HDCP_ReadBksvList(pcbe, HDCPModuleIndex, pHdcpContext->pBKsvList, pHdcpContext->DeviceCount); + } + + if(cbHDCP_CheckRevokedBksv(pcbe, pHdcpContext->pBKsvList, pHdcpContext->BKsvListBufferSize, + pHdcpContext->pRevocationList, pHdcpContext->RevocationListBufferSize)) + { +#ifndef UEFI_DIAGTOOL + cbHDCP_OnOff(pcbe, Device, IGAIndex, CBIOS_FALSE); +#else + cbHDCP_OnOff(pcbe, Device, IGAIndex, CBIOS_FALSE, 2); +#endif + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_DISABLE; + } + else + { + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_BKSV_LIST_VERIF_DONE; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO),"%s: no receiver connected to repeater\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_BKSV_LIST_VERIF_DONE; + } + + if (pHdcpContext->bRepeaterAuthPass) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO),"%s: repeater auth pass\n", FUNCTION_NAME)); + pHdcpContext->AuthStatus = CBIOS_HDCP_AUTH_PASS; + } + } + } +} + +CBIOS_VOID cbHDCP_Init(PCBIOS_VOID pvcbe, PCBIOS_VOID *ppHdcpContext) +{ + PCBIOS_HDCP_CONTEXT pHdcpContext = CBIOS_NULL; + + pHdcpContext = cb_AllocateNonpagedPool(sizeof(CBIOS_HDCP_CONTEXT)); + if(pHdcpContext == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"%s: pHdcpContext allocate error!!!\n", FUNCTION_NAME)); + return; + } + + cbHDCP_InitHdcpContext(pvcbe, pHdcpContext); + + *ppHdcpContext = pHdcpContext; +} + +CBIOS_VOID cbHDCP_DeInit(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + + if (pDevCommon->pHDCPContext) + { + cb_FreePool(pDevCommon->pHDCPContext); + pDevCommon->pHDCPContext = CBIOS_NULL; + } +} diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDCP.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDCP.h new file mode 100644 index 0000000000000..811daf5229631 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDCP.h @@ -0,0 +1,153 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** HDCP hw block interface function prototype. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_DIU_HDCP_H_ +#define _CBIOS_DIU_HDCP_H_ + +#include "../../Device/CBiosDeviceShare.h" + +#define CBIOS_HW_BKSV_LIST_FIFO_SIZE 4 + +#define CBIOS_HDCP_REAUTH_TRY_COUNT_MAX 3 + +#define HDCP_MODU_NUM 4 + +typedef enum +{ + CBIOS_HDCP_VERSION_1x, + CBIOS_HDCP_VERSION_2x, +}CBIOS_HDCP_VERSION; + +typedef enum +{ + CBIOS_HW_I2C_Freq_50kHz = 1, + CBIOS_HW_I2C_Freq_80kHz, + CBIOS_HW_I2C_Freq_100kHz, + CBIOS_HW_I2C_Freq_200kHz, + CBIOS_HW_I2C_Freq_300kHz, + CBIOS_HW_I2C_Freq_400kHz, + CBIOS_HW_I2C_Freq_1MHz, +}CBIOS_HW_I2C_Freq; + +typedef enum +{ + CBIOS_HDMI_HDCP1x_INT_AUTH_FAIL = 0, + CBIOS_HDMI_HDCP1x_INT_Ri_VERIF_FAIL, + CBIOS_HDMI_HDCP1x_INT_Pj_VERIF_FAIL, + CBIOS_HDMI_HDCP1x_INT_KSV_READY, + CBIOS_HDMI_HDCP1x_INT_BKSV_INVALID, + CBIOS_HDMI_HDCP1x_INT_V_LIST_CHECK_FAIL, + CBIOS_HDMI_HDCP1x_INT_Ri_VERIF_TIMEOUT, + CBIOS_HDMI_HDCP1x_INT_MAX_CASCADE, + CBIOS_HDMI_HDCP1x_INT_MAX_DEVICES, + CBIOS_HDMI_HDCP1x_INT_ZERO_DEVICE, + CBIOS_HDMI_HDCP1x_INT_RESERVED1, + CBIOS_HDMI_HDCP1x_INT_RESERVED2, + CBIOS_HDMI_HDCP1x_INT_RESERVED3, + CBIOS_HDMI_HDCP1x_INT_RESERVED4, + CBIOS_HDMI_HDCP1x_INT_RESERVED5, + CBIOS_HDMI_HDCP1x_INT_AUTH_PASS, +}CBIOS_HDMI_HDCP1x_INT_SRC; + +typedef enum +{ + CBIOS_DP_HDCP1x_INT_AUTH_FAIL, + CBIOS_DP_HDCP1x_INT_NOT_HDCP_CAPABLE, + CBIOS_DP_HDCP1x_INT_BKSV_INVALID, + CBIOS_DP_HDCP1x_INT_RO_INVALID, + CBIOS_DP_HDCP1x_INT_KSV_VERIF_TIMEOUT, + CBIOS_DP_HDCP1x_INT_MAX_CASCADE, + CBIOS_DP_HDCP1x_INT_MAX_DEVS, + CBIOS_DP_HDCP1x_INT_ZERO_DEVS, + CBIOS_DP_HDCP1x_INT_KSV_READY, + CBIOS_DP_HDCP1x_INT_V_LIST_CHECK_FAIL, + CBIOS_DP_HDCP1x_INT_AUX_FAIL, + CBIOS_DP_HDCP1x_INT_RESERVED1, + CBIOS_DP_HDCP1x_INT_RESERVED2, + CBIOS_DP_HDCP1x_INT_RESERVED3, + CBIOS_DP_HDCP1x_INT_RESERVED4, + CBIOS_DP_HDCP1x_INT_AUTH_PASS, +}CBIOS_DP_HDCP1x_INT_SRC; + +typedef enum +{ + CBIOS_HDCP2x_INT_MASK_MSG_ID = 0x00000001, + CBIOS_HDCP2x_INT_MASK_GET_RECID = 0x00000002, + CBIOS_HDCP2x_INT_MASK_KSVFF = 0x00000004, + CBIOS_HDCP2x_INT_MASK_NOT_HDCP22 = 0x00000008, + CBIOS_HDCP2x_INT_MASK_IS_HDCP22 = 0x00000010, + CBIOS_HDCP2x_INT_MASK_CSM_FAIL = 0x00000040, + CBIOS_HDCP2x_INT_MASK_AUTH_FAIL = 0x00000080, + CBIOS_HDCP2x_INT_MASK_I2C_FAIL = 0x00000100, + CBIOS_HDCP2x_INT_MASK_DEV_ZERO = 0x00000200, + CBIOS_HDCP2x_INT_MASK_CSM_PASS = 0x00000400, + CBIOS_HDCP2x_INT_MASK_AUTH_PASS = 0x00000800, + CBIOS_HDCP2x_INT_MASK_SEQ_NUM_M_ROLLOVER = 0x00001000, + CBIOS_HDCP2x_INT_MASK_M_RETRY_NUMOUT = 0x00002000, + CBIOS_HDCP2x_INT_MASK_M_TIMEOUT = 0x00004000, + CBIOS_HDCP2x_INT_MASK_M_FAIL = 0x00008000, + CBIOS_HDCP2x_INT_MASK_NONZERO_SEQ_NUM_V = 0x00010000, + CBIOS_HDCP2x_INT_MASK_SEQ_NUM_V_ROLLOVER = 0x00020000, + CBIOS_HDCP2x_INT_MASK_V_FAIL = 0x00040000, + CBIOS_HDCP2x_INT_MASK_MAX_CAS = 0x00080000, + CBIOS_HDCP2x_INT_MASK_MAX_DEVS = 0x00100000, + CBIOS_HDCP2x_INT_MASK_WAIT_RECID_TIMEOUT = 0x00200000, + CBIOS_HDCP2x_INT_MASK_REAUTH_REQ = 0x00400000, + CBIOS_HDCP2x_INT_MASK_L_FAIL = 0x00800000, + CBIOS_HDCP2x_INT_MASK_LC_RETRY_NUMOUT = 0x01000000, + CBIOS_HDCP2x_INT_MASK_LC_TIMEOUT = 0x02000000, + CBIOS_HDCP2x_INT_MASK_EKH_TIMEOUT = 0x04000000, + CBIOS_HDCP2x_INT_MASK_H_FAIL = 0x08000000, + CBIOS_HDCP2x_INT_MASK_H_TIMEOUT = 0x10000000, + CBIOS_HDCP2x_INT_MASK_CERT_FAIL = 0x20000000, + CBIOS_HDCP2x_INT_MASK_RECID_INVALID = 0x40000000, + CBIOS_HDCP2x_INT_MASK_CERT_TIMEOUT = 0x80000000, +}CBIOS_HDCP2x_INT_MASK; + +typedef struct +{ + CBIOS_HDCP_VERSION HdcpVersion; + CBIOS_HDCP_AUTHENTICATION_STATUS AuthStatus; + CBIOS_U8 BKsv[5]; + CBIOS_BOOL bRepeater; + PCBIOS_U8 pBKsvList; + CBIOS_U32 BKsvListBufferSize; + CBIOS_U8 DeviceCount; + PCBIOS_U8 pRevocationList; + CBIOS_U32 RevocationListBufferSize; + CBIOS_BOOL bRepeaterAuthPass; + CBIOS_BOOL HdcpReAuthTryCount; +}CBIOS_HDCP_CONTEXT, *PCBIOS_HDCP_CONTEXT; + +CBIOS_VOID cbHDCP_Init(PCBIOS_VOID pvcbe, PCBIOS_VOID *ppHdcpContext); +CBIOS_VOID cbHDCP_DeInit(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device); +#ifndef UEFI_DIAGTOOL +CBIOS_VOID cbHDCP_OnOff(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 IGAIndex, CBIOS_BOOL bTurnOn); +#else +CBIOS_VOID cbHDCP_OnOff(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 IGAIndex, CBIOS_BOOL bTurnOn, CBIOS_U16 hdcpVer); +#endif +CBIOS_VOID cbHDCP_Isr(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device); +CBIOS_HDCP_AUTHENTICATION_STATUS cbHDCP_GetStatus(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device); +CBIOS_BOOL cbHDCP_GetHDCPBKsv(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, PCBIOS_U8 pBKsv, PCBIOS_BOOL bRepeater); +CBIOS_VOID cbHDCP_WorkThread(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 IGAIndex); +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDMI.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDMI.c new file mode 100644 index 0000000000000..894b06ebc09d3 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDMI.c @@ -0,0 +1,795 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** HDMI hw block interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosDIU_HDMI.h" +#include "CBiosDIU_HDTV.h" +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" +#include "CBiosDIU_HDAC.h" + + +CBIOS_U32 HDMI_REG_GEN_CTRL[HDMI_MODU_NUM] = {0x8280, 0x33D70, 0x34470, 0x34B70}; +CBIOS_U32 HDMI_REG_INFO_FRAME[HDMI_MODU_NUM] = {0x8284, 0x33D74, 0x34474, 0x34B74}; +CBIOS_U32 HDMI_REG_AUDIO_CTRL[HDMI_MODU_NUM] = {0x8294, 0x33D78, 0x34478, 0x34B78}; +CBIOS_U32 HDMI_REG_AUDIO_CTSN[HDMI_MODU_NUM] = {0x83A8, 0x33D7C, 0x3447C, 0x34B7C}; +CBIOS_U32 HDMI_REG_AUDIO_CTS[HDMI_MODU_NUM] = {0x83AC, 0x33D80, 0x34480, 0x34B80}; +CBIOS_U32 HDMI_REG_CTRL[HDMI_MODU_NUM] = {0x336B0, 0x33D88, 0x34488, 0x34B88}; +CBIOS_U32 HDMI_REG_SCDC_CTRL[HDMI_MODU_NUM] = {0x336B8, 0x33D84, 0x34484, 0x34B84}; + + +CBIOS_VOID cbDIU_HDMI_WriteFIFO(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE DeviceType, CBIOS_U8 FIFOIndex, CBIOS_U8 *pDataBuff, CBIOS_U32 BuffLen) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, DeviceType); + CBIOS_MONITOR_TYPE MonitorType = pDevCommon->CurrentMonitorType; + CBIOS_BOOL bDPDevice = CBIOS_FALSE; + CBIOS_U8 SR47Value = cbMMIOReadReg(pcbe, SR_47); + CBIOS_MODULE_INDEX HDACModuleIndex = cbGetModuleIndex(pcbe, DeviceType, CBIOS_MODULE_TYPE_HDAC); + CBIOS_U32 i = 0; + + if (HDACModuleIndex >= HDAC_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, WARNING), "%s: invalid HDAC module index!\n", FUNCTION_NAME)); + } + + if ((MonitorType == CBIOS_MONITOR_TYPE_DP) || (MonitorType == CBIOS_MONITOR_TYPE_PANEL)) + { + bDPDevice = CBIOS_TRUE; + } + + if (DeviceType == CBIOS_TYPE_DP1) + { + //select LUT + if (bDPDevice) + { + cbMMIOWriteReg(pcbe, SR_47, 0x06, 0xF0); + } + else + { + cbMMIOWriteReg(pcbe, SR_47, 0x04, 0xF0); + } + } + else if (DeviceType == CBIOS_TYPE_DP2) + { + //select LUT + if (bDPDevice) + { + cbMMIOWriteReg(pcbe, SR_47, 0x07, 0xF0); + } + else + { + cbMMIOWriteReg(pcbe, SR_47, 0x05, 0xF0); + } + } + else if (DeviceType == CBIOS_TYPE_DP3) + { + //select LUT + if (bDPDevice) + { + cbMMIOWriteReg(pcbe, SR_47, 0x0E, 0xF0); + } + else + { + cbMMIOWriteReg(pcbe, SR_47, 0x0C, 0xF0); + } + } + else if (DeviceType == CBIOS_TYPE_DP4) + { + //select LUT + if (bDPDevice) + { + cbMMIOWriteReg(pcbe, SR_47, 0x0F, 0xF0); + } + else + { + cbMMIOWriteReg(pcbe, SR_47, 0x0D, 0xF0); + } + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI/DP device!\n", FUNCTION_NAME)); + return; + } + + cb_WriteU8(pcbe->pAdapterContext, 0x83C8, FIFOIndex); + + for (i = BuffLen; i > 0; i--) + { + cb_WriteU8(pcbe->pAdapterContext, 0x83C9, pDataBuff[i - 1]); + } + + //restore SR47 + cbMMIOWriteReg(pcbe, SR_47, SR47Value, 0x00); +} + +CBIOS_VOID cbDIU_HDMI_ReadFIFO(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE DeviceType, CBIOS_U8 FIFOIndex, CBIOS_U8 *pDataBuff, CBIOS_U32 BuffLen) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, DeviceType); + CBIOS_MONITOR_TYPE MonitorType = pDevCommon->CurrentMonitorType; + CBIOS_BOOL bDPDevice = CBIOS_FALSE; + CBIOS_U8 SR47Value = cbMMIOReadReg(pcbe, SR_47); + CBIOS_MODULE_INDEX HDACModuleIndex = cbGetModuleIndex(pcbe, DeviceType, CBIOS_MODULE_TYPE_HDAC); + CBIOS_U32 i = 0; + + if (HDACModuleIndex >= HDAC_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDAC module index!\n", FUNCTION_NAME)); + } + + if ((MonitorType == CBIOS_MONITOR_TYPE_DP) || (MonitorType == CBIOS_MONITOR_TYPE_PANEL)) + { + bDPDevice = CBIOS_TRUE; + } + + if (DeviceType == CBIOS_TYPE_DP1) + { + //select LUT + if (bDPDevice) + { + cbMMIOWriteReg(pcbe, SR_47, 0x06, 0xF0); + } + else + { + cbMMIOWriteReg(pcbe, SR_47, 0x04, 0xF0); + } + } + else if (DeviceType == CBIOS_TYPE_DP2) + { + //select LUT + if (bDPDevice) + { + cbMMIOWriteReg(pcbe, SR_47, 0x07, 0xF0); + } + else + { + cbMMIOWriteReg(pcbe, SR_47, 0x05, 0xF0); + } + } + else if (DeviceType == CBIOS_TYPE_DP3) + { + //select LUT + if (bDPDevice) + { + cbMMIOWriteReg(pcbe, SR_47, 0x0E, 0xF0); + } + else + { + cbMMIOWriteReg(pcbe, SR_47, 0x0C, 0xF0); + } + } + else if (DeviceType == CBIOS_TYPE_DP4) + { + //select LUT + if (bDPDevice) + { + cbMMIOWriteReg(pcbe, SR_47, 0x0F, 0xF0); + } + else + { + cbMMIOWriteReg(pcbe, SR_47, 0x0D, 0xF0); + } + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI/DP device!\n", FUNCTION_NAME)); + return; + } + + cb_WriteU8(pcbe->pAdapterContext, 0x83C7, FIFOIndex); + + for (i = BuffLen; i > 0; i--) + { + pDataBuff[i - 1] = cb_ReadU8(pcbe->pAdapterContext, 0x83C9); + } + + //restore SR47 + cbMMIOWriteReg(pcbe, SR_47, SR47Value, 0x00); +} + +CBIOS_VOID cbDIU_HDMI_SetHDCPDelay(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bHDCPCapable) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8280 HDMIGenCtrlRegValue, HDMIGenCtrlRegMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + HDMIGenCtrlRegValue.Value = 0; + if (bHDCPCapable) + { + HDMIGenCtrlRegValue.Delay_for_HDCP = HDMI_DELAY_FOR_HDCP - HDMI_LEADING_GUARD_BAND_PERIOD - + HDMI_PREAMBLE_PERIOD + HDCP_HW_PROCESS_PERIOD; + } + HDMIGenCtrlRegValue.Delay_for_HDCP_SEL = 1; + + HDMIGenCtrlRegMask.Value = 0xFFFFFFFF; + HDMIGenCtrlRegMask.Delay_for_HDCP = 0; + HDMIGenCtrlRegMask.Delay_for_HDCP_SEL = 0; + + cbMMIOWriteReg32(pcbe, HDMI_REG_GEN_CTRL[HDMIModuleIndex], HDMIGenCtrlRegValue.Value, HDMIGenCtrlRegMask.Value); +} + +CBIOS_VOID cbDIU_HDMI_SetHVSync(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_U8 HVPolarity) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8280 HDMIGenCtrlRegValue, HDMIGenCtrlRegMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + HDMIGenCtrlRegValue.Value = 0; + if (HVPolarity & HorNEGATIVE) + { + HDMIGenCtrlRegValue.HSYNC_Invert_Enable = 1; + } + if (HVPolarity & VerNEGATIVE) + { + HDMIGenCtrlRegValue.VSYNC_Invert_Enable = 1; + } + + HDMIGenCtrlRegMask.Value = 0xFFFFFFFF; + HDMIGenCtrlRegMask.HSYNC_Invert_Enable = 0; + HDMIGenCtrlRegMask.VSYNC_Invert_Enable = 0; + + cbMMIOWriteReg32(pcbe, HDMI_REG_GEN_CTRL[HDMIModuleIndex], HDMIGenCtrlRegValue.Value, HDMIGenCtrlRegMask.Value); +} + +CBIOS_VOID cbDIU_HDMI_SendInfoFrame(PCBIOS_VOID pvcbe, CBIOS_U32 HDMIMaxPacketNum, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 Length) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 StartAddress = 0; + CBIOS_MODULE_INDEX HDMIModuleIndex = CBIOS_MODULE_INDEX_INVALID; + REG_MM8284 HDMIInfoFrameRegValue; + + HDMIModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_HDMI); + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + HDMIInfoFrameRegValue.Value = 0; + HDMIInfoFrameRegValue.InfoFrame_FIFO_1_Ready = 1; + HDMIInfoFrameRegValue.Horiz_Blank_Max_Packets = HDMIMaxPacketNum; + HDMIInfoFrameRegValue.InfoFrame_FIFO_1_Start_Address = StartAddress; + HDMIInfoFrameRegValue.InfoFrame_FIFO_1_Length = (Length - 1); + cb_WriteU32(pcbe->pAdapterContext, HDMI_REG_INFO_FRAME[HDMIModuleIndex], HDMIInfoFrameRegValue.Value); +} + +CBIOS_VOID cbDIU_HDMI_SetPixelFormat(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_U32 OutputSignal) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8280 HDMIGenCtrlRegValue, HDMIGenCtrlRegMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + HDMIGenCtrlRegValue.Value = 0; + HDMIGenCtrlRegMask.Value = 0xFFFFFFFF; + HDMIGenCtrlRegMask.Convert_to_YCbCr422_Enable = 0; + HDMIGenCtrlRegMask.TMDS_Video_Pixel_Format_Select = 0; + + // Make the TMDS's source is RGB TV data or YPbPr + if(OutputSignal == CBIOS_YCBCR422OUTPUT) // YCbCr 4:2:2 output + { + HDMIGenCtrlRegValue.Convert_to_YCbCr422_Enable = 1; + HDMIGenCtrlRegValue.TMDS_Video_Pixel_Format_Select = 2; + } + else if(OutputSignal == CBIOS_YCBCR444OUTPUT) // YCbCr 4:4:4 output + { + HDMIGenCtrlRegValue.Convert_to_YCbCr422_Enable = 0; + HDMIGenCtrlRegValue.TMDS_Video_Pixel_Format_Select = 1; + } + else if(OutputSignal == CBIOS_YCBCR420OUTPUT) // YCbCr 4:2:0 output + { + HDMIGenCtrlRegValue.Convert_to_YCbCr422_Enable = 0; + HDMIGenCtrlRegValue.TMDS_Video_Pixel_Format_Select = 3; + } + else // For RGB output + { + HDMIGenCtrlRegValue.Convert_to_YCbCr422_Enable = 0; + HDMIGenCtrlRegValue.TMDS_Video_Pixel_Format_Select = 0; + } + cbMMIOWriteReg32(pcbe, HDMI_REG_GEN_CTRL[HDMIModuleIndex], HDMIGenCtrlRegValue.Value, HDMIGenCtrlRegMask.Value); + + + if(OutputSignal == CBIOS_YCBCR420OUTPUT) + { + cbDIU_HDMI_EnableYCbCr420(pcbe, HDMIModuleIndex, CBIOS_TRUE); + } + else + { + cbDIU_HDMI_EnableYCbCr420(pcbe, HDMIModuleIndex, CBIOS_FALSE); + } +} + +CBIOS_VOID cbDIU_HDMI_SetColorDepth(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_U8 ColorDepth) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bNeedSetColorDepth = CBIOS_FALSE; + REG_MM8280 HDMIGenCtrlRegValue, HDMIGenCtrlRegMask; + REG_MM8294 HDMIAudioCtrlRegValue, HDMIAudioCtrlRegMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + HDMIGenCtrlRegValue.Value = 0; + HDMIGenCtrlRegMask.Value = 0xFFFFFFFF; + HDMIGenCtrlRegMask.Deep_Color_Mode = 0; + + HDMIAudioCtrlRegValue.Value = 0; + HDMIAudioCtrlRegMask.Value = 0xFFFFFFFF; + HDMIAudioCtrlRegMask.DC_Gen_Cntl_Pkt_EN = 0; + HDMIAudioCtrlRegMask.PP_SELECT = 0; + HDMIAudioCtrlRegMask.CD = 0; // color depth + HDMIAudioCtrlRegMask.Default_Phase = 0; + + if (pcbe->ChipCaps.IsSupportDeepColor) + { + bNeedSetColorDepth = CBIOS_TRUE; + } + else + { + bNeedSetColorDepth = CBIOS_FALSE; + } + + if (bNeedSetColorDepth) + { + if (ColorDepth == 30) + { + HDMIGenCtrlRegValue.Deep_Color_Mode = 1; + + HDMIAudioCtrlRegValue.DC_Gen_Cntl_Pkt_EN = 1; + HDMIAudioCtrlRegValue.PP_SELECT = 0; + HDMIAudioCtrlRegValue.CD = 5; + HDMIAudioCtrlRegValue.Default_Phase = 0; + } + else if (ColorDepth == 36) + { + HDMIGenCtrlRegValue.Deep_Color_Mode = 2; + + HDMIAudioCtrlRegValue.DC_Gen_Cntl_Pkt_EN = 1; + HDMIAudioCtrlRegValue.PP_SELECT = 0; + HDMIAudioCtrlRegValue.CD = 6; + HDMIAudioCtrlRegValue.Default_Phase = 0; + } + else//set to 24 bit by default + { + HDMIGenCtrlRegValue.Deep_Color_Mode = 0; + + HDMIAudioCtrlRegValue.DC_Gen_Cntl_Pkt_EN = 0; + HDMIAudioCtrlRegValue.PP_SELECT = 0; + HDMIAudioCtrlRegValue.CD = 0; + HDMIAudioCtrlRegValue.Default_Phase = 0; + } + + cbMMIOWriteReg32(pcbe, HDMI_REG_GEN_CTRL[HDMIModuleIndex], HDMIGenCtrlRegValue.Value, HDMIGenCtrlRegMask.Value); + cbMMIOWriteReg32(pcbe, HDMI_REG_AUDIO_CTRL[HDMIModuleIndex], HDMIAudioCtrlRegValue.Value, HDMIAudioCtrlRegMask.Value); + } +} + +// set HDMI module mode between HDMI mode and DVI mode +CBIOS_VOID cbDIU_HDMI_SetModuleMode(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bHDMIMode) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8280 HDMIGenCtrlRegValue, HDMIGenCtrlRegMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + HDMIGenCtrlRegValue.Value = 0; + HDMIGenCtrlRegMask.Value = 0xFFFFFFFF; + HDMIGenCtrlRegMask.DVI_Mode_during_HDMI_Enable = 0; + + if (!bHDMIMode) + { + HDMIGenCtrlRegValue.DVI_Mode_during_HDMI_Enable = 1; // DVI mode + } + else + { + HDMIGenCtrlRegValue.DVI_Mode_during_HDMI_Enable = 0; // HDMI mode + } + + cbMMIOWriteReg32(pcbe, HDMI_REG_GEN_CTRL[HDMIModuleIndex], HDMIGenCtrlRegValue.Value, HDMIGenCtrlRegMask.Value); +} + +CBIOS_VOID cbDIU_HDMI_SelectSource(PCBIOS_VOID pvcbe, CBIOS_MODULE *pHDMIModule, CBIOS_MODULE *pNextModule) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + if ((pHDMIModule == CBIOS_NULL) || (pNextModule == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param or 3rd param is NULL!\n", FUNCTION_NAME)); + return; + } + + if (pNextModule->Type == CBIOS_MODULE_TYPE_HDTV) + { + cbDIU_HDTV_LBBypass(pcbe, pHDMIModule->Index, CBIOS_FALSE); + } + else if (pNextModule->Type == CBIOS_MODULE_TYPE_IGA) + { + cbDIU_HDTV_LBBypass(pcbe, pHDMIModule->Index, CBIOS_TRUE); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR),"%s: cannot select HDMI source.\n", FUNCTION_NAME)); + } +} + +CBIOS_VOID cbDIU_HDMI_ModuleOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bTurnOn) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8280 HDMIGenCtrlRegValue, HDMIGenCtrlRegMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + HDMIGenCtrlRegValue.Value = 0; + HDMIGenCtrlRegMask.Value = 0xFFFFFFFF; + HDMIGenCtrlRegMask.HDMI_Reset= 0; + + if (bTurnOn) + { + HDMIGenCtrlRegValue.HDMI_Reset= 1; + } + cbMMIOWriteReg32(pcbe, HDMI_REG_GEN_CTRL[HDMIModuleIndex], HDMIGenCtrlRegValue.Value, HDMIGenCtrlRegMask.Value); + + cb_DelayMicroSeconds(1); + + HDMIGenCtrlRegValue.Value = 0; + HDMIGenCtrlRegMask.Value = 0xFFFFFFFF; + HDMIGenCtrlRegMask.HDMI_Reset= 0; + + HDMIGenCtrlRegValue.HDMI_Reset= 0; + cbMMIOWriteReg32(pcbe, HDMI_REG_GEN_CTRL[HDMIModuleIndex], HDMIGenCtrlRegValue.Value, HDMIGenCtrlRegMask.Value); + + HDMIGenCtrlRegValue.Value = 0; + HDMIGenCtrlRegMask.Value = 0xFFFFFFFF; + HDMIGenCtrlRegMask.HDMI_Enable = 0; + +#ifdef __LINUX__ + // Always set HDMI_Enable = 1 and fix HDA Link Position can't work issue when HDMI is off. + HDMIGenCtrlRegValue.HDMI_Enable = 1; +#else + if (bTurnOn) + { + HDMIGenCtrlRegValue.HDMI_Enable = 1; + } + else + { + HDMIGenCtrlRegValue.HDMI_Enable = 0; + } +#endif + + cbMMIOWriteReg32(pcbe, HDMI_REG_GEN_CTRL[HDMIModuleIndex], HDMIGenCtrlRegValue.Value, HDMIGenCtrlRegMask.Value); +} + +CBIOS_VOID cbDIU_HDMI_DisableVideoAudio(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8294 HDMIAudioCtrlReg, HDMIAudioCtrlMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + //disable video and audio + HDMIAudioCtrlReg.Value = 0; + HDMIAudioCtrlReg.Set_AVMUTE_Enable = 1; + HDMIAudioCtrlReg.Clear_AVMUTE_Enable = 0; + + HDMIAudioCtrlMask.Value = 0xFFFFFFFF; + HDMIAudioCtrlMask.Set_AVMUTE_Enable = 0; + HDMIAudioCtrlMask.Clear_AVMUTE_Enable =0; + cbMMIOWriteReg32(pcbe, HDMI_REG_AUDIO_CTRL[HDMIModuleIndex], HDMIAudioCtrlReg.Value, HDMIAudioCtrlMask.Value); +} + +CBIOS_VOID cbDIU_HDMI_EnableVideoAudio(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8294 HDMIAudioCtrlReg, HDMIAudioCtrlMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + //disable video and audio + HDMIAudioCtrlReg.Value = 0; + HDMIAudioCtrlReg.Set_AVMUTE_Enable = 0; + HDMIAudioCtrlReg.Clear_AVMUTE_Enable = 1; + + HDMIAudioCtrlMask.Value = 0xFFFFFFFF; + HDMIAudioCtrlMask.Set_AVMUTE_Enable = 0; + HDMIAudioCtrlMask.Clear_AVMUTE_Enable =0; + cbMMIOWriteReg32(pcbe, HDMI_REG_AUDIO_CTRL[HDMIModuleIndex], HDMIAudioCtrlReg.Value, HDMIAudioCtrlMask.Value); +} + +CBIOS_VOID cbDIU_HDMI_SetCTSN(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_MODULE_INDEX HDACModuleIndex, CBIOS_U32 StreamFormat) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 N = 0; + CBIOS_BOOL bCloseDummyAudio = CBIOS_FALSE; + REG_MM8294 HDMIAudioCtrlRegValue, HDMIAudioCtrlRegMask; + REG_MM829C HDACPacket2RegValue, HDACPacket2RegMask; + REG_MM82AC HDACChStatusCtrlRegValue, HDACChStatusCtrlRegMask; + REG_MM83A8 HDACCtsNRegValue, HDACCtsNRegMask; + REG_MM83AC HDACCtsRegValue, HDACCtsRegMask; + REG_MM336B0 RegMM336B0Value, RegMM336B0Mask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + if (HDACModuleIndex >= HDAC_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDAC module index!\n", FUNCTION_NAME)); + return; + } + // 1. Audio enable + HDMIAudioCtrlRegValue.Value = 0; + HDMIAudioCtrlRegValue.HDMI_Audio_Enable = 1; + HDMIAudioCtrlRegMask.Value = 0xFFFFFFFF; + HDMIAudioCtrlRegMask.HDMI_Audio_Enable = 0; + cbMMIOWriteReg32(pcbe, HDMI_REG_AUDIO_CTRL[HDMIModuleIndex], HDMIAudioCtrlRegValue.Value, HDMIAudioCtrlRegMask.Value); + + // 2. Audio Source select + // DP1/DP2/MHL Dual Mode + HDMIAudioCtrlRegValue.Value = 0; + HDMIAudioCtrlRegValue.Select_HDMI_Audio_Source = (HDMIModuleIndex == CBIOS_MODULE_INDEX1)? 0 : 1; + HDMIAudioCtrlRegMask.Value = 0xFFFFFFFF; + HDMIAudioCtrlRegMask.Select_HDMI_Audio_Source = 0; + cbMMIOWriteReg32(pcbe, HDMI_REG_AUDIO_CTRL[HDMIModuleIndex], HDMIAudioCtrlRegValue.Value, HDMIAudioCtrlRegMask.Value); + + // 3. Set CTS/N + switch(StreamFormat) + { + case 192000: + N = 24576; + break; + case 176400: + N = 25088; + break; + case 96000: + N = 12288; + break; + case 88200: + N = 12544; + break; + case 48000: + N = 6144; + break; + case 44100: + N = 6272; + break; + case 32000: + N = 4096; + break; + default: + N = 6144; + break; + } + + HDACCtsNRegValue.Value = 0; + HDACCtsNRegValue.N = N; + HDACCtsNRegMask.Value = 0xFFFFFFFF; + HDACCtsNRegMask.N = 0; + cbMMIOWriteReg32(pcbe, HDMI_REG_AUDIO_CTSN[HDMIModuleIndex], HDACCtsNRegValue.Value, HDACCtsNRegMask.Value); + + // set hw CTS + HDACCtsRegValue.Value = 0; + HDACCtsRegValue.CTS_Select = 0; + HDACCtsRegMask.Value = 0xFFFFFFFF; + HDACCtsRegMask.CTS_Select = 0; + cbMMIOWriteReg32(pcbe, HDMI_REG_AUDIO_CTS[HDMIModuleIndex], HDACCtsRegValue.Value, HDACCtsRegMask.Value); + + // 4. Set hw ACR ratio & ACR enable [28] + HDACPacket2RegValue.Value = 0; + HDACPacket2RegValue.CODEC1_ACR_ENABLE = 1; + HDACPacket2RegMask.Value = 0xFFFFFFFF; + HDACPacket2RegMask.CODEC1_ACR_ENABLE = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_PACKET2[HDACModuleIndex], HDACPacket2RegValue.Value, HDACPacket2RegMask.Value); + + HDMIAudioCtrlRegValue.Value = 0; + HDMIAudioCtrlRegValue.ACR_ratio_select = 1; + HDMIAudioCtrlRegMask.Value = 0xFFFFFFFF; + HDMIAudioCtrlRegMask.ACR_ratio_select = 0; + cbMMIOWriteReg32(pcbe, HDMI_REG_AUDIO_CTRL[HDMIModuleIndex], HDMIAudioCtrlRegValue.Value, HDMIAudioCtrlRegMask.Value); + + //for 480p to play 192k audio + HDACChStatusCtrlRegValue.Value = 0; + HDACChStatusCtrlRegValue.multiple_sample = 1; + HDACChStatusCtrlRegMask.Value = 0xFFFFFFFF; + HDACChStatusCtrlRegMask.multiple_sample = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_CHSTATUS_CTRL[HDACModuleIndex], HDACChStatusCtrlRegValue.Value, HDACChStatusCtrlRegMask.Value); + + RegMM336B0Value.Value = 0; + RegMM336B0Value.PKTLEG_SEL_DISABLE = 0; + RegMM336B0Value.PKTLEG_VBLANK = 0XFF; + RegMM336B0Mask.Value = 0xFFFFFFFF; + RegMM336B0Mask.PKTLEG_SEL_DISABLE = 0; + RegMM336B0Mask.PKTLEG_VBLANK = 0; + cbMMIOWriteReg32(pcbe, HDMI_REG_CTRL[HDMIModuleIndex], RegMM336B0Value.Value, RegMM336B0Mask.Value); + + // Short Audio patch + if(bCloseDummyAudio) + { + HDACChStatusCtrlRegValue.Value = 0; + HDACChStatusCtrlRegValue.Always_Output_Audio = 0; + HDACChStatusCtrlRegMask.Value = 0xFFFFFFFF; + HDACChStatusCtrlRegMask.Always_Output_Audio = 0; + cbMMIOWriteReg32(pcbe, HDAC_REG_CHSTATUS_CTRL[HDACModuleIndex], HDACChStatusCtrlRegValue.Value, HDACChStatusCtrlRegMask.Value); + } +} + + +CBIOS_VOID cbDIU_HDMI_ConfigScrambling(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bEnableScrambling) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM336B0 HDMICtrlRegValue, HDMICtrlRegMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + HDMICtrlRegValue.Value = 0; + HDMICtrlRegValue.HDMI1_SCRAMBLE_EN = (bEnableScrambling)? 1 : 0; + HDMICtrlRegMask.Value = 0xFFFFFFFF; + HDMICtrlRegMask.HDMI1_SCRAMBLE_EN = 0; + + cbMMIOWriteReg32(pcbe, HDMI_REG_CTRL[HDMIModuleIndex], HDMICtrlRegValue.Value, HDMICtrlRegMask.Value); +} + +CBIOS_VOID cbDIU_HDMI_EnableReadRequest(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bEnableRR) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM336B8 HDMIScdcCtrlRegValue, HDMIScdcCtrlRegMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + + HDMIScdcCtrlRegValue.Value = 0; + HDMIScdcCtrlRegMask.Value = 0xFFFFFFFF; + HDMIScdcCtrlRegMask.HDMI1_SCDC_RR_ENABLE = 0; + HDMIScdcCtrlRegMask.HDMI1_SCDC_HW_DRV_START_ENABLE = 0; + HDMIScdcCtrlRegMask.HDMI1_SCDC_HW_DRV_STOP_ENABLE = 0; + HDMIScdcCtrlRegMask.HDMI1_SCDC_START_STOP_ENABLE = 0; + + if(bEnableRR) + { + HDMIScdcCtrlRegValue.HDMI1_SCDC_RR_ENABLE = 0; + HDMIScdcCtrlRegValue.HDMI1_SCDC_HW_DRV_START_ENABLE = 0; + HDMIScdcCtrlRegValue.HDMI1_SCDC_HW_DRV_STOP_ENABLE = 0; + HDMIScdcCtrlRegValue.HDMI1_SCDC_START_STOP_ENABLE = 1; + + cbMMIOWriteReg32(pcbe, HDMI_REG_SCDC_CTRL[HDMIModuleIndex], HDMIScdcCtrlRegValue.Value, HDMIScdcCtrlRegMask.Value); + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG), "%s: Enable Source Read Request!\n", FUNCTION_NAME)); + } + else + { + HDMIScdcCtrlRegValue.HDMI1_SCDC_RR_ENABLE = 0; + HDMIScdcCtrlRegValue.HDMI1_SCDC_HW_DRV_START_ENABLE = 0; + HDMIScdcCtrlRegValue.HDMI1_SCDC_HW_DRV_STOP_ENABLE = 0; + HDMIScdcCtrlRegValue.HDMI1_SCDC_START_STOP_ENABLE = 0; + + cbMMIOWriteReg32(pcbe, HDMI_REG_SCDC_CTRL[HDMIModuleIndex], HDMIScdcCtrlRegValue.Value, HDMIScdcCtrlRegMask.Value); + cbDebugPrint((MAKE_LEVEL(HDMI, DEBUG), "%s: Disable Source Read Request!\n", FUNCTION_NAME)); + } +} + +CBIOS_VOID cbDIU_HDMI_EnableYCbCr420(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bEnable420) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM336B0 HDMICtrlRegValue, HDMICtrlRegMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + HDMICtrlRegValue.Value = 0; + HDMICtrlRegValue.HDMI1_YC_420_EN = (bEnable420)? 1 : 0; + HDMICtrlRegValue.HDMI1_YC_420_MODE = (bEnable420)? 1 : 0; + HDMICtrlRegMask.Value = 0xFFFFFFFF; + HDMICtrlRegMask.HDMI1_YC_420_EN = 0; + HDMICtrlRegMask.HDMI1_YC_420_MODE = 0; + cbMMIOWriteReg32(pcbe, HDMI_REG_CTRL[HDMIModuleIndex], HDMICtrlRegValue.Value, HDMICtrlRegMask.Value); +} + +CBIOS_VOID cbDIU_HDMI_EnableClkLane(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bEnableClkLane) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM336B0 HDMICtrlRegValue, HDMICtrlRegMask; + + if (HDMIModuleIndex >= HDMI_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return; + } + + HDMICtrlRegValue.Value = 0; + HDMICtrlRegValue.HDMI1_CLK_LANE_EN = (bEnableClkLane)? 1 : 0; + HDMICtrlRegMask.Value = 0xFFFFFFFF; + HDMICtrlRegMask.HDMI1_CLK_LANE_EN = 0; + cbMMIOWriteReg32(pcbe, HDMI_REG_CTRL[HDMIModuleIndex], HDMICtrlRegValue.Value, HDMICtrlRegMask.Value); +} + +CBIOS_BOOL cbDIU_HDMI_IsOn(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8280 HDMIGenCtrlRegValue; + CBIOS_BOOL status = CBIOS_FALSE; + + if (HDMIModuleIndex == CBIOS_MODULE_INDEX_INVALID) + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "%s: invalid HDMI module index!\n", FUNCTION_NAME)); + return status; + } + + HDMIGenCtrlRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, HDMI_REG_GEN_CTRL[HDMIModuleIndex]); + + if(HDMIGenCtrlRegValue.HDMI_Enable) + { + status = CBIOS_TRUE; + } + else + { + status = CBIOS_FALSE; + } + + return status; +} + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDMI.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDMI.h new file mode 100644 index 0000000000000..d30086dd06b91 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDMI.h @@ -0,0 +1,59 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** HDMI hw block interface function prototype. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_DIU_HDMI_H_ +#define _CBIOS_DIU_HDMI_H_ + +#include "../../Device/CBiosDeviceShare.h" + +#define HDMI_MODU_NUM 4 + +#define HDMI_DELAY_FOR_HDCP 58 //58 TMDS clocks of the horizontal blanking interval is required for content protection re-synchronization +#define HDMI_GUARD_BAND_PERIOD 2 // each Guard Band is 2 TMDS clocks +#define HDMI_LEADING_GUARD_BAND_PERIOD HDMI_GUARD_BAND_PERIOD +#define HDMI_TRAILING_GUARD_BAND_PERIOD HDMI_GUARD_BAND_PERIOD +#define HDMI_PREAMBLE_PERIOD 8 // each Preamble is 8 TMDS clocks +#define HDMI_MIN_CTL_PERIOD (HDMI_PREAMBLE_PERIOD + 4) + +#define HDCP_HW_PROCESS_PERIOD 7 + +CBIOS_VOID cbDIU_HDMI_WriteFIFO(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE DeviceType, CBIOS_U8 FIFOIndex, CBIOS_U8 *pDataBuff, CBIOS_U32 BuffLen); +CBIOS_VOID cbDIU_HDMI_ReadFIFO(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE DeviceType, CBIOS_U8 FIFOIndex, CBIOS_U8 *pDataBuff, CBIOS_U32 BuffLen); +CBIOS_VOID cbDIU_HDMI_SendInfoFrame(PCBIOS_VOID pvcbe, CBIOS_U32 HDMIMaxPacketNum, CBIOS_ACTIVE_TYPE Device, CBIOS_U8 Length); +CBIOS_VOID cbDIU_HDMI_SetHDCPDelay(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bHDCPCapable); +CBIOS_VOID cbDIU_HDMI_SetHVSync(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_U8 HVPolarity); +CBIOS_VOID cbDIU_HDMI_SetColorDepth(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_U8 ColorDepth); +CBIOS_VOID cbDIU_HDMI_SetPixelFormat(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_U32 OutputSignal); +CBIOS_VOID cbDIU_HDMI_SetModuleMode(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bHDMIMode); +CBIOS_VOID cbDIU_HDMI_SelectSource(PCBIOS_VOID pvcbe, CBIOS_MODULE *pHDMIModule, CBIOS_MODULE *pNextModule); +CBIOS_VOID cbDIU_HDMI_ModuleOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bTurnOn); +CBIOS_VOID cbDIU_HDMI_SetCTSN(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_MODULE_INDEX HDACModuleIndex,CBIOS_U32 StreamFormat); +CBIOS_VOID cbDIU_HDMI_ConfigScrambling(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bEnableScrambling); +CBIOS_VOID cbDIU_HDMI_EnableReadRequest(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bEnableRR); +CBIOS_VOID cbDIU_HDMI_EnableYCbCr420(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bEnable420); +CBIOS_VOID cbDIU_HDMI_EnableClkLane(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex, CBIOS_BOOL bEnableClkLane); +CBIOS_VOID cbDIU_HDMI_DisableVideoAudio(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex); +CBIOS_VOID cbDIU_HDMI_EnableVideoAudio(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex); +CBIOS_BOOL cbDIU_HDMI_IsOn(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDMIModuleIndex); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDTV.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDTV.c new file mode 100644 index 0000000000000..bb7b0c01a4223 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDTV.c @@ -0,0 +1,283 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** HDTV hw block interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosDIU_HDTV.h" +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" + +CBIOS_U32 HDTV_REG_LB[HDTV_MODU_NUM] = {0x33694, 0x33C34, 0x34334, 0x34A34}; +CBIOS_U32 HDTV_REG_CTRL[HDTV_MODU_NUM] = {0x338B8, 0x33E88, 0x34598, 0x34C98}; +CBIOS_U32 HDTV_REG_SYNC_DELAY[HDTV_MODU_NUM] = {0x338C0, 0x33E90, 0x345A0, 0x34CA0}; +CBIOS_U32 HDTV_REG_LEFT_BLANK[HDTV_MODU_NUM] = {0x338CC, 0x33E9C, 0x345AC, 0x34CAC}; +CBIOS_U32 HDTV_REG_HSYNC[HDTV_MODU_NUM] = {0x338D0, 0x33EA0, 0x345B0, 0x34CB0}; +CBIOS_U32 HDTV_REG_BROAD_PULSE[HDTV_MODU_NUM] = {0x338D4, 0x33EA4, 0x345B4, 0x34CB4}; +CBIOS_U32 HDTV_REG_HALF_SYNC[HDTV_MODU_NUM] = {0x338D8, 0x33EA8, 0x345B8, 0x34CB8}; +CBIOS_U32 HDTV_REG_HDE[HDTV_MODU_NUM] = {0x338E4, 0x33EB4, 0x345C4, 0x34CC4}; +CBIOS_U32 HDTV_REG_ENABLE[HDTV_MODU_NUM] = {0x338FC, 0x33ECC, 0x345DC, 0x34CDC}; + + +CBIOS_VOID cbDIU_HDTV_ModuleOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDTVModuleIndex, CBIOS_BOOL bTurnOn) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_VOID)pvcbe; + REG_MM338B8 HDTVCtrlRegValue, HDTVCtrlRegMask; + REG_MM338FC HDTVEnableRegValue, HDTVEnableRegMask; + + if (HDTVModuleIndex >= HDTV_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid HDTV module index!\n", FUNCTION_NAME)); + return; + } + + if (bTurnOn) + { + HDTVCtrlRegValue.Value = 0; + HDTVCtrlRegValue.HDTV_Timing_Enable_Control = 1; + HDTVCtrlRegMask.Value = 0xFFFFFFFF; + HDTVCtrlRegMask.HDTV_Timing_Enable_Control = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_CTRL[HDTVModuleIndex], HDTVCtrlRegValue.Value, HDTVCtrlRegMask.Value); + + HDTVEnableRegValue.Value = 0; + HDTVEnableRegValue.HDTV_Enable = 1; + HDTVEnableRegMask.Value = 0xFFFFFFFF; + HDTVEnableRegMask.HDTV_Enable = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_ENABLE[HDTVModuleIndex], HDTVEnableRegValue.Value, HDTVEnableRegMask.Value); + } + else + { + HDTVEnableRegValue.Value = 0; + HDTVEnableRegValue.HDTV_Enable = 0; + HDTVEnableRegMask.Value = 0xFFFFFFFF; + HDTVEnableRegMask.HDTV_Enable = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_ENABLE[HDTVModuleIndex], HDTVEnableRegValue.Value, HDTVEnableRegMask.Value); + + HDTVCtrlRegValue.Value = 0; + HDTVCtrlRegValue.HDTV_Timing_Enable_Control = 0; + HDTVCtrlRegMask.Value = 0xFFFFFFFF; + HDTVCtrlRegMask.HDTV_Timing_Enable_Control = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_CTRL[HDTVModuleIndex], HDTVCtrlRegValue.Value, HDTVCtrlRegMask.Value); + } +} + +CBIOS_VOID cbDIU_HDTV_LBBypass(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDTVModuleIndex, CBIOS_BOOL isBypass) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_VOID)pvcbe; + REG_MM33694 HDTVLineBufRegValue, HDTVLineBufRegMask; + + if (HDTVModuleIndex >= HDTV_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid HDTV module index!\n", FUNCTION_NAME)); + return; + } + + HDTVLineBufRegValue.Value = 0; + HDTVLineBufRegValue.LB1_BYPASS = (isBypass)? 1 : 0; + HDTVLineBufRegMask.Value = 0xFFFFFFFF; + HDTVLineBufRegMask.LB1_BYPASS = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_LB[HDTVModuleIndex], HDTVLineBufRegValue.Value, HDTVLineBufRegMask.Value); +} + + +CBIOS_VOID cbDoHDTVFuncSetting_Arise(PCBIOS_VOID pvcbe, + PCBIOS_DISP_MODE_PARAMS pModeParams, + CBIOS_U32 IGAIndex, + CBIOS_ACTIVE_TYPE ulDevices) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_VOID)pvcbe; + CBIOS_U32 HSyncWidth, VSyncWidth, HSyncToHActive, BlankLevel; + CBIOS_U32 HSyncDelay = 0; + CBIOS_U32 HorizontalDisplayEnd, HorizontalTotal; + REG_MM338B8 HDTVCtrlRegValue, HDTVCtrlRegMask; + REG_MM338C0 HDTVSyncDelayRegValue, HDTVSyncDelayRegMask; + REG_MM338CC HDTVLeftBlankRegValue, HDTVLeftBlankRegMask; + REG_MM338D0 HDTVHsyncRegValue, HDTVHsyncRegMask; + REG_MM338D4 HDTVBroadPulseRegValue, HDTVBroadPulseRegMask; + REG_MM338D8 HDTVHalfSyncRegValue, HDTVHalfSyncRegMask; + REG_MM338E4 HDTVHdeRegValue, HDTVHdeRegMask; + REG_MM338FC HDTVEnableRegValue, HDTVEnableRegMask; + PCBIOS_TIMING_ATTRIB pTimingReg = &pModeParams->TargetTiming; + CBIOS_MODULE_INDEX HDTVModuleIndex = IGAIndex; + + if (HDTVModuleIndex >= HDTV_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid HDTV module index!\n", FUNCTION_NAME)); + return; + } + + // always not compatible with ITU470 + HDTVCtrlRegValue.Value = 0; + HDTVCtrlRegValue.ITU470_SELECT = 0; + HDTVCtrlRegMask.Value = 0xFFFFFFFF; + HDTVCtrlRegMask.ITU470_SELECT = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_CTRL[HDTVModuleIndex], HDTVCtrlRegValue.Value, HDTVCtrlRegMask.Value); + + HSyncWidth = (pTimingReg->HorSyncEnd - pTimingReg->HorSyncStart); + HorizontalDisplayEnd = (CBIOS_U32)pTimingReg->HorDisEnd; + HorizontalTotal = (CBIOS_U32)pTimingReg->HorTotal; + HSyncToHActive = (pTimingReg->HorTotal - pTimingReg->HorSyncStart); + VSyncWidth = (pTimingReg->VerSyncEnd - pTimingReg->VerSyncStart); + + if(pTimingReg->XRes == 720) + { + HSyncDelay = 05; + } + else + { + HSyncDelay = 0; + } + + if ((pModeParams->TargetModePara.bInterlace) + && (pTimingReg->YRes == 576)) + { + BlankLevel = 126; + } + else + { + BlankLevel = 252; + } + + // HDTV Tri-Level SYNC Width, HDTV BLANK Level + HDTVCtrlRegValue.Value = 0; + HDTVCtrlRegValue.Trilevel_Sync_Width = HSyncWidth - 6; + HDTVCtrlRegValue.Blank_Level = BlankLevel; + HDTVCtrlRegMask.Value = 0xFFFFFFFF; + HDTVCtrlRegMask.Trilevel_Sync_Width = 0; + HDTVCtrlRegMask.Blank_Level = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_CTRL[HDTVModuleIndex], HDTVCtrlRegValue.Value, HDTVCtrlRegMask.Value); + + // HDTV SYNC Delay + HDTVSyncDelayRegValue.Value = 0; + HDTVSyncDelayRegMask.Value = 0xFFFFFFFF; + HDTVSyncDelayRegMask.HDTV_SYNC_Delay_7to0 = 0; + HDTVSyncDelayRegMask.HDTV_SYNC_Delay_10to8 = 0; + if (pModeParams->TargetModePara.bInterlace) + { + HDTVSyncDelayRegValue.HDTV_SYNC_Delay_7to0 = (HorizontalTotal/2) & 0xFF; + HDTVSyncDelayRegValue.HDTV_SYNC_Delay_10to8 = ((HorizontalTotal/2) >> 8 ) & 0x07; + } + else + { + HDTVSyncDelayRegValue.HDTV_SYNC_Delay_7to0 = 0; + HDTVSyncDelayRegValue.HDTV_SYNC_Delay_10to8 = 0; + } + cbMMIOWriteReg32(pcbe, HDTV_REG_SYNC_DELAY[HDTVModuleIndex], HDTVSyncDelayRegValue.Value, HDTVSyncDelayRegMask.Value); + + // HDTV Left Blank Pixels, this value of HDTV and HDMI are different. + HDTVLeftBlankRegValue.Value = 0; + HDTVLeftBlankRegValue.Left_Blank_Pixels_7to0 = (HSyncToHActive - 1) & 0xFF; + HDTVLeftBlankRegValue.Left_Blank_Pixels_10to8 = ((HSyncToHActive - 1) >> 8 ) & 0x07; + HDTVLeftBlankRegMask.Value = 0xFFFFFFFF; + HDTVLeftBlankRegMask.Left_Blank_Pixels_7to0 = 0; + HDTVLeftBlankRegMask.Left_Blank_Pixels_10to8 = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_LEFT_BLANK[HDTVModuleIndex], HDTVLeftBlankRegValue.Value, HDTVLeftBlankRegMask.Value); + + // HDTV Digital HSYNC Width and HDTV HSYNC Delay + HDTVHsyncRegValue.Value = 0; + HDTVHsyncRegValue.HDTV_Digital_HSYNC_Width = (HSyncWidth - 1); + HDTVHsyncRegValue.HDTV_HSYNC_Delay = HSyncDelay; + HDTVHsyncRegMask.Value = 0xFFFFFFFF; + HDTVHsyncRegMask.HDTV_Digital_HSYNC_Width = 0; + HDTVHsyncRegMask.HDTV_HSYNC_Delay = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_HSYNC[HDTVModuleIndex], HDTVHsyncRegValue.Value, HDTVHsyncRegMask.Value); + + // HDTV Broad Pulse + HDTVBroadPulseRegValue.Value = 0; + HDTVBroadPulseRegMask.Value = 0xFFFFFFFF; + HDTVBroadPulseRegMask.Hdtv_Broad_Pulse_6to0 = 0; + HDTVHalfSyncRegValue.Value = 0; + HDTVHalfSyncRegMask.Value = 0xFFFFFFFF; + HDTVHalfSyncRegMask.Hdtv_Broad_Pulse_14to7 = 0; + + if (pModeParams->TargetModePara.bInterlace) + { + HDTVBroadPulseRegValue.Hdtv_Broad_Pulse_6to0 = (HorizontalTotal*VSyncWidth/2) & 0x7F; + HDTVHalfSyncRegValue.Hdtv_Broad_Pulse_14to7 = ((HorizontalTotal*VSyncWidth/2) >> 7) & 0xFF; + } + else + { + HDTVBroadPulseRegValue.Hdtv_Broad_Pulse_6to0 = (HorizontalTotal*VSyncWidth) & 0x7F; + HDTVHalfSyncRegValue.Hdtv_Broad_Pulse_14to7 = ((HorizontalTotal*VSyncWidth) >> 7) & 0xFF; + } + cbMMIOWriteReg32(pcbe, HDTV_REG_BROAD_PULSE[HDTVModuleIndex], HDTVBroadPulseRegValue.Value, HDTVBroadPulseRegMask.Value); + cbMMIOWriteReg32(pcbe, HDTV_REG_HALF_SYNC[HDTVModuleIndex], HDTVHalfSyncRegValue.Value, HDTVHalfSyncRegMask.Value); + + // HDTV Half SYNC, only applies to SMPTE274M 1080i + if ((pModeParams->TargetModePara.bInterlace) + && (pModeParams->TargetModePara.XRes == 1920) + && (pModeParams->TargetModePara.YRes == 1080)) + { + HDTVHalfSyncRegValue.Value = 0; + HDTVHalfSyncRegValue.Hdtv_Half_Sync_10to0 = (HorizontalTotal/2); + HDTVHalfSyncRegMask.Value = 0xFFFFFFFF; + HDTVHalfSyncRegMask.Hdtv_Half_Sync_10to0 = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_HALF_SYNC[HDTVModuleIndex], HDTVHalfSyncRegValue.Value, HDTVHalfSyncRegMask.Value); + } + + // HDTV HDE + HDTVHdeRegValue.Value = 0; + HDTVHdeRegValue.HDTV_HDE_10to0 = (HorizontalDisplayEnd-1); + HDTVHdeRegMask.Value = 0xFFFFFFFF; + HDTVHdeRegMask.HDTV_HDE_10to0 = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_HDE[HDTVModuleIndex], HDTVHdeRegValue.Value, HDTVHdeRegMask.Value); + + //Disable first in case SRB_8F.HDTV_Enable already set somewhere,which will causing timing incorrect + //and the final result is display show abnormal, like image sperated into three part. + HDTVEnableRegValue.Value = 0; + HDTVEnableRegValue.HDTV_Enable = 0; + HDTVEnableRegMask.Value = 0xFFFFFFFF; + HDTVEnableRegMask.HDTV_Enable = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_ENABLE[HDTVModuleIndex], HDTVEnableRegValue.Value, HDTVEnableRegMask.Value); + + if (pModeParams->TargetModePara.bInterlace) + { + HDTVCtrlRegValue.Value = 0; + HDTVCtrlRegValue.Progressive_Mode_Enable = 0; + HDTVCtrlRegMask.Value = 0xFFFFFFFF; + HDTVCtrlRegMask.Progressive_Mode_Enable = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_CTRL[HDTVModuleIndex], HDTVCtrlRegValue.Value, HDTVCtrlRegMask.Value); + + if (((pTimingReg->XRes == 720) &&(pTimingReg->YRes == 576)) || ((pTimingReg->XRes == 720) &&(pTimingReg->YRes == 480))) + { + HDTVCtrlRegValue.Value = 0; + HDTVCtrlRegValue._576i_480i_enable = 1; + HDTVCtrlRegMask.Value = 0xFFFFFFFF; + HDTVCtrlRegMask._576i_480i_enable = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_CTRL[HDTVModuleIndex], HDTVCtrlRegValue.Value, HDTVCtrlRegMask.Value); + } + else if ((pTimingReg->XRes == 1920) &&(pTimingReg->YRes == 1080)) + { + HDTVCtrlRegValue.Value = 0; + HDTVCtrlRegValue.SMPTE_274M_Enable = 1; + HDTVCtrlRegMask.Value = 0xFFFFFFFF; + HDTVCtrlRegMask.SMPTE_274M_Enable = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_CTRL[HDTVModuleIndex], HDTVCtrlRegValue.Value, HDTVCtrlRegMask.Value); + } + } + else + { + HDTVCtrlRegValue.Value = 0; + HDTVCtrlRegValue.Progressive_Mode_Enable = 1; + HDTVCtrlRegMask.Value = 0xFFFFFFFF; + HDTVCtrlRegMask.Progressive_Mode_Enable = 0; + cbMMIOWriteReg32(pcbe, HDTV_REG_CTRL[HDTVModuleIndex], HDTVCtrlRegValue.Value, HDTVCtrlRegMask.Value); + } +} diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDTV.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDTV.h new file mode 100644 index 0000000000000..c9be4cb459a2a --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_HDTV.h @@ -0,0 +1,35 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** HDTV hw block interface function prototype. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_DIU_HDTV_H_ +#define _CBIOS_DIU_HDTV_H_ + +#include "../../Display/CBiosDisplayManager.h" +#include "../../Device/CBiosDeviceShare.h" + +#define HDTV_MODU_NUM 4 + +CBIOS_VOID cbDIU_HDTV_ModuleOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDTVModuleIndex, CBIOS_BOOL bTurnOn); +CBIOS_VOID cbDIU_HDTV_LBBypass(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX HDTVModuleIndex, CBIOS_BOOL isBypass); +CBIOS_VOID cbDoHDTVFuncSetting_Arise(PCBIOS_VOID pvcbe, PCBIOS_DISP_MODE_PARAMS pModeParams, CBIOS_U32 IGAIndex, CBIOS_ACTIVE_TYPE ulDevices); +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_VIP.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_VIP.c new file mode 100644 index 0000000000000..b269090ad2b9d --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_VIP.c @@ -0,0 +1,1122 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** VIP hw block interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosDIU_VIP.h" +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" + +typedef struct _CBIOS_ADV7611_REGISTER +{ + CBIOS_U8 SlaveAddress; + CBIOS_U8 Offset; + CBIOS_U8 Data; + CBIOS_U8 DataMask; +} CBIOS_ADV7611_REGISTER, *PCBIOS_ADV7611_REGISTER; + +#define ADV7611_EDID_SLAVE 0x6C +#define ADV7611_REPEATER_SLAVE 0x64 +#define ADV7611_IO_SLAVE 0x98 +#define ADV7611_HDMI_SLAVE 0x68 +//perchip +CBIOS_VIP_MODE vipModeCapsTable[] = +{ + {1920, 1080, 6000, CBIOS_VIP_FMT_RGB444_24BIT_SDR}, + {1920, 1080, 6000, CBIOS_VIP_FMT_YCBCR444_24BIT_SDR}, + {1280, 720, 6000, CBIOS_VIP_FMT_YCBCR422_8BIT_SDR_ES}, +}; + +static CBIOS_ADV7611_REGISTER ADV7611RegTable[5][43] = +{ + // 0---1920x1080p@60Hz, RGB444-24bit-SDR-SS + { + {0x98, 0xf4, 0x80, 0xff}, + {0x98, 0xf5, 0x7c, 0xff}, + {0x98, 0xf8, 0x4c, 0xff}, + {0x98, 0xf9, 0x64, 0xff}, + {0x98, 0xfa, 0x6c, 0xff}, + {0x98, 0xfb, 0x68, 0xff}, + {0x98, 0xfd, 0x44, 0xff}, + {0x98, 0x00, 0x1e, 0x3f}, // 0x00[5:0]: VID_STD = 0x1e 1920x1080p@60Hz mode + {0x98, 0x01, 0x05, 0x7f}, // 0x01[3:0]: PRIM_MODE = 0x5; 0x01[6:4]: V_FREQ=3'b000, vertical frequency=60Hz; + {0x98, 0x02, 0xf2, 0xff}, + {0x98, 0x03, 0x40, 0xff}, + {0x98, 0x04, 0x42, 0xe6}, + {0x98, 0x05, 0x08, 0x1f}, + {0x98, 0x06, 0x86, 0x8f}, + {0x98, 0x0b, 0x00, 0x03}, + {0x98, 0x0c, 0x00, 0x25}, + {0x98, 0x14, 0x3f, 0x3f}, + {0x98, 0x15, 0x00, 0x1e}, + {0x98, 0x19, 0x83, 0xdf}, + {0x98, 0x33, 0x40, 0x40}, + {0x44, 0xba, 0x01, 0x03}, + {0x44, 0xc9, 0x05, 0x05}, + {0x64, 0x40, 0x81, 0xff}, + {0x68, 0x8d, 0x0b, 0xff}, //0x8d[7:0]:EQ_DYN1_LF = 0x0b, Default LF gain equalizer settings for dynamic mode range 1 + {0x68, 0x8e, 0x80, 0xff}, //0x8e[7:0]:EQ_DYN1_HF = 0x80, Default HF gain equalizer settings for dynamic mode range 1 + {0x68, 0x96, 0x00, 0x01}, //0x96[0]:EQ_DTN_EN=1'b0, Disable HDMI equalizer dynamic mode + {0x68, 0x9b, 0x03, 0xff}, + {0x68, 0xc1, 0x01, 0xff}, + {0x68, 0xc2, 0x01, 0xff}, + {0x68, 0xc3, 0x01, 0xff}, + {0x68, 0xc4, 0x01, 0xff}, + {0x68, 0xc5, 0x01, 0xff}, + {0x68, 0xc6, 0x01, 0xff}, + {0x68, 0xc7, 0x01, 0xff}, + {0x68, 0xc8, 0x01, 0xff}, + {0x68, 0xc9, 0x01, 0xff}, + {0x68, 0xca, 0x01, 0xff}, + {0x68, 0xcb, 0x01, 0xff}, + {0x68, 0xcc, 0x01, 0xff}, + {0x68, 0x00, 0x00, 0x07}, + {0x68, 0x83, 0x00, 0x01}, + {0x68, 0x6c, 0x06, 0xff},//hpd + {0xff, 0xff, 0xff, 0xff}, + }, + // 1 ---1280x720p@60Hz, YCbCr422-8bit-SDR-ES + { + {0x98, 0xf4, 0x80, 0xff}, + {0x98, 0xf5, 0x7c, 0xff}, + {0x98, 0xf8, 0x4c, 0xff}, + {0x98, 0xf9, 0x64, 0xff}, + {0x98, 0xfa, 0x6c, 0xff}, + {0x98, 0xfb, 0x68, 0xff}, + {0x98, 0xfd, 0x44, 0xff}, + {0x98, 0x00, 0x13, 0x3f}, // 0x00[5:0]: VID_STD = 0x13 1280x720p@60Hz mode + {0x98, 0x01, 0x05, 0x7f}, // 0x01[3:0]: PRIM_MODE = 0x5; 0x01[6:4]: V_FREQ=3'b000, vertical frequency=60Hz; + {0x98, 0x02, 0xf4, 0xff}, // 0x02[1]: RGB_OUT=1'b0, YPbPr color space output; + {0x98, 0x03, 0x20, 0xff}, // 0x03[7:0]: OP_FORMAT_SEL=0x20, 8bit 4:2:2 SDR ITU-656 mode output; + {0x98, 0x04, 0x82, 0xe6}, // 0x04[7:5]: OP_CH_SEL=3'b100, P[7:0]=YCbCr8; + {0x98, 0x05, 0x0c, 0x1f}, // 0x05[2]: AVCODE_INSERT_EN=1'b1, insert AV codes into data stream; + //{0x98, 0x06, 0x86, 0x8f}, + {0x98, 0x0b, 0x00, 0x03}, + {0x98, 0x0c, 0x00, 0x25}, + {0x98, 0x14, 0x3f, 0x3f}, + {0x98, 0x15, 0x00, 0x1e}, + {0x98, 0x19, 0xc3, 0xdf}, // 0x19[6]: LLC_DLL_DOUBLE=1'b1, Double LLC frequency; + {0x98, 0x33, 0x40, 0x40}, + {0x44, 0xba, 0x01, 0x03}, + {0x44, 0xc9, 0x05, 0x05}, + {0x64, 0x40, 0x81, 0xff}, + {0x68, 0x8d, 0x0b, 0xff}, //0x8d[7:0]:EQ_DYN1_LF = 0x0b, Default LF gain equalizer settings for dynamic mode range 1 + {0x68, 0x8e, 0x80, 0xff}, //0x8e[7:0]:EQ_DYN1_HF = 0x80, Default HF gain equalizer settings for dynamic mode range 1 + {0x68, 0x96, 0x00, 0x01}, //0x96[0]:EQ_DTN_EN=1'b0, Disable HDMI equalizer dynamic mode + {0x68, 0x9b, 0x03, 0xff}, + {0x68, 0xc1, 0x01, 0xff}, + {0x68, 0xc2, 0x01, 0xff}, + {0x68, 0xc3, 0x01, 0xff}, + {0x68, 0xc4, 0x01, 0xff}, + {0x68, 0xc5, 0x01, 0xff}, + {0x68, 0xc6, 0x01, 0xff}, + {0x68, 0xc7, 0x01, 0xff}, + {0x68, 0xc8, 0x01, 0xff}, + {0x68, 0xc9, 0x01, 0xff}, + {0x68, 0xca, 0x01, 0xff}, + {0x68, 0xcb, 0x01, 0xff}, + {0x68, 0xcc, 0x01, 0xff}, + {0x68, 0x00, 0x00, 0x07}, + {0x68, 0x83, 0x00, 0x01}, + {0x68, 0x6c, 0x06, 0xff},//hpd + {0xff, 0xff, 0xff, 0xff}, + }, + // 2 ---800x600p@60Hz, YCbCr422-8bit-DDR-ES + { + {0x98, 0xf4, 0x80, 0xff}, + {0x98, 0xf5, 0x7c, 0xff}, + {0x98, 0xf8, 0x4c, 0xff}, + {0x98, 0xf9, 0x64, 0xff}, + {0x98, 0xfa, 0x6c, 0xff}, + {0x98, 0xfb, 0x68, 0xff}, + {0x98, 0xfd, 0x44, 0xff}, + {0x98, 0x00, 0x01, 0x3f}, // 0x00[5:0]: VID_STD = 0x01 800x600@60Hz mode + {0x98, 0x01, 0x06, 0x7f}, // 0x01[3:0]: PRIM_MODE = 0x6; 0x01[6:4]: V_FREQ=3'b000, vertical frequency=60Hz; + {0x98, 0x02, 0xf4, 0xff}, // 0x02[1]: RGB_OUT=1'b0, YPbPr color space output; + {0x98, 0x03, 0x20, 0xff}, // 0x03[7:0]: OP_FORMAT_SEL=0x20, 8bit 4:2:2 DDR ITU-656 mode output; + {0x98, 0x04, 0x82, 0xe6}, // 0x04[7:5]: OP_CH_SEL=3'b100, P[7:0]=YCbCr8; + {0x98, 0x05, 0x0c, 0x1f}, // 0x05[2]: AVCODE_INSERT_EN=1'b1, insert AV codes into data stream; + //{0x98, 0x06, 0x86, 0x8f}, + {0x98, 0x0b, 0x00, 0x03}, + {0x98, 0x0c, 0x00, 0x25}, + {0x98, 0x14, 0x3f, 0x3f}, + {0x98, 0x15, 0x00, 0x1e}, + //{0x98, 0x19, 0xc3, 0xdf}, // 0x19[6]: LLC_DLL_DOUBLE=1'b1, Double LLC frequency; + {0x98, 0x19, 0x83, 0xdf}, // 0x19[6]: LLC_DLL_DOUBLE=1'b0, Normal LLC frequency, not double; + {0x98, 0x33, 0x40, 0x40}, + {0x44, 0xba, 0x01, 0x03}, + {0x44, 0xc9, 0x05, 0x05}, + {0x64, 0x40, 0x81, 0xff}, + {0x68, 0x8d, 0x0b, 0xff}, //0x8d[7:0]:EQ_DYN1_LF = 0x0b, Default LF gain equalizer settings for dynamic mode range 1 + {0x68, 0x8e, 0x80, 0xff}, //0x8e[7:0]:EQ_DYN1_HF = 0x80, Default HF gain equalizer settings for dynamic mode range 1 + {0x68, 0x96, 0x00, 0x01}, //0x96[0]:EQ_DTN_EN=1'b0, Disable HDMI equalizer dynamic mode + {0x68, 0x9b, 0x03, 0xff}, + {0x68, 0xc1, 0x01, 0xff}, + {0x68, 0xc2, 0x01, 0xff}, + {0x68, 0xc3, 0x01, 0xff}, + {0x68, 0xc4, 0x01, 0xff}, + {0x68, 0xc5, 0x01, 0xff}, + {0x68, 0xc6, 0x01, 0xff}, + {0x68, 0xc7, 0x01, 0xff}, + {0x68, 0xc8, 0x01, 0xff}, + {0x68, 0xc9, 0x01, 0xff}, + {0x68, 0xca, 0x01, 0xff}, + {0x68, 0xcb, 0x01, 0xff}, + {0x68, 0xcc, 0x01, 0xff}, + {0x68, 0x00, 0x00, 0x07}, + {0x68, 0x83, 0x00, 0x01}, + {0x68, 0x6c, 0x06, 0xff},//hpd + {0xff, 0xff, 0xff, 0xff}, + }, + // 3---1920x1080p@60Hz, YCbCr444-24bit-SDR-SS + { + {0x98, 0xf4, 0x80, 0xff}, + {0x98, 0xf5, 0x7c, 0xff}, + {0x98, 0xf8, 0x4c, 0xff}, + {0x98, 0xf9, 0x64, 0xff}, + {0x98, 0xfa, 0x6c, 0xff}, + {0x98, 0xfb, 0x68, 0xff}, + {0x98, 0xfd, 0x44, 0xff}, + {0x98, 0x00, 0x1e, 0x3f}, // 0x00[5:0]: VID_STD = 0x1e 1920x1080p@60Hz mode + {0x98, 0x01, 0x05, 0x7f}, // 0x01[3:0]: PRIM_MODE = 0x5; 0x01[6:4]: V_FREQ=3'b000, vertical frequency=60Hz; + {0x98, 0x02, 0xf0, 0xff}, // 0x02[1]: RGB_OUT=1'b0, YPbPr color space output; + {0x98, 0x03, 0x40, 0xff}, // 0x03[7:0]: OP_FORMAT_SEL=0x40, 24bit 444 SDR mode output; + {0x98, 0x04, 0x42, 0xe6}, // 0x04[7:5]: OP_CH_SEL=3'b010, P[23:0]=UYV888=CbYCr888; + {0x98, 0x05, 0x08, 0x1f}, + {0x98, 0x06, 0x86, 0x8f}, + {0x98, 0x0b, 0x00, 0x03}, + {0x98, 0x0c, 0x00, 0x25}, + {0x98, 0x14, 0x3f, 0x3f}, + {0x98, 0x15, 0x00, 0x1e}, + {0x98, 0x19, 0x83, 0xdf}, + {0x98, 0x33, 0x40, 0x40}, + {0x44, 0xba, 0x01, 0x03}, + {0x44, 0xc9, 0x05, 0x05}, + {0x64, 0x40, 0x81, 0xff}, + {0x68, 0x8d, 0x0b, 0xff}, //0x8d[7:0]:EQ_DYN1_LF = 0x0b, Default LF gain equalizer settings for dynamic mode range 1 + {0x68, 0x8e, 0x80, 0xff}, //0x8e[7:0]:EQ_DYN1_HF = 0x80, Default HF gain equalizer settings for dynamic mode range 1 + {0x68, 0x96, 0x00, 0x01}, //0x96[0]:EQ_DTN_EN=1'b0, Disable HDMI equalizer dynamic mode + {0x68, 0x9b, 0x03, 0xff}, + {0x68, 0xc1, 0x01, 0xff}, + {0x68, 0xc2, 0x01, 0xff}, + {0x68, 0xc3, 0x01, 0xff}, + {0x68, 0xc4, 0x01, 0xff}, + {0x68, 0xc5, 0x01, 0xff}, + {0x68, 0xc6, 0x01, 0xff}, + {0x68, 0xc7, 0x01, 0xff}, + {0x68, 0xc8, 0x01, 0xff}, + {0x68, 0xc9, 0x01, 0xff}, + {0x68, 0xca, 0x01, 0xff}, + {0x68, 0xcb, 0x01, 0xff}, + {0x68, 0xcc, 0x01, 0xff}, + {0x68, 0x00, 0x00, 0x07}, + {0x68, 0x83, 0x00, 0x01}, + {0x68, 0x6c, 0x06, 0xff},//hpd + {0xff, 0xff, 0xff, 0xff}, + }, + // 4 ---1280x720p@60Hz, YCbCr422-8bit-DDR-ES + { + {0x98, 0xf4, 0x80, 0xff}, + {0x98, 0xf5, 0x7c, 0xff}, + {0x98, 0xf8, 0x4c, 0xff}, + {0x98, 0xf9, 0x64, 0xff}, + {0x98, 0xfa, 0x6c, 0xff}, + {0x98, 0xfb, 0x68, 0xff}, + {0x98, 0xfd, 0x44, 0xff}, + {0x98, 0x00, 0x13, 0x3f}, // 0x00[5:0]: VID_STD = 0x13 1280x720p@60Hz mode + {0x98, 0x01, 0x05, 0x7f}, // 0x01[3:0]: PRIM_MODE = 0x5; 0x01[6:4]: V_FREQ=3'b000, vertical frequency=60Hz; + {0x98, 0x02, 0xf4, 0xff}, // 0x02[1]: RGB_OUT=1'b0, YPbPr color space output; + {0x98, 0x03, 0x20, 0xff}, // 0x03[7:0]: OP_FORMAT_SEL=0x20, 8bit 4:2:2 DDR ITU-656 mode output; + {0x98, 0x04, 0x82, 0xe6}, // 0x04[7:5]: OP_CH_SEL=3'b100, P[7:0]=YCbCr8; + {0x98, 0x05, 0x0c, 0x1f}, // 0x05[2]: AVCODE_INSERT_EN=1'b1, insert AV codes into data stream; + //{0x98, 0x06, 0x86, 0x8f}, + {0x98, 0x0b, 0x00, 0x03}, + {0x98, 0x0c, 0x00, 0x25}, + {0x98, 0x14, 0x3f, 0x3f}, + {0x98, 0x15, 0x00, 0x1e}, + {0x98, 0x19, 0x83, 0xdf}, // 0x19[6]: LLC_DLL_DOUBLE=1'b0, Normal LLC frequency, not double; + {0x98, 0x33, 0x40, 0x40}, + {0x44, 0xba, 0x01, 0x03}, + {0x44, 0xc9, 0x05, 0x05}, + {0x64, 0x40, 0x81, 0xff}, + {0x68, 0x8d, 0x0b, 0xff}, //0x8d[7:0]:EQ_DYN1_LF = 0x0b, Default LF gain equalizer settings for dynamic mode range 1 + {0x68, 0x8e, 0x80, 0xff}, //0x8e[7:0]:EQ_DYN1_HF = 0x80, Default HF gain equalizer settings for dynamic mode range 1 + {0x68, 0x96, 0x00, 0x01}, //0x96[0]:EQ_DTN_EN=1'b0, Disable HDMI equalizer dynamic mode + {0x68, 0x9b, 0x03, 0xff}, + {0x68, 0xc1, 0x01, 0xff}, + {0x68, 0xc2, 0x01, 0xff}, + {0x68, 0xc3, 0x01, 0xff}, + {0x68, 0xc4, 0x01, 0xff}, + {0x68, 0xc5, 0x01, 0xff}, + {0x68, 0xc6, 0x01, 0xff}, + {0x68, 0xc7, 0x01, 0xff}, + {0x68, 0xc8, 0x01, 0xff}, + {0x68, 0xc9, 0x01, 0xff}, + {0x68, 0xca, 0x01, 0xff}, + {0x68, 0xcb, 0x01, 0xff}, + {0x68, 0xcc, 0x01, 0xff}, + {0x68, 0x00, 0x00, 0x07}, + {0x68, 0x83, 0x00, 0x01}, + {0x68, 0x6c, 0x06, 0xff},//hpd + {0xff, 0xff, 0xff, 0xff}, + }, +}; + +CBIOS_PARALLEL_REGISTER VIP_Parallel_Reg_Tbl[] = +{ + {VIP_REG0, {0x33730, 0x33734, 0x33738, 0x3373C}}, + {VIP_REG1, {0x33740, 0x33770, 0x337A0, 0x337D0}}, + {VIP_REG2, {0x33744, 0x33774, 0x337A4, 0x337D4}}, + {VIP_REG3, {0x33748, 0x33778, 0x337A8, 0x337D8}}, + {VIP_REG4, {0x3374C, 0x3377C, 0x337AC, 0x337DC}}, + {VIP_REG5, {0x33750, 0x33780, 0x337B0, 0x337E0}}, + {VIP_REG6, {0x33754, 0x33784, 0x337B4, 0x337E4}}, + {VIP_REG7, {0x33758, 0x33788, 0x337B8, 0x337E8}}, + {VIP_REG8, {0x3375C, 0x3378C, 0x337BC, 0x337EC}}, + {VIP_REG9, {0x33760, 0x33790, 0x337C0, 0x337F0}}, + {VIP_REG10, {0x33764, 0x33794, 0x337C4, 0x337F4}}, + {VIP_REG11, {0x33768, 0x33798, 0x337C8, 0x337F8}}, + {VIP_REG12, {0x3376C, 0x3379C, 0x337CC, 0x337FC}}, + {PARALLEL_TABLE_END_INDEX, {0, 0, 0, 0}}, +}; + +CBIOS_PARALLEL_REGISTER VIP_IIC_Parallel_Reg_Tbl[] = +{ + {VIP_IIC_RW_DATA_REG, {0x33888, 0x33890, 0x33898, 0x338A0}}, + {VIP_IIC_CONTROL_REG, {0x3388C, 0x33894, 0x3389C, 0x338A4}}, + {VIP_IIC_IE, {CR_EE, CR_EF, CR_B_C7, CR_B_C8}}, + {PARALLEL_TABLE_END_INDEX, {0, 0, 0, 0}}, +}; + +CBIOS_STATUS cbVIPI2CDataRead(PCBIOS_VOID pvcbe, PCBIOS_PARAM_VIPI2C_DATA pCbiosVIPI2CParams); +CBIOS_STATUS cbVIPI2CDataWrite(PCBIOS_VOID pvcbe, PCBIOS_PARAM_VIPI2C_DATA pCbiosVIPI2CParams); + +CBIOS_U8 TestVIPEDID[256] = +{ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x59, 0x30, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x1E, 0x01, 0x03, 0x80, 0x30, 0x1B, 0x78, 0x2E, 0x35, 0x85, 0xA6, 0x56, 0x48, 0x9A, 0x24, + 0x12, 0x50, 0x54, 0x21, 0x08, 0x00, 0x81, 0x80, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C, + 0x45, 0x00, 0xDC, 0x0C, 0x11, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x31, 0x31, 0x31, + 0x31, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x56, + 0x49, 0x50, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3B, + 0x02, 0x03, 0x16, 0xF1, 0x43, 0x90, 0x04, 0x01, 0x23, 0x09, 0x06, 0x03, 0x83, 0x01, 0x00, 0x00, + 0x65, 0x03, 0x0C, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF +}; + +CBIOS_STATUS cbAdv7611SetEDID(PCBIOS_VOID pvcbe, CBIOS_U8 VIPPortIndex, CBIOS_U8 *pEDIDBuffer, CBIOS_U32 Size) +{ + CBIOS_U32 i = 0; + CBIOS_U8 data = 0; + CBIOS_PARAM_VIPI2C_DATA CbiosVIPI2CParams = {0}; + + if ((Size > 512) || ((Size & 0x7F) != 0) || (pEDIDBuffer == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "Invalid EDID!! VIPPortIndex=%d\n", VIPPortIndex)); + return CBIOS_FALSE; + } + + + //disable internal edid + CbiosVIPI2CParams.PortNumber = VIPPortIndex; + CbiosVIPI2CParams.SlaveAddress = ADV7611_REPEATER_SLAVE; + CbiosVIPI2CParams.Offset = 0x77; + data = 0x00; + CbiosVIPI2CParams.Buffer = &data; + CbiosVIPI2CParams.BufferLen = 1; + + cbVIPI2CDataWrite(pvcbe, &CbiosVIPI2CParams); + + + //write EDID + for (i = 0; i < Size; i++) + { + CbiosVIPI2CParams.SlaveAddress = ADV7611_EDID_SLAVE; + CbiosVIPI2CParams.Offset = (CBIOS_U8)i; + CbiosVIPI2CParams.Buffer = pEDIDBuffer + i; + CbiosVIPI2CParams.BufferLen = 1; + + cbVIPI2CDataWrite(pvcbe, &CbiosVIPI2CParams); + } + + //enable internal EDID + CbiosVIPI2CParams.SlaveAddress = ADV7611_REPEATER_SLAVE; + CbiosVIPI2CParams.Offset = 0x74; + data = 0x03; + CbiosVIPI2CParams.Buffer = &data; + CbiosVIPI2CParams.BufferLen = 1; + + cbVIPI2CDataWrite(pvcbe, &CbiosVIPI2CParams); + + //hotplug assert + CbiosVIPI2CParams.SlaveAddress = ADV7611_IO_SLAVE; + CbiosVIPI2CParams.Offset = 0x20; + CbiosVIPI2CParams.Buffer = &data; + CbiosVIPI2CParams.BufferLen = 1; + cbVIPI2CDataRead(pvcbe, &CbiosVIPI2CParams); + data |= 0x80; + cbVIPI2CDataWrite(pvcbe, &CbiosVIPI2CParams); + cb_DelayMicroSeconds(100000);//delay 100ms to avoid flash blue screen when source device setting mode + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "set edid done!\n")); + + return CBIOS_TRUE; + +} +CBIOS_STATUS cbSetVIPCard(PCBIOS_VOID pvcbe, PCBIOS_PARAM_VIPSETCARD_DATA pCbiosVIPSetCardParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_PARAM_VIPI2C_DATA CbiosVIPI2CParams = {0}; + CBIOS_U8 VIPI2CData; + CBIOS_U32 i, j; + CBIOS_U8 VIPPortIndex = pCbiosVIPSetCardParams->PortNumber; + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "cbSetVIPCard: VIP=%d, %dx%d@%dHz, VIPFormat=%d\n", + VIPPortIndex, pCbiosVIPSetCardParams->XRes, pCbiosVIPSetCardParams->YRes, pCbiosVIPSetCardParams->RefreshRate / 100, pCbiosVIPSetCardParams->VIPFormat)); + + if(VIPPortIndex > 3) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "NOT support this VIP Port: VIPPortIndex=%d\n", VIPPortIndex)); + return CBIOS_ER_NOT_YET_IMPLEMENTED; + } + + if((pCbiosVIPSetCardParams->XRes == 1920) && (pCbiosVIPSetCardParams->YRes == 1080) && (pCbiosVIPSetCardParams->RefreshRate == 6000) + && (pCbiosVIPSetCardParams->VIPFormat == CBIOS_VIP_FMT_RGB444_24BIT_SDR)) + { + i = 0; + } + else if((pCbiosVIPSetCardParams->XRes == 1280) && (pCbiosVIPSetCardParams->YRes == 720) && (pCbiosVIPSetCardParams->RefreshRate == 6000) + && (pCbiosVIPSetCardParams->VIPFormat == CBIOS_VIP_FMT_YCBCR422_8BIT_SDR_ES)) + { + i = 1; + } + else if((pCbiosVIPSetCardParams->XRes == 800) && (pCbiosVIPSetCardParams->YRes == 600) && (pCbiosVIPSetCardParams->RefreshRate == 6000) + && (pCbiosVIPSetCardParams->VIPFormat == CBIOS_VIP_FMT_YCBCR422_8BIT_DDR_ES)) + { + i = 2; + } + else if((pCbiosVIPSetCardParams->XRes == 1920) && (pCbiosVIPSetCardParams->YRes == 1080) && (pCbiosVIPSetCardParams->RefreshRate == 6000) + && (pCbiosVIPSetCardParams->VIPFormat == CBIOS_VIP_FMT_YCBCR444_24BIT_SDR)) + { + i = 3; + } + else if((pCbiosVIPSetCardParams->XRes == 1280) && (pCbiosVIPSetCardParams->YRes == 720) && (pCbiosVIPSetCardParams->RefreshRate == 6000) + && (pCbiosVIPSetCardParams->VIPFormat == CBIOS_VIP_FMT_YCBCR422_8BIT_DDR_ES)) + { + i = 4; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "NOT support this format: %dx%d@%dHz, Format=%d\n", + pCbiosVIPSetCardParams->XRes, pCbiosVIPSetCardParams->YRes, pCbiosVIPSetCardParams->RefreshRate / 100, pCbiosVIPSetCardParams->VIPFormat)); + return CBIOS_ER_NOT_YET_IMPLEMENTED; + } + + CbiosVIPI2CParams.PortNumber = VIPPortIndex; + CbiosVIPI2CParams.Buffer = &VIPI2CData; + CbiosVIPI2CParams.BufferLen = 1; //read/write one byte + + for(j=0; ADV7611RegTable[i][j].SlaveAddress != 0xFF; j++) + { + CbiosVIPI2CParams.SlaveAddress = ADV7611RegTable[i][j].SlaveAddress; + CbiosVIPI2CParams.Offset = ADV7611RegTable[i][j].Offset; + + cbVIPI2CDataRead(pcbe, &CbiosVIPI2CParams); + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "VIP=%d, I2C read, offset:0x%02x, value:0x%02x \n",VIPPortIndex, CbiosVIPI2CParams.Offset, VIPI2CData)); + + VIPI2CData = (VIPI2CData & ~ADV7611RegTable[i][j].DataMask) | (ADV7611RegTable[i][j].Data & ADV7611RegTable[i][j].DataMask); + CbiosVIPI2CParams.Buffer = &VIPI2CData; + cbVIPI2CDataWrite(pcbe, &CbiosVIPI2CParams); + cb_DelayMicroSeconds(1000);//delay 1ms + //cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "VIP=%d, I2C write, offset:0x%02x, data:0x%02x, value:0x%02x \n",VIPPortIndex, CbiosVIPI2CParams.Offset, ADV7611RegTable[i][j].Data, VIPI2CData)); + } + + cbAdv7611SetEDID(pcbe, VIPPortIndex, TestVIPEDID, sizeof(TestVIPEDID)); + + return CBIOS_OK; +} + +CBIOS_STATUS cbAdv7611Init(PCBIOS_VOID pvcbe, CBIOS_U8 VIPPortIndex) +{ + + CBIOS_PARAM_VIPI2C_DATA CbiosVIPI2CParams = {0}; + CBIOS_U8 data = 0; + + //reset + CbiosVIPI2CParams.PortNumber = VIPPortIndex; + CbiosVIPI2CParams.SlaveAddress = ADV7611_IO_SLAVE; + CbiosVIPI2CParams.Offset = 0xFF; + data = 0x80; + CbiosVIPI2CParams.Buffer = &data; + CbiosVIPI2CParams.BufferLen = 1; + + cbVIPI2CDataWrite(pvcbe, &CbiosVIPI2CParams); + //wait at least 5ms + cbDelayMilliSeconds(10); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "ADV7611 reset!\n")); + //should move mode independent adv7611 init setting here + + return CBIOS_OK; + +} + +CBIOS_STATUS cbAdv7611DeInit(PCBIOS_VOID pvcbe, CBIOS_U8 VIPPortIndex) +{ + CBIOS_PARAM_VIPI2C_DATA CbiosVIPI2CParams = {0}; + CBIOS_U8 data = 0; + + + //disable internal edid + CbiosVIPI2CParams.PortNumber = VIPPortIndex; + CbiosVIPI2CParams.SlaveAddress = ADV7611_REPEATER_SLAVE; + CbiosVIPI2CParams.Offset = 0x74; + data = 0x00; + CbiosVIPI2CParams.Buffer = &data; + CbiosVIPI2CParams.BufferLen = 1; + + cbVIPI2CDataWrite(pvcbe, &CbiosVIPI2CParams); + + //hotplug de-assert + CbiosVIPI2CParams.SlaveAddress = ADV7611_IO_SLAVE; + CbiosVIPI2CParams.Offset = 0x20; + CbiosVIPI2CParams.Buffer = &data; + CbiosVIPI2CParams.BufferLen = 1; + cbVIPI2CDataRead(pvcbe, &CbiosVIPI2CParams); + data &= ~0x80; + cbVIPI2CDataWrite(pvcbe, &CbiosVIPI2CParams); + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "hpd out, clear EDID\n")); + + return CBIOS_OK; +} + +CBIOS_STATUS cbVIPQueryCaps(PCBIOS_VOID pvcbe, PCBIOS_VIP_CTRL_DATA pCbiosVIPCtlData) +{ + pCbiosVIPCtlData->caps.supportModeNum = sizeof(vipModeCapsTable)/sizeof(CBIOS_VIP_MODE); + pCbiosVIPCtlData->caps.mode = vipModeCapsTable; + + return CBIOS_OK; +} + +CBIOS_STATUS cbVIPSetMode(PCBIOS_VOID pvcbe, PCBIOS_VIP_CTRL_DATA pCbiosVIPCtlData) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 VIPPortIndex = pCbiosVIPCtlData->vip; + CBIOS_U32 VIP33740RegIndex; + CBIOS_U32 VIP33744RegIndex; + CBIOS_U32 VIP33748RegIndex; + CBIOS_U32 VIP3374CRegIndex; + CBIOS_U32 VIP33750RegIndex; + CBIOS_U32 VIP33760RegIndex; + + REG_MM33740_Arise VIP33740RegValue, VIP33740RegMask; + REG_MM33744_Arise VIP33744RegValue, VIP33744RegMask; + REG_MM33748_Arise VIP33748RegValue, VIP33748RegMask; + REG_MM3374C_Arise VIP3374CRegValue, VIP3374CRegMask; + REG_MM33750_Arise VIP33750RegValue, VIP33750RegMask; + REG_MM33760_Arise VIP33760RegValue, VIP33760RegMask; + + CBIOS_PARAM_VIPSETCARD_DATA CbiosVIPSetCardParams = {0}; + CBIOS_STATUS status = CBIOS_OK; + + VIP33740RegIndex = cbGetParallelRegIndex(VIP_Parallel_Reg_Tbl, VIP_REG1, VIPPortIndex); + VIP33744RegIndex = cbGetParallelRegIndex(VIP_Parallel_Reg_Tbl, VIP_REG2, VIPPortIndex); + VIP33748RegIndex = cbGetParallelRegIndex(VIP_Parallel_Reg_Tbl, VIP_REG3, VIPPortIndex); + VIP3374CRegIndex = cbGetParallelRegIndex(VIP_Parallel_Reg_Tbl, VIP_REG4, VIPPortIndex); + VIP33750RegIndex = cbGetParallelRegIndex(VIP_Parallel_Reg_Tbl, VIP_REG5, VIPPortIndex); + VIP33760RegIndex = cbGetParallelRegIndex(VIP_Parallel_Reg_Tbl, VIP_REG9, VIPPortIndex); + + //put adv7611 init here first + cbAdv7611Init(pvcbe, VIPPortIndex); + + if(((pCbiosVIPCtlData->modeSet.fmt != CBIOS_VIP_FMT_RGB444_24BIT_SDR) && + (pCbiosVIPCtlData->modeSet.fmt != CBIOS_VIP_FMT_YCBCR444_24BIT_SDR) && + (pCbiosVIPCtlData->modeSet.fmt != CBIOS_VIP_FMT_YCBCR422_8BIT_SDR_ES) && + (pCbiosVIPCtlData->modeSet.fmt != CBIOS_VIP_FMT_YCBCR422_8BIT_DDR_ES)) || + ((pCbiosVIPCtlData->modeSet.xRes > 1920) || (pCbiosVIPCtlData->modeSet.yRes > 1080))) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "NOT support this format: %dx%d, VIPFormat=%d\n",pCbiosVIPCtlData->modeSet.xRes, pCbiosVIPCtlData->modeSet.yRes, pCbiosVIPCtlData->modeSet.fmt)); + return CBIOS_ER_NOT_YET_IMPLEMENTED; + } + + // VIP Card configure + CbiosVIPSetCardParams.PortNumber = VIPPortIndex; + CbiosVIPSetCardParams.XRes = pCbiosVIPCtlData->modeSet.xRes; + CbiosVIPSetCardParams.YRes = pCbiosVIPCtlData->modeSet.yRes; + CbiosVIPSetCardParams.RefreshRate = pCbiosVIPCtlData->modeSet.refs; + CbiosVIPSetCardParams.VIPFormat = pCbiosVIPCtlData->modeSet.fmt; +#if 0 + vip_card = cbFindVipCard(pCbiosVIPCtlData->modeSet.vCard); + + if (vip_card != CBIOS_NULL) + { + vip_card->setMode(pvcbe, pCbiosVIPCtlData); + } +#endif + + status = cbSetVIPCard(pvcbe, &CbiosVIPSetCardParams); + if (CBIOS_OK != status) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "set vip card mode : %dx%d, VIPFormat=%d failed !!!\n",pCbiosVIPCtlData->modeSet.xRes, pCbiosVIPCtlData->modeSet.yRes, pCbiosVIPCtlData->modeSet.fmt)); + return status; + } + + // vip configure + VIP33750RegValue.Value = 0; + VIP33750RegValue.fifo_threshold = 10; + VIP33750RegValue.fifo_high_threshold = 50; + VIP33750RegValue.VIP_input_data_select = 0xFF; + VIP33750RegValue.reserved_2 = 1; + VIP33750RegValue.VIP_DVO_enable = 1; + VIP33750RegMask.Value = 0; + cbMMIOWriteReg32(pcbe, VIP33750RegIndex, VIP33750RegValue.Value, VIP33750RegMask.Value); + + VIP33744RegValue.Value = 0; + VIP33744RegValue.REG_auto_gen = 1; + if((pCbiosVIPCtlData->modeSet.fmt == CBIOS_VIP_FMT_RGB444_24BIT_SDR) || (pCbiosVIPCtlData->modeSet.fmt == CBIOS_VIP_FMT_YCBCR444_24BIT_SDR)) + { + VIP33744RegValue.VIP_hde_enable = 1; + VIP33744RegValue.VIP_sync_enable = 1; + } + VIP33744RegMask.Value = 0; + cbMMIOWriteReg32(pcbe, VIP33744RegIndex, VIP33744RegValue.Value, VIP33744RegMask.Value); + + VIP33760RegValue.Value = 0; + if((pCbiosVIPCtlData->modeSet.fmt == CBIOS_VIP_FMT_RGB444_24BIT_SDR) || (pCbiosVIPCtlData->modeSet.fmt == CBIOS_VIP_FMT_YCBCR444_24BIT_SDR)) + { + VIP33760RegValue.FB_stride = (pCbiosVIPCtlData->modeSet.xRes * 4) >> 6; + } + else + { + VIP33760RegValue.FB_stride = (pCbiosVIPCtlData->modeSet.xRes * 2) >> 6; + } + VIP33760RegMask.Value = 0; + cbMMIOWriteReg32(pcbe, VIP33760RegIndex, VIP33760RegValue.Value, VIP33760RegMask.Value); + + VIP33748RegValue.Value = 0; + VIP33748RegValue.VIP_ver_window_length = pCbiosVIPCtlData->modeSet.yRes; + VIP33748RegValue.crop_window_enable = 1; + VIP33748RegMask.Value = 0; + cbMMIOWriteReg32(pcbe, VIP33748RegIndex, VIP33748RegValue.Value, VIP33748RegMask.Value); + + VIP3374CRegValue.Value = 0; + if(pCbiosVIPCtlData->modeSet.fmt == CBIOS_VIP_FMT_YCBCR422_8BIT_SDR_ES) + { + VIP3374CRegValue.VIP_hor_length = pCbiosVIPCtlData->modeSet.xRes * 2; + } + else + { + VIP3374CRegValue.VIP_hor_length = pCbiosVIPCtlData->modeSet.xRes; + } + VIP3374CRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, VIP3374CRegIndex, VIP3374CRegValue.Value, VIP3374CRegMask.Value); + + VIP33740RegValue.Value = 0; + VIP33740RegMask.Value = 0XFFFFFFFF; + if(pCbiosVIPCtlData->modeSet.fmt == CBIOS_VIP_FMT_RGB444_24BIT_SDR) + { + VIP33740RegValue.video_mode = VIP_FMT_RGB444_24BIT_SDR; + VIP33740RegMask.video_mode = 0; + } + else if(pCbiosVIPCtlData->modeSet.fmt == CBIOS_VIP_FMT_YCBCR444_24BIT_SDR) + { + VIP33740RegValue.video_mode = VIP_FMT_YCBCR444_24BIT_SDR; + VIP33740RegMask.video_mode = 0; + } + else if(pCbiosVIPCtlData->modeSet.fmt == CBIOS_VIP_FMT_YCBCR422_8BIT_SDR_ES) + { + VIP33740RegValue.video_mode = VIP_FMT_YCBCR422_8BIT_SDR_ES; + VIP33740RegMask.video_mode = 0; + } + else if(pCbiosVIPCtlData->modeSet.fmt == CBIOS_VIP_FMT_YCBCR422_8BIT_DDR_ES) + { + VIP33740RegValue.video_mode = VIP_FMT_YCBCR422_8BIT_DDR_ES; + VIP33740RegValue.header_type = 1; + + VIP33740RegMask.video_mode = 0; + VIP33740RegMask.header_type = 1; + } + cbMMIOWriteReg32(pcbe, VIP33740RegIndex, VIP33740RegValue.Value, VIP33740RegMask.Value); + + return status; +} + + +CBIOS_STATUS cbVIPSetBuffer(PCBIOS_VOID pvcbe, PCBIOS_VIP_CTRL_DATA pCbiosVIPCtlData) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 VIPPortIndex = pCbiosVIPCtlData->vip; + CBIOS_U32 VIP33754RegIndex; + CBIOS_U32 VIP33758RegIndex; + CBIOS_U32 VIP3375CRegIndex; + + REG_MM33754_Arise VIP33754RegValue, VIP33754RegMask; + REG_MM33758_Arise VIP33758RegValue, VIP33758RegMask; + REG_MM3375C_Arise VIP3375CRegValue, VIP3375CRegMask; + + VIP33754RegIndex = cbGetParallelRegIndex(VIP_Parallel_Reg_Tbl, VIP_REG6, VIPPortIndex); + VIP33758RegIndex = cbGetParallelRegIndex(VIP_Parallel_Reg_Tbl, VIP_REG7, VIPPortIndex); + VIP3375CRegIndex = cbGetParallelRegIndex(VIP_Parallel_Reg_Tbl, VIP_REG8, VIPPortIndex); + + VIP33754RegValue.Value = 0; + VIP33754RegValue.FB_mode = pCbiosVIPCtlData->fbSet.num -1; + VIP33754RegMask.Value = 0XFFFFFFFF; + VIP33754RegMask.FB_mode = 0; + + if (pCbiosVIPCtlData->fbSet.idx == 0) + { + VIP33754RegValue.FB_base0 = (CBIOS_U32)(pCbiosVIPCtlData->fbSet.addr >> 6); + VIP33754RegMask.FB_base0 = 0; + cbMMIOWriteReg32(pcbe, VIP33754RegIndex, VIP33754RegValue.Value, VIP33754RegMask.Value); + } + else if (pCbiosVIPCtlData->fbSet.idx == 1) + { + VIP33758RegValue.Value = 0; + VIP33758RegValue.FB_base1 = (CBIOS_U32)(pCbiosVIPCtlData->fbSet.addr >> 6); + VIP33758RegMask.Value = 0XFFFFFFFF; + VIP33758RegMask.FB_base1 = 0; + cbMMIOWriteReg32(pcbe, VIP33758RegIndex, VIP33758RegValue.Value, VIP33758RegMask.Value); + } + else if (pCbiosVIPCtlData->fbSet.idx == 2) + { + VIP3375CRegValue.Value = 0; + VIP3375CRegValue.FB_base2 = (CBIOS_U32)(pCbiosVIPCtlData->fbSet.addr >> 6); + VIP3375CRegMask.Value = 0XFFFFFFFF; + VIP3375CRegMask.FB_base2 = 0; + cbMMIOWriteReg32(pcbe, VIP3375CRegIndex, VIP3375CRegValue.Value, VIP3375CRegMask.Value); + } + + if (pCbiosVIPCtlData->fbSet.idx == 2 || pCbiosVIPCtlData->fbSet.idx == 3) + { + cbMMIOWriteReg32(pcbe, VIP33754RegIndex, VIP33754RegValue.Value, VIP33754RegMask.Value); + } + + return CBIOS_OK; +} + + +CBIOS_STATUS cbVIPEnable(PCBIOS_VOID pvcbe, PCBIOS_VIP_CTRL_DATA pCbiosVIPCtlData) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 VIPPortIndex = pCbiosVIPCtlData->vip; + + CBIOS_U32 VIP33740RegIndex; + CBIOS_U32 VIP3376CRegIndex; + + REG_MM33740_Arise VIP33740RegValue, VIP33740RegMask; + REG_MM3376C_Arise VIP3376CRegValue, VIP3376CRegMask; + + VIP33740RegIndex = cbGetParallelRegIndex(VIP_Parallel_Reg_Tbl, VIP_REG1, VIPPortIndex); + VIP3376CRegIndex = cbGetParallelRegIndex(VIP_Parallel_Reg_Tbl, VIP_REG12, VIPPortIndex); + + VIP3376CRegValue.Value = 0; + VIP3376CRegValue.EOF_INT_enable = pCbiosVIPCtlData->enable; + + VIP3376CRegMask.Value = 0xFFFFFFFF; + VIP3376CRegMask.EOF_INT_enable = 0; + cbMMIOWriteReg32(pcbe, VIP3376CRegIndex, VIP3376CRegValue.Value, VIP3376CRegMask.Value); + + VIP33740RegValue.Value = 0; + VIP33740RegValue.VIP_enable = pCbiosVIPCtlData->enable; + VIP33740RegValue.SCE = 1; + + VIP33740RegMask.Value = 0XFFFFFFFF; + VIP33740RegMask.SCE = 0; + VIP33740RegMask.VIP_enable = 0; + cbMMIOWriteReg32(pcbe, VIP33740RegIndex, VIP33740RegValue.Value, VIP33740RegMask.Value); + + //adv7611 disable + if (!pCbiosVIPCtlData->enable) + { + cbAdv7611DeInit(pcbe, VIPPortIndex); + } + + + return CBIOS_OK; +} + +CBIOS_STATUS cbVIPCtl(PCBIOS_VOID pvcbe, PCBIOS_VIP_CTRL_DATA pCbiosVIPCtlData) +{ + CBIOS_U8 VIPPortIndex = pCbiosVIPCtlData->vip; + + if(VIPPortIndex > 3) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "NOT support this VIP Port: VIPPortIndex=%d\n", VIPPortIndex)); + return CBIOS_ER_NOT_YET_IMPLEMENTED; + } + + if (pCbiosVIPCtlData->cmd == CBIOS_VIP_QUERY_CAPS) + { + return cbVIPQueryCaps(pvcbe, pCbiosVIPCtlData); + } + + if (pCbiosVIPCtlData->cmd == CBIOS_VIP_SET_MODE) + { + return cbVIPSetMode(pvcbe, pCbiosVIPCtlData); + } + + if (pCbiosVIPCtlData->cmd == CBIOS_VIP_SET_BUFFER) + { + return cbVIPSetBuffer(pvcbe, pCbiosVIPCtlData); + } + + if (pCbiosVIPCtlData->cmd == CBIOS_VIP_ENABLE) + { + return cbVIPEnable(pvcbe, pCbiosVIPCtlData); + } + + return CBIOS_ER_NOT_YET_IMPLEMENTED; +} + + +CBIOS_STATUS cbVIPI2CDataRead(PCBIOS_VOID pvcbe, PCBIOS_PARAM_VIPI2C_DATA pCbiosVIPI2CParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8* Buffer; + CBIOS_U32 BufferLen; + + CBIOS_U32 i= 0, j= 0; + CBIOS_U32 maxloop = MAXI2CWAITLOOP; + CBIOS_U32 I2CDELAY = 200; + CBIOS_U32 VIPnI2CDataReg, VIPnI2CCtrlReg; + CBIOS_U16 VIPnI2CIEReg; + CBIOS_U8 VIPPortIndex = pCbiosVIPI2CParams->PortNumber; + +//cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s():PortNumber=%d, SlaveAddress=0x%x, Offset=0x%x, Buffer=0x%x, BufferLen=%d.\n", +// FUNCTION_NAME, pCbiosVIPI2CParams->PortNumber, pCbiosVIPI2CParams->SlaveAddress, pCbiosVIPI2CParams->Offset, *pCbiosVIPI2CParams->Buffer, pCbiosVIPI2CParams->BufferLen)); + + if(VIPPortIndex > 3) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "NOT support this VIP Port: VIPPortIndex=%d\n", VIPPortIndex)); + return CBIOS_ER_NOT_YET_IMPLEMENTED; + } + + BufferLen = pCbiosVIPI2CParams->BufferLen; + Buffer = pCbiosVIPI2CParams->Buffer; + cb_memset(Buffer,0,BufferLen); + + VIPnI2CDataReg = cbGetParallelRegIndex(VIP_IIC_Parallel_Reg_Tbl, VIP_IIC_RW_DATA_REG, VIPPortIndex); + VIPnI2CCtrlReg = cbGetParallelRegIndex(VIP_IIC_Parallel_Reg_Tbl, VIP_IIC_CONTROL_REG, VIPPortIndex); + VIPnI2CIEReg = (CBIOS_U16)cbGetParallelRegIndex(VIP_IIC_Parallel_Reg_Tbl, VIP_IIC_IE, VIPPortIndex); + + cbMMIOWriteReg(pcbe,VIPnI2CIEReg, 0x0C, ~0x0C); + cb_DelayMicroSeconds(I2CDELAY); + + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_FUNCTION_ENABLE, ~VIPI2C_FUNCTION_ENABLE); + cb_DelayMicroSeconds(I2CDELAY); + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, 0x800, ~0xE00); // 200KHz + cb_DelayMicroSeconds(I2CDELAY); + + //start + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_START_REQUEST, ~(VIPI2C_START_REQUEST)); + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set START & WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & (VIPI2C_START_REQUEST | VIPI2C_WDAV)) //query START until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + cbMMIOWriteReg32(pcbe, VIPnI2CDataReg, pCbiosVIPI2CParams->SlaveAddress & ~1, ~0xFF); //write the I2C address, write slave address + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & VIPI2C_WDAV) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + cbMMIOWriteReg32(pcbe, VIPnI2CDataReg, pCbiosVIPI2CParams->Offset, ~0xFF); //write the I2C address, write offset + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & VIPI2C_WDAV) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + //start + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_START_REQUEST, ~(VIPI2C_START_REQUEST)); + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set START & WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & (VIPI2C_START_REQUEST | VIPI2C_WDAV)) //query START until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + cbMMIOWriteReg32(pcbe, VIPnI2CDataReg, pCbiosVIPI2CParams->SlaveAddress | 1, ~0xFF); //write the I2C address, write slave address + 1 + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & VIPI2C_WDAV) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + for(i = 0;i < BufferLen;i++) + { + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & VIPI2C_WDAV) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + j = 0; + while((cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & VIPI2C_READ_FINISHED) == 0) //query RDATA_AV until it is 1 + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + *(Buffer+i) = (CBIOS_UCHAR)((cb_ReadU32(pcbe->pAdapterContext,VIPnI2CDataReg) & 0x00ff0000) >> 16);//read the I2C data + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, ~VIPI2C_READ_FINISHED, ~VIPI2C_READ_FINISHED); //clear RDATA_AV + } + + //stop + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_STOP_REQUEST, ~(VIPI2C_STOP_REQUEST)); + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set stop & WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & (VIPI2C_STOP_REQUEST | VIPI2C_WDAV)) //query STOP until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + return CBIOS_TRUE; +} + +CBIOS_STATUS cbVIPI2CDataWrite(PCBIOS_VOID pvcbe, PCBIOS_PARAM_VIPI2C_DATA pCbiosVIPI2CParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8* Buffer; + CBIOS_U32 BufferLen; + + CBIOS_U32 i= 0, j= 0; + CBIOS_U32 maxloop = MAXI2CWAITLOOP; + CBIOS_U32 I2CDELAY = 200; + CBIOS_U32 VIPnI2CDataReg, VIPnI2CCtrlReg; + CBIOS_U16 VIPnI2CIEReg; + CBIOS_U8 VIPPortIndex = pCbiosVIPI2CParams->PortNumber; + +//cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "%s():PortNumber=%d, SlaveAddress=0x%x, Offset=0x%x, Buffer=0x%x, BufferLen=%d.\n", +// FUNCTION_NAME, pCbiosVIPI2CParams->PortNumber, pCbiosVIPI2CParams->SlaveAddress, pCbiosVIPI2CParams->Offset, *pCbiosVIPI2CParams->Buffer, pCbiosVIPI2CParams->BufferLen)); + + if(VIPPortIndex > 3) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "NOT support this VIP Port: VIPPortIndex=%d\n", VIPPortIndex)); + return CBIOS_ER_NOT_YET_IMPLEMENTED; + } + + BufferLen = pCbiosVIPI2CParams->BufferLen; + Buffer = pCbiosVIPI2CParams->Buffer; + + VIPnI2CDataReg = cbGetParallelRegIndex(VIP_IIC_Parallel_Reg_Tbl, VIP_IIC_RW_DATA_REG, VIPPortIndex); + VIPnI2CCtrlReg = cbGetParallelRegIndex(VIP_IIC_Parallel_Reg_Tbl, VIP_IIC_CONTROL_REG, VIPPortIndex); + VIPnI2CIEReg = (CBIOS_U16)cbGetParallelRegIndex(VIP_IIC_Parallel_Reg_Tbl, VIP_IIC_IE, VIPPortIndex); + + cbMMIOWriteReg(pcbe,VIPnI2CIEReg, 0x0C, ~0x0C); + cb_DelayMicroSeconds(I2CDELAY); + + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_FUNCTION_ENABLE, ~VIPI2C_FUNCTION_ENABLE); + cb_DelayMicroSeconds(I2CDELAY); + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, 0x800, ~0xE00); // 200KHz + cb_DelayMicroSeconds(I2CDELAY); + + //start + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_START_REQUEST, ~(VIPI2C_START_REQUEST)); + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set START & WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & (VIPI2C_START_REQUEST | VIPI2C_WDAV)) //query START & WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + cbMMIOWriteReg32(pcbe, VIPnI2CDataReg, pCbiosVIPI2CParams->SlaveAddress & ~1, ~0xFF); //write the I2C data, write slave address + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & VIPI2C_WDAV) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + cbMMIOWriteReg32(pcbe, VIPnI2CDataReg, pCbiosVIPI2CParams->Offset, ~0xFF); //write the I2C data, write offset + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & VIPI2C_WDAV) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + for(i = 0;i < BufferLen;i++) + { + //write data + cbMMIOWriteReg32(pcbe, VIPnI2CDataReg, *(Buffer+i), ~0xFF); //write the I2C data + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & VIPI2C_WDAV) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + } + + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_STOP_REQUEST, ~(VIPI2C_STOP_REQUEST)); + cbMMIOWriteReg32(pcbe, VIPnI2CCtrlReg, VIPI2C_WDAV, ~(VIPI2C_WDAV)); //set stop & WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg) & (VIPI2C_STOP_REQUEST | VIPI2C_WDAV)) //query stop until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!mmio %x=%x.\n", FUNCTION_NAME, LINE_NUM, VIPnI2CCtrlReg, cb_ReadU32(pcbe->pAdapterContext,VIPnI2CCtrlReg))); + return CBIOS_FALSE; + } + } + + cbTraceExit(GENERIC); + + return CBIOS_TRUE; +} diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_VIP.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_VIP.h new file mode 100644 index 0000000000000..a70d194091ee7 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_VIP.h @@ -0,0 +1,81 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** VIP hw block interface function prototype and parameter definition. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_DIU_VIP_H_ +#define _CBIOS_DIU_VIP_H_ + + +#include "../../Device/CBiosDeviceShare.h" + +#define VIPI2C_FUNCTION_ENABLE 0x00000100 +#define VIPI2C_START_REQUEST 0x00000001 +#define VIPI2C_STOP_REQUEST 0x00000002 +#define VIPI2C_WDAV 0x00000004 +#define VIPI2C_READ_FINISHED 0x00000008 + +#define VIP_FMT_RAW_8BIT 0x00 // +#define VIP_FMT_RAW_10BIT 0x00 // 0b0100000 +#define VIP_FMT_RAW_16BIT 0x00 // 0b1000000 +#define VIP_FMT_RGB444_24BIT_SDR 0x01 // 0b0000001 +#define VIP_FMT_RGB444_15BIT_DDR 0x31 // 0b0110001 +#define VIP_FMT_RGB444_12BIT_DDR 0x11 // 0b0010001 +#define VIP_FMT_YCBCR444_24BIT_SDR 0x02 // 0b0000010 +#define VIP_FMT_YCBCR444_15BIT_DDR 0x32 // 0b0110010 +#define VIP_FMT_YCBCR444_12BIT_DDR 0x12 // 0b0010010 +#define VIP_FMT_YCBCR422_20BIT_SDR_ES 0x2B // 0b0101011 +#define VIP_FMT_YCBCR422_20BIT_SDR_SS 0x23 // 0b0100011 +#define VIP_FMT_YCBCR422_20BIT_DDR_ES 0x3B // 0b0111011 +#define VIP_FMT_YCBCR422_20BIT_DDR_SS 0x33 // 0b0110011 +#define VIP_FMT_YCBCR422_16BIT_SDR_ES 0x0B // 0b0001011 +#define VIP_FMT_YCBCR422_16BIT_SDR_SS 0x03 // 0b0000011 +#define VIP_FMT_YCBCR422_16BIT_DDR_ES 0x1B // 0b0011011 +#define VIP_FMT_YCBCR422_16BIT_DDR_SS 0x13 // 0b0010011 +#define VIP_FMT_YCBCR422_10BIT_SDR_ES 0x2C // 0b0101100 +#define VIP_FMT_YCBCR422_10BIT_SDR_SS 0x24 // 0b0100100 +#define VIP_FMT_YCBCR422_8BIT_SDR_ES 0x0C // 0b0001100 +#define VIP_FMT_YCBCR422_8BIT_SDR_SS 0x04 // 0b0000100 +#define VIP_FMT_YCBCR422_8BIT_DDR_ES 0x1C // 0b0011100 +#define VIP_FMT_YCBCR422_8BIT_DDR_SS 0x14 // 0b0010100 + +typedef struct _CBIOS_PARAM_VIPI2C_DATA { + CBIOS_U32 Size; + CBIOS_UCHAR PortNumber; // vip i2c port number + CBIOS_UCHAR SlaveAddress; // daughter card's slave address + CBIOS_UCHAR Offset; + CBIOS_UCHAR* Buffer; + CBIOS_U32 BufferLen; // vip i2c buffer size +} CBIOS_PARAM_VIPI2C_DATA, *PCBIOS_PARAM_VIPI2C_DATA; + +typedef struct _CBIOS_PARAM_VIPSETCARD_DATA { + CBIOS_U32 Size; + CBIOS_U8 PortNumber; // vip i2c port number + CBIOS_U32 XRes; + CBIOS_U32 YRes; + CBIOS_U32 RefreshRate; + CBIOS_VIP_FORMAT VIPFormat; + //CBIOS_U8 DaughterCard; // =1, ADV7611 card +} CBIOS_PARAM_VIPSETCARD_DATA, *PCBIOS_PARAM_VIPSETCARD_DATA; + +CBIOS_STATUS cbVIPCtl(PCBIOS_VOID pvcbe, PCBIOS_VIP_CTRL_DATA pCbiosVIPCtlData); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosIGA_Timing.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosIGA_Timing.c new file mode 100644 index 0000000000000..6e9b03805da82 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosIGA_Timing.c @@ -0,0 +1,593 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** IGA block interface function implementation. +** Mainly includes set timing, set dclk, set/get active devices. +** +** NOTE: +** The functions in this file are hw layer internal functions, +** CAN ONLY be called by files under Hw folder. +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" +#include "CBiosIGA_Timing.h" +#include "CBiosScaler.h" + +extern CBIOS_U32 OvlKeyIndex[CBIOS_IGACOUNTS][OVL_NUM_E3K]; + +static CBREGISTER ZXGInitBaseRegs_NonPaired[] = +{ + {SR,(CBIOS_U8)~0xDF, 0x01, 0x01}, + {SR, 0x00, 0x02, 0x0F}, + {SR, 0x00, 0x03, 0x00}, + {SR, 0x00, 0x04, 0x0E}, + {AR, 0x00, 0x00, 0x00}, + {AR, 0x00, 0x01, 0x01}, + {AR, 0x00, 0x02, 0x02}, + {AR, 0x00, 0x03, 0x03}, + {AR, 0x00, 0x04, 0x04}, + {AR, 0x00, 0x05, 0x05}, + {AR, 0x00, 0x06, 0x06}, + {AR, 0x00, 0x07, 0x07}, + {AR, 0x00, 0x08, 0x08}, + {AR, 0x00, 0x09, 0x09}, + {AR, 0x00, 0x0A, 0x0A}, + {AR, 0x00, 0x0B, 0x0B}, + {AR, 0x00, 0x0C, 0x0C}, + {AR, 0x00, 0x0D, 0x0D}, + {AR, 0x00, 0x0E, 0x0E}, + {AR, 0x00, 0x0F, 0x0F}, + {AR, 0x00, 0x10, 0x41}, + {AR, 0x00, 0x11, 0x00}, + {AR, 0x00, 0x12, 0x0F}, + {AR, 0x00, 0x13, 0x00}, + {GR, 0x00, 0x00, 0x00}, + {GR, 0x00, 0x01, 0x00}, + {GR, 0x00, 0x02, 0x00}, + {GR, 0x00, 0x03, 0x00}, + {GR, 0x00, 0x04, 0x00}, + {GR, 0x00, 0x05, 0x00}, + {GR, 0x00, 0x06, 0x05}, + {GR, 0x00, 0x07, 0x0F}, + {GR, 0x00, 0x08, 0xFF}, + {CR, 0x00, 0x0A, 0x00}, + {CR, 0x00, 0x0B, 0x00}, + {CR, 0x00, 0x0E, 0xFF}, + {CR, 0x00, 0x0F, 0x00}, + {CR, 0x00, 0x14, 0x60}, + {CR, 0x00, 0x18, 0xFF}, +}; + +static CBREGISTER ZXGInitBaseRegs_Paired[]= +{ + {CR, 0x00, 0x08, 0x00}, + {CR, 0x00, 0x09, 0x40}, + {CR, 0x00, 0x0C, 0x00}, + {CR, 0x00, 0x0D, 0x00}, + {CR, 0x00, 0x17, 0x80}, +}; + +static CBREGISTER ZXGInitExtBaseRegs[] = +{ + {CR, 0x00, 0x33, 0x08}, + {CR, 0x00, 0x3B, 0x58}, + {CR, 0x00, 0x5E, 0xC0}, + {CR,(CBIOS_U8)~0x0F, 0x64, 0x00}, + {CR, 0x00, 0x69, 0x00}, +}; + +static CBREGISTER ZXGVesaNonPlanarReg_Paired[] = +{ + {CR,(CBIOS_U8)~0x7F, 0x31, 0x09}, + {CR,(CBIOS_U8)~0x44, 0x32, 0x00}, + {CR,(CBIOS_U8)~0x30, 0x3A, 0x10}, + {CR,(CBIOS_U8)~0x01, 0x66, 0x01}, +}; + +#if 0 + +static CBIOS_VOID cbSet3DVideoMode(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_3D_STRUCTURE Video3DStruct, CBIOS_U32 IGAIndex) +{ + REG_CR44_Pair RegCR44Value; + REG_CR44_Pair RegCR44Mask; + switch (Video3DStruct) + { + case TOP_AND_BOTTOM: + RegCR44Value.Value = 0; + RegCR44Value._3D_Video_Mode = 4; + RegCR44Mask.Value = 0xF8; + cbBiosMMIOWriteReg(pcbe, CR_44, RegCR44Value.Value, RegCR44Mask.Value, IGAIndex); + break; + case FRAME_PACKING: + case L_DEPTH: + RegCR44Value.Value = 0; + RegCR44Value._3D_Video_Mode = 5; + RegCR44Mask.Value = 0xF8; + cbBiosMMIOWriteReg(pcbe, CR_44, RegCR44Value.Value, RegCR44Mask.Value, IGAIndex); + break; + case LINE_ALTERNATIVE: + RegCR44Value.Value = 0; + RegCR44Value._3D_Video_Mode = 6; + RegCR44Mask.Value = 0xF8; + cbBiosMMIOWriteReg(pcbe, CR_44, RegCR44Value.Value, RegCR44Mask.Value, IGAIndex); + break; + case SIDE_BY_SIDE_FULL: + case SIDE_BY_SIDE_HALF: + RegCR44Value.Value = 0; + RegCR44Value._3D_Video_Mode = 7; + RegCR44Mask.Value = 0xF8; + cbBiosMMIOWriteReg(pcbe, CR_44, RegCR44Value.Value, RegCR44Mask.Value, IGAIndex); + break; + default: + RegCR44Value.Value = 0; + RegCR44Value._3D_Video_Mode = 0; + RegCR44Mask.Value = 0xF8; + cbBiosMMIOWriteReg(pcbe, CR_44, RegCR44Value.Value, RegCR44Mask.Value, IGAIndex); + break; + } +} + +#endif + +static CBIOS_VOID cbSetPixelRepetition(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 PixelRepitition, CBIOS_U32 IGAIndex) +{ + REG_CRF1 RegCRF1Value, RegCRF1Mask; + + //check pixel repetition + if (PixelRepitition == 1) + { + if (IGAIndex == IGA1) + { + RegCRF1Value.Value = 0; + RegCRF1Value.IGA1_Pixel_Repetition = 0; + RegCRF1Mask.Value = 0xFF; + RegCRF1Mask.IGA1_Pixel_Repetition = 0; + cbMMIOWriteReg(pcbe, CR_F1, RegCRF1Value.Value, RegCRF1Mask.Value); + } + else + { + RegCRF1Value.Value = 0; + RegCRF1Value.IGA2_Pixel_Repetition = 0; + RegCRF1Mask.Value = 0xFF; + RegCRF1Mask.IGA2_Pixel_Repetition = 0; + cbMMIOWriteReg(pcbe, CR_F1, RegCRF1Value.Value, RegCRF1Mask.Value); + } + } + else if (PixelRepitition == 2) + { + if (IGAIndex == IGA1) + { + RegCRF1Value.Value = 0; + RegCRF1Value.IGA1_Pixel_Repetition = 1; + RegCRF1Mask.Value = 0xFF; + RegCRF1Mask.IGA1_Pixel_Repetition = 0; + cbMMIOWriteReg(pcbe, CR_F1, RegCRF1Value.Value, RegCRF1Mask.Value); + } + else + { + RegCRF1Value.Value = 0; + RegCRF1Value.IGA2_Pixel_Repetition = 1; + RegCRF1Mask.Value = 0xFF; + RegCRF1Mask.IGA2_Pixel_Repetition = 0; + cbMMIOWriteReg(pcbe, CR_F1, RegCRF1Value.Value, RegCRF1Mask.Value); + } + } + else if (PixelRepitition == 4) + { + if (IGAIndex == IGA1) + { + RegCRF1Value.Value = 0; + RegCRF1Value.IGA1_Pixel_Repetition = 2; + RegCRF1Mask.Value = 0xFF; + RegCRF1Mask.IGA1_Pixel_Repetition = 0; + cbMMIOWriteReg(pcbe, CR_F1, RegCRF1Value.Value, RegCRF1Mask.Value); + } + else + { + RegCRF1Value.Value = 0; + RegCRF1Value.IGA2_Pixel_Repetition = 2; + RegCRF1Mask.Value = 0xFF; + RegCRF1Mask.IGA2_Pixel_Repetition = 0; + cbMMIOWriteReg(pcbe, CR_F1, RegCRF1Value.Value, RegCRF1Mask.Value); + } + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: wrong pixel repetition\n", FUNCTION_NAME)); + } +} + +static CBIOS_VOID cbDstTimingRegSetting(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams, CBIOS_U32 IGAIndex) +{ + PCBIOS_TIMING_ATTRIB pTiming = &(pModeParams->TargetTiming); + CBIOS_TIMING_FLAGS TimingFlags = {0}; + + cbTraceEnter(GENERIC); + + if (pModeParams->TargetModePara.bInterlace) + { + TimingFlags.IsInterlace = 1; + } + + cbSetSRTimingReg(pcbe, pTiming, IGAIndex, TimingFlags); + + cbProgramDclk(pcbe, (CBIOS_U8)IGAIndex, pTiming->PLLClock); + + //reset h/v counter to avoid wait vblank timeout + cbBiosMMIOWriteReg(pcbe, CR_23, 0, 0, IGAIndex); + cbBiosMMIOWriteReg(pcbe, CR_29, 0, 0, IGAIndex); + cbBiosMMIOWriteReg(pcbe, CR_26, 0, 0, IGAIndex); + + cbMMIOWriteReg(pcbe, CR_B_F5, 0x00, 0xDF); //disable SSC + + cbSetPixelRepetition(pcbe, pModeParams->PixelRepitition, IGAIndex); + + cbTraceExit(GENERIC); +} + +static CBIOS_VOID cbDstTimingInitial(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 IGAIndex) +{ + if(IGAIndex == IGA1) + { + //unlock sr01_0 value. + cbMMIOWriteReg(pcbe, CR_34, 0x00, 0xDF); + + cbMMIOWriteReg(pcbe,SR_01,0x01,0xFE); + //Lock sr01_0 value to avoid being modified by other apps. + cbMMIOWriteReg(pcbe, CR_34, 0x20, 0xDF); + } + + //SRAB(character clock) will affect IGA timing, clear it here + if(IGAIndex == IGA1) + { + cbBiosMMIOWriteReg(pcbe, SR_AB, 0x00, ~0x7, IGA1); + cbBiosMMIOWriteReg(pcbe, SR_AB, 0x00, ~0x7, IGA2); + } + else if(IGAIndex == IGA2) + { + cbBiosMMIOWriteReg(pcbe, SR_AB, 0x00, ~0x38, IGA1); + cbBiosMMIOWriteReg(pcbe, SR_AB, 0x00, ~0x38, IGA2); + } +} + +static CBIOS_VOID cbPlanarset(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 IGAIndex) +{ + cbTraceEnter(GENERIC); + + // enhanced mode + cbLoadtable(pcbe, + ZXGVesaNonPlanarReg_Paired, + sizeofarray(ZXGVesaNonPlanarReg_Paired), + IGAIndex); + + if(IGAIndex == IGA2) + { + cbMMIOWriteReg(pcbe,SR_30, 0x00, 0xFE); + } + else if(IGAIndex == IGA3) + { + cbMMIOWriteReg(pcbe,SR_30, 0x00, 0xDF); + } + else if(IGAIndex == IGA4) + { + //need add IGA4 code later + } + + cbTraceExit(GENERIC); +} + + +static CBIOS_VOID cbSetBPSL(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 IGAIndex) +{ + if(IGAIndex == IGA1) + { + // PS1 timeout + cbMMIOWriteReg(pcbe,CR_88, 0x20, 0x00); + } + else if(IGAIndex == IGA2) + { + // PS2 timeout + cbMMIOWriteReg(pcbe,CR_BC, 0x24, 0x00); + } + else if(IGAIndex == IGA3) + { + // PS3 timeout + cbMMIOWriteReg(pcbe,CR_93, 0x20, 0x00); + } + else + { + //need add IGA4 code later + } +} + +static CBIOS_VOID cbModeEnvSetup(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 IGAIndex) +{ + cbTraceEnter(GENERIC); + // 1. Load Init Base Table + cbLoadtable(pcbe, ZXGInitBaseRegs_NonPaired, sizeofarray(ZXGInitBaseRegs_NonPaired), CBIOS_NOIGAENCODERINDEX); + // 2. init primary address + cbLoadtable(pcbe, ZXGInitBaseRegs_Paired, sizeofarray(ZXGInitBaseRegs_Paired), IGAIndex); + + // 3. timing trigger + cbBiosMMIOWriteReg(pcbe, CR_17, 0x80, 0x00, IGAIndex); + // 4. Load Init Ext Base Table + cbLoadtable(pcbe, ZXGInitExtBaseRegs, sizeofarray(ZXGInitExtBaseRegs), IGAIndex); + cbTraceExit(GENERIC); +} + +#if 0 + +static CBIOS_VOID cbSetDacRegisters(PCBIOS_EXTENSION_COMMON pcbe) +{ + CBIOS_U8 byDacIndex; + + if (cb_ReadU8(pcbe->pAdapterContext, 0x83C6)!=0xFF) + { + cb_WriteU8(pcbe->pAdapterContext, 0x83C6,0xFF); + } + + for(byDacIndex=0x0;byDacIndex<=0xF7;byDacIndex++) + { + cb_WriteU8(pcbe->pAdapterContext, 0x83C8, byDacIndex); + cb_WriteU8(pcbe->pAdapterContext, 0x83C9, 0x80); + cb_WriteU8(pcbe->pAdapterContext, 0x83C9, 0x80); + cb_WriteU8(pcbe->pAdapterContext, 0x83C9, 0x80); + } + + //patch for mmio fault BEGIN--added by Ramonwang + cb_ReadU8(pcbe->pAdapterContext, CB_SEQ_ADDR_REG); + cb_ReadU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG); + //patch for mmio END +} + +#endif + +static CBIOS_VOID cbSetSrcTiming(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams, CBIOS_U32 IGAIndex) +{ + CBIOS_U32 ulDevices = pcbe->DispMgr.ActiveDevices[IGAIndex]; + CBiosDestModeParams ModeParams = {0}; + CBIOS_TIMING_ATTRIB Timing = {0}; + CBIOS_TIMING_FLAGS TimingFlags = {0}; + REG_SR47 SR47Value = {0}, SR47Mask = {0xff}; + REG_MM33718_Arise CursorCtrl1RegValue = {0}; + REG_MM33720_Arise CursorBaseAddrRegValue = {0}; + CBIOS_U32 CursorControl1Index[CBIOS_IGACOUNTS] = {0x33718, 0x33bb4, 0x342b4, 0x349b4}; + CBIOS_U32 CursorBaseAddrIndex[CBIOS_IGACOUNTS] = {0x33720, 0x33bbc, 0x342bc, 0x349bc}; + + cbTraceEnter(GENERIC); + + // if more than one devices assign on one IGA, + // do simultaneous view and set timing of primary device + ulDevices = cbDevGetPrimaryDevice((CBIOS_U32)pcbe->DispMgr.ActiveDevices[IGAIndex]); + + // disable gamma + SR47Value.SP_Gamma_Enable = 0; + SR47Mask.SP_Gamma_Enable = 0; + SR47Value.SP_LUT_Interpolation_Enable = 0; + SR47Mask.SP_LUT_Interpolation_Enable = 0; + cbBiosMMIOWriteReg(pcbe, SR_47, SR47Value.Value, SR47Mask.Value, IGAIndex); + + // disable HW cursor + CursorCtrl1RegValue.Cursor_1_Enable = 0; + CursorBaseAddrRegValue.Cursor_1_Enable_Work_Registers = 1; + cbMMIOWriteReg32(pcbe, CursorControl1Index[IGAIndex], CursorCtrl1RegValue.Value, 0); + cbMMIOWriteReg32(pcbe, CursorBaseAddrIndex[IGAIndex], CursorBaseAddrRegValue.Value, 0); + + cbModeEnvSetup(pcbe, (CBIOS_U8)IGAIndex); + + ModeParams.AspectRatioFlag = 0; + ModeParams.XRes = pModeParams->SrcModePara.XRes; + ModeParams.YRes = pModeParams->SrcModePara.YRes; + ModeParams.RefreshRate = pModeParams->TargetModePara.RefRate; + ModeParams.InterlaceFlag = CBIOS_FALSE; + + cbMode_GetHVTiming(pcbe, + ModeParams.XRes, + ModeParams.YRes, + ModeParams.RefreshRate, + ModeParams.InterlaceFlag, + ulDevices, + &Timing); + + cbSetCRTimingReg(pcbe, &Timing, IGAIndex, TimingFlags); + + //Planar Set + cbPlanarset(pcbe, (CBIOS_U8)IGAIndex); + + //Set FIFO and Offset register value + cbSetBPSL(pcbe, (CBIOS_U8)IGAIndex); + + cbTraceExit(GENERIC); +} + +static CBIOS_VOID cbSetDstTiming(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams, CBIOS_U32 IGAIndex) +{ + cbTraceEnter(GENERIC); + + cbDstTimingInitial(pcbe, (CBIOS_U8)IGAIndex); + + cbDstTimingRegSetting(pcbe, pModeParams, IGAIndex); + + cbTraceExit(GENERIC); +} + + +CBIOS_VOID cbProgramDclk(PCBIOS_VOID pvcbe, CBIOS_U8 IGAIndex, CBIOS_U32 ClockFreq) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 ClockType = CBIOS_DCLK1TYPE; + CBIOS_U32 CurrentFreq; + REG_SR1B RegSR1BValue; + REG_SR1B RegSR1BMask; + REG_SR30_Pair RegSR30Value; + REG_SR30_Pair RegSR30Mask; + + // Program DClk + if(IGAIndex == IGA1) + { + ClockType = CBIOS_DCLK1TYPE; + } + else if(IGAIndex == IGA2) + { + ClockType = CBIOS_DCLK2TYPE; + } + else if(IGAIndex == IGA3) + { + ClockType = CBIOS_DCLK3TYPE; + } + else if(IGAIndex == IGA4) + { + ClockType = CBIOS_DCLK4TYPE; + } + + // Only IGA1 contains VGA logic, so there are two Dclk sources types for IGA1; + // SR1B[7] for selecting IGA1 source; + // Now do not skip program dclk temporarily since for down scale and deep color case, + // the values get from cbGetProgClock may not correct + // Need refine + + cbGetProgClock(pcbe, &CurrentFreq, ClockType); + + //force IGA1 Dclk source from SR12/13 + if(IGAIndex == IGA1) + { + RegSR1BValue.Value = 0; + RegSR1BValue.Controller1_DCLK_Parm_Source = 1; + RegSR1BMask.Value = 0xFF; + RegSR1BMask.Controller1_DCLK_Parm_Source = 0; + cbMMIOWriteReg(pcbe,SR_1B, RegSR1BValue.Value, RegSR1BMask.Value); + } + + //Confirm that controller1 use dclk1, controller2 use dclk2, controller3 use dclk3 + //controller4 is cre3[7], its default value is 0. + RegSR30Value.Value = 0; + RegSR30Value.Controller1_DCLK = 0; + RegSR30Value.Controller2_DCLK = 0; + RegSR30Value.Controller3_DCLK = 0; + RegSR30Mask.Value = 0xA7; + cbMMIOWriteReg(pcbe,SR_30, RegSR30Value.Value, RegSR30Mask.Value); + + cbProgClock(pcbe, ClockFreq, ClockType, IGAIndex); +} + + +CBIOS_VOID cbIGA_HW_SetMode(PCBIOS_VOID pvcbe, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 IGAIndex = pModeParams->IGAIndex; + REG_CR42_Pair RegCR42Value, RegCR42Mask; + REG_SR31_Pair RegSR31Value, RegSR31Mask; + + RegSR31Value.Value = 0; + RegSR31Value.Controller1_is_Flat_Panel_Source = 1; + RegSR31Mask.Value = 0xFF; + RegSR31Mask.Controller1_is_Flat_Panel_Source = 0; + cbBiosMMIOWriteReg(pcbe, SR_31, RegSR31Value.Value, RegSR31Mask.Value, IGAIndex); + + // source timing + cbSetSrcTiming(pcbe, pModeParams, IGAIndex); + + // dst timing + cbSetDstTiming(pcbe, pModeParams, IGAIndex); + + cbSetScaler(pcbe, pModeParams); + + //Bandwidth issue: The point enable/disable Reduced_Blanking during disable stream to avoid FIFO underflow + RegCR42Value.Value = 0; + RegCR42Value.Reduced_Blanking_Enable = 1; + RegCR42Mask.Value = 0xFF; + RegCR42Mask.Reduced_Blanking_Enable = 0; + cbBiosMMIOWriteReg(pcbe, CR_42, RegCR42Value.Value, RegCR42Mask.Value, IGAIndex); + + //one shot enable + if (IGA1 == IGAIndex) + { + cbMMIOWriteReg32(pcbe, 0x840c, 0xfff, 0); //ps, ss, ts ,qs, cursor, write back and overlay + } + else if (IGA2 == IGAIndex) + { + cbMMIOWriteReg32(pcbe, 0x33a2c, 0xfff, 0); + } + else if (IGA3 == IGAIndex) + { + cbMMIOWriteReg32(pcbe, 0x3412c, 0xfff, 0); + } + else + { + cbMMIOWriteReg32(pcbe, 0x3482c, 0xfff, 0); + } + + { + //set default value kp = 8, ks = 0, to 4 OVLs, temp add it at bring up + CBIOS_U32 OvlIndex = CBIOS_OVERLAY0; + REG_MM33840_Arise OvlKeyValue = {0}; + OvlKeyValue.Ka_3to0_Or_Ks = 0; + OvlKeyValue.Ka_7to4_Or_Kp = 8; + OvlKeyValue.Key_Mode = 0; // B over A window key + OvlKeyValue.Ovl0_Enable_Work = 1; + for(; OvlIndex < OVL_NUM_E3K; OvlIndex++) + { + OvlKeyValue.Ovl0_Input_Stream = OvlIndex; + cbMMIOWriteReg32(pcbe, OvlKeyIndex[IGAIndex][OvlIndex], OvlKeyValue.Value, 0); + } + } +} + +// Update the CR6B scratch pad Regiseter for compatible with VBIOS. +CBIOS_VOID cbIGA_UpdateActiveDeviceToReg(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Devices, i; + + cbTraceEnter(GENERIC); + + Devices = CBIOS_TYPE_NONE; + for (i = IGA1; i < pDispMgr->IgaCount; i++) + { + Devices |= pDispMgr->ActiveDevices[i]; + } + + if(MORE_THAN_1BIT(Devices)) + { + Devices |= CBIOS_TYPE_DUOVIEW; + } + + Devices = cbConvertCBiosDevBit2VBiosDevBit(Devices); + + cbMMIOWriteReg(pcbe, CR_6B, (CBIOS_U8)Devices, 0x00); + + Devices = Devices >> 8; + cbMMIOWriteReg(pcbe, CR_6C, (CBIOS_U8)Devices, 0x00); + + cbTraceExit(GENERIC); +} + + +CBIOS_U32 cbIGA_GetActiveDeviceFromReg(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 wTemp = 0; + wTemp = (CBIOS_U32) cbMMIOReadReg(pcbe,CR_6C); + wTemp = wTemp << 8; + wTemp |= (CBIOS_U32) cbMMIOReadReg(pcbe,CR_6B); + + wTemp = cbConvertVBiosDevBit2CBiosDevBit(wTemp); + wTemp &= pcbe->DeviceMgr.SupportDevices; + return wTemp; +} + diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosIGA_Timing.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosIGA_Timing.h new file mode 100644 index 0000000000000..4c5b0f76ab145 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosIGA_Timing.h @@ -0,0 +1,32 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** IGA block interface prototype. +** +** NOTE: +** This header file CAN ONLY be included by hw layer those files under Hw folder. +******************************************************************************/ + +#ifndef _CBIOS_IGA_TIMING_H_ +#define _CBIOS_IGA_TIMING_H_ + +CBIOS_VOID cbProgramDclk(PCBIOS_VOID pvcbe, CBIOS_U8 IGAIndex, CBIOS_U32 ClockFreq); +CBIOS_VOID cbIGA_HW_SetMode(PCBIOS_VOID pvcbe, PCBIOS_DISP_MODE_PARAMS pModeParams); +CBIOS_VOID cbIGA_UpdateActiveDeviceToReg(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr); +CBIOS_U32 cbIGA_GetActiveDeviceFromReg(PCBIOS_VOID pvcbe); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.c new file mode 100644 index 0000000000000..1243daae0c9e2 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.c @@ -0,0 +1,1725 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DP PHY interface function implementation. +** +** NOTE: +** +******************************************************************************/ + +#include "CBiosPHY_DP.h" +#include "CBiosDIU_DP.h" +#include "CBiosDIU_HDTV.h" +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" + +DP_EPHY_MODE cbPHY_DP_GetEphyMode(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8348 DPEphyMiscRegValue; + DP_EPHY_MODE Mode; + + DPEphyMiscRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_EPHY_MISC[DPModuleIndex]); + + if(DPEphyMiscRegValue.Driver_Mode == 0) + { + Mode = DP_EPHY_TMDS_MODE; + } + else + { + Mode = DP_EPHY_DP_MODE; + } + + return Mode; +} + +CBIOS_VOID cbPHY_DP_SelectEphyMode(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, DP_EPHY_MODE DPEphyMode) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_SR3B_Pair RegSR3BValue; + REG_SR3B_Pair RegSR3BMask; + REG_MM8348 DPEphyMiscRegValue, DPEphyMiscRegMask; + + switch (DPEphyMode) + { + case DP_EPHY_TMDS_MODE: + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.Driver_Mode = 0; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.Driver_Mode = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + RegSR3BValue.Value = 0; + RegSR3BValue.Sel_DP_TMDS = 1; + RegSR3BMask.Value = 0xFF; + RegSR3BMask.Sel_DP_TMDS = 0; + cbBiosMMIOWriteReg(pcbe, SR_3B, RegSR3BValue.Value, RegSR3BMask.Value, DPModuleIndex); + break; + case DP_EPHY_DP_MODE: + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.Driver_Mode = 1; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.Driver_Mode = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + RegSR3BValue.Value = 0; + RegSR3BValue.Sel_DP_TMDS = 0; + RegSR3BMask.Value = 0xFF; + RegSR3BMask.Sel_DP_TMDS = 0; + cbBiosMMIOWriteReg(pcbe, SR_3B, RegSR3BValue.Value, RegSR3BMask.Value, DPModuleIndex); + break; + default: + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid ephy mode!\n", FUNCTION_NAME)); + break; + + } +} + +CBIOS_VOID cbPHY_DP_DPModeOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U32 LinkSpeed, CBIOS_BOOL status) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM82CC DPEphyCtrlRegValue, DPEphyCtrlRegMask; + REG_MM8340 DPEphyMpllRegValue, DPEphyMpllRegMask; + REG_MM8344 DPEphyTxRegValue, DPEphyTxRegMask; + REG_MM8348 DPEphyMiscRegValue, DPEphyMiscRegMask; + + cbTraceEnter(DP); + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + if (status)//DP on + { + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Resistance_Value = 8; + DPEphyTxRegValue.EPHY1_SR_MAN_L0 = 0; + DPEphyTxRegValue.EPHY1_SR_MAN_L1 = 0; + DPEphyTxRegValue.EPHY1_SR_MAN_L2 = 0; + DPEphyTxRegValue.EPHY1_SR_MAN_L3 = 0; + DPEphyTxRegValue.DIU_EPHY1_AUX_DIAJ = 2; // {mm82cc[24], mm8344[22:20]} = 4'b1010 + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Resistance_Value = 0; + DPEphyTxRegMask.EPHY1_SR_MAN_L0 = 0; + DPEphyTxRegMask.EPHY1_SR_MAN_L1 = 0; + DPEphyTxRegMask.EPHY1_SR_MAN_L2 = 0; + DPEphyTxRegMask.EPHY1_SR_MAN_L3 = 0; + DPEphyTxRegMask.DIU_EPHY1_AUX_DIAJ = 0; + + DPEphyCtrlRegValue.Value = 0; + DPEphyCtrlRegValue.DIU_EPHY1_AUX_DIAJ = 1; + DPEphyCtrlRegValue.TX0T = 0; + DPEphyCtrlRegValue.TX1T = 0; + DPEphyCtrlRegValue.TX2T = 0; + DPEphyCtrlRegValue.TX3T = 0; + DPEphyCtrlRegMask.Value = 0xFFFFFFFF; + DPEphyCtrlRegMask.DIU_EPHY1_AUX_DIAJ = 0; + DPEphyCtrlRegMask.TX0T = 0; + DPEphyCtrlRegMask.TX1T = 0; + DPEphyCtrlRegMask.TX2T = 0; + DPEphyCtrlRegMask.TX3T = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_CTRL[DPModuleIndex], DPEphyCtrlRegValue.Value, DPEphyCtrlRegMask.Value); + + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.Driver_Mode = 1; + DPEphyMiscRegValue.M1V = 0; + DPEphyMiscRegValue.T1V = 1; + DPEphyMiscRegValue.TT = 0; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.Driver_Mode = 0; + DPEphyMiscRegMask.M1V = 0; + DPEphyMiscRegMask.T1V = 0; + DPEphyMiscRegMask.TT = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + } + else//DP off + { + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.Bandgap_Power_Down = 0; + DPEphyMpllRegValue.MPLL_Reg_Power_Down = 0; + DPEphyMpllRegValue.MPLL_Power_Down = 0; + DPEphyMpllRegValue.MPLL_PTAT_Current = 1; + DPEphyMpllRegValue.MPLL_CP_Current = 4; + DPEphyMpllRegValue.MPLL_N = 0xBE; + DPEphyMpllRegValue.MPLL_R = 0; + DPEphyMpllRegValue.MPLL_P = 2; + DPEphyMpllRegValue.SSC_Enable = 0; + DPEphyMpllRegValue.SSC_Freq_Spread = 0; + DPEphyMpllRegValue.Dither = 0; + DPEphyMpllRegValue.Signal_Profile = 1; + DPEphyMpllRegValue.Spread_Magnitude = 0; + DPEphyMpllRegValue.TPLL_Reg_Power_Down = 0; + DPEphyMpllRegValue.TPLL_Power_Down = 0; + DPEphyMpllRegValue.TPLL_N_Div = 1; + + DPEphyMpllRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.Driver_Mode = 0; + DPEphyMiscRegValue.Reserved = 1; + DPEphyMiscRegValue.RTNBIST = 3; + DPEphyMiscRegValue.CKHLD = 0; + DPEphyMiscRegValue.M1V = 0; + DPEphyMiscRegValue.MT = 1; + DPEphyMiscRegValue.T1V = 0; + DPEphyMiscRegValue.TT = 0; + DPEphyMiscRegValue.EPHY1_TPLL_CP = 0; + DPEphyMiscRegValue.AUC_Ch_Op_Mode = 0; + DPEphyMiscRegValue.HPD_Power_Down = 1; + DPEphyMiscRegValue.TPLL_Reset_Signal = 0; + DPEphyMiscRegValue.MPLL_SSC_Output = 0; + DPEphyMiscRegValue.TPLL_Lock_Indicator = 0; + DPEphyMiscRegValue.MPLL_Lock_Indicator = 0; + DPEphyMiscRegValue.RTN_Results = 0; + DPEphyMiscRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.Resistance_Tuning_PD = 0; + DPEphyTxRegValue.Resistance_Tuning_Reset = 1; + DPEphyTxRegValue.Resistance_Tuning_Enable = 0; + DPEphyTxRegValue.TX_Resistance_Set_Enable = 0; + DPEphyTxRegValue.TX_Resistance_Value = 8; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane0 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane1 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane2 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane3 = 0; + DPEphyTxRegValue.Driver_Control_Lane0 = 0; + DPEphyTxRegValue.Driver_Control_Lane1 = 0; + DPEphyTxRegValue.Driver_Control_Lane2 = 0; + DPEphyTxRegValue.Driver_Control_Lane3 = 0; + DPEphyTxRegValue.EPHY1_SR_MAN_L0 = 0; + DPEphyTxRegValue.EPHY1_SR_MAN_L1 = 0; + DPEphyTxRegValue.EPHY1_SR_MAN_L2 = 0; + DPEphyTxRegValue.EPHY1_SR_MAN_L3 = 0; + DPEphyTxRegValue.DIU_EPHY1_AUX_DIAJ = 0; + DPEphyTxRegValue.EPHY_MPLL_CP = 0; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 3; + DPEphyTxRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + } + + cbTraceExit(DP); +} + + +CBIOS_VOID cbPHY_DP_DualModeOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U32 ClockFreq, CBIOS_BOOL bTurnOn) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8214 DPLinkRegValue, DPLinkRegMask; + REG_MM82CC DPEphyCtrlRegValue, DPEphyCtrlRegMask; + REG_MM8340 DPEphyMpllRegValue, DPEphyMpllRegMask; + REG_MM8344 DPEphyTxRegValue, DPEphyTxRegMask; + REG_MM8348 DPEphyMiscRegValue, DPEphyMiscRegMask; + REG_MM8368 DPSwingRegValue, DPSwingRegMask; + REG_MM334E0 DPEphySetting1RegValue, DPEphySetting1RegMask; + REG_MM836C DPEphyStatusRegValue, DPEphyStatusRegMask; + REG_MM334E4 DPEphySetting2RegValue, DPEphySetting2RegMask; + + cbTraceEnter(DP); + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + if (bTurnOn)//on + { + /* 1. set parameters before enable TPLL*/ + + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.Resistance_Tuning_PD = 0; + DPEphyTxRegValue.Resistance_Tuning_Reset = 1; + DPEphyTxRegValue.Resistance_Tuning_Enable = 0; + DPEphyTxRegValue.TX_Resistance_Set_Enable = 1; + DPEphyTxRegValue.EPHY1_SR_MAN_L0 = 0; + DPEphyTxRegValue.EPHY1_SR_MAN_L1 = 0; + DPEphyTxRegValue.EPHY1_SR_MAN_L2 = 0; + DPEphyTxRegValue.EPHY1_SR_MAN_L3 = 0; + DPEphyTxRegValue.DIU_EPHY1_AUX_DIAJ = 0; + if(ClockFreq > 3400000) + { + DPEphyTxRegValue.TX_Resistance_Value = 0xF; + } + else + { + DPEphyTxRegValue.TX_Resistance_Value = 0xD; + } + + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.Resistance_Tuning_PD = 0; + DPEphyTxRegMask.Resistance_Tuning_Reset = 0; + DPEphyTxRegMask.Resistance_Tuning_Enable = 0; + DPEphyTxRegMask.TX_Resistance_Set_Enable = 0; + DPEphyTxRegMask.TX_Resistance_Value = 0; + DPEphyTxRegMask.EPHY1_SR_MAN_L0 = 0; + DPEphyTxRegMask.EPHY1_SR_MAN_L1 = 0; + DPEphyTxRegMask.EPHY1_SR_MAN_L2 = 0; + DPEphyTxRegMask.EPHY1_SR_MAN_L3 = 0; + DPEphyTxRegMask.DIU_EPHY1_AUX_DIAJ = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.CKHLD = 0; + DPEphyMiscRegValue.TT = 0; + DPEphyMiscRegValue.TX_High_Impedance_Lane0 = 1; + DPEphyMiscRegValue.TX_High_Impedance_Lane1 = 0; + DPEphyMiscRegValue.TX_High_Impedance_Lane2 = 0; + DPEphyMiscRegValue.TX_High_Impedance_Lane3 = 0; + DPEphyMiscRegValue.AUC_Ch_Op_Mode = 0; + DPEphyMiscRegValue.HPD_Power_Down = 1; + + if (ClockFreq >= 3400000) + { + DPEphyMiscRegValue.T1V = 1; + DPEphyMiscRegValue.MT = 0; + DPEphyMiscRegValue.EPHY1_TPLL_CP = 0x8; + } + else if (ClockFreq >= 1700000) + { + DPEphyMiscRegValue.T1V = 0; + DPEphyMiscRegValue.MT = 1; + DPEphyMiscRegValue.EPHY1_TPLL_CP = 2; + } + else + { + + DPEphyMiscRegValue.T1V = 0; + DPEphyMiscRegValue.MT = 1; + DPEphyMiscRegValue.EPHY1_TPLL_CP = 8; + } + + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.CKHLD = 0; + DPEphyMiscRegMask.T1V = 0; + DPEphyMiscRegMask.TT = 0; + DPEphyMiscRegMask.EPHY1_TPLL_CP = 0; + DPEphyMiscRegMask.TX_High_Impedance_Lane0 = 0; + DPEphyMiscRegMask.TX_High_Impedance_Lane1 = 0; + DPEphyMiscRegMask.TX_High_Impedance_Lane2 = 0; + DPEphyMiscRegMask.TX_High_Impedance_Lane3 = 0; + DPEphyMiscRegMask.AUC_Ch_Op_Mode = 0; + DPEphyMiscRegMask.HPD_Power_Down = 0; + DPEphyMiscRegMask.MT = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + if (ClockFreq >= 3400000) + { + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.TPLL_N_Div = 0; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.TPLL_N_Div = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + } + else if (ClockFreq >= 1700000) + { + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.TPLL_N_Div = 0; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.TPLL_N_Div = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + } + else if (ClockFreq >= 850000) + { + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.TPLL_N_Div = 1; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.TPLL_N_Div = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + } + else if (ClockFreq >= 425000) + { + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.TPLL_N_Div = 2; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.TPLL_N_Div = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + } + else + { + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.TPLL_N_Div = 3; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.TPLL_N_Div = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + } + + DPEphyStatusRegValue.Value = 0; + DPEphyStatusRegValue.EPHY1_TPLL_ISEL = 0; + if (ClockFreq == 5940000 && (pcbe->ChipID == CHIPID_E3K || pcbe->ChipID == CHIPID_ARISE10C0T)) + { + DPEphyStatusRegValue.TR = 0; + DPEphyStatusRegValue.TC = 7; + } + else + { + DPEphyStatusRegValue.TR = 7; + DPEphyStatusRegValue.TC = 3; + } + DPEphyStatusRegMask.Value = 0xFFFFFFFF; + DPEphyStatusRegMask.EPHY1_TPLL_ISEL = 0; + DPEphyStatusRegMask.TR = 0; + DPEphyStatusRegMask.TC = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_STATUS[DPModuleIndex], DPEphyStatusRegValue.Value, DPEphyStatusRegMask.Value); + + DPEphySetting1RegValue.Value = 0; + DPEphySetting1RegValue.EPHY1_FBOOST_2 = 0; + DPEphySetting1RegValue.EPHY1_FBOOST_1 = 0; + + if (ClockFreq >= 3400000) + { + DPEphySetting1RegValue.EPHY1_HDCKBY4 = 1; // HDMI clock divided by 4 (HDMI 2.0) + DPEphySetting1RegValue.EPHY1_SR_SPD = 0; + DPEphySetting1RegValue.EPHY1_SR_DLY = 0; + DPEphySetting1RegValue.EPHY1_SR_NDLY = 0; + if (ClockFreq == 5940000 && (pcbe->ChipID == CHIPID_E3K || pcbe->ChipID == CHIPID_ARISE10C0T)) //signal will be better if set FBOOST = 1 when clock is 594M + { + DPEphySetting1RegValue.EPHY1_FBOOST = 2; + } + else + { + DPEphySetting1RegValue.EPHY1_FBOOST = 1; + } + } + else if(ClockFreq >= 1700000) + { + DPEphySetting1RegValue.EPHY1_HDCKBY4 = 0; + DPEphySetting1RegValue.EPHY1_SR_SPD = 0; + DPEphySetting1RegValue.EPHY1_SR_DLY = 0; + DPEphySetting1RegValue.EPHY1_SR_NDLY = 0; + DPEphySetting1RegValue.EPHY1_FBOOST = 0; + } + else if(ClockFreq >= 850000) + { + DPEphySetting1RegValue.EPHY1_HDCKBY4 = 0; + DPEphySetting1RegValue.EPHY1_SR_SPD = 0; + DPEphySetting1RegValue.EPHY1_SR_DLY = 0; + DPEphySetting1RegValue.EPHY1_SR_NDLY = 0; + DPEphySetting1RegValue.EPHY1_FBOOST = 0; + } + else if (ClockFreq >= 425000) + { + DPEphySetting1RegValue.EPHY1_HDCKBY4 = 0; + DPEphySetting1RegValue.EPHY1_SR_SPD = 0; + DPEphySetting1RegValue.EPHY1_SR_DLY = 0; + DPEphySetting1RegValue.EPHY1_SR_NDLY = 0; + DPEphySetting1RegValue.EPHY1_FBOOST = 0; + } + else + { + DPEphySetting1RegValue.EPHY1_HDCKBY4 = 0; + DPEphySetting1RegValue.EPHY1_SR_SPD = 0; + DPEphySetting1RegValue.EPHY1_SR_DLY = 0; + DPEphySetting1RegValue.EPHY1_SR_NDLY = 0; + DPEphySetting1RegValue.EPHY1_FBOOST = 0; + } + + DPEphySetting1RegMask.Value = 0xFFFFFFFF; + DPEphySetting1RegMask.EPHY1_HDCKBY4 = 0; + DPEphySetting1RegMask.EPHY1_FBOOST = 0; + DPEphySetting1RegMask.EPHY1_FBOOST_1 = 0; + DPEphySetting1RegMask.EPHY1_FBOOST_2 = 0; + DPEphySetting1RegMask.EPHY1_SR_SPD = 0; + DPEphySetting1RegMask.EPHY1_SR_DLY = 0; + DPEphySetting1RegMask.EPHY1_SR_NDLY = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_SETTING1[DPModuleIndex], DPEphySetting1RegValue.Value, DPEphySetting1RegMask.Value); + + DPEphyCtrlRegValue.Value = 0; + DPEphyCtrlRegValue.TX0T = 0; + DPEphyCtrlRegValue.TX1T = 0; + DPEphyCtrlRegValue.TX2T = 0; + DPEphyCtrlRegValue.TX3T = 0; + if(ClockFreq >= 3400000) + { + if (ClockFreq == 5940000 && (pcbe->ChipID == CHIPID_E3K || pcbe->ChipID == CHIPID_ARISE10C0T)) + { + DPEphyCtrlRegValue.DIAJ_L0 = 3; + DPEphyCtrlRegValue.DIAJ_L1 = 5; + } + else + { + DPEphyCtrlRegValue.DIAJ_L0 = 4; + DPEphyCtrlRegValue.DIAJ_L1 = 4; + } + DPEphyCtrlRegValue.DIAJ_L2 = 4; + DPEphyCtrlRegValue.DIAJ_L3 = 2; + } + else if(ClockFreq >= 1700000) + { + DPEphyCtrlRegValue.DIAJ_L0 = 5; + DPEphyCtrlRegValue.DIAJ_L1 = 5; + DPEphyCtrlRegValue.DIAJ_L2 = 5; + DPEphyCtrlRegValue.DIAJ_L3 = 5; + } + else if(ClockFreq >= 850000) + { + DPEphyCtrlRegValue.DIAJ_L0 = 3; + DPEphyCtrlRegValue.DIAJ_L1 = 3; + DPEphyCtrlRegValue.DIAJ_L2 = 3; + DPEphyCtrlRegValue.DIAJ_L3 = 3; + } + else + { + DPEphyCtrlRegValue.DIAJ_L0 = 4; + DPEphyCtrlRegValue.DIAJ_L1 = 4; + DPEphyCtrlRegValue.DIAJ_L2 = 4; + DPEphyCtrlRegValue.DIAJ_L3 = 4; + } + DPEphyCtrlRegMask.Value = 0xFFFFFFFF; + DPEphyCtrlRegMask.TX0T = 0; + DPEphyCtrlRegMask.TX1T = 0; + DPEphyCtrlRegMask.TX2T = 0; + DPEphyCtrlRegMask.TX3T = 0; + DPEphyCtrlRegMask.DIAJ_L0 = 0; + DPEphyCtrlRegMask.DIAJ_L1 = 0; + DPEphyCtrlRegMask.DIAJ_L2 = 0; + DPEphyCtrlRegMask.DIAJ_L3 = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_CTRL[DPModuleIndex], DPEphyCtrlRegValue.Value, DPEphyCtrlRegMask.Value); + + DPEphySetting2RegValue.Value = 0; + if(ClockFreq >= 3400000) + { + DPEphySetting2RegValue.EPHY1_TXDU_L0 = 0x3B; + DPEphySetting2RegValue.EPHY1_TXDU_L1 = 0x3B; + DPEphySetting2RegValue.EPHY1_TXDU_L2 = 0x3B; + DPEphySetting2RegValue.EPHY1_TXDU_L3 = 0x3F; + } + else + { + DPEphySetting2RegValue.EPHY1_TXDU_L0 = 0x3B; + DPEphySetting2RegValue.EPHY1_TXDU_L1 = 0x3B; + DPEphySetting2RegValue.EPHY1_TXDU_L2 = 0x3B; + DPEphySetting2RegValue.EPHY1_TXDU_L3 = 0x3F; + } + DPEphySetting2RegValue.EPHY1_TX_VMR = 0xF; + DPEphySetting2RegValue.EPHY1_TX_VMX = 0; + DPEphySetting2RegValue.EPHY1_TX_H1V2= 1; + + DPEphySetting2RegMask.Value = 0xFFFFFFFF; + DPEphySetting2RegMask.EPHY1_TXDU_L0 = 0; + DPEphySetting2RegMask.EPHY1_TXDU_L1 = 0; + DPEphySetting2RegMask.EPHY1_TXDU_L2 = 0; + DPEphySetting2RegMask.EPHY1_TXDU_L3 = 0; + DPEphySetting2RegMask.EPHY1_TX_VMR = 0; + DPEphySetting2RegMask.EPHY1_TX_VMX = 0; + DPEphySetting2RegMask.EPHY1_TX_H1V2= 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_SETTING2[DPModuleIndex], DPEphySetting2RegValue.Value, DPEphySetting2RegMask.Value); + + /* 2. Set DRV_Current and PRE_Current. Use SW setting*/ + + if(ClockFreq > 3400000) + { + if(ClockFreq == 5940000 && (pcbe->ChipID == CHIPID_E3K || pcbe->ChipID == CHIPID_ARISE10C0T)) + { + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 9; + DPSwingRegValue.DP1_SW_swing = 0x3F; + DPSwingRegValue.DP1_SW_pp = 0xA; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 1; + DPSwingRegValue.DP1_SW_swing = 0x33; + DPSwingRegValue.DP1_SW_pp = 9; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 5; + DPSwingRegValue.DP1_SW_swing = 0x21; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + } + else + { + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 1; + DPSwingRegValue.DP1_SW_swing = 0x3F; + DPSwingRegValue.DP1_SW_pp = 0x18; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPSwingRegValue.Value = 0; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 5; + DPSwingRegValue.DP1_SW_swing = 0x21; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + } + DPLinkRegValue.Value = 0; + DPLinkRegValue.Start_Link_Training = 0; + DPLinkRegValue.Start_Link_Rate_0 = 0; + DPLinkRegValue.Max_V_swing = 0; + DPLinkRegValue.Max_Pre_emphasis = 0; + DPLinkRegValue.SW_Hpd_assert = 0; + DPLinkRegValue.Num_of_Lanes = 4; + DPLinkRegValue.SW_Link_Train_Enable = 1; + DPLinkRegValue.SW_Link_Train_State = 1; + DPLinkRegValue.Software_Bit_Rate = 0; + DPLinkRegValue.SW_Lane0_Swing = 0; + DPLinkRegValue.SW_Lane0_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane1_Swing = 0; + DPLinkRegValue.SW_Lane1_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane2_Swing = 0; + DPLinkRegValue.SW_Lane2_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane3_Swing =0; + DPLinkRegValue.SW_Lane3_Pre_emphasis = 1; + DPLinkRegValue.SW_Set_Link_Train_Fail = 0; + DPLinkRegValue.HW_Link_Training_Done = 0; + if(ClockFreq == 5940000 && (pcbe->ChipID == CHIPID_E3K || pcbe->ChipID == CHIPID_ARISE10C0T)) + { + DPLinkRegValue.SW_Lane0_Pre_emphasis = 2; + } + DPLinkRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + } + else if(ClockFreq > 1700000) + { + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 1; + DPSwingRegValue.DP1_SW_swing = 0x30; + DPSwingRegValue.DP1_SW_pp = 2; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPLinkRegValue.Value = 0; + DPLinkRegValue.Start_Link_Training = 0; + DPLinkRegValue.Start_Link_Rate_0 = 0; + DPLinkRegValue.Max_V_swing = 0; + DPLinkRegValue.Max_Pre_emphasis = 0; + DPLinkRegValue.SW_Hpd_assert = 0; + DPLinkRegValue.Num_of_Lanes = 4; + DPLinkRegValue.SW_Link_Train_Enable = 1; + DPLinkRegValue.SW_Link_Train_State = 1; + DPLinkRegValue.Software_Bit_Rate = 0; + DPLinkRegValue.SW_Lane0_Swing = 0; + DPLinkRegValue.SW_Lane0_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane1_Swing = 0; + DPLinkRegValue.SW_Lane1_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane2_Swing = 0; + DPLinkRegValue.SW_Lane2_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane3_Swing =0; + DPLinkRegValue.SW_Lane3_Pre_emphasis = 0; + DPLinkRegValue.SW_Set_Link_Train_Fail = 0; + DPLinkRegValue.HW_Link_Training_Done = 0; + DPLinkRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + } + else if(ClockFreq > 850000) + { + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 1; + DPSwingRegValue.DP1_SW_swing = 0x2C; + DPSwingRegValue.DP1_SW_pp = 2; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPLinkRegValue.Value = 0; + DPLinkRegValue.Start_Link_Training = 0; + DPLinkRegValue.Start_Link_Rate_0 = 0; + DPLinkRegValue.Max_V_swing = 0; + DPLinkRegValue.Max_Pre_emphasis = 0; + DPLinkRegValue.SW_Hpd_assert = 0; + DPLinkRegValue.Num_of_Lanes = 4; + DPLinkRegValue.SW_Link_Train_Enable = 1; + DPLinkRegValue.SW_Link_Train_State = 1; + DPLinkRegValue.Software_Bit_Rate = 0; + DPLinkRegValue.SW_Lane0_Swing = 0; + DPLinkRegValue.SW_Lane0_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane1_Swing = 0; + DPLinkRegValue.SW_Lane1_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane2_Swing = 0; + DPLinkRegValue.SW_Lane2_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane3_Swing =0; + DPLinkRegValue.SW_Lane3_Pre_emphasis = 0; + DPLinkRegValue.SW_Set_Link_Train_Fail = 0; + DPLinkRegValue.HW_Link_Training_Done = 0; + DPLinkRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + } + else + { + DPSwingRegValue.Value = 0; + DPSwingRegValue.enable_SW_swing_pp = 1; + DPSwingRegValue.SW_swing_SW_PP_SW_post_cursor_load_index = 1; + DPSwingRegValue.DP1_SW_swing = 0xD; + DPSwingRegValue.DP1_SW_pp = 0; + DPSwingRegValue.DP1_SW_post_cursor = 0; + + DPSwingRegMask.Value = 0xFFFFFFFF; + DPSwingRegMask.enable_SW_swing_pp = 0; + DPSwingRegMask.SW_swing_SW_PP_SW_post_cursor_load_index = 0; + DPSwingRegMask.DP1_SW_swing = 0; + DPSwingRegMask.DP1_SW_pp = 0; + DPSwingRegMask.DP1_SW_post_cursor = 0; + cbMMIOWriteReg32(pcbe, DP_REG_SWING[DPModuleIndex], DPSwingRegValue.Value, DPSwingRegMask.Value); + + DPLinkRegValue.Value = 0; + DPLinkRegValue.Start_Link_Training = 0; + DPLinkRegValue.Start_Link_Rate_0 = 0; + DPLinkRegValue.Max_V_swing = 0; + DPLinkRegValue.Max_Pre_emphasis = 0; + DPLinkRegValue.SW_Hpd_assert = 0; + DPLinkRegValue.Num_of_Lanes = 4; + DPLinkRegValue.SW_Link_Train_Enable = 1; + DPLinkRegValue.SW_Link_Train_State = 1; + DPLinkRegValue.Software_Bit_Rate = 0; + DPLinkRegValue.SW_Lane0_Swing = 0; + DPLinkRegValue.SW_Lane0_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane1_Swing = 0; + DPLinkRegValue.SW_Lane1_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane2_Swing = 0; + DPLinkRegValue.SW_Lane2_Pre_emphasis = 0; + DPLinkRegValue.SW_Lane3_Swing =0; + DPLinkRegValue.SW_Lane3_Pre_emphasis = 0; + DPLinkRegValue.SW_Set_Link_Train_Fail = 0; + DPLinkRegValue.HW_Link_Training_Done = 0; + DPLinkRegMask.Value = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + } + + /* 3. Enable Bandgap, disable MPLL*/ + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.Bandgap_Power_Down = 1; + DPEphyMpllRegValue.MPLL_Reg_Power_Down = 0; + DPEphyMpllRegValue.MPLL_Power_Down = 0; + + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.Bandgap_Power_Down = 0; + DPEphyMpllRegMask.MPLL_Reg_Power_Down = 0; + DPEphyMpllRegMask.MPLL_Power_Down = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + /* 4. Enable TPLL*/ + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.TPLL_Reg_Power_Down = 1; + DPEphyMpllRegValue.TPLL_Power_Down = 1; + + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.TPLL_Reg_Power_Down = 0; + DPEphyMpllRegMask.TPLL_Power_Down = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + cb_DelayMicroSeconds(1500); + + /* 5. Check TPLL Lock Status */ + DPEphyMiscRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_EPHY_MISC[DPModuleIndex]); + if (DPEphyMiscRegValue.TPLL_Lock_Indicator == 0) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR),"%s: TPLL is not locked.\n", FUNCTION_NAME)); + } + + /* 6. Enable TX Power State Machine. */ + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 3; + + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Power_Control_Lane0 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane1 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane2 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane3 = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + cb_DelayMicroSeconds(20); + + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 2; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 2; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 2; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 2; + + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Power_Control_Lane0 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane1 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane2 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane3 = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane0 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane1 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane2 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane3 = 1; + + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane0 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane1 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane2 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane3 = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + cbDelayMilliSeconds(2);//2ms + + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 0; + + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Power_Control_Lane0 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane1 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane2 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane3 = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + cb_DelayMicroSeconds(1); + + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.Driver_Control_Lane0 = 1; + DPEphyTxRegValue.Driver_Control_Lane1 = 1; + DPEphyTxRegValue.Driver_Control_Lane2 = 1; + DPEphyTxRegValue.Driver_Control_Lane3 = 1; + + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.Driver_Control_Lane0 = 0; + DPEphyTxRegMask.Driver_Control_Lane1 = 0; + DPEphyTxRegMask.Driver_Control_Lane2 = 0; + DPEphyTxRegMask.Driver_Control_Lane3 = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + } + else // turn off + { + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.Bandgap_Power_Down = 0; + DPEphyMpllRegValue.MPLL_Reg_Power_Down = 0; + DPEphyMpllRegValue.MPLL_Power_Down = 0; + DPEphyMpllRegValue.TPLL_Reg_Power_Down = 0; + DPEphyMpllRegValue.TPLL_Power_Down = 0; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.Bandgap_Power_Down = 0; + DPEphyMpllRegMask.MPLL_Reg_Power_Down = 0; + DPEphyMpllRegMask.MPLL_Power_Down = 0; + DPEphyMpllRegMask.TPLL_Reg_Power_Down = 0; + DPEphyMpllRegMask.TPLL_Power_Down = 0; + + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.EPHY_MPLL_CP = 0; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 3; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane0 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane1 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane2 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane3 = 0; + DPEphyTxRegValue.Driver_Control_Lane0 = 0; + DPEphyTxRegValue.Driver_Control_Lane1 = 0; + DPEphyTxRegValue.Driver_Control_Lane2 = 0; + DPEphyTxRegValue.Driver_Control_Lane3 = 0; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.EPHY_MPLL_CP = 0; + DPEphyTxRegMask.TX_Power_Control_Lane0 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane1 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane2 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane3 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane0 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane1 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane2 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane3 = 0; + DPEphyTxRegMask.Driver_Control_Lane0 = 0; + DPEphyTxRegMask.Driver_Control_Lane1 = 0; + DPEphyTxRegMask.Driver_Control_Lane2 = 0; + DPEphyTxRegMask.Driver_Control_Lane3 = 0; + + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.AUC_Ch_Op_Mode = 0; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.AUC_Ch_Op_Mode = 0; + + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + } + + cbTraceExit(DP); +} + +CBIOS_VOID cbPHY_DP_InitEPHY(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8240 DPEnableRegValue, DPEnableRegMask; + REG_MM8214 DPLinkRegValue, DPLinkRegMask; + REG_MM82CC DPEphyCtrlRegValue, DPEphyCtrlRegMask; + REG_MM8340 DPEphyMpllRegValue, DPEphyMpllRegMask; + REG_MM8344 DPEphyTxRegValue, DPEphyTxRegMask; + REG_MM8348 DPEphyMiscRegValue, DPEphyMiscRegMask; + REG_MM836C DPEphyStatusRegValue, DPEphyStatusRegMask; + REG_MM334CC DPCtrl2RegValue, DPCtrl2RegMask; + REG_MM334E0 DPEphySetting1RegValue, DPEphySetting1RegMask; + REG_MM334E4 DPEphySetting2RegValue, DPEphySetting2RegMask; + REG_MM334C8 DPLinkCtrlRegValue, DPLinkCtrlRegMask; + + cbTraceEnter(DP); + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + //Enable DP + DPEnableRegValue.Value = 0; + DPEnableRegValue.DP_Enable = 0; + DPEnableRegMask.Value = 0xFFFFFFFF; + DPEnableRegMask.DP_Enable = 0; + cbMMIOWriteReg32(pcbe, DP_REG_ENABLE[DPModuleIndex], DPEnableRegValue.Value, DPEnableRegMask.Value); + + DPLinkRegValue.Value = 0; + DPLinkRegValue.Max_V_swing = 3; + DPLinkRegValue.Max_Pre_emphasis = 2; + DPLinkRegMask.Value = 0xFFFFFFFF; + DPLinkRegMask.Max_V_swing = 0; + DPLinkRegMask.Max_Pre_emphasis = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK[DPModuleIndex], DPLinkRegValue.Value, DPLinkRegMask.Value); + + DPLinkCtrlRegValue.Value = 0; + DPLinkCtrlRegValue.MAX_POST_EMPHASIS = 0; + DPLinkCtrlRegValue.DP_SUPPORT_POST_CURSOR = 0; + DPLinkCtrlRegMask.Value = 0xFFFFFFFF; + DPLinkCtrlRegMask.MAX_POST_EMPHASIS = 0; + DPLinkCtrlRegMask.DP_SUPPORT_POST_CURSOR = 0; + cbMMIOWriteReg32(pcbe, DP_REG_LINK_CTRL[DPModuleIndex], DPLinkCtrlRegValue.Value, DPLinkCtrlRegMask.Value); + + // Select EPHY MPLL Clock as DP clock + DPEphyCtrlRegValue.Value = 0; + DPEphyCtrlRegValue.DP_Clock_Debug = 0; + DPEphyCtrlRegValue.check_sync_cnt = 0x1;//HW don't check sync counter for aux receiver + DPEphyCtrlRegValue.DIAJ_L0 = 0x4; + DPEphyCtrlRegValue.DIAJ_L1 = 0x4; + DPEphyCtrlRegValue.DIAJ_L2 = 0x4; + DPEphyCtrlRegValue.DIAJ_L3 = 0x4; + DPEphyCtrlRegMask.Value = 0xFFFFFFFF; + DPEphyCtrlRegMask.DP_Clock_Debug = 0; + DPEphyCtrlRegMask.check_sync_cnt = 0x0; + DPEphyCtrlRegMask.DIAJ_L0 = 0; + DPEphyCtrlRegMask.DIAJ_L1 = 0; + DPEphyCtrlRegMask.DIAJ_L2 = 0; + DPEphyCtrlRegMask.DIAJ_L3 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_CTRL[DPModuleIndex], DPEphyCtrlRegValue.Value, DPEphyCtrlRegMask.Value); + + // Disable Bandgap, MPLL and TPLL + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.Bandgap_Power_Down = 0; + DPEphyMpllRegValue.MPLL_Reg_Power_Down = 0; + DPEphyMpllRegValue.MPLL_Power_Down = 0; + DPEphyMpllRegValue.TPLL_Reg_Power_Down = 0; + DPEphyMpllRegValue.TPLL_Power_Down = 0; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.Bandgap_Power_Down = 0; + DPEphyMpllRegMask.MPLL_Reg_Power_Down = 0; + DPEphyMpllRegMask.MPLL_Power_Down = 0; + DPEphyMpllRegMask.TPLL_Reg_Power_Down = 0; + DPEphyMpllRegMask.TPLL_Power_Down = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + // Bandgap power up + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.Bandgap_Power_Down = 1; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.Bandgap_Power_Down = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + + //MPLL & SSC + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.MPLL_R = 0; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.MPLL_R = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + //MPLL PTAT Current = 16uA. mm8340[4:3] = 2'b01 + //MPLL CP Current = 8uA. {mm8340[7:5], mm8344[23]} = 4'b1000 + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.MPLL_PTAT_Current = 1; + DPEphyMpllRegValue.MPLL_CP_Current = 4; + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.EPHY_MPLL_CP = 0; + + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.MPLL_PTAT_Current = 0; + DPEphyMpllRegMask.MPLL_CP_Current = 0; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.EPHY_MPLL_CP = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + //MPLL N, P. MPLL Clk=ref_clk*(N+2)/P. ref_clk=13.5MHz=27MHz/2=input_clk/R. + //RBR: N=0xBE, P=16 + //HBR: N=0x9E, P=8 + //HBR2: N=0x9E, P=4 + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.MPLL_N = 0xBE; // RBR 1.62G + DPEphyMpllRegValue.MPLL_P = 2; // RBR 1.62G + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.MPLL_N = 0; + DPEphyMpllRegMask.MPLL_P = 0; + DPCtrl2RegValue.Value = 0; + DPCtrl2RegValue.SW_MPLL_M_1 = 0x9E; // HBR 2.7G + DPCtrl2RegValue.SW_MPLL_P_1 = 1; // HBR 2.7G + DPCtrl2RegValue.SW_MPLL_M_2 = 0x9E; // HBR2 5.4G + DPCtrl2RegValue.SW_MPLL_P_2 = 0; // HBR2 5.4G + DPCtrl2RegMask.Value = 0xFFFFFFFF; + DPCtrl2RegMask.SW_MPLL_M_1 = 0; + DPCtrl2RegMask.SW_MPLL_P_1 = 0; + DPCtrl2RegMask.SW_MPLL_M_2 = 0; + DPCtrl2RegMask.SW_MPLL_P_2 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + cbMMIOWriteReg32(pcbe, DP_REG_CTRL2[DPModuleIndex], DPCtrl2RegValue.Value, DPCtrl2RegMask.Value); + + //MPLL loop filter R and C + DPEphyStatusRegValue.Value = 0; + DPEphyStatusRegValue.MR = 0; + DPEphyStatusRegValue.MC = 0; + DPEphyStatusRegMask.Value = 0xFFFFFFFF; + DPEphyStatusRegMask.MR = 0; + DPEphyStatusRegMask.MC = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_STATUS[DPModuleIndex], DPEphyStatusRegValue.Value, DPEphyStatusRegMask.Value); + + + // SSC OFF + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.SSC_Enable = 0; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.SSC_Enable = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + // SSC Frequency Spread Magnitude peak-to-peak control = 0.25%. SSC Frequency Spread = down_spread. SSC Dither Control = dither_off. SSC Modulating Signal Profile = asymmetric_triangular + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.SSC_Freq_Spread = 0; + DPEphyMpllRegValue.Dither = 0; + DPEphyMpllRegValue.Signal_Profile = 1; + DPEphyMpllRegValue.Spread_Magnitude = 0; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.SSC_Freq_Spread = 0; + DPEphyMpllRegMask.Dither = 0; + DPEphyMpllRegMask.Signal_Profile = 0; + DPEphyMpllRegMask.Spread_Magnitude = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + // MPLL Power Up + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.MPLL_Power_Down = 1; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.MPLL_Power_Down = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + // MPLL Regulator Power Up + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.MPLL_Reg_Power_Down = 1; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.MPLL_Reg_Power_Down = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + cb_DelayMicroSeconds(1000); + // Check MPLL Lock Indicator + DPEphyMiscRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_EPHY_MISC[DPModuleIndex]); + if (DPEphyMiscRegValue.MPLL_Lock_Indicator == 0) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR),"%s: MPLL is not locked.\n", FUNCTION_NAME)); + } + + // TPLL + // TPLL Charge pump current = 8uA + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.EPHY1_TPLL_CP = 8; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.EPHY1_TPLL_CP = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + // TPLL Nx + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.TPLL_N_Div = 1; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.TPLL_N_Div = 0; + DPCtrl2RegValue.Value = 0; + DPCtrl2RegValue.SW_NX_P = 1; + DPCtrl2RegValue.SW_NX_P_1 = 1; + DPCtrl2RegValue.SW_MPLL_P_2 = 0; + DPCtrl2RegMask.Value = 0xFFFFFFFF; + DPCtrl2RegMask.SW_NX_P = 0; + DPCtrl2RegMask.SW_NX_P_1 = 0; + DPCtrl2RegMask.SW_NX_P_2 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + cbMMIOWriteReg32(pcbe, DP_REG_CTRL2[DPModuleIndex], DPCtrl2RegValue.Value, DPCtrl2RegMask.Value); + + // TPLL FBoost, VCO frequency boost. + DPEphySetting1RegValue.Value = 0; + DPEphySetting1RegValue.EPHY1_FBOOST = 0; + DPEphySetting1RegValue.EPHY1_FBOOST_1 = 0; + DPEphySetting1RegValue.EPHY1_FBOOST_2 = 1; + DPEphySetting1RegValue.EPHY1_HDCKBY4 = 0; + DPEphySetting1RegMask.Value = 0xFFFFFFFF; + DPEphySetting1RegMask.EPHY1_FBOOST = 0; + DPEphySetting1RegMask.EPHY1_FBOOST_1 = 0; + DPEphySetting1RegMask.EPHY1_FBOOST_2 = 0; + DPEphySetting1RegMask.EPHY1_HDCKBY4 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_SETTING1[DPModuleIndex], DPEphySetting1RegValue.Value, DPEphySetting1RegMask.Value); + + // TPLL bias current, loop filter R and C + DPEphyStatusRegValue.Value = 0; + DPEphyStatusRegValue.EPHY1_TPLL_ISEL = 0; + DPEphyStatusRegValue.TR = 0; + DPEphyStatusRegValue.TC = 7; + DPEphyStatusRegMask.Value = 0xFFFFFFFF; + DPEphyStatusRegMask.EPHY1_TPLL_ISEL = 0; + DPEphyStatusRegMask.TR = 0; + DPEphyStatusRegMask.TC = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_STATUS[DPModuleIndex], DPEphyStatusRegValue.Value, DPEphyStatusRegMask.Value); + + // TPLL Power Up + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.TPLL_Power_Down = 1; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.TPLL_Power_Down = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + // TPLL Regulator Power Up + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.TPLL_Reg_Power_Down = 1; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.TPLL_Reg_Power_Down = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + cb_DelayMicroSeconds(1100); + // Check TPLL Lock Indicator + // DPEphyMiscRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_EPHY_MISC[DPModuleIndex]); + // if (DPEphyMiscRegValue.TPLL_Lock_Indicator == 0) + // { + // cbDebugPrint((MAKE_LEVEL(DP, ERROR),"%s: TPLL is not locked.\n", FUNCTION_NAME)); + // } + + // RTN + // Disable RTN BIST. + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.RTNBIST = 0; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.RTNBIST = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + // Auto Calibration + // Disable resistance overwrite manually mode. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Resistance_Set_Enable = 1; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Resistance_Set_Enable = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + // Power down RTN. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.Resistance_Tuning_PD = 0; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.Resistance_Tuning_PD = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // Disable RTN. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.Resistance_Tuning_Enable = 0; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.Resistance_Tuning_Enable = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // Reset RTN. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.Resistance_Tuning_Reset = 0; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.Resistance_Tuning_Reset = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // delay for at least 10ns + cb_DelayMicroSeconds(1); + // Power up RTN. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.Resistance_Tuning_PD = 1; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.Resistance_Tuning_PD = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // delay for at least 10ns + cb_DelayMicroSeconds(1); + // De-assert RTN reset. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.Resistance_Tuning_Reset = 1; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.Resistance_Tuning_Reset = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // delay for at least 160ns + cb_DelayMicroSeconds(1); + // Enable RTN. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.Resistance_Tuning_Enable = 1; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.Resistance_Tuning_Enable = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // delay for at least 20us + cb_DelayMicroSeconds(1); + // Disable RTN. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.Resistance_Tuning_Enable = 0; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.Resistance_Tuning_Enable = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // delay for at least 40ns + cb_DelayMicroSeconds(1); + // Power down RTN to hold the result. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.Resistance_Tuning_PD = 0; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.Resistance_Tuning_PD = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // Read RTN result. + DPEphyMiscRegValue.Value = cb_ReadU32(pcbe->pAdapterContext, DP_REG_EPHY_MISC[DPModuleIndex]); + cbDebugPrint((MAKE_LEVEL(DP, DEBUG), "%s: RTN value = 0x%x.\n", FUNCTION_NAME, DPEphyMiscRegValue.RTN_Results)); + + // Force on SSC_PDB + // RTN select bit. 1: lower the termination resistance. + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.M1V = 0; + DPEphyMiscRegValue.MT = 1; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.M1V = 0; + DPEphyMiscRegMask.MT = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + // TX + // TX PISO. CKHLD = 2'b00, no delay. + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.CKHLD = 0; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.CKHLD = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + // TX driver voltage control, TX_H1V2 = 2'b00(1.16v), {mm8348[16], mm34E4[29]} + // All the 4 lanes have the same control. + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.TX_High_Impedance_Lane0 = 0; + DPEphyMiscRegValue.TX_High_Impedance_Lane1 = 0; + DPEphyMiscRegValue.TX_High_Impedance_Lane2 = 0; + DPEphyMiscRegValue.TX_High_Impedance_Lane3 = 0; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.TX_High_Impedance_Lane0 = 0; + DPEphyMiscRegMask.TX_High_Impedance_Lane1 = 0; + DPEphyMiscRegMask.TX_High_Impedance_Lane2 = 0; + DPEphyMiscRegMask.TX_High_Impedance_Lane3 = 0; + DPEphySetting2RegValue.Value = 0; + DPEphySetting2RegValue.EPHY1_TX_H1V2 = 0; + DPEphySetting2RegMask.Value = 0xFFFFFFFF; + DPEphySetting2RegMask.EPHY1_TX_H1V2 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_SETTING2[DPModuleIndex], DPEphySetting2RegValue.Value, DPEphySetting2RegMask.Value); + + // TX driver slew rate + DPEphySetting1RegValue.Value = 0; + DPEphySetting1RegValue.EPHY1_SR_SPD = 0; + DPEphySetting1RegValue.EPHY1_SR_DLY = 0; + DPEphySetting1RegValue.EPHY1_SR_NDLY = 0; + DPEphySetting1RegMask.Value = 0xFFFFFFFF; + DPEphySetting1RegMask.EPHY1_SR_SPD = 0; + DPEphySetting1RegMask.EPHY1_SR_DLY = 0; + DPEphySetting1RegMask.EPHY1_SR_NDLY = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_SETTING1[DPModuleIndex], DPEphySetting1RegValue.Value, DPEphySetting1RegMask.Value); + + // TX output duty-cycle adjust + DPEphySetting2RegValue.Value = 0; + DPEphySetting2RegValue.EPHY1_TXDU_L0 = 0x3F; + DPEphySetting2RegValue.EPHY1_TXDU_L1 = 0x3F; + DPEphySetting2RegValue.EPHY1_TXDU_L2 = 0x3F; + DPEphySetting2RegValue.EPHY1_TXDU_L3 = 0x3F; + DPEphySetting2RegValue.EPHY1_TX_VMR = 0xF; + DPEphySetting2RegValue.EPHY1_TX_VMX = 0; + DPEphySetting2RegMask.Value = 0xE0000000; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_SETTING2[DPModuleIndex], DPEphySetting2RegValue.Value, DPEphySetting2RegMask.Value); + + // TX Driver Initial + // TX_PWR_Lx[1:0]=2'b11, REGPDB_Lx=0, EIDLEB_Lx=0. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane0 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane1 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane2 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane3 = 0; + DPEphyTxRegValue.Driver_Control_Lane0 = 0; + DPEphyTxRegValue.Driver_Control_Lane1 = 0; + DPEphyTxRegValue.Driver_Control_Lane2 = 0; + DPEphyTxRegValue.Driver_Control_Lane3 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 3; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane0 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane1 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane2 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane3 = 0; + DPEphyTxRegMask.Driver_Control_Lane0 = 0; + DPEphyTxRegMask.Driver_Control_Lane1 = 0; + DPEphyTxRegMask.Driver_Control_Lane2 = 0; + DPEphyTxRegMask.Driver_Control_Lane3 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane0 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane1 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane2 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane3 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // TX_PWR_Lx[1:0]=2'b10, REGPDB_Lx=1, EIDLEB_Lx=0. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane0 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane1 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane2 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane3 = 1; + DPEphyTxRegValue.Driver_Control_Lane0 = 0; + DPEphyTxRegValue.Driver_Control_Lane1 = 0; + DPEphyTxRegValue.Driver_Control_Lane2 = 0; + DPEphyTxRegValue.Driver_Control_Lane3 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 2; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 2; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 2; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 2; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane0 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane1 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane2 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane3 = 0; + DPEphyTxRegMask.Driver_Control_Lane0 = 0; + DPEphyTxRegMask.Driver_Control_Lane1 = 0; + DPEphyTxRegMask.Driver_Control_Lane2 = 0; + DPEphyTxRegMask.Driver_Control_Lane3 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane0 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane1 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane2 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane3 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + // delay for at least 1.5ms + cb_DelayMicroSeconds(1500); + + // TX_PWR_Lx[1:0]=2'b00, REGPDB_Lx=1, EIDLEB_Lx=0. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane0 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane1 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane2 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane3 = 1; + DPEphyTxRegValue.Driver_Control_Lane0 = 0; + DPEphyTxRegValue.Driver_Control_Lane1 = 0; + DPEphyTxRegValue.Driver_Control_Lane2 = 0; + DPEphyTxRegValue.Driver_Control_Lane3 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 0; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane0 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane1 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane2 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane3 = 0; + DPEphyTxRegMask.Driver_Control_Lane0 = 0; + DPEphyTxRegMask.Driver_Control_Lane1 = 0; + DPEphyTxRegMask.Driver_Control_Lane2 = 0; + DPEphyTxRegMask.Driver_Control_Lane3 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane0 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane1 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane2 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane3 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + // delay for at least 100ns + cb_DelayMicroSeconds(1); + + // TX_PWR_Lx[1:0]=2'b00, REGPDB_Lx=1, EIDLEB_Lx=1. + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane0 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane1 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane2 = 1; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane3 = 1; + DPEphyTxRegValue.Driver_Control_Lane0 = 1; + DPEphyTxRegValue.Driver_Control_Lane1 = 1; + DPEphyTxRegValue.Driver_Control_Lane2 = 1; + DPEphyTxRegValue.Driver_Control_Lane3 = 1; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 0; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane0 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane1 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane2 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane3 = 0; + DPEphyTxRegMask.Driver_Control_Lane0 = 0; + DPEphyTxRegMask.Driver_Control_Lane1 = 0; + DPEphyTxRegMask.Driver_Control_Lane2 = 0; + DPEphyTxRegMask.Driver_Control_Lane3 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane0 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane1 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane2 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane3 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // AUX Initial + // AUX_CTRL_Lx[1:0]=2'b00. AUX CH power off. + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.AUC_Ch_Op_Mode = 0; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.AUC_Ch_Op_Mode = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + // AUX_CTRL_Lx[1:0]=2'b01. The CMOP is on; the TX and RX are off. + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.AUC_Ch_Op_Mode = 1; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.AUC_Ch_Op_Mode = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + // delay for at least 1.5ms + cb_DelayMicroSeconds(1500); + + // AUX_CTRL_Lx[1:0]=2'b10. HW controls operation. + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.AUC_Ch_Op_Mode = 2; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.AUC_Ch_Op_Mode = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + // HPD Power Up. + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.HPD_Power_Down = 1; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.HPD_Power_Down = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + cbTraceExit(DP); + return; +} + + +CBIOS_VOID cbPHY_DP_DeInitEPHY(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8340 DPEphyMpllRegValue, DPEphyMpllRegMask; + REG_MM8344 DPEphyTxRegValue, DPEphyTxRegMask; + REG_MM8348 DPEphyMiscRegValue, DPEphyMiscRegMask; + + cbTraceEnter(DP); + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + // Disable Bandgap, MPLL and TPLL + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.Bandgap_Power_Down = 0; + DPEphyMpllRegValue.MPLL_Reg_Power_Down = 0; + DPEphyMpllRegValue.MPLL_Power_Down = 0; + DPEphyMpllRegValue.TPLL_Reg_Power_Down = 0; + DPEphyMpllRegValue.TPLL_Power_Down = 0; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.Bandgap_Power_Down = 0; + DPEphyMpllRegMask.MPLL_Reg_Power_Down = 0; + DPEphyMpllRegMask.MPLL_Power_Down = 0; + DPEphyMpllRegMask.TPLL_Reg_Power_Down = 0; + DPEphyMpllRegMask.TPLL_Power_Down = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + + // Disable TX Driver + DPEphyTxRegValue.Value = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane0 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane1 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane2 = 0; + DPEphyTxRegValue.TX_Reg_Power_Down_Lane3 = 0; + DPEphyTxRegValue.Driver_Control_Lane0 = 0; + DPEphyTxRegValue.Driver_Control_Lane1 = 0; + DPEphyTxRegValue.Driver_Control_Lane2 = 0; + DPEphyTxRegValue.Driver_Control_Lane3 = 0; + DPEphyTxRegValue.TX_Power_Control_Lane0 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane1 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane2 = 3; + DPEphyTxRegValue.TX_Power_Control_Lane3 = 3; + DPEphyTxRegMask.Value = 0xFFFFFFFF; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane0 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane1 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane2 = 0; + DPEphyTxRegMask.TX_Reg_Power_Down_Lane3 = 0; + DPEphyTxRegMask.Driver_Control_Lane0 = 0; + DPEphyTxRegMask.Driver_Control_Lane1 = 0; + DPEphyTxRegMask.Driver_Control_Lane2 = 0; + DPEphyTxRegMask.Driver_Control_Lane3 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane0 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane1 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane2 = 0; + DPEphyTxRegMask.TX_Power_Control_Lane3 = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_TX[DPModuleIndex], DPEphyTxRegValue.Value, DPEphyTxRegMask.Value); + + // Disable AUX + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.AUC_Ch_Op_Mode = 0; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.AUC_Ch_Op_Mode = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + cbTraceExit(DP); + return; +} + + +static CBIOS_BOOL cbPHY_DP_SelectTMDSModeSource(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_DISPLAY_SOURCE pDispSource, CBIOS_MONITOR_TYPE MonitorType) +{ + REG_SR3A_Pair RegSR3AValue; + REG_SR3A_Pair RegSR3AMask; + CBIOS_BOOL Ret = CBIOS_FALSE; + CBIOS_MODULE **pModulePath = pDispSource->ModulePath; + + if (pModulePath == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 3rd param is NULL!\n", FUNCTION_NAME)); + return Ret; + } + + switch (pModulePath[0]->Type) + { + case CBIOS_MODULE_TYPE_HDCP: + switch (pModulePath[1]->Type) + { + case CBIOS_MODULE_TYPE_HDMI: + if(MonitorType == CBIOS_MONITOR_TYPE_HDMI) + { + RegSR3AValue.Value = 0; + RegSR3AValue.DP_PHY_Source_Sel = 4; + } + else if(MonitorType == CBIOS_MONITOR_TYPE_DVI) + { + RegSR3AValue.Value = 0; + RegSR3AValue.DP_PHY_Source_Sel = 0; + } + RegSR3AMask.Value = 0xFF; + RegSR3AMask.DP_PHY_Source_Sel = 0; + cbBiosMMIOWriteReg(pcbe, SR_3A, RegSR3AValue.Value, RegSR3AMask.Value, DPModuleIndex); + + Ret = CBIOS_TRUE; + break; + case CBIOS_MODULE_TYPE_IGA://should set DP_PHY_Source_Sel to 0,otherwise, like DVI can't light. + if (pModulePath[1]->Index != CBIOS_MODULE_INDEX_INVALID) + { + RegSR3AValue.Value = 0; + RegSR3AValue.DP_PHY_Source_Sel = 0; + RegSR3AMask.Value = 0xFF; + RegSR3AMask.DP_PHY_Source_Sel = 0; + cbBiosMMIOWriteReg(pcbe, SR_3A, RegSR3AValue.Value, RegSR3AMask.Value, DPModuleIndex); + + Ret = CBIOS_TRUE; + } + break; + default: + break; + } + break; + default: + break; + } + + if (!Ret) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: cannot select DP TMDS mode source!!!\n", FUNCTION_NAME)); + } + return Ret; +} + +static CBIOS_VOID cbPHY_DP_SelectDPModeSource(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_MODULE_INDEX DPModuleIndex, PCBIOS_DISPLAY_SOURCE pDispSource) +{ + CBIOS_U32 i = 0; + CBIOS_MODULE *pHDTVModule = CBIOS_NULL; + CBIOS_MODULE *pIGAModule = CBIOS_NULL; + CBIOS_MODULE **pModulePath = pDispSource->ModulePath; + + if (pModulePath == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return; + } + + while (pModulePath[i]) + { + if (pModulePath[i]->Type == CBIOS_MODULE_TYPE_HDTV) + { + pHDTVModule = pModulePath[i]; + } + else if (pModulePath[i]->Type == CBIOS_MODULE_TYPE_IGA) + { + pIGAModule = pModulePath[i]; + break; + } + i++; + } + + // HDTV1 is hardcoded to DP1 by HW design + if (pHDTVModule && pIGAModule) + { + cbDIU_HDTV_LBBypass(pcbe, DPModuleIndex, CBIOS_FALSE); + } + else if (pIGAModule) + { + cbDIU_HDTV_LBBypass(pcbe, DPModuleIndex, CBIOS_TRUE); + } + else + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: cannot select DP mode source!\n", FUNCTION_NAME)); + } +} + +CBIOS_VOID cbPHY_DP_SelectPhySource(PCBIOS_VOID pvcbe, DP_EPHY_MODE DPEphyMode, PCBIOS_DISPLAY_SOURCE pDispSource, CBIOS_MONITOR_TYPE MonitorType) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_MODULE_INDEX DPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + + if (pDispSource == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return; + } + + DPModuleIndex = pDispSource->ModuleList.DPModule.Index; + + cbPHY_DP_SelectEphyMode(pcbe, DPModuleIndex, DPEphyMode); + + if (DPEphyMode == DP_EPHY_TMDS_MODE) + { + cbPHY_DP_SelectTMDSModeSource(pcbe, DPModuleIndex, pDispSource, MonitorType); + } + else if (DPEphyMode == DP_EPHY_DP_MODE) + { + cbPHY_DP_SelectDPModeSource(pcbe, DPModuleIndex, pDispSource); + } + else + { + ASSERT(CBIOS_FALSE); + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: unsupported ephy mode!\n", FUNCTION_NAME)); + } +} + +CBIOS_VOID cbPHY_DP_AuxPowerOn(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8340 DPEphyMpllRegValue, DPEphyMpllRegMask; + REG_MM8348 DPEphyMiscRegValue, DPEphyMiscRegMask; + + if (DPModuleIndex >= DP_MODU_NUM) + { + cbDebugPrint((MAKE_LEVEL(DP, ERROR), "%s: invalid DP module index!\n", FUNCTION_NAME)); + return; + } + + // 1. enable Bandgap + DPEphyMpllRegValue.Value = 0; + DPEphyMpllRegValue.Bandgap_Power_Down = 1; + DPEphyMpllRegMask.Value = 0xFFFFFFFF; + DPEphyMpllRegMask.Bandgap_Power_Down = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MPLL[DPModuleIndex], DPEphyMpllRegValue.Value, DPEphyMpllRegMask.Value); + + cb_DelayMicroSeconds(20); + + // 2. start AUX channel, CMOP on, Tx/Rx off + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.AUC_Ch_Op_Mode = 1; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.AUC_Ch_Op_Mode = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); + + cbDelayMilliSeconds(2); + + DPEphyMiscRegValue.Value = 0; + DPEphyMiscRegValue.AUC_Ch_Op_Mode = 2; + DPEphyMiscRegMask.Value = 0xFFFFFFFF; + DPEphyMiscRegMask.AUC_Ch_Op_Mode = 0; + cbMMIOWriteReg32(pcbe, DP_REG_EPHY_MISC[DPModuleIndex], DPEphyMiscRegValue.Value, DPEphyMiscRegMask.Value); +} + diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.h new file mode 100644 index 0000000000000..deb4bc8410eb0 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.h @@ -0,0 +1,45 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DP PHY interface function prototype and parameter definition. +** +** NOTE: +** +******************************************************************************/ + +#ifndef _CBIOS_PHY_DP_H_ +#define _CBIOS_PHY_DP_H_ + +#include "../../Device/CBiosDeviceShare.h" + +typedef enum _DP_EPHY_MODE +{ + DP_EPHY_MODE_UNINITIALIZED = 0, + DP_EPHY_TMDS_MODE, + DP_EPHY_DP_MODE, + DP_EHPY_MODE_LAST +}DP_EPHY_MODE; + +CBIOS_VOID cbPHY_DP_InitEPHY(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex); +CBIOS_VOID cbPHY_DP_DeInitEPHY(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex); +CBIOS_VOID cbPHY_DP_SelectPhySource(PCBIOS_VOID pvcbe, DP_EPHY_MODE DPEphyMode, PCBIOS_DISPLAY_SOURCE pDispSource, CBIOS_MONITOR_TYPE MonitorType); +CBIOS_VOID cbPHY_DP_SelectEphyMode(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, DP_EPHY_MODE DPEphyMode); +DP_EPHY_MODE cbPHY_DP_GetEphyMode(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex); +CBIOS_VOID cbPHY_DP_DPModeOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U32 LinkSpeed, CBIOS_BOOL status); +CBIOS_VOID cbPHY_DP_DualModeOnOff(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex, CBIOS_U32 ClockFreq, CBIOS_BOOL bTurnOn); +CBIOS_VOID cbPHY_DP_AuxPowerOn(PCBIOS_VOID pvcbe, CBIOS_MODULE_INDEX DPModuleIndex); +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosScaler.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosScaler.c new file mode 100644 index 0000000000000..95ae6889199c9 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosScaler.c @@ -0,0 +1,620 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** Down scaler hw block interface implementation. +** +** NOTE: +** The functions in this file are hw layer internal functions, +** CAN ONLY be called by files under Hw folder. +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "CBiosScaler.h" +#include "../CBiosHwShare.h" + +static CBREGISTER_IDX HorDisplayShiftReg_INDEX[] = { + {CR_59, 0xFF}, //CR59[7:0] + {CR_5B, 0x01}, //CR5B[0] + {MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX VerDisplayShiftReg_INDEX[] = { + {CR_5A, 0xFF}, //CR59[7:0] + {CR_5B, 0xF0}, //CR5B[7:4] + {MAPMASK_EXIT}, +}; + +static WB_SCL_RATIO_TABLE DSCLTable[] = { + /* 1280x720 ----> 720x480 */ + { + WORD_CAT(1280, 720), + WORD_CAT(720, 480), + WORD_CAT(9, 16), + WORD_CAT(12, 18), + }, + + /* 1280x720 ----> 720x576 */ + { + WORD_CAT(1280, 720), + WORD_CAT(720, 576), + WORD_CAT(18, 32), + WORD_CAT(8, 10), + }, + + /* 1920x1080 ----> 720x480 */ + { + WORD_CAT(1920, 1080), + WORD_CAT(720, 480), + WORD_CAT(6, 16), + WORD_CAT(8, 18), + }, + + /* 1920x1080 ----> 720x576 */ + { + WORD_CAT(1920, 1080), + WORD_CAT(720, 576), + WORD_CAT(9, 24), + WORD_CAT(8, 15), + }, + + /* 3840x2160 ----> 720x480 */ + { + WORD_CAT(3840, 2160), + WORD_CAT(720, 480), + WORD_CAT(3, 16), + WORD_CAT(4, 18), + }, + + /* 3840x2160 ----> 720x576 */ + { + WORD_CAT(3840, 2160), + WORD_CAT(720, 576), + WORD_CAT(6, 32), + WORD_CAT(4, 15), + }, + + /* 3840x2160 ----> 1920x1080 */ + { + WORD_CAT(3840, 2160), + WORD_CAT(1920, 1080), + WORD_CAT(9, 18), + WORD_CAT(9, 16), + }, + + /* 3840x2160 ----> 1920x1200 */ + { + WORD_CAT(3840, 2160), + WORD_CAT(1920, 1200), + WORD_CAT(16, 32), + WORD_CAT(5, 9), + }, + + /* 3840x2160 ----> 1280x720 */ + { + WORD_CAT(3840, 2160), + WORD_CAT(1280, 720), + WORD_CAT(10, 30), + WORD_CAT(3, 9), + }, + + /* 4096x2160 ----> 1920x1080 */ + { + WORD_CAT(4096, 2160), + WORD_CAT(1920, 1080), + WORD_CAT(15, 32), + WORD_CAT(5, 10), + }, + + /* 4096x2160 ----> 1920x1200 */ + { + WORD_CAT(4096, 2160), + WORD_CAT(1920, 1200), + WORD_CAT(15, 32), + WORD_CAT(5, 9), + }, + + /* 4096x2160 ----> 2048x1080 */ + { + WORD_CAT(4096, 2160), + WORD_CAT(2048, 1080), + WORD_CAT(16, 32), + WORD_CAT(5, 10), + }, + + /* 4096x2160 ----> 2048x1200 */ + { + WORD_CAT(4096, 2160), + WORD_CAT(2048, 1200), + WORD_CAT(16, 32), + WORD_CAT(5, 9), + }, + + /* 4096x2160 ----> 1280x720 */ + { + WORD_CAT(4096, 2160), + WORD_CAT(1280, 720), + WORD_CAT(5, 16), + WORD_CAT(7, 21), + }, + + /* 1920x1080 ----> 1280x720 */ + { + WORD_CAT(1920, 1080), + WORD_CAT(1280, 720), + WORD_CAT(12, 18), + WORD_CAT(10, 15), + }, + +}; + +static CBIOS_U32 DSCLTableSize = sizeof(DSCLTable)/sizeof(DSCLTable[0]); + +static CBIOS_U32 REG33278INDEX[CBIOS_IGACOUNTS] = {0x33278, 0x33bf4, 0x342f4, 0x349f4}; +static CBIOS_U32 REG33290INDEX[CBIOS_IGACOUNTS] = {0x33290, 0x33c1c, 0x3431c, 0x34a1c}; +static CBIOS_U32 REG3327cINDEX[CBIOS_IGACOUNTS] = {0x3327c, 0x33bf8, 0x342f8, 0x349f8}; +static CBIOS_U32 REG33280INDEX[CBIOS_IGACOUNTS] = {0x33280, 0x33bfc, 0x342fc, 0x349fc}; +static CBIOS_U32 REG33284INDEX[CBIOS_IGACOUNTS] = {0x33284, 0x33c00, 0x34300, 0x34a00}; +static CBIOS_U32 REG33288INDEX[CBIOS_IGACOUNTS] = {0x33288, 0x33c04, 0x34304, 0x34a04}; +static CBIOS_U32 REG33880INDEX[CBIOS_IGACOUNTS] = {0x33880, 0x33c08, 0x34308, 0x34a08}; + +static CBIOS_U32 WBCSCIndex[CBIOS_IGACOUNTS] = {0x8264, 0x33bdc, 0x342dc, 0x349dc}; + +static CBIOS_VOID cbDisplayShiftOnOff(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_BOOL bOn, CBIOS_U32 IGAIndex) +{ + REG_CR5B_Pair RegCR5BValue, RegCR5BMask; + + if(bOn) //Enable Display Shift + { + RegCR5BValue.Value = 0; + RegCR5BValue.Enable_Shift_On = 1; + RegCR5BMask.Value = 0xFF; + RegCR5BMask.Enable_Shift_On = 0; + cbBiosMMIOWriteReg(pcbe,CR_5B, RegCR5BValue.Value, RegCR5BMask.Value, IGAIndex); + } + else //Disable Display Shift + { + RegCR5BValue.Value = 0; + RegCR5BValue.Enable_Shift_On = 0; + RegCR5BMask.Value = 0xFF; + RegCR5BMask.Enable_Shift_On = 0; + cbBiosMMIOWriteReg(pcbe,CR_5B, RegCR5BValue.Value, RegCR5BMask.Value, IGAIndex); + } +} + +static CBIOS_VOID cbSetDisplayShiftValue(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 IGAIndex, + CBIOS_U32 HorShiftPos, CBIOS_U32 VerShiftPos) +{ + CBIOS_U32 HorShiftValue = HorShiftPos >> 3; // character clocks + + cbMapMaskWrite(pcbe, HorShiftValue, HorDisplayShiftReg_INDEX, IGAIndex); + cbMapMaskWrite(pcbe, VerShiftPos, VerDisplayShiftReg_INDEX, IGAIndex); + +} + +CBIOS_STATUS cbPanelScalerOnOff(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + CBIOS_U32 ScalerXRes = pModeParams->ScalerPara.XRes; + CBIOS_U32 ScalerYRes = pModeParams->ScalerPara.YRes; + CBIOS_U32 IGAIndex = pModeParams->IGAIndex; + + REG_SR4F RegSR4FValue = {0}, RegSR4FMask = {0xff}; + REG_SR49 RegSR49Value = {0}, RegSR49Mask = {0xff}; + REG_SR59 RegSR59Value = {0}, RegSR59Mask = {0xff}; + REG_SR5A RegSR5AValue = {0}, RegSR5AMask = {0xff}; + REG_SR5B RegSR5BValue = {0}, RegSR5BMask = {0xff}; + + if(pModeParams->ScalerStatusToUse != ENABLE_UPSCALER && pModeParams->ScalerStatusToUse != DISABLE_SCALER) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbPanelScalerOnOff: Invalid Scaler Status\n")); + return CBIOS_ER_INVALID_PARAMETER; + } + + //set scaler on off + if(pModeParams->ScalerStatusToUse == DISABLE_SCALER) + { + RegSR4FValue.PS1_Upscaler_Enable = 0; + RegSR4FValue.PS1_Horizontal_upscaling_Enable = 0; + RegSR4FValue.PS1_Vertical_upscaling_Enable = 0; + RegSR4FValue.PS1_Upscaler_Auto_Ratio = 0; + RegSR4FMask.PS1_Upscaler_Enable = 0; + RegSR4FMask.PS1_Horizontal_upscaling_Enable = 0; + RegSR4FMask.PS1_Vertical_upscaling_Enable = 0; + RegSR4FMask.PS1_Upscaler_Auto_Ratio = 0; + + cbBiosMMIOWriteReg(pcbe, SR_4F, RegSR4FValue.Value, RegSR4FMask.Value, IGAIndex); + + return CBIOS_OK; + } + + RegSR4FValue.PS1_Upscaler_Auto_Ratio = 1; + RegSR4FValue.PS1_Upscaler_Enable = 1; + RegSR4FValue.PS1_Horizontal_upscaling_Enable = 1; + RegSR4FValue.PS1_Vertical_upscaling_Enable = 1; + RegSR4FMask.PS1_Upscaler_Auto_Ratio = 0; + RegSR4FMask.PS1_Upscaler_Enable = 0; + RegSR4FMask.PS1_Horizontal_upscaling_Enable = 0; + RegSR4FMask.PS1_Vertical_upscaling_Enable = 0; + + //scaler destination width + RegSR59Value.PS1_Upscaler_Dest_Width_7_0 = ((ScalerXRes - 1) & 0xff); + RegSR59Mask.PS1_Upscaler_Dest_Width_7_0 = 0; + RegSR5AValue.PS1_Upscaler_Dest_width = ((ScalerXRes - 1) >> 8 & 0xf); + RegSR5AMask.PS1_Upscaler_Dest_width = 0; + RegSR49Value.PS1_Scalar_Dest_Width_bit12 = ((ScalerXRes - 1) >> 12 & 0x01); + RegSR49Mask.PS1_Scalar_Dest_Width_bit12 = 0; + + //scaler destination height + RegSR5BValue.PS1_Upscaler_Dest_Height_7_0 = ((ScalerYRes - 1) & 0xff); + RegSR5BMask.PS1_Upscaler_Dest_Height_7_0 = 0; + RegSR5AValue.PS1_Upscaler_Dest_Height = ((ScalerYRes - 1) >> 8 & 0xf); + RegSR5AMask.PS1_Upscaler_Dest_Height = 0; + + cbBiosMMIOWriteReg(pcbe, SR_49, RegSR49Value.Value, RegSR49Mask.Value, IGAIndex); + cbBiosMMIOWriteReg(pcbe, SR_59, RegSR59Value.Value, RegSR59Mask.Value, IGAIndex); + cbBiosMMIOWriteReg(pcbe, SR_5A, RegSR5AValue.Value, RegSR5AMask.Value, IGAIndex); + cbBiosMMIOWriteReg(pcbe, SR_5B, RegSR5BValue.Value, RegSR5BMask.Value, IGAIndex); + cbBiosMMIOWriteReg(pcbe, SR_4F, RegSR4FValue.Value, RegSR4FMask.Value, IGAIndex); + + return CBIOS_OK; +} + +CBIOS_STATUS cbSetScaler(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + CBIOS_U32 ulBackPorchWidth = 0; + CBIOS_BOOL bUseHbackPatch = CBIOS_FALSE; + PCBIOS_TIMING_ATTRIB pTiming = &(pModeParams->TargetTiming); + + ulBackPorchWidth = pTiming->HorTotal - pTiming->HorSyncEnd; + bUseHbackPatch = ((ulBackPorchWidth > 25) && (ulBackPorchWidth < 32)) ? CBIOS_TRUE : CBIOS_FALSE; + + if(pcbe->ChipCaps.IsSupportUpScaling) + { + cbPanelScalerOnOff(pcbe, pModeParams); + } + + if(cbIsNeedCentering(pcbe, pModeParams)) + { + cbEnableCentering(pcbe, pModeParams); + } + else + { + //for the case of ulBackPorchWidth greater than 25 and less than 32, driver need enable + //displayshift in timing setting to patch display skew to left, no need disable centering in this case + if(!bUseHbackPatch) + { + cbDisableCentering(pcbe, pModeParams->IGAIndex); + } + } + + return CBIOS_OK; +} + +CBIOS_BOOL cbIsNeedCentering(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + CBIOS_U32 ScaleXRes, ScaleYRes; + CBIOS_U32 TargetXRes, TargetYRes; + + ScaleXRes = pModeParams->ScalerPara.XRes; + ScaleYRes = pModeParams->ScalerPara.YRes; + TargetXRes = pModeParams->TargetModePara.XRes; + TargetYRes = pModeParams->TargetModePara.YRes; + + if ((TargetXRes > ScaleXRes && TargetYRes >= ScaleYRes) + || (TargetXRes >= ScaleXRes && TargetYRes > ScaleYRes)) + { + return CBIOS_TRUE; + } + else + { + return CBIOS_FALSE; + } +} + +CBIOS_VOID cbEnableCentering(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + CBIOS_U32 HorShiftPos = 0; + CBIOS_U32 VerShiftPos = 0; + + HorShiftPos = (pModeParams->TargetModePara.XRes - pModeParams->ScalerPara.XRes) >> 1; + VerShiftPos = (pModeParams->TargetModePara.YRes - pModeParams->ScalerPara.YRes) >> 1; + + cbSetDisplayShiftValue(pcbe, pModeParams->IGAIndex, HorShiftPos, VerShiftPos); + cbDisplayShiftOnOff(pcbe, CBIOS_TRUE, pModeParams->IGAIndex); +} + +CBIOS_VOID cbDisableCentering(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 IGAIndex) +{ + cbDisplayShiftOnOff(pcbe, CBIOS_FALSE, IGAIndex); +} + +static PWB_SCL_RATIO_TABLE cbGetDownScalerRatio(CBIOS_U32 Src, CBIOS_U32 Dst) +{ + CBIOS_U32 i = 0; + + for (i = 0; i < DSCLTableSize; i++) + { + if (DSCLTable[i].SrcSize == Src && DSCLTable[i].DstSize == Dst) + { + return &DSCLTable[i]; + } + } + + return CBIOS_NULL; +} + +static CBIOS_BOOL cbEnableWBDownscaler(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_WB_PARA pWBPara) +{ + PWB_SCL_RATIO_TABLE pRatio = CBIOS_NULL; + REG_MM33290_Arise MM33290Value = {0}; + REG_MM3327C_Arise MM3327CValue = {0}; + REG_MM33280_Arise MM33280Value = {0}; + REG_MM33284_Arise MM33284Value = {0}; + REG_MM33288_Arise MM33288Value = {0}; + REG_MM33880_Arise MM33880Value = {0}; + CBIOS_U32 Stride = 0; + CBIOS_U32 IGAIndex = pWBPara->IGAIndex; + + /* get proper ratio in the table */ + pRatio = cbGetDownScalerRatio(pWBPara->SrcSize, pWBPara->DSCL.DstSize); + if (!pRatio) + { + pWBPara->bNotSupport = CBIOS_TRUE; + return CBIOS_FALSE; + } + + /* 1. address */ + MM33290Value.WriteBackBaseAddress = (CBIOS_U32)(pWBPara->DstBaseAddr >> 6); + + /* 2. ratio */ + MM3327CValue.DOWNSCALING_EN = 1; + //horizontal + MM3327CValue.HOR_INC = LOW_WORD(pRatio->HRatio) & 0xf; + MM3327CValue.REG_HOR_INC = (LOW_WORD(pRatio->HRatio) >> 4) & 0x01; + MM3327CValue.HOR_MODULAR = HIGH_WORD(pRatio->HRatio) & 0x1f; + MM33280Value.REG_HOR_MODULAR_5 = (HIGH_WORD(pRatio->HRatio) >> 5) & 0x01; + //vertical + MM3327CValue.VER_INC = LOW_WORD(pRatio->VRatio) & 0xf; + MM3327CValue.VER_MODULAR = HIGH_WORD(pRatio->VRatio) & 0xf; + MM3327CValue.REG_VER_MODULAR = (HIGH_WORD(pRatio->VRatio) >> 4) & 0x01; + + MM3327CValue.SCALING_RCP = (1 << 18) / ( HIGH_WORD(pRatio->HRatio) * HIGH_WORD(pRatio->VRatio) ); + + /* 3. format */ + MM3327CValue.DST_FORMAT = 1; + MM33280Value.REG_DAT_FORMAT = 0; + + /* 4. clip */ + MM33280Value.clip_left_10to0 = 0; + MM33280Value.clip_left_11 = 0; + MM33280Value.clip_right_11to0 = (LOW_WORD(pWBPara->SrcSize) - 1) & 0xfff; + MM33280Value.clip_right_12 = ( (LOW_WORD(pWBPara->SrcSize) - 1) >> 12 ) & 0x01; + + /* 5. p2p or p2i + * P2P double buffer : REG_SCL_MODE_0 = 0, stride = stride*2 + * P2P single buffer : not support + * P2I single buffer : REG_SCL_MODE_0 = 0, stride = stride*2 + * P2I double buffer : not support + */ + //512 bits aligned + Stride = (LOW_WORD(pWBPara->DSCL.DstSize) * 4 + 63) & ~63; + if (CBIOS_WB_P2P == pWBPara->DSCL.Mode) + { + MM33280Value.DOUBLE_FB = 1; + MM33280Value.REG_SCL_MODE_0 = 0; + Stride = Stride * 2 / 64; + + MM33288Value.OFFSET = ( ( LOW_WORD(pWBPara->DSCL.DstSize) * HIGH_WORD(pWBPara->DSCL.DstSize) * 4 + 63) & ~63 ) / 64; + } + else if (CBIOS_WB_P2I == pWBPara->DSCL.Mode) + { + if (pWBPara->DSCL.bDoubleBuffer) + { + pWBPara->bNotSupport = CBIOS_TRUE; + return CBIOS_FALSE; + } + else + { + MM33280Value.DOUBLE_FB = 0; + MM33280Value.REG_SCL_MODE_0 = 0; + Stride = Stride * 2 / 64; + } + } + else + { + pWBPara->bNotSupport = CBIOS_TRUE; + return CBIOS_FALSE; + } + + MM33288Value.STRIDE = Stride & 0x1ff; + MM33880Value.REG_STRIDE_11_9 = (Stride >> 9) & 0x7; + + /* 6. reset */ + MM33280Value.FIFO_RST_EN = 1; + MM33280Value.SCALING_SW_RESET = 1; + + /* 7. enable */ + MM33280Value.REG_SCL_MODE_1 = 1; + + cbMMIOWriteReg32(pcbe, REG33290INDEX[IGAIndex], MM33290Value.Value, 0); + cbMMIOWriteReg32(pcbe, REG3327cINDEX[IGAIndex], MM3327CValue.Value, 0); + cbMMIOWriteReg32(pcbe, REG33280INDEX[IGAIndex], MM33280Value.Value, 0); + cbMMIOWriteReg32(pcbe, REG33284INDEX[IGAIndex], MM33284Value.Value, 0); + cbMMIOWriteReg32(pcbe, REG33288INDEX[IGAIndex], MM33288Value.Value, 0); + cbMMIOWriteReg32(pcbe, REG33880INDEX[IGAIndex], MM33880Value.Value, 0); + + return CBIOS_TRUE; +} + +static CBIOS_BOOL cbBypassWBDownscaler(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_WB_PARA pWBPara) +{ + REG_MM33290_Arise MM33290Value = {0}, MM33290RegMask = {0xFFFFFFFF}; + REG_MM3327C_Arise MM3327CValue = {0}, MM3327CRegMask = {0xFFFFFFFF}; + REG_MM33280_Arise MM33280Value = {0}, MM33280RegMask = {0xFFFFFFFF}; + REG_MM33284_Arise MM33284Value = {0}, MM33284RegMask = {0xFFFFFFFF}; + REG_MM33288_Arise MM33288Value = {0}, MM33288RegMask = {0xFFFFFFFF}; + REG_MM33880_Arise MM33880Value = {0}, MM33880RegMask = {0xFFFFFFFF}; + + CBIOS_U32 Stride = 0; + CBIOS_U32 IGAIndex = pWBPara->IGAIndex; + + /* 1. address */ + if (pWBPara->bSetAddrOP) + { + MM33290Value.WriteBackBaseAddress = (CBIOS_U32)(pWBPara->DstBaseAddr >> 6); + + MM33290RegMask.WriteBackBaseAddress = 0; + } + + + if (pWBPara->bSetModeOP && pWBPara->bEnableOP) + { + /* 2. diable downscaler */ + MM3327CValue.DOWNSCALING_EN = 0; + MM3327CRegMask.DOWNSCALING_EN = 0; + + /* 3. format */ + MM3327CValue.DST_FORMAT = 1; + MM3327CRegMask.DST_FORMAT = 0; + + MM33280Value.REG_DAT_FORMAT = 0; + MM33280RegMask.REG_DAT_FORMAT = 0; + + /* 4. clip */ + MM33280Value.clip_left_10to0 = 0; + MM33280Value.clip_left_11 = 0; + MM33280Value.clip_right_11to0 = (LOW_WORD(pWBPara->SrcSize) - 1) & 0xfff; + MM33280Value.clip_right_12 = ( (LOW_WORD(pWBPara->SrcSize) - 1) >> 12 ) & 0x01; + + MM33280RegMask.clip_left_10to0 = 0; + MM33280RegMask.clip_left_11 = 0; + MM33280RegMask.clip_right_11to0 = 0; + MM33280RegMask.clip_right_12 = 0; + + /* 5. strid + * 512 bits aligned + */ + Stride = (LOW_WORD(pWBPara->SrcSize) * 4 + 63) & ~63; + Stride = Stride / 64; + + MM33288Value.STRIDE = Stride & 0x1ff; + MM33288RegMask.STRIDE = 0; + + MM33880Value.REG_STRIDE_11_9 = (Stride >> 9) & 0x7; + MM33280Value.DOUBLE_FB = 0; + MM33280Value.REG_SCL_MODE_0 = 1; + + MM33880RegMask.REG_STRIDE_11_9 = 0; + MM33280RegMask.DOUBLE_FB = 0; + MM33280RegMask.REG_SCL_MODE_0 = 0; + + /* 6. reset */ + MM33280Value.FIFO_RST_EN = 1; + MM33280Value.SCALING_SW_RESET = 1; + + MM33280RegMask.FIFO_RST_EN = 0; + MM33280RegMask.SCALING_SW_RESET = 0; + + /* 7. enable */ + MM33280Value.REG_SCL_MODE_1 = 1; + MM33280RegMask.REG_SCL_MODE_1 = 0; + + } + + + if (pWBPara->bSetAddrOP) + { + cbMMIOWriteReg32(pcbe, REG33290INDEX[IGAIndex], MM33290Value.Value, MM33290RegMask.Value); + } + + if (pWBPara->bSetModeOP && pWBPara->bEnableOP) + { + cbMMIOWriteReg32(pcbe, REG3327cINDEX[IGAIndex], MM3327CValue.Value, MM3327CRegMask.Value); + cbMMIOWriteReg32(pcbe, REG33280INDEX[IGAIndex], MM33280Value.Value, MM33280RegMask.Value); + cbMMIOWriteReg32(pcbe, REG33284INDEX[IGAIndex], MM33284Value.Value, MM33284RegMask.Value); + cbMMIOWriteReg32(pcbe, REG33288INDEX[IGAIndex], MM33288Value.Value, MM33288RegMask.Value); + cbMMIOWriteReg32(pcbe, REG33880INDEX[IGAIndex], MM33880Value.Value, MM33880RegMask.Value); + } + + return CBIOS_TRUE; +} + +CBIOS_STATUS cbSetWriteback(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_WB_PARA pWBPara) +{ + CBIOS_U32 IGAIndex = pWBPara->IGAIndex; + REG_MM33278_Arise MM33278Value = {0}, MM33278Mask = {0xffffffff}; + REG_MM33280_Arise MM33280Value = {0}, MM33280Mask = {0xffffffff}; + REG_MM8264 MM8264Value = {0}, MM8264Mask = {0xffffffff}; + CBIOS_BOOL Ret = CBIOS_TRUE; + + if (pWBPara->bEnableOP && pWBPara->bEnable == 0) + { + MM33280Value.REG_SCL_MODE_1 = 0; + MM33280Mask.REG_SCL_MODE_1 = 0; + + MM33278Value.Value = 0; + MM33278Value.Enable_Work_Register = 1; + MM33278Mask.Value = 0xffffffff; + MM33278Mask.Enable_Work_Register = 0; + + cbMMIOWriteReg32(pcbe, REG33280INDEX[IGAIndex], MM33280Value.Value, MM33280Mask.Value); + cbMMIOWriteReg32(pcbe, REG33278INDEX[IGAIndex], MM33278Value.Value, MM33278Mask.Value); + + return CBIOS_OK; + } + + if (pWBPara->bUpdateImme) + { + MM33278Value.Vsync_Off_Flip = 1; + } + else + { + MM33278Value.Vsync_Off_Flip = 0; + } + MM33278Mask.Vsync_Off_Flip = 0; + + + /* configure down scaler */ + if (pWBPara->bByPass) + { + Ret = cbBypassWBDownscaler(pcbe, pWBPara); + } + else + { + Ret = cbEnableWBDownscaler(pcbe, pWBPara); + } + + + if (pWBPara->bSetModeOP) + { + /* CSC */ + MM8264Value.CSC_DATA_IN_FMT = CSC_FMT_RGB; + MM8264Value.CSC_DATA_OUT_FMT = pWBPara->CscOutFmt; + MM8264Mask.CSC_DATA_IN_FMT = 0; + MM8264Mask.CSC_DATA_OUT_FMT = 0; + cbMMIOWriteReg32(pcbe, WBCSCIndex[IGAIndex], MM8264Value.Value, MM8264Mask.Value); + } + + /* trigger them */ + MM33278Value.Enable_Work_Register = 1; + MM33278Mask.Value = 0xffffffff; + MM33278Mask.Enable_Work_Register = 0; + + cbMMIOWriteReg32(pcbe, REG33278INDEX[IGAIndex], MM33278Value.Value, MM33278Mask.Value); + + return (Ret == CBIOS_TRUE) ? CBIOS_OK : CBIOS_ER_INVALID_PARAMETER; +} + diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosScaler.h b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosScaler.h new file mode 100644 index 0000000000000..e565de3b19784 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosScaler.h @@ -0,0 +1,155 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** Down scaler block interface prototype and parameter definition. +** +** NOTE: +** This header file CAN ONLY be included by hw layer those files under Hw folder. +******************************************************************************/ + +#ifndef _CBIOSSCALER_H_ +#define _CBIOSSCALER_H_ + + +/* +** Scaler logic function +*/ + +typedef enum +{ + I2I_576_576 = 0, + P2I_576_576 = 1, + P2I_720_576 = 2, + P2P_720_576 = 3, + P2I_1080_576 = 4, + P2P_1080_576 = 5, + P2P_2160_576 = 6, + I2I_480_480 = 7, + P2I_480_480 = 8, + P2I_720_480 = 9, + P2P_720_480 = 10, + P2I_1080_480 = 11, + P2P_1080_480 = 12, + P2P_2160_480 = 13, + P2P_720_720 = 14, + P2P_1080_1080 = 15, + SCALER_MODE_DISABLE = 16, +}SCALER_MODE; + +typedef enum +{ + SCL_DIS = 0, + SCL_TVENCODER = 2, + SCL_BYPASS = 3, +}SCL_MODE; + +typedef enum +{ + NORMAL_EDGE = 0, + NORMAL_STRETCH = 1, + NORMAL_CLIP = 2, + HDTV_EDGE = 3, + HDTV_STRETCH = 4, + HDTV_CLIP = 5, + FORMAT_101010 = 6, //change output format of 3D bypass mode to RGB101010 +}SCALER_EFFECT; + + +typedef union _REG_MM3278 //_REG_SCALER_BASE //diu_downscaler_register_group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED :5; + CBIOS_U32 BASE_ADDR :27; + }; +}REG_MM3278; + + +typedef union _REG_MM327C //_REG_SCALER_CONTROL_0 //diu_downscaler_register_group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DOWNSCALING_EN :1; + CBIOS_U32 LEFT_RIGHT_3D :1; + CBIOS_U32 RESERVED :2; + CBIOS_U32 VER_INC :4; + CBIOS_U32 HOR_INC :4; + CBIOS_U32 VER_MODULAR :4; + CBIOS_U32 HOR_MODULAR :5; + CBIOS_U32 DST_FORMAT :1; + CBIOS_U32 SCALING_RCP :10; + }; +}REG_MM327C; + + +typedef union _REG_MM3280 //_REG_SCALER_CONTROL_1 //diu_downscaler_register_group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED :4; + CBIOS_U32 DOUBLE_FB :1; + CBIOS_U32 SCALING_SW_RESET :1; + CBIOS_U32 FIFO_RST_EN :1; + CBIOS_U32 SCALING_MODE :2; + CBIOS_U32 CLIP_LEFT :11; + CBIOS_U32 CLIP_RIGHT :12; + }; +}REG_MM3280; + + +typedef union _REG_MM3284 //_REG_SCALER_CONTROL_2 //diu_downscaler_register_group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED :20; + CBIOS_U32 HIGH_THRESHOLD :6; + CBIOS_U32 LOW_THRESHOLD :6; + }; +}REG_MM3284; + + +typedef union _REG_MM3288 //_REG_SCALER_CONTROL_3 //diu_downscaler_register_group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED :2; + CBIOS_U32 STRIDE :10; + CBIOS_U32 OFFSET :20; + }; +}REG_MM3288; + +typedef struct _WB_SCL_RATIO_TABLE +{ + CBIOS_U32 SrcSize; // X | (Y << 16) + CBIOS_U32 DstSize; + + CBIOS_U32 HRatio; // Inc | (Modular << 16) + CBIOS_U32 VRatio; +}WB_SCL_RATIO_TABLE, *PWB_SCL_RATIO_TABLE; + +CBIOS_STATUS cbSetScaler(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams); +CBIOS_BOOL cbIsNeedCentering(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams); +CBIOS_VOID cbEnableCentering(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_DISP_MODE_PARAMS pModeParams); +CBIOS_VOID cbDisableCentering(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 IGAIndex); +CBIOS_STATUS cbSetWriteback(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_WB_PARA pWBPara); + +#endif //_CBIOSSCALER_H_ diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwCallback/CBiosCallbacksHw.c b/drivers/gpu/drm/arise/cbios/Hw/HwCallback/CBiosCallbacksHw.c new file mode 100644 index 0000000000000..ee7524e37402d --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwCallback/CBiosCallbacksHw.c @@ -0,0 +1,449 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios hw dependent callback function implementation. +** +** NOTE: +** The functions in this file are hw layer internal functions, +** CAN ONLY be called by files under Hw folder. +******************************************************************************/ + +#include "CBiosCallbacksHw.h" +#include "CBiosChipShare.h" + + +extern CBIOS_CALLBACK_FUNCTIONS FnCallback; + +CBIOS_VOID cb_WriteU8(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort, CBIOS_UCHAR Value) +{ + if (FnCallback.pFnWriteUchar != CBIOS_NULL) + { + ((CALLBACK_cbWriteU8)FnCallback.pFnWriteUchar)(pAdapterContext, RegisterPort, Value); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + +} + + + +CBIOS_VOID cb_WriteU16(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort, CBIOS_U16 Value) +{ + if (FnCallback.pFnWriteUshort != CBIOS_NULL) + { + ((CALLBACK_cbWriteU16)FnCallback.pFnWriteUshort)(pAdapterContext, RegisterPort, Value); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + +} + + + +CBIOS_VOID cb_WriteU32(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort, CBIOS_U32 Value) +{ + if (FnCallback.pFnWriteUlong != CBIOS_NULL) + { + ((CALLBACK_cbWriteU32)FnCallback.pFnWriteUlong)(pAdapterContext, RegisterPort, Value); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + +} + + + +CBIOS_UCHAR cb_ReadU8(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort) +{ + + CBIOS_UCHAR ret = 0; + + if(FnCallback.pFnReadUchar != CBIOS_NULL) + { + ret = ((CALLBACK_cbReadU8)FnCallback.pFnReadUchar)(pAdapterContext, RegisterPort); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + + return ret; + +} + + + +CBIOS_U16 cb_ReadU16(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort) +{ + + CBIOS_U16 ret = 0; + + if(FnCallback.pFnReadUshort!= CBIOS_NULL) + { + ret = ((CALLBACK_cbReadU16)FnCallback.pFnReadUshort)(pAdapterContext, RegisterPort); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + + return ret; + +} + + +CBIOS_U32 cb_ReadU32(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort) +{ + CBIOS_U32 ret = 0; + + if(FnCallback.pFnReadUlong != CBIOS_NULL) + { + ret = ((CALLBACK_cbReadU32)FnCallback.pFnReadUlong)(pAdapterContext, RegisterPort); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + + return ret; + +} + + + + +/*use IO to access VGA registers under NT platforms*/ +CBIOS_UCHAR cb_ReadPortUchar(PCBIOS_UCHAR RegisterPort) +{ + CBIOS_UCHAR ret = 0; + + if(FnCallback.pFnReadPortUchar != CBIOS_NULL) + { + ret = ((CALLBACK_cbReadPortUchar)FnCallback.pFnReadPortUchar)(RegisterPort); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + + return ret; + +} + + + +CBIOS_VOID cb_WritePortUchar(PCBIOS_UCHAR RegisterPort, CBIOS_UCHAR Value) +{ + + if (FnCallback.pFnWritePortUchar != CBIOS_NULL) + { + ((CALLBACK_cbWritePortUchar)FnCallback.pFnWritePortUchar)(RegisterPort, Value); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + +} + + + +CBIOS_VOID cbWriteRegisterU32(PCBIOS_VOID pvcbe, CBIOS_REGISTER_BLOCK_TYPE RegType, CBIOS_U32 RegIndex,CBIOS_U32 Value) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + + if (FnCallback.pFnWriteRegisterU32 != CBIOS_NULL) + { + ((CALLBACK_cbWriteRegisterU32)FnCallback.pFnWriteRegisterU32)(pcbe->pAdapterContext, RegType, RegIndex,Value); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } +} + + + +CBIOS_VOID cbWriteRegisterU32WithMask(PCBIOS_VOID pvcbe, CBIOS_REGISTER_BLOCK_TYPE RegType, CBIOS_U32 RegIndex, CBIOS_U32 Value, CBIOS_U32 Mask) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + CBIOS_U32 Temp = 0; + + if ((FnCallback.pFnWriteRegisterU32 != CBIOS_NULL) && (FnCallback.pFnReadRegisterU32 != CBIOS_NULL)) + { + Temp = ((CALLBACK_cbReadRegisterU32)FnCallback.pFnReadRegisterU32)(pcbe->pAdapterContext, RegType, RegIndex) & Mask; + Value &= (~Mask); + Value |= Temp; + ((CALLBACK_cbWriteRegisterU32)FnCallback.pFnWriteRegisterU32)(pcbe->pAdapterContext, RegType, RegIndex, Value); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } +} + + + +CBIOS_U32 cbReadRegisterU32(PCBIOS_VOID pvcbe, CBIOS_REGISTER_BLOCK_TYPE RegType, CBIOS_U32 RegIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + CBIOS_U32 Temp = 0; + + if (FnCallback.pFnReadRegisterU32 != CBIOS_NULL) + { + Temp = ((CALLBACK_cbReadRegisterU32)FnCallback.pFnReadRegisterU32)(pcbe->pAdapterContext, RegType, RegIndex); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + + return Temp; +} + + +CBIOS_U32 cbReadGPIO(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex) +{ + CBIOS_U32 ret = 0; + + if(FnCallback.pFnGpioGetValue != CBIOS_NULL) + { + ret = ((CALLBACK_cbGetSysGPIO)FnCallback.pFnGpioGetValue)(GPIOIndex, (GPIOType << 8) ); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + + return ret; +} + + + +CBIOS_VOID cbWriteGPIO(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex, CBIOS_U32 Value) +{ + + if (FnCallback.pFnGpioSetValue != CBIOS_NULL) + { + ((CALLBACK_cbSetSysGPIO)FnCallback.pFnGpioSetValue)(GPIOIndex, (GPIOType << 8), Value); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback func is not defined!\n", FUNCTION_NAME)); + } + +} + + +//gpio +CBIOS_STATUS cbRequestGPIO(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex) +{ + CBIOS_STATUS Ret = CBIOS_ER_LAST; + + if (FnCallback.pFnGpioRequest != CBIOS_NULL) + { + Ret = ((CALLBACK_cbRequestSysGPIO)FnCallback.pFnGpioRequest)(GPIOIndex , (GPIOType << 8) ); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + + return Ret; +} + + +CBIOS_VOID cbFreeGPIO(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex) +{ + if (FnCallback.pFnGpioFree != CBIOS_NULL) + { + ((CALLBACK_cbFreeSysGPIO)FnCallback.pFnGpioFree)(GPIOIndex , (GPIOType << 8) ); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } +} + + + +CBIOS_STATUS cbSetGPIODirectionInput(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex) +{ + CBIOS_STATUS ret = CBIOS_ER_LAST; + + if(FnCallback.pFnGpioDirectionInput != CBIOS_NULL ) + { + ret = ((CALLBACK_cbSysGPIODirectionInput)FnCallback.pFnGpioDirectionInput)(GPIOIndex , (GPIOType << 8) ); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + + return ret ; +} + + + +CBIOS_STATUS cbSetGPIODirectionOutput(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex, CBIOS_U32 Value) +{ + CBIOS_STATUS ret = CBIOS_ER_LAST; + + if(FnCallback.pFnGpioDirectionOutput != CBIOS_NULL ) + { + ret = ((CALLBACK_cbSysGPIODirectionOutput)FnCallback.pFnGpioDirectionOutput)(GPIOIndex , (GPIOType << 8) , Value); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + + return ret ; +} + + + +//regulator +PCBIOS_VOID cbRegulatorGet(PCBIOS_VOID pvcbe, PCBIOS_CHAR id) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_VOID Regulator = CBIOS_NULL; + + if (FnCallback.pFnRegulatorGet != CBIOS_NULL) + { + Regulator = ((CALLBACK_cbRegulatorGet)FnCallback.pFnRegulatorGet)(pcbe->pAdapterContext, id); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + + return Regulator; +} + + + +CBIOS_STATUS cbRegulatorEnable(PCBIOS_VOID Regulator) +{ + CBIOS_STATUS Ret = CBIOS_ER_LAST; + + if (FnCallback.pFnRegulatorEnable != CBIOS_NULL) + { + Ret = ((CALLBACK_cbRegulatorEnable)FnCallback.pFnRegulatorEnable)(Regulator); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + + return Ret; +} + + + +CBIOS_STATUS cbRegulatorDisable(PCBIOS_VOID Regulator) +{ + CBIOS_STATUS Ret = CBIOS_ER_LAST; + + if (FnCallback.pFnRegulatorDisable != CBIOS_NULL) + { + Ret = ((CALLBACK_cbRegulatorDisable)FnCallback.pFnRegulatorDisable)(Regulator); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + + return Ret; +} + + + +CBIOS_S32 cbRegulatorIsEnabled(PCBIOS_VOID Regulator) +{ + CBIOS_S32 Ret = 0; + + if (FnCallback.pFnRegulatorIsEnabled != CBIOS_NULL) + { + Ret = ((CALLBACK_cbRegulatorIsEnabled)FnCallback.pFnRegulatorIsEnabled)(Regulator); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + + return Ret; +} + + + +CBIOS_S32 cbRegulatorGetVoltage(PCBIOS_VOID Regulator) +{ + CBIOS_S32 Ret = 0; + + if (FnCallback.pFnRegulatorGetVoltage != CBIOS_NULL) + { + Ret = ((CALLBACK_cbRegulatorGetVoltage)FnCallback.pFnRegulatorGetVoltage)(Regulator); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + + return Ret; +} + + + +CBIOS_STATUS cbRegulatorSetVoltage(PCBIOS_VOID Regulator, CBIOS_S32 min_uV,CBIOS_S32 max_uV) +{ + CBIOS_STATUS Ret = CBIOS_ER_LAST; + + if (FnCallback.pFnRegulatorSetVoltage != CBIOS_NULL) + { + Ret = ((CALLBACK_cbRegulatorSetVoltage)FnCallback.pFnRegulatorSetVoltage)(Regulator, min_uV, max_uV); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + + return Ret; +} + + + +CBIOS_VOID cbRegulatorPut(PCBIOS_VOID Regulator) +{ + if (FnCallback.pFnRegulatorPut != CBIOS_NULL) + { + ((CALLBACK_cbRegulatorPut)FnCallback.pFnRegulatorPut)(Regulator); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: callback not defined!\n",FUNCTION_NAME)); + } + +} + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwCallback/CBiosCallbacksHw.h b/drivers/gpu/drm/arise/cbios/Hw/HwCallback/CBiosCallbacksHw.h new file mode 100644 index 0000000000000..fe42c56f55964 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwCallback/CBiosCallbacksHw.h @@ -0,0 +1,115 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios hw dependent callback function prototype. +** +** NOTE: +** This header file CAN ONLY be included by hw layer those files under Hw folder. +******************************************************************************/ + +#ifndef _CBIOS_CALLBACKS_HW_H_ +#define _CBIOS_CALLBACKS_HW_H_ + +#include "../../Device/CBiosShare.h" + + +typedef enum _CBIOS_GPIO_TYPE +{ + CBIOS_GPIO_GFX = 0X00, + CBIOS_GPIO_VSOC = 0x01, + CBIOS_GPIO_VSUS = 0x02, + CBIOS_GPIO_AUD = 0x04, + CBIOS_GPIO_ISP = 0x08, +}CBIOS_GPIO_TYPE; + +/******Call Back function *********/ + +//******** general VGA reg access functions ******************** +//use MMIO to access VGA registers under NT platforms +//RegisterPort: register port address offset, based on MMIO Base address. +typedef CBIOS_UCHAR (*CALLBACK_cbReadU8)(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort); +typedef CBIOS_U16 (*CALLBACK_cbReadU16)(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort); +typedef CBIOS_U32 (*CALLBACK_cbReadU32)(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort); +typedef CBIOS_VOID (*CALLBACK_cbWriteU8)(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort, CBIOS_UCHAR Value); +typedef CBIOS_VOID (*CALLBACK_cbWriteU16)(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort, CBIOS_U16 Value); +typedef CBIOS_VOID (*CALLBACK_cbWriteU32)(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort, CBIOS_U32 Value); +////////////////////////////////////////////////////////////////////////////// +//use MMIO to access VGA registers under NT platforms +//IN RegisterPort: register port address +typedef CBIOS_U32 (*CALLBACK_cbReadBufferU32)(PCBIOS_U32 RegisterPort); +typedef CBIOS_VOID (*CALLBACK_cbWriteBufferU32)(PCBIOS_U32 RegisterPort, CBIOS_U32 Value); + +/*use IO to access VGA registers under NT platforms*/ +typedef CBIOS_UCHAR (*CALLBACK_cbReadPortUchar)(PCBIOS_UCHAR RegisterPort); +typedef CBIOS_VOID (*CALLBACK_cbWritePortUchar)(PCBIOS_UCHAR RegisterPort, CBIOS_UCHAR Value); + +typedef CBIOS_VOID (*CALLBACK_cbWriteRegisterU32)(PCBIOS_VOID pAdapterContext, CBIOS_REGISTER_BLOCK_TYPE RegType, CBIOS_U32 RegIndex, CBIOS_U32 Value); +typedef CBIOS_U32 (*CALLBACK_cbReadRegisterU32)(PCBIOS_VOID pAdapterContext, CBIOS_REGISTER_BLOCK_TYPE RegType, CBIOS_U32 RegIndex); +typedef CBIOS_VOID (*CALLBACK_cbDbgPrintToFile)(CBIOS_U32 DebugPrintLevel, PCBIOS_CHAR DebugMessage, PCBIOS_VOID pBuffer, CBIOS_U32 Size); +//gpio +typedef CBIOS_U32 (*CALLBACK_cbGetSysGPIO)(CBIOS_U32 gpio, CBIOS_U32 GpioType); +typedef CBIOS_VOID (*CALLBACK_cbSetSysGPIO)(CBIOS_U32 gpio, CBIOS_U32 GpioType,CBIOS_S32 value); +typedef CBIOS_U32 (*CALLBACK_cbRequestSysGPIO)(CBIOS_U32 gpio, CBIOS_U32 GpioType); +typedef CBIOS_VOID (*CALLBACK_cbFreeSysGPIO)(CBIOS_U32 gpio, CBIOS_U32 GpioType); +typedef CBIOS_U32 (*CALLBACK_cbSysGPIODirectionInput)(CBIOS_U32 gpio, CBIOS_U32 GpioType); +typedef CBIOS_U32 (*CALLBACK_cbSysGPIODirectionOutput)(CBIOS_U32 gpio, CBIOS_U32 GpioType,CBIOS_S32 value); + +typedef CBIOS_BOOL (*CALLBACK_cbGetPlatformConfigU32)(PCBIOS_VOID pAdapterContext, const CBIOS_U8 *pName, CBIOS_U32* pBuffer, CBIOS_U32 Length); +//regulator +typedef PCBIOS_VOID (*CALLBACK_cbRegulatorGet)(PCBIOS_VOID pAdapterContext, PCBIOS_CHAR id); +typedef CBIOS_S32 (*CALLBACK_cbRegulatorEnable)(PCBIOS_VOID Regulator); +typedef CBIOS_S32 (*CALLBACK_cbRegulatorDisable)(PCBIOS_VOID Regulator); +typedef CBIOS_S32 (*CALLBACK_cbRegulatorIsEnabled)(PCBIOS_VOID Regulator); +typedef CBIOS_S32 (*CALLBACK_cbRegulatorGetVoltage)(PCBIOS_VOID Regulator); +typedef CBIOS_S32 (*CALLBACK_cbRegulatorSetVoltage)(PCBIOS_VOID Regulator, CBIOS_S32 min_uV,CBIOS_S32 max_uV); +typedef CBIOS_VOID (*CALLBACK_cbRegulatorPut)(PCBIOS_VOID Regulator); + + +CBIOS_UCHAR cb_ReadU8(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort); +CBIOS_U16 cb_cbReadU16(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort); +CBIOS_U32 cb_ReadU32(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort); + +CBIOS_VOID cb_WriteU8(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort, CBIOS_UCHAR Value); +CBIOS_VOID cb_WriteU16(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort, CBIOS_U16 Value); +CBIOS_VOID cb_WriteU32(PCBIOS_VOID pAdapterContext, CBIOS_U32 RegisterPort, CBIOS_U32 Value); + +/*use IO to access VGA registers under NT platforms*/ +CBIOS_UCHAR cb_ReadPortUchar(PCBIOS_UCHAR RegisterPort); +CBIOS_VOID cb_WritePortUchar(PCBIOS_UCHAR RegisterPort, CBIOS_UCHAR Value); + +CBIOS_VOID cbWriteRegisterU32(PCBIOS_VOID pvcbe, CBIOS_REGISTER_BLOCK_TYPE RegType, CBIOS_U32 RegIndex, CBIOS_U32 Value ); +CBIOS_VOID cbWriteRegisterU32WithMask(PCBIOS_VOID pvcbe, CBIOS_REGISTER_BLOCK_TYPE RegType, CBIOS_U32 RegIndex, CBIOS_U32 Value, CBIOS_U32 Mask); +CBIOS_U32 cbReadRegisterU32(PCBIOS_VOID pvcbe, CBIOS_REGISTER_BLOCK_TYPE RegType, CBIOS_U32 RegIndex); + +//gpio +CBIOS_STATUS cbRequestGPIO(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex); +CBIOS_VOID cbFreeGPIO(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex); +CBIOS_STATUS cbSetGPIODirectionOutput(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex, CBIOS_U32 Value); +CBIOS_STATUS cbSetGPIODirectionInput(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex); +CBIOS_U32 cbReadGPIO(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex); +CBIOS_VOID cbWriteGPIO(PCBIOS_VOID pvcbe, CBIOS_GPIO_TYPE GPIOType, CBIOS_U32 GPIOIndex, CBIOS_U32 Value); + +//regulator +PCBIOS_VOID cbRegulatorGet(PCBIOS_VOID pvcbe, PCBIOS_CHAR id); +CBIOS_STATUS cbRegulatorEnable(PCBIOS_VOID Regulator); +CBIOS_STATUS cbRegulatorDisable(PCBIOS_VOID Regulator); +CBIOS_S32 cbRegulatorIsEnabled(PCBIOS_VOID Regulator); +CBIOS_S32 cbRegulatorGetVoltage(PCBIOS_VOID Regulator); +CBIOS_STATUS cbRegulatorSetVoltage(PCBIOS_VOID Regulator, CBIOS_S32 min_uV,CBIOS_S32 max_uV); +CBIOS_VOID cbRegulatorPut(PCBIOS_VOID Regulator); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwInit/CBiosInitHw.c b/drivers/gpu/drm/arise/cbios/Hw/HwInit/CBiosInitHw.c new file mode 100644 index 0000000000000..22e9fa86ad478 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwInit/CBiosInitHw.c @@ -0,0 +1,1416 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios hw initialization functions, mainly POST and chip initialize. +** +** NOTE: +** The functions in this file are hw layer internal functions, +** CAN ONLY be called by files under Hw folder. +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" +#include "../HwBlock/CBiosDIU_HDAC.h" + +#define QT_DDR3_2CH CBIOS_FALSE +#define QT_DDR3_1CH CBIOS_FALSE +#define FPGA_DDR2 CBIOS_FALSE +#define QT_DDR4_2CH CBIOS_TRUE + +#define CBIOS_CLOCK_MAX 1200 +#define CBIOS_CLOCK_MIN 200 +#define CBIOS_ECLK_DEFAULT 350 +#define CBIOS_ICLK_DEFAULT 700 +#define CBIOS_VCLK_DEFAULT 350 + +#define E3K_PMPTAG_OFFSET 0x70020 +#define E3K_PMPVER_OFFSET 0x70024 +#define E3K_PMPTAG_SIZE 4 +#define E3K_PMPVER_SIZE 64 + + + +#if QT_DDR3_2CH +static MMIOREGISTER Mclk_300_Timing_Desktop[]={ + {0x0000850c, 0x00000002, 32}, + {0x00005040, 0x00000000, 32}, + {0x00005044, 0xfcfcfcfc, 32}, + {0x00005100, 0xffffffff, 32}, + {0x00005104, 0xffffffff, 32}, + {0x00005108, 0x00000000, 32}, + {0x0000510c, 0x00000000, 32}, + + {0x00005148, 0xc2ff3800, 32}, + + {0x00005158, 0x67380503, 32}, + {0x0000515c, 0x1f83177f, 32}, + {0x00005160, 0x88008000, 32}, + {0x00005164, 0x00000000, 32}, + {0x00005168, 0x5d004e4e, 32}, + {0x0000516c, 0x48118010, 32}, + + {0x00005250, 0x00ff0000, 32}, + {0x0000516c, 0x48118030, 32}, + {0x00005118, 0xba98ba98, 32}, + + {0x0000511c, 0xb4, 8}, + {0x0000511d, 0x5a, 8}, + {0x0000511e, 0xb0, 8}, + {0x00005120, 0x44, 8}, + {0x00005121, 0x82, 8}, + + {0x00005126, 0x90, 8}, + {0x0000512c, 0x01, 8}, + {0x0000512d, 0x80, 8}, + {0x0000512f, 0x00, 8}, + + {0x00005138, 0x00000000, 32}, + + {0x0000513d, 0x00, 8}, + {0x0000513e, 0x33, 8}, + {0x0000513f, 0xa6, 8}, + {0x00005140, 0x26108804, 32}, + {0x00005145, 0x08, 8}, + + {0x00005110, 0x04040404, 32}, + {0x00005114, 0x44444444, 32}, + {0x00005148, 0xc2ff3800, 32}, + + {0x0000515c, 0x1f83177f, 32}, + + {0x00005161, 0x80, 8}, + {0x00005164, 0x00, 8}, + {0x00005165, 0x00, 8}, + + {0x0000516a, 0x00, 8}, + + {0x00005170, 0x40, 8}, + {0x00005171, 0x00, 8}, + {0x00005172, 0x15, 8}, + + {0x00005176, 0x12, 8}, + {0x00005177, 0x40, 8}, + + {0x00005181, 0x44, 8}, + {0x00005191, 0x00, 8}, + {0x00005203, 0x02, 8}, + + {0x00005390, 0x90909090, 32}, + {0x00005394, 0x90909090, 32}, + {0x00005398, 0x90909090, 32}, + {0x0000539c, 0x90909090, 32}, + {0x000053a0, 0x90909090, 32}, + {0x000053a4, 0x90909090, 32}, + {0x000053a8, 0x90909090, 32}, + {0x000053ac, 0x90909090, 32}, + {0x000053b0, 0x90909090, 32}, + {0x000053b4, 0x90909090, 32}, + {0x000053b8, 0x90909090, 32}, + {0x000053bc, 0x90909090, 32}, + {0x000053c0, 0x90909090, 32}, + {0x000053c4, 0x90909090, 32}, + {0x000053c8, 0x90909090, 32}, + {0x000053cc, 0x90909090, 32}, + {0x000053d0, 0x90909090, 32}, + {0x000053d4, 0x90909090, 32}, + + + {0x00005a00, 0x48484848, 32}, + {0x00005a04, 0x48484848, 32}, + {0x00005a08, 0x48484848, 32}, + {0x00005a0c, 0x48484848, 32}, + {0x00005a10, 0x00004848, 32}, + {0x00005a24, 0x6a6a6a6a, 32}, + {0x00005a28, 0x6a6a6a6a, 32}, + {0x00005a2c, 0x6a6a6a6a, 32}, + {0x00005a30, 0x6a6a6a6a, 32}, + {0x00005a34, 0x6c6c6a6a, 32}, + {0x00005a38, 0x6c6c6c6c, 32}, + {0x00005a3c, 0x6c6c6c6c, 32}, + {0x00005a40, 0x6c6c6c6c, 32}, + {0x00005a44, 0x6c6c6c6c, 32}, + {0x00005a48, 0x48484848, 32}, + {0x00005a4c, 0x48484848, 32}, + {0x00005a50, 0x48484848, 32}, + {0x00005a54, 0x48484848, 32}, + {0x00005a58, 0x00004848, 32}, + {0x00005a6c, 0x00000000, 32}, + {0x00005a70, 0x00000000, 32}, + {0x00005a74, 0x00000000, 32}, + {0x00005a78, 0x00000000, 32}, + {0x00005a7c, 0x00000000, 32}, + {0x00005a80, 0x00000000, 32}, + {0x00005a84, 0x00000000, 32}, + {0x00005a88, 0x00000000, 32}, + {0x00005a8c, 0x00000000, 32}, + {0x00005d5c, 0x2e2e0000, 32}, + {0x00005d60, 0x00000000, 32}, + {0x00005e0c, 0x00626200, 32}, + {0x00005e18, 0x04000000, 32}, + {0x00005e1c, 0x04040404, 32}, + {0x00005e20, 0x04040404, 32}, + {0x00005e24, 0x04040404, 32}, + {0x00005e28, 0x04040404, 32}, + {0x00005e2c, 0x04040404, 32}, + {0x00005e30, 0x04040404, 32}, + {0x00005e34, 0x04040404, 32}, + {0x00005e38, 0x04040404, 32}, + {0x00005e3c, 0x00040404, 32}, + {0x00005300, 0x01010101, 32}, + {0x00005304, 0x01010101, 32}, + {0x00005308, 0x01010101, 32}, + {0x0000530c, 0x01010101, 32}, + {0x00005310, 0x01010101, 32}, + {0x00005314, 0x01010101, 32}, + {0x00005318, 0x01010101, 32}, + {0x0000531c, 0x01010101, 32}, + {0x00005320, 0x01010101, 32}, + {0x00005324, 0x01010101, 32}, + {0x00005328, 0x01010101, 32}, + {0x0000532c, 0x01010101, 32}, + {0x00005330, 0x01010101, 32}, + {0x00005334, 0x01010101, 32}, + {0x00005338, 0x01010101, 32}, + {0x0000533c, 0x01010101, 32}, + {0x00005340, 0x01010101, 32}, + {0x00005344, 0x01010101, 32}, + {0x00005348, 0x01010101, 32}, + {0x0000534c, 0x01010101, 32}, + {0x00005350, 0x01010101, 32}, + {0x00005354, 0x01010101, 32}, + {0x00005358, 0x01010101, 32}, + {0x0000535c, 0x01010101, 32}, + {0x00005360, 0x01010101, 32}, + {0x00005364, 0x01010101, 32}, + {0x00005368, 0x01010101, 32}, + {0x0000536c, 0x01010101, 32}, + {0x00005370, 0x01010101, 32}, + {0x00005374, 0x01010101, 32}, + {0x00005378, 0x01010101, 32}, + {0x0000537c, 0x01010101, 32}, + {0x00005380, 0x01010101, 32}, + {0x00005384, 0x01010101, 32}, + {0x00005388, 0x01010101, 32}, + {0x0000538c, 0x01010101, 32}, + {0x000053d8, 0x55555555, 32}, + {0x000053dc, 0x55555550, 32}, + {0x000053e0, 0x55555055, 32}, + {0x000053e4, 0x55505555, 32}, + {0x000053e8, 0x50555555, 32}, + {0x000053ec, 0x55555555, 32}, + {0x000053f0, 0x55555550, 32}, + {0x000053f4, 0x55555055, 32}, + {0x000053f8, 0x55505555, 32}, + {0x000053fc, 0x50555555, 32}, + {0x0000591d, 0x0c, 8}, + + {0x0000508e, 0x01, 8}, + {0x0000508e, 0x00, 8}, + {0x0000857c, 0x80000000, 32}, + {0x00005017, 0x80, 8}, + {0x0000500b, 0x00, 8}, + {0x00008af2, 0x01, 8}, + {0x00008aa0, 0x10, 8} +}; +#elif QT_DDR4_2CH +static MMIOREGISTER Mclk_300_Timing_Desktop[] = { + { 0x0000850c, 0x00000002, 32 }, + { 0x00005040, 0x00000000, 32 }, + { 0x00005044, 0x00000000, 32 }, + { 0x00005100, 0xffff1008, 32 }, + { 0x00005104, 0xffff1008, 32 }, + { 0x00005108, 0xffff0800, 32 }, + { 0x0000510c, 0xffff0800, 32 }, + + { 0x00005148, 0xc2ff3800, 32 }, + + { 0x00005158, 0x27380200, 32 }, + { 0x0000515c, 0x32818069, 32 }, + { 0x00005160, 0x88004040, 32 }, + { 0x00005164, 0x00006024, 32 }, + { 0x00005168, 0x5d184e4e, 32 }, + { 0x0000516c, 0x08104010, 32 }, + + { 0x00005250, 0x00ff0000, 32 }, + { 0x0000516c, 0x08104030, 32 }, + { 0x0000516c, 0x48114030, 32 }, + { 0x00005118, 0xba98ba98, 32 }, + + { 0x00005acc, 0x00010000, 32 }, + { 0x00005110, 0x04040404, 32 }, + { 0x00005114, 0x44444444, 32 }, + + { 0x0000511c, 0x00b06cd8, 32 }, + + { 0x00005120, 0x00008122, 32 }, + + { 0x00005124, 0x019007c1, 32 }, + + { 0x0000512c, 0x01, 8 }, + { 0x0000512d, 0x80, 8 }, + { 0x0000512f, 0x00, 8 }, + + { 0x00005138, 0x00000000, 32 }, + + { 0x0000513d, 0x00, 8 }, + { 0x0000513e, 0x33, 8 }, + { 0x0000513f, 0xa6, 8 }, + { 0x00005140, 0x24908804, 32 }, + { 0x00005145, 0x08, 8 }, + + { 0x00005148, 0xc2ff3800, 32 }, + + { 0x0000515c, 0x32828069, 32 }, + + { 0x00005161, 0x40, 8 }, + { 0x00005164, 0x24, 8 }, + { 0x00005165, 0x60, 8 }, + + { 0x0000516a, 0x18, 8 }, + + { 0x00005171, 0x00, 8 }, + { 0x00005172, 0x05, 8 }, + + { 0x00005176, 0x12, 8 }, + { 0x00005177, 0x40, 8 }, + + { 0x00005181, 0x44, 8 }, + { 0x00005191, 0x00, 8 }, + { 0x00005203, 0x02, 8 }, + + { 0x00005390, 0x6c6c6c6c, 32 }, + { 0x00005394, 0x6c6c6c6c, 32 }, + { 0x00005398, 0x6c6c6c6c, 32 }, + { 0x0000539c, 0x6c6c6c6c, 32 }, + { 0x000053a0, 0x6c6c6c6c, 32 }, + { 0x000053a4, 0x6c6c6c6c, 32 }, + { 0x000053a8, 0x6c6c6c6c, 32 }, + { 0x000053ac, 0x6c6c6c6c, 32 }, + { 0x000053b0, 0x6c6c6c6c, 32 }, + { 0x000053b4, 0x6c6c6c6c, 32 }, + { 0x000053b8, 0x6c6c6c6c, 32 }, + { 0x000053bc, 0x6c6c6c6c, 32 }, + { 0x000053c0, 0x6c6c6c6c, 32 }, + { 0x000053c4, 0x6c6c6c6c, 32 }, + { 0x000053c8, 0x6c6c6c6c, 32 }, + { 0x000053cc, 0x6c6c6c6c, 32 }, + { 0x000053d0, 0x6c6c6c6c, 32 }, + { 0x000053d4, 0x6c6c6c6c, 32 }, + + + { 0x00005a00, 0x48484848, 32 }, + { 0x00005a04, 0x48484848, 32 }, + { 0x00005a08, 0x48484848, 32 }, + { 0x00005a0c, 0x48484848, 32 }, + + { 0x00005a10, 0x00004848, 32 }, + { 0x00005a14, 0x00000000, 32 }, + { 0x00005a18, 0x00000000, 32 }, + { 0x00005a1c, 0x00000000, 32 }, + { 0x00005a20, 0x00000000, 32 }, + + { 0x00005a24, 0x6a6a6a6a, 32 }, + { 0x00005a28, 0x6a6a6a6a, 32 }, + { 0x00005a2c, 0x6a6a6a6a, 32 }, + { 0x00005a30, 0x6a6a6a6a, 32 }, + { 0x00005a34, 0x6c6c6a6a, 32 }, + { 0x00005a38, 0x6c6c6c6c, 32 }, + { 0x00005a3c, 0x6c6c6c6c, 32 }, + { 0x00005a40, 0x6c6c6c6c, 32 }, + { 0x00005a44, 0x6c6c6c6c, 32 }, + { 0x00005a48, 0x48484848, 32 }, + { 0x00005a4c, 0x48484848, 32 }, + { 0x00005a50, 0x48484848, 32 }, + { 0x00005a54, 0x48484848, 32 }, + + { 0x00005a58, 0x00004848, 32 }, + { 0x00005a6c, 0x00000000, 32 }, + { 0x00005a70, 0x00000000, 32 }, + { 0x00005a74, 0x00000000, 32 }, + { 0x00005a78, 0x00000000, 32 }, + { 0x00005a7c, 0x00000000, 32 }, + { 0x00005a80, 0x00000000, 32 }, + { 0x00005a84, 0x00000000, 32 }, + { 0x00005a88, 0x00000000, 32 }, + { 0x00005a8c, 0x00000000, 32 }, + + { 0x00005d5c, 0x2e2e0000, 32 }, + { 0x00005d60, 0x00000000, 32 }, + { 0x00005e0c, 0x00626200, 32 }, + { 0x00005e18, 0x04000000, 32 }, + { 0x00005e1c, 0x04040404, 32 }, + { 0x00005e20, 0x04040404, 32 }, + { 0x00005e24, 0x04040404, 32 }, + { 0x00005e28, 0x04040404, 32 }, + { 0x00005e2c, 0x04040404, 32 }, + { 0x00005e30, 0x04040404, 32 }, + { 0x00005e34, 0x04040404, 32 }, + { 0x00005e38, 0x04040404, 32 }, + { 0x00005e3c, 0x00040404, 32 }, + + { 0x00005300, 0x00000000, 32 }, + { 0x00005304, 0x00000000, 32 }, + { 0x00005308, 0x00000000, 32 }, + { 0x0000530c, 0x00000000, 32 }, + { 0x00005310, 0x00000000, 32 }, + { 0x00005314, 0x00000000, 32 }, + { 0x00005318, 0x00000000, 32 }, + { 0x0000531c, 0x00000000, 32 }, + { 0x00005320, 0x00000000, 32 }, + { 0x00005324, 0x00000000, 32 }, + { 0x00005328, 0x00000000, 32 }, + { 0x0000532c, 0x00000000, 32 }, + { 0x00005330, 0x00000000, 32 }, + { 0x00005334, 0x00000000, 32 }, + { 0x00005338, 0x00000000, 32 }, + { 0x0000533c, 0x00000000, 32 }, + { 0x00005340, 0x00000000, 32 }, + { 0x00005344, 0x00000000, 32 }, + { 0x00005348, 0x00000000, 32 }, + { 0x0000534c, 0x00000000, 32 }, + { 0x00005350, 0x00000000, 32 }, + { 0x00005354, 0x00000000, 32 }, + { 0x00005358, 0x00000000, 32 }, + { 0x0000535c, 0x00000000, 32 }, + { 0x00005360, 0x00000000, 32 }, + { 0x00005364, 0x00000000, 32 }, + { 0x00005368, 0x00000000, 32 }, + { 0x0000536c, 0x00000000, 32 }, + { 0x00005370, 0x00000000, 32 }, + { 0x00005374, 0x00000000, 32 }, + { 0x00005378, 0x00000000, 32 }, + { 0x0000537c, 0x00000000, 32 }, + { 0x00005380, 0x00000000, 32 }, + { 0x00005384, 0x00000000, 32 }, + { 0x00005388, 0x00000000, 32 }, + { 0x0000538c, 0x00000000, 32 }, + + { 0x000053d8, 0x00000000, 32 }, + { 0x000053dc, 0x00000000, 32 }, + { 0x000053e0, 0x00000000, 32 }, + { 0x000053e4, 0x00000000, 32 }, + { 0x000053e8, 0x00000000, 32 }, + { 0x000053ec, 0x00000000, 32 }, + { 0x000053f0, 0x00000000, 32 }, + { 0x000053f4, 0x00000000, 32 }, + { 0x000053f8, 0x00000000, 32 }, + { 0x000053fc, 0x00000000, 32 }, + { 0x0000513c, 0x02, 8 }, + { 0x0000513c, 0x06, 8 }, + { 0x0000591d, 0x0c, 8 }, + + { 0x0000508c, 0x01, 8 }, + { 0x0000508c, 0x00, 8 }, + { 0x0000857c, 0x80000000, 32 }, + { 0x00005014, 0x80, 8 }, + { 0x0000500b, 0x00, 8 }, + { 0x00008af2, 0x01, 8 }, + { 0x00008aa0, 0x10, 8 } +}; +#elif QT_DDR3_1CH +static MMIOREGISTER Mclk_300_Timing_Desktop[]={ + {0x0000850c, 0x00000002, 32}, + {0x00005040, 0x00000000, 32}, + {0x00005044, 0x00000000, 32}, + {0x00005100, 0x100c0804, 32}, + {0x00005104, 0x201c1814, 32}, + {0x00005108, 0x0c080400, 32}, + {0x0000510c, 0x1c181410, 32}, + {0x00005158, 0x67380503, 32}, + {0x0000515c, 0x1f83177f, 32}, + {0x00005160, 0x88008000, 32}, + {0x00005164, 0x00000000, 32}, + {0x00005168, 0x5d004e4e, 32}, + {0x0000516c, 0x48118010, 32}, + {0x00005250, 0x00ff0000, 32}, + {0x0000516c, 0x48118030, 32}, + {0x00005118, 0xba98ba98, 32}, + {0x0000511c, 0xb4, 8}, + {0x0000511d, 0x5a, 8}, + {0x0000511e, 0xb0, 8}, + {0x00005120, 0x01, 8}, + {0x00005121, 0x80, 8}, + {0x00005126, 0x90, 8}, + {0x0000512c, 0x01, 8}, + {0x0000512d, 0x80, 8}, + {0x0000512f, 0x00, 8}, + {0x00005138, 0x00000000, 32}, + {0x0000513d, 0x00, 8}, + {0x0000513e, 0x33, 8}, + {0x0000513f, 0xa6, 8}, + {0x00005140, 0x26108804, 32}, + {0x00005145, 0x08, 8}, + {0x00005148, 0xc2ff2800, 32}, + {0x0000515c, 0x1f83177f, 32}, + {0x00005161, 0x80, 8}, + {0x00005164, 0x00, 8}, + {0x00005165, 0x00, 8}, + {0x0000516a, 0x00, 8}, + {0x00005170, 0x40, 8}, + {0x00005171, 0x00, 8}, + {0x00005172, 0x15, 8}, + {0x00005176, 0x12, 8}, + {0x00005177, 0x40, 8}, + {0x00005181, 0x44, 8}, + {0x00008191, 0x00, 8}, + {0x00005203, 0x02, 8}, + {0x00005390, 0x90909090, 32}, + {0x00005394, 0x90909090, 32}, + {0x00005398, 0x90909090, 32}, + {0x0000539c, 0x90909090, 32}, + {0x000053a0, 0x90909090, 32}, + {0x000053a4, 0x90909090, 32}, + {0x000053a8, 0x90909090, 32}, + {0x000053ac, 0x90909090, 32}, + {0x000053b0, 0x90909090, 32}, + {0x000053b4, 0x90909090, 32}, + {0x000053b8, 0x90909090, 32}, + {0x000053bc, 0x90909090, 32}, + {0x000053c0, 0x90909090, 32}, + {0x000053c4, 0x90909090, 32}, + {0x000053c8, 0x90909090, 32}, + {0x000053cc, 0x90909090, 32}, + {0x000053d0, 0x90909090, 32}, + {0x000053d4, 0x90909090, 32}, + + {0x00005a00, 0x48484848, 32}, + {0x00005a04, 0x48484848, 32}, + {0x00005a08, 0x48484848, 32}, + {0x00005a0c, 0x48484848, 32}, + {0x00005a10, 0x00004848, 32}, + {0x00005a24, 0x6a6a6a6a, 32}, + {0x00005a28, 0x6a6a6a6a, 32}, + {0x00005a2c, 0x6a6a6a6a, 32}, + {0x00005a30, 0x6a6a6a6a, 32}, + {0x00005a34, 0x6c6c6a6a, 32}, + {0x00005a38, 0x6c6c6c6c, 32}, + {0x00005a3c, 0x6c6c6c6c, 32}, + {0x00005a40, 0x6c6c6c6c, 32}, + {0x00005a44, 0x6c6c6c6c, 32}, + {0x00005a48, 0x48484848, 32}, + {0x00005a4c, 0x48484848, 32}, + {0x00005a50, 0x48484848, 32}, + {0x00005a54, 0x48484848, 32}, + {0x00005a58, 0x00004848, 32}, + {0x00005a6c, 0x00000000, 32}, + {0x00005a70, 0x00000000, 32}, + {0x00005a74, 0x00000000, 32}, + {0x00005a78, 0x00000000, 32}, + {0x00005a7c, 0x00000000, 32}, + {0x00005a80, 0x00000000, 32}, + {0x00005a84, 0x00000000, 32}, + {0x00005a88, 0x00000000, 32}, + {0x00005a8c, 0x00000000, 32}, + {0x00005d5c, 0x2e2e0000, 32}, + {0x00005d60, 0x00000000, 32}, + {0x00005e0c, 0x00626200, 32}, + {0x00005e18, 0x04000000, 32}, + {0x00005e1c, 0x04040404, 32}, + {0x00005e20, 0x04040404, 32}, + {0x00005e24, 0x04040404, 32}, + {0x00005e28, 0x04040404, 32}, + {0x00005e2c, 0x04040404, 32}, + {0x00005e30, 0x04040404, 32}, + {0x00005e34, 0x04040404, 32}, + {0x00005e38, 0x04040404, 32}, + {0x00005e3c, 0x00040404, 32}, + {0x00005300, 0x01010101, 32}, + {0x00005304, 0x01010101, 32}, + {0x00005308, 0x01010101, 32}, + {0x0000530c, 0x01010101, 32}, + {0x00005310, 0x01010101, 32}, + {0x00005314, 0x01010101, 32}, + {0x00005318, 0x01010101, 32}, + {0x0000531c, 0x01010101, 32}, + {0x00005320, 0x01010101, 32}, + {0x00005324, 0x01010101, 32}, + {0x00005328, 0x01010101, 32}, + {0x0000532c, 0x01010101, 32}, + {0x00005330, 0x01010101, 32}, + {0x00005334, 0x01010101, 32}, + {0x00005338, 0x01010101, 32}, + {0x0000533c, 0x01010101, 32}, + {0x00005340, 0x01010101, 32}, + {0x00005344, 0x01010101, 32}, + {0x00005348, 0x01010101, 32}, + {0x0000534c, 0x01010101, 32}, + {0x00005350, 0x01010101, 32}, + {0x00005354, 0x01010101, 32}, + {0x00005358, 0x01010101, 32}, + {0x0000535c, 0x01010101, 32}, + {0x00005360, 0x01010101, 32}, + {0x00005364, 0x01010101, 32}, + {0x00005368, 0x01010101, 32}, + {0x0000536c, 0x01010101, 32}, + {0x00005370, 0x01010101, 32}, + {0x00005374, 0x01010101, 32}, + {0x00005378, 0x01010101, 32}, + {0x0000537c, 0x01010101, 32}, + {0x00005380, 0x01010101, 32}, + {0x00005384, 0x01010101, 32}, + {0x00005388, 0x01010101, 32}, + {0x0000538c, 0x01010101, 32}, + {0x000053d8, 0x55555555, 32}, + {0x000053dc, 0x55555550, 32}, + {0x000053e0, 0x55555055, 32}, + {0x000053e4, 0x55505555, 32}, + {0x000053e8, 0x50555555, 32}, + {0x000053ec, 0x55555555, 32}, + {0x000053f0, 0x55555550, 32}, + {0x000053f4, 0x55555055, 32}, + {0x000053f8, 0x55505555, 32}, + {0x000053fc, 0x50555555, 32}, + {0x0000513c, 0x02, 8}, + {0x0000513c, 0x06, 8}, + {0x0000508e, 0x01, 8}, + {0x0000508e, 0x00, 8}, + {0x0000857c, 0x80000000, 32}, + {0x00005017, 0x80, 8}, + {0x0000500b, 0x00, 8}, + {0x00008af2, 0x01, 8}, + {0x00008aa0, 0x10, 8}, +}; +#elif FPGA_DDR2 +static MMIOREGISTER Mclk_300_Timing_Desktop[]={ + {0x0000516c, 0x10, 8}, + {0x00005040, 0x00000000, 32}, + {0x00005044, 0x00000000, 32}, + {0x00005100, 0x40302010, 32}, + {0x00005104, 0x80706050, 32}, + {0x00005108, 0x30201000, 32}, + {0x0000510c, 0x70605040, 32}, + {0x00005158, 0x67380202, 32}, + {0x0000515c, 0x1f83177f, 32}, + {0x00005160, 0x88008000, 32}, + {0x00005164, 0x00000000, 32}, + {0x00005168, 0x5d004e4e, 32}, + {0x0000516c, 0x48118030, 32}, + {0x00005250, 0x00ff0000, 32}, + + {0x0000516c, 0x48118030, 32}, + {0x00005118, 0xba98ba98, 32}, + {0x0000511c, 0xd4, 8}, + {0x0000511d, 0x6c, 8}, + {0x0000511e, 0xb0, 8}, + {0x00005120, 0x01, 8}, + {0x00005121, 0x80, 8}, + {0x00005126, 0xc0, 8}, + {0x0000512c, 0x01, 8}, + {0x0000512d, 0x80, 8}, + {0x0000512f, 0x00, 8}, + {0x00005138, 0x00000000, 32}, + {0x0000513d, 0x00, 8}, + {0x0000513e, 0x33, 8}, + {0x0000513f, 0xa6, 8}, + {0x00005140, 0x26108804, 32}, + {0x00005145, 0x08, 8}, + {0x00005148, 0xc2ff2800, 32}, + {0x0000515c, 0x1f83177f, 32}, + {0x00005161, 0x80, 8}, + {0x00005164, 0x00, 8}, + {0x00005165, 0x00, 8}, + {0x0000516a, 0x00, 8}, + {0x00005170, 0x40, 8}, + {0x00005171, 0x00, 8}, + {0x00005172, 0x15, 8}, + {0x00005176, 0x12, 8}, + {0x00005177, 0x40, 8}, + {0x00005181, 0x44, 8}, + {0x00005191, 0x00, 8}, + {0x00005203, 0x02, 8}, + {0x00005390, 0x90909090, 32}, + {0x00005394, 0x90909090, 32}, + {0x00005398, 0x90909090, 32}, + {0x0000539c, 0x90909090, 32}, + {0x000053a0, 0x90909090, 32}, + {0x000053a4, 0x90909090, 32}, + {0x000053a8, 0x90909090, 32}, + {0x000053ac, 0x90909090, 32}, + {0x000053b0, 0x90909090, 32}, + {0x000053b4, 0x90909090, 32}, + {0x000053b8, 0x90909090, 32}, + {0x000053bc, 0x90909090, 32}, + {0x000053c0, 0x90909090, 32}, + {0x000053c4, 0x90909090, 32}, + {0x000053c8, 0x90909090, 32}, + {0x000053cc, 0x90909090, 32}, + {0x000053d0, 0x90909090, 32}, + {0x000053d4, 0x90909090, 32}, + {0x00005a00, 0x48484848, 32}, + {0x00005a04, 0x48484848, 32}, + {0x00005a08, 0x48484848, 32}, + {0x00005a0c, 0x48484848, 32}, + {0x00005a10, 0x00004848, 32}, + {0x00005a24, 0x6a6a6a6a, 32}, + {0x00005a28, 0x6a6a6a6a, 32}, + {0x00005a2c, 0x6a6a6a6a, 32}, + {0x00005a30, 0x6a6a6a6a, 32}, + {0x00005a34, 0x6c6c6a6a, 32}, + {0x00005a38, 0x6c6c6c6c, 32}, + {0x00005a3c, 0x6c6c6c6c, 32}, + {0x00005a40, 0x6c6c6c6c, 32}, + {0x00005a44, 0x6c6c6c6c, 32}, + {0x00005a48, 0x48484848, 32}, + {0x00005a4c, 0x48484848, 32}, + {0x00005a50, 0x48484848, 32}, + {0x00005a54, 0x48484848, 32}, + {0x00005a58, 0x00004848, 32}, + {0x00005a6c, 0x00000000, 32}, + {0x00005a70, 0x00000000, 32}, + {0x00005a74, 0x00000000, 32}, + {0x00005a78, 0x00000000, 32}, + {0x00005a7c, 0x00000000, 32}, + {0x00005a80, 0x00000000, 32}, + {0x00005a84, 0x00000000, 32}, + {0x00005a88, 0x00000000, 32}, + {0x00005a8c, 0x00000000, 32}, + {0x00005d5c, 0x2e2e0000, 32}, + {0x00005d60, 0x00000000, 32}, + {0x00005e0c, 0x00626200, 32}, + {0x00005e18, 0x04000000, 32}, + {0x00005e1c, 0x04040404, 32}, + {0x00005e20, 0x04040404, 32}, + {0x00005e24, 0x04040404, 32}, + {0x00005e28, 0x04040404, 32}, + {0x00005e2c, 0x04040404, 32}, + {0x00005e30, 0x04040404, 32}, + {0x00005e34, 0x04040404, 32}, + {0x00005e38, 0x04040404, 32}, + {0x00005e3c, 0x00040404, 32}, + {0x00005300, 0x01010101, 32}, + {0x00005304, 0x01010101, 32}, + {0x00005308, 0x01010101, 32}, + {0x0000530c, 0x01010101, 32}, + {0x00005310, 0x01010101, 32}, + {0x00005314, 0x01010101, 32}, + {0x00005318, 0x01010101, 32}, + {0x0000531c, 0x01010101, 32}, + {0x00005320, 0x01010101, 32}, + {0x00005324, 0x01010101, 32}, + {0x00005328, 0x01010101, 32}, + {0x0000532c, 0x01010101, 32}, + {0x00005330, 0x01010101, 32}, + {0x00005334, 0x01010101, 32}, + {0x00005338, 0x01010101, 32}, + {0x0000533c, 0x01010101, 32}, + {0x00005340, 0x01010101, 32}, + {0x00005344, 0x01010101, 32}, + {0x00005348, 0x01010101, 32}, + {0x0000534c, 0x01010101, 32}, + {0x00005350, 0x01010101, 32}, + {0x00005354, 0x01010101, 32}, + {0x00005358, 0x01010101, 32}, + {0x0000535c, 0x01010101, 32}, + {0x00005360, 0x01010101, 32}, + {0x00005364, 0x01010101, 32}, + {0x00005368, 0x01010101, 32}, + {0x0000536c, 0x01010101, 32}, + {0x00005370, 0x01010101, 32}, + {0x00005374, 0x01010101, 32}, + {0x00005378, 0x01010101, 32}, + {0x0000537c, 0x01010101, 32}, + {0x00005380, 0x01010101, 32}, + {0x00005384, 0x01010101, 32}, + {0x00005388, 0x01010101, 32}, + {0x0000538c, 0x01010101, 32}, + {0x000053d8, 0x55555555, 32}, + {0x000053dc, 0x55555550, 32}, + {0x000053e0, 0x55555055, 32}, + {0x000053e4, 0x55505555, 32}, + {0x000053e8, 0x50555555, 32}, + {0x000053ec, 0x55555555, 32}, + {0x000053f0, 0x55555550, 32}, + {0x000053f4, 0x55555055, 32}, + {0x000053f8, 0x55505555, 32}, + {0x000053fc, 0x50555555, 32}, + + {0x0000513c, 0x02, 8}, + + {0x0000513c, 0x06, 8}, + {0x0000508e, 0x01, 8}, + + {0x0000508e, 0x00, 8}, + {0x000490a0, 0x1fffff1f, 32}, + {0x0000857C, 0x80000000, 32}, + + {0x00005017, 0x80, 8}, + {0x0000500b, 0x00, 8}, + {0x00008af1, 0x01, 8}, + {0x0000850c, 0x02, 8}, + {0x00008aa0, 0x10, 8}, + {0x00005158, 0x67380204, 32}, +}; +#else //not QT +static CBREGISTER Mclk_300_Timing_Desktop[]={ +}; +#endif + +static CBREGISTER SRDefaultVCP[]= +{ + {SR, (CBIOS_U8)~0xFE,0x09,0x7E}, + {SR, (CBIOS_U8)~0x8D,0x0B,0x00}, + {SR, (CBIOS_U8)~0xF7,0x0D,0x50}, + {SR, (CBIOS_U8)~0xFF, 0x0E, 0xC1}, + {SR, (CBIOS_U8)~0xFF, 0x0F, 0x6B}, + {SR, (CBIOS_U8)~0xDF, 0x14, 0x00}, + {SR, (CBIOS_U8)~0x6E, 0x15, 0x4A}, + {SR, (CBIOS_U8)~0x20, 0x18,0x20}, + {SR, (CBIOS_U8)~0xFF, 0x19, 0x31}, + {SR, (CBIOS_U8)~0x1F, 0x1C, 0x1C}, + {SR, (CBIOS_U8)~0x67, 0x1D, 0x67}, + {SR, (CBIOS_U8)~0x1F, 0x1E, 0x12}, + {SR, (CBIOS_U8)~0xF1, 0x1F, 0x50}, + {SR, (CBIOS_U8)~0xFF, 0x20, 0x7F}, + {SR, (CBIOS_U8)~0xFF, 0x21, 0xCE}, + {SR, (CBIOS_U8)~0xE7, 0x10, 0x84}, + {SR, (CBIOS_U8)~0x7F, 0x22, 0x0E}, + {SR, (CBIOS_U8)~0xFF, 0x23, 0xE8}, + {SR, (CBIOS_U8)~0x3F, 0x24, 0x10}, + {SR, (CBIOS_U8)~0xFF, 0x25, 0xC8}, + {SR, (CBIOS_U8)~0x80, 0x26, 0x00}, + {SR, (CBIOS_U8)~0xFF, 0x27, 0xB3}, + {SR, (CBIOS_U8)~0x3C, 0x28, 0x14}, + {SR, (CBIOS_U8)~0xFF, 0x29, 0x00}, + {SR, (CBIOS_U8)~0xFF, 0x2B, 0x00}, + {SR, (CBIOS_U8)~0xD0, 0x2D, 0x00}, + {SR, (CBIOS_U8)~0x3F, 0x30, 0x03}, + {SR, (CBIOS_U8)~0x76, 0x31, 0x00}, + {SR, (CBIOS_U8)~0xF8, 0x39, 0x98}, + {SR, (CBIOS_U8)~0x18, 0x3C, 0x18}, + {SR, (CBIOS_U8)~0x3F, 0x3F, 0x00}, + {SR, (CBIOS_U8)~0xFF, 0x42, 0x01}, + {SR, (CBIOS_U8)~0xFF, 0x43, 0x01}, + {SR, (CBIOS_U8)~0x88, 0x44, 0x80}, + {SR, (CBIOS_U8)~0x9F, 0x45, 0x00}, + {SR, (CBIOS_U8)~0xFF, 0x47, 0x01}, + {SR, (CBIOS_U8)~0xFF, 0x4F, 0x00}, + {SR, (CBIOS_U8)~0x01, 0x70, 0x00}, + {SR, (CBIOS_U8)~0x10, 0x94, 0x00}, + {SR, (CBIOS_U8)~0x10, 0x40, 0x00}, + {SR, (CBIOS_U8)~0x81, 0x37, 0x00}, + {SR, (CBIOS_U8)~0xFF, 0x38, 0x00}, + {SR, (CBIOS_U8)~0xFF, 0x3E, 0x00}, + {SR, (CBIOS_U8)~0x1C, 0x31, 0x1C}, + {SR, (CBIOS_U8)~0xFF, 0x36, 0x00},//disable dither for dp1 + {SR_B, (CBIOS_U8)~0xFF, 0x36, 0x00},//disable dither for dp2 +}; + +static CBREGISTER CRDefaultVCP[]= +{ + {CR, (CBIOS_U8)~0x09, 0x31, 0x09}, + {CR, (CBIOS_U8)~0xB0, 0x34, 0x00}, + {CR, (CBIOS_U8)~0x01, 0x3D, 0x00}, + {CR, (CBIOS_U8)~0x68, 0x43, 0x00}, + {CR, (CBIOS_U8)~0x0F, 0x45, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0x52, 0x00}, + {CR, (CBIOS_U8)~0x20, 0x55, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0x59, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0x5A, 0x00}, + {CR, (CBIOS_U8)~0xF8, 0x5B, 0x00}, + {CR, (CBIOS_U8)~0xD9, 0x63, 0x00}, + {CR, (CBIOS_U8)~0x02, 0x66, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0x6B, 0x01}, + {CR, (CBIOS_U8)~0xFF, 0x6C, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0x6D, 0x33}, + {CR, (CBIOS_U8)~0xFF, 0x6E, 0x00}, + {CR, (CBIOS_U8)~0x22, 0x71, 0x22}, + {CR, (CBIOS_U8)~0xFF, 0x86, 0xA8}, + {CR, (CBIOS_U8)~0xFF, 0x87, 0x68}, + {CR, (CBIOS_U8)~0xFF, 0x88, 0x20}, + {CR, (CBIOS_U8)~0xFF, 0x89, 0xE0}, + {CR, (CBIOS_U8)~0xFF, 0x8D, 0x68}, + {CR, (CBIOS_U8)~0xFF, 0xA1, 0x00}, + {CR, (CBIOS_U8)~0xFB, 0xA2, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0xA3, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0xA4, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0xA6, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0xB0, 0x55}, + {CR, (CBIOS_U8)~0x1F, 0xB1, 0x09}, + {CR, (CBIOS_U8)~0x3F, 0xB2, 0x01}, + {CR, (CBIOS_U8)~0x3F, 0xB3, 0x01}, + {CR, (CBIOS_U8)~0xFF, 0xBC, 0x20}, + {CR, (CBIOS_U8)~0xFF, 0xBD, 0xA8}, + {CR, (CBIOS_U8)~0xFF, 0xBE, 0x08}, + {CR, (CBIOS_U8)~0xFF, 0xC0, 0x24}, + {CR, (CBIOS_U8)~0xFF, 0xC1, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0xC2, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0xC3, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0xC4, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0xC5, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0xC6, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0xC7, 0x00}, + {CR, (CBIOS_U8)~0xFF, 0xC8, 0x00}, + {CR, (CBIOS_U8)~0x01, 0xCD, 0x00}, + {CR, (CBIOS_U8)~0x1F, 0xCE, 0x0F}, + {CR, (CBIOS_U8)~0x80, 0xD4, 0x80}, + {CR_B, (CBIOS_U8)~0x09, 0x31, 0x09}, + {CR_B, (CBIOS_U8)~0x22, 0x71, 0x22}, + {CR_B, (CBIOS_U8)~0x1F, 0xB1, 0x09}, + {CR_B, (CBIOS_U8)~0xFF, 0xC0, 0x7F}, + {CR_B, (CBIOS_U8)~0xFF, 0xC1, 0x7F}, + {CR_B, (CBIOS_U8)~0xFF, 0xC2, 0x00}, + {CR_B, (CBIOS_U8)~0xFF, 0xC3, 0x00}, + {CR_B, (CBIOS_U8)~0xFF, 0xC4, 0x00}, + {CR_B, (CBIOS_U8)~0x1F, 0xCE, 0x0F}, + {CR_B, (CBIOS_U8)~0x40, 0xD2, 0x40}, + {CR_B, (CBIOS_U8)~0x1F, 0xE0, 0x04}, + {CR_B, (CBIOS_U8)~0xFF, 0xF5, 0x09}, + {CR_B, (CBIOS_U8)~0xFF, 0xF6, 0x1F}, + {CR_B, (CBIOS_U8)~0xFF, 0xFC, 0x00}, + {CR_B, (CBIOS_U8)~0x80, 0xFD, 0x00}, + {CR_C, (CBIOS_U8)~0x04, 0x9D, 0x04}, + {CR_C, (CBIOS_U8)~0x1F, 0xA0, 0x02}, + {CR_C, (CBIOS_U8)~0x10, 0xA1, 0x00}, + {CR_C, (CBIOS_U8)~0x01, 0xA2,0x00}, + {CR_C, (CBIOS_U8)~0xC0, 0xA3, 0x00}, + {CR_C, (CBIOS_U8)~0xA0, 0xA4, 0x00}, + {CR_C, (CBIOS_U8)~0x80, 0xA5, 0x00}, + {CR_C, (CBIOS_U8)~0xD0, 0xA6, 0x00}, + {CR_C, (CBIOS_U8)~0x3E, 0xC2, 0x00}, +}; + +static CBREGISTER ZXGModeExtRegDefault[] = +{ + {SR,(CBIOS_U8)~0xC0, 0x19, 0x00}, + {SR,(CBIOS_U8)~0x60, 0x1A, 0x00}, + {SR,(CBIOS_U8)~0xF8, 0x1B, 0x00}, + {SR,(CBIOS_U8)~0xD8, 0x47, 0x00}, + {CR,(CBIOS_U8)~0xEF, 0x31, 0x05}, + {CR,(CBIOS_U8)~0x44, 0x32, 0x40}, + {CR,(CBIOS_U8)~0x7A, 0x33, 0x08}, + {CR,(CBIOS_U8)~0x38, 0x3A, 0x00}, + {CR, 0x00, 0x3B, 0x00}, + {CR, 0x00, 0x3C, 0x10}, + {CR,(CBIOS_U8)~0x3F, 0x42, 0x00}, + {CR,(CBIOS_U8)~0xF1, 0x50, 0x00}, + {CR,(CBIOS_U8)~0x7F, 0x51, 0x00}, + {CR,(CBIOS_U8)~0x80, 0x53, 0x00}, + {CR, 0x00, 0x5D, 0x00}, + {CR, 0x00, 0x5E, 0xC0}, + {CR,(CBIOS_U8)~0x0F, 0x64, 0x00}, + {CR,(CBIOS_U8)~0xFB, 0x65, 0x00}, + {CR,(CBIOS_U8)~0x01, 0x66, 0x00}, + {CR, 0x00, 0x69, 0x00}, + {CR, 0x00, 0x6A, 0x00}, +}; + +static CBREGISTER ZXGMode3SRRegTable[] = +{ + {SR, 0x00, 0x02, 0x03}, + {SR, 0x00, 0x03, 0x00}, + {SR, 0x00, 0x04, 0x02}, +}; + +static CBREGISTER ZXGMode3CRRegTable[] = +{ + {CR, 0x00, 0x00, 0x5F}, + {CR, 0x00, 0x01, 0x4F}, + {CR, 0x00, 0x02, 0x50}, + {CR, 0x00, 0x03, 0x82}, + {CR, 0x00, 0x04, 0x55}, + {CR, 0x00, 0x05, 0x81}, + {CR, 0x00, 0x06, 0xBF}, + {CR, 0x00, 0x07, 0x1F}, + {CR, ~0x7F, 0x08, 0x00}, + {CR, 0x00, 0x09, 0x4F}, + {CR, ~0x3F, 0x0A, 0x0D}, + {CR, ~0x7F, 0x0B, 0x0E}, + {CR, 0x00, 0x0C, 0x00}, + {CR, 0x00, 0x0D, 0x00}, + {CR, 0x00, 0x0E, 0x00}, + {CR, 0x00, 0x0F, 0x00}, + {CR, 0x00, 0x10, 0x9C}, + {CR, 0x00, 0x11, 0x8E}, + {CR, 0x00, 0x12, 0x8F}, + {CR, 0x00, 0x13, 0x28}, + {CR, ~0x7F, 0x14, 0x1F}, + {CR, 0x00, 0x15, 0x96}, + {CR, 0x00, 0x16, 0xB9}, + {CR, 0x00, 0x17, 0xA3}, + {CR, 0x00, 0x18, 0xFF}, + {CR, ~0x3F, 0x42, 0x00}, + {CR, ~0x7F, 0x51, 0x00}, + {CR, ~0x7F, 0x5D, 0x00}, + {CR, 0x00, 0x5E, 0xC0}, + {CR, 0x00, 0x6A, 0x00}, +}; + +static CBREGISTER ZXGMode3ARRegTable[] = +{ + {AR, 0x00, 0x00, 0x00}, + {AR, 0x00, 0x01, 0x01}, + {AR, 0x00, 0x02, 0x02}, + {AR, 0x00, 0x03, 0x03}, + {AR, 0x00, 0x04, 0x04}, + {AR, 0x00, 0x05, 0x05}, + {AR, 0x00, 0x06, 0x14}, + {AR, 0x00, 0x07, 0x07}, + {AR, 0x00, 0x08, 0x38}, + {AR, 0x00, 0x09, 0x39}, + {AR, 0x00, 0x0A, 0x3A}, + {AR, 0x00, 0x0B, 0x3B}, + {AR, 0x00, 0x0C, 0x3C}, + {AR, 0x00, 0x0D, 0x3D}, + {AR, 0x00, 0x0E, 0x3E}, + {AR, 0x00, 0x0F, 0x3F}, + + {AR, 0x00, 0x10, 0x0C}, + {AR, 0x00, 0x11, 0x00}, + {AR, 0x00, 0x12, 0x0F}, + {AR, 0x00, 0x13, 0x08}, + {AR, 0x00, 0x14, 0x00}, + + {GR, 0x00, 0x00, 0x00}, + {GR, 0x00, 0x01, 0x00}, + {GR, 0x00, 0x02, 0x00}, + {GR, 0x00, 0x03, 0x00}, + {GR, 0x00, 0x04, 0x00}, + {GR, 0x00, 0x05, 0x10}, + {GR, 0x00, 0x06, 0x0E}, + {GR, 0x00, 0x07, 0x00}, + {GR, 0x00, 0x08, 0xFF}, +}; + +static CBREGISTER ZXGMode3RegOnIGA2[] = +{ + {CR, 0x00, 0x00, 0x5F}, + {CR, 0x00, 0x01, 0x4F}, + {CR, 0x00, 0x02, 0x50}, + {CR, 0x00, 0x03, 0x82}, + {CR, 0x00, 0x04, 0x52}, + {CR, 0x00, 0x05, 0x9E}, + {CR, 0x00, 0x06, 0x0B}, + {CR, 0x00, 0x07, 0x3E}, + {CR, 0x00, 0x08, 0x00}, + {CR, 0x00, 0x09, 0x40}, + {CR, 0x00, 0x0D, 0x00}, + {CR, 0x00, 0x10, 0xEA}, + {CR, 0x00, 0x11, 0x0C}, + {CR, 0x00, 0x12, 0xDF}, + {CR, 0x00, 0x15, 0xE7}, + {CR, 0x00, 0x16, 0x05}, + {CR,(CBIOS_U8)~0x80, 0x17, 0x80}, + {CR, 0x00, 0x5D, 0x00}, + {CR, 0x00, 0x5E, 0xC0}, + {CR,(CBIOS_U8)~0xC0, 0x63, 0x00}, +}; + +/*****************************************************************************/ +/* ------------------------------------- HW Init --------------------------------------- */ +/*****************************************************************************/ + +static CBIOS_STATUS cbChipEnable(PCBIOS_EXTENSION_COMMON pcbe) +{ + CBIOS_STATUS status = CBIOS_OK; + + // 850C bit 1 should be used to wake chip. + cb_WriteU8(pcbe->pAdapterContext, 0x850C, 0x2); + + //Wakeup chip, 3C3 bit0 = 1 + cb_WriteU8(pcbe->pAdapterContext, 0x83C3, 0x01); + + // 3C2 MISCELLANEOUS reg + // Bit 0 Color emulation. Address base at 0x3Dx. + // Bit 1 Enable access of CPU + cb_WriteU8(pcbe->pAdapterContext, 0x83C2, 0x03); + + cbUnlockCR(pcbe); + cbUnlockSR(pcbe); + + cbMMIOWriteReg(pcbe, SR_2A, 0x00, 0x00); + cbMMIOWriteReg(pcbe, SR_26, 0x40, 0x00); + +#if CBIOS_CHECK_HARDWARE_STATUS + // If MMIO failure, try to use standard IO. + if (cbIsMMIOWell(pcbe) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "\n\nMMIO not enabled!!!\n")); + + return CBIOS_ER_MMIO; + } + +#endif + + + return status; +} + +#if 0 + +static CBIOS_VOID cbPOSTSetClock(PCBIOS_EXTENSION_COMMON pcbe) +{ + CBIOS_U32 dwEClock, dwIClock, dwVppClock; + + cbMMIOWriteReg(pcbe, SR_01, 0x20, 0xDF); //screen off + + dwEClock = pcbe->SysBiosInfo.ECLK; + dwIClock = pcbe->SysBiosInfo.ICLK; + dwVppClock = pcbe->SysBiosInfo.VCLK; + + if(dwEClock < CBIOS_CLOCK_MIN || dwEClock > CBIOS_CLOCK_MAX) + { + dwEClock = CBIOS_ECLK_DEFAULT; + } + if(dwIClock < CBIOS_CLOCK_MIN || dwIClock > CBIOS_CLOCK_MAX) + { + dwIClock = CBIOS_ICLK_DEFAULT; + } + if(dwVppClock < CBIOS_CLOCK_MIN || dwVppClock > CBIOS_CLOCK_MAX) + { + dwVppClock = CBIOS_VCLK_DEFAULT; + } + + dwEClock *= 10000; + dwIClock *= 10000; + dwVppClock *= 10000; + + cbProgClock(pcbe,dwEClock, ECLKTYPE_Post, IGA1); + //cbProgClock(pcbe,dwIClock, ICLKTYPE_Post, IGA1); + cbProgClock(pcbe,dwVppClock, CBIOS_VCLKTYPE, IGA1); +} + +#endif + +static CBIOS_STATUS cbLoadDefaultTables(PCBIOS_EXTENSION_COMMON pcbe) +{ + CBIOS_STATUS status = CBIOS_OK; + + //For QT only, load default MIU table. + if(pcbe->bRunOnQT && !pcbe->bDriverLoadQTiming)// || !pcbe->ChipCaps.bNoMemoryControl) + { + cbLoadMemoryTimingTbl(pcbe, Mclk_300_Timing_Desktop, + sizeofarray(Mclk_300_Timing_Desktop)); + + cbLoadtable(pcbe, + SRDefaultVCP, + sizeofarray(SRDefaultVCP), + CBIOS_NOIGAENCODERINDEX); + + cbLoadtable(pcbe, + CRDefaultVCP, + sizeofarray(CRDefaultVCP), + CBIOS_NOIGAENCODERINDEX); + } + + cbLoadtable(pcbe, + pcbe->PostRegTable[VCP_TABLE].pSRDefault, + pcbe->PostRegTable[VCP_TABLE].sizeofSRDefault, + CBIOS_NOIGAENCODERINDEX); + + cbLoadtable(pcbe, + pcbe->PostRegTable[VCP_TABLE].pCRDefault, + pcbe->PostRegTable[VCP_TABLE].sizeofCRDefault, + CBIOS_NOIGAENCODERINDEX); + + return status; +} + +static CBIOS_VOID cbEndOfPost(PCBIOS_EXTENSION_COMMON pcbe) +{ + + REG_CR6B RegCR6BValue; + REG_CR6B RegCR6BMask; + REG_CR6C RegCR6CValue; + REG_CR6C RegCR6CMask; + + // Clear active device in scratch pad. + RegCR6BValue.Value = 0; + RegCR6BValue.BIOS_Flag_3 = 0; + RegCR6BMask.Value = 0xFF; + RegCR6BMask.BIOS_Flag_3 = 0; + cbMMIOWriteReg(pcbe,CR_6B, RegCR6BValue.Value, RegCR6BMask.Value); + RegCR6CValue.Value = 0; + RegCR6CValue.BIOS_Flag_4 = 0; + RegCR6CMask.Value = 0xFF; + RegCR6CMask.BIOS_Flag_4 = 0; + cbMMIOWriteReg(pcbe,CR_6C, RegCR6CValue.Value, RegCR6CMask.Value); + + cbUnlockSR(pcbe); + cbUnlockCR(pcbe); +} + +static CBIOS_VOID cbSetupVGA(PCBIOS_EXTENSION_COMMON pcbe) +{ + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_ADDR_REG, 0x41); + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_DATA_REG, 0x03); //mode 3 + + cbLoadtable(pcbe, ZXGModeExtRegDefault, + sizeofarray(ZXGModeExtRegDefault), + CBIOS_NOIGAENCODERINDEX); + // do sync reset + cb_WriteU16(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x0100); + cb_WriteU16(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x2001); + cb_WriteU16(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x2001); // Do this two times + + cb_WriteU8(pcbe->pAdapterContext, CB_MISC_OUTPUT_WRITE_REG,0x67); + cb_WriteU16(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x0300); + + cb_DelayMicroSeconds( 150); + + cbLoadtable(pcbe, + ZXGMode3SRRegTable, + sizeofarray(ZXGMode3SRRegTable), + CBIOS_NOIGAENCODERINDEX); + cb_WriteU16(pcbe->pAdapterContext, CB_CRT_ADDR_REG, 0x0011); // Unlock writing to CRT + + cbLoadtable(pcbe, + ZXGMode3CRRegTable, + sizeofarray(ZXGMode3CRRegTable), + CBIOS_NOIGAENCODERINDEX); + cbLoadtable(pcbe, + ZXGMode3RegOnIGA2, + sizeofarray(ZXGMode3RegOnIGA2), + IGA2); + + cbLoadtable(pcbe, + ZXGMode3RegOnIGA2, + sizeofarray(ZXGMode3RegOnIGA2), + IGA3); + + cbLoadtable(pcbe, + ZXGMode3RegOnIGA2, + sizeofarray(ZXGMode3RegOnIGA2), + IGA4); + + + cb_ReadU8(pcbe->pAdapterContext, CB_INPUT_STATUS_1_REG); // lock writing to CRT + + cbLoadtable(pcbe, + ZXGMode3ARRegTable, + sizeofarray(ZXGMode3ARRegTable), + CBIOS_NOIGAENCODERINDEX); +} + +CBIOS_STATUS cbPost(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS status = CBIOS_OK; + REG_CR68 RegCR68Value, RegCR68Mask; + + /*this is a patch, we must write something to 3c6h,3c7h,3c8h or 3c9h + to generate hblank vblank signal for CRT*/ + cb_WriteU8(pcbe->pAdapterContext, 0x83C8, 0); + + cbWritePort80(pcbe,CBIOS_PORT80_ID_CBiosPost_Enter); + + status =cbChipEnable(pcbe); + cbWritePort80(pcbe, CBIOS_PORT80_ID_AfterChipEnable); + if( status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"Chip is not enable!\n")); + cbPrintMsgToFile(DBG_LEVEL_ERROR_MSG, "cbPost: Chip is not enable!\n", CBIOS_NULL, 0); + return status; + } + + RegCR68Value.Value = 0; + RegCR68Value.EOCLK_Source = 0; + RegCR68Mask.Value = 0xFF; + RegCR68Mask.EOCLK_Source = 0; + cbMMIOWriteReg(pcbe, CR_68, RegCR68Value.Value, RegCR68Mask.Value); //force internal Eclk + + cbMMIOWriteReg(pcbe, CR_C_F3, 0x04, ~0x04); //reset will not check PLL lock + //Just keep default clock now and GFX will adjust it dynamically + //cbPOSTSetClock(pcbe); + cbWritePort80(pcbe,CBIOS_PORT80_ID_AfterPrePost); + + cbLoadDefaultTables(pcbe); + cbWritePort80(pcbe,CBIOS_PORT80_ID_AfterLoadDefautTables); + + cbWritePort80(pcbe,CBIOS_PORT80_ID_AfterInitMemory); + + cbWritePort80(pcbe,CBIOS_PORT80_ID_AfterIsMemoryWriteable); + + if(!pcbe->bRunOnQT) + { + cbSetupVGA(pcbe); + } + + // Per Henry, this code should come AFTER the MIU reset + cbEndOfPost(pcbe); + + cbWritePort80(pcbe,CBIOS_PORT80_ID_CBiosPost_Exit); + + pcbe->DbgDataToFile[0] = status; + cbPrintMsgToFile(DBG_LEVEL_CHIP_INFO, "Exit cbPost and return status", pcbe->DbgDataToFile, 4); + + cbHWSetChipPostFlag(pcbe); + + return status; +} + +static CBIOS_VOID cbGetPMPInfo(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_UCHAR PMPVer[E3K_PMPVER_SIZE]; + CBIOS_UCHAR PMPTag[E3K_PMPTAG_SIZE]; + CBIOS_U8 DateIndex = 0, TimeIndex = 0; + CBIOS_U8 Count = 0; + CBIOS_U8 i = 0; + + if(pcbe->bRunOnQT) + { + return; + } + + cb_memset((PCBIOS_VOID)(PMPVer), 0, sizeof(PMPVer)); + cb_memset((PCBIOS_VOID)(PMPTag), 0, sizeof(PMPTag)); + + + for(i = 0; i < E3K_PMPTAG_SIZE; i++) + { + PMPTag[i] = cb_ReadU8(pcbe->pAdapterContext, E3K_PMPTAG_OFFSET+i); + } + + if(!cb_strcmp(PMPTag, (CBIOS_UCHAR*)"pmp")) + { + for(i = 0; i < E3K_PMPVER_SIZE; i++) + { + PMPVer[i] = cb_ReadU8(pcbe->pAdapterContext, E3K_PMPVER_OFFSET+i); + if(PMPVer[i] == '\0' && Count < 2) + { + if(Count == 0) + { + DateIndex = i+1; + } + else + { + TimeIndex = i+1; + } + Count++; + } + } + cb_memcpy(pcbe->PMPVer, PMPVer, E3K_PMPVER_SIZE); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO),"Firmware timing table version:%s Build Time: %s %s \n", PMPVer, PMPVer+DateIndex, PMPVer+TimeIndex)); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO),"Can't get Firmware timing table version\n")); + } +} + +CBIOS_STATUS cbInitChip(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 SupportDevices = 0, Index = 0, CurDev = 0; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_GAMMA_PARA GammaSet = {0}; + + cbGetPMPInfo(pcbe); + + SupportDevices = pcbe->DeviceMgr.SupportDevices; + while (SupportDevices) + { + CurDev = GET_LAST_BIT(SupportDevices); + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, CurDev); + + cbDevDeviceHwInit(pcbe, pDevCommon); + SupportDevices &= (~CurDev); + } + + cbDIU_HDAC_SetStatus(pcbe); + + GammaSet.Flags.bDisableGamma = 1; + for(Index = 0; Index < pcbe->DispMgr.IgaCount; Index++) + { + //patch for Issue 137273: if Dac color mode = 4bpp/8bpp, Ps will go though LUT even gamma is disabled! + cbBiosMMIOWriteReg(pcbe, CR_67, 0x40, ~0x70, Index); + //patch for Issue137093, shut down screen to prevent garbage. + cbBiosMMIOWriteReg(pcbe, CR_71, 0x20, ~0x20, Index); + //disable stream + cbDisableStream(pcbe, Index); + + //disable gamma + GammaSet.IGAIndex = Index; + cbSetGamma(pcbe, &GammaSet); + } + + cbMMIOWriteReg32(pcbe, 0x33524, 0xfffff, ~0xfffff); // enable all security_r of DIU + + //threshold + cbMMIOWriteReg32(pcbe, 0x8454,0xa0a0a0a0, 0); + cbMMIOWriteReg32(pcbe, 0x33928,0xa0a0a0a0, 0); + cbMMIOWriteReg32(pcbe, 0x34028,0xa0a0a0a0, 0); + cbMMIOWriteReg32(pcbe, 0x34728,0xa0a0a0a0, 0); + + cbMMIOWriteReg32(pcbe, 0x3346c,0xa0a0a0a0, 0); + cbMMIOWriteReg32(pcbe, 0x33a9c,0xa0a0a0a0, 0); + cbMMIOWriteReg32(pcbe, 0x3419c,0xa0a0a0a0, 0); + cbMMIOWriteReg32(pcbe, 0x3489c,0xa0a0a0a0, 0); + + cbMMIOWriteReg32(pcbe, 0x33428,0xa0a0a0a0, 0); + cbMMIOWriteReg32(pcbe, 0x33b18,0xa0a0a0a0, 0); + cbMMIOWriteReg32(pcbe, 0x34218,0xa0a0a0a0, 0); + cbMMIOWriteReg32(pcbe, 0x34918,0xa0a0a0a0, 0); + + //timeout + cbMMIOWriteReg32(pcbe, 0x3328c,0x08080808, 0); + cbMMIOWriteReg32(pcbe, 0x332b0,0x08080808, 0); + cbMMIOWriteReg32(pcbe, 0x332b4,0x08080808, 0); + cbMMIOWriteReg32(pcbe, 0x332b8,0x08080808, 0); + + //force high & enable new feature + cbMMIOWriteReg(pcbe, CR_A5, 0x08, 0x00); + + //prefetch 8 line + + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_ADDR_REG, 0x8f); + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_DATA_REG, 0x80); + + + cbBiosMMIOWriteReg(pcbe, CR_8F, 0x80, (CBIOS_U8)~0xc0, IGA2); + cbBiosMMIOWriteReg(pcbe, CR_8F, 0x80, (CBIOS_U8)~0xc0, IGA3); + cbBiosMMIOWriteReg(pcbe, CR_8F, 0x80, (CBIOS_U8)~0xc0, IGA4); + + // set HPD signal to high level active if this feature enabled + if(pcbe->FeatureSwitch.HPDActiveHighEnable) + { + cbMMIOWriteReg32(pcbe, 0x334e0, 0, 0x7fffffff); + cbMMIOWriteReg32(pcbe, 0x33d54, 0, 0x7fffffff); + cbMMIOWriteReg32(pcbe, 0x34454, 0, 0x7fffffff); + cbMMIOWriteReg32(pcbe, 0x34b54, 0, 0x7fffffff); + } + else + { + cbMMIOWriteReg32(pcbe, 0x334e0, 0x80000000, 0x7fffffff); + cbMMIOWriteReg32(pcbe, 0x33d54, 0x80000000, 0x7fffffff); + cbMMIOWriteReg32(pcbe, 0x34454, 0x80000000, 0x7fffffff); + cbMMIOWriteReg32(pcbe, 0x34b54, 0x80000000, 0x7fffffff); + } + + if(pcbe->FeatureSwitch.BIUBackdoorEnable) + { + cbMMIOWriteReg(pcbe,CR_C_70, 0x00, 0xF7); + } + else + { + cbMMIOWriteReg(pcbe,CR_C_70, 0x08, 0xF7); + } + + //enable vga mem access when linear address enable + cbMMIOWriteReg32(pcbe, 0x8520, 0x3000000, 0xfcffffff); + + //Enable linear address access. + cbMMIOWriteReg(pcbe,CR_C_A0,0x10, ~0x10); + + //DO NOT reset bar when link down + cbMMIOWriteReg(pcbe, CR_C_A7, 0x01, 0xFE); + + return CBIOS_OK; +} + + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwInit/CBiosInitHw.h b/drivers/gpu/drm/arise/cbios/Hw/HwInit/CBiosInitHw.h new file mode 100644 index 0000000000000..51ecd069bea12 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwInit/CBiosInitHw.h @@ -0,0 +1,30 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios hw initialization interface prototype. +** +** NOTE: +** This header file CAN ONLY be included by hw layer those files under Hw folder. +******************************************************************************/ + +#ifndef _CBIOS_INIT_HW_H_ +#define _CBIOS_INIT_HW_H_ + +CBIOS_STATUS cbPost(PCBIOS_VOID pvcbe); +CBIOS_STATUS cbInitChip(PCBIOS_VOID pvcbe); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwInterface/CBiosHwInterface.c b/drivers/gpu/drm/arise/cbios/Hw/HwInterface/CBiosHwInterface.c new file mode 100644 index 0000000000000..116a257d083a0 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwInterface/CBiosHwInterface.c @@ -0,0 +1,1398 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios hw layer interface function implementation. +** +** NOTE: +** The sw layer CAN call the hw interface defined in this file to do some hw related operation. +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "CBiosHwInterface.h" +#include "../CBiosHwShare.h" +#include "../HwInit/CBiosInitHw.h" +#include "../HwBlock/CBiosIGA_Timing.h" +#include "../HwBlock/CBiosScaler.h" +#include "../Arise/CBios_Arise.h" +#include "../Arise/CBiosVCP_Arise.h" +#include "../HwBlock/CBiosDIU_VIP.h" + +static CBIOS_U32 CECMiscReg1Tab[4] = {0x33148,0x33e34,0x34538,0x34c38}; +static CBIOS_U32 CECInitiatorCmdTab[4] = {0x3314c,0x33e38,0x3453c,0x34c3c}; +static CBIOS_U32 CECMiscReg2Tab[4] = {0x33150,0x33e3c,0x34540,0x34c40}; +static CBIOS_U32 CECFollowerCmdTab[4] = {0x33154,0x33e40,0x34544,0x34c44}; + +CBIOS_STATUS cbHWInit(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS status = CBIOS_OK; + CBIOS_U32 wait_us = 100, timeout = 10000, count = 0; + + if(!pcbe->bRunOnQT) + { + while (1) + { + if (cb_ReadU32(pcbe->pAdapterContext, 0xd370) == 0xdeadbeaf) + { + break; + } + + cb_DelayMicroSeconds(wait_us); + count++; + if (count > timeout) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: wait memory init time out\n", FUNCTION_NAME)); + break; + } + } + } + + if(cbHWIsChipPost(pcbe)) + { + cbUnlockSR(pcbe); + cbUnlockCR(pcbe); + } + else + { + status = cbPost(pcbe); + } + + status = cbInitChip(pcbe); + + if(status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbHWInit: post failed!\n")); + } + + return status; +} + + +CBIOS_VOID cbHWInitChipAttribute(PCBIOS_VOID pvcbe, CBIOS_U32 ChipID) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + cbInitChipAttribute_Arise(pcbe); +} + +CBIOS_BOOL cbHWIsChipPost(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 byTemp = 0; + CBIOS_U8 byResult = 0; + byTemp = cbMMIOReadReg(pcbe, CR_52); + if(0xA == byTemp) + { + byResult = 1; + } + return byResult; +} + +CBIOS_STATUS cbHWSetChipPostFlag(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS status = CBIOS_OK; + cbMMIOWriteReg(pcbe, CR_52, 0x0A, 0x0); + return status; +} + +CBIOS_BOOL cbHWIsChipEnable(PCBIOS_VOID pvcbe) +{ + CBIOS_U8 byTemp1 = 0, byTemp2 = 0; + CBIOS_U8 byResult = 0; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + byTemp1 = cb_ReadU8(pcbe->pAdapterContext, 0x850C) & 0x2; + byTemp2 = cb_ReadU8(pcbe->pAdapterContext, 0x83C3) & 0x01; + byResult = (byTemp1 >> 1) | byTemp2; + if(!byResult) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO),"Chip is not enable!\n")); + } + return byResult; +} + +CBIOS_STATUS cbHWSetMmioEndianMode(PCBIOS_VOID pAdapterContext) +{ + CBIOS_U32 crf0_c = cb_ReadU32(pAdapterContext, 0x8af0); + +#ifdef __BIG_ENDIAN__ + //here has a littel side effect when POST D3 as BE mode under BE system. + //If D3 has been POST BE mode and now POST it again,because D3 BE is enabled, + //fetched crf0_c[DW] will be byte swapped by BIU. so crf2_c[7] will be set 1 wrongly instead crf1_c[7]. + //but currently crf2_c[7] is reserved, so we can ignore it. + crf0_c |= 0x00800000;//enable d3 big endian mode +#else + crf0_c &= ~0x00008000; //enable d3 little endian mode +#endif + + cb_WriteU32(pAdapterContext, 0x8af0, crf0_c);//endian selection + + return CBIOS_OK; +} + + +CBIOS_STATUS cbHWUnload(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 byRomType = 0; + CBIOS_U8 byTemp = 0; + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + return CBIOS_ER_CHIPDISABLE; +#endif + + if(!pcbe->bMAMMPrimaryAdapter) + { + REG_CR37 RegCR37Mask; + //Harrison: + //VBios & CBios will invalid the Rom type after Post and save the + //correct Rom type into CRC8, so for Secondary adapter we need + //restore the correct Rom type for CR37 or the Vista's StartDevice() + //can not read RomImage again + + //CRC8 low 3bits is the rom type saved by CBios init code + byRomType = cbMMIOReadReg(pcbe, CR_C8) & 0x07; + byTemp = cbMMIOReadReg(pcbe, CR_37) & 0xF8; + RegCR37Mask.Value = 0xFF; + RegCR37Mask.reserved = 0; + cbMMIOWriteReg(pcbe,CR_37,byTemp|byRomType, RegCR37Mask.Value); + } + + cbDeInitDeviceArray(pcbe); + cbDispMgrDeInit(pcbe); + cbReleaseDebugBuffer(); + return CBIOS_OK; +} + +CBIOS_STATUS cbHWSetIgaScreenOnOffState(PCBIOS_VOID pvcbe, CBIOS_BOOL status, CBIOS_U8 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_CR71_Pair RegCR71Value; + REG_CR71_Pair RegCR71Mask; + REG_SR01 RegSR01Value; + REG_SR01 RegSR01Mask; + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + return CBIOS_ER_CHIPDISABLE; +#endif + + cbTraceEnter(GENERIC); + + if (status) //Screen On + { + RegCR71Value.Value = 0; + RegCR71Value.Screen_Off_Control_Select = 1; + RegCR71Value.Screen_Off = 0; + RegCR71Mask.Value = 0xFF; + RegCR71Mask.Screen_Off_Control_Select = 0; + RegCR71Mask.Screen_Off = 0; + cbBiosMMIOWriteReg(pcbe,CR_71, RegCR71Value.Value, RegCR71Mask.Value, IGAIndex); + } + else //Screen Off + { + cbWaitNonFullVBlank(pcbe, IGAIndex); + RegCR71Value.Value = 0; + RegCR71Value.Screen_Off_Control_Select = 1; + RegCR71Value.Screen_Off = 1; + RegCR71Mask.Value = 0xFF; + RegCR71Mask.Screen_Off_Control_Select = 0; + RegCR71Mask.Screen_Off = 0; + cbBiosMMIOWriteReg(pcbe,CR_71, RegCR71Value.Value, RegCR71Mask.Value, IGAIndex); + } + + if (IGAIndex == IGA1) + { + if (status) //Screen On + { + RegSR01Value.Value = 0; + RegSR01Value.Screen_Off = 0; + RegSR01Mask.Value = 0xFF; + RegSR01Mask.Screen_Off = 0; + cbMMIOWriteReg(pcbe,SR_01, RegSR01Value.Value, RegSR01Mask.Value); + } + else //Screen Off + { + RegSR01Value.Value = 0; + RegSR01Value.Screen_Off = 1; + RegSR01Mask.Value = 0xFF; + RegSR01Mask.Screen_Off = 0; + cbMMIOWriteReg(pcbe,SR_01, RegSR01Value.Value, RegSR01Mask.Value); + } + } + + cbTraceExit(GENERIC); + + return CBIOS_OK; +} + + +CBIOS_STATUS cbHWResetBlock(PCBIOS_VOID pvcbe, CBIOS_HW_BLOCK HWBlock) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_GAMMA_PARA GammaParam = {0}; + CBIOS_U32 i = 0; + CBIOS_U32 PSVsyncOffIndex[CBIOS_IGACOUNTS] = {0x81C4, 0x33908, 0x34008, 0x34708}; + CBIOS_U32 PSStrideIndex[CBIOS_IGACOUNTS] = {0x81C8, 0x3390C, 0x3400C, 0x3470C}; + CBIOS_U32 PSShadowIndex[CBIOS_IGACOUNTS] = {0x81FC, 0x33924, 0x34024, 0x34724}; + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + return CBIOS_ER_CHIPDISABLE; +#endif + + if(HWBlock == CBIOS_HW_IGA) + { + for(i = 0; i < pcbe->DispMgr.IgaCount; i++) + { + cbBiosMMIOWriteReg(pcbe, CR_67, 0x00, (CBIOS_U8)~0x0E, i); + cbMMIOWriteReg32(pcbe, PSVsyncOffIndex[i], 0, ~0x10000000); + cbMMIOWriteReg32(pcbe, PSStrideIndex[i], 0, 0); + cbMMIOWriteReg32(pcbe, PSShadowIndex[i], 0, ~0x0003FF81); + + //disable gamma + GammaParam.IGAIndex = i; + GammaParam.Flags.bDisableGamma = 1; + cbSetGamma(pcbe, &GammaParam); + } + + // Clear the CRBD[7] to let BIOS control the screen on/off + cbMMIOWriteReg(pcbe, CR_BD, 0x00, (CBIOS_U8)~0x80); + } + return CBIOS_OK; +} + + +CBIOS_STATUS cbHWDumpReg(PCBIOS_VOID pvcbe, PCBIOS_PARAM_DUMP_REG pCBParamDumpReg) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_S32 i; + CBIOS_UCHAR ch; + + cbUnlockSR(pcbe); + cbUnlockCR(pcbe); + + cb_WriteU16(pcbe->pAdapterContext, CB_CRT_ADDR_REG, 0xA039); + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_ADDR_REG, 0x35); + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_DATA_REG,(CBIOS_U8)(cb_ReadU8(pcbe->pAdapterContext, CB_CRT_DATA_REG)&0x0F)); + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_ADDR_REG, 0x11); + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_DATA_REG,(CBIOS_U8)(cb_ReadU8(pcbe->pAdapterContext, CB_CRT_DATA_REG)&0x7F)); + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\nSR registers:")); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\n 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F")); + cb_WriteU16(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x4026); + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x2A); + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG, cb_ReadU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG)&~0x08); + for (i=0; ipAdapterContext, CB_SEQ_ADDR_REG, (CBIOS_U8)i); + ch = cb_ReadU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), " %02X", ch)); + } + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\nCR registers:")); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\n 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F")); + for (i=0; ipAdapterContext, CB_CRT_ADDR_REG, (CBIOS_U8)i); + ch = cb_ReadU8(pcbe->pAdapterContext, CB_CRT_DATA_REG); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), " %02X", ch)); + } + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\nCR_B registers:")); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\n 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F")); + //Switch to CR_B + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x2A); + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG,(CBIOS_U8)(cb_ReadU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG)|0x08)); + for (i=0xc0; i>4)); + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_ADDR_REG, (CBIOS_U8)i); + ch = cb_ReadU8(pcbe->pAdapterContext, CB_CRT_DATA_REG); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), " %02X", ch)); +// cbDebugPrint((DBG_LEVEL_ERROR_MSG, " %2x", ch)); + } + //Switch back + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x2A); + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG,(CBIOS_U8)(cb_ReadU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG)&~0x08)); + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\nCR_C registers:")); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\n 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F")); + //Switch to CR_C + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x2A); + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG,(CBIOS_U8)(cb_ReadU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG)|0x04)); + for (i=0x0; i>4)); + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_ADDR_REG, (CBIOS_U8)i); + ch = cb_ReadU8(pcbe->pAdapterContext, CB_CRT_DATA_REG); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), " %02X", ch)); +// cbDebugPrint((DBG_LEVEL_ERROR_MSG, " %2x", ch)); + } + //Switch back + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x2A); + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG,(CBIOS_U8)(cb_ReadU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG)&~0x04)); + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\nCR_D registers:")); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\n 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F")); + //Switch to CR_D + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x2A); + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG,(CBIOS_U8)(cb_ReadU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG)|0x46)); + for (i=0x0; i>4)); + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_ADDR_REG, (CBIOS_U8)i); + ch = cb_ReadU8(pcbe->pAdapterContext, CB_CRT_DATA_REG); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), " %02X", ch)); + //cbDebugPrint((DBG_LEVEL_ERROR_MSG, " %2x", ch)); + } + //Switch back + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x2A); + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG,(CBIOS_U8)(cb_ReadU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG)&~0x46)); + + //Switch to Paired SR, CR + cb_WriteU16(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x4E26); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\nPaired SR registers:")); + for (i=0; i>4)); + cb_WriteU8(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, (CBIOS_U8)i); + ch = cb_ReadU8(pcbe->pAdapterContext, CB_SEQ_DATA_REG); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), " %02X", ch)); +// cbDebugPrint((DBG_LEVEL_ERROR_MSG, " %2x", ch)); + } + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "\nPaired CR registers:")); + for (i=0; i>4)); + cb_WriteU8(pcbe->pAdapterContext, CB_CRT_ADDR_REG, (CBIOS_U8)i); + ch = cb_ReadU8(pcbe->pAdapterContext, CB_CRT_DATA_REG); + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), " %02X", ch)); +// cbDebugPrint((DBG_LEVEL_ERROR_MSG, " %2x", ch)); + } + //Switch back + cb_WriteU16(pcbe->pAdapterContext, CB_SEQ_ADDR_REG, 0x4026); + return CBIOS_OK; + +} + + +CBIOS_STATUS cbHWReadReg(PCBIOS_VOID pvcbe, CBIOS_U8 type, CBIOS_U8 index, PCBIOS_U8 result) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + *result = cbMMIOReadReg(pcbe, (((CBIOS_U16)type<<8)|index)); + return CBIOS_OK; +} + +CBIOS_STATUS cbHWWriteReg(PCBIOS_VOID pvcbe, CBIOS_U8 type, CBIOS_U8 index, CBIOS_U8 value, CBIOS_U8 mask) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + cbMMIOWriteReg(pcbe, (((CBIOS_U16)type<<8)|index), value, mask); + return CBIOS_OK; +} + + +//can only read one segment at most for one time. +CBIOS_BOOL cbHWReadEDID(PCBIOS_VOID pvcbe, CBIOS_U8 I2CBUSNum, CBIOS_U8 EDIDData[], CBIOS_U32 ulReadEdidOffset, CBIOS_U32 ulBufferSize, CBIOS_U8 nSegNum) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bRet = CBIOS_FALSE; + CBIOS_U8 HDCP_Port,HDCP_Port2; + CBIOS_U32 ulHDCPNum = 0; + PCBIOS_VOID pAp = pcbe->pAdapterContext; + CBIOS_BOOL bHdcpDisabled = CBIOS_TRUE; + + HDCP_Port=cbMMIOReadReg(pcbe, CR_AA);//HDCP1 + HDCP_Port2=cbMMIOReadReg(pcbe, CR_B_C6);//HDCP2 + HDCP_Port >>= 6; + HDCP_Port2 >>= 6; + + cb_AcquireMutex(pcbe->pI2CMutex[I2CBUSNum]); + + #if HDCP_ENABLE + //if HDCP1 enable and Call HDCP1 I2CBus + if((HDCP_Port == I2CBUSNum)&& + (cb_ReadU32(pAp,HDCPCTL2_DEST)&HDCP_I2C_ENABLE_DEST)) + { + ulHDCPNum = HDCP1; + } + //if HDCP2 enable and Call HDCP2 I2CBus + else if((HDCP_Port2 ==I2CBUSNum)&& + (cb_ReadU32(pAp,HDCP2_CTL2_DEST)&HDCP_I2C_ENABLE_DEST)) + { + ulHDCPNum = HDCP2; + } + + if(ulHDCPNum != 0) + { + bRet = cbHDCPProxyGetEDID(pcbe, EDIDData, ulReadEdidOffset, ulBufferSize, ulHDCPNum, nSegNum); + } + #endif + + if(!bRet) + { + if(ulHDCPNum != 0) //if HDCP is enabled. + bHdcpDisabled = cbDisableHdcp(pcbe, ulHDCPNum); + + if(bHdcpDisabled) + { + //if cannot use HDCP to getEDID,use normal I2C method to get EDID + bRet = cbNormalI2cGetEDID(pcbe, I2CBUSNum, EDIDData, ulReadEdidOffset, ulBufferSize, nSegNum); + + if(ulHDCPNum != 0) //if HDCP is enabled. + cbEnableHdcpStatus(pcbe, ulHDCPNum); + } + } + + cb_ReleaseMutex(pcbe->pI2CMutex[I2CBUSNum]); + + return bRet; +} + +CBIOS_STATUS cbHWGetClockByType(PCBIOS_VOID pvcbe, PCBios_GetClock_Params pCBiosGetClockParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + cbGetProgClock(pcbe, pCBiosGetClockParams->ClockFreq, pCBiosGetClockParams->ClockType); + + // change ClockFreq unit to KHz + *pCBiosGetClockParams->ClockFreq /= 10; + + return CBIOS_OK; +} + + +//in func cbHWSetClockByType we can set ICLK and VCLK now. +CBIOS_STATUS cbHWSetClockByType(PCBIOS_VOID pvcbe, PCBios_SetClock_Params pCBiosSetClockParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS status = CBIOS_OK; + switch(pCBiosSetClockParams->ClockType) + { + case CBIOS_ICLKTYPE: + cbProgClock(pcbe, pCBiosSetClockParams->ClockFreq, pCBiosSetClockParams->ClockType, IGA1); + break; + case CBIOS_ECLKTYPE: + cbProgClock(pcbe, pCBiosSetClockParams->ClockFreq, pCBiosSetClockParams->ClockType, IGA1); + break; + + case CBIOS_CPUFRQTYPE: + cbProgClock(pcbe, pCBiosSetClockParams->ClockFreq, pCBiosSetClockParams->ClockType, IGA1); + break; + + case CBIOS_VCLKTYPE: + cbProgClock(pcbe, pCBiosSetClockParams->ClockFreq, pCBiosSetClockParams->ClockType, IGA1); + break; + + case CBIOS_DCLK1TYPE: + cbProgramDclk(pcbe, IGA1, pCBiosSetClockParams->ClockFreq); + break; + + case CBIOS_DCLK2TYPE: + cbProgramDclk(pcbe, IGA2, pCBiosSetClockParams->ClockFreq); + break; + + case CBIOS_DCLK3TYPE: + cbProgramDclk(pcbe, IGA3, pCBiosSetClockParams->ClockFreq); + break; + + case CBIOS_DCLK4TYPE: + cbProgramDclk(pcbe, IGA4, pCBiosSetClockParams->ClockFreq); + break; + + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbHWSetClockByType: Your ClockType error.\n")); + status = CBIOS_ER_INVALID_PARAMETER; + break; + } + return status; +} + +static CBREGISTER_IDX PCIDeviceRevTable[] = { + { CR_C_82, 0xff}, //CR82_C + { CR_C_83, 0xff}, //CR83_C + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX PCIDeviceIDTable[] = { + { CR_C_81, 0xFF}, //CR81_C + { CR_C_80, 0xFF}, //CR80_C + { MAPMASK_EXIT}, +}; + +CBIOS_STATUS cbHwSyncDataWithVbios(PCBIOS_VOID pvcbe, PCBIOS_VBIOS_DATA_PARAM pDataPara) +{ + CBIOS_U32 i; + CBIOS_U32 ActiveDevices = 0; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_GET_DEV_COMB GetDevComb = {0}; + CBIOS_DEVICE_COMB DeviceComb = {0}; + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + return CBIOS_ER_CHIPDISABLE; +#endif + if(pDataPara != CBIOS_NULL) + { + if(pDataPara->SyncToVbios) + { + + } + else + { + ActiveDevices = cbHwGetActDeviceFromReg(pcbe); + ActiveDevices &= (~CBIOS_TYPE_DUOVIEW); + + //update active device from hibernation using CR6B,CR6C + GetDevComb.Size = sizeof(CBIOS_GET_DEV_COMB); + GetDevComb.pDeviceComb = &DeviceComb; + DeviceComb.Devices = ActiveDevices; + cbPathMgrGetDevComb(pcbe, &GetDevComb); + pcbe->DispMgr.ActiveDevices[IGA1] = DeviceComb.Iga1Dev; + pcbe->DispMgr.ActiveDevices[IGA2] = DeviceComb.Iga2Dev; + pcbe->DispMgr.ActiveDevices[IGA3] = DeviceComb.Iga3Dev; + pcbe->DispMgr.ActiveDevices[IGA4] = DeviceComb.Iga4Dev; + + for (i = 0; i < CBIOS_MAX_DEVICE_BITS; i++) + { + if ((1u << i) & ActiveDevices) + { + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, ((1u << i) & ActiveDevices)); + if (pDevCommon) + { + pDevCommon->PowerState = CBIOS_PM_ON; + } + } + } + } + return CBIOS_OK; + } + else + { + cbDebugPrint((0, "CBiosSyncDataWithVbios_dst: null pointer is transfered!\n")); + return CBIOS_ER_NULLPOINTER; + } +} + +CBIOS_STATUS cbHWGetVBiosInfo(PCBIOS_VOID pvcbe, PCBIOS_VBINFO_PARAM pVbiosInfo) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 size = 0; + + if(CBIOS_NULL == pVbiosInfo) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),("cbHWGetVBiosInfo: pVbiosInfo is CBIOS_NULL!\n"))); + return CBIOS_ER_NULLPOINTER; + } + + // to see if driver is older or newer than cbios version, get min size + size = (pVbiosInfo->Size < sizeof(CBIOS_VBINFO_PARAM)) ? + pVbiosInfo->Size : sizeof(CBIOS_VBINFO_PARAM); + + // clear ELD buffer with min size + cb_memset(pVbiosInfo, 0, size); + + pVbiosInfo->Size = size; + + pVbiosInfo->BiosVersion = pcbe->BiosVersion; + + pVbiosInfo->FBSize = pcbe->SysBiosInfo.FBSize; + + + //Get Revision ID / Device ID + pVbiosInfo->RevisionID = cbMapMaskRead(pcbe,PCIDeviceRevTable, CBIOS_NOIGAENCODERINDEX) & 0xFFFF; + pVbiosInfo->DeviceID = cbMapMaskRead(pcbe,PCIDeviceIDTable, CBIOS_NOIGAENCODERINDEX) & 0xFFFF; + + pVbiosInfo->SupportDev = pcbe->DeviceMgr.SupportDevices; + pVbiosInfo->PortSplitSupport = pcbe->PortSplitSupport & pVbiosInfo->SupportDev; + pVbiosInfo->HPDDevicesMask = pcbe->HPDDeviceMasks; + pVbiosInfo->BootDevInCMOS = pcbe->SysBiosInfo.BootUpDev; + pVbiosInfo->PollingDevMask = 0; + if (pcbe->DeviceMgr.SupportDevices & CBIOS_TYPE_CRT) + { + pVbiosInfo->PollingDevMask |= CBIOS_TYPE_CRT; + } + + pVbiosInfo->bNoHDCPSupport = CBIOS_FALSE; + + pVbiosInfo->NonSimulChip = pcbe->FeatureSwitch.bNonSimulChip; + + if (pVbiosInfo->Size >= SIZEOF_STRUCT_TILL_MEMBER(pVbiosInfo, TotalMemSize)) + { + cbHwGetMemInfo(pcbe, pVbiosInfo); + } + + cb_memcpy(pVbiosInfo->PMPVer,pcbe->PMPVer,sizeof(pcbe->PMPVer)); + pVbiosInfo->FwVersion = pcbe->FwVersion; + cb_memcpy(pVbiosInfo->FwName, pcbe->FwName, sizeof(pcbe->FwName)); + + if(cbNeedSetHdaudioToLocal(pcbe)) + { + pVbiosInfo->HdaudioToLocal = 1; + } + + return CBIOS_OK; +} + + +CBIOS_STATUS cbHWI2CDataRead(PCBIOS_VOID pvcbe, PCBIOS_PARAM_I2C_DATA pCBParamI2CData) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 PortNumber, SlaveAddr, Offset; + CBIOS_U8* DataBuffer; + CBIOS_U32 BufferSize, Flags, RequestType; + CBIOS_BOOL bRet=CBIOS_FALSE,DDC=CBIOS_FALSE; + CBIOS_STATUS status = CBIOS_ER_INVALID_PARAMETER; + CBIOS_U8 HDCP_Port,HDCP_Port2,HDCP_Port3,HDCP_Port4; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_MODULE_I2C_PARAMS I2CParams; + cb_memset(&I2CParams, 0, sizeof(CBIOS_MODULE_I2C_PARAMS)); + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + return CBIOS_ER_CHIPDISABLE; +#endif + + if (pCBParamI2CData->bUseDevType)//user PortType to get i2c bus + { + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, pCBParamI2CData->DeviceId); + PortNumber = (CBIOS_U8)pDevCommon->I2CBus; + if ((pCBParamI2CData->DeviceId & ALL_DP_TYPES) && + cbDPPort_IsDeviceInDpMode(pcbe, pDevCommon)) + { + if (pCBParamI2CData->DeviceId == CBIOS_TYPE_DP1) + { + PortNumber = I2CBUS_VIRTUAL_DP1; + } + else if (pCBParamI2CData->DeviceId == CBIOS_TYPE_DP2) + { + PortNumber = I2CBUS_VIRTUAL_DP2; + } + else if (pCBParamI2CData->DeviceId == CBIOS_TYPE_DP3) + { + PortNumber = I2CBUS_VIRTUAL_DP3; + } + else if (pCBParamI2CData->DeviceId == CBIOS_TYPE_DP4) + { + PortNumber = I2CBUS_VIRTUAL_DP4; + } + + } + + } + else//driver directly send i2c bus + { + PortNumber = (CBIOS_U8)pCBParamI2CData->PortNumber; + } + + SlaveAddr = pCBParamI2CData->SlaveAddress; + BufferSize = pCBParamI2CData->BufferLen; + DataBuffer = pCBParamI2CData->Buffer; + Flags = pCBParamI2CData->Flags; + Offset = pCBParamI2CData->OffSet; + RequestType = pCBParamI2CData->RequestType; + + I2CParams.ConfigType = CONFIG_I2C_BY_BUSNUM; + I2CParams.I2CBusNum = PortNumber; + I2CParams.SlaveAddress = pCBParamI2CData->SlaveAddress; + I2CParams.OffSet = pCBParamI2CData->OffSet; + I2CParams.BufferLen = pCBParamI2CData->BufferLen; + I2CParams.Buffer = pCBParamI2CData->Buffer; + I2CParams.Flags = pCBParamI2CData->Flags; + + cbWritePort80(pcbe,CBIOS_PORT80_ID_CBiosI2CDataRead_Enter); + cb_memset(DataBuffer,0,BufferSize); + + #if HDCP_ENABLE + if(pCBParamI2CData->bHDCPEnable) + { + HDCP_Port = cbMMIOReadReg(pcbe, CR_AA);//HDCP1 + HDCP_Port2= cbMMIOReadReg(pcbe, CR_B_C6);//HDCP2 + HDCP_Port3= cbMMIOReadReg(pcbe,CR_B_F8);//HDCP3 + HDCP_Port4= cbMMIOReadReg(pcbe,CR_B_C5);//HDCP4 + HDCP_Port >>= 6; + HDCP_Port2 >>= 6; + HDCP_Port3 >>= 6; + HDCP_Port4 >>= 6; + + //if HDCP1 enable and Call HDCP1 I2CBus + if((HDCP_Port == PortNumber)&& + (cb_ReadU32(pcbe->pAdapterContext,HDCPCTL2_DEST)&HDCP_I2C_ENABLE_DEST)) + { + bRet=cbHDCPDDCciPortRead(pcbe,(CBIOS_U8)SlaveAddr, (CBIOS_U8)Offset, (PCBIOS_UCHAR)DataBuffer, BufferSize,HDCP1); + } + //if HDCP2 enable and Call HDCP2 I2CBus + else if((HDCP_Port2 == PortNumber)&& + (cb_ReadU32(pcbe->pAdapterContext,HDCP2_CTL2_DEST)&HDCP_I2C_ENABLE_DEST)) + { + bRet=cbHDCPDDCciPortRead(pcbe,(CBIOS_U8)SlaveAddr, (CBIOS_U8)Offset, (PCBIOS_UCHAR)DataBuffer, BufferSize,HDCP2); + } + else if ((HDCP_Port3 == PortNumber)&& + (cb_ReadU32(pcbe->pAdapterContext,HDCP3_CTL2_DEST)&HDCP_I2C_ENABLE_DEST)) + { + bRet=cbHDCPDDCciPortRead(pcbe,(CBIOS_U8)SlaveAddr, (CBIOS_U8)Offset, (PCBIOS_UCHAR)DataBuffer, BufferSize,HDCP3); + } + else if ((HDCP_Port4 == PortNumber)&& + (cb_ReadU32(pcbe->pAdapterContext,HDCP4_CTL2_DEST)&HDCP_I2C_ENABLE_DEST)) + { + bRet=cbHDCPDDCciPortRead(pcbe,(CBIOS_U8)SlaveAddr, (CBIOS_U8)Offset, (PCBIOS_UCHAR)DataBuffer, BufferSize,HDCP4); + } + else//when two device plug and only one of them enable HDCP,the other device should use I2CDDC + DDC=CBIOS_TRUE;//status will be updated in DDC + status = (bRet ? CBIOS_OK : CBIOS_ER_INVALID_PARAMETER); + } + #endif + + if(DDC || (pCBParamI2CData->bHDCPEnable == 0)) //DDC + { + if(RequestType == CBIOS_I2CDDCCI) + { + status = cbI2CModule_ReadDDCCIData(pcbe, &I2CParams, Flags); + } + else if (RequestType == CBIOS_I2CCAPTURE) + { + bRet = cbI2CModule_ReadData(pcbe, &I2CParams); + status = (bRet ? CBIOS_OK : CBIOS_ER_INTERNAL); + } + else + { + bRet = cbI2CModule_ReadData(pcbe, &I2CParams); + status = (bRet ? CBIOS_OK : CBIOS_ER_INTERNAL); + } + } + cbWritePort80(pcbe,CBIOS_PORT80_ID_CBiosI2CDataRead_Exit); + if(status != CBIOS_OK) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbHWI2CDataRead: function failure!\n")); + } + return status; +} + + +CBIOS_STATUS cbHWI2CDataWrite(PCBIOS_VOID pvcbe, PCBIOS_PARAM_I2C_DATA pCBParamI2CData) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U8 PortNumber, SlaveAddr, Offset; + CBIOS_U8* DataBuffer; + CBIOS_U32 BufferSize, RequestType; + CBIOS_BOOL bRet=CBIOS_FALSE,DDC=CBIOS_FALSE; + CBIOS_STATUS status = CBIOS_ER_INVALID_PARAMETER; + CBIOS_U8 HDCP_Port,HDCP_Port2,HDCP_Port3,HDCP_Port4; + CBIOS_MODULE_I2C_PARAMS I2CParams; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + cb_memset(&I2CParams, 0, sizeof(CBIOS_MODULE_I2C_PARAMS)); + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + return CBIOS_ER_CHIPDISABLE; +#endif + + if (pCBParamI2CData->bUseDevType)//user PortType to get i2c bus + { + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, pCBParamI2CData->DeviceId); + PortNumber = (CBIOS_U8)pDevCommon->I2CBus; + if ((pCBParamI2CData->DeviceId & ALL_DP_TYPES) && + cbDPPort_IsDeviceInDpMode(pcbe, pDevCommon)) + { + if (pCBParamI2CData->DeviceId == CBIOS_TYPE_DP1) + { + PortNumber = I2CBUS_VIRTUAL_DP1; + } + else if (pCBParamI2CData->DeviceId == CBIOS_TYPE_DP2) + { + PortNumber = I2CBUS_VIRTUAL_DP2; + } + else if (pCBParamI2CData->DeviceId == CBIOS_TYPE_DP3) + { + PortNumber = I2CBUS_VIRTUAL_DP3; + } + else if (pCBParamI2CData->DeviceId == CBIOS_TYPE_DP4) + { + PortNumber = I2CBUS_VIRTUAL_DP4; + } + + } + } + else//driver directly send i2c bus + { + PortNumber = (CBIOS_U8)pCBParamI2CData->PortNumber; + } + + SlaveAddr = pCBParamI2CData->SlaveAddress; + BufferSize = pCBParamI2CData->BufferLen; + DataBuffer = pCBParamI2CData->Buffer; + Offset = pCBParamI2CData->OffSet; + RequestType = pCBParamI2CData->RequestType; + + I2CParams.ConfigType = CONFIG_I2C_BY_BUSNUM; + I2CParams.I2CBusNum = PortNumber; + I2CParams.SlaveAddress = pCBParamI2CData->SlaveAddress; + I2CParams.OffSet = pCBParamI2CData->OffSet; + I2CParams.BufferLen = pCBParamI2CData->BufferLen; + I2CParams.Buffer = pCBParamI2CData->Buffer; + + cbWritePort80(pcbe,CBIOS_PORT80_ID_CBiosI2CDataWrite_Enter); + + #if HDCP_ENABLE + if(pCBParamI2CData->bHDCPEnable)//HDCP + { + HDCP_Port=cbMMIOReadReg(pcbe, CR_AA);//HDCP1 + HDCP_Port2=cbMMIOReadReg(pcbe, CR_B_C6);//HDCP2 + HDCP_Port3= cbMMIOReadReg(pcbe,CR_B_F8);//HDCP3 + HDCP_Port4= cbMMIOReadReg(pcbe,CR_B_C5);//HDCP4 + HDCP_Port >>= 6; + HDCP_Port2 >>= 6; + HDCP_Port3 >>= 6; + HDCP_Port4 >>= 6; + + //if HDCP1 enable and Call HDCP1 I2CBus + if((HDCP_Port == PortNumber)&& + (cb_ReadU32(pcbe->pAdapterContext,HDCPCTL2_DEST)&HDCP_I2C_ENABLE_DEST)) + { + bRet=cbHDCPDDCciPortWrite(pcbe,(CBIOS_U8)SlaveAddr, (CBIOS_U8)Offset, (PCBIOS_UCHAR)DataBuffer, BufferSize,HDCP1); + } + //if HDCP2 enable and Call HDCP2 I2CBus + else if((HDCP_Port2 ==PortNumber)&& + (cb_ReadU32(pcbe->pAdapterContext,HDCP2_CTL2_DEST)&HDCP_I2C_ENABLE_DEST)) + { + bRet=cbHDCPDDCciPortWrite(pcbe,(CBIOS_U8)SlaveAddr, (CBIOS_U8)Offset, (PCBIOS_UCHAR)DataBuffer, BufferSize,HDCP2); + } + else if ((HDCP_Port3 == PortNumber)&& + (cb_ReadU32(pcbe->pAdapterContext,HDCP3_CTL2_DEST)&HDCP_I2C_ENABLE_DEST)) + { + bRet=cbHDCPDDCciPortWrite(pcbe,(CBIOS_U8)SlaveAddr, (CBIOS_U8)Offset, (PCBIOS_UCHAR)DataBuffer, BufferSize,HDCP3); + } + else if ((HDCP_Port4 == PortNumber)&& + (cb_ReadU32(pcbe->pAdapterContext,HDCP4_CTL2_DEST)&HDCP_I2C_ENABLE_DEST)) + { + bRet=cbHDCPDDCciPortWrite(pcbe,(CBIOS_U8)SlaveAddr, (CBIOS_U8)Offset, (PCBIOS_UCHAR)DataBuffer, BufferSize,HDCP4); + } + else//when two device plug and one enable HDCP,the other device should use I2CDDC + DDC=CBIOS_TRUE;//status will be updated in DDC + status = (bRet ? CBIOS_OK : CBIOS_ER_INVALID_PARAMETER); + } + #endif + + if(DDC || (pCBParamI2CData->bHDCPEnable == 0)) //DDC + { + if(RequestType == CBIOS_I2CDDCCI) + { + bRet = cbI2CModule_WriteDDCCIData(pcbe, &I2CParams); + } + else if (RequestType == CBIOS_I2CCAPTURE) + { + bRet = cbI2CModule_WriteData(pcbe, &I2CParams); + } + else + { + bRet = cbI2CModule_WriteData(pcbe, &I2CParams); + } + status = (bRet ? CBIOS_OK : CBIOS_ER_INTERNAL); + } + cbWritePort80(pcbe,CBIOS_PORT80_ID_CBiosI2CDataWrite_Exit); + if(!(status==CBIOS_OK)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbHWI2CDataWrite: function failure!\n")); + } + return status; +} + + +CBIOS_BOOL cbHWDumpInfo(PCBIOS_VOID pvcbe, CBIOS_DUMP_TYPE DumpType) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + if (DumpType & CBIOS_DUMP_VCP_INFO) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),"can't dump VCP info!\n")); + DumpType &= (~CBIOS_DUMP_VCP_INFO); + } + if (DumpType & CBIOS_DUMP_MODE_INFO) + { + cbDumpModeInfo(pcbe); + DumpType &= (~CBIOS_DUMP_MODE_INFO); + } + if (DumpType & CBIOS_DUMP_CLOCK_INFO) + { + cbDumpClockInfo(pcbe); + DumpType &= (~CBIOS_DUMP_CLOCK_INFO); + } + + cbDumpRegisters(pcbe, DumpType); + + return CBIOS_TRUE; +} + + +CBIOS_STATUS cbHWSetWriteback(PCBIOS_VOID pvcbe, PCBIOS_WB_PARA pWBPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + return cbSetWriteback(pcbe, pWBPara); +} + +CBIOS_STATUS cbHWCECTransmitMessage(PCBIOS_VOID pvcbe, PCBIOS_CEC_MESSAGE pCECMessage, CBIOS_CEC_INDEX CECIndex) +{ + CBIOS_U32 CECMiscReg1Index = 0, CECMiscReg2Index = 0, CECInitiatorCmdRegIndex = 0; + CEC_MISC_REG1 CECMiscReg1; + CEC_MISC_REG2 CECMiscReg2; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 CMDData = 0; + CBIOS_U8 i = 0; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + if (pCECMessage == CBIOS_NULL) + { + Status = CBIOS_ER_NULLPOINTER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbHWCECTransmitMessage: pCECMessage is NULL!")); + } + else if (!pcbe->ChipCaps.IsSupportCEC) + { + Status = CBIOS_ER_HARDWARE_LIMITATION; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbHWCECTransmitMessage: Can't support CEC!")); + } + else if (CECIndex >= CBIOS_CEC_INDEX_COUNT) + { + Status = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbHWCECTransmitMessage: invalid CEC index!")); + } + else if (!pcbe->CECPara[CECIndex].CECEnable) + { + Status = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbHWCECTransmitMessage: CEC module is not enabled!")); + } + else + { + CECMiscReg1Index = CECMiscReg1Tab[CECIndex]; + CECInitiatorCmdRegIndex = CECInitiatorCmdTab[CECIndex]; + CECMiscReg2Index = CECMiscReg2Tab[CECIndex]; + + //load command + //write consequently, 4 bytes 1 time. + //Byte0 | Byte1 | Byte2 | Byte3 + if (pCECMessage->CmdLen != 0) + { + for (i = 0; i < pCECMessage->CmdLen / 4; i++) + { + CMDData = ((CBIOS_U32)pCECMessage->Command[i * 4] << 24) + ((CBIOS_U32)pCECMessage->Command[i * 4 + 1] << 16) + + ((CBIOS_U32)pCECMessage->Command[i * 4 + 2] << 8) + (CBIOS_U32)pCECMessage->Command[i * 4 + 3]; + + //MM3314c/MM33190 has 4 dwords. Every read/write operation will increase register index by 1 + //so remember that DO NOT add any other r/w operations here!!! + cb_WriteU32(pcbe->pAdapterContext, CECInitiatorCmdRegIndex, CMDData); + } + //get remained bytes + if ((pCECMessage->CmdLen % 4) != 0) + { + CMDData = 0; + for (i = 0; i < pCECMessage->CmdLen % 4; i++) + { + CMDData |= (CBIOS_U32)pCECMessage->Command[i] << ((3 - i) * 8); + } + //MM3314c/MM33190 has 4 dwords. Every read/write operation will increase register index by 1 + //so remember that DO NOT add any other r/w operations here!!! + cb_WriteU32(pcbe->pAdapterContext, CECInitiatorCmdRegIndex, CMDData); + + } + + } + + //clear Follower_Received_Ready to receive next command + //if we have received a message but not handled before transmit, + //Follower_Received_Ready will be set, then we may miss the reply message + cb_memset(&CECMiscReg2, 0, sizeof(CECMiscReg2)); + CECMiscReg2.FolReceiveReady = 0; + cbMMIOWriteReg32(pcbe, CECMiscReg2Index, CECMiscReg2.CECMiscReg2Value, ~BIT13); + + cb_memset(&CECMiscReg1, 0, sizeof(CECMiscReg1)); + + //logical address + CECMiscReg1.DeviceAddr = pCECMessage->SourceAddr; + + //config retry times + CECMiscReg1.IniRetryCnt = pCECMessage->RetryCnt; + + //set initiator destination address + CECMiscReg1.IniDestAddr = pCECMessage->DestAddr; + + //set initiator command length + CECMiscReg1.IniCmdLen = pCECMessage->CmdLen; + + //set initiator command type + if (pCECMessage->bBroadcast) + { + CECMiscReg1.IniBroadcast = 1; + } + else + { + CECMiscReg1.IniBroadcast = 0; + } + + + //start transmission + CECMiscReg1.IniCmdAvailable = 1; + cbMMIOWriteReg32(pcbe, CECMiscReg1Index, CECMiscReg1.CECMiscReg1Value, 0xFFF60000); + + + //wait for transmit done + for (i = 0; i < 100; i++) + { + + CECMiscReg2.CECMiscReg2Value = cb_ReadU32(pcbe->pAdapterContext, CECMiscReg2Index); + if (CECMiscReg2.IniTransFinish && CECMiscReg2.IniTransSucceed) + { + break; + } + else + { + cb_DelayMicroSeconds(4000); + //we'd better use sleep instead of delay here to avoid kernel soft lock error + //cbSleepMilliSeconds(10000); + } + } + if (CECMiscReg2.IniTransFinish && CECMiscReg2.IniTransSucceed) + { + Status = CBIOS_OK; + } + else + { + cbDebugPrint((DBG_LEVEL_ERROR_MSG, "cbHWCECTransmitMessage: Message transmission fail!\n")); + Status = CBIOS_ER_INTERNAL; + } + + //clear transmit finish and succeed bits + CECMiscReg2.IniTransFinish = 0; + CECMiscReg2.IniTransSucceed = 0; + cbMMIOWriteReg32(pcbe, CECMiscReg2Index, CECMiscReg2.CECMiscReg2Value, 0xFFFFFFFC); + + } + + + + return Status; + +} + + +CBIOS_STATUS cbHWCECReceiveMessage(PCBIOS_VOID pvcbe, PCBIOS_CEC_MESSAGE pCECMessage, CBIOS_CEC_INDEX CECIndex) +{ + CBIOS_U32 CECMiscReg2Index = 0, CECFollowerCmdRegIndex = 0; + CEC_MISC_REG2 CECMiscReg2; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 CMDData = 0; + CBIOS_U8 i = 0; + CBIOS_U8 *pTmpCommand = CBIOS_NULL; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + if (pCECMessage == CBIOS_NULL) + { + Status = CBIOS_ER_NULLPOINTER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbHWCECReceiveMessage: pCECMessage is NULL!")); + } + else if (!pcbe->ChipCaps.IsSupportCEC) + { + Status = CBIOS_ER_HARDWARE_LIMITATION; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbHWCECReceiveMessage: Can't support CEC!")); + } + else if (CECIndex >= CBIOS_CEC_INDEX_COUNT) + { + Status = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbHWCECReceiveMessage: invalid CEC index!")); + } + else if (!pcbe->CECPara[CECIndex].CECEnable) + { + Status = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbHWCECReceiveMessage: CEC module is not enabled!")); + } + else + { + + //CECMiscReg1Index = CECMiscReg1Tab[CECIndex]; + CECMiscReg2Index = CECMiscReg2Tab[CECIndex]; + CECFollowerCmdRegIndex = CECFollowerCmdTab[CECIndex]; + + //check whether a transaction has been successfully received. + CECMiscReg2.CECMiscReg2Value = cb_ReadU32(pcbe->pAdapterContext, CECMiscReg2Index); + if (CECMiscReg2.FolReceiveReady) + { + //The source address received by CEC Follower. + pCECMessage->SourceAddr = (CBIOS_U8)CECMiscReg2.FolSrcAddr; + + //transaction type + pCECMessage->bBroadcast = CECMiscReg2.FolBroadcast == 1 ? CBIOS_TRUE : CBIOS_FALSE; + + //Follower received command length + pCECMessage->CmdLen = CECMiscReg2.FolCmdLen; + + //get command data + //write consequently, 4 bytes 1 time. + //Byte0 | Byte1 | Byte2 | Byte3 + cb_memset(pCECMessage->Command, 0, sizeof(pCECMessage->Command)); + pTmpCommand = pCECMessage->Command; + + if (pCECMessage->CmdLen != 0) + { + for (i = 0; i < pCECMessage->CmdLen / 4; i++) + { + CMDData = cb_ReadU32(pcbe->pAdapterContext, CECFollowerCmdRegIndex); + *(pTmpCommand++) = (CBIOS_U8)((CMDData >> 24) & 0x000000FF); + *(pTmpCommand++) = (CBIOS_U8)((CMDData >> 16) & 0x000000FF); + *(pTmpCommand++) = (CBIOS_U8)((CMDData >> 8) & 0x000000FF); + *(pTmpCommand++) = (CBIOS_U8)(CMDData & 0x000000FF); + + } + //get remained bytes + if ((pCECMessage->CmdLen % 4) != 0) + { + CMDData = cb_ReadU32(pcbe->pAdapterContext, CECFollowerCmdRegIndex); + for (i = 0; i < pCECMessage->CmdLen % 4; i++) + { + *(pTmpCommand++) = (CBIOS_U8)((CMDData >> ((3 - i) * 8)) & 0x000000FF); + } + } + } + + Status = CBIOS_OK; + + } + else + { + cbDebugPrint((DBG_LEVEL_ERROR_MSG, "cbHWCECReceiveMessage: Message receive fail!\n")); + Status = CBIOS_ER_INTERNAL; + } + + //clear received command + CECMiscReg2.FolReceiveReady = 0; + cbMMIOWriteReg32(pcbe, CECMiscReg2Index, CECMiscReg2.CECMiscReg2Value, ~BIT13); + + + } + + return Status; + +} + + +CBIOS_STATUS cbHwI2CDDCCIOpen(PCBIOS_VOID pvcbe, CBIOS_BOOL bOpen, PCBIOS_I2CCONTROL pI2CControl, CBIOS_U8 I2CBUSNum) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + return cbI2CModule_DDCCI_OPEN(pcbe, bOpen, pI2CControl, I2CBUSNum); +} + + +CBIOS_STATUS cbHwI2CDDCCIAccess(PCBIOS_VOID pvcbe, PCBIOS_I2CCONTROL pI2CControl, CBIOS_U8 I2CBUSNum) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + return cbI2CModule_DDCCI_ACCESS(pcbe, pI2CControl, I2CBUSNum); +} + +CBIOS_VOID cbHwUpdateActDeviceToReg(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + cbIGA_UpdateActiveDeviceToReg(pcbe, pDispMgr); +} + +CBIOS_U32 cbHwGetActDeviceFromReg(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + return cbIGA_GetActiveDeviceFromReg(pcbe); +} + +CBIOS_VOID cbHwSetModeToIGA(PCBIOS_VOID pvcbe, PCBIOS_DISP_MODE_PARAMS pModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + cbDisableStream(pcbe, pModeParams->IGAIndex); + + cbIGA_HW_SetMode(pcbe, pModeParams); +} + +#define MIN_MODE_X 640 +#define MIN_MODE_Y 480 + +CBIOS_STATUS cbHwGetCounter(PCBIOS_VOID pvcbe, PCBIOS_GET_HW_COUNTER pGetCounter) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DISPLAY_MANAGER pDispMgr = &pcbe->DispMgr; + PCBIOS_DISP_MODE_PARAMS pModeParams = CBIOS_NULL; + CBIOS_U32 FrameCntIndex = 0, FrameCntValue = 0; + CBIOS_U32 PixelLineCntIndex = 0, PixelLineCntValue = 0; + CBIOS_BOOL bModeValid = CBIOS_FALSE; + CBIOS_U8 byCR34Value = 0; + + if(pGetCounter->IgaIndex >= pDispMgr->IgaCount) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + pModeParams = pDispMgr->pModeParams[pGetCounter->IgaIndex]; + if( pModeParams && pModeParams ->TargetTiming.XRes >= MIN_MODE_X && pModeParams->TargetTiming.YRes >= MIN_MODE_Y) + { + bModeValid = CBIOS_TRUE; + } + + if(pGetCounter->IgaIndex == IGA1) + { + FrameCntIndex = 0x8220; + PixelLineCntIndex = 0x8224; + } + else if(pGetCounter->IgaIndex == IGA2) + { + FrameCntIndex = 0x8230; + PixelLineCntIndex = 0x8234; + } + else if(pGetCounter->IgaIndex == IGA3) + { + FrameCntIndex = 0x34014; + PixelLineCntIndex = 0x34018; + } + else + { + FrameCntIndex = 0x34714; + PixelLineCntIndex = 0x34718; + } + + FrameCntValue = cb_ReadU32(pcbe->pAdapterContext, FrameCntIndex); + PixelLineCntValue = cb_ReadU32(pcbe->pAdapterContext, PixelLineCntIndex); + byCR34Value = cbBiosMMIOReadReg(pcbe, CR_34, pGetCounter->IgaIndex); + + if(pGetCounter->bGetFrameCnt) + { + pGetCounter->Value[CBIOS_COUNTER_FRAME] = FrameCntValue & 0xFFFF; + } + + if(pGetCounter->bGetLineCnt) + { + pGetCounter->Value[CBIOS_COUNTER_LINE] = PixelLineCntValue & 0xFFFF; + if(bModeValid) + { + pGetCounter->Value[CBIOS_COUNTER_LINE] += pModeParams->TargetTiming.VerSyncStart; + if(pGetCounter->Value[CBIOS_COUNTER_LINE] >= pModeParams->TargetTiming.VerTotal) + { + pGetCounter->Value[CBIOS_COUNTER_LINE] -= pModeParams->TargetTiming.VerTotal; + } + } + } + + if(pGetCounter->bGetPixelCnt) + { + pGetCounter->Value[CBIOS_COUNTER_PIXEL] = (PixelLineCntValue >> 16) & 0xFFFF; + if(bModeValid) + { + pGetCounter->Value[CBIOS_COUNTER_PIXEL] += pModeParams->TargetTiming.HorSyncStart; + if(pGetCounter->Value[CBIOS_COUNTER_PIXEL] >= pModeParams->TargetTiming.HorTotal) + { + pGetCounter->Value[CBIOS_COUNTER_PIXEL] -= pModeParams->TargetTiming.HorTotal; + } + } + } + + pGetCounter->bInVblank = (byCR34Value & VBLANK_ACTIVE_CR34)? 1 : 0; + + return CBIOS_OK; +} + + +CBIOS_STATUS cbHwGetMemInfo(PCBIOS_VOID pvcbe, PCBIOS_VBINFO_PARAM pVbiosInfo) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 MM49024RegValue = 0, MMD374RegValue = 0; + CBIOS_U32 ChannelSize, ChannelNum; + CBIOS_STATUS status = CBIOS_OK; + + MM49024RegValue = cb_ReadU32(pcbe->pAdapterContext, 0x49024); + MMD374RegValue = cb_ReadU32(pcbe->pAdapterContext, 0xD374); + + if ((MMD374RegValue & 0xFF) == 0) + { + ChannelNum = 3 - cbGetBitsNum(MM49024RegValue & 0x07); + ChannelSize = 4096; // hardcode 4G for old PMP + } + else + { + ChannelNum = (MMD374RegValue & 0xF0) >> 4; + ChannelSize = (MMD374RegValue & 0x0F) * 1024; + } + + switch(ChannelNum) + { + case 1: + case 2: + pVbiosInfo->AvalMemSize = ChannelNum * ChannelSize; + pVbiosInfo->TotalMemSize = ChannelNum * ChannelSize; + break; + case 3: + pVbiosInfo->TotalMemSize = ChannelNum * ChannelSize; + if(pVbiosInfo->TotalMemSize == (3*1024)) + { + pVbiosInfo->AvalMemSize = pVbiosInfo->TotalMemSize - 24; + } + else if(pVbiosInfo->TotalMemSize == (6*1024)) + { + pVbiosInfo->AvalMemSize = pVbiosInfo->TotalMemSize - 72; + } + else if(pVbiosInfo->TotalMemSize == (12*1024)) + { + pVbiosInfo->AvalMemSize = pVbiosInfo->TotalMemSize - 144; + } + else if(pVbiosInfo->TotalMemSize == (24*1024)) + { + pVbiosInfo->AvalMemSize = pVbiosInfo->TotalMemSize - 288; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "Total mem size %d is error!\n", pVbiosInfo->TotalMemSize)); + status = CBIOS_ER_INVALID_PARAMETER; + } + break; + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "Mem channel number %d is error!\n", ChannelNum)); + status = CBIOS_ER_INVALID_PARAMETER; + break; + } + pVbiosInfo->MemChNum = ChannelNum; + + return status; +} + +CBIOS_STATUS cbHWVIPCtl(PCBIOS_VOID pvcbe, PCBIOS_VIP_CTRL_DATA pCbiosVIPCtlData) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + return cbVIPCtl(pcbe, pCbiosVIPCtlData); +} diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwInterface/CBiosHwInterface.h b/drivers/gpu/drm/arise/cbios/Hw/HwInterface/CBiosHwInterface.h new file mode 100644 index 0000000000000..2906ac88d00c0 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwInterface/CBiosHwInterface.h @@ -0,0 +1,68 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios hw layer interface function prototype. +** +** NOTE: +** This header file CAN be included by sw layer. +******************************************************************************/ + +#ifndef _CBIOS_HW_INTERFACE_H_ +#define _CBIOS_HW_INTERFACE_H_ + +#include "../CBiosChipFunc.h" + +CBIOS_STATUS cbHWInit(PCBIOS_VOID pvcbe); +CBIOS_VOID cbHWInitChipAttribute(PCBIOS_VOID pvcbe, CBIOS_U32 ChipID); +CBIOS_BOOL cbHWIsChipEnable(PCBIOS_VOID pvcbe); +CBIOS_BOOL cbHWIsChipPost(PCBIOS_VOID pvcbe); +CBIOS_STATUS cbHWSetChipPostFlag(PCBIOS_VOID pvcbe); +CBIOS_STATUS cbHWSetMmioEndianMode(PCBIOS_VOID pAdapterContext); +CBIOS_STATUS cbHWUnload(PCBIOS_VOID pvcbe); +CBIOS_STATUS cbHWSetIgaScreenOnOffState(PCBIOS_VOID pvcbe, CBIOS_BOOL status, CBIOS_U8 IGAIndex); +CBIOS_STATUS cbHWResetBlock(PCBIOS_VOID pvcbe, CBIOS_HW_BLOCK HWBlock); +CBIOS_STATUS cbHWDumpReg(PCBIOS_VOID pvcbe, PCBIOS_PARAM_DUMP_REG pCBParamDumpReg); +CBIOS_STATUS cbHWReadReg(PCBIOS_VOID pvcbe, CBIOS_U8 type, CBIOS_U8 index, PCBIOS_U8 result); +CBIOS_STATUS cbHWWriteReg(PCBIOS_VOID pvcbe, CBIOS_U8 type, CBIOS_U8 index, CBIOS_U8 value, CBIOS_U8 mask); +CBIOS_BOOL cbHWReadEDID(PCBIOS_VOID pvcbe, CBIOS_U8 I2CBUSNum, CBIOS_U8 EDIDData[], CBIOS_U32 ulReadEdidOffset, CBIOS_U32 ulBufferSize, CBIOS_U8 nSegNum); +CBIOS_STATUS cbHWGetClockByType(PCBIOS_VOID pvcbe, PCBios_GetClock_Params PCBiosGetClockParams); +CBIOS_STATUS cbHWSetClockByType(PCBIOS_VOID pvcbe, PCBios_SetClock_Params PCBiosSetClockParams); +CBIOS_STATUS cbHWGetVBiosInfo(PCBIOS_VOID pvcbe, PCBIOS_VBINFO_PARAM pVbiosInfo); +CBIOS_STATUS cbHwSyncDataWithVbios(PCBIOS_VOID pvcbe, PCBIOS_VBIOS_DATA_PARAM pDataPara); +CBIOS_STATUS cbHWI2CDataRead(PCBIOS_VOID pvcbe, PCBIOS_PARAM_I2C_DATA pCBParamI2CData); +CBIOS_STATUS cbHWI2CDataWrite(PCBIOS_VOID pvcbe, PCBIOS_PARAM_I2C_DATA pCBParamI2CData); +CBIOS_BOOL cbHWDumpInfo(PCBIOS_VOID pvcbe, CBIOS_DUMP_TYPE RegType); +CBIOS_STATUS cbHWSetWriteback(PCBIOS_VOID pvcbe, PCBIOS_WB_PARA pWBPara); +CBIOS_VOID cbHWSetPwm(PCBIOS_VOID pvcbe, CBIOS_U32 on, CBIOS_U32 def); +CBIOS_STATUS cbHWCECTransmitMessage(PCBIOS_VOID pvcbe, PCBIOS_CEC_MESSAGE pCECMessage, CBIOS_CEC_INDEX CECIndex); +CBIOS_STATUS cbHWCECReceiveMessage(PCBIOS_VOID pvcbe, PCBIOS_CEC_MESSAGE pCECMessage, CBIOS_CEC_INDEX CECIndex); +CBIOS_STATUS cbHwI2CDDCCIOpen(PCBIOS_VOID pvcbe, CBIOS_BOOL bOpen, PCBIOS_I2CCONTROL pI2CControl, CBIOS_U8 I2CBUSNum); +CBIOS_STATUS cbHwI2CDDCCIAccess(PCBIOS_VOID pvcbe, PCBIOS_I2CCONTROL pI2CControl, CBIOS_U8 I2CBUSNum); +CBIOS_VOID cbHwUpdateActDeviceToReg(PCBIOS_VOID pvcbe, PCBIOS_DISPLAY_MANAGER pDispMgr); +CBIOS_U32 cbHwGetActDeviceFromReg(PCBIOS_VOID pvcbe); +CBIOS_VOID cbHwSetModeToIGA(PCBIOS_VOID pvcbe, PCBIOS_DISP_MODE_PARAMS pModeParams); +CBIOS_STATUS cbHwGetCounter(PCBIOS_VOID pvcbe, PCBIOS_GET_HW_COUNTER pGetCounter); +CBIOS_STATUS cbHwGetMemInfo(PCBIOS_VOID pvcbe, PCBIOS_VBINFO_PARAM pVbiosInfo); + +CBIOS_STATUS cbGetInterruptInfo(PCBIOS_VOID pvcbe, PCBIOS_INTERRUPT_INFO pIntInfo); +CBIOS_STATUS cbGetCECInterruptInfo(PCBIOS_VOID pvcbe, PCBIOS_CEC_INTERRUPT_INFO pCECIntInfo); +CBIOS_STATUS cbGetHDCPInterruptInfo(PCBIOS_VOID pvcbe, PCBIOS_HDCP_INFO_PARA pHdcpInfoParam); +CBIOS_STATUS cbGetHDACInterruptInfo(PCBIOS_VOID pvcbe, PCBIOS_HDAC_INFO_PARA pHdacInfoParam); + +CBIOS_STATUS cbHWVIPCtl(PCBIOS_VOID pvcbe, PCBIOS_VIP_CTRL_DATA pCbiosVIPCtlData); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosI2C.c b/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosI2C.c new file mode 100644 index 0000000000000..372f8aff63ed7 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosI2C.c @@ -0,0 +1,1751 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** I2C module interface function implementation. +** Mainly includes read/write data of I2C bus, GPIO simulate I2C, and DDCCIP +** +** NOTE: +** The functions in this file are hw layer internal functions, +** CAN ONLY be called by files under Hw folder. +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "CBiosUtilHw.h" +#include "../HwBlock/CBiosDIU_DP.h" + +/*************************************************************** +Function: cbI2CModule_SetScl + +Description: Set I2C clock line to specific lineLvl + +Input: PCBIOS_EXTENSION_COMMON + PCBIOS_I2C_REG_PARAMS + lineLvl, can be LEVEL_HIGH or LEVEL_LOW + +Output: + +Return: +***************************************************************/ +static CBIOS_VOID cbI2CModule_SetScl(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_I2C_REG_PARAMS pI2CRegParams, + CBIOS_U8 lineLvl) +{ + CBIOS_U8 ulValue = 0, ulMask = 0; + + ulValue = lineLvl << pI2CRegParams->CLineRegWriteBitNum; + ulValue += pI2CRegParams->CLineRegWriteEnableValue; + ulMask = 1 << pI2CRegParams->CLineRegWriteBitNum; + ulMask = pI2CRegParams->CLineRegWriteEnableMask & (~ulMask); + + cbMMIOWriteReg(pcbe, pI2CRegParams->CLineRegType_Index, ulValue, ulMask); +} + +/*************************************************************** +Function: cbI2CModule_GetScl + +Description: Get I2C clock line level + +Input: PCBIOS_EXTENSION_COMMON + PCBIOS_I2C_REG_PARAMS + +Output: + +Return: the line level of I2C clock line +***************************************************************/ +static CBIOS_U8 cbI2CModule_GetScl(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_I2C_REG_PARAMS pI2CRegParams) +{ + CBIOS_U8 ulValue = 0, ulMask = 0, ulRet = 0; + + //first enable read function + ulValue = pI2CRegParams->CLineRegReadEnableValue; + ulMask = pI2CRegParams->CLineRegReadEnableMask; + cbMMIOWriteReg(pcbe, pI2CRegParams->CLineRegType_Index, ulValue, ulMask); + + ulRet = cbMMIOReadReg(pcbe, pI2CRegParams->CLineRegType_Index); + ulRet = ulRet >> pI2CRegParams->CLineRegReadBitNum; + ulRet = ulRet & 0x01; + return ulRet; +} + +/*************************************************************** +Function: cbI2CModule_SetSda + +Description: Set I2C data line to specific lineLvl + +Input: PCBIOS_EXTENSION_COMMON + PCBIOS_MODULE_I2C_PARAMS + lineLvl, can be LEVEL_HIGH or LEVEL_LOW + +Output: + +Return: +***************************************************************/ +static CBIOS_VOID cbI2CModule_SetSda(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_I2C_REG_PARAMS pI2CRegParams, + CBIOS_U8 lineLvl) +{ + CBIOS_U8 ulValue = 0, ulMask = 0; + + ulValue = lineLvl << pI2CRegParams->DLineRegWriteBitNum; + ulValue += pI2CRegParams->DLineRegWriteEnableValue; + ulMask = 1 << pI2CRegParams->DLineRegWriteBitNum; + ulMask = pI2CRegParams->DLineRegWriteEnableMask & (~ulMask); + + cbMMIOWriteReg(pcbe, pI2CRegParams->DLineRegType_Index, ulValue, ulMask); +} + +/*************************************************************** +Function: cbI2CModule_GetSda + +Description: Get I2C data line level + +Input: PCBIOS_MODULE_I2C_PARAMS + PCBIOS_I2C_REG_PARAMS + +Output: + +Return: the line level of I2C data line +***************************************************************/ +static CBIOS_U8 cbI2CModule_GetSda(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_I2C_REG_PARAMS pI2CRegParams) +{ + CBIOS_U8 ulValue = 0, ulMask = 0, ulRet = 0; + + //first enable read function + ulValue = pI2CRegParams->DLineRegReadEnableValue; + ulMask = pI2CRegParams->DLineRegReadEnableMask; + cbMMIOWriteReg(pcbe, pI2CRegParams->DLineRegType_Index, ulValue, ulMask); + + ulRet = cbMMIOReadReg(pcbe, pI2CRegParams->DLineRegType_Index); + ulRet = ulRet >> pI2CRegParams->DLineRegReadBitNum; + ulRet = ulRet & 0x01; + return ulRet; +} + +/*************************************************************** +Function: cbI2CModule_CheckBusNum + +Description: Check the I2C bus num is valid. + +Input: PCBIOS_EXTENSION_COMMON + PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: CBIOS_TURE if I2C bus num is valid + CBIOS_FALSE if I2C bus num is invalid +***************************************************************/ +static CBIOS_BOOL cbI2CModule_CheckBusNum(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + CBIOS_U8 I2CBusNum = pCBModuleI2CParams->I2CBusNum; + CBIOS_BOOL bRet = CBIOS_FALSE; + + //normal I2C + if ((I2CBusNum >= MIN_NORMAL_I2C_BUS) && (I2CBusNum <= MAX_NORMAL_I2C_BUS)) + { + bRet = CBIOS_TRUE; + } + //GPIO simulate I2C + else if ((I2CBusNum >= MIN_GPIO_I2C_BUS) && (I2CBusNum <= MAX_GPIO_I2C_BUS)) + { + bRet = CBIOS_TRUE; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbI2CModule_CheckBusNum: I2CBusNum invalid! \n")); + bRet = CBIOS_FALSE; + } + return bRet; +} + +/*************************************************************** +Function: cbI2CModule_Start + +Description: Send the start signal to the I2C bus + +Input: PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: +***************************************************************/ +static CBIOS_VOID cbI2CModule_Start(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + CBIOS_U8 bySCL = 0, bySDL = 0; + CBIOS_U32 i = 0; + CBIOS_U32 MaxLoop = MAXI2CWAITLOOP; + CBIOS_U8 I2CDELAY = pcbe->I2CDelay; + PCBIOS_I2C_REG_PARAMS pI2CRegParams = &(pCBModuleI2CParams->I2CRegParams); + + //check I2CBusNum + if(cbI2CModule_CheckBusNum(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbI2CModule_Start: I2CBusNum invalid! \n")); + return; + } + + //check the SCL status + bySCL = cbI2CModule_GetScl(pcbe, pI2CRegParams); + + //SCL Low + if (bySCL == LEVEL_LOW) + { + //wait for SCL High + for (i = 0; i < MaxLoop; i++) + { + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + + bySCL = cbI2CModule_GetScl(pcbe, pI2CRegParams); + if (bySCL == LEVEL_HIGH) + { + break; + } + } + } + + //check the SDL status + bySDL = cbI2CModule_GetSda(pcbe, pI2CRegParams); + + //SCL High + SDA Low + if ((bySCL == LEVEL_HIGH) && (bySDL == LEVEL_LOW)) + { + //set SCL Low + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + + //set SDA High + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + + //wait for SCLHigh + for (i = 0; i < MaxLoop; i++) + { + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + + bySCL = cbI2CModule_GetScl(pcbe, pI2CRegParams); + if (bySCL == LEVEL_HIGH) + { + break; + } + } + } + + //check SCL High + SDA High + bySCL = cbI2CModule_GetScl(pcbe, pI2CRegParams); + bySDL = cbI2CModule_GetSda(pcbe, pI2CRegParams); + if ((bySCL == LEVEL_HIGH) && (bySDL == LEVEL_HIGH)) + { + //I2C start: SCL High, SDA High->Low + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbI2CModule_Start: I2C start failed! \n")); + } +} + +/*************************************************************** +Function: cbI2CModule_Stop + +Description: Send the stop signal to the I2C bus + +Input: PCBIOS_EXTENSION_COMMON + PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: CBIOS_TRUE for success, CBIOS_FALSE for fail +***************************************************************/ +static CBIOS_BOOL cbI2CModule_Stop(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + CBIOS_U8 byTemp = 0; + CBIOS_U32 i = 0; + CBIOS_U32 MaxLoop = MAXI2CWAITLOOP; + CBIOS_U8 I2CDELAY = pcbe->I2CDelay; + PCBIOS_I2C_REG_PARAMS pI2CRegParams = &(pCBModuleI2CParams->I2CRegParams); + + //check I2CBusNum + if(cbI2CModule_CheckBusNum(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbI2CModule_Stop: I2CBusNum invalid! \n")); + return CBIOS_FALSE; + } + + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + + for (i = 0; i < MaxLoop; i++) + { + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + byTemp = cbI2CModule_GetScl(pcbe, pI2CRegParams); + if (byTemp == LEVEL_HIGH) + { + break; + } + } + + if (byTemp == LEVEL_HIGH) + { + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_HIGH); + } + + return CBIOS_TRUE; +} + +/*************************************************************** +Function: cbI2CModule_Enable + +Description: enable I2C input and output + +Input: PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: +***************************************************************/ +static CBIOS_VOID cbI2CModule_Enable(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + CBIOS_U8 I2CDELAY = pcbe->I2CDelay; + PCBIOS_I2C_REG_PARAMS pI2CRegParams = &(pCBModuleI2CParams->I2CRegParams); + + //check I2CBusNum + if(cbI2CModule_CheckBusNum(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbI2CModule_Enable: I2CBusNum invalid! \n")); + return; + } + + //release Sda + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + //release Scl + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); +} + +/*************************************************************** +Function: cbI2CModule_Disable + +Description: disable I2C input and output + +Input: PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: +***************************************************************/ +static CBIOS_VOID cbI2CModule_Disable(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + + CBIOS_U8 ulValue = 0, ulMask = 0; + PCBIOS_I2C_REG_PARAMS pI2CRegParams = &(pCBModuleI2CParams->I2CRegParams); + + //check I2CBusNum + if(cbI2CModule_CheckBusNum(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbI2CModule_Disable: I2CBusNum invalid! \n")); + return; + } + + //disable Scl + ulValue = pI2CRegParams->CLineRegReadEnableValue; + ulMask = pI2CRegParams->CLineRegReadEnableMask; + ulValue = (~ulValue) & (~ulMask); //cline read disable value + cbMMIOWriteReg(pcbe, pI2CRegParams->CLineRegType_Index, ulValue, ulMask); + ulValue = pI2CRegParams->CLineRegWriteEnableValue; + ulMask = pI2CRegParams->CLineRegWriteEnableMask; + ulValue = (~ulValue) & (~ulMask); //cline write disable value + cbMMIOWriteReg(pcbe, pI2CRegParams->CLineRegType_Index, ulValue, ulMask); + + //disable Sda + ulValue = pI2CRegParams->DLineRegReadEnableValue; + ulMask = pI2CRegParams->DLineRegReadEnableMask; + ulValue = (~ulValue) & (~ulMask); //dline read disable value + cbMMIOWriteReg(pcbe, pI2CRegParams->DLineRegType_Index, ulValue, ulMask); + ulValue = pI2CRegParams->DLineRegWriteEnableValue; + ulMask = pI2CRegParams->DLineRegWriteEnableMask; + ulValue = (~ulValue) & (~ulMask); //dline write disable value + cbMMIOWriteReg(pcbe, pI2CRegParams->DLineRegType_Index, ulValue, ulMask); +} + +/*************************************************************** +Function: cbI2CModule_AckRead + +Description: Read the Acknowledge signal from the I2C bus. + +Input: PCBIOS_EXTENSION_COMMON + PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: CBIOS_TRUE if read ACK successfully, + CBIOS_FALSE if read ACK failed +***************************************************************/ +static CBIOS_BOOL cbI2CModule_AckRead(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + CBIOS_U8 byTemp = 0; + CBIOS_U32 j = 0; + CBIOS_U32 MaxLoop = MAXI2CWAITLOOP; + CBIOS_BOOL bAck = CBIOS_FALSE; + CBIOS_U8 I2CDELAY = pcbe->I2CDelay; + PCBIOS_I2C_REG_PARAMS pI2CRegParams = &(pCBModuleI2CParams->I2CRegParams); + + //check I2CBusNum + if(cbI2CModule_CheckBusNum(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbI2CModule_AckRead: I2CBusNum invalid! \n")); + return CBIOS_FALSE; + } + + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + + for (j = 0; j < MaxLoop; j++) + { + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + + byTemp = cbI2CModule_GetScl(pcbe, pI2CRegParams); + + if (byTemp == LEVEL_HIGH) + { + break; + } + } + + if (j >= MaxLoop) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbI2CModule_AckRead: can't pull up SCL! \n")); + bAck = CBIOS_FALSE; + } + else + { + byTemp = cbI2CModule_GetSda(pcbe, pI2CRegParams); + if (byTemp == LEVEL_LOW) + { + bAck = CBIOS_TRUE; + } + else + { + bAck = CBIOS_FALSE; + } + } + + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + + return bAck; +} + +/*************************************************************** +Function: cbI2CModule_AckWrite + +Description: Send ACKnowledgement when reading information. + A ACK is DATA low during one clock pulse. + +Input: PCBIOS_EXTENSION_COMMON + PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: CBIOS_TURE if write ACK successfully + CBIOS_FALSE if write failed +***************************************************************/ +static CBIOS_BOOL cbI2CModule_AckWrite(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + CBIOS_U8 byTemp = 0; + CBIOS_U32 i = 0; + CBIOS_U32 MaxLoop = MAXI2CWAITLOOP; + CBIOS_BOOL bStatus = CBIOS_FALSE; + CBIOS_U8 I2CDELAY = pcbe->I2CDelay; + PCBIOS_I2C_REG_PARAMS pI2CRegParams = &(pCBModuleI2CParams->I2CRegParams); + + //check I2CBusNum + if(cbI2CModule_CheckBusNum(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbI2CModule_AckWrite: I2CBusNum invalid! \n")); + return CBIOS_FALSE; + } + + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + + for ( i = 0; i < MaxLoop; i++) + { + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + + byTemp = cbI2CModule_GetScl(pcbe, pI2CRegParams); + + if (byTemp == LEVEL_HIGH) + { + break; + } + } + + if (i < MaxLoop) + { + bStatus = CBIOS_TRUE; + } + else + { + bStatus = CBIOS_FALSE; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbI2CModule_AckWrite: write ack failed! \n")); + } + + return bStatus; +} + +/*************************************************************** +Function: cbI2CModule_NackWrite + +Description: Send Not ACKnowledgement when reading information. + A NACK is DATA high during one clock pulse. + +Input: PCBIOS_EXTENSION_COMMON + PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: CBIOS_TURE if write NACK successfully + CBIOS_FALSE if write failed +***************************************************************/ +static CBIOS_VOID cbI2CModule_NackWrite(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + CBIOS_U8 byTemp = 0; + CBIOS_U32 j = 0; + CBIOS_U32 MaxLoop = MAXI2CWAITLOOP; + CBIOS_U8 I2CDELAY = pcbe->I2CDelay; + PCBIOS_I2C_REG_PARAMS pI2CRegParams = &(pCBModuleI2CParams->I2CRegParams); + + //check I2CBusNum + if(cbI2CModule_CheckBusNum(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbI2CModule_NackWrite: I2CBusNum invalid! \n")); + return; + } + + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + + for (j = 0; j < MaxLoop; j++) + { + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + + byTemp = cbI2CModule_GetScl(pcbe, pI2CRegParams); + + if (byTemp == LEVEL_HIGH) + break; + } + + if (j >= MaxLoop) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbI2CModule_NackWrite: can't pull up SCL! \n")); + } + + //check SDA + byTemp = cbI2CModule_GetSda(pcbe, pI2CRegParams); + if (byTemp == LEVEL_LOW) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbI2CModule_NackWrite: can't pull up SDA! \n")); + } +} + +/*************************************************************** +Function: cbI2CModule_ReadByte + +Description: Read one byte data from I2C bus. + +Input: PCBIOS_EXTENSION_COMMON + PCBIOS_MODULE_I2C_PARAMS + +Output: pData, the one byte data read + +Return: CBIOS_TURE if read data successfully + CBIOS_FALSE if read data failed +***************************************************************/ +static CBIOS_BOOL cbI2CModule_ReadByte(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams, + CBIOS_U8* pData) +{ + CBIOS_U8 byTemp; + CBIOS_U8 data = 0; + CBIOS_U32 i = 0; + CBIOS_U32 j = 0; + CBIOS_U32 MaxLoop = MAXI2CWAITLOOP; + CBIOS_BOOL bStatus = CBIOS_TRUE; + CBIOS_U8 I2CDELAY = pcbe->I2CDelay; + PCBIOS_I2C_REG_PARAMS pI2CRegParams = &(pCBModuleI2CParams->I2CRegParams); + + //check I2CBusNum + if(cbI2CModule_CheckBusNum(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbI2CModule_ReadByte: I2CBusNum invalid! \n")); + return CBIOS_FALSE; + } + + for (i=0; i<8; i++) + { + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + + for (j = 0; j < MaxLoop; j++) + { + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + byTemp = cbI2CModule_GetScl(pcbe, pI2CRegParams); + + if (byTemp == LEVEL_HIGH) + break; + } + + if(j == MaxLoop) + { + bStatus = CBIOS_FALSE; + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbI2CModule_ReadByte: can't pull up SCL! \n")); + break; + } + + data = (data << 1) + cbI2CModule_GetSda(pcbe, pI2CRegParams); + + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + } + + *pData = data; + + return bStatus; +} + +/*************************************************************** +Function: cbI2CModule_WriteByte + +Description: Write one byte data to I2C bus. + +Input: PCBIOS_EXTENSION_COMMON + PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: +***************************************************************/ +static CBIOS_VOID cbI2CModule_WriteByte(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams, + CBIOS_U8 data) +{ + CBIOS_S32 i, value; + CBIOS_U8 byTemp = 0; + CBIOS_U32 j = 0; + CBIOS_U32 MaxLoop = MAXI2CWAITLOOP; + CBIOS_U8 I2CDELAY = pcbe->I2CDelay; + PCBIOS_I2C_REG_PARAMS pI2CRegParams = &(pCBModuleI2CParams->I2CRegParams); + + //check I2CBusNum + if(cbI2CModule_CheckBusNum(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbI2CModule_WriteByte: I2CBusNum invalid! \n")); + return; + } + + //loop for 1 byte, start from MSB + for (i = 7; i >= 0; i--) + { + value = (data >> i) & 0x01; + + //set SCL low + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + //Set SDA + if (value == 0) + { + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_LOW); + } + else + { + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_HIGH); + } + cb_DelayMicroSeconds(I2CDELAY); + + //wait for SCL high + for (j = 0; j < MaxLoop; j++) + { + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + + byTemp = cbI2CModule_GetScl(pcbe, pI2CRegParams); + if (byTemp == LEVEL_HIGH) + { + break; + } + } + //can't wait for SCL high, fail + if (j == MaxLoop) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbI2CModule_WriteByte: can't pull SCL high! \n")); + break; + } + if (value == 1) + { + //check SDA + byTemp = cbI2CModule_GetSda(pcbe, pI2CRegParams); + if (byTemp != LEVEL_HIGH) + { + //can't pull up SDA, fail + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbI2CModule_WriteByte: can't pull SDA high! \n")); + break; + } + } + + cbI2CModule_SetScl(pcbe, pI2CRegParams, LEVEL_LOW); + cb_DelayMicroSeconds(I2CDELAY); + cbI2CModule_SetSda(pcbe, pI2CRegParams, LEVEL_HIGH); + cb_DelayMicroSeconds(I2CDELAY); + } + +} + +/*************************************************************** +Function: cbI2CModule_GetI2CParams + +Description: Get the clock and data line params of specific I2C bus. + +Input: PCBIOS_EXTENSION_COMMON + PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: CBIOS_TURE if get params successfully + CBIOS_FALSE if get params failed +***************************************************************/ +static CBIOS_BOOL cbI2CModule_GetI2CParams(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + CBIOS_U8 I2CBusNum = pCBModuleI2CParams->I2CBusNum; + PCBIOS_I2C_REG_PARAMS pI2CRegParams = &(pCBModuleI2CParams->I2CRegParams); + + //check I2CBusNum + if(cbI2CModule_CheckBusNum(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbI2CModule_GetI2CParams: I2CBusNum invalid! \n")); + return CBIOS_FALSE; + } + + switch(I2CBusNum) + { + case I2CBUS0: //Normal I2C bus0 + { + pI2CRegParams->CLineRegType_Index = CR_A0; + pI2CRegParams->CLineRegReadEnableMask = 0xFF; + pI2CRegParams->CLineRegReadEnableValue = 0; + pI2CRegParams->CLineRegReadBitNum = 2; + pI2CRegParams->CLineRegWriteBitNum = 0; + pI2CRegParams->CLineRegWriteEnableMask = 0xEF; + pI2CRegParams->CLineRegWriteEnableValue = 0x10; + + + pI2CRegParams->DLineRegType_Index = CR_A0; + pI2CRegParams->DLineRegReadEnableMask = 0xFF; + pI2CRegParams->DLineRegReadEnableValue = 0; + pI2CRegParams->DLineRegReadBitNum = 3; + pI2CRegParams->DLineRegWriteBitNum = 1; + pI2CRegParams->DLineRegWriteEnableMask = 0xEF; + pI2CRegParams->DLineRegWriteEnableValue = 0x10; + } + break; + case I2CBUS1: //Normal I2C bus1 + { + pI2CRegParams->CLineRegType_Index = CR_AA; + pI2CRegParams->CLineRegReadEnableMask = 0xFF; + pI2CRegParams->CLineRegReadEnableValue = 0; + pI2CRegParams->CLineRegReadBitNum = 2; + pI2CRegParams->CLineRegWriteBitNum = 0; + pI2CRegParams->CLineRegWriteEnableMask = 0xEF; + pI2CRegParams->CLineRegWriteEnableValue = 0x10; + + + pI2CRegParams->DLineRegType_Index = CR_AA; + pI2CRegParams->DLineRegReadEnableMask = 0xFF; + pI2CRegParams->DLineRegReadEnableValue = 0; + pI2CRegParams->DLineRegReadBitNum = 3; + pI2CRegParams->DLineRegWriteBitNum = 1; + pI2CRegParams->DLineRegWriteEnableMask = 0xEF; + pI2CRegParams->DLineRegWriteEnableValue = 0x10; + } + break; + case I2CBUS2: //Normal I2C bus2 + { + pI2CRegParams->CLineRegType_Index = CR_B_C5; + pI2CRegParams->CLineRegReadEnableMask = 0xFF; + pI2CRegParams->CLineRegReadEnableValue = 0; + pI2CRegParams->CLineRegReadBitNum = 2; + pI2CRegParams->CLineRegWriteBitNum = 0; + pI2CRegParams->CLineRegWriteEnableMask = 0xEF; + pI2CRegParams->CLineRegWriteEnableValue = 0x10; + + + pI2CRegParams->DLineRegType_Index = CR_B_C5; + pI2CRegParams->DLineRegReadEnableMask = 0xFF; + pI2CRegParams->DLineRegReadEnableValue = 0; + pI2CRegParams->DLineRegReadBitNum = 3; + pI2CRegParams->DLineRegWriteBitNum = 1; + pI2CRegParams->DLineRegWriteEnableMask = 0xEF; + pI2CRegParams->DLineRegWriteEnableValue = 0x10; + } + break; + case I2CBUS3: //Normal I2C bus3 + { + pI2CRegParams->CLineRegType_Index = CR_B_C6; + pI2CRegParams->CLineRegReadEnableMask = 0xFF; + pI2CRegParams->CLineRegReadEnableValue = 0; + pI2CRegParams->CLineRegReadBitNum = 2; + pI2CRegParams->CLineRegWriteBitNum = 0; + pI2CRegParams->CLineRegWriteEnableMask = 0xEF; + pI2CRegParams->CLineRegWriteEnableValue = 0x10; + + + pI2CRegParams->DLineRegType_Index = CR_B_C6; + pI2CRegParams->DLineRegReadEnableMask = 0xFF; + pI2CRegParams->DLineRegReadEnableValue = 0; + pI2CRegParams->DLineRegReadBitNum = 3; + pI2CRegParams->DLineRegWriteBitNum = 1; + pI2CRegParams->DLineRegWriteEnableMask = 0xEF; + pI2CRegParams->DLineRegWriteEnableValue = 0x10; + } + break; + case I2CBUS4: //Normal I2C bus4 + { + pI2CRegParams->CLineRegType_Index = CR_B_F8; + pI2CRegParams->CLineRegReadEnableMask = 0xFF; + pI2CRegParams->CLineRegReadEnableValue = 0; + pI2CRegParams->CLineRegReadBitNum = 2; + pI2CRegParams->CLineRegWriteBitNum = 0; + pI2CRegParams->CLineRegWriteEnableMask = 0xEF; + pI2CRegParams->CLineRegWriteEnableValue = 0x10; + + + pI2CRegParams->DLineRegType_Index = CR_B_F8; + pI2CRegParams->DLineRegReadEnableMask = 0xFF; + pI2CRegParams->DLineRegReadEnableValue = 0; + pI2CRegParams->DLineRegReadBitNum = 3; + pI2CRegParams->DLineRegWriteBitNum = 1; + pI2CRegParams->DLineRegWriteEnableMask = 0xEF; + pI2CRegParams->DLineRegWriteEnableValue = 0x10; + } + break; + case I2CBUS_SCLGPIO4_SDAGPIO5: //GPIO4-SCLK GPIO5-SDAT + { + pI2CRegParams->CLineRegType_Index = SR_48; + pI2CRegParams->CLineRegReadEnableMask = 0xBF; + pI2CRegParams->CLineRegReadEnableValue = 0x40; + pI2CRegParams->CLineRegReadBitNum = 7; + pI2CRegParams->CLineRegWriteBitNum = 4; + pI2CRegParams->CLineRegWriteEnableMask = 0xDF; + pI2CRegParams->CLineRegWriteEnableValue = 0x20; + + + pI2CRegParams->DLineRegType_Index = SR_4A; + pI2CRegParams->DLineRegReadEnableMask = 0xFB; + pI2CRegParams->DLineRegReadEnableValue = 0x04; + pI2CRegParams->DLineRegReadBitNum = 3; + pI2CRegParams->DLineRegWriteBitNum = 0; + pI2CRegParams->DLineRegWriteEnableMask = 0xFD; + pI2CRegParams->DLineRegWriteEnableValue = 0x02; + } + break; + case I2CBUS_SCLGPIO5_SDAGPIO2: //GPIO5-SCLK GPIO2-SDAT + { + pI2CRegParams->CLineRegType_Index = SR_4A; + pI2CRegParams->CLineRegReadEnableMask = 0xFB; + pI2CRegParams->CLineRegReadEnableValue = 0x04; + pI2CRegParams->CLineRegReadBitNum = 3; + pI2CRegParams->CLineRegWriteBitNum = 0; + pI2CRegParams->CLineRegWriteEnableMask = 0xFD; + pI2CRegParams->CLineRegWriteEnableValue = 0x02; + + + pI2CRegParams->DLineRegType_Index = CR_B_DA; + pI2CRegParams->DLineRegReadEnableMask = 0xBF; + pI2CRegParams->DLineRegReadEnableValue = 0x40; + pI2CRegParams->DLineRegReadBitNum = 7; + pI2CRegParams->DLineRegWriteBitNum = 4; + pI2CRegParams->DLineRegWriteEnableMask = 0xDF; + pI2CRegParams->DLineRegWriteEnableValue = 0x20; + } + break; + case I2CBUS_SCLGPIO3_SDAGPIO4: // GPIO3-SCLK GPIO4-SDAT + { + pI2CRegParams->CLineRegType_Index = SR_48; + pI2CRegParams->CLineRegReadEnableMask = 0xFB; + pI2CRegParams->CLineRegReadEnableValue = 0x04; + pI2CRegParams->CLineRegReadBitNum = 3; + pI2CRegParams->CLineRegWriteBitNum = 0; + pI2CRegParams->CLineRegWriteEnableMask = 0xFD; + pI2CRegParams->CLineRegWriteEnableValue = 0x02; + + pI2CRegParams->DLineRegType_Index = SR_48; + pI2CRegParams->DLineRegReadEnableMask = 0xBF; + pI2CRegParams->DLineRegReadEnableValue = 0x40; + pI2CRegParams->DLineRegReadBitNum = 7; + pI2CRegParams->DLineRegWriteBitNum = 4; + pI2CRegParams->DLineRegWriteEnableMask = 0xDF; + pI2CRegParams->DLineRegWriteEnableValue = 0x20; + } + break; + case I2CBUS_SCLGPIO2_SDAGPIO5://GPIO2-SCLK GPIO5-SDAT + { + pI2CRegParams->CLineRegType_Index = CR_B_DA; + pI2CRegParams->CLineRegReadEnableMask = 0xBF; + pI2CRegParams->CLineRegReadEnableValue = 0x40; + pI2CRegParams->CLineRegReadBitNum = 7; + pI2CRegParams->CLineRegWriteBitNum = 4; + pI2CRegParams->CLineRegWriteEnableMask = 0xDF; + pI2CRegParams->CLineRegWriteEnableValue = 0x20; + + pI2CRegParams->DLineRegType_Index = SR_4A; + pI2CRegParams->DLineRegReadEnableMask = 0xFB; + pI2CRegParams->DLineRegReadEnableValue = 0x04; + pI2CRegParams->DLineRegReadBitNum = 3; + pI2CRegParams->DLineRegWriteBitNum = 0; + pI2CRegParams->DLineRegWriteEnableMask = 0xFD; + pI2CRegParams->DLineRegWriteEnableValue = 0x02; + } + break; + case I2CBUS_SCLGPIO2_SDAGPIO3://GPIO2-SCLK GPIO3-SDAT + { + pI2CRegParams->CLineRegType_Index = CR_B_DA; + pI2CRegParams->CLineRegReadEnableMask = 0xBF; + pI2CRegParams->CLineRegReadEnableValue = 0x40; + pI2CRegParams->CLineRegReadBitNum = 7; + pI2CRegParams->CLineRegWriteBitNum = 4; + pI2CRegParams->CLineRegWriteEnableMask = 0xDF; + pI2CRegParams->CLineRegWriteEnableValue = 0x20; + + pI2CRegParams->DLineRegType_Index = SR_48; + pI2CRegParams->DLineRegReadEnableMask = 0xFB; + pI2CRegParams->DLineRegReadEnableValue = 0x04; + pI2CRegParams->DLineRegReadBitNum = 3; + pI2CRegParams->DLineRegWriteBitNum = 0; + pI2CRegParams->DLineRegWriteEnableMask = 0xFD; + pI2CRegParams->DLineRegWriteEnableValue = 0x02; + } + break; + default: + { + ASSERT(CBIOS_FALSE); + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),("Not support this I2C bus number %d!\n"), I2CBusNum)); + return CBIOS_FALSE; + } + break; + } + return CBIOS_TRUE; +} + +static CBIOS_U32 cbI2CModule_DDCCI_StopService(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + if(cbI2CModule_Stop(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_Stop failure!\n")); + return DDCCII2C_STATUS_ERROR; + } + + return DDCCII2C_STATUS_NOERROR; +} + +static CBIOS_U32 cbI2CModule_DDCCI_Stop(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + cbI2CModule_NackWrite(pcbe, pCBModuleI2CParams); + + return cbI2CModule_DDCCI_StopService(pcbe, pCBModuleI2CParams); +} + +static CBIOS_VOID cbI2CModule_DDCCI_StartService(PCBIOS_EXTENSION_COMMON pcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + cbI2CModule_Start(pcbe, pCBModuleI2CParams); +} + +static CBIOS_U32 cbI2CModule_DDCCI_Null(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_I2CCONTROL pI2CControl, + PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + if(pI2CControl->Flags & DDCCII2C_FLAGS_DATACHAINING) + { + if(cbI2CModule_DDCCI_StopService(pcbe, pCBModuleI2CParams) == DDCCII2C_STATUS_ERROR) + { + return DDCCII2C_STATUS_ERROR; + } + + cbI2CModule_DDCCI_StartService(pcbe, pCBModuleI2CParams); + } + + if(pI2CControl->Flags & DDCCII2C_FLAGS_START) + { + cbI2CModule_DDCCI_StartService(pcbe, pCBModuleI2CParams); + } + + if(pI2CControl->Flags & DDCCII2C_FLAGS_STOP) + { + if(cbI2CModule_DDCCI_Stop(pcbe, pCBModuleI2CParams) == DDCCII2C_STATUS_ERROR) + { + return DDCCII2C_STATUS_ERROR; + } + } + + return DDCCII2C_STATUS_NOERROR; +} + +static CBIOS_U32 cbI2CModule_DDCCI_Read(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_I2CCONTROL pI2CControl, + PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + if(pI2CControl->Flags & DDCCII2C_FLAGS_DATACHAINING) + { + if(cbI2CModule_DDCCI_StopService(pcbe, pCBModuleI2CParams) == DDCCII2C_STATUS_ERROR) + { + return DDCCII2C_STATUS_ERROR; + } + + cbI2CModule_DDCCI_StartService(pcbe, pCBModuleI2CParams); + } + + if(pI2CControl->Flags & DDCCII2C_FLAGS_START) + { + cbI2CModule_DDCCI_StartService(pcbe, pCBModuleI2CParams); + } + + if(cbI2CModule_ReadByte(pcbe, pCBModuleI2CParams, &pI2CControl->Data) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_DDCCI_Read: cbI2CModule_ReadByte failure!\n")); + return DDCCII2C_STATUS_ERROR; + } + + if(pI2CControl->Flags & DDCCII2C_FLAGS_ACK) + { + if(cbI2CModule_AckWrite(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_DDCCI_Read: Ack Write error!\n")); + return DDCCII2C_STATUS_ERROR; + } + } + + if(pI2CControl->Flags & DDCCII2C_FLAGS_STOP) + { + if(cbI2CModule_DDCCI_Stop(pcbe, pCBModuleI2CParams) == DDCCII2C_STATUS_ERROR) + { + return DDCCII2C_STATUS_ERROR; + } + } + + return DDCCII2C_STATUS_NOERROR; +} + +static CBIOS_U32 cbI2CModule_DDCCI_Write(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_I2CCONTROL pI2CControl, + PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + if(pI2CControl->Flags & DDCCII2C_FLAGS_DATACHAINING) + { + if(cbI2CModule_DDCCI_StopService(pcbe, pCBModuleI2CParams) == DDCCII2C_STATUS_ERROR) + { + return DDCCII2C_STATUS_ERROR; + } + + cbI2CModule_DDCCI_StartService(pcbe, pCBModuleI2CParams); + } + + if(pI2CControl->Flags & DDCCII2C_FLAGS_START) + { + cbI2CModule_DDCCI_StartService(pcbe, pCBModuleI2CParams); + } + + cbI2CModule_WriteByte(pcbe, pCBModuleI2CParams, pI2CControl->Data); + + //if(pI2CControl->Flags & DDCCII2C_FLAGS_ACK) + { + if(cbI2CModule_AckRead(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_DDCCI_Write: Ack Read error!\n")); + return DDCCII2C_STATUS_ERROR; + } + } + + if(pI2CControl->Flags & DDCCII2C_FLAGS_STOP) + { + if(cbI2CModule_DDCCI_Stop(pcbe, pCBModuleI2CParams) == DDCCII2C_STATUS_ERROR) + { + return DDCCII2C_STATUS_ERROR; + } + } + + return DDCCII2C_STATUS_NOERROR; +} + +static CBIOS_BOOL cbI2CModule_DDCCI_GetCookie(PCBIOS_U32 Cookie) +{ + *Cookie = 0x12345678; + return CBIOS_TRUE; +} + +/***********************************************************************************/ +/* I2C Module Interfaces */ +/***********************************************************************************/ + + +/*************************************************************** +Function: cbI2CModule_ReadData + +Description: Read data from I2C bus. + +Input: PCBIOS_VOID + PCBIOS_MODULE_I2C_PARAMS + +Output: The data read is in pCBModuleI2CParams->Buffer + +Return: CBIOS_TURE if read data successfully + CBIOS_FALSE if read data failed +***************************************************************/ +CBIOS_BOOL cbI2CModule_ReadData(PCBIOS_VOID pvcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + CBIOS_U32 i = 0; + CBIOS_U8 SlaveAddr = pCBModuleI2CParams->SlaveAddress; + CBIOS_U8 Offset = pCBModuleI2CParams->OffSet; + CBIOS_U32 BufferLen = pCBModuleI2CParams->BufferLen; + CBIOS_U8 I2CBusNum = pCBModuleI2CParams->I2CBusNum; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bStatus = CBIOS_FALSE; + + cbTraceEnter(GENERIC); + if ((I2CBusNum == I2CBUS_VIRTUAL_DP1) || (I2CBusNum == I2CBUS_VIRTUAL_DP2) || (I2CBusNum == I2CBUS_VIRTUAL_DP3) || (I2CBusNum == I2CBUS_VIRTUAL_DP4)) + { + CBIOS_ACTIVE_TYPE Device = CBIOS_TYPE_NONE; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_MODULE_INDEX DPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + if (I2CBusNum == I2CBUS_VIRTUAL_DP1) + { + Device = CBIOS_TYPE_DP1; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP2) + { + Device = CBIOS_TYPE_DP2; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP3) + { + Device = CBIOS_TYPE_DP3; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP4) + { + Device = CBIOS_TYPE_DP4; + } + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + DPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_DP); + if (cbDPPort_IsDeviceInDpMode(pcbe, pDevCommon)) + { +#if DP_MONITOR_SUPPORT + bStatus = cbDIU_DP_ReadData(pvcbe, DPModuleIndex, pCBModuleI2CParams, pCBModuleI2CParams->Flags, CBIOS_FALSE); + if(bStatus == CBIOS_OK) + return CBIOS_TRUE; + else + return CBIOS_FALSE; +#endif + } + else // Dual Mode, just switch to normal I2C operation + { + pCBModuleI2CParams->I2CBusNum = (CBIOS_U8)pDevCommon->I2CBus; + } + } + + if (pCBModuleI2CParams->ConfigType == CONFIG_I2C_BY_BUSNUM) + { + if (cbI2CModule_GetI2CParams(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + return CBIOS_FALSE; + } + + } + + cbI2CModule_Enable(pcbe, pCBModuleI2CParams); + cbI2CModule_Start(pcbe, pCBModuleI2CParams); + + cbI2CModule_WriteByte(pcbe, pCBModuleI2CParams, SlaveAddr); + if(cbI2CModule_AckRead(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + + cbI2CModule_WriteByte(pcbe, pCBModuleI2CParams, Offset); + if(cbI2CModule_AckRead(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + + cbI2CModule_Start(pcbe, pCBModuleI2CParams); + + cbI2CModule_WriteByte(pcbe, pCBModuleI2CParams, SlaveAddr + 1); //LSB=1, indicate read + if(cbI2CModule_AckRead(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + + for(i = 0; i < BufferLen-1; i++) + { + if(cbI2CModule_ReadByte(pcbe, pCBModuleI2CParams, &(pCBModuleI2CParams->Buffer[i])) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + if(cbI2CModule_AckWrite(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + } + if(cbI2CModule_ReadByte(pcbe, pCBModuleI2CParams, &(pCBModuleI2CParams->Buffer[i])) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + + cbI2CModule_NackWrite(pcbe, pCBModuleI2CParams); + + if(cbI2CModule_Stop(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + bStatus = CBIOS_TRUE; + +exit: + if(!bStatus) + { + cbI2CModule_Stop(pcbe, pCBModuleI2CParams); + } + cbI2CModule_Disable(pcbe, pCBModuleI2CParams); + cbTraceExit(GENERIC); + return bStatus; + +} + +/*************************************************************** +Function: cbI2CModule_WriteData + +Description: Write data to I2C bus. + +Input: PCBIOS_VOID + PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: CBIOS_TURE if write data successfully + CBIOS_FALSE if write data failed +***************************************************************/ +CBIOS_BOOL cbI2CModule_WriteData(PCBIOS_VOID pvcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + CBIOS_U32 i = 0; + CBIOS_U8 SlaveAddr = pCBModuleI2CParams->SlaveAddress; + CBIOS_U8 Offset = pCBModuleI2CParams->OffSet; + CBIOS_U32 BufferLen = pCBModuleI2CParams->BufferLen; + CBIOS_U8 I2CBusNum = pCBModuleI2CParams->I2CBusNum; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL bStatus = CBIOS_FALSE; + + cbTraceEnter(GENERIC); + if ((I2CBusNum == I2CBUS_VIRTUAL_DP1) || (I2CBusNum == I2CBUS_VIRTUAL_DP2) || (I2CBusNum == I2CBUS_VIRTUAL_DP3) || (I2CBusNum == I2CBUS_VIRTUAL_DP4)) + { + CBIOS_ACTIVE_TYPE Device = CBIOS_TYPE_NONE; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_MODULE_INDEX DPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + if (I2CBusNum == I2CBUS_VIRTUAL_DP1) + { + Device = CBIOS_TYPE_DP1; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP2) + { + Device = CBIOS_TYPE_DP2; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP3) + { + Device = CBIOS_TYPE_DP3; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP4) + { + Device = CBIOS_TYPE_DP4; + } + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + DPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_DP); + if (cbDPPort_IsDeviceInDpMode(pcbe, pDevCommon)) + { +#if DP_MONITOR_SUPPORT + bStatus = cbDIU_DP_WriteData(pvcbe, DPModuleIndex, pCBModuleI2CParams, CBIOS_FALSE); + return bStatus; +#endif + } + else // Dual Mode, just switch to normal I2C operation + { + pCBModuleI2CParams->I2CBusNum = (CBIOS_U8)pDevCommon->I2CBus; + } + } + + if (pCBModuleI2CParams->ConfigType == CONFIG_I2C_BY_BUSNUM) + { + if (cbI2CModule_GetI2CParams(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + return CBIOS_FALSE; + } + } + + cbI2CModule_Enable(pcbe, pCBModuleI2CParams); + cbI2CModule_Start(pcbe, pCBModuleI2CParams); + + cbI2CModule_WriteByte(pcbe, pCBModuleI2CParams, SlaveAddr); + if(cbI2CModule_AckRead(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + + cbI2CModule_WriteByte(pcbe, pCBModuleI2CParams, Offset); + if(cbI2CModule_AckRead(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + + for(i=0; i< BufferLen; i++) + { + cbI2CModule_WriteByte(pcbe, pCBModuleI2CParams, pCBModuleI2CParams->Buffer[i]); + if(cbI2CModule_AckRead(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + } + + + if(cbI2CModule_Stop(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + + bStatus = CBIOS_TRUE; + +exit: + if(!bStatus) + { + cbI2CModule_Stop(pcbe, pCBModuleI2CParams); + } + cbI2CModule_Disable(pcbe, pCBModuleI2CParams); + cbTraceExit(GENERIC); + return bStatus; + +} + +/*************************************************************** +Function: cbI2CModule_ReadDDCCIData + +Description: Read DDC-CI data from I2C bus. + +Input: PCBIOS_VOID + PCBIOS_MODULE_I2C_PARAMS + Flags + +Output: + +Return: CBIOS_TURE if read data successfully + CBIOS_FALSE if read data failed +***************************************************************/ +CBIOS_STATUS cbI2CModule_ReadDDCCIData(PCBIOS_VOID pvcbe, + PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams, + CBIOS_U32 Flags) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 ulLength = 0, i = 0; + CBIOS_STATUS bStatus = CBIOS_ER_INTERNAL; + CBIOS_U8 I2CBusNum = pCBModuleI2CParams->I2CBusNum; + CBIOS_U8 SlaveAddress = pCBModuleI2CParams->SlaveAddress; + CBIOS_U32 BufferLen = pCBModuleI2CParams->BufferLen; + CBIOS_U8* buffer = pCBModuleI2CParams->Buffer; + CBIOS_STATUS Status = CBIOS_ER_IO; + + cbTraceEnter(GENERIC); + + if ((I2CBusNum == I2CBUS_VIRTUAL_DP1) || (I2CBusNum == I2CBUS_VIRTUAL_DP2) || (I2CBusNum == I2CBUS_VIRTUAL_DP3) || (I2CBusNum == I2CBUS_VIRTUAL_DP4)) + { + CBIOS_ACTIVE_TYPE Device = CBIOS_TYPE_NONE; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_MODULE_INDEX DPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + + if (I2CBusNum == I2CBUS_VIRTUAL_DP1) + { + Device = CBIOS_TYPE_DP1; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP2) + { + Device = CBIOS_TYPE_DP2; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP3) + { + Device = CBIOS_TYPE_DP3; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP4) + { + Device = CBIOS_TYPE_DP4; + } + + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + DPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_DP); + + if (cbDPPort_IsDeviceInDpMode(pcbe, pDevCommon)) + { +#if DP_MONITOR_SUPPORT + bStatus = cbDIU_DP_ReadData(pvcbe, DPModuleIndex, pCBModuleI2CParams, Flags, CBIOS_TRUE); + return bStatus; +#endif + } + else // Dual Mode, just switch to normal I2C operation + { + pCBModuleI2CParams->I2CBusNum = (CBIOS_U8)pDevCommon->I2CBus; + } + } + + if (pCBModuleI2CParams->ConfigType == CONFIG_I2C_BY_BUSNUM) + { + if (cbI2CModule_GetI2CParams(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_ReadDDCCIData: get I2C params failed!\n")); + return CBIOS_ER_INTERNAL; + } + } + cbI2CModule_Enable(pcbe, pCBModuleI2CParams); + cbI2CModule_Start(pcbe, pCBModuleI2CParams); + + cbI2CModule_WriteByte(pcbe, pCBModuleI2CParams, SlaveAddress + 1); + if(cbI2CModule_AckRead(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + Status = CBIOS_ER_IO; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_ReadDDCCIData: Ack Read error!\n")); + goto exit; + } + for(i = 0; i < BufferLen-1; i++) + { + if(cbI2CModule_ReadByte(pcbe, pCBModuleI2CParams, &buffer[i]) == CBIOS_FALSE) + { + Status = CBIOS_ER_IO; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_ReadDDCCIData: cbI2CModule_ReadByte failure!\n")); + goto exit; + } + if(cbI2CModule_AckWrite(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + Status = CBIOS_ER_IO; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_ReadDDCCIData: Ack Write error!\n")); + goto exit; + } + if ((i == 1) && (Flags & 0x000000001)) + { + ulLength = buffer[i] & ~0x80; + if (ulLength > (BufferLen - 3)) + { + cbI2CModule_Stop(pcbe, pCBModuleI2CParams); + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_ReadDDCCIData: buffer is too small!\n")); + Status = CBIOS_ER_BUFFER_TOO_SMALL; + goto exit; + } + BufferLen = ulLength + 3; + } + } + if(cbI2CModule_ReadByte(pcbe, pCBModuleI2CParams, &buffer[i]) == CBIOS_FALSE) + { + Status = CBIOS_ER_IO; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_ReadDDCCIData: cbI2CModule_ReadByte failure!\n")); + goto exit; + } + + cbI2CModule_NackWrite(pcbe, pCBModuleI2CParams); + + if(cbI2CModule_Stop(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + Status = CBIOS_ER_IO; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_ReadDDCCIData: cbI2CModule_Stop failure!\n")); + goto exit; + } + Status = CBIOS_OK; +exit: + cbI2CModule_Stop(pcbe, pCBModuleI2CParams); + cbI2CModule_Disable(pcbe, pCBModuleI2CParams); + cbTraceExit(GENERIC); + return Status; + +} + +/*************************************************************** +Function: cbI2CModule_WriteDDCCIData + +Description: Write DDC-CI data to I2C bus. + +Input: PCBIOS_VOID + PCBIOS_MODULE_I2C_PARAMS + +Output: + +Return: CBIOS_TURE if write data successfully + CBIOS_FALSE if write data failed +***************************************************************/ +CBIOS_BOOL cbI2CModule_WriteDDCCIData(PCBIOS_VOID pvcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 i; + CBIOS_BOOL bStatus = CBIOS_FALSE; + CBIOS_U8 I2CBusNum = pCBModuleI2CParams->I2CBusNum; + CBIOS_U8 SlaveAddress = pCBModuleI2CParams->SlaveAddress; + + cbTraceEnter(GENERIC); + if ((I2CBusNum == I2CBUS_VIRTUAL_DP1) || (I2CBusNum == I2CBUS_VIRTUAL_DP2) || (I2CBusNum == I2CBUS_VIRTUAL_DP3) || (I2CBusNum == I2CBUS_VIRTUAL_DP4)) + { + CBIOS_ACTIVE_TYPE Device = CBIOS_TYPE_NONE; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_MODULE_INDEX DPModuleIndex = CBIOS_MODULE_INDEX_INVALID; + + if (I2CBusNum == I2CBUS_VIRTUAL_DP1) + { + Device = CBIOS_TYPE_DP1; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP2) + { + Device = CBIOS_TYPE_DP2; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP3) + { + Device = CBIOS_TYPE_DP3; + } + else if (I2CBusNum == I2CBUS_VIRTUAL_DP4) + { + Device = CBIOS_TYPE_DP4; + } + + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, Device); + DPModuleIndex = cbGetModuleIndex(pcbe, Device, CBIOS_MODULE_TYPE_DP); + + if (cbDPPort_IsDeviceInDpMode(pcbe, pDevCommon)) + { +#if DP_MONITOR_SUPPORT + bStatus = cbDIU_DP_WriteData(pvcbe, DPModuleIndex, pCBModuleI2CParams, CBIOS_TRUE); + return bStatus; +#endif + } + else // Dual Mode, just switch to normal I2C operation + { + pCBModuleI2CParams->I2CBusNum = (CBIOS_U8)pDevCommon->I2CBus; + } + } + + if (pCBModuleI2CParams->ConfigType == CONFIG_I2C_BY_BUSNUM) + { + if (cbI2CModule_GetI2CParams(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + return CBIOS_FALSE; + } + } + + cbI2CModule_Enable(pcbe, pCBModuleI2CParams); + cbI2CModule_Start(pcbe, pCBModuleI2CParams); + + //write slave address + cbI2CModule_WriteByte(pcbe, pCBModuleI2CParams, SlaveAddress); + if(cbI2CModule_AckRead(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + + for(i=0; i< pCBModuleI2CParams->BufferLen - 1; i++) + { + cbI2CModule_WriteByte(pcbe, pCBModuleI2CParams, pCBModuleI2CParams->Buffer[i]); + if(cbI2CModule_AckRead(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + } + cbI2CModule_WriteByte(pcbe, pCBModuleI2CParams, pCBModuleI2CParams->Buffer[i]); + cbI2CModule_AckRead(pcbe, pCBModuleI2CParams); + if(SlaveAddress != 0x60) + { + if(cbI2CModule_Stop(pcbe, pCBModuleI2CParams) == CBIOS_FALSE) + { + bStatus = CBIOS_FALSE; + goto exit; + } + } + bStatus = CBIOS_TRUE; +exit: + cbI2CModule_Disable(pcbe, pCBModuleI2CParams); + cbTraceExit(GENERIC); + return bStatus; +} + +CBIOS_STATUS cbI2CModule_DDCCI_OPEN(PCBIOS_VOID pvcbe, CBIOS_BOOL bOpen, PCBIOS_I2CCONTROL pI2CControl, CBIOS_U8 I2CBUSNum) +{ + CBIOS_MODULE_I2C_PARAMS I2CParams; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + cb_memset(&I2CParams, 0, sizeof(CBIOS_MODULE_I2C_PARAMS)); + I2CParams.I2CBusNum = I2CBUSNum; + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + return CBIOS_ER_CHIPDISABLE; +#endif + + pI2CControl->Status = DDCCII2C_STATUS_ERROR; + + if ((pI2CControl->ClockRate > DDCCIMAX_CLOCK_RATE) || (pI2CControl->ClockRate == 0)) + { + pI2CControl->ClockRate = DDCCIMAX_CLOCK_RATE; + } + + if (cbI2CModule_GetI2CParams(pcbe, &I2CParams)) + { + if (bOpen) + { + cbI2CModule_Enable(pcbe, &I2CParams); + if (cbI2CModule_DDCCI_GetCookie(&pI2CControl->dwCookie)) + { + pI2CControl->Status = DDCCII2C_STATUS_NOERROR; + } + } + else + { + cbI2CModule_Disable(pcbe, &I2CParams); + pI2CControl->dwCookie = 0; + pI2CControl->Status = DDCCII2C_STATUS_NOERROR; + } + + if (pI2CControl->Status != DDCCII2C_STATUS_NOERROR) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_DDCCI_OPEN: funciton failure!\n")); + } + + return pI2CControl->Status; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_DDCCI_OPEN: Not support this I2C bus number!\n")); + return DDCCII2C_STATUS_ERROR; + } +} + +CBIOS_STATUS cbI2CModule_DDCCI_ACCESS(PCBIOS_VOID pvcbe, PCBIOS_I2CCONTROL pI2CControl, CBIOS_U8 I2CBUSNum) +{ + CBIOS_MODULE_I2C_PARAMS I2CParams; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + cb_memset(&I2CParams, 0, sizeof(CBIOS_MODULE_I2C_PARAMS)); + I2CParams.I2CBusNum = I2CBUSNum; + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + return CBIOS_ER_CHIPDISABLE; +#endif + + pI2CControl->Status = DDCCII2C_STATUS_NOERROR; + + if ((pI2CControl->ClockRate > DDCCIMAX_CLOCK_RATE) || (pI2CControl->ClockRate == 0)) + { + pI2CControl->ClockRate = DDCCIMAX_CLOCK_RATE; + } + + if (cbI2CModule_GetI2CParams(pcbe, &I2CParams)) + { + switch(pI2CControl->Command) + { + case DDCCII2C_COMMAND_NULL: + pI2CControl->Status = cbI2CModule_DDCCI_Null(pcbe, pI2CControl, &I2CParams); + break; + + case DDCCII2C_COMMAND_READ: + pI2CControl->Status = cbI2CModule_DDCCI_Read(pcbe, pI2CControl, &I2CParams); + break; + + case DDCCII2C_COMMAND_WRITE: + pI2CControl->Status = cbI2CModule_DDCCI_Write(pcbe, pI2CControl, &I2CParams); + break; + + case DDCCII2C_COMMAND_RESET: + pI2CControl->Status = cbI2CModule_DDCCI_Stop(pcbe, &I2CParams); + break; + + case DDCCII2C_COMMAND_STATUS: + break; + + default: + pI2CControl->Status = DDCCII2C_STATUS_ERROR; + break; + } + + if(pI2CControl->Status != DDCCII2C_STATUS_NOERROR) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_DDCCI_ACCESS: funciton failure!\n")); + } + return pI2CControl->Status; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbI2CModule_DDCCI_ACCESS: Not support this I2C bus number!\n")); + return DDCCII2C_STATUS_ERROR; + } +} + +CBIOS_VOID cbI2CModule_HDCPI2CEnableDisable(PCBIOS_VOID pvcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams, CBIOS_BOOL bIsEnable) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + if (pCBModuleI2CParams->ConfigType == CONFIG_I2C_BY_BUSNUM) + { + cbI2CModule_GetI2CParams(pcbe, pCBModuleI2CParams); + } + + if (bIsEnable) + { + cbI2CModule_Enable(pcbe, pCBModuleI2CParams); + } + else + { + cbI2CModule_Disable(pcbe, pCBModuleI2CParams); + } +} diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosI2C.h b/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosI2C.h new file mode 100644 index 0000000000000..347bfaf32ca1a --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosI2C.h @@ -0,0 +1,133 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** I2C module interface prototype and parameter definition. +** +** NOTE: +** This header file CAN ONLY be included by hw layer those files under Hw folder. +******************************************************************************/ + +#ifndef _CBIOS_I2C_H_ +#define _CBIOS_I2C_H_ + +#define LEVEL_HIGH 1 //line level high +#define LEVEL_LOW 0 //line level low +#define MAXI2CWAITLOOP 4000 + +/* For DDC-CI */ +/* I2C Commands */ +#define DDCCII2C_COMMAND_NULL 0x0000 +#define DDCCII2C_COMMAND_READ 0x0001 +#define DDCCII2C_COMMAND_WRITE 0x0002 +#define DDCCII2C_COMMAND_STATUS 0x0004 +#define DDCCII2C_COMMAND_RESET 0x0008 + +/* The following flags are provided on a READ or WRITE command */ +#define DDCCII2C_FLAGS_START 0x0001 /* START + addx */ +#define DDCCII2C_FLAGS_STOP 0x0002 /* STOP */ +#define DDCCII2C_FLAGS_DATACHAINING 0x0004 /* STOP, START + addx */ +#define DDCCII2C_FLAGS_ACK 0x0010 /* ACKNOWLEDGE (normally set)*/ + +/* The following status flags are returned on completion of the operation */ +#define DDCCII2C_STATUS_NOERROR 0x0000 +#define DDCCII2C_STATUS_BUSY 0x0001 +#define DDCCII2C_STATUS_ERROR 0x0002 + +#define DDCCIMAX_CLOCK_RATE 1000*1000 /* in Hz */ +#define DDCCIMIN_CLOCK_RATE 10*1000 /* in Hz */ + +// I2C & GPIO pair as I2C index definition +typedef enum _CBIOS_I2CBUS_INDEX +{ + I2CBUS0 = 0, + I2CBUS1 = 1, + I2CBUS2 = 2, + I2CBUS3 = 3, + I2CBUS4 = 4, + RSVD_I2CBUS5 = 5, + RSVD_I2CBUS6 = 6, + RSVD_I2CBUS7 = 7, + I2CBUS_SCLGPIO4_SDAGPIO5 = 8, + I2CBUS_SCLGPIO5_SDAGPIO2 = 9, + I2CBUS_SCLGPIO3_SDAGPIO4 = 10, + I2CBUS_SCLGPIO2_SDAGPIO5 = 11, + I2CBUS_SCLGPIO2_SDAGPIO3 = 12, + RSVD_I2CBUS13 = 13, + RSVD_I2CBUS14 = 14, + RSVD_I2CBUS15 = 15, + I2CBUS_VIRTUAL_DP1 = 16, + I2CBUS_VIRTUAL_DP2 = 17, + I2CBUS_VIRTUAL_DAC1 = 18, //for no-edid device to store fake edid + I2CBUS_VIRTUAL_DAC2 = 19, //for no-edid device to store fake edid + I2CBUS_VIRTUAL_DVO1 = 20, //for no-edid device to store fake edid + I2CBUS_VIRTUAL_DVO2 = 21, //for no-edid device to store fake edid + I2CBUS_VIRTUAL_COMBO1 = 22, //for no-edid device to store fake edid + I2CBUS_VIRTUAL_COMBO2 = 23, //for no-edid device to store fake edid + I2CBUS_VIRTUAL_DP3 = 24, + I2CBUS_VIRTUAL_DP4 = 25, + TOTAL_I2CBUS_NUM, +}CBIOS_I2CBUS_INDEX; +#define MIN_NORMAL_I2C_BUS I2CBUS0 +#define MAX_NORMAL_I2C_BUS I2CBUS4 +#define MIN_GPIO_I2C_BUS I2CBUS_SCLGPIO4_SDAGPIO5 +#define MAX_GPIO_I2C_BUS I2CBUS_SCLGPIO2_SDAGPIO3 + +typedef enum _CBIOS_I2C_CONFIGTYPE +{ + CONFIG_I2C_BY_BUSNUM = 0, //only set I2C bus num + CONFIG_I2C_BY_REG = 1 //set the Dline and Cline registers directly +}CBIOS_I2C_CONFIGTYPE; + +typedef struct _CBIOS_I2C_REG_PARAMS { + CBIOS_U16 DLineRegType_Index; + CBIOS_U8 DLineRegReadBitNum; + CBIOS_U8 DLineRegReadEnableValue; // only used for GPIO, should set value to zero for I2C + CBIOS_U8 DLineRegReadEnableMask; // only used for GPIO, should set mask to 0xFF for I2C + CBIOS_U8 DLineRegWriteBitNum; + CBIOS_U8 DLineRegWriteEnableValue; // equal port enable value for I2C + CBIOS_U8 DLineRegWriteEnableMask; // equal port enable mask for I2C + CBIOS_U16 CLineRegType_Index; + CBIOS_U8 CLineRegReadBitNum; + CBIOS_U8 CLineRegReadEnableValue; // only used for GPIO, should set value to zero for I2C + CBIOS_U8 CLineRegReadEnableMask; // only used for GPIO, should set mask to 0xFF for I2C + CBIOS_U8 CLineRegWriteBitNum; + CBIOS_U8 CLineRegWriteEnableValue; // equal port enable value for I2C + CBIOS_U8 CLineRegWriteEnableMask; // equal port enable mask for I2C +} CBIOS_I2C_REG_PARAMS, *PCBIOS_I2C_REG_PARAMS; + +typedef struct _CBIOS_MODULE_I2C_PARAMS { + CBIOS_U32 Size; + CBIOS_I2C_REG_PARAMS I2CRegParams; + CBIOS_U8 I2CBusNum; + CBIOS_U8 SlaveAddress; + CBIOS_U8 OffSet; + CBIOS_U8* Buffer; + CBIOS_U32 BufferLen; + CBIOS_U8 ConfigType; // CONFIG_I2C_BY_REG: set the Dline and Cline registers directly;CONFIG_I2C_BY_BUSNUM: only use I2C bus num + CBIOS_U32 Flags; +} CBIOS_MODULE_I2C_PARAMS, *PCBIOS_MODULE_I2C_PARAMS; + +//I2C module interfaces +CBIOS_BOOL cbI2CModule_ReadData(PCBIOS_VOID pvcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams); +CBIOS_BOOL cbI2CModule_WriteData(PCBIOS_VOID pvcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams); +CBIOS_STATUS cbI2CModule_ReadDDCCIData(PCBIOS_VOID pvcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams, CBIOS_U32 Flags); +CBIOS_BOOL cbI2CModule_WriteDDCCIData(PCBIOS_VOID pvcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams); +CBIOS_STATUS cbI2CModule_DDCCI_OPEN(PCBIOS_VOID pvcbe, CBIOS_BOOL bOpen, PCBIOS_I2CCONTROL pI2CControl, CBIOS_U8 I2CBUSNum); +CBIOS_STATUS cbI2CModule_DDCCI_ACCESS(PCBIOS_VOID pvcbe, PCBIOS_I2CCONTROL pI2CControl, CBIOS_U8 I2CBUSNum); +CBIOS_VOID cbI2CModule_HDCPI2CEnableDisable(PCBIOS_VOID pvcbe, PCBIOS_MODULE_I2C_PARAMS pCBModuleI2CParams, CBIOS_BOOL bIsEnable); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.c b/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.c new file mode 100644 index 0000000000000..872d0a7afa51c --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.c @@ -0,0 +1,2518 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios hw utility common functions implementation. +** +** NOTE: +** The functions in this file are hw layer internal functions, +** CAN ONLY be called by files under Hw folder. +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" +#include "../Register/BIU_SBI_registers.h" + +//CLK - start +static CBREGISTER_IDX E3K_DCLK1_Integer_MAP[] = { + { SR_12, 0xFF}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK1_Fraction_MAP[] = { + { SR_13, 0xFF}, + { CR_B_EC, 0xFF}, + { SR_29, 0x0F}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK1_R_MAP[] = { + { SR_10, 0x0C}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK1_DIV_MAP[] = { + { CR_B_D0, 0xC0}, + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX E3K_DCLK2_Integer_MAP[] = { + { SR_0E, 0xFF}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK2_Fraction_MAP[] = { + { SR_0F, 0xFF}, + { CR_F2, 0xFF}, + { CR_B_E5, 0x0F}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK2_R_MAP[] = { + { SR_29, 0x30}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK2_DIV_MAP[] = { + { CR_B_D1, 0xC0}, + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX E3K_DCLK3_Integer_MAP[] = { + { CR_B5, 0xFF}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK3_Fraction_MAP[] = { + { CR_B6, 0xFF}, + { CR_B7, 0xFF}, + { CR_B8, 0x0F}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK3_R_MAP[] = { + { CR_B4, 0x03}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK3_DIV_MAP[] = { + { CR_B_D2, 0xC0}, + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX E3K_DCLK4_Integer_MAP[] = { + { CR_D6, 0xFF}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK4_Fraction_MAP[] = { + { CR_D5, 0xFC}, + { CR_D7, 0xFF}, + { CR_D8, 0x3F}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK4_R_MAP[] = { + { CR_D5, 0x03}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_DCLK4_DIV_MAP[] = { + { CR_D9, 0x03}, + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX E3K_ECLK_Integer_MAP[] = { + { CR_DF, 0x7F}, + { CR_DE, 0x10}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_ECLK_R_MAP[] = { + { CR_DD, 0x06}, + { MAPMASK_EXIT}, +}; + +static CBREGISTER_IDX E3K_VCLK_Integer_MAP[] = { + { CR_DC, 0x7F}, + { CR_DB, 0x10}, + { MAPMASK_EXIT}, +}; +static CBREGISTER_IDX E3K_VCLK_R_MAP[] = { + { CR_DA, 0x06}, + { MAPMASK_EXIT}, +}; +//CLK - end + +CBIOS_REGISTER_RANGE CBIOS_CR_REGS[] = +{ + {CBIOS_REGISTER_MMIO, 1, 0x8800, 0x88FF}, + {CBIOS_REGISTER_MMIO, 1, 0x8900, 0x89FF}, + {CBIOS_REGISTER_MMIO, 1, 0x9500, 0x95ff}, +}; + + +CBIOS_REGISTER_RANGE CBIOS_SR_REGS[] = +{ + {CBIOS_REGISTER_MMIO, 1, 0x8600, 0x86FF}, + {CBIOS_REGISTER_MMIO, 1, 0x8700, 0x87FF}, + {CBIOS_REGISTER_MMIO, 1, 0x9400, 0x94ff}, +}; + +CBIOS_REGISTER_RANGE CBIOS_HDMI_REGS[] = +{ + {CBIOS_REGISTER_MMIO, 1, 0x873B, 0x873B}, + + {CBIOS_REGISTER_MMIO, 4, 0x81A0, 0x81A0}, + {CBIOS_REGISTER_MMIO, 4, 0x8194, 0x8194}, + {CBIOS_REGISTER_MMIO, 4, 0x34A4, 0x34B8}, + {CBIOS_REGISTER_MMIO, 4, 0x8280, 0x8298}, + +}; + +CBIOS_REGISTER_RANGE CBIOS_SS1_REGS[] = +{ + {CBIOS_REGISTER_MMIO, 1, 0x8864, 0x8867}, + + {CBIOS_REGISTER_MMIO, 4, 0x8184, 0x8184}, + {CBIOS_REGISTER_MMIO, 4, 0x8190, 0x819C}, + {CBIOS_REGISTER_MMIO, 4, 0x81A8, 0x81A8}, + {CBIOS_REGISTER_MMIO, 4, 0x81D0, 0x81D8}, + {CBIOS_REGISTER_MMIO, 4, 0x81E4, 0x81E4}, + {CBIOS_REGISTER_MMIO, 4, 0x81EC, 0x81EC}, + {CBIOS_REGISTER_MMIO, 4, 0x81F8, 0x81FC}, + {CBIOS_REGISTER_MMIO, 4, 0x8278, 0x8278}, + {CBIOS_REGISTER_MMIO, 4, 0x828C, 0x828C}, + {CBIOS_REGISTER_MMIO, 4, 0x32C4, 0x32C4}, + {CBIOS_REGISTER_MMIO, 4, 0x30BC, 0x30BC}, + +}; + +CBIOS_REGISTER_RANGE CBIOS_SS2_REGS[] = +{ + {CBIOS_REGISTER_MMIO, 1, 0x8864, 0x8867}, + + {CBIOS_REGISTER_MMIO, 4, 0x8188, 0x818C}, + {CBIOS_REGISTER_MMIO, 4, 0x81AC, 0x81AC}, + {CBIOS_REGISTER_MMIO, 4, 0x81BC, 0x81BC}, + {CBIOS_REGISTER_MMIO, 4, 0x81CC, 0x81CC}, + {CBIOS_REGISTER_MMIO, 4, 0x81DC, 0x81DC}, + {CBIOS_REGISTER_MMIO, 4, 0x81E0, 0x81E0}, + {CBIOS_REGISTER_MMIO, 4, 0x81F0, 0x81F4}, + {CBIOS_REGISTER_MMIO, 4, 0x8200, 0x8200}, + {CBIOS_REGISTER_MMIO, 4, 0x8204, 0x8204}, + {CBIOS_REGISTER_MMIO, 4, 0x8208, 0x820C}, + {CBIOS_REGISTER_MMIO, 4, 0x8260, 0x8260}, + {CBIOS_REGISTER_MMIO, 4, 0x827C, 0x827C}, + {CBIOS_REGISTER_MMIO, 4, 0x32CC, 0x32CC}, + {CBIOS_REGISTER_MMIO, 4, 0x30FC, 0x30FC}, +}; + +CBIOS_REGISTER_GROUP CBIOS_REGISTER_TABLE[] = +{ + {"CR", CBIOS_CR_REGS, sizeofarray(CBIOS_CR_REGS)}, + {"SR", CBIOS_SR_REGS, sizeofarray(CBIOS_SR_REGS)}, + {"PMU", CBIOS_NULL, 0}, + {"TIMING", CBIOS_NULL, 0}, + {"DSI0", CBIOS_NULL, 0}, + {"DSI1", CBIOS_NULL, 0}, + {"MHL", CBIOS_NULL, 0}, + {"DP", CBIOS_NULL, 0}, + {"HDMI", CBIOS_HDMI_REGS, sizeofarray(CBIOS_HDMI_REGS)}, + {"PS1", CBIOS_NULL, 0}, + {"PS2", CBIOS_NULL, 0}, + {"SS1", CBIOS_SS1_REGS, sizeofarray(CBIOS_SS1_REGS)}, + {"SS2", CBIOS_SS2_REGS, sizeofarray(CBIOS_SS2_REGS)}, +}; + + +CBIOS_VOID cbUnlockSR(PCBIOS_EXTENSION_COMMON pcbe) +{ + REG_SR08 RegSR08Value; + REG_SR08 RegSR08Mask; + RegSR08Value.Value = 0; + RegSR08Value.Unlock_Extended_Sequencer = 0x06; + RegSR08Mask.Value = 0; + cbMMIOWriteReg(pcbe, SR_08, RegSR08Value.Value, RegSR08Mask.Value); +} + +CBIOS_VOID cbUnlockCR(PCBIOS_EXTENSION_COMMON pcbe) +{ + REG_CR38 RegCR38Value; + REG_CR38 RegCR38Mask; + REG_CR39 RegCR39Value; + REG_CR39 RegCR39Mask; + REG_CR35_Pair RegCR35Value; + REG_CR35_Pair RegCR35Mask; + REG_CR11_Pair RegCR11Value; + REG_CR11_Pair RegCR11Mask; + REG_CR35_Pair RegCR35_BValue; + REG_CR35_Pair RegCR35_BMask; + REG_CR11_Pair RegCR11_BValue; + REG_CR11_Pair RegCR11_BMask; + + RegCR38Value.Value = 0; + RegCR38Value.CRTC_Register_Lock_1 = 0x48; + RegCR38Mask.Value = 0x00; + cbMMIOWriteReg(pcbe, CR_38, RegCR38Value.Value, RegCR38Mask.Value); + + RegCR39Value.Value = 0; + RegCR39Value.CRTC_Register_Lock_2 = 0xA5; + RegCR39Mask.Value = 0x00; + cbMMIOWriteReg(pcbe, CR_39, RegCR39Value.Value, RegCR39Mask.Value); + + RegCR35Value.Value = 0; + RegCR35Value.Vertical_Timing_Registers_Lock = 0; + RegCR35Value.Horizontal_Timing_Registers_Lock = 0; + RegCR35Value.CR01_3C2h_6_Lock = 0; + RegCR35Value.CR12_3C2h_7_Lock = 0; + RegCR35Mask.Value = 0x0F; + cbMMIOWriteReg(pcbe, CR_35, RegCR35Value.Value, RegCR35Mask.Value); + + RegCR11Value.Value = 0; + RegCR11Value.Lock_Writes_to_CR00_to_CR07 = 0; + RegCR11Mask.Value = 0xFF; + RegCR11Mask.Lock_Writes_to_CR00_to_CR07 = 0; + cbMMIOWriteReg(pcbe, CR_11, RegCR11Value.Value, RegCR11Mask.Value); + + RegCR35_BValue.Value = 0; + RegCR35_BValue.Vertical_Timing_Registers_Lock = 0; + RegCR35_BValue.Horizontal_Timing_Registers_Lock = 0; + RegCR35_BValue.CR01_3C2h_6_Lock = 0; + RegCR35_BValue.CR12_3C2h_7_Lock = 0; + RegCR35_BMask.Value = 0x0F; + cbMMIOWriteReg(pcbe, CR_B_35, RegCR35_BValue.Value, RegCR35_BMask.Value); + + RegCR11_BValue.Value = 0; + RegCR11_BValue.Lock_Writes_to_CR00_to_CR07 = 0; + RegCR11_BMask.Value = 0xFF; + RegCR11_BMask.Lock_Writes_to_CR00_to_CR07 = 0; + cbMMIOWriteReg(pcbe, CR_B_11, RegCR11_BValue.Value, RegCR11_BMask.Value); + + + cbMMIOWriteReg(pcbe, CR_T_35, RegCR35_BValue.Value, RegCR35_BMask.Value); + cbMMIOWriteReg(pcbe, CR_T_11, RegCR11_BValue.Value, RegCR11_BMask.Value); + + cbMMIOWriteReg(pcbe, CR_F_35, RegCR35_BValue.Value, RegCR35_BMask.Value); + cbMMIOWriteReg(pcbe, CR_F_11, RegCR11_BValue.Value, RegCR11_BMask.Value); + +} + +CBIOS_VOID cbWaitForBlank(PCBIOS_EXTENSION_COMMON pcbe) +{ + if(pcbe->bRunOnQT) + { + return; + } + else + { + CBIOS_S32 i; + for (i=0;i<65536;i++) + { + //3xA,VSYNC (0=display, 1=blank) +// if((cb_ReadU8(pcbe->pAdapterContext, CB_INPUT_STATUS_1_REG)&0x08)!=0) + if((cbMMIOReadReg(pcbe, CR_1A)&0x08)!=0) + break; + } + } +} + +CBIOS_VOID cbWaitForDisplay(PCBIOS_EXTENSION_COMMON pcbe) +{ + if(pcbe->bRunOnQT) + { + return; + } + else + { + CBIOS_S32 i; + for (i=0;i<65536;i++) + { + //3xA,VSYNC (0=display, 1=blank) +// if((cb_ReadU8(pcbe->pAdapterContext, CB_INPUT_STATUS_1_REG)&0x08)==0) + if((cbMMIOReadReg(pcbe, CR_1A)&0x08)==0) + break; + } + } +} + +CBIOS_VOID cbWaitForActive(PCBIOS_EXTENSION_COMMON pcbe) +{ + //Wait for the start of blank signal, or we are already in blank. + cbWaitForBlank(pcbe); + //Wait for the display signal. + cbWaitForDisplay(pcbe); +} + +CBIOS_VOID cbWaitForInactive(PCBIOS_EXTENSION_COMMON pcbe) +{ + //Wait for the display signal, or we are already in display. + cbWaitForDisplay(pcbe); + //Wait for the start of the blank signal. + cbWaitForBlank(pcbe); +} + +CBIOS_U32 cbGetParallelRegIndex(PCBIOS_PARALLEL_REGISTER pRegTbl, CBIOS_U32 RegNameIndex, CBIOS_U32 ModuleIndex) +{ + CBIOS_U32 i = 0; + CBIOS_U32 ParallelRegIndex = 0xFFFFFFFF; + + while((i < PARALLEL_TABLE_MAX_SIZE) && (pRegTbl[i].RegNameIndex != PARALLEL_TABLE_END_INDEX)) + { + if(pRegTbl[i].RegNameIndex == RegNameIndex) + { + ParallelRegIndex = pRegTbl[RegNameIndex].RegIndex[ModuleIndex]; + break; + } + i++; + } + + return ParallelRegIndex; +} + +CBIOS_U8 cbBiosMMIOReadReg(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U16 type_index, + CBIOS_U32 IGAModuleIndex) +{ + CBIOS_U8 type = (CBIOS_U8) ((type_index&0xFF00) >> 8); + CBIOS_U8 index = (CBIOS_U8) (type_index&0x00FF); + CBIOS_U8 inType = type; + + if ((IGAModuleIndex == IGA2) || (IGAModuleIndex == CBIOS_MODULE_INDEX2)) + { + if(type == CR) + { + inType = CR_B; + } + else if (type == SR) + { + inType = SR_B; + } + } + else if ((IGAModuleIndex == IGA3) || (IGAModuleIndex == CBIOS_MODULE_INDEX3)) + { + if(type == CR) + { + inType = CR_T; + } + else if(type == SR) + { + inType = SR_T; + } + } + else if ((IGAModuleIndex == IGA4) || (IGAModuleIndex == CBIOS_MODULE_INDEX4)) + { + if(type == CR) + { + inType = CR_F; + } + else if(type == SR) + { + inType = SR_F; + } + } + + return cbMMIOReadReg(pcbe, (((CBIOS_U16)inType<<8)|index)); +} + +CBIOS_VOID cbBiosMMIOWriteReg(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U16 type_index, + CBIOS_U8 value, + CBIOS_U8 mask, + CBIOS_U32 IGAModuleIndex) +{ + CBIOS_U8 type = (CBIOS_U8) ((type_index&0xFF00) >> 8); + CBIOS_U8 index = (CBIOS_U8) (type_index&0x00FF); + CBIOS_U8 inType = type; + + if ((IGAModuleIndex == IGA2) || (IGAModuleIndex == CBIOS_MODULE_INDEX2)) + { + if(type == CR) + { + inType = CR_B; + } + else if (type == SR) + { + inType = SR_B; + } + } + else if ((IGAModuleIndex == IGA3) || (IGAModuleIndex == CBIOS_MODULE_INDEX3)) + { + if(type == CR) + { + inType = CR_T; + } + else if(type == SR) + { + inType = SR_T; + } + } + else if((IGAModuleIndex == IGA4) || (IGAModuleIndex == CBIOS_MODULE_INDEX4)) + { + if(type == CR) + { + inType = CR_F; + } + else if(type == SR) + { + inType = SR_F; + } + } + cbMMIOWriteReg(pcbe, (((CBIOS_U16)inType<<8)|index), value, mask); +} + +static CBIOS_U32 cbMMIOGetGroupOffset(CBIOS_U8 type) +{ + CBIOS_U32 MmioOffset = 0; + switch(type) + { + case CR: + MmioOffset = MMIO_OFFSET_CR_GROUP_A; + break; + case CR_B: + MmioOffset = MMIO_OFFSET_CR_GROUP_B; + break; + case CR_C: + MmioOffset = MMIO_OFFSET_CR_GROUP_C; + break; + case CR_D: + MmioOffset = MMIO_OFFSET_CR_GROUP_D; + break; + case CR_D_0: + MmioOffset = MMIO_OFFSET_CR_GROUP_D0; + break; + case CR_D_1: + MmioOffset = MMIO_OFFSET_CR_GROUP_D1; + break; + case CR_D_2: + MmioOffset = MMIO_OFFSET_CR_GROUP_D2; + break; + case CR_D_3: + MmioOffset = MMIO_OFFSET_CR_GROUP_D3; + break; + case CR_T: + MmioOffset = MMIO_OFFSET_CR_GROUP_T; + break; + case CR_F: + MmioOffset = MMIO_OFFSET_CR_GROUP_F; + break; + case SR: + MmioOffset = MMIO_OFFSET_SR_GROUP_A; + break; + case SR_B: + MmioOffset = MMIO_OFFSET_SR_GROUP_B; + break; + case SR_T: + MmioOffset = MMIO_OFFSET_SR_GROUP_T; + break; + case SR_F: + MmioOffset = MMIO_OFFSET_SR_GROUP_F; + break; + default: + MmioOffset = 0xFFFFFFFF; + break; + } + + return MmioOffset; +} + +CBIOS_U8 cbMMIOReadReg(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U16 type_index) +{ + CBIOS_U64 oldIrql = 0; + CBIOS_U32 mmioAddress; + CBIOS_U8 type = (CBIOS_U8) ((type_index&0xFF00) >> 8); + CBIOS_U8 index = (CBIOS_U8) (type_index&0x00FF); + CBIOS_U8 byRet = 0; + + if(type == MISC) + { + byRet = cb_ReadU8(pcbe->pAdapterContext, CB_MISC_OUTPUT_READ_REG); + } + else if(type == AR) + { + oldIrql = cb_AcquireSpinLock(pcbe->pSpinLock); + + cb_ReadU8(pcbe->pAdapterContext, CB_ATTR_INITIALIZE_REG); + cb_WriteU8(pcbe->pAdapterContext, CB_ATTR_ADDR_REG, index); + byRet = cb_ReadU8(pcbe->pAdapterContext, CB_ATTR_DATA_READ_REG); + + cb_ReleaseSpinLock(pcbe->pSpinLock, oldIrql ); + } + else if(type == GR) + { + oldIrql = cb_AcquireSpinLock(pcbe->pSpinLock); + + cb_WriteU8(pcbe->pAdapterContext, CB_GRAPH_ADDR_REG, index); + byRet = cb_ReadU8(pcbe->pAdapterContext, CB_GRAPH_DATA_REG); + + cb_ReleaseSpinLock(pcbe->pSpinLock, oldIrql ); + } + else + { + mmioAddress = cbMMIOGetGroupOffset(type); + if(mmioAddress != 0xFFFFFFFF) + { + byRet = cb_ReadU8(pcbe->pAdapterContext, mmioAddress+index); + } + } + + return byRet; +} + + +CBIOS_VOID cbMMIOWriteReg(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U16 type_index, + CBIOS_U8 value, + CBIOS_U8 mask) +{ + CBIOS_U64 oldIrql = 0; + CBIOS_U32 mmioAddress; + CBIOS_U8 type = (CBIOS_U8) ((type_index&0xFF00) >> 8); + CBIOS_U8 index = (CBIOS_U8) (type_index&0x00FF); + CBIOS_U8 byTemp; //Temp value, also save register's old value + + if((value & mask) != 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "**Register mask wrong, index=%x, value=%x, mask=%x**\n", type_index, value, mask)); + return; + } + + if(mask == 0xFF) + { + return; + } + + if(type == MISC) + { + byTemp = cb_ReadU8(pcbe->pAdapterContext, CB_MISC_OUTPUT_READ_REG); + byTemp = (byTemp & mask) | (value); + cb_WriteU8(pcbe->pAdapterContext, CB_MISC_OUTPUT_WRITE_REG,byTemp); + } + else if(type == AR) + { + oldIrql = cb_AcquireSpinLock(pcbe->pSpinLock); + + cb_ReadU8(pcbe->pAdapterContext, CB_ATTR_INITIALIZE_REG); + cb_WriteU8(pcbe->pAdapterContext, CB_ATTR_ADDR_REG, index); + byTemp = cb_ReadU8(pcbe->pAdapterContext, CB_ATTR_DATA_READ_REG); + byTemp = (byTemp & mask) | (value); + cb_ReadU8(pcbe->pAdapterContext, CB_ATTR_INITIALIZE_REG); + cb_WriteU8(pcbe->pAdapterContext, CB_ATTR_ADDR_REG, index); + cb_WriteU8(pcbe->pAdapterContext, CB_ATTR_DATA_WRITE_REG, byTemp); + + cb_ReleaseSpinLock(pcbe->pSpinLock, oldIrql ); + } + else if(type == GR) + { + oldIrql = cb_AcquireSpinLock(pcbe->pSpinLock); + + cb_WriteU8(pcbe->pAdapterContext, CB_GRAPH_ADDR_REG, index); + byTemp = cb_ReadU8(pcbe->pAdapterContext, CB_GRAPH_DATA_REG); + byTemp = (byTemp & mask) | (value); + cb_WriteU8(pcbe->pAdapterContext, CB_GRAPH_DATA_REG, byTemp); + + cb_ReleaseSpinLock(pcbe->pSpinLock, oldIrql ); + } + else + { + mmioAddress = cbMMIOGetGroupOffset(type); + if(mmioAddress != 0xFFFFFFFF) + { + mmioAddress += index; + byTemp = cb_ReadU8(pcbe->pAdapterContext, mmioAddress); + byTemp = (byTemp & mask) | (value); + cb_WriteU8(pcbe->pAdapterContext, mmioAddress, byTemp); + } + } +} + + +CBIOS_VOID cbMMIOWriteReg32(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 Index, CBIOS_U32 Value, CBIOS_U32 Mask) +{ + CBIOS_U32 ulTemp = 0; + + if(Mask == 0xFFFFFFFF) + { + return; + } + + ulTemp = cb_ReadU32(pcbe->pAdapterContext, Index) & Mask; + + Value &= (~Mask); + Value |= ulTemp; + + cb_WriteU32(pcbe->pAdapterContext, Index, Value); +} + + +/////////////////////////////////////////////////////////////////////////////// +//Read registers value into map masked value +//BIOS func name:MAPMASK_EBX_Read +/////////////////////////////////////////////////////////////////////////////// +// Input IGAEncoderIndex = 0: For IGA1. +// = 1: For IGA2. +// = 2: Reserve +// = 3: Reserve +// = 4: Reserve +// = 5: Reserve +// = 6: HDTVEncoder1. +// = 7: HDTVEncoder2. +// = 8: NonPaired. +CBIOS_U32 cbMapMaskRead(PCBIOS_EXTENSION_COMMON pcbe, CBREGISTER_IDX *regTable, CBIOS_U32 IGAEncoderIndex) +{ + CBIOS_U32 uRet = 0; + CBIOS_U8 byRegValue = 0; + CBREGISTER_IDX *reg = regTable; + CBIOS_U32 i,j=0; + + while(reg->type_index != MAPMASK_EXIT) + { + byRegValue = cbBiosMMIOReadReg(pcbe, reg->type_index, IGAEncoderIndex); + for(i = 0;i<8;i++) + { + if( reg->mask & 1<type_index != MAPMASK_EXIT) + { + byWritten = 0; + for(i = 0;i<8;i++) + { + if( reg->mask & 1<type_index, byWritten, ~(reg->mask), IGAEncoderIndex); + reg++; + } + // cbDebugPrint((DBG_LEVEL_DEBUG_MSG,"Exit:cbMapMaskWrite.\n")); +} + +CBIOS_VOID cbLoadtable(PCBIOS_EXTENSION_COMMON pcbe, + CBREGISTER *pRegTable, + CBIOS_U32 Table_Size, + CBIOS_U32 IGAEncoderIndex) +{ + CBREGISTER *pReg; + CBIOS_U32 i; + CBIOS_U8 bData; + CBIOS_U8 index; + CBIOS_U8 mask; + CBIOS_U8 type; + + pReg = pRegTable; + for( i = 0; i < Table_Size && pReg; i++,pReg++) + { + index = pReg->index; + mask = pReg->mask; + bData = pReg->value; + type = pReg->type; + type &= ZXG_POST_TYPE_MASK; + cbBiosMMIOWriteReg(pcbe, (((CBIOS_U16)type<<8)|index), bData, mask,IGAEncoderIndex); + } +} + + +CBIOS_VOID cbLoadMemoryTimingTbl(PCBIOS_EXTENSION_COMMON pcbe, + MMIOREGISTER* pRegTable, + CBIOS_U32 Table_Size) +{ + MMIOREGISTER* pReg = CBIOS_NULL; + CBIOS_U32 i = 0; + CBIOS_U32 data = 0; + CBIOS_U32 index = 0; + + pReg = pRegTable; + for( i = 0; (i < Table_Size) && pReg; i++,pReg++) + { + index = pReg->index; + data = pReg->value; + if(pReg->length == 32) + { + cb_WriteU32(pcbe->pAdapterContext, index, data); + } + else if(pReg->length == 16) + { + cb_WriteU16(pcbe->pAdapterContext, index, (CBIOS_U16)data); + } + else + { + cb_WriteU8(pcbe->pAdapterContext, index, (CBIOS_U8)data); + } + } +} + +CBIOS_VOID cbSaveRegTableU8(PCBIOS_EXTENSION_COMMON pcbe, CBREGISTER *pRegTable, const CBIOS_U32 TableSize, CBIOS_U8* SavedRegTable) +{ + CBIOS_U32 i = 0; + + for(i = 0; i < TableSize; i++) + { + SavedRegTable[i] = (cbBiosMMIOReadReg(pcbe, (((CBIOS_U16)pRegTable[i].type << 8) | pRegTable[i].index), + CBIOS_NOIGAENCODERINDEX))&((CBIOS_U8)~pRegTable[i].mask); + + cbMMIOWriteReg(pcbe, (((CBIOS_U16)pRegTable[i].type << 8) | pRegTable[i].index), + pRegTable[i].value, pRegTable[i].mask); + } +} + +CBIOS_VOID cbRestoreRegTableU8(PCBIOS_EXTENSION_COMMON pcbe, const CBREGISTER *pRegTable, const CBIOS_U32 TableSize, CBIOS_U8* SavedRegTable) +{ + CBIOS_U32 i = 0; + + for(i = 0; i < TableSize; i++) + { + cbMMIOWriteReg(pcbe, (((CBIOS_U16)pRegTable[i].type<<8) | pRegTable[i].index), SavedRegTable[i], pRegTable[i].mask); + } +} + +CBIOS_VOID cbSaveRegTableU32(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_REGISTER32 *pRegTable, const CBIOS_U32 TableSize) +{ + CBIOS_U32 i = 0; + + for(i = 0; i < TableSize; i++) + { + pRegTable[i].value = cbReadRegisterU32(pcbe, pRegTable[i].type, pRegTable[i].index) & (~pRegTable[i].mask); + } +} + +CBIOS_VOID cbRestoreRegTableU32(PCBIOS_EXTENSION_COMMON pcbe, const CBIOS_REGISTER32 *pRegTable, const CBIOS_U32 TableSize) +{ + CBIOS_U32 i = 0; + + for(i = 0; i < TableSize; i++) + { + cbWriteRegisterU32(pcbe, pRegTable[i].type, pRegTable[i].index, pRegTable[i].mask); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// CalClock - Find Integral/Fractional part of PLL divider value +// and PLL R value +// Entry: EDI = Clock / 10000 +// Exit: Databuf.Integer = Intergal part +// Databuf.Fraction = Fractional part +// Databuf.R = R value +/////////////////////////////////////////////////////////////////////////////// +static CBIOS_BOOL cbCalCLK(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 ClockFreq, CBIOS_U32 ClockType, PCBIOS_CLOCK_INFO pClock, CBIOS_BOOL bGivenR)//ClockFreq(in MHz)*10000 +{ + CBIOS_S8 i; + CBIOS_U32 iClkFreq; + CBIOS_U64 uTemp; + CBIOS_U32 ulVcoValue = 0; + CBIOS_U32 ulRefFreq; + CBIOS_S8 R_range = 7; // 3-bits + + R_range = 6; // max div 64 + + ulVcoValue = 12000000; + + if(bGivenR && pClock->R > 0 && pClock->R <= R_range) + { + iClkFreq = ClockFreq << pClock->R; + } + else + { + for(i = R_range ; i >= 0 ; i--) + { + + iClkFreq = ClockFreq << i; + if ((iClkFreq < ulVcoValue) || (iClkFreq > 2*ulVcoValue)) + { + continue; + } + else + { + break; + } + } + if( i < 0 ) + { + //out of range + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbCalCLK: fata error -- out of range!!!\n")); + return CBIOS_FALSE; + } + + pClock->R = (i > 3) ? 3 : i; + pClock->PLLDiv = (i > 3) ? (i - 3) : 0; + } + + if(pcbe->ChipCaps.Is24MReferenceClock) + ulRefFreq = RefFreq24; + else + ulRefFreq = RefFreq27; + + // Xinwei's suggestion to set CP = 0; + pClock->CP = 0;// (iClkFreq <= Vco_Ref) ? 1 : 2; + + // Prevent being divided by zero + if (ulRefFreq == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbCalCLK: fata error -- ulRefFreq is ZERO!!!\n")); + return CBIOS_FALSE; + } + uTemp = iClkFreq / ulRefFreq; + pClock->Integer = (CBIOS_U8)uTemp - 2; + + uTemp = iClkFreq % ulRefFreq; + uTemp = uTemp<<20; + + uTemp = cb_do_div(uTemp, ulRefFreq); + pClock->Fraction = (CBIOS_U32) uTemp; + + return CBIOS_TRUE; +} + +static CBIOS_VOID cbCalFreq(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 *ClockFreq, PCBIOS_CLOCK_INFO pClock) +{ + CBIOS_U16 Integer = 0; + CBIOS_U64 Fraction = 0; + CBIOS_U16 R = 0; + CBIOS_U32 ulRefFreq = 0; + + if (pClock == CBIOS_NULL) + { + //input para error + return; + } + Integer = pClock->Integer; + Fraction = pClock->Fraction; + R = pClock->R; + + ulRefFreq = (pcbe->ChipCaps.Is24MReferenceClock) ? RefFreq24 : RefFreq27; + + *ClockFreq = (((Integer+2)*ulRefFreq) + (CBIOS_U32)((Fraction*ulRefFreq)>>20))>>(R + pClock->PLLDiv); +} + + +CBIOS_BOOL cbProgClock(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 ClockFreq, CBIOS_U32 ClockType, CBIOS_U8 IGAIndex) +{ + CBIOS_CLOCK_INFO ClkInfo; + CBIOS_U32 ClockTypeRep = ClockType; + + REG_SR15 RegSR15Value, RegSR15Mask; + REG_CRDA RegCRDAValue, RegCRDAMask; + REG_CRDB RegCRDBValue, RegCRDBMask; + REG_CRDD RegCRDDValue, RegCRDDMask; + REG_CRDE RegCRDEValue, RegCRDEMask; + REG_CRE0 RegCRE0Value, RegCRE0Mask; + REG_CRE2 RegCRE2Value, RegCRE2Mask; + REG_CRFD_B RegCRFD_B_Value, RegCRFD_B_Mask; + + cb_memset(&ClkInfo, 0, sizeof(CBIOS_CLOCK_INFO)); + + cbTraceEnter(GENERIC); + + if(pcbe->bRunOnQT) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO),"Exit: cbProgClock for QT PCIID !\n")); + return CBIOS_TRUE; + } + + if(pcbe->ChipID == CHIPID_ARISE10C0T && (ClockType == CBIOS_ECLKTYPE || ClockType == CBIOS_VCLKTYPE)) + { + //Don't support set ECLK or VCLK by driver for Arise 10C0t card + return CBIOS_TRUE; + } + + if((ClockType == CBIOS_ECLKTYPE) || (ClockType == CBIOS_VCLKTYPE)) + { + ClockFreq *= 2; //EPLL/VPLL always output ECLK2x/VCLK2x + } + + if(ClockType >= CBIOS_INVALID_CLK) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbProgClock: Invalid ClockType !!\n")); + return CBIOS_FALSE; + } + + if (!cbCalCLK(pcbe, ClockFreq, ClockType, &ClkInfo, CBIOS_FALSE)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbCalCLK failure, clocktype is %d !\n", ClockType)); + return CBIOS_FALSE; + } + + switch (ClockTypeRep) + { + case CBIOS_DCLK1TYPE: + cbMapMaskWrite(pcbe,ClkInfo.Integer, E3K_DCLK1_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.Fraction, E3K_DCLK1_Fraction_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.R, E3K_DCLK1_R_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.PLLDiv, E3K_DCLK1_DIV_MAP, CBIOS_NOIGAENCODERINDEX); + + //Load DClk1 + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK1_M_R_Load = 1; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK1_M_R_Load = 0; + cbMMIOWriteReg(pcbe,SR_15,RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK1_M_R_Load = 0; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK1_M_R_Load = 0; + cbMMIOWriteReg(pcbe,SR_15,RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK1_PLL_LOAD = 0; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK1_PLL_LOAD = 0; + cbMMIOWriteReg(pcbe,SR_15, RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK1_PLL_LOAD = 1; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK1_PLL_LOAD = 0; + cbMMIOWriteReg(pcbe,SR_15, RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + + break; + case CBIOS_DCLK2TYPE: + cbMapMaskWrite(pcbe,ClkInfo.Integer, E3K_DCLK2_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.Fraction, E3K_DCLK2_Fraction_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.R, E3K_DCLK2_R_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.PLLDiv, E3K_DCLK2_DIV_MAP, CBIOS_NOIGAENCODERINDEX); + + //Load DClk2 + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK2_M_R_Load = 1; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK2_M_R_Load = 0; + cbMMIOWriteReg(pcbe,SR_15, RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK2_M_R_Load = 0; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK2_M_R_Load = 0; + cbMMIOWriteReg(pcbe,SR_15, RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK2_PLL_LOAD = 0; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK2_PLL_LOAD = 0; + cbMMIOWriteReg(pcbe,SR_15, RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK2_PLL_LOAD = 1; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK2_PLL_LOAD = 0; + cbMMIOWriteReg(pcbe,SR_15, RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + break; + case CBIOS_DCLK3TYPE: + cbMapMaskWrite(pcbe,ClkInfo.Integer, E3K_DCLK3_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.Fraction, E3K_DCLK3_Fraction_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.R, E3K_DCLK3_R_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.PLLDiv, E3K_DCLK3_DIV_MAP, CBIOS_NOIGAENCODERINDEX); + + //Load DClk3 + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK3_M_R_Load = 1; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK3_M_R_Load = 0; + cbMMIOWriteReg(pcbe,SR_15, RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK3_M_R_Load = 0; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK3_M_R_Load = 0; + cbMMIOWriteReg(pcbe,SR_15, RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK3_PLL_LOAD = 0; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK3_PLL_LOAD = 0; + cbMMIOWriteReg(pcbe,SR_15, RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + + RegSR15Value.Value = 0; + RegSR15Value.DCLK3_PLL_LOAD = 1; + RegSR15Mask.Value = 0xFF; + RegSR15Mask.DCLK3_PLL_LOAD = 0; + cbMMIOWriteReg(pcbe,SR_15, RegSR15Value.Value, RegSR15Mask.Value); + + cb_DelayMicroSeconds(50); + + break; + case CBIOS_DCLK4TYPE: + cbMapMaskWrite(pcbe,ClkInfo.Integer, E3K_DCLK4_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.Fraction, E3K_DCLK4_Fraction_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.R, E3K_DCLK4_R_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.PLLDiv, E3K_DCLK4_DIV_MAP, CBIOS_NOIGAENCODERINDEX); + + //Load DClk4 + cb_DelayMicroSeconds(50); + + RegCRFD_B_Value.Value = 0; + RegCRFD_B_Value.LOAD_DCLK4 = 1; + RegCRFD_B_Mask.Value = 0xFF; + RegCRFD_B_Mask.LOAD_DCLK4 = 0; + cbMMIOWriteReg(pcbe, CR_B_FD, RegCRFD_B_Value.Value, RegCRFD_B_Mask.Value); + + cb_DelayMicroSeconds(50); + + RegCRFD_B_Value.Value = 0; + RegCRFD_B_Value.LOAD_DCLK4 = 0; + RegCRFD_B_Mask.Value = 0xFF; + RegCRFD_B_Mask.LOAD_DCLK4 = 0; + cbMMIOWriteReg(pcbe, CR_B_FD, RegCRFD_B_Value.Value, RegCRFD_B_Mask.Value); + + cb_DelayMicroSeconds(50); + + RegCRFD_B_Value.Value = 0; + RegCRFD_B_Value.SOFT_LOAD_D4CLK = 0; + RegCRFD_B_Mask.Value = 0xFF; + RegCRFD_B_Mask.SOFT_LOAD_D4CLK = 0; + cbMMIOWriteReg(pcbe, CR_B_FD, RegCRFD_B_Value.Value, RegCRFD_B_Mask.Value); + + cb_DelayMicroSeconds(50); + + RegCRFD_B_Value.Value = 0; + RegCRFD_B_Value.SOFT_LOAD_D4CLK = 1; + RegCRFD_B_Mask.Value = 0xFF; + RegCRFD_B_Mask.SOFT_LOAD_D4CLK = 0; + cbMMIOWriteReg(pcbe, CR_B_FD, RegCRFD_B_Value.Value, RegCRFD_B_Mask.Value); + + cb_DelayMicroSeconds(50); + break; + case ECLKTYPE_Post: + case CBIOS_ECLKTYPE: + // EPLL setting sequence: + // RST down -> set PLL regs -> load setting -> wait 1us -> RST up + // ECLK only use Integer part, hardcode CKOUT1 by HW + RegCRE2Value.Value = 0; + RegCRE2Value.EPLL_SW_CTRL = 1; + RegCRE2Value.EPLL_SW_LOAD = 0; + RegCRE2Value.EPLL_RST_DOWN = 1; + RegCRE2Mask.Value = 0xFF; + RegCRE2Mask.EPLL_SW_CTRL = 0; + RegCRE2Mask.EPLL_SW_LOAD = 0; + RegCRE2Mask.EPLL_RST_DOWN = 0; + cbMMIOWriteReg(pcbe, CR_E2, RegCRE2Value.Value, RegCRE2Mask.Value); + + RegCRDDValue.Value = 0; + RegCRDDValue.EPLL_Band_Sel = 1; + RegCRDDValue.EPLL_PU_Down = 0; + RegCRDDMask.Value = 0xFF; + RegCRDDMask.EPLL_Band_Sel = 0; + RegCRDDMask.EPLL_PU_Down = 0; + cbMMIOWriteReg(pcbe, CR_DD, RegCRDDValue.Value, RegCRDDMask.Value); + + RegCRDEValue.Value = 0; + RegCRDEValue.EPLL_Fraction_EN = 0; + RegCRDEMask.Value = 0xFF; + RegCRDEMask.EPLL_Fraction_EN = 0; + cbMMIOWriteReg(pcbe, CR_DE, RegCRDEValue.Value, RegCRDEMask.Value); + + cbMapMaskWrite(pcbe,ClkInfo.Integer, E3K_ECLK_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.R, E3K_ECLK_R_MAP, CBIOS_NOIGAENCODERINDEX); + + // load ECLK + RegCRE2Value.Value = 0; + RegCRE2Value.EPLL_SW_LOAD = 1; + RegCRE2Mask.Value = 0xFF; + RegCRE2Mask.EPLL_SW_LOAD = 0; + cbMMIOWriteReg(pcbe, CR_E2, RegCRE2Value.Value, RegCRE2Mask.Value); + + cb_DelayMicroSeconds(1); + + RegCRE2Value.Value = 0; + RegCRE2Value.EPLL_SW_CTRL = 1; + RegCRE2Value.EPLL_SW_LOAD = 0; + RegCRE2Value.EPLL_RST_DOWN = 0; + RegCRE2Mask.Value = 0xFF; + RegCRE2Mask.EPLL_SW_CTRL = 0; + RegCRE2Mask.EPLL_SW_LOAD = 0; + RegCRE2Mask.EPLL_RST_DOWN = 0; + cbMMIOWriteReg(pcbe, CR_E2, RegCRE2Value.Value, RegCRE2Mask.Value); + + break; + case CBIOS_VCLKTYPE: + //VPLL setting sequence: + // RST down -> set PLL regs -> load setting -> wait 1us -> RST up + //VCLK only use Integer part, hardcode CKOUT1 by HW + RegCRE0Value.Value = 0; + RegCRE0Value.VPLL_SW_CTRL = 1; + RegCRE0Value.VPLL_SW_LOAD = 0; + RegCRE0Value.VPLL_RST_DOWN = 1; + RegCRE0Mask.Value = 0xFF; + RegCRE0Mask.VPLL_SW_CTRL = 0; + RegCRE0Mask.VPLL_SW_LOAD = 0; + RegCRE0Mask.VPLL_RST_DOWN = 0; + cbMMIOWriteReg(pcbe, CR_E0, RegCRE0Value.Value, RegCRE0Mask.Value); + + RegCRDAValue.Value = 0; + RegCRDAValue.VPLL_Band_Sel = 1; + RegCRDAValue.VPLL_PU_Down = 0; + RegCRDAMask.Value = 0xFF; + RegCRDAMask.VPLL_Band_Sel = 0; + RegCRDAMask.VPLL_PU_Down = 0; + cbMMIOWriteReg(pcbe, CR_DA, RegCRDAValue.Value, RegCRDAMask.Value); + + RegCRDBValue.Value = 0; + RegCRDBValue.VPLL_Fraction_EN = 0; + RegCRDBMask.Value = 0xFF; + RegCRDBMask.VPLL_Fraction_EN = 0; + cbMMIOWriteReg(pcbe, CR_DB, RegCRDBValue.Value, RegCRDBMask.Value); + + cbMapMaskWrite(pcbe,ClkInfo.Integer, E3K_VCLK_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + cbMapMaskWrite(pcbe,ClkInfo.R, E3K_VCLK_R_MAP, CBIOS_NOIGAENCODERINDEX); + + // load VCLK + RegCRE0Value.Value = 0; + RegCRE0Value.VPLL_SW_LOAD = 1; + RegCRE0Mask.Value = 0xFF; + RegCRE0Mask.VPLL_SW_LOAD = 0; + cbMMIOWriteReg(pcbe, CR_E0, RegCRE0Value.Value, RegCRE0Mask.Value); + + cb_DelayMicroSeconds(1); + + RegCRE0Value.Value = 0; + RegCRE0Value.VPLL_SW_CTRL = 1; + RegCRE0Value.VPLL_SW_LOAD = 0; + RegCRE0Value.VPLL_RST_DOWN = 0; + RegCRE0Mask.Value = 0xFF; + RegCRE0Mask.VPLL_SW_CTRL = 0; + RegCRE0Mask.VPLL_SW_LOAD = 0; + RegCRE0Mask.VPLL_RST_DOWN = 0; + cbMMIOWriteReg(pcbe, CR_E0, RegCRE0Value.Value, RegCRE0Mask.Value); + + break; + + default: + break; + } + cbTraceExit(GENERIC); + return CBIOS_TRUE;//??? not found in BIOS code +} + + +/////////////////////////////////////////////////////////////////////////////// +// GetProgClock - This function returns the clock value. +// +// Entry: CL = (00h) Select MCLK +// (01h) Select DCLK1 +// (02h) Select DCLK2 +// (03h) Select TVCLK +// (04h) Select ECLK +// (05h) Select ICLK +// Exit: EDI = (??h) Current clock frequency +/////////////////////////////////////////////////////////////////////////////// +CBIOS_U32 cbGetProgClock(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 *ClockFreq, CBIOS_U32 ClockType) +{ + CBIOS_CLOCK_INFO ClkInfo = {0}; + CBIOS_U32 RegD130 = 0; + + if(ClockType >= CBIOS_INVALID_CLK) + { + return -1; + } + + switch (ClockType) + { + case CBIOS_DCLK1TYPE: + ClkInfo.Integer = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK1_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.Fraction = (CBIOS_U32)cbMapMaskRead(pcbe, E3K_DCLK1_Fraction_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.R = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK1_R_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.PLLDiv = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK1_DIV_MAP, CBIOS_NOIGAENCODERINDEX); + break; + case CBIOS_DCLK2TYPE: + ClkInfo.Integer = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK2_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.Fraction = (CBIOS_U32)cbMapMaskRead(pcbe, E3K_DCLK2_Fraction_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.R = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK2_R_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.PLLDiv = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK2_DIV_MAP, CBIOS_NOIGAENCODERINDEX); + break; + case CBIOS_DCLK3TYPE: + ClkInfo.Integer = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK3_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.Fraction = (CBIOS_U32)cbMapMaskRead(pcbe, E3K_DCLK3_Fraction_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.R = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK3_R_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.PLLDiv = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK3_DIV_MAP, CBIOS_NOIGAENCODERINDEX); + break; + case CBIOS_DCLK4TYPE: + ClkInfo.Integer = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK4_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.Fraction = (CBIOS_U32)cbMapMaskRead(pcbe, E3K_DCLK4_Fraction_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.R = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK4_R_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.PLLDiv = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_DCLK4_DIV_MAP, CBIOS_NOIGAENCODERINDEX); + break; + case CBIOS_ECLKTYPE: + if (pcbe->ChipID == CHIPID_ARISE10C0T) + { + *ClockFreq = cb_ReadU32(pcbe->pAdapterContext, 0xD3E4); + } + else + { + ClkInfo.Integer = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_ECLK_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.R = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_ECLK_R_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.Fraction = 0; + ClkInfo.PLLDiv = 0; + } + break; + case CBIOS_VCLKTYPE: + if (pcbe->ChipID == CHIPID_ARISE10C0T) + { + *ClockFreq = cb_ReadU32(pcbe->pAdapterContext, 0xD3E8); + } + else + { + ClkInfo.Integer = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_VCLK_Integer_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.R = (CBIOS_U8)cbMapMaskRead(pcbe, E3K_VCLK_R_MAP, CBIOS_NOIGAENCODERINDEX); + ClkInfo.Fraction = 0; + ClkInfo.PLLDiv = 0; + } + break; + case CBIOS_MCLKTYPE: + RegD130 = cb_ReadU32(pcbe->pAdapterContext, 0xd130); + ClkInfo.Integer = ((RegD130 >> 0x7) & 0x7F) | ((RegD130 & 0x10)? 0x80:0); + ClkInfo.R = (RegD130 >> 0x11) & 0x3; + ClkInfo.Fraction = 0; + ClkInfo.PLLDiv = 0; + break; + default: + break; + } + + if (pcbe->ChipID == CHIPID_ARISE10C0T && (ClockType == CBIOS_ECLKTYPE || ClockType == CBIOS_VCLKTYPE)) + { + (*ClockFreq) *= 10000; + } + else + { + cbCalFreq(pcbe,ClockFreq,&ClkInfo); + + if((ClockType == CBIOS_ECLKTYPE) || (ClockType == CBIOS_VCLKTYPE)) + { + (*ClockFreq) /= 2; //EPLL/VPLL always output ECLK2x/VCLK2x + } + } + + return CBIOS_TRUE; +} + +CBIOS_BOOL cbWaitNonFullVBlank(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 IGAIndex) +{ + CBIOS_GET_HW_COUNTER GetCnt = {0}; + CBIOS_U32 i = 0, oldcnt, newcnt; + CBIOS_UCHAR byte; + + if (pcbe->bRunOnQT) + { + return CBIOS_TRUE; + } + + byte= cbBiosMMIOReadReg(pcbe, CR_34, IGAIndex); + if (byte & VBLANK_ACTIVE_CR34) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Skip wait, IGA %d already in VBlank.\n", IGAIndex)); + return CBIOS_TRUE; + } + + GetCnt.IgaIndex = IGAIndex; + GetCnt.bGetPixelCnt = 1; + + cbHwGetCounter(pcbe, &GetCnt); + oldcnt = GetCnt.Value[CBIOS_COUNTER_PIXEL]; + cb_DelayMicroSeconds(1); + cbHwGetCounter(pcbe, &GetCnt); + newcnt = GetCnt.Value[CBIOS_COUNTER_PIXEL]; + + if(oldcnt == newcnt) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Skip wait IGA %d VBlank as no timing.\n", IGAIndex)); + return CBIOS_TRUE; + } + + for(i = 0; i < 800; i++) + { + byte= cbBiosMMIOReadReg(pcbe, CR_34, IGAIndex); + if (byte & VBLANK_ACTIVE_CR34) + { + break; + } + + cb_DelayMicroSeconds(50); + } + + if(i == 800) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "Wait IGA %d NonFullVBlank time out!\n", IGAIndex)); + } + + return (i == 800)? CBIOS_FALSE : CBIOS_TRUE; +} + + +/* +Routine Description: + Wait for the vertical blanking interval on the chip based on IGAs + It is a paired register, so it is the caller responsiblity to + set the correct IGA first before call here. + +Return Value: + Always CBIOS_TRUE +*/ +CBIOS_BOOL cbWaitVBlank(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 IGAIndex) +{ + CBIOS_GET_HW_COUNTER GetCnt = {0}; + CBIOS_U32 i = 0, timeout = 0, oldcnt, newcnt; + CBIOS_UCHAR byte; + + if (pcbe->bRunOnQT) + { + return CBIOS_TRUE; + } + + GetCnt.IgaIndex = IGAIndex; + GetCnt.bGetPixelCnt = 1; + + cbHwGetCounter(pcbe, &GetCnt); + oldcnt = GetCnt.Value[CBIOS_COUNTER_PIXEL]; + cb_DelayMicroSeconds(1); + cbHwGetCounter(pcbe, &GetCnt); + newcnt = GetCnt.Value[CBIOS_COUNTER_PIXEL]; + + if(oldcnt == newcnt) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Skip wait IGA %d VBlank as no timing.\n", IGAIndex)); + return CBIOS_TRUE; + } + + //wait for not-VBlank area + //vblank is about (0.4ms ~ 2ms), display active is about (7ms ~ 18ms) + //wait display active, one step is 1ms, max 15ms + for(i = 0; i < 16; i++) + { + byte= cbBiosMMIOReadReg(pcbe, CR_34, IGAIndex); + if (!(byte & VBLANK_ACTIVE_CR34)) + { + break; + } + cb_DelayMicroSeconds(1000); + } + + if(i == 16) + { + timeout = 1; + goto End; + } + + //wait vblank, one step is 0.05ms, max 40ms + for(i = 0; i < 800; i++) + { + byte= cbBiosMMIOReadReg(pcbe, CR_34, IGAIndex); + if (byte & VBLANK_ACTIVE_CR34) + { + break; + } + + cb_DelayMicroSeconds(50); + } + + if(i == 800) + { + timeout = 1; + goto End; + } + +End: + if (timeout) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "Wait IGA %d VBlank time out!\n", IGAIndex)); + } + + return CBIOS_TRUE; +} //cbWait_VBlank + +/* +Routine Description: + Wait for the vertical Sync on the chip based on IGAs + It is a paired register, so it is the caller responsiblity to + set the correct IGA first before call here. + +Return Value: + Always CBIOS_TRUE +*/ +CBIOS_BOOL cbWaitVSync(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 IGAIndex) +{ + + CBIOS_U32 i = 0; // Record the loop times. + CBIOS_UCHAR byte; + + if (pcbe->bRunOnQT) + { + return CBIOS_TRUE; + } + + //wait for not-VSYNC area + for (i = 0; i < CBIOS_VBLANK_RETRIES; i++) + { + byte= cbBiosMMIOReadReg(pcbe, CR_33, IGAIndex); + if (!(byte & VSYNC_ACTIVE_CR33)) + { + break; + } + } + + // Now wait VSYNC again. + for (i = 0; i < CBIOS_VBLANK_RETRIES; i++) + { + byte= cbBiosMMIOReadReg(pcbe, CR_33, IGAIndex); + if (byte & VSYNC_ACTIVE_CR33) + { + break; + } + } + + if (i == CBIOS_VBLANK_RETRIES) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "wait VSYNC time out!\n")); + } + + return (CBIOS_TRUE); + +} //cbWait_VSync + +CBIOS_BOOL cbHDCPDDCciPortWrite(PCBIOS_EXTENSION_COMMON pcbe,CBIOS_UCHAR Port, CBIOS_UCHAR Offset, const PCBIOS_UCHAR pWriteDataBuf, CBIOS_U32 DataLen, CBIOS_S32 HDCPChannel) +{ + CBIOS_U32 i, j; + CBIOS_U32 maxloop = MAXI2CWAITLOOP; + CBIOS_U8 I2CDELAY = pcbe->I2CDelay; + CBIOS_U32 HdcpCtrl1Reg, HdcpCtrl2Reg; + + cbTraceEnter(GENERIC); + switch(HDCPChannel) + { + case HDCP1: + { + HdcpCtrl1Reg = HDCPCTL1_DEST; + HdcpCtrl2Reg = HDCPCTL2_DEST; + } + break; + case HDCP2: + { + HdcpCtrl1Reg = HDCP2_CTL1_DEST; + HdcpCtrl2Reg = HDCP2_CTL2_DEST; + } + break; + case HDCP3: + { + HdcpCtrl1Reg = HDCP3_CTL1_DEST; + HdcpCtrl2Reg = HDCP3_CTL2_DEST; + } + break; + case HDCP4: + { + HdcpCtrl1Reg = HDCP4_CTL1_DEST; + HdcpCtrl2Reg = HDCP4_CTL2_DEST; + } + break; + default: + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP channel: %d\n", FUNCTION_NAME, HDCPChannel)); + return CBIOS_FALSE; + } + break; + } + + //start + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_START_DEST);//set START & WDATA_AV + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST); + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & (HDCP_I2C_START_DEST | HDCP_I2C_WDAV_DEST)) //query START & WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl1Reg, + (cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl1Reg)&0xff00ffff)|((CBIOS_U32)(Port&~1))<<16);//write the I2C data,first byte should be I2C address + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg, + cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) |HDCP_I2C_WDAV_DEST);//set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl1Reg, + (cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl1Reg)&0xff00ffff)|((CBIOS_U32)(Offset))<<16);//write the I2C data,first byte should be I2C address + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg, + cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) |HDCP_I2C_WDAV_DEST);//set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + + for(i = 0;ipAdapterContext,HdcpCtrl1Reg, + (cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl1Reg)&0xff00ffff)|((CBIOS_U32)*(pWriteDataBuf+i))<<16);//write the I2C data,first byte should be I2C address + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg, + cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST);//set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + } + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_STOP_DEST);//set stop & WDATA_AV;HW bug + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST); + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & (HDCP_I2C_STOP_DEST )) //query stop until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + + cbTraceExit(GENERIC); + + return CBIOS_TRUE; +} + +CBIOS_BOOL cbHDCPDDCciPortRead(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_UCHAR Port, CBIOS_UCHAR Offset, const PCBIOS_UCHAR pReadDataBuf, CBIOS_U32 DataLen, CBIOS_S32 HDCPChannel) +{ + CBIOS_U32 i, j; + CBIOS_U32 maxloop = MAXI2CWAITLOOP; + CBIOS_U8 I2CDELAY = pcbe->I2CDelay; + CBIOS_U32 HdcpCtrl1Reg, HdcpCtrl2Reg; + + cbTraceEnter(GENERIC); + switch(HDCPChannel) + { + case HDCP1: + { + HdcpCtrl1Reg = HDCPCTL1_DEST; + HdcpCtrl2Reg = HDCPCTL2_DEST; + } + break; + case HDCP2: + { + HdcpCtrl1Reg = HDCP2_CTL1_DEST; + HdcpCtrl2Reg = HDCP2_CTL2_DEST; + } + break; + case HDCP3: + { + HdcpCtrl1Reg = HDCP3_CTL1_DEST; + HdcpCtrl2Reg = HDCP3_CTL2_DEST; + } + break; + case HDCP4: + { + HdcpCtrl1Reg = HDCP4_CTL1_DEST; + HdcpCtrl2Reg = HDCP4_CTL2_DEST; + } + break; + default: + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP channel: %d\n", FUNCTION_NAME, HDCPChannel)); + return CBIOS_FALSE; + } + break; + } + + //start + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_START_DEST);//set START & WDATA_AV + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST); + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & (HDCP_I2C_START_DEST | HDCP_I2C_WDAV_DEST )) //query START until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl1Reg,(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl1Reg) & 0xff00ffff) | (Port & ~1) << 16);//write the I2C address + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST);//set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl1Reg,(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl1Reg) & 0xff00ffff) | (Offset << 16));//write the I2C address + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST);//set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + + //start + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_START_DEST);//set START & WDATA_AV + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST); + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & (HDCP_I2C_START_DEST | HDCP_I2C_WDAV_DEST )) //query START until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl1Reg,(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl1Reg) & 0xff00ffff) | (Port |1) << 16);//write the I2C address + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST);//set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & ~HDCP_I2C_RDAV_DEST);//clear RDATA_AV firstly + + for(i = 0;i < DataLen;i++) + { + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST);//set WDATA_AV + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST) //query WDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + + j = 0; + while((cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & HDCP_I2C_RDAV_DEST) == 0) //query RDATA_AV until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + + *(pReadDataBuf+i) = (CBIOS_UCHAR)((cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl1Reg) & 0x0000ff00) >> 8);//read the I2C data + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & ~HDCP_I2C_RDAV_DEST);//clear RDATA_AV + } + + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_STOP_DEST);//set stop & WDATA_AV;HW bug + cb_WriteU32(pcbe->pAdapterContext,HdcpCtrl2Reg,cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST); + + j = 0; + while(cb_ReadU32(pcbe->pAdapterContext,HdcpCtrl2Reg) & (HDCP_I2C_STOP_DEST | HDCP_I2C_WDAV_DEST)) //query STOP until they are zero + { + if(j < maxloop) + { + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s(%d):wait time out!\n", FUNCTION_NAME, LINE_NUM)); + return CBIOS_FALSE; + } + } + + cbTraceExit(GENERIC); + return CBIOS_TRUE; +} + +#if CBIOS_CHECK_HARDWARE_STATUS +CBIOS_BOOL cbIsMMIOWell(PCBIOS_EXTENSION_COMMON pcbe) +{ + CBIOS_BOOL bResult = CBIOS_TRUE; + CBIOS_UCHAR CR6B = cb_ReadU8(pcbe->pAdapterContext, 0x886B); + + cb_WriteU8(pcbe->pAdapterContext, 0x886B, 0xAA); + bResult = (0xAA == cb_ReadU8(pcbe->pAdapterContext, 0x886B)); + cb_WriteU8(pcbe->pAdapterContext, 0x886B, CR6B); + + return bResult; +} +#endif + + +CBIOS_BOOL cbDumpRegisters(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_DUMP_TYPE DumpType) +{ + CBIOS_U32 GroupIndex = 0; + CBIOS_REGISTER_GROUP *pRegGroup = CBIOS_NULL; + CBIOS_U32 i = 0,j = 0; + CBIOS_U8 Values[256]; + CBIOS_U32 DValues[128]; + CBIOS_U16 IndexLen=0; + CBIOS_REGISTER_GROUP *pRegTable = CBIOS_NULL; + CBIOS_U32 TableLen = 0; + + pRegTable = CBIOS_REGISTER_TABLE; + TableLen = sizeofarray(CBIOS_REGISTER_TABLE); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "======Dump registers======\n")); + + for (GroupIndex = 0; GroupIndex < TableLen; GroupIndex++) + { + if (DumpType & (1 << GroupIndex)) + { + pRegGroup = &pRegTable[GroupIndex]; + if(pRegGroup == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "=====pRegGroup NULL\n")); + return CBIOS_FALSE; + } + + if(CBIOS_NULL == (pRegGroup->pRegRange)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "=====DumpType %d is not implemented, skip it!\n", DumpType)); + continue; + } + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "=============[Begin %s group]=============\n", pRegGroup->GroupName)); + + for (i = 0; i < pRegGroup->RangeNum; i++) + { + if(pRegGroup->pRegRange[i].RegLen == 1) + { + IndexLen = pRegGroup->pRegRange[i].EndIndex - pRegGroup->pRegRange[i].StartIndex + 1; + for(j = 0;j < IndexLen;j++) + { + Values[j] = cb_ReadU8(pcbe->pAdapterContext,pRegGroup->pRegRange[i].StartIndex + j); + } + + if(1 == IndexLen) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "[0x%04x]: %02x\n",pRegGroup->pRegRange[i].StartIndex,Values[0])); + } + else{ + cbPrintU8String(Values,IndexLen,pRegGroup->pRegRange[i].StartIndex); + } + } + + if(pRegGroup->pRegRange[i].RegLen == 4) + { + IndexLen = (pRegGroup->pRegRange[i].EndIndex - pRegGroup->pRegRange[i].StartIndex)/4 + 1; + for(j = 0;j < IndexLen;j++) + { + DValues[j] = cb_ReadU32(pcbe->pAdapterContext, pRegGroup->pRegRange[i].StartIndex + 4*j); + } + + if(1 == IndexLen) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "[0x%04x]: %08x\n",pRegGroup->pRegRange[i].StartIndex,DValues[0])); + } + else + { + cbPrintU32String(DValues,IndexLen,pRegGroup->pRegRange[i].StartIndex); + } + } + } + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "=============[End %s group]=============\n\n", pRegGroup->GroupName)); + } + } + + return CBIOS_TRUE; +} + + +CBIOS_VOID cbDumpModeInfo(PCBIOS_EXTENSION_COMMON pcbe) +{ + CBIOS_U32 IGAIndex = 0; + PCBIOS_DISP_MODE_PARAMS pModeParams = CBIOS_NULL; + PCBIOS_MODE_SRC_PARA pSrcPara = CBIOS_NULL; + PCBIOS_MODE_TARGET_PARA pTargetPara = CBIOS_NULL; + PCBIOS_TIMING_ATTRIB pTiming = CBIOS_NULL; + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "===============[ Dump Mode INFO ]===============\n")); + + for (IGAIndex = 0; IGAIndex < pcbe->DispMgr.IgaCount; IGAIndex++) + { + pModeParams = pcbe->DispMgr.pModeParams[IGAIndex]; + + if(CBIOS_NULL == pModeParams) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "Mode parameter is NULL\n")); + return; + } + + if(CBIOS_TYPE_NONE == pcbe->DispMgr.ActiveDevices[IGAIndex]) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "no device connected on IGA %d\n", IGAIndex)); + continue; + } + + pSrcPara = &(pModeParams->SrcModePara); + pTargetPara = &(pModeParams->TargetModePara); + pTiming = &(pModeParams->TargetTiming); + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "------------ IGA%d Mode INFO ------------\n", IGAIndex)); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Source Mode: XRes = %d YRes = %d\n", pSrcPara->XRes, pSrcPara->YRes)); + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Target Mode: XRes = %d YRes = %d RefRate = %d bInterlace = %d AspectRatioFlag = %d OutputSignal = %d\n", + pTargetPara->XRes, pTargetPara->YRes, pTargetPara->RefRate, pTargetPara->bInterlace, pTargetPara->AspectRatioFlag, pTargetPara->OutputSignal)); + + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Target Timing: XRes = %d YRes = %d RefreshRate = %d PixelClock = %x AspectRatio = %x HVPolarity = %x\n", + pTiming->XRes, pTiming->YRes, pTiming->RefreshRate, pTiming->PixelClock, pTiming->AspectRatio, pTiming->HVPolarity)); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Target Timing: HorTotal = %d HorDisEnd = %d HorBStart = %d HorBEnd = %d HorSyncStart = %d HorSyncEnd = %d\n", + pTiming->HorTotal, pTiming->HorDisEnd, pTiming->HorBStart, pTiming->HorBEnd, pTiming->HorSyncStart, pTiming->HorSyncEnd)); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Target Timing: VerTotal = %d VerDisEnd = %d VerBStart = %d VerBEnd = %d VerSyncStart = %d VerSyncEnd = %d\n", + pTiming->VerTotal, pTiming->VerDisEnd, pTiming->VerBStart, pTiming->VerBEnd, pTiming->VerSyncStart, pTiming->VerSyncEnd)); + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "IsEnable3DVideo: %d IsxvYCC: %d IsSingleBuffer: %d\n", + pModeParams->IsEnable3DVideo, pModeParams->IsxvYCC, pModeParams->IsSingleBuffer)); + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Video3DStruct: %d VICCode: %d PixelRepitition: %d BitPerComponent: %d\n\n", + pModeParams->Video3DStruct, pModeParams->VICCode, pModeParams->PixelRepitition, pModeParams->BitPerComponent)); + } + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "===============[ End Mode INFO ]===============\n\n")); + +} + +CBIOS_VOID cbDumpClockInfo(PCBIOS_EXTENSION_COMMON pcbe) +{ + CBIOS_U32 ClockFreq = 0; + CBIOS_U32 RegPMU9038Value; + + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "===============[ Dump Clock INFO ]===============\n")); + cbGetProgClock(pcbe, &ClockFreq, CBIOS_DCLK1TYPE); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "DCLK1: %x\n", ClockFreq)); + cbGetProgClock(pcbe, &ClockFreq, CBIOS_DCLK2TYPE); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "DCLK2: %x\n", ClockFreq)); + cbGetProgClock(pcbe, &ClockFreq, CBIOS_ECLKTYPE); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "ECLK: %x\n", ClockFreq)); + cbGetProgClock(pcbe, &ClockFreq, CBIOS_CPUFRQTYPE); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "CPUFRQ: %x\n", ClockFreq)); + + RegPMU9038Value = cbReadRegisterU32(pcbe, CBIOS_REGISTER_PMU, 0x9038); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "DIUM_CLK_DIV: %x\n", (RegPMU9038Value & 0x1F))); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "===============[ End Clock INFO ]===============\n\n")); +} + + +CBIOS_BOOL cbDisableHdcp(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 ulHDCPNum) +{ + PCBIOS_VOID pAp = pcbe->pAdapterContext; + CBIOS_U32 HdcpReg = 0; + CBIOS_U32 HdcpStatus = 0; + CBIOS_U32 TmpStatus = 0; + CBIOS_U32 i, j, maxloop = MAXI2CWAITLOOP * 10; + CBIOS_BOOL bRet = CBIOS_TRUE; + + if(ulHDCPNum == HDCP1) + HdcpReg = HDCPCTL2_DEST; + else if(ulHDCPNum == HDCP2) + HdcpReg = HDCP2_CTL2_DEST; + + if(HdcpReg != 0) + { + HdcpStatus = cb_ReadU32(pAp, HdcpReg); + + //Software Requests I2C Access + cb_WriteU32(pAp, HdcpReg, HdcpStatus | HDCP_I2C_REQUEST_DEST); + + i = 0; + while(i < maxloop) + { + j = 0; + while(j < maxloop) + { + TmpStatus = cb_ReadU32(pAp, HdcpReg); + if(!(TmpStatus & HDCP_I2C_STATUS_DEST)) //wait i2c idle + break; + + cb_DelayMicroSeconds(4); + j++; + } + + if(j < maxloop) + break; + i++; + } + + //disable HDCP I2C function if take control, else restore bit[1]. + if(i < maxloop) + { + cb_WriteU32(pAp, HdcpReg, TmpStatus&(~HDCP_I2C_ENABLE_DEST)); + bRet = CBIOS_TRUE; + } + else + { + cb_WriteU32(pAp, HdcpReg, TmpStatus&(~HDCP_I2C_REQUEST_DEST)); + bRet = CBIOS_FALSE; + } + } + + return bRet; +} + +CBIOS_VOID cbEnableHdcpStatus(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 ulHDCPNum) +{ + PCBIOS_VOID pAp = pcbe->pAdapterContext; + CBIOS_U32 HdcpReg = 0; + CBIOS_U32 HdcpStatus = 0; + + if(ulHDCPNum == HDCP1) + HdcpReg = HDCPCTL2_DEST; + else if(ulHDCPNum == HDCP2) + HdcpReg = HDCP2_CTL2_DEST; + + if(HdcpReg != 0) + { + HdcpStatus = cb_ReadU32(pAp, HdcpReg); + if(HdcpStatus & HDCP_I2C_ENABLE_DEST) + return; + + HdcpStatus &= ~HDCP_I2C_REQUEST_DEST; + HdcpStatus |= HDCP_I2C_ENABLE_DEST; + cb_WriteU32(pAp, HdcpReg, HdcpStatus); + } + + return; +} + +static CBIOS_BOOL cbHDCPEdidRead(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U8 I2CAddress, + CBIOS_U8 I2CSubAddr, + PCBIOS_UCHAR pReadDataBuf, + CBIOS_U32 DataLen, + CBIOS_S32 HDCPChannel, + CBIOS_U8 nSegNum) +{ + CBIOS_BOOL bResult = CBIOS_TRUE; + CBIOS_U32 i, j; + CBIOS_U32 maxloop = MAXI2CWAITLOOP; + PCBIOS_VOID pAp = pcbe->pAdapterContext; + CBIOS_U8 I2CDELAY = pcbe->I2CDelay; + CBIOS_U32 HdcpCtrl1Reg, HdcpCtrl2Reg; + + cbTraceEnter(GENERIC); + if (HDCPChannel == HDCP1) + { + HdcpCtrl1Reg = HDCPCTL1_DEST; + HdcpCtrl2Reg = HDCPCTL2_DEST; + } + else if (HDCPChannel == HDCP2) + { + HdcpCtrl1Reg = HDCP2_CTL1_DEST; + HdcpCtrl2Reg = HDCP2_CTL2_DEST; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: invalid HDCP channel: %d\n", FUNCTION_NAME, HDCPChannel)); + return CBIOS_FALSE; + } + + if(nSegNum != 0) + { + // Write the extension segment index + cb_WriteU32(pAp,HdcpCtrl2Reg, + cb_ReadU32(pAp,HdcpCtrl2Reg) | (HDCP_I2C_START_DEST));//set START&WDATA_AV + cb_WriteU32(pAp,HdcpCtrl2Reg, + cb_ReadU32(pAp,HdcpCtrl2Reg) | (HDCP_I2C_WDAV_DEST)); + + j = 0; + while(j < maxloop)//query START & WDATA_AV until they are zero + { + if(!(cb_ReadU32(pAp,HdcpCtrl2Reg) & (HDCP_I2C_START_DEST | HDCP_I2C_WDAV_DEST))) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + + cb_WriteU32(pAp,HdcpCtrl1Reg, + (cb_ReadU32(pAp,HdcpCtrl1Reg)&0xff00ffff)|((CBIOS_U32)(0x60&~1))<<16);//write the I2C data,first byte should be I2C address + cb_WriteU32(pAp,HdcpCtrl2Reg, + cb_ReadU32(pAp,HdcpCtrl2Reg) |HDCP_I2C_WDAV_DEST);//set WDATA_AV + j = 0; + while(j < maxloop)//query WDATA_AV until they are zero + { + if(!(cb_ReadU32(pAp,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST)) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + + //write segment index + cb_WriteU32(pAp,HdcpCtrl1Reg, + (cb_ReadU32(pAp,HdcpCtrl1Reg)&0xff00ffff)|((CBIOS_U32)nSegNum)<<16);//write the I2C data,first byte should be I2C address + cb_WriteU32(pAp,HdcpCtrl2Reg, + cb_ReadU32(pAp,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST);//set WDATA_AV + j = 0; + while(j < maxloop)//query WDATA_AV until they are zero + { + if(!(cb_ReadU32(pAp,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST)) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + + cb_WriteU32(pAp,HdcpCtrl2Reg, + cb_ReadU32(pAp,HdcpCtrl2Reg) | (HDCP_I2C_STOP_DEST));//set stop & WDATA_AV;HW bug + cb_WriteU32(pAp,HdcpCtrl2Reg, + cb_ReadU32(pAp,HdcpCtrl2Reg) | (HDCP_I2C_WDAV_DEST)); + j = 0; + while(j < maxloop)//query stop until they are zero + { + if(!(cb_ReadU32(pAp,HdcpCtrl2Reg) & HDCP_I2C_STOP_DEST)) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + } + // write device addr + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | + (HDCP_I2C_START_DEST));//set START & WDATA_AV + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | + (HDCP_I2C_WDAV_DEST)); + j = 0; + while(j < maxloop)//query START & WDATA_AV until they are zero + { + if(!(cb_ReadU32(pAp,HdcpCtrl2Reg) & (HDCP_I2C_START_DEST | HDCP_I2C_WDAV_DEST))) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + + cb_WriteU32(pAp,HdcpCtrl1Reg, (cb_ReadU32(pAp,HdcpCtrl1Reg)&0xff00ffff)|((CBIOS_U32)I2CAddress)<<16);//write the I2C data,first byte should be I2C address + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | + HDCP_I2C_WDAV_DEST);//set WDATA_AV + j = 0; + while(j < maxloop)//query WDATA_AV until they are zero + { + if(!(cb_ReadU32(pAp,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST)) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + + //write sub addr + cb_WriteU32(pAp,HdcpCtrl1Reg, (cb_ReadU32(pAp,HdcpCtrl1Reg)&0xff00ffff)|((CBIOS_U32)I2CSubAddr)<<16);//write the I2C data,first byte should be I2C address + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | HDCP_I2C_WDAV_DEST);//set WDATA_AV + + j = 0; + while(j < maxloop)//query WDATA_AV until they are zero + { + if(!(cb_ReadU32(pAp,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST)) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | + (HDCP_I2C_STOP_DEST));//set stop & WDATA_AV;HW bug + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | + (HDCP_I2C_WDAV_DEST)); + j = 0; + while(j < maxloop)//query stop until they are zero + { + if(!(cb_ReadU32(pAp,HdcpCtrl2Reg) & HDCP_I2C_STOP_DEST)) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + + //write device addr : restart; then write + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | + (HDCP_I2C_START_DEST));//set START & WDATA_AV + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | + (HDCP_I2C_WDAV_DEST)); + j = 0; + while(j < maxloop)//query START & WDATA_AV until they are zero + { + if(!(cb_ReadU32(pAp,HdcpCtrl2Reg) & (HDCP_I2C_START_DEST | HDCP_I2C_WDAV_DEST))) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + + cb_WriteU32(pAp,HdcpCtrl1Reg,(cb_ReadU32(pAp,HdcpCtrl1Reg)&0xff00ffff)|((CBIOS_U32)(I2CAddress+1)) << 16);//write the I2C address + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | + HDCP_I2C_WDAV_DEST);//set WDATA_AV + j = 0; + while(j < maxloop)//query WDATA_AV until they are zero + { + if(!(cb_ReadU32(pAp,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST)) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + + + for(i = 0;i < DataLen;i++) + { + //cbWriteU32(pAp,HDCPCTL2_DEST,cb_ReadU32(pAp,HDCPCTL2_DEST) | + // HDCP_I2C_RDREQ_DEST);//set RDREQ + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | + HDCP_I2C_WDAV_DEST);//set WDATA_AV + j = 0; + while(j < maxloop)//query WDATA_AV until they are zero + { + if(!(cb_ReadU32(pAp,HdcpCtrl2Reg) & HDCP_I2C_WDAV_DEST)) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + + j = 0; + while(j < maxloop)//query RDATA_AV until they are not zero + { + if(cb_ReadU32(pAp,HdcpCtrl2Reg) & HDCP_I2C_RDAV_DEST) + break; + cb_DelayMicroSeconds(I2CDELAY); + j++; + } + if(j >= maxloop) + return CBIOS_FALSE; + + *pReadDataBuf++ = (CBIOS_UCHAR)((cb_ReadU32(pAp,HdcpCtrl1Reg) & 0x0000ff00) >> 8);//read the I2C data + + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) &~ + HDCP_I2C_RDAV_DEST);//clear RDATA_AV + } + + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | + (HDCP_I2C_STOP_DEST));//set STOP + cb_WriteU32(pAp,HdcpCtrl2Reg,cb_ReadU32(pAp,HdcpCtrl2Reg) | + (HDCP_I2C_WDAV_DEST)); + + return bResult; +} + +CBIOS_BOOL cbHDCPProxyGetEDID(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 EDIDData[], CBIOS_U32 ulReadEdidOffset, CBIOS_U32 ulBufferSize, CBIOS_U32 ulHDCPNum, CBIOS_U8 nSegNum) +{ + CBIOS_U8 edid_address[] = {0xA0,0x00,0xA2,0x20,0xA6,0x20}; + CBIOS_U8 byTemp; + CBIOS_U32 i = 0; + CBIOS_BOOL bFound = CBIOS_FALSE; + CBIOS_BOOL bRet = CBIOS_FALSE; + + if(nSegNum == 0) + { + for(i= 0; i<3*2;i +=2) + { + bRet = cbHDCPEdidRead(pcbe,edid_address[i],0x0,&byTemp,1,ulHDCPNum, nSegNum); + if(bRet == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),("Can't Read the edid data!\n"))); + return CBIOS_FALSE; + } + + if(byTemp == edid_address[i+1]) + { + bFound = CBIOS_TRUE; + break; + } + } + } + else + { + i = 0; + bFound = CBIOS_TRUE; + } + + if (!bFound) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),("Can't find the edid address!\n"))); + return CBIOS_FALSE; + } + + bRet=cbHDCPEdidRead(pcbe,edid_address[i],(CBIOS_U8)ulReadEdidOffset,EDIDData,ulBufferSize,ulHDCPNum,nSegNum); + return bRet; + +} + +CBIOS_BOOL cbNormalI2cGetEDID(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 I2CBUSNum, CBIOS_U8 EDIDData[], CBIOS_U32 ulReadEdidOffset, CBIOS_U32 ulBufferSize, CBIOS_U8 nSegNum) +{ + CBIOS_U8 edid_address[] = {0xA0,0x00,0xA2,0x20,0xA6,0x20}; + CBIOS_U8 byTemp; + CBIOS_U8 I2CAddress = 0; + CBIOS_U32 i = 0, j = 0; + CBIOS_BOOL bFound = CBIOS_FALSE; + CBIOS_BOOL bRet = CBIOS_FALSE; + CBIOS_BOOL bStatus = CBIOS_TRUE; + CBIOS_MODULE_I2C_PARAMS I2CParams; + cb_memset(&I2CParams, 0, sizeof(CBIOS_MODULE_I2C_PARAMS)); + + I2CParams.I2CBusNum = I2CBUSNum; + I2CParams.ConfigType = CONFIG_I2C_BY_BUSNUM; + + // Sometimes I2C is not stably at begining of start, so edid may be incorrct. + // Here, we read edid maximum three times if edid sum check failed. + for(j=1; j<4; j++) + { + //First write segment index + if(nSegNum != 0) + { + I2CAddress = edid_address[0]; + bFound = CBIOS_TRUE; + } + else if(nSegNum == 0) + { + I2CParams.SlaveAddress = 0x60; + I2CParams.Buffer = &nSegNum; + I2CParams.BufferLen = 1; + cbI2CModule_WriteDDCCIData(pcbe, &I2CParams); + for(i= 0; i<3*2;i +=2) + { + I2CParams.SlaveAddress = edid_address[i]; + I2CParams.OffSet = 0x0; + I2CParams.Buffer = &byTemp; + I2CParams.BufferLen = 1; + bRet = cbI2CModule_ReadData(pcbe, &I2CParams); + if(bRet == CBIOS_FALSE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),("Can't Read the edid data!\n"))); + bFound = CBIOS_FALSE; + break; + } + + if(byTemp == edid_address[i+1]) + { + I2CAddress = edid_address[i]; + bFound = CBIOS_TRUE; + break; + } + } + } + if (!bFound) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),("Can't find the edid address!\n"))); + bStatus = CBIOS_FALSE; + break; + } + + //First write segment index + if(nSegNum != 0) + { + I2CParams.SlaveAddress = 0x60; + I2CParams.Buffer = &nSegNum; + I2CParams.BufferLen = 1; + cbI2CModule_WriteDDCCIData(pcbe, &I2CParams); + } + I2CParams.SlaveAddress = I2CAddress; + I2CParams.OffSet = (CBIOS_U8)ulReadEdidOffset; + I2CParams.BufferLen = ulBufferSize; + I2CParams.Buffer = EDIDData; + bRet = cbI2CModule_ReadData(pcbe, &I2CParams); + + if(!bRet) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),("Read EDID error!\n"))); + bStatus = CBIOS_FALSE; + break; + } + + // Judge if need check the extension block. + if ((ulBufferSize == 256) && (EDIDData[0x7E] == 0)) + ulBufferSize = ulBufferSize / 2; + + if((ulBufferSize % 128 == 0) && (ulReadEdidOffset == 0)) //full edid + { + byTemp = 0; + + for (i = 0 ; i < 128 ; i++) + { + byTemp += EDIDData[i]; + } + + if(byTemp == 0) + { + if((EDIDData[0] == 0x00)&&(EDIDData[1] == 0xff)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),("EDID reading is OK!\n"))); + } + else if((EDIDData[0]&0xF0) == 0x20) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),("EDID reading is OK!\n"))); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING),("EDID reading OK, But the version wrong!\n"))); + } + bStatus = CBIOS_TRUE; + break; + } + else + { + cb_DelayMicroSeconds(j * 50); + continue; + } + } + else //part of EDID + { + bStatus = CBIOS_TRUE; + break; + } + } + + return bStatus; +} + +CBIOS_VOID cbWritePort80(PCBIOS_VOID pvcbe,CBIOS_U8 value) +{ + +} + +CBIOS_BOOL cbNeedSetHdaudioToLocal(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_BOOL ret = CBIOS_FALSE; + + if(cbMMIOReadReg(pcbe, CR_C_9B) == 0x3D + && cbMMIOReadReg(pcbe, CR_C_9A) == 0x40) + { + ret = CBIOS_TRUE; + } + + return ret; +} diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.h b/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.h new file mode 100644 index 0000000000000..cc11bc3be5e65 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.h @@ -0,0 +1,204 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios hw utility common functions prototype. +** +** NOTE: +** This header file CAN ONLY be included by hw layer those files under Hw folder. +******************************************************************************/ + +#ifndef _CBIOS_UTIL_HW_H_ +#define _CBIOS_UTIL_HW_H_ + +// Bit 2 of Backward Comp2 Register (CR33 read-only) is Vertical Sync Active. +// If set, then display is in the vertical retrace mode; +// if clear, then display is in display mode. +#define VSYNC_ACTIVE_CR33 0x04 +#define VBLANK_ACTIVE_CR34 0x08 + +//mmioOffset of registers +#define MMIO_OFFSET_SR_GROUP_A 0x8600 +#define MMIO_OFFSET_SR_GROUP_B 0x8700 +#define MMIO_OFFSET_SR_GROUP_T 0x9400 // IGA3 registers +#define MMIO_OFFSET_SR_GROUP_F 0x9000 +#define MMIO_OFFSET_CR_GROUP_A 0x8800 +#define MMIO_OFFSET_CR_GROUP_B 0x8900 +#define MMIO_OFFSET_CR_GROUP_C 0x8A00 +#define MMIO_OFFSET_CR_GROUP_D 0x8B00 // for 4-channel MIU CR_D registers +#define MMIO_OFFSET_CR_GROUP_D0 0x8C00 // MIU channel 0 CR_D registers +#define MMIO_OFFSET_CR_GROUP_D1 0x8D00 // MIU channel 1 CR_D registers +#define MMIO_OFFSET_CR_GROUP_D2 0x8E00 // MIU channel 2 CR_D registers +#define MMIO_OFFSET_CR_GROUP_D3 0x8F00 // MIU channel 3 CR_D registers +#define MMIO_OFFSET_CR_GROUP_T 0x9500 // IGA3 registers +#define MMIO_OFFSET_CR_GROUP_F 0x9100 + +#define CB_ATTR_ADDR_REG 0x83C0 +#define CB_ATTR_DATA_WRITE_REG 0x83C0 +#define CB_ATTR_DATA_READ_REG 0x83C1 +#define CB_GRAPH_ADDR_REG 0x83CE +#define CB_GRAPH_DATA_REG 0x83CF +#define CB_INPUT_STATUS_0_REG 0x83C2 +#define CB_INPUT_STATUS_1_REG 0x83DA +#define CB_ATTR_INITIALIZE_REG CB_INPUT_STATUS_1_REG +#define CB_MISC_OUTPUT_READ_REG 0x83CC +#define CB_MISC_OUTPUT_WRITE_REG 0x83C2 +#define CB_SEQ_ADDR_REG 0x83C4 +#define CB_SEQ_DATA_REG 0x83C5 +#define CB_CRT_ADDR_REG 0x83D4 +#define CB_CRT_DATA_REG 0x83D5 + +// HDCP +#define HDCP1 1 +#define HDCP2 2 +#define HDCP3 3 +#define HDCP4 4 + +#define HDCPCTL1_DEST 0x82B4 +#define HDCPCTL2_DEST 0x82B8 +#define HDCP2_CTL1_DEST 0x33C60 +#define HDCP2_CTL2_DEST 0x33C64 +#define HDCP3_CTL1_DEST 0x34360 +#define HDCP3_CTL2_DEST 0x34364 +#define HDCP4_CTL1_DEST 0x34A60 +#define HDCP4_CTL2_DEST 0x34A64 + + +//for HDCP 0x82B8/0x33008 bit definition +#define HDCP_I2C_ENABLE_DEST 0x00000001 +#define HDCP_I2C_START_DEST 0x00000010 +#define HDCP_I2C_WDAV_DEST 0x00000008 +#define HDCP_I2C_RDREQ_DEST 0x00000040 +#define HDCP_I2C_RDAV_DEST 0x00000080 +#define HDCP_I2C_STOP_DEST 0x00000020 +#define HDCP_I2C_STATUS_DEST 0x00000800 +#define HDCP_I2C_REQUEST_DEST 0x00000002 +#define HDCP_KEY_RW_DEST 0x00004000 +#define HDCP_KEY_AVL_DEST 0x00008000 +#define HDCP_KEY_LAST_DEST 0x40000000 +#define HDCP_KEY_RKEY_DEST 0x80000000 + +/* +* Following is Port80 value been used in CBIOS +* 0xA0C0xFF for CBIOS +* and 0xF0-0xF4 for CBIOS team internal debug +* Notes:Following Port80 value has been used in VBIOS,can not been used in CBIOS +* 0A0h 0A1h 0A2h 0A3h 0A4h 0A5h 0A6h 0A7h 0A9h 0ABh 0ADh 0AFh +* 0B0h 0B1h 0B2h 0B3h 0B4h 0B5h 0B6h 0B7h +* 0D0h 0D1h 0D2h 0D3h 0D4h 0D6h 0D7h 0D8h 0D9h 0DCh +* 0F9h 0FAh 0FBh +*/ +#define CBIOS_PORT80_ID_CBiosPost_Enter 0xB8 +#define CBIOS_PORT80_ID_CBiosPost_Exit 0xB9 +#define CBIOS_PORT80_ID_CBiosSetModeToIGA_Enter 0xC3 +#define CBIOS_PORT80_ID_CBiosSetModeToIGA_Exit 0xC4 +#define CBIOS_PORT80_ID_CBiosSetClock_Enter 0xC8 +#define CBIOS_PORT80_ID_CBiosSetClock_Exit 0xC9 +#define CBIOS_PORT80_ID_CBiosVoltageFunction_Enter 0xCA +#define CBIOS_PORT80_ID_CBiosVoltageFunction_Exit 0xCB +#define CBIOS_PORT80_ID_DestructiveDeviceDetect_Enter 0xCC +#define CBIOS_PORT80_ID_DestructiveDeviceDetect_Exit 0xCD +#define CBIOS_PORT80_ID_NonDestructiveDeviceDetect_Enter 0xCE +#define CBIOS_PORT80_ID_NonDestructiveDeviceDetect_Exit 0xCF +#define CBIOS_PORT80_ID_CBiosI2CDataWrite_Enter 0xEC +#define CBIOS_PORT80_ID_CBiosI2CDataWrite_Exit 0xED +#define CBIOS_PORT80_ID_CBiosI2CDataRead_Enter 0xEE +#define CBIOS_PORT80_ID_CBiosI2CDataRead_Exit 0xEF +/* CBIOS post internal function */ +#define CBIOS_PORT80_ID_AfterChipEnable 0xBA +#define CBIOS_PORT80_ID_AfterPrePost 0xBB +#define CBIOS_PORT80_ID_AfterLoadDefautTables 0xBC +#define CBIOS_PORT80_ID_AfterInitMemory 0xBD +#define CBIOS_PORT80_ID_AfterIsMemoryWriteable 0xBE +#define CBIOS_PORT80_ID_AfterReadHWPanelID 0xBF +#define CBIOS_PORT80_ID_AfterProgramPCISSID 0xC0 +#define CBIOS_PORT80_ID_AfterSetupVGA 0xC1 +#define CBIOS_PORT80_ID_AfterEndOfPost 0xC2 +#define CBIOS_PORT80_ID_AfterLoadSWBootStrap 0xF5 +#define CBIOS_PORT80_ID_AfterLoadMIUTable 0xF6 +#define CBIOS_PORT80_ID_AfterAutoMemConfig 0xF7 +#define CBIOS_PORT80_ID_AfterLoadModeExtRegDefault 0xF8 +#define CBIOS_PORT80_ID_AfterLoadMode3SRRegTable 0xFC +#define CBIOS_PORT80_ID_AfterLoadMode3CRRegTable 0xFD +#define CBIOS_PORT80_ID_AfterLoadMode3RegOnIGA2 0xFE +/* Set Mode To IGA */ +#define CBIOS_PORT80_ID_AfterSetSrcTiming 0xC5 +#define CBIOS_PORT80_ID_AfterSetDstTiming 0xC6 +#define CBIOS_PORT80_ID_AfterSetScalerSize 0xC7 +/* Set Source Mode */ +#define CBIOS_PORT80_ID_AfterModeEnvSetup 0xDA +#define CBIOS_PORT80_ID_AfterSetCRTimingReg 0xDB +#define CBIOS_PORT80_ID_AfterRamDacSet 0xDD +#define CBIOS_PORT80_ID_AfterPlanarSet 0xDE +#define CBIOS_PORT80_ID_AfterSetBPSL 0xDF +#define CBIOS_PORT80_ID_AfterSetDacRegisters 0xE0 +/* Set Destination Mode */ +#define CBIOS_PORT80_ID_AfterDstTimingInitial 0xE1 +#define CBIOS_PORT80_ID_AfterDstTimingPatchForTech 0xE2 +#define CBIOS_PORT80_ID_AfterDstTimingRegSetting 0xE3 +#define CBIOS_PORT80_ID_AfterDstTimingContractionSetting 0xE4 +#define CBIOS_PORT80_ID_AfterDstTimingPositionSetting 0xE5 +#define CBIOS_PORT80_ID_AfterStreamPathMux 0xE6 +#define CBIOS_PORT80_ID_AfterDstTimingPatch 0xE7 +#define CBIOS_PORT80_ID_AfterGlobalModePatch 0xE8 +/* Set Scaler Size */ +#define CBIOS_PORT80_ID_AfterEnableUpScaler 0xE9 +#define CBIOS_PORT80_ID_AfterDisableUpScaler 0xEA +#define CBIOS_PORT80_ID_AfterEnableCentering 0xEB + +//Register +CBIOS_VOID cbUnlockSR(PCBIOS_EXTENSION_COMMON pcbe); +CBIOS_VOID cbUnlockCR(PCBIOS_EXTENSION_COMMON pcbe); +CBIOS_VOID cbWaitForInactive(PCBIOS_EXTENSION_COMMON pcbe); +CBIOS_VOID cbWaitForActive(PCBIOS_EXTENSION_COMMON pcbe); +CBIOS_VOID cbWaitForBlank(PCBIOS_EXTENSION_COMMON pcbe); +CBIOS_VOID cbWaitForDisplay(PCBIOS_EXTENSION_COMMON pcbe); +CBIOS_U32 cbGetParallelRegIndex(PCBIOS_PARALLEL_REGISTER pRegTbl, CBIOS_U32 RegNameIndex, CBIOS_U32 ModuleIndex); +CBIOS_U8 cbBiosMMIOReadReg(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U16 type_index, CBIOS_U32 IGAIndex); +CBIOS_VOID cbBiosMMIOWriteReg(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U16 type_index, CBIOS_U8 value, CBIOS_U8 mask, CBIOS_U32 IGAIndex) ; +CBIOS_U8 cbMMIOReadReg(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U16 type_index); +CBIOS_VOID cbMMIOWriteReg(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U16 type_index, CBIOS_U8 value, CBIOS_U8 mask); +CBIOS_VOID cbMMIOWriteReg32(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 Index, CBIOS_U32 Value, CBIOS_U32 Mask); +CBIOS_U32 cbMapMaskRead(PCBIOS_EXTENSION_COMMON pcbe, CBREGISTER_IDX *regTable, CBIOS_U32 IGAIndex); +CBIOS_VOID cbMapMaskWrite(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 Value, CBREGISTER_IDX *regTable, CBIOS_U32 IGAIndex); +CBIOS_VOID cbLoadtable(PCBIOS_EXTENSION_COMMON pcbe, CBREGISTER *pRegTable, CBIOS_U32 Table_Size, CBIOS_U32 IGAIndex); +CBIOS_VOID cbLoadMemoryTimingTbl(PCBIOS_EXTENSION_COMMON pcbe, MMIOREGISTER* pRegTable, CBIOS_U32 Table_Size); +CBIOS_VOID cbSaveRegTableU8(PCBIOS_EXTENSION_COMMON pcbe, CBREGISTER *pRegTable, const CBIOS_U32 TableSize, CBIOS_U8* SavedRegTable); +CBIOS_VOID cbRestoreRegTableU8(PCBIOS_EXTENSION_COMMON pcbe, const CBREGISTER *pRegTable, const CBIOS_U32 TableSize, CBIOS_U8* SavedRegTable); +CBIOS_VOID cbSaveRegTableU32(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_REGISTER32 *pRegTable, const CBIOS_U32 TableSize); +CBIOS_VOID cbRestoreRegTableU32(PCBIOS_EXTENSION_COMMON pcbe, const CBIOS_REGISTER32 *pRegTable, const CBIOS_U32 TableSize); +CBIOS_BOOL cbProgClock(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 ClockFreq, CBIOS_U32 ClockType, CBIOS_U8 IGAIndex); +CBIOS_U32 cbGetProgClock(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 *ClockFreq, CBIOS_U32 ClockType); +CBIOS_BOOL cbWaitVBlank( PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 IGAIndex); +CBIOS_BOOL cbWaitNonFullVBlank(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 IGAIndex); +CBIOS_BOOL cbWaitVSync(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 IGAIndex); +CBIOS_BOOL cbHDCPDDCciPortWrite(PCBIOS_EXTENSION_COMMON pcbe,CBIOS_UCHAR Port, CBIOS_UCHAR Offset, const PCBIOS_UCHAR pWriteDataBuf, CBIOS_U32 DataLen, CBIOS_S32 HDCPChannel); +CBIOS_BOOL cbHDCPDDCciPortRead(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_UCHAR Port, CBIOS_UCHAR Offset, const PCBIOS_UCHAR pReadDataBuf, CBIOS_U32 DataLen, CBIOS_S32 HDCPChannel); +CBIOS_BOOL cbIsMMIOWell(PCBIOS_EXTENSION_COMMON pcbe); +CBIOS_BOOL cbDumpRegisters(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_DUMP_TYPE DumpType); +CBIOS_VOID cbDumpModeInfo(PCBIOS_EXTENSION_COMMON pcbe); +CBIOS_VOID cbDumpClockInfo(PCBIOS_EXTENSION_COMMON pcbe); +CBIOS_BOOL cbDisableHdcp(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 ulHDCPNum); +CBIOS_VOID cbEnableHdcpStatus(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 ulHDCPNum); +CBIOS_BOOL cbHDCPProxyGetEDID(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 EDIDData[], CBIOS_U32 ulReadEdidOffset, CBIOS_U32 ulBufferSize, CBIOS_U32 ulHDCPNum, CBIOS_U8 nSegNum); +CBIOS_BOOL cbNormalI2cGetEDID(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 I2CBUSNum, CBIOS_U8 EDIDData[], CBIOS_U32 ulReadEdidOffset, CBIOS_U32 ulBufferSize, CBIOS_U8 nSegNum); + +//Port 80 +CBIOS_VOID cbWritePort80(PCBIOS_VOID pcbe, CBIOS_U8 value); + +CBIOS_BOOL cbNeedSetHdaudioToLocal(PCBIOS_VOID pvcbe); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/Interrupt/CBiosISR.c b/drivers/gpu/drm/arise/cbios/Hw/Interrupt/CBiosISR.c new file mode 100644 index 0000000000000..2bbe78605a5d5 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Interrupt/CBiosISR.c @@ -0,0 +1,372 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios interrupt service routine functions implementation. +** +** NOTE: +** The print, delay and mutex lock SHOULD NOT be called in isr functions. +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "../CBiosHwShare.h" +#include "../Register/BIU_SBI_registers.h" +#include "../HwBlock/CBiosDIU_DP.h" + +CBIOS_STATUS cbGetInterruptInfo(PCBIOS_VOID pvcbe, PCBIOS_INTERRUPT_INFO pIntInfo) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + REG_MM8574 RegMM8574Value; + REG_MM8578 RegMM8578Value; + + /* NOTE 1: any write to MM8574, both MM8574 & MM8578 will copied from MM8504 & MM8548 and MM8504 & MM8548 are cleared */ + /* NOTE 2: For register 8574 do not use mask write func cbMMIOWriteReg32, one more read may have side effect for this ISR register*/ + cb_WriteU32(pcbe->pAdapterContext, 0x8574, 0); + + RegMM8574Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x8574); + RegMM8578Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x8578); + + pIntInfo->InterruptType = 0; + // MM8504 + if (RegMM8574Value.VSYNC1_INT) + { + pIntInfo->InterruptType |= CBIOS_VSYNC_1_INT; + } + + if (RegMM8574Value.VSYNC2_INT) + { + pIntInfo->InterruptType |= CBIOS_VSYNC_2_INT; + } + + if (RegMM8574Value.VSYNC3_INT) + { + pIntInfo->InterruptType |= CBIOS_VSYNC_3_INT; + } + + if (RegMM8574Value.VSYNC4_INT) + { + pIntInfo->InterruptType |= CBIOS_VSYNC_4_INT; + } + + if (RegMM8574Value.DP1_INT) + { + pIntInfo->InterruptType |= CBIOS_DP_1_INT; + } + + if (RegMM8574Value.DP2_INT) + { + pIntInfo->InterruptType |= CBIOS_DP_2_INT; + } + + if (RegMM8574Value.DP3_INT) + { + pIntInfo->InterruptType |= CBIOS_DP_3_INT; + } + + if (RegMM8574Value.DP4_INT) + { + pIntInfo->InterruptType |= CBIOS_DP_4_INT; + } + + if (RegMM8574Value.HDCP_INT) + { + pIntInfo->InterruptType |= CBIOS_HDCP_INT; + } + + if (RegMM8574Value.HDA_AUDIO_INT) + { + pIntInfo->InterruptType |= CBIOS_HDA_AUDIO_INT; + } + + if ((RegMM8574Value.HDA_CODEC_INT) || (RegMM8574Value.MB_INT)) + { + pIntInfo->InterruptType |= CBIOS_HDA_CODEC_INT; + } + + if (RegMM8574Value.CORRECTABLE_ERR_INT) + { + pIntInfo->InterruptType |= CBIOS_CORRECTABLE_ERR_INT; + } + + if (RegMM8574Value.NON_FATAL_ERR_INT) + { + pIntInfo->InterruptType |= CBIOS_NON_FATAL_ERR_INT; + } + + if (RegMM8574Value.FATAL_ERR_INT) + { + pIntInfo->InterruptType |= CBIOS_FATAL_ERR_INT; + } + + if (RegMM8574Value.UNSUPPORTED_ERR_INT) + { + pIntInfo->InterruptType |= CBIOS_UNSUPPORTED_ERR_INT; + } + + pIntInfo->AdvancedIntType = 0; + // MM8548 + if (RegMM8578Value.FENCE_CMD_INT) + { + pIntInfo->AdvancedIntType |= CBIOS_FENCE_INT; + } + + return CBIOS_OK; +} + + +CBIOS_STATUS cbGetCECInterruptInfo(PCBIOS_VOID pvcbe, PCBIOS_CEC_INTERRUPT_INFO pCECIntInfo) +{ + CBIOS_STATUS Status = CBIOS_OK; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CEC_MISC_REG2 CECMiscReg2; + + if (pCECIntInfo == CBIOS_NULL) + { + Status = CBIOS_ER_NULLPOINTER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbGetCECInterruptInfo: pCECIntInfo is NULL!")); + } + else if (!pcbe->ChipCaps.IsSupportCEC) + { + Status = CBIOS_ER_HARDWARE_LIMITATION; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbGetCECInterruptInfo: Can't support CEC!")); + } + else if (!(pCECIntInfo->InterruptBitMask & BIT6)) + { + Status = CBIOS_OK; + pCECIntInfo->InterruptType = INVALID_CEC_INTERRUPT; + } + else + { + //set to invalid interrupt by default + pCECIntInfo->InterruptType = INVALID_CEC_INTERRUPT; + + //first check CEC1 + CECMiscReg2.CECMiscReg2Value = cb_ReadU32(pcbe->pAdapterContext, 0x33150); + + if (CECMiscReg2.FolReceiveReady) + { + pCECIntInfo->CEC1MsgReceived = 1; + pCECIntInfo->InterruptType = NORMAL_CEC_INTERRUPT; + } + else + { + pCECIntInfo->CEC1MsgReceived = 0; + } + + + //CEC2 + CECMiscReg2.CECMiscReg2Value = cb_ReadU32(pcbe->pAdapterContext, 0x33e3c); + + if (CECMiscReg2.FolReceiveReady) + { + pCECIntInfo->CEC2MsgReceived = 1; + pCECIntInfo->InterruptType = NORMAL_CEC_INTERRUPT; + } + else + { + pCECIntInfo->CEC2MsgReceived = 0; + } + + //CEC3 + CECMiscReg2.CECMiscReg2Value = cb_ReadU32(pcbe->pAdapterContext, 0x34540); + + if (CECMiscReg2.FolReceiveReady) + { + pCECIntInfo->CEC3MsgReceived = 1; + pCECIntInfo->InterruptType = NORMAL_CEC_INTERRUPT; + } + else + { + pCECIntInfo->CEC3MsgReceived = 0; + } + + //CEC4 + CECMiscReg2.CECMiscReg2Value = cb_ReadU32(pcbe->pAdapterContext, 0x34c40); + + if (CECMiscReg2.FolReceiveReady) + { + pCECIntInfo->CEC4MsgReceived = 1; + pCECIntInfo->InterruptType = NORMAL_CEC_INTERRUPT; + } + else + { + pCECIntInfo->CEC4MsgReceived = 0; + } + + Status = CBIOS_OK; + + } + return Status; +} + +CBIOS_STATUS cbGetHDCPInterruptInfo(PCBIOS_VOID pvcbe, PCBIOS_HDCP_INFO_PARA pHdcpInfoParam) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + REG_MM82C8 RegMM82C8Value, RegMM33C70Value, RegMM34370Value, RegMM34A70Value; + REG_MM8374 RegMM8374Value, RegMM33C78Value, RegMM34378Value, RegMM34A78Value; + REG_MM3368C RegMM3368CValue, RegMM33C88Value, RegMM34388Value, RegMM34A88Value; + + if(pHdcpInfoParam == CBIOS_NULL) + { + Status = CBIOS_ER_NULLPOINTER; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pHdcpInfoParam is NULL!", FUNCTION_NAME)); + } + else if(pHdcpInfoParam->InterruptType != CBIOS_HDCP_INT) + { + Status = CBIOS_ER_INVALID_PARAMETER; + + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: InterruptType invalid!", FUNCTION_NAME)); + } + else + { + pHdcpInfoParam->IntDevicesId = CBIOS_TYPE_NONE; + RegMM82C8Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x82C8); + RegMM33C70Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x33C70); + RegMM34370Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x34370); + RegMM34A70Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x34A70); + + if(RegMM82C8Value.HDCP1_Interrupt) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP1; + RegMM82C8Value.HDCP1_Interrupt = 0; + cb_WriteU32(pcbe->pAdapterContext, 0x82C8, RegMM82C8Value.Value); + } + + if(RegMM33C70Value.HDCP1_Interrupt) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP2; + RegMM33C70Value.HDCP1_Interrupt = 0; + cb_WriteU32(pcbe->pAdapterContext, 0x33C70, RegMM33C70Value.Value); + } + + if(RegMM34370Value.HDCP1_Interrupt) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP3; + RegMM34370Value.HDCP1_Interrupt = 0; + cb_WriteU32(pcbe->pAdapterContext, 0x34370, RegMM34370Value.Value); + } + + if(RegMM34A70Value.HDCP1_Interrupt) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP4; + RegMM34A70Value.HDCP1_Interrupt = 0; + cb_WriteU32(pcbe->pAdapterContext, 0x34A70, RegMM34A70Value.Value); + } + + RegMM8374Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x8374); + RegMM33C78Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x33C78); + RegMM34378Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x34378); + RegMM34A78Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x34A78); + + if(RegMM8374Value.DP_HDCP_INT) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP1; + RegMM8374Value.DP_HDCP_INT = 0; + cb_WriteU32(pcbe->pAdapterContext, 0x8374, RegMM8374Value.Value); + } + + if(RegMM33C78Value.DP_HDCP_INT) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP2; + RegMM33C78Value.DP_HDCP_INT = 0; + cb_WriteU32(pcbe->pAdapterContext, 0x33C78, RegMM33C78Value.Value); + } + + if(RegMM34378Value.DP_HDCP_INT) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP3; + RegMM34378Value.DP_HDCP_INT = 0; + cb_WriteU32(pcbe->pAdapterContext, 0x34378, RegMM34378Value.Value); + } + + if(RegMM34A78Value.DP_HDCP_INT) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP4; + RegMM34A78Value.DP_HDCP_INT = 0; + cb_WriteU32(pcbe->pAdapterContext, 0x34A78, RegMM34A78Value.Value); + } + + RegMM3368CValue.Value = cb_ReadU32(pcbe->pAdapterContext, 0x368C); + RegMM33C88Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x33C88); + RegMM34388Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x34388); + RegMM34A88Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x34A88); + + if(RegMM3368CValue.Value != 0) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP1; + } + + if(RegMM33C88Value.Value != 0) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP2; + } + + if(RegMM34388Value.Value != 0) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP3; + } + + if(RegMM34A88Value.Value != 0) + { + pHdcpInfoParam->IntDevicesId |= CBIOS_TYPE_DP4; + } + } + + return Status; +} + +CBIOS_STATUS cbGetHDACInterruptInfo(PCBIOS_VOID pvcbe, PCBIOS_HDAC_INFO_PARA pHdacInfoParam) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + REG_MM8288 RegMM8288Value, RegMM33D9CValue; + + if(pHdacInfoParam == CBIOS_NULL) + { + Status = CBIOS_ER_NULLPOINTER; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pHdacInfoParam is NULL!", FUNCTION_NAME)); + } + else if(pHdacInfoParam->InterruptType != CBIOS_HDA_CODEC_INT) + { + Status = CBIOS_ER_INVALID_PARAMETER; + + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: InterruptType invalid!", FUNCTION_NAME)); + } + else + { + pHdacInfoParam->IntDevicesId = CBIOS_TYPE_NONE; + RegMM8288Value.Value = cb_ReadU32(pcbe->pAdapterContext, 0x8288); + RegMM33D9CValue.Value = cb_ReadU32(pcbe->pAdapterContext, 0x33D9C); + + if(RegMM8288Value.Int_Src_Codec) + { + pHdacInfoParam->IntDevicesId |= CBIOS_TYPE_DP1; + RegMM8288Value.Int_Src_Codec = 0; + cb_WriteU32(pcbe->pAdapterContext, 0x8288, RegMM8288Value.Value); + } + + if(RegMM33D9CValue.Int_Src_Codec) + { + pHdacInfoParam->IntDevicesId |= CBIOS_TYPE_DP2; + RegMM33D9CValue.Int_Src_Codec = 0; + cb_WriteU32(pcbe->pAdapterContext, 0x33D9C, RegMM33D9CValue.Value); + } + + } + + return Status; +} diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_CR_C_BUS_registers.h b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_CR_C_BUS_registers.h new file mode 100644 index 0000000000000..82f26e7d85249 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_CR_C_BUS_registers.h @@ -0,0 +1,1587 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +typedef union _REG_CR00_C //BIU_Debug_Bus_Selection_Register +{ + struct + { + CBIOS_U8 Debug_Bus_Sub_module_Selection :3; + CBIOS_U8 Debug_Bus_Selection :4; + CBIOS_U8 Reserved :1; + }; + CBIOS_U8 Value; +}REG_CR00_C; + + +typedef union _REG_CR04_CR07_C //Reserved_1_Dword +{ + struct + { + CBIOS_U32 Reserved :32; + }; + CBIOS_U32 Value; +}REG_CR04_CR07_C; + + +typedef union _REG_CR08_CR0B_C //BIU_TLR_Debug_Register_Dword +{ + struct + { + CBIOS_U32 FBFF_full :1; + CBIOS_U32 FBFF_empty :1; + CBIOS_U32 MWFF_empty :1; + CBIOS_U32 TLA_idle :1; + CBIOS_U32 Mem_W_request_busy :1; + CBIOS_U32 NP_request_idle :1; + CBIOS_U32 PH_queue_empty :1; + CBIOS_U32 NPH_queue_empty :1; + CBIOS_U32 PH_queue_pop_enable :1; + CBIOS_U32 NPH_queue_pop_enable :1; + CBIOS_U32 Setup_state_of_TLA_pipe :1; + CBIOS_U32 Ready_state_of_TLA_pipe :1; + CBIOS_U32 Flush_state_of_TLA_pipe :1; + CBIOS_U32 Residual_state_of_TLA_pipe :1; + CBIOS_U32 Wait_state_of_TLA_pipe :1; + CBIOS_U32 Pre_ready_state_of_TLA_pipe :1; + CBIOS_U32 Prepare_phase :1; + CBIOS_U32 Header_phase :1; + CBIOS_U32 Data_phase :1; + CBIOS_U32 Pipe_contex_valid :1; + CBIOS_U32 FMTFF_full :1; + CBIOS_U32 MISC_bus_busy :1; + CBIOS_U32 Offset_Fifo_Full :1; + CBIOS_U32 Offset_Fifo_Empty :1; + CBIOS_U32 CBUCMD_RES :2; + CBIOS_U32 Reserved :6; + }; + CBIOS_U32 Value; +}REG_CR08_CR0B_C; + + +typedef union _REG_CR0C_CR0F_C //Reserved_1_Dword +{ + struct + { + CBIOS_U32 Reverved :32; + }; + CBIOS_U32 Value; +}REG_CR0C_CR0F_C; + + +typedef union _REG_CR10_CR13_C //Reserved_1_Dword +{ + struct + { + CBIOS_U32 Reverved :32; + }; + CBIOS_U32 Value; +}REG_CR10_CR13_C; + + +typedef union _REG_CR14_CR17_C //Reserved_1_Dword +{ + struct + { + CBIOS_U32 Reserved :32; + }; + CBIOS_U32 Value; +}REG_CR14_CR17_C; + + +typedef union _REG_CR18_CR1B_C_000 //BIU_TLM_Debug_Queue_Request_Register_DWord +{ + struct + { + CBIOS_U32 Queue_read_ptr :6; + CBIOS_U32 Request_header_queue_empty :1; + CBIOS_U32 Comp_packet_queue_empty :1; + CBIOS_U32 Comp_packet_queue_read_ptr :6; + CBIOS_U32 Np_Read_Request_or_P_Write_Request :1; + CBIOS_U32 rqpcnt_inc :1; + CBIOS_U32 Completion_queue_available_space :6; + CBIOS_U32 Completion_queue_pass_completion :1; + CBIOS_U32 P_write_request :1; + CBIOS_U32 Read_request_control_state_machine :3; + CBIOS_U32 NP_read_request :1; + CBIOS_U32 Write_request_control_state :2; + CBIOS_U32 TLR_completion_sop_assert :1; + CBIOS_U32 TLR_return_bad_completion :1; + }; + CBIOS_U32 Value; +}REG_CR18_CR1B_C_000; + + +typedef union _REG_CR18_CR1B_C_001 //BIU_TLM_Debug_Queue_Request_Register_DWord +{ + struct + { + CBIOS_U32 completion_packet_queue_write_ptr :6; + CBIOS_U32 completion_write_control_state_machine :2; + CBIOS_U32 Length :4; + CBIOS_U32 CPL_DVALID :1; + CBIOS_U32 CPL_DISCARD_Delay_from_TLR :1; + CBIOS_U32 CPL_EOP :1; + CBIOS_U32 CPL_SOP :1; + CBIOS_U32 CPL_queue_available_space :6; + CBIOS_U32 CPL_queue_full :1; + CBIOS_U32 CPL_DISCARD :1; + CBIOS_U32 CPL_TAG :6; + CBIOS_U32 CPL_Header_Write_enable :1; + CBIOS_U32 CPL_Header_queue_full :1; + }; + CBIOS_U32 Value; +}REG_CR18_CR1B_C_001; + + +typedef union _REG_CR18_CR1B_C_010 //BIU_TLM_Debug_Queue_Request__Register_DWord +{ + struct + { + CBIOS_U32 CPL_Queue_SM :2; + CBIOS_U32 CPL_Header_queue_empty :1; + CBIOS_U32 CPL_Header_available :1; + CBIOS_U32 Request_FIFO_Control_SM :3; + CBIOS_U32 qtag_full_or_cplq_zero :1; + CBIOS_U32 Request_queue_write_pointer :6; + CBIOS_U32 Request_queue_full :1; + CBIOS_U32 Master_write_request :1; + CBIOS_U32 Write_data_queue_write_pointer :6; + CBIOS_U32 Write_data_queue_full :1; + CBIOS_U32 Master_read_request :1; + CBIOS_U32 CPL_length :5; + CBIOS_U32 Sub_index_rd_extag :2; + CBIOS_U32 TAG_queue_write_enable :1; + }; + CBIOS_U32 Value; +}REG_CR18_CR1B_C_010; + + +typedef union _REG_CR18_CR1B_C_011 //BIU_TLM_Debug_Queue_Request_Register_DWord +{ + struct + { + CBIOS_U32 Completion_queue_read_ptr :6; + CBIOS_U32 Completion_queue_empty :1; + CBIOS_U32 Completion_tag_queue_empty :1; + CBIOS_U32 TAG_queue_write_pointer :6; + CBIOS_U32 Completion_ECLK_write_ptr_0 :2; + CBIOS_U32 Completion_tag_read_ptr :6; + CBIOS_U32 Completion_ECLK_write_ptr_1 :2; + CBIOS_U32 Completion_ECLK_read_ptr :6; + CBIOS_U32 Completion_ECLK_write_ptr_2 :2; + }; + CBIOS_U32 Value; +}REG_CR18_CR1B_C_011; + + +typedef union _REG_CR18_CR1B_C_100 //BIU_TLM_Debug_Queue_Request_Register_Dword +{ + struct + { + CBIOS_U32 MSI_USS_Control_SM :3; + CBIOS_U32 Reserved_4to3 :2; + CBIOS_U32 CSP_request_pulse :1; + CBIOS_U32 MSI_request_pulse :1; + CBIOS_U32 Reserved_bit7 :1; + CBIOS_U32 CR19_C_100_Reserved :8; + CBIOS_U32 CR1A_C_100_Reserved :8; + CBIOS_U32 CR1B_C_100_Reserved :8; + }; + CBIOS_U32 Value; +}REG_CR18_CR1B_C_100; + + +typedef union _REG_CR18_CR1B_C_101 //BIU_TLM_Debug_Queue_Request_Register_DWord +{ + struct + { + CBIOS_U32 CR18_C_101_Reserved :8; + CBIOS_U32 CR19_C_101_Reserved :8; + CBIOS_U32 CR1A_C_101_Reserved :8; + CBIOS_U32 CR1B_C_101_Reserved :8; + }; + CBIOS_U32 Value; +}REG_CR18_CR1B_C_101; + + +typedef union _REG_CR18_CR1B_C_110 //BIU_TLM_EMR_Debug_Queue_Request_Register_DWord +{ + struct + { + CBIOS_U32 out_emr_read_request :1; + CBIOS_U32 out_emr_write_request :1; + CBIOS_U32 in_emr_read_request :1; + CBIOS_U32 _1k_master_write_continue :1; + CBIOS_U32 master_write_continue :1; + CBIOS_U32 in_emr_write_request :1; + CBIOS_U32 out_emr_send_request_SM :4; + CBIOS_U32 in_emr_read_SM_0 :3; + CBIOS_U32 out_emr_write_SM :4; + CBIOS_U32 in_emr_read_SM_1 :4; + CBIOS_U32 in_emr_write_SM :6; + CBIOS_U32 Reserved_31to27 :5; + }; + CBIOS_U32 Value; +}REG_CR18_CR1B_C_110; + + +typedef union _REG_CR18_CR1B_C_111 //BIU_TLM_Debug_Reserved_Register_DWord +{ + struct + { + CBIOS_U32 Reserved_31to0 :32; + }; + CBIOS_U32 Value; +}REG_CR18_CR1B_C_111; + + +typedef union _REG_CR1C_CR1F_C_000 //BIU_MSG_FSM_State_Debug_Register_DWord +{ + struct + { + CBIOS_U32 MSG_FSM_state :3; + CBIOS_U32 Reserved_0 :5; + CBIOS_U32 Reserved_1 :8; + CBIOS_U32 Reserved_2 :8; + CBIOS_U32 Reserved_3 :8; + }; + CBIOS_U32 Value; +}REG_CR1C_CR1F_C_000; + + +typedef union _REG_CR1C_CR1F_C_100 //BIU_MSG_Header_31:0_Debug_Register_Dword +{ + struct + { + CBIOS_U32 message_header_31to0 :32; + }; + CBIOS_U32 Value; +}REG_CR1C_CR1F_C_100; + + +typedef union _REG_CR1C_CR1F_C_101 //BIU_MSG_Header_63:32_Debug_Register_Dword +{ + struct + { + CBIOS_U32 message_header_63to32 :32; + }; + CBIOS_U32 Value; +}REG_CR1C_CR1F_C_101; + + +typedef union _REG_CR1C_CR1F_C_110 //BIU_MSG_Header_95:64_Debug_Register_Dword +{ + struct + { + CBIOS_U32 message_header_95to64 :32; + }; + CBIOS_U32 Value; +}REG_CR1C_CR1F_C_110; + + +typedef union _REG_CR1C_CR1F_C_111 //BIU_MSG_Header_127:96_Debug_Register_Dword +{ + struct + { + CBIOS_U32 message_header_127to96 :32; + }; + CBIOS_U32 Value; +}REG_CR1C_CR1F_C_111; + + +typedef union _REG_CR20_C //BIU_PMC_State_Debug_Register +{ + struct + { + CBIOS_U8 PM_state :4; + CBIOS_U8 PM_sub_state_of_TX_L0s :2; + CBIOS_U8 PM_sub_state_of_RX_L0s :2; + }; + CBIOS_U8 Value; +}REG_CR20_C; + + +typedef union _REG_CR21_C //BIU_PMC_Command_and_Gating_Clock_Debug_Register +{ + struct + { + CBIOS_U8 PM_command :2; + CBIOS_U8 block_TLP :1; + CBIOS_U8 gating_T_L_clock :1; + CBIOS_U8 gating_T_R_clock :1; + CBIOS_U8 block_DLLP :1; + CBIOS_U8 gating_D_L_TX_clock :1; + CBIOS_U8 Reserved :1; + }; + CBIOS_U8 Value; +}REG_CR21_C; + + +typedef union _REG_CR22_C //BIU_PMC_Gating_D-L_Clock_Debug_Register +{ + struct + { + CBIOS_U8 gating_D_L_RX_clock :1; + CBIOS_U8 Reserved :7; + }; + CBIOS_U8 Value; +}REG_CR22_C; + + +typedef union _REG_CR23_C //BIU_PMC_Debug_Reserved_Register +{ + struct + { + CBIOS_U8 Reserved :8; + }; + CBIOS_U8 Value; +}REG_CR23_C; + + +typedef union _REG_CR24_CR27_C_000 //Reserved_DWord +{ + struct + { + CBIOS_U32 Reserved :32; + }; + CBIOS_U32 Value; +}REG_CR24_CR27_C_000; + + +typedef union _REG_CR24_CR27_C_001 //Reserved_DWord +{ + struct + { + CBIOS_U32 Reserved :32; + }; + CBIOS_U32 Value; +}REG_CR24_CR27_C_001; + + +typedef union _REG_CR24_CR27_C_010 //BIU_CIF_CFA_Status_Debug_Register_DWord +{ + struct + { + CBIOS_U32 DQEmpty :1; + CBIOS_U32 FBFF2_EMPTY :1; + CBIOS_U32 FBFF_EMPTY :1; + CBIOS_U32 DQFull :1; + CBIOS_U32 DQFull_1 :1; + CBIOS_U32 CFA_CS :3; + CBIOS_U32 OFFSET2_EMPTY :1; + CBIOS_U32 OFFSET_EMPTY :1; + CBIOS_U32 APT_CFA_EMPTY :1; + CBIOS_U32 CFAIFX_BUSY :1; + CBIOS_U32 VGAMR_W :1; + CBIOS_U32 VGAM_REQ :1; + CBIOS_U32 INVALID_CPURW :1; + CBIOS_U32 BIU_MXU_RW :1; + CBIOS_U32 BIU_MXU_REQ :1; + CBIOS_U32 vga_idle :1; + CBIOS_U32 DQRe :1; + CBIOS_U32 PWH_TIMEOUT :1; + CBIOS_U32 CR26_C_010_Reserved_23to20 :4; + CBIOS_U32 CR27_C_010_Reserved :8; + }; + CBIOS_U32 Value; +}REG_CR24_CR27_C_010; + + +typedef union _REG_CR24_CR27_C_011 //BIU_CIF_IO_Debug_Register_DWord +{ + struct + { + CBIOS_U32 read_ROM_registers :1; + CBIOS_U32 write_ROM_registers :1; + CBIOS_U32 RW_LUT_registers :1; + CBIOS_U32 RW_BIU_registers :1; + CBIOS_U32 Rw_Miu0_Registers :1; + CBIOS_U32 Rw_Miu1_registers :1; + CBIOS_U32 Rw_Miu2_Registers :1; + CBIOS_U32 Rw_Miu3_Registers :1; + CBIOS_U32 Rw_Mxu_Registers :1; + CBIOS_U32 Rw_Iga_Registers :1; + CBIOS_U32 Rw_3c3 :1; + CBIOS_U32 BIU_DIU_MMIO_MODE :1; + CBIOS_U32 DIU_BIU_MIUCRALL :1; + CBIOS_U32 DIU_BIU_MIUCRSET :2; + CBIOS_U32 DIU_BIU_SELCRD :2; + CBIOS_U32 IO_RW_BS :1; + CBIOS_U32 IO_REQ_IFX :1; + CBIOS_U32 CR26_C_011_Reserved_23to19 :5; + CBIOS_U32 CR27_C_011_Reserved :8; + }; + CBIOS_U32 Value; +}REG_CR24_CR27_C_011; + + +typedef union _REG_CR24_CR27_C_100 //BIU_CIF_MMIO_Debug_Register_DWord +{ + struct + { + CBIOS_U32 RW_error_header_registers :1; + CBIOS_U32 RW_Debug_registers :1; + CBIOS_U32 RW_TLA_registers :1; + CBIOS_U32 RW_CBU_registers :1; + CBIOS_U32 RW_BIU_registers :1; + CBIOS_U32 RW_CSP_registers :1; + CBIOS_U32 RW_SP_registers :1; + CBIOS_U32 sel_pcounter :1; + CBIOS_U32 sel_sli :1; + CBIOS_U32 sel_vpt :1; + CBIOS_U32 sel_mxu :1; + CBIOS_U32 TLR_MMIO_HDAD :1; + CBIOS_U32 MMIO_RW_BS :1; + CBIOS_U32 MMIO_REQ_BS :1; + CBIOS_U32 Reserved :18; + }; + CBIOS_U32 Value; +}REG_CR24_CR27_C_100; + + +typedef union _REG_CR24_CR27_C_101 //BIU_CIF_VGAIFX_Debug_Register_DWord +{ + struct + { + CBIOS_U32 VGAIFX_state_machine_Status :3; + CBIOS_U32 VGA_RW_BS :1; + CBIOS_U32 VGA_REQ_IFX :1; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 Reserved_1 :8; + CBIOS_U32 Reserved_2 :8; + CBIOS_U32 Reserved_3 :8; + }; + CBIOS_U32 Value; +}REG_CR24_CR27_C_101; + + +typedef union _REG_CR24_CR27_C_110 //BIU_CIF_VGAMFX_Debug_Reserved_Register_Dword +{ + struct + { + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 Reserved_1 :8; + CBIOS_U32 Reserved_2 :8; + CBIOS_U32 Reserved_3 :8; + }; + CBIOS_U32 Value; +}REG_CR24_CR27_C_110; + + +typedef union _REG_CR24_CR27_C_111 //BIU_CIF_CBU2_Debug_Register_Dword +{ + struct + { + CBIOS_U32 Hardwared_to_01 :2; + CBIOS_U32 CBUFF_FULL :1; + CBIOS_U32 Hardwared_to_00 :2; + CBIOS_U32 CBUFF_EMPTY :1; + CBIOS_U32 Hardwared_to_000 :3; + CBIOS_U32 Cbu_Fifo_Upper_Threshold_Arrived :1; + CBIOS_U32 Cbu_Fifo_Lower_Threshold_Arrived :1; + CBIOS_U32 Hardwared_to_0000 :4; + CBIOS_U32 vptifx_State_Machine_Status :1; + CBIOS_U32 BIU_VPT_MASK :4; + CBIOS_U32 VPT_BIU_READ :1; + CBIOS_U32 BIU_VPT_REQ :1; + CBIOS_U32 CBUCMDFF_AV :1; + CBIOS_U32 CBUCMDFF_WE :1; + CBIOS_U32 Reserved :8; + }; + CBIOS_U32 Value; +}REG_CR24_CR27_C_111; + + +typedef union _REG_CR28_C //BIU_TLM_Underrun_Overrun_Debug_Register +{ + struct + { + CBIOS_U8 TLT_BF_Underrun :1; + CBIOS_U8 TLT_BF_Overrun :1; + CBIOS_U8 TLM_CPLQ_Underrun :1; + CBIOS_U8 TLM_CPLQ_Overrun :1; + CBIOS_U8 TLM_WDQ_Underrun :1; + CBIOS_U8 TLM_WDQ_Overrun :1; + CBIOS_U8 TLM_RREQQ_Underrun :1; + CBIOS_U8 TLM_RREQQ_Overrun :1; + }; + CBIOS_U8 Value; +}REG_CR28_C; + + +typedef union _REG_CR29_C //BIU_TLR_Debug_Register +{ + struct + { + CBIOS_U8 TLR_MEMW_BUSY :1; + CBIOS_U8 BIU_Frame_Buffer_FIFO_full :1; + CBIOS_U8 BIU_Frame_Buffer_FIFO_empty :1; + CBIOS_U8 BIU_MW_FIFO_empty :1; + CBIOS_U8 TLR_RDFF_empty :1; + CBIOS_U8 TLR_PHQ_empty :1; + CBIOS_U8 TLR_NPHQ_empty :1; + CBIOS_U8 TLR_FMTFF_full :1; + }; + CBIOS_U8 Value; +}REG_CR29_C; + + +typedef union _REG_CR2A_C //BIU_Status_Register +{ + struct + { + CBIOS_U8 TLM_busy :1; + CBIOS_U8 TLT_busy :1; + CBIOS_U8 TLR_busy :1; + CBIOS_U8 DLR_busy :1; + CBIOS_U8 DLT_busy :1; + CBIOS_U8 CBU_busy :1; + CBIOS_U8 BIU_CBU_Interface_Status :1; + CBIOS_U8 CFAIFX_busy :1; + }; + CBIOS_U8 Value; +}REG_CR2A_C; + + +typedef union _REG_CR2B_C //BIU_TLM_Error_Status_Register +{ + struct + { + CBIOS_U8 TLM_CPL_PLEN_ERR :1; + CBIOS_U8 TLM_CPL_TAG_ERR :1; + CBIOS_U8 TLM_CPL_ELEN_ERR :1; + CBIOS_U8 CBU2_BUSY :1; + CBIOS_U8 CBU2IFX_BUSY :1; + CBIOS_U8 Reserved :3; + }; + CBIOS_U8 Value; +}REG_CR2B_C; + + +typedef union _REG_CR2C_CR2F_C //BIU_Debug_Bus_Reserved_Register_Dword +{ + struct + { + CBIOS_U32 Reserved :32; + }; + CBIOS_U32 Value; +}REG_CR2C_CR2F_C; + + +typedef union _REG_CR40_C //Reserved +{ + struct + { + CBIOS_U8 Reserved :8; + }; + CBIOS_U8 Value; +}REG_CR40_C; + + +typedef union _REG_CR41_C //BIU_TLR_Event_Trigger_Register +{ + struct + { + CBIOS_U8 Generate_CPL_TLPt :1; + CBIOS_U8 Generate_CPLD_TLP :1; + CBIOS_U8 Reserved :6; + }; + CBIOS_U8 Value; +}REG_CR41_C; + + +typedef union _REG_CR42_C //Reserved +{ + struct + { + CBIOS_U8 Reserved :8; + }; + CBIOS_U8 Value; +}REG_CR42_C; + + +typedef union _REG_CR45_C //Reserved_1_Byte +{ + struct + { + CBIOS_U8 Reserved :8; + }; + CBIOS_U8 Value; +}REG_CR45_C; + + +typedef union _REG_CR46_C //BIU_MSG_Event_Trigger_Register +{ + struct + { + CBIOS_U8 force_send_ASSERT_DEASSERT_msg :1; + CBIOS_U8 force_send_correctable_err_message :1; + CBIOS_U8 force_send_nonfatal_err_message :1; + CBIOS_U8 force_send_fatal_err_message :1; + CBIOS_U8 Reserved :3; + CBIOS_U8 REG_MSG_TMODE :1; + }; + CBIOS_U8 Value; +}REG_CR46_C; + + +typedef union _REG_CR47_C //BIU_PMC_Event_Trigger_Register +{ + struct + { + CBIOS_U8 force_send_PM_enter_L23_DLLP :1; + CBIOS_U8 force_send_PM_enter_L1_DLLP :1; + CBIOS_U8 force_send_PM_ASPM_L1_DLLP :1; + CBIOS_U8 force_send_PME_TO_ACK_message :1; + CBIOS_U8 force_enter_to_TX_L0s :1; + CBIOS_U8 force_enter_to_TX_L0_RX_L0 :1; + CBIOS_U8 REG_PMC_TMODE_0 :1; + CBIOS_U8 REG_PMC_TMODE_1 :1; + }; + CBIOS_U8 Value; +}REG_CR47_C; + + +typedef union _REG_CR48_C //BIU_TLR_Control_1_Register +{ + struct + { + CBIOS_U8 Threshold_for_update_PH_credit :4; + CBIOS_U8 Reserved :3; + CBIOS_U8 PWHD_Timer_Enable :1; + }; + CBIOS_U8 Value; +}REG_CR48_C; + + +typedef union _REG_CR56_C //BIU_PCLK_Work_Mode_Select_Register +{ + struct + { + CBIOS_U8 Reserved :3; + CBIOS_U8 Pclk_Work_Mode_Select :1; + CBIOS_U8 RESERVED :4; + }; + CBIOS_U8 Value; +}REG_CR56_C; + + +typedef union _REG_CR5A_C //BIU_PMC_L1_Timer_7:0__Register +{ + struct + { + CBIOS_U8 TIMER_L1 :8; + }; + CBIOS_U8 Value; +}REG_CR5A_C; + + +typedef union _REG_CR5B_C //BIU_PMC_L1_Timer_11:8_Register +{ + struct + { + CBIOS_U8 TIMER_L1 :4; + CBIOS_U8 Reserved :4; + }; + CBIOS_U8 Value; +}REG_CR5B_C; + + +typedef union _REG_CR60_C //BIU_Correctable_Error_Status_Register +{ + struct + { + CBIOS_U8 receiver_err_Status :1; + CBIOS_U8 Reserved :3; + CBIOS_U8 replay_timer_time_out :1; + CBIOS_U8 replay_num_rollover :1; + CBIOS_U8 Bad_TLP :1; + CBIOS_U8 Bad_DLLP :1; + }; + CBIOS_U8 Value; +}REG_CR60_C; + + +typedef union _REG_CR61_C //BIU_Correctable_Error_Mask_Register +{ + struct + { + CBIOS_U8 Mask_of_receiver_err_Status :1; + CBIOS_U8 Reserved :3; + CBIOS_U8 Mask_of_timer_time_out :1; + CBIOS_U8 Mask_of_replay_num_rollover :1; + CBIOS_U8 Mask_of_Bad_TLP :1; + CBIOS_U8 Mask_of_Bad_DLLP :1; + }; + CBIOS_U8 Value; +}REG_CR61_C; + + +typedef union _REG_CR62_C //BIU_UNCorrectable_Error_Status_1_Register +{ + struct + { + CBIOS_U8 UNSUPPORTED_Completion :1; + CBIOS_U8 Data_Link_Protocol_Error :1; + CBIOS_U8 POISIONED_TLP :1; + CBIOS_U8 Flow_Control_Protocol_Error :1; + CBIOS_U8 Completion_Timeout :1; + CBIOS_U8 Completer_Abort :1; + CBIOS_U8 Unexpected_Completion :1; + CBIOS_U8 Receiver_Overflow_Error :1; + }; + CBIOS_U8 Value; +}REG_CR62_C; + + +typedef union _REG_CR63_C //BIU_UNCorrectable_Error_Status_2_Register +{ + struct + { + CBIOS_U8 unsupported_request_error :1; + CBIOS_U8 malformed_TLP :1; + CBIOS_U8 Reserved :6; + }; + CBIOS_U8 Value; +}REG_CR63_C; + + +typedef union _REG_CR64_C //BIU_UNCorrectable_Error_Mask_1_Register +{ + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 Data_link_protocol_error :1; + CBIOS_U8 poisioned_TLP :1; + CBIOS_U8 flow_control_protocol_error :1; + CBIOS_U8 completion_timeout :1; + CBIOS_U8 Reserved_1 :2; + CBIOS_U8 receiver_overflow_error :1; + }; + CBIOS_U8 Value; +}REG_CR64_C; + + +typedef union _REG_CR65_C //BIU_UNCorrectable_Error_Mask_2_Register +{ + struct + { + CBIOS_U8 unsupported_request_error :1; + CBIOS_U8 malformed_TLP :1; + CBIOS_U8 Reserved :6; + }; + CBIOS_U8 Value; +}REG_CR65_C; + + +typedef union _REG_CR69_C //BIU_Timer_for_Post_Write_Hang_Detection_Register +{ + struct + { + CBIOS_U8 Timer :8; + }; + CBIOS_U8 Value; +}REG_CR69_C; + + +typedef union _REG_CR6A_C //BIU_Timer_for_CSP_MMIO_Write_Hang_Detection_Register +{ + struct + { + CBIOS_U8 Timer :8; + }; + CBIOS_U8 Value; +}REG_CR6A_C; + + +typedef union _REG_CR6F_C //BIU_Boundary_Request_Split_Register +{ + struct + { + CBIOS_U8 Reserved :4; + CBIOS_U8 Reg_Tlm_Rd_Len_Cfg :2; + CBIOS_U8 _0 :1; + CBIOS_U8 _1 :1; + }; + CBIOS_U8 Value; +}REG_CR6F_C; + + +typedef union _REG_CR70_C //BIU_TLM_Control_1_Register +{ + struct + { + CBIOS_U8 Reserved_0 :3; + CBIOS_U8 REG_TLM_REQ_LIMIT_EN :1; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 REG_MULTI_MSI_EN :1; + CBIOS_U8 REG_TLB_HP :1; + CBIOS_U8 Reserved_bit7 :1; + }; + CBIOS_U8 Value; +}REG_CR70_C; + + +typedef union _REG_CR74_C //L0s_Recovery_Debug_Register +{ + struct + { + CBIOS_U8 Reserved_0 :3; + CBIOS_U8 BIU_MXU_Priority_Control :1; + CBIOS_U8 Reserved_1 :4; + }; + CBIOS_U8 Value; +}REG_CR74_C; + + +typedef union _REG_CR75_C_CR76_C //Reserved_2_Bytes +{ + struct + { + CBIOS_U8 Reserved :8; + }; + CBIOS_U8 Value; +}REG_CR75_C_CR76_C; + + +typedef union _REG_CR77_C //Reserved_1_Byte +{ + struct + { + CBIOS_U8 Reserved :8; + }; + CBIOS_U8 Value; +}REG_CR77_C; + + +typedef union _REG_CR78_C_CR7A_C //Reserved_3_Bytes +{ + struct + { + CBIOS_U8 Reserved :8; + }; + CBIOS_U8 Value; +}REG_CR78_C_CR7A_C; + + +typedef union _REG_CR7D_C //Dynamic_Clock_Management_Control_Register +{ + struct + { + CBIOS_U8 REG_DYN_CLK_EN :1; + CBIOS_U8 REG_GFX_BUSY_EN :1; + CBIOS_U8 Reserved_3to2 :2; + CBIOS_U8 Reg_Gfx_Busy :1; + CBIOS_U8 Reserved_7to5 :3; + }; + CBIOS_U8 Value; +}REG_CR7D_C; + + +typedef union _REG_CR7E_C //Dynamic_Clock_Management_Timer_7:0_Register +{ + struct + { + CBIOS_U8 Reg_Dynamic_Clk_Close_Timer_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR7E_C; + + +typedef union _REG_CR7F_C //Dynamic_Clock_Management_Timer_15:8_Register +{ + struct + { + CBIOS_U8 Reg_Dynamic_Clk_Close_Timer_15to8 :8; + }; + CBIOS_U8 Value; +}REG_CR7F_C; + + +typedef union _REG_CR80_C //Device_ID_High_Register +{ + struct + { + CBIOS_U8 Chip_ID_15to8 :8; + }; + CBIOS_U8 Value; +}REG_CR80_C; + + +typedef union _REG_CR81_C //Device_ID_Low_Register +{ + struct + { + CBIOS_U8 Chip_ID_4to0 :5; + CBIOS_U8 Chip_ID_7to5 :3; + }; + CBIOS_U8 Value; +}REG_CR81_C; + + +typedef union _REG_CR82_C //Revision_ID_Register +{ + struct + { + CBIOS_U8 Revision_ID :8; + }; + CBIOS_U8 Value; +}REG_CR82_C; + + +typedef union _REG_CR83_C //Chip_ID/Revision_Register +{ + struct + { + CBIOS_U8 REVISION_Status :4; + CBIOS_U8 Chip_ID :4; + }; + CBIOS_U8 Value; +}REG_CR83_C; + + +typedef union _REG_CR84_C //PCI_Subsystem_Vendor_ID_Shadow_Low_Register +{ + struct + { + CBIOS_U8 PCI_SUBSYS_Vendor_ID :8; + }; + CBIOS_U8 Value; +}REG_CR84_C; + + +typedef union _REG_CR85_C //PCI_Subsystem_Vendor_ID_Shadow_High_Register +{ + struct + { + CBIOS_U8 PCI_SUBSYS_Vendor_ID :8; + }; + CBIOS_U8 Value; +}REG_CR85_C; + + +typedef union _REG_CR86_C //PCI_Subsystem_ID_Shadow_Low_Register +{ + struct + { + CBIOS_U8 PCI_SUBSYS_ID :8; + }; + CBIOS_U8 Value; +}REG_CR86_C; + + +typedef union _REG_CR87_C //PCI_Subsystem_ID_Shadow_High_Register +{ + struct + { + CBIOS_U8 PCI_SUBSYS_ID :8; + }; + CBIOS_U8 Value; +}REG_CR87_C; + + +typedef union _REG_CR88_C //Subsystem_ID_Register +{ + struct + { + CBIOS_U8 SSID_Func0 :4; + CBIOS_U8 SSID_Func1 :4; + }; + CBIOS_U8 Value; +}REG_CR88_C; + + +typedef union _REG_CR8A_C //MMIO_Address_Window_Position_Register +{ + struct + { + CBIOS_U8 Reserved :3; + CBIOS_U8 MMIO_Address_Window_position :5; + }; + CBIOS_U8 Value; +}REG_CR8A_C; + + +typedef union _REG_CR8B_C //MMIO_Address_Window_Position_Register_2 +{ + struct + { + CBIOS_U8 MMIO_Address_Window_position :8; + }; + CBIOS_U8 Value; +}REG_CR8B_C; + + +typedef union _REG_CR90_C //Linear_Address_Window_Position_1_Register +{ + struct + { + CBIOS_U8 Reserved :2; + CBIOS_U8 La_Window_Position_Bit28to26 :3; + CBIOS_U8 LA_Window_position_31to29 :3; + }; + CBIOS_U8 Value; +}REG_CR90_C; + + +typedef union _REG_CR91_C //Linear_Address_Window_Position_2_Register +{ + struct + { + CBIOS_U8 LA_Window_position :8; + }; + CBIOS_U8 Value; +}REG_CR91_C; + + +typedef union _REG_CR92_C //Linear_Address_Window_Position_3_Register +{ + struct + { + CBIOS_U8 LA_Window_position :8; + }; + CBIOS_U8 Value; +}REG_CR92_C; + + +typedef union _REG_CR93_C //Linear_Address_Window_Position_4_Register +{ + struct + { + CBIOS_U8 LA_Window_position :8; + }; + CBIOS_U8 Value; +}REG_CR93_C; + + +typedef union _REG_CR94_C //Linear_Address_Window_Position_5_Register +{ + struct + { + CBIOS_U8 LA_Window_position :8; + }; + CBIOS_U8 Value; +}REG_CR94_C; + + +typedef union _REG_CR98_C //PCI_Function1_Subsystem_Vendor_ID_Low_Shadow_Register +{ + struct + { + CBIOS_U8 SSVID_Low_Shadow_Func1 :8; + }; + CBIOS_U8 Value; +}REG_CR98_C; + + +typedef union _REG_CR99_C //PCI_Function1_Subsystem_Vendor_ID_High_Shadow_Register +{ + struct + { + CBIOS_U8 SSVID_High_Shadow_Func1 :8; + }; + CBIOS_U8 Value; +}REG_CR99_C; + + +typedef union _REG_CR9A_C //PCI_Function1_Subsystem_ID_Low_Shadow_Register +{ + struct + { + CBIOS_U8 SSID_Low_Shadow_Func1 :8; + }; + CBIOS_U8 Value; +}REG_CR9A_C; + + +typedef union _REG_CR9B_C //PCI_Function1_Subsystem_ID_High_Shadow_Register +{ + struct + { + CBIOS_U8 SSID_High_Shadow_Func1 :8; + }; + CBIOS_U8 Value; +}REG_CR9B_C; + + +typedef union _REG_CR9C_C //Error_Status_Cross_Check_Disable_Register +{ + struct + { + CBIOS_U8 ERR_STATUS_CROSS_CHECK_DIS :1; + CBIOS_U8 Reserved_bits7to1 :7; + }; + CBIOS_U8 Value; +}REG_CR9C_C; + + +typedef union _REG_CR9D_C //BIU_Internal_Test_Register_1 +{ + struct + { + CBIOS_U8 PACK_Enable :1; + CBIOS_U8 Reserved_0 :2; + CBIOS_U8 MMIO_read_async_enable :1; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 Reserved_2 :3; + }; + CBIOS_U8 Value; +}REG_CR9D_C; + + +typedef union _REG_CR9E_C //BIU_Internal_Test_Register_2 +{ + struct + { + CBIOS_U8 _5_Bit_PACK_timer :5; + CBIOS_U8 Reserved :3; + }; + CBIOS_U8 Value; +}REG_CR9E_C; + + +typedef union _REG_CRA0_C //BIU_Control_1_Register +{ + struct + { + CBIOS_U8 Interrupt_Enable :1; + CBIOS_U8 MMIO_Enable :1; + CBIOS_U8 Old_MMIO_Window :1; + CBIOS_U8 VGA_Memory_access_disable :1; + CBIOS_U8 Enable_Linear_Addressing :1; + CBIOS_U8 Reserved :3; + }; + CBIOS_U8 Value; +}REG_CRA0_C; + + +typedef union _REG_CRA1_C //BIU_Shadow_Update_Control_Register +{ + struct + { + CBIOS_U8 REG_OUTFB_UREN :1; + CBIOS_U8 Reserved :3; + CBIOS_U8 Shadow_Update :1; + CBIOS_U8 REG_FBSIZE_EXIST :3; + }; + CBIOS_U8 Value; +}REG_CRA1_C; + + +typedef union _REG_CRA2_C //Software_Reset_0_Register +{ + struct + { + CBIOS_U8 PCI_interrupt :1; + CBIOS_U8 Reserved :7; + }; + CBIOS_U8 Value; +}REG_CRA2_C; + + +typedef union _REG_CRA3_C //Software_Reset_1_Register +{ + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 Reserved_2 :1; + CBIOS_U8 Reserved_3 :1; + CBIOS_U8 Reserved_4 :1; + CBIOS_U8 Reserved_5 :1; + CBIOS_U8 TV_Unit_Software_Reset :1; + CBIOS_U8 Chip_reset_except_PCI_config_space :1; + }; + CBIOS_U8 Value; +}REG_CRA3_C; + + +typedef union _REG_CRA4_C //Software_Reset_2_Register +{ + struct + { + CBIOS_U8 Reserved_0 :5; + CBIOS_U8 MDI_software_reset :1; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 _3D_Engine_Software_Reset :1; + }; + CBIOS_U8 Value; +}REG_CRA4_C; + + +typedef union _REG_CRA5_C //Software_Reset_3_Register +{ + struct + { + CBIOS_U8 Reserved_0 :4; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 Reserved_2 :1; + CBIOS_U8 Reserved_3 :1; + CBIOS_U8 SLV_Software_Reset :1; + }; + CBIOS_U8 Value; +}REG_CRA5_C; + + +typedef union _REG_CRA6_C //Software_Reset_4_Register +{ + struct + { + CBIOS_U8 TLM_Software_Reset :1; + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 Reserved_2 :1; + CBIOS_U8 TLR_Software_Reset :1; + CBIOS_U8 Reserved_3 :1; + CBIOS_U8 PMC_Software_Reset :1; + CBIOS_U8 MSG_Software_Reset :1; + }; + CBIOS_U8 Value; +}REG_CRA6_C; + + +typedef union _REG_CRA8_C //BIU_Power_Management_1_Register +{ + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 TLR_Power_Management_On :1; + CBIOS_U8 BIU_Power_Management_On :1; + CBIOS_U8 Reserved_2 :1; + CBIOS_U8 Wait_until_CPL_back_then_enter_L1_or_L3 :1; + CBIOS_U8 PCI_Memory_IO_cycle_PM_Disable :1; + CBIOS_U8 Chip_Power_Management :1; + }; + CBIOS_U8 Value; +}REG_CRA8_C; + + +typedef union _REG_CRA9_C //BIU_Power_Management_2_Register +{ + struct + { + CBIOS_U8 when_receiving_PME_TURN_OFF :1; + CBIOS_U8 REG_PMC_BLKTLP_EN :1; + CBIOS_U8 REG_ASPML1_ONLY :1; + CBIOS_U8 Reserved :5; + }; + CBIOS_U8 Value; +}REG_CRA9_C; + + +typedef union _REG_CRAA_C //BIU_Power_Management_3_Register +{ + struct + { + CBIOS_U8 receiving_PME_TURN_OFF :8; + }; + CBIOS_U8 Value; +}REG_CRAA_C; + + +typedef union _REG_CRAB_C //BIU_Reset_Mode_Register +{ + struct + { + CBIOS_U8 BIU_RESET_MODE :1; + CBIOS_U8 BIU_ECLK_RESET_MODE :1; + CBIOS_U8 Reserved :6; + }; + CBIOS_U8 Value; +}REG_CRAB_C; + + +typedef union _REG_CRAC_C //BIU-MXU_Request_Priority_Assertion_Register +{ + struct + { + CBIOS_U8 Assert_BIU_MXU_Request :1; + CBIOS_U8 Reserved :7; + }; + CBIOS_U8 Value; +}REG_CRAC_C; + + +typedef union _REG_CRAD_C //BIU_CSP_PW_REGISTER +{ + struct + { + CBIOS_U8 BIU_CSP_PW_EN :8; + }; + CBIOS_U8 Value; +}REG_CRAD_C; + + +typedef union _REG_CRAE_C //BIU_BACKDOOR_ENABLE_REGISTER +{ + struct + { + CBIOS_U8 backdoor_enable :1; + CBIOS_U8 c4p_enable :1; + CBIOS_U8 Reserved :6; + }; + CBIOS_U8 Value; +}REG_CRAE_C; + + +typedef union _REG_CRAF_C //C4P_timer +{ + struct + { + CBIOS_U8 C4P_timer_7_0 :8; + }; + CBIOS_U8 Value; +}REG_CRAF_C; + + +typedef union _REG_CRB0_C //BIU_BACKDOOR__REGISTER1 +{ + struct + { + CBIOS_U8 Backdoor_Vendor_ID_7_0 :8; + }; + CBIOS_U8 Value; +}REG_CRB0_C; + + +typedef union _REG_CRB1_C //BIU_BACKDOOR__REGISTER2 +{ + struct + { + CBIOS_U8 Backdoor_Vendor_ID_15_8 :8; + }; + CBIOS_U8 Value; +}REG_CRB1_C; + + +typedef union _REG_CRB2_C //BIU_BACKDOOR__REGISTER3 +{ + struct + { + CBIOS_U8 Backdoor_Device_ID_7_0 :8; + }; + CBIOS_U8 Value; +}REG_CRB2_C; + + +typedef union _REG_CRB3_C //BIU_BACKDOOR__REGISTER4 +{ + struct + { + CBIOS_U8 Backdoor_Device_ID_15_8 :8; + }; + CBIOS_U8 Value; +}REG_CRB3_C; + + +typedef union _REG_CRB4_C //Software_Reset_5_Register +{ + struct + { + CBIOS_U8 CSP_Software_Reset :1; + CBIOS_U8 CNM_software_Reset :1; + CBIOS_U8 S3VD_Software_Reset :1; + CBIOS_U8 S0TU_Software_Reset :1; + CBIOS_U8 S0EUC_Software_Reset :1; + CBIOS_U8 MXU_Software_Reset :1; + CBIOS_U8 S0FFU_Software_Reset :1; + CBIOS_U8 SLRZ1_Software_Reset :1; + }; + CBIOS_U8 Value; +}REG_CRB4_C; + + +typedef union _REG_CRB5_C //Software_Reset_6_Register +{ + struct + { + CBIOS_U8 S0PECTL_Software_Reset :1; + CBIOS_U8 S0PEALU_software_Reset :1; + CBIOS_U8 Reserved :6; + }; + CBIOS_U8 Value; +}REG_CRB5_C; + + +typedef union _REG_CRC0_C //Process_Monitor_Counter_[7:0]_Register +{ + struct + { + CBIOS_U8 Process_Monitor_Counter :8; + }; + CBIOS_U8 Value; +}REG_CRC0_C; + + +typedef union _REG_CRC1_C //Process_Monitor_Counter_[15:8]_Register +{ + struct + { + CBIOS_U8 Process_Monitor_Counter :8; + }; + CBIOS_U8 Value; +}REG_CRC1_C; + + +typedef union _REG_CRC2_C //Process_Monitor_Counter_Control_Register +{ + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 Process_Monitor_Counter_Enable :1; + CBIOS_U8 Sample_clock_Selection :1; + CBIOS_U8 clock_Division_Select :3; + CBIOS_U8 Reserved_1 :2; + }; + CBIOS_U8 Value; +}REG_CRC2_C; + + +typedef union _REG_CRC3_C //Preset_Engine_Idle_7:4_Register +{ + struct + { + CBIOS_U8 Reserved :4; + CBIOS_U8 Preset_Engine_Idle_Cntr_7to4 :4; + }; + CBIOS_U8 Value; +}REG_CRC3_C; + + +typedef union _REG_CRC4_C //Preset_Engine_Idle_15:8_Register +{ + struct + { + CBIOS_U8 Preset_Engine_Idle_Cntr :8; + }; + CBIOS_U8 Value; +}REG_CRC4_C; + + +typedef union _REG_CRC6_C //Read_Back_Current_Engine_Idle_Counter_[7:0]_Register +{ + struct + { + CBIOS_U8 Current_Engine_Idle_Cntr :8; + }; + CBIOS_U8 Value; +}REG_CRC6_C; + + +typedef union _REG_CRC7_C //Read_Back_Current_Engine_Idle_Counter_[15:8]_Register +{ + struct + { + CBIOS_U8 Current_Engine_Idle_Cntr :8; + }; + CBIOS_U8 Value; +}REG_CRC7_C; + + +typedef union _REG_CRC9_C //Preset_Chip_Idle_7:4_Register +{ + struct + { + CBIOS_U8 Reserved :4; + CBIOS_U8 Preset_Chip_Idle_Cntr :4; + }; + CBIOS_U8 Value; +}REG_CRC9_C; + + +typedef union _REG_CRCA_C //Preset_Chip_Idle_15:8_Register +{ + struct + { + CBIOS_U8 Preset_Chip_Idle_Cntr :8; + }; + CBIOS_U8 Value; +}REG_CRCA_C; + + +typedef union _REG_CRD7_C //Swizzle_Control_Register +{ + struct + { + CBIOS_U8 swizzle_disable :1; + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 Reserved_2 :1; + CBIOS_U8 Reserved_bit_4 :1; + CBIOS_U8 Reserved_7to5 :3; + }; + CBIOS_U8 Value; +}REG_CRD7_C; + + +typedef union _REG_CRDD_C //Role-Based_Error_Report_Enable_Register +{ + struct + { + CBIOS_U8 RBE_EN :1; + CBIOS_U8 Reserved :7; + }; + CBIOS_U8 Value; +}REG_CRDD_C; + + +typedef union _REG_CREF_C //Physical_Layer_Debug_2_Register +{ + struct + { + CBIOS_U8 Reserved_0 :2; + CBIOS_U8 Reserved_1 :5; + CBIOS_U8 DIU_BIU_PLL_LOCK :1; + }; + CBIOS_U8 Value; +}REG_CREF_C; + + +typedef union _REG_CRF0_C //Power_On_Strapping_1_Register +{ + struct + { + CBIOS_U8 Hdad_Enable :1; + CBIOS_U8 Pm_D1d2_Dis :1; + CBIOS_U8 Reserved :6; + }; + CBIOS_U8 Value; +}REG_CRF0_C; + + +typedef union _REG_CRF2_C //BIU_DBG_Software_Reset_Mask_Register +{ + struct + { + CBIOS_U8 REG_MASK_RST :1; + CBIOS_U8 RESERVED :7; + }; + CBIOS_U8 Value; +}REG_CRF2_C; + +typedef union _REG_CRF5_C //BIU_DBG_Software_Reset_Mask_Register +{ + struct + { + CBIOS_U8 EPLL_HW_LOAD :1; + CBIOS_U8 IPLL_HW_LOAD :1; + CBIOS_U8 VPLL_HW_LOAD :1; + CBIOS_U8 RESERVED :5; + }; + CBIOS_U8 Value; +}REG_CRF5_C; + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_HDA_registers.h b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_HDA_registers.h new file mode 100644 index 0000000000000..fb307906d403a --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_HDA_registers.h @@ -0,0 +1,504 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +typedef union _REG_Global_Caps //HDA_Global_Capabilities_Register +{ + struct + { + CBIOS_U32 _64OK :1; + CBIOS_U32 NSS :2; + CBIOS_U32 BSS :5; + CBIOS_U32 ISS :4; + CBIOS_U32 OSS :4; + CBIOS_U32 Minor_Version :8; + CBIOS_U32 Major_Version :8; + }; + CBIOS_U32 Value; +}REG_Global_Caps; + + +typedef union _REG_Total_Payload_Capacity //HDA_Total_Payload_Capacity_Register +{ + struct + { + CBIOS_U32 Out_Pay :16; + CBIOS_U32 In_Pay :16; + }; + CBIOS_U32 Value; +}REG_Total_Payload_Capacity; + + +typedef union _REG_GLOBAL_CONTROL //HDA__Global_Control_Register +{ + struct + { + CBIOS_U32 CRST :1; + CBIOS_U32 FCNTRL :1; + CBIOS_U32 Reserved_0 :6; + CBIOS_U32 UNSOL :1; + CBIOS_U32 Reserved_1 :23; + }; + CBIOS_U32 Value; +}REG_GLOBAL_CONTROL; + + +typedef union _REG_WAKEN //HDA_Wake_Enable_&_State_Change_Status_Register +{ + struct + { + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 SDIWEN_1 :1; + CBIOS_U32 SDIWEN_2 :1; + CBIOS_U32 Reserved_1 :14; + CBIOS_U32 STATESTS_1 :1; + CBIOS_U32 STATESTS_2 :1; + CBIOS_U32 Reserved_3 :12; + CBIOS_U32 Undefined_Bit_31_to_31 :1; + }; + CBIOS_U32 Value; +}REG_WAKEN; + + +typedef union _REG_GLOBAL_STS //HDA_Global_Status_Register +{ + struct + { + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 FSTS :1; + CBIOS_U32 Reserved_1 :30; + }; + CBIOS_U32 Value; +}REG_GLOBAL_STS; + + +typedef union _REG_Stream_Payload_Capacity //HDA_Stream_Payload_Capacity_Register +{ + struct + { + CBIOS_U32 Out_Strm_Pay :16; + CBIOS_U32 In_Strm_Pay :16; + }; + CBIOS_U32 Value; +}REG_Stream_Payload_Capacity; + + +typedef union _REG_INTERRUPT_CONTROL //HDA_Interrupt_Control_Register +{ + struct + { + CBIOS_U32 SIE_0 :1; + CBIOS_U32 SIE_1 :1; + CBIOS_U32 Reserved_0 :28; + CBIOS_U32 CIE :1; + CBIOS_U32 GIE :1; + }; + CBIOS_U32 Value; +}REG_INTERRUPT_CONTROL; + + +typedef union _REG_INTERRUPT_STATUS //HDA_Interrupt_Status_Register +{ + struct + { + CBIOS_U32 SIS_0 :1; + CBIOS_U32 SIS_1 :1; + CBIOS_U32 Reserved_0 :28; + CBIOS_U32 CIS :1; + CBIOS_U32 GIS :1; + }; + CBIOS_U32 Value; +}REG_INTERRUPT_STATUS; + + +typedef union _REG_WALL_CLK_CTR //HDA_Wall_Clock_Counter_Register +{ + struct + { + CBIOS_U32 Counter :32; + }; + CBIOS_U32 Value; +}REG_WALL_CLK_CTR; + + +typedef union _REG_STREAM_SYNC //HDA_Stream_Synchronization_Register +{ + struct + { + CBIOS_U32 S0_SYNC :1; + CBIOS_U32 S1_SYNC :1; + CBIOS_U32 Reserved :30; + }; + CBIOS_U32 Value; +}REG_STREAM_SYNC; + + +typedef union _REG_CORB_LOW_ADDR //HDA_CORB_Base_Address_Low_Register +{ + struct + { + CBIOS_U32 CORB_LBASE_6to0 :7; + CBIOS_U32 CORB_LBASE_31to7 :25; + }; + CBIOS_U32 Value; +}REG_CORB_LOW_ADDR; + + +typedef union _REG_CORB_UPPER_ADDR //HDA_CORB_Base_Address_High_Register +{ + struct + { + CBIOS_U32 CORB_UPPER_ADDR_39to32 :8; + CBIOS_U32 RESERVED :24; + }; + CBIOS_U32 Value; +}REG_CORB_UPPER_ADDR; + + +typedef union _REG_CORB_RW_POINTER //HDA_CORB_Read_Write_Pointer_Register +{ + struct + { + CBIOS_U32 CORBWP :8; + CBIOS_U32 RESERVED_0 :8; + CBIOS_U32 CORBRP :8; + CBIOS_U32 RESERVED_1 :7; + CBIOS_U32 CORBRPRST :1; + }; + CBIOS_U32 Value; +}REG_CORB_RW_POINTER; + + +typedef union _REG_CORB_CTRL //HDA_CORB_Control_Register +{ + struct + { + CBIOS_U32 CMEIE :1; + CBIOS_U32 CORBRUN :1; + CBIOS_U32 RESERVED_0 :6; + CBIOS_U32 CMEI :1; + CBIOS_U32 RESERVED_1 :7; + CBIOS_U32 CORBSIZE :2; + CBIOS_U32 RESERVED_2 :2; + CBIOS_U32 CORBSZCAP :4; + CBIOS_U32 RESERVED_3 :8; + }; + CBIOS_U32 Value; +}REG_CORB_CTRL; + + +typedef union _REG_RIRB_LOW_ADDR //HDA_RIRB_Base_Address_Low_Register +{ + struct + { + CBIOS_U32 RIRB_LBASE_6to0 :7; + CBIOS_U32 RIRB_LBASE_31to7 :25; + }; + CBIOS_U32 Value; +}REG_RIRB_LOW_ADDR; + + +typedef union _REG_RIRB_UPPER_ADDR //HDA_RIRB_Base_Address_High_Register +{ + struct + { + CBIOS_U32 RIRB_UPPER_ADDR_39to32 :8; + CBIOS_U32 RESERVED :24; + }; + CBIOS_U32 Value; +}REG_RIRB_UPPER_ADDR; + + +typedef union _REG_RIRB_WP_RESP_INT //HDA_RIRB_Write_Pointer_and_Response_Interrupt_Register +{ + struct + { + CBIOS_U32 RIRBWP :8; + CBIOS_U32 RESERVED_0 :7; + CBIOS_U32 RIRBWPRST :1; + CBIOS_U32 RINTCNT :8; + CBIOS_U32 RESERVED_1 :7; + CBIOS_U32 Undefined_Bit_31_to_31 :1; + }; + CBIOS_U32 Value; +}REG_RIRB_WP_RESP_INT; + + +typedef union _REG_RIRB_CTRL //HDA_RIRB_Control_Register +{ + struct + { + CBIOS_U32 RINTCTL :1; + CBIOS_U32 RIRBDMAEN :1; + CBIOS_U32 RIRBOIC :1; + CBIOS_U32 RESERVED_0 :6; + CBIOS_U32 RINTFL :1; + CBIOS_U32 RESERVED_1 :1; + CBIOS_U32 RINTOIS :1; + CBIOS_U32 RESERVED_2 :4; + CBIOS_U32 RIRBSIZE :2; + CBIOS_U32 RESERVED_3 :2; + CBIOS_U32 RIRBSZCAP :4; + CBIOS_U32 RESERVED_4 :8; + }; + CBIOS_U32 Value; +}REG_RIRB_CTRL; + + +typedef union _REG_IM_CMD_OUT_INTERFACE //HDA_Immediate_Command_Output_Interface_Register +{ + struct + { + CBIOS_U32 ICW :32; + }; + CBIOS_U32 Value; +}REG_IM_CMD_OUT_INTERFACE; + + +typedef union _REG_IM_RESP_INPUT_INTERFACE //HDA_Immediate_Response_Input_Interface_Register +{ + struct + { + CBIOS_U32 IRR :32; + }; + CBIOS_U32 Value; +}REG_IM_RESP_INPUT_INTERFACE; + + +typedef union _REG_IM_CMD_STATUS //HDA_Immediate_Command_Status_Register +{ + struct + { + CBIOS_U32 ICB :1; + CBIOS_U32 IRV :1; + CBIOS_U32 RESERVED_0 :2; + CBIOS_U32 IRRADD :4; + CBIOS_U32 RESERVED_1 :24; + }; + CBIOS_U32 Value; +}REG_IM_CMD_STATUS; + + +typedef union _REG_OS0_DESC_CTRL //HDA_Output_Stream_0_Descriptor_Control_Register +{ + struct + { + CBIOS_U32 SRST :1; + CBIOS_U32 STRM_RUN :1; + CBIOS_U32 IOCE :1; + CBIOS_U32 FEIE :1; + CBIOS_U32 DEIE :1; + CBIOS_U32 RESERVED :11; + CBIOS_U32 STRIPE :2; + CBIOS_U32 TP :1; + CBIOS_U32 DIR :1; + CBIOS_U32 STRM_NUM :4; + CBIOS_U32 RESERVED_2 :2; + CBIOS_U32 BCIS :1; + CBIOS_U32 FIFOE :1; + CBIOS_U32 DESE :1; + CBIOS_U32 FIFORDY :1; + CBIOS_U32 RESERVED_31to30 :2; + }; + CBIOS_U32 Value; +}REG_OS0_DESC_CTRL; + + +typedef union _REG_OS0_DESC_LINK_POS //HDA_Output_Stream_0_Descriptor_Link_Position_Register +{ + struct + { + CBIOS_U32 LPIB :32; + }; + CBIOS_U32 Value; +}REG_OS0_DESC_LINK_POS; + + +typedef union _REG_OS0_DESC_CBL //HDA_Output_Stream_0_Descriptor_Cycle_Buffer_Length_Register +{ + struct + { + CBIOS_U32 CBL :32; + }; + CBIOS_U32 Value; +}REG_OS0_DESC_CBL; + + +typedef union _REG_OS0_DESC_LVI //HDA_Output_Stream_0_Descriptor_Last_Valid_Index_Register +{ + struct + { + CBIOS_U32 LVI :8; + CBIOS_U32 RESERVED :24; + }; + CBIOS_U32 Value; +}REG_OS0_DESC_LVI; + + +typedef union _REG_OS0_DESC_FIFO_DESC //HDA_Output_Stream_0_Descriptor_FIFO_Description_Register +{ + struct + { + CBIOS_U32 FIFO_SIZE :8; + CBIOS_U32 RESERVED :8; + CBIOS_U32 CHAN :4; + CBIOS_U32 BITS :3; + CBIOS_U32 RESERVED_23 :1; + CBIOS_U32 DIV :3; + CBIOS_U32 MULT :3; + CBIOS_U32 BASE :1; + CBIOS_U32 RESERVED_31to30 :1; + }; + CBIOS_U32 Value; +}REG_OS0_DESC_FIFO_DESC; + + +typedef union _REG_OS0_BDL_LOW_ADDR //HDA_Stream_0_BDL_Base_Address_Low_Register +{ + struct + { + CBIOS_U32 BDL_LBASE_6to0 :7; + CBIOS_U32 BDL_LBASE_31to7 :25; + }; + CBIOS_U32 Value; +}REG_OS0_BDL_LOW_ADDR; + + +typedef union _REG_OS0_BDL_UPPER_ADDR //HDA_Stream_0_BDL_Base_Address_High_Register +{ + struct + { + CBIOS_U32 BDL_UPPER_ADDR_39to32 :8; + CBIOS_U32 RESERVED :24; + }; + CBIOS_U32 Value; +}REG_OS0_BDL_UPPER_ADDR; + + +typedef union _REG_OS1_DESC_CTRL //HDA_Output_Stream_1_Descriptor_Control_Register +{ + struct + { + CBIOS_U32 SRST :1; + CBIOS_U32 STRM_RUN :1; + CBIOS_U32 IOCE :1; + CBIOS_U32 FEIE :1; + CBIOS_U32 DEIE :1; + CBIOS_U32 RESERVED :11; + CBIOS_U32 STRIPE :2; + CBIOS_U32 TP :1; + CBIOS_U32 DIR :1; + CBIOS_U32 STRM_NUM :4; + CBIOS_U32 RESERVED_2 :2; + CBIOS_U32 BCIS :1; + CBIOS_U32 FIFOE :1; + CBIOS_U32 DESE :1; + CBIOS_U32 FIFORDY :1; + CBIOS_U32 RESERVED_31to30 :2; + }; + CBIOS_U32 Value; +}REG_OS1_DESC_CTRL; + + +typedef union _REG_OS1_DESC_LINK_POS //HDA_Output_Stream_1_Descriptor_Link_Position_Register +{ + struct + { + CBIOS_U32 LPIB :32; + }; + CBIOS_U32 Value; +}REG_OS1_DESC_LINK_POS; + + +typedef union _REG_OS1_DESC_CBL //HDA_Output_Stream_1_Descriptor_Cycle_Buffer_Length_Register +{ + struct + { + CBIOS_U32 CBL :32; + }; + CBIOS_U32 Value; +}REG_OS1_DESC_CBL; + + +typedef union _REG_OS1_DESC_LVI //HDA_Output_Stream_1_Descriptor_Last_Valid_Index_Register +{ + struct + { + CBIOS_U32 LVI :8; + CBIOS_U32 RESERVED :24; + }; + CBIOS_U32 Value; +}REG_OS1_DESC_LVI; + + +typedef union _REG_OS1_DESC_FIFO_DESC //HDA_Output_Stream_1_Descriptor_FIFO_Description_Register +{ + struct + { + CBIOS_U32 FIFO_SIZE :8; + CBIOS_U32 RESERVED :8; + CBIOS_U32 CHAN :4; + CBIOS_U32 BITS :3; + CBIOS_U32 RESERVED_23 :1; + CBIOS_U32 DIV :3; + CBIOS_U32 MULT :3; + CBIOS_U32 BASE :1; + CBIOS_U32 RESERVED_31to30 :1; + }; + CBIOS_U32 Value; +}REG_OS1_DESC_FIFO_DESC; + + +typedef union _REG_OS1_BDL_LOW_ADDR //HDA_Stream_1_BDL_Base_Address_Low_Register +{ + struct + { + CBIOS_U32 BDL_LBASE_6to0 :7; + CBIOS_U32 BDL_LBASE_31to7 :25; + }; + CBIOS_U32 Value; +}REG_OS1_BDL_LOW_ADDR; + + +typedef union _REG_OS1_BDL_UPPER_ADDR //HDA_Stream_1_BDL_Base_Address_High_Register +{ + struct + { + CBIOS_U32 BDL_UPPER_ADDR_39to32 :8; + CBIOS_U32 RESERVED :24; + }; + CBIOS_U32 Value; +}REG_OS1_BDL_UPPER_ADDR; + + +typedef union _REG_WALL_CLK_CTR_ALIAS //HDA_Wall_Clock_Counter_Alias_Register +{ + struct + { + CBIOS_U32 Counter :32; + }; + CBIOS_U32 Value; +}REG_WALL_CLK_CTR_ALIAS; + + +typedef union _REG_OS0_LINK_POS_ALIAS //HDA_Output_Stream_0_Descriptor_Link_Position_Alias_Register +{ + struct + { + CBIOS_U32 LPIB :32; + }; + CBIOS_U32 Value; +}REG_OS0_LINK_POS_ALIAS; + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_MM_registers.h b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_MM_registers.h new file mode 100644 index 0000000000000..bd0fe51b62fda --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_MM_registers.h @@ -0,0 +1,273 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + + +typedef union _REG_MM9340 //GRX_Frame_Buffer_Base_Address_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 GFX_FB_BASE_ADDR :12; + CBIOS_U32 Reserved :20; + }; +}REG_MM9340; + + +typedef union _REG_MM9344 //INT_USS_Address_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 INT_USS_ADDR_31to0 :32; + }; +}REG_MM9344; + + +typedef union _REG_MM9348 //INT_USS_Address_High_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 INT_USS_ADDR_63to32 :32; + }; +}REG_MM9348; + + +typedef union _REG_MM934C //INT_USS_Data_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 INT_USS_DATA_31to0 :32; + }; +}REG_MM934C; + + +typedef union _REG_MM9350 //INT_USS_Data_High_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 INT_USS_DATA_63to32 :32; + }; +}REG_MM9350; + + +typedef union _REG_MM9358 //BIU_MXU_Subindex_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :7; + CBIOS_U32 BIU_MXU_SUBINDEX_EN :1; + CBIOS_U32 RESERVED :24; + }; +}REG_MM9358; + + +typedef union _REG_MM935C //CLK_select_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 ICLK_SEL :2; + CBIOS_U32 SCLK_SEL :2; + CBIOS_U32 VCLK_SEL :2; + CBIOS_U32 FUNC_PLL_MON_ON :1; + CBIOS_U32 FUNC_PLL_MON_SEL :2; + CBIOS_U32 FUNC_PLL_MON_DIV :3; + CBIOS_U32 Reserved :20; + }; +}REG_MM935C; + + +typedef union _REG_MM9360 //Performance_Upstream_Utilization_Counter_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 UP_STRM_UTIL_31to0 :32; + }; +}REG_MM9360; + + +typedef union _REG_MM9364 //Performance_Upstream_Utilization_Counter_High_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 UP_STRM_UTIL_47to32 :16; + CBIOS_U32 RESERVED :16; + }; +}REG_MM9364; + + +typedef union _REG_MM9368 //Performance_HDA_ACK_Counter_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDA_ACK_31to0 :32; + }; +}REG_MM9368; + + +typedef union _REG_MM936C //Performance_HDA_ACK_Counter_High_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDA_ACK_47to32 :16; + CBIOS_U32 RESERVED :16; + }; +}REG_MM936C; + + +typedef union _REG_MM9370 //Performance_Downstream_Utilization_Counter_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DOWN_STRM_UTIL__31to0 :32; + }; +}REG_MM9370; + + +typedef union _REG_MM9374 //Performance_Downstream_Utilization_Counter_High_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DOWN_STRM_UTIL_47to32 :16; + CBIOS_U32 RESERVED :16; + }; +}REG_MM9374; + + +typedef union _REG_MM9378 //Performance_DZT_MXU_Idle_Counter_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DZT_Idle_Ctr_31to0 :32; + }; +}REG_MM9378; + + +typedef union _REG_MM937C //Performance_DZT_MXU_Idle_Counter_High_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DZT_Idle_Ctr_47to32 :16; + CBIOS_U32 RESERVED :16; + }; +}REG_MM937C; + + +typedef union _REG_MM9380 //Performance_DZT_MXU_ACK_Counter_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DZT_ACK_Ctr_31to0 :32; + }; +}REG_MM9380; + + +typedef union _REG_MM9384 //Performance_DZT_MXU_ACK_Counter_High_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DZT_ACK_Ctr_47to32 :16; + CBIOS_U32 RESERVED :16; + }; +}REG_MM9384; + + +typedef union _REG_MM9388 //Performance_DZT_MXU_Pending_Counter_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DZT_Pending_Ctr_31to0 :32; + }; +}REG_MM9388; + + +typedef union _REG_MM938C //Performance_DZT_MXU_Pending_Counter_High_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DZT_Pending_Ctr_47to32 :16; + CBIOS_U32 RESERVED :16; + }; +}REG_MM938C; + + +typedef union _REG_MM9390 //Performance_VPT_Idle_Counter_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VPT_Idle_Ctr_31to0 :32; + }; +}REG_MM9390; + + +typedef union _REG_MM9394 //Performance_VPT_Idle_Counter_High_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VPT_Idle_Ctr_47to32 :16; + CBIOS_U32 RESERVED :16; + }; +}REG_MM9394; + + +typedef union _REG_MM9398 //Performance_VPT_ACK_CounterLow_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VPT_ACK_Ctr_31to0 :32; + }; +}REG_MM9398; + + +typedef union _REG_MM939C //Performance_VPT_ACK_Counter_High_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VPT_ACK_Ctr_47to32 :16; + CBIOS_U32 RESERVED :16; + }; +}REG_MM939C; + + +typedef union _REG_MM93A0 //Performance_VPT_Pending_Counter_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VPT_Pending_Ctr_31to0 :32; + }; +}REG_MM93A0; + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_SBI_registers.h b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_SBI_registers.h new file mode 100644 index 0000000000000..0a4d33958ea6d --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_SBI_registers.h @@ -0,0 +1,471 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +typedef union _REG_MM8508 //Command_FIFO_Control_Register +{ + struct + { + CBIOS_U32 VSYNC1_INT_EN :1; + CBIOS_U32 ENGINE_BUSY_INT_EN :1; + CBIOS_U32 VSYNC2_INT_EN :1; + CBIOS_U32 VSYNC3_INT_EN :1; + CBIOS_U32 VSYNC4_INT_EN :1; + CBIOS_U32 PAGE_FAULT_INT_EN :1; + CBIOS_U32 DIU_BIU_CEC_INT_EN :1; + CBIOS_U32 DP1_INT_EN :1; + CBIOS_U32 DP2_INT_EN :1; + CBIOS_U32 INT_TLPMATCH_INT_EN :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 CORRECTABLE_ERR_INT_EN :1; + CBIOS_U32 NON_FATAL_ERR_INT_EN :1; + CBIOS_U32 FATAL_ERR_INT_EN :1; + CBIOS_U32 UNSUPPORTED_ERR_INT_EN :1; + CBIOS_U32 INVALID_CPURW_INT_EN :1; + CBIOS_U32 DP3_INT_EN :1; + CBIOS_U32 DP4_INT_EN :1; + CBIOS_U32 INT_TS_INT_EN :1; + CBIOS_U32 INT_FS0_INT_INT_EN :1; + CBIOS_U32 INT_GPIO_EXT_IRQ_X86_INT_EN :1; + CBIOS_U32 INT_MB_INT_EN :1; + CBIOS_U32 HDCP_INT_EN :1; + CBIOS_U32 CHIP_IDLE_CNTR_EXPIRE_INT_EN :1; + CBIOS_U32 INT_VIP0_EOF_INT_EN :1; + CBIOS_U32 VBI_CLEAR_INT_EN :1; + CBIOS_U32 INT_VIP_INT_EN :1; + CBIOS_U32 INT_VIP1_EOF_INT_EN :1; + CBIOS_U32 INT_VIP2_EOF_INT_EN :1; + CBIOS_U32 HDA_AUDIO_INT_EN :1; + CBIOS_U32 INT_VIP3_EOF_INT_EN :1; + CBIOS_U32 INT_FS1_EOF_INT_EN :1; + }; + CBIOS_U32 Value; +}REG_MM8508; + +typedef union _REG_MM8510 //Transaction_Layer/Data_Link_Layer_Status_0_Register +{ + struct + { + CBIOS_U32 Reserved_7to0 :8; + CBIOS_U32 TLR_MEMW_BUSY :1; + CBIOS_U32 FB_FIFO_Full :1; + CBIOS_U32 FB_FIFO_Empty :1; + CBIOS_U32 BIU_MW_FIFO_Empty :1; + CBIOS_U32 TLR_RDFF_EMPTY :1; + CBIOS_U32 TLR_PHQ_EMPTY :1; + CBIOS_U32 TLR_NPHQ_EMPTY :1; + CBIOS_U32 TLR_FMTFF_FULL :1; + CBIOS_U32 TLM_BusY :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 TLR_BusY :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 Reserved_3 :1; + CBIOS_U32 Reserved_4 :1; + CBIOS_U32 CFAIFX_BusY :1; + CBIOS_U32 Reserved_5 :1; + CBIOS_U32 Reserved_6 :1; + CBIOS_U32 Reserved_7 :6; + }; + CBIOS_U32 Value; +}REG_MM8510; + + +typedef union _REG_MM8514 //Transaction_Layer/Data_Link_Layer_Status_1_Register +{ + struct + { + CBIOS_U32 PECPL_OSCNT :7; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 TRANSACTION_OSCNT :6; + CBIOS_U32 Reserved_1 :2; + CBIOS_U32 Reserved_2 :6; + CBIOS_U32 Reserved_3 :2; + CBIOS_U32 Reserved_4 :4; + CBIOS_U32 Reserved_5 :4; + }; + CBIOS_U32 Value; +}REG_MM8514; + + +typedef union _REG_MM8524 //CRAx_BIU_Shadow_Software_RESET_Register +{ + struct + { + CBIOS_U32 CRA3_C_Software_Reset_register :8; + CBIOS_U32 CRA4_C_Software_Reset_register :8; + CBIOS_U32 CRA5_C_Software_Reset_register :8; + CBIOS_U32 CRA6_C_Software_Reset_register :8; + }; + CBIOS_U32 Value; +}REG_MM8524; + + +typedef union _REG_MM8528 //GTS_Counter_Low_Register +{ + struct + { + CBIOS_U32 GTS_low_32_bits :32; + }; + CBIOS_U32 Value; +}REG_MM8528; + + +typedef union _REG_MM852C //GTS_Counter_High_Register +{ + struct + { + CBIOS_U32 GTS_High_32_bits :32; + }; + CBIOS_U32 Value; +}REG_MM852C; + + +typedef union _REG_MM8530 //GTS_Address_0_Register +{ + struct + { + CBIOS_U32 GTS_ADDRESS_low :32; + }; + CBIOS_U32 Value; +}REG_MM8530; + + +typedef union _REG_MM8534 //GTS_Address_1_Register +{ + struct + { + CBIOS_U32 GTS_ADDRESS_high :32; + }; + CBIOS_U32 Value; +}REG_MM8534; + + +typedef union _REG_MM8538 //Reserved +{ + struct + { + CBIOS_U32 Reserved :32; + }; + CBIOS_U32 Value; +}REG_MM8538; + + +typedef union _REG_MM853C //Stop/Trap_CSP_Control_Register +{ + struct + { + CBIOS_U32 issue_Stop_to_CSP :1; + CBIOS_U32 Trap_clear :1; + CBIOS_U32 Reserved_31to2 :30; + }; + CBIOS_U32 Value; +}REG_MM853C; + + +typedef union _REG_MM8540 //TLM_Control_Register +{ + struct + { + CBIOS_U32 Reserved12_0 :13; + CBIOS_U32 REG_INT_USS_EN :1; + CBIOS_U32 REG_MULTI_MSI_EN :1; + CBIOS_U32 REG_HDA_HI_PRI_EN :1; + CBIOS_U32 Reserved_27_16 :12; + CBIOS_U32 Reserved :4; + }; + CBIOS_U32 Value; +}REG_MM8540; + + +typedef union _REG_MM8544 //Apeture_Table_(APT)_Base_Address_Register +{ + struct + { + CBIOS_U32 Reserved_11to0 :12; + CBIOS_U32 APT_Base_Addr :18; + CBIOS_U32 Reserved_31to30 :2; + }; + CBIOS_U32 Value; +}REG_MM8544; + + +typedef union _REG_MM8548 //CSP_Interrupt_Status_Register +{ + struct + { + CBIOS_U32 VD0_INT0 :1; + CBIOS_U32 VD0_INT1 :1; + CBIOS_U32 VD0_INT2 :1; + CBIOS_U32 VD0_INT3 :1; + CBIOS_U32 VD1_INT0 :1; + CBIOS_U32 VD1_INT1 :1; + CBIOS_U32 VD1_INT2 :1; + CBIOS_U32 VD1_INT3 :1; + CBIOS_U32 Reserved :8; + CBIOS_U32 CSP_TIMEOUT_INT :1; + CBIOS_U32 SP_TIMEOUT_INT :1; + CBIOS_U32 VPP_TIMEOUT_INT :1; + CBIOS_U32 PECTL_TIMEOUT_INT :1; + CBIOS_U32 MSVD_TIMEOUT_INT :1; + CBIOS_U32 MXU_TIMEOUT_INT :1; + CBIOS_U32 MIU0_TIMEOUT_INT :1; + CBIOS_U32 MIU1_TIMEOUT_INT :1; + CBIOS_U32 MIU2_TIMEOUT_INT :1; + CBIOS_U32 PMP_TIMEOUT_INT :1; + CBIOS_U32 VCP_TIMEOUT_INT :1; + CBIOS_U32 FENCE_CMD_INT :1; + CBIOS_U32 VIRQ :1; + CBIOS_U32 Reserved1 :3; + }; + CBIOS_U32 Value; +}REG_MM8548; + + +typedef union _REG_MM854C //CSP_Interrupt_Enable_Register +{ + struct + { + CBIOS_U32 VD0_INT0_EN :1; + CBIOS_U32 VD0_INT1_EN :1; + CBIOS_U32 VD0_INT2_EN :1; + CBIOS_U32 VD0_INT3_EN :1; + CBIOS_U32 VD1_INT0_EN :1; + CBIOS_U32 VD1_INT1_EN :1; + CBIOS_U32 VD1_INT2_EN :1; + CBIOS_U32 VD1_INT3_EN :1; + CBIOS_U32 Reserved :8; + CBIOS_U32 CSP_TIMEOUT_INT_EN :1; + CBIOS_U32 SP_TIMEOUT_INT_EN :1; + CBIOS_U32 VPP_TIMEOUT_INT_EN :1; + CBIOS_U32 PECTL_TIMEOUT_INT_EN :1; + CBIOS_U32 MSVD_TIMEOUT_INT_EN :1; + CBIOS_U32 MXU_TIMEOUT_INT_EN :1; + CBIOS_U32 MIU0_TIMEOUT_INT_EN :1; + CBIOS_U32 MIU1_TIMEOUT_INT_EN :1; + CBIOS_U32 MIU2_TIMEOUT_INT_EN :1; + CBIOS_U32 PMP_TIMEOUT_INT_EN :1; + CBIOS_U32 VCP_TIMEOUT_INT_EN :1; + CBIOS_U32 FENCE_CMD_INT_EN :1; + CBIOS_U32 Reserved1 :4; + }; + CBIOS_U32 Value; +}REG_MM854C; + +typedef union _REG_MM8574 //Interrupt_Synchronization_MM8504_Mirror_Register +{ + struct + { + CBIOS_U32 VSYNC1_INT :1; + CBIOS_U32 ENGINE_BUSY_INT :1; + CBIOS_U32 VSYNC2_INT :1; + CBIOS_U32 VSYNC3_INT :1; + CBIOS_U32 VSYNC4_INT :1; + CBIOS_U32 PAGE_FAULT_INT :1; + CBIOS_U32 DIU_BIU_CEC_INT :1; + CBIOS_U32 DP1_INT :1; + CBIOS_U32 DP2_INT :1; + CBIOS_U32 TLPMATCH_INT :1; + CBIOS_U32 MST_ABORT :1; + CBIOS_U32 CORRECTABLE_ERR_INT :1; + CBIOS_U32 NON_FATAL_ERR_INT :1; + CBIOS_U32 FATAL_ERR_INT :1; + CBIOS_U32 UNSUPPORTED_ERR_INT :1; + CBIOS_U32 INVALID_CPURW_INT :1; + CBIOS_U32 DP3_INT :1; + CBIOS_U32 DP4_INT :1; + CBIOS_U32 TS_INT :1; + CBIOS_U32 FS0_INT :1; + CBIOS_U32 GPIO_EXT_IRQ_INT :1; + CBIOS_U32 MB_INT :1; + CBIOS_U32 HDCP_INT :1; + CBIOS_U32 CHIP_IDLE_CNTR_EXPIRE_INT :1; + CBIOS_U32 VIP0_EOF_INT :1; + CBIOS_U32 VBI_CLEAR_INT :1; + CBIOS_U32 HDA_CODEC_INT :1; + CBIOS_U32 VIP1_EOF :1; + CBIOS_U32 VIP2_EOF :1; + CBIOS_U32 HDA_AUDIO_INT :1; + CBIOS_U32 VIP3_EOF :1; + CBIOS_U32 FS1_INT :1; + }; + CBIOS_U32 Value; +}REG_MM8574; + + +typedef union _REG_MM8578 //Interrupt_Synchronization_MM8548_Mirror_Register +{ + struct + { + CBIOS_U32 VD0_INT0 :1; + CBIOS_U32 VD0_INT1 :1; + CBIOS_U32 VD0_INT2 :1; + CBIOS_U32 VD0_INT3 :1; + CBIOS_U32 VD1_INT0 :1; + CBIOS_U32 VD1_INT1 :1; + CBIOS_U32 VD1_INT2 :1; + CBIOS_U32 VD1_INT3 :1; + CBIOS_U32 Reserved :8; + CBIOS_U32 CSP_TIMEOUT_INT :1; + CBIOS_U32 SP_TIMEOUT_INT :1; + CBIOS_U32 VPP_TIMEOUT_INT :1; + CBIOS_U32 PECTL_TIMEOUT_INT :1; + CBIOS_U32 MSVD_TIMEOUT_INT :1; + CBIOS_U32 MXU_TIMEOUT_INT :1; + CBIOS_U32 MIU0_TIMEOUT_INT :1; + CBIOS_U32 MIU1_TIMEOUT_INT :1; + CBIOS_U32 MIU2_TIMEOUT_INT :1; + CBIOS_U32 PMP_TIMEOUT_INT :1; + CBIOS_U32 VCP_TIMEOUT_INT :1; + CBIOS_U32 FENCE_CMD_INT :1; + CBIOS_U32 VIRQ :1; + CBIOS_U32 Reserved1 :3; + }; + CBIOS_U32 Value; +}REG_MM8578; + + +typedef union _REG_MM85B4 //CRBx_C_Shadow_Software_RESET_Register +{ + struct + { + CBIOS_U32 CRB4_C_Software_Reset_register :8; + CBIOS_U32 CRB5_C_Software_Reset_register :8; + CBIOS_U32 CRB6_C_Software_Reset_register :8; + CBIOS_U32 CRB7_C_Software_Reset_register :8; + }; + CBIOS_U32 Value; +}REG_MM85B4; + + +typedef union _REG_MM85D0 //EPLL_control_Register +{ + struct + { + CBIOS_U32 EPLL_integer_division_setting :8; + CBIOS_U32 EPLL_fractional_division_setting :20; + CBIOS_U32 EPLL_Clock1_output_division_ratio :2; + CBIOS_U32 EPLL_VCO_frequency_range_setting :1; + CBIOS_U32 EPLL_enable_Clock1_output :1; + }; + CBIOS_U32 Value; +}REG_MM85D0; + + +typedef union _REG_MM85D4 //EPLL_control_Register +{ + struct + { + CBIOS_U32 EPLL_Power_up_control :1; + CBIOS_U32 EPLL_Reset_control :1; + CBIOS_U32 Reserved :30; + }; + CBIOS_U32 Value; +}REG_MM85D4; + + +typedef union _REG_MM85D8 //EPLL_control_Register +{ + struct + { + CBIOS_U32 EPLL_Charge_Pump_current_selection_setting :3; + CBIOS_U32 EPLL_Fractional_function_enable :1; + CBIOS_U32 EPLL_Enable_Clock2_output :1; + CBIOS_U32 EPLL_Clock2_output_division_ratio :2; + CBIOS_U32 Reserved :25; + }; + CBIOS_U32 Value; +}REG_MM85D8; + + +typedef union _REG_MM85E0 //IPLL_control_Register +{ + struct + { + CBIOS_U32 IPLL_integer_division_setting :8; + CBIOS_U32 IPLL_fractional_division_setting :20; + CBIOS_U32 IPLL_Clock1_output_division_ratio :2; + CBIOS_U32 IPLL_VCO_frequency_range_setting :1; + CBIOS_U32 IPLL_enable_Clock1_output :1; + }; + CBIOS_U32 Value; +}REG_MM85E0; + + +typedef union _REG_MM85E4 //IPLL_control_Register +{ + struct + { + CBIOS_U32 IPLL_Power_up_control :1; + CBIOS_U32 IPLL_Reset_control :1; + CBIOS_U32 Reserved :30; + }; + CBIOS_U32 Value; +}REG_MM85E4; + + +typedef union _REG_MM85E8 //IPLL_control_Register +{ + struct + { + CBIOS_U32 IPLL_Charge_Pump_current_selection_setting :3; + CBIOS_U32 IPLL_Fractional_function_enable :1; + CBIOS_U32 IPLL_Enable_Clock2_output :1; + CBIOS_U32 IPLL_Clock2_output_division_ratio :2; + CBIOS_U32 Reserved :25; + }; + CBIOS_U32 Value; +}REG_MM85E8; + + +typedef union _REG_MM85F0 //VPLL_control_Register +{ + struct + { + CBIOS_U32 VPLL_integer_division_setting :8; + CBIOS_U32 VPLL_fractional_division_setting :20; + CBIOS_U32 VPLL_Clock1_output_division_ratio :2; + CBIOS_U32 VPLL_VCO_frequency_range_setting :1; + CBIOS_U32 VPLL_enable_Clock1_output :1; + }; + CBIOS_U32 Value; +}REG_MM85F0; + + +typedef union _REG_MM85F4 //VPLL_control_Register +{ + struct + { + CBIOS_U32 VPLL_Power_up_control :1; + CBIOS_U32 VPLL_Reset_control :1; + CBIOS_U32 Reserved :30; + }; + CBIOS_U32 Value; +}REG_MM85F4; + + +typedef union _REG_MM85F8 //VPLL_control_Register +{ + struct + { + CBIOS_U32 VPLL_Charge_Pump_current_selection_setting :3; + CBIOS_U32 VPLL_Fractional_function_enable :1; + CBIOS_U32 VPLL_Enable_Clock2_output :1; + CBIOS_U32 VPLL_Clock2_output_division_ratio :2; + CBIOS_U32 Reserved :25; + }; + CBIOS_U32 Value; +}REG_MM85F8; + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_TSR_registers.h b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_TSR_registers.h new file mode 100644 index 0000000000000..400416b0236cb --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_TSR_registers.h @@ -0,0 +1,54 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +typedef union _REG_MM48C00_MM48C78 //Tile_Surface_Start_Range_Registers_0-15 +{ + struct + { + CBIOS_U32 TS_Height_8 :11; + CBIOS_U32 TS_Start_Range_28to8 :21; + }; + CBIOS_U32 Value; +}REG_MM48C00_MM48C78; + + +typedef union _REG_MM48C04_MM48C7C //Tile_Surface_End_Range_Registers_0-15 +{ + struct + { + CBIOS_U32 TS_Width_8 :11; + CBIOS_U32 End_Range_Value :21; + }; + CBIOS_U32 Value; +}REG_MM48C04_MM48C7C; + + +typedef union _REG_MM48C80_MM48CBC //Tile_Surface_Description_Registers__0-15 +{ + struct + { + CBIOS_U32 Format :4; + CBIOS_U32 Rotation_Angle :2; + CBIOS_U32 Start_Range_Value_29 :1; + CBIOS_U32 End_Range_Value_29 :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 Reciprical_of_Surface_Width :14; + CBIOS_U32 Destination_Surface :1; + CBIOS_U32 Destination_Surface_Width :8; + }; + CBIOS_U32 Value; +}REG_MM48C80_MM48CBC; + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_VCP_registers.h b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_VCP_registers.h new file mode 100644 index 0000000000000..4cc043226eab2 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/BIU_VCP_registers.h @@ -0,0 +1,35 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +typedef union _REG_MM49200 //BIU_VCP_Active_Counter_Register +{ + struct + { + CBIOS_U32 RISC_ACT_CNT :32; + }; + CBIOS_U32 Value; +}REG_MM49200; + + +typedef union _REG_MM49204 //BIU_VCP_Operation_Counter_Register +{ + struct + { + CBIOS_U32 RISC_OP_CNT :32; + }; + CBIOS_U32 Value; +}REG_MM49204; + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_CR_registers.h b/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_CR_registers.h new file mode 100644 index 0000000000000..a88da3b9261da --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_CR_registers.h @@ -0,0 +1,2094 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +typedef union _REG_CR22_Pair //CRT_Test_DAC_Data_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Test_Reset :1; + CBIOS_U8 RESERVED_0 :3; + CBIOS_U8 Test_Sync :1; + CBIOS_U8 RESERVED_1 :2; + CBIOS_U8 Test_DAC_Data :1; + }; +}REG_CR22_Pair; + + +typedef union _REG_CR23_Pair //Test_Data_High_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Test_Data_10to3 :8; + }; +}REG_CR23_Pair; + + +typedef union _REG_CR26_Pair //Test_Data_Load_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Load_Test_Data :8; + }; +}REG_CR26_Pair; + + +typedef union _REG_CR29_Pair //Test_Data_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Test_Data_2to0 :3; + CBIOS_U8 Test_Data_bit11 :1; + CBIOS_U8 RESERVED :4; + }; +}REG_CR29_Pair; + + +typedef union _REG_CR31_Pair //Memory_Configuration_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 CPU_Base_Address_Offset_Bits_Enable :1; + CBIOS_U8 Two_Page_Screen_Enable :1; + CBIOS_U8 VGA_16bit_Bus_Width :1; + CBIOS_U8 Enhanced_Mode_Map :1; + CBIOS_U8 Display_Start_Address_19to18 :2; + CBIOS_U8 High_Speed_Text :1; + CBIOS_U8 RESERVED :1; + }; +}REG_CR31_Pair; + + +typedef union _REG_CR32_Pair //Backward_Compatibility_1_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS_Read_Length :2; + CBIOS_U8 Force_Char_Clock_High :1; + CBIOS_U8 RESERVED_0 :1; + CBIOS_U8 vretrace_inter_EN :1; + CBIOS_U8 MISC_bit_7_EN :1; + CBIOS_U8 VGA_Memory_Wrap :1; + CBIOS_U8 RESERVED_1 :1; + }; +}REG_CR32_Pair; + + +typedef union _REG_CR33_Pair //Backward_Compatibility_2_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Display_Mode_Inactive :1; + CBIOS_U8 VDE_Protection_Disable :1; + CBIOS_U8 Vertical_Sync_Active :1; + CBIOS_U8 VCLK_Is_Inverted_DCLK :1; + CBIOS_U8 Lock_DAC_Writes :1; + CBIOS_U8 BLANK_Active_Time_Select :1; + CBIOS_U8 Palette_Border_Color_Lock :1; + CBIOS_U8 Flicker_Filter_Odd_Even_Status :1; + }; +}REG_CR33_Pair; + + +typedef union _REG_CR34_Pair //Backward_Compatibility_3_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PCI_DAC_Snoop_Handling :1; + CBIOS_U8 PCI_Master_Abort_Handling :1; + CBIOS_U8 PCI_Retry_Handling :1; + CBIOS_U8 Vertical_Blank_Active :1; + CBIOS_U8 Reserved_bit4 :1; + CBIOS_U8 SR01_0_Lock :1; + CBIOS_U8 VGA_Register_Lock :1; + CBIOS_U8 VGA_Clock_Frequency_Lock :1; + }; +}REG_CR34_Pair; + + +typedef union _REG_CR35_Pair //CRT_Register_Lock_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 For_VGA_mem_offset :4; + CBIOS_U8 Vertical_Timing_Registers_Lock :1; + CBIOS_U8 Horizontal_Timing_Registers_Lock :1; + CBIOS_U8 CR01_3C2h_6_Lock :1; + CBIOS_U8 CR12_3C2h_7_Lock :1; + }; +}REG_CR35_Pair; + + +typedef union _REG_CR36 //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :8; + }; +}REG_CR36; + + +typedef union _REG_CR37 //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :8; + }; +}REG_CR37; + + +typedef union _REG_CR38 //Register_CR2D-3F_Lock_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 CRTC_Register_Lock_1 :8; + }; +}REG_CR38; + + +typedef union _REG_CR39 //Register_CR40-FF_Lock_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 CRTC_Register_Lock_2 :8; + }; +}REG_CR39; + + +typedef union _REG_CR3A_Pair //Miscellaneous_1_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 C1_Vertical_Counter_2to0_Read :3; + CBIOS_U8 Top_of_Memory_Access :1; + CBIOS_U8 Enhanced_Mode_Enable :1; + CBIOS_U8 High_Speed_Text :1; + CBIOS_U8 C1_Vertical_Counter_bit_11_Read :1; + CBIOS_U8 RESERVED :1; + }; +}REG_CR3A_Pair; + + +typedef union _REG_CR3B_Pair //Start_Display_FIFO_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Start_Display_FIFO_Fetch_7to0 :8; + }; +}REG_CR3B_Pair; + + +typedef union _REG_CR3C_Pair //Interlace_Retrace_Start_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Interlace_Retrace_Start_Position :8; + }; +}REG_CR3C_Pair; + + +typedef union _REG_CR3E_Pair //Vertical_Counter_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vertical_Counter_Bits_10to3 :8; + }; +}REG_CR3E_Pair; + + +typedef union _REG_CR3F //LED_panel_Power_ON/OFF_Sequence_for_PWM_signal +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Timer_step_setting :7; + CBIOS_U8 Timer_status_ :1; + }; +}REG_CR3F; + + +typedef union _REG_CR41 //Extended_BIOS_Flag_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 BIOS_Flag_1 :8; + }; +}REG_CR41; + + +typedef union _REG_CR42_Pair //Mode_Control_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 CPU_Base_Address_11to8 :4; + CBIOS_U8 Reduced_Blanking_Enable :1; + CBIOS_U8 Interlaced_Mode :1; + CBIOS_U8 Controller2_HSYNC_VSYNC :2; + }; +}REG_CR42_Pair; + + +typedef union _REG_CR43_Pair //Extended_Mode_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 RESERVED_0 :1; + CBIOS_U8 Controller3_HSYNC_VSYNC :2; + CBIOS_U8 Character_Blink :1; + CBIOS_U8 PS1_VR_FRAME :1; + CBIOS_U8 Cursor_Blink :2; + CBIOS_U8 PS2_VR_FRAME :1; + }; +}REG_CR43_Pair; + + +typedef union _REG_CR44_Pair //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 _3D_Video_Mode :4; + CBIOS_U8 PS_FIFO_share :1; + CBIOS_U8 PS_X_Rotation_Enable :1; + CBIOS_U8 PS_Y_Rotation_Enable :1; + CBIOS_U8 enable_page_flip_every_2_frame_for_3D_video :1; + }; +}REG_CR44_Pair; + + +typedef union _REG_CR45_Pair //Hardware_Graphics_Cursor_Mode_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Enable :1; + CBIOS_U8 HW_Cursor_Position :1; + CBIOS_U8 HW_Cursor_Type :2; + CBIOS_U8 HW_Cursor_X_Rotation :1; + CBIOS_U8 HW_Cursor_Y_Rotation :1; + CBIOS_U8 HW_Cursor_Size :1; + CBIOS_U8 Reserved :1; + }; +}REG_CR45_Pair; + + +typedef union _REG_CR46_Pair //Hardware_Graphics_Cursor_Origin-X_High_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_X_Origin_12to8 :6; + CBIOS_U8 RESERVED :2; + }; +}REG_CR46_Pair; + + +typedef union _REG_CR47_Pair //Hardware_Graphics_Cursor_Origin-X_Low_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_X_Origin_7to0 :8; + }; +}REG_CR47_Pair; + + +typedef union _REG_CR48_Pair //Hardware_Graphics_Cursor_Origin-Y_HIgh_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Y_Origin_11to8 :5; + CBIOS_U8 RESERVED :3; + }; +}REG_CR48_Pair; + + +typedef union _REG_CR49_Pair //Hardware_Graphics_Cursor_Origin-Y_Low_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Y_Origin_7to0 :8; + }; +}REG_CR49_Pair; + + +typedef union _REG_CR4A_Pair //Hardware_Graphics_Cursor_Foreground_Color_Stack_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Color_Foreground_Stack :8; + }; +}REG_CR4A_Pair; + + +typedef union _REG_CR4B_Pair //Hardware_Graphics_Cursor_Background_Color_Stack_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Color_Background_Stack :8; + }; +}REG_CR4B_Pair; + + +typedef union _REG_CR4C_Pair //Hardware_Graphics_Cursor_Start_Address_15to8_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Start_Address_15to8 :8; + }; +}REG_CR4C_Pair; + + +typedef union _REG_CR4D_Pair //Hardware_Graphics_Cursor_Start_Address_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Start_Address_7to0 :8; + }; +}REG_CR4D_Pair; + + +typedef union _REG_CR4E_Pair //Hardware_Graphics_Cursor_Display_Start_X_Pixel_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Display_Start_X :7; + CBIOS_U8 RESERVED :1; + }; +}REG_CR4E_Pair; + + +typedef union _REG_CR4F_Pair //Hardware_Graphics_Cursor_Display_Start_Y_Pixel_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Display_Start_Y :7; + CBIOS_U8 RESERVED :1; + }; +}REG_CR4F_Pair; + + +typedef union _REG_CR50 //Extended_System_Control_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Screen_Width_bit2 :1; + CBIOS_U8 RESERVED :3; + CBIOS_U8 Pixel_Length_Select :2; + CBIOS_U8 Screen_Width_1to0 :2; + }; +}REG_CR50; + + +typedef union _REG_CR51_Pair //Extended_System_Control_2_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Controller2_VSYNC_Lock :1; + CBIOS_U8 Controller2_HSYNC_Lock :1; + CBIOS_U8 Logical_Screen_Width_13to8 :6; + }; +}REG_CR51_Pair; + + +typedef union _REG_CR52 //Extended_BIOS_Flag_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 BIOS_Flag_2 :8; + }; +}REG_CR52; + + +typedef union _REG_CR53 //Extended_Memory_Control_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 output_to_BIU :7; + CBIOS_U8 VGA_Access_Disable :1; + }; +}REG_CR53; + + +typedef union _REG_CR54_Pair //Hardware_Graphics_Cursor_Start_Address_3_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Start_Address_23to16 :8; + }; +}REG_CR54_Pair; + + +typedef union _REG_CR55 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SS3_Load_Control :1; + CBIOS_U8 PS3_Load_Control :1; + CBIOS_U8 Cursor_1_Load_Control :1; + CBIOS_U8 Cursor_2_Load_Control :1; + CBIOS_U8 Cursor_3_Load_Control :1; + CBIOS_U8 Reserved :3; + }; +}REG_CR55; + + +typedef union _REG_CR56 //NB_Product_SKU_and_HDCP_Allow_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Pdmod0 :1; + CBIOS_U8 Pdmod1 :1; + CBIOS_U8 Hdcp_Bopt :1; + CBIOS_U8 RESERVED :5; + }; +}REG_CR56; + + +typedef union _REG_CR57_Pair //Hardware_Graphics_Cursor_Start_Address_4_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Start_Address_27to24 :3; + CBIOS_U8 HW_Cursor_Right_Frame_Start_Address__27to24 :3; + CBIOS_U8 RESERVED :2; + }; +}REG_CR57_Pair; + + +typedef union _REG_CR58_Pair //Adjust_Horizontal_Display_Enable_Control +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Remainder_Of_Pixel_for_One_Line_of_Active_Display_Divided_by_8 :3; + CBIOS_U8 Enable_HDE_adjusting_function :1; + CBIOS_U8 output_to_BIU :4; + }; +}REG_CR58_Pair; + + +typedef union _REG_CR59_Pair //Horizontal_Display_Shift_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDES_7_to_0 :8; + }; +}REG_CR59_Pair; + + +typedef union _REG_CR5A_Pair //Vertical_Display_Shift_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VDES_7to0 :8; + }; +}REG_CR5A_Pair; + + +typedef union _REG_CR5B_Pair //Display_Shift_Overflow_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDES_8 :1; + CBIOS_U8 RESERVED :2; + CBIOS_U8 Enable_Shift_On :1; + CBIOS_U8 VDES :4; + }; +}REG_CR5B_Pair; + + +typedef union _REG_CR5C //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :8; + }; +}REG_CR5C; + + +typedef union _REG_CR5D_Pair //Extended_Horizontal_Overflow_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_total_bit_8 :1; + CBIOS_U8 Horizontal_Display_End_bit_8 :1; + CBIOS_U8 Start_Horizontal_Blank_bit_8 :1; + CBIOS_U8 End_Horizontal_Blank_bit_6 :1; + CBIOS_U8 Start_Horizontal_Sync_Position_bit_8 :1; + CBIOS_U8 End_Horizontal_Sync_Period_bit_5 :1; + CBIOS_U8 Start_FIFO_Fetch_bit_8 :1; + CBIOS_U8 Start_TV_Hsync_Position_8 :1; + }; +}REG_CR5D_Pair; + + +typedef union _REG_CR5E_Pair //Extended_Vertical_Overflow_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vdisplay_end_bit_10 :2; + CBIOS_U8 Start_Vertical_Blank_11to10 :2; + CBIOS_U8 Vertical_Retrace_Start_11to10 :2; + CBIOS_U8 Line_Compare_11to10 :2; + }; +}REG_CR5E_Pair; + + +typedef union _REG_CR5F_Pair //Extended_Horizontal_Overflow_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_total_bit_9 :1; + CBIOS_U8 Horizontal_Display_End_bit_9 :1; + CBIOS_U8 Start_Horizontal_Blank_bit_9 :1; + CBIOS_U8 Start_TV_Horizontal_Sync_Position_bit_9 :1; + CBIOS_U8 Start_FIFO_Fetch_bit_9 :1; + CBIOS_U8 Start_TV_Hsync_Position_bit_9 :1; + CBIOS_U8 RESERVED :2; + }; +}REG_CR5F_Pair; + + +typedef union _REG_CR60_Pair //Hardware_Graphics_Cursor_Right_Frame_Start_Address_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Right_Frame_Start_Address_7to0 :8; + }; +}REG_CR60_Pair; + + +typedef union _REG_CR61_Pair //Hardware_Graphics_Cursor_Right_Frame_Start_Address_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Right_Frame_Start__15to8 :8; + }; +}REG_CR61_Pair; + + +typedef union _REG_CR62 //Hardware_Graphics_Cursor_Right_Frame_Start_Address_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HW_Cursor_Right_Frame_Start__23to16 :8; + }; +}REG_CR62; + + +typedef union _REG_CR63_Pair //Start_FIFO_Fetch_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HSYNC_Timing :1; + CBIOS_U8 PS_Request_Disable_Pos :1; + CBIOS_U8 Start_FIFO_Fetch_Pos :1; + CBIOS_U8 Start_FIFO_Fetch :2; + CBIOS_U8 RESERVED :1; + CBIOS_U8 Vertical_Display_End_bit_11 :2; + }; +}REG_CR63_Pair; + + +typedef union _REG_CR64_Pair //Display_Start_Address_27:24_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Display_Start_Address_29to24 :6; + CBIOS_U8 PS_shadow_bit_select :1; + CBIOS_U8 RESERVED :1; + }; +}REG_CR64_Pair; + + +typedef union _REG_CR65_Pair //Extended_Miscellaneous_Control_0_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS2_Load_Control :1; + CBIOS_U8 PS1_Load_Control :1; + CBIOS_U8 PS_LUT_before_Blender :1; + CBIOS_U8 BLANK_Delay_in_DCLK :3; + CBIOS_U8 SS2_Load_Control :1; + CBIOS_U8 SS1_Load_Control :1; + }; +}REG_CR65_Pair; + + +typedef union _REG_CR66_Pair //Extended_Miscellaneous_Control_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Enhanced_Mode :1; + CBIOS_U8 RESERVED_0 :1; + CBIOS_U8 Enhanced_Pixel_Length :1; + CBIOS_U8 RESERVED_1 :5; + }; +}REG_CR66_Pair; + + +typedef union _REG_CR67_Pair //Extended_Miscellaneous_Control_2_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SS_Blender_Disable :1; + CBIOS_U8 Primary_Stream_Disable :1; + CBIOS_U8 Secondary_Stream_Enable :1; + CBIOS_U8 Primary_Streams_Control :1; + CBIOS_U8 DAC1_Color_Mode :3; + CBIOS_U8 reserved :1; + }; +}REG_CR67_Pair; + + +typedef union _REG_CR68 //Configuration_3_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 EOCLK_Source :1; + CBIOS_U8 DCLK1_CLK_Source :1; + CBIOS_U8 DCLK2_CLK_Source :1; + CBIOS_U8 EICLK_Source :1; + CBIOS_U8 reserved :3; + CBIOS_U8 HDCP_eFuse_Blow_Enable :1; + }; +}REG_CR68; + + +typedef union _REG_CR69_Pair //Display_Start_Address_23:16_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Display_Start_Address_23to16 :8; + }; +}REG_CR69_Pair; + + +typedef union _REG_CR6A //CPU_Base_Address_7:0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 CPU_Base_Address_7to0 :8; + }; +}REG_CR6A; + + +typedef union _REG_CR6B //Extended_BIOS_Flag_3_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 BIOS_Flag_3 :8; + }; +}REG_CR6B; + + +typedef union _REG_CR6C //Extended_BIOS_Flag_4_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 BIOS_Flag_4 :8; + }; +}REG_CR6C; + + +typedef union _REG_CR6D //Extended_BIOS_Flag_5_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 BIOS_Flag_5 :8; + }; +}REG_CR6D; + + +typedef union _REG_CR6E //DAC_Signature_Test_Data_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DAC_SIG_TEST_DATA_STATUS :8; + }; +}REG_CR6E; + + +typedef union _REG_CR6F //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :8; + }; +}REG_CR6F; + + +typedef union _REG_CR70_Pair //Start_TV_Horizontal_Sync_Position_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Start_TV_Hsync_Position_7_to_0 :8; + }; +}REG_CR70_Pair; + + +typedef union _REG_CR71_Pair //Dual_Image_Control_Register__Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 RESERVED :1; + CBIOS_U8 Screen_Off_Control_Select :1; + CBIOS_U8 DLYSEL :1; + CBIOS_U8 SENSEL :2; + CBIOS_U8 Screen_Off :1; + CBIOS_U8 SENWIDTH :2; + }; +}REG_CR71_Pair; + + +typedef union _REG_CR72_Pair //Adjusting_Timing_Control_1 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Adjust_H_Bottom_Right_Border_H_Front_Porch_period :3; + CBIOS_U8 Adjust_HSYNC_period :3; + CBIOS_U8 RESERVED :2; + }; +}REG_CR72_Pair; + + +typedef union _REG_CR73_Pair //Adjusting_Timing_Control_2 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Adjust_H_Back_Porch_H_Top_Left_Border_period :3; + CBIOS_U8 RESERVED :5; + }; +}REG_CR73_Pair; + + +typedef union _REG_CR74 //high_bit__for_timing_control_register1_pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_total_bit_10 :1; + CBIOS_U8 Horizontal_Display_End_bit_10 :1; + CBIOS_U8 Start_Horizontal_Blank_bit_10 :1; + CBIOS_U8 Horizontal_Blank_end_bit_9_7 :3; + CBIOS_U8 Start_Horizontal_Sync_Position_bit_10 :1; + CBIOS_U8 reserved :1; + }; +}REG_CR74; + + +typedef union _REG_CR75 //high_bit__for_timing_control_register2_pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Start_FIFO_Fetch_bit_10 :1; + CBIOS_U8 HDES_9 :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 Start_TV_Hsync_Position_bit_10 :1; + CBIOS_U8 reserved :4; + }; +}REG_CR75; + + +typedef union _REG_CR76 //high_bit__for_timing_control_register3_pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Interlace_mode_enable :1; + CBIOS_U8 s_vblnk_end_off :3; + CBIOS_U8 s_vsync_off :3; + CBIOS_U8 s_totol_off_bit2 :1; + }; +}REG_CR76; + + +typedef union _REG_CR77 //high_bit__for_timing_control_register4_pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 s_totol_off_bit1_0 :2; + CBIOS_U8 reserved_0 :1; + CBIOS_U8 double_FrameBuffer_mode :1; + CBIOS_U8 enable_4_frame_page_flip_for_FRC :1; + CBIOS_U8 use_L_R_or_ODD_EVEN_to_do_2_frame_page_flip :1; + CBIOS_U8 reserved_1 :2; + }; +}REG_CR77; + + +typedef union _REG_CR79 //high_bit__for_timing_control_register5_pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vertical_Retrace_Start_bit_13 :1; + CBIOS_U8 reserved :1; + CBIOS_U8 Vertical_Total_bit_13 :1; + CBIOS_U8 Vertical_Display_End_bit_13 :1; + CBIOS_U8 Start_Vertical_Blank_bit_13 :1; + CBIOS_U8 End_Vertical_Blank_bit9 :1; + CBIOS_U8 Vertical_Retrace_End__bit6 :1; + CBIOS_U8 VDES_bit13 :1; + }; +}REG_CR79; + + +typedef union _REG_CR7A //high_bit__for_timing_control_register6_pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Line_Compare_bit_13 :1; + CBIOS_U8 reserved :7; + }; +}REG_CR7A; + + +typedef union _REG_CR7B //pt_request_control_pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS1_pt_request_conotrl :1; + CBIOS_U8 RESERVED :7; + }; +}REG_CR7B; + + +typedef union _REG_CR85 // +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DIU_MEM_IDLE_mode :2; + CBIOS_U8 DIU_MEM_IDLE :1; + CBIOS_U8 HDA_PWSEN :1; + CBIOS_U8 IGA3_PWSEN :1; + CBIOS_U8 TS_PWSEN :1; + CBIOS_U8 IGA1_PWSEN :1; + CBIOS_U8 IGA2_PWSEN :1; + }; +}REG_CR85; + + +typedef union _REG_CR86 //reerved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :8; + }; +}REG_CR86; + + +typedef union _REG_CR87 //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :8; + }; +}REG_CR87; + + +typedef union _REG_CR88 //Primary_Stream_1_Timeout_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS1_Timeout :8; + }; +}REG_CR88; + + +typedef union _REG_CR89 //Secondary_Stream_1_Timeout_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :6; + CBIOS_U8 Memory_Bank_Info :1; + CBIOS_U8 Display_Requests_to_MIU :1; + }; +}REG_CR89; + + +typedef union _REG_CR8D //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :8; + }; +}REG_CR8D; + + +typedef union _REG_CR90_Pair //Primary_Stream_FIFO_Fetch_Control_1_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS_L1_10to8 :3; + CBIOS_U8 RESERVED_0 :2; + CBIOS_U8 EOF_Signal_to_BIU_Select :1; + CBIOS_U8 RESERVED_1 :1; + CBIOS_U8 Enable_PS_L1 :1; + }; +}REG_CR90_Pair; + + +typedef union _REG_CR91_Pair //Primary_Stream_FIFO_Fetch_Control_2_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS_L1_7to0 :8; + }; +}REG_CR91_Pair; + + +typedef union _REG_CR92 //TIMEOUT_CONTROL +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS3_Timeout :1; + CBIOS_U8 SS3_Timeout :1; + CBIOS_U8 AUDIO_Timeout :1; + CBIOS_U8 TVW_Timeout :1; + CBIOS_U8 RESERVED_7to6 :4; + }; +}REG_CR92; + + +typedef union _REG_CR93 // +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS3_request_timeout_reg_bit_7_0 :8; + }; +}REG_CR93; + + +typedef union _REG_CR94 // +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :7; + CBIOS_U8 Disable_PS3_odd_or_even_line_check :1; + }; +}REG_CR94; + + +typedef union _REG_CR95 // +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SS3_request_timeout_reg_bit_7_0 :8; + }; +}REG_CR95; + + +typedef union _REG_CR96 // +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PT_request_timeout_reg_bit_7_0 :8; + }; +}REG_CR96; + + +typedef union _REG_CR9A //MDI_latency_check_control +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 mdi_read_latency_check_eanble :1; + CBIOS_U8 reset_latency_recorder_counter :1; + CBIOS_U8 ps_ss_requeset_method :1; + CBIOS_U8 reserved :5; + }; +}REG_CR9A; + + +typedef union _REG_CRA0 //Serial_Port_1_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SPCLK1_Write :1; + CBIOS_U8 SPDAT1_Write :1; + CBIOS_U8 SPCLK1_Read :1; + CBIOS_U8 SPDAT1_Read :1; + CBIOS_U8 Serial_Port_1_Enable :1; + CBIOS_U8 Reserved :2; + CBIOS_U8 signature_reset :1; + }; +}REG_CRA0; + + +typedef union _REG_CRA1 //LVDS_Test_Pattern_Sequence_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRA1; + + +typedef union _REG_CRA2 //LVDS_Test_Pattern_Sequence_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRA2; + + +typedef union _REG_CRA3 //LVDS_Test_Pattern_Sequence_3_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRA3; + + +typedef union _REG_CRA4 //LVDS_Test_Pattern_Sequence_4_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRA4; + + +typedef union _REG_CRA5 //pt_request_control0 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PT_enable :1; + CBIOS_U8 pt_requset_threshold_value :5; + CBIOS_U8 mdi_round_robbin_in_idle_st_control :1; + CBIOS_U8 reserved :1; + }; +}REG_CRA5; + + +typedef union _REG_CRA7 // +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 tvw_timeout_control_bit_7_0 :8; + }; +}REG_CRA7; + + +typedef union _REG_CRA8 // +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 hdaudio_timeout_control_bit_7_0 :8; + }; +}REG_CRA8; + + +typedef union _REG_CRAA //Serial_Port_2_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SPCLK2_Write :1; + CBIOS_U8 SPDAT2_Write :1; + CBIOS_U8 SPCLK2_Read :1; + CBIOS_U8 SPDAT2_Read :1; + CBIOS_U8 Serial_Port_2_Enable :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 HDCP1_I2C_port_selection :2; + }; +}REG_CRAA; + + +typedef union _REG_CRAB //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SP3_LUT_Interpolation_Enable :1; + CBIOS_U8 SP3_LUT_Split :1; + CBIOS_U8 reserved_0 :1; + CBIOS_U8 SP3_CRT_Gamma :2; + CBIOS_U8 reserved_1 :1; + CBIOS_U8 SP3_TV_Gamma :2; + }; +}REG_CRAB; + + +typedef union _REG_CRAC //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 CLUT3_Select :1; + CBIOS_U8 Signature_Test_Data_Source :1; + CBIOS_U8 reserved :3; + CBIOS_U8 CLUT3_Configuration :2; + CBIOS_U8 Controller3_DAC_Blank_Power_Down :1; + }; +}REG_CRAC; + + +typedef union _REG_CRB0 //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :8; + }; +}REG_CRB0; + + +typedef union _REG_CRB1 //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRB1; + + +typedef union _REG_CRB4 //PLL_DCLK3_parameter_setting +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PLL_DCLK3_R :2; + CBIOS_U8 Reserved_7to2 :6; + }; +}REG_CRB4; + + +typedef union _REG_CRB5 //PLL_DCLK3_parameter_setting +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PLL_DCLK3_integer_M :8; + }; +}REG_CRB5; + + +typedef union _REG_CRB6 //PLL_DCLK3_parameter_setting +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PLL_DCLK3_fractional_7to0_bits :8; + }; +}REG_CRB6; + + +typedef union _REG_CRB7 //PLL_DCLK3_parameter_setting +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PLL_DCLK3_fractional_15to8_bits :8; + }; +}REG_CRB7; + + +typedef union _REG_CRB8 //PLL_DCLK3_parameter_setting +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PLL_DCLK3_fractional_19to16_bits :8; + }; +}REG_CRB8; + + +typedef union _REG_CRB9 //PLL_DCLK1_parameter_setting +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VGA2_fractional_11to4_bits :8; + }; +}REG_CRB9; + + +typedef union _REG_CRBA //PLL_DCLK1_parameter_setting +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VGA1_PLL_fractional_bits_3to0 :4; + CBIOS_U8 VGA2_fractional_3to0_bits :4; + }; +}REG_CRBA; + + +typedef union _REG_CRBB //PLL_DCLK1_parameter_setting +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VGA1_fractional_11to4_bits :8; + }; +}REG_CRBB; + + +typedef union _REG_CRBC //Primary_Stream_2_Timeout_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS2_Timeout :8; + }; +}REG_CRBC; + + +typedef union _REG_CRBD //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reseerved :8; + }; +}REG_CRBD; + + +typedef union _REG_CRBE //Secondary_Stream_2_Timeout_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SS2_Timeout_7_0 :8; + }; +}REG_CRBE; + + +typedef union _REG_CRC0_B //Pad_Pull_Up/Down_Driving_Setting_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DISP1_DQ_PS :3; + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 DISP1_DQ_NS :3; + CBIOS_U8 Reserved_1 :1; + }; +}REG_CRC0_B; + + +typedef union _REG_CRC1_B //Pad_Pull_Up/Down_Driving_Setting_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DISP1CLK_DQ_PS :3; + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 DISP1CLK_DQ_NS :3; + CBIOS_U8 Reserved_1 :1; + }; +}REG_CRC1_B; + + +typedef union _REG_CRC2_B //Frame_Buffer_Base_Address_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 FB_Base_Addr_Source :1; + CBIOS_U8 Reserved :3; + CBIOS_U8 FB_Base_Addr_A23_A20 :4; + }; +}REG_CRC2_B; + + +typedef union _REG_CRC3_B //Frame_Buffer_Base_Address_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 FB_Base_Addr_A31_A24 :8; + }; +}REG_CRC3_B; + + +typedef union _REG_CRC4_B //Pad_Pull_Up/Down_Driving_Setting_5_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 GP_DQ_PS :3; + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 GP_DQ_NS :3; + CBIOS_U8 Reserved_1 :1; + }; +}REG_CRC4_B; + + +typedef union _REG_CRC5_B //Serial_Port_3_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SPCLK3_Write :1; + CBIOS_U8 SPDAT3_Write :1; + CBIOS_U8 SPCLK3_Read :1; + CBIOS_U8 SPDAT3_Read :1; + CBIOS_U8 Serial_Port_3_Enable :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 HDCP4_I2C_port_selection :2; + }; +}REG_CRC5_B; + + +typedef union _REG_CRC6_B //Serial_Port_4_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SPCLK4 :1; + CBIOS_U8 SPDAT4_Data_Write :1; + CBIOS_U8 SPCLK4_Read :1; + CBIOS_U8 SPDAT4_Read :1; + CBIOS_U8 Serial_Port_4_Enable :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 HDCP2_I2C_port_selection :2; + }; +}REG_CRC6_B; + + +typedef union _REG_CRCE //LVDS_TESTMODE[16:9]_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 LOCKSEL :1; + CBIOS_U8 WINSEL :1; + CBIOS_U8 Testmode_4to3 :2; + CBIOS_U8 BYPASS :1; + CBIOS_U8 Testmode_7to5 :3; + }; +}REG_CRCE; + + +typedef union _REG_CRCF //PS_odd/even_line_check_control +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :4; + CBIOS_U8 Hreq_Force :1; + CBIOS_U8 Reserved_bit5 :1; + CBIOS_U8 Disable_PS1_odd_or_even_line_check :1; + CBIOS_U8 Disable_PS2_odd_or_even_line_check :1; + }; +}REG_CRCF; + + +typedef union _REG_CRD0_B //PLL_Parameter_and_DCLK2_Charge_Pump_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK1_fractional_function_en :1; + CBIOS_U8 DCLK1_Band :1; + CBIOS_U8 DCLK1_PLL_clk_output_enable :1; + CBIOS_U8 DCLK1_CP_Current :3; + CBIOS_U8 DCLK1_DIV_SEL :2; + }; +}REG_CRD0_B; + + +typedef union _REG_CRD1_B //PLL_DCLK2_Parameter_and_Charge_Pump_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK2_fractional_function_en :1; + CBIOS_U8 DCLK2_Band :1; + CBIOS_U8 DCLK2_PLL_CLK_output_enable :1; + CBIOS_U8 DCLK2_CP_Current :3; + CBIOS_U8 DCLK2_DIV_SEL :2; + }; +}REG_CRD1_B; + + +typedef union _REG_CRD2_B //PLL_DCLK3_Parameter_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK3_fractional_function_en :1; + CBIOS_U8 DCLK3_Band :1; + CBIOS_U8 DCLK3_PLL_CLK_output_enable :1; + CBIOS_U8 DCLK3_CP_Current :3; + CBIOS_U8 DCLK3_DIV_SEL :2; + }; +}REG_CRD2_B; + + +typedef union _REG_CRD6 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRD6; + + +typedef union _REG_CRD7 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRD7; + + +typedef union _REG_CRD8 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRD8; + + +typedef union _REG_CRD9 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRD9; + + +typedef union _REG_CRDA // +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VPLL_Band_Sel :1; + CBIOS_U8 VPLL_CKOUT1_DIVN :2; + CBIOS_U8 VPLL_PU_Down :1; + CBIOS_U8 reserved_1 :4; + }; +}REG_CRDA; + + +typedef union _REG_CRDA_B //GPIO2_and_THERM_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 THERM_Output_Data :1; + CBIOS_U8 THERM_Output_Enable :1; + CBIOS_U8 THERM_Input_Enable :1; + CBIOS_U8 THERM_Input_Data :1; + CBIOS_U8 GPIO2_Ouptut_Data :1; + CBIOS_U8 GPIO2_Output_Enable :1; + CBIOS_U8 GPIO2_Input_Enable :1; + CBIOS_U8 GPIO2_Input_Data :1; + }; +}REG_CRDA_B; + + +typedef union _REG_CRDB // +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved_1 :3; + CBIOS_U8 VPLL_Fraction_EN :1; + CBIOS_U8 reserved_2 :4; + }; +}REG_CRDB; + + +typedef union _REG_CRDD // +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 EPLL_Band_Sel :1; + CBIOS_U8 EPLL_CKOUT1_DIVN :2; + CBIOS_U8 EPLL_PU_Down :1; + CBIOS_U8 reserved_1 :4; + }; +}REG_CRDD; + + +typedef union _REG_CRDE // +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved_1 :3; + CBIOS_U8 EPLL_Fraction_EN :1; + CBIOS_U8 reserved_2 :4; + }; +}REG_CRDE; + + +typedef union _REG_CRE0 //VPLL +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VPLL_SW_CTRL :1; + CBIOS_U8 VPLL_SW_LOAD :1; + CBIOS_U8 VPLL_RST_DOWN :1; + CBIOS_U8 Reserved :5; + }; +}REG_CRE0; + + +typedef union _REG_CRE0_B //DAC_Output_Current_Select_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 MTEST2 :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 M_PLL_Select :1; + CBIOS_U8 DAC1_Output_Select :1; + CBIOS_U8 Reserved_4 :3; + CBIOS_U8 Reserved_7 :1; + }; +}REG_CRE0_B; + + +typedef union _REG_CRE1 //Reserved_3_Bytes +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRE1; + + +typedef union _REG_CRE2 //EPLL +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 EPLL_SW_CTRL :1; + CBIOS_U8 EPLL_SW_LOAD :1; + CBIOS_U8 EPLL_RST_DOWN :1; + CBIOS_U8 LOAD_ECLK :1; + CBIOS_U8 EPLL_DISABLE :1; + CBIOS_U8 LUT_MMIO_EN :1; + CBIOS_U8 Reserved :2; + }; +}REG_CRE2; + + +typedef union _REG_CRE3_B //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 RESERVED :8; + }; +}REG_CRE3_B; + + +typedef union _REG_CRE4 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 LUT1_BIT_width :2; + CBIOS_U8 Reserved :6; + }; +}REG_CRE4; + + +typedef union _REG_CRE4_B //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :8; + }; +}REG_CRE4_B; + + +typedef union _REG_CRE5 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRE5; + + +typedef union _REG_CRE5_B //EOCLK_PLL_R_and_PLL_Load_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PLL_DCLK2_fractional_19to16_bit :4; + CBIOS_U8 RESERVED_7to4 :4; + }; +}REG_CRE5_B; + + +typedef union _REG_CRE6 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRE6; + + +typedef union _REG_CRE7 //FIFO_Underflow_Indicators_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS1FF_Underflow :1; + CBIOS_U8 PS2FF_Underflow :1; + CBIOS_U8 SS1FF_Underflow :1; + CBIOS_U8 SS2FF_Underflow :1; + CBIOS_U8 HWC1FF_Underflow :1; + CBIOS_U8 HWC2FF_Underflow :1; + CBIOS_U8 PS3FF_Underflow :1; + CBIOS_U8 SS3FF_Underflow :1; + }; +}REG_CRE7; + + +typedef union _REG_CRE8 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HWC3FF_Underflow :1; + CBIOS_U8 TVW_ACK_fake_flag :1; + CBIOS_U8 Reserved :6; + }; +}REG_CRE8; + + +typedef union _REG_CRE8_B //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved :8; + }; +}REG_CRE8_B; + + +typedef union _REG_CRE9 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRE9; + + +typedef union _REG_CREA_CREB //Reserved_2_Bytes +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CREA_CREB; + + +typedef union _REG_CREC_B //DCLK1_PLL_Fractional_M_bit_9_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK_1_M_Fractional_bit15to8 :8; + }; +}REG_CREC_B; + + +typedef union _REG_CRED_CREF //Reserved_3_Bytes +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRED_CREF; + + +typedef union _REG_CRF1 //IGA1/IGA2_Pixel_Repetition_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 reserved_0 :1; + CBIOS_U8 reserved_1 :1; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 IGA2_Pixel_Repetition :2; + CBIOS_U8 IGA1_Pixel_Repetition :2; + }; +}REG_CRF1; + + +typedef union _REG_CRF2_B //PLL_DCLK2_Parameter_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PLL_DCLK2_fractional_value :8; + }; +}REG_CRF2_B; + + +typedef union _REG_CRF3_CRF4 //Reserved_2_Bytes +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRF3_CRF4; + + +typedef union _REG_CRF5 //Time_Out_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS1_Timeout :1; + CBIOS_U8 PS2_Timeout :1; + CBIOS_U8 SS1_Timeout :1; + CBIOS_U8 SS2_Timeout :1; + CBIOS_U8 Disable_High_Request :1; + CBIOS_U8 reserved :1; + CBIOS_U8 RESERVED_7to6 :2; + }; +}REG_CRF5; + + +typedef union _REG_CRF5_B //Spread_Spectrum_Control_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SSC_Frequency_Control :5; + CBIOS_U8 SSC_Enable :1; + CBIOS_U8 DCLK1_SSC_Enable :1; + CBIOS_U8 DCLK2_SSC_Enable :1; + }; +}REG_CRF5_B; + + +typedef union _REG_CRF6 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRF6; + + +typedef union _REG_CRF6_B //Spread_Spectrum_Control_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Address_Generation_Control :5; + CBIOS_U8 SSC_LUT_Reset_Enable :1; + CBIOS_U8 External_Spread_Spectrum_Control :1; + CBIOS_U8 Clock_Output :1; + }; +}REG_CRF6_B; + + +typedef union _REG_CRF7 //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRF7; + + +typedef union _REG_CRF7_B //Spread_Spectrum_Control_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SSC_Mode :1; + CBIOS_U8 Reserved_0 :4; + CBIOS_U8 SSC_Frequency_Contro :2; + CBIOS_U8 Reserved_1 :1; + }; +}REG_CRF7_B; + + +typedef union _REG_CRF8 //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRF8; + + +typedef union _REG_CRF8_B //PWM_output_enable +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SPCLK5 :1; + CBIOS_U8 SPDAT5_Data_Write :1; + CBIOS_U8 SPCLK5_Read :1; + CBIOS_U8 SPDAT5_Read :1; + CBIOS_U8 Serial_Port_5_Enable :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 HDCP3_I2C_port_selection :2; + }; +}REG_CRF8_B; + + +typedef union _REG_CRF9_Pair //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRF9_Pair; + + +typedef union _REG_CRFA //Flat_Panel_Power_Sequence_Control_Time_Factor_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 RESERVED :7; + CBIOS_U8 Time_Factor :1; + }; +}REG_CRFA; + + +typedef union _REG_CRFB //reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 resreved :8; + }; +}REG_CRFB; + + +typedef union _REG_CRFB_B //Test_Data_Source_Select_3:0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 S3D_DEBUG_SEL_7_0 :8; + }; +}REG_CRFB_B; + + +typedef union _REG_CRFC //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SS1_Timeout_bit_7_0 :8; + }; +}REG_CRFC; + + +typedef union _REG_CRFC_B //PLL_Power_Down_and_Lock_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PLL_DCLK1_POWER_DOWN :1; + CBIOS_U8 PLL_DCLK3_Power_Down :1; + CBIOS_U8 PLL_EICLK_Power_Down :1; + CBIOS_U8 RESERVED :1; + CBIOS_U8 DPLL_Lock :1; + CBIOS_U8 D2PLL_Lock :1; + CBIOS_U8 D3PLL_Lock :1; + CBIOS_U8 EOPLL_LOCK :1; + }; +}REG_CRFC_B; + + +typedef union _REG_CRFD //Debug_Bus_Status_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Debug_Bus_Status_23to16 :8; + }; +}REG_CRFD; + + +typedef union _REG_CRFD_B +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK4_PLL_PWDN :1; + CBIOS_U8 RESERVED0 :2; + CBIOS_U8 SOFT_LOAD_D4CLK :1; + CBIOS_U8 LOAD_DCLK4 :1; + CBIOS_U8 RESERVED1 :3; + }; +}REG_CRFD_B; + + +typedef union _REG_CRFE //Debug_Bus_Status_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Debug_Bus_Status_15to8 :8; + }; +}REG_CRFE; + + +typedef union _REG_CRFE_B //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRFE_B; + + +typedef union _REG_CRFF //Debug_Bus_Status_3_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Debug_Bus_Status_7to0 :8; + }; +}REG_CRFF; + + +typedef union _REG_CRFF_B //Reserved_1_Byte +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_CRFF_B; + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_MM_registers.h b/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_MM_registers.h new file mode 100644 index 0000000000000..47cae86d522e1 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_MM_registers.h @@ -0,0 +1,3902 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +typedef union _REG_MM8180 //Cursor_3_Contrl_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor_3_Enable :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Cursor_3_Type :2; + CBIOS_U32 Cursor_3_X_Rotation :1; + CBIOS_U32 Cursor_3_Y_Rotation :1; + CBIOS_U32 Cursor_3_Size :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 Cursor_3_Display_Start_X :7; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 Cursor_3_Display_Start_Y :7; + CBIOS_U32 Reserved_3 :1; + CBIOS_U32 Cursor_3_csc_format :3; + CBIOS_U32 Cursor_3_YCbCr420_Enable :1; + CBIOS_U32 Reserved_4 :3; + CBIOS_U32 Cursor_3_mmio_reg_en :1; + }; +}REG_MM8180; + + +typedef union _REG_MM8184 //Secondary_Stream_1_Color/Chroma_8bit_Key_Lower_Bound_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_8bit_B_V_Cr_Key_Lower_Bound :8; + CBIOS_U32 SS1_8bit_G_U_Cb_Key_Lower_Bound :8; + CBIOS_U32 SS1_8bit_R_Y_Key_Lower_Bound :8; + CBIOS_U32 Reserved_8bit :8; + }; + struct + { + CBIOS_U32 SS1_10bit_B_V_Cr_Key_Lower_Bound :10; + CBIOS_U32 SS1_10bit_G_U_Cb_Key_Lower_Bound :10; + CBIOS_U32 SS1_10bit_R_Y_Key_Lower_Bound :10; + CBIOS_U32 RESERVED_10bit :2; + }; +}REG_MM8184; + + +typedef union _REG_MM8188 //Secondary_Stream_2_Color/Chroma_8bit_Key_Lower_Bound_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_8bit_B_V_Cr_Key_Lower_Bound :8; + CBIOS_U32 SS2_8bit_G_U_Cb_Key_Lower_Bound :8; + CBIOS_U32 SS2_8bit_R_Y_Key_Lower_Bound :8; + CBIOS_U32 RESERVED_8bit :8; + }; + struct + { + CBIOS_U32 SS2_10bit_B_V_Cr_Key_Lower_Bound :10; + CBIOS_U32 SS2_10bit_G_U_Cb_Key_Lower_Bound :10; + CBIOS_U32 SS2_10bit_R_Y_Key_Lower_Bound :10; + CBIOS_U32 RESERVED_10bit :2; + }; +}REG_MM8188; + + +typedef union _REG_MM818C //Secondary_Stream_2_Color/Chroma_Key_Upper_Bound_and_Key_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_V_Cr_Key_Upper_Bound :8; + CBIOS_U32 SS2_U_Cb_Key_Upper_Bound :8; + CBIOS_U32 SS2_Y_Key_Upper_Bound :8; + CBIOS_U32 SS2_Keying_Mode_Select :4; + CBIOS_U32 Invert_Alpha2_or_Ka2 :1; + CBIOS_U32 RESERVED :3; + }; +}REG_MM818C; + +typedef union _REG_MM8190 //Streams_1_&_2_Blend_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ka1_3to0_or_Ks1 :4; + CBIOS_U32 Ka1_7to4_or_Kp1 :4; + CBIOS_U32 SS1_Input_Format :3; + CBIOS_U32 SS1_YCbCr_order :1; + CBIOS_U32 RESERVED_0 :4; + CBIOS_U32 SS1_Source_Line_Width :13; + CBIOS_U32 RESERVED_1 :2; + CBIOS_U32 RESERVED_2 :1; + }; +}REG_MM8190; + + +typedef union _REG_MM8194 //Secondary_Stream_1_Chroma_Key_Upper_Bound_and_Key_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_V_Cr_Key_Upper_Bound :8; + CBIOS_U32 SS1_U_Cb_Key_Upper_Bound :8; + CBIOS_U32 SS1_Y_Key_Upper_Bound :8; + CBIOS_U32 Keying_Mode :4; + CBIOS_U32 Invert_Alpha1_or_Ka1 :1; + CBIOS_U32 RESERVED :3; + }; +}REG_MM8194; + + +typedef union _REG_MM8198 //Cursor_1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor_1_Enable :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Cursor_1_Type :2; + CBIOS_U32 Cursor_1_X_Rotation :1; + CBIOS_U32 Cursor_1_Y_Rotation :1; + CBIOS_U32 Cursor_1_Size :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 Cursor_1_Display_Start_X :7; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 Cursor_1_Display_Start_Y :7; + CBIOS_U32 Reserved_3 :1; + CBIOS_U32 Cursor_1_csc_format :3; + CBIOS_U32 Cursor_1_YCbCr420_Enable :1; + CBIOS_U32 Reserved_4 :3; + CBIOS_U32 Cursor_1_mmio_reg_en :1; + }; +}REG_MM8198; + + +typedef union _REG_MM819C //Cursor_1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor_1_X_Origin :14; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 Cursor_1_Y_Origin :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM819C; + + +typedef union _REG_MM81A0 //Cursor_1_Base_Address_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :3; + CBIOS_U32 Cursor_1_Base_Address :27; + CBIOS_U32 Cursor_1_Vsync_Off_Page_Flip :1; + CBIOS_U32 Cursor_1_Enable_Work_Registers :1; + }; +}REG_MM81A0; + + +typedef union _REG_MM81A4 //Cursor_1_Right_Frame_Base_Address_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 Cursor_1_Right_Frame_Base_Address :27; + CBIOS_U32 Reserved_1 :2; + }; +}REG_MM81A4; + +typedef union _REG_MM81A8 //Secondary_Stream_Source_Height_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_Line_Height :13; + CBIOS_U32 SS1_Buffer_Select :1; + CBIOS_U32 SS1_Double_Buffering_Select :1; + CBIOS_U32 SS1_Triple_Buffering_Enable :1; + CBIOS_U32 Reserved :16; + }; +}REG_MM81A8; + + +typedef union _REG_MM81AC //Secondary_Stream_2_Window_Size_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_Window_Height :13; + CBIOS_U32 RESERVED_0 :2; + CBIOS_U32 SS2_First_Line_Swizzle :1; + CBIOS_U32 SS2_Window_Width :13; + CBIOS_U32 RESERVED_1 :3; + }; +}REG_MM81AC; + + +typedef union _REG_MM81B0 //Primary_Stream_2_Frame_Buffer_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_Enable_Work_Registers_0 :1; + CBIOS_U32 SS2_Enable_Work_Registers :1; + CBIOS_U32 PS2_Start_Address_0 :28; + CBIOS_U32 PS2_Vsync_Off_Page_Flip :1; + CBIOS_U32 PS2_Enable_Work_Registers_1 :1; + }; +}REG_MM81B0; + + +typedef union _REG_MM81B4 //Cursor_3_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor_3_X_Origin :14; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 Cursor_3_Y_Origin :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM81B4; + + +typedef union _REG_MM81B8 //Primary_Stream_2_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 reserved_0 :1; + CBIOS_U32 PS2_ABGR_EN :1; + CBIOS_U32 PS2_First_Line_Swizzle :1; + CBIOS_U32 PS2_Work_Reg_Enable :1; + CBIOS_U32 PS2_Stride_or_Tile_Stride :12; + CBIOS_U32 PS2_Start_Address_Pixel_Offset :5; + CBIOS_U32 PS2_Tiling_X_Offset :3; + CBIOS_U32 PS2_Tiling_Line_Offset :6; + CBIOS_U32 reserved_1 :1; + CBIOS_U32 PS2_Tile_Addressing_Enable :1; + }; +}REG_MM81B8; + + +typedef union _REG_MM81BC //Secondary_Stream_2_Frame_Buffer_Start_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED :3; + CBIOS_U32 SS2_FB_Start_Address_0 :27; + CBIOS_U32 SS2_VSYNC_Off_Page_Flip :1; + CBIOS_U32 SS2_Work_Reg_En :1; + }; +}REG_MM81BC; + + +typedef union _REG_MM81C0 //Primary_Stream_1_Frame_Buffer_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_Enable_Work_Registers_0 :1; + CBIOS_U32 SS1_Enable_Work_Registers :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 PS1_Start_Address_0 :27; + CBIOS_U32 PS1_Vsync_Off_Page_Flip :1; + CBIOS_U32 PS1_Enable_Work_Registers_1 :1; + }; +}REG_MM81C0; + +typedef union _REG_MM81C4 //Cursor_3_Base_Address_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :3; + CBIOS_U32 Cursor_3_Base_Address :27; + CBIOS_U32 Cursor_3_Vsync_Off_Page_Flip :1; + CBIOS_U32 Cursor_3_Enable_Work_Registers :1; + }; +}REG_MM81C4; + + +typedef union _REG_MM81C8 //Primary_Stream_1_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 reserved :1; + CBIOS_U32 PS1_ABGR_EN :1; + CBIOS_U32 PS1_First_Line_Swizzle :1; + CBIOS_U32 PS1_Work_Reg_Enable :1; + CBIOS_U32 PS1_Stride_or_Tile_Stride :12; + CBIOS_U32 PS1_Start_Address_Pixel_Offset :5; + CBIOS_U32 PS1_Tiling_X_Offset :3; + CBIOS_U32 PS1_Tiling_Line_Offset :6; + CBIOS_U32 RESERVED :1; + CBIOS_U32 PS1_Tile_Addressing_Enable :1; + }; +}REG_MM81C8; + +typedef union _REG_MM81CC //Secondary_Stream_2_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_Read_length :2; + CBIOS_U32 RESERVED :2; + CBIOS_U32 SS2_Stride :12; + CBIOS_U32 SS2_Start_Address_Pixel_Offset :6; + CBIOS_U32 SS2_Tiling_X_Offset :3; + CBIOS_U32 SS2_Tiling_Line_Offset :6; + CBIOS_U32 SS2_ABGR_EN :1; + }; +}REG_MM81CC; + + +typedef union _REG_MM81D0 //Secondary_Stream_1_Frame_Buffer_Start_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED :3; + CBIOS_U32 SS1_FB_Start_Address_0 :27; + CBIOS_U32 SS1_VSYNC_Off_Page_Flip :1; + CBIOS_U32 SS1_Work_Reg_En :1; + }; +}REG_MM81D0; + +typedef union _REG_MM81D4 //Secondary_Stream_1_ROFFSET_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED_0 :3; + CBIOS_U32 SS1_Right_Base_Address :27; + CBIOS_U32 RESERVED_1 :2; + }; +}REG_MM81D4; + +typedef union _REG_MM81D8 //Secondary_Stream_1_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_Read_Length :2; + CBIOS_U32 RESERVED :2; + CBIOS_U32 SS1_Stride :12; + CBIOS_U32 SS1_Start_Address_Byte_Offset :6; + CBIOS_U32 SS1_Tiling_X_Offset :3; + CBIOS_U32 SS1_Tiling_Line_Offset :6; + CBIOS_U32 SS1_ABGR_EN :1; + }; +}REG_MM81D8; + +typedef union _REG_MM81DC //Secondary_Stream_Source_Width_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 KA2_3to0_or_KS2 :4; + CBIOS_U32 KA2_7to4_or_KP2 :4; + CBIOS_U32 SS2_Input_Format :3; + CBIOS_U32 SS2_YCbCr_order :1; + CBIOS_U32 RESERVED_0 :4; + CBIOS_U32 SS2_Source_Line_Width :13; + CBIOS_U32 RESERVED_1 :2; + CBIOS_U32 RESERVED_2 :1; + }; +}REG_MM81DC; + + +typedef union _REG_MM81E0 //Secondary_Stream_2_ROFFSET_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED_0 :3; + CBIOS_U32 SS2_Right_Base_Address :27; + CBIOS_U32 RESERVED_1 :2; + }; +}REG_MM81E0; + + +typedef union _REG_MM81E4 //Cursor_2_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor_2_Enable :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Cursor_2_Type :2; + CBIOS_U32 Cursor_2_X_Rotation :1; + CBIOS_U32 Cursor_2_Y_Rotation :1; + CBIOS_U32 Cursor_2_Size :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 Cursor_2_Display_Start_X :7; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 Cursor_2_Display_Start_Y :7; + CBIOS_U32 Reserved_3 :1; + CBIOS_U32 Cursor_2_csc_format :3; + CBIOS_U32 Cursor_2_YCbCr420_Enable :1; + CBIOS_U32 Reserved_4 :3; + CBIOS_U32 Cursor_2_mmio_reg_en :1; + }; +}REG_MM81E4; + + +typedef union _REG_MM81E8 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor_2_X_Origin :14; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 Cursor_2_Y_Origin :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM81E8; + + +typedef union _REG_MM81EC //Secondary_Stream_1_Frame_Buffer_Start_Address_2_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED_0 :3; + CBIOS_U32 SS1_FB_Start_Address_2 :27; + CBIOS_U32 RESERVED_1 :2; + }; +}REG_MM81EC; + + +typedef union _REG_MM81F0 //Cursor_2_Base_Address_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :3; + CBIOS_U32 Cursor_2_Base_Address :27; + CBIOS_U32 Cursor_2_Vsync_Off_Page_Flip :1; + CBIOS_U32 Cursor_2_Enable_Work_Registers :1; + }; +}REG_MM81F0; + + +typedef union _REG_MM81F4 //Cursor_2_Right_Frame_Base_Address_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 Cursor_2_Right_Frame_Base_Address :27; + CBIOS_U32 Reserved_1 :2; + }; +}REG_MM81F4; + + +typedef union _REG_MM81F8 //Secondary_Stream_1_Window_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_Y_Start :13; + CBIOS_U32 RESERVED_0 :3; + CBIOS_U32 SS1_X_Start_0 :12; + CBIOS_U32 SS1_Loading_Enable :1; + CBIOS_U32 SS1_X_Start_1 :1; + CBIOS_U32 RESERVED_1 :2; + }; +}REG_MM81F8; + + +typedef union _REG_MM81FC //Secondary_Stream1_Window_Size_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_Window_Height :13; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 SS1_First_Line_swizzle :1; + CBIOS_U32 SS1_Window_Width :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM81FC; + +typedef union _REG_MM8200 //Cursor_3_Right_Frame_Base_Address_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED_0 :3; + CBIOS_U32 Cursor_3_Right_Frame_Base_Address :27; + CBIOS_U32 RESERVED_1 :2; + }; +}REG_MM8200; + + +typedef union _REG_MM8208 //interlace_right_offset[31:2] +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 reserved :2; + CBIOS_U32 PS_INTR_ROFFSET_31_2 :30; + }; +}REG_MM8208; + + +typedef union _REG_MM820C //Secondary_Stream_2_Window_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_Y_Start :13; + CBIOS_U32 RESERVED_0 :3; + CBIOS_U32 SS2_X_Start_0 :12; + CBIOS_U32 SS2_Loading_Enable :1; + CBIOS_U32 SS2_X_Start_1 :1; + CBIOS_U32 RESERVED_1 :2; + }; +}REG_MM820C; + + +typedef union _REG_MM8210 //DP_NVID_amd_MISC1_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 NVID :24; + CBIOS_U32 MISC1_Even :1; + CBIOS_U32 MISC1_Stereo_Video :2; + CBIOS_U32 MISC1_Reserved :5; + }; +}REG_MM8210; + + +typedef union _REG_MM8214 //DP_Link_Training_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Start_Link_Training :1; + CBIOS_U32 Start_Link_Rate_0 :1; + CBIOS_U32 Max_V_swing :2; + CBIOS_U32 Max_Pre_emphasis :2; + CBIOS_U32 SW_Hpd_assert :1; + CBIOS_U32 Num_of_Lanes :3; + CBIOS_U32 SW_Link_Train_Enable :1; + CBIOS_U32 SW_Link_Train_State :2; + CBIOS_U32 Software_Bit_Rate :1; + CBIOS_U32 SW_Lane0_Swing :2; + CBIOS_U32 SW_Lane0_Pre_emphasis :2; + CBIOS_U32 SW_Lane1_Swing :2; + CBIOS_U32 SW_Lane1_Pre_emphasis :2; + CBIOS_U32 SW_Lane2_Swing :2; + CBIOS_U32 SW_Lane2_Pre_emphasis :2; + CBIOS_U32 SW_Lane3_Swing :2; + CBIOS_U32 SW_Lane3_Pre_emphasis :2; + CBIOS_U32 SW_Set_Link_Train_Fail :1; + CBIOS_U32 HW_Link_Training_Done :1; + }; +}REG_MM8214; + + +typedef union _REG_MM8218 //DP_Video_Input_Select_and_General_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Scramble_enable :1; + CBIOS_U32 Switch_Idle_mode_to_video :1; + CBIOS_U32 Idle_Pattern_Counter :9; + CBIOS_U32 AUX_Length :5; + CBIOS_U32 Audio_Strm_Select :1; + CBIOS_U32 HW_Link_Train_Fail :1; + CBIOS_U32 Min_AUX_SYNC_Count :6; + CBIOS_U32 DELAY :6; + CBIOS_U32 reseved :2; + }; +}REG_MM8218; + + +typedef union _REG_MM821C //DP_Version_and_Extension_Packet_Head_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ext_Pkt_Head :24; + CBIOS_U32 Ext_Pkt_ID_value :4; + CBIOS_U32 RESEVERD :2; + CBIOS_U32 Horizontal_Width_bit12to11 :2; + }; +}REG_MM821C; + +typedef union _REG_MM8220 //Primary_Stream_1_Display_Position_Frame_Line_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_Frame_Counter :16; + CBIOS_U32 PS1_Line_Counter :16; + }; +}REG_MM8220; + + +typedef union _REG_MM8224 //Primary_Stream_1_Display_Position_Line_Pixel_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_Line_Counter :16; + CBIOS_U32 PS1_Pixel_Counter :16; + }; +}REG_MM8224; + + +typedef union _REG_MM8828 //Primary_Stream_1_Top_Left_Pixel_Line_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_Top_Left_Line :16; + CBIOS_U32 PS1_Top_Leftt_Pixel :16; + }; +}REG_MM8828; + + +typedef union _REG_MM822C //Primary_Stream_1_Bottom_Right_Pixel_Line_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_Bottom_Right_Line :16; + CBIOS_U32 PS1_Bottom_Right_Pixel :16; + }; +}REG_MM822C; + + +typedef union _REG_MM8230 //Primary_Stream_2_Display_Position_Frame_Line_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_Frame_Counter :16; + CBIOS_U32 PS2_Line_Counter :16; + }; +}REG_MM8230; + + +typedef union _REG_MM8234 //Primary_Stream_2_Display_Position_Line_Pixel_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_Line_Counter :16; + CBIOS_U32 PS2_Pixel_Counter :16; + }; +}REG_MM8234; + + +typedef union _REG_MM8238 //Primary_Stream_2_VDC_Top_Left_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_Top_Left_Line :16; + CBIOS_U32 PS2_Top_Leftt_Pixel :16; + }; +}REG_MM8238; + + +typedef union _REG_MM823C //Primary_Stream_2_VDC_Bottom_Right_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_Bottom_Right_Line :16; + CBIOS_U32 PS2_Bottom_Right_Pixel :16; + }; +}REG_MM823C; + + +typedef union _REG_MM8240 //DP_Display_Port_Enable_and_InfoFrame_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DP_Enable :1; + CBIOS_U32 Field_Invert :1; + CBIOS_U32 Enhanced_Framing_Mode :1; + CBIOS_U32 Video_Enable :1; + CBIOS_U32 InfoFrame_FIFO_1_Ready :1; + CBIOS_U32 INFOFRAME_FIFO_2_READY :1; + CBIOS_U32 InfoFrame_FIFO_Select :1; + CBIOS_U32 InfoFrame_FIFO_1_Start_Address :4; + CBIOS_U32 InfoFrame_FIFO_2_Start_Address :4; + CBIOS_U32 InfoFrame_FIFO_1_Length :4; + CBIOS_U32 InfoFrame_FIFO_2_Length :4; + CBIOS_U32 Ext_Packet_Enable :1; + CBIOS_U32 Enable_Audio :1; + CBIOS_U32 Generate_MVID :1; + CBIOS_U32 output_format_is_BIAS_RGB :1; + CBIOS_U32 header_of_audio_info_frame_is_from_HDAudio_codec :1; + CBIOS_U32 Main_Link_Status :2; + CBIOS_U32 Link_Qual_Pattern_Set :2; + }; +}REG_MM8240; + + +typedef union _REG_MM8244 //DP_Horizontal_Width_and_TU_Size_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Horiz_Width :11; + CBIOS_U32 TU_Size :6; + CBIOS_U32 TU_Ratio :15; + }; +}REG_MM8244; + + +typedef union _REG_MM8248 //DP_Horizontal_Line_Duration_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Horiz_Line_Duration :15; + CBIOS_U32 HBLANK_Duration :12; + CBIOS_U32 Ext_Packet_Byte_Num :4; + CBIOS_U32 Ext_Packet_Available :1; + }; +}REG_MM8248; + + +typedef union _REG_MM824C //DP_MVID_and_MISC0_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MVID :24; + CBIOS_U32 MISC0_Sync_Clk :1; + CBIOS_U32 MISC0_Component_Format :2; + CBIOS_U32 MISC0_Dynamic_Range :1; + CBIOS_U32 MISC0_YCbCr_Colorimetry :1; + CBIOS_U32 MISC0_Bit_depth :3; + }; +}REG_MM824C; + + +typedef union _REG_MM8250 //DP_HTOTAL_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 H_Total :16; + CBIOS_U32 V_Total :16; + }; +}REG_MM8250; + + +typedef union _REG_MM8254 //DP_Horiz_Vert_Start_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 H_Start :16; + CBIOS_U32 V_Start :16; + }; +}REG_MM8254; + + +typedef union _REG_MM8258 //DP_Polarity/Width_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HSYNC_Width :15; + CBIOS_U32 HSYNC_Polarity :1; + CBIOS_U32 VSYNC_Width :15; + CBIOS_U32 VSYNC_Polarity :1; + }; +}REG_MM8258; + + +typedef union _REG_MM825C //DP_Polarity/Width_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Acitve_Width :16; + CBIOS_U32 Active_Height :16; + }; +}REG_MM825C; + + +typedef union _REG_MM8260 //DSCL/Write_back_csc_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_Line_Height :13; + CBIOS_U32 SS2_Buffer_Select :1; + CBIOS_U32 SS2_Double_Buffering_Select :1; + CBIOS_U32 SS2_Triple_Buffering_Enable :1; + CBIOS_U32 Reserved :16; + }; +}REG_MM8260; + + +typedef union _REG_MM8264 //DSCL/Write_back_csc_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 dscl_write_back_src_sel :1; + CBIOS_U32 CSC_DATA_IN_FMT :3; + CBIOS_U32 CSC_DATA_OUT_FMT :3; + CBIOS_U32 CSC_PROGRAMMBLE :1; + CBIOS_U32 CSC_BRIGHT :9; + CBIOS_U32 CSC_COEF_F9 :14; + CBIOS_U32 Reserved_31 :1; + }; +}REG_MM8264; + + +typedef union _REG_MM8268 //DSCL/Write_back_csc_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CSC_COEF_F3 :14; + CBIOS_U32 CSC_COEF_F4 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM8268; + + +typedef union _REG_MM826C //DSCL/Write_back_csc_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CSC_COEF_F5 :14; + CBIOS_U32 CSC_COEF_F6 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM826C; + + +typedef union _REG_MM8270 //Primary_Stream_1_Right_Frame_Offset_Address_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ps1_Right_Frame_Base :30; + CBIOS_U32 RESERVED :2; + }; +}REG_MM8270; + + +typedef union _REG_MM8274 //Primary_Stream_2_Right_Frame_Offset_Address_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ps2_Right_Frame_Base :30; + CBIOS_U32 RESERVED :2; + }; +}REG_MM8274; + + +typedef union _REG_MM8278 //Secondary_Stream_1_Horizontal_Scaling_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_HACC :21; + CBIOS_U32 SS1_HTAP_SEL :1; + CBIOS_U32 RESERVED :10; + }; +}REG_MM8278; + + +typedef union _REG_MM827C //Secondary_Stream_2_Horizontal_Scaling_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_HACC :21; + CBIOS_U32 SS2_HTAP_SEL :1; + CBIOS_U32 RESERVED :10; + }; +}REG_MM827C; + + +typedef union _REG_MM8280 //HDMI1_General_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDMI_Reset :1; + CBIOS_U32 HDMI_Enable :1; + CBIOS_U32 Deep_Color_Mode :2; + CBIOS_U32 reserved :1; + CBIOS_U32 Video_Clip :1; + CBIOS_U32 DVI_Mode_during_HDMI_Enable :1; + CBIOS_U32 TMDS_Video_Pixel_Format_Select :2; + CBIOS_U32 Convert_to_YCbCr422_Enable :1; + CBIOS_U32 HSYNC_Invert_Enable :1; + CBIOS_U32 HDMI_Debug_Bus_Select :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 VSYNC_Invert_Enable :1; + CBIOS_U32 Reserved_15to14 :2; + CBIOS_U32 Delay_for_HDCP :7; + CBIOS_U32 Delay_for_HDCP_SEL :1; + CBIOS_U32 Transmit_Between_AE_300_Enable :1; + CBIOS_U32 Transmit_Between_385_507_Enable :1; + CBIOS_U32 Transmit_After_650_Enable :1; + CBIOS_U32 STATUS_OF_HDMI_STATION_MACHINE :5; + }; +}REG_MM8280; + + +typedef union _REG_MM8284 //HDMI1__InfoFrame_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 InfoFrame_FIFO_2_Select :1; + CBIOS_U32 InfoFrame_FIFO_1_Ready :1; + CBIOS_U32 INFOFRAME_FIFO_2_READY :1; + CBIOS_U32 INFO_VSYNC_EN :1; + CBIOS_U32 InfoFrame_FIFO_1_Start_Address :4; + CBIOS_U32 InfoFrame_FIFO_1_Length :5; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 InfoFrame_FIFO_2_Start_Address :4; + CBIOS_U32 InfoFrame_FIFO_2_Length :5; + CBIOS_U32 Reserved_1 :3; + CBIOS_U32 Horiz_Blank_Max_Packets :4; + }; +}REG_MM8284; + + +typedef union _REG_MM8288 //HD_Audio_Codec_Status_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :25; + CBIOS_U32 Int_Src_Codec :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 Reserved_2 :5; + }; +}REG_MM8288; + + +typedef union _REG_MM828C //Secondary_Stream_1_Vertical_Scaling_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_VACC :21; + CBIOS_U32 SS1_Vscale_Selection :1; + CBIOS_U32 SS1_VDUP :1; + CBIOS_U32 RESERVED :8; + CBIOS_U32 SS1_Deinterlacing :1; + }; +}REG_MM828C; + + +typedef union _REG_MM8290 //Secondary_Stream_1_Frame_Buffer_Start_Address_1_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 SS1_FB_Start_Address_1 :27; + CBIOS_U32 Reserved_1 :2; + }; +}REG_MM8290; + + +typedef union _REG_MM8294 //HDMI1_Audio_Insert_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Select_HDMI_Audio_Source :1; + CBIOS_U32 HDMI_Audio_Enable :1; + CBIOS_U32 Set_AVMUTE_Enable :1; + CBIOS_U32 Clear_AVMUTE_Enable :1; + CBIOS_U32 HDAUDIO_Stream1_Threshold :6; + CBIOS_U32 HDAUDIO_Stream2_Threshold :6; + CBIOS_U32 Reserved :1; + CBIOS_U32 DC_Gen_Cntl_Pkt_EN :1; + CBIOS_U32 SW_PP :4; + CBIOS_U32 PP_SELECT :1; + CBIOS_U32 CD :4; + CBIOS_U32 Default_Phase :1; + CBIOS_U32 ACR_ratio_select :1; + CBIOS_U32 RIRB_WPTR_INC_SEL :1; + CBIOS_U32 Reserved_31to30 :2; + }; +}REG_MM8294; + + +typedef union _REG_MM8298 //HDAUDIO_CODEC1_Audio_Packet_to_Clock_Ratio_Register_1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CODEC1_Audio_Packet_to_DClk_Ratio_31to0 :32; + }; +}REG_MM8298; + + +typedef union _REG_MM829C //HDAUDIO_CODEC1_Audio_Packet_to_Clock_Ratio_Register_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CODEC1_Audio_Packet_to_DClk_Ratio_39to32 :8; + CBIOS_U32 CODEC1_ACR_ratio :20; + CBIOS_U32 CODEC1_ACR_ENABLE :1; + CBIOS_U32 CODEC1_MUTE_EN :1; + CBIOS_U32 CODEC1_WAKE_FROM_S3 :1; + CBIOS_U32 CODEC1_SW_RESET :1; + }; +}REG_MM829C; + + +typedef union _REG_MM82A0 //HDAUDIO_CODEC1_Audio_Mode_and_Response_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HD_AUDIO_MODE_SELECT :1; + CBIOS_U32 ResP_generation :1; + CBIOS_U32 Resp_Ready :1; + CBIOS_U32 Send_UNSOLRESP :1; + CBIOS_U32 HDAUDIO_CODEC1_Enable :1; + CBIOS_U32 up_Sample_incoming_audio :4; + CBIOS_U32 Driver_ready :1; + CBIOS_U32 Ignore_driver_ready :1; + CBIOS_U32 Down_sample_incoming_audio_factor :4; + CBIOS_U32 Use_SW_Stream_Format :1; + CBIOS_U32 SW_Stream_Format :16; + }; +}REG_MM82A0; + + +typedef union _REG_MM82A4 //HDAUDIO_CODEC1_Command_Field_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDA_HDMI_CMD_Verb :20; + CBIOS_U32 NID :8; + CBIOS_U32 Cad :4; + }; +}REG_MM82A4; + + +typedef union _REG_MM82A8 //HDAUDIO_CODEC1_Software_Response_Field_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Response :32; + }; +}REG_MM82A8; + + +typedef union _REG_MM82AC //HDAUDIO_CODEC1_Speaker_Allocation_and_Channel_Status_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 ELD_READ_Status :1; + CBIOS_U32 DIP_WRITE_Status :1; + CBIOS_U32 DIP_READ_Status :1; + CBIOS_U32 HDA_Setconvert_Int_Status :1; + CBIOS_U32 HDA_Cpcontrol_Int_Status :1; + CBIOS_U32 SET_CONVERTER1_DigiConvert3_INT_Status :1; + CBIOS_U32 SET_FunGroup_PowerState_INT_status :1; + CBIOS_U32 Set_ELD_Default :1; + CBIOS_U32 sample_flat :1; + CBIOS_U32 Always_Output_Audio :1; + CBIOS_U32 multiple_sample :1; + CBIOS_U32 faudio_selsect :1; + CBIOS_U32 Ratio_CLK_Select :1; + CBIOS_U32 Codec_Type :3; + CBIOS_U32 Reserved_bits_18to16 :3; + CBIOS_U32 BCIS_SEL :1; + CBIOS_U32 Reserved_bits_23to20 :4; + CBIOS_U32 ELD_Use_LUT :1; + CBIOS_U32 Enable_Transmit_DIP_Packet :1; + CBIOS_U32 Enable_HDA_POS_CTR :1; + CBIOS_U32 Converter_Stream_Channel :1; + CBIOS_U32 CP_Control_CES_State :1; + CBIOS_U32 CP_Control_Ready_Status :1; + CBIOS_U32 Channel_status_control :2; + }; +}REG_MM82AC; + + +typedef union _REG_MM82B0 //HDCP1_Key_Selection_Vector_(KSV)_Register_1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 KSV_39to8 :32; + }; +}REG_MM82B0; + + +typedef union _REG_MM82B4 //HDCP1_Control_1_and_Key_Selection_Vector_(KSV)_2_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 KSV_7to0 :8; + CBIOS_U32 Read_Data :8; + CBIOS_U32 Write_Data :8; + CBIOS_U32 Source_Select :2; + CBIOS_U32 Test_Key_Enable :1; + CBIOS_U32 CP_EN :1; + CBIOS_U32 Mode_Sel :1; + CBIOS_U32 AC_EN :1; + CBIOS_U32 Verify_Pj_Enable :1; + CBIOS_U32 EESS_Signaling_Select :1; + }; +}REG_MM82B4; + + +typedef union _REG_MM82B8 //HDCP1_Control_2_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDCP_I2C_Function_Enable :1; + CBIOS_U32 SW_Request_I2C_Access :1; + CBIOS_U32 HDCP_Test_Mode_Select :1; + CBIOS_U32 Write_Data_Available :1; + CBIOS_U32 START_Request :1; + CBIOS_U32 STOP_REQUEST :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 READ_Finished :1; + CBIOS_U32 KSV_Revocation_List_Available :1; + CBIOS_U32 KSV_Verification_Done :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 I2C_Status :1; + CBIOS_U32 Authentication_Protocol_Status :2; + CBIOS_U32 Reserved_2 :2; + CBIOS_U32 EFUSE_read_Address :7; + CBIOS_U32 Reserved_3 :9; + }; +}REG_MM82B8; + + +typedef union _REG_MM82BC //Efuse_Read_Data +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Efuse_Read_Data :32; + }; +}REG_MM82BC; + + +typedef union _REG_MM82C0 //HDCP1_Slave_receiver_not_ready_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :24; + CBIOS_U32 Slave_Receiver_Not_Ready :1; + CBIOS_U32 EFUSE_read_request :1; + CBIOS_U32 Reserved_1 :2; + CBIOS_U32 efuse_mode :3; + CBIOS_U32 Reserved_2 :1; + }; +}REG_MM82C0; + + +typedef union _REG_MM82C4 //HDCP1_Miscellaneous_1_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Interrupt_Source :4; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 AUTH_FAIL_INT_SEL :1; + CBIOS_U32 HDCP_SW_Reset :1; + CBIOS_U32 Repeater_Flag :1; // 0: receiver, 1: repeater + CBIOS_U32 Device_Count :7; + CBIOS_U32 Reserved_1 :3; + CBIOS_U32 CTL :4; // 1: Encryption is disabled for this frame, 9: Encryption is enabled for this frame + CBIOS_U32 I2C_Frequency_Sleect :3; + CBIOS_U32 reserved :1; + CBIOS_U32 Disable_hamming_decoder :1; + CBIOS_U32 Reserved_2 :4; + }; +}REG_MM82C4; + + +typedef union _REG_MM82C8 //HDCP1_Miscellaneous_Register_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RI_Verification_Counter :4; + CBIOS_U32 OW_Config :3; + CBIOS_U32 Re_Auth_Off :1; + CBIOS_U32 Auto_Detect_I2C_Off :1; + CBIOS_U32 CTL_Select :1; + CBIOS_U32 Not_support_0_KSV_repeater :1; + CBIOS_U32 No_check_KSV_list_ready :1; + CBIOS_U32 Reserved_14to12 :3; + CBIOS_U32 Read_Out_AKSV :1; + CBIOS_U32 HDCP1_Interrupt :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Reserved_1 :2; + CBIOS_U32 command_buffer_nfull :1; + CBIOS_U32 command_buffer_nempty :1; + CBIOS_U32 Reserved_2 :2; + CBIOS_U32 Reserved_3 :1; + CBIOS_U32 DRV_EFUSE_RWL :1; + CBIOS_U32 DRV_EFUSE_RWL_SEL :1; + CBIOS_U32 reserved :1; + CBIOS_U32 DRV_EFUSE_RSB :1; + CBIOS_U32 Reserved_4 :3; + }; +}REG_MM82C8; + +typedef union _REG_MM82CC //DP1_control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TX0T :3; + CBIOS_U32 TX1T :3; + CBIOS_U32 TX2T :3; + CBIOS_U32 TX3T :3; + CBIOS_U32 DIAJ_L0 :3; + CBIOS_U32 DIAJ_L1 :3; + CBIOS_U32 DIAJ_L2 :3; + CBIOS_U32 DIAJ_L3 :3; + CBIOS_U32 DIU_EPHY1_AUX_DIAJ :1; + CBIOS_U32 check_sync_cnt :1; + CBIOS_U32 int_mode :1; + CBIOS_U32 RST_PISO_EN :1; + CBIOS_U32 CR2EQ_WR02_ONLY :1; + CBIOS_U32 EN_DEFER_LT8 :1; + CBIOS_U32 EDP_ASSR :1; + CBIOS_U32 DP_Clock_Debug :1; + }; +}REG_MM82CC; + + +typedef union _REG_MM82D0 //HDAUDIO_CODEC1_Vendor_ID_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Device_ID :16; + CBIOS_U32 Vendor_ID :16; + }; +}REG_MM82D0; + + +typedef union _REG_MM82D4 //HDAUDIO_CODEC1_Revision_ID_and_Support_Parameters_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Stepping_ID :8; + CBIOS_U32 Revision_ID :8; + CBIOS_U32 MinRev :4; + CBIOS_U32 MajRev :4; + CBIOS_U32 PCM_Support :1; + CBIOS_U32 PCM_Float32_Only_Support :1; + CBIOS_U32 AC3_16_bit_only_Support :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 SuppPowerState_D0Sup :1; + CBIOS_U32 SuppPowerState_D1Sup :1; + CBIOS_U32 SuppPowerState_D2Sup :1; + CBIOS_U32 SuppPowerState_D3Sup :1; + }; +}REG_MM82D4; + + +typedef union _REG_MM82D8 //HDAUDIO_CODEC1_Function_Group_Subordinate_Node_Count_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FunGroup_Sub_Node_Count_Total :8; + CBIOS_U32 Reserved_15to8 :8; + CBIOS_U32 FunGroup_Sub_Node_Start_Num :8; + CBIOS_U32 Reserved_31to24 :8; + }; +}REG_MM82D8; + + +typedef union _REG_MM82DC //HDAUDIO_CODEC1_Audio_Function_Group_Type_and_Capability_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AFGC_Output_Delay :4; + CBIOS_U32 Reserved_7to4 :4; + CBIOS_U32 AFGC_Input_Delay :4; + CBIOS_U32 Reserved_15to12 :4; + CBIOS_U32 AFGC_BeepGen :1; + CBIOS_U32 Reserved :2; + CBIOS_U32 _7_3_4_12_EPSS :1; + CBIOS_U32 _7_3_4_12_CLKSTOP :1; + CBIOS_U32 _7_3_4_12_S3D3coldSup :1; + CBIOS_U32 _7_3_4_12_D3COLDSUP :1; + CBIOS_U32 AFGT_NodeType :8; + CBIOS_U32 AFGT_UnSol_Capable :1; + }; +}REG_MM82DC; + + +typedef union _REG_MM82E0 //HDAUDIO_CODEC1_PCM_Size_and_Sample_Rate_Capability_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 R1 :1; + CBIOS_U32 R2 :1; + CBIOS_U32 R3 :1; + CBIOS_U32 R4 :1; + CBIOS_U32 R5 :1; + CBIOS_U32 R6 :1; + CBIOS_U32 R7 :1; + CBIOS_U32 R8 :1; + CBIOS_U32 R9 :1; + CBIOS_U32 R10 :1; + CBIOS_U32 R11 :1; + CBIOS_U32 R12 :1; + CBIOS_U32 Reserved_15to12 :4; + CBIOS_U32 B8 :1; + CBIOS_U32 B16 :1; + CBIOS_U32 B20 :1; + CBIOS_U32 B24 :1; + CBIOS_U32 B32 :1; + CBIOS_U32 Reserved_31to21 :11; + }; +}REG_MM82E0; + + +typedef union _REG_MM82E4 //HDAUDIO_CODEC1_Output_Amplifier_Capability_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 OutputAmpC_Offset :7; + CBIOS_U32 Reserved_7 :1; + CBIOS_U32 OutputAmpC_NumSteps :7; + CBIOS_U32 Reserved_15 :1; + CBIOS_U32 OutputAmpC_StepSize :7; + CBIOS_U32 Reserved_30to23 :8; + CBIOS_U32 OutputAmpC_Mute_Capable :1; + }; +}REG_MM82E4; + + +typedef union _REG_MM82E8 //HDAUDIO_CODEC1_Functional_Group_Subsystem_ID_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FunGroup__SubsystemID_SSID :32; + }; +}REG_MM82E8; + + +typedef union _REG_MM82EC //HDAUDIO_CODEC1_Converter1_Audio_Widget_Capatibility_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Stereo :1; + CBIOS_U32 In_Amp_Present :1; + CBIOS_U32 Out_Amp_Present :1; + CBIOS_U32 Amp_Param_Override :1; + CBIOS_U32 Format_Override :1; + CBIOS_U32 Stripe :1; + CBIOS_U32 Proc_Widget :1; + CBIOS_U32 Unsol_Capable :1; + CBIOS_U32 Conn_List :1; + CBIOS_U32 Digital :1; + CBIOS_U32 Power_Cntrl :1; + CBIOS_U32 L_R_Swap :1; + CBIOS_U32 Reserved_15to12 :4; + CBIOS_U32 Delay :4; + CBIOS_U32 Type :4; + CBIOS_U32 Reserved_31to24 :8; + }; +}REG_MM82EC; + + +typedef union _REG_MM82F0 //HDAUDIO_CODEC1_PinWidget1_Audio_Widget_Capability_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Stereo :1; + CBIOS_U32 In_Amp_Present :1; + CBIOS_U32 Out_Amp_Present :1; + CBIOS_U32 Amp_Param_Override :1; + CBIOS_U32 Format_Override :1; + CBIOS_U32 Stripe :1; + CBIOS_U32 Proc_Widget :1; + CBIOS_U32 Unsol_Capable :1; + CBIOS_U32 Conn_List :1; + CBIOS_U32 Digital :1; + CBIOS_U32 Power_Cntrl :1; + CBIOS_U32 L_R_Swap :1; + CBIOS_U32 Reserved_15to12 :4; + CBIOS_U32 Delay :4; + CBIOS_U32 Type :4; + CBIOS_U32 Reserved_31to24 :8; + }; +}REG_MM82F0; + + +typedef union _REG_MM82F4 //HDAUDIO_CODEC1_PinWidget1_Pin_Capability_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Impedance_Sense_Capable :1; + CBIOS_U32 Trigger_Reqd :1; + CBIOS_U32 Presense_Detect_Capable :1; + CBIOS_U32 Headphone_Drive_Capable :1; + CBIOS_U32 Output_Capable :1; + CBIOS_U32 Input_Capable :1; + CBIOS_U32 Balanced_IO_Pins :1; + CBIOS_U32 HDMI :1; + CBIOS_U32 Vref_Control_0_Hi_Z :1; + CBIOS_U32 Vref_Control_1_50_percent :1; + CBIOS_U32 Vref_Control_2_Ground :1; + CBIOS_U32 Vref_Control_3_Reserved :1; + CBIOS_U32 Vref_Control_4_80_percent :1; + CBIOS_U32 Vref_Control_5_100_percent :1; + CBIOS_U32 Vref_Control_7to6_Reserved :2; + CBIOS_U32 EAPD_Capable :1; + CBIOS_U32 Reserved_31to17 :15; + }; +}REG_MM82F4; + + +typedef union _REG_MM82F8 //HDAUDIO_CODEC1_PinWidget1_Configuration_Default_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Config_Default_Sequence :4; + CBIOS_U32 Config_Default_Default_Assn :4; + CBIOS_U32 Config_Default_Misc :4; + CBIOS_U32 Config_Default_Color :4; + CBIOS_U32 Config_Default_Connect_Type :4; + CBIOS_U32 Config_Default_Default_Device :4; + CBIOS_U32 Config_Default_Location_low_bits :4; + CBIOS_U32 Config_Default_Location_hi_bits :2; + CBIOS_U32 Config_Default_Port_Connectivity :2; + }; +}REG_MM82F8; + + +typedef union _REG_MM82FC //HDAUDIO_CODEC1_Converter1_Stream_Format_and_Channel_Stream_ID_Controls_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Converter_Format_CHAN :4; + CBIOS_U32 Converter_Format_BITS :3; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Converter_Format_DIV :3; + CBIOS_U32 Converter_Format_MULT :3; + CBIOS_U32 Converter_Format_BASE :1; + CBIOS_U32 Converter_Format_TYPE :1; + CBIOS_U32 Reserved_1 :8; + CBIOS_U32 Converter_Channel :4; + CBIOS_U32 Converter_Stream :4; + }; +}REG_MM82FC; + + +typedef union _REG_MM8300 //HDAUDIO_CODEC1_Converter1_Digital_Converter_and_PinWidget1_Unsolicited_Response_Controls_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CONVERTER1_DigiConvert_SIC_DigEn :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_V :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_VCFG :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_PRE :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_COPY :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_AUDIO :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_PRO :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_L :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_CC_6to0 :7; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_Reserved :1; + CBIOS_U32 IEC_CODING_TYPE :4; + CBIOS_U32 disable_non_audio :1; + CBIOS_U32 copy_bit_polarity :1; + CBIOS_U32 enable_73eh_73fh_verb :1; + CBIOS_U32 keep_alive_enable :1; + CBIOS_U32 PINWIDGET1_UnsoliResponse_EnableUnsol_Tag :6; + CBIOS_U32 PINWIDGET1_UnsoliResponse_EnableUnsol_bit6 :1; + CBIOS_U32 PINWIDGET1_UnsoliResponse_EnableUnsol_Enable :1; + }; +}REG_MM8300; + + +typedef union _REG_MM8304 //HDAUDIO_CODEC1_Converter_1_Stripe_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CONVERTER1_Stripe_Control :2; + CBIOS_U32 CONVERTER1_StripeControl_Reserved_7to2 :6; + CBIOS_U32 Undefined :12; + CBIOS_U32 CONVERTER1_StripeControl_Stripe_Capability__bit_0 :1; + CBIOS_U32 CONVERTER1_StripeControl_Stripe_Capability__bit_1 :1; + CBIOS_U32 CONVERTER1_StripeControl_Stripe_Capability__bit_2 :1; + CBIOS_U32 CONVERTER1_StripeControl_Reserved_31to23 :9; + }; +}REG_MM8304; + + +typedef union _REG_MM8308 //HDAUDIO_CODEC1_PinWidget1_Pin_Sense_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PINWIDGET1_PinSense_RightChnl :1; + CBIOS_U32 PINWIDGET1_PinSense_Impedance :30; + CBIOS_U32 PINWIDGET1_PinSense_Presense_Detect :1; + }; +}REG_MM8308; + + +typedef union _REG_MM830C //HDAUDIO_CODEC1_PinWidget1_Pin_Widget_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PINWIDGET1_Control__VRefEn :3; + CBIOS_U32 PINWIDGET1_Control_Reserved_4to3 :2; + CBIOS_U32 PINWIDGET1_Control__In_Enable :1; + CBIOS_U32 PINWIDGET1_Control__Out_Enable :1; + CBIOS_U32 PINWIDGET1_Control__H_Phn_Enable :1; + CBIOS_U32 FunGroup_Power_State_PS_Set_PS_Act :4; + CBIOS_U32 power_state :7; + CBIOS_U32 hda_power_saving_en :1; + CBIOS_U32 PS_SettingsReset :1; + CBIOS_U32 Reserved_31 :11; + }; +}REG_MM830C; + + +typedef union _REG_MM8310 //DP_Software_AUX_Write_Data_Bytes_3-0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Write_Bytes_3_0 :32; + }; +}REG_MM8310; + + +typedef union _REG_MM8314 //DP_Software_AUX_Write_Data_Bytes_7-4_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Write_Bytes_7_4 :32; + }; +}REG_MM8314; + + +typedef union _REG_MM8318 //DP_Software_AUX_Write_Data_Bytes_11-8_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Write_Bytes_11_8 :32; + }; +}REG_MM8318; + + +typedef union _REG_MM831C //DP_Software_AUX_Write_Data_Bytes_15-12_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Write_Bytes_15_12 :32; + }; +}REG_MM831C; + + +typedef union _REG_MM8320 //DP_Software_AUX_Read_Data_Bytes_3-0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Read_Bytes_3_0 :32; + }; +}REG_MM8320; + + +typedef union _REG_MM8324 //DP_Software_AUX_Read_Data_Bytes_7-4_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Read_Bytes_7_4 :32; + }; +}REG_MM8324; + + +typedef union _REG_MM8328 //DP_Software_AUX_Read_Data_Bytes_11-8_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Read_Bytes_11_8 :32; + }; +}REG_MM8328; + + +typedef union _REG_MM832C //DP_Software_AUX_Read_Data_Bytes_15-12_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Read_Bytes_15_12 :32; + }; +}REG_MM832C; + + +typedef union _REG_MM8330 //DP_Software_AUX_Timer_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SW_AUX :1; + CBIOS_U32 AUX_Request :1; + CBIOS_U32 AUX_DRDY :1; + CBIOS_U32 AUX_Timeout :1; + CBIOS_U32 SW_Timer_Clear :1; + CBIOS_U32 SW_Timer_Enable :1; + CBIOS_U32 SW_Timer_Counter :20; + CBIOS_U32 AUX_Command :4; + CBIOS_U32 HPD_Status :2; + }; +}REG_MM8330; + + +typedef union _REG_MM8334 //DP_Software_AUX_Command_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SW_AUX_CMD :4; + CBIOS_U32 SW_AUX_Length :8; + CBIOS_U32 SW_AUX_Addr :20; + }; +}REG_MM8334; + + +typedef union _REG_MM8338 //DP_NAUD_and_Mute_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 NAUD :24; + CBIOS_U32 Audio_InfoFrame :1; + CBIOS_U32 Audio_Output_Enable :1; + CBIOS_U32 Mute :1; + CBIOS_U32 Mute_Mode :1; + CBIOS_U32 Generate_MAUD :1; + CBIOS_U32 Generated_MAUD_Mode :1; + CBIOS_U32 AUX_SW_Reset :1; + CBIOS_U32 Link_Training_SW_Reset :1; + }; +}REG_MM8338; + + +typedef union _REG_MM833C //DP_MAUD_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MAUD :24; + CBIOS_U32 Secondary_data_Packet_ID :8; + }; +}REG_MM833C; + + +typedef union _REG_MM8340 //DP_EPHY_MPLL_Power_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Bandgap_Power_Down :1; + CBIOS_U32 MPLL_Reg_Power_Down :1; + CBIOS_U32 MPLL_Power_Down :1; + CBIOS_U32 MPLL_PTAT_Current :2; + CBIOS_U32 MPLL_CP_Current :3; + CBIOS_U32 MPLL_N :8; + CBIOS_U32 MPLL_R :1; + CBIOS_U32 MPLL_P :2; + CBIOS_U32 SSC_Enable :1; + CBIOS_U32 SSC_Freq_Spread :1; + CBIOS_U32 Dither :1; + CBIOS_U32 Signal_Profile :1; + CBIOS_U32 Spread_Magnitude :2; + CBIOS_U32 TPLL_Reg_Power_Down :1; + CBIOS_U32 TPLL_Power_Down :1; + CBIOS_U32 reserverd :3; + CBIOS_U32 TPLL_N_Div :2; + }; +}REG_MM8340; + + +typedef union _REG_MM8344 //DP_EPHY_TX_Power_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Resistance_Tuning_PD :1; + CBIOS_U32 Resistance_Tuning_Reset :1; + CBIOS_U32 Resistance_Tuning_Enable :1; + CBIOS_U32 TX_Resistance_Set_Enable :1; + CBIOS_U32 TX_Resistance_Value :4; + CBIOS_U32 TX_Reg_Power_Down_Lane0 :1; + CBIOS_U32 TX_Reg_Power_Down_Lane1 :1; + CBIOS_U32 TX_Reg_Power_Down_Lane2 :1; + CBIOS_U32 TX_Reg_Power_Down_Lane3 :1; + CBIOS_U32 Driver_Control_Lane0 :1; + CBIOS_U32 Driver_Control_Lane1 :1; + CBIOS_U32 Driver_Control_Lane2 :1; + CBIOS_U32 Driver_Control_Lane3 :1; + CBIOS_U32 EPHY1_SR_MAN_L0 :1; + CBIOS_U32 EPHY1_SR_MAN_L1 :1; + CBIOS_U32 EPHY1_SR_MAN_L2 :1; + CBIOS_U32 EPHY1_SR_MAN_L3 :1; + CBIOS_U32 DIU_EPHY1_AUX_DIAJ :3; + CBIOS_U32 EPHY_MPLL_CP :1; + CBIOS_U32 TX_Power_Control_Lane0 :2; + CBIOS_U32 TX_Power_Control_Lane1 :2; + CBIOS_U32 TX_Power_Control_Lane2 :2; + CBIOS_U32 TX_Power_Control_Lane3 :2; + }; +}REG_MM8344; + + +typedef union _REG_MM8348 //DP_EPHY_Miscellaneous_Power_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Driver_Mode :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 RTNBIST :2; + CBIOS_U32 CKHLD :2; + CBIOS_U32 M1V :1; + CBIOS_U32 MT :1; + CBIOS_U32 T1V :1; + CBIOS_U32 TT :1; + CBIOS_U32 EPHY1_TPLL_CP :4; + CBIOS_U32 AUC_Ch_Op_Mode :2; + CBIOS_U32 TX_High_Impedance_Lane0 :1; + CBIOS_U32 TX_High_Impedance_Lane1 :1; + CBIOS_U32 TX_High_Impedance_Lane2 :1; + CBIOS_U32 TX_High_Impedance_Lane3 :1; + CBIOS_U32 HPD_Power_Down :1; + CBIOS_U32 TPLL_Reset_Signal :1; + CBIOS_U32 MPLL_SSC_Output :4; + CBIOS_U32 TPLL_Lock_Indicator :1; + CBIOS_U32 MPLL_Lock_Indicator :1; + CBIOS_U32 RTN_Results :4; + }; +}REG_MM8348; + +typedef union _REG_MM834C //HDAUDIO_CODEC1_Channel_Count_and_ELD_DIP_Buffer_Size_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Converter_Channel_Count :8; + CBIOS_U32 Byte_Offset_into_ELD_memory :8; + CBIOS_U32 ELD_Buffer_Size :8; + CBIOS_U32 DIP_packet_buffer_size :3; + CBIOS_U32 DIP_PI_base_size :5; + }; +}REG_MM834C; + + +typedef union _REG_MM8350 //HDAUDIO_CODEC1_ASP_Channel_Map_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 ASP_Channel_Map_Slot_0 :4; + CBIOS_U32 ASP_Channel_Map_Slot_1 :4; + CBIOS_U32 ASP_Channel_Map_Slot_2 :4; + CBIOS_U32 ASP_Channel_Map_Slot_3 :4; + CBIOS_U32 ASP_Channel_Map_Slot_4 :4; + CBIOS_U32 ASP_Channel_Map_Slot_5 :4; + CBIOS_U32 ASP_Channel_Map_Slot_6 :4; + CBIOS_U32 ASP_Channel_Map_Slot_7 :4; + }; +}REG_MM8350; + + +typedef union _REG_MM8354 //HDAUDIO_CODEC1_DIP_Transmit_and_CP_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DIP_XmitCtrl_PI0 :2; + CBIOS_U32 DIP_XmitCtrl_PI1 :2; + CBIOS_U32 DIP_XmitCtrl_PI2 :2; + CBIOS_U32 DIP_XmitCtrl_PI3 :2; + CBIOS_U32 DIP_XmitCtrl_PI4 :2; + CBIOS_U32 DIP_XmitCtrl_PI5 :2; + CBIOS_U32 DIP_XmitCtrl_PI6 :2; + CBIOS_U32 DIP_XmitCtrl_PI7 :2; + CBIOS_U32 CP_Control_Requested_State :2; + CBIOS_U32 CP_Control_0 :1; + CBIOS_U32 CP_Control_UR_subtag :5; + CBIOS_U32 One_Bit_Audio_En :1; + CBIOS_U32 One_Bit_AUdio_Mapping :1; + CBIOS_U32 ELD_Rd_Status_Control :1; + CBIOS_U32 DIP_Write_Status_Control :1; + CBIOS_U32 DIP_Read_Status_Control :1; + CBIOS_U32 Reserved :3; + }; +}REG_MM8354; + + +typedef union _REG_MM8358 //DP_Extension_Packet_Payload_Bytes_3-0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Extension_Packet_Payload_Bytes_3_0 :32; + }; +}REG_MM8358; + + +typedef union _REG_MM835C //DP_Extension_Packet_Payload_Bytes_7-4_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Extension_Packet_Payload_Bytes_7_4 :32; + }; +}REG_MM835C; + + +typedef union _REG_MM8360 //DP_Extension_Packet_Payload_Bytes_11-8_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Extension_Packet_Payload_Bytes_11_8 :32; + }; +}REG_MM8360; + + +typedef union _REG_MM8364 //DP_Extension_Packet_Payload_Bytes_15-12_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Extension_Packet_Payload_Bytes_15_12 :32; + }; +}REG_MM8364; + +typedef union _REG_MM8368 //DP +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DP1_SW_swing :6; + CBIOS_U32 DP1_SW_pp :5; + CBIOS_U32 DP1_SW_post_cursor :4; + CBIOS_U32 SW_swing_SW_PP_SW_post_cursor_load_index :6; + CBIOS_U32 enable_SW_swing_pp :1; + CBIOS_U32 PSR_ML_AUTOOFF :1; + CBIOS_U32 VER1P2 :1; + CBIOS_U32 RD_INTVAL :3; + CBIOS_U32 PSR_UPDATE :1; + CBIOS_U32 PSR_EXIT :1; + CBIOS_U32 PSR_ENTER :1; + CBIOS_U32 PSR_FORCE_BS :1; + CBIOS_U32 bugfix_en :1; + }; +}REG_MM8368; + + +typedef union _REG_MM836C //DP +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 EPHY_lane3_pre_pp :2; + CBIOS_U32 EPHY_lane2_pre_pp :2; + CBIOS_U32 EPHY_lane1_pre_pp :2; + CBIOS_U32 EPHY_lane0_pre_pp :2; + CBIOS_U32 EPHY_lane3_swing_level :2; + CBIOS_U32 EPHY_lane2_swing_level :2; + CBIOS_U32 EPHY_lane1_swing_level :2; + CBIOS_U32 EPHY_lane0_swing_level :2; + CBIOS_U32 EPHY_bit_rate :1; + CBIOS_U32 EPHY_HPD_IN :1; + CBIOS_U32 EPHY1_TPLL_ISEL :2; + CBIOS_U32 MR :3; + CBIOS_U32 MC :3; + CBIOS_U32 TR :3; + CBIOS_U32 TC :3; + }; +}REG_MM836C; + + +typedef union _REG_MM8370 //DP_HDCP_Key_Selection_Vector_(KSV)_1_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 KSV_39to8 :32; + }; +}REG_MM8370; + + +typedef union _REG_MM8374 //DP_HDCP_Control_1_and_Key_Selection_Vector_(KSV)_2_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 KSV_7to0 :8; + CBIOS_U32 Key_ECC_Done :1; + CBIOS_U32 DP_HDCP_INT :1; + CBIOS_U32 Key_Error_detect :1; + CBIOS_U32 Key_Error_correct :1; + CBIOS_U32 Reserved_14to12 :3; + CBIOS_U32 DPHDCP_Test_Mode_Select :1; + CBIOS_U32 Test_Key_Enable :1; + CBIOS_U32 AUX_Fail_Config :3; + CBIOS_U32 AUX_Def_Config :2; + CBIOS_U32 Notfinish_Fail :1; + CBIOS_U32 Disable_AUX :1; + CBIOS_U32 Not_support_0_KSV_repeater :1; + CBIOS_U32 Reserved_26to25 :2; + CBIOS_U32 CP_EN :1; + CBIOS_U32 Enc_Sel :1; + CBIOS_U32 Enc_Con :1; + CBIOS_U32 KSV_Rev_List :1; + CBIOS_U32 KSV_Verifcation_Done :1; + }; +}REG_MM8374; + + +typedef union _REG_MM8378 //DP_HDCP_Control_2_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Authentication_Protocol_Status :2; + CBIOS_U32 Repeater_Flag :1; + CBIOS_U32 Device_Count :7; + CBIOS_U32 Interrupt_Source :4; + CBIOS_U32 AUX_Status :2; + CBIOS_U32 Reserved :16; + }; +}REG_MM8378; + + +typedef union _REG_MM837C //HDAUDIO_CODEC1_Control_Writes_Default_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Load_Converter1_StreamFormat :1; + CBIOS_U32 Load_Converter1_ChanStreamID :1; + CBIOS_U32 Load_Converter1_DigiConvert :1; + CBIOS_U32 Load_Pinwidget1_UnsoliResponse :1; + CBIOS_U32 Load_Converter1_StripeControl :1; + CBIOS_U32 Load_Pinwidget1_PinSense :1; + CBIOS_U32 Load_Pinwidget1_Control :1; + CBIOS_U32 Load_Pinwidget1_ConfigDefault :1; + CBIOS_U32 Load_Convert1_Converter_Channel_Count :1; + CBIOS_U32 Load_ASP_Channel_Mapping :1; + CBIOS_U32 Load_ELD_Offset :1; + CBIOS_U32 Load_DIP_XmitCtrl :1; + CBIOS_U32 Load_CP_Control :1; + CBIOS_U32 Load_One_Bit_audio_Control :1; + CBIOS_U32 Reserved :18; + }; +}REG_MM837C; + + +typedef union _REG_MM8380 //HDAUDIO_CODEC1_Read_Out_Control_Select_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Load_Function_Group_SubsystemID :1; + CBIOS_U32 Load_Function_Group_Power_state :1; + CBIOS_U32 SW_Strm1_FIFO_Depth_Select :1; + CBIOS_U32 SW_Strm1_FIFO_Depth :5; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Reserved_1 :5; + CBIOS_U32 Strm1_Link_Position_Select :1; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 HDA_Offset_84_PRS :1; + CBIOS_U32 IMM_CMD_Response_V_SEL :1; + CBIOS_U32 Reserved_3 :1; + CBIOS_U32 HDAUDIO_Wall_Clock_Select :2; + CBIOS_U32 Wal_Clk_Cnt_Sel :1; + CBIOS_U32 Wal_Clk_Cnt_Clock_Sel1 :1; + CBIOS_U32 Wal_Clk_Cnt_Clock_Sel2 :1; + CBIOS_U32 Read_Out_Control_Select :8; + }; +}REG_MM8380; + + +typedef union _REG_MM8384 //HDAUDIO_CODEC1_Read_Out_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Codec_Read_Out :32; + }; +}REG_MM8384; + + +typedef union _REG_MM8388 //HDAUDIO_Wall_Clock_Ratio_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Wall_clock_ratio_low :32; + }; +}REG_MM8388; + + +typedef union _REG_MM838C //HDAUDIO_Wall_Clock_Ratio_Hi_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Wall_clock__ratio__hi :8; + CBIOS_U32 Wall_clock_ratio_enable :1; + CBIOS_U32 Reserved :23; + }; +}REG_MM838C; + + +typedef union _REG_MM8390 //HDAUDIO_CODEC1_Channel_Status_Bits_31:0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 bit_0 :1; + CBIOS_U32 bit_1 :1; + CBIOS_U32 Channel_status_31_2 :30; + }; +}REG_MM8390; + + +typedef union _REG_MM8394 //HDAUDIO_CODEC1_Channel_Status_Bits_63:32_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Channel_status_63_32 :32; + }; +}REG_MM8394; + + +typedef union _REG_MM8398 //HDAUDIO_CODEC1_Channel_Status_Bits_95:64_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Channel_status_95_64 :32; + }; +}REG_MM8398; + + +typedef union _REG_MM839C //HDAUDIO_CODEC1_Channel_Status_Block_Bits_127:96_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Channel_status_127_96 :32; + }; +}REG_MM839C; + + +typedef union _REG_MM83A0 //HDAUDIO_CODEC1_Channel_Status_Bits_159:128_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Channel_status_159_128 :32; + }; +}REG_MM83A0; + + +typedef union _REG_MM83A4 //HDAUDIO_CODEC1_Channel_Status_Bits_191:160_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Channel_status_191_160 :32; + }; +}REG_MM83A4; + + +typedef union _REG_MM83A8 //HDMI1_CODEC1_Audio_Clock_Regeneration_Numerator_(N)_and_CTS_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 N :20; + CBIOS_U32 CTS :12; + }; +}REG_MM83A8; + + +typedef union _REG_MM83AC //HDMI_AUDIO_CODEC1_Audio_Clock_Cycle_Time_Stamp_(CTS)__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CTS :8; + CBIOS_U32 HW_Generated_CTS :20; + CBIOS_U32 Reserved :2; + CBIOS_U32 CTS_Select :1; + CBIOS_U32 HW_CTS_MODE :1; + }; +}REG_MM83AC; + + +typedef union _REG_MM8400 //Primary_Stream_2_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_Blank_Alpha :8; + CBIOS_U32 PS2_YCBCR_Mode :1; + CBIOS_U32 PS2_YBCR420_Enable :1; + CBIOS_U32 PS2_Reserve_Pre_Multiple_Alpha :1; + CBIOS_U32 PS2_Reserve_Pre_Multiple_use_Invert_Alpha :1; + CBIOS_U32 PS2_fifo_depth_control :3; + CBIOS_U32 Ps2_Uyvy422 :1; + CBIOS_U32 RESERVED :16; + }; +}REG_MM8400; + + +typedef union _REG_MM8404 //Primary_Stream_3_Frame_Buffer_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_Enable_Work_Registers_0 :1; + CBIOS_U32 SS3_Enable_Work_Registers :1; + CBIOS_U32 PS3_Start_Address_0 :28; + CBIOS_U32 PS3_Vsync_Off_Page_Flip :1; + CBIOS_U32 PS3_Enable_Work_Registers_1 :1; + }; +}REG_MM8404; + + +typedef union _REG_MM8408 //Primary_Stream_3_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED_0 :1; + CBIOS_U32 PS3_ABGR_EN :1; + CBIOS_U32 PS3_First_Line_Swizzle :1; + CBIOS_U32 PS3_Work_Reg_Enable :1; + CBIOS_U32 PS3_Stride_or_Tile_Stride :12; + CBIOS_U32 PS3_Start_Address_Pixel_Offset :5; + CBIOS_U32 PS3_Tiling_X_Offset :3; + CBIOS_U32 PS3_Tiling_Line_Offset :6; + CBIOS_U32 RESERVED_1 :1; + CBIOS_U32 PS3_Tile_Addressing_Enable :1; + }; +}REG_MM8408; + + +typedef union _REG_MM840C //interlace_right_offset[31:2] +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 reserved :2; + CBIOS_U32 PS2_INTR_ROFFSET_31_2 :30; + }; +}REG_MM840C; + + +typedef union _REG_MM8410 //Primary_Stream_3_Right_Frame_Offset_Address_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_Right_Frame_Base :30; + CBIOS_U32 RESERVED :2; + }; +}REG_MM8410; + + +typedef union _REG_MM8414 //Primary_Stream_3_YCbCr420_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_Blank_Alpha :8; + CBIOS_U32 PS3_YCBCR_Mode :1; + CBIOS_U32 PS3_YBCR420_Enable :1; + CBIOS_U32 PS3_Reserve_Pre_Multiple_Alpha :1; + CBIOS_U32 PS3_Reserve_Pre_Multiple_use_Invert_Alpha :1; + CBIOS_U32 PS3_fifo_depth_control :3; + CBIOS_U32 Ps3_Uyvy422 :1; + CBIOS_U32 RESERVED :16; + }; +}REG_MM8414; + + +typedef union _REG_MM8418 //Primary_Stream_1_YCbCr420_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_Blank_Alpha :8; + CBIOS_U32 PS1_YCBCR_Mode :1; //0=Crycb_Mode_When_Ycbcr444 1=Ycbcr_Mode_When_Ycbcr444 + CBIOS_U32 PS1_YBCR420_Enable :1; + CBIOS_U32 PS1_Reserve_Pre_Multiple_Alpha :1; + CBIOS_U32 PS1_Reserve_Pre_Multiple_use_Invert_Alpha :1; + CBIOS_U32 PS1_fifo_depth_control :3; + CBIOS_U32 Ps1_Uyvy422 :1; + CBIOS_U32 RESERVED :16; + }; +}REG_MM8418; + + +typedef union _REG_MM841C //Secondary_Stream_1_control_Regsiter +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_Plane_Alpha :8; + CBIOS_U32 SS1_Alpha_Blend_Mode :1; + CBIOS_U32 SS1_Sor_Des_Select :1; + CBIOS_U32 SS1_YCbCr_Mode :1; + CBIOS_U32 SS1_YCbCr420_Enable :1; + CBIOS_U32 SS1_fifo_depth_control :3; + CBIOS_U32 RESERVED :15; + CBIOS_U32 SS1_enable :1; + CBIOS_U32 SS1_enable_use_mmio :1; + }; +}REG_MM841C; + + +typedef union _REG_MM8420 //Primary_Stream_3_Display_Position_Frame_Line_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_Frame_Counter :16; + CBIOS_U32 PS3_Line_Counter :16; + }; +}REG_MM8420; + + +typedef union _REG_MM8424 //Primary_Stream_1_Display_Position_Line_Pixel_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_Line_Counter :16; + CBIOS_U32 PS3_Pixel_Counter :16; + }; +}REG_MM8424; + + +typedef union _REG_MM8428 //Primary_Stream_1_Top_Left_Pixel_Line_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_Top_Left_Line :16; + CBIOS_U32 PS3_Top_Leftt_Pixel :16; + }; +}REG_MM8428; + + +typedef union _REG_MM842C //Primary_Stream_1_Bottom_Right_Pixel_Line_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_Bottom_Right_Line :16; + CBIOS_U32 PS3_Bottom_Right_Pixel :16; + }; +}REG_MM842C; + + +typedef union _REG_MM8430 //Secondary_Stream_3_Color/Chroma_8bit_Key_Lower_Bound_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_8bit_B_V_Cr_Key_Lower_Bound :8; + CBIOS_U32 SS3_8bit_G_U_Cb_Key_Lower_Bound :8; + CBIOS_U32 SS3_8bit_R_Y_Key_Lower_Bound :8; + CBIOS_U32 Reserved_8bit :8; + }; + struct + { + CBIOS_U32 SS3_10bit_B_V_Cr_Key_Lower_Bound :10; + CBIOS_U32 SS3_10bit_G_U_Cb_Key_Lower_Bound :10; + CBIOS_U32 SS3_10bit_R_Y_Key_Lower_Bound :10; + CBIOS_U32 RESERVED_10bit :2; + }; +}REG_MM8430; + + +typedef union _REG_MM8434 //Streams_3_Blend_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ka3_3to0_or_Ks3 :4; + CBIOS_U32 Ka3_7to4_or_Kp3 :4; + CBIOS_U32 SS3_Input_Format :3; + CBIOS_U32 SS3_YCbCr_order :1; + CBIOS_U32 RESERVED :20; + }; +}REG_MM8434; + + +typedef union _REG_MM8438 //Secondary_Stream_1_Chroma_Key_Upper_Bound_and_Key_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_V_Cr_Key_Upper_Bound :8; + CBIOS_U32 SS3_U_Cb_Key_Upper_Bound :8; + CBIOS_U32 SS3_Y_Key_Upper_Bound :8; + CBIOS_U32 Keying_Mode :4; + CBIOS_U32 Invert_Alpha3_or_Ka3 :1; + CBIOS_U32 RESERVED :3; + }; +}REG_MM8438; + + +typedef union _REG_MM843C //Secondary_Stream_3_Source_Height_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_Line_Height :13; + CBIOS_U32 SS3_Buffer_Select :1; + CBIOS_U32 SS3_Double_Buffering_Select :1; + CBIOS_U32 SS3_Triple_Buffering_Enable :1; + CBIOS_U32 SS3_Source_Line_Width :13; + CBIOS_U32 RESERVED :2; + CBIOS_U32 RESEREED :1; + }; +}REG_MM843C; + + +typedef union _REG_MM8440 //Secondary_Stream_3_Frame_Buffer_Start_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED :3; + CBIOS_U32 SS3_FB_Start_Address_0 :27; + CBIOS_U32 SS3_VSYNC_Off_Page_Flip :1; + CBIOS_U32 SS3_Work_Reg_En :1; + }; +}REG_MM8440; + + +typedef union _REG_MM8444 //Secondary_Stream_3_ROFFSET_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED_0 :3; + CBIOS_U32 SS3_Right_Base_Address :27; + CBIOS_U32 RESERVED_1 :2; + }; +}REG_MM8444; + + +typedef union _REG_MM8448 //Secondary_Stream_3_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_Read_Length :2; + CBIOS_U32 RESERVED :2; + CBIOS_U32 SS3_Stride :12; + CBIOS_U32 SS3_Start_Address_Byte_Offset :6; + CBIOS_U32 SS3_Tiling_X_Offset :3; + CBIOS_U32 SS3_Tiling_Line_Offset :6; + CBIOS_U32 SS3_ABGR_EN :1; + }; +}REG_MM8448; + + +typedef union _REG_MM844C //interlace_right_offset[31:2] +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 reserved :2; + CBIOS_U32 PS3_INTR_ROFFSET_31_2 :30; + }; +}REG_MM844C; + + +typedef union _REG_MM8450 //Secondary_Stream_3_Window_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_Y_Start :13; + CBIOS_U32 RESERVED_0 :3; + CBIOS_U32 SS3_X_Start_0 :12; + CBIOS_U32 SS3_Loading_Enable :1; + CBIOS_U32 SS3_X_Start_1 :1; + CBIOS_U32 RESERVED_1 :2; + }; +}REG_MM8450; + + +typedef union _REG_MM8454 //Secondary_Stream_3_Window_Size_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_Window_Height :13; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 SS3_First_Line_swizzle :1; + CBIOS_U32 SS3_Window_Width :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM8454; + + +typedef union _REG_MM8458 //Secondary_Stream_3_Horizontal_Scaling_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_HACC :21; + CBIOS_U32 SS3_HTAP_SEL :1; + CBIOS_U32 RESERVED :10; + }; +}REG_MM8458; + + +typedef union _REG_MM845C //Secondary_Stream_3_Vertical_Scaling_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_VACC :21; + CBIOS_U32 SS3_Vscale_Selection :1; + CBIOS_U32 SS3_VDUP :1; + CBIOS_U32 RESERVED :8; + CBIOS_U32 SS3_Deinterlacing :1; + }; +}REG_MM845C; + + +typedef union _REG_MM8460 //Secondary_Stream_3_Frame_Buffer_Start_Address_1_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 SS3_FB_Start_Address_1 :27; + CBIOS_U32 Reserved_1 :2; + }; +}REG_MM8460; + + +typedef union _REG_MM8464 //Secondary_Stream_3_Frame_Buffer_Start_Address_2_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED_0 :3; + CBIOS_U32 SS3_FB_Start_Address_2 :27; + CBIOS_U32 RESERVED_1 :2; + }; +}REG_MM8464; + + +typedef union _REG_MM8468 //Secondary_Stream_3_Control__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_Plane_Alpha :8; + CBIOS_U32 SS3_Alpha_Blend_Mode :1; + CBIOS_U32 SS3_Sor_Des_Select :1; + CBIOS_U32 SS3_YCbCr_Mode :1; + CBIOS_U32 SS3_YCbCr420_Enable :1; + CBIOS_U32 SS3_fifo_depth_control :3; + CBIOS_U32 RESERVED :15; + CBIOS_U32 SS3_enable :1; + CBIOS_U32 SS3_enable_use_mmio :1; + }; +}REG_MM8468; + + +typedef union _REG_MM846C //Secondary_Stream_2_Control__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_Plane_Alpha :8; + CBIOS_U32 SS2_Alpha_Blend_Mode :1; + CBIOS_U32 SS2_Sor_Des_Select :1; + CBIOS_U32 SS2_YCbCr_Mode :1; + CBIOS_U32 SS2_YCbCr420_Enable :1; + CBIOS_U32 SS2_fifo_depth_control :3; + CBIOS_U32 RESERVED :15; + CBIOS_U32 SS2_enable :1; + CBIOS_U32 SS2_enable_use_mmio :1; + }; +}REG_MM846C; + + +typedef union _REG_MM8470 //Primary_Stream_1_CSC_Format__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_CSC_input_Format :3; + CBIOS_U32 reserved :1; + CBIOS_U32 PS1_CSC_output_Format :3; + CBIOS_U32 Programmable :1; + CBIOS_U32 PS1_disable :1; + CBIOS_U32 PS1_L1_bit11 :1; + CBIOS_U32 PS1_3D_Video_Mode :3; + CBIOS_U32 PS1_Read_Length :2; + CBIOS_U32 Enable_PS1_L1 :1; + CBIOS_U32 PS1_L1_7to0 :8; + CBIOS_U32 PS1_L1_10to8 :3; + CBIOS_U32 DAC1_Color_Mode :3; + CBIOS_U32 use_L_R_or_ODD_EVEN_to_do_2_frame_page_flip :1; + CBIOS_U32 enable_page_flip_every_2_frame_for_3D_video :1; + }; +}REG_MM8470; + + +typedef union _REG_MM8474 //Primary_Stream_1_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_F1 :14; + CBIOS_U32 PS1_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM8474; + + +typedef union _REG_MM8478 //Primary_Stream_1_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_F3 :14; + CBIOS_U32 PS1_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM8478; + + +typedef union _REG_MM847C //Primary_Stream_1_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_F5 :14; + CBIOS_U32 PS1_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM847C; + + +typedef union _REG_MM8480 //Primary_Stream_1_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_F7 :14; + CBIOS_U32 PS1_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM8480; + + +typedef union _REG_MM8484 //Primary_Stream_1_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_F9 :14; + CBIOS_U32 PS1_Bright :9; + CBIOS_U32 Reserved :9; + }; +}REG_MM8484; + + +typedef union _REG_MM8488 //Primary_Stream_2_CSC_Format__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_CSC_input_Format :3; + CBIOS_U32 RESERVED :1; + CBIOS_U32 PS2_CSC_output_Format :3; + CBIOS_U32 Programmable :1; + CBIOS_U32 PS2_disable :1; + CBIOS_U32 PS2_L1_bit11 :1; + CBIOS_U32 PS2_3D_Video_Mode :3; + CBIOS_U32 PS2_Read_Length :2; + CBIOS_U32 Enable_PS2_L1 :1; + CBIOS_U32 PS2_L1_7to0 :8; + CBIOS_U32 PS2_L1_10to8 :3; + CBIOS_U32 DAC2_Color_Mode :3; + CBIOS_U32 use_L_R_or_ODD_EVEN_to_do_2_frame_page_flip :1; + CBIOS_U32 enable_page_flip_every_2_frame_for_3D_video :1; + }; +}REG_MM8488; + + +typedef union _REG_MM848C //Primary_Stream_2_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_F1 :14; + CBIOS_U32 PS2_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM848C; + + +typedef union _REG_MM8490 //Primary_Stream_2_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_F3 :14; + CBIOS_U32 PS2_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM8490; + + +typedef union _REG_MM8494 //Primary_Stream_2_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_F5 :14; + CBIOS_U32 PS2_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM8494; + + +typedef union _REG_MM8498 //Primary_Stream_2_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_F7 :14; + CBIOS_U32 PS2_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM8498; + + +typedef union _REG_MM849C //Primary_Stream_2_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_F9 :14; + CBIOS_U32 PS2_Bright :9; + CBIOS_U32 Reserved :9; + }; +}REG_MM849C; + + +typedef union _REG_MM84A0 //Primary_Stream_3_CSC_Format__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_CSC_input_Format :3; + CBIOS_U32 RESERVED :1; + CBIOS_U32 PS3_CSC_output_Format :3; + CBIOS_U32 Programmable :1; + CBIOS_U32 PS3_disable :1; + CBIOS_U32 PS3_L1_bit11 :1; + CBIOS_U32 PS3_3D_Video_Mode :3; + CBIOS_U32 PS3_Read_Length :2; + CBIOS_U32 Enable_PS3_L1 :1; + CBIOS_U32 PS3_L1_7to0 :8; + CBIOS_U32 PS3_L1_10to8 :3; + CBIOS_U32 DAC3_Color_Mode :3; + CBIOS_U32 use_L_R_or_ODD_EVEN_to_do_2_frame_page_flip :1; + CBIOS_U32 enable_page_flip_every_2_frame_for_3D_video :1; + }; +}REG_MM84A0; + + +typedef union _REG_MM84A4 //Primary_Stream_3_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_F1 :14; + CBIOS_U32 PS3_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84A4; + + +typedef union _REG_MM84A8 //Primary_Stream_3_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_F3 :14; + CBIOS_U32 PS3_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84A8; + + +typedef union _REG_MM84AC //Primary_Stream_3_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_F5 :14; + CBIOS_U32 PS3_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84AC; + + +typedef union _REG_MM84B0 //Primary_Stream_3_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_F7 :14; + CBIOS_U32 PS3_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84B0; + + +typedef union _REG_MM84B4 //Primary_Stream_3_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_F9 :14; + CBIOS_U32 PS3_Bright :9; + CBIOS_U32 Reserved :9; + }; +}REG_MM84B4; + + +typedef union _REG_MM84B8 //Secondary_Stream_1_CSC_Format__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_CSC_input_Format :3; + CBIOS_U32 RESERVED_0 :1; + CBIOS_U32 SS1_CSC_output_Format :3; + CBIOS_U32 Programmable :1; + CBIOS_U32 RESERVED_1 :8; + CBIOS_U32 SS1_Reverse_Pre_Mulitple :1; + CBIOS_U32 SS1_Invert_Alpha :1; + CBIOS_U32 RESERVED_2 :14; + }; +}REG_MM84B8; + + +typedef union _REG_MM84BC //Secondary_Stream_1_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_F1 :14; + CBIOS_U32 SS1_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84BC; + + +typedef union _REG_MM84C0 //Secondary_Stream_1_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_F3 :14; + CBIOS_U32 SS1_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84C0; + + +typedef union _REG_MM84C4 //Secondary_Stream_1_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_F5 :14; + CBIOS_U32 SS1_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84C4; + + +typedef union _REG_MM84C8 //Secondary_Stream_1_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_F7 :14; + CBIOS_U32 SS1_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84C8; + + +typedef union _REG_MM84CC //Secondary_Stream_1_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_F9 :14; + CBIOS_U32 SS1_Bright :9; + CBIOS_U32 Reserved :9; + }; +}REG_MM84CC; + + +typedef union _REG_MM84D0 //Secondary_Stream_2_CSC_Format__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_CSC_input_Format :3; + CBIOS_U32 RESERVED_0 :1; + CBIOS_U32 SS2_CSC_output_Format :3; + CBIOS_U32 Programmable :1; + CBIOS_U32 RESERVED_1 :8; + CBIOS_U32 SS2_Reverse_Pre_Mulitple :1; + CBIOS_U32 SS2_Invert_Alpha :1; + CBIOS_U32 RESERVED_2 :14; + }; +}REG_MM84D0; + + +typedef union _REG_MM84D4 //Secondary_Stream_2_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_F1 :14; + CBIOS_U32 SS2_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84D4; + + +typedef union _REG_MM84D8 //Secondary_Stream_2_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_F3 :14; + CBIOS_U32 SS2_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84D8; + + +typedef union _REG_MM84DC //Secondary_Stream_2_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_F5 :14; + CBIOS_U32 SS2_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84DC; + + +typedef union _REG_MM84E0 //Secondary_Stream_2_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_F7 :14; + CBIOS_U32 SS2_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84E0; + + +typedef union _REG_MM84E4 //Secondary_Stream_2_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS2_F9 :14; + CBIOS_U32 SS2_Bright :9; + CBIOS_U32 Reserved :9; + }; +}REG_MM84E4; + + +typedef union _REG_MM84E8 //Secondary_Stream_3_CSC_Format__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_CSC_input_Format :3; + CBIOS_U32 RESERVED_0 :1; + CBIOS_U32 SS3_CSC_output_Format :3; + CBIOS_U32 Programmable :1; + CBIOS_U32 RESERVED_1 :8; + CBIOS_U32 SS3_Reverse_Pre_Mulitple :1; + CBIOS_U32 SS3_Invert_Alpha :1; + CBIOS_U32 RESERVED_2 :14; + }; +}REG_MM84E8; + + +typedef union _REG_MM84EC //Secondary_Stream_3_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_F1 :14; + CBIOS_U32 SS3_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84EC; + + +typedef union _REG_MM84F0 //Secondary_Stream_3_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_F3 :14; + CBIOS_U32 SS3_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84F0; + + +typedef union _REG_MM84F4 //Secondary_Stream_3_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_F5 :14; + CBIOS_U32 SS3_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84F4; + + +typedef union _REG_MM84F8 //Secondary_Stream_3_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_F7 :14; + CBIOS_U32 SS3_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM84F8; + + +typedef union _REG_MM84FC //Secondary_Stream_3_CSC_Coefficient_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_F9 :14; + CBIOS_U32 SS3_Bright :9; + CBIOS_U32 Reserved :9; + }; +}REG_MM84FC; + +typedef union _REG_MM334C8 //DP1_control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LINK_QUAL_SET_EN :1; + CBIOS_U32 LINK_QUAL_SET_LANE :3; + CBIOS_U32 EQ_USE_TP3 :1; + CBIOS_U32 Start_LINK_RATE_1 :1; + CBIOS_U32 SW_bit_rate_1 :1; + CBIOS_U32 IDLE_FIFO_INFO_SEND_EN :1; + CBIOS_U32 DPCD102_B5 :1; + CBIOS_U32 Aux_time_Reduced :1; + CBIOS_U32 DUR_HTOTAL_15 :1; + CBIOS_U32 DUR_HBLANK_12 :1; + CBIOS_U32 DP_SUPPORT_POST_CURSOR :1; + CBIOS_U32 MAX_POST_EMPHASIS :2; + CBIOS_U32 EQ_WRITE_POST :1; + CBIOS_U32 HBR2_COMPLIANCE_SCRAMBLER_RESET :16; + }; +}REG_MM334C8; + + +typedef union _REG_MM334CC //DP1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SW_MPLL_M_1 :8; + CBIOS_U32 SW_MPLL_P_1 :2; + CBIOS_U32 SW_NX_P :2; + CBIOS_U32 SW_NX_P_1 :2; + CBIOS_U32 SW_NX_P_2 :2; + CBIOS_U32 SW_MPLL_M_2 :8; + CBIOS_U32 SW_MPLL_P_2 :2; + CBIOS_U32 DP_VERSION_VALUE :6; + }; +}REG_MM334CC; + + +typedef union _REG_MM334DC //DP1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Link_Rate_value_1 :8; + CBIOS_U32 Link_Rate_value_2 :8; + CBIOS_U32 Link_Rate_value_3 :8; + CBIOS_U32 VCS_SUPPORT_FIELD_3D :1; + CBIOS_U32 VCS_FIELD_INV :1; + CBIOS_U32 LINK_bit_rate_status_1_0 :2; + CBIOS_U32 RESEVERD :2; + CBIOS_U32 HBR_M_GEN_MOD :1; + CBIOS_U32 Link_Rate_use_DPCP115 :1; + }; +}REG_MM334DC; + + +typedef union _REG_MM334E0 //DP1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 EPHY1_FBOOST :3; + CBIOS_U32 EPHY1_HDCKBY4 :1; + CBIOS_U32 EPHY1_FBOOST_1 :3; + CBIOS_U32 EPHY1_FBOOST_2 :3; + CBIOS_U32 reseverd_0 :6; + CBIOS_U32 reseverd_1 :4; + CBIOS_U32 EPHY1_SR_SPD :2; + CBIOS_U32 EPHY1_SR_DLY :2; + CBIOS_U32 EPHY1_SR_NDLY :2; + CBIOS_U32 Reserved_30to26 :5; + CBIOS_U32 DP1_HPD_INV :1; + }; +}REG_MM334E0; + + +typedef union _REG_MM334E4 //DP1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 EPHY1_TXDU_L0 :6; + CBIOS_U32 EPHY1_TXDU_L1 :6; + CBIOS_U32 EPHY1_TXDU_L2 :6; + CBIOS_U32 EPHY1_TXDU_L3 :6; + CBIOS_U32 EPHY1_TX_VMR :4; + CBIOS_U32 EPHY1_TX_VMX :1; + CBIOS_U32 EPHY1_TX_H1V2 :1; + CBIOS_U32 Reserved_31to30 :2; + }; +}REG_MM334E4; + + +typedef union _REG_MM33680 //HDMI1_HDCP22_control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 STREAM_ID :8; + CBIOS_U32 STREAM_TYPE :8; + CBIOS_U32 RNG_OSC_MD :2; + CBIOS_U32 RNG_OSC_EN_HDCP :1; + CBIOS_U32 RNG_EN_HDCP :1; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 HDCP22_AUTH_SEL :1; + CBIOS_U32 HDCP22_AUTH_TRIG :1; + CBIOS_U32 CSM_TRIGGER :1; + CBIOS_U32 AKE_Stored_km_DIS :1; + CBIOS_U32 HDCP22_VER_RD_DIS :1; // disable reading HDCP 2.2 version register, for debug + CBIOS_U32 TEST_REPEATER :1; + CBIOS_U32 TEST_MODE :1; + CBIOS_U32 CONT_STREAM_EN :1; + CBIOS_U32 HDCP22_CP_EN :1; + }; +}REG_MM33680; + + +typedef union _REG_MM33684 //DP1_HDCP22_control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :23; + CBIOS_U32 DPHDCP22_AUTH_SEL :1; + CBIOS_U32 DPHDCP22_AUTH_TRIG :1; + CBIOS_U32 DPHDCP22_CSM_TRIGGER :1; + CBIOS_U32 DPHDCP22_AKE_Stored_km_DIS :1; + CBIOS_U32 Reserved_1 :2; + CBIOS_U32 DPHDCP22_CAP_EN :1; + CBIOS_U32 DPHDCP22_CONT_STREAM_EN :1; + CBIOS_U32 DPHDCP22_CP_EN :1; + }; +}REG_MM33684; + + +typedef union _REG_MM33688 //DP1/HDMI1_HDCP22_control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TxCaps :24; + CBIOS_U32 Reserved :2; + CBIOS_U32 PGM_OPEN :1; + CBIOS_U32 RNG_TEST_FAIL :1; + CBIOS_U32 HDCP22_CSM_PASS_DP1 :1; + CBIOS_U32 HDCP22_AUTH_PASS_DP1 :1; + CBIOS_U32 HDCP22_CSM_PASS_HDMI1 :1; + CBIOS_U32 HDCP22_AUTH_PASS_HDMI1 :1; + }; +}REG_MM33688; + + +typedef union _REG_MM3368C //DP1/HDMI1_HDCP22_interrupt_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MSG_ID_ERR_INT :1; + CBIOS_U32 RecID_INT :1; + CBIOS_U32 KSVFF_INT :1; + CBIOS_U32 NOT_HDCP22_INT :1; + CBIOS_U32 IS_HDCP22_INT :1; + CBIOS_U32 LINK_INT_FAIL :1; + CBIOS_U32 CSM_FAIL :1; + CBIOS_U32 AUTH_FAIL :1; + CBIOS_U32 AUXFAIL_INT_IICFAIL_INT :1; + CBIOS_U32 DEV_ZERO :1; + CBIOS_U32 CSM_PASS :1; + CBIOS_U32 AUTH_PASS :1; + CBIOS_U32 SEQ_NUM_M_ROLLOVER :1; + CBIOS_U32 M_RETRY_NUMOUT :1; + CBIOS_U32 M_TIMEOUT :1; + CBIOS_U32 M_FAIL :1; + CBIOS_U32 NONZERO_SEQ_NUM_V_INT :1; + CBIOS_U32 SEQ_NUM_V_ROLLOVER_INT :1; + CBIOS_U32 V_FAIL :1; + CBIOS_U32 MAX_CAS :1; + CBIOS_U32 MAX_DEVS :1; + CBIOS_U32 WAIT_RECID_TIMEOUT :1; + CBIOS_U32 REAUTH_REQ :1; + CBIOS_U32 L_FAIL :1; + CBIOS_U32 LC_RETRY_NUMOUT :1; + CBIOS_U32 LC_TIMEOUT :1; + CBIOS_U32 Ekh_TIMEOUT :1; + CBIOS_U32 H_FAIL :1; + CBIOS_U32 H_TIMEOUT :1; + CBIOS_U32 CERT_FAIL :1; + CBIOS_U32 RECID_INVALID :1; + CBIOS_U32 CERT_TIMEOUT :1; + }; +}REG_MM3368C; + + +typedef union _REG_MM33694 //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_CSC_IN_FMT :3; + CBIOS_U32 Reserved_bit4 :1; + CBIOS_U32 LB1_CSC_OUT_FMT :3; + CBIOS_U32 LB1_PROGRAMMBLE :1; + CBIOS_U32 LB1_BYPASS :1; + CBIOS_U32 Reserved_31to9 :23; + }; +}REG_MM33694; + + +typedef union _REG_MM336B0 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDMI1_SSCP_UCC_POS :12; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 HDMI1_SCRAMBLE_ACTIVE_POS_SEL :1; + CBIOS_U32 HDMI1_SCRAMBLE_MODE :1; + CBIOS_U32 HDMI1_SCRAMBLE_EN :1; + CBIOS_U32 HDMI1_YC_420_EN :1; + CBIOS_U32 HDMI1_YC_420_MODE :1; + CBIOS_U32 HDMI1_CENTRAL_START_MODE :1; + CBIOS_U32 HDMI1_CLK_LANE_EN :1; + CBIOS_U32 DATA_ISLAND_START_SEL :1; + CBIOS_U32 Reserved_1 :2; + CBIOS_U32 PKTLEG_SEL_DISABLE :1; + CBIOS_U32 PKTLEG_VBLANK :8; + }; +}REG_MM336B0; + + +typedef union _REG_MM336B4 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RIRB_WPTR_SEL :1; + CBIOS_U32 CORB_RPTR_SEL :1; + CBIOS_U32 CIE_GIE_RST_CTL :1; + CBIOS_U32 HW_CORB_RST_SEL :1; + CBIOS_U32 STRM1_FREE_RUN :1; + CBIOS_U32 STRM2_FREE_RUN :1; + CBIOS_U32 STRM_NUM_SUPPORT :1; + CBIOS_U32 ADDR_64OK :1; + CBIOS_U32 CORB_VIR :1; + CBIOS_U32 STRM1_BDL_VIR :1; + CBIOS_U32 STRM1_VIR :1; + CBIOS_U32 STRM2_BDL_VIR :1; + CBIOS_U32 STRM2_VIR :1; + CBIOS_U32 DMAP_DES1_VIR :1; + CBIOS_U32 DMAP_DES2_VIR :1; + CBIOS_U32 RIRB_VIR :1; + CBIOS_U32 CORB_FB :1; + CBIOS_U32 STRM1_BDL_FB :1; + CBIOS_U32 STRM1_FB :1; + CBIOS_U32 STRM2_BDL_FB :1; + CBIOS_U32 STRM2_FB :1; + CBIOS_U32 DMAP_DES1_FB :1; + CBIOS_U32 DMAP_DES2_FB :1; + CBIOS_U32 RIRB_FB :1; + CBIOS_U32 CORB_SNOOP :1; + CBIOS_U32 STRM1_BDL_SNOOP :1; + CBIOS_U32 STRM1_SNOOP :1; + CBIOS_U32 STRM2_BDL_SNOOP :1; + CBIOS_U32 STRM2_SNOOP :1; + CBIOS_U32 DMAP_DES1_SNOOP :1; + CBIOS_U32 DMAP_DES2_SNOOP :1; + CBIOS_U32 RIRB_SNOOP :1; + }; +}REG_MM336B4; + + +typedef union _REG_MM336B8 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDMI1_SCDC_WAIT_TIMEOUT :24; + CBIOS_U32 HDMI1_SCDC_RR_INT_STATUS :1; + CBIOS_U32 Reserved :3; + CBIOS_U32 HDMI1_SCDC_START_STOP_ENABLE :1; + CBIOS_U32 HDMI1_SCDC_HW_DRV_STOP_ENABLE :1; + CBIOS_U32 HDMI1_SCDC_HW_DRV_START_ENABLE :1; + CBIOS_U32 HDMI1_SCDC_RR_ENABLE :1; + }; +}REG_MM336B8; + + +typedef union _REG_MM336BC //HDMI1_SCDC_control_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDMI1_SCDC_WDATA :8; + CBIOS_U32 HDMI1_SCDC_WDATA_SEL :1; + CBIOS_U32 IIC1_STATIMEOUT :23; + }; +}REG_MM336BC; + + +typedef union _REG_MM338B8 //HDTV1_control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Progressive_Mode_Enable :1; + CBIOS_U32 SMPTE_274M_Enable :1; + CBIOS_U32 SMPTE_296M_Enable :1; + CBIOS_U32 SMPTE_293M_Enable :1; + CBIOS_U32 _576P_Enable :1; + CBIOS_U32 HDTV_Timing_Enable_Control :1; + CBIOS_U32 ITU470_SELECT :1; + CBIOS_U32 _576i_480i_enable :1; + CBIOS_U32 Trilevel_Sync_Width :6; + CBIOS_U32 HDTV_EN_TRIG_PULSE :2; + CBIOS_U32 Blank_Level :10; + CBIOS_U32 _1x_2x_4x_oversampling_sel :2; + CBIOS_U32 Reserved :4; + }; +}REG_MM338B8; + + +typedef union _REG_MM338BC // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CSC_input_data_format :5; + CBIOS_U32 HDTV_CSC_coefficients_sel :1; + CBIOS_U32 HDTV_old_slope_enable :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 HDTV_Contrast_tuning_value :8; + CBIOS_U32 HDTV_Pb_Saturation_tuning_value :8; + CBIOS_U32 HDTV_Pr_Saturation_tuning_value :8; + }; +}REG_MM338BC; + + +typedef union _REG_MM338C0 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_y_dac_filter_select_coef :5; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 HDMI_SYNC_Delay_7to0 :8; + CBIOS_U32 HDTV_SYNC_Delay_10to8 :3; + CBIOS_U32 Reserved_1 :5; + CBIOS_U32 HDTV_SYNC_Delay_7to0 :8; + }; +}REG_MM338C0; + + +typedef union _REG_MM338C4 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CSC_F0_7to0 :8; + CBIOS_U32 HDTV_CSC_F1_7to0 :8; + CBIOS_U32 HDTV_CSC_F2_7to0 :8; + CBIOS_U32 HDTV_CSC_F3_7to0 :8; + }; +}REG_MM338C4; + + +typedef union _REG_MM338C8 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CSC_F4_7to0 :8; + CBIOS_U32 HDTV_CSC_F5_7to0 :8; + CBIOS_U32 HDTV_CSC_F6_7to0 :8; + CBIOS_U32 HDTV_CSC_F7_7to0 :8; + }; +}REG_MM338C8; + + +typedef union _REG_MM338CC // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CSC_F8_7to0 :8; + CBIOS_U32 Left_Blank_Pixels_10to8 :3; + CBIOS_U32 Reserved :5; + CBIOS_U32 Left_Blank_Pixels_7to0 :8; + CBIOS_U32 HDTV_Brightness_Control :8; + }; +}REG_MM338CC; + + +typedef union _REG_MM338D0 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Undefined_Bit_0_to_7 :8; + CBIOS_U32 HDTV_Digital_HSYNC_Width :8; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 HDTV_WSS_Clock_Ratio_bit_14 :1; + CBIOS_U32 Reserved_1 :5; + CBIOS_U32 HDTV_HSYNC_Delay :3; + CBIOS_U32 Reserved_2 :5; + }; +}REG_MM338D0; + + +typedef union _REG_MM338D4 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Iga1_Character_Clock :3; + CBIOS_U32 Iga2_Character_Clock :3; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 HDTV_WSS_Clock_Ratio13to6 :8; + CBIOS_U32 HDTV_SENSE_Line_Sleect :5; + CBIOS_U32 Reserved_1 :3; + CBIOS_U32 Hdtv_Broad_Pulse_6to0 :7; + CBIOS_U32 Reserved_2 :1; + }; +}REG_MM338D4; + + +typedef union _REG_MM338D8 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Hdtv_Broad_Pulse_14to7 :8; + CBIOS_U32 Hdtv_Half_Sync_10to0 :11; + CBIOS_U32 Reserved :5; + CBIOS_U32 HDTV_CC_Clock_Ratio_7to0 :8; + }; +}REG_MM338D8; + + +typedef union _REG_MM338DC // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CC_Clock_Ratio_14to8 :7; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 HDTV_CC_Line_Select :6; + CBIOS_U32 HDTV_CC_Field_Select :2; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 HDTV_CC_End_10to8 :3; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 HDTV_CC_Start_bit_8 :1; + CBIOS_U32 HDTV_CC_Sermode :1; + CBIOS_U32 HDTV_CC_Word_Mode_Select :1; + CBIOS_U32 HDTV_CC_Start_7to0 :8; + }; +}REG_MM338DC; + + +typedef union _REG_MM338E0 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CC_WSS_End_7to0 :8; + CBIOS_U32 HDTV_CC_Field1_Word0 :7; + CBIOS_U32 HDTV_CC_Field1_Data_Write_Status :1; + CBIOS_U32 HDTV_CC_Field1_Word1 :7; + CBIOS_U32 Reserved :1; + CBIOS_U32 HDTV_Parm0_Start_HDTV_HSYNC_7to0 :8; + }; +}REG_MM338E0; + + +typedef union _REG_MM338E4 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_Parm1_End_1st_Equalizing_7to0_0 :8; + CBIOS_U32 HDTV_Parm1_End_1st_Equalizing_7to0_1 :8; + CBIOS_U32 HDTV_HDE_10to0 :11; + CBIOS_U32 Reserved :5; + }; +}REG_MM338E4; + + +typedef union _REG_MM338E8 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_Parm3_Start_HDTV_HSYNC_7to0 :8; + CBIOS_U32 HDTV_Parm4_End_1st_Serration_Start_2nd_Equalization_7to0 :8; + CBIOS_U32 HDTV_Parm5_End_2nd_Equalization_7to0 :8; + CBIOS_U32 HDTV_Parm6_End_2nd_Equalization_7to0 :8; + }; +}REG_MM338E8; + + +typedef union _REG_MM338EC // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_Parm6_Start_2nd_Serration_10to8 :3; + CBIOS_U32 Reserved :4; + CBIOS_U32 VBI_Enable :1; + CBIOS_U32 WSS_Word0_or_B_Data_Byte_2_or_WSS_Word_13to8 :8; + CBIOS_U32 WSS_Word1_or_B_Data_Byte_2_or_WSS_Word_13to8 :8; + CBIOS_U32 WSS_Word2_or_Packet_A_Data_or_Packet_B_Data_Byte :8; + }; +}REG_MM338EC; + + +typedef union _REG_MM338F0 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CC_Field0_Word0 :7; + CBIOS_U32 HDTV_CC_Field0_Data_Write_Status :1; + CBIOS_U32 HDTV_CC_Field0_Word1_or_HDTV_Packet_A_CRC_Or_Packet_B_Data_Byte_14 :7; + CBIOS_U32 Reserved_OR__Packet_B_Data_Byte_14 :1; + CBIOS_U32 WSS_Clock_Ratio_5to0 :6; + CBIOS_U32 WSS_Mode_Enable :2; + CBIOS_U32 WSS_CGMS_A_Line_Select :6; + CBIOS_U32 WSS_Field_Select :2; + }; +}REG_MM338F0; + + +typedef union _REG_MM338F4 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CGMSA_Header :6; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 Reserved_1 :3; + CBIOS_U32 HDTV_WSS_CGMSA_Start_4to0 :5; + CBIOS_U32 HDTV_WSS_CGMSA_Start_8to5 :4; + CBIOS_U32 HDTV_WSS_Sermode :1; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 HDTV_CGMSA_Mode :2; + CBIOS_U32 _576i_initial_programming :2; + CBIOS_U32 HDTV__pbpr_dac_filter_select_coef :5; + CBIOS_U32 Reserved_3 :1; + }; +}REG_MM338F4; + + +typedef union _REG_MM338F8 // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Undefined_Bit_0_to_7 :8; + CBIOS_U32 Pr_channel_delay :2; + CBIOS_U32 Pb_channel_delay :2; + CBIOS_U32 HDTV_Parm1_End_1st_Equalizing_10to8 :3; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 HDTV_Parm2_End_TV_HSYNC_10to8 :3; + CBIOS_U32 Y_channel_delay :2; + CBIOS_U32 Reserved_1 :3; + CBIOS_U32 HDTV_Parm3_Start_First_Serration_9to8 :2; + CBIOS_U32 HDTV_Parm4_End_1st_Serration_Start_2nd_Equalization_9to8 :2; + CBIOS_U32 HDTV_Parm5_End_2nd_Equalization_9to8 :2; + CBIOS_U32 Reserved_2 :2; + }; +}REG_MM338F8; + + +typedef union _REG_MM338FC // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Undefined_Bit_0_to_7 :8; + CBIOS_U32 Reserved_bit0 :1; + CBIOS_U32 HDTV_CSC_F8_10to8 :3; + CBIOS_U32 Reserved_bit1 :3; + CBIOS_U32 HDTV_Enable :1; + CBIOS_U32 Undefined_Bit_16_to_31 :16; + }; +}REG_MM338FC; + + +typedef union _REG_MM33394 //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_COEF_F1 :14; + CBIOS_U32 LB1_COEF_F2 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM33394; + + +typedef union _REG_MM33398 //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_COEF_F3 :14; + CBIOS_U32 LB1_COEF_F4 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM33398; + + +typedef union _REG_MM3339C //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_COEF_F5 :14; + CBIOS_U32 LB1_COEF_F6 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM3339C; + + +typedef union _REG_MM333A0 //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_COEF_F7 :14; + CBIOS_U32 LB1_COEF_F8 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM333A0; + + +typedef union _REG_MM333A4 //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_COEF_F9 :14; + CBIOS_U32 LB1_BRIGHT :9; + CBIOS_U32 Reserved_31to23 :9; + }; +}REG_MM333A4; + + +typedef union _REG_MM333AC //hdtv2_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB2_COEF_F1 :14; + CBIOS_U32 LB2_COEF_F2 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM333AC; + + +typedef union _REG_MM333B0 //hdtv2_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB2_COEF_F3 :14; + CBIOS_U32 LB2_COEF_F4 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM333B0; + + +typedef union _REG_MM333B4 //hdtv2_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB2_COEF_F5 :14; + CBIOS_U32 LB2_COEF_F6 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM333B4; + + +typedef union _REG_MM333B8 //hdtv2_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB2_COEF_F7 :14; + CBIOS_U32 LB2_COEF_F8 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM333B8; + + +typedef union _REG_MM333BC //hdtv2_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB2_COEF_F9 :14; + CBIOS_U32 LB2_BRIGHT :9; + CBIOS_U32 Reserved_31to23 :9; + }; +}REG_MM333BC; + + +typedef union _REG_MM333C0 //DAC_csc_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DAC_DATA_IN_FMT :3; + CBIOS_U32 DAC_DATA_OUT_FMT :3; + CBIOS_U32 DAC_PROGRAMMBLE :1; + CBIOS_U32 Reserved_31to7 :25; + }; +}REG_MM333C0; + + +typedef union _REG_MM333C4 //DAC_csc_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DAC_COEF_F1 :14; + CBIOS_U32 DAC_COEF_F2 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM333C4; + + +typedef union _REG_MM333C8 //DAC_csc_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DAC_COEF_F3 :14; + CBIOS_U32 DAC_COEF_F4 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM333C8; + + +typedef union _REG_MM333CC //DAC_csc_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DAC_COEF_F5 :14; + CBIOS_U32 DAC_COEF_F6 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM333CC; + + +typedef union _REG_MM333D0 //DAC_csc_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DAC_COEF_F7 :14; + CBIOS_U32 DAC_COEF_F8 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM333D0; + + +typedef union _REG_MM333D4 //DAC_csc_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DAC_COEF_F9 :14; + CBIOS_U32 DAC_BRIGHT :9; + CBIOS_U32 Reserved_31to23 :9; + }; +}REG_MM333D4; + + +typedef union _REG_MM333D8 //PWM_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 backlight_value :16; + CBIOS_U32 PWM_frequency_counter :16; + }; +}REG_MM333D8; + + +typedef union _REG_MM333DC //PWM_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 REG_PWM_EN :1; + CBIOS_U32 REG_PWM_CTRL :2; + CBIOS_U32 PWM_frequency_counter :2; + CBIOS_U32 DIU_DIO_PWM_oen :1; + CBIOS_U32 Reserved_31to6 :26; + }; +}REG_MM333DC; + + +typedef union _REG_MM333E0 //Primary_Stream_1_Frame_Buffer_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_Enable_Work_Registers :1; + CBIOS_U32 SS1_Enable_Work_Registers :1; + CBIOS_U32 Cursor_1_Enable_Work_Registers :1; + CBIOS_U32 Write_Back1_Enable_Work_Registers :1; + CBIOS_U32 Reserved :27; + CBIOS_U32 Stream1_Enable_Work_Registers :1; + }; +}REG_MM333E0; + + +typedef union _REG_MM333E4 //Primary_Stream_1_Frame_Buffer_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_Enable_Work_Registers :1; + CBIOS_U32 SS2_Enable_Work_Registers :1; + CBIOS_U32 Cursor_2_Enable_Work_Registers :1; + CBIOS_U32 Write_Back2_Enable_Work_Registers :1; + CBIOS_U32 Reserved :27; + CBIOS_U32 Stream2_Enable_Work_Registers :1; + }; +}REG_MM333E4; + + +typedef union _REG_MM333E8 //Primary_Stream_1_Frame_Buffer_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_Enable_Work_Registers :1; + CBIOS_U32 SS3_Enable_Work_Registers :1; + CBIOS_U32 Cursor_3_Enable_Work_Registers :1; + CBIOS_U32 Reserved :28; + CBIOS_U32 Stream3_Enable_Work_Registers :1; + }; +}REG_MM333E8; + diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_MM_registers_Arise.h b/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_MM_registers_Arise.h new file mode 100644 index 0000000000000..b48fa117f9f84 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_MM_registers_Arise.h @@ -0,0 +1,7689 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +typedef union _REG_MM8180_Arise //backlight_adjustment_&_FRC +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Backlight_Adj_Pwm_Factor :8; + CBIOS_U32 Backlight_Adj_Factor :9; + CBIOS_U32 PS1_Backlight_Adjust :1; + CBIOS_U32 Reserved_0 :11; + CBIOS_U32 PS1_Ffc_Distrib_Dither :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 PS1_Ffc_Enable :1; + }; +}REG_MM8180_Arise; + + +typedef union _REG_MM8184_Arise //Secondary_Stream_1_Color/Chroma_8bit_Key_Lower_Bound_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_8bit_B__Cb_Key_Lower_Bound :8; + CBIOS_U32 SS_8bit_G_Y_Key_Lower_Bound :8; + CBIOS_U32 SS_8bit_R_Cr_Key_Lower_Bound :8; + CBIOS_U32 Reserved :8; + }; + struct + { + CBIOS_U32 SS_10bit_B_Cb_Key_Lower_Bound :10; + CBIOS_U32 SS_10bit_G_Y_Key_Lower_Bound :10; + CBIOS_U32 SS_10bit_R_Cr_Key_Lower_Bound :10; + CBIOS_U32 Reserved_0 :2; + }; +}REG_MM8184_Arise; + +typedef union _REG_MM8188_Arise //PS_KEYH_for_chorma_key +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_KeyH :24; + CBIOS_U32 Reserved :8; + }; +}REG_MM8188_Arise; + + +typedef union _REG_MM8190_Arise //Streams_1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 SS_Input_Format :3; + CBIOS_U32 SS_Uyvy422 :1; + CBIOS_U32 NV12_Tile_Enable :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 SS_YCbCr_Mode :1; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 SS_Src_Line_Width :13; + CBIOS_U32 Reserved_3 :3; + }; +}REG_MM8190_Arise; + + +typedef union _REG_MM8194_Arise //OVL2 register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ka_3to0_Or_Ks :4; + CBIOS_U32 Ka_7to4_or_Kp :4; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 Ovl1_Input_Stream :2; + CBIOS_U32 Color_Key_Sel :2; + CBIOS_U32 Alpha_Select :2; + CBIOS_U32 Alpha_Range :1; + CBIOS_U32 Alpha_Round :1; + CBIOS_U32 Reserved :6; + CBIOS_U32 Key_Mode :4; + CBIOS_U32 Invert_Alpha_Or_Ka :1; + CBIOS_U32 Ovl1_One_Shot :1; + CBIOS_U32 Ovl1_Vsync_Off_Flip :1; + CBIOS_U32 Ovl1_Enable_Work :1; + }; +}REG_MM8194_Arise; + + +typedef union _REG_MM8198_Arise //Secondary_Stream_1_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_Compress_Type :6; + CBIOS_U32 SS_Comp_Mode_Enable :1; + CBIOS_U32 Reserved_0 :17; + CBIOS_U32 SS_Fifo_Depth_Control :3; + CBIOS_U32 SS_Share_Scaler_Fifo :1; + CBIOS_U32 Reserved_3 :4; + }; +}REG_MM8198_Arise; + + +typedef union _REG_MM819C_Arise //SS1_destination_size_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_Dest_Height :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 SS_Dest_Width :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM819C_Arise; + + +typedef union _REG_MM81A0_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Lut_Read_Data :32; + }; +}REG_MM81A0_Arise; + + +typedef union _REG_MM81A4_Arise //Primary_Stream_1_Register_1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_Compress_Type :6; + CBIOS_U32 PS_Dis_Oddeven :1; + CBIOS_U32 Reserved_0 :17; + CBIOS_U32 PS_Fifo_Depth :3; + CBIOS_U32 PS_Share_Scl_Fifo :1; + CBIOS_U32 Reserved_3 :4; + }; +}REG_MM81A4_Arsie; + + +typedef union _REG_MM81A8_Arise //Secondary_Stream_Source_Height_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_Line_Height :12; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 SS_Buffer_Select :1; + CBIOS_U32 SS_Double_Buf_Select :1; + CBIOS_U32 SS_Triple_Buf_Enable :1; + CBIOS_U32 Reserved_1 :16; + }; +}REG_MM81A8_Arise; + + +typedef union _REG_MM81AC_Arise //PS1_key_reg +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_B_Cb_Low_Or_Alpha_Key :8; + CBIOS_U32 PS_G_Y_Low_Key :8; + CBIOS_U32 PS_R_Cr_Low_Key :8; + CBIOS_U32 Reserved :8; + }; +}REG_MM81AC_Arise; + + +typedef union _REG_MM81C0_Arise //Primary_Stream_1_Frame_Buffer_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Corrupt_Frame_Dscl_ :1; + CBIOS_U32 Reserved :30; + CBIOS_U32 PS_Enable_Work :1; + }; +}REG_MM81C0_Arise; + + +typedef union _REG_MM81C4_Arise //Primary_Stream_1_ROFFSET_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_Right_Frame_Base :30; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 VsyncOff :1; + }; +}REG_MM81C4_Arise; + + +typedef union _REG_MM81C8_Arise //Primary_Stream_1_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 PS_Abgr_En :1; + CBIOS_U32 Reserved_1 :2; + CBIOS_U32 PS_Stride :12; + CBIOS_U32 PS_Pixel_Offset :4; + CBIOS_U32 PS_Blank_Alpha :8; + CBIOS_U32 PS_Ycbcr_Mode :1; + CBIOS_U32 Eanble_422_To_420 :1; + CBIOS_U32 PS_Pixel_Offset_Bit4 :1; + CBIOS_U32 PS_Uyvy422 :1; + }; +}REG_MM81C8_Arise; + + +typedef union _REG_MM81D0_Arise //Secondary_Stream_1_Frame_Buffer_Start_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_Start_Address0 :31; + CBIOS_U32 SS_Work_Reg_En :1; + }; +}REG_MM81D0_Arise; + + +typedef union _REG_MM81D4_Arise //Secondary_Stream_1_Frame_Buffer_Start_Address_1__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_Roffset :31; + CBIOS_U32 SS_Vsync_Off_Flip :1; + }; +}REG_MM81D4_Arise; + + +typedef union _REG_MM81D8_Arise //Secondary_Stream_1_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_Read_Length :2; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 SS_Stride :12; + CBIOS_U32 SS_Pixel_Offset :4; + CBIOS_U32 Reserved_1 :11; + CBIOS_U32 SS_Abgr_En :1; + }; +}REG_MM81D8_Arise; + +typedef union _REG_MM81DC_Arise +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 PS1_Start_Address :31; + }; +}REG_MM81DC_Arise; + +typedef union _REG_MM81E0_Arise +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_Right_Frame_Base :32; + }; +}REG_MM81E0_Arise; + +typedef union _REG_MM81E4_Arise //Cursor1_control_reg +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor1_One_Shot :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Cursor_420_Input :1; + CBIOS_U32 Reserved_1 :5; + CBIOS_U32 Cursor1_Csc_output_Fmt :3; + CBIOS_U32 Reserved_2 :21; + }; +}REG_MM81E4_Arise; + + +typedef union _REG_MM81EC_Arise //Secondary_Stream_1_Frame_Buffer_Start_Address_2_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_Start_Address2 :31; + CBIOS_U32 Reserved :1; + }; +}REG_MM81EC_Arise; + + +typedef union _REG_MM81F4_Arise //NV12C_offset +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 Nv12y_Offset_X :4; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 Nv12y_Offset_Y :7; + CBIOS_U32 Reserved_2 :4; + CBIOS_U32 Nv12c_Offset_X :4; + CBIOS_U32 Reserved_3 :1; + CBIOS_U32 Nv12c_Offset_Y :7; + CBIOS_U32 Reserved_4 :1; + }; +}REG_MM81F4_Arise; + + +typedef union _REG_MM81F8_Arise //Secondary_Stream_1_Window_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_Y_Start :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 SS_X_Start :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM81F8_Arise; + + +typedef union _REG_MM81FC_Arise //Primary_Stream1_Shadow_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_L1_Bit11 :1; + CBIOS_U32 PS_3D_Video_Mode :3; + CBIOS_U32 PS_Read_Length :2; + CBIOS_U32 Enable_PS_L1 :1; + CBIOS_U32 PS_L1_10to0 :11; + CBIOS_U32 DAC_Color_Mode :3; + CBIOS_U32 Use_2_Frame_Page_Flip :1; + CBIOS_U32 Page_Flip_Every_2_Frame :1; + CBIOS_U32 PS_Disable :1; + CBIOS_U32 PS_Compress_Enable :1; + CBIOS_U32 Reserved :7; + }; +}REG_MM81FC_Arise; + + +typedef union _REG_MM8200_Arise //Stream_1_one_shot_control +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_Enable_Work :1; + CBIOS_U32 SS_Enable_Work :1; + CBIOS_U32 TS_Enable_Work :1; + CBIOS_U32 QS_Enable_Work :1; + CBIOS_U32 Write_Back_Enable_Work :1; + CBIOS_U32 Ovl1_Enable_Work :1; + CBIOS_U32 Ovl2_Enable_Work :1; + CBIOS_U32 Ovl3_Enable_Work :1; + CBIOS_U32 Hwc_Enable_Work :1; + CBIOS_U32 TS_win2_Enable_Work :1; + CBIOS_U32 QS_win2_Enable_Work :1; + CBIOS_U32 Ovl0_Enable_Work :1; + CBIOS_U32 Reserved :19; + CBIOS_U32 Iga_Enable_Work :1; + }; +}REG_MM8200_Arise; + + +typedef union _REG_MM8210_Arise //DP_NVID_amd_MISC1_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 NVID :24; + CBIOS_U32 MISC1_Even :1; + CBIOS_U32 MISC1_Stereo_Video :2; + CBIOS_U32 MISC1_Reserved :5; + }; +}REG_MM8210_Arise; + + +typedef union _REG_MM8214_Arise //DP_Link_Training_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Start_Link_Training :1; + CBIOS_U32 Start_Link_Rate_0 :1; + CBIOS_U32 Max_V_swing :2; + CBIOS_U32 Max_Pre_emphasis :2; + CBIOS_U32 SW_Hpd_assert :1; + CBIOS_U32 Num_of_Lanes :3; + CBIOS_U32 SW_Link_Train_Enable :1; + CBIOS_U32 SW_Link_Train_State :2; + CBIOS_U32 Software_Bit_Rate :1; + CBIOS_U32 SW_Lane0_Swing :2; + CBIOS_U32 SW_Lane0_Pre_emphasis :2; + CBIOS_U32 SW_Lane1_Swing :2; + CBIOS_U32 SW_Lane1_Pre_emphasis :2; + CBIOS_U32 SW_Lane2_Swing :2; + CBIOS_U32 SW_Lane2_Pre_emphasis :2; + CBIOS_U32 SW_Lane3_Swing :2; + CBIOS_U32 SW_Lane3_Pre_emphasis :2; + CBIOS_U32 SW_Set_Link_Train_Fail :1; + CBIOS_U32 HW_Link_Training_Done :1; + }; +}REG_MM8214_Arise; + + +typedef union _REG_MM8218_Arise //DP_Video_Input_Select_and_General_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Scramble_Enable :1; + CBIOS_U32 Switch_Idle_Mode_To_Video :1; + CBIOS_U32 Idle_Pattern_Counter :9; + CBIOS_U32 Aux_Length :5; + CBIOS_U32 Audio_Strm_Select :1; + CBIOS_U32 Hw_Link_Train_Fail :1; + CBIOS_U32 Min_Aux_Sync_Count :6; + CBIOS_U32 Delay :6; + CBIOS_U32 Reseved :2; + }; +}REG_MM8218_Arise; + + +typedef union _REG_MM821C_Arise //DP_Version_and_Extension_Packet_Head_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ext_Pkt_Head :24; + CBIOS_U32 Ext_Pkt_ID_Value :4; + CBIOS_U32 Reserved :2; + CBIOS_U32 Horizontal_Width_Bit12to11 :2; + }; +}REG_MM821C_Arise; + + +typedef union _REG_MM8220_Arise //Primary_Stream_1_Display_Position_Frame_Line_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_Frame_Counter :16; + CBIOS_U32 PS1_Line_Counter :16; + }; +}REG_MM8220_Arise; + + +typedef union _REG_MM8224_Arise //Primary_Stream_1_Display_Position_Line_Pixel_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_Line_Counter :16; + CBIOS_U32 PS1_Pixel_Counter :16; + }; +}REG_MM8224_Arise; + + +typedef union _REG_MM8228_Arise //Primary_Stream_1_Top_Left_Pixel_Line_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_Top_Left_Line :16; + CBIOS_U32 PS1_Top_Leftt_Pixel :16; + }; +}REG_MM8228_Arise; + + +typedef union _REG_MM822C_Arise //Primary_Stream_1_Bottom_Right_Pixel_Line_Count_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_Bottom_Right_Line :16; + CBIOS_U32 PS1_Bottom_Right_Pixel :16; + }; +}REG_MM822C_Arise; + + +typedef union _REG_MM8240_Arise //DP_Display_Port_Enable_and_InfoFrame_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DP_Enable :1; + CBIOS_U32 Field_Invert :1; + CBIOS_U32 Enhanced_Framing_Mode :1; + CBIOS_U32 Video_Enable :1; + CBIOS_U32 InfoFrame_FIFO_1_Ready :1; + CBIOS_U32 INFOFRAME_FIFO_2_READY :1; + CBIOS_U32 InfoFrame_FIFO_Select :1; + CBIOS_U32 InfoFrame_FIFO_1_Start_Address :4; + CBIOS_U32 InfoFrame_FIFO_2_Start_Address :4; + CBIOS_U32 InfoFrame_FIFO_1_Length :4; + CBIOS_U32 InfoFrame_FIFO_2_Length :4; + CBIOS_U32 Ext_Packet_Enable :1; + CBIOS_U32 Enable_Audio :1; + CBIOS_U32 Generate_MVID :1; + CBIOS_U32 output_format_is_BIAS_RGB :1; + CBIOS_U32 header_of_audio_info_frame_is_from_HDAudio_codec :1; + CBIOS_U32 Main_Link_Status :2; + CBIOS_U32 Link_Qual_Pattern_Set :2; + }; +}REG_MM8240_Arise; + + +typedef union _REG_MM8244_Arise //DP_Horizontal_Width_and_TU_Size_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Horiz_Width :11; + CBIOS_U32 TU_Size :6; + CBIOS_U32 TU_Ratio :15; + }; +}REG_MM8244_Arise; + + +typedef union _REG_MM8248_Arise //DP_Horizontal_Line_Duration_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Horiz_Line_Duration :15; + CBIOS_U32 HBLANK_Duration :12; + CBIOS_U32 Ext_Packet_Byte_Num :4; + CBIOS_U32 Ext_Packet_Available :1; + }; +}REG_MM8248_Arise; + + +typedef union _REG_MM824C_Arise //DP_MVID_and_MISC0_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MVID :24; + CBIOS_U32 MISC0_Sync_Clk :1; + CBIOS_U32 MISC0_Component_Format :2; + CBIOS_U32 MISC0_Dynamic_Range :1; + CBIOS_U32 MISC0_YCbCr_Colorimetry :1; + CBIOS_U32 MISC0_Bit_depth :3; + }; +}REG_MM824C_Arise; + + +typedef union _REG_MM8250_Arise //DP_HTOTAL_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 H_Total :16; + CBIOS_U32 V_Total :16; + }; +}REG_MM8250_Arise; + + +typedef union _REG_MM8254_Arise //DP_Horiz_Vert_Start_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 H_Start :16; + CBIOS_U32 V_Start :16; + }; +}REG_MM8254_Arise; + + +typedef union _REG_MM8258_Arise //DP_Polarity/Width_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HSYNC_Width :15; + CBIOS_U32 HSYNC_Polarity :1; + CBIOS_U32 VSYNC_Width :15; + CBIOS_U32 VSYNC_Polarity :1; + }; +}REG_MM8258_Arise; + + +typedef union _REG_MM825C_Arise //DP_Polarity/Width_Attribute_Data_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Acitve_Width :16; + CBIOS_U32 Active_Height :16; + }; +}REG_MM825C_Arise; + + +typedef union _REG_MM8264_Arise //down_Scaling1_write_back_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Down_Scale_Src_Select :1; + CBIOS_U32 Csc_In_Format :3; + CBIOS_U32 Csc_Out_Format :3; + CBIOS_U32 Csc_Coef_In_Dscl_Mux :1; + CBIOS_U32 Program_Bright_255_255_In_Dscl_Csc :9; + CBIOS_U32 Reserved_0 :15; + }; +}REG_MM8264_Arise; + + +typedef union _REG_MM8268_Arise //Dscl1_CSC_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Program_Coef_1_In_Dscl_Csc :14; + CBIOS_U32 Program_Coef_2_In_Dscl_Csc :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM8268_Arise; + + +typedef union _REG_MM826C_Arise //Dscl1_CSC_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Program_Coef_3_In_Dscl_Csc :14; + CBIOS_U32 Program_Coef_4_In_Dscl_Csc :14; + CBIOS_U32 Reserved_0 :4; + }; +}REG_MM826C_Arise; + + +typedef union _REG_MM8270_Arise //Dscl1_CSC_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Program_Coef_5_In_Dscl_Csc :14; + CBIOS_U32 Program_Coef_6_In_Dscl_Csc :14; + CBIOS_U32 Reserved_0 :4; + }; +}REG_MM8270_Arise; + + +typedef union _REG_MM8274_Arise //Dscl1_CSC_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Program_Coef_7_In_Dscl_Csc :14; + CBIOS_U32 Program_Coef_8_In_Dscl_Csc :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM8274_Arise; + + +typedef union _REG_MM8278_Arise //Dscl1_CSC_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Program_Coef_9_In_Dscl_Csc :14; + CBIOS_U32 Reserved_0 :18; + }; +}REG_MM8278_Arise; + + +typedef union _REG_MM8280_Arise //HDMI1_General_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDMI_Reset :1; + CBIOS_U32 HDMI_Enable :1; + CBIOS_U32 Deep_Color_Mode :2; + CBIOS_U32 reserved :1; + CBIOS_U32 Video_Clip :1; + CBIOS_U32 DVI_Mode_during_HDMI_Enable :1; + CBIOS_U32 TMDS_Video_Pixel_Format_Select :2; + CBIOS_U32 Convert_to_YCbCr422_Enable :1; + CBIOS_U32 HSYNC_Invert_Enable :1; + CBIOS_U32 HDMI_Debug_Bus_Select :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 VSYNC_Invert_Enable :1; + CBIOS_U32 Reserved_15to14 :2; + CBIOS_U32 Delay_for_HDCP :7; + CBIOS_U32 Delay_for_HDCP_SEL :1; + CBIOS_U32 Transmit_Between_AE_300_Enable :1; + CBIOS_U32 Transmit_Between_385_507_Enable :1; + CBIOS_U32 Transmit_After_650_Enable :1; + CBIOS_U32 STATUS_OF_HDMI_STATION_MACHINE :5; + }; +}REG_MM8280_Arise; + + +typedef union _REG_MM8284_Arise //HDMI1__InfoFrame_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 InfoFrame_FIFO_2_Select :1; + CBIOS_U32 InfoFrame_FIFO_1_Ready :1; + CBIOS_U32 INFOFRAME_FIFO_2_READY :1; + CBIOS_U32 INFO_VSYNC_EN :1; + CBIOS_U32 InfoFrame_FIFO_1_Start_Address :4; + CBIOS_U32 InfoFrame_FIFO_1_Length :5; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 InfoFrame_FIFO_2_Start_Address :4; + CBIOS_U32 InfoFrame_FIFO_2_Length :5; + CBIOS_U32 Reserved_1 :3; + CBIOS_U32 Horiz_Blank_Max_Packets :4; + }; +}REG_MM8284_Arise; + + +typedef union _REG_MM8288_Arise //HD_Audio_Codec_Status_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :25; + CBIOS_U32 Int_Src_Codec1 :1; + CBIOS_U32 Reserved_1 :6; + }; +}REG_MM8288_Arise; + + +typedef union _REG_MM8294_Arise //HDMI1_Audio_Insert_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Select_HDMI_Audio_Source :1; + CBIOS_U32 HDMI_Audio_Enable :1; + CBIOS_U32 Set_AVMUTE_Enable :1; + CBIOS_U32 Clear_AVMUTE_Enable :1; + CBIOS_U32 HDAUDIO_Stream1_Threshold :6; + CBIOS_U32 HDAUDIO_Stream2_Threshold :6; + CBIOS_U32 Reserved :1; + CBIOS_U32 DC_Gen_Cntl_Pkt_EN :1; + CBIOS_U32 SW_PP :4; + CBIOS_U32 PP_SELECT :1; + CBIOS_U32 CD :4; + CBIOS_U32 Default_Phase :1; + CBIOS_U32 ACR_ratio_select :1; + CBIOS_U32 RIRB_WPTR_INC_SEL :1; + CBIOS_U32 Reserved_31to30 :2; + }; +}REG_MM8294_Arise; + + +typedef union _REG_MM8298_Arise //HDAUDIO_CODEC1_Audio_Packet_to_Clock_Ratio_Register_1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CODEC1_Audio_Packet_to_DClk_Ratio_31to0 :32; + }; +}REG_MM8298_Arise; + + +typedef union _REG_MM829C_Arise //HDAUDIO_CODEC1_Audio_Packet_to_Clock_Ratio_Register_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CODEC1_Audio_Packet_to_DClk_Ratio_39to32 :8; + CBIOS_U32 CODEC1_ACR_ratio :20; + CBIOS_U32 CODEC1_ACR_ENABLE :1; + CBIOS_U32 CODEC1_MUTE_EN :1; + CBIOS_U32 CODEC1_WAKE_FROM_S3 :1; + CBIOS_U32 CODEC1_SW_RESET :1; + }; +}REG_MM829C_Arise; + + +typedef union _REG_MM82A0_Arise //HDAUDIO_CODEC1_Audio_Mode_and_Response_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HD_AUDIO_MODE_SELECT :1; + CBIOS_U32 ResP_generation :1; + CBIOS_U32 Resp_Ready :1; + CBIOS_U32 Send_UNSOLRESP :1; + CBIOS_U32 HDAUDIO_CODEC1_Enable :1; + CBIOS_U32 up_Sample_incoming_audio :4; + CBIOS_U32 Driver_ready :1; + CBIOS_U32 Ignore_driver_ready :1; + CBIOS_U32 Down_sample_incoming_audio_factor :4; + CBIOS_U32 Use_SW_Stream_Format :1; + CBIOS_U32 SW_Stream_Format :16; + }; +}REG_MM82A0_Arise; + + +typedef union _REG_MM82A4_Arise //HDAUDIO_CODEC1_Command_Field_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDA_HDMI_CMD_Verb :20; + CBIOS_U32 NID :8; + CBIOS_U32 Cad :4; + }; +}REG_MM82A4_Arise; + + +typedef union _REG_MM82A8_Arise //HDAUDIO_CODEC1_Software_Response_Field_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Response :32; + }; +}REG_MM82A8_Arise; + + +typedef union _REG_MM82AC_Arise //HDAUDIO_CODEC1_Speaker_Allocation_and_Channel_Status_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 ELD_READ_Status :1; + CBIOS_U32 DIP_WRITE_Status :1; + CBIOS_U32 DIP_READ_Status :1; + CBIOS_U32 HDA_Setconvert_Int_Status :1; + CBIOS_U32 HDA_Cpcontrol_Int_Status :1; + CBIOS_U32 SET_CONVERTER1_DigiConvert3_INT_Status :1; + CBIOS_U32 SET_FunGroup_PowerState_INT_status :1; + CBIOS_U32 Set_ELD_Default :1; + CBIOS_U32 sample_flat :1; + CBIOS_U32 Always_Output_Audio :1; + CBIOS_U32 multiple_sample :1; + CBIOS_U32 faudio_selsect :1; + CBIOS_U32 Ratio_CLK_Select :1; + CBIOS_U32 Codec_Type :2; + CBIOS_U32 Reserved_bits_18to15 :4; + CBIOS_U32 BCIS_SEL :1; + CBIOS_U32 Reserved_bits_23to21 :4; + CBIOS_U32 ELD_Use_LUT :1; + CBIOS_U32 Enable_Transmit_DIP_Packet :1; + CBIOS_U32 Enable_HDA_POS_CTR :1; + CBIOS_U32 Converter_Stream_Channel :1; + CBIOS_U32 CP_Control_CES_State :1; + CBIOS_U32 CP_Control_Ready_Status :1; + CBIOS_U32 Channel_status_control :2; + }; +}REG_MM82AC_Arise; + + +typedef union _REG_MM82B0_Arise //HDCP1_Key_Selection_Vector_(KSV)_Register_1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 KSV_39to8 :32; + }; +}REG_MM82B0_Arise; + + +typedef union _REG_MM82B4_Arise //HDCP1_Control_1_and_Key_Selection_Vector_(KSV)_2_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 KSV_7to0 :8; + CBIOS_U32 Read_Data :8; + CBIOS_U32 Write_Data :8; + CBIOS_U32 Source_Select :2; + CBIOS_U32 Test_Key_Enable :1; + CBIOS_U32 CP_EN :1; + CBIOS_U32 Mode_Sel :1; + CBIOS_U32 AC_EN :1; + CBIOS_U32 Verify_Pj_Enable :1; + CBIOS_U32 EESS_Signaling_Select :1; + }; +}REG_MM82B4_Arsise; + + +typedef union _REG_MM82B8_Arise //HDCP1_Control_2_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDCP_I2C_Function_Enable :1; + CBIOS_U32 SW_Request_I2C_Access :1; + CBIOS_U32 HDCP_Test_Mode_Select :1; + CBIOS_U32 Write_Data_Available :1; + CBIOS_U32 START_Request :1; + CBIOS_U32 STOP_REQUEST :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 READ_Finished :1; + CBIOS_U32 KSV_Revocation_List_Available :1; + CBIOS_U32 KSV_Verification_Done :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 I2C_Status :1; + CBIOS_U32 Authentication_Protocol_Status :2; + CBIOS_U32 Reserved_2 :2; + CBIOS_U32 EFUSE_read_Address :7; + CBIOS_U32 Reserved_3 :9; + }; +}REG_MM82B8_Arise; + + +typedef union _REG_MM82BC_Arise //Efuse_Read_Data +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Efuse_Read_Data :32; + }; +}REG_MM82BC_Arise; + + +typedef union _REG_MM82C0_Arise //HDCP1_Slave_receiver_not_ready_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :24; + CBIOS_U32 Slave_Receiver_Not_Ready :1; + CBIOS_U32 EFUSE_read_request :1; + CBIOS_U32 Reserved_1 :2; + CBIOS_U32 efuse_mode :3; + CBIOS_U32 Reserved_2 :1; + }; +}REG_MM82C0_Arise; + + +typedef union _REG_MM82C4_Arise //HDCP1_Miscellaneous_1_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :7; + CBIOS_U32 HDCP_SW_Reset :1; + CBIOS_U32 Repeater_Flag :1; + CBIOS_U32 Device_Count :7; + CBIOS_U32 Interrupt_Source :3; + CBIOS_U32 CTL :4; + CBIOS_U32 I2C_Frequency_Sleect :3; + CBIOS_U32 reserved :1; + CBIOS_U32 Disable_hamming_decoder :1; + CBIOS_U32 Reserved_1 :4; + }; +}REG_MM82C4_Arise; + + +typedef union _REG_MM82C8_Arise //HDCP1_Miscellaneous_Register_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RI_Verification_Counter :4; + CBIOS_U32 OW_Config :3; + CBIOS_U32 Re_Auth_Off :1; + CBIOS_U32 Auto_Detect_I2C_Off :1; + CBIOS_U32 CTL_Select :1; + CBIOS_U32 Not_support_0_KSV_repeater :1; + CBIOS_U32 No_check_KSV_list_ready :1; + CBIOS_U32 Reserved_14to12 :3; + CBIOS_U32 Read_Out_AKSV :1; + CBIOS_U32 HDCP1_Interrupt :1; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 command_buffer_nfull :1; + CBIOS_U32 command_buffer_nempty :1; + CBIOS_U32 Reserved_2 :3; + CBIOS_U32 DRV_EFUSE_RWL :1; + CBIOS_U32 DRV_EFUSE_RWL_SEL :1; + CBIOS_U32 reserved :1; + CBIOS_U32 DRV_EFUSE_RSB :1; + CBIOS_U32 Reserved_4 :3; + }; +}REG_MM82C8_Arise; + + +typedef union _REG_MM82CC_Arise //DP1_control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TX0T :3; + CBIOS_U32 TX1T :3; + CBIOS_U32 TX2T :3; + CBIOS_U32 TX3T :3; + CBIOS_U32 DIAJ_L0 :3; + CBIOS_U32 DIAJ_L1 :3; + CBIOS_U32 DIAJ_L2 :3; + CBIOS_U32 DIAJ_L3 :3; + CBIOS_U32 DIU_EPHY1_AUX_DIAJ :1; + CBIOS_U32 check_sync_cnt :1; + CBIOS_U32 int_mode :1; + CBIOS_U32 RST_PISO_EN :1; + CBIOS_U32 CR2EQ_WR02_ONLY :1; + CBIOS_U32 EN_DEFER_LT8 :1; + CBIOS_U32 EDP_ASSR :1; + CBIOS_U32 DP_Clock_Debug :1; + }; +}REG_MM82CC_Arise; + + +typedef union _REG_MM82D0_Arise //HDAUDIO_CODEC1_Vendor_ID_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Device_ID :16; + CBIOS_U32 Vendor_ID :16; + }; +}REG_MM82D0_Arise; + + +typedef union _REG_MM82D4_Arise //HDAUDIO_CODEC1_Revision_ID_and_Support_Parameters_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Stepping_ID :8; + CBIOS_U32 Revision_ID :8; + CBIOS_U32 MinRev :4; + CBIOS_U32 MajRev :4; + CBIOS_U32 PCM_Support :1; + CBIOS_U32 PCM_Float32_Only_Support :1; + CBIOS_U32 AC3_16_bit_only_Support :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 SuppPowerState_D0Sup :1; + CBIOS_U32 SuppPowerState_D1Sup :1; + CBIOS_U32 SuppPowerState_D2Sup :1; + CBIOS_U32 SuppPowerState_D3Sup :1; + }; +}REG_MM82D4_Arise; + + +typedef union _REG_MM82D8_Arise //HDAUDIO_CODEC1_Function_Group_Subordinate_Node_Count_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FunGroup_Sub_Node_Count_Total :8; + CBIOS_U32 Reserved_15to8 :8; + CBIOS_U32 FunGroup_Sub_Node_Start_Num :8; + CBIOS_U32 Reserved_31to24 :8; + }; +}REG_MM82D8_Arise; + + +typedef union _REG_MM82DC_Arise //HDAUDIO_CODEC1_Audio_Function_Group_Type_and_Capability_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AFGC_Output_Delay :4; + CBIOS_U32 Reserved_7to4 :4; + CBIOS_U32 AFGC_Input_Delay :4; + CBIOS_U32 Reserved_15to12 :4; + CBIOS_U32 AFGC_BeepGen :1; + CBIOS_U32 Reserved :2; + CBIOS_U32 _7_3_4_12_EPSS :1; + CBIOS_U32 _7_3_4_12_CLKSTOP :1; + CBIOS_U32 _7_3_4_12_S3D3coldSup :1; + CBIOS_U32 _7_3_4_12_D3COLDSUP :1; + CBIOS_U32 AFGT_NodeType :8; + CBIOS_U32 AFGT_UnSol_Capable :1; + }; +}REG_MM82DC_Arise; + + +typedef union _REG_MM82E0_Arise //HDAUDIO_CODEC1_PCM_Size_and_Sample_Rate_Capability_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 R1 :1; + CBIOS_U32 R2 :1; + CBIOS_U32 R3 :1; + CBIOS_U32 R4 :1; + CBIOS_U32 R5 :1; + CBIOS_U32 R6 :1; + CBIOS_U32 R7 :1; + CBIOS_U32 R8 :1; + CBIOS_U32 R9 :1; + CBIOS_U32 R10 :1; + CBIOS_U32 R11 :1; + CBIOS_U32 R12 :1; + CBIOS_U32 Reserved_15to12 :4; + CBIOS_U32 B8 :1; + CBIOS_U32 B16 :1; + CBIOS_U32 B20 :1; + CBIOS_U32 B24 :1; + CBIOS_U32 B32 :1; + CBIOS_U32 Reserved_31to21 :11; + }; +}REG_MM82E0_Arise; + + +typedef union _REG_MM82E4_Arise //HDAUDIO_CODEC1_Output_Amplifier_Capability_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 OutputAmpC_Offset :7; + CBIOS_U32 Reserved_7 :1; + CBIOS_U32 OutputAmpC_NumSteps :7; + CBIOS_U32 Reserved_15 :1; + CBIOS_U32 OutputAmpC_StepSize :7; + CBIOS_U32 Reserved_30to23 :8; + CBIOS_U32 OutputAmpC_Mute_Capable :1; + }; +}REG_MM82E4_Arise; + + +typedef union _REG_MM82E8_Arise //HDAUDIO_CODEC1_Functional_Group_Subsystem_ID_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FunGroup__SubsystemID_SSID :32; + }; +}REG_MM82E8_Arise; + + +typedef union _REG_MM82EC_Arise //HDAUDIO_CODEC1_Converter1_Audio_Widget_Capatibility_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Stereo :1; + CBIOS_U32 In_Amp_Present :1; + CBIOS_U32 Out_Amp_Present :1; + CBIOS_U32 Amp_Param_Override :1; + CBIOS_U32 Format_Override :1; + CBIOS_U32 Stripe :1; + CBIOS_U32 Proc_Widget :1; + CBIOS_U32 Unsol_Capable :1; + CBIOS_U32 Conn_List :1; + CBIOS_U32 Digital :1; + CBIOS_U32 Power_Cntrl :1; + CBIOS_U32 L_R_Swap :1; + CBIOS_U32 Reserved_15to12 :4; + CBIOS_U32 Delay :4; + CBIOS_U32 Type :4; + CBIOS_U32 Reserved_31to24 :8; + }; +}REG_MM82EC_Arise; + + +typedef union _REG_MM82F0_Arise //HDAUDIO_CODEC1_PinWidget1_Audio_Widget_Capability_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Stereo :1; + CBIOS_U32 In_Amp_Present :1; + CBIOS_U32 Out_Amp_Present :1; + CBIOS_U32 Amp_Param_Override :1; + CBIOS_U32 Format_Override :1; + CBIOS_U32 Stripe :1; + CBIOS_U32 Proc_Widget :1; + CBIOS_U32 Unsol_Capable :1; + CBIOS_U32 Conn_List :1; + CBIOS_U32 Digital :1; + CBIOS_U32 Power_Cntrl :1; + CBIOS_U32 L_R_Swap :1; + CBIOS_U32 Reserved_15to12 :4; + CBIOS_U32 Delay :4; + CBIOS_U32 Type :4; + CBIOS_U32 Reserved_31to24 :8; + }; +}REG_MM82F0_Arise; + + +typedef union _REG_MM82F4_Arise //HDAUDIO_CODEC1_PinWidget1_Pin_Capability_Parameter_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Impedance_Sense_Capable :1; + CBIOS_U32 Trigger_Reqd :1; + CBIOS_U32 Presense_Detect_Capable :1; + CBIOS_U32 Headphone_Drive_Capable :1; + CBIOS_U32 Output_Capable :1; + CBIOS_U32 Input_Capable :1; + CBIOS_U32 Balanced_IO_Pins :1; + CBIOS_U32 HDMI :1; + CBIOS_U32 Vref_Control_0_Hi_Z :1; + CBIOS_U32 Vref_Control_1_50_percent :1; + CBIOS_U32 Vref_Control_2_Ground :1; + CBIOS_U32 Vref_Control_3_Reserved :1; + CBIOS_U32 Vref_Control_4_80_percent :1; + CBIOS_U32 Vref_Control_5_100_percent :1; + CBIOS_U32 Vref_Control_7to6_Reserved :2; + CBIOS_U32 EAPD_Capable :1; + CBIOS_U32 Reserved_31to17 :15; + }; +}REG_MM82F4_Arise; + + +typedef union _REG_MM82F8_Arise //HDAUDIO_CODEC1_PinWidget1_Configuration_Default_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Config_Default_Sequence :4; + CBIOS_U32 Config_Default_Default_Assn :4; + CBIOS_U32 Config_Default_Misc :4; + CBIOS_U32 Config_Default_Color :4; + CBIOS_U32 Config_Default_Connect_Type :4; + CBIOS_U32 Config_Default_Default_Device :4; + CBIOS_U32 Config_Default_Location_low_bits :4; + CBIOS_U32 Config_Default_Location_hi_bits :2; + CBIOS_U32 Config_Default_Port_Connectivity :2; + }; +}REG_MM82F8_Arise; + + +typedef union _REG_MM82FC_Arise //HDAUDIO_CODEC1_Converter1_Stream_Format_and_Channel_Stream_ID_Controls_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Converter_Format_CHAN :4; + CBIOS_U32 Converter_Format_BITS :3; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Converter_Format_DIV :3; + CBIOS_U32 Converter_Format_MULT :3; + CBIOS_U32 Converter_Format_BASE :1; + CBIOS_U32 Converter_Format_TYPE :1; + CBIOS_U32 Reserved_1 :8; + CBIOS_U32 Converter_Channel :4; + CBIOS_U32 Converter_Stream :4; + }; +}REG_MM82FC_Arise; + + +typedef union _REG_MM8300_Arise //HDAUDIO_CODEC1_Converter1_Digital_Converter_and_PinWidget1_Unsolicited_Response_Controls_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CONVERTER1_DigiConvert_SIC_DigEn :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_V :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_VCFG :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_PRE :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_COPY :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_AUDIO :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_PRO :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_L :1; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_CC_6to0 :7; + CBIOS_U32 CONVERTER1_DigiConvert_SIC_Reserved :1; + CBIOS_U32 IEC_CODING_TYPE :4; + CBIOS_U32 disable_non_audio :1; + CBIOS_U32 copy_bit_polarity :1; + CBIOS_U32 enable_73eh_73fh_verb :1; + CBIOS_U32 keep_alive_enable :1; + CBIOS_U32 PINWIDGET1_UnsoliResponse_EnableUnsol_Tag :6; + CBIOS_U32 PINWIDGET1_UnsoliResponse_EnableUnsol_bit6 :1; + CBIOS_U32 PINWIDGET1_UnsoliResponse_EnableUnsol_Enable :1; + }; +}REG_MM8300_Arise; + + +typedef union _REG_MM8304_Arise //HDAUDIO_CODEC1_Converter_1_Stripe_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CONVERTER1_Stripe_Control :2; + CBIOS_U32 CONVERTER1_StripeControl_Reserved_7to2 :6; + CBIOS_U32 Undefined :12; + CBIOS_U32 CONVERTER1_StripeControl_Stripe_Capability__bit_0 :1; + CBIOS_U32 CONVERTER1_StripeControl_Stripe_Capability__bit_1 :1; + CBIOS_U32 CONVERTER1_StripeControl_Stripe_Capability__bit_2 :1; + CBIOS_U32 CONVERTER1_StripeControl_Reserved_31to23 :9; + }; +}REG_MM8304_Arise; + + +typedef union _REG_MM8308_Arise //HDAUDIO_CODEC1_PinWidget1_Pin_Sense_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PINWIDGET1_PinSense_RightChnl :1; + CBIOS_U32 PINWIDGET1_PinSense_Impedance :30; + CBIOS_U32 PINWIDGET1_PinSense_Presense_Detect :1; + }; +}REG_MM8308_Arise; + + +typedef union _REG_MM830C_Arise //HDAUDIO_CODEC1_PinWidget1_Pin_Widget_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PINWIDGET1_Control__VRefEn :3; + CBIOS_U32 PINWIDGET1_Control_Reserved_4to3 :2; + CBIOS_U32 PINWIDGET1_Control__In_Enable :1; + CBIOS_U32 PINWIDGET1_Control__Out_Enable :1; + CBIOS_U32 PINWIDGET1_Control__H_Phn_Enable :1; + CBIOS_U32 FunGroup_Power_State_PS_Set_PS_Act :4; + CBIOS_U32 power_state :7; + CBIOS_U32 hda_power_saving_en :1; + CBIOS_U32 PS_SettingsReset :1; + CBIOS_U32 Reserved_31 :11; + }; +}REG_MM830C_Arise; + + +typedef union _REG_MM8310_Arise //DP_Software_AUX_Write_Data_Bytes_3-0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Write_Bytes_3_0 :32; + }; +}REG_MM8310_Arise; + + +typedef union _REG_MM8314_Arise //DP_Software_AUX_Write_Data_Bytes_7-4_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Write_Bytes_7_4 :32; + }; +}REG_MM8314_Arise; + + +typedef union _REG_MM8318_Arise //DP_Software_AUX_Write_Data_Bytes_11-8_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Write_Bytes_11_8 :32; + }; +}REG_MM8318_Arsie; + + +typedef union _REG_MM831C_Arise //DP_Software_AUX_Write_Data_Bytes_15-12_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Write_Bytes_15_12 :32; + }; +}REG_MM831C_Arise; + + +typedef union _REG_MM8320_Arise //DP_Software_AUX_Read_Data_Bytes_3-0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Read_Bytes_3_0 :32; + }; +}REG_MM8320_Arise; + + +typedef union _REG_MM8324_Arise //DP_Software_AUX_Read_Data_Bytes_7-4_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Read_Bytes_7_4 :32; + }; +}REG_MM8324_Arise; + + +typedef union _REG_MM8328_Arise //DP_Software_AUX_Read_Data_Bytes_11-8_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Read_Bytes_11_8 :32; + }; +}REG_MM8328_Arise; + + +typedef union _REG_MM832C_Arise //DP_Software_AUX_Read_Data_Bytes_15-12_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUX_Read_Bytes_15_12 :32; + }; +}REG_MM832C_Arise; + + +typedef union _REG_MM8330_Arise //DP_Software_AUX_Timer_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SW_AUX :1; + CBIOS_U32 AUX_Request :1; + CBIOS_U32 AUX_DRDY :1; + CBIOS_U32 AUX_Timeout :1; + CBIOS_U32 SW_Timer_Clear :1; + CBIOS_U32 SW_Timer_Enable :1; + CBIOS_U32 SW_Timer_Counter :20; + CBIOS_U32 AUX_Command :4; + CBIOS_U32 HPD_Status :2; + }; +}REG_MM8330_Arise; + + +typedef union _REG_MM8334_Arise //DP_Software_AUX_Command_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SW_AUX_CMD :4; + CBIOS_U32 SW_AUX_Length :8; + CBIOS_U32 SW_AUX_Addr :20; + }; +}REG_MM8334_Arise; + + +typedef union _REG_MM8338_Arise //DP_NAUD_and_Mute_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 NAUD :24; + CBIOS_U32 Audio_InfoFrame :1; + CBIOS_U32 Audio_Output_Enable :1; + CBIOS_U32 Mute :1; + CBIOS_U32 Mute_Mode :1; + CBIOS_U32 Generate_MAUD :1; + CBIOS_U32 Generated_MAUD_Mode :1; + CBIOS_U32 AUX_SW_Reset :1; + CBIOS_U32 Link_Training_SW_Reset :1; + }; +}REG_MM8338_Arise; + + +typedef union _REG_MM833C_Arise //DP_MAUD_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MAUD :24; + CBIOS_U32 Secondary_data_Packet_ID :8; + }; +}REG_MM833C_Arise; + + +typedef union _REG_MM8340_Arise //DP_EPHY_MPLL_Power_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Bandgap_Power_Down :1; + CBIOS_U32 MPLL_Reg_Power_Down :1; + CBIOS_U32 MPLL_Power_Down :1; + CBIOS_U32 MPLL_PTAT_Current :2; + CBIOS_U32 MPLL_CP_Current :3; + CBIOS_U32 MPLL_N :8; + CBIOS_U32 MPLL_R :1; + CBIOS_U32 MPLL_P :2; + CBIOS_U32 SSC_Enable :1; + CBIOS_U32 SSC_Freq_Spread :1; + CBIOS_U32 Dither :1; + CBIOS_U32 Signal_Profile :1; + CBIOS_U32 Spread_Magnitude :2; + CBIOS_U32 TPLL_Reg_Power_Down :1; + CBIOS_U32 TPLL_Power_Down :1; + CBIOS_U32 reserverd :3; + CBIOS_U32 TPLL_N_Div :2; + }; +}REG_MM8340_Arise; + + +typedef union _REG_MM8344_Arise //DP_EPHY_TX_Power_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Resistance_Tuning_PD :1; + CBIOS_U32 Resistance_Tuning_Reset :1; + CBIOS_U32 Resistance_Tuning_Enable :1; + CBIOS_U32 TX_Resistance_Set_Enable :1; + CBIOS_U32 TX_Resistance_Value :4; + CBIOS_U32 TX_Reg_Power_Down_Lane0 :1; + CBIOS_U32 TX_Reg_Power_Down_Lane1 :1; + CBIOS_U32 TX_Reg_Power_Down_Lane2 :1; + CBIOS_U32 TX_Reg_Power_Down_Lane3 :1; + CBIOS_U32 Driver_Control_Lane0 :1; + CBIOS_U32 Driver_Control_Lane1 :1; + CBIOS_U32 Driver_Control_Lane2 :1; + CBIOS_U32 Driver_Control_Lane3 :1; + CBIOS_U32 EPHY1_SR_MAN_L0 :1; + CBIOS_U32 EPHY1_SR_MAN_L1 :1; + CBIOS_U32 EPHY1_SR_MAN_L2 :1; + CBIOS_U32 EPHY1_SR_MAN_L3 :1; + CBIOS_U32 DIU_EPHY1_AUX_DIAJ :3; + CBIOS_U32 EPHY_MPLL_CP :1; + CBIOS_U32 TX_Power_Control_Lane0 :2; + CBIOS_U32 TX_Power_Control_Lane1 :2; + CBIOS_U32 TX_Power_Control_Lane2 :2; + CBIOS_U32 TX_Power_Control_Lane3 :2; + }; +}REG_MM8344_Arise; + + +typedef union _REG_MM8348_Arise //DP_EPHY_Miscellaneous_Power_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Driver_Mode :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 RTNBIST :2; + CBIOS_U32 CKHLD :2; + CBIOS_U32 M1V :1; + CBIOS_U32 MT :1; + CBIOS_U32 T1V :1; + CBIOS_U32 TT :1; + CBIOS_U32 EPHY1_TPLL_CP :4; + CBIOS_U32 AUC_Ch_Op_Mode :2; + CBIOS_U32 TX_High_Impedance_Lane0 :1; + CBIOS_U32 TX_High_Impedance_Lane1 :1; + CBIOS_U32 TX_High_Impedance_Lane2 :1; + CBIOS_U32 TX_High_Impedance_Lane3 :1; + CBIOS_U32 HPD_Power_Down :1; + CBIOS_U32 TPLL_Reset_Signal :1; + CBIOS_U32 MPLL_SSC_Output :4; + CBIOS_U32 TPLL_Lock_Indicator :1; + CBIOS_U32 MPLL_Lock_Indicator :1; + CBIOS_U32 RTN_Results :4; + }; +}REG_MM8348_Arise; + + +typedef union _REG_MM834C_Arise //HDAUDIO_CODEC1_Channel_Count_and_ELD_DIP_Buffer_Size_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Converter_Channel_Count :8; + CBIOS_U32 Byte_Offset_into_ELD_memory :8; + CBIOS_U32 ELD_Buffer_Size :8; + CBIOS_U32 DIP_packet_buffer_size :3; + CBIOS_U32 DIP_PI_base_size :5; + }; +}REG_MM834C_Arise; + + +typedef union _REG_MM8350_Arise //HDAUDIO_CODEC1_ASP_Channel_Map_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 ASP_Channel_Map_Slot_0 :4; + CBIOS_U32 ASP_Channel_Map_Slot_1 :4; + CBIOS_U32 ASP_Channel_Map_Slot_2 :4; + CBIOS_U32 ASP_Channel_Map_Slot_3 :4; + CBIOS_U32 ASP_Channel_Map_Slot_4 :4; + CBIOS_U32 ASP_Channel_Map_Slot_5 :4; + CBIOS_U32 ASP_Channel_Map_Slot_6 :4; + CBIOS_U32 ASP_Channel_Map_Slot_7 :4; + }; +}REG_MM8350_Arise; + + +typedef union _REG_MM8354_Arise //HDAUDIO_CODEC1_DIP_Transmit_and_CP_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DIP_XmitCtrl_PI0 :2; + CBIOS_U32 DIP_XmitCtrl_PI1 :2; + CBIOS_U32 DIP_XmitCtrl_PI2 :2; + CBIOS_U32 DIP_XmitCtrl_PI3 :2; + CBIOS_U32 DIP_XmitCtrl_PI4 :2; + CBIOS_U32 DIP_XmitCtrl_PI5 :2; + CBIOS_U32 DIP_XmitCtrl_PI6 :2; + CBIOS_U32 DIP_XmitCtrl_PI7 :2; + CBIOS_U32 CP_Control_Requested_State :2; + CBIOS_U32 CP_Control_0 :1; + CBIOS_U32 CP_Control_UR_subtag :5; + CBIOS_U32 One_Bit_Audio_En :1; + CBIOS_U32 One_Bit_AUdio_Mapping :1; + CBIOS_U32 ELD_Rd_Status_Control :1; + CBIOS_U32 DIP_Write_Status_Control :1; + CBIOS_U32 DIP_Read_Status_Control :1; + CBIOS_U32 Reserved :3; + }; +}REG_MM8354_Arise; + + +typedef union _REG_MM8358_Arise //DP_Extension_Packet_Payload_Bytes_3-0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Extension_Packet_Payload_Bytes_3_0 :32; + }; +}REG_MM8358_Arise; + + +typedef union _REG_MM835C_Arise //DP_Extension_Packet_Payload_Bytes_7-4_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Extension_Packet_Payload_Bytes_7_4 :32; + }; +}REG_MM835C_Arise; + + +typedef union _REG_MM8360_Arise //DP_Extension_Packet_Payload_Bytes_11-8_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Extension_Packet_Payload_Bytes_11_8 :32; + }; +}REG_MM8360_Arise; + + +typedef union _REG_MM8364_Arise //DP_Extension_Packet_Payload_Bytes_15-12_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Extension_Packet_Payload_Bytes_15_12 :32; + }; +}REG_MM8364_Arise; + + +typedef union _REG_MM8368_Arise //DP +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DP1_SW_swing :6; + CBIOS_U32 DP1_SW_pp :5; + CBIOS_U32 DP1_SW_post_cursor :4; + CBIOS_U32 SW_swing_SW_PP_SW_post_cursor_load_index :6; + CBIOS_U32 enable_SW_swing_pp :1; + CBIOS_U32 PSR_ML_AUTOOFF :1; + CBIOS_U32 VER1P2 :1; + CBIOS_U32 RD_INTVAL :3; + CBIOS_U32 PSR_UPDATE :1; + CBIOS_U32 PSR_EXIT :1; + CBIOS_U32 PSR_ENTER :1; + CBIOS_U32 PSR_FORCE_BS :1; + CBIOS_U32 bugfix_en :1; + }; +}REG_MM8368_Arise; + + +typedef union _REG_MM836C_Arise //DP +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 EPHY_lane3_pre_pp :2; + CBIOS_U32 EPHY_lane2_pre_pp :2; + CBIOS_U32 EPHY_lane1_pre_pp :2; + CBIOS_U32 EPHY_lane0_pre_pp :2; + CBIOS_U32 EPHY_lane3_swing_level :2; + CBIOS_U32 EPHY_lane2_swing_level :2; + CBIOS_U32 EPHY_lane1_swing_level :2; + CBIOS_U32 EPHY_lane0_swing_level :2; + CBIOS_U32 EPHY_bit_rate :1; + CBIOS_U32 EPHY_HPD_IN :1; + CBIOS_U32 EPHY1_TPLL_ISEL :2; + CBIOS_U32 MR :3; + CBIOS_U32 MC :3; + CBIOS_U32 TR :3; + CBIOS_U32 TC :3; + }; +}REG_MM836C_Arise; + + +typedef union _REG_MM8370_Arise //DP_HDCP_Key_Selection_Vector_(KSV)_1_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 KSV_39to8 :32; + }; +}REG_MM8370_Arise; + + +typedef union _REG_MM8374_Arise //DP_HDCP_Control_1_and_Key_Selection_Vector_(KSV)_2_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 KSV_7to0 :8; + CBIOS_U32 Key_ECC_Done :1; + CBIOS_U32 DP_HDCP_INT :1; + CBIOS_U32 Key_Error_detect :1; + CBIOS_U32 Key_Error_correct :1; + CBIOS_U32 Reserved_14to12 :3; + CBIOS_U32 DPHDCP_Test_Mode_Select :1; + CBIOS_U32 Test_Key_Enable :1; + CBIOS_U32 AUX_Fail_Config :3; + CBIOS_U32 AUX_Def_Config :2; + CBIOS_U32 Notfinish_Fail :1; + CBIOS_U32 Disable_AUX :1; + CBIOS_U32 Not_support_0_KSV_repeater :1; + CBIOS_U32 Reserved_26to25 :2; + CBIOS_U32 CP_EN :1; + CBIOS_U32 Enc_Sel :1; + CBIOS_U32 Enc_Con :1; + CBIOS_U32 KSV_Rev_List :1; + CBIOS_U32 KSV_Verifcation_Done :1; + }; +}REG_MM8374_Arise; + + +typedef union _REG_MM8378_Arise //DP_HDCP_Control_2_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Authentication_Protocol_Status :2; + CBIOS_U32 Repeater_Flag :1; + CBIOS_U32 Device_Count :7; + CBIOS_U32 Interrupt_Source :4; + CBIOS_U32 AUX_Status :2; + CBIOS_U32 Reserved :16; + }; +}REG_MM8378_Arise; + + +typedef union _REG_MM837C_Arise //HDAUDIO_CODEC1_Control_Writes_Default_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Load_Converter1_StreamFormat :1; + CBIOS_U32 Load_Converter1_ChanStreamID :1; + CBIOS_U32 Load_Converter1_DigiConvert :1; + CBIOS_U32 Load_Pinwidget1_UnsoliResponse :1; + CBIOS_U32 Load_Converter1_StripeControl :1; + CBIOS_U32 Load_Pinwidget1_PinSense :1; + CBIOS_U32 Load_Pinwidget1_Control :1; + CBIOS_U32 Load_Pinwidget1_ConfigDefault :1; + CBIOS_U32 Load_Convert1_Converter_Channel_Count :1; + CBIOS_U32 Load_ASP_Channel_Mapping :1; + CBIOS_U32 Load_ELD_Offset :1; + CBIOS_U32 Load_DIP_XmitCtrl :1; + CBIOS_U32 Load_CP_Control :1; + CBIOS_U32 Load_One_Bit_audio_Control :1; + CBIOS_U32 Reserved :18; + }; +}REG_MM837C_Arise; + + +typedef union _REG_MM8380_Arise //HDAUDIO_CODEC1_Read_Out_Control_Select_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Load_Function_Group_SubsystemID :1; + CBIOS_U32 Load_Function_Group_Power_state :1; + CBIOS_U32 SW_Strm1_FIFO_Depth_Select :1; + CBIOS_U32 SW_Strm1_FIFO_Depth :5; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Reserved_1 :5; + CBIOS_U32 Strm1_Link_Position_Select :1; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 HDA_Offset_84_PRS :1; + CBIOS_U32 IMM_CMD_Response_V_SEL :1; + CBIOS_U32 Reserved_3 :1; + CBIOS_U32 HDAUDIO_Wall_Clock_Select :2; + CBIOS_U32 Wal_Clk_Cnt_Sel :1; + CBIOS_U32 Wal_Clk_Cnt_Clock_Sel1 :1; + CBIOS_U32 Wal_Clk_Cnt_Clock_Sel2 :1; + CBIOS_U32 Read_Out_Control_Select :8; + }; +}REG_MM8380_Arise; + + +typedef union _REG_MM8384_Arise //HDAUDIO_CODEC1_Read_Out_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Codec_Read_Out :32; + }; +}REG_MM8384_Arise; + + +typedef union _REG_MM8388_Arise //HDAUDIO_Wall_Clock_Ratio_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Wall_clock_ratio_low :32; + }; +}REG_MM8388_Arise; + + +typedef union _REG_MM838C_Arise //HDAUDIO_Wall_Clock_Ratio_Hi_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Wall_clock__ratio__hi :8; + CBIOS_U32 Wall_clock_ratio_enable :1; + CBIOS_U32 Reserved :23; + }; +}REG_MM838C_Arise; + + +typedef union _REG_MM8390_Arise //HDAUDIO_CODEC1_Channel_Status_Bits_31:0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 bit_0 :1; + CBIOS_U32 bit_1 :1; + CBIOS_U32 Channel_status_31_2 :30; + }; +}REG_MM8390_Arise; + + +typedef union _REG_MM8394_Arise //HDAUDIO_CODEC1_Channel_Status_Bits_63:32_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Channel_status_63_32 :32; + }; +}REG_MM8394_Arise; + + +typedef union _REG_MM8398_Arise //HDAUDIO_CODEC1_Channel_Status_Bits_95:64_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Channel_status_95_64 :32; + }; +}REG_MM8398_Arise; + + +typedef union _REG_MM839C_Arise //HDAUDIO_CODEC1_Channel_Status_Block_Bits_127:96_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Channel_status_127_96 :32; + }; +}REG_MM839C_Arise; + + +typedef union _REG_MM83A0_Arise //HDAUDIO_CODEC1_Channel_Status_Bits_159:128_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Channel_status_159_128 :32; + }; +}REG_MM83A0_Arise; + + +typedef union _REG_MM83A4_Arise //HDAUDIO_CODEC1_Channel_Status_Bits_191:160_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Channel_status_191_160 :32; + }; +}REG_MM83A4_Arise; + + +typedef union _REG_MM83A8_Arise //HDMI1_CODEC1_Audio_Clock_Regeneration_Numerator_(N)_and_CTS_Low_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 N :20; + CBIOS_U32 CTS :12; + }; +}REG_MM83A8_Arise; + + +typedef union _REG_MM83AC_Arise //HDMI_AUDIO_CODEC1_Audio_Clock_Cycle_Time_Stamp_(CTS)__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CTS :8; + CBIOS_U32 HW_Generated_CTS :20; + CBIOS_U32 Reserved :2; + CBIOS_U32 CTS_Select :1; + CBIOS_U32 HW_CTS_MODE :1; + }; +}REG_MM83AC_Arise; + + +typedef union _REG_MM8400_Arise //Thrid_Stream_1_Color/Chroma_8bit_Key_Lower_Bound_Register_(windows1) +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS1_8bit_B__Cb_Key_Lower_Bound :8; + CBIOS_U32 TS1_8bit_G_Y_Key_Lower_Bound :8; + CBIOS_U32 TS1_8bit_R_Cr_Key_Lower_Bound :8; + CBIOS_U32 Reserved0 :8; + }; + struct + { + CBIOS_U32 TS1_10bit_B__Cb_Key_Lower_Bound :10; + CBIOS_U32 TS1_10bit_G_Y_Key_Lower_Bound :10; + CBIOS_U32 TS1_10bit_R_Cr_Key_Lower_Bound :10; + CBIOS_U32 Reserved1 :2; + }; +}REG_MM8400_Arise; + +typedef union _REG_MM8410_Arise //Third_OVL +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ka_3to0_Or_Ks :4; + CBIOS_U32 Ka_7to4_oOr_Kp :4; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 Ovl2_Input_Stream :2; + CBIOS_U32 Ovl2_Color_Key_sel :2; + CBIOS_U32 Ovl2_Alpha_Select :2; + CBIOS_U32 Alpha_Rang :1; + CBIOS_U32 Alpha_Round :1; + CBIOS_U32 Reserved_1 :6; + CBIOS_U32 Ovl2_Key_Mode :4; + CBIOS_U32 Invert_Alpha_or_Ka :1; + CBIOS_U32 Ovl2_One_Shot :1; + CBIOS_U32 Ovl2_Vsync_Off_Flip :1; + CBIOS_U32 Ovl2_Enable_Work :1; + }; +}REG_MM8410_Arise; + + +typedef union _REG_MM8414_Arise //Third_Stream_1_windows1__Register_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Comp_Type :6; + CBIOS_U32 TS_Comp_Enable :1; + CBIOS_U32 Reserved_0 :17; + CBIOS_U32 TS_Fifo_Depth :3; + CBIOS_U32 TS_Share_Scaler_Fifo :1; + CBIOS_U32 Reserved_1 :4; + }; +}REG_MM8414_Arise; + + +typedef union _REG_MM8430_Arise //Thrid_Stream_windows_1_Frame_Buffer_Start_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_FB_Start_Address_0 :31; + CBIOS_U32 TS_Work_Reg_En :1; + }; +}REG_MM8430_Arise; + + +typedef union _REG_MM8438_Arise //ThirdStream_1_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Read_Length :2; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 TS_Stride :12; + CBIOS_U32 TS_Start_Address_Byte_Offset :4; + CBIOS_U32 Reserved_1 :11; + CBIOS_U32 TS_Abgr_En :1; + }; +}REG_MM8438_Arise; + + +typedef union _REG_MM843C_Arise //Third_Stream_1__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win1_KeyH :24; + CBIOS_U32 Reserved :8; + }; +}REG_MM843C_Arise; + + +typedef union _REG_MM8444_Arise //Third_Stream__Window_1_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Y_Start :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 TS_X_Start :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM8444_Arise; + + +typedef union _REG_MM8448_Arise //Third_Stream__Window_1_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win1_Src_H :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 TS_Win1_Src_W :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM8448_Arise; + + +typedef union _REG_MM844C_Arise //Third_Stream_window_1_Frame_Buffer_Start_Address_1__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win1_Roffset :31; + CBIOS_U32 TS_Win1_Vsync_Off_Flip :1; + }; +}REG_MM844C_Arise; + + +typedef union _REG_MM8450_Arise //Third_Stream__windows1__Frame_Buffer_display_timing +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win1_Dst_H :12; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 TS_Win1_Buf_Sel :1; + CBIOS_U32 TS_Win1_Dbl_Buf_Mode :1; + CBIOS_U32 TS_Win1_Triple_Buf_En :1; + CBIOS_U32 TS_Win1_Dst_W :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM8450_Arise; + + +typedef union _REG_MM8454_Arise //PS1/SS1_threshold +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_low_thrld :8; + CBIOS_U32 PS1_high_thrld :8; + CBIOS_U32 SS1_low_thrld :8; + CBIOS_U32 SS1_high_thrld :8; + }; +}REG_MM8454_Arise; + + +typedef union _REG_MM8458_Arise //TS_QS_two_window_enable +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_En :1; + CBIOS_U32 TS_Win2_En :1; + CBIOS_U32 Reserved :30; + }; +}REG_MM8458_Arise; + + +typedef union _REG_MM8460_Arise //MDI_read_latency_debug_register_1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_CHECKTAG :9; + CBIOS_U32 PS2_CHECKTAG :9; + CBIOS_U32 PS3_CHECKTAG :9; + CBIOS_U32 Reserved :5; + }; +}REG_MM8460_Arise; + + +typedef union _REG_MM8464_Arise //MDI_read_latency_debug_register_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS4_CHECKTAG :9; + CBIOS_U32 SS1_CHECKTAG :9; + CBIOS_U32 SS2_CHECKTAG :9; + CBIOS_U32 Reserved :5; + }; +}REG_MM8464_Arise; + + +typedef union _REG_MM8468_Arise //MDI_read_latency_debug_register_3 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS3_CHECKTAG :9; + CBIOS_U32 SS4_CHECKTAG :9; + CBIOS_U32 TS1_CHECKTAG :9; + CBIOS_U32 Reserved :5; + }; +}REG_MM8468_Arise; + + +typedef union _REG_MM846C_Arise //MDI_read_latency_debug_register_4 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS2_CHECKTAG :9; + CBIOS_U32 TS3_CHECKTAG :9; + CBIOS_U32 TS4_CHECKTAG :9; + CBIOS_U32 RESERVED :5; + }; +}REG_MM846C_Arise; + + +typedef union _REG_MM8470_Arise //MDI_read_latency_debug_register_5 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS1_CHECKTAG :9; + CBIOS_U32 QS2_CHECKTAG :9; + CBIOS_U32 QS3_CHECKTAG :9; + CBIOS_U32 RESERVED :5; + }; +}REG_MM8470_Arise; + + +typedef union _REG_MM8474_Arise //MDI_read_latency_debug_register_6 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS4_CHECKTAG :9; + CBIOS_U32 BURST_CHECKTAG :6; + CBIOS_U32 RESERVED_0 :1; + CBIOS_U32 Check_en :1; + CBIOS_U32 Check_rst :1; + CBIOS_U32 RESERVED_1 :14; + }; +}REG_MM8474_Arise; + + +typedef union _REG_MM8478_Arise //MDI_read_latency_debug_register_7 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_CTR_MAX :13; + CBIOS_U32 RESERVED_0 :3; + CBIOS_U32 SS1_CTR_MAX :13; + CBIOS_U32 RESERVED_1 :3; + }; +}REG_MM8478_Arise; + + +typedef union _REG_MM847C_Arise //MDI_read_latency_debug_register_8 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS1_CTR_MAX :13; + CBIOS_U32 RESERVED_0 :3; + CBIOS_U32 QS1_CTR_MAX :13; + CBIOS_U32 RESERVED_1 :3; + }; +}REG_MM847C_Arise; + + +typedef union _REG_MM8480_Arise //Thrid_Stream_windows_2_Frame_Buffer_Start_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_FB_Start_Address_0 :31; + CBIOS_U32 TS_Win2_Work_Reg_En :1; + }; +}REG_MM8480_Arise; + + +typedef union _REG_MM8484_Arise //Third_Stream_window_2_Frame_Buffer_Start_Address_1__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_Roffset :31; + CBIOS_U32 TS_Win2_Vsync_Off_Flip :1; + }; +}REG_MM8484_Arise; + + +typedef union _REG_MM8488_Arise //ThirdStream_windows2_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_Read_Length :2; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 TS_Win2_Stride :12; + CBIOS_U32 TS_Win2_Start_Address_Byte_Offset :4; + CBIOS_U32 Reserved_1 :11; + CBIOS_U32 TS_Win2_Abgr_En :1; + }; +}REG_MM8488_Arise; + + +typedef union _REG_MM848C_Arise //Third_Stream__Windows2_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_Y_Start :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 TS_Win2_X_Start :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM848C_Arise; + + +typedef union _REG_MM8490_Arise //Third_Stream__Windows2_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_Src_H :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 TS_Win2_Src_W :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM8490_Arise; + + +typedef union _REG_MM8494_Arise //Third_Stream__windows2__Frame_Buffer_display_timing +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_Dst_H :12; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 TS_Win2_Buf_Sel :1; + CBIOS_U32 TS_Win2_Dbl_Buf_Mode :1; + CBIOS_U32 TS_Win2_Triple_Buf_En :1; + CBIOS_U32 TS_Win2_Dst_W :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM8494_Arise; + + +typedef union _REG_MM8498_Arise //Third_stream_windows1_surface_address_offset +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :5; + CBIOS_U32 TS_Win1_Base_Offset :27; + }; +}REG_MM8498_Arise; + + +typedef union _REG_MM849C_Arise //Third_stream_windows2_surface_address_offset +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :5; + CBIOS_U32 TS_Win2_Base_Offset :27; + }; +}REG_MM849C_Arise; + + +typedef union _REG_MM84A0_Arise //Third_Stream_1_windows2__Register_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_Comp_Type :6; + CBIOS_U32 TS_Win2_Comp_Enable :1; + CBIOS_U32 Reserved_0 :17; + CBIOS_U32 TS_Win2_Fifo_Depth :3; + CBIOS_U32 TS_Win2_Share_Scaler_Fifo :1; + CBIOS_U32 Reserved_1 :4; + }; +}REG_MM84A0_Arise; + + +typedef union _REG_MM84A4_Arise //Third_stream_windows1_upsacler_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win1_Hacc :21; + CBIOS_U32 TS_Win1_Htap_Sel :1; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 TS_Win1_Alpha_Scale :1; + CBIOS_U32 Reserved_1 :7; + }; +}REG_MM84A4_Arise; + + +typedef union _REG_MM84A8_Arise //Third_stream_windows1_upsacler_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win1_Vacc :21; + CBIOS_U32 TS_Win1_Vtap_Sel :1; + CBIOS_U32 TS_Win1_Vdup_En :1; + CBIOS_U32 Reserved :8; + CBIOS_U32 TS_Win1_Deint_En :1; + }; +}REG_MM84A8_Arise; + + +typedef union _REG_MM84B0_Arise //Third_stream_windows2_chroma_keyH +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_KeyH :24; + CBIOS_U32 RESERVED :8; + }; +}REG_MM84B0_Arise; + + +typedef union _REG_MM84B4_Arise //Third_stream_windows2_upsacler_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_Hacc :21; + CBIOS_U32 Ts_Win2_Htap_Sel :1; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 TS_Win2_Alpha_Scale :1; + CBIOS_U32 Reserved_1 :7; + }; +}REG_MM84B4_Arise; + + +typedef union _REG_MM84B8_Arise //Third_stream_windows2_upsacler_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_Vacc :21; + CBIOS_U32 TS_Win2_Vtap_Sel :1; + CBIOS_U32 TS_Win2_Vdup_En :1; + CBIOS_U32 Reserved :8; + CBIOS_U32 TS_Win2_Deint_En :1; + }; +}REG_MM84B8_Arise; + + +typedef union _REG_MM33000_Arise //ChipID_read_request_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :7; + CBIOS_U32 CHIP_ID_read_request :1; + CBIOS_U32 Reserved_1 :24; + }; +}REG_MM33000_Arise; + + +typedef union _REG_MM33100_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDMIIN_EN :1; + CBIOS_U32 BCH_BYPASS :1; + CBIOS_U32 Channel_status_sel :1; + CBIOS_U32 audio_Mute_value_sel :1; + CBIOS_U32 Ctrl_period_length :4; + CBIOS_U32 audio_Mute_vale_SW :1; + CBIOS_U32 ISRC_int_mode :1; + CBIOS_U32 DST_mode :1; + CBIOS_U32 one_base_address :1; + CBIOS_U32 sw_flush :1; + CBIOS_U32 sw_reset :1; + CBIOS_U32 counter_en :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 Line_number :12; + CBIOS_U32 video_Mute_value_sel :1; + CBIOS_U32 video_Mute_value_SW :1; + CBIOS_U32 stable_clear_contidon_1_enable :1; + CBIOS_U32 stable_clear_contidon_2_enable :1; + }; +}REG_MM33100_Arise; + + +typedef union _REG_MM33104_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PR_SW :4; + CBIOS_U32 STRUC_3D_SW :4; + CBIOS_U32 CD_SW :4; + CBIOS_U32 Y_SW :2; + CBIOS_U32 default_phase_SW :1; + CBIOS_U32 Interlace_SW :1; + CBIOS_U32 HDMI_FORMAT_SW :3; + CBIOS_U32 video_software_setting_enable :1; + CBIOS_U32 XCLK_NU :11; + CBIOS_U32 stable_output_enable :1; + }; +}REG_MM33104_Arise; + + +typedef union _REG_MM33108_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VDEN_SW :12; + CBIOS_U32 HDEN_SW :12; + CBIOS_U32 VBLK_SW :7; + CBIOS_U32 stable_clear_contidon_3_enable :1; + }; +}REG_MM33108_Arise; + + +typedef union _REG_MM3310C_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :5; + CBIOS_U32 audio_int_size :27; + }; +}REG_MM3310C_Arise; + + +typedef union _REG_MM33110_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :5; + CBIOS_U32 BASADR1 :27; + }; +}REG_MM33110_Arise; + + +typedef union _REG_MM33114_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :5; + CBIOS_U32 LENGTH1 :27; + }; +}REG_MM33114_Arise; + + +typedef union _REG_MM33118_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :5; + CBIOS_U32 BASADR2 :27; + }; +}REG_MM33118_Arise; + + +typedef union _REG_MM3311C_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :5; + CBIOS_U32 LENGTH2 :27; + }; +}REG_MM3311C_Arise; + + +typedef union _REG_MM33120_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 WHDEN :12; + CBIOS_U32 WHBACK :9; + CBIOS_U32 WVSYNC :4; + CBIOS_U32 WVBLK :7; + }; +}REG_MM33120_Arise; + + +typedef union _REG_MM33124_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 WVDEN :12; + CBIOS_U32 WHFRONT :12; + CBIOS_U32 WVBACK :7; + CBIOS_U32 INTERLACE :1; + }; +}REG_MM33124_Arise; + + +typedef union _REG_MM33128_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 WHSYNC :9; + CBIOS_U32 WVFRONT :5; + CBIOS_U32 HSYNC_INV :1; + CBIOS_U32 VSYNC_INV :1; + CBIOS_U32 INT_source_0_enable :1; + CBIOS_U32 INT_source_1_enable :1; + CBIOS_U32 INT_source_2_enable :1; + CBIOS_U32 INT_source_3_enable :1; + CBIOS_U32 INT_source_4_enable :1; + CBIOS_U32 INT_source_5_enable :1; + CBIOS_U32 INT_source_6_enable :1; + CBIOS_U32 INT_source_7_enable :1; + CBIOS_U32 INT_source_8_enable :1; + CBIOS_U32 INT_source_9_enable :1; + CBIOS_U32 INT_source_10_enable :1; + CBIOS_U32 INT_source_11_enable :1; + CBIOS_U32 INT_source_12_enable :1; + CBIOS_U32 INT_source_13_enable :1; + CBIOS_U32 INT_source_14_enable :1; + CBIOS_U32 INT_source_15_enable :1; + }; +}REG_MM33128_Arise; + + +typedef union _REG_MM3312C_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUDIO_INT1 :1; + CBIOS_U32 AUDIO_INT2 :1; + CBIOS_U32 AVL_GAMUT :1; + CBIOS_U32 AVL_ISRC1 :1; + CBIOS_U32 AVL_ISRC2 :1; + CBIOS_U32 AVL_ACP :1; + CBIOS_U32 ACP_TIMEOUT :1; + CBIOS_U32 AVL_GCP :1; + CBIOS_U32 FEDGE_EPHY_DATA_OK :1; + CBIOS_U32 AVL_INFO_MPEG :1; + CBIOS_U32 AVL_INFO_SPD :1; + CBIOS_U32 AVL_INFO_VENDOR :1; + CBIOS_U32 AVL_INFO_AUDIO :1; + CBIOS_U32 AVL_INFO_AVI :1; + CBIOS_U32 ERR_INFO_CHECKSUM :1; + CBIOS_U32 AVL_ONEBIT :1; + CBIOS_U32 AVL_HBR :1; + CBIOS_U32 AVL_AUDIO_CSTATUS :1; + CBIOS_U32 ERR_AUDIO_PARITY :1; + CBIOS_U32 AVL_AUDIO_CK_REG :1; + CBIOS_U32 BCH_ERRH :1; + CBIOS_U32 BCH_ERR0 :1; + CBIOS_U32 BCH_ERR1 :1; + CBIOS_U32 BCH_ERR2 :1; + CBIOS_U32 BCH_ERR3 :1; + CBIOS_U32 BCH_CORECTH :1; + CBIOS_U32 BCH_CORECT0 :1; + CBIOS_U32 BCH_CORECT1 :1; + CBIOS_U32 BCH_CORECT2 :1; + CBIOS_U32 BCH_CORECT3 :1; + CBIOS_U32 FEDGE_EPHY_INCLK_OK :1; + CBIOS_U32 FEDGE_EPHY_INCLK_LOCK :1; + }; +}REG_MM3312C_Arise; + + +typedef union _REG_MM33130_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :5; + CBIOS_U32 LINK_position :27; + }; +}REG_MM33130_Arise; + + +typedef union _REG_MM33134_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Recived_Gamut_packet_PB_Bytes_3_0 :32; + }; +}REG_MM33134_Arise; + + +typedef union _REG_MM33138_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Recived_Gamut_packet_PB_Bytes_7_4 :32; + }; +}REG_MM33138_Arise; + + +typedef union _REG_MM3313C_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Recived_Gamut_packet_PB_Bytes_11_8 :32; + }; +}REG_MM3313C_Arise; + + +typedef union _REG_MM33140_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Recived_Gamut_packet_PB_Bytes_15_12 :32; + }; +}REG_MM33140_Arise; + + +typedef union _REG_MM33144_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Recived_Gamut_packet_PB_Bytes_19_16 :32; + }; +}REG_MM33144_Arise; + + +typedef union _REG_MM33148_Arise //CEC1_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CEC_Initiator_Retry_Cnt :3; + CBIOS_U32 CEC_Device_Addr :4; + CBIOS_U32 CEC_Initiator_Dest_Addr :4; + CBIOS_U32 CEC_Initiator_Cmd_Len :5; + CBIOS_U32 CEC_Initiator_Broadcast :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 CEC_Enable :1; + CBIOS_U32 CEC_Initiator_Cmd_Available :1; + CBIOS_U32 cec20_enable :1; + CBIOS_U32 pulse_sel :1; + CBIOS_U32 error_detect_sel :1; + CBIOS_U32 fall_to_rise_error_en :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 cec_start_total_l_para_reg :7; + }; +}REG_MM33148_Arise; + + +typedef union _REG_MM3314C_Arise //CEC1_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CEC_Initiator_Command :32; + }; +}REG_MM3314C_Arise; + + +typedef union _REG_MM33150_Arise //CEC1_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Initiator_Transmit_Finished :1; + CBIOS_U32 Initiator_Transmit_Succeed :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 Follower_Received_Source_Addr :4; + CBIOS_U32 Follower_Received_Broadcast :1; + CBIOS_U32 Follower_Received_Cmd_Len :5; + CBIOS_U32 Follower_Received_Ready :1; + CBIOS_U32 Debug_use :18; + }; +}REG_MM33150_Arise; + + +typedef union _REG_MM33154_Arise //CEC1_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Follower_Recvd_Command :32; + }; +}REG_MM33154_Arise; + + +typedef union _REG_MM33158_Arise //CEC1_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 cec_start_para_reg :7; + CBIOS_U32 cec_logic0_para_reg :7; + CBIOS_U32 cec_logic1_para_reg :7; + CBIOS_U32 cec_error_para_reg :7; + CBIOS_U32 cec_f2r_error_para4_reg :2; + CBIOS_U32 reserved :1; + CBIOS_U32 cec_timing_para_sel :1; + }; +}REG_MM33158_Arise; + + +typedef union _REG_MM3315C_Arise //CEC1_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 cec_ack0_para_reg :7; + CBIOS_U32 cec_ack1_para_reg :7; + CBIOS_U32 cec_start_rise_l_para_reg :7; + CBIOS_U32 cec_start_rise_h_para_reg :7; + CBIOS_U32 cec_f2r_error_para3_reg :4; + }; +}REG_MM3315C_Arise; + + +typedef union _REG_MM33160_Arise //CEC1_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 cec_start_total_h_para_reg :7; + CBIOS_U32 cec_ack_total_para_reg :7; + CBIOS_U32 cec_error_total_para_reg :7; + CBIOS_U32 cec_data_strobe_para_reg :7; + CBIOS_U32 cec_f2r_error_para4_reg :4; + }; +}REG_MM33160_Arise; + + +typedef union _REG_MM33164_Arise //CEC1_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 cec_wr_para_reg :7; + CBIOS_U32 cec_f2f_error_para_reg :7; + CBIOS_U32 cec_f2r_error_para1_reg :7; + CBIOS_U32 cec_f2r_error_para2_reg :7; + CBIOS_U32 cec_f2r_error_para3_reg :3; + CBIOS_U32 cec_f2r_error_para4_reg :1; + }; +}REG_MM33164_Arise; + + +typedef union _REG_MM33168_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_ISRC2_packet_PB_Bytes_11_8 :32; + }; +}REG_MM33168_Arise; + + +typedef union _REG_MM3316C_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_ISRC2_packet_PB_Bytes_15_12 :32; + }; +}REG_MM3316C_Arise; + + +typedef union _REG_MM33170_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_ACP_packet_PB_Byte_0_3 :32; + }; +}REG_MM33170_Arise; + + +typedef union _REG_MM33174_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_ACP_packet_PB_Byte_7_4 :32; + }; +}REG_MM33174_Arise; + + +typedef union _REG_MM33178_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_ACP_packet_PB_Byte_11_8 :32; + }; +}REG_MM33178_Arise; + + +typedef union _REG_MM3317C_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_ACP_packet_PB_Byte_15_12 :32; + }; +}REG_MM3317C_Arise; + + +typedef union _REG_MM33180_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_MPEG_info_packet_PB_Byte_0_3 :32; + }; +}REG_MM33180_Arise; + + +typedef union _REG_MM33184_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_MPEG_info_packet_PB_Byte_7_4 :32; + }; +}REG_MM33184_Arise; + + +typedef union _REG_MM33188_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_MPEG_info_packet_PB_Byte_9_8 :16; + CBIOS_U32 Received_MPEG_info_packet_version :8; + CBIOS_U32 Received_SPD_info_packet_version :8; + }; +}REG_MM33188_Arise; + + +typedef union _REG_MM3318C_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_Gamut_packet_HB_value :16; + CBIOS_U32 Received_ISRC1_packet_HB :8; + CBIOS_U32 Received_ACP_packet_type :8; + }; +}REG_MM3318C_Arise; + + +typedef union _REG_MM33190_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_SPD_packet_information_Byte_0_3 :32; + }; +}REG_MM33190_Arise; + + +typedef union _REG_MM33194_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_SPD_packet_information_Byte_7_4 :32; + }; +}REG_MM33194_Arise; + + +typedef union _REG_MM33198_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_SPD_packet_information_Byte_11_8 :32; + }; +}REG_MM33198_Arise; + + +typedef union _REG_MM3319C_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_SPD_packet_information_Byte_15_12 :32; + }; +}REG_MM3319C_Arise; + + +typedef union _REG_MM331A0_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_SPD_packet_information_Byte_19_16 :32; + }; +}REG_MM331A0_Arise; + + +typedef union _REG_MM331A4_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_SPD_packet_information_Byte_23_20 :32; + }; +}REG_MM331A4_Arise; + + +typedef union _REG_MM331A8_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_Audio_info_packet_PB_byte9_8 :16; + CBIOS_U32 Received_Audio_info_packet_version :8; + CBIOS_U32 Received_SPD_info_packet_PB_byte_24 :8; + }; +}REG_MM331A8_Arise; + + +typedef union _REG_MM331AC_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_VENDOR_info_packet_PB_byte3_0 :32; + }; +}REG_MM331AC_Arise; + + +typedef union _REG_MM331B0_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_VENDOR_info_packet_PB_byte7_4 :32; + }; +}REG_MM331B0_Arise; + + +typedef union _REG_MM331B4_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_VENDOR_info_packet_PB_byte11_8 :32; + }; +}REG_MM331B4_Arise; + + +typedef union _REG_MM331B8_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_VENDOR_info_packet_PB_byte15_12 :32; + }; +}REG_MM331B8_Arise; + + +typedef union _REG_MM331BC_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_VENDOR_info_packet_PB_byte19_16 :32; + }; +}REG_MM331BC_Arise; + + +typedef union _REG_MM331C0_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_VENDOR_info_packet_PB_byte23_20 :32; + }; +}REG_MM331C0_Arise; + + +typedef union _REG_MM331C4_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_VENDOR_info_packet_PB_byte26_24 :24; + CBIOS_U32 Received_VENDOR_info_packet_version :8; + }; +}REG_MM331C4_Arise; + + +typedef union _REG_MM331C8_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_Audio_info_packet_PB_byte3_0 :32; + }; +}REG_MM331C8_Arise; + + +typedef union _REG_MM331CC_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_Audio_info_packet_PB_7_4 :32; + }; +}REG_MM331CC_Arise; + + +typedef union _REG_MM331D0_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_AVI_info_packet_PB_byte3_0 :32; + }; +}REG_MM331D0_Arise; + + +typedef union _REG_MM331D4_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_AVI_info_packet_PB_byte7_4 :32; + }; +}REG_MM331D4_Arise; + + +typedef union _REG_MM331D8_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_AVI_info_packet_PB_byte11_8 :32; + }; +}REG_MM331D8_Arise; + + +typedef union _REG_MM331DC_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_AVI_info_packet_PB_byte_12 :8; + CBIOS_U32 Received_AVI_info_packet_version_value :8; + CBIOS_U32 INT_source_16_enable :1; + CBIOS_U32 INT_source_17_enable :1; + CBIOS_U32 INT_source_18_enable :1; + CBIOS_U32 INT_source_19_enable :1; + CBIOS_U32 INT_source_20_enable :1; + CBIOS_U32 INT_source_21_enable :1; + CBIOS_U32 INT_source_22_enable :1; + CBIOS_U32 INT_source_23_enable :1; + CBIOS_U32 INT_source_24_enable :1; + CBIOS_U32 SEL_SUB_CSTATUS :2; + CBIOS_U32 VSYNC_NU :1; + CBIOS_U32 range :4; + }; +}REG_MM331DC_Arise; + + +typedef union _REG_MM331E0_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_Channel_status_byte_3_0 :32; + }; +}REG_MM331E0_Arise; + + +typedef union _REG_MM331E4_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_Channel_status_byte_7_4 :32; + }; +}REG_MM331E4_Arise; + + +typedef union _REG_MM331E8_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_Channel_status_byte_11_8 :32; + }; +}REG_MM331E8_Arise; + + +typedef union _REG_MM331EC_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_Channel_status_byte_15_12 :32; + }; +}REG_MM331EC_Arise; + + +typedef union _REG_MM331F0_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_Channel_status_byte_19_16 :32; + }; +}REG_MM331F0_Arise; + + +typedef union _REG_MM331F4_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_Channel_status_byte_23_20 :32; + }; +}REG_MM331F4_Arise; + + +typedef union _REG_MM331F8_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_user_data_value_byte_3_0 :32; + }; +}REG_MM331F8_Arise; + + +typedef union _REG_MM331FC_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_user_data_value_byte_7_4 :32; + }; +}REG_MM331FC_Arise; + + +typedef union _REG_MM33200_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_user_data_value_byte_11_8 :32; + }; +}REG_MM33200_Arise; + + +typedef union _REG_MM33204_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_user_data_value_byte_15_12 :32; + }; +}REG_MM33204_Arise; + + +typedef union _REG_MM33208_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_user_data_value_byte_19_16 :32; + }; +}REG_MM33208_Arise; + + +typedef union _REG_MM3320C_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Received_user_data_value_byte_23_20 :32; + }; +}REG_MM3320C_Arise; + + +typedef union _REG_MM33210_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUDIO_CK_CTS :20; + CBIOS_U32 GCP_PP :4; + CBIOS_U32 GCP_CD :4; + CBIOS_U32 GCP_default_PHASE :1; + CBIOS_U32 GCP_AVMUTE :1; + CBIOS_U32 STABLE_OUT :1; + CBIOS_U32 LAYOUT_REG :1; + }; +}REG_MM33210_Arise; + + +typedef union _REG_MM33214_Arise //HDMI_IN_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 AUDIO_CK_N :20; + CBIOS_U32 DEEPC_CDOUT :4; + CBIOS_U32 DET_PASS0 :1; + CBIOS_U32 DET_PASS1 :1; + CBIOS_U32 DET_PASS2 :1; + CBIOS_U32 FLATDONTW :1; + CBIOS_U32 LSBZERO :1; + CBIOS_U32 FLAT2ZERO :1; + CBIOS_U32 HUNSAME :1; + CBIOS_U32 AVL_DST :1; + }; +}REG_MM33214_Arise; + + +typedef union _REG_MM33218_Arise //HDMI_IN_Ephy_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FHH_EPHYMSTEN :1; + CBIOS_U32 FHH_BG_OW :1; + CBIOS_U32 FHH_BG_TRIM :2; + CBIOS_U32 FHP_MPLL0_CP :3; + CBIOS_U32 FHH_MPLL_LOCK_EN :1; + CBIOS_U32 FHHS0_RTNRXSET :4; + CBIOS_U32 FHH_RTNBIST :2; + CBIOS_U32 FHHS0_RTNRXSETEN :1; + CBIOS_U32 FHH00_DATA_OW :1; + CBIOS_U32 FHH01_DATA_OW :1; + CBIOS_U32 FHH02_DATA_OW :1; + CBIOS_U32 FHH_INCLK_LOCK_EN :1; + CBIOS_U32 FHH_INCLK_OK_EN :1; + CBIOS_U32 FHH_DATADETVTH :3; + CBIOS_U32 FHH_CLKDETVTH :3; + CBIOS_U32 FHH00_RXPWRSET :2; + CBIOS_U32 FHH01_RXPWRSET :2; + CBIOS_U32 FHH02_RXPWRSET :2; + }; +}REG_MM33218_Arise; + + +typedef union _REG_MM3321C_Arise //HDMI_IN_Ephy_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FHH00_RXPWRSETEN :1; + CBIOS_U32 FHH01_RXPWRSETEN :1; + CBIOS_U32 FHH02_RXPWRSETEN :1; + CBIOS_U32 FHH_RXCLKSEL :3; + CBIOS_U32 FHH_VCOPDSEL :1; + CBIOS_U32 FHH_RCVPDSEL :1; + CBIOS_U32 FHH_IVCPSEL :3; + CBIOS_U32 FHH00_FTXSWNSETEN :1; + CBIOS_U32 FHH01_FTXSWNSETEN :1; + CBIOS_U32 FHH02_FTXSWNSETEN :1; + CBIOS_U32 FHH00_FTXSWNSET :2; + CBIOS_U32 FHH01_FTXSWNSET :2; + CBIOS_U32 FHH02_FTXSWNSET :2; + CBIOS_U32 FHH00_DFC_OWEN :1; + CBIOS_U32 FHH01_DFC_OWEN :1; + CBIOS_U32 FHH02_DFC_OWEN :1; + CBIOS_U32 FHH_CDR_UGB_HBW :1; + CBIOS_U32 FHH_RTN_VTH :2; + CBIOS_U32 FHHc_RXPWRSETEN :1; + CBIOS_U32 FHHS_RCVVCM_CLKLANE :1; + CBIOS_U32 FHHc_RXPWRSET :2; + CBIOS_U32 FHH_DFC_VTH :2; + }; +}REG_MM3321C_Arise; + + +typedef union _REG_MM33220_Arise //HDMI_IN_Ephy_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FHH_EQTNMODE :4; + CBIOS_U32 FHH_Eqtndcbw :4; + CBIOS_U32 FHH_Eqtnhfbw :4; + CBIOS_U32 FHH_Eqtnosbw :4; + CBIOS_U32 FHH_Eqtnwtbw :4; + CBIOS_U32 FHHs0_Eqtndfe :2; + CBIOS_U32 FHH_Eqtndiven :1; + CBIOS_U32 Eqtnen_Lf :1; + CBIOS_U32 Eqtnalwy :1; + CBIOS_U32 FHH0_Eqtnspdswen :1; + CBIOS_U32 FHHS0_EQTNDFETRN :1; + CBIOS_U32 FHHS0_DCSETEN :1; + CBIOS_U32 FHHS0_EQTNVTH :3; + CBIOS_U32 FHHS0_HFSETEN :1; + }; +}REG_MM33220_Arise; + + +typedef union _REG_MM33224_Arise //HDMI_IN_Ephy_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FHHS0_DCSET :5; + CBIOS_U32 FHHS0_HFSET :5; + CBIOS_U32 FHHS0_OSSET :5; + CBIOS_U32 FHHS0_W1SET :5; + CBIOS_U32 FHHS0_W2SET :5; + CBIOS_U32 FHHS0_OSSETEN :1; + CBIOS_U32 FHHS0_W1SETEN :1; + CBIOS_U32 FHHS0_W2SETEN :1; + CBIOS_U32 FHH_EQTNBISTEVT :3; + CBIOS_U32 FHH_EQTNBISTEN :1; + }; +}REG_MM33224_Arise; + + +typedef union _REG_MM33228_Arise //HDMI_IN_Ephy_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FHHS0_FDRATIO :3; + CBIOS_U32 FHHS0_FTSRATIO :3; + CBIOS_U32 FHHS0_P1EXT :3; + CBIOS_U32 FHHS0_P0SEXT :3; + CBIOS_U32 FHHS0_NIPRSEL :2; + CBIOS_U32 FHHS0_KIPRSEL :2; + CBIOS_U32 FHHS0_NIPCSEL :2; + CBIOS_U32 FHHS0_KIPCSEL :2; + CBIOS_U32 FHHS0_NLFSEL :2; + CBIOS_U32 FHHS0_KLFSEL :2; + CBIOS_U32 FHHS0_NTSEL :1; + CBIOS_U32 FHHS0_KTSEL :1; + CBIOS_U32 FHHS0_PWUP :2; + CBIOS_U32 FHHS0_DIVTMSETEN :1; + CBIOS_U32 FHS0_DIVICPSETEN :1; + CBIOS_U32 FHS0_DFC_VCOST :2; + }; +}REG_MM33228_Arise; + + +typedef union _REG_MM3322C_Arise //HDMI_IN_Ephy_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 EPH00_DCOUT :5; + CBIOS_U32 EPH01_DCOUT :5; + CBIOS_U32 EPH02_DCOUT :5; + CBIOS_U32 Reserved :1; + CBIOS_U32 FHHSc_KTSEL :1; + CBIOS_U32 FHHSc_KLFSEL :2; + CBIOS_U32 RAWSPIDF_SW :1; + CBIOS_U32 NPCM_BIT_SW :1; + CBIOS_U32 AUDIO_BIT_SW :1; + CBIOS_U32 EN_SW_AUDIO :1; + CBIOS_U32 NPCM_mode_SW :1; + CBIOS_U32 CA_SW :8; + }; +}REG_MM3322C_Arise; + + +typedef union _REG_MM33230_Arise //HDMI_IN_Ephy_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 EPH_BG_OK :1; + CBIOS_U32 EPH_MPLL_OK :1; + CBIOS_U32 EPHS0_RTNRXOUT :4; + CBIOS_U32 EPH_INCLK_LOCKED :1; + CBIOS_U32 EPH_INCLK_OK :1; + CBIOS_U32 EPH00_DIV :2; + CBIOS_U32 EPH01_DIV :2; + CBIOS_U32 EPH02_DIV :2; + CBIOS_U32 FHHc_VCO_BAND :1; + CBIOS_U32 FHH02_VCO_BAND :1; + CBIOS_U32 FHH01_VCO_BAND :1; + CBIOS_U32 FHH00_VCO_BAND :1; + CBIOS_U32 EPHc_DIV :2; + CBIOS_U32 EPHc_DFC_WORK :1; + CBIOS_U32 EPH02_DFC_WORK :1; + CBIOS_U32 EPH01_DFC_WORK :1; + CBIOS_U32 EPH00_DFC_WORK :1; + CBIOS_U32 EPH02_RCAD_OK :1; + CBIOS_U32 EPH01_RCAD_OK :1; + CBIOS_U32 EPH00_RCAD_OK :1; + CBIOS_U32 TRUE_RCAD_OK :1; + CBIOS_U32 MASTER_OK :1; + CBIOS_U32 EPH00_DATA_OK :1; + CBIOS_U32 EPH01_DATA_OK :1; + CBIOS_U32 EPH02_DATA_OK :1; + }; +}REG_MM33230_Arise; + + +typedef union _REG_MM33234_Arise //HDMI_IN_Ephy_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 EPH00_HFOUT :5; + CBIOS_U32 EPH01_HFOUT :5; + CBIOS_U32 EPH02_HFOUT :5; + CBIOS_U32 EPH00_OSOUT :5; + CBIOS_U32 EPH01_OSOUT :5; + CBIOS_U32 EPH02_OSOUT :5; + CBIOS_U32 EPHS0_DFCRSTB :1; + CBIOS_U32 EPHSc_DFCRSTB :1; + }; +}REG_MM33234_Arise; + + +typedef union _REG_MM33238_Arise //HDMI_IN_Ephy_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 EPH00_W1OUT :5; + CBIOS_U32 EPH01_W1OUT :5; + CBIOS_U32 EPH02_W1OUT :5; + CBIOS_U32 EPH00_W2OUT :5; + CBIOS_U32 EPH01_W2OUT :5; + CBIOS_U32 EPH02_W2OUT :5; + CBIOS_U32 LPH00_EQTNEN :1; + CBIOS_U32 LPH00_EQTNRSTB :1; + }; +}REG_MM33238_Arise; + + +typedef union _REG_MM3323C_Arise //HDMI_IN_Ephy_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LPH_MPLLPDB :1; + CBIOS_U32 LPHS0_RTNPDB :1; + CBIOS_U32 LPHS0_RTNRSTB :1; + CBIOS_U32 LPHS0_RTNEN :1; + CBIOS_U32 LPH00_DATADETPDB :1; + CBIOS_U32 LPH01_DATADETPDB :1; + CBIOS_U32 LPH02_DATADETPDB :1; + CBIOS_U32 LPH_CLKDETPDB :1; + CBIOS_U32 LPH00_RXPWR :2; + CBIOS_U32 LPH01_RXPWR :2; + CBIOS_U32 LPH02_RXPWR :2; + CBIOS_U32 LPHc_RXPWR :2; + CBIOS_U32 LPH_BG_PDB :1; + CBIOS_U32 EQTNEN0_SW :1; + CBIOS_U32 EQTNEN1_SW :1; + CBIOS_U32 EQTNEN2_SW :1; + CBIOS_U32 EQTNRSTB0_SW :1; + CBIOS_U32 EQTNRSTB1_SW :1; + CBIOS_U32 EQTNRSTB2_SW :1; + CBIOS_U32 LPH00_FTXSWN :2; + CBIOS_U32 LPH01_FTXSWN :2; + CBIOS_U32 LPH02_FTXSWN :2; + CBIOS_U32 LPHc_FTXSWN :2; + CBIOS_U32 EQ_SoftWare_Setting_enable :1; + }; +}REG_MM3323C_Arise; + + +typedef union _REG_MM33240_Arise //HDMI_IN__register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 WFRAME :32; + }; +}REG_MM33240_Arise; + + +typedef union _REG_MM33244_Arise //HDMI_IN_Ephy_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FHH00_DFC_OW :3; + CBIOS_U32 FHH01_DFC_OW :3; + CBIOS_U32 FHH02_DFC_OW :3; + CBIOS_U32 FHH_PFDDBW :2; + CBIOS_U32 FHHc_FTXSWNSETEN :1; + CBIOS_U32 FHHc_FTXSWNSET :2; + CBIOS_U32 FHHc_DFC_OW :3; + CBIOS_U32 FHHc_DFC_OWEN :1; + CBIOS_U32 FHHS_PFD_ICP :2; + CBIOS_U32 FHHS_PFD_ICP_EN :1; + CBIOS_U32 FHHSc_NIPRSEL :2; + CBIOS_U32 FHHSc_KIPRSEL :2; + CBIOS_U32 FHHSc_NIPCSEL :2; + CBIOS_U32 FHHSc_KIPCSEL :2; + CBIOS_U32 FHHSc_NTSEL :1; + CBIOS_U32 FHHSc_NLFSEL :2; + }; +}REG_MM33244_Arise; + + +typedef union _REG_MM33248_Arise //STREAM_Process_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FRC_REG0 :32; + }; +}REG_MM33248_Arise; + + +typedef union _REG_MM3324C_Arise //STREAM_Process_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FRC_REG1 :32; + }; +}REG_MM3324C_Arise; + + +typedef union _REG_MM33250_Arise //STREAM_Process_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FRC_REG2 :32; + }; +}REG_MM33250_Arise; + + +typedef union _REG_MM33254_Arise //STREAM_Process_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FRC_REG3 :32; + }; +}REG_MM33254_Arise; + + +typedef union _REG_MM33258_Arise //STREAM_Process_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FRC_REG4 :32; + }; +}REG_MM33258_Arise; + + +typedef union _REG_MM3325C_Arise //STREAM_Process_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FRC_REG5 :32; + }; +}REG_MM3325C_Arise; + + +typedef union _REG_MM33260_Arise //STREAM_Process_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FRC_REG6 :32; + }; +}REG_MM33260_Arise; + + +typedef union _REG_MM33264_Arise //STREAM_Process_register_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FRC_REG7 :32; + }; +}REG_MM33264_Arise; + + +typedef union _REG_MM33268_Arise //HDMI_IN__Registers_Group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 page_flip_mode :1; + CBIOS_U32 Allign_enable :1; + CBIOS_U32 TERC4_Error_0 :1; + CBIOS_U32 TERC4_Error_1 :1; + CBIOS_U32 TERC4_Error_2 :1; + CBIOS_U32 TMDS_state_error :1; + CBIOS_U32 Data_island_timeout :1; + CBIOS_U32 Data_island_length_error :1; + CBIOS_U32 Allign_error :1; + CBIOS_U32 CK_COUNT_Enable :1; + CBIOS_U32 EDID_R_W_enable :1; + CBIOS_U32 IIC_EDID_RW_EN :1; + CBIOS_U32 DRV_FORCE_WEN :1; + CBIOS_U32 Reserved :4; + CBIOS_U32 EDID_Status :4; + CBIOS_U32 HDMIIN_TestPass_Status :3; + CBIOS_U32 HDMIIN_SEL0 :2; + CBIOS_U32 HDMIIN_SEL1 :2; + CBIOS_U32 HDMIIN_SEL2 :2; + CBIOS_U32 HDMIIN_FIRST_ALLIGN :1; + CBIOS_U32 HDMIIN_ALLIGN :1; + }; +}REG_MM33268_Arise; + + +typedef union _REG_MM3326C_Arise +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 ctl_byte :16; + CBIOS_U32 Reserved_0 :5; + CBIOS_U32 reverse_Hsync_signal :1; + CBIOS_U32 reverse_Vsync_signal :1; + CBIOS_U32 _3d_mode_enable :1; + CBIOS_U32 _3d_frame_identification :1; + CBIOS_U32 phy_switch :1; + CBIOS_U32 pixel_source :2; + CBIOS_U32 lane_mode :2; + CBIOS_U32 byte_mode :1; + CBIOS_U32 Reserved_1 :1; + }; +}REG_MM3326C_Arise; + + +typedef union _REG_MM33270_Arise +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 padding_counter :30; + CBIOS_U32 padding__type :2; + }; +}REG_MM33270_Arise; + + +typedef union _REG_MM33274_Arise +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :28; + CBIOS_U32 vx1_state :2; + CBIOS_U32 manual_boot_up :1; + CBIOS_U32 en_vx1 :1; + }; +}REG_MM33274_Arise; + + +typedef union _REG_MM33278_Arise //diu_downscaler_register_group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Enable_Work_Register :1; + CBIOS_U32 Vsync_Off_Flip :1; + CBIOS_U32 Reserved :30; + }; +}REG_MM33278_Arise; + + +typedef union _REG_MM3327C_Arise //diu_downscaler_register_group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DOWNSCALING_EN :1; + CBIOS_U32 _3D_LEFT_RIGHT :1; + CBIOS_U32 REG_HOR_INC :1; + CBIOS_U32 REG_VER_MODULAR :1; + CBIOS_U32 VER_INC :4; + CBIOS_U32 HOR_INC :4; + CBIOS_U32 VER_MODULAR :4; + CBIOS_U32 HOR_MODULAR :5; + CBIOS_U32 DST_FORMAT :1; + CBIOS_U32 SCALING_RCP :10; + }; +}REG_MM3327C_Arise; + + +typedef union _REG_MM33280_Arise //diu_downscaler_register_group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 clip_left_11 :1; + CBIOS_U32 REG_HOR_MODULAR_5 :1; + CBIOS_U32 clip_right_12 :1; + CBIOS_U32 REG_DAT_FORMAT :1; + CBIOS_U32 DOUBLE_FB :1; + CBIOS_U32 SCALING_SW_RESET :1; + CBIOS_U32 FIFO_RST_EN :1; + CBIOS_U32 REG_SCL_MODE_0 :1; + CBIOS_U32 REG_SCL_MODE_1 :1; //write back enable bit + CBIOS_U32 clip_left_10to0 :11; + CBIOS_U32 clip_right_11to0 :12; + }; +}REG_MM33280_Arise; + + +typedef union _REG_MM33284_Arise //diu_downscaler_register_group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HIGH_THRESHOLD_7_6 :2; + CBIOS_U32 LOW_THRESHOLD_7_6 :2; + CBIOS_U32 REG_YCBCR422_MAP :1; + CBIOS_U32 REG_DROP_FRAME :1; + CBIOS_U32 reserved_0 :1; + CBIOS_U32 BASE_ADDR_29_26 :4; + CBIOS_U32 reserved_1 :9; + CBIOS_U32 HIGH_THRESHOLD :6; + CBIOS_U32 LOW_THRESHOLD :6; + }; +}REG_MM33284_Arise; + + +typedef union _REG_MM33288_Arise //diu_downscaler_register_group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :3; + CBIOS_U32 STRIDE :9; + CBIOS_U32 OFFSET :20; + }; +}REG_MM33288_Arise; + + +typedef union _REG_MM3328C_Arise //MDI_time_out_reg +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_time_out :8; + CBIOS_U32 SS1_time_out :8; + CBIOS_U32 TS1_time_out :8; + CBIOS_U32 QS1_time_out :8; + }; +}REG_MM3328C_Arise; + + +typedef union _REG_MM33290_Arise //iga1_centre_mode_register, PS dst window +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 WriteBackBaseAddress :30; + CBIOS_U32 Reserved :2; + }; +}REG_MM33290_Arise; + + +typedef union _REG_MM33294_Arise //iga1_centre_mode_register, PS dst window +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Center_Vde_Begin :13; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 Center_Vde_End :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM33294_Arise; + + +typedef union _REG_MM332A0_Arise //ss1_plane_alpha +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ovl1_pPlane_Alpha :8; + CBIOS_U32 Reserved_0 :6; + CBIOS_U32 Ovl1_Alpha_Blend_Mode :1; + CBIOS_U32 Reserved_1 :17; + }; +}REG_MM332A0_Arise; + + +typedef union _REG_MM332A4_Arise //ts1_plane_alpha +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ovl2_Plane_Alpha :8; + CBIOS_U32 Reserved_0 :6; + CBIOS_U32 Ovl2_Alpha_Blend_Mode :1; + CBIOS_U32 Reserved_1 :17; + }; +}REG_MM332A4_Arise; + + +typedef union _REG_MM332A8_Arise //GPIO_REN_and_DAC_mode_en +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FPVEE_FPVDD_pinmux_oen :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 DAC_mode_enable :1; + CBIOS_U32 Reserved_1 :29; + }; +}REG_MM332A8_Arise; + + +typedef union _REG_MM332AC_Arise //DAC_SENSE_Read_and_LUT_read_pointer_control +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LUT_SSC_HDMI_INFO_DP_INFO_write_current_index :8; + CBIOS_U32 LUT_SSC_HDMI_INFO_DP_INFO_Read_current_index :8; + CBIOS_U32 reserved :8; + CBIOS_U32 Reserved :4; + CBIOS_U32 DAC1_SENSE_C :1; + CBIOS_U32 DAC1_SENSE_R :1; + CBIOS_U32 DAC1_SENSE_G :1; + CBIOS_U32 DAC1_SENSE_B :1; + }; +}REG_MM332AC_Arise; + + +typedef union _REG_MM332B0_Arise //MDI_time_out_reg_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_time_out :8; + CBIOS_U32 SS2_time_out :8; + CBIOS_U32 TS2_time_out :8; + CBIOS_U32 QS2_time_out :8; + }; +}REG_MM332B0_Arise; + + +typedef union _REG_MM332B4_Arise //MDI_time_out_reg_3 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP0_time_out :8; + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 Reserved_1 :8; + CBIOS_U32 VIP1_time_out :8; + }; +}REG_MM332B4_Arise; + + +typedef union _REG_MM332B8_Arise //MDI_time_out_reg_4 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS4_timtout :8; + CBIOS_U32 SS4_timeout :8; + CBIOS_U32 TS4_timeout :8; + CBIOS_U32 QS4_timeout :8; + }; +}REG_MM332B8_Arise; + + +typedef union _REG_MM332BC_Arise //QS_overlay_register_1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ka_3to0_Or_Ks :4; + CBIOS_U32 Ka_7to4_Or_Kp :4; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 Ovl3_Input_Stream :2; + CBIOS_U32 Reserved_1 :12; + CBIOS_U32 Ovl3_Key_Mode_Sel :4; + CBIOS_U32 Invert_Alpha_Or_Ka :1; + CBIOS_U32 Ovl3_One_Shot :1; + CBIOS_U32 Ovl3_Vsync_Off_Flip :1; + CBIOS_U32 Ovl3_Enable_Work :1; + }; +}REG_MM332BC_Arise; + + +typedef union _REG_MM332C0_Arise //QS1_overlay_register_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ovl3_Plane_Alpha :8; + CBIOS_U32 Reserved_0 :6; + CBIOS_U32 Ovl3_Alpha_Blend_Mode :1; + CBIOS_U32 Reserved_1 :17; + }; +}REG_MM332C0_Arise; + + +typedef union _REG_MM332C4_Arise //NV12C_base_address +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :5; + CBIOS_U32 BASE_ADDR_C :27; + }; +}REG_MM332C4_Arise; + + +typedef union _REG_MM332C8_Arise //EFUSE_redundancy_data_0_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DRV_EFUSE_R_DATA0 :32; + }; +}REG_MM332C8_Arise; + + +typedef union _REG_MM332CC_Arise //EFUSE_redundancy_data_1_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DRV_EFUSE_R_DATA1 :32; + }; +}REG_MM332CC_Arise; + + +typedef union _REG_MM332D0_Arise //EFUSE_redundancy_data_2_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DRV_EFUSE_R_DATA2 :32; + }; +}REG_MM332D0_Arise; + + +typedef union _REG_MM332D4_Arise //EFUSE_redundancy_data_3_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DRV_EFUSE_R_DATA3 :32; + }; +}REG_MM332D4_Arise; + + +typedef union _REG_MM332D8_Arise //EFUSE_redundancy_flag_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DRV_EFUSE_RF :8; + CBIOS_U32 DRV_EFUSE_R_READ_ST :2; + CBIOS_U32 Reserved :22; + }; +}REG_MM332D8_Arise; + + +typedef union _REG_MM332DC_Arise //HDCP_EFUSE_driver_programming_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PGM_EFUSE_ADDR :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 PGM_EFUSE_TIME :9; + CBIOS_U32 Reserved_1 :4; + CBIOS_U32 PGM_EFUSE_TIME_SEL :1; + CBIOS_U32 PGM_EFUSE_FINISH :1; + CBIOS_U32 PGM_EFUSE_REQ :1; + }; +}REG_MM332DC_Arise; + + +typedef union _REG_MM332E0_Arise //SS1_SCL_H_Reg +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_Hacc :21; + CBIOS_U32 SS_Htap_Sel :1; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 SS_Alpha_Ups_En :1; + CBIOS_U32 Reserved_1 :7; + }; +}REG_MM332E0_Arise; + + +typedef union _REG_MM332E4_Arise //SS1_SCL_V_Reg +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_Vacc :21; + CBIOS_U32 SS_Vtap_Sel :1; + CBIOS_U32 SS_Vdup_En :1; + CBIOS_U32 Reserved :8; + CBIOS_U32 SS_Vint_En :1; + }; +}REG_MM332E4_Arise; + + +typedef union _REG_MM332E8_Arise //SS_KEYH_for_chroma_key +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_KeyH :24; + CBIOS_U32 Reserved :8; + }; +}REG_MM332E8_Arise; + + +typedef union _REG_MM332F0_Arise //MDI_timeout_reg_5 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TVW0_timeout :8; + CBIOS_U32 TVW1_timeout :8; + CBIOS_U32 TVW2_timeout :8; + CBIOS_U32 TVW3_timeout :8; + }; +}REG_MM332F0_Arise; + + +typedef union _REG_MM332F4_Arise //MDI_timeout_reg_6 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP0_time_out :8; + CBIOS_U32 VIP1_time_out :8; + CBIOS_U32 VIP2_time_out :8; + CBIOS_U32 VIP3_time_out :8; + }; +}REG_MM332F4_Arise; + + +typedef union _REG_MM332F8_Arise //MDI_timeout_reg_7 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDA_timeout :8; + CBIOS_U32 Reserved :24; + }; +}REG_MM332F8_Arise; + + +typedef union _REG_MM332FC_Arise //MDI_timeout_disable_reg +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 read_clients_timeout_disable :16; + CBIOS_U32 write_clients_timeout_disable :8; + CBIOS_U32 HDA_timeout_disable :1; + CBIOS_U32 Reserved :7; + }; +}REG_MM332FC_Arise; + + +typedef union _REG_MM33300_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 s_vtotal :13; + CBIOS_U32 reserved_0 :3; + CBIOS_U32 s_vdisp_end :13; + CBIOS_U32 TIM_USE_MMIO :1; + CBIOS_U32 reserved_1 :2; + }; +}REG_MM33300_Arise; + + +typedef union _REG_MM33304_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 s_vblnk_beg :13; + CBIOS_U32 reserved_0 :3; + CBIOS_U32 s_vblnk_end :9; + CBIOS_U32 reserved_1 :7; + }; +}REG_MM33304_Arise; + + +typedef union _REG_MM33318_Arise //SCL_SD_Width_Ratio_Reg +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_Scl_Width_Ratio :21; + CBIOS_U32 Reserved :9; + CBIOS_U32 PS_Htap_Sel :1; + CBIOS_U32 PS_Alpha_Upen :1; + }; +}REG_MM33318_Arise; + + +typedef union _REG_MM3331C_Arise //SCL_SD_Height_Ratio_Reg +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_Scl_Height_Ratio :21; + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 PS_Vdup_En :1; + CBIOS_U32 PS_Vtap_Sel :1; + CBIOS_U32 PS1_Deint_En :1; + }; +}REG_MM3331C_Arise; + + +typedef union _REG_MM33320_Arise //SCL_Src_Size_Reg +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_Scl_Src_Width :13; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 PS_Scl_Src_Height :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM33320_Arise; + + +typedef union _REG_MM333D8_Arise //PWM_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 backlight_value :16; + CBIOS_U32 PWM_frequency_counter :16; + }; +}REG_MM333D8_Arise; + + +typedef union _REG_MM333DC_Arise //PWM_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 REG_PWM_EN :1; + CBIOS_U32 REG_PWM_CTRL :2; + CBIOS_U32 PWM_frequency_counter :2; + CBIOS_U32 DIU_DIO_PWM_oen :1; + CBIOS_U32 Reserved_31to6 :26; + }; +}REG_MM333DC_Arise; + + +typedef union _REG_MM333E0_Arise //PWM1_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 backlight_value :16; + CBIOS_U32 PWM_frequency_counter :16; + }; +}REG_MM333E0_Arise; + + +typedef union _REG_MM333E4_Arise //PWM1_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 REG_PWM_EN :1; + CBIOS_U32 REG_PWM_CTRL :2; + CBIOS_U32 PWM_frequency_counter :2; + CBIOS_U32 DIU_DIO_PWM_oen :1; + CBIOS_U32 Reserved_31to6 :26; + }; +}REG_MM333E4_Arise; + + +typedef union _REG_MM333E8_Arise //PWM2_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 backlight_value :16; + CBIOS_U32 PWM_frequency_counter :16; + }; +}REG_MM333E8_Arise; + + +typedef union _REG_MM333EC_Arise //PWM2_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 REG_PWM_EN :1; + CBIOS_U32 REG_PWM_CTRL :2; + CBIOS_U32 PWM_frequency_counter :2; + CBIOS_U32 DIU_DIO_PWM_oen :1; + CBIOS_U32 Reserved_31to6 :26; + }; +}REG_MM333EC_Arise; + + +typedef union _REG_MM333F0_Arise //PWM3_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 backlight_value :16; + CBIOS_U32 PWM_frequency_counter :16; + }; +}REG_MM333F0_Arise; + + +typedef union _REG_MM333F4_Arise //PWM3_setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 REG_PWM_EN :1; + CBIOS_U32 REG_PWM_CTRL :2; + CBIOS_U32 PWM_frequency_counter :2; + CBIOS_U32 DIU_DIO_PWM_oen :1; + CBIOS_U32 Reserved_31to6 :26; + }; +}REG_MM333F4_Arise; + + +typedef union _REG_MM33400_Arise //QS_compress/threshold_register(windows1) +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_Comp_Type :6; + CBIOS_U32 QS_Win1_Comp_Enable :1; + CBIOS_U32 Reserved_0 :17; + CBIOS_U32 QS_Win1_Fifo_Depth_Control :3; + CBIOS_U32 QS_Win1_Share_Scaler_Fifo :1; + CBIOS_U32 Reserved_1 :4; + }; +}REG_MM33400_Arise; + + +typedef union _REG_MM33404_Arise //Quad__windows_1_Frame_Buffer_Start_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_FB_Start_Address_0 :31; + CBIOS_U32 QS_Win1_Work_Reg_En :1; + }; +}REG_MM33404_Arise; + + +typedef union _REG_MM33408_Arise //Quad_Stream_window_1_Frame_Buffer_Start_Address_1__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_Roffset :31; + CBIOS_U32 QS_Win1_Vsync_Off_Flip :1; + }; +}REG_MM33408_Arise; + + +typedef union _REG_MM3340C_Arise //Quad_Stream_1_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_Read_Length :2; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 QS_Win1_Stride :12; + CBIOS_U32 QS_Win1_Start_Address_Byte_Offset :4; + CBIOS_U32 Reserved_1 :11; + CBIOS_U32 QS_Win1_Abgr_En :1; + }; +}REG_MM3340C_Arise; + + +typedef union _REG_MM33410_Arise //Quad_stream_windows1_surface_address_offset +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :5; + CBIOS_U32 Suf_Badr_Off :27; + }; +}REG_MM33410_Arise; + + +typedef union _REG_MM33414_Arise //Quad_Stream__Window_1_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Q1_Dat_H :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 Q1_Dat_W :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM33414_Arise; + + +typedef union _REG_MM33418_Arise //Quad_Stream__Window_1_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_Y_Start :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 QS_Win1_X_Start :13; + CBIOS_U32 RESERVED_1 :3; + }; +}REG_MM33418_Arise; + + +typedef union _REG_MM3341C_Arise //Quad_Stream__windows1__Frame_Buffer_display_timing +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_Crt_H :12; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 QS_Win1_Buf_SEL :1; + CBIOS_U32 QS_Win1_Dbl_Buf_Mode :1; + CBIOS_U32 QS_Win1_Triple_Buf_En :1; + CBIOS_U32 QS_Win1_Crt_W :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM3341C_Arise; + + +typedef union _REG_MM33420_Arise //Quad_stream_windows1_upsacler_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_Hacc :21; + CBIOS_U32 Qs_Win1_Htap_Sel :1; + CBIOS_U32 Reserved :10; + }; +}REG_MM33420_Arise; + + +typedef union _REG_MM33424_Arise //Quad_stream_windows1_upsacler_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_Vacc :21; + CBIOS_U32 QS_Win1_Vtap_Sel :1; + CBIOS_U32 QS_Win1_Vdup_En :1; + CBIOS_U32 Reserved :8; + CBIOS_U32 QS_Win1_Deint_En :1; + }; +}REG_MM33424_Arise; + + +typedef union _REG_MM33428_Arise //QS1_win1/win2_threshold +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_Low_Thrld :8; + CBIOS_U32 QS_Win1_High_Thrld :8; + CBIOS_U32 QS_Win2_Low_Thrld :8; + CBIOS_U32 QS_Win2_High_Thrld :8; + }; +}REG_MM33428_Arise; + + +typedef union _REG_MM3342C_Arise //Quad_Stream_1_Color/Chroma_8bit_Key_Lower_Bound_Register_(windows1_) +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_8bit_B__Cb_Key_Lower_Bound :8; + CBIOS_U32 QS_Win1_8bit_G_Y_Key_Lower_Bound :8; + CBIOS_U32 QS_Win1_8bit_R_Cr_Key_Lower_Bound :8; + CBIOS_U32 Reserved_0 :7; + CBIOS_U32 QS_Win1_oneshot :1; + }; + struct + { + CBIOS_U32 QS_Win1_10bit_B__Cb_Key_Lower_Bound :10; + CBIOS_U32 QS_Win1_10bit_G_Y_Key_Lower_Bound :10; + CBIOS_U32 QS_Win1_10bit_R_Cr_Key_Lower_Bound :10; + CBIOS_U32 Reserved :1; + CBIOS_U32 QS_Win1_Oneshot_Bit :1; + }; +}REG_MM3342C_Arise; + + +typedef union _REG_MM33430_Arise //qs_windows2__csc_control_register_(qs_windows1_register_MM3480) +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :11; + CBIOS_U32 QS_Win2_YCbCr_Order :1; + CBIOS_U32 QS_Win2_Format :3; + CBIOS_U32 Reserved_2 :3; + CBIOS_U32 QS_Win2_Alpha_Upscaler :1; + CBIOS_U32 QS_Win2_444_YCbCr_Order :1; + CBIOS_U32 QS_Win2_Enable :1; + CBIOS_U32 Reserved_3 :11; + }; +}REG_MM33430_Arise; + + +typedef union _REG_MM33434_Arise //qs_windows2_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win2_F1 :14; + CBIOS_U32 QS_Win2_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33434_Arise; + + +typedef union _REG_MM33438_Arise //qs_windows2_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win2_F3 :14; + CBIOS_U32 QS_Win2_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33438_Arise; + + +typedef union _REG_MM3343C_Arise //qs_windows2_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win2_F5 :14; + CBIOS_U32 QS_Win2_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM3343C_Arise; + + +typedef union _REG_MM33440_Arise //qs_windows2_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win2_F7 :14; + CBIOS_U32 QS_Win2_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33440_Arise; + + +typedef union _REG_MM33444_Arise //qs_windows2_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win2_F9 :14; + CBIOS_U32 QS_Win2_Bright :9; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 QS_Win2_In_Format :3; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 QS_Win2_Out_Format :3; + CBIOS_U32 QS_Win2_Program :1; + }; +}REG_MM33444_Arise; + + +typedef union _REG_MM33448_Arise //Quad_Stream_1_Color/Chroma_8bit_Key_Lower_Bound_Register_(windows2_) +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win2_8bit_B__Cb_Key_Lower_Bound :8; + CBIOS_U32 QS_Win2_8bit_G_Y_Key_Lower_Bound :8; + CBIOS_U32 QS_Win2_8bit_R_Cr_Key_Lower_Bound :8; + CBIOS_U32 Reserved_0 :7; + CBIOS_U32 QS_Win2_Oneshot :1; + }; + struct + { + CBIOS_U32 QS_Win2_10bit_B__Cb_Key_Lower_Bound :10; + CBIOS_U32 QS_Win2_10bit_G_Y_Key_Lower_Bound :10; + CBIOS_U32 QS_Win2_10bit_R_Cr_Key_Lower_Bound :10; + CBIOS_U32 Reserved :1; + CBIOS_U32 QS_Win2_Oneshot_Bit :1; + }; +}REG_MM33448_Arise; + + +typedef union _REG_MM3344C_Arise //qs_windows2_chroma_keyh +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win2_KeyH :24; + CBIOS_U32 Reserved :8; + }; +}REG_MM3344C_Arise; + + +typedef union _REG_MM33450_Arise //QS_compress/threshold_register(windows2) +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win2_Comp_Type :6; + CBIOS_U32 QS_Win2_Comp_Enable :1; + CBIOS_U32 Reserved_0 :17; + CBIOS_U32 QS_Win2_Fifo_Depth_Control :3; + CBIOS_U32 QS_Win2_Share_Scaler_Fifo :1; + CBIOS_U32 Reserved_1 :4; + }; +}REG_MM33450_Arise; + + +typedef union _REG_MM33454_Arise //Quad__windows_1_Frame_Buffer_Start_Address_0_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win2_FB_Start_Address_0 :31; + CBIOS_U32 QS_Win2_Work_Reg_En :1; + }; +}REG_MM33454_Arise; + + +typedef union _REG_MM33458_Arise //Quad_Stream_window2_Frame_Buffer_Start_Address_1__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_win2_ROFFSET :31; + CBIOS_U32 QS_win2_VSYNC_OFF_page_flip :1; + }; +}REG_MM33458_Arise; + + +typedef union _REG_MM3345C_Arise //Quad_Stream_1_Stride_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_win2_Read_Length :2; + CBIOS_U32 RESERVED_0 :2; + CBIOS_U32 QS_win2_Stride :12; + CBIOS_U32 QS_win2__Start_Address_Byte_Offset :4; + CBIOS_U32 RESERVED_1 :11; + CBIOS_U32 QS_win2_ABGR_EN :1; + }; +}REG_MM3345C_Arise; + + +typedef union _REG_MM33460_Arise //Quad_stream_window2_surface_address_offset +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RESERVED :5; + CBIOS_U32 SUF_BADR_OFF :27; + }; +}REG_MM33460_Arise; + + +typedef union _REG_MM33464_Arise //Quad_Stream__Window2_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Q1_DAT_H :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 Q1_DAT_W :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM33464_Arise; + + +typedef union _REG_MM33468_Arise //Quad_Stream__Window2_Start_Coordinates_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS1_Y_Start :12; + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 QS1_X_Start :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM33468_Arise; + + +typedef union _REG_MM3346C_Arise //Third_Stream_Window1_and_Window2_threshold__Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win1_Lthrhld :8; + CBIOS_U32 TS_Win1_Hthrhld :8; + CBIOS_U32 TS_Win2_Lthrhld :8; + CBIOS_U32 TS_Win2_Hthrhld :8; + }; +}REG_MM3346C_Arise; + + +typedef union _REG_MM33470_Arise //Quad_stream_windows2_upsacler_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win2_Hacc :21; + CBIOS_U32 Qs_Win2_Htap_Sel :1; + CBIOS_U32 Reserved :10; + }; +}REG_MM33470_Arise; + + +typedef union _REG_MM33474_Arise //Quad_stream_windows2_upsacler_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win2_Vacc :21; + CBIOS_U32 QS_Win2_Vtap_Sel :1; + CBIOS_U32 QS_Win2_Vdup_En :1; + CBIOS_U32 Reserved :8; + CBIOS_U32 QS_Win2_Deint_En :1; + }; +}REG_MM33474_Arise; + + +typedef union _REG_MM33478_Arise //Quad_Stream__windows2__Frame_Buffer_display_timing +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Q1_CRT_H :12; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Q1_BUF_SEL :1; + CBIOS_U32 Q1_DBLBUF_MODE :1; + CBIOS_U32 Q1_TRIPLEBUF_EN :1; + CBIOS_U32 Q1_CRT_W :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM33478_Arise; + + +typedef union _REG_MM33480_Arise //qs_windows1__csc_control_register_(qs_windows1_register_MM34A0) +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :11; + CBIOS_U32 QS_Win1_YCbCr_Order :1; + CBIOS_U32 QS_Win2_Format :3; + CBIOS_U32 Reserved_2 :3; + CBIOS_U32 QS_Win1_Alpha_Upscaler :1; + CBIOS_U32 QS_Win1_444_YCbCr_Order :1; + CBIOS_U32 QS_Win2_Enable :1; + CBIOS_U32 Reserved_3 :11; + }; +}REG_MM33480_Arise; + + +typedef union _REG_MM33484_Arise //qs_windows1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_F1 :14; + CBIOS_U32 QS_Win1_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33484_Arise; + + +typedef union _REG_MM33488_Arise //qs_windows1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_F3 :14; + CBIOS_U32 QS_Win1_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33488_Arise; + + +typedef union _REG_MM3348C_Arise //qs_windows1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_F5 :14; + CBIOS_U32 QS_Win1_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM3348C_Arise; + + +typedef union _REG_MM33490_Arise //qs_windows1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_F7 :14; + CBIOS_U32 QS_Win1_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33490_Arise; + + +typedef union _REG_MM33494_Arise //qs_windows1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_F9 :14; + CBIOS_U32 QS_Win1_Bright :9; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 QS_Win1_In_Format :3; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 QS_Win1_Out_Format :3; + CBIOS_U32 QS_Win1_Program :1; + }; +}REG_MM33494_Arise; + + +typedef union _REG_MM33498_Arise //qs_windows1_chroma_keyh +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_Win1_KeyH :24; + CBIOS_U32 Reserved :8; + }; +}REG_MM33498_Arise; + + +typedef union _REG_MM334A0_Arise //ts_windows2__csc_control_register_(ts_windows2_register_MM34A0) +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :11; + CBIOS_U32 TS_Win2_YCbCr_Order :1; + CBIOS_U32 TS_Win2_Format :3; + CBIOS_U32 Reserved_2 :3; + CBIOS_U32 TS_Win1_Alpha_Upscaler :1; + CBIOS_U32 TS_Win2_444_YCbCr_Order :1; + CBIOS_U32 TS_Win2_Enable :1; + CBIOS_U32 Reserved_3 :11; + }; +}REG_MM334A0_Arise; + + +typedef union _REG_MM334A4_Arise //ts_windows2_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_F1 :14; + CBIOS_U32 TS_Win2_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM334A4_Arise; + + +typedef union _REG_MM334A8_Arise //ts_windows2_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_F3 :14; + CBIOS_U32 TS_Win2_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM334A8_Arise; + + +typedef union _REG_MM334AC_Arise //ts_windows2_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_F5 :14; + CBIOS_U32 TS_Win2_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM334AC_Arise; + + +typedef union _REG_MM334B0_Arise //ts_windows2_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_F7 :14; + CBIOS_U32 TS_Win2_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM334B0_Arise; + + +typedef union _REG_MM334B4_Arise //ts_windows2_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_F9 :14; + CBIOS_U32 TS_Win2_Bright :9; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 TS_Win2_In_Format :3; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 TS_Win2_Out_Format :3; + CBIOS_U32 TS_Win2_Program :1; + }; +}REG_MM334B4_Arise; + + +typedef union _REG_MM334B8_Arise //Thrid_Stream_1_Color/Chroma_8bit_Key_Lower_Bound_Register_(windows2_) +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_Win2_8bit_B__Cb_Key_Lower_Bound :8; + CBIOS_U32 TS_Win2_8bit_G_Y_Key_Lower_Bound :8; + CBIOS_U32 TS_Win2_8bit_R_Cr_Key_Lower_Bound :8; + CBIOS_U32 Reserved_0 :7; + CBIOS_U32 TS_Win2_Oneshot :1; + }; + struct + { + CBIOS_U32 TS_Win2_10bit_B__Cb_Key_Lower_Bound :10; + CBIOS_U32 TS_Win2_10bit_G_Y_Key_Lower_Bound :10; + CBIOS_U32 TS_Win2_10bit_R_Cr_Key_Lower_Bound :10; + CBIOS_U32 Reserved :1; + CBIOS_U32 TS_Win2_Oneshot_Bit :1; + }; +}REG_MM334B8_Arise; + + +typedef union _REG_MM334BC_Arise //eDP1_PSR_control +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VSC_SW_CRC_47_32 :16; + CBIOS_U32 PSR_EN :1; + CBIOS_U32 CRC_ENREG :1; + CBIOS_U32 PSR_BURST_UPDATE :1; + CBIOS_U32 PSR_SLEEP :1; + CBIOS_U32 PSR_ENTER_MODE :1; + CBIOS_U32 PSR_UPDATE_MODE :1; + CBIOS_U32 PSR_CRC_MODE :1; + CBIOS_U32 SEL_SW_CRC :1; + CBIOS_U32 PSR_MAINLINK_ON :1; + CBIOS_U32 Reserved :7; + }; +}REG_MM334BC_Arise; + + +typedef union _REG_MM334C0_Arise //eDP1_PSR_control +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VSC_SW_CRC_31_0 :32; + }; +}REG_MM334C0_Arise; + + +typedef union _REG_MM334C4_Arise //eDP1_PSR_control +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VSC_HEAD :8; + CBIOS_U32 VSC_DB0 :8; + CBIOS_U32 VSC_COUNT :12; + CBIOS_U32 PSR_ST :3; + CBIOS_U32 MAINLINK_TURNOFF :1; + }; +}REG_MM334C4_Arise; + + +typedef union _REG_MM334C8_Arise //DP1_control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LINK_QUAL_SET_EN :1; + CBIOS_U32 LINK_QUAL_SET_LANE :3; + CBIOS_U32 EQ_USE_TP3 :1; + CBIOS_U32 Start_LINK_RATE_1 :1; + CBIOS_U32 SW_bit_rate_1 :1; + CBIOS_U32 IDLE_FIFO_INFO_SEND_EN :1; + CBIOS_U32 DPCD102_B5 :1; + CBIOS_U32 Aux_time_Reduced :1; + CBIOS_U32 DUR_HTOTAL_15 :1; + CBIOS_U32 DUR_HBLANK_12 :1; + CBIOS_U32 DP_SUPPORT_POST_CURSOR :1; + CBIOS_U32 MAX_POST_EMPHASIS :2; + CBIOS_U32 EQ_WRITE_POST :1; + CBIOS_U32 HBR2_COMPLIANCE_SCRAMBLER_RESET :16; + }; +}REG_MM334C8_Arise; + + +typedef union _REG_MM334CC_Arise //DP1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SW_MPLL_M_1 :8; + CBIOS_U32 SW_MPLL_P_1 :2; + CBIOS_U32 SW_NX_P :2; + CBIOS_U32 SW_NX_P_1 :2; + CBIOS_U32 SW_NX_P_2 :2; + CBIOS_U32 SW_MPLL_M_2 :8; + CBIOS_U32 SW_MPLL_P_2 :2; + CBIOS_U32 DP_VERSION_VALUE :6; + }; +}REG_MM334CC_Arise; + + +typedef union _REG_MM334D0_Arise //DP1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CUSTOM_80BIT_PATTERN_31_0 :32; + }; +}REG_MM334D0_Arise; + + +typedef union _REG_MM334D4_Arise //DP1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CUSTOM_80BIT_PATTERN_63_32 :32; + }; +}REG_MM334D4_Arise; + + +typedef union _REG_MM334D8_Arise //DP1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 CUSTOM_80BIT_PATTERN_79_64 :16; + CBIOS_U32 SW_LANE0_post_pp :2; + CBIOS_U32 SW_LANE1_post_pp :2; + CBIOS_U32 SW_LANE2_post_pp :2; + CBIOS_U32 SW_LANE3_post_pp :2; + CBIOS_U32 Lane0_POST_CURSOR_level_status :2; + CBIOS_U32 Lane1_POST_CURSOR_level_status :2; + CBIOS_U32 Lane2_POST_CURSOR_level_status :2; + CBIOS_U32 Lane3_POST_CURSOR_level_status :2; + }; +}REG_MM334D8_Arise; + + +typedef union _REG_MM334DC_Arise //DP1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Link_Rate_value_1 :8; + CBIOS_U32 Link_Rate_value_2 :8; + CBIOS_U32 Link_Rate_value_3 :8; + CBIOS_U32 VCS_SUPPORT_FIELD_3D :1; + CBIOS_U32 VCS_FIELD_INV :1; + CBIOS_U32 LINK_bit_rate_status_1_0 :2; + CBIOS_U32 RESEVERD :2; + CBIOS_U32 HBR_M_GEN_MOD :1; + CBIOS_U32 Link_Rate_use_DPCP115 :1; + }; +}REG_MM334DC_Arise; + + +typedef union _REG_MM334E0_Arise //DP1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 EPHY1_FBOOST :3; + CBIOS_U32 EPHY1_HDCKBY4 :1; + CBIOS_U32 EPHY1_FBOOST_1 :3; + CBIOS_U32 EPHY1_FBOOST_2 :3; + CBIOS_U32 reseverd_0 :10; + CBIOS_U32 EPHY1_SR_SPD :2; + CBIOS_U32 EPHY1_SR_DLY :2; + CBIOS_U32 EPHY1_SR_NDLY :2; + CBIOS_U32 Reserved_30to26 :5; + CBIOS_U32 DP1_HPD_INV :1; + }; +}REG_MM334E0_Arise; + + +typedef union _REG_MM334E4_Arise //DP1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 EPHY1_TXDU_L0 :6; + CBIOS_U32 EPHY1_TXDU_L1 :6; + CBIOS_U32 EPHY1_TXDU_L2 :6; + CBIOS_U32 EPHY1_TXDU_L3 :6; + CBIOS_U32 EPHY1_TX_VMR :4; + CBIOS_U32 EPHY1_TX_VMX :1; + CBIOS_U32 EPHY1_TX_H1V2 :1; + CBIOS_U32 Reserved_31to30 :2; + }; +}REG_MM334E4_Arise; + + +typedef union _REG_MM33500_Arise //mdi_strobe_read_back_data_register_0 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MDI_DSP_RDAT_31_0 :32; + }; +}REG_MM33500_Arise; + + +typedef union _REG_MM33504_Arise //mdi_strobe_read_back_data_register_1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MDI_DSP_RDAT_63_32 :32; + }; +}REG_MM33504_Arise; + + +typedef union _REG_MM33508_Arise //mdi_strobe_read_back_data_register_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MDI_DSP_RDAT_95_64 :32; + }; +}REG_MM33508_Arise; + + +typedef union _REG_MM3350C_Arise //mdi_strobe_read_back_data_register_3 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MDI_DSP_RDAT_127_96 :32; + }; +}REG_MM3350C_Arise; + + +typedef union _REG_MM33510_Arise //mdi_strobe_read_back_data_register_4 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MDI_DSP_RDAT_159_128 :32; + }; +}REG_MM33510_Arise; + + +typedef union _REG_MM33514_Arise //mdi_strobe_read_back_data_register_5 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MDI_DSP_RDAT_191_160 :32; + }; +}REG_MM33514_Arise; + + +typedef union _REG_MM33518_Arise //mdi_strobe_read_back_data_register_6 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MDI_DSP_RDAT_223_192 :32; + }; +}REG_MM33518_Arise; + + +typedef union _REG_MM3351C_Arise //mdi_strobe_read_back_data_register_7 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MDI_DSP_RDAT_255_224 :32; + }; +}REG_MM3351C_Arise; + + +typedef union _REG_MM33520_Arise //mdi_strobe_control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 strobe_enable :1; + CBIOS_U32 strobe_reset :1; + CBIOS_U32 data_type :1; + CBIOS_U32 engine_ID :5; + CBIOS_U32 group_number :2; + CBIOS_U32 fifo_write_address :9; + CBIOS_U32 strobe_status :1; + CBIOS_U32 reserved :12; + }; +}REG_MM33520_Arise; + + +typedef union _REG_MM33524_Arise //security_flag +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 security_r :20; + CBIOS_U32 security_w :8; + CBIOS_U32 Reserved :4; + }; +}REG_MM33524_Arise; + + +typedef union _REG_MM33528_Arise //MDI_read_latency_debug_register_9 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_CTR_MAX :13; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 SS2_CTR_MAX :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM33528_Arise; + + +typedef union _REG_MM3352C_Arise //MDI_read_latency_debug_register_10 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS2_CTR_MAX :13; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 QS2_CTR_MAX :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM3352C_Arise; + + +typedef union _REG_MM33530_Arise //MDI_read_latency_debug_register_11 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS3_CTR_MAX :13; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 SS3_CTR_MAX :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM33530_Arise; + + +typedef union _REG_MM33534_Arise //MDI_read_latency_debug_register_12 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS3_CTR_MAX :13; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 QS3_CTR_MAX :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM33534_Arise; + + +typedef union _REG_MM33538_Arise //MDI_read_latency_debug_register_13 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS4_CTR_MAX :13; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 SS4_CTR_MAX :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM33538_Arise; + + +typedef union _REG_MM3353C_Arise //MDI_read_latency_debug_register_14 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS4_CTR_MAX :13; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 QS4_CTR_MAX :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM3353C_Arise; + + +typedef union _REG_MM33540_Arise //MDI_read_latency_debug_register_15 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 BURST_CTR_MAX :13; + CBIOS_U32 Reserved :19; + }; +}REG_MM33540_Arise; + + +typedef union _REG_MM33600_Arise //ts_windows1__csc_control_register_(ts_windows2_register_MM34A0) +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :11; + CBIOS_U32 TS_YCbCr_Order :1; + CBIOS_U32 TS_Win1_Format :3; + CBIOS_U32 Reserved_2 :3; + CBIOS_U32 TS_Win1_Alpha_Upscaler :1; + CBIOS_U32 TS_444_YCbCr_Order :1; + CBIOS_U32 Reserved_3 :12; + }; +}REG_MM33600_Arise; + + +typedef union _REG_MM33604_Arise //ts_windows1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_F1 :14; + CBIOS_U32 TS_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33604_Arise; + + +typedef union _REG_MM33608_Arise //ts_windows1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_F3 :14; + CBIOS_U32 TS_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33608_Arise; + + +typedef union _REG_MM3360C_Arise //ts_windows1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_F5 :14; + CBIOS_U32 TS_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM3360C_Arise; + + +typedef union _REG_MM33610_Arise //ts_windows1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_F7 :14; + CBIOS_U32 TS_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33610_Arise; + + +typedef union _REG_MM33614_Arise //ts_windows1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_F9 :14; + CBIOS_U32 TS_Bright :9; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 TS_In_Format :3; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 TS_Out_Format :3; + CBIOS_U32 TS_Program :1; + }; +}REG_MM33614_Arise; + +typedef union _REG_MM3361C_Arise //ss1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_F1 :14; + CBIOS_U32 SS_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM3361C_Arise; + + +typedef union _REG_MM33620_Arise //ss1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_F3 :14; + CBIOS_U32 SS_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33620_Arise; + + +typedef union _REG_MM33624_Arise //ss1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_F5 :14; + CBIOS_U32 SS_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33624_Arise; + + +typedef union _REG_MM33628_Arise //ss1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_F7 :14; + CBIOS_U32 SS_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33628_Arise; + + +typedef union _REG_MM3362C_Arise //ss1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_F9 :14; + CBIOS_U32 SS_Bright :9; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 SS_Data_In_Format :3; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 SS_Data_Out_Format :3; + CBIOS_U32 SS_Program :1; + }; +}REG_MM3362C_Arise; + + +typedef union _REG_MM33634_Arise //ps1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_F1 :14; + CBIOS_U32 PS_F2 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33634_Arise; + + +typedef union _REG_MM33638_Arise //ps1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_F3 :14; + CBIOS_U32 PS_F4 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33638_Arise; + + +typedef union _REG_MM3363C_Arise //ps1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_F5 :14; + CBIOS_U32 PS_F6 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM3363C_Arise; + + +typedef union _REG_MM33640_Arise //ps1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_F7 :14; + CBIOS_U32 PS_F8 :14; + CBIOS_U32 Reserved :4; + }; +}REG_MM33640_Arise; + + +typedef union _REG_MM33644_Arise //ps1_csc_coefficient +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS_F9 :14; + CBIOS_U32 PS_Bright :9; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 PS_Data_In_Fmt :3; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 PS_Data_Out_Fmt :3; + CBIOS_U32 PS_Program :1; + }; +}REG_MM33644_Arise; + + +typedef union _REG_MM33648_Arise //tv_csc_control +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :4; + CBIOS_U32 TV_Csc_Coef_Sel :1; + CBIOS_U32 TV_Csc_Coef_Tune :1; + CBIOS_U32 Reserved_1 :2; + CBIOS_U32 TV_Contrast_Tune_Value :8; + CBIOS_U32 TV_U_Satu_Tune_Value :8; + CBIOS_U32 TV_V_Satu_Tune_Value :8; + }; +}REG_MM33648_Arise; + + +typedef union _REG_MM33658_Arise //tv_csc_factor_register_4 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TV_Color_Space_Conv_Factor_0_F6 :11; + CBIOS_U32 Reserved_0 :5; + CBIOS_U32 TV_Color_Space_Conv_Factor_1_F7 :11; + CBIOS_U32 Reserved_1 :5; + }; +}REG_MM33658_Arise; + + +typedef union _REG_MM33660_Arise //iga1_interlace_mode_right_base +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved :2; + CBIOS_U32 IGA1_Interlace_Right_Base :30; + }; +}REG_MM33660_Arise; + + +typedef union _REG_MM33664_Arise //iga2_interlace_mode_right_base +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 reserved :2; + CBIOS_U32 IGA2_Interlace_Right_Base :30; + }; +}REG_MM33664_Arise; + + +typedef union _REG_MM33668_Arise //PS_1_dynamic_sync_control +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Dynamic_Sync_Enable :1; + CBIOS_U32 Select_PS_Load_Or_SS_Load :1; + CBIOS_U32 Max_Line_Number :13; + CBIOS_U32 Edp_Frc_Enable :1; + CBIOS_U32 Reserved :16; + }; +}REG_MM33668_Arise; + + +typedef union _REG_MM33670_Arise //Color_value_outside_of_3rd_overlay_window +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Backgnd_Color_Value :30; + CBIOS_U32 Backgnd_Color_Ycbcr :1; + CBIOS_U32 reserved :1; + }; +}REG_MM33670_Arise; + + +typedef union _REG_MM33680_Arise //HDMI1_HDCP22_control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 STREAM_ID :8; + CBIOS_U32 STREAM_TYPE :8; + CBIOS_U32 RNG_OSC_MD :2; + CBIOS_U32 RNG_OSC_EN_HDCP :1; + CBIOS_U32 RNG_EN_HDCP :1; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 HDCP22_AUTH_SEL :1; + CBIOS_U32 HDCP22_AUTH_TRIG :1; + CBIOS_U32 CSM_TRIGGER :1; + CBIOS_U32 AKE_Stored_km_DIS :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 TEST_REPEATER :1; + CBIOS_U32 TEST_MODE :1; + CBIOS_U32 CONT_STREAM_EN :1; + CBIOS_U32 HDCP22_CP_EN :1; + }; +}REG_MM33680_Arise; + + +typedef union _REG_MM33684_Arise //DP1_HDCP22_control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :23; + CBIOS_U32 DPHDCP22_AUTH_SEL :1; + CBIOS_U32 DPHDCP22_AUTH_TRIG :1; + CBIOS_U32 DPHDCP22_CSM_TRIGGER :1; + CBIOS_U32 DPHDCP22_AKE_Stored_km_DIS :1; + CBIOS_U32 Reserved_1 :2; + CBIOS_U32 DPHDCP22_CAP_EN :1; + CBIOS_U32 DPHDCP22_CONT_STREAM_EN :1; + CBIOS_U32 DPHDCP22_CP_EN :1; + }; +}REG_MM33684_Arise; + + +typedef union _REG_MM33688_Arise //DP1/HDMI1_HDCP22_control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TxCaps :24; + CBIOS_U32 Reserved :2; + CBIOS_U32 PGM_OPEN :1; + CBIOS_U32 RNG_TEST_FAIL :1; + CBIOS_U32 HDCP22_CSM_PASS_DP1 :1; + CBIOS_U32 HDCP22_AUTH_PASS_DP1 :1; + CBIOS_U32 HDCP22_CSM_PASS_HDMI1 :1; + CBIOS_U32 HDCP22_AUTH_PASS_HDMI1 :1; + }; +}REG_MM33688_Arise; + + +typedef union _REG_MM3368C_Arise //DP1/HDMI1_HDCP22_interrupt_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 MSG_ID_ERR_INT :1; + CBIOS_U32 RecID_INT :1; + CBIOS_U32 KSVFF_INT :1; + CBIOS_U32 NOT_HDCP22_INT :1; + CBIOS_U32 IS_HDCP22_INT :1; + CBIOS_U32 LINK_INT_FAIL :1; + CBIOS_U32 CSM_FAIL :1; + CBIOS_U32 AUTH_FAIL :1; + CBIOS_U32 AUXFAIL_INT_IICFAIL_INT :1; + CBIOS_U32 DEV_ZERO :1; + CBIOS_U32 CSM_PASS :1; + CBIOS_U32 AUTH_PASS :1; + CBIOS_U32 SEQ_NUM_M_ROLLOVER :1; + CBIOS_U32 M_RETRY_NUMOUT :1; + CBIOS_U32 M_TIMEOUT :1; + CBIOS_U32 M_FAIL :1; + CBIOS_U32 NONZERO_SEQ_NUM_V_INT :1; + CBIOS_U32 SEQ_NUM_V_ROLLOVER_INT :1; + CBIOS_U32 V_FAIL :1; + CBIOS_U32 MAX_CAS :1; + CBIOS_U32 MAX_DEVS :1; + CBIOS_U32 WAIT_RECID_TIMEOUT :1; + CBIOS_U32 REAUTH_REQ :1; + CBIOS_U32 L_FAIL :1; + CBIOS_U32 LC_RETRY_NUMOUT :1; + CBIOS_U32 LC_TIMEOUT :1; + CBIOS_U32 Ekh_TIMEOUT :1; + CBIOS_U32 H_FAIL :1; + CBIOS_U32 H_TIMEOUT :1; + CBIOS_U32 CERT_FAIL :1; + CBIOS_U32 RECID_INVALID :1; + CBIOS_U32 CERT_TIMEOUT :1; + }; +}REG_MM3368C_Arise; + + +typedef union _REG_MM33690_Arise //DP1/HDMI1_HDCP22_interrupt_mask_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDCP22_INT_MASK :32; + }; +}REG_MM33690_Arise; + + +typedef union _REG_MM33694_Arise //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_CSC_IN_FMT :3; + CBIOS_U32 Reserved_bit4 :1; + CBIOS_U32 LB1_CSC_OUT_FMT :3; + CBIOS_U32 LB1_PROGRAMMBLE :1; + CBIOS_U32 LB1_BYPASS :1; + CBIOS_U32 Reserved_31to9 :23; + }; +}REG_MM33694_Arise; + + +typedef union _REG_MM33698_Arise //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_COEF_F1 :14; + CBIOS_U32 LB1_COEF_F2 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM33698_Arise; + + +typedef union _REG_MM3369C_Arise //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_COEF_F3 :14; + CBIOS_U32 LB1_COEF_F4 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM3369C_Arise; + + +typedef union _REG_MM336A0_Arise //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_COEF_F5 :14; + CBIOS_U32 LB1_COEF_F6 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM336A0_Arise; + + +typedef union _REG_MM336A4_Arise //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_COEF_F7 :14; + CBIOS_U32 LB1_COEF_F8 :14; + CBIOS_U32 Reserved_31to28 :4; + }; +}REG_MM336A4_Arise; + + +typedef union _REG_MM336A8_Arise //hdtv1_line_buffer__ps_csc__setting +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 LB1_COEF_F9 :14; + CBIOS_U32 LB1_BRIGHT :9; + CBIOS_U32 Reserved_31to23 :9; + }; +}REG_MM336A8_Arise; + + +typedef union _REG_MM336B0_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDMI1_SSCP_UCC_POS :12; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 HDMI1_SCRAMBLE_ACTIVE_POS_SEL :1; + CBIOS_U32 HDMI1_SCRAMBLE_MODE :1; + CBIOS_U32 HDMI1_SCRAMBLE_EN :1; + CBIOS_U32 HDMI1_YC_420_EN :1; + CBIOS_U32 HDMI1_YC_420_MODE :1; + CBIOS_U32 HDMI1_CENTRAL_START_MODE :1; + CBIOS_U32 HDMI1_CLK_LANE_EN :1; + CBIOS_U32 DATA_ISLAND_START_SEL :1; + CBIOS_U32 Reserved_1 :2; + CBIOS_U32 PKTLEG_SEL_DISABLE :1; + CBIOS_U32 PKTLEG_VBLANK :8; + }; +}REG_MM336B0_Arise; + + +typedef union _REG_MM336B4_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 RIRB_WPTR_SEL :1; + CBIOS_U32 CORB_RPTR_SEL :1; + CBIOS_U32 CIE_GIE_RST_CTL :1; + CBIOS_U32 HW_CORB_RST_SEL :1; + CBIOS_U32 STRM1_FREE_RUN :1; + CBIOS_U32 STRM2_FREE_RUN :1; + CBIOS_U32 STRM_NUM_SUPPORT :1; + CBIOS_U32 ADDR_64OK :1; + CBIOS_U32 CORB_VIR :1; + CBIOS_U32 STRM1_BDL_VIR :1; + CBIOS_U32 STRM1_VIR :1; + CBIOS_U32 STRM2_BDL_VIR :1; + CBIOS_U32 STRM2_VIR :1; + CBIOS_U32 DMAP_DES1_VIR :1; + CBIOS_U32 DMAP_DES2_VIR :1; + CBIOS_U32 RIRB_VIR :1; + CBIOS_U32 CORB_FB :1; + CBIOS_U32 STRM1_BDL_FB :1; + CBIOS_U32 STRM1_FB :1; + CBIOS_U32 STRM2_BDL_FB :1; + CBIOS_U32 STRM2_FB :1; + CBIOS_U32 DMAP_DES1_FB :1; + CBIOS_U32 DMAP_DES2_FB :1; + CBIOS_U32 RIRB_FB :1; + CBIOS_U32 CORB_SNOOP :1; + CBIOS_U32 STRM1_BDL_SNOOP :1; + CBIOS_U32 STRM1_SNOOP :1; + CBIOS_U32 STRM2_BDL_SNOOP :1; + CBIOS_U32 STRM2_SNOOP :1; + CBIOS_U32 DMAP_DES1_SNOOP :1; + CBIOS_U32 DMAP_DES2_SNOOP :1; + CBIOS_U32 RIRB_SNOOP :1; + }; +}REG_MM336B4_Arise; + + +typedef union _REG_MM336B8_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDMI1_SCDC_RR_START :1; + CBIOS_U32 HDMI1_SCDC_WAIT_TIMEOUT :23; + CBIOS_U32 HDMI1_SCDC_RR_INT_STATUS :1; + CBIOS_U32 Reserved :3; + CBIOS_U32 HDMI1_SCDC_START_STOP_ENABLE :1; + CBIOS_U32 HDMI1_SCDC_HW_DRV_STOP_ENABLE :1; + CBIOS_U32 HDMI1_SCDC_HW_DRV_START_ENABLE :1; + CBIOS_U32 HDMI1_SCDC_RR_ENABLE :1; + }; +}REG_MM336B8_Arise; + + +typedef union _REG_MM336BC_Arise //HDMI1_SCDC_control_2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDMI1_SCDC_WDATA :8; + CBIOS_U32 HDMI1_SCDC_WDATA_SEL :1; + CBIOS_U32 IIC1_STATIMEOUT :23; + }; +}REG_MM336BC_Arise; + + +typedef union _REG_MM33700_Arise //PS1_base_offset +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 Base_Offset :27; + CBIOS_U32 Reserved_1 :2; + }; +}REG_MM33700_Arise; + + +typedef union _REG_MM33704_Arise //PS2_base_offset +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 Reserved_1 :25; + CBIOS_U32 Reserved_2 :4; + }; +}REG_MM33704_Arise; + + +typedef union _REG_MM33708_Arise //SS1_base_offset/NV12Y_base_offset +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :5; + CBIOS_U32 SS_Base_Offset :25; + CBIOS_U32 Reserved_1 :2; + }; +}REG_MM33708_Arise; + + +typedef union _REG_MM3370C_Arise //SS1_NV12C_base_offset +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :5; + CBIOS_U32 offset_value :25; + CBIOS_U32 Reserved_1 :2; + }; +}REG_MM3370C_Arise; + + +typedef union _REG_MM33710_Arise //PS1_right_frame_base_offset +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 offset_value :27; + CBIOS_U32 Reserved_1 :2; + }; +}REG_MM33710_Arise; + + +typedef union _REG_MM33714_Arise //PS2_right_frame_base_offset +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 Reserved_1 :25; + CBIOS_U32 Reserved_2 :4; + }; +}REG_MM33714_Arise; + + +typedef union _REG_MM33718_Arise //Cursor_1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor_1_Enable :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Cursor_1_Type :2; + CBIOS_U32 Cursor_1_X_Rotation :1; + CBIOS_U32 Cursor_1_Y_Rotation :1; + CBIOS_U32 Cursor_1_Size :2; + CBIOS_U32 Cursor_1_Display_Start_X :7; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 Cursor_1_Display_Start_Y :7; + CBIOS_U32 Cursor_1_reverse_alpha_enable :1; + CBIOS_U32 Cursor_1_inverse_alpha :1; + CBIOS_U32 Reserved_3 :3; + CBIOS_U32 Reserved_4 :3; + CBIOS_U32 Cursor_1_mmio_reg_en :1; + }; +}REG_MM33718_Arise; + + +typedef union _REG_MM3371C_Arise //Cursor_1_Control_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor_1_X_Origin :14; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 Cursor_1_Y_Origin :13; + CBIOS_U32 Reserved_1 :3; + }; +}REG_MM3371C_Arise; + + +typedef union _REG_MM33720_Arise //Cursor_1_Base_Address_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor_1_Base_Address :31; + CBIOS_U32 Cursor_1_Enable_Work_Registers :1; + }; +}REG_MM33720_Arise; + + +typedef union _REG_MM33724_Arise //Cursor_1_Right_Frame_Base_Address_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor_1_Right_Frame_Base_Address :31; + CBIOS_U32 Cursor_1_Vsync_Off_Page_Flip :1; + }; +}REG_MM33724_Arise; + + +typedef union _REG_MM33728_Arise //Cursor_1_end +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Cursor_1_X_end :7; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 Cursor_1_Y_end :7; + CBIOS_U32 Reserved_1 :17; + }; +}REG_MM33728_Arise; + + +typedef union _REG_MM3372C_Arise //SS1_NV12T_block_total_Register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 NV12Y_request_block_total :8; + CBIOS_U32 NV12C_request_block_total :8; + CBIOS_U32 Reserved :16; + }; +}REG_MM3372C_Arise; + + +typedef union _REG_MM33730_Arise //VIP0_REG0 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_vcount :14; + CBIOS_U32 VIP_hcount :14; + CBIOS_U32 reserved :4; + }; +}REG_MM33730_Arise; + + +typedef union _REG_MM33734_Arise //VIP1_REG0 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_vcount :14; + CBIOS_U32 VIP_hcount :14; + CBIOS_U32 reserved :4; + }; +}REG_MM33734_Arise; + + +typedef union _REG_MM33738_Arise //VIP2_REG0 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_vcount :14; + CBIOS_U32 VIP_hcount :14; + CBIOS_U32 reserved :4; + }; +}REG_MM33738_Arise; + + +typedef union _REG_MM3373C_Arise //VIP3_REG0 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_vcount :14; + CBIOS_U32 VIP_hcount :14; + CBIOS_U32 reserved :4; + }; +}REG_MM3373C_Arise; + + +typedef union _REG_MM33740_Arise //VIP0_REG1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_reset :1; + CBIOS_U32 VIP_enable :1; + CBIOS_U32 video_mode :7; + CBIOS_U32 VIP_hsync_polarity_invert :1; + CBIOS_U32 VIP_vsync_polarity_invert :1; + CBIOS_U32 SCE :1; + CBIOS_U32 header_select :1; + CBIOS_U32 SMB :2; + CBIOS_U32 VBI_enable :1; + CBIOS_U32 RAW_VBI_enable :1; + CBIOS_U32 VIP_video_data_delay :2; + CBIOS_U32 VBI_header_type :1; + CBIOS_U32 VBI_double_mode :1; + CBIOS_U32 header_type :1; + CBIOS_U32 _10bits_mode :1; + CBIOS_U32 one_more_SVBI :2; + CBIOS_U32 DROP_frame_mode :2; + CBIOS_U32 Drop_VBI :1; + CBIOS_U32 drop_frame :1; + CBIOS_U32 drop_odd_even :1; + CBIOS_U32 VIP_load_work_register :1; + CBIOS_U32 Load_at_VIP_vsync_enable :1; + }; +}REG_MM33740_Arise; + + +typedef union _REG_MM33744_Arise //VIP0_REG2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 REG_auto_gen :1; + CBIOS_U32 control_word_0_select :2; + CBIOS_U32 control_word_1_select :2; + CBIOS_U32 control_word_2_select :2; + CBIOS_U32 control_word_3_select :2; + CBIOS_U32 VIP_hde_enable :1; + CBIOS_U32 VIP_sync_enable :1; + CBIOS_U32 enable_data_0 :1; + CBIOS_U32 data_type :1; + CBIOS_U32 data_word_0_select :2; + CBIOS_U32 data_word_1_select :2; + CBIOS_U32 data_word_2_select :2; + CBIOS_U32 data_word_3_select :2; + CBIOS_U32 video_data_out_format :1; + CBIOS_U32 SVBI_data_out_format :1; + CBIOS_U32 VBI_control_word0_sel :2; + CBIOS_U32 VBI_control_word1_sel :2; + CBIOS_U32 VBI_control_word2_sel :2; + CBIOS_U32 VBI_control_word3_sel :2; + CBIOS_U32 Undefined_Bit_31_to_31 :1; + }; +}REG_MM33744_Arise; + + +typedef union _REG_MM33748_Arise //VIP0_REG3 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_ver_start :14; + CBIOS_U32 reserved :2; + CBIOS_U32 VIP_ver_window_length :14; + CBIOS_U32 enable_error_detect :1; + CBIOS_U32 crop_window_enable :1; + }; +}REG_MM33748_Arise; + + +typedef union _REG_MM3374C_Arise //VIP0_REG4 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_hor_start :14; + CBIOS_U32 reserved_0 :2; + CBIOS_U32 VIP_hor_length :14; + CBIOS_U32 reserved_1 :2; + }; +}REG_MM3374C_Arise; + + +typedef union _REG_MM33750_Arise //VIP0_REG5 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 fifo_threshold :7; + CBIOS_U32 reserved_0 :1; + CBIOS_U32 fifo_high_threshold :7; + CBIOS_U32 reserved_1 :1; + CBIOS_U32 VIP_input_clock_inv :1; + CBIOS_U32 VIP_input_clock_delay_select :4; + CBIOS_U32 VIP_input_clock_xor_enable :1; + CBIOS_U32 VIP_input_data_select :8; + CBIOS_U32 reserved_2 :1; + CBIOS_U32 VIP_DVO_enable :1; + }; +}REG_MM33750_Arise; + + +typedef union _REG_MM33754_Arise //VIP0_REG6 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FB_mode :2; + CBIOS_U32 FB_base0 :30; + }; +}REG_MM33754_Arise; + + +typedef union _REG_MM33758_Arise //VIP0_REG7 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_overflow :1; + CBIOS_U32 XYZ_error_flg :1; + CBIOS_U32 FB_base1 :30; + }; +}REG_MM33758_Arise; + + +typedef union _REG_MM3375C_Arise //VIP0_REG8 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_clk_detect :1; + CBIOS_U32 Line_cnt_wr_en :1; + CBIOS_U32 FB_base2 :30; + }; +}REG_MM3375C_Arise; + + +typedef union _REG_MM33760_Arise //VIP0_REG9 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 interleave_enable :1; + CBIOS_U32 frame_by_frame_odd_on_top :1; + CBIOS_U32 flush_enable :1; + CBIOS_U32 frame_end_reset :1; + CBIOS_U32 fifo_overfloe_clr :1; + CBIOS_U32 XYZ_error_clr :1; + CBIOS_U32 FB_stride :10; + CBIOS_U32 reserved :5; + CBIOS_U32 FB_VBI_size :11; + }; +}REG_MM33760_Arise; + + +typedef union _REG_MM33764_Arise //VIP0_REG10 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 cap_full_frame :1; + CBIOS_U32 VIP_data_type :1; + CBIOS_U32 FB_max_size :30; + }; +}REG_MM33764_Arise; + + +typedef union _REG_MM33768_Arise //VIP0_REG11 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_VBI_count0 :16; + CBIOS_U32 VIP_VBI_count1 :16; + }; +}REG_MM33768_Arise; + + +typedef union _REG_MM3376C_Arise //VIP0_REG12 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_which_BAR :2; + CBIOS_U32 VIP_interlace_detect :1; + CBIOS_U32 VREF :1; + CBIOS_U32 HREF :1; + CBIOS_U32 FIELD_ID :1; + CBIOS_U32 frame_odd_even :1; + CBIOS_U32 reserved_0 :1; + CBIOS_U32 EOF_INT_enable :1; + CBIOS_U32 HPD_INT_enable :1; + CBIOS_U32 EOF_INT :1; + CBIOS_U32 HPD_INT :1; + CBIOS_U32 VIP_HPD_INT_status :2; + CBIOS_U32 reserved_1 :18; + }; +}REG_MM3376C_Arise; + + +typedef union _REG_MM33770_Arise //VIP1_REG1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_reset :1; + CBIOS_U32 VIP_enable :1; + CBIOS_U32 video_mode :7; + CBIOS_U32 VIP_hsync_polarity_invert :1; + CBIOS_U32 VIP_vsync_polarity_invert :1; + CBIOS_U32 SCE :1; + CBIOS_U32 header_select :1; + CBIOS_U32 SMB :2; + CBIOS_U32 VBI_enable :1; + CBIOS_U32 RAW_VBI_enable :1; + CBIOS_U32 VIP_video_data_delay :2; + CBIOS_U32 VBI_header_type :1; + CBIOS_U32 VBI_double_mode :1; + CBIOS_U32 header_type :1; + CBIOS_U32 _10bits_mode :1; + CBIOS_U32 one_more_SVBI :2; + CBIOS_U32 DROP_frame_mode :2; + CBIOS_U32 Drop_VBI :1; + CBIOS_U32 drop_frame :1; + CBIOS_U32 drop_odd_even :1; + CBIOS_U32 VIP_load_work_register :1; + CBIOS_U32 Load_at_VIP_vsync_enable :1; + }; +}REG_MM33770_Arise; + + +typedef union _REG_MM33774_Arise //VIP1_REG2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 REG_auto_gen :1; + CBIOS_U32 control_word_0_select :2; + CBIOS_U32 control_word_1_select :2; + CBIOS_U32 control_word_2_select :2; + CBIOS_U32 control_word_3_select :2; + CBIOS_U32 VIP_hde_enable :1; + CBIOS_U32 VIP_sync_enable :1; + CBIOS_U32 enable_data_0 :1; + CBIOS_U32 data_type :1; + CBIOS_U32 data_word_0_select :2; + CBIOS_U32 data_word_1_select :2; + CBIOS_U32 data_word_2_select :2; + CBIOS_U32 data_word_3_select :2; + CBIOS_U32 video_data_out_format :1; + CBIOS_U32 SVBI_data_out_format :1; + CBIOS_U32 VBI_control_word0_sel :2; + CBIOS_U32 VBI_control_word1_sel :2; + CBIOS_U32 VBI_control_word2_sel :2; + CBIOS_U32 VBI_control_word3_sel :2; + CBIOS_U32 Undefined_Bit_31_to_31 :1; + }; +}REG_MM33774_Arise; + + +typedef union _REG_MM33778_Arise //VIP1_REG3 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_ver_start :14; + CBIOS_U32 reserved :2; + CBIOS_U32 VIP_ver_window_length :14; + CBIOS_U32 enable_error_detect :1; + CBIOS_U32 crop_window_enable :1; + }; +}REG_MM33778_Arise; + + +typedef union _REG_MM3377C_Arise //VIP1_REG4 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_hor_start :14; + CBIOS_U32 reserved_0 :2; + CBIOS_U32 VIP_hor_length :14; + CBIOS_U32 reserved_1 :2; + }; +}REG_MM3377C_Arise; + + +typedef union _REG_MM33780_Arise //VIP1_REG5 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 fifo_threshold :7; + CBIOS_U32 reserved_0 :1; + CBIOS_U32 fifo_high_threshold :7; + CBIOS_U32 reserved_1 :1; + CBIOS_U32 VIP_input_clock_inv :1; + CBIOS_U32 VIP_input_clock_delay_select :4; + CBIOS_U32 VIP_input_clock_xor_enable :1; + CBIOS_U32 VIP_input_data_select :8; + CBIOS_U32 reserved_2 :1; + CBIOS_U32 VIP_DVO_enable :1; + }; +}REG_MM33780_Arise; + + +typedef union _REG_MM33784_Arise //VIP1_REG6 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FB_mode :2; + CBIOS_U32 FB_base0 :30; + }; +}REG_MM33784_Arise; + + +typedef union _REG_MM33788_Arise //VIP1_REG7 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_overflow :1; + CBIOS_U32 XYZ_error_flg :1; + CBIOS_U32 FB_base1 :30; + }; +}REG_MM33788_Arise; + + +typedef union _REG_MM3378C_Arise //VIP1_REG8 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_clk_detect :1; + CBIOS_U32 Line_cnt_wr_en :1; + CBIOS_U32 FB_base2 :30; + }; +}REG_MM3378C_Arise; + + +typedef union _REG_MM33790_Arise //VIP1_REG9 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 interleave_enable :1; + CBIOS_U32 frame_by_frame_odd_on_top :1; + CBIOS_U32 flush_enable :1; + CBIOS_U32 frame_end_reset :1; + CBIOS_U32 fifo_overfloe_clr :1; + CBIOS_U32 XYZ_error_clr :1; + CBIOS_U32 FB_stride :10; + CBIOS_U32 reserved :5; + CBIOS_U32 FB_VBI_size :11; + }; +}REG_MM33790_Arise; + + +typedef union _REG_MM33794_Arise //VIP1_REG10 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 cap_full_frame :1; + CBIOS_U32 VIP_data_type :1; + CBIOS_U32 FB_max_size :30; + }; +}REG_MM33794_Arise; + + +typedef union _REG_MM33798_Arise //VIP1_REG11 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_VBI_count0 :16; + CBIOS_U32 VIP_VBI_count1 :16; + }; +}REG_MM33798_Arise; + + +typedef union _REG_MM3379C_Arise //VIP1_REG12 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_which_BAR :2; + CBIOS_U32 VIP_interlace_detect :1; + CBIOS_U32 VREF :1; + CBIOS_U32 HREF :1; + CBIOS_U32 FIELD_ID :1; + CBIOS_U32 frame_odd_even :1; + CBIOS_U32 reserved_0 :1; + CBIOS_U32 EOF_INT_enable :1; + CBIOS_U32 HPD_INT_enable :1; + CBIOS_U32 EOF_INT :1; + CBIOS_U32 HPD_INT :1; + CBIOS_U32 VIP_HPD_INT_status :2; + CBIOS_U32 reserved_1 :18; + }; +}REG_MM3379C_Arise; + + +typedef union _REG_MM337A0_Arise //VIP2_REG1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_reset :1; + CBIOS_U32 VIP_enable :1; + CBIOS_U32 video_mode :7; + CBIOS_U32 VIP_hsync_polarity_invert :1; + CBIOS_U32 VIP_vsync_polarity_invert :1; + CBIOS_U32 SCE :1; + CBIOS_U32 header_select :1; + CBIOS_U32 SMB :2; + CBIOS_U32 VBI_enable :1; + CBIOS_U32 RAW_VBI_enable :1; + CBIOS_U32 VIP_video_data_delay :2; + CBIOS_U32 VBI_header_type :1; + CBIOS_U32 VBI_double_mode :1; + CBIOS_U32 header_type :1; + CBIOS_U32 _10bits_mode :1; + CBIOS_U32 one_more_SVBI :2; + CBIOS_U32 DROP_frame_mode :2; + CBIOS_U32 Drop_VBI :1; + CBIOS_U32 drop_frame :1; + CBIOS_U32 drop_odd_even :1; + CBIOS_U32 VIP_load_work_register :1; + CBIOS_U32 Load_at_VIP_vsync_enable :1; + }; +}REG_MM337A0_Arise; + + +typedef union _REG_MM337A4_Arise //VIP2_REG2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 REG_auto_gen :1; + CBIOS_U32 control_word_0_select :2; + CBIOS_U32 control_word_1_select :2; + CBIOS_U32 control_word_2_select :2; + CBIOS_U32 control_word_3_select :2; + CBIOS_U32 VIP_hde_enable :1; + CBIOS_U32 VIP_sync_enable :1; + CBIOS_U32 enable_data_0 :1; + CBIOS_U32 data_type :1; + CBIOS_U32 data_word_0_select :2; + CBIOS_U32 data_word_1_select :2; + CBIOS_U32 data_word_2_select :2; + CBIOS_U32 data_word_3_select :2; + CBIOS_U32 video_data_out_format :1; + CBIOS_U32 SVBI_data_out_format :1; + CBIOS_U32 VBI_control_word0_sel :2; + CBIOS_U32 VBI_control_word1_sel :2; + CBIOS_U32 VBI_control_word2_sel :2; + CBIOS_U32 VBI_control_word3_sel :2; + CBIOS_U32 Undefined_Bit_31_to_31 :1; + }; +}REG_MM337A4_Arise; + + +typedef union _REG_MM337A8_Arise //VIP2_REG3 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_ver_start :14; + CBIOS_U32 reserved :2; + CBIOS_U32 VIP_ver_window_length :14; + CBIOS_U32 enable_error_detect :1; + CBIOS_U32 crop_window_enable :1; + }; +}REG_MM337A8_Arise; + + +typedef union _REG_MM337AC_Arise //VIP2_REG4 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_hor_start :14; + CBIOS_U32 reserved_0 :2; + CBIOS_U32 VIP_hor_length :14; + CBIOS_U32 reserved_1 :2; + }; +}REG_MM337AC_Arise; + + +typedef union _REG_MM337B0_Arise //VIP2_REG5 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 fifo_threshold :7; + CBIOS_U32 reserved_0 :1; + CBIOS_U32 fifo_high_threshold :7; + CBIOS_U32 reserved_1 :1; + CBIOS_U32 VIP_input_clock_inv :1; + CBIOS_U32 VIP_input_clock_delay_select :4; + CBIOS_U32 VIP_input_clock_xor_enable :1; + CBIOS_U32 VIP_input_data_select :8; + CBIOS_U32 reserved_2 :1; + CBIOS_U32 VIP_DVO_enable :1; + }; +}REG_MM337B0_Arise; + + +typedef union _REG_MM337B4_Arise //VIP2_REG6 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FB_mode :2; + CBIOS_U32 FB_base0 :30; + }; +}REG_MM337B4_Arise; + + +typedef union _REG_MM337B8_Arise //VIP2_REG7 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_overflow :1; + CBIOS_U32 XYZ_error_flg :1; + CBIOS_U32 FB_base1 :30; + }; +}REG_MM337B8_Arise; + + +typedef union _REG_MM337BC_Arise //VIP2_REG8 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_clk_detect :1; + CBIOS_U32 Line_cnt_wr_en :1; + CBIOS_U32 FB_base2 :30; + }; +}REG_MM337BC_Arise; + + +typedef union _REG_MM337C0_Arise //VIP2_REG9 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 interleave_enable :1; + CBIOS_U32 frame_by_frame_odd_on_top :1; + CBIOS_U32 flush_enable :1; + CBIOS_U32 frame_end_reset :1; + CBIOS_U32 fifo_overfloe_clr :1; + CBIOS_U32 XYZ_error_clr :1; + CBIOS_U32 FB_stride :10; + CBIOS_U32 reserved :5; + CBIOS_U32 FB_VBI_size :11; + }; +}REG_MM337C0_Arise; + + +typedef union _REG_MM337C4_Arise //VIP2_REG10 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 cap_full_frame :1; + CBIOS_U32 VIP_data_type :1; + CBIOS_U32 FB_max_size :30; + }; +}REG_MM337C4_Arise; + + +typedef union _REG_MM337C8_Arise //VIP2_REG11 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_VBI_count0 :16; + CBIOS_U32 VIP_VBI_count1 :16; + }; +}REG_MM337C8_Arise; + + +typedef union _REG_MM337CC_Arise //VIP2_REG12 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_which_BAR :2; + CBIOS_U32 VIP_interlace_detect :1; + CBIOS_U32 VREF :1; + CBIOS_U32 HREF :1; + CBIOS_U32 FIELD_ID :1; + CBIOS_U32 frame_odd_even :1; + CBIOS_U32 reserved_0 :1; + CBIOS_U32 EOF_INT_enable :1; + CBIOS_U32 HPD_INT_enable :1; + CBIOS_U32 EOF_INT :1; + CBIOS_U32 HPD_INT :1; + CBIOS_U32 VIP_HPD_INT_status :2; + CBIOS_U32 reserved_1 :18; + }; +}REG_MM337CC_Arise; + + +typedef union _REG_MM337D0_Arise //VIP3_REG1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_reset :1; + CBIOS_U32 VIP_enable :1; + CBIOS_U32 video_mode :7; + CBIOS_U32 VIP_hsync_polarity_invert :1; + CBIOS_U32 VIP_vsync_polarity_invert :1; + CBIOS_U32 SCE :1; + CBIOS_U32 header_select :1; + CBIOS_U32 SMB :2; + CBIOS_U32 VBI_enable :1; + CBIOS_U32 RAW_VBI_enable :1; + CBIOS_U32 VIP_video_data_delay :2; + CBIOS_U32 VBI_header_type :1; + CBIOS_U32 VBI_double_mode :1; + CBIOS_U32 header_type :1; + CBIOS_U32 _10bits_mode :1; + CBIOS_U32 one_more_SVBI :2; + CBIOS_U32 DROP_frame_mode :2; + CBIOS_U32 Drop_VBI :1; + CBIOS_U32 drop_frame :1; + CBIOS_U32 drop_odd_even :1; + CBIOS_U32 VIP_load_work_register :1; + CBIOS_U32 Load_at_VIP_vsync_enable :1; + }; +}REG_MM337D0_Arise; + + +typedef union _REG_MM337D4_Arise //VIP2_REG2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 REG_auto_gen :1; + CBIOS_U32 control_word_0_select :2; + CBIOS_U32 control_word_1_select :2; + CBIOS_U32 control_word_2_select :2; + CBIOS_U32 control_word_3_select :2; + CBIOS_U32 VIP_hde_enable :1; + CBIOS_U32 VIP_sync_enable :1; + CBIOS_U32 enable_data_0 :1; + CBIOS_U32 data_type :1; + CBIOS_U32 data_word_0_select :2; + CBIOS_U32 data_word_1_select :2; + CBIOS_U32 data_word_2_select :2; + CBIOS_U32 data_word_3_select :2; + CBIOS_U32 video_data_out_format :1; + CBIOS_U32 SVBI_data_out_format :1; + CBIOS_U32 VBI_control_word0_sel :2; + CBIOS_U32 VBI_control_word1_sel :2; + CBIOS_U32 VBI_control_word2_sel :2; + CBIOS_U32 VBI_control_word3_sel :2; + CBIOS_U32 Undefined_Bit_31_to_31 :1; + }; +}REG_MM337D4_Arise; + + +typedef union _REG_MM337D8_Arise //VIP3_REG3 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_ver_start :14; + CBIOS_U32 reserved :2; + CBIOS_U32 VIP_ver_window_length :14; + CBIOS_U32 enable_error_detect :1; + CBIOS_U32 crop_window_enable :1; + }; +}REG_MM337D8_Arise; + + +typedef union _REG_MM337DC_Arise //VIP3_REG4 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_hor_start :14; + CBIOS_U32 reserved_0 :2; + CBIOS_U32 VIP_hor_length :14; + CBIOS_U32 reserved_1 :2; + }; +}REG_MM337DC_Arise; + + +typedef union _REG_MM337E0_Arise //VIP3_REG5 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 fifo_threshold :7; + CBIOS_U32 reserved_0 :1; + CBIOS_U32 fifo_high_threshold :7; + CBIOS_U32 reserved_1 :1; + CBIOS_U32 VIP_input_clock_inv :1; + CBIOS_U32 VIP_input_clock_delay_select :4; + CBIOS_U32 VIP_input_clock_xor_enable :1; + CBIOS_U32 VIP_input_data_select :8; + CBIOS_U32 reserved_2 :1; + CBIOS_U32 VIP_DVO_enable :1; + }; +}REG_MM337E0_Arise; + + +typedef union _REG_MM337E4_Arise //VIP3_REG6 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 FB_mode :2; + CBIOS_U32 FB_base0 :30; + }; +}REG_MM337E4_Arise; + + +typedef union _REG_MM337E8_Arise //VIP3_REG7 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_overflow :1; + CBIOS_U32 XYZ_error_flg :1; + CBIOS_U32 FB_base1 :30; + }; +}REG_MM337E8_Arise; + + +typedef union _REG_MM337EC_Arise //VIP3_REG8 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_clk_detect :1; + CBIOS_U32 Line_cnt_wr_en :1; + CBIOS_U32 FB_base2 :30; + }; +}REG_MM337EC_Arise; + + +typedef union _REG_MM337F0_Arise //VIP3_REG9 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 interleave_enable :1; + CBIOS_U32 frame_by_frame_odd_on_top :1; + CBIOS_U32 flush_enable :1; + CBIOS_U32 frame_end_reset :1; + CBIOS_U32 fifo_overfloe_clr :1; + CBIOS_U32 XYZ_error_clr :1; + CBIOS_U32 FB_stride :10; + CBIOS_U32 reserved :5; + CBIOS_U32 FB_VBI_size :11; + }; +}REG_MM337F0_Arise; + + +typedef union _REG_MM337F4_Arise //VIP3_REG10 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 cap_full_frame :1; + CBIOS_U32 VIP_data_type :1; + CBIOS_U32 FB_max_size :30; + }; +}REG_MM337F4_Arise; + + +typedef union _REG_MM337F8_Arise //VIP3_REG11 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_VBI_count0 :16; + CBIOS_U32 VIP_VBI_count1 :16; + }; +}REG_MM337F8_Arise; + + +typedef union _REG_MM337FC_Arise //VIP3_REG12 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 VIP_which_BAR :2; + CBIOS_U32 VIP_interlace_detect :1; + CBIOS_U32 VREF :1; + CBIOS_U32 HREF :1; + CBIOS_U32 FIELD_ID :1; + CBIOS_U32 frame_odd_even :1; + CBIOS_U32 reserved_0 :1; + CBIOS_U32 EOF_INT_enable :1; + CBIOS_U32 HPD_INT_enable :1; + CBIOS_U32 EOF_INT :1; + CBIOS_U32 HPD_INT :1; + CBIOS_U32 VIP_HPD_INT_status :2; + CBIOS_U32 reserved_1 :18; + }; +}REG_MM337FC_Arise; + + +typedef union _REG_MM33800_Arise //dp +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DP1_EQ_USE_TP4 :1; + CBIOS_U32 DP1_SW_FBOOST_3 :3; + CBIOS_U32 DP1_SW_NX_P_3 :2; + CBIOS_U32 DP1_SW_MPLL_P_3 :2; + CBIOS_U32 DP1_SW_MPLL_M_3 :8; + CBIOS_U32 DP1_Link_Rate_value_4 :8; + CBIOS_U32 DP1_SWX :1; + CBIOS_U32 DP1_AUX_SWX :1; + CBIOS_U32 DP1_PH1REG_PDB :1; + CBIOS_U32 DP1_PH1REG_1V2 :2; + CBIOS_U32 DP1_PH2REG_PDB :1; + CBIOS_U32 DP1_PH2REG_1V2 :2; + }; +}REG_MM33800_Arise; + + +typedef union _REG_MM33804_Arise //dp +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DP1__CR_DONE_CLR :1; + CBIOS_U32 Reserved :31; + }; +}REG_MM33804_Arise; + + +typedef union _REG_MM33810_Arise //kevinq +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DP2_Clock_Debug :1; + CBIOS_U32 DP3_Clock_Debug :1; + CBIOS_U32 DP4_Clock_Debug :1; + CBIOS_U32 reserved_0 :3; + CBIOS_U32 reserved_1 :1; + CBIOS_U32 reserved_2 :1; + CBIOS_U32 reserved_3 :1; + CBIOS_U32 reserved_4 :1; + CBIOS_U32 VIPCLK_INV :1; + CBIOS_U32 VIP1CLK_INV :1; + CBIOS_U32 VIP2CLK_INV :1; + CBIOS_U32 VIP3CLK_INV :1; + CBIOS_U32 PS1_BL_IDX :18; + }; +}REG_MM33810_Arise; + + +typedef union _REG_MM33814_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_BL_IDX_R :18; + CBIOS_U32 PS1_BL_IDX2 :14; + }; +}REG_MM33814_Arise; + + +typedef union _REG_MM33818_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 ps1_base_address :4; + CBIOS_U32 PS1_BASE_R :4; + CBIOS_U32 PS1_INTR_ROFFSET :4; + CBIOS_U32 reserved :20; + }; +}REG_MM33818_Arise; + + +typedef union _REG_MM3381C_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS1_BL_IDX2 :4; + CBIOS_U32 PS1_BL_IDX_R2 :18; + CBIOS_U32 reserved :10; + }; +}REG_MM3381C_Arise; + + +typedef union _REG_MM33824_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 s_vsync_beg_vga_pre :13; + CBIOS_U32 reserved_0 :3; + CBIOS_U32 s_vsync_end_vga_pre :6; + CBIOS_U32 reserved_1 :10; + }; +}REG_MM33824_Arise; + + +typedef union _REG_MM33828_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 s_htotal :11; + CBIOS_U32 reserved_0 :5; + CBIOS_U32 s_hdisp_end :11; + CBIOS_U32 reserved_1 :5; + }; +}REG_MM33828_Arise; + + +typedef union _REG_MM3382C_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 s_hblnk_beg :11; + CBIOS_U32 reserved_0 :5; + CBIOS_U32 s_hblnk_end :10; + CBIOS_U32 reserved_1 :6; + }; +}REG_MM3382C_Arise; + + +typedef union _REG_MM33830_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 s_hsync_beg :11; + CBIOS_U32 reserved_0 :5; + CBIOS_U32 s_hsync_end :6; + CBIOS_U32 reserved_1 :10; + }; +}REG_MM33830_Arise; + + +typedef union _REG_MM33834_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS_Enable :1; + CBIOS_U32 SS_Use_Mmio_En :1; + CBIOS_U32 Reserved :30; + }; +}REG_MM33834_Arise; + + +typedef union _REG_MM33840_Arise //background_overlay_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ka_3to0_Or_Ks :4; + CBIOS_U32 Ka_7to4_Or_Kp :4; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 Ovl0_Input_Stream :2; + CBIOS_U32 Color_Key_Sel :2; + CBIOS_U32 Alpha_Select :2; + CBIOS_U32 Alpha_Rang :1; + CBIOS_U32 Alpha_Round :1; + CBIOS_U32 Reserved_1 :6; + CBIOS_U32 Key_Mode :4; + CBIOS_U32 Invert_Alpha_Or_Ka :1; + CBIOS_U32 Ovl0_One_Shot :1; + CBIOS_U32 Ovl0_Vsync_Off_Flip :1; + CBIOS_U32 Ovl0_Enable_Work :1; + }; +}REG_MM33840_Arise; + + +typedef union _REG_MM33844_Arise //background_overlay_plane_alpha +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Ovl0_Plane_Alpha :8; + CBIOS_U32 Reserved_0 :6; + CBIOS_U32 Ovl0_Alpha_Blend_Mode :1; + CBIOS_U32 Reserved_1 :17; + }; +}REG_MM33844_Arise; + + +typedef union _REG_MM33854_Arise //SS1_burst_index +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 SS1_burst_index :18; + CBIOS_U32 Reserved :14; + }; +}REG_MM33854_Arise; + + +typedef union _REG_MM33858_Arise //TS1_win1_burst_index +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_win1_burst_index :18; + CBIOS_U32 Reserved :14; + }; +}REG_MM33858_Arise; + + +typedef union _REG_MM3385C_Arise //TS1_win2_burst_index +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 TS_win2_burst_index :18; + CBIOS_U32 Reserved :14; + }; +}REG_MM3385C_Arise; + + +typedef union _REG_MM33860_Arise //QS_win1_burst_index +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_win1_burst_index :18; + CBIOS_U32 Reserved :14; + }; +}REG_MM33860_Arise; + + +typedef union _REG_MM33864_Arise //QS_win2_burst_index +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 QS_win2_burst_index :18; + CBIOS_U32 Reserved :14; + }; +}REG_MM33864_Arise; + + +typedef union _REG_MM33868_Arise //DAC_CSC_REG1 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Dac_Csc_In_Format :3; + CBIOS_U32 Dac_Csc_Out_Format :3; + CBIOS_U32 Dac_Csc_Program :1; + CBIOS_U32 Reserved :25; + }; +}REG_MM33868_Arise; + + +typedef union _REG_MM3386C_Arise //DAC_CSC_REG2 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DAC_CSC_COEF1 :14; + CBIOS_U32 DAC_CSC_COEF2 :14; + CBIOS_U32 reserved :4; + }; +}REG_MM3386C_Arise; + + +typedef union _REG_MM33870_Arise //DAC_CSC_REG3 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DAC_CSC_COEF3 :14; + CBIOS_U32 DAC_CSC_COEF4 :14; + CBIOS_U32 reserved :4; + }; +}REG_MM33870_Arise; + + +typedef union _REG_MM33874_Arise //DAC_CSC_REG4 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DAC_CSC_COEF5 :14; + CBIOS_U32 DAC_CSC_COEF6 :14; + CBIOS_U32 reserved :4; + }; +}REG_MM33874_Arise; + + +typedef union _REG_MM33878_Arise //DAC_CSC_REG5 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DAC_CSC_COEF7 :14; + CBIOS_U32 DAC_CSC_COEF8 :14; + CBIOS_U32 reserved :4; + }; +}REG_MM33878_Arise; + + +typedef union _REG_MM3387C_Arise //DAC_CSC_REG6 +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DAC_CSC_COEF9 :14; + CBIOS_U32 DAC_CSC_bright :9; + CBIOS_U32 reserved :9; + }; +}REG_MM3387C_Arise; + + +typedef union _REG_MM33880_Arise //DSCL1_register_group +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 REG_STRIDE_11_9 :3; + CBIOS_U32 REG_OFFSET :10; + CBIOS_U32 reserved :17; + CBIOS_U32 DROPPED_FRAME_STATUS :1; + CBIOS_U32 DOUBLE_BUFF_STATUS :1; + }; +}REG_MM33880_Arise; + + +typedef union _REG_MM33884_Arise //HDTV1_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 HDTV_CSC_F1_10to8 :3; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 HDTV_CSC_F0_10to8 :3; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 HDTV_CSC_F3_10to8 :3; + CBIOS_U32 Reserved_3 :1; + CBIOS_U32 HDTV_CSC_F2_10to8 :3; + CBIOS_U32 Reserved_4 :1; + CBIOS_U32 HDTV_CSC_F5_10to8 :3; + CBIOS_U32 Reserved_5 :1; + CBIOS_U32 HDTV_CSC_F4_10to8 :3; + CBIOS_U32 Reserved_6 :1; + CBIOS_U32 HDTV_CSC_F7_10to8 :3; + CBIOS_U32 Reserved_7 :1; + CBIOS_U32 HDTV_CSC_F6_10to8 :3; + }; +}REG_MM33884_Arise; + + +typedef union _REG_MM33888_Arise //VIP0_IIC_R/W_data_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DRV2HW_WDATA :8; + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 HW2DRV_RDATA :8; + CBIOS_U32 Reserved_1 :8; + }; +}REG_MM33888_Arise; + + +typedef union _REG_MM3388C_Arise //VIP0_IIC_Control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 START_Request :1; + CBIOS_U32 STOP_REQUEST :1; + CBIOS_U32 Write_Data_Available :1; + CBIOS_U32 READ_Finished :1; + CBIOS_U32 VIP_I2C_Function_Enable :1; + CBIOS_U32 I2C_Frequency_Sleect :3; + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 Slave_Receiver_Not_Ready :1; + CBIOS_U32 I2C_Status :1; + CBIOS_U32 command_buffer_nempty :1; + CBIOS_U32 command_buffer_nfull :1; + CBIOS_U32 Reserved_1 :12; + }; +}REG_MM3388C_Arise; + + +typedef union _REG_MM33890_Arise //VIP1_IIC_R/W_data_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DRV2HW_WDATA :8; + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 HW2DRV_RDATA :8; + CBIOS_U32 Reserved_1 :8; + }; +}REG_MM33890_Arise; + + +typedef union _REG_MM33894_Arise //VIP1_IIC_Control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 START_Request :1; + CBIOS_U32 STOP_REQUEST :1; + CBIOS_U32 Write_Data_Available :1; + CBIOS_U32 READ_Finished :1; + CBIOS_U32 VIP_I2C_Function_Enable :1; + CBIOS_U32 I2C_Frequency_Sleect :3; + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 Slave_Receiver_Not_Ready :1; + CBIOS_U32 I2C_Status :1; + CBIOS_U32 command_buffer_nempty :1; + CBIOS_U32 command_buffer_nfull :1; + CBIOS_U32 Reserved_1 :12; + }; +}REG_MM33894_Arise; + + +typedef union _REG_MM33898_Arise //VIP2_IIC_R/W_data_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DRV2HW_WDATA :8; + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 HW2DRV_RDATA :8; + CBIOS_U32 Reserved_1 :8; + }; +}REG_MM33898_Arise; + + +typedef union _REG_MM3389C_Arise //VIP2_IIC_Control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 START_Request :1; + CBIOS_U32 STOP_REQUEST :1; + CBIOS_U32 Write_Data_Available :1; + CBIOS_U32 READ_Finished :1; + CBIOS_U32 VIP_I2C_Function_Enable :1; + CBIOS_U32 I2C_Frequency_Sleect :3; + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 Slave_Receiver_Not_Ready :1; + CBIOS_U32 I2C_Status :1; + CBIOS_U32 command_buffer_nempty :1; + CBIOS_U32 command_buffer_nfull :1; + CBIOS_U32 Reserved_1 :12; + }; +}REG_MM3389C_Arise; + + +typedef union _REG_MM338A0_Arise //VIP3_IIC_R/W_data_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 DRV2HW_WDATA :8; + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 HW2DRV_RDATA :8; + CBIOS_U32 Reserved_1 :8; + }; +}REG_MM338A0_Arise; + + +typedef union _REG_MM338A4_Arise //VIP3_IIC_Control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 START_Request :1; + CBIOS_U32 STOP_REQUEST :1; + CBIOS_U32 Write_Data_Available :1; + CBIOS_U32 READ_Finished :1; + CBIOS_U32 VIP_I2C_Function_Enable :1; + CBIOS_U32 I2C_Frequency_Sleect :3; + CBIOS_U32 Reserved_0 :8; + CBIOS_U32 Slave_Receiver_Not_Ready :1; + CBIOS_U32 I2C_Status :1; + CBIOS_U32 command_buffer_nempty :1; + CBIOS_U32 command_buffer_nfull :1; + CBIOS_U32 Reserved_1 :12; + }; +}REG_MM338A4_Arise; + + +typedef union _REG_MM338A8_Arise //VIP0_IIC_TIMEOUT_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 IIC_STATIMEOUT :23; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 IIC_TIMEOUT_HIT :1; + CBIOS_U32 Reserved_1 :7; + }; +}REG_MM338A8_Arise; + + +typedef union _REG_MM338AC_Arise //VIP1_IIC_TIMEOUT_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 IIC_STATIMEOUT :23; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 IIC_TIMEOUT_HIT :1; + CBIOS_U32 Reserved_1 :7; + }; +}REG_MM338AC_Arise; + + +typedef union _REG_MM338B0_Arise //VIP2_IIC_TIMEOUT_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 IIC_STATIMEOUT :23; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 IIC_TIMEOUT_HIT :1; + CBIOS_U32 Reserved_1 :7; + }; +}REG_MM338B0_Arise; + + +typedef union _REG_MM338B4_Arise //VIP3_IIC_TIMEOUT_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 IIC_STATIMEOUT :23; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 IIC_TIMEOUT_HIT :1; + CBIOS_U32 Reserved_1 :7; + }; +}REG_MM338B4_Arise; + + +typedef union _REG_MM338B8_Arise //HDTV1_control_register +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Progressive_Mode_Enable :1; + CBIOS_U32 SMPTE_274M_Enable :1; + CBIOS_U32 SMPTE_296M_Enable :1; + CBIOS_U32 SMPTE_293M_Enable :1; + CBIOS_U32 _576P_Enable :1; + CBIOS_U32 HDTV_Timing_Enable_Control :1; + CBIOS_U32 ITU470_SELECT :1; + CBIOS_U32 _576i_480i_enable :1; + CBIOS_U32 Trilevel_Sync_Width :6; + CBIOS_U32 HDTV_EN_TRIG_PULSE :2; + CBIOS_U32 Blank_Level_7to0 :8; + CBIOS_U32 Blank_Level_9to8 :2; + CBIOS_U32 _1x_2x_4x_oversampling_sel :2; + CBIOS_U32 Reserved :4; + }; +}REG_MM338B8_Arise; + + +typedef union _REG_MM338BC_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CSC_input_data_format :5; + CBIOS_U32 HDTV_CSC_coefficients_sel :1; + CBIOS_U32 HDTV_old_slope_enable :1; + CBIOS_U32 Reserved :1; + CBIOS_U32 HDTV_Contrast_tuning_value :8; + CBIOS_U32 HDTV_Pb_Saturation_tuning_value :8; + CBIOS_U32 HDTV_Pr_Saturation_tuning_value :8; + }; +}REG_MM338BC_Arise; + + +typedef union _REG_MM338C0_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_y_dac_filter_select_coef :5; + CBIOS_U32 Reserved_0 :3; + CBIOS_U32 HDMI_SYNC_Delay_7to0 :8; + CBIOS_U32 HDTV_SYNC_Delay_10to8 :3; + CBIOS_U32 Reserved_1 :5; + CBIOS_U32 HDTV_SYNC_Delay_7to0 :8; + }; +}REG_MM338C0_Arise; + + +typedef union _REG_MM338C4_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CSC_F0_7to0 :8; + CBIOS_U32 HDTV_CSC_F1_7to0 :8; + CBIOS_U32 HDTV_CSC_F2_7to0 :8; + CBIOS_U32 HDTV_CSC_F3_7to0 :8; + }; +}REG_MM338C4_Arise; + + +typedef union _REG_MM338C8_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CSC_F4_7to0 :8; + CBIOS_U32 HDTV_CSC_F5_7to0 :8; + CBIOS_U32 HDTV_CSC_F6_7to0 :8; + CBIOS_U32 HDTV_CSC_F7_7to0 :8; + }; +}REG_MM338C8_Arise; + + +typedef union _REG_MM338CC_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CSC_F8_7to0 :8; + CBIOS_U32 Left_Blank_Pixels_10to8 :3; + CBIOS_U32 Reserved :5; + CBIOS_U32 Left_Blank_Pixels_7to0 :8; + CBIOS_U32 HDTV_Brightness_Control :8; + }; +}REG_MM338CC_Arise; + + +typedef union _REG_MM338D0_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Undefined_Bit_0_to_7 :8; + CBIOS_U32 HDTV_Digital_HSYNC_Width :8; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 HDTV_WSS_Clock_Ratio_bit_14 :1; + CBIOS_U32 Reserved_1 :5; + CBIOS_U32 HDTV_HSYNC_Delay :3; + CBIOS_U32 Reserved_2 :5; + }; +}REG_MM338D0_Arise; + + +typedef union _REG_MM338D4_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Iga1_Character_Clock :3; + CBIOS_U32 Iga2_Character_Clock :3; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 HDTV_WSS_Clock_Ratio13to6 :8; + CBIOS_U32 HDTV_SENSE_Line_Sleect :5; + CBIOS_U32 Reserved_1 :3; + CBIOS_U32 Hdtv_Broad_Pulse_6to0 :7; + CBIOS_U32 Reserved_2 :1; + }; +}REG_MM338D4_Arise; + + +typedef union _REG_MM338D8_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Hdtv_Broad_Pulse_14to7 :8; + CBIOS_U32 Hdtv_Half_Sync_7to0 :8; + CBIOS_U32 Hdtv_Half_Sync_10to8 :3; + CBIOS_U32 Reserved :5; + CBIOS_U32 HDTV_CC_Clock_Ratio_7to0 :8; + }; +}REG_MM338D8_Arise; + + +typedef union _REG_MM338DC_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CC_Clock_Ratio_14to8 :7; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 HDTV_CC_Line_Select :6; + CBIOS_U32 HDTV_CC_Field_Select :2; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 HDTV_CC_End_10to8 :3; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 HDTV_CC_Start_bit_8 :1; + CBIOS_U32 HDTV_CC_Sermode :1; + CBIOS_U32 HDTV_CC_Word_Mode_Select :1; + CBIOS_U32 HDTV_CC_Start_7to0 :8; + }; +}REG_MM338DC_Arise; + + +typedef union _REG_MM338E0_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CC_WSS_End_7to0 :8; + CBIOS_U32 HDTV_CC_Field1_Word0 :7; + CBIOS_U32 HDTV_CC_Field1_Data_Write_Status :1; + CBIOS_U32 HDTV_CC_Field1_Word1 :7; + CBIOS_U32 Reserved :1; + CBIOS_U32 HDTV_Parm0_Start_HDTV_HSYNC_7to0 :8; + }; +}REG_MM338E0_Arise; + + +typedef union _REG_MM338E4_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_Parm1_End_1st_Equalizing_7to0_0 :8; + CBIOS_U32 HDTV_Parm1_End_1st_Equalizing_7to0_1 :8; + CBIOS_U32 HDTV_HDE_7to0 :8; + CBIOS_U32 HDTV_HDE_10to8 :3; + CBIOS_U32 Reserved :5; + }; +}REG_MM338E4_Arise; + + +typedef union _REG_MM338E8_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_Parm3_Start_HDTV_HSYNC_7to0 :8; + CBIOS_U32 HDTV_Parm4_End_1st_Serration_Start_2nd_Equalization_7to0 :8; + CBIOS_U32 HDTV_Parm5_End_2nd_Equalization_7to0 :8; + CBIOS_U32 HDTV_Parm6_End_2nd_Equalization_7to0 :8; + }; +}REG_MM338E8_Arise; + + +typedef union _REG_MM338EC_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_Parm6_Start_2nd_Serration_10to8 :3; + CBIOS_U32 Reserved :4; + CBIOS_U32 VBI_Enable :1; + CBIOS_U32 WSS_Word0_or_B_Data_Byte_2_or_WSS_Word_13to8 :8; + CBIOS_U32 WSS_Word1_or_B_Data_Byte_2_or_WSS_Word_13to8 :8; + CBIOS_U32 WSS_Word2_or_Packet_A_Data_or_Packet_B_Data_Byte :8; + }; +}REG_MM338EC_Arise; + + +typedef union _REG_MM338F0_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CC_Field0_Word0 :7; + CBIOS_U32 HDTV_CC_Field0_Data_Write_Status :1; + CBIOS_U32 HDTV_CC_Field0_Word1_or_HDTV_Packet_A_CRC_Or_Packet_B_Data_Byte_14 :7; + CBIOS_U32 Reserved_OR__Packet_B_Data_Byte_14 :1; + CBIOS_U32 WSS_Clock_Ratio_5to0 :6; + CBIOS_U32 WSS_Mode_Enable :2; + CBIOS_U32 WSS_CGMS_A_Line_Select :6; + CBIOS_U32 WSS_Field_Select :2; + }; +}REG_MM338F0_Arise; + + +typedef union _REG_MM338F4_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 HDTV_CGMSA_Header :6; + CBIOS_U32 Reserved_0 :2; + CBIOS_U32 Reserved_1 :3; + CBIOS_U32 HDTV_WSS_CGMSA_Start_4to0 :5; + CBIOS_U32 HDTV_WSS_CGMSA_Start_8to5 :4; + CBIOS_U32 HDTV_WSS_Sermode :1; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 HDTV_CGMSA_Mode :2; + CBIOS_U32 _576i_initial_programming :2; + CBIOS_U32 HDTV__pbpr_dac_filter_select_coef :5; + CBIOS_U32 Reserved_3 :1; + }; +}REG_MM338F4_Arise; + + +typedef union _REG_MM338F8_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Undefined_Bit_0_to_7 :8; + CBIOS_U32 Pr_channel_delay :2; + CBIOS_U32 Pb_channel_delay :2; + CBIOS_U32 HDTV_Parm1_End_1st_Equalizing_10to8 :3; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 HDTV_Parm2_End_TV_HSYNC_10to8 :3; + CBIOS_U32 Y_channel_delay :2; + CBIOS_U32 Reserved_1 :3; + CBIOS_U32 HDTV_Parm3_Start_First_Serration_9to8 :2; + CBIOS_U32 HDTV_Parm4_End_1st_Serration_Start_2nd_Equalization_9to8 :2; + CBIOS_U32 HDTV_Parm5_End_2nd_Equalization_9to8 :2; + CBIOS_U32 Reserved_2 :2; + }; +}REG_MM338F8_Arise; + + +typedef union _REG_MM338FC_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 Undefined_Bit_0_to_7 :8; + CBIOS_U32 Reserved_bit0 :1; + CBIOS_U32 HDTV_CSC_F8_10to8 :3; + CBIOS_U32 Reserved_bit1 :3; + CBIOS_U32 HDTV_Enable :1; + CBIOS_U32 Undefined_Bit_16_to_31 :16; + }; +}REG_MM338FC_Arise; + +typedef union _REG_MM33E6C_Arise // +{ + CBIOS_U32 Value; + struct + { + CBIOS_U32 PS2_BL_IDX :18; + CBIOS_U32 Reserved0 :8; + CBIOS_U32 PS2_INTR_ROFFSET_B35_32 :4; + CBIOS_U32 Reserved1 :2; + }; +}REG_MM33E6C_Arise; diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_SR_registers.h b/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_SR_registers.h new file mode 100644 index 0000000000000..e173988ab0e67 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_SR_registers.h @@ -0,0 +1,3090 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +typedef union _REG_SR08 //Unlock_Extended_Sequencer_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Unlock_Extended_Sequencer :8; + }; +}REG_SR08; + + +typedef union _REG_SR09 //Extended_Sequencer_9_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :3; + CBIOS_U8 Virtual_DCLK1_Standby_Enable :1; + CBIOS_U8 Virtual_DCLK1_Suspend_Enable :1; + CBIOS_U8 True_DCLK1_Standby_Enable :1; + CBIOS_U8 True_DCLK1_Suspend_Enable :1; + CBIOS_U8 MMIO_Access_Only :1; + }; +}REG_SR09; + + +typedef union _REG_SR0A //iga_blank_adjust +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 adjust_iga1__blank :1; + CBIOS_U8 adjust_iga2__blank :1; + CBIOS_U8 adjust_iga3__blank :1; + CBIOS_U8 reserved :5; + }; +}REG_SR0A; + + +typedef union _REG_SR0B //DCLK2_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK2_Power_Down :1; + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 PLL_MTEST1 :1; + CBIOS_U8 True_DCLK3_Standby_Enable :1; + CBIOS_U8 True_DCLK3_Suspend_Enable :1; + CBIOS_U8 Reserved_2 :2; + }; +}REG_SR0B; + + +typedef union _REG_SR0D //Extended_Sequencer_D_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :1; + CBIOS_U8 DCLK1_Invert_Enable :1; + CBIOS_U8 DCLK2_Invert_Enable :1; + CBIOS_U8 DCLK3_Invert_Enable :1; + CBIOS_U8 CRT1_HSYNC :2; + CBIOS_U8 CRT1_VSYNC :2; + }; +}REG_SR0D; + + +typedef union _REG_SR0E //DCLK2_PLL_Integer_M_and_R_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK2_M_Integer :8; + }; +}REG_SR0E; + + +typedef union _REG_SR0F //DCLK2_PLL_Fractional_M_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK2_M_Fractional_7to0 :8; + }; +}REG_SR0F; + + +typedef union _REG_SR10 //VGA_Clock_PLL_R_Divider_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VGA_R_25_175_MHz :2; + CBIOS_U8 PLL1_R :2; + CBIOS_U8 VGA1_M :2; + CBIOS_U8 VGA_R_28_322_MHz :2; + }; +}REG_SR10; + + +typedef union _REG_SR12 //DCLK1_PLL_Integer_M_and_R_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK1_M_Integer :8; + }; +}REG_SR12; + + +typedef union _REG_SR13 //DCLK1_PLL_Fractional_M_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK1_M_Fract_7to0 :8; + }; +}REG_SR13; + + +typedef union _REG_SR14 //PLL_Clock_Synthesizer_Control_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK1_Power_Down_Test :1; + CBIOS_U8 Counter_Timer_Enable :1; + CBIOS_U8 Enable_Counters :1; + CBIOS_U8 MTEST0 :1; + CBIOS_U8 Clear_Counter :1; + CBIOS_U8 Reserved :3; + }; +}REG_SR14; + + +typedef union _REG_SR15 //PLL_Clock_Synthesizer_Control_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK3_M_R_Load :1; + CBIOS_U8 DCLK1_PLL_LOAD :1; + CBIOS_U8 DCLK1_M_R_Load :1; + CBIOS_U8 DCLK2_PLL_LOAD :1; + CBIOS_U8 DCLK3_PLL_LOAD :1; + CBIOS_U8 DCLK2_M_R_Load :1; + CBIOS_U8 Auto_Load_Reset_Enable :1; + CBIOS_U8 For_VGA_mem_access :1; + }; +}REG_SR15; + + +typedef union _REG_SR16 //CLKSYN_Test_High_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Clock_Test_Results_High_Byte :8; + }; +}REG_SR16; + + +typedef union _REG_SR17 //CLKSYN_Test_Low_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Clock_Test_Results_Low_Byte :8; + }; +}REG_SR17; + + +typedef union _REG_SR18 //DAC/CLKSYN_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reset_Signature_Test :1; + CBIOS_U8 Signature_Data_to_Read :3; + CBIOS_U8 Signature_Test_Data_Source :1; + CBIOS_U8 DAC1_Power_Up :1; + CBIOS_U8 Reserved :2; + }; +}REG_SR18; + + +typedef union _REG_SR19 //SP1_Gamma_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :2; + CBIOS_U8 SP1_LUT_Interpolation_Enable :1; + CBIOS_U8 Dac1_Test_Mode :2; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 SP1_Gamma :2; + }; +}REG_SR19; + + +typedef union _REG_SR1A //Extended_Sequencer_1A_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Debug_sel_11_8 :4; + CBIOS_U8 Software_Debug_Disable :1; + CBIOS_U8 CLUT2_Configuration :2; + CBIOS_U8 SP1_LUT_Split :1; + }; +}REG_SR1A; + + +typedef union _REG_SR1B //Extended_Sequencer_1B_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :3; + CBIOS_U8 SP1_CRT_Gamma :2; + CBIOS_U8 CLUT1_Configuration :2; + CBIOS_U8 Controller1_DCLK_Parm_Source :1; + }; +}REG_SR1B; + + +typedef union _REG_SR1C //Extended_Sequencer_1C_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SP2_LUT_Interpolation_Enable :1; + CBIOS_U8 SP2_LUT_Split :1; + CBIOS_U8 TV_Encoder_Clock_Power_Down :1; + CBIOS_U8 TV_Encoder_Clock_Standby_Power_Down :1; + CBIOS_U8 TV_Encoder_Clock_Suspend_Power_Down :1; + CBIOS_U8 Reserved :3; + }; +}REG_SR1C; + + +typedef union _REG_SR1D //Extended_Sequencer_ID_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PCI_PAD_PD_Enable :1; + CBIOS_U8 Reserved_0 :2; + CBIOS_U8 SP1_DCLK_PD_Enable :1; + CBIOS_U8 SP1_DCLK_Standby_PD_Enable :1; + CBIOS_U8 SP1_DCLK_Suspend_PD_Enable :1; + CBIOS_U8 SP3_DCLK_Suspend_PD_Enable :1; + CBIOS_U8 Reserved_1 :1; + }; +}REG_SR1D; + + +typedef union _REG_SR1E //Power_Management_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Controller_1_DCLK_PD_Enable :1; + CBIOS_U8 PLL_Suspend_Power_Down_Enable :1; + CBIOS_U8 Controller_2_DCLK_Power_Down :1; + CBIOS_U8 Controller_3_DCLK_Power_Down :1; + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 Controller_2_Standby_Power_Down :1; + CBIOS_U8 Controller_2_Suspend_Power_Down :1; + CBIOS_U8 Reserved_1 :1; + }; +}REG_SR1E; + + +typedef union _REG_SR1F //Extended_Sequencer_1F_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Engine_Clock_Suspend_Enable :1; + CBIOS_U8 Reserved :2; + CBIOS_U8 PCIE0_PM_Enable :1; + CBIOS_U8 Reserved_7to4 :4; + }; +}REG_SR1F; + + +typedef union _REG_SR20 //Extended_Sequencer_20_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK2_PLL_Suspend_Enable :1; + CBIOS_U8 DAC1_Standby_Enable :1; + CBIOS_U8 DAC1_Suspend_Enable :1; + CBIOS_U8 DCLK1_PLL_Suspend_Enable :1; + CBIOS_U8 MCLK_PLL_Suspend_Enable :1; + CBIOS_U8 Reserved :2; + CBIOS_U8 Pads_Suspend_Enable :1; + }; +}REG_SR20; + + +typedef union _REG_SR21 //Extended_Sequencer_21_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 CLUT1_Disable :1; + CBIOS_U8 DAC1_SENSE_Power_Down_Enable :1; + CBIOS_U8 CLUT1_Standby_Enable :1; + CBIOS_U8 CLUT1_Suspend_Enable :1; + CBIOS_U8 CLUT2_Disable :1; + CBIOS_U8 SEN_SEL :1; + CBIOS_U8 CLUT2_Standby_Enable :1; + CBIOS_U8 CLUT2_Suspend_Enable :1; + }; +}REG_SR21; + + +typedef union _REG_SR22 //VGA_Clock_1_Low_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VGA1_PLL_Integral_M_Divider :6; + CBIOS_U8 External_D1CLK :1; + CBIOS_U8 External_D2CLK :1; + }; +}REG_SR22; + + +typedef union _REG_SR23 //VGA_Clock_1_High_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VGA1_PLL_Fractional_M_Divider_19to12 :8; + }; +}REG_SR23; + + +typedef union _REG_SR24 //VGA_Clock2_M_Integer_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VGA2_PLL_Integral_M_Dividier :8; + }; +}REG_SR24; + + +typedef union _REG_SR25 //VGA_Clock2_M_Fractional_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VGA2_PLL_Fractional_M_Divider :8; + }; +}REG_SR25; + + +typedef union _REG_SR26 //Paired_Register_Read/Write_Select_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Controller_Reads_select :2; + CBIOS_U8 Controller1_write_Disable :1; + CBIOS_U8 Controller2_Writes_Enable :1; + CBIOS_U8 Controller3_Writes_Enable :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 Vertical_Interrupt_Source :2; + }; +}REG_SR26; + + +typedef union _REG_SR27 //DAC_Current_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DAC1_Gain_Adjust :3; + CBIOS_U8 DAC1_BLANK_Pedestal_Enable :1; + CBIOS_U8 RD0_DAC1 :1; + CBIOS_U8 RD1_DAC1 :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 Controller1_DAC_Blank_Power_Down :1; + }; +}REG_SR27; + + +typedef union _REG_SR28 //DCLK_PLL_IREF_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :2; + CBIOS_U8 DCLK1_IREF :2; + CBIOS_U8 DCLK2_IREF :2; + CBIOS_U8 Reserved_1 :2; + }; +}REG_SR28; + + +typedef union _REG_SR29 //DCLK_PLL_M_and_R_Value_Overflow_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DCLK1_Fractional_M_bit_19to16 :4; + CBIOS_U8 DCLK2_R :2; + CBIOS_U8 Reserved_7to6 :2; + }; +}REG_SR29; + + +typedef union _REG_SR2A //Paired_/_Alternate_Register_Select_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Paired_SR_Registers_Select_bit0 :1; + CBIOS_U8 Alternate_D_Registers_Select :2; + CBIOS_U8 Paired_CR_Registers_Select_bit0 :1; + CBIOS_U8 reserved :1; + CBIOS_U8 Paired_SR_Registers_Select_bit1 :1; + CBIOS_U8 MIUCRALL :1; + CBIOS_U8 Paired_CR_Registers_Select_bit1 :1; + }; +}REG_SR2A; + + +typedef union _REG_SR2B //DVO_Data_Source_Select_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DVO1_Source_Select :2; + CBIOS_U8 Reserved_7to2 :6; + }; +}REG_SR2B; + + +typedef union _REG_SR2C //LVDS_Power_Up_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 LVDS_Power_Up_0 :1; + CBIOS_U8 LVDS_Power_Up_1 :1; + CBIOS_U8 LVDS_Power_Down_Standby_Enable :1; + CBIOS_U8 LVDS_Power_Down_Suspend_Enable :1; + CBIOS_U8 LVDS_Power_Down_FP_Inactive_Enable :1; + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 PDCH3_L :1; + CBIOS_U8 Reserved_1 :1; + }; +}REG_SR2C; + + +typedef union _REG_SR2D //DVO-1_Port_Control_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :4; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 Reserved_2 :1; + CBIOS_U8 Invert_DVO1_HSYNC :1; + CBIOS_U8 Invert_DVO1_VSYNC :1; + }; +}REG_SR2D; + + +typedef union _REG_SR2E //high_bit__for_timing_control_register1_when_fp_is_enalbed__pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_total_bit_10 :1; + CBIOS_U8 Horizontal_Display_End_bit_10 :1; + CBIOS_U8 Start_Horizontal_Blank_bit_10 :1; + CBIOS_U8 Horizontal_Blank_end_bit_9_7 :3; + CBIOS_U8 Start_Horizontal_Sync_Position_bit_10 :1; + CBIOS_U8 reserved :1; + }; +}REG_SR2E; + + +typedef union _REG_SR2F //high_bit__for_timing_control_register2_when_fp_is_enabled_pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vertical_Total_bit_12 :1; + CBIOS_U8 Vertical_Display_End_bit_12 :1; + CBIOS_U8 Start_Vertical_Blank_bit_12 :1; + CBIOS_U8 End_Vertical_Blank_bit8 :1; + CBIOS_U8 Vertical_Retrace_Start_bit_12 :1; + CBIOS_U8 Vertical_Retrace_End_bit9_8 :2; + CBIOS_U8 reserved :1; + }; +}REG_SR2F; + + +typedef union _REG_SR30_Pair //Architecture_Configuration_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS2_VGA_Enable :1; + CBIOS_U8 Reset_CLK_DIV :1; + CBIOS_U8 reserved :1; + CBIOS_U8 Controller1_DCLK :1; + CBIOS_U8 Controller2_DCLK :1; + CBIOS_U8 VGA3_enable :1; + CBIOS_U8 Controller3_DCLK :1; + CBIOS_U8 SS2_FIFO_share :1; + }; +}REG_SR30_Pair; + + +typedef union _REG_SR30_B //Architecture_Configuration_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved_0 :2; + CBIOS_U8 HDTV1_Data_Source_Select :1; + CBIOS_U8 reserved_1 :5; + }; +}REG_SR30_B; + + +typedef union _REG_SR30_T //Architecture_Configuration_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved_0 :2; + CBIOS_U8 HDTV2_Data_Source_Select :1; + CBIOS_U8 reserved_1 :5; + }; +}REG_SR30_T; + + +typedef union _REG_SR31_Pair //Flat_Panel_Display_Mode_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 F1C :1; + CBIOS_U8 reserved :1; + CBIOS_U8 DAC1_Source_Select :2; + CBIOS_U8 Controller1_is_Flat_Panel_Source :1; + CBIOS_U8 Power_On_Sequence :1; + CBIOS_U8 DAC1_SENSE_Source :1; + CBIOS_U8 DAC_SENSE_INT :1; + }; +}REG_SR31_Pair; + + +typedef union _REG_SR31_B_Pair //Flat_Panel_Display_Mode_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved_0 :1; + CBIOS_U8 reserved_1 :1; + CBIOS_U8 reserved_2 :2; + CBIOS_U8 Controller2_is_Flat_Panel_Source :1; + CBIOS_U8 reserved_3 :3; + }; +}REG_SR31_B_Pair; + + +typedef union _REG_SR31_T_Pair //Flat_Panel_Display_Mode_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved_0 :1; + CBIOS_U8 reserved_1 :1; + CBIOS_U8 reserved_2 :2; + CBIOS_U8 Controller3_is_Flat_Panel_Source :1; + CBIOS_U8 reserved_3 :3; + }; +}REG_SR31_T_Pair; + + +typedef union _REG_SR32 //DVO_Port_Output_Enable_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DVO_1_DAT_Pad_Out :1; + CBIOS_U8 DVO_1_HSYNC_VSYNC_Pad_Out :1; + CBIOS_U8 DVO_1_DEN_CLK_Pad_Out :1; + CBIOS_U8 DVO_1_CLKB_Pad_Out :1; + CBIOS_U8 DIU_BIU_DVO_INT_ien :1; + CBIOS_U8 reserved :1; + CBIOS_U8 DAC_mode_en :1; + CBIOS_U8 CRT_H_VSYNC_output_en :1; + }; +}REG_SR32; + + +typedef union _REG_SR33 //Flat_Panel_Function_Control_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 LVDS_PLL_Lock_Status :1; + CBIOS_U8 DAC_test_mode :1; + CBIOS_U8 GPIO0_Input_Data :1; + CBIOS_U8 LVDS_TEST_Enable :1; + CBIOS_U8 DAC_TEST_Enable :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 GPIO1_Input_Data :1; + CBIOS_U8 consider_MXU_DIU_BUSY_to_generate_G2N_VB_C4P :1; + }; +}REG_SR33; + + +typedef union _REG_SR34 //GFX_MISC_PAD_PD/PU_select +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 GFX_MISC_PAD_PD_sel :1; + CBIOS_U8 GFX_MISC_PAD_PU_sel :1; + CBIOS_U8 GFX_MISC_PAD_PU0_sel :1; + CBIOS_U8 GFX_MISC_PAD_PU1_sel :1; + CBIOS_U8 DVO_PAD_PD_sel :1; + CBIOS_U8 DVO_PAD_PAD_PU_sel :1; + CBIOS_U8 Reserved :2; + }; +}REG_SR34; + + +typedef union _REG_SR35_Pair //Flat_Panel_1_Function_Control_2_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 GPIO0_Select :2; + CBIOS_U8 TMDS_Y_Z_Sense_or_DC_GOP0_Status :1; + CBIOS_U8 GPIO0_Data :1; + CBIOS_U8 TMDS_YZ_Sense_or_DC_GPOUT1_Status :1; + CBIOS_U8 FP_Test_Mode_1 :1; + CBIOS_U8 FP_Test_Mode_2 :1; + CBIOS_U8 General_Test_Mode_2 :1; + }; +}REG_SR35_Pair; + + +typedef union _REG_SR35_B_Pair //Flat_Panel_2_Function_Control_2_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 GPIO1_Select :2; + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 GPIO1_Data :1; + CBIOS_U8 Reserved_1 :4; + }; +}REG_SR35_B_Pair; + + +typedef union _REG_SR36 //Flat_Panel_Dither_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Dither_Pattern_Select :1; // 0:dither 2x2 1:dither 4x4 + CBIOS_U8 Reserved_1 :2; + CBIOS_U8 Dither_Bit_Select :3; + CBIOS_U8 Dither_EN :1; + CBIOS_U8 Reserved_2 :1; + }; +}REG_SR36; + + +typedef union _REG_SR36_B //GPIO6_and_GPIO7_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Dither_Pattern_Select :1; // 0:dither 2x2 1:dither 4x4 + CBIOS_U8 Reserved_1 :2; + CBIOS_U8 Dither_Bit_Select :3; + CBIOS_U8 Dither_EN :1; + CBIOS_U8 Reserved_2 :1; + }; +}REG_SR36_B; + + +typedef union _REG_SR37 //Flat_Panel_Pulse_Width_Modulation_(PWM)_Enable_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PWM0_Enable :1; + CBIOS_U8 PWM_FQ_CNTL_1 :3; + CBIOS_U8 PWM_FQ_CNTL_2 :3; + CBIOS_U8 PWM1_Enable :1; + }; +}REG_SR37; + + +typedef union _REG_SR38 //Flat_Panel_PWM0__Duty_Cycle_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PWM0_Duty_Cycle_LSB :8; + }; +}REG_SR38; + + +typedef union _REG_SR39 //DVO-1_Port_Control_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DVO_mapping_mode :1; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 DVO_mode_select :1; + CBIOS_U8 DVO1_Delta_Delay :4; + CBIOS_U8 Invert_DVO1_CLK :1; + }; +}REG_SR39; + + +typedef union _REG_SR3A_Pair //DP_PHY_Source_Select_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DP_PHY_Test_Mode_Select :3; + CBIOS_U8 DP_PHY_Source_Sel :3; + CBIOS_U8 FP_DP_HYSNC_POL :1; + CBIOS_U8 FP_DP_VYSNC_POL :1; + }; +}REG_SR3A_Pair; + + +typedef union _REG_SR3B_Pair //DP_PHY_Source_Select_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Sel_DP_TMDS :1; + CBIOS_U8 CLK_Delay :4; + CBIOS_U8 Reserved :2; + CBIOS_U8 DP_test_enable :1; + }; +}REG_SR3B_Pair; + + +typedef union _REG_SR3C_Pair //LVDS_Dither_Enable_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 FPVDD_high_to_FP_signals_active :1; + CBIOS_U8 FP_Active_to_FPVEE_High_0 :1; + CBIOS_U8 FPVEE_Low_to_Flat_panel_signals_inactive :1; + CBIOS_U8 ENVEE :1; + CBIOS_U8 ENVDD :1; + CBIOS_U8 LVDS_RGB_Distributed_Dither :1; + CBIOS_U8 FP_Active_to_FPVEE_High_1 :2; + }; +}REG_SR3C_Pair; + + +typedef union _REG_SR3C_B //LVDS_Dither_Enable_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 reserved_0 :5; + CBIOS_U8 LVDS_RGB_Distributed_Dither :1; + CBIOS_U8 reserved_1 :2; + }; +}REG_SR3C_B; + + +typedef union _REG_SR3D //LVDS_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 ENVDD_oen_en :1; + CBIOS_U8 ENVEE_oen_en :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 Color_Mapping_Mode_Select :1; + CBIOS_U8 LVDS_Test_Mode :1; + CBIOS_U8 Flat_Panel_Source_Select :3; + }; +}REG_SR3D; + + +typedef union _REG_SR3E //Flat_Panel_PWM1_Pulse_Width_Modulation_Duty_Cycle_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PWM1_Duty_Cycle_LSB :8; + }; +}REG_SR3E; + + +typedef union _REG_SR3F //DAC_SENSE_LSB_and_Mode_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 B_Sense_1to0 :2; + CBIOS_U8 G_Sense_1to0 :2; + CBIOS_U8 R_Sense_1to0 :2; + CBIOS_U8 SENSE_Mode :1; + CBIOS_U8 Reserved :1; + }; +}REG_SR3F; + + +typedef union _REG_SR40 //LVDS_Configuration_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 Reserved_1 :2; + CBIOS_U8 Reserved_2 :1; + CBIOS_U8 PWM_Disable :1; + CBIOS_U8 LVDS_Test_Mode :3; + }; +}REG_SR40; + + +typedef union _REG_SR41 //Flat_Panel_Power_Sequence_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 FPVEE_Low :2; + CBIOS_U8 FPVDD_Low :2; + CBIOS_U8 FPVDD_High :2; + CBIOS_U8 Standby_Timer_Resolution :2; + }; +}REG_SR41; + + +typedef union _REG_SR42 //Flat_Panel_Power_Management_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Sync_Outputs :1; + CBIOS_U8 SW_Suspend_Enable :1; + CBIOS_U8 FPVSYNC_Tri_State :1; + CBIOS_U8 FPHSYNC_Tri_State :1; + CBIOS_U8 Hardware_Standby :1; + CBIOS_U8 Software_Standby :1; + CBIOS_U8 Suspend_Debounce_Timer :2; + }; +}REG_SR42; + + +typedef union _REG_SR43 //Flat_Panel_Standby_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Standby_Timeout :6; + CBIOS_U8 Activity_Enable :1; + CBIOS_U8 FP_signals_inactive_to_FPVDD_low :1; + }; +}REG_SR43; + + +typedef union _REG_SR44 //Flat_Panel_Power_Management_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :4; + CBIOS_U8 STANDBY_Pin :1; + CBIOS_U8 Reserved_1 :2; + CBIOS_U8 DAC_Power_Down :1; + }; +}REG_SR44; + + +typedef union _REG_SR45 //Flat_Panel_PLL_Power_Management_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PLL_Wait :2; + CBIOS_U8 Hot_Plug_Select :1; + CBIOS_U8 PWM1_Control :1; + CBIOS_U8 PWM1_Function_Select :1; + CBIOS_U8 Reserved :2; + CBIOS_U8 FP_Hot_Plug_Function_Enable :1; + }; +}REG_SR45; + + +typedef union _REG_SR46 //Flat_Panel_Power_Management_Status_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PM_Current_State :5; + CBIOS_U8 Standby_Status :1; + CBIOS_U8 Idle_Power_Down_State :1; + CBIOS_U8 Idle_Power_Up_State :1; + }; +}REG_SR46; + + +typedef union _REG_SR47 //CLUT_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 CLUT_Select :4; + CBIOS_U8 SP_Gamma_Enable :1; + CBIOS_U8 SP_LUT_Interpolation_Enable :1; + CBIOS_U8 Reserved :2; + }; +}REG_SR47; + + +typedef union _REG_SR48 //GPIO3_and_GPIO4_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 GPIO3_Ouptut_Data :1; + CBIOS_U8 GPIO3_Output_Enable :1; + CBIOS_U8 GPIO3_Input_Enable :1; + CBIOS_U8 GPIO3_Input_Data :1; + CBIOS_U8 GPIO4_Ouptut_Data :1; + CBIOS_U8 GPIO4_Output_Enable :1; + CBIOS_U8 GPIO4_Input_Enable :1; + CBIOS_U8 GPIO4_Input_Data :1; + }; +}REG_SR48; + + +typedef union _REG_SR49 //Primary_Stream_1_Scalar_Destination_Width_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS1_Scalar_Dest_Width_bit12 :1; + CBIOS_U8 Reserved :7; + }; +}REG_SR49; + + +typedef union _REG_SR4A //GPIO5_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 GPIO5_Ouptut_Data :1; + CBIOS_U8 GPIO5_Output_Enable :1; + CBIOS_U8 GPIO5_Input_Enable :1; + CBIOS_U8 GPIO5_Input_Data :1; + CBIOS_U8 Reserved :4; + }; +}REG_SR4A; + + +typedef union _REG_SR4B //R_SENSE_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 R_SENSE :8; + }; +}REG_SR4B; + + +typedef union _REG_SR4C //G_SENSE_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 G_SENSE :8; + }; +}REG_SR4C; + + +typedef union _REG_SR4D //B_SENSE_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 B_SENSE :8; + }; +}REG_SR4D; + + +typedef union _REG_SR4E //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR4E; + + +typedef union _REG_SR4E_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR4E_B; + + +typedef union _REG_SR4F //Primary_Stream_1_Upscaler_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS1_Upscaler_Enable :1; + CBIOS_U8 PS1_Horizontal_upscaling_Enable :1; + CBIOS_U8 PS1_Vertical_upscaling_Enable :1; + CBIOS_U8 PS1_Upscaler_Auto_Ratio :1; + CBIOS_U8 PS1_Upscaler_Cosine_Interpolation_Enable :1; + CBIOS_U8 Reserved :2; + CBIOS_U8 PS1_Upscaler_RATIO_MUTE_1 :1; + }; +}REG_SR4F; + + +typedef union _REG_SR4F_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR4F_B; + + +typedef union _REG_SR50 //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR50; + + +typedef union _REG_SR50_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR50_B; + + +typedef union _REG_SR51 //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR51; + + +typedef union _REG_SR51_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR51_B; + + +typedef union _REG_SR52 //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR52; + + +typedef union _REG_SR52_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR52_B; + + +typedef union _REG_SR53 //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR53; + + +typedef union _REG_SR53_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR53_B; + + +typedef union _REG_SR54 //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR54; + + +typedef union _REG_SR54_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR54_B; + + +typedef union _REG_SR55 //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR55; + + +typedef union _REG_SR55_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR55_B; + + +typedef union _REG_SR56 //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR56; + + +typedef union _REG_SR56_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR56_B; + + +typedef union _REG_SR57 //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR57; + + +typedef union _REG_SR57_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR57_B; + + +typedef union _REG_SR58 //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR58; + + +typedef union _REG_SR58_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR58_B; + + +typedef union _REG_SR59 //Primary_Stream_1_Upscaler_Destination_Width_7:0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS1_Upscaler_Dest_Width_7_0 :8; + }; +}REG_SR59; + + +typedef union _REG_SR59_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR59_B; + + +typedef union _REG_SR5A //Primary_Stream_1_Upscaler_Destination_Overflow_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS1_Upscaler_Dest_width :4; + CBIOS_U8 PS1_Upscaler_Dest_Height :4; + }; +}REG_SR5A; + + +typedef union _REG_SR5A_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR5A_B; + + +typedef union _REG_SR5B //Primary_Stream_1_Upscaler_Destination_Height_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 PS1_Upscaler_Dest_Height_7_0 :8; + }; +}REG_SR5B; + + +typedef union _REG_SR5B_B //Reserved +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :8; + }; +}REG_SR5B_B; + + +typedef union _REG_SR5C_Pair //Flat_Panel_Enable_Position_Control_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 FP_Display_Enable_Control_1 :4; + CBIOS_U8 FP_Display_Enable_Control_2 :4; + }; +}REG_SR5C_Pair; + + +typedef union _REG_SR5D_Pair //Flat_Panel_/_CRT_Sync_Position_Control_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 FP_CRT_Sync_Control_1 :4; + CBIOS_U8 FP_CRT_Sync_Control_2 :4; + }; +}REG_SR5D_Pair; + + +typedef union _REG_SR5E_Pair //Flat_Panel_BIOS_Scratch_1_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 BIOS_Scratch :8; + }; +}REG_SR5E_Pair; + + +typedef union _REG_SR5F_Pair //Flat_Panel_BIOS_Scratch_2_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 BIOS_Scratch :8; + }; +}REG_SR5F_Pair; + + +typedef union _REG_SR60_Pair //Flat_Panel_Horizontal_Total_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_Total_7to0 :8; + }; +}REG_SR60_Pair; + + +typedef union _REG_SR61_Pair //Flat_Panel_Horizontal_Panel_Size_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_Panel_Size_7to0 :8; + }; +}REG_SR61_Pair; + + +typedef union _REG_SR62_Pair //Flat_Panel_Horizontal_Blank_Start_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_Blank_Start_7to0 :8; + }; +}REG_SR62_Pair; + + +typedef union _REG_SR63_Pair //Flat_Panel_Horizontal_Blank_End_Low_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_Blank_End_6to0 :7; + CBIOS_U8 Reserved :1; + }; +}REG_SR63_Pair; + + +typedef union _REG_SR64_Pair //Flat_Panel_Horizontal_Sync_Start_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_Sync_Start_7to0 :8; + }; +}REG_SR64_Pair; + + +typedef union _REG_SR65_Pair //Flat_Panel_Horizontal_Sync_End_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_Sync_End_5to0 :6; + CBIOS_U8 Reserved :2; + }; +}REG_SR65_Pair; + + +typedef union _REG_SR66_Pair //Flat_Panel_Horizontal_Overflow_Register_Pair_1 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_Total_bit_8 :1; + CBIOS_U8 Horizontal_Panel_Size_bit_8 :1; + CBIOS_U8 Horizontal_Blank_Start_bit_8 :1; + CBIOS_U8 Horizontal_Sync_Start_bit_8 :1; + CBIOS_U8 Reserved :4; + }; +}REG_SR66_Pair; + + +typedef union _REG_SR67 //Flat_Panel_Horizontal_Overflow_Register_Pair_2 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Horizontal_Total_bit_9 :1; + CBIOS_U8 Horizontal_Panel_Size_bit_9 :1; + CBIOS_U8 Horizontal_Blank_Start_bit_9 :1; + CBIOS_U8 Horizontal_Sync_Start_bit_9 :1; + CBIOS_U8 Reserved :4; + }; +}REG_SR67; + + +typedef union _REG_SR68_Pair //Flat_Panel_Vertical_Total_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vertical_Total_7to0 :8; + }; +}REG_SR68_Pair; + + +typedef union _REG_SR69_Pair //Flat_Panel_Vertical_Panel_Size_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vertical_Panel_Size_7to0 :8; + }; +}REG_SR69_Pair; + + +typedef union _REG_SR6A_Pair //Flat_Panel_Vertical_Blank_Start_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vertical_Blank_Start_7to0 :8; + }; +}REG_SR6A_Pair; + + +typedef union _REG_SR6B_Pair //Flat_Panel_Vertical_Blank_End_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vertical_Blank_End_7to0 :8; + }; +}REG_SR6B_Pair; + + +typedef union _REG_SR6C_Pair //Flat_Panel_Vertical_Sync_Start_Low_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vertical_Sync_Start_7to0 :8; + }; +}REG_SR6C_Pair; + + +typedef union _REG_SR6D_Pair //Flat_Panel_Vertical_Sync_End_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vertical_Sync_End_3to0 :4; + CBIOS_U8 Reserved :4; + }; +}REG_SR6D_Pair; + + +typedef union _REG_SR6E_Pair //Flat_Panel_Vertical_Overflow_1_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vertical_Total_11to8 :4; + CBIOS_U8 Vertical_Panel_Size_11to8 :4; + }; +}REG_SR6E_Pair; + + +typedef union _REG_SR6F_Pair //Flat_Panel_Vertical_Overflow_2_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Vertical_Blank_Start_11to8 :4; + CBIOS_U8 Vertical_Sync_Start_11to8 :4; + }; +}REG_SR6F_Pair; + + +typedef union _REG_SR70_B //HDTV1_Mode_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Progressive_Mode_Enable :1; + CBIOS_U8 SMPTE_274M_Enable :1; + CBIOS_U8 SMPTE_296M_Enable :1; + CBIOS_U8 SMPTE_293M_Enable :1; + CBIOS_U8 _576P_Enable :1; + CBIOS_U8 HDTV_Timing_Enable_Control :1; + CBIOS_U8 ITU470_SELECT :1; + CBIOS_U8 _576i_480i_enable :1; + }; +}REG_SR70_B; + + +typedef union _REG_SR70_T //HDTV2_Mode_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Progressive_Mode_Enable :1; + CBIOS_U8 SMPTE_274M_Enable :1; + CBIOS_U8 SMPTE_296M_Enable :1; + CBIOS_U8 SMPTE_293M_Enable :1; + CBIOS_U8 _576P_Enable :1; + CBIOS_U8 HDTV_Timing_Enable_Control :1; + CBIOS_U8 ITU470_SELECT :1; + CBIOS_U8 _576i_480i_enable :1; + }; +}REG_SR70_T; + + +typedef union _REG_SR71_B //HDTV1_Tri-Level_SYNC_Width +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Trilevel_Sync_Width :6; + CBIOS_U8 HDTV_EN_TRIG_PULSE :2; + }; +}REG_SR71_B; + + +typedef union _REG_SR71_T //HDTV2_Tri-Level_SYNC_Width +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Trilevel_Sync_Width :6; + CBIOS_U8 HDTV_EN_TRIG_PULSE :2; + }; +}REG_SR71_T; + + +typedef union _REG_SR72_B //HDTV1_BLANK_Level_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Blank_Level_7to0 :8; + }; +}REG_SR72_B; + + +typedef union _REG_SR72_T //HDTV2_BLANK_Level_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Blank_Level_7to0 :8; + }; +}REG_SR72_T; + + +typedef union _REG_SR73_B //HDTV1_BLANK_Level_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Blank_Level_9to8 :2; + CBIOS_U8 _1x_2x_4x_oversampling_sel :2; + CBIOS_U8 Reserved :4; + }; +}REG_SR73_B; + + +typedef union _REG_SR73_T //HDTV2_BLANK_Level_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Blank_Level_9to8 :2; + CBIOS_U8 _1x_2x_4x_oversampling_sel :2; + CBIOS_U8 Reserved :4; + }; +}REG_SR73_T; + + +typedef union _REG_SR74_B //HDTV1_CSC_input_data_format +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_input_data_format :5; + CBIOS_U8 HDTV_CSC_coefficients_sel :1; + CBIOS_U8 HDTV_old_slope_enable :1; + CBIOS_U8 Reserved :1; + }; +}REG_SR74_B; + + +typedef union _REG_SR74_T //HDTV2_CSC_input_data_format +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_input_data_format :5; + CBIOS_U8 HDTV_CSC_coefficients_sel :1; + CBIOS_U8 HDTV_old_slope_enable :1; + CBIOS_U8 Reserved :1; + }; +}REG_SR74_T; + + +typedef union _REG_SR75_B //HDTV_1_contrast_tuning_register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Contrast_tuning_value :8; + }; +}REG_SR75_B; + + +typedef union _REG_SR75_T //HDTV2_contrast_tuning_register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Contrast_tuning_value :8; + }; +}REG_SR75_T; + + +typedef union _REG_SR76_B //HDTV1_Pb_saturation_tuning +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Pb_Saturation_tuning_value :8; + }; +}REG_SR76_B; + + +typedef union _REG_SR76_T //HDTV2_Pb_saturation_tuning +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Pb_Saturation_tuning_value :8; + }; +}REG_SR76_T; + + +typedef union _REG_SR77_B //HDTV1_Pr_saturation_tuning +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Pr_Saturation_tuning_value :8; + }; +}REG_SR77_B; + + +typedef union _REG_SR77_T //HDTV2_Pr_saturation_tuning +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Pr_Saturation_tuning_value :8; + }; +}REG_SR77_T; + + +typedef union _REG_SR78_B //HDTV1_576i_initial_programming_data_enable +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 _576i_initial_programming :2; + CBIOS_U8 HDTV__pbpr_dac_filter_select_coef :5; + CBIOS_U8 Reserved :1; + }; +}REG_SR78_B; + + +typedef union _REG_SR78_T //HDTV2_576i_initial_programming_data_enable +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 _576i_initial_programming :2; + CBIOS_U8 HDTV__pbpr_dac_filter_select_coef :5; + CBIOS_U8 Reserved :1; + }; +}REG_SR78_T; + + +typedef union _REG_SR79_B //HDTV1_y_dac_filter_select_coef +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_y_dac_filter_select_coef :5; + CBIOS_U8 HDMI_SYNC_Delay_9to8 :2; + CBIOS_U8 Reserved :1; + }; +}REG_SR79_B; + + +typedef union _REG_SR79_T //HDTV2__dac_filter_select_coef +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_y_dac_filter_select_coef :5; + CBIOS_U8 HDMI_SYNC_Delay_9to8 :2; + CBIOS_U8 Reserved :1; + }; +}REG_SR79_T; + + +typedef union _REG_SR7A_B //HDTV1_HDMI_SYNC_Delay_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDMI_SYNC_Delay_7to0 :8; + }; +}REG_SR7A_B; + + +typedef union _REG_SR7A_T //HDTV2_HDMI_SYNC_Delay_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDMI_SYNC_Delay_7to0 :8; + }; +}REG_SR7A_T; + + +typedef union _REG_SR7D_B //HDTV1_SYNC_Delay_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_SYNC_Delay_10to8 :3; + CBIOS_U8 Reserved :5; + }; +}REG_SR7D_B; + + +typedef union _REG_SR7D_T //HDTV2_SYNC_Delay_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_SYNC_Delay_10to8 :3; + CBIOS_U8 Reserved :5; + }; +}REG_SR7D_T; + + +typedef union _REG_SR7E_B //HDTV1_SYNC_Delay_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_SYNC_Delay_7to0 :8; + }; +}REG_SR7E_B; + + +typedef union _REG_SR7E_T //HDTV2_SYNC_Delay_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_SYNC_Delay_7to0 :8; + }; +}REG_SR7E_T; + + +typedef union _REG_SR80_B //HDTV1_Color_Space_Converter_Factor_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F0_7to0 :8; + }; +}REG_SR80_B; + + +typedef union _REG_SR80_T //HDTV2_Color_Space_Converter_Factor_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F0_7to0 :8; + }; +}REG_SR80_T; + + +typedef union _REG_SR81_B //HDTV1_Color_Space_Converter_Factor_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F1_7to0 :8; + }; +}REG_SR81_B; + + +typedef union _REG_SR81_T //HDTV2_Color_Space_Converter_Factor_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F1_7to0 :8; + }; +}REG_SR81_T; + + +typedef union _REG_SR82_B //HDTV1_Color_Space_Converter_Factor_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F2_7to0 :8; + }; +}REG_SR82_B; + + +typedef union _REG_SR82_T //HDTV2_Color_Space_Converter_Factor_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F2_7to0 :8; + }; +}REG_SR82_T; + + +typedef union _REG_SR83_B //HDTV1_Color_Space_Converter_Factor_3_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F3_7to0 :8; + }; +}REG_SR83_B; + + +typedef union _REG_SR83_T //HDTV2_Color_Space_Converter_Factor_3_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F3_7to0 :8; + }; +}REG_SR83_T; + + +typedef union _REG_SR84_B //HDTV1_Color_Space_Converter_Factor_4_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F4_7to0 :8; + }; +}REG_SR84_B; + + +typedef union _REG_SR84_T //HDTV2_Color_Space_Converter_Factor_4_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F4_7to0 :8; + }; +}REG_SR84_T; + + +typedef union _REG_SR85_B //HDTV1_Color_Space_Converter_Factor_5_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F5_7to0 :8; + }; +}REG_SR85_B; + + +typedef union _REG_SR85_T //HDTV2_Color_Space_Converter_Factor_5_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F5_7to0 :8; + }; +}REG_SR85_T; + + +typedef union _REG_SR86_B //HDTV1_Color_Space_Converter_Factor_6_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F6_7to0 :8; + }; +}REG_SR86_B; + + +typedef union _REG_SR86_T //HDTV2_Color_Space_Converter_Factor_6_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F6_7to0 :8; + }; +}REG_SR86_T; + + +typedef union _REG_SR87_B //HDTV1_Color_Space_Converter_Factor_7_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F7_7to0 :8; + }; +}REG_SR87_B; + + +typedef union _REG_SR87_T //HDTV2_Color_Space_Converter_Factor_7_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F7_7to0 :8; + }; +}REG_SR87_T; + + +typedef union _REG_SR88_B //HDTV1_Color_Space_Converter_Factor_8_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F8_7to0 :8; + }; +}REG_SR88_B; + + +typedef union _REG_SR88_T //HDTV2_Color_Space_Converter_Factor_8_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CSC_F8_7to0 :8; + }; +}REG_SR88_T; + + +typedef union _REG_SR89_B //HDTV1_Left_Blank_Pixels_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Left_Blank_Pixels_10to8 :3; + CBIOS_U8 Reserved :5; + }; +}REG_SR89_B; + + +typedef union _REG_SR89_T //HDTV2_Left_Blank_Pixels_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Left_Blank_Pixels_10to8 :3; + CBIOS_U8 Reserved :5; + }; +}REG_SR89_T; + + +typedef union _REG_SR8A_B //HDTV1_Left_Blank_Pixels_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Left_Blank_Pixels_7to0 :8; + }; +}REG_SR8A_B; + + +typedef union _REG_SR8A_T //HDTV2_Left_Blank_Pixels_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Left_Blank_Pixels_7to0 :8; + }; +}REG_SR8A_T; + + +typedef union _REG_SR8E_B //HDTV1_Brightness_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Brightness_Control :8; + }; +}REG_SR8E_B; + + +typedef union _REG_SR8E_T //HDTV2_Brightness_Control_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Brightness_Control :8; + }; +}REG_SR8E_T; + + +typedef union _REG_SR8F_B //HDTV1_Enable_and_CSC_F8_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_bit0 :1; + CBIOS_U8 HDTV_CSC_F8_10to8 :3; + CBIOS_U8 Reserved_bit1 :3; + CBIOS_U8 HDTV_Enable :1; + }; +}REG_SR8F_B; + + +typedef union _REG_SR8F_T //HDTV2_Enable_and_CSC_F8_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_bit0 :1; + CBIOS_U8 HDTV_CSC_F8_10to8 :3; + CBIOS_U8 Reserved_bit1 :3; + CBIOS_U8 HDTV_Enable :1; + }; +}REG_SR8F_T; + + +typedef union _REG_SRA3_B //HDTV1_Digital_HSYNC_Width_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Digital_HSYNC_Width :8; + }; +}REG_SRA3_B; + + +typedef union _REG_SRA3_T //HDTV2_Digital_HSYNC_Width_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Digital_HSYNC_Width :8; + }; +}REG_SRA3_T; + + +typedef union _REG_SRA4_B //HDTV1_Color_Space_Converter_Factor_0_and_1_Upper_Bits_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 HDTV_CSC_F1_10to8 :3; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 HDTV_CSC_F0_10to8 :3; + }; +}REG_SRA4_B; + + +typedef union _REG_SRA4_T //HDTV2_Color_Space_Converter_Factor_0_and_1_Upper_Bits_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 HDTV_CSC_F1_10to8 :3; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 HDTV_CSC_F0_10to8 :3; + }; +}REG_SRA4_T; + + +typedef union _REG_SRA5_B //HDTV1_Color_Space_Converter_Factor_2_and_3_Upper_Bits_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 HDTV_CSC_F3_10to8 :3; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 HDTV_CSC_F2_10to8 :3; + }; +}REG_SRA5_B; + + +typedef union _REG_SRA5_T //HDTV2_Color_Space_Converter_Factor_2_and_3_Upper_Bits_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 HDTV_CSC_F3_10to8 :3; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 HDTV_CSC_F2_10to8 :3; + }; +}REG_SRA5_T; + + +typedef union _REG_SRA6_B //HDTV1_Color_Space_Converter_Factor_4_and_5_Upper_Bits_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 HDTV_CSC_F5_10to8 :3; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 HDTV_CSC_F4_10to8 :3; + }; +}REG_SRA6_B; + + +typedef union _REG_SRA6_T //HDTV2_Color_Space_Converter_Factor_4_and_5_Upper_Bits_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 HDTV_CSC_F5_10to8 :3; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 HDTV_CSC_F4_10to8 :3; + }; +}REG_SRA6_T; + + +typedef union _REG_SRA7_B //HDTV1_Color_Space_Converter_Factor_6_and_7_Upper_Bits_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 HDTV_CSC_F7_10to8 :3; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 HDTV_CSC_F6_10to8 :3; + }; +}REG_SRA7_B; + + +typedef union _REG_SRA7_T //HDTV2_Color_Space_Converter_Factor_6_and_7_Upper_Bits_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 HDTV_CSC_F7_10to8 :3; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 HDTV_CSC_F6_10to8 :3; + }; +}REG_SRA7_T; + + +typedef union _REG_SRA8_B //HDTV1_Miscellaneous_Overflow_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :2; + CBIOS_U8 HDTV_WSS_Clock_Ratio_bit_14 :1; + CBIOS_U8 Reserved_1 :5; + }; +}REG_SRA8_B; + + +typedef union _REG_SRA8_T //HDTV2_Miscellaneous_Overflow_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :2; + CBIOS_U8 HDTV_WSS_Clock_Ratio_bit_14 :1; + CBIOS_U8 Reserved_1 :5; + }; +}REG_SRA8_T; + + +typedef union _REG_SRAA_B //HDTV1_HSYNC_Delay_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_HSYNC_Delay :3; + CBIOS_U8 Reserved :5; + }; +}REG_SRAA_B; + + +typedef union _REG_SRAA_T //HDTV2_HSYNC_Delay_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_HSYNC_Delay :3; + CBIOS_U8 Reserved :5; + }; +}REG_SRAA_T; + + +typedef union _REG_SRAB_B //HDTV1_Character_Clock_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Iga1_Character_Clock :3; + CBIOS_U8 Iga2_Character_Clock :3; + CBIOS_U8 Reserved :2; + }; +}REG_SRAB_B; + + +typedef union _REG_SRAB_T //HDTV2_Character_Clock_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Iga1_Character_Clock :3; + CBIOS_U8 Iga2_Character_Clock :3; + CBIOS_U8 Reserved :2; + }; +}REG_SRAB_T; + + +typedef union _REG_SRAD_B //HDTV1_Wide_Screen_Signal_(WSS)_Clock_Ratio_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_WSS_Clock_Ratio13to6 :8; + }; +}REG_SRAD_B; + + +typedef union _REG_SRAD_T //HDTV2_Wide_Screen_Signal_(WSS)_Clock_Ratio_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_WSS_Clock_Ratio13to6 :8; + }; +}REG_SRAD_T; + + +typedef union _REG_SRBF_B //HDTV1_SENSE_Line_Select_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_SENSE_Line_Sleect :5; + CBIOS_U8 Reserved :3; + }; +}REG_SRBF_B; + + +typedef union _REG_SRBF_T //HDTV2_SENSE_Line_Select_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_SENSE_Line_Sleect :5; + CBIOS_U8 Reserved :3; + }; +}REG_SRBF_T; + + +typedef union _REG_SRD0_B //HDTV1_Broad_Pulse_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Hdtv_Broad_Pulse_6to0 :7; + CBIOS_U8 Reserved :1; + }; +}REG_SRD0_B; + + +typedef union _REG_SRD0_T //HDTV2_Broad_Pulse_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Hdtv_Broad_Pulse_6to0 :7; + CBIOS_U8 Reserved :1; + }; +}REG_SRD0_T; + + +typedef union _REG_SRD1_B //HDTV1_Broad_Pulse_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Hdtv_Broad_Pulse_14to7 :8; + }; +}REG_SRD1_B; + + +typedef union _REG_SRD1_T //HDTV2_Broad_Pulse_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Hdtv_Broad_Pulse_14to7 :8; + }; +}REG_SRD1_T; + + +typedef union _REG_SRD2_B //HDTV1_Half_SYNC_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Hdtv_Half_Sync_7to0 :8; + }; +}REG_SRD2_B; + + +typedef union _REG_SRD2_T //HDTV2_Half_SYNC_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Hdtv_Half_Sync_7to0 :8; + }; +}REG_SRD2_T; + + +typedef union _REG_SRD3_B //HDTV1_Half_SYNC_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Hdtv_Half_Sync_10to8 :3; + CBIOS_U8 Reserved :5; + }; +}REG_SRD3_B; + + +typedef union _REG_SRD3_T //HDTV2_Half_SYNC_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Hdtv_Half_Sync_10to8 :3; + CBIOS_U8 Reserved :5; + }; +}REG_SRD3_T; + + +typedef union _REG_SRD6_B //HDTV1_576i/580i_Closed_Caption_(CC)_Clock_Ratio_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Clock_Ratio_7to0 :8; + }; +}REG_SRD6_B; + + +typedef union _REG_SRD6_T //HDTV2_576i/580i_Closed_Caption_(CC)_Clock_Ratio_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Clock_Ratio_7to0 :8; + }; +}REG_SRD6_T; + + +typedef union _REG_SRD7_B //HDTV1_576i/480i_Closed_Caption_(CC)_Clock_Ratio_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Clock_Ratio_14to8 :7; + CBIOS_U8 Reserved :1; + }; +}REG_SRD7_B; + + +typedef union _REG_SRD7_T //HDTV2_576i/480i_Closed_Caption_(CC)_Clock_Ratio_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Clock_Ratio_14to8 :7; + CBIOS_U8 Reserved :1; + }; +}REG_SRD7_T; + + +typedef union _REG_SRD8_B //HDTV1_576i/480i_Closed_Caption_(CC)_Line_and_Field_Select_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Line_Select :6; + CBIOS_U8 HDTV_CC_Field_Select :2; + }; +}REG_SRD8_B; + + +typedef union _REG_SRD8_T //HDTV2_576i/480i_Closed_Caption_(CC)_Line_and_Field_Select_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Line_Select :6; + CBIOS_U8 HDTV_CC_Field_Select :2; + }; +}REG_SRD8_T; + + +typedef union _REG_SRD9_B //HDTV1_576i/480i_Closed_Caption_(CC)/WSS_Range_Overflow_and_Word_Mode_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 HDTV_CC_End_10to8 :3; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 HDTV_CC_Start_bit_8 :1; + CBIOS_U8 HDTV_CC_Sermode :1; + CBIOS_U8 HDTV_CC_Word_Mode_Select :1; + }; +}REG_SRD9_B; + + +typedef union _REG_SRD9_T //HDTV2_576i/480i_Closed_Caption_(CC)/WSS_Range_Overflow_and_Word_Mode_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 HDTV_CC_End_10to8 :3; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 HDTV_CC_Start_bit_8 :1; + CBIOS_U8 HDTV_CC_Sermode :1; + CBIOS_U8 HDTV_CC_Word_Mode_Select :1; + }; +}REG_SRD9_T; + + +typedef union _REG_SRDA_B //HDTV1_576i/480i_Closed_Caption_(CC)_Start_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Start_7to0 :8; + }; +}REG_SRDA_B; + + +typedef union _REG_SRDA_T //HDTV2_576i/480i_Closed_Caption_(CC)_Start_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Start_7to0 :8; + }; +}REG_SRDA_T; + + +typedef union _REG_SRDB_B //HDTV1_576i/480i_Closed_Caption_(CC)/WSS_End_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_WSS_End_7to0 :8; + }; +}REG_SRDB_B; + + +typedef union _REG_SRDB_T //HDTV2_576i/480i_Closed_Caption_(CC)/WSS_End_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_WSS_End_7to0 :8; + }; +}REG_SRDB_T; + + +typedef union _REG_SRDC_B //HDTV1_576i/480i_Closed_Caption_(CC)_Field_1_Word_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Field1_Word0 :7; + CBIOS_U8 HDTV_CC_Field1_Data_Write_Status :1; + }; +}REG_SRDC_B; + + +typedef union _REG_SRDC_T //HDTV2_576i/480i_Closed_Caption_(CC)_Field_1_Word_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Field1_Word0 :7; + CBIOS_U8 HDTV_CC_Field1_Data_Write_Status :1; + }; +}REG_SRDC_T; + + +typedef union _REG_SRDD_B //HDTV1_576i/480i_Closed_Caption_(CC)_Field_1_Word_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Field1_Word1 :7; + CBIOS_U8 Reserved :1; + }; +}REG_SRDD_B; + + +typedef union _REG_SRDD_T //HDTV2_576i/480i_Closed_Caption_(CC)_Field_1_Word_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Field1_Word1 :7; + CBIOS_U8 Reserved :1; + }; +}REG_SRDD_T; + + +typedef union _REG_SRE0_B //HDTV1_576i/480i_Parameter_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm0_Start_HDTV_HSYNC_7to0 :8; + }; +}REG_SRE0_B; + + +typedef union _REG_SRE0_T //HDTV2_576i/480i_Parameter_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm0_Start_HDTV_HSYNC_7to0 :8; + }; +}REG_SRE0_T; + + +typedef union _REG_SRE1_B //HDTV1_576i/480i_Parameter_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm1_End_1st_Equalizing_7to0 :8; + }; +}REG_SRE1_B; + + +typedef union _REG_SRE1_T //HDTV2_576i/480i_Parameter_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm1_End_1st_Equalizing_7to0 :8; + }; +}REG_SRE1_T; + + +typedef union _REG_SRE2_B //HDTV1_576i/480i_Parameter_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm1_End_1st_Equalizing_7to0 :8; + }; +}REG_SRE2_B; + + +typedef union _REG_SRE2_T //HDTV2_576i/480i_Parameter_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm1_End_1st_Equalizing_7to0 :8; + }; +}REG_SRE2_T; + + +typedef union _REG_SRE4_B //HDTV1_HDE_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_HDE_7to0 :8; + }; +}REG_SRE4_B; + + +typedef union _REG_SRE4_T //HDTV2_HDE_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_HDE_7to0 :8; + }; +}REG_SRE4_T; + + +typedef union _REG_SRE5_B //HDTV1_HDE_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_HDE_10to8 :3; + CBIOS_U8 Reserved :5; + }; +}REG_SRE5_B; + + +typedef union _REG_SRE5_T //HDTV2_HDE_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_HDE_10to8 :3; + CBIOS_U8 Reserved :5; + }; +}REG_SRE5_T; + + +typedef union _REG_SRE6_B //HDTV1_576i/480i_Parameter_3_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm3_Start_HDTV_HSYNC_7to0 :8; + }; +}REG_SRE6_B; + + +typedef union _REG_SRE6_T //HDTV2_576i/480i_Parameter_3_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm3_Start_HDTV_HSYNC_7to0 :8; + }; +}REG_SRE6_T; + + +typedef union _REG_SRE7_B //HDTV1_576i/480i_Parameter_4_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm4_End_1st_Serration_Start_2nd_Equalization_7to0 :8; + }; +}REG_SRE7_B; + + +typedef union _REG_SRE7_T //HDTV2_576i/480i_Parameter_4_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm4_End_1st_Serration_Start_2nd_Equalization_7to0 :8; + }; +}REG_SRE7_T; + + +typedef union _REG_SRE8_B //HDTV1_576i/480i_Parameter_5_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm5_End_2nd_Equalization_7to0 :8; + }; +}REG_SRE8_B; + + +typedef union _REG_SRE8_T //HDTV2_576i/480i_Parameter_5_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm5_End_2nd_Equalization_7to0 :8; + }; +}REG_SRE8_T; + + +typedef union _REG_SRE9_B //HDTV1_576i/480i_Parameter_6_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm6_End_2nd_Equalization_7to0 :8; + }; +}REG_SRE9_B; + + +typedef union _REG_SRE9_T //HDTV2_576i/480i_Parameter_6_Register_Pair +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm6_End_2nd_Equalization_7to0 :8; + }; +}REG_SRE9_T; + + +typedef union _REG_SREB_B //HDTV1(576i/480i)_Parameter_Overflow_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Pr_channel_delay :2; + CBIOS_U8 Pb_channel_delay :2; + CBIOS_U8 HDTV_Parm1_End_1st_Equalizing_10to8 :3; + CBIOS_U8 Reserved :1; + }; +}REG_SREB_B; + + +typedef union _REG_SREB_T //HDTV2(576i/480i)_Parameter_Overflow_0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Pr_channel_delay :2; + CBIOS_U8 Pb_channel_delay :2; + CBIOS_U8 HDTV_Parm1_End_1st_Equalizing_10to8 :3; + CBIOS_U8 Reserved :1; + }; +}REG_SREB_T; + + +typedef union _REG_SREC_B //HDTV1(576i/480i)_Parameter_Overflow_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm2_End_TV_HSYNC_10to8 :3; + CBIOS_U8 Y_channel_delay :2; + CBIOS_U8 Reserved :3; + }; +}REG_SREC_B; + + +typedef union _REG_SREC_T //HDTV2(576i/480i)_Parameter_Overflow_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm2_End_TV_HSYNC_10to8 :3; + CBIOS_U8 Y_channel_delay :2; + CBIOS_U8 Reserved :3; + }; +}REG_SREC_T; + + +typedef union _REG_SREE_B //HDTV1(576i/480i)_Parameter_Overflow_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm3_Start_First_Serration_9to8 :2; + CBIOS_U8 HDTV_Parm4_End_1st_Serration_Start_2nd_Equalization_9to8 :2; + CBIOS_U8 HDTV_Parm5_End_2nd_Equalization_9to8 :2; + CBIOS_U8 Reserved :2; + }; +}REG_SREE_B; + + +typedef union _REG_SREE_T //HDTV2(576i/480i)_Parameter_Overflow_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm3_Start_First_Serration_9to8 :2; + CBIOS_U8 HDTV_Parm4_End_1st_Serration_Start_2nd_Equalization_9to8 :2; + CBIOS_U8 HDTV_Parm5_End_2nd_Equalization_9to8 :2; + CBIOS_U8 Reserved :2; + }; +}REG_SREE_T; + + +typedef union _REG_SREF_B //HDTV1(576i/480i)_Parameter_Overflow_3_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm6_Start_2nd_Serration_10to8 :3; + CBIOS_U8 Reserved :4; + CBIOS_U8 VBI_Enable :1; + }; +}REG_SREF_B; + + +typedef union _REG_SREF_T //HDTV2(576i/480i)_Parameter_Overflow_3_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_Parm6_Start_2nd_Serration_10to8 :3; + CBIOS_U8 Reserved :4; + CBIOS_U8 VBI_Enable :1; + }; +}REG_SREF_T; + + +typedef union _REG_SRF0_B //HDTV1_Wide_Screen_Signal_(WSS)_Word_or_Packet_B_Data_Byte_1Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 WSS_Word0_or_B_Data_Byte_2_or_WSS_Word_13to8 :8; + }; +}REG_SRF0_B; + + +typedef union _REG_SRF0_T //HDTV2_Wide_Screen_Signal_(WSS)_Word_or_Packet_B_Data_Byte_1Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 WSS_Word0_or_B_Data_Byte_2_or_WSS_Word_13to8 :8; + }; +}REG_SRF0_T; + + +typedef union _REG_SRF1_B //HDTV1_Wide_Screen_Signal_(WSS)_Word_or_Packet_B_Data_Byte_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 WSS_Word1_or_B_Data_Byte_2_or_WSS_Word_13to8 :8; + }; +}REG_SRF1_B; + + +typedef union _REG_SRF1_T //HDTV2_Wide_Screen_Signal_(WSS)_Word_or_Packet_B_Data_Byte_2_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 WSS_Word1_or_B_Data_Byte_2_or_WSS_Word_13to8 :8; + }; +}REG_SRF1_T; + + +typedef union _REG_SRF2_B //HDTV1_WSS_or_Packet_B_Data_Byte_3_or_Packet_A_Data_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 WSS_Word2_or_Packet_A_Data_or_Packet_B_Data_Byte :8; + }; +}REG_SRF2_B; + + +typedef union _REG_SRF2_T //HDTV2_WSS_or_Packet_B_Data_Byte_3_or_Packet_A_Data_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 WSS_Word2_or_Packet_A_Data_or_Packet_B_Data_Byte :8; + }; +}REG_SRF2_T; + + +typedef union _REG_SRF3_B //HDTV1(576i/480i)_Closed_Caption_(CC)_Field0_Word0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Field0_Word0 :7; + CBIOS_U8 HDTV_CC_Field0_Data_Write_Status :1; + }; +}REG_SRF3_B; + + +typedef union _REG_SRF3_T //HDTV2(576i/480i)_Closed_Caption_(CC)_Field0_Word0_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Field0_Word0 :7; + CBIOS_U8 HDTV_CC_Field0_Data_Write_Status :1; + }; +}REG_SRF3_T; + + +typedef union _REG_SRF4_B //HDTV1(576i/480i)_Closed_Caption_(CC)_Field0_Word1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Field0_Word1_or_HDTV_Packet_A_CRC_Or_Packet_B_Data_Byte_14 :7; + CBIOS_U8 Reserved_OR__Packet_B_Data_Byte_14 :1; + }; +}REG_SRF4_B; + + +typedef union _REG_SRF4_T //HDTV2(576i/480i)_Closed_Caption_(CC)_Field0_Word1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CC_Field0_Word1_or_HDTV_Packet_A_CRC_Or_Packet_B_Data_Byte_14 :7; + CBIOS_U8 Reserved_OR__Packet_B_Data_Byte_14 :1; + }; +}REG_SRF4_T; + + +typedef union _REG_SRF5_B //HDTV1_Wide_Screen_Signal_(WSS)_Clock_Ratio_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 WSS_Clock_Ratio_5to0 :6; + CBIOS_U8 WSS_Mode_Enable :2; + }; +}REG_SRF5_B; + + +typedef union _REG_SRF5_T //HDTV2_Wide_Screen_Signal_(WSS)_Clock_Ratio_1_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 WSS_Clock_Ratio_5to0 :6; + CBIOS_U8 WSS_Mode_Enable :2; + }; +}REG_SRF5_T; + + +typedef union _REG_SRF6_B //HDTV1_Wide_Screen_Signal_(WSS)/CGMS-A_Line_and_Field_Select_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 WSS_CGMS_A_Line_Select :6; + CBIOS_U8 WSS_Field_Select :2; + }; +}REG_SRF6_B; + + +typedef union _REG_SRF6_T //HDTV2_Wide_Screen_Signal_(WSS)/CGMS-A_Line_and_Field_Select_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 WSS_CGMS_A_Line_Select :6; + CBIOS_U8 WSS_Field_Select :2; + }; +}REG_SRF6_T; + + +typedef union _REG_SRF7_B //HDTV1_CGMSA_Header_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CGMSA_Header :6; + CBIOS_U8 Reserved :2; + }; +}REG_SRF7_B; + + +typedef union _REG_SRF7_T //HDTV2_CGMSA_Header_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_CGMSA_Header :6; + CBIOS_U8 Reserved :2; + }; +}REG_SRF7_T; + + +typedef union _REG_SRF8_B //HDTV1_WSS/CGMSA_Start_LSB_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :3; + CBIOS_U8 HDTV_WSS_CGMSA_Start_4to0 :5; + }; +}REG_SRF8_B; + + +typedef union _REG_SRF8_T //HDTV2_WSS/CGMSA_Start_LSB_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Reserved :3; + CBIOS_U8 HDTV_WSS_CGMSA_Start_4to0 :5; + }; +}REG_SRF8_T; + + +typedef union _REG_SRF9_B //HDTV1_WSS/CGMSA_Enable_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_WSS_CGMSA_Start_8to5 :4; + CBIOS_U8 HDTV_WSS_Sermode :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 HDTV_CGMSA_Mode :2; + }; +}REG_SRF9_B; + + +typedef union _REG_SRF9_T //HDTV2_WSS/CGMSA_Enable_Register +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 HDTV_WSS_CGMSA_Start_8to5 :4; + CBIOS_U8 HDTV_WSS_Sermode :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 HDTV_CGMSA_Mode :2; + }; +}REG_SRF9_T; + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_vga_registers.h b/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_vga_registers.h new file mode 100644 index 0000000000000..86d86bd153036 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/DIU_vga_registers.h @@ -0,0 +1,771 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +typedef union _REG_ARX //Attribute_Controller_Index_Register +{ + struct + { + CBIOS_U8 Attribute_Address :5; + CBIOS_U8 Enable_Video_Display_via_Palette :1; + CBIOS_U8 RESERVED :2; + }; + CBIOS_U8 Value; +}REG_ARX; + + +typedef union _REG_ARD //Attribute_Controller_Data_Read_Register +{ + struct + { + CBIOS_U8 Attribute_Data :8; + }; + CBIOS_U8 Value; +}REG_ARD; + + +typedef union _REG_AR00_AR0F //Palette_Registers_0-15 +{ + struct + { + CBIOS_U8 Palette_Color_Primary_RGB :3; + CBIOS_U8 Palette_Color__SR__SGI_SBV :3; + CBIOS_U8 RESERVED :2; + }; + CBIOS_U8 Value; +}REG_AR00_AR0F; + + +typedef union _REG_AR10 //Atrribute_Mode_Control_Register +{ + struct + { + CBIOS_U8 Attribute_Control_Mode :1; + CBIOS_U8 Monochrome_Attributes :1; + CBIOS_U8 Enable_Line_Graphics :1; + CBIOS_U8 Enable_Blinking :1; + CBIOS_U8 RESERVED :1; + CBIOS_U8 Enable_Top_Panning :1; + CBIOS_U8 Select_256_Color :1; + CBIOS_U8 Select_Pixel_Padding :1; + }; + CBIOS_U8 Value; +}REG_AR10; + + +typedef union _REG_AR11 //Border_Color_Register +{ + struct + { + CBIOS_U8 Border_Color :8; + }; + CBIOS_U8 Value; +}REG_AR11; + + +typedef union _REG_AR12 //Color_Plane_Enable_Register +{ + struct + { + CBIOS_U8 Display_Plane_Enable :4; + CBIOS_U8 Video_Test_Select :2; + CBIOS_U8 RESERVED :2; + }; + CBIOS_U8 Value; +}REG_AR12; + + +typedef union _REG_AR13 //Horizontal_Pixel_Panning_Register +{ + struct + { + CBIOS_U8 Number_of_Pixel_Pan_Shift_Left :4; + CBIOS_U8 RESERVED :4; + }; + CBIOS_U8 Value; +}REG_AR13; + + +typedef union _REG_AR14 //Pixel_Padding_Register +{ + struct + { + CBIOS_U8 Pixel_Padding_V5_V4 :2; + CBIOS_U8 Pixel_Padding_V7_V6 :2; + CBIOS_U8 RESERVED :4; + }; + CBIOS_U8 Value; +}REG_AR14; + + +typedef union _REG_VGA_STATUS_0 //Input_Status_0_Register_(Read_Only) +{ + struct + { + CBIOS_U8 RESERVED :4; + CBIOS_U8 DAC1_B_Sense :1; + CBIOS_U8 DAC1_G_Sense :1; + CBIOS_U8 DAC1_R_Sense :1; + CBIOS_U8 CRT_Vert_Retrace_Interrupt_Status :1; + }; + CBIOS_U8 Value; +}REG_VGA_STATUS_0; + + +typedef union _REG_VGA_ENABLE //VGA_Display_Enable_Register +{ + struct + { + CBIOS_U8 Chip_Enable :1; + CBIOS_U8 RESERVED :7; + }; + CBIOS_U8 Value; +}REG_VGA_ENABLE; + + +typedef union _REG_SRX //Sequencer_Index_Register +{ + struct + { + CBIOS_U8 Sequencer_Address_Index :8; + }; + CBIOS_U8 Value; +}REG_SRX; + + +typedef union _REG_SRD //Sequencer_Data_Register +{ + struct + { + CBIOS_U8 Sequencer_Register_Data :8; + }; + CBIOS_U8 Value; +}REG_SRD; + + +typedef union _REG_SR00 //Reset_Register +{ + struct + { + CBIOS_U8 RESERVED_0 :1; + CBIOS_U8 RESERVED_1 :1; + CBIOS_U8 RESERVED_2 :6; + }; + CBIOS_U8 Value; +}REG_SR00; + + +typedef union _REG_SR01 //Clocking_Mode_Register +{ + struct + { + CBIOS_U8 RESERVED_0 :1; + CBIOS_U8 RESERVED_1 :1; + CBIOS_U8 RESERVED_2 :1; + CBIOS_U8 RESERVED_3 :1; + CBIOS_U8 RESERVED_4 :1; + CBIOS_U8 Screen_Off :1; + CBIOS_U8 RESERVED_5 :2; + }; + CBIOS_U8 Value; +}REG_SR01; + + +typedef union _REG_SR02 //Enable_Write_Plane_Register +{ + struct + { + CBIOS_U8 Enable_Write_to_Plane :4; + CBIOS_U8 RESERVED :4; + }; + CBIOS_U8 Value; +}REG_SR02; + + +typedef union _REG_SR03 //Character_Font_Select_Register +{ + struct + { + CBIOS_U8 Reserved_0 :2; + CBIOS_U8 Reserved_1 :2; + CBIOS_U8 Reserved_2 :1; + CBIOS_U8 Reserved_3 :1; + CBIOS_U8 RESERVED :2; + }; + CBIOS_U8 Value; +}REG_SR03; + + +typedef union _REG_SR04 //Memory_Mode_Control_Register +{ + struct + { + CBIOS_U8 RESERVED_0 :1; + CBIOS_U8 Extended_Memory_Access :1; + CBIOS_U8 Sequential_Addressing_Mode :1; + CBIOS_U8 Chain_4_Mode_Select :1; + CBIOS_U8 RESERVED_1 :4; + }; + CBIOS_U8 Value; +}REG_SR04; + + +typedef union _REG_DAC_Mask //DAC_Mask_Register +{ + struct + { + CBIOS_U8 DAC_Address_Mask :8; + }; + CBIOS_U8 Value; +}REG_DAC_Mask; + + +typedef union _REG_DAC_Read_Index //DAC_Read_Index_Register +{ + struct + { + CBIOS_U8 DAC_Read_Address :8; + }; + CBIOS_U8 Value; +}REG_DAC_Read_Index; + + +typedef union _REG_DAC_Status //DAC_Read_Status_Register +{ + struct + { + CBIOS_U8 DAC_Status :2; + CBIOS_U8 RESERVED :6; + }; + CBIOS_U8 Value; +}REG_DAC_Status; + + +typedef union _REG_DAC_Write_Index //DAC_Write_Index_Register +{ + struct + { + CBIOS_U8 DAC_Write_Address :8; + }; + CBIOS_U8 Value; +}REG_DAC_Write_Index; + + +typedef union _REG_DAC_Data //RAMDAC_Data_Register +{ + struct + { + CBIOS_U8 DAC_Read_Write_Data :8; + }; + CBIOS_U8 Value; +}REG_DAC_Data; + + +typedef union _REG_VGA_FCR_AD //Feature_Control_Read_Register +{ + struct + { + CBIOS_U8 RESERVED_0 :3; + CBIOS_U8 Vertical_Sync_Type :1; + CBIOS_U8 RESERVED_1 :4; + }; + CBIOS_U8 Value; +}REG_VGA_FCR_AD; + + +typedef union _REG_VGA_MISC_Read //Miscellaneous_Output_Register_(Read_Only) +{ + struct + { + CBIOS_U8 IO_Address_Select :1; + CBIOS_U8 Enable_RAM :1; + CBIOS_U8 Clock_Select :2; + CBIOS_U8 RESERVED :1; + CBIOS_U8 Page_Select :1; + CBIOS_U8 Sync_Polarity_Vertical_Size :2; + }; + CBIOS_U8 Value; +}REG_VGA_MISC_Read; + + +typedef union _REG_GRX //Graphics_Controller_Index_Register +{ + struct + { + CBIOS_U8 Graphics_Controller_Address_Index :4; + CBIOS_U8 RESERVED :4; + }; + CBIOS_U8 Value; +}REG_GRX; + + +typedef union _REG_GRD //Graphics_Controller_Data_Register +{ + struct + { + CBIOS_U8 Graphics_Controller_Data :8; + }; + CBIOS_U8 Value; +}REG_GRD; + + +typedef union _REG_GR00 //Graphics_Controller_Set/Reset_Data_Register +{ + struct + { + CBIOS_U8 Set_Reset_Data :4; + CBIOS_U8 RESERVED :4; + }; + CBIOS_U8 Value; +}REG_GR00; + + +typedef union _REG_GR01 //Graphics_Controller_Enable_Set/Reset_Data_Register +{ + struct + { + CBIOS_U8 Enable_Set_Reset_Data :4; + CBIOS_U8 RESERVED :4; + }; + CBIOS_U8 Value; +}REG_GR01; + + +typedef union _REG_GR02 //Color_Compare_Register +{ + struct + { + CBIOS_U8 Color_Compare_Data :4; + CBIOS_U8 RESERVED :4; + }; + CBIOS_U8 Value; +}REG_GR02; + + +typedef union _REG_GR03 //Raster_Operation/Rotate_Count_Register +{ + struct + { + CBIOS_U8 Rotate_Count :3; + CBIOS_U8 Raster_Operation_Select :2; + CBIOS_U8 RESERVED :3; + }; + CBIOS_U8 Value; +}REG_GR03; + + +typedef union _REG_GR04 //Read_Plane_Select_Register +{ + struct + { + CBIOS_U8 Read_Plane_Select :2; + CBIOS_U8 RESERVED :6; + }; + CBIOS_U8 Value; +}REG_GR04; + + +typedef union _REG_GR06 //Memory_Map_Mode_Control_Register +{ + struct + { + CBIOS_U8 Select_Addressing_Mode :1; + CBIOS_U8 Chain_Odd_Even :1; + CBIOS_U8 Memory_Map_Mode :2; + CBIOS_U8 RESERVED :4; + }; + CBIOS_U8 Value; +}REG_GR06; + + +typedef union _REG_GR07 //Color_Don't_Care_Register +{ + struct + { + CBIOS_U8 Compare_Plane_Select :4; + CBIOS_U8 RESERVED :4; + }; + CBIOS_U8 Value; +}REG_GR07; + + +typedef union _REG_GR08 //Bit_Mask_Register +{ + struct + { + CBIOS_U8 Bit_Mask :8; + }; + CBIOS_U8 Value; +}REG_GR08; + + +typedef union _REG_CRX //CRT_Controller_Index_Register +{ + struct + { + CBIOS_U8 CRTC_Address_Index :8; + }; + CBIOS_U8 Value; +}REG_CRX; + + +typedef union _REG_CRD //CRT_Controller_Data_Register +{ + struct + { + CBIOS_U8 CRTC_Data :8; + }; + CBIOS_U8 Value; +}REG_CRD; + + +typedef union _REG_CR00_Pair //Horizontal_Total_Register_Pair +{ + struct + { + CBIOS_U8 Horizontal_Total_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR00_Pair; + + +typedef union _REG_CR01_Pair //Horizontal_Display_End_Register_Pair +{ + struct + { + CBIOS_U8 Horizontal_Display_End_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR01_Pair; + + +typedef union _REG_CR02_Pair //Start_Horizontal_Blank_Register_Pair +{ + struct + { + CBIOS_U8 Start_Horizontal_Blank_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR02_Pair; + + +typedef union _REG_CR03_Pair //End_Horizontal_Blank_Register_Pair +{ + struct + { + CBIOS_U8 End_Horizontal_Blank_9to5 :5; + CBIOS_U8 Display_Enable_Skew :2; + CBIOS_U8 RESERVED :1; + }; + CBIOS_U8 Value; +}REG_CR03_Pair; + + +typedef union _REG_CR04_Pair //Start_Horizontal_Sync_Position_Register_Pair +{ + struct + { + CBIOS_U8 Start_Horizontal_Sync_Position_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR04_Pair; + + +typedef union _REG_CR05_Pair //End_Horizontal_Sync_Position_Register_Pair +{ + struct + { + CBIOS_U8 End_Horizontal_Sync_Position_4to0 :5; + CBIOS_U8 HSYNC_Signal_Delay_Skew :2; + CBIOS_U8 End_Horizontal_Blank_bit_10 :1; + }; + CBIOS_U8 Value; +}REG_CR05_Pair; + + +typedef union _REG_CR06_Pair //Vertical_Total_Register_Pair +{ + struct + { + CBIOS_U8 Vertical_Total_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR06_Pair; + + +typedef union _REG_CR07_Pair //CRTC_Overflow_Register_Pair +{ + struct + { + CBIOS_U8 Vertical_Total_bit_8 :1; + CBIOS_U8 Vertical_Display_End_bit_8 :1; + CBIOS_U8 Vertical_Retrace_Start_bit_8 :1; + CBIOS_U8 Start_Vertical_Blank_bit_8 :1; + CBIOS_U8 Line_Compare_bit_8 :1; + CBIOS_U8 Vertical_Total_bit_9 :1; + CBIOS_U8 Vertical_Display_End_bit_9 :1; + CBIOS_U8 Vertical_Retrace_Start_bit_9 :1; + }; + CBIOS_U8 Value; +}REG_CR07_Pair; + + +typedef union _REG_CR08_Pair //Preset_Row_Scan_Register_Pair +{ + struct + { + CBIOS_U8 Preset_Row_Scan_Count :5; + CBIOS_U8 Byte_Pan :2; + CBIOS_U8 RESERVED :1; + }; + CBIOS_U8 Value; +}REG_CR08_Pair; + + +typedef union _REG_CR09_Pair //Maximum_Scan_Line_Register_Pair +{ + struct + { + CBIOS_U8 Reserved :5; + CBIOS_U8 Start_Vertical_Blank_bit_9 :1; + CBIOS_U8 Line_Compare_bit_9 :1; + CBIOS_U8 Double_Scan :1; + }; + CBIOS_U8 Value; +}REG_CR09_Pair; + + +typedef union _REG_CR0A_Pair //Text_Cursor_Start_Scan_Line_Register_Pair +{ + struct + { + CBIOS_U8 Reserved :5; + CBIOS_U8 Text_Cursor_Off :1; + CBIOS_U8 RESERVED :2; + }; + CBIOS_U8 Value; +}REG_CR0A_Pair; + + +typedef union _REG_CR0B_Pair //Text_Cursor_End_Scan_Line_Register_Pair +{ + struct + { + CBIOS_U8 Reserved :5; + CBIOS_U8 Text_Cursor_Signal_Delay_Skew :2; + CBIOS_U8 RESERVED :1; + }; + CBIOS_U8 Value; +}REG_CR0B_Pair; + + +typedef union _REG_CR0C_Pair //Start_Address_High_Register_Pair +{ + struct + { + CBIOS_U8 Display_Start_Address_15to8 :8; + }; + CBIOS_U8 Value; +}REG_CR0C_Pair; + + +typedef union _REG_CR0D_Pair //Start_Address_Low_Register_Pair +{ + struct + { + CBIOS_U8 Display_Start_Address__7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR0D_Pair; + + +typedef union _REG_CR0E_Pair //Cursor_Location_Address_High_Register_Pair +{ + struct + { + CBIOS_U8 Reserved :8; + }; + CBIOS_U8 Value; +}REG_CR0E_Pair; + + +typedef union _REG_CR0F_Pair //Cursor_Location_Address_Low_Register_Pair +{ + struct + { + CBIOS_U8 Reserved :8; + }; + CBIOS_U8 Value; +}REG_CR0F_Pair; + + +typedef union _REG_CR10_Pair //Vertical_Retrace_Start_Register_Pair +{ + struct + { + CBIOS_U8 Vertical_Retrace_Start_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR10_Pair; + + +typedef union _REG_CR11_Pair //Vertical_Retrace_End_Register_Pair +{ + struct + { + CBIOS_U8 Vertical_Retrace_End_3to0 :4; + CBIOS_U8 Clear_Vertical_Retrace_Interrupt :1; + CBIOS_U8 Disable_Vertical_Interrupt :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 Lock_Writes_to_CR00_to_CR07 :1; + }; + CBIOS_U8 Value; +}REG_CR11_Pair; + + +typedef union _REG_CR12_Pair //Vertical_Display_End_Register_Pair +{ + struct + { + CBIOS_U8 Vertical_Display_End_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR12_Pair; + + +typedef union _REG_CR13_Pair //Screen_Offset_Register_Pair +{ + struct + { + CBIOS_U8 Logical_Screen_Width_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR13_Pair; + + +typedef union _REG_CR14_Pair //Underline_Location_Register_Pair +{ + struct + { + CBIOS_U8 Reserved :5; + CBIOS_U8 Count_by_4_Mode :1; + CBIOS_U8 DoubleWord_Addressing :1; + CBIOS_U8 RESERVED :1; + }; + CBIOS_U8 Value; +}REG_CR14_Pair; + + +typedef union _REG_CR15_Pair //Start_Vertical_Blank_Register_Pair +{ + struct + { + CBIOS_U8 Start_Vertical_Blank_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR15_Pair; + + +typedef union _REG_CR16_Pair //End_Vertical_Blank_Register_Pair +{ + struct + { + CBIOS_U8 End_Vertical_Blank_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR16_Pair; + + +typedef union _REG_CR17_Pair //CRTC_Mode_Control_Register_Pair +{ + struct + { + CBIOS_U8 Reserved_0 :1; + CBIOS_U8 Reserved_1 :1; + CBIOS_U8 Vertical_Total_Double_Mode :1; + CBIOS_U8 Reserved_2 :1; + CBIOS_U8 RESERVED :1; + CBIOS_U8 Reserved_3 :1; + CBIOS_U8 Reserved_4 :1; + CBIOS_U8 Hardware_Reset :1; + }; + CBIOS_U8 Value; +}REG_CR17_Pair; + + +typedef union _REG_CR18_Pair //Line_Compare_Register_Pair +{ + struct + { + CBIOS_U8 Line_Compare_7to0 :8; + }; + CBIOS_U8 Value; +}REG_CR18_Pair; + + +typedef union _REG_CR19 //Attribute_Controller_Alternate_Register +{ + struct + { + CBIOS_U8 I_O_Address_Select :1; + CBIOS_U8 Enable_Display_Memory_Access_from_CPU :1; + CBIOS_U8 Clock_Select :1; + CBIOS_U8 Reserved :1; + CBIOS_U8 Vertical_Sync_Type :1; + CBIOS_U8 Page_Select :1; + CBIOS_U8 Sync_Polarity_and_Vertical_Size :2; + }; + CBIOS_U8 Value; +}REG_CR19; + + +typedef union _REG_CR1A //Attribute_Controller_Alternate_Register +{ + struct + { + CBIOS_U8 Display_Mode_Inactive :1; + CBIOS_U8 Reserved_0 :2; + CBIOS_U8 Vertical_Sync_Active :1; + CBIOS_U8 Reserved_1 :3; + CBIOS_U8 CRT_Vertical_Retrace_Interrupt_Status :1; + }; + CBIOS_U8 Value; +}REG_CR1A; + + +typedef union _REG_CR26 //Attribute_Controller_Alternate_Register +{ + struct + { + CBIOS_U8 RESERVED :8; + }; + CBIOS_U8 Value; +}REG_CR26; + + +typedef union _REG_VGA_STATUS_1 //Input_Status_1_Read_Register +{ + struct + { + CBIOS_U8 Display_Mode_Inactive :1; + CBIOS_U8 RESERVED_0 :1; + CBIOS_U8 RESERVED_1 :1; + CBIOS_U8 Vert_Sync_Active :1; + CBIOS_U8 Video_Signal_Test_bits_1to0 :2; + CBIOS_U8 RESERVED_2 :2; + }; + CBIOS_U8 Value; +}REG_VGA_STATUS_1; + + diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/Monitor/CBiosDPCDRegister.h b/drivers/gpu/drm/arise/cbios/Hw/Register/Monitor/CBiosDPCDRegister.h new file mode 100644 index 0000000000000..9694aa22f9c09 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/Monitor/CBiosDPCDRegister.h @@ -0,0 +1,660 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** DPCD(DP Configuration Data) register definition. +** For detailed register definition, please refer to DP1.2 spec in sector 2.9.3.1 +******************************************************************************/ + +#ifndef _CBIOS_DPCD_REGISTER_H_ +#define _CBIOS_DPCD_REGISTER_H_ + +typedef union _DPCD_REG_00000 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Minor_Rev_Num :4; + CBIOS_U8 Major_Rev_Num :4; + }; +}DPCD_REG_00000; + +typedef union _DPCD_REG_00001 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 MAX_LINK_RATE :8; // 0x06: 1.62Gbps per lane + // 0x0A: 2.7 Gbps per lane + // 0x14: 5.4 Gbps per lane + }; +}DPCD_REG_00001; + +typedef union _DPCD_REG_00002 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 MAX_LANE_COUNT :5; + CBIOS_U8 Reserved0 :1; + CBIOS_U8 TPS3_SUPPORTED :1; // For DPCD Rev.1.2 + CBIOS_U8 ENHANCED_FRAME_CAP :1; // For DPCD Rev.1.1 + }; +}DPCD_REG_00002; + +typedef union _DPCD_REG_00003 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 MAX_DOWNSPREAD :1; + CBIOS_U8 Reserved0 :5; + CBIOS_U8 NO_AUX_HANDSHAKE_LINK_TRAINING :1; // For DPCD Rev.1.1 + CBIOS_U8 Reserved1 :1; + }; +}DPCD_REG_00003; + +typedef union _DPCD_REG_00004 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 NORP :1; // Number of Receiver Ports = Value + 1 + CBIOS_U8 Reserved0 :4; + CBIOS_U8 DP_PWR_CAP_5V :1; // For DPCD Rev 1.2 + CBIOS_U8 DP_PWR_CAP_12V :1; // For DPCD Rev 1.2 + CBIOS_U8 DP_PWR_CAP_18V :1; // For DPCD Rev 1.2 + }; +}DPCD_REG_00004; + +typedef union _DPCD_REG_00005 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DWN_STRM_PORT_PRESENT :1; + CBIOS_U8 DWN_STRM_PORT_TYPE :2; // 0 = DisplayPort + // 1 = Analog VGA or analog video over DVI-I + // 2 = DVI, HDMI or DP++ + // 3 = Others (This Downstream port type will have no EDID in the Sink device) + CBIOS_U8 FORMAT_CONVERSION :1; // For DPCD Rev 1.1 + CBIOS_U8 DETAILED_CAP_INFO_AVAILABLE :1; // For DPCD Rev 1.1 + CBIOS_U8 Reserved0 :3; // For DPCD Rev 1.1 + }; +}DPCD_REG_00005; + +typedef union _DPCD_REG_00007 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 DWN_STRM_PORT_COUNT :4; // For DPCD Rev 1.1 + CBIOS_U8 Reserved0 :2; // For DPCD Rev 1.1 + CBIOS_U8 MSA_TIMING_PAR_IGNORED :1; // For DPCD Rev 1.1 + CBIOS_U8 OUI_Support :1; // For DPCD Rev 1.1 + }; +}DPCD_REG_00007; + +typedef union _DPCD_REG_0000D // eDP_CONFIGURATION_CAP +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 ALTERNATE_SCRAMBLER_RESET_CAPABLE :1; // A setting of 1 indicates that this is an eDP device that can use + // the eDP alternate scrambler reset value of FFFEh. + CBIOS_U8 FRAMING_CHANGE_CAPABLE :1; // A setting of 1 indicates that this is an eDP device that uses only + // Enhanced Framing, independently of the setting by the source of + // ENHANCED_FRAME_EN + CBIOS_U8 Reserved0 :6; + }; +}DPCD_REG_0000D; + +typedef union _DPCD_REG_0000E //From DP1.3, bit 7 is used to identify extended capability present +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TRAINING_AUX_RD_INTERVAL :7; // 0x00: 100us + // 0x01: 4 ms + // 0x02: 8 ms + // 0x03: 12 ms + // 0x04: 16 ms + CBIOS_U8 EXTENDED_RECEIVER_CAPABILITY_FIELD_PRESENT :1; + //0 = Not present. 1 = Present at DPCD Addresses 02200h through 022FFh. + //A DPRX with DPCD Rev. 1.4 (or higher) must have an Extended Receiver Capability field. + }; +}DPCD_REG_0000E; + +typedef union _DPCD_REG_00100 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 LINK_BW_SET :8; + }; +}DPCD_REG_00100; + +typedef union _DPCD_REG_00101 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 LANE_COUNT_SET :5; + CBIOS_U8 Reserved0 :2; + CBIOS_U8 ENHANCED_FRAME_EN :1; + }; +}DPCD_REG_00101; + +typedef union _DPCD_REG_00102 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TRAINING_PATTERN_SELECT :2; // 0: Training not in progress (or disabled) + // 1: Training Pattern 1 + // 2: Training Pattern 2 + // 3: Training Pattern 3 + CBIOS_U8 LINK_QUAL_PATTERN_SET :2; // 0: Link quality test pattern not transmitted + // 1: D10.2 test pattern (unscrambled) transmitted (same as Training Pattern 1) + // 2: Symbol Error Rate measurement pattern transmitted + // 3: PRBS7 transmitted + CBIOS_U8 RECOVERED_CLOCK_OUT_EN :1; + CBIOS_U8 SCRAMBLING_DISABLE :1; + CBIOS_U8 SYMBOL_ERROR_COUNT_SEL :2; // 0: Disparity error and Illegal Symbol error + // 1: Disparity error + // 2: Illegal symbol error + // 3: RESERVED + }; +}DPCD_REG_00102; + +// 00103, 00104, 00105, 00106 +typedef union _DPCD_REG_00103 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VOLTAGE_SWING_SET :2; // 0: Voltage swing level 0 + // 1: Voltage swing level 1 + // 2: Voltage swing level 2 + // 3: Voltage swing level 3 + CBIOS_U8 MAX_SWING_REACHED :1; + CBIOS_U8 PRE_EMPHASIS_SET :2; // 0: Pre-emphasis level 0 + // 1: Pre-emphasis level 1 + // 2: Pre-emphasis level 2 + // 3: Pre-emphasis level 3 + CBIOS_U8 MAX_PRE_EMPHASIS_REACHED :1; + CBIOS_U8 Reserved0 :2; + }; +}DPCD_REG_00103; + +typedef union _DPCD_REG_0010A +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 ALTERNATE_SCRAMBER_RESET_ENABLE :1; + CBIOS_U8 FRAMING_CHANGE_ENABLE :1; + CBIOS_U8 Reserved0 :5; + CBIOS_U8 PANEL_SELF_TEST_ENABLE :1; + }; +}DPCD_REG_0010A; + +// 0010B, 0010C, 0010D, 0010E +typedef union _DPCD_REG_0010B +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 LINK_QUAL_PATTERN_SET :3; // 0: Link quality test pattern not transmitted + // 1: D10.2 test pattern (unscrambled) transmitted (same as Training Pattern 1) + // 2: Symbol Error Rate measurement pattern transmitted + // 3: PRBS7 transmitted + // 4: 80 bit custom pattern transmitted + // 5: HBR2 Compliance EYE pattern transmitted + CBIOS_U8 Reserved0 :5; + }; +}DPCD_REG_0010B; + +// 0010F, 00110 +typedef union _DPCD_REG_0010F +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 LANE0_POST_CURSOR2_SET :2; // 0: Training Pattern 2 or 3 with post cursor2 level 0 + // 1: Training Pattern 2 or 3 with post cursor2 level 1 + // 2: Training Pattern 2 or 3 with post cursor2 level 2 + // 3: Training Pattern 2 or 3 with post cursor2 level 3 + CBIOS_U8 Lane0_MAX_POST_CURSOR2_REACHED :1; + CBIOS_U8 Reserved0 :1; + CBIOS_U8 LANE1_POST_CURSOR2_SET :2; // 0: Training Pattern 2 or 3 with post cursor2 level 0 + // 1: Training Pattern 2 or 3 with post cursor2 level 1 + // 2: Training Pattern 2 or 3 with post cursor2 level 2 + // 3: Training Pattern 2 or 3 with post cursor2 level 3 + CBIOS_U8 Lane1_MAX_POST_CURSOR2_REACHED :1; + CBIOS_U8 Reserved1 :1; + }; +}DPCD_REG_0010F; + +typedef union _DPCD_REG_00200 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SINK_COUNT_5_0 :6; // Bits 5:0 + CBIOS_U8 CP_READY :1; + CBIOS_U8 SINK_COUNT_6 :1; // Bits 6 + }; +}DPCD_REG_00200; + +typedef union _DPCD_REG_00201 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 REMOTE_CONTROL_COMMAND_PENDING :1; + CBIOS_U8 AUTOMATED_TEST_REQUEST :1; + CBIOS_U8 CP_IRQ :1; + CBIOS_U8 MCCS_IRQ :1; + CBIOS_U8 DOWN_REP_MSG_RDY :1; + CBIOS_U8 UP_REQ_MSG_RDY :1; + CBIOS_U8 SINK_SPECIFIC_IRQ :1; + CBIOS_U8 Reserved0 :1; + }; +}DPCD_REG_00201; + +typedef union _DPCD_REG_00202 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 LANE0_CR_DONE :1; + CBIOS_U8 LANE0_CHANNEL_EQ_DONE :1; + CBIOS_U8 LANE0_SYMBOL_LOCKED :1; + CBIOS_U8 Reserved0 :1; + CBIOS_U8 LANE1_CR_DONE :1; + CBIOS_U8 LANE1_CHANNEL_EQ_DONE :1; + CBIOS_U8 LANE1_SYMBOL_LOCKED :1; + CBIOS_U8 Reserved1 :1; + }; +}DPCD_REG_00202; + +typedef union _DPCD_REG_00203 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 LANE2_CR_DONE :1; + CBIOS_U8 LANE2_CHANNEL_EQ_DONE :1; + CBIOS_U8 LANE2_SYMBOL_LOCKED :1; + CBIOS_U8 Reserved0 :1; + CBIOS_U8 LANE3_CR_DONE :1; + CBIOS_U8 LANE3_CHANNEL_EQ_DONE :1; + CBIOS_U8 LANE3_SYMBOL_LOCKED :1; + CBIOS_U8 Reserved1 :1; + }; +}DPCD_REG_00203; + +typedef union _DPCD_REG_00204 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 INTERLANE_ALIGN_DONE :1; + CBIOS_U8 Reserved0 :5; + CBIOS_U8 DOWNSTREAM_PORT_STATUS_CHANGED :1; + CBIOS_U8 LINK_STATUS_UPDATED :1; + }; +}DPCD_REG_00204; + +typedef union _DPCD_REG_00205 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 RECEIVE_PORT_0_STATUS :1; // 0: SINK out of synchronization + // 1: SINK in synchronization + CBIOS_U8 RECEIVE_PORT_1_STATUS :1; + CBIOS_U8 Reserved0 :6; + }; +}DPCD_REG_00205; + +typedef union _DPCD_REG_00206 // ADJUST_REQUEST_LANE0_1 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VOLTAGE_SWING_LANE0 :2; + CBIOS_U8 PRE_EMPHASIS_LANE0 :2; + CBIOS_U8 VOLTAGE_SWING_LANE1 :2; + CBIOS_U8 PRE_EMPHASIS_LANE1 :2; + }; +}DPCD_REG_00206; + +typedef union _DPCD_REG_00207 // ADJUST_REQUEST_LANE2_3 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 VOLTAGE_SWING_LANE2 :2; + CBIOS_U8 PRE_EMPHASIS_LANE2 :2; + CBIOS_U8 VOLTAGE_SWING_LANE3 :2; + CBIOS_U8 PRE_EMPHASIS_LANE3 :2; + }; +}DPCD_REG_00207; + +typedef union _DPCD_REG_0020C // ADJUST_REQUEST_POST_CURSOR2 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 POST_CURSOR2_LANE0 :2; + CBIOS_U8 POST_CURSOR2_LANE1 :2; + CBIOS_U8 POST_CURSOR2_LANE2 :2; + CBIOS_U8 POST_CURSOR2_LANE3 :2; + }; +}DPCD_REG_0020C; + +typedef union _DPCD_REG_00210 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Error_Count_Bits_7_0 :8; + }; +}DPCD_REG_00210; + +typedef union _DPCD_REG_00211 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 Error_Count_Bits_14_8 :7; + CBIOS_U8 Error_Count_Valid :1; + }; +}DPCD_REG_00211; + +typedef union _DPCD_REG_00218 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_LINK_TRAINING :1; + CBIOS_U8 TEST_PATTERN :1; + CBIOS_U8 TEST_EDID_READ :1; + CBIOS_U8 PHY_TEST_PATTERN :1; // For DPCD version 1.1 + CBIOS_U8 FAUX_TEST_PATTERN :1; // For DPCD Version 1.2 + CBIOS_U8 Reserved0 :3; + }; +}DPCD_REG_00218; + +typedef union _DPCD_REG_00219 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_LINK_RATE :8; + }; +}DPCD_REG_00219; + +typedef union _DPCD_REG_00220 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_LANE_COUNT :5; + CBIOS_U8 Reserved0 :3; + }; +}DPCD_REG_00220; + +typedef union _DPCD_REG_00221 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_PATTERN :8; // 00h = No test pattern transmitted + // 01h = color ramps + // 02h = black and white vertical lines + // 03h = color square + }; +}DPCD_REG_00221; + +typedef union _DPCD_REG_00222 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_H_TOTAL_15_8 :8; + }; +}DPCD_REG_00222; + +typedef union _DPCD_REG_00223 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_H_TOTAL_7_0 :8; + }; +}DPCD_REG_00223; + +typedef union _DPCD_REG_00224 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_V_TOTAL_15_8 :8; + }; +}DPCD_REG_00224; + +typedef union _DPCD_REG_00225 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_V_TOTAL_7_0 :8; + }; +}DPCD_REG_00225; + +typedef union _DPCD_REG_00226 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_H_START_15_8 :8; + }; +}DPCD_REG_00226; + +typedef union _DPCD_REG_00227 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_H_START_7_0 :8; + }; +}DPCD_REG_00227; + +typedef union _DPCD_REG_00228 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_V_START_15_8 :8; + }; +}DPCD_REG_00228; + +typedef union _DPCD_REG_00229 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_V_START_7_0 :8; + }; +}DPCD_REG_00229; + +typedef union _DPCD_REG_0022A +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_HSYNC_WIDTH_14_8 :7; + CBIOS_U8 TEST_HSYNC_POLARITY :1; + }; +}DPCD_REG_0022A; + +typedef union _DPCD_REG_0022B +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_HSYNC_WIDTH_7_0 :8; + }; +}DPCD_REG_0022B; + +typedef union _DPCD_REG_0022C +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_VSYNC_WIDTH_14_8 :7; + CBIOS_U8 TEST_VSYNC_POLARITY :1; + }; +}DPCD_REG_0022C; + +typedef union _DPCD_REG_0022D +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_VSYNC_WIDTH_7_0 :8; + }; +}DPCD_REG_0022D; + +typedef union _DPCD_REG_0022E +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_H_WIDTH_15_8 :8; + }; +}DPCD_REG_0022E; + +typedef union _DPCD_REG_0022F +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_H_WIDTH_7_0 :8; + }; +}DPCD_REG_0022F; + +typedef union _DPCD_REG_00230 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_V_WIDTH_15_8 :8; + }; +}DPCD_REG_00230; + +typedef union _DPCD_REG_00231 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_V_WIDTH_7_0 :8; + }; +}DPCD_REG_00231; + +typedef union _DPCD_REG_00232 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_SYNCHRONOUS_CLOCK :1; // 0 = Link clock and stream clock asynchronous + // 1 = Link clock and stream clock synchronous + CBIOS_U8 TEST_COLOR_FORMAT :2; // 00 = RGB + // 01 = YCbCr 4:2:2 + // 10 = YCbCr 4:4:4 + CBIOS_U8 TEST_DYNAMIC_RANGE :1; // 0 = VESA range (from 0 to the maximum) + // 1 = CEA range (as defined in CEA-861C Section 5) + CBIOS_U8 TEST_YCBCR_COEFFICIENTS :1; + CBIOS_U8 TEST_BIT_DEPTH :3; // 000 = 6 bits + // 001 = 8 bits + // 010 = 10 bits + // 011 = 12 bits + // 100 = 16 bits + }; +}DPCD_REG_00232; + +typedef union _DPCD_REG_00233 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_REFRESH_DENOMINATOR :1; + CBIOS_U8 TEST_INTERLACED :1; + CBIOS_U8 Reserved0 :6; + }; +}DPCD_REG_00233; + +typedef union _DPCD_REG_00234 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_REFRESH_RATE_NUMERATOR :8; + }; +}DPCD_REG_00234; + +typedef union _DPCD_REG_00260 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_ACK :1; + CBIOS_U8 TEST_NACK :1; + CBIOS_U8 TEST_EDID_CHECKSUM_WRITE :1; + CBIOS_U8 Reserved0 :5; + }; +}DPCD_REG_00260; + +typedef union _DPCD_REG_00261 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 TEST_EDID_CHECKSUM :8; + }; +}DPCD_REG_00261; + +typedef union _DPCD_REG_00600 +{ + CBIOS_U8 Value; + struct + { + CBIOS_U8 SET_POWER :3; // 1: Set local sink and all downstream sinks to D0 (normal operation mode) + // 2: Set local sink and all downstream sinks to D3 (power down mode) + // 5: Set main link for local sink and all downstream sinks to D3 (power down mode), + // keep AUX block fully powered, ready to reply within a Response Time-Out period + // of 300µs to Manchester transactions and FAUX Power State 1 or 2 (if FAUX supported) + CBIOS_U8 Reserved0 :2; + CBIOS_U8 SET_DN_DEVICE_DP_PWR_5V :1; + CBIOS_U8 SET_DN_DEVICE_DP_PWR_12V :1; + CBIOS_U8 SET_DN_DEVICE_DP_PWR_18V :1; + }; +}DPCD_REG_00600; + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Hw/Register/pmu_registers.h b/drivers/gpu/drm/arise/cbios/Hw/Register/pmu_registers.h new file mode 100644 index 0000000000000..260fe344dba70 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Hw/Register/pmu_registers.h @@ -0,0 +1,249 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +#ifndef _PMU_REGISTER_H_ +#define _PMU_REGISTER_H_ + + +typedef union _REG_PMU_C6C0 +{ + struct + { + CBIOS_U32 DIU_BIU_DVO_INT :1; + CBIOS_U32 DIU_BIU_HDMIIN5V_INT :1; + CBIOS_U32 DP1_INT :1; + CBIOS_U32 DP2_INT :1; + CBIOS_U32 CEC1_INT :1; + CBIOS_U32 CEC2_INT :1; + CBIOS_U32 RESERVED :26; + }; + CBIOS_U32 Value; +}REG_PMU_C6C0; + +typedef union _REG_PMU_C6C4 +{ + struct + { + CBIOS_U32 DIU_BIU_DVO_INT_CLR :1; + CBIOS_U32 DIU_BIU_HDMIIN5V_INT_CLR :1; + CBIOS_U32 DP1_INT_CLR :1; + CBIOS_U32 DP2_INT_CLR :1; + CBIOS_U32 CEC1_INT_CLR :1; + CBIOS_U32 CEC2_INT_CLR :1; + CBIOS_U32 RESERVED :26; + }; + CBIOS_U32 Value; +}REG_PMU_C6C4; + +typedef union _REG_PMU_C6C8 +{ + struct + { + CBIOS_U32 DP_INT_MODE :1; + CBIOS_U32 Reserved :31; + }; + CBIOS_U32 Value; +}REG_PMU_C6C8; + +typedef union _REG_PMU_C6CC +{ + struct + { + CBIOS_U32 DIU_BIU_DVO_INT_FE :1; + CBIOS_U32 DIU_BIU_DVO_INT_RE :1; + CBIOS_U32 DIU_BIU_HDMIIN5V_INT_FE :1; + CBIOS_U32 DIU_BIU_HDMIIN5V_INT_RE :1; + CBIOS_U32 DP2_INT_SC :1; + CBIOS_U32 DP2_INT_POUT :1; + CBIOS_U32 DP2_INT_PIN :1; + CBIOS_U32 DP1_INT_SC :1; + CBIOS_U32 DP1_INT_POUT :1; + CBIOS_U32 DP1_INT_PIN :1; + CBIOS_U32 CEC1_INT :1; + CBIOS_U32 CEC2_INT :1; + CBIOS_U32 GPIO5_INT_FE :1; + CBIOS_U32 GPIO5_INT_RE :1; + CBIOS_U32 GPIO4_INT_FE :1; + CBIOS_U32 GPIO4_INT_RE :1; + CBIOS_U32 PWRBTN_SHORT_PRESS :1; + CBIOS_U32 PWRBTN_LONG_PRESS :1; + CBIOS_U32 Reserved :14; + }; + CBIOS_U32 Value; +}REG_PMU_C6CC; + +typedef union _REG_PMU_3200 +{ + struct + { + CBIOS_U32 Gpio1_Ouptut_Data :1; + CBIOS_U32 Gpio1_Output_Enable :1; + CBIOS_U32 Gpio1_Input_Enable :1; + CBIOS_U32 Gpio1_Input_Data :1; + CBIOS_U32 GPIO_1_PU0 :1; + CBIOS_U32 GPIO_1_PU1 :1; + CBIOS_U32 GPIO_1_PD0 :1; + CBIOS_U32 GPIO_1_PD1 :1; + CBIOS_U32 Reserved :24; + }; + CBIOS_U32 Value; +}REG_PMU_3200; + +typedef union _REG_PMU_320C +{ + struct + { + CBIOS_U32 Gpio4_Ouptut_Data :1; + CBIOS_U32 Gpio4_Output_Enable :1; + CBIOS_U32 Gpio4_Input_Enable :1; + CBIOS_U32 Gpio4_Input_Data :1; + CBIOS_U32 Reserved :24; + }; + CBIOS_U32 Value; +}REG_PMU_320C; + +typedef union _REG_PMU_3210 +{ + struct + { + CBIOS_U32 Gpio5_Ouptut_Data :1; + CBIOS_U32 Gpio5_Output_Enable :1; + CBIOS_U32 Gpio5_Input_Enable :1; + CBIOS_U32 Gpio5_Input_Data :1; + CBIOS_U32 Reserved :24; + }; + CBIOS_U32 Value; +}REG_PMU_3210; + +typedef union _REG_PMU_D2E0 +{ + struct + { + CBIOS_U32 Mpll_Int :7; + CBIOS_U32 Mpll_Fn :10; + CBIOS_U32 Mpll_R :3; + CBIOS_U32 Mpll_Cp :3; + CBIOS_U32 Mpll_Lpf :2; + CBIOS_U32 Mpll_Order :1; + CBIOS_U32 Mpll_Sscg_Sel :1; + CBIOS_U32 Mpll_Sscg_Flag1 :1; + CBIOS_U32 Mpll_Testb :1; + CBIOS_U32 Sw_Mpll_Reset :1; + CBIOS_U32 Sw_Mpll_Load :1; + CBIOS_U32 Sw_Mpll_Pd :1; + }; + CBIOS_U32 Value; +}REG_PMU_D2E0; + +typedef union _REG_PMU_C6F4 +{ + struct + { + CBIOS_U32 s3vd_clk_sel :1; + CBIOS_U32 s3vd_clk_en :1; + CBIOS_U32 s3vd_eipll_clk_div :2; + CBIOS_U32 s3vd_peripll_clk_div :2; + CBIOS_U32 Reserved :26; + }; + CBIOS_U32 Value; +}REG_PMU_C6F4; + +typedef union _REG_PMU_C340 +{ + struct + { + CBIOS_U32 CPUPLL_FN :10; + CBIOS_U32 CPUPLL_INT :7; + CBIOS_U32 Reserved_1 :3; + CBIOS_U32 CPUPLL_R :3; + CBIOS_U32 Reserved_2 :4; + CBIOS_U32 manual_cfg_en :1; + CBIOS_U32 CPUPLL_LOAD :1; + CBIOS_U32 CPUPLL_PD :1; + CBIOS_U32 Reserved_3 :2; + }; + CBIOS_U32 Value; +}REG_PMU_C340; + +typedef union _REG_PMU_C348 //CPU_PLL_STATUS +{ + struct + { + CBIOS_U32 CPUPLL_FN :10; + CBIOS_U32 CPUPLL_INT :7; + CBIOS_U32 Reserved_1 :3; + CBIOS_U32 CPUPLL_R :3; + CBIOS_U32 Reserved_2 :5; + CBIOS_U32 CPUPLL_LOAD :1; + CBIOS_U32 CPUPLL_PD :1; + CBIOS_U32 Reserved_3 :1; + CBIOS_U32 CPU_PLL_LOCK :1; + }; + CBIOS_U32 Value; +}REG_PMU_C348; + +typedef union _REG_PMU_E080 //DEBUG_INFO_CTRL +{ + struct + { + CBIOS_U32 SPNIDEN_PL310 :1; + CBIOS_U32 Reserved_1 :17; + CBIOS_U32 CPU_CLK_MUX_SEL :1; + CBIOS_U32 Reserved_2 :13; + }; + CBIOS_U32 Value; +}REG_PMU_E080; + + +typedef union _REG_PMC_0250 +{ + struct + { + CBIOS_U32 I2C1_Clock_Enable :1; + CBIOS_U32 UART0_Clock_Enable :1; + CBIOS_U32 UART1_Clock_Enable :1; + CBIOS_U32 UART2_Clock_Enable :1; + CBIOS_U32 UART3_Clock_Enable :1; + CBIOS_U32 I2C0_Clock_Enable :1; + CBIOS_U32 Reserved_0 :1; + CBIOS_U32 RTC_Clock_Enable :1; + CBIOS_U32 TZPC_Clock_Enable :1; + CBIOS_U32 KPAD_Clock_Enable :1; + CBIOS_U32 PWM_Clock_Enable :1; + CBIOS_U32 GPIO_Clock_Enable :1; + CBIOS_U32 SPI0_Clock_Enable :1; + CBIOS_U32 SPI1_Clock_Enable :1; + CBIOS_U32 UART4_Clock_Enable :1; + CBIOS_U32 Reserved_1 :1; + CBIOS_U32 SD1_Clock_Enable :1; + CBIOS_U32 CIR_Timers_Clock_Enable :1; + CBIOS_U32 Random_Num_Clock_Enable :1; + CBIOS_U32 Reserved_2 :1; + CBIOS_U32 PCM :1; + CBIOS_U32 SCC_Clock_Enable :1; + CBIOS_U32 Reserved_3 :3; + CBIOS_U32 SD2_Clock_Enable :1; + CBIOS_U32 SD3_Clock_Enable :1; + CBIOS_U32 Reserved_4 :1; + CBIOS_U32 PCIE0_Clock_Enable :1; + CBIOS_U32 Reserved_5 :2; + CBIOS_U32 GFX_BIU_Clock_Enable :1; + }; + CBIOS_U32 Value; +}REG_PMC_0250; + + + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Init/CBiosInit.c b/drivers/gpu/drm/arise/cbios/Init/CBiosInit.c new file mode 100644 index 0000000000000..08b8023aefbe1 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Init/CBiosInit.c @@ -0,0 +1,208 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios sw initialization function. +** Initialize CBIOS_EXTENSION_COMMON structure. +** +** NOTE: +** The hw dependent initialization SHOULD NOT be added to this file. +******************************************************************************/ + +#include "CBiosChipShare.h" +#include "CBiosDevice.h" + +extern CBIOS_HDMI_FORMAT_MTX CEAVideoFormatTable[CBIOS_HDMIFORMATCOUNTS]; + + +static CBIOS_VOID cbCbiosChipCapsInit(PCBIOS_EXTENSION_COMMON pcbe) +{ + switch(pcbe->ChipID) + { + case CHIPID_E3K: + case CHIPID_ARISE1020: + case CHIPID_ARISE1040: + case CHIPID_ARISE1010: + case CHIPID_ARISE10C0T: + case CHIPID_ARISE2030: + case CHIPID_ARISE2020: + pcbe->ChipCaps.IsSupportUpScaling = CBIOS_TRUE; + pcbe->ChipCaps.bNoMemoryControl = CBIOS_FALSE; + pcbe->ChipCaps.Is24MReferenceClock = CBIOS_FALSE; + pcbe->ChipCaps.IsSupport3DVideo = CBIOS_TRUE; + pcbe->ChipCaps.IsSupportDeepColor = CBIOS_TRUE; + pcbe->ChipCaps.IsSupportCEC = CBIOS_TRUE; + pcbe->ChipCaps.bSupportConfigEclkByEfuse = CBIOS_FALSE; + pcbe->ChipCaps.bSupportScrambling = CBIOS_TRUE; + pcbe->ChipCaps.bSupportReadRequest = CBIOS_FALSE; + pcbe->ChipLimits.ulMaxPUHorSrc = 2560; + pcbe->ChipLimits.ulMaxPUVerSrc = 1600; + pcbe->ChipLimits.ulMaxPUHorDst = 4096; + pcbe->ChipLimits.ulMaxPUVerDst = 4096; + pcbe->ChipLimits.ulMaxHDMIClock = 6000000; + pcbe->ChipLimits.ulMaxIGAClock = 6000000; + break; + default: + pcbe->ChipCaps.IsSupportUpScaling = CBIOS_FALSE; + pcbe->ChipCaps.bNoMemoryControl = CBIOS_TRUE; + pcbe->ChipCaps.IsSupportDeepColor = CBIOS_FALSE; + pcbe->ChipCaps.IsSupportCEC = CBIOS_FALSE; + pcbe->ChipCaps.bSupportConfigEclkByEfuse = CBIOS_FALSE; + pcbe->ChipCaps.bSupportScrambling = CBIOS_FALSE; + pcbe->ChipCaps.bSupportReadRequest = CBIOS_FALSE; + pcbe->ChipLimits.ulMaxPUHorSrc = 1600; + pcbe->ChipLimits.ulMaxPUVerSrc = 1200; + pcbe->ChipLimits.ulMaxPUHorDst = 4096; + pcbe->ChipLimits.ulMaxPUVerDst = 4096; + pcbe->ChipLimits.ulMaxHDMIClock = 1650000; + pcbe->ChipLimits.ulMaxIGAClock = 1650000; + break; + } + if(pcbe->bRunOnQT) + { + pcbe->ChipCaps.bNoMemoryControl = CBIOS_FALSE; + } +} + + +//SW Initialization: init CBIOS_EXTENSION_COMMON structure, and port struct init +CBIOS_BOOL cbInitialize(PCBIOS_VOID pvcbe, PCBIOS_PARAM_INIT pCBParamInit) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_VOID pRomBase = pCBParamInit->RomImage; + PCBIOS_VOID pVCPBase = CBIOS_NULL; + CBIOS_U32 i = 0; + PVCP_INFO pVCP = CBIOS_NULL; + + cbTraceEnter(GENERIC); + + pcbe->pSpinLock = pCBParamInit->pSpinLock; + pcbe->pAuxMutex = pCBParamInit->pAuxMutex; + pcbe->pAdapterContext = pCBParamInit->pAdapterContext; + pcbe->bMAMMPrimaryAdapter = pCBParamInit->MAMMPrimaryAdapter; + pcbe->PCIDeviceID = pCBParamInit->PCIDeviceID; + pcbe->ChipID = pCBParamInit->ChipID; + pcbe->ChipRevision = pCBParamInit->ChipRevision; + pcbe->BoardVersion = CBIOS_BOARD_VERSION_DEFAULT; + pcbe->bRunOnQT = pCBParamInit->bRunOnQT; + pcbe->bDriverLoadQTiming = pCBParamInit->bDriverLoadQTiming; + pcbe->RomImageLength = pCBParamInit->RomImageLength; + + for(i = 0;i < CBIOS_MAX_I2CBUS;i++) + { + pcbe->pI2CMutex[i] = pCBParamInit->pI2CMutex[i]; + } + + cbHWInitChipAttribute((PCBIOS_VOID)pcbe, pcbe->ChipID); + + //init HDMI format table + pcbe->pHDMIFormatTable = CEAVideoFormatTable; + + //init Memory Type + pcbe->MemoryType = Default_Mem_Type; //It will be reset once when change clocks + + //Init cbios chip caps first + cbCbiosChipCapsInit(pcbe); + + //Init VCP info structure. + pVCP = cb_AllocatePagedPool(sizeof(VCP_INFO)); + + if(pVCP == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pVCP allocate error\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + /*find VCP in RomBase,otherwise in RomBase + 64kb + 4kb*/ + pVCPBase = pRomBase; + if(pVCPBase && cb_swab16(*(CBIOS_U16*)((CBIOS_U8*)pVCPBase+ VCP_OFFSET))!= VCP_TAG) + { + pVCPBase = CBIOS_NULL; + } + + if(!cbInitVCP(pcbe, pVCP, pVCPBase)) + { + return CBIOS_FALSE; + } + else + { + //Init table. + pcbe->sizeofBootDevPriority = pVCP->sizeofBootDevPriority; + pcbe->PostRegTable[VCP_TABLE].sizeofCRDefault = pVCP->sizeofCR_DEFAULT_TABLE; + pcbe->PostRegTable[VCP_TABLE].sizeofSRDefault = pVCP->sizeofSR_DEFAULT_TABLE; + pcbe->PostRegTable[VCP_TABLE].sizeofModeExtRegDefault_TBL = 0; + + pcbe->pBootDevPriority = cb_AllocateNonpagedPool(sizeof(CBIOS_U16) * pVCP->sizeofBootDevPriority); + pcbe->PostRegTable[VCP_TABLE].pCRDefault = cb_AllocateNonpagedPool(sizeof(CBREGISTER) * pVCP->sizeofCR_DEFAULT_TABLE); + pcbe->PostRegTable[VCP_TABLE].pSRDefault = cb_AllocateNonpagedPool(sizeof(CBREGISTER) * pVCP->sizeofSR_DEFAULT_TABLE); + pcbe->PostRegTable[VCP_TABLE].pModeExtRegDefault_TBL = CBIOS_NULL; + + cb_memcpy(pcbe->pBootDevPriority, pVCP->BootDevPriority, sizeof(CBIOS_U16) * pVCP->sizeofBootDevPriority); + cb_memcpy(pcbe->PostRegTable[VCP_TABLE].pCRDefault, pVCP->pCR_DEFAULT_TABLE, sizeof(CBREGISTER) * pVCP->sizeofCR_DEFAULT_TABLE); + cb_memcpy(pcbe->PostRegTable[VCP_TABLE].pSRDefault, pVCP->pSR_DEFAULT_TABLE, sizeof(CBREGISTER) * pVCP->sizeofSR_DEFAULT_TABLE); + } + + cb_memcpy(&pcbe->FeatureSwitch, &pVCP->FeatureSwitch, sizeof(CBIOS_U32)); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Feature switch for bNonSimulChip: %d\n", pcbe->FeatureSwitch.bNonSimulChip)); + + pcbe->bUseVCP = pVCP->bUseVCP; + pcbe->BiosVersion = pVCP->BiosVersion; + pcbe->EClock = pVCP->EClock; + pcbe->EVcoLow = pVCP->EVcoLow; + pcbe->DVcoLow = pVCP->DVcoLow; + pcbe->DeviceMgr.SupportDevices = pVCP->SupportDevices; + pcbe->SliceNum = pVCP->SliceNum; + pcbe->FwVersion = pVCP->FwVersion; + cb_memcpy(pcbe->FwName, pVCP->FwName, sizeof(pVCP->FwName)); + + //RealVision requires I2C speed up to 400kbps + if ((pVCP->SubVendorID == 0x12EA) && (pVCP->SubSystemID == 0x0002)) + { + pcbe->I2CDelay = 3; + } + else + { + pcbe->I2CDelay = I2C_DELAY_DEFAULT; + } + + //initialize CEC para + for (i = 0; i < CBIOS_CEC_INDEX_COUNT; i++) + { + pcbe->CECPara[i].CECEnable = CBIOS_FALSE; + pcbe->CECPara[i].LogicalAddr = CEC_UNREGISTERED_DEVICE; + pcbe->CECPara[i].PhysicalAddr = CEC_INVALID_PHYSICAL_ADDR; + } + + cbInitDeviceArray(pcbe, pVCP); + + cbDispMgrInit(pcbe); + + if(pVCP->pCR_DEFAULT_TABLE) + { + cb_FreePool(pVCP->pCR_DEFAULT_TABLE); + pVCP->pCR_DEFAULT_TABLE = CBIOS_NULL; + } + if(pVCP->pSR_DEFAULT_TABLE) + { + cb_FreePool(pVCP->pSR_DEFAULT_TABLE); + pVCP->pSR_DEFAULT_TABLE = CBIOS_NULL; + } + cb_FreePool(pVCP); + + return CBIOS_TRUE; +} + + diff --git a/drivers/gpu/drm/arise/cbios/Interface/CBios.c b/drivers/gpu/drm/arise/cbios/Interface/CBios.c new file mode 100644 index 0000000000000..dc18b4a7376f9 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Interface/CBios.c @@ -0,0 +1,1729 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios interface implementation. +** +** NOTE: +** The interface and parameters SHOULD NOT be modified under normal condition. +** If the interface need modify for some special case, please make sure to +** update the code where calls this interface. +******************************************************************************/ + +#include "CBiosShare.h" +#include "CBiosTypes.h" +#include "CBiosChipShare.h" +#include "../Hw/HwInterface/CBiosHwInterface.h" +#include "../Hw/HwUtil/CBiosUtilHw.h" +#include "../Callback/CBiosCallbacks.h" + + +CBIOS_STATUS +DllInitialize( CBIOS_IN PCBIOS_VOID pus ) +{ + return CBIOS_OK; +} + +CBIOS_STATUS +DllUnload( CBIOS_VOID ) +{ + return CBIOS_OK; +} + +// The DLL must have an entry point, but it is never called. +// +CBIOS_STATUS +DriverEntry( + CBIOS_IN PCBIOS_VOID DriverObject, + CBIOS_IN PCBIOS_VOID RegistryPath +) +{ + return CBIOS_OK; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetExtensionSize(PCBIOS_CHIP_ID pCBChipId, CBIOS_U32 *pulExtensionSize) +{ + if(pulExtensionSize == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),("CBiosGetExtensionSize: pulExtensionSize is CBIOS_NULL!\n"))); + return CBIOS_ER_INVALID_PARAMETER; + } + + cbGetExtensionSize(pulExtensionSize); + + return CBIOS_OK; +} + +DLLEXPORTS CBIOS_STATUS +CBiosInit(PCBIOS_VOID pvcbe, PCBIOS_PARAM_INIT pCBParamInit) +{ + if(pvcbe == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"CBiosInit: pvcbe is CBIOS_NULL!\n")); + return CBIOS_ER_INVALID_PARAMETER; + } + + if (cbInitialize(pvcbe, pCBParamInit)) + { + return CBIOS_OK; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbInitialize: function failure!\n")); + cbPrintMsgToFile(DBG_LEVEL_ERROR_MSG, "cbInitialize: function failure!\n", CBIOS_NULL, 0); + return CBIOS_ER_INTERNAL; + } + +} + +DLLEXPORTS CBIOS_STATUS +CBiosInitialize(CBIOS_IN CBIOS_OUT PCBIOS_INITIALIZATION_PARA pCBiosInitPara) +{ + CBIOS_STATUS Status; + PCBIOS_VOID pcbe = CBIOS_NULL; + + if(CBIOS_NULL == pCBiosInitPara) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "pCBiosInitPara is NULL!\n")); + Status = CBIOS_ER_INVALID_PARAMETER; + goto end; + } + + Status = cbSetCallBackFunctions(&(pCBiosInitPara->CBiosCallbacks)); + if (Status == CBIOS_OK) + { + pcbe = cb_AllocateNonpagedPool(sizeof(CBIOS_EXTENSION_COMMON)); + if(pcbe == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: CBIOS_EXTENSION_COMMON allocate error\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + pCBiosInitPara->pCBiosExtension = pcbe; + + if(cbInitialize(pcbe, &pCBiosInitPara->CBiosParamInit)) + { + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetVersion = CBiosGetVersion; + pCBiosInitPara->CBiosInterfaces.CBiosDdiInitHW = CBiosInitHW; + pCBiosInitPara->CBiosInterfaces.CBiosDdiDetectAttachedDisplayDevices = CBiosDetectAttachedDisplayDevices; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetDeviceModeListBufferSize = CBiosGetDeviceModeListBufferSize; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetDeviceModeList = CBiosGetDeviceModeList; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetAdapterModeListBufferSize = CBiosGetAdapterModeListBufferSize; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetAdapterModeList = CBiosGetAdapterModeList; + pCBiosInitPara->CBiosInterfaces.CBiosDdiSetModeToIGA = CBiosSetModeToIGA; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetModeFromIGA = CBiosGetModeFromIGA; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetModeTiming = CBiosGetModeTiming; + pCBiosInitPara->CBiosInterfaces.CBiosDdiSetScreenOnOff = CBiosSetIgaScreenOnOffState; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetDevicePowerState = CBiosGetDisplayDevicePowerState; + pCBiosInitPara->CBiosInterfaces.CBiosDdiSetDevicePowerState = CBiosSetDisplayDevicePowerState; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetEdid = CBiosGetEdid; + pCBiosInitPara->CBiosInterfaces.CBiosDdiSetEdid = CBiosSetEdid; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetClock = CBiosGetClock; + pCBiosInitPara->CBiosInterfaces.CBiosDdiSetClock = CBiosSetClock; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetActiveDevice = CBiosGetActiveDevice; + pCBiosInitPara->CBiosInterfaces.CBiosDdiSetActiveDevice = CBiosSetActiveDevice; + pCBiosInitPara->CBiosInterfaces.CBiosDdiSyncDataWithVBios = CBiosSyncDataWithVbios; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetVBiosInfo = CBiosGetVBiosInfo; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetMonitorTypePerPort = CBiosGetMonitorTypePerPort; + pCBiosInitPara->CBiosInterfaces.CBiosDdiQueryMonitorAttribute = CBiosQueryMonitorAttribute; + pCBiosInitPara->CBiosInterfaces.CBiosDdiQueryMonitor3DCapability = CBiosQueryMonitor3DCapability; + pCBiosInitPara->CBiosInterfaces.CBiosDdiI2CDataRead = CBiosI2CDataRead; + pCBiosInitPara->CBiosInterfaces.CBiosDdiI2CDataWrite = CBiosI2CDataWrite; + pCBiosInitPara->CBiosInterfaces.CBiosDdiDDCCII2COpen = CBiosDDCCII2COpen; + pCBiosInitPara->CBiosInterfaces.CBiosDdiDDCCII2CAccess = CBiosDDCCII2CAccess; + pCBiosInitPara->CBiosInterfaces.CBiosDdiReadReg = CBiosReadReg; + pCBiosInitPara->CBiosInterfaces.CBiosDdiWriteReg = CBiosWriteReg; + pCBiosInitPara->CBiosInterfaces.CBiosDdiSetHDACodecPara = CBiosSetHDACodecPara; + pCBiosInitPara->CBiosInterfaces.CBiosDdiSetHDACConnectStatus = CBiosSetHDACConnectStatus; + pCBiosInitPara->CBiosInterfaces.CBiosDdiAccessDpcdData = CBiosAccessDpcdData; + pCBiosInitPara->CBiosInterfaces.CBiosDdiContentProtectionOnOff = CBiosContentProtectionOnOff; + pCBiosInitPara->CBiosInterfaces.CBiosDdiHDCPIsr = CBiosHDCPIsr; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetHDCPStatus = CBiosGetHDCPStatus; + pCBiosInitPara->CBiosInterfaces.CBiosDdiHDCPWorkThread = CBiosHDCPWorkThread; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetHDCPInterruptInfo = CBiosGetHDCPInterruptInfo; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetHDACInterruptInfo = CBiosGetHDACInterruptInfo; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetDevComb = CBiosGetDevComb; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetIgaMask = CBiosGetIgaMask; + pCBiosInitPara->CBiosInterfaces.CBiosDdiInterruptEnableDisable = CBiosInterruptEnableDisable; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetInterruptInfo = CBiosGetInterruptInfo; + pCBiosInitPara->CBiosInterfaces.CBiosDdiSetCursor = CBiosSetCursor; + pCBiosInitPara->CBiosInterfaces.CBiosDdiResetHWBlock = CBiosResetHWBlock; + pCBiosInitPara->CBiosInterfaces.CBiosDdiUnload = CBiosUnload; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetDispAddr = CBiosGetDisplayAddr; + pCBiosInitPara->CBiosInterfaces.CBiosDdiUpdateFrame = CBiosUpdateFrame; + pCBiosInitPara->CBiosInterfaces.CBiosDdiSetGamma = CBiosSetGamma; + pCBiosInitPara->CBiosInterfaces.CBiosDdiDPIsr = CBiosDPIsr; + pCBiosInitPara->CBiosInterfaces.CBiosDdiDPWorkThreadMainFunc = CBiosDPWorkThreadMainFunc; + pCBiosInitPara->CBiosInterfaces.CBiosDdiDPGetCustomizedTiming = CBiosDPGetCustomizedTiming; + pCBiosInitPara->CBiosInterfaces.CBiosDdiDPSetNotifications = CBiosDPSetNotifications; + pCBiosInitPara->CBiosInterfaces.CBiosDdiWaitVBlank = CBiosWaitVBlank; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetSliceNum = CBiosGetSliceNum; + pCBiosInitPara->CBiosInterfaces.CBiosDdiGetHwCounter = CBiosGetHwCounter; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbInitialize: function failure!\n")); + cb_FreePool(pcbe); + pCBiosInitPara->pCBiosExtension = CBIOS_NULL; + cb_memset((PCBIOS_VOID)(&(pCBiosInitPara->CBiosInterfaces)), 0, sizeof(CBIOS_INTERFACES)); + Status = CBIOS_ER_INTERNAL; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "set callback functions error!\n")); + Status = CBIOS_ER_INTERNAL; + } + +end: + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosSetCallBackFunctions(PCBIOS_CALLBACK_FUNCTIONS pFnCallBack) +{ + CBIOS_STATUS Status; + + Status = cbSetCallBackFunctions(pFnCallBack); + + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosDetectAttachedDisplayDevices(PCBIOS_VOID pvcbe, PCIP_DEVICES_DETECT_PARAM pDevicesDetectParam) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_ACTIVE_TYPE CurDevice = CBIOS_TYPE_NONE; + CBIOS_U32 Devices =0, Detected = 0; + CBIOS_BOOL bHardcodeDetected[CBIOS_MAX_DISPLAY_DEVICES_NUM]; + + cb_memset(bHardcodeDetected, CBIOS_FALSE, sizeof(bHardcodeDetected)); + + if (pDevicesDetectParam == CBIOS_NULL || pDevicesDetectParam->DevicesToDetect == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + Devices = pDevicesDetectParam->DevicesToDetect; + if(pcbe->bRunOnQT) + { + Devices &= (CBIOS_TYPE_CRT | CBIOS_TYPE_DP1); + + if(Devices & CBIOS_TYPE_CRT) + { + bHardcodeDetected[cbConvertDeviceBit2Index(CBIOS_TYPE_CRT)] = CBIOS_TRUE; + } + + if(Devices & CBIOS_TYPE_DP1) + { + bHardcodeDetected[cbConvertDeviceBit2Index(CBIOS_TYPE_DP1)] = CBIOS_TRUE; + } + } + + while (Devices) + { + CurDevice = GET_LAST_BIT(Devices); + Devices &= ~CurDevice; + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(CurDevice)]; + + if(pDevCommon == CBIOS_NULL) + { + continue; + } + + if(cbDevDeviceDetect(pcbe, pDevCommon, bHardcodeDetected[cbConvertDeviceBit2Index(CurDevice)], pDevicesDetectParam->FullDetect)) + { + Detected |= CurDevice; + pcbe->DeviceMgr.ConnectedDevices |= CurDevice; + } + else + { + pcbe->DeviceMgr.ConnectedDevices &= ~CurDevice; + } + } + + pDevicesDetectParam->DetectedDevices = Detected; + + return CBIOS_OK; +} + + +DLLEXPORTS CBIOS_STATUS +CBiosInitHW(PCBIOS_VOID pvcbe) +{ + return cbHWInit(pvcbe); +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetEdid(PCBIOS_VOID pvcbe, PCBIOS_PARAM_GET_EDID pCBParamGetEdid) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if (pCBParamGetEdid == CBIOS_NULL || pCBParamGetEdid->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pCBParamGetEdid->DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDevCommon is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + return cbDevGetEdidFromBuffer(pcbe, pDevCommon, pCBParamGetEdid); +} + +DLLEXPORTS CBIOS_STATUS +CBiosI2CDataRead(PCBIOS_VOID pvcbe, PCBIOS_PARAM_I2C_DATA pCBParamI2CData) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_U32 PortNumber = 0; + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pCBParamI2CData == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pCBParamI2CData is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + if (pCBParamI2CData->bUseDevType) + { + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, pCBParamI2CData->DeviceId); + PortNumber = pDevCommon->I2CBus; + } + else + { + PortNumber = pCBParamI2CData->PortNumber; + } + + if (PortNumber < CBIOS_MAX_I2CBUS) + { + cb_AcquireMutex(pcbe->pI2CMutex[PortNumber]); + } + + Status = cbHWI2CDataRead(pcbe,pCBParamI2CData); + + if (PortNumber < CBIOS_MAX_I2CBUS) + { + cb_ReleaseMutex(pcbe->pI2CMutex[PortNumber]); + } + + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosI2CDataWrite(PCBIOS_VOID pvcbe, PCBIOS_PARAM_I2C_DATA pCBParamI2CData) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_U32 PortNumber = 0; + CBIOS_STATUS Status = CBIOS_ER_NOT_YET_IMPLEMENTED; + + if (pCBParamI2CData == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pCBParamI2CData is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + if (pCBParamI2CData->bUseDevType) + { + pDevCommon = cbGetDeviceCommon(&pcbe->DeviceMgr, pCBParamI2CData->DeviceId); + PortNumber = pDevCommon->I2CBus; + } + else + { + PortNumber = pCBParamI2CData->PortNumber; + } + + if (PortNumber < CBIOS_MAX_I2CBUS) + { + cb_AcquireMutex(pcbe->pI2CMutex[PortNumber]); + } + + Status = cbHWI2CDataWrite(pcbe, pCBParamI2CData); + + if (PortNumber < CBIOS_MAX_I2CBUS) + { + cb_ReleaseMutex(pcbe->pI2CMutex[PortNumber]); + } + + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosUnload(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + CBIOS_U32 i = 0; + + if (!pcbe) + { + return Status; + } + + Status = cbHWUnload(pcbe); + + if (Status == CBIOS_OK) + { + if (pcbe->pSpinLock != CBIOS_NULL) + { + cb_FreePool(pcbe->pSpinLock); + pcbe->pSpinLock = CBIOS_NULL; + } + if(pcbe->pAuxMutex != CBIOS_NULL) + { + cb_FreePool(pcbe->pAuxMutex); + pcbe->pAuxMutex = CBIOS_NULL; + } + + for(i = 0;i < CBIOS_MAX_I2CBUS;i++) + { + if(pcbe->pI2CMutex[i] != CBIOS_NULL) + { + cb_FreePool(pcbe->pI2CMutex[i]); + pcbe->pI2CMutex[i] = CBIOS_NULL; + } + } + + if (pcbe->pBootDevPriority != CBIOS_NULL) + { + cb_FreePool(pcbe->pBootDevPriority); + pcbe->pBootDevPriority = CBIOS_NULL; + } + if (pcbe->PostRegTable[VCP_TABLE].pCRDefault != CBIOS_NULL) + { + cb_FreePool(pcbe->PostRegTable[VCP_TABLE].pCRDefault); + pcbe->PostRegTable[VCP_TABLE].pCRDefault = CBIOS_NULL; + } + if (pcbe->PostRegTable[VCP_TABLE].pSRDefault != CBIOS_NULL) + { + cb_FreePool(pcbe->PostRegTable[VCP_TABLE].pSRDefault); + pcbe->PostRegTable[VCP_TABLE].pSRDefault = CBIOS_NULL; + } + if (pcbe != CBIOS_NULL) + { + cb_FreePool(pcbe); + pcbe = CBIOS_NULL; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), " CBiosUnload failed!\n")); + } + + return Status; + +} + +//The following interface is for new setting mode logic +DLLEXPORTS CBIOS_STATUS +CBiosGetDeviceModeListBufferSize(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_U32 DeviceId, + CBIOS_OUT CBIOS_U32 *pBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pBufferSize == CBIOS_NULL || DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pBufferSize or DeviceId is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDevCommon is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevGetDeviceModeListBufferSize(pcbe, pDevCommon, pBufferSize); +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetDeviceModeList(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_U32 DeviceId, + CBIOS_OUT PCBiosModeInfoExt pModeList, + CBIOS_IN CBIOS_OUT CBIOS_U32 * pBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pBufferSize == CBIOS_NULL || DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pBufferSize or DeviceId is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDevCommon is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevGetDeviceModeList(pcbe, pDevCommon, pModeList, pBufferSize); +} + + +DLLEXPORTS CBIOS_STATUS +CBiosGetModeFromIGA(CBIOS_IN CBIOS_VOID* pvcbe, + CBIOS_OUT PCBiosSettingModeParams pModeParams) +{ + CBIOS_STATUS status = CBIOS_ER_INVALID_PARAMETER; + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + if(pModeParams) + { + status = cbDispMgrGetMode(pcbe, &pcbe->DispMgr, pModeParams); + } + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetHwCounter(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_GET_HW_COUNTER pGetCounter) +{ + CBIOS_STATUS status = CBIOS_ER_INVALID_PARAMETER; + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + + if(pGetCounter) + { + status = cbDispMgrGetHwCounter(pcbe, pGetCounter); + } + + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetModeFromReg(CBIOS_IN CBIOS_VOID* pvcbe, + CBIOS_IN CBIOS_OUT PCBiosSettingModeParams pModeParams) +{ + CBIOS_STATUS status = CBIOS_ER_INVALID_PARAMETER; + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + if(pModeParams) + { + status = cbDispMgrGetModeFromReg(pcbe, &pcbe->DispMgr, pModeParams); + } + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosSetModeToIGA(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBiosSettingModeParams pSettingModeParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + return cbDispMgrSetMode(pcbe, &pcbe->DeviceMgr, &pcbe->DispMgr, pSettingModeParams); +} + +DLLEXPORTS CBIOS_STATUS +CBiosUpdateFrame(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_UPDATE_FRAME_PARA pUpdateFrame) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + return cbDispMgrUpdateFrame(pcbe, pUpdateFrame); +} + +DLLEXPORTS CBIOS_STATUS +CBiosDoCSCAdjust(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_CSC_ADJUST_PARA pCSCAdjustPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + + return cbDispMgrDoCSCAdjust(pcbe, &pcbe->DispMgr, pCSCAdjustPara); +} + +DLLEXPORTS CBIOS_STATUS +CBiosAdjustStreamCSC(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_STREAM_CSC_PARA pCSCAdjustPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + + return cbDispMgrAdjustStreamCSC(pcbe, pCSCAdjustPara); +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetDispResource(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_GET_DISP_RESOURCE pGetDispRes) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + return cbDispMgrGetDispResource(pcbe, pGetDispRes); +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetDisplayCaps(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_DISPLAY_CAPS pDispCaps) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + return cbDispMgrGetDisplayCaps(pcbe, pDispCaps); +} + + +DLLEXPORTS CBIOS_STATUS +CBiosSetCursor(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN PCBIOS_CURSOR_PARA pSetCursor) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + + if(CBIOS_NULL == pSetCursor) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: Cursor param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDispMgrSetHwCursor(pcbe, pSetCursor); +} + + +DLLEXPORTS CBIOS_STATUS +CBiosCheckSurfaceOnDisplay(PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_CHECK_SURFACE_ON_DISP pChkSurfacePara) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + if(pChkSurfacePara == CBIOS_NULL || pChkSurfacePara->pSurfaceAttr == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + return cbDispMgrCheckSurfaceOnDisplay(pcbe, pChkSurfacePara); +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetDisplayAddr(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_GET_DISP_ADDR pGetDispAddr) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + if (pGetDispAddr == CBIOS_NULL) + { + return CBIOS_ER_NULLPOINTER; + } + return cbDispMgrGetDispAddr(pcbe, pGetDispAddr); +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetActiveDevice(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_OUT PCIP_ACTIVE_DEVICES pActiveDevices) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + + if (pActiveDevices == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + Status = cbDispMgrGetActiveDevice(pcbe, &pcbe->DispMgr, pActiveDevices); + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosSetActiveDevice(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCIP_ACTIVE_DEVICES pActiveDevices) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status = CBIOS_OK; + + if (pActiveDevices == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + Status = cbDispMgrSetActiveDevice(pcbe, &pcbe->DispMgr, pActiveDevices); + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetModeTiming(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_GET_MODE_TIMING_PARAM pGetModeTiming) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pGetModeTiming == CBIOS_NULL || pGetModeTiming->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pGetModeTiming->DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDevCommon is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + return cbDevGetModeTiming(pcbe, pDevCommon, pGetModeTiming); +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetVBiosInfo(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_VBINFO_PARAM pVbiosInfo) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS status; + + status = cbHWGetVBiosInfo(pcbe, pVbiosInfo); + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosSyncDataWithVbios(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_VBIOS_DATA_PARAM pDataParam) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + CBIOS_STATUS status; + //check function pointer + + status = cbHwSyncDataWithVbios(pcbe, pDataParam); + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosSetMmioEndianMode(CBIOS_IN CBIOS_VOID* pAdapterContext) +{ + CBIOS_STATUS Status; + Status = cbHWSetMmioEndianMode(pAdapterContext); + return Status; +} + + +DLLEXPORTS CBIOS_STATUS +CBiosSetWriteback(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_OUT PCBIOS_WB_PARA pWBPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + return cbHWSetWriteback(pcbe, pWBPara); +} + +DLLEXPORTS CBIOS_STATUS +CBiosDbgLevelCtl(PCBIOS_DBG_LEVEL_CTRL pDbgLevelCtl) +{ + CBIOS_STATUS status = CBIOS_ER_INVALID_PARAMETER; + if(pDbgLevelCtl) + { + status = cbDbgLevelCtl(pDbgLevelCtl); + } + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetVersion(PCBIOS_VOID pvcbe, PCBIOS_VERSION pCbiosVersion) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + if(pCbiosVersion == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),("CBiosGetVersion: pCbiosVersion is CBIOS_NULL!\n"))); + return CBIOS_ER_INVALID_PARAMETER; + } + return cbGetVersion(pcbe, pCbiosVersion); +} + +DLLEXPORTS CBIOS_STATUS +CBiosIsChipEnable(PCBIOS_VOID pvcbe, PCBIOS_PARAM_CHECK_CHIPENABLE pCBParamCheckChipenable) +{ + CBIOS_STATUS status = CBIOS_ER_MMIO; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + if ((pvcbe == CBIOS_NULL) || (pCBParamCheckChipenable == CBIOS_NULL)) + { + status = CBIOS_ER_NULLPOINTER; + return status; + } + + if (cbHWIsChipEnable(pcbe) == CBIOS_FALSE) + { + pCBParamCheckChipenable->IsChipEnable = CBIOS_FALSE; + status = CBIOS_ER_MMIO; + } + else + { + pCBParamCheckChipenable->IsChipEnable = CBIOS_TRUE; + status = CBIOS_OK; + } + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosDumpReg(PCBIOS_VOID pvcbe, PCBIOS_PARAM_DUMP_REG pCBParamDumpReg) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + return cbHWDumpReg(pcbe,pCBParamDumpReg); +} + +DLLEXPORTS CBIOS_STATUS +CBiosReadReg(PCBIOS_VOID pvcbe, + CBIOS_U8 type, + CBIOS_U8 index, + CBIOS_U8 * result) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + return cbHWReadReg(pcbe, type, index, result); +} + +DLLEXPORTS CBIOS_STATUS +CBiosWriteReg(PCBIOS_VOID pvcbe, + CBIOS_U8 type, + CBIOS_U8 index, + CBIOS_U8 value, + CBIOS_U8 mask) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + + return cbHWWriteReg(pcbe, type, index, value, mask); +} + +DLLEXPORTS CBIOS_STATUS +CBiosDDCCII2COpen(PCBIOS_VOID pvcbe, CBIOS_BOOL bOpen, PCBIOS_I2CCONTROL pI2CControl, CBIOS_U8 I2CBUSNum) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + return cbHwI2CDDCCIOpen(pcbe, bOpen, pI2CControl, I2CBUSNum); +} + +DLLEXPORTS CBIOS_STATUS +CBiosDDCCII2CAccess(PCBIOS_VOID pvcbe, PCBIOS_I2CCONTROL pI2CControl, CBIOS_U8 I2CBUSNum) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + return cbHwI2CDDCCIAccess(pcbe, pI2CControl, I2CBUSNum); +} + +DLLEXPORTS CBIOS_STATUS +CBiosSetIgaScreenOnOffState(PCBIOS_VOID pvcbe, CBIOS_BOOL status, CBIOS_U8 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + return cbHWSetIgaScreenOnOffState(pcbe, status, IGAIndex); +} + +DLLEXPORTS CBIOS_STATUS +CBiosSetDisplayDevicePowerState(PCBIOS_VOID pvcbe, CBIOS_U32 DevicesId, CBIOS_PM_STATUS PMState) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + CBIOS_ACTIVE_TYPE CurDev = CBIOS_TYPE_NONE; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_U32 i = 0, Devices = DevicesId; + + if(Devices == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),("DeviceId is 0!\n"))); + return CBIOS_ER_INVALID_PARAMETER; + } + +#ifdef CHECK_CHIPENABLE + if (!cbHWIsChipEnable(pcbe)) + return CBIOS_ER_CHIPDISABLE; +#endif + + while (Devices) + { + CurDev = GET_LAST_BIT(Devices); + Devices &= (~CurDev); + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(CurDev)]; + + if(pDevCommon == CBIOS_NULL) + { + continue; + } + + for (i = IGA1; i < pcbe->DispMgr.IgaCount; i++) + { + if (CurDev & pcbe->DispMgr.ActiveDevices[i]) + { + break; + } + } + + if (i == pcbe->DispMgr.IgaCount && (PMState == CBIOS_PM_ON)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "%s: device 0x%x is not active device!\n", FUNCTION_NAME, CurDev)); + continue; + } + + cbDevSetDisplayDevicePowerState(pcbe, pDevCommon, PMState); + } + + return CBIOS_OK; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetDisplayDevicePowerState(PCBIOS_VOID pvcbe, CBIOS_U32 DeviceId, PCBIOS_PM_STATUS pPMState) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),("DeviceId is 0!\n"))); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(DeviceId)]; + if(pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),("pDevCommon is CBIOS_NULL!\n"))); + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevGetDisplayDevicePowerState(pcbe, pDevCommon, pPMState); +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetAdapterModeListBufferSize(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_OUT CBIOS_U32 * pBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + CBIOS_U32 ulModeCount = 0; + + cbMode_GetAdapterModeNum(pcbe, &ulModeCount); + *pBufferSize = ulModeCount*sizeof(CBiosModeInfoExt); + + return CBIOS_OK; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetAdapterModeList(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_OUT PCBiosModeInfoExt pModeList, + CBIOS_IN CBIOS_OUT CBIOS_U32 * pBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + return cbMode_FillAdapterModeList(pcbe, pModeList, pBufferSize); +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetHDMIAudioFomatList(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_U32 DeviceId, + CBIOS_OUT PCBiosHDMIAudioFormat pAudioFormatList, + CBIOS_IN CBIOS_OUT CBIOS_U32 *pBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_HDMI_AUDIO_INFO HDAFormatList[CBIOS_HDMI_AUDIO_FORMAT_COUNTS]; + CBIOS_U8 i = 0, HDAFormatNum = 0; + + if ((pBufferSize == CBIOS_NULL) || (pAudioFormatList == CBIOS_NULL) || (DeviceId == CBIOS_TYPE_NONE)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + HDAFormatNum = (CBIOS_U8)cbDevGetHDAFormatList(pcbe, pDevCommon, HDAFormatList); + + for (i = 0; i < HDAFormatNum; i++) + { + pAudioFormatList[i].Format = HDAFormatList[i].Format; + pAudioFormatList[i].MaxChannelNum = HDAFormatList[i].MaxChannelNum; + pAudioFormatList[i].SampleRateUnit = HDAFormatList[i].SampleRateUnit; + pAudioFormatList[i].Unit = HDAFormatList[i].Unit; + } + *pBufferSize = HDAFormatNum * sizeof(CBiosHDMIAudioFormat); + + return CBIOS_OK; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetHDMIAudioFomatListBufferSize(CBIOS_IN PCBIOS_VOID pvcbe, + CBIOS_IN CBIOS_U32 DeviceId, + CBIOS_OUT CBIOS_U32 * pBufferSize) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_U32 HDAFormatNum = 0; + + if (pBufferSize == CBIOS_NULL || DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + HDAFormatNum = cbDevGetHDAFormatList(pcbe, pDevCommon, CBIOS_NULL); + *pBufferSize = HDAFormatNum * sizeof(CBiosHDMIAudioFormat); + + return CBIOS_OK; +} + + +DLLEXPORTS CBIOS_STATUS +CBiosQueryMonitorAttribute(PCBIOS_VOID pvcbe, PCBiosMonitorAttribute pMonitorAttribute) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pMonitorAttribute == CBIOS_NULL || pMonitorAttribute->ActiveDevId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pMonitorAttribute->ActiveDevId)]; + + if(pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDevCommon is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + return cbDevQueryMonitorAttribute(pcbe, pDevCommon, pMonitorAttribute); +} + +#ifndef UEFI_DIAGTOOL +DLLEXPORTS CBIOS_STATUS +CBiosContentProtectionOnOff(PCBIOS_VOID pvcbe, PCBiosContentProtectionOnOffParams pContentProtectionOnOffParams) +#else +DLLEXPORTS CBIOS_STATUS +CBiosContentProtectionOnOff(PCBIOS_VOID pvcbe, PCBiosContentProtectionOnOffParams pContentProtectionOnOffParams, CBIOS_U16 hdcpVer) +#endif +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_U32 i, DeviceId; + + if(pContentProtectionOnOffParams == CBIOS_NULL || pContentProtectionOnOffParams->DevicesId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + DeviceId = pContentProtectionOnOffParams->DevicesId; + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(DeviceId)]; + + for(i = 0; i < pcbe->DispMgr.IgaCount; i++) + { + if(DeviceId == pcbe->DispMgr.ActiveDevices[i]) + { + break; + } + } + + if(pDevCommon == CBIOS_NULL || i == pcbe->DispMgr.IgaCount) + { + return CBIOS_ER_INVALID_PARAMETER; + } + +#ifndef UEFI_DIAGTOOL + return cbDevContentProtectionOnOff(pcbe, pDevCommon, (CBIOS_U8)i, pContentProtectionOnOffParams); +#else + return cbDevContentProtectionOnOff(pcbe, pDevCommon, (CBIOS_U8)i, pContentProtectionOnOffParams, hdcpVer); +#endif +} + +DLLEXPORTS CBIOS_STATUS +CBiosAccessDpcdData(CBIOS_VOID* pvcbe, PCBiosAccessDpcdDataParams pAccessDpcdDataParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_U32 DeviceId; + + if(pAccessDpcdDataParams == CBIOS_NULL || pAccessDpcdDataParams->RequestConnectedDevId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + DeviceId = pAccessDpcdDataParams->RequestConnectedDevId; + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevAccessDpcdData(pcbe, pDevCommon, pAccessDpcdDataParams); +} + +DLLEXPORTS CBIOS_STATUS +CBiosResetHWBlock(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_HW_BLOCK HWBlock) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + return cbHWResetBlock(pcbe, HWBlock); +} + +CBIOS_STATUS +CBiosSetEdid(CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_PARAM_SET_EDID pCBParamSetEdid) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pCBParamSetEdid == CBIOS_NULL || pCBParamSetEdid->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pCBParamSetEdid->DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDevCommon is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + return cbDevSetEdid(pcbe, pDevCommon, pCBParamSetEdid); +} + +CBIOS_STATUS +CBiosSetGamma(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_GAMMA_PARA pGammaParam) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + return cbSetGamma(pcbe, pGammaParam); +} + +DLLEXPORTS CBIOS_STATUS +CBiosQueryMonitor3DCapability(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_MONITOR_3D_CAPABILITY_PARA p3DCapability) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if (p3DCapability == CBIOS_NULL || p3DCapability->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(p3DCapability->DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDevCommon is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + return cbDevQueryMonitor3DCapability(pcbe, pDevCommon, p3DCapability); +} + +DLLEXPORTS CBIOS_STATUS +CBiosSetHDACodecPara(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_HDAC_PARA pCbiosHDACPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pCbiosHDACPara == CBIOS_NULL || pCbiosHDACPara->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pCbiosHDACPara->DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevSetHDACodecPara(pcbe, pDevCommon, pCbiosHDACPara); +} + +DLLEXPORTS CBIOS_STATUS +CBiosSetHDACConnectStatus(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_HDAC_PARA pCbiosHDACPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pCbiosHDACPara == CBIOS_NULL || pCbiosHDACPara->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pCbiosHDACPara->DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevSetHDACConnectStatus(pcbe, pDevCommon, pCbiosHDACPara); +} + +DLLEXPORTS CBIOS_STATUS +CBiosCECEnableDisable(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_CEC_ENABLE_DISABLE_PARA pCECEnableDisablePara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Status = CBIOS_OK; + Status = cbCECEnableDisable(pcbe, pCECEnableDisablePara); + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosCECTransmitMessage(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_CEC_TRANSIMIT_MESSAGE_PARA pCECPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Status = CBIOS_OK; + CBIOS_CEC_MESSAGE CECMessage; + + if (pCECPara == CBIOS_NULL) + { + Status = CBIOS_ER_NULLPOINTER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECTransmitMessage: pCECPara is NULL!")); + } + else if (!pcbe->ChipCaps.IsSupportCEC) + { + Status = CBIOS_ER_HARDWARE_LIMITATION; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECTransmitMessage: Can't support CEC!")); + } + else if (pCECPara->CECIndex >= CBIOS_CEC_INDEX_COUNT) + { + Status = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECTransmitMessage: invalid CEC index!")); + } + else if (!pcbe->CECPara[pCECPara->CECIndex].CECEnable) + { + Status = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECTransmitMessage: CEC module is not enabled!")); + } + else + { + cb_memset(&CECMessage, 0, sizeof(CBIOS_CEC_MESSAGE)); + + CECMessage.SourceAddr = pcbe->CECPara[pCECPara->CECIndex].LogicalAddr; + CECMessage.DestAddr = pCECPara->DestAddr; + CECMessage.CmdLen = pCECPara->CmdLen; + if (CECMessage.CmdLen > 16) + { + CECMessage.CmdLen = 16; + } + cb_memcpy(CECMessage.Command, pCECPara->Command, CECMessage.CmdLen); + CECMessage.bBroadcast = pCECPara->bBroadcast; + CECMessage.RetryCnt = pCECPara->RetryCnt; + + Status = cbHWCECTransmitMessage(pcbe, &CECMessage, pCECPara->CECIndex); + } + + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosCECReceiveMessage(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_CEC_RECEIVE_MESSAGE_PARA pCECPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Status = CBIOS_OK; + CBIOS_CEC_MESSAGE CECMessage; + + if (pCECPara == CBIOS_NULL) + { + Status = CBIOS_ER_NULLPOINTER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECReceiveMessage: pCECPara is NULL!")); + } + else if (!pcbe->ChipCaps.IsSupportCEC) + { + Status = CBIOS_ER_HARDWARE_LIMITATION; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECReceiveMessage: Can't support CEC!")); + } + else if (pCECPara->CECIndex >= CBIOS_CEC_INDEX_COUNT) + { + Status = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECReceiveMessage: invalid CEC index!")); + } + else if (!pcbe->CECPara[pCECPara->CECIndex].CECEnable) + { + Status = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECReceiveMessage: CEC module is not enabled!")); + } + else + { + cb_memset(&CECMessage, 0, sizeof(CBIOS_CEC_MESSAGE)); + + Status = cbHWCECReceiveMessage(pcbe, &CECMessage, pCECPara->CECIndex); + + pCECPara->SourceAddr = CECMessage.SourceAddr; + pCECPara->CmdLen = CECMessage.CmdLen; + cb_memcpy(pCECPara->Command, CECMessage.Command, CECMessage.CmdLen); + pCECPara->bBroadcast = CECMessage.bBroadcast; + + } + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosCECGetInfo(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_OUT PCBIOS_CEC_INFO pCECInfo) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Status = CBIOS_OK; + + if (pCECInfo == CBIOS_NULL) + { + Status = CBIOS_ER_NULLPOINTER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECGetInfo: pCECInfo is NULL!")); + } + else if (!pcbe->ChipCaps.IsSupportCEC) + { + Status = CBIOS_ER_HARDWARE_LIMITATION; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECReceiveMessage: Can't support CEC!")); + } + else if (pCECInfo->CECIndex >= CBIOS_CEC_INDEX_COUNT) + { + Status = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECReceiveMessage: invalid CEC index!")); + } + else if (!pcbe->CECPara[pCECInfo->CECIndex].CECEnable) + { + Status = CBIOS_ER_INVALID_PARAMETER; + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "CBiosCECReceiveMessage: CEC module is not enabled!")); + } + else + { + pCECInfo->PhysicalAddr = pcbe->CECPara[pCECInfo->CECIndex].PhysicalAddr; + pCECInfo->LogicalAddr = pcbe->CECPara[pCECInfo->CECIndex].LogicalAddr; + } + + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetCECInterruptInfo(CBIOS_IN CBIOS_VOID* pvcbe, CBIOS_IN PCBIOS_CEC_INTERRUPT_INFO pCECIntInfo) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Status = CBIOS_OK; + Status = cbGetCECInterruptInfo(pcbe, pCECIntInfo); + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetMonitorTypePerPort(CBIOS_IN CBIOS_VOID* pvcbe,CBIOS_IN CBIOS_OUT PCBIOS_QUERY_MONITOR_TYPE_PER_PORT pCBiosQueryMonitorTypePerPort) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON) pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pCBiosQueryMonitorTypePerPort == CBIOS_NULL || pCBiosQueryMonitorTypePerPort->ActiveDevId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pCBiosQueryMonitorTypePerPort->ActiveDevId)]; + + if(pDevCommon == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDevCommon is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_NULLPOINTER; + } + + return cbDevGetSupportedMonitorType(pcbe, pDevCommon, pCBiosQueryMonitorTypePerPort); +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetDevComb(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_GET_DEV_COMB pGetDevComb) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON) pvcbe; + CBIOS_STATUS status; + + if(pGetDevComb != CBIOS_NULL && pGetDevComb->pDeviceComb != CBIOS_NULL) + { + status = cbPathMgrGetDevComb(pcbe, pGetDevComb); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "CBiosGetDevComb: pGetDevComb is CBIOS_NULL!\n")); + status = CBIOS_ER_NULLPOINTER; + } + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetIgaMask(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN CBIOS_OUT PCBIOS_GET_IGA_MASK pGetIgaMask) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON) pvcbe; + CBIOS_STATUS status; + + if(pGetIgaMask != CBIOS_NULL) + { + status = cbPathMgrGetIgaMask(pcbe, pGetIgaMask); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "CBiosGetIgaMask: pGetIgaMask is CBIOS_NULL!\n")); + status = CBIOS_ER_NULLPOINTER; + } + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetDeviceName(PCBIOS_VOID pvcbe, PCBIOS_GET_DEVICE_NAME pGetName) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON) pvcbe; + CBIOS_STATUS status; + + status = cbGetDeviceName(pcbe, pGetName); + + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetClock(PCBIOS_VOID pvcbe, PCBios_GetClock_Params pCBiosGetClockParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Status = CBIOS_OK; + Status = cbHWGetClockByType(pcbe, pCBiosGetClockParams); + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosSetClock(PCBIOS_VOID pvcbe, PCBios_SetClock_Params pCBiosSetClockParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Status = CBIOS_OK; + Status = cbHWSetClockByType(pcbe, pCBiosSetClockParams); + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetHDCPStatus(PCBIOS_VOID pvcbe, PCBIOS_HDCP_STATUS_PARA pCBiosHdcpStatusParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON) pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_U32 DeviceId; + + if(pCBiosHdcpStatusParams == CBIOS_NULL || pCBiosHdcpStatusParams->DevicesId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is CBIOS_NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + DeviceId = pCBiosHdcpStatusParams->DevicesId; + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(DeviceId)]; + + if(pDevCommon == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevGetHDCPStatus(pcbe, pDevCommon, pCBiosHdcpStatusParams); +} + +DLLEXPORTS CBIOS_STATUS +CBiosHDCPWorkThread(PCBIOS_VOID pvcbe, PCBIOS_HDCP_WORK_PARA pCBiosHdcpWorkParams) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON) pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + CBIOS_U32 i, DeviceId; + + if(pCBiosHdcpWorkParams == CBIOS_NULL || pCBiosHdcpWorkParams->DevicesId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + DeviceId = pCBiosHdcpWorkParams->DevicesId; + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(DeviceId)]; + + for(i = 0; i < pcbe->DispMgr.IgaCount; i++) + { + if(DeviceId == pcbe->DispMgr.ActiveDevices[i]) + { + break; + } + } + + if(pDevCommon == CBIOS_NULL || i == pcbe->DispMgr.IgaCount) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevHDCPWorkThread(pcbe, pDevCommon, (CBIOS_U8)i, pCBiosHdcpWorkParams); +} + +DLLEXPORTS CBIOS_STATUS +CBiosHDCPIsr(PCBIOS_VOID pvcbe, PCBIOS_HDCP_ISR_PARA pHdcpIsrParam) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pHdcpIsrParam == CBIOS_NULL || pHdcpIsrParam->DevicesId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pHdcpIsrParam->DevicesId)]; + if(pDevCommon == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevHDCPIsr(pcbe, pDevCommon, pHdcpIsrParam); +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetHDCPInterruptInfo(PCBIOS_VOID pvcbe, PCBIOS_HDCP_INFO_PARA pHdcpInfoParam) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status; + Status = cbGetHDCPInterruptInfo(pcbe, pHdcpInfoParam); + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetHDACInterruptInfo(PCBIOS_VOID pvcbe, PCBIOS_HDAC_INFO_PARA pHdacInfoParam) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS Status; + Status = cbGetHDACInterruptInfo(pcbe, pHdacInfoParam); + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosInterruptEnableDisable(PCBIOS_VOID pvcbe, PCBIOS_INT_ENABLE_DISABLE_PARA pIntPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Status; + + if(pIntPara != CBIOS_NULL) + { + Status = cbInterruptEnableDisable(pcbe, pIntPara); + } + else + { + Status = CBIOS_ER_INVALID_PARAMETER; + } + return Status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetInterruptInfo(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_INTERRUPT_INFO pIntInfo) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 Status; + + if(pIntInfo != CBIOS_NULL) + { + Status = cbGetInterruptInfo(pcbe, pIntInfo); + } + else + { + Status = CBIOS_ER_INVALID_PARAMETER; + } + return Status; +} + + + DLLEXPORTS CBIOS_STATUS +CBiosGetDPIntType(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_INT_PARA pDPIntPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pDPIntPara == CBIOS_NULL || pDPIntPara->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pDPIntPara->DeviceId)]; + if(pDevCommon == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevGetDPIntType(pcbe, pDevCommon, pDPIntPara); +} + +DLLEXPORTS CBIOS_STATUS +CBiosHandleDPIrq(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_HANDLE_IRQ_PARA pDPHandleIrqPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pDPHandleIrqPara == CBIOS_NULL || pDPHandleIrqPara->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pDPHandleIrqPara->DeviceId)]; + if(pDevCommon == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevDPHandleIrq(pcbe, pDevCommon, pDPHandleIrqPara); +} + +DLLEXPORTS CBIOS_STATUS +CBiosDumpInfo(PCBIOS_VOID pvcbe, PCBIOS_DUMP_PARA pDumpPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + CBIOS_STATUS status = CBIOS_ER_INTERNAL; + + if (pDumpPara != CBIOS_NULL) + { + if (cbHWDumpInfo(pcbe, pDumpPara->DumpType)) + { + status = CBIOS_OK; + } + else + { + status = CBIOS_ER_INTERNAL; + } + } + else + { + status = CBIOS_ER_NULLPOINTER; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pDumpPara is NULL", FUNCTION_NAME)); + } + + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosDPGetCustomizedTiming(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_CUSTOMIZED_TIMING pDPCustomizedTiming) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if(pDPCustomizedTiming == CBIOS_NULL || pDPCustomizedTiming->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pDPCustomizedTiming->DeviceId)]; + if(pDevCommon == CBIOS_NULL) + { + return CBIOS_ER_INVALID_PARAMETER; + } + + return cbDevDPGetCustomizedTiming(pcbe, pDevCommon, pDPCustomizedTiming); +} + +DLLEXPORTS CBIOS_STATUS +CBiosDPIsr(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_ISR_PARA pDPIsrPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if (pDPIsrPara == CBIOS_NULL || pDPIsrPara->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pDPIsrPara->DeviceId)]; + + return cbDevDPIsr(pcbe, pDevCommon, pDPIsrPara); +} + +DLLEXPORTS CBIOS_BOOL +CBiosDPWorkThreadMainFunc(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_WORKTHREAD_PARA pDPWorkThreadPara) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if (pDPWorkThreadPara == CBIOS_NULL || pDPWorkThreadPara->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_FALSE; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pDPWorkThreadPara->DeviceId)]; + + return cbDevDPWorkThreadMainFunc(pcbe, pDevCommon, pDPWorkThreadPara); +} + +DLLEXPORTS CBIOS_STATUS +CBiosDPSetNotifications(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN PCBIOS_DP_NOTIFICATIONS pDPNotifications) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + PCBIOS_DEVICE_COMMON pDevCommon = CBIOS_NULL; + + if (pDPNotifications == CBIOS_NULL || pDPNotifications->DeviceId == CBIOS_TYPE_NONE) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 2nd param is NULL!\n", FUNCTION_NAME)); + return CBIOS_ER_INVALID_PARAMETER; + } + + pDevCommon = pcbe->DeviceMgr.pDeviceArray[cbConvertDeviceBit2Index(pDPNotifications->DeviceId)]; + + return cbDevDPSetNotifications(pcbe, pDevCommon, pDPNotifications); +} + +DLLEXPORTS CBIOS_STATUS +CBiosWaitVBlank(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_IN CBIOS_U32 IGAIndex) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + return (CBIOS_TRUE == cbWaitVBlank(pcbe, (CBIOS_U8)IGAIndex)) ? CBIOS_OK : CBIOS_ER_INVALID_PARAMETER; +} + +DLLEXPORTS CBIOS_STATUS +CBiosVIPCtl(PCBIOS_VOID pvcbe, PCBIOS_VIP_CTRL_DATA pCbiosVIPCtlData) +{ + PCBIOS_EXTENSION_COMMON pcbe = pvcbe; + CBIOS_STATUS status = CBIOS_ER_INTERNAL; + + status = cbHWVIPCtl(pcbe, pCbiosVIPCtlData); + + return status; +} + +DLLEXPORTS CBIOS_STATUS +CBiosGetSliceNum(CBIOS_IN PCBIOS_VOID pvcbe, CBIOS_OUT PCBIOS_U8 pSliceNum, CBIOS_OUT PCBIOS_U32 pGPCReg) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_STATUS status = CBIOS_ER_INTERNAL; + CBIOS_U32 RegValue, i; + + *pSliceNum = pcbe->SliceNum; + + /* read GPC register value from efuse + step 1: write address 0x70 to MM82B8[22:16] + step 2: Using A_READ_MODE and Set Efuse_Read_Request bit in MM82C0[25] to start request. + HW will clear this bit after data of EUFSE has been put on MM82BC[31:0] + step 3: Read data from MM82BC[31:0] + */ + + cbMMIOWriteReg32(pcbe, 0x82B8, 0x700000, 0xFF80FFFF); + cbMMIOWriteReg32(pcbe, 0x82C0, 0x22000000, 0x81FFFFFF); + for (i = 0; i < 10; i++) + { + RegValue = cb_ReadU32(pcbe->pAdapterContext, 0x82C0); + if ((RegValue & 0x2000000) == 0) + { + status = CBIOS_OK; + break; + } + cb_DelayMicroSeconds(10); + } + + if (status == CBIOS_OK) + { + *pGPCReg = cb_ReadU32(pcbe->pAdapterContext, 0x82BC); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: read EFUSE GPC register failed!\n", FUNCTION_NAME)); + } + + return status; +} diff --git a/drivers/gpu/drm/arise/cbios/Util/CBiosEDID.c b/drivers/gpu/drm/arise/cbios/Util/CBiosEDID.c new file mode 100644 index 0000000000000..a6b7e6a5da547 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Util/CBiosEDID.c @@ -0,0 +1,3044 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + + +/***************************************************************************** +** DESCRIPTION: +** CBios EDID module interface function implementation. +** Parse the raw EDID data and store to the CBIOS_EDID_STRUCTURE_DATA. +** +** NOTE: +** ONLY EDID related and hw independent function can be added to this file. +******************************************************************************/ + +#include "CBiosChipShare.h" + +CBIOS_U8 PHL_24PFL3545_Edid[256] = +{ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x41, 0x0C, 0x10, 0x00, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x17, 0x01, 0x03, 0x80, 0x35, 0x1E, 0x78, 0x2A, 0x47, 0x89, 0xA3, 0x57, 0x47, 0x9F, 0x22, + 0x11, 0x48, 0x4C, 0xBF, 0xEF, 0x80, 0xB3, 0x00, 0x95, 0x00, 0x81, 0x80, 0x81, 0x40, 0x71, 0x4F, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C, + 0x45, 0x00, 0x09, 0x25, 0x21, 0x00, 0x00, 0x1E, 0x66, 0x21, 0x50, 0xB0, 0x51, 0x00, 0x1B, 0x30, + 0x40, 0x70, 0x36, 0x00, 0x09, 0x25, 0x21, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x37, + 0x4C, 0x1E, 0x52, 0x11, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, + 0x00, 0x42, 0x32, 0x34, 0x50, 0x46, 0x4C, 0x33, 0x35, 0x34, 0x35, 0x2F, 0x54, 0x33, 0x01, 0x31, + 0x02, 0x03, 0x22, 0xF2, 0x4F, 0x9F, 0x14, 0x13, 0x12, 0x11, 0x16, 0x15, 0x90, 0x05, 0x04, 0x03, + 0x02, 0x07, 0x06, 0x01, 0x23, 0x09, 0x07, 0x01, 0x83, 0x01, 0x00, 0x00, 0x65, 0x03, 0x0C, 0x00, + 0x10, 0x00, 0x02, 0x3A, 0x80, 0xD0, 0x72, 0x38, 0x2D, 0x40, 0x10, 0x2C, 0x45, 0x80, 0x09, 0x25, + 0x21, 0x00, 0x00, 0x1E, 0x01, 0x1D, 0x80, 0xD0, 0x72, 0x1C, 0x16, 0x20, 0x10, 0x2C, 0x25, 0x80, + 0x09, 0x25, 0x21, 0x00, 0x00, 0x9E, 0x01, 0x1D, 0x00, 0xBC, 0x52, 0xD0, 0x1E, 0x20, 0xB8, 0x28, + 0x55, 0x40, 0x09, 0x25, 0x21, 0x00, 0x00, 0x18, 0x8C, 0x0A, 0xD0, 0x90, 0x20, 0x40, 0x31, 0x20, + 0x0C, 0x40, 0x55, 0x00, 0x09, 0x25, 0x21, 0x00, 0x00, 0x18, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, + 0x2D, 0x40, 0x58, 0x2C, 0x45, 0x00, 0x09, 0x25, 0x21, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x26, +}; + +//RefRateIndex init to 0FFh, which means not legal index. +CBIOS_HDMI_FORMAT_MTX CEAVideoFormatTable[] = +{ +// 1:interlace 1: 4:3; 2: 16:9; 3: 64:27; 4: 256:135 +// Video interlace Aspect +// codes H V V freq Ratio + //normal VICs + {1, 640, 480, 0, { 6000, 5994}, 1, 1}, + {2, 720, 480, 0, { 6000, 5994}, 1, 1}, + {3, 720, 480, 0, { 6000, 5994}, 2, 1}, + {4, 1280, 720, 0, { 6000, 5994}, 2, 0}, + {5, 1920, 1080, 1, { 6000, 5994}, 2, 0}, + {6, 720, 480, 1, { 6000, 5994}, 1, 1}, + {7, 720, 480, 1, { 6000, 5994}, 2, 1}, + {8, 720, 240, 0, { 6000, 5994}, 1, 1}, + {9, 720, 240, 0, { 6000, 5994}, 2, 1}, + {10, 1440, 480, 1, { 6000, 5994}, 1, 1}, + {11, 1440, 480, 1, { 6000, 5994}, 2, 1}, + {12, 1440, 240, 0, { 6000, 5994}, 1, 1}, + {13, 1440, 240, 0, { 6000, 5994}, 2, 1}, + {14, 1440, 480, 0, { 6000, 5994}, 1, 1}, + {15, 1440, 480, 0, { 6000, 5994}, 2, 1}, + {16, 1920, 1080, 0, { 6000, 5994}, 2, 0}, + {17, 720, 576, 0, { 5000, 0000}, 1, 0}, + {18, 720, 576, 0, { 5000, 0000}, 2, 0}, + {19, 1280, 720, 0, { 5000, 0000}, 2, 0}, + {20, 1920, 1080, 1, { 5000, 0000}, 2, 0}, + {21, 720, 576, 1, { 5000, 0000}, 1, 0}, + {22, 720, 576, 1, { 5000, 0000}, 2, 0}, + {23, 720, 288, 0, { 5000, 0000}, 1, 0}, + {24, 720, 288, 0, { 5000, 0000}, 2, 0}, + {25, 1440, 576, 1, { 5000, 0000}, 1, 0}, + {26, 1440, 576, 1, { 5000, 0000}, 2, 0}, + {27, 1440, 288, 0, { 5000, 0000}, 1, 0}, + {28, 1440, 288, 0, { 5000, 0000}, 2, 0}, + {29, 1440, 576, 0, { 5000, 0000}, 1, 0}, + {30, 1440, 576, 0, { 5000, 0000}, 2, 0}, + {31, 1920, 1080, 0, { 5000, 0000}, 2, 0}, + {32, 1920, 1080, 0, { 2400, 2397}, 2, 0}, + {33, 1920, 1080, 0, { 2500, 0000}, 2, 0}, + {34, 1920, 1080, 0, { 3000, 2997}, 2, 0}, + {35, 2880, 480, 0, { 6000, 5994}, 1, 1}, + {36, 2880, 480, 0, { 6000, 5994}, 2, 1}, + {37, 2880, 576, 0, { 5000, 0000}, 1, 0}, + {38, 2880, 576, 0, { 5000, 0000}, 2, 0}, + {39, 1920, 1080 ,1, { 5000, 0000}, 2, 0}, + {40, 1920, 1080, 1, {10000, 0000}, 2, 0}, + {41, 1280, 720, 0, {10000, 0000}, 2, 0}, + {42, 720, 576, 0, {10000, 0000}, 1, 0}, + {43, 720, 576, 0, {10000, 0000}, 2, 0}, + {44, 720, 576, 1, {10000, 0000}, 1, 0}, + {45, 720, 576, 1, {10000, 0000}, 2, 0}, + {46, 1920, 1080, 1, {12000,11988}, 2, 0}, + {47, 1280, 720, 0, {12000,11988}, 2, 0}, + {48, 720, 480, 0, {12000,11988}, 1, 1}, + {49, 720, 480, 0, {12000,11988}, 2, 1}, + {50, 720, 480, 1, {12000,11988}, 1, 1}, + {51, 720, 480, 1, {12000,11988}, 2, 1}, + {52, 720, 576, 0, {20000, 0000}, 1, 0}, + {53, 720, 576, 0, {20000, 0000}, 2, 0}, + {54, 720, 576, 1, {20000, 0000}, 1, 0}, + {55, 720, 576, 1, {20000, 0000}, 2, 0}, + {56, 720, 480, 0, {24000,23976}, 1, 1}, + {57, 720, 480, 0, {24000,23976}, 2, 1}, + {58, 720, 480, 1, {24000,23976}, 1, 1}, + {59, 720, 480, 1, {24000,23976}, 2, 1}, + {60, 1280, 720, 0, { 2400, 2398}, 2, 0}, + {61, 1280, 720, 0, { 2500, 0000}, 2, 0}, + {62, 1280, 720, 0, { 3000, 2997}, 2, 0}, + {63, 1920, 1080, 0, {12000,11988}, 2, 0}, + {64, 1920, 1080, 0, {10000, 0000}, 2, 0}, +// CEA-861-F + {65, 1280, 720, 0, { 2400, 2398}, 3, 0}, + {66, 1280, 720, 0, { 2500, 0000}, 3, 0}, + {67, 1280, 720, 0, { 3000, 2997}, 3, 0}, + {68, 1280, 720, 0, { 5000, 0000}, 3, 0}, + {69, 1280, 720, 0, { 6000, 5994}, 3, 0}, + {70, 1280, 720, 0, {10000, 0000}, 3, 0}, + {71, 1280, 720, 0, {12000,11988}, 3, 0}, + {72, 1920, 1080, 0, { 2400, 2398}, 3, 0}, + {73, 1920, 1080, 0, { 2500, 0000}, 3, 0}, + {74, 1920, 1080, 0, { 3000, 2997}, 3, 0}, + {75, 1920, 1080, 0, { 5000, 0000}, 3, 0}, + {76, 1920, 1080, 0, { 6000, 5994}, 3, 0}, + {77, 1920, 1080, 0, {10000, 0000}, 3, 0}, + {78, 1920, 1080, 0, {12000,11988}, 3, 0}, + {79, 1680, 720, 0, { 2400, 2398}, 3, 0}, + {80, 1680, 720, 0, { 2500, 0000}, 3, 0}, + {81, 1680, 720, 0, { 3000, 2997}, 3, 0}, + {82, 1680, 720, 0, { 5000, 0000}, 3, 0}, + {83, 1680, 720, 0, { 6000, 5994}, 3, 0}, + {84, 1680, 720, 0, {10000, 0000}, 3, 0}, + {85, 1680, 720, 0, {12000,11988}, 3, 0}, + {86, 2560, 1080, 0, { 2400, 2398}, 3, 0}, + {87, 2560, 1080, 0, { 2500, 0000}, 3, 0}, + {88, 2560, 1080, 0, { 3000, 2997}, 3, 0}, + {89, 2560, 1080, 0, { 5000, 0000}, 3, 0}, + {90, 2560, 1080, 0, { 6000, 5994}, 3, 0}, + {91, 2560, 1080, 0, {10000, 0000}, 3, 0}, + {92, 2560, 1080, 0, {12000,11988}, 3, 0}, + {93, 3840, 2160, 0, { 2400, 2398}, 2, 0}, + {94, 3840, 2160, 0, { 2500, 0000}, 2, 0}, + {95, 3840, 2160, 0, { 3000, 2997}, 2, 0}, + {96, 3840, 2160, 0, { 5000, 0000}, 2, 0}, + {97, 3840, 2160, 0, { 6000, 5994}, 2, 0}, + {98, 4096, 2160, 0, { 2400, 2398}, 4, 0}, + {99, 4096, 2160, 0, { 2500, 0000}, 4, 0}, + {100,4096, 2160, 0, { 3000, 2997}, 4, 0}, + {101,4096, 2160, 0, { 5000, 0000}, 4, 0}, + {102,4096, 2160, 0, { 6000, 5994}, 4, 0}, + {103,3840, 2160, 0, { 2400, 2398}, 3, 0}, + {104,3840, 2160, 0, { 2500, 0000}, 3, 0}, + {105,3840, 2160, 0, { 3000, 2997}, 3, 0}, + {106,3840, 2160, 0, { 5000, 0000}, 3, 0}, + {107,3840, 2160, 0, { 6000, 5994}, 3, 0}, + + //normal VIC end + //extened VIC begin + { CBIOS_HDMI_NORMAL_VIC_COUNTS + 1, 3840, 2160, 0, { 3000, 2997}, 2, 0}, + { CBIOS_HDMI_NORMAL_VIC_COUNTS + 2, 3840, 2160, 0, { 2500, 0000}, 2, 0}, + { CBIOS_HDMI_NORMAL_VIC_COUNTS + 3, 3840, 2160, 0, { 2400, 2397}, 2, 0}, + { CBIOS_HDMI_NORMAL_VIC_COUNTS + 4, 4096, 2160, 0, { 2400, 0000}, 2, 0}, + //extened VIC end + +}; + +static DETAILEDTIMING_TABLE EDIDPixelClock[]= { + {EDIDTIMING,0x00,0xFF}, + {EDIDTIMING,0x01,0xFF}, + {EDIDTIMINGEXIT,}, +}; +static DETAILEDTIMING_TABLE EDIDHorizontalActive[] = { + {EDIDTIMING,0x02,0xFF}, + {EDIDTIMING,0X04,0XF0}, + {EDIDTIMINGEXIT,}, +}; +static DETAILEDTIMING_TABLE EDIDHorizontalBlanking[] = { + {EDIDTIMING,0x03,0xFF}, + {EDIDTIMING,0X04,0X0F}, + {EDIDTIMINGEXIT,}, +}; +static DETAILEDTIMING_TABLE EDIDVerticalActive[] = { + {EDIDTIMING,0x05,0xFF}, + {EDIDTIMING,0X07,0XF0}, + {EDIDTIMINGEXIT,}, +}; +static DETAILEDTIMING_TABLE EDIDVerticalBlanking[] = { + {EDIDTIMING,0x06,0xFF}, + {EDIDTIMING,0X07,0X0F}, + {EDIDTIMINGEXIT,}, +}; +static DETAILEDTIMING_TABLE EDIDHorizontalSyncOffset[] = { + {EDIDTIMING,0x08,0xFF}, + {EDIDTIMING,0x0B,0xC0}, + {EDIDTIMINGEXIT,}, +}; +static DETAILEDTIMING_TABLE EDIDHorizontalSyncPulseWidth[] = { + {EDIDTIMING,0x09,0xFF}, + {EDIDTIMING,0x0B,0x30}, + {EDIDTIMINGEXIT,}, +}; +static DETAILEDTIMING_TABLE EDIDVerticalSyncOffset[] = { + {EDIDTIMING,0x0A,0xF0}, + {EDIDTIMING,0x0B,0x0C}, + {EDIDTIMINGEXIT,}, +}; +static DETAILEDTIMING_TABLE EDIDVerticalSyncPulseWidth[] = { + {EDIDTIMING,0x0A,0x0F}, + {EDIDTIMING,0x0B,0x03}, + {EDIDTIMINGEXIT,}, +}; +// The following is just for DTV +static DETAILEDTIMING_TABLE EDIDHorizontalImageSize[] = { + {EDIDTIMING,0x0C,0xFF}, + {EDIDTIMING,0x0E,0xF0}, + {EDIDTIMINGEXIT,}, +}; +static DETAILEDTIMING_TABLE EDIDVerticalImageSize[] = { + {EDIDTIMING,0x0D,0xFF}, + {EDIDTIMING,0x0E,0x0F}, + {EDIDTIMINGEXIT,}, +}; +/* +static DETAILEDTIMING_TABLE EDIDIsInterlaced[] = { + {EDIDTIMING,0x11,0x80}, + {EDIDTIMINGEXIT,}, +}; +*/ +static CBIOS_Module_EDID_ESTTIMINGS EstTiming1[] = { + { 0x320, 0x258, 6000},// EDID23h[0]: 800x600@60Hz + { 0x320, 0x258, 5600},// EDID23h[1]: 800x600@56Hz + { 0x280, 0x1E0, 7500},// EDID23h[2]: 640x480@75Hz + { 0x280, 0x1E0, 7200},// EDID23h[3]: 640x480@72Hz + { 0x280, 0x1E0, 6700},// EDID23h[4]: 640x480@67Hz + { 0x280, 0x1E0, 6000},// EDID23h[5]: 640x480@60Hz + { 0x2D0, 0x190, 8800},// EDID23h[6]: 720x400@88Hz + { 0x2D0, 0x190, 7000},// EDID23h[7]: 720x400@70Hz +}; +static CBIOS_Module_EDID_ESTTIMINGS EstTiming2[] = { + { 0x500, 0x400, 7500},// EDID24h[0]: 1280x1024@75Hz + { 0x400, 0x300, 7500},// EDID24h[1]: 1024x768@75Hz + { 0x400, 0x300, 7000},// EDID24h[2]: 1024x768@70Hz + { 0x400, 0x300, 6000},// EDID24h[3]: 1024x768@60Hz + { 0x400, 0x300, 8700},// EDID24h[4]: 1024x768@87HzInterlace + { 0x340, 0x270, 7500},// EDID24h[5]: 832x624@75Hz + { 0x320, 0x258, 7500},// EDID24h[6]: 800x600@75Hz + { 0x320, 0x258, 7200},// EDID24h[7]: 800x600@72Hz +}; +static CBIOS_Module_EDID_ESTTIMINGS EstTiming3[] = { + { 0x480, 0x366, 7500},// EDID25h[7]: 1152x870@75Hz +}; + +static CBIOS_BOOL cbEDIDModule_GetFmtIdxFromSVD(CBIOS_U8 SVD, CBIOS_U8 *pFormatIdx, CBIOS_BOOL *pIsNative) +{ + CBIOS_BOOL bRet = CBIOS_TRUE; + + *pIsNative = CBIOS_FALSE; +/* +According to CEA-861-F: + If SVD >=1 and SVD <=64 then + 7-bit VIC is defined (7-LSB\u2019s) and NOT a native code + Elseif SVD >=65 and SVD <=127 then + 8-bit VIC is defined (from first new set) + Elseif SVD >=129 and SVD <=192 then + 7-bit VIC is defined (7-LSB\u2019s) and IS a native code + Elseif SVD >=193 and SVD <=253 then + 8-bit VIC is defined (from second new set) + Elseif SVD == 0/128/254/255 then + Reserved + End if +*/ + if (SVD >=1 && SVD <= 64) + { + *pFormatIdx = SVD & 0x7F; + } + else if (SVD >= 65 && SVD <= 127) + { + *pFormatIdx = SVD; + } + else if (SVD >= 129 && SVD <= 192) + { + *pFormatIdx = SVD & 0x7F; + *pIsNative = CBIOS_TRUE; + } + else if ((SVD >= 193) && (SVD <= 253)) + { + *pFormatIdx = SVD; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEDIDModule_GetFmtIdxFromSVD: SVD = %d which is a reserved SVD code\n", SVD)); + bRet = CBIOS_FALSE; + } + + if ((*pFormatIdx == 0) || (*pFormatIdx > CBIOS_HDMI_NORMAL_VIC_COUNTS)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEDIDModule_GetFmtIdxFromSVD: FormatIdx = %d which is invalid\n", *pFormatIdx)); + bRet = CBIOS_FALSE; + } + + return bRet; +} + +static CBIOS_U32 cbEDIDModule_MapMaskGetEdidInfo(CBIOS_U8* DetailedTimings, CBIOS_U32 Base, DETAILEDTIMING_TABLE* TimingTable) +{ + CBIOS_U32 uRet = 0; + CBIOS_U8 byRegValue = 0; + DETAILEDTIMING_TABLE *reg = TimingTable; + CBIOS_U32 i,j=0; + + while(reg->type != EDIDTIMINGEXIT) + { + byRegValue = DetailedTimings[18*Base + reg->index]; + for(i = 0;i<8;i++) + { + if( reg->mask & 1<PixelClock = + cbEDIDModule_MapMaskGetEdidInfo(pEdidDtlData,0,EDIDPixelClock)*100; + if(pDtlTiming->PixelClock == 0) + { + pDtlTiming->Valid = 0; + bRet = CBIOS_FALSE; + } + else + { + pDtlTiming->Valid = 1; + bRet = CBIOS_TRUE; + pDtlTiming->HActive = + (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pEdidDtlData,0,EDIDHorizontalActive); + pDtlTiming->HSyncOffset = + (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pEdidDtlData,0,EDIDHorizontalSyncOffset); + pDtlTiming->HSyncPulseWidth = + (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pEdidDtlData,0,EDIDHorizontalSyncPulseWidth); + pDtlTiming->HBlank = + (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pEdidDtlData,0,EDIDHorizontalBlanking); + + pDtlTiming->VActive = + (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pEdidDtlData,0,EDIDVerticalActive); + pDtlTiming->VSyncOffset = + (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pEdidDtlData,0,EDIDVerticalSyncOffset); + pDtlTiming->VSyncPulseWidth = + (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pEdidDtlData,0,EDIDVerticalSyncPulseWidth); + pDtlTiming->VBlank = + (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pEdidDtlData,0,EDIDVerticalBlanking); + pDtlTiming->HImageSize = + (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pEdidDtlData,0,EDIDHorizontalImageSize); + pDtlTiming->VImageSize = + (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pEdidDtlData,0,EDIDVerticalImageSize); + + if((pDtlTiming->HActive == 0 )|| (pDtlTiming->VActive == 0)) + { + pDtlTiming->Valid = 0; + bRet = CBIOS_FALSE; + } + else + { + if(pDtlTiming->VImageSize != 0) // Prevent being divided by zero + { + Ratio = (CBIOS_U16)((CBIOS_U32)(pDtlTiming->HImageSize * 10000) / pDtlTiming->VImageSize); + + if((Ratio>13000) && (Ratio<14000)) // 4:3 + pDtlTiming->AspectRatio = 1; + else //16:9 + pDtlTiming->AspectRatio = 2; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbEDIDModule_ParseDtlTiming: fata error -- pDtlTiming->VImageSize is ZERO!!!\n")); + pDtlTiming->AspectRatio = 2; + } + + // HSync = 1, means HSync is positive. + // else, means negative. the same as VSync. + if((pEdidDtlData[0x11]&0x18) == 0x18) + { + //V polarity + if((pEdidDtlData[0x11]&0x04) == 0x04) + pDtlTiming->VSync = VerPOSITIVE; + else + pDtlTiming->VSync = VerNEGATIVE; + + //H polarity + if((pEdidDtlData[0x11]&0x02) == 0x02) + pDtlTiming->HSync = HorPOSITIVE; + else + pDtlTiming->HSync = HorNEGATIVE; + } + else + { + pDtlTiming->HSync = HorNEGATIVE; + pDtlTiming->VSync = VerNEGATIVE; + } + + // Prevent being divided by zero + if ((pDtlTiming->HActive + pDtlTiming->HBlank) == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbEDIDModule_ParseDtlTiming: fata error -- (pDtlTiming->HActive + pDtlTiming->HBlank) is ZERO!!!\n")); + return CBIOS_FALSE; + } + if ((pDtlTiming->VActive + pDtlTiming->VBlank) == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbEDIDModule_ParseDtlTiming: fata error -- (pDtlTiming->VActive + pDtlTiming->VBlank) is ZERO!!!\n")); + return CBIOS_FALSE; + } + + pDtlTiming->Refreshrate = cbCalcRefreshRate(pDtlTiming->PixelClock, + pDtlTiming->HActive, + pDtlTiming->HBlank, + pDtlTiming->VActive, + pDtlTiming->VBlank); + + //Adjust refreshrate, for CEA mode, CBIOS will add the 5994Hz mode + //in the end of cbModeModule_GetDeviceMode + pDtlTiming->Refreshrate = 100 * cbRound(pDtlTiming->Refreshrate, 100, ROUND_NEAREST); + + if(pEdidDtlData[0x11]&0x80) + { + pDtlTiming->InterLaced = CBIOS_TRUE; + pDtlTiming->VActive *= 2; + pDtlTiming->VBlank *=2; + pDtlTiming->VBlank += 1; + pDtlTiming->VSyncOffset *= 2; + pDtlTiming->VSyncPulseWidth *= 2; + } + else + { + pDtlTiming->InterLaced = CBIOS_FALSE; + } + } + } + if(!bRet) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),"cbEDIDModule_ParseDtlTiming: Dtl Timing invalid!\n")); + } + + return bRet; +} + +/*************************************************************** +Function: cbEDIDModule_GetEstablishMode + +Description: Get EDID establish mode + +Input: pEDID, EDID data buffer + +Output: pEstablishMode, statistic establish mode in EDID + +Return: the number of establish mode supported in EDID +***************************************************************/ +static CBIOS_U32 cbEDIDModule_GetEstablishMode(CBIOS_U8 *pEDID, PCBIOS_MODE_INFO pEstablishMode) +{ + CBIOS_U32 ulNumOfEstMode = 0; + CBIOS_U32 i = 0; + CBIOS_U32 ulMask = 0x01; + CBIOS_U8 *pEstTimingsInEDID = pEDID + ESTABLISH_TIMINGS_INDEX; + + + for(i=0; i<8; i++) + { + if( *pEstTimingsInEDID & ulMask ) + { + ulNumOfEstMode++; + pEstablishMode[i].Valid = 1; + pEstablishMode[i].XResolution = EstTiming1[i].XResolution; + pEstablishMode[i].YResolution = EstTiming1[i].YResolution; + pEstablishMode[i].Refreshrate = EstTiming1[i].RefreshRate; + } + else + { + pEstablishMode[i].Valid = 0; + } + ulMask = ulMask << 1; + } + + ulMask = 0x01; + for(i=0; i<8; i++) + { + if( *(pEstTimingsInEDID+1) & ulMask ) + { + ulNumOfEstMode++; + pEstablishMode[i+8].Valid = 1; + pEstablishMode[i+8].XResolution = EstTiming2[i].XResolution; + pEstablishMode[i+8].YResolution = EstTiming2[i].YResolution; + pEstablishMode[i+8].Refreshrate = EstTiming2[i].RefreshRate; + } + else + { + pEstablishMode[i+8].Valid = 0; + } + ulMask = ulMask << 1; + } + + ulMask = 0x80; + if ( *(pEstTimingsInEDID+2) & ulMask ) + { + ulNumOfEstMode++; + pEstablishMode[16].Valid = 1; + pEstablishMode[16].XResolution = EstTiming3[0].XResolution; + pEstablishMode[16].YResolution = EstTiming3[0].YResolution; + pEstablishMode[16].Refreshrate = EstTiming3[0].RefreshRate; + } + else + { + pEstablishMode[16].Valid = 0; + } + + return ulNumOfEstMode; +} + +/*************************************************************** +Function: cbEDIDModule_GetStandardMode + +Description: Get EDID standard mode + +Input: pEDID, EDID data buffer + +Output: pStandardMode, statistic standard mode in EDID + +Return: the number of standard mode supported in EDID +***************************************************************/ +static CBIOS_U32 cbEDIDModule_GetStandardMode(CBIOS_U8 *pEDID, PCBIOS_MODE_INFO pStandardMode) +{ + CBIOS_U32 ulNumOfStdMode = 0; + CBIOS_U32 i = 0; + CBIOS_U8 *pStdTimingsInEDID = pEDID + STANDARD_TIMINGS_INDEX; + + for ( i=0; i<8; i++) + { + if ((*(pStdTimingsInEDID + i*2) == 0x01) || + (*(pStdTimingsInEDID + i*2) == 0x00)) + { + pStandardMode[i].Valid = 0; + continue; + } + + ulNumOfStdMode++; + pStandardMode[i].Valid = 1; + pStandardMode[i].XResolution = (CBIOS_U16)(*(pStdTimingsInEDID + i*2) + 31) * 8; + pStandardMode[i].Refreshrate = ((*(pStdTimingsInEDID + i*2 + 1) & 0x3F) + 60) * 100; + + switch((*(pStdTimingsInEDID + i*2 + 1) & 0xC0) >> 6) //Image Aspect Ratio + { + case 0: // 16:10 AR + pStandardMode[i].YResolution = pStandardMode[i].XResolution*10 / 16 * 10 /10; + break; + case 1: // 4:3 AR + pStandardMode[i].YResolution = pStandardMode[i].XResolution*10 / 4 * 3 /10; + break; + case 2: // 5:4 AR + pStandardMode[i].YResolution = pStandardMode[i].XResolution*10 / 5 * 4 /10; + break; + case 3: // 16:9 AR + pStandardMode[i].YResolution = pStandardMode[i].XResolution*10 / 16 * 9 /10; + break; + } + } + + return ulNumOfStdMode; +} + +/*************************************************************** +Function: cbEDIDModule_GetDetailedMode + +Description: Get detailed timings in base EDID + +Input: pEDID, EDID data buffer + byTotalModeNum, specify how many 18 byte data blocks want to parse + +Output: pDetailedMode, statistic detailed timings in base EDID + +Return: the number of detailed timings get in base EDID +***************************************************************/ +static CBIOS_U32 cbEDIDModule_GetDetailedMode(CBIOS_U8 *pEDID, PCBIOS_MODE_INFO_EXT pDetailedMode, CBIOS_U32 byTotalModeNum) +{ + CBIOS_U32 ulNumOfDtlMode = 0; + CBIOS_U32 i = 0; + CBIOS_U8 *pDtlTimingsInBaseEDID = pEDID + DETAILED_TIMINGS_INDEX; + + //get detailed timings in base EDID 18 byte data blocks + for(i = 0; i < byTotalModeNum; i++, pDtlTimingsInBaseEDID += 18) + { + if (pDtlTimingsInBaseEDID + 18 > pEDID + 128) + { + break; + } + + if(!cbEDIDModule_ParseDtlTiming(pDtlTimingsInBaseEDID, &pDetailedMode[i])) + { + continue; + } + + ulNumOfDtlMode++; + } + + return ulNumOfDtlMode; +} + +/*************************************************************** +Function: cbEDIDModule_GetCEADetailedMode + +Description: Get detailed timing descriptor in CEA extension + +Input: pEDID, EDID data buffer + +Output: pExtDtlMode, statistic detailed timings in CEA extension + +Return: the number of detailed timings get in CEA extension +***************************************************************/ +static CBIOS_U32 cbEDIDModule_GetCEADetailedMode(CBIOS_U8 *pEDID, PCBIOS_MODE_INFO_EXT pCEADtlMode, CBIOS_U32 TotalBlocks) +{ + CBIOS_U32 ulNumOfExtDtlMode = 0; + CBIOS_U32 i, j = 0; + CBIOS_U32 BlockIndex = 0; + CBIOS_U8 DtlTimingOffset = 0; // Detailed Timing Descriptor offset in extension block + CBIOS_U8 *pEDIDBlock = CBIOS_NULL; + CBIOS_BOOL isNeedPixelRep = CBIOS_FALSE; + CBIOS_BOOL isCEAMode = CBIOS_FALSE; + CBIOS_MODE_INFO_EXT tmpExtDltTiming; + + if (TotalBlocks > MAX_EDID_BLOCK_NUM) + { + // TBD: support for more than 8 blocks + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEDIDModule_GetCEADetailedMode: Total %d blocks but currently only parse 8 blocks!\n", TotalBlocks)); + //ASSERT(CBIOS_FALSE); + + TotalBlocks = MAX_EDID_BLOCK_NUM; + } + + //get detailed timings in CEA extension + for (BlockIndex = 1; BlockIndex < TotalBlocks; BlockIndex++) + { + pEDIDBlock = pEDID + BlockIndex * 128; + + //check CEA Tag + if (pEDIDBlock[0x00] != CEA_TAG) + { + continue; + } + + DtlTimingOffset = pEDIDBlock[0x02]; + if (DtlTimingOffset == 0) + { + //no detailed timing block, no reserved data block + continue; + } + + // Parse the extension detailed timing descriptors + i = DtlTimingOffset; + while ((i + 18) < 128) + { + cb_memset(&tmpExtDltTiming, 0, sizeof(CBIOS_MODE_INFO_EXT)); + if (!cbEDIDModule_ParseDtlTiming(&pEDIDBlock[i], &tmpExtDltTiming)) + { + break; + } + else + { + //Check pixel repetition + //For CEA format 6~9, 21~24, horizontal timing stored in EDID is doubled, so we should add /2 patch to get the real timing + if (tmpExtDltTiming.HActive == 1440)//check horizontal resolution. Since we only support 2 times pixel repetition, so xres == 1440 + { + if ((tmpExtDltTiming.InterLaced && ((tmpExtDltTiming.VActive == 480) || (tmpExtDltTiming.VActive == 576))) //720x480i & 720x576i + ||((!tmpExtDltTiming.InterLaced) && ((tmpExtDltTiming.VActive == 240) || (tmpExtDltTiming.VActive == 288))))//720x240p & 720x288p + { + isNeedPixelRep = CBIOS_TRUE; + tmpExtDltTiming.HActive /= 2; + } + } + + //check whether it's CEA mode. + for(j = 0; j < sizeofarray(CEAVideoFormatTable); j++) + { + if((tmpExtDltTiming.HActive == CEAVideoFormatTable[j].XRes)&& + (tmpExtDltTiming.VActive == CEAVideoFormatTable[j].YRes)&& + (tmpExtDltTiming.InterLaced == CEAVideoFormatTable[j].Interlace)&& + (tmpExtDltTiming.AspectRatio == CEAVideoFormatTable[j].AspectRatio)&& + (((tmpExtDltTiming.Refreshrate / 100) == (CEAVideoFormatTable[j].RefRate[0] / 100))|| + ((tmpExtDltTiming.Refreshrate / 100) == (CEAVideoFormatTable[j].RefRate[1] / 100)))) + { + isCEAMode = CBIOS_TRUE; + break; + } + } + + //If current mode is not CEA mode, we will not enable pixel repetition, so restore HActive back. + if ((!isCEAMode) && isNeedPixelRep) + { + isNeedPixelRep = CBIOS_FALSE; + tmpExtDltTiming.HActive *= 2; + } + + cb_memcpy(&pCEADtlMode[ulNumOfExtDtlMode++], &tmpExtDltTiming, sizeof(CBIOS_MODE_INFO_EXT)); + + } + i += 18; + } + + } + + return ulNumOfExtDtlMode; +} + +/*************************************************************** +Function: cbEDIDModule_GetSVDMode + +Description: Get short video descriptor in video data block of CEA extension + +Input: pSVDDataInEDID, short video descriptor data buffer + BlockIndex, the index of data block + +Output: pEDIDStruct, statistic video format in short video descriptor and SVD data block + +Return: the number of video format get in short video descriptor +***************************************************************/ +static CBIOS_U32 cbEDIDModule_GetSVDMode(CBIOS_U8 *pSVDDataInEDID, PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct, CBIOS_U32 BlockIndex) +{ + CBIOS_U32 ulNumOfSVDMode = 0; + CBIOS_U32 PayloadLength = 0; + PCBIOS_HDMI_FORMAT_DESCRIPTOR pCEAVideoFormat = CBIOS_NULL; + CBIOS_U32 j = 0; + CBIOS_U8 SVD = 0; + CBIOS_BOOL IsNative = CBIOS_FALSE; + CBIOS_BOOL Status = CBIOS_FALSE; + + //decode short video descriptor + PayloadLength = pSVDDataInEDID[0] & 0x1F; + + pEDIDStruct->Attribute.SVDData[BlockIndex - 1].SVDCount = (CBIOS_U8)PayloadLength; + cb_memcpy(pEDIDStruct->Attribute.SVDData[BlockIndex - 1].SVD, &pSVDDataInEDID[1], PayloadLength); + + pCEAVideoFormat = pEDIDStruct->HDMIFormat; + for (j = 0; j < PayloadLength; j++) + { + CBIOS_U8 FormatNum = 0; + + SVD = pSVDDataInEDID[1 + j]; + Status = cbEDIDModule_GetFmtIdxFromSVD(SVD, &FormatNum, &IsNative); + if (!Status) + { + continue; + } + + //for formats listed in SVD, use default refresh rate + pCEAVideoFormat[FormatNum - 1].RefreshIndex = CEAVideoFormatTable[FormatNum - 1].DefaultRefRateIndex; + + if (!pCEAVideoFormat[FormatNum - 1].IsSupported) + { + pCEAVideoFormat[FormatNum - 1].BlockIndex = (CBIOS_U8)BlockIndex; + pCEAVideoFormat[FormatNum - 1].IsSupported = CBIOS_TRUE; + pCEAVideoFormat[FormatNum - 1].IsNative = (IsNative == CBIOS_TRUE)? 1 : 0; + ulNumOfSVDMode++; + } + } + + return ulNumOfSVDMode; +} + +/*************************************************************** +Function: cbEDIDModule_GetSVDMode + +Description: Get short audio descriptor in audio data block of CEA extension + +Input: pAudioFormatDataInEDID, short audio descriptor data buffer + +Output: pCEAAudioFormat, statistic audio format in short audio descriptor + +Return: the number of audio format get in short audio descriptor +***************************************************************/ +static CBIOS_U32 cbEDIDModule_GetHDMIAudioFormat(CBIOS_U8 *pAudioFormatDataInEDID, PCBIOS_HDMI_AUDIO_INFO pCEAAudioFormat) +{ + CBIOS_U32 ulNumOfAudioFormat = 0; + CBIOS_U32 PayloadLength = 0; + CBIOS_U32 AudioFormatCode = 0; + CBIOS_U32 MaxBitRateIndex = 0; + CBIOS_U32 j = 0; + + //decode short video descriptor + PayloadLength = pAudioFormatDataInEDID[0] & 0x1F; + + for (j = 0; j < PayloadLength/3; j++) + { + AudioFormatCode = (pAudioFormatDataInEDID[1 + j * 3] >> 3) & 0xF; + if ((AudioFormatCode > 0) && (AudioFormatCode < 16)) + { + if (AudioFormatCode < 15) + { + pCEAAudioFormat[ulNumOfAudioFormat].Format = AudioFormatCode; + } + + pCEAAudioFormat[ulNumOfAudioFormat].MaxChannelNum = (pAudioFormatDataInEDID[1 + j * 3] & 0x7) + 1; + pCEAAudioFormat[ulNumOfAudioFormat].SampleRateUnit = pAudioFormatDataInEDID[2 + j * 3] & 0x7F; + if (AudioFormatCode == 1) + { + pCEAAudioFormat[ulNumOfAudioFormat].BitDepth.BD_16bit = pAudioFormatDataInEDID[3 + j * 3] & 0x1; + pCEAAudioFormat[ulNumOfAudioFormat].BitDepth.BD_20bit = (pAudioFormatDataInEDID[3 + j * 3] >> 1) & 0x1; + pCEAAudioFormat[ulNumOfAudioFormat].BitDepth.BD_24bit = (pAudioFormatDataInEDID[3 + j * 3] >> 2) & 0x1; + } + else if (AudioFormatCode <= 8) + { + MaxBitRateIndex = pAudioFormatDataInEDID[3 + j * 3]; + pCEAAudioFormat[ulNumOfAudioFormat].MaxBitRate = MaxBitRateIndex * 8; + } + else if (AudioFormatCode <= 13) + { + pCEAAudioFormat[ulNumOfAudioFormat].AudioFormatDependValue = pAudioFormatDataInEDID[3 + j * 3]; + } + else if (AudioFormatCode == 14) + { + pCEAAudioFormat[ulNumOfAudioFormat].Profile.Value = pAudioFormatDataInEDID[3 + j * 3] & 0x7; + } + else + { + if (((pAudioFormatDataInEDID[3 + j * 3] >> 3) & 0x1F) == 1) + { + pCEAAudioFormat[ulNumOfAudioFormat].Format = CBIOS_AUDIO_FORMAT_HE_AAC; + } + else if(((pAudioFormatDataInEDID[3 + j * 3] >> 3) & 0x1F) == 2) + { + pCEAAudioFormat[ulNumOfAudioFormat].Format = CBIOS_AUDIO_FORMAT_HE_AAC_V2; + } + else if(((pAudioFormatDataInEDID[3 + j * 3] >> 3) & 0x1F) == 3) + { + pCEAAudioFormat[ulNumOfAudioFormat].Format = CBIOS_AUDIO_FORMAT_MPEG_SURROUND; + } + } + + ulNumOfAudioFormat++; + } + } + + return ulNumOfAudioFormat; +} + +static CBIOS_VOID cbEDIDPatchHDMIAudio(PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct, PCBIOS_HDMI_AUDIO_INFO pCEAAudioFormat) +{ + CBIOS_U32 i = 0; + CBIOS_U32 AudioFormatNum; + CBIOS_BOOL PcmSupport = CBIOS_FALSE; + AudioFormatNum = pEDIDStruct->TotalHDMIAudioFormatNum; + + if(!pEDIDStruct->Attribute.IsCEA861Audio) + { + return; + } + for(i = 0; i < AudioFormatNum; i++) + { + if(pCEAAudioFormat[i].Format == CBIOS_AUDIO_FORMAT_LPCM) + { + PcmSupport = CBIOS_TRUE; + break; + } + } + //if all AudioFormat not support LPCM,but it indicates support basic audio,should patch here + if(!PcmSupport) + { + if(i >= CBIOS_HDMI_AUDIO_FORMAT_COUNTS) + { + i = CBIOS_HDMI_AUDIO_FORMAT_COUNTS - 1; + } + pCEAAudioFormat[i].Format = CBIOS_AUDIO_FORMAT_LPCM; + pCEAAudioFormat[i].MaxChannelNum = 2;//two channel + pCEAAudioFormat[i].SampleRateUnit = 7;//sample rates of 32kHz,44.1kHz,48kHz + pCEAAudioFormat[i].BitDepth.BD_16bit = 1;//16 bits + if(i != CBIOS_HDMI_AUDIO_FORMAT_COUNTS -1 ) + { + pEDIDStruct->TotalHDMIAudioFormatNum = pEDIDStruct->TotalHDMIAudioFormatNum + 1; + } + } +} + +static CBIOS_VOID cbEDIDPatchHDMICEAMode(CBIOS_U8 *pEDID, PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct, PCBIOS_U32 pModeNumOfCEABlock) +{ + PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttrib = &(pEDIDStruct->Attribute); + PCBIOS_HDMI_FORMAT_DESCRIPTOR pCEAVideoFormat = pEDIDStruct->HDMIFormat; + CBIOS_UCHAR MonitorID[8] = {0}; + + if ((pMonitorAttrib == CBIOS_NULL) || (pCEAVideoFormat == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pMonitorAttrib is null.\n", FUNCTION_NAME)); + return; + } + + cbEDIDModule_GetMonitorID(pEDID, MonitorID); + + // patch for SKY 24X1Q monitor, filter 1920x1080@24Hz mode as it can't display + if ((!cb_strcmp(MonitorID, (CBIOS_UCHAR*)"SKY2380")) && (!cb_strcmp(pMonitorAttrib->MonitorName, (CBIOS_UCHAR*)"24X1Q"))) + { + pCEAVideoFormat[31].IsSupported = CBIOS_FALSE; + *pModeNumOfCEABlock = *pModeNumOfCEABlock - 1; + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "%s: filter 1080p@24Hz, ModeNumOfCEABlock = %d\n", FUNCTION_NAME, *pModeNumOfCEABlock)); + } + +} + +/*************************************************************** +Function: cbEDIDModule_ParseHDMIVSDB + +Description: Decode vendor specific data block of CEA extension + +Input: pVSDBDataInEDID, vendor specific data buffer + +Output: pVSDBData, decoded VSDB data + +Return: the total length of vendor specific data block +***************************************************************/ + +/* + HDMI Vendor Specific Data Block + ------------------------------------------------------------------------------------------------------------------------- + |Byte # | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + |-------|---------------------------------------------------------------------------------------------------------------| + | 0 | Vendor-specific tag code (=3) | Length (=N) | + |-------|---------------------------------------------------------------------------------------------------------------| + | 1 | | + |-------| 24-bit IEEE Registration Identifier (0x000C03) | + | 2 | (least significant byte first) | + |-------| | + | 3 | | + |-------|---------------------------------------------------------------------------------------------------------------| + | 4 | A | B | + |-------|---------------------------------------------------------------------------------------------------------------| + | 5 | C | D | + |-------|---------------------------------------------------------------------------------------------------------------|----------- + | | Supports | DC_ | DC_ | DC_ | DC_ | Rsvd | Rsvd | DVI_ | extension + | 6 | _AI | 48bit | 36bit | 30bit | Y444 | (0) | (0) | Dual | fields + |-------|---------------------------------------------------------------------------------------------------------------| + | 7 | Max_TMDS_Clock | + |-------|---------------------------------------------------------------------------------------------------------------| + | | Latency_ | I_Latency_| HDMI_V | Rsvd | | | | | + | 8 | Fields_ | Fields_ | ideo_pre | (0) | CNC3 | CNC2 | CNC1 | CNC0 | + | | Present | Present | sent | | | | | | + |-------|---------------------------------------------------------------------------------------------------------------| + | (9) | Video_Latency | + |-------|---------------------------------------------------------------------------------------------------------------| + | (10) | Audio_Latency | + |-------|---------------------------------------------------------------------------------------------------------------| + | (11) | Interlaced_Video_Latency | + |-------|---------------------------------------------------------------------------------------------------------------| + | (12) | Interlaced_Audio_Latency | + |-------|---------------------------------------------------------------------------------------------------------------| + | (13) | 3D_pres | 3D_Multi_present | Image_Size | Rsvd | Rsvd | Rsvd | + | | ent | | | (0) | (0) | (0) | + |-------|---------------------------------------------------------------------------------------------------------------| + | (14) | HDMI_VIC_LEN | HDMI_3D_LEN | + |-------|---------------------------------------------------------------------------------------------------------------| + | (15) |(if HDMI_VIC_LEN > 0) | + | | HDMI_VIC_1 | + |-------|---------------------------------------------------------------------------------------------------------------| + | ... | ... | + |-------|---------------------------------------------------------------------------------------------------------------| + | | HDMI_VIC_M | + |-------|---------------------------------------------------------------------------------------------------------------| + | |(if 3D_Multi_present = 01 or 10) | + | | 3D_Structure_ALL_15...8 | + |-------|---------------------------------------------------------------------------------------------------------------| + | | 3D_Structure_ALL_7...0 | + |-------|---------------------------------------------------------------------------------------------------------------| + | |(if 3D_Multi_present = 10) | + | | 3D_MASK_15...8 | + |-------|---------------------------------------------------------------------------------------------------------------| + | | 3D_MASK_7... | + |-------|---------------------------------------------------------------------------------------------------------------| + | | 2D_VIC_order_1 | 3D_Structure_1 | + |-------|---------------------------------------------------------------------------------------------------------------| + | | 3D_Detail_1 *** | Reserved(0) *** | + |-------|---------------------------------------------------------------------------------------------------------------| + | | ... | + |-------|---------------------------------------------------------------------------------------------------------------| + | | 2D_VIC_order_L | 3D_Structure_L | + |-------|---------------------------------------------------------------------------------------------------------------| + |()*...N| Reserved (0)** | + ------------------------------------------------------------------------------------------------------------------------------------- +*/ + +static CBIOS_U32 cbEDIDModule_ParseHDMIVSDB(CBIOS_U8 *pVSDBDataInEDID, PCBIOS_HDMI_VSDB_EXTENTION pVSDBData) +{ + CBIOS_U8 *pCurByte = pVSDBDataInEDID; + CBIOS_U32 i = 0; + CBIOS_U32 PayloadLen = 0; + CBIOS_U8 dataLow = 0; + CBIOS_U8 dataHigh = 0; + + if ((pVSDBDataInEDID == CBIOS_NULL) || (pVSDBData == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEDIDModule_ParseVSDB: NULL pointer!\n")); + return 0; + } + + //initialize CBIOS_HDMI_VSDB_EXTENTION + cb_memset(pVSDBData, 0, sizeof(CBIOS_HDMI_VSDB_EXTENTION)); + pVSDBData->HDMI3DMask = 0xFFFF; + + //check tag and length + cb_memcpy(&(pVSDBData->Tag), pCurByte++, sizeof(pVSDBData->Tag)); + + if ((pVSDBData->Tag.VSDBTag != VENDOR_SPECIFIC_DATA_BLOCK_TAG) + ||(pVSDBData->Tag.VSDBLength < 5)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEDIDModule_ParseHDMIVSDB: invalid VSDB data!\n")); + pVSDBData->Tag.VSDBLength = 0; + } + else//tag OK + { + PayloadLen = 0; + //Byte 1-5, VSDB header + pVSDBData->VSDBHeader.RegistrationIDByte0 = *(pCurByte++); + pVSDBData->VSDBHeader.RegistrationIDByte1 = *(pCurByte++); + pVSDBData->VSDBHeader.RegistrationIDByte2 = *(pCurByte++); + dataHigh = *(pCurByte++); + dataLow = *(pCurByte++); + pVSDBData->VSDBHeader.SourcePhyAddr = (CBIOS_U16) (dataHigh << 8) | dataLow; + + PayloadLen += 5; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + + //byte 6 + cb_memcpy(&(pVSDBData->SupportCaps), pCurByte, sizeof(CBIOS_U8)); + pCurByte++; + + PayloadLen++; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + + //byte 7, max TMDS clock in MHz / 5 + pVSDBData->MaxTMDSClock = (CBIOS_U16)(*pCurByte) * 5;//max tmds clock in MHz + pCurByte++; + + PayloadLen++; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + + //byte 8 + cb_memcpy(&(pVSDBData->PresentFlags), pCurByte, sizeof(CBIOS_U8)); + pCurByte++; + + PayloadLen++; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + + //These 2 bytes are present only if LatencyFieldsPresent is set to 1 + if (pVSDBData->LatencyFieldsPresent) + { + pVSDBData->VideoLatency = *(pCurByte++); + pVSDBData->AudioLatency = *(pCurByte++); + + PayloadLen += 2; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + } + else + { + pVSDBData->VideoLatency = 0; + pVSDBData->AudioLatency = 0; + } + + //These 2 bytes are present only if ILatencyFieldsPresent is set to 1 + //In fact, if ILatencyFieldsPresent == 1, LatencyFieldsPresent must = 1 + if (pVSDBData->ILatencyFieldsPresent) + { + pVSDBData->InterlacedVideoLatency = *(pCurByte++); + pVSDBData->InterlacedAudioLatency = *(pCurByte++); + + PayloadLen += 2; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + } + else + { + pVSDBData->InterlacedVideoLatency = 0; + pVSDBData->InterlacedAudioLatency = 0; + } + + // If HDMIVideoPresent =1 then additional video format capabilities are described by using the fields starting after the Latency area. + if (pVSDBData->HDMIVideoPresent) + { + CBIOS_U32 HDMI3DFormatLength = 0; + CBIOS_U32 HDMI3DFormatCount = 0; + CBIOS_U8 ExtVICCnt = 0; + + + cb_memcpy(&(pVSDBData->HDMI3DPresentFlags), pCurByte++, sizeof(pVSDBData->HDMI3DPresentFlags)); + + PayloadLen++; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + + //HDMI_3D_LEN[5bits] indicates the total length of following 3D video format capabilities, + //including 3D_Structure_ALL_15...0, 3D_MASK_15...0, 2D_VIC_order_X,3D_Structure_X and 3D_Detail_X fields. + pVSDBData->HDMI3DLen = (*pCurByte) & 0x1F; + + //HDMI_VIC_LEN [3bits] indicates the total length of HDMI_VIC_X + pVSDBData->HDMIVICLen = (*pCurByte >> 5) & 0x07; + pCurByte++; + + PayloadLen++; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + + //HDMI_VIC_X + for (i = 0; i < pVSDBData->HDMIVICLen; i++) + { + + if ((*pCurByte >= 1) && (*pCurByte <= CBIOS_HDMI_EXTENED_VIC_COUNTS)) + { + pVSDBData->HDMIVIC[ExtVICCnt++] = *pCurByte; + } + + pCurByte++; + + } + pVSDBData->HDMIVICLen = ExtVICCnt; + + PayloadLen += i; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + + HDMI3DFormatLength = pVSDBData->HDMI3DLen; + + // If 3D_Multi_present = 01, 3D_Structure_ALL_15...0 is present + // and assigns 3D formats to all of the VICs listed in the first 16 entries in the EDID. + // 3D_MASK_15...0 is not present. + if (pVSDBData->HDMI3DMultiPresent == 0x01) + { + // 2 Byte 3D_Structure_ALL_15...8 and 3D_Structure_ALL_7...0 + dataHigh = *(pCurByte++); + dataLow = *(pCurByte++); + + pVSDBData->HDMI3DStructAll = (dataHigh << 8) | dataLow; + + // 3D_Multi_Present = 01, 3D_MASK_X is not present + pVSDBData->HDMI3DMask = 0xFFFF; + + //subtract 3D_Structure_ALL_15...0 length from HDMI_3D_LEN + HDMI3DFormatLength -= 2; + + PayloadLen += 2; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + } + else if (pVSDBData->HDMI3DMultiPresent == 0x02) + { + // If 3D_Multi_present = 10, + // 3D_Structure_ALL_15...0 and 3D_MASK_15...0 are present and assign 3D formats to + // some of the VICs listed in the first 16 entries in the EDID. + + // 2 Byte 3D_Structure_ALL_15...8 and 3D_Structure_ALL_7...0 + dataHigh = *(pCurByte++); + dataLow = *(pCurByte++); + + pVSDBData->HDMI3DStructAll = (dataHigh << 8) | dataLow; + + // 2 Byte 3D_MASK_15...8 and 3D_MASK_7...0 + dataHigh = *(pCurByte++); + dataLow = *(pCurByte++); + + pVSDBData->HDMI3DMask = (dataHigh << 8) | dataLow; + + //subtract 3D_Structure_ALL_15...0 and 3D_MASK_15...0 length from HDMI_3D_LEN + HDMI3DFormatLength -= 4; + + PayloadLen += 4; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + } + else + { + // 3D_Multi_Present = 00 or 11, 3D_Structure_ALL_15...0 and 3D_MASK_15...0 are not present + pVSDBData->HDMI3DStructAll = 0x0000; + pVSDBData->HDMI3DMask = 0xFFFF; + } + + if (pVSDBData->HDMI3DLen < HDMI3DFormatLength) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbEDIDModule_ParseHDMIVSDB: HDMI_3D_LEN error!\n")); + } + else + { + i = 0; + HDMI3DFormatCount = 0; + while (i < HDMI3DFormatLength) + { + // 2D_VIC_order_X: a pointer to a particular VIC in the EDID based on the order in which the VICs are stored in the EDID. + pVSDBData->HDMI3DForamt[HDMI3DFormatCount].HDMI2DVICOrder = (*pCurByte >> 4) & 0x0F; + // 3D_Structure_X: This field indicates the 3D capability for the corresponding VIC code indicated by 2D_VIC_order_X. + pVSDBData->HDMI3DForamt[HDMI3DFormatCount].HDMI3DStructure = (*pCurByte) & 0x0F; + pCurByte++; + i++; + + // 3D_Detail_X: This field indicates the 3D capability for the corresponding VIC code indicated by 2D_VIC_order_X. + // If If 3D_Structure_X is 0000~0111, this field shall not be present + // If 3D_Structure_X is 1000~1111 (including Side-by-Side (Half)), this field shall be present + if (pVSDBData->HDMI3DForamt[HDMI3DFormatCount].HDMI3DStructure >= 0x08) + { + pVSDBData->HDMI3DForamt[HDMI3DFormatCount].HDMI3DDetail = ((*pCurByte++) >> 4) & 0x0F; + i++; + } + HDMI3DFormatCount++; + } + pVSDBData->HDMI3DFormatCount = HDMI3DFormatCount; + + PayloadLen += HDMI3DFormatLength; + if (PayloadLen >= pVSDBData->Tag.VSDBLength) + { + goto VSDB_DONE; + } + } + + + } + + } + +VSDB_DONE: + + //check payload length + if (PayloadLen != pVSDBData->Tag.VSDBLength) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbEDIDModule_ParseHDMIVSDB: payload length error!\n")); + } + + //block total length = payload len + 1 + return (pVSDBData->Tag.VSDBLength + 1); + +} + +/*************************************************************** +Function: cbEDIDModule_ParseHFVSDB + +Description: Decode HDMI Forum vendor specific data block of CEA extension + +Input: pVSDBDataInEDID, HDMI Forum vendor specific data buffer + +Output: pVSDBData, decoded HDMI Forum VSDB data + +Return: the total length of HDMI Forum vendor specific data block +***************************************************************/ + +/* + HDMI Forum Vendor Specific Data Block + ----------------------------------------------------------------------------------------------------------------------------- + |Byte\Bit # | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + |-----------|---------------------------------------------------------------------------------------------------------------| + | | Vendor-specific tag code (=3) | Length (=N) | + |-----------|---------------------------------------------------------------------------------------------------------------| + | 1 | IEEE OUI, Third Octet (0xD8) | + |-----------|---------------------------------------------------------------------------------------------------------------| + | 2 | IEEE OUI, Second Octet (0x5D) | + |-----------|---------------------------------------------------------------------------------------------------------------| + | 3 | IEEE OUI, First Octet (0xC4) | + |-----------|---------------------------------------------------------------------------------------------------------------| + | 4 | Version (=1) | + |-----------|---------------------------------------------------------------------------------------------------------------| + | 5 | Max_TMDS_Character_Rate | + |-----------|---------------------------------------------------------------------------------------------------------------| + | | SCDC_ | RR_ | Rsvd | Rsvd | LTE_340Mcsc| Independent | Dual | 3D_OSD_ | + | 6 | Present | Capable | (0) | (0) | _scramble | _view | _View | Disparity | + |-----------|---------------------------------------------------------------------------------------------------------------| + | | Rsvd | Rsvd | Rsvd | Rsvd | Rsvd | DC_48Bit | DC_36Bit | DC_30Bit | + | 7 | (0) | (0) | (0) | (0) | (0) | _420 | _420 | _420 | + |-----------|---------------------------------------------------------------------------------------------------------------| + | ...N | Reserved(0)* | + |---------------------------------------------------------------------------------------------------------------------------| + +*/ + +static CBIOS_U32 cbEDIDModule_ParseHFVSDB(CBIOS_U8 *pVSDBDataInEDID, PCBIOS_HF_HDMI_VSDB_EXTENTION pVSDBData) +{ + CBIOS_U8 *pCurByte = pVSDBDataInEDID; + CBIOS_U32 PayloadLen = 0; + + if ((pVSDBDataInEDID == CBIOS_NULL) || (pVSDBData == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEDIDModule_ParseHFVSDB: NULL pointer!\n")); + return 0; + } + + //initialize CBIOS_HDMI_VSDB_EXTENTION + cb_memset(pVSDBData, 0, sizeof(CBIOS_HF_HDMI_VSDB_EXTENTION)); + + //check tag and length + cb_memcpy(&(pVSDBData->Tag), pCurByte++, sizeof(pVSDBData->Tag)); + + if ((pVSDBData->Tag.VSDBTag != VENDOR_SPECIFIC_DATA_BLOCK_TAG) + ||(pVSDBData->Tag.VSDBLength < 7)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEDIDModule_ParseHFVSDB: invalid VSDB data!\n")); + pVSDBData->Tag.VSDBLength = 0; + } + else//tag OK + { + PayloadLen = 0; + //Byte 1-3, The IEEE Organizationally Unique Identifier (OUI) of C4-5D-D8 + pVSDBData->HFVSDBOUI.IEEEOUIByte0 = *(pCurByte++); + pVSDBData->HFVSDBOUI.IEEEOUIByte1 = *(pCurByte++); + pVSDBData->HFVSDBOUI.IEEEOUIByte2 = *(pCurByte++); + PayloadLen += 3; + + //byte 4 version + pVSDBData->Version = *(pCurByte++); + PayloadLen++; + + //byte 5 Max_TMDS_Character_Rate in MHz / 5 + pVSDBData->MaxTMDSCharacterRate = (CBIOS_U16)(*pCurByte) * 5; + pCurByte++; + PayloadLen++; + + //byte 6-7 + cb_memcpy(&(pVSDBData->SupportCaps), pCurByte, sizeof(CBIOS_U16)); + pCurByte += 2; + PayloadLen += 2; + } + + //check payload length + if (PayloadLen != pVSDBData->Tag.VSDBLength) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbEDIDModule_ParseHFVSDB: payload length error!\n")); + } + + //block total length = payload len + 1 + return (pVSDBData->Tag.VSDBLength + 1); + +} + + +/*************************************************************** +Function: cbEDIDModule_ParseCEAExtBlock + +Description: Parse extended data block of CEA extension + +Input: pExtBlockDataInEDID, extended block data buffer + +Output: pEDIDStruct, decoded extend block data + +Return: the total length of vendor specific data block +***************************************************************/ +static CBIOS_U32 cbEDIDModule_ParseCEAExtBlock(CBIOS_U8 *pExtBlockDataInEDID, PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct, CBIOS_U32 BlockIndex) +{ + CBIOS_U32 PayloadLen = 0; + CBIOS_U8 ExtTagCode = 0; + CBIOS_U8 FormatIndex = 0; + PCBIOS_HDMI_FORMAT_DESCRIPTOR pCEAVideoFormat = CBIOS_NULL; + PCBIOS_CEA_SVD_DATA pSVDData = CBIOS_NULL; + PCBIOS_CEA_EXTENED_BLOCK pCEAExtData = CBIOS_NULL; + CBIOS_U8 SVD = 0; + CBIOS_BOOL IsNative = CBIOS_FALSE; + CBIOS_BOOL Status = CBIOS_FALSE; + CBIOS_U8 i = 0, j = 0; + + pCEAVideoFormat = pEDIDStruct->HDMIFormat; + pSVDData = &pEDIDStruct->Attribute.SVDData[BlockIndex - 1]; + + //check tag code + if (((((*pExtBlockDataInEDID) >> 5) & 0x07) != CEA_EXTENDED_BLOCK_TAG) + || (((*pExtBlockDataInEDID) & 0x1F) == 0)) + { + PayloadLen = 0; + } + else + { + PayloadLen = (*pExtBlockDataInEDID) & 0x1F; + ExtTagCode = pExtBlockDataInEDID[1]; + + if(ExtTagCode == VIDEO_CAPABILITY_DATA_BLOCK_TAG) + { + //Video Capability Data Block + pCEAExtData = &pEDIDStruct->Attribute.ExtDataBlock[VIDEO_CAPABILITY_DATA_BLOCK_TAG]; + cb_memcpy(&pCEAExtData->VideoCapabilityData, &pExtBlockDataInEDID[2], sizeof(CBIOS_VIDEO_CAPABILITY_DATA)); + } + else if(ExtTagCode == VENDOR_SPECIFIC_VIDEO_DATA_BLOCK_TAG) + { + //Vendor Specific Video Data Block + } + else if(ExtTagCode == COLORIMETRY_DATA_BLOCK_TAG) + { + //Colorimetry Data Block + pCEAExtData = &pEDIDStruct->Attribute.ExtDataBlock[COLORIMETRY_DATA_BLOCK_TAG]; + cb_memcpy(&pCEAExtData->ColorimetryData, &pExtBlockDataInEDID[2], sizeof(CBIOS_COLORIMETRY_DATA)); + } + else if(ExtTagCode == VIDEO_FMT_PREFERENCE_DATA_BLOCK) + { + /* + Video Format Preference Data Block + VFPDB indicates the order of preference for(selected)Video Formats listed as DTDs and/or + SVDs throughout the entire EDID. When present, the VFPDB shall take precedence over preferred + indications defined elsewhere in CEA-861-F. + */ + CBIOS_U8 SVR = 0; + for (i = 0; i < PayloadLen - 1; i++) + { + SVR = pExtBlockDataInEDID[2 + i]; + if(((SVR >= 1) && (SVR <= 127)) || ((SVR >= 193) && (SVR <= 253))) + { + //Interpret as a VIC + pEDIDStruct->Attribute.ShortVideoRef[i].SVRValue = SVR; + pEDIDStruct->Attribute.ShortVideoRef[i].SVRFlag = SVR_FLAG_VIC; + } + else if((SVR >= 129) && (SVR <= 144)) + { + //Interpret as the Kth DTD in the EDID, where K = SVR -128 + pEDIDStruct->Attribute.ShortVideoRef[i].SVRValue = SVR - 128; + pEDIDStruct->Attribute.ShortVideoRef[i].SVRFlag = SVR_FLAG_DTD_INDEX; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC,INFO), "Reserved SVR!\n")); + } + } + } + else if(ExtTagCode == YCBCR420_VIDEO_DATA_BLOCK) + { + /* + According to CEA-861-F 7.5.10 + A YCBCR4:2:0 Video Data Block (Y420VDB) lists Video Formats, supported by the Sink, that only allow + YCBCR4:2:0 sampling mode (i.e., do not support RGB, YCBCR4:4:4, or YCBCR4:2:2 sampling modes). + */ + for (i = 0; i < PayloadLen - 1; i++) + { + SVD = pExtBlockDataInEDID[2 + i]; + Status = cbEDIDModule_GetFmtIdxFromSVD(SVD, &FormatIndex, &IsNative); + if (!Status) + { + continue; + } + + pCEAVideoFormat[FormatIndex - 1].IsSupportYCbCr420 = 1; + pCEAVideoFormat[FormatIndex - 1].IsSupportOtherFormats = 0; + } + } + else if(ExtTagCode == YCBCR420_CAP_MAP_DATA_BLOCK) + { + /* + According to CEA-861-F 7.5.11 + A YCBCR4:2:0 Capability Map Data Block (Y420CMDB) indicates exactly which SVDs, listed in one or + more regular Video Data Blocks (see Section 7.5.1), also support YCBCR4:2:0 sampling mode - in + addition to other modes such as RGB, YCBCR4:4:4, and/or YCBCR4:2:2. The Y420CMDB does not indicate which RGB, + YCBCR 4:4:4, and/or YCBCR4:2:2 modes are supported. + */ + + CBIOS_U8 YCbCr420CapMap = 0; + CBIOS_U8 Step = 0; + + if (PayloadLen == 1) + { + // payload length == 1, all regular SVDs supports YCbCr420 + for (i = 0; i < pSVDData->SVDCount; i++) + { + SVD = pSVDData->SVD[i]; + Status = cbEDIDModule_GetFmtIdxFromSVD(SVD, &FormatIndex, &IsNative); + if (!Status) + { + continue; + } + + pCEAVideoFormat[FormatIndex - 1].IsSupportYCbCr420 = 1; + pCEAVideoFormat[FormatIndex - 1].IsSupportOtherFormats = 1; + } + } + else + { + for (i = 0; i < PayloadLen - 1; i++) + { + YCbCr420CapMap = pExtBlockDataInEDID[2 + i]; + + for (j = 0; j < 8; j++) + { + if (((YCbCr420CapMap >> j) & 0x1) && (j + Step < pSVDData->SVDCount)) + { + SVD = pSVDData->SVD[j+Step]; + Status = cbEDIDModule_GetFmtIdxFromSVD(SVD, &FormatIndex, &IsNative); + if (!Status) + { + continue; + } + + pCEAVideoFormat[FormatIndex - 1].IsSupportYCbCr420 = 1; + pCEAVideoFormat[FormatIndex - 1].IsSupportOtherFormats = 1; + } + } + Step += 8; + } + } + } + else if(ExtTagCode == VENDOR_SPECIFIC_AUDIO_DATA_BLOCK_TAG) + { + //Vendor Specific Audio Data Block + } + else if(ExtTagCode == RSVD_HDMI_AUDIO_DATA_BLOCK_TAG) + { + //HDMI Audio Data Block + pCEAExtData = &pEDIDStruct->Attribute.ExtDataBlock[RSVD_HDMI_AUDIO_DATA_BLOCK_TAG]; + + pCEAExtData->HDMIAudioData.MaxStreamCount = pExtBlockDataInEDID[2] & 0x3; + pCEAExtData->HDMIAudioData.SupportsMSNonMixed = (pExtBlockDataInEDID[2] >> 2) & 0x1; + pCEAExtData->HDMIAudioData.NumHDMI3DAD = pExtBlockDataInEDID[3] & 0x7; + + if(pCEAExtData->HDMIAudioData.NumHDMI3DAD > 0) + { + CBIOS_U32 AudioFormatCode = 0; + for(i = 0;i < pCEAExtData->HDMIAudioData.NumHDMI3DAD;i++) + { + AudioFormatCode = pExtBlockDataInEDID[4 + i*4] & 0xF; + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].Format = AudioFormatCode; + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].MaxChannelNum = (pExtBlockDataInEDID[4 + i*4 + 1] & 0x1F) + 1; + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].SampleRateUnit = pExtBlockDataInEDID[4 + i*4 + 2] & 0x7F; + + if (AudioFormatCode == 1) + { + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].BitDepth.BD_16bit = pExtBlockDataInEDID[4 + i*4 + 3] & 0x1; + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].BitDepth.BD_20bit = (pExtBlockDataInEDID[4 + i*4 + 3] >> 1) & 0x1; + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].BitDepth.BD_24bit = (pExtBlockDataInEDID[4 + i*4 + 3] >> 2) & 0x1; + } + else if (AudioFormatCode <= 8) + { + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].MaxBitRate = pExtBlockDataInEDID[4 + i*4 + 3] * 8; + } + else if (AudioFormatCode <= 13) + { + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].AudioFormatDependValue = pExtBlockDataInEDID[4 + i*4 + 3]; + } + else if (AudioFormatCode == 14) + { + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].Profile.Value = pExtBlockDataInEDID[4 + i*4 + 3] & 0x7; + } + else + { + if (((pExtBlockDataInEDID[4 + i*4 + 3] >> 3) & 0x1F) == 1) + { + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].Format = CBIOS_AUDIO_FORMAT_HE_AAC; + } + else if(((pExtBlockDataInEDID[4 + i*4 + 3] >> 3) & 0x1F) == 2) + { + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].Format = CBIOS_AUDIO_FORMAT_HE_AAC_V2; + } + else if(((pExtBlockDataInEDID[4 + i*4 + 3] >> 3) & 0x1F) == 3) + { + pCEAExtData->HDMIAudioData.HDMI3DAudioDesc[i].Format = CBIOS_AUDIO_FORMAT_MPEG_SURROUND; + } + } + } + } + } + else if(ExtTagCode == INFOFRAME_DATA_BLOCK) + { + //InfoFrame Data Block + CBIOS_U8 Index = 2; + CBIOS_U8 TypeCode = 0; + CBIOS_U8 SIDHeader = 0; + CBIOS_U8 SupportPriority = 0; + + //InfoFrame Processing Descriptor + CBIOS_U8 Len = (pExtBlockDataInEDID[Index++] >> 5) & 0x7; + pEDIDStruct->Attribute.NumOfAdditionalVSIFs = pExtBlockDataInEDID[Index++]; + Index += Len; + + /* + Declared InfoFrame types shall be listed in order of priority; + meaning that the first is the one that the display manufacturer + has identified as most desirable. Sources may use this infomation + as a basis for selecting which InfoFrame to send(e.g. in case where + the Sources may not be capable of delivering all defined or + supported InfoFrame types). + */ + + for(;Index < PayloadLen;) + { + SIDHeader = pExtBlockDataInEDID[Index++]; + Len = (SIDHeader >> 5) & 0x7; + TypeCode = SIDHeader & 0x1F; + + if(TypeCode == VENDOR_SPECIFIC_INFO_FRAME_TYPE) + { + if((pExtBlockDataInEDID[Index + 1] == 0x03) && + (pExtBlockDataInEDID[Index + 2] == 0x0c) && + (pExtBlockDataInEDID[Index + 3] == 0x00)) + { + pEDIDStruct->Attribute.InfoFrameSupCaps.HDMISpecificInfoFrameCaps.bSupport = CBIOS_TRUE; + pEDIDStruct->Attribute.InfoFrameSupCaps.HDMISpecificInfoFrameCaps.Priority = SupportPriority; + } + else if((pExtBlockDataInEDID[Index + 1] == 0xD8) && + (pExtBlockDataInEDID[Index + 2] == 0x5D) && + (pExtBlockDataInEDID[Index + 3] == 0xC4)) + { + pEDIDStruct->Attribute.InfoFrameSupCaps.HFSpecificInfoFrameCaps.bSupport = CBIOS_TRUE; + pEDIDStruct->Attribute.InfoFrameSupCaps.HFSpecificInfoFrameCaps.Priority = SupportPriority; + } + + Index += 3;//24-bit OUI Registration Identifier + } + else if(TypeCode == AVI_INFO_FRAME_TYPE) + { + pEDIDStruct->Attribute.InfoFrameSupCaps.AVIInfoFrameCaps.bSupport = CBIOS_TRUE; + pEDIDStruct->Attribute.InfoFrameSupCaps.AVIInfoFrameCaps.Priority = SupportPriority; + } + else if(TypeCode == SOURCE_PRODUCT_DESCRIPTION_INFO_FRAME_TYPE) + { + pEDIDStruct->Attribute.InfoFrameSupCaps.SourceProductDescInfoFrameCaps.bSupport = CBIOS_TRUE; + pEDIDStruct->Attribute.InfoFrameSupCaps.SourceProductDescInfoFrameCaps.Priority = SupportPriority; + } + else if(TypeCode == AUDIO_INFO_FRAME_TYPE) + { + pEDIDStruct->Attribute.InfoFrameSupCaps.AudioInfoFrameCaps.bSupport = CBIOS_TRUE; + pEDIDStruct->Attribute.InfoFrameSupCaps.AudioInfoFrameCaps.Priority = SupportPriority; + } + else if(TypeCode == MPEG_SOURCE_INFO_FRAME_TYPE) + { + pEDIDStruct->Attribute.InfoFrameSupCaps.MpegSourceInfoFrameCaps.bSupport = CBIOS_TRUE; + pEDIDStruct->Attribute.InfoFrameSupCaps.MpegSourceInfoFrameCaps.Priority = SupportPriority; + } + else if(TypeCode == NTSC_VBI_INFO_FRAME_TYPE) + { + pEDIDStruct->Attribute.InfoFrameSupCaps.NTSCVBIInfoFrameCaps.bSupport = CBIOS_TRUE; + pEDIDStruct->Attribute.InfoFrameSupCaps.NTSCVBIInfoFrameCaps.Priority = SupportPriority; + } + + SupportPriority++; + Index += Len; + } + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEDIDModule_ParseCEAExtBlock: ExtTagCode = 0x%x which is not parsed yet!\n", ExtTagCode)); + } + } + + //return total block len + return PayloadLen + 1; +} + +/*************************************************************** +Function: cbEDIDModule_GetHDMIVICMode + +Description: Get HDMI VIC mode number in VSDB + +Input: pVSDBData, VSDB data buffer + +Output: pCEAVideoFormat, statistic HDMI VIC format in VSDB + +Return: the number of HDMI VIC mode +***************************************************************/ +static CBIOS_U32 cbEDIDModule_GetHDMIVICMode(PCBIOS_HDMI_VSDB_EXTENTION pVSDBData, PCBIOS_HDMI_FORMAT_DESCRIPTOR pCEAVideoFormat) +{ + CBIOS_U32 ulNumOfHDMIVICMode = 0; + CBIOS_U32 i = 0; + + //extended VICs + for (i = 0; i < pVSDBData->HDMIVICLen; i++) + { + CBIOS_U16 FormatIndex = pVSDBData->HDMIVIC[i] + CBIOS_HDMI_NORMAL_VIC_COUNTS - 1; + if ((FormatIndex < CBIOS_HDMIFORMATCOUNTS) && (!pCEAVideoFormat[FormatIndex].IsSupported)) + { + pCEAVideoFormat[FormatIndex].IsSupported = CBIOS_TRUE; + pCEAVideoFormat[FormatIndex].BlockIndex = (CBIOS_U8)0; + pCEAVideoFormat[FormatIndex].IsNative = CBIOS_FALSE; + pCEAVideoFormat[FormatIndex].RefreshIndex= CEAVideoFormatTable[FormatIndex].DefaultRefRateIndex; + ulNumOfHDMIVICMode++; + } + } + + return ulNumOfHDMIVICMode; + +} + +/*************************************************************** +Function: cbEDIDModule_Get3DFormat + +Description: Set some format 3D attribute if the monitor support 3D video + +Input: pSVDDataInEDID, short video descriptor data buffer + pVSDBData, VSDB data buffer + +Output: pCEAVideoFormat, set some format 3D attribute through VSDB data + +Return: the number of 3D video mandatory formats that not in SVD +***************************************************************/ +static CBIOS_U32 cbEDIDModule_Get3DFormat(CBIOS_U8 *pSVDDataInEDID, PCBIOS_HDMI_VSDB_EXTENTION pVSDBData, PCBIOS_HDMI_FORMAT_DESCRIPTOR pCEAVideoFormat) +{ + CBIOS_BOOL b50HzSupport = CBIOS_FALSE, b60HzSupport = CBIOS_FALSE; + CBIOS_U32 ulNumOf3DFormat = 0; + CBIOS_U8 formatNum = 0; + CBIOS_U32 SVDPayloadLength = 0; + CBIOS_U32 i = 0; + CBIOS_U8 SVDList[MAX_SVD_COUNT]; + CBIOS_BOOL IsNative = CBIOS_FALSE; + CBIOS_BOOL Status = CBIOS_FALSE; + + SVDPayloadLength = pSVDDataInEDID[0] & 0x1F; + cb_memset(SVDList, 0, MAX_SVD_COUNT); + cb_memcpy(SVDList, pSVDDataInEDID+1, (sizeof(CBIOS_U8)*SVDPayloadLength)); + + // first check if 59.94/60Hz or 50Hz 2D video format support + for (i = 0; i < SVDPayloadLength; i++) + { + Status = cbEDIDModule_GetFmtIdxFromSVD(SVDList[i], &formatNum, &IsNative); + if (!Status) + { + continue; + } + + if ((formatNum >= 1) && (formatNum <= 16)) + { + b60HzSupport = CBIOS_TRUE; + } + else if ((formatNum >= 17) && (formatNum <= 31)) + { + b50HzSupport = CBIOS_TRUE; + } + } + + // Set 3D video mandatory formats + if (b60HzSupport) + { + // An HDMI sink which supports at least one 59.94/60Hz 2D video format shall support all of below + + // format 32, 1920x1080p@23.98/24Hz + if( !pCEAVideoFormat[31].IsSupported) + { + pCEAVideoFormat[31].IsSupported=CBIOS_TRUE; + pCEAVideoFormat[31].BlockIndex = (CBIOS_U8)0; + pCEAVideoFormat[31].IsNative = CBIOS_FALSE; + pCEAVideoFormat[31].RefreshIndex= CEAVideoFormatTable[31].DefaultRefRateIndex; + ulNumOf3DFormat++; + } + pCEAVideoFormat[31].Video3DSupportStructs.FramePacking = 1; + pCEAVideoFormat[31].Video3DSupportStructs.TopAndBottom = 1; + + // format 5, 1920x1080i@59.94/60Hz + if( !pCEAVideoFormat[4].IsSupported) + { + pCEAVideoFormat[4].IsSupported=CBIOS_TRUE; + pCEAVideoFormat[4].BlockIndex = (CBIOS_U8)0; + pCEAVideoFormat[4].IsNative = CBIOS_FALSE; + pCEAVideoFormat[4].RefreshIndex= CEAVideoFormatTable[4].DefaultRefRateIndex; + ulNumOf3DFormat++; + } + pCEAVideoFormat[4].Video3DSupportStructs.SideBySideHalf = 1; + + //format 4, 1280x720p@59.94/60Hz + if( !pCEAVideoFormat[3].IsSupported) + { + pCEAVideoFormat[3].IsSupported=CBIOS_TRUE; + pCEAVideoFormat[3].BlockIndex = (CBIOS_U8)0; + pCEAVideoFormat[3].IsNative = CBIOS_FALSE; + pCEAVideoFormat[3].RefreshIndex= CEAVideoFormatTable[3].DefaultRefRateIndex; + ulNumOf3DFormat++; + } + pCEAVideoFormat[3].Video3DSupportStructs.FramePacking = 1; + pCEAVideoFormat[3].Video3DSupportStructs.TopAndBottom = 1; + + } + + if (b50HzSupport) + { + //format 32, 1920x1080p@23.98/24Hz + if( !pCEAVideoFormat[31].IsSupported) + { + pCEAVideoFormat[31].IsSupported=CBIOS_TRUE; + pCEAVideoFormat[31].BlockIndex = (CBIOS_U8)0; + pCEAVideoFormat[31].IsNative = CBIOS_FALSE; + pCEAVideoFormat[31].RefreshIndex= CEAVideoFormatTable[31].DefaultRefRateIndex; + ulNumOf3DFormat++; + } + pCEAVideoFormat[31].Video3DSupportStructs.FramePacking = 1; + pCEAVideoFormat[31].Video3DSupportStructs.TopAndBottom = 1; + + // format 20, 1920x1080i@50Hz + if( !pCEAVideoFormat[19].IsSupported) + { + pCEAVideoFormat[19].IsSupported=CBIOS_TRUE; + pCEAVideoFormat[19].BlockIndex = (CBIOS_U8)0; + pCEAVideoFormat[19].IsNative = CBIOS_FALSE; + pCEAVideoFormat[19].RefreshIndex= CEAVideoFormatTable[19].DefaultRefRateIndex; + ulNumOf3DFormat++; + } + pCEAVideoFormat[19].Video3DSupportStructs.SideBySideHalf = 1; + + //format 19, 1280x720p@50Hz + if( !pCEAVideoFormat[18].IsSupported) + { + pCEAVideoFormat[18].IsSupported=CBIOS_TRUE; + pCEAVideoFormat[18].BlockIndex = (CBIOS_U8)0; + pCEAVideoFormat[18].IsNative = CBIOS_FALSE; + pCEAVideoFormat[18].RefreshIndex= CEAVideoFormatTable[18].DefaultRefRateIndex; + ulNumOf3DFormat++; + } + pCEAVideoFormat[18].Video3DSupportStructs.FramePacking = 1; + pCEAVideoFormat[18].Video3DSupportStructs.TopAndBottom = 1; + } + + //Additional 3D formats + //check 3D_structure_all_X + for (i = 0; (i < SVDPayloadLength) && (i < 16); i++) + { + Status = cbEDIDModule_GetFmtIdxFromSVD(SVDList[i], &formatNum, &IsNative); + if (!Status) + { + continue; + } + + if (pVSDBData->HDMI3DMask & (1 << i)) + { + pCEAVideoFormat[formatNum - 1].Video3DSupportCaps |= pVSDBData->HDMI3DStructAll; + } + } + + //check 3D structure + for (i = 0; i < pVSDBData->HDMI3DFormatCount; i++) + { + Status = cbEDIDModule_GetFmtIdxFromSVD(SVDList[pVSDBData->HDMI3DForamt[i].HDMI2DVICOrder], &formatNum, &IsNative); + if (!Status) + { + continue; + } + + pCEAVideoFormat[formatNum - 1].Video3DSupportCaps |= 1 << pVSDBData->HDMI3DForamt[i].HDMI3DStructure; + } + + return ulNumOf3DFormat; +} + +static CBIOS_U32 cbEDIDModule_GetDisplayIDType1DetailedMode(CBIOS_U8 *pType1TimingInEDID, PCBIOS_MODE_INFO_EXT pDisplayIDDtlMode) +{ + CBIOS_U32 i = 0; + CBIOS_U32 PayloadLen = 0; + CBIOS_U32 ulNumOfModes = 0; + + PayloadLen = pType1TimingInEDID[2]; + + for (i = 0; i < PayloadLen/DID_TYPE1_TIMING_DESCRIPTOR_LENGTH; i++) + { + pDisplayIDDtlMode[ulNumOfModes].PixelClock = (((pType1TimingInEDID[5 + i*20] << 16) | (pType1TimingInEDID[4 + i*20] << 8) | (pType1TimingInEDID[3 + i*20])) * 100); + if(pDisplayIDDtlMode[ulNumOfModes].PixelClock == 0) + { + pDisplayIDDtlMode[ulNumOfModes].Valid = 0; + continue; + } + else + { + pDisplayIDDtlMode[ulNumOfModes].Valid = 1; + pDisplayIDDtlMode[ulNumOfModes].HActive = (((pType1TimingInEDID[8 + i*20] << 8) | (pType1TimingInEDID[7 + i*20])) + 1); + pDisplayIDDtlMode[ulNumOfModes].HBlank = (((pType1TimingInEDID[10 + i*20] << 8) | (pType1TimingInEDID[9 + i*20])) + 1); + pDisplayIDDtlMode[ulNumOfModes].HSyncOffset= ((((pType1TimingInEDID[12 + i*20] & 0x7F) << 8) | (pType1TimingInEDID[11 + i*20])) + 1); + pDisplayIDDtlMode[ulNumOfModes].HSyncPulseWidth = (((pType1TimingInEDID[14 + i*20] << 8) | (pType1TimingInEDID[13 + i*20])) + 1); + pDisplayIDDtlMode[ulNumOfModes].HSync = (pType1TimingInEDID[12 + i*20] & 0x80) ? HorPOSITIVE : HorNEGATIVE; + pDisplayIDDtlMode[ulNumOfModes].VActive = (((pType1TimingInEDID[16 + i*20] << 8) | (pType1TimingInEDID[15 + i*20])) + 1); + pDisplayIDDtlMode[ulNumOfModes].VBlank = (((pType1TimingInEDID[18 + i*20] << 8) | (pType1TimingInEDID[17 + i*20])) + 1); + pDisplayIDDtlMode[ulNumOfModes].VSyncOffset = ((((pType1TimingInEDID[20 + i*20] & 0x7F) << 8) | (pType1TimingInEDID[19 + i*20])) + 1); + pDisplayIDDtlMode[ulNumOfModes].VSyncPulseWidth = (((pType1TimingInEDID[22 + i*20] << 8) | (pType1TimingInEDID[21 + i*20])) + 1); + pDisplayIDDtlMode[ulNumOfModes].VSync = (pType1TimingInEDID[20 + i*20] & 0x80) ? VerPOSITIVE : VerNEGATIVE; + pDisplayIDDtlMode[ulNumOfModes].InterLaced = (pType1TimingInEDID[6 + i*20] & 0x10) ? CBIOS_TRUE : CBIOS_FALSE; + + if((pDisplayIDDtlMode[ulNumOfModes].HActive == 0 )|| (pDisplayIDDtlMode[ulNumOfModes].VActive == 0)) + { + pDisplayIDDtlMode[ulNumOfModes].Valid = 0; + continue; + } + + pDisplayIDDtlMode[ulNumOfModes].Refreshrate = cbCalcRefreshRate(pDisplayIDDtlMode[ulNumOfModes].PixelClock, + pDisplayIDDtlMode[ulNumOfModes].HActive, + pDisplayIDDtlMode[ulNumOfModes].HBlank, + pDisplayIDDtlMode[ulNumOfModes].VActive, + pDisplayIDDtlMode[ulNumOfModes].VBlank); + pDisplayIDDtlMode[ulNumOfModes].Refreshrate = 100 * cbRound(pDisplayIDDtlMode[ulNumOfModes].Refreshrate, 100, ROUND_NEAREST); + + ulNumOfModes++; + } + } + return ulNumOfModes; +} + +/*************************************************************** +Function: cbEDIDModule_GetCEADetailedMode + +Description: + +Input: pEDID, EDID data buffer + +Output: pEDIDStruct, store decoded CEA data + +Return: the number of mode get in CEA extension +***************************************************************/ +static CBIOS_U32 cbEDIDModule_GetCEA861Mode(CBIOS_U8 *pEDID, PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct, CBIOS_U32 TotalBlocks) +{ + CBIOS_U32 BlockIndex = 0; + CBIOS_U8 *pEDIDBlock = CBIOS_NULL; + CBIOS_U8 DetailedTimingOffset = 0, SVDDataOffset = 0; + CBIOS_U8 AudioFormatDataOffset = 0; + CBIOS_U32 PayloadLength = 0; + CBIOS_U32 i = 0; + CBIOS_U32 ulModeNumOfCEABlock = 0; + + if (TotalBlocks > MAX_EDID_BLOCK_NUM) + { + // TBD: support for more than 8 blocks + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEDIDModule_GetCEA861Mode: Total %d blocks but currently only parse 8 blocks!\n", TotalBlocks)); + //ASSERT(CBIOS_FALSE); + + TotalBlocks = MAX_EDID_BLOCK_NUM; + } + + //parse extension blocks + for (BlockIndex = 1; BlockIndex < TotalBlocks; BlockIndex++) + { + pEDIDBlock = pEDID + BlockIndex * 128; + + //check CEA Tag + if (pEDIDBlock[0x00] != CEA_TAG) + { + continue; + } + + // Check CEA861 Version. + if (pEDIDBlock[0x01] == 0x00) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbEDIDModule_GetCEA861Mode: EDID block%d indicates invalid CEA861 block version!\n", BlockIndex)); + } + + DetailedTimingOffset = pEDIDBlock[0x02]; + if (DetailedTimingOffset == 0) + { + //no detailed timing block, no reserved data block + continue; + } + + //parse data blocks + for (i = 4; i < DetailedTimingOffset;) + { + if (((pEDIDBlock[i] >> 5) & 0x07) == AUDIO_DATA_BLOCK_TAG) + { + //audio data block + AudioFormatDataOffset = (CBIOS_U8)i; + PayloadLength = pEDIDBlock[i++] & 0x1F; + pEDIDStruct->TotalHDMIAudioFormatNum += cbEDIDModule_GetHDMIAudioFormat(&pEDIDBlock[AudioFormatDataOffset], pEDIDStruct->HDMIAudioFormat); + i += PayloadLength; + } + else if (((pEDIDBlock[i] >> 5) & 0x07) == VIDEO_DATA_BLOCK_TAG) + { + //decode short video descriptor + SVDDataOffset = (CBIOS_U8)i; + PayloadLength = pEDIDBlock[i++] & 0x1F; + ulModeNumOfCEABlock += cbEDIDModule_GetSVDMode(&pEDIDBlock[SVDDataOffset], pEDIDStruct, BlockIndex); + i += PayloadLength; + } + else if ((((pEDIDBlock[i] >> 5) & 0x07) == VENDOR_SPECIFIC_DATA_BLOCK_TAG))//now consider HDMI VSDB and HDMI Forum VSDB only, ignore other VSDBs + { + if((pEDIDBlock[i + 1] == 0x03) && + (pEDIDBlock[i + 2] == 0x0c) && + (pEDIDBlock[i + 3] == 0x00)) + { + i += cbEDIDModule_ParseHDMIVSDB(&pEDIDBlock[i], &(pEDIDStruct->Attribute.VSDBData)); + } + else if((pEDIDBlock[i + 1] == 0xD8) && + (pEDIDBlock[i + 2] == 0x5D) && + (pEDIDBlock[i + 3] == 0xC4)) + { + i += cbEDIDModule_ParseHFVSDB(&pEDIDBlock[i], &(pEDIDStruct->Attribute.HFVSDBData)); + } + else + { + PayloadLength = pEDIDBlock[i++] & 0x1F; + i += PayloadLength; + } + + } + else if (((pEDIDBlock[i] >> 5) & 0x07) == SPEAKER_ALLOCATION_DATA_BLOCK_TAG) + { + //This payload is preceded by a Tag Code Byte that includes a tag equal to 4 and a length of 3 + i += 4; + } + else if (((pEDIDBlock[i] >> 5) & 0x07) == CEA_EXTENDED_BLOCK_TAG) + { + i += cbEDIDModule_ParseCEAExtBlock(&pEDIDBlock[i], pEDIDStruct, BlockIndex); + } + else + { + PayloadLength = pEDIDBlock[i++] & 0x1F; + i += PayloadLength; + } + } + } + //some monitor's AUDIO_DATA_BLOCK not support LPCM,but it indicates support basic audio, should patch here + cbEDIDPatchHDMIAudio(pEDIDStruct,&pEDIDStruct->HDMIAudioFormat[0]); + //patch for some monitor can't display some CEA modes. + cbEDIDPatchHDMICEAMode(pEDID, pEDIDStruct, &ulModeNumOfCEABlock); + + // get the detailed timing in CEA extension + ulModeNumOfCEABlock += cbEDIDModule_GetCEADetailedMode(pEDID, pEDIDStruct->DTDTimings, TotalBlocks); + + // get the 3D video mandatory formats + if (pEDIDStruct->Attribute.VSDBData.HDMI3DPresent) + { + ulModeNumOfCEABlock += cbEDIDModule_Get3DFormat(&pEDIDBlock[SVDDataOffset], + &(pEDIDStruct->Attribute.VSDBData), + pEDIDStruct->HDMIFormat); + } + + // get HDMI VIC mode + ulModeNumOfCEABlock += cbEDIDModule_GetHDMIVICMode(&(pEDIDStruct->Attribute.VSDBData), + pEDIDStruct->HDMIFormat); + + //check if modes support YCbCr420 but not listed in svd exist. if so, add it + for(i=0; iHDMIFormat[i].IsSupportYCbCr420 && (!pEDIDStruct->HDMIFormat[i].IsSupported)) + { + pEDIDStruct->HDMIFormat[i].IsSupported=CBIOS_TRUE; + pEDIDStruct->HDMIFormat[i].BlockIndex = (CBIOS_U8)0; + pEDIDStruct->HDMIFormat[i].IsNative = CBIOS_FALSE; + pEDIDStruct->HDMIFormat[i].RefreshIndex= CEAVideoFormatTable[i].DefaultRefRateIndex; + ulModeNumOfCEABlock++; + } + } + + return ulModeNumOfCEABlock; + +} + +static CBIOS_U32 cbEDIDModule_GetDisplayIDMode(CBIOS_U8 *pEDID, PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct) +{ + CBIOS_U32 TotalBlocks = 0, BlockIndex = 0; + CBIOS_U8 *pEDIDBlock = CBIOS_NULL; + CBIOS_U32 PayloadLength = 0; + CBIOS_U32 i = 0; + CBIOS_U32 ulModeNumOfDisplayIDBlock = 0; + + TotalBlocks = pEDID[0x7E] + 1; // Ext. blocks plus base block. + if (TotalBlocks > MAX_EDID_BLOCK_NUM) + { + // TBD: support for more than 8 blocks + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEDIDModule_GetDisplayIDMode: Total %d blocks but currently only parse 4 blocks!\n", TotalBlocks)); + //ASSERT(CBIOS_FALSE); + + TotalBlocks = MAX_EDID_BLOCK_NUM; + } + + //parse extension blocks + for (BlockIndex = 1; BlockIndex < TotalBlocks; BlockIndex++) + { + pEDIDBlock = pEDID + BlockIndex * 128; + //check DisplayID Tag + if (pEDIDBlock[0x00] != DISPLAYID_TAG) + { + continue; + } + // check Section Size + if(pEDIDBlock[2] <= 0) + { + continue; + } + + for(i = 5; i < 128;) + { + if(pEDIDBlock[i] == VIDEO_TIMING_MODES_DATA_BLOCK_TYPE1_TAG) + { + PayloadLength = pEDIDBlock[i+2]; + ulModeNumOfDisplayIDBlock += cbEDIDModule_GetDisplayIDType1DetailedMode(&pEDIDBlock[i],pEDIDStruct->DisplayID_TYPE1_Timings); + i = i + 3 + PayloadLength; + } + else + { + //TODO for other block + PayloadLength = pEDIDBlock[i+2]; + i = i + 3 + PayloadLength; + } + } + } + return ulModeNumOfDisplayIDBlock; +} + +/*************************************************************** +Function: cbEDIDModule_SetNativeFlag + +Description: Set native mode flag of detailed timings in base and CEA extension EDID + +Input: PCBIOS_EDID_STRUCTURE_DATA, parsed EDID structure data buffer + +Output: + +Return: +***************************************************************/ +static CBIOS_VOID cbEDIDModule_SetNativeFlag(PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct) +{ + CBIOS_U32 NativeModeNum = 0; + CBIOS_U32 i; + + NativeModeNum = pEDIDStruct->Attribute.TotalNumberOfNativeFormat; + + for (i = 0; i < CBIOS_DTLMODECOUNT; i++) + { + if ((NativeModeNum > 0) && (pEDIDStruct->DtlTimings[i].Valid)) + { + pEDIDStruct->DtlTimings[i].IsNativeMode = CBIOS_TRUE; + NativeModeNum--; + + if (NativeModeNum <= 0) + { + break; + } + } + } + + if (NativeModeNum > 0) + { + for (i = 0; i < CBIOS_DTDTIMINGCOUNTS; i++) + { + if ((NativeModeNum > 0) && (pEDIDStruct->DTDTimings[i].Valid)) + { + pEDIDStruct->DTDTimings[i].IsNativeMode = CBIOS_TRUE; + NativeModeNum--; + + if(NativeModeNum <= 0) + { + break; + } + } + } + } + + return; +} + +/*************************************************************** +Function: cbEDIDModule_GetMonitorSize + +Description: Get monitor image size. + +Input: pEDID, EDID data buffer + +Output: + +Return: Monitor DPI +***************************************************************/ +static CBIOS_VOID cbEDIDModule_GetMonitorSize(CBIOS_U8 *pEDID, PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttrib) +{ + CBIOS_U16 HImageSize = 0, VImageSize = 0; + CBIOS_U8 *pDtlTimingsInBaseEDID = pEDID + DETAILED_TIMINGS_INDEX; + + HImageSize = (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pDtlTimingsInBaseEDID,0,EDIDHorizontalImageSize); + VImageSize = (CBIOS_U16)cbEDIDModule_MapMaskGetEdidInfo(pDtlTimingsInBaseEDID,0,EDIDVerticalImageSize); + if ((HImageSize != 0) && (VImageSize != 0)) + { + pMonitorAttrib->MonitorHorSize = HImageSize; // monitor screen image horizontal size in millimeter(mm) + pMonitorAttrib->MonitorVerSize = VImageSize; // monitor screen image vertical size in millimeter(mm) + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbEDIDModule_GetMonitorDPI: error -- monitor image size is zero!\n")); + } + + return; + +} + +/*************************************************************** +Function: cbEDIDModule_GetMonitorAttrib + +Description: Get monitor attribute + +Input: pEDID, EDID data buffer + +Output: pMonitorAttrib, store decoded monitor attributes + +Return: CEA861 MonitorCaps +***************************************************************/ +CBIOS_U32 cbEDIDModule_GetMonitorAttrib(CBIOS_U8 *pEDID, PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttrib, CBIOS_U32 TotalBlocks) +{ + CBIOS_BOOL bIsHDMIDevice = CBIOS_FALSE; + CBIOS_U32 BlockIndex = 0; + CBIOS_U8 *pEDIDBlock = CBIOS_NULL; + CBIOS_U32 i = 0, j = 0; + CBIOS_U8 *pDtlTimingsInBaseEDID = pEDID + DETAILED_TIMINGS_INDEX; + CBIOS_U8 SADCnt = 0; + + if(!cbEDIDModule_IsEDIDValid(pEDID)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: Not valid EDID!\n", FUNCTION_NAME)); + return CBIOS_ER_EDID_INVALID; + } + + // Manufacture name, EDID base block offset 0x08~0x09 + cb_memcpy(pMonitorAttrib->ManufactureName, &pEDID[0x08], 0x02); + // ProductCode, EDID base block offset 0x0a~0x0b + cb_memcpy(pMonitorAttrib->ProductCode, &pEDID[0x0A], 0x02); + + // scan base EDID + for (i = 0; i < 4; i++) + { + // detail timing + if ((pDtlTimingsInBaseEDID[i*18] != 0x00) && + (pDtlTimingsInBaseEDID[i*18+0x1] != 0x00)) + { + CBIOS_U8 byte17 = 0; + byte17 = (pDtlTimingsInBaseEDID[i*18+0x11]&0x61); + + if(byte17) + { + pMonitorAttrib->bStereoViewSupport = CBIOS_TRUE; + switch(byte17) + { + case 0x20: + pMonitorAttrib->StereoViewType = FIELD_SEQ_RIGHT; + break; + case 0x40: + pMonitorAttrib->StereoViewType = FIELD_SEQ_LEFT; + break; + case 0x21: + pMonitorAttrib->StereoViewType = TWO_WAY_RIGHT; + break; + case 0x41: + pMonitorAttrib->StereoViewType = TWO_WAY_LEFT; + break; + case 0x60: + pMonitorAttrib->StereoViewType = FOUR_WAY; + break; + case 0x61: + pMonitorAttrib->StereoViewType = SIDE_BY_SIDE_INTERLEAVE; + break; + default: + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbEDIDModule_GetMonitorAttrib: No matched StereoViewType, byte17 is %d!\n", byte17)); + break; + } + } + } + + + // the monitor descriptor block + if((pDtlTimingsInBaseEDID[i*18] == 0x00) && + (pDtlTimingsInBaseEDID[i*18+0x1] == 0x00) && + (pDtlTimingsInBaseEDID[i*18+0x2] == 0x00) && + (pDtlTimingsInBaseEDID[i*18+0x3] == 0xFC) && + (pDtlTimingsInBaseEDID[i*18+0x4] == 0x00)) + { + for (j = 0; j < 13; j++) + { + if (pDtlTimingsInBaseEDID[i*18+5+j] == 0x0A) // end signature of monitor name + { + break; + } + + pMonitorAttrib->MonitorName[j] = pDtlTimingsInBaseEDID[i*18+5+j]; + } + } + + } + + // get monitor screen image horizontal and vertical size in base EDID detailed timing + cbEDIDModule_GetMonitorSize(pEDID, pMonitorAttrib); + + pMonitorAttrib->CEA861MonitorCaps = 0; + + // check EDID version 1.4, since majority of DP monitors don't have extended EDID block + if ((pEDID[0x12] == 0x01) && (pEDID[0x13] == 0x04)) + { + if (pEDID[0x14] & 0x80) + { + pMonitorAttrib->IsCEA861RGB = 1; + if ((pEDID[0x18] & 0x18) == 0x08) + { + pMonitorAttrib->IsCEA861YCbCr444 = 1; + } + else if ((pEDID[0x18] & 0x18) == 0x10) + { + pMonitorAttrib->IsCEA861YCbCr422 = 1; + } + else if ((pEDID[0x18] & 0x18) == 0x18) + { + pMonitorAttrib->IsCEA861YCbCr444 = 1; + pMonitorAttrib->IsCEA861YCbCr422 = 1; + } + } + } + + if (TotalBlocks > MAX_EDID_BLOCK_NUM) + { + // TBD: support for more than 8 blocks + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbEDIDModule_GetCEAMonitorCaps: Total %d blocks but currently only parse 8 blocks!\n", TotalBlocks)); + //ASSERT(CBIOS_FALSE); + + TotalBlocks = MAX_EDID_BLOCK_NUM; + } + + for (BlockIndex = 1; BlockIndex < TotalBlocks; BlockIndex++) + { + pEDIDBlock = pEDID + BlockIndex * 128; + + //check CEA Tag + if (pEDIDBlock[0x00] != CEA_TAG) + { + continue; + } + + // Check CEA861 Version. + if (pEDIDBlock[0x01] == 0x00) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbEDIDModule_GetCEAMonitorCaps: EDID block%d indicates invalid CEA861 block version!\n", BlockIndex)); + continue; + } + + pMonitorAttrib->IsCEA861Monitor = CBIOS_TRUE; + pMonitorAttrib->IsCEA861RGB = CBIOS_TRUE; + + // Initialize the CEA861 misc attribution. + pMonitorAttrib->Tag = pEDIDBlock[0x00]; + pMonitorAttrib->RevisionNumber = pEDIDBlock[0x01]; + pMonitorAttrib->OffsetOfDetailedTimingBlock = pEDIDBlock[0x02]; + pMonitorAttrib->TotalNumberOfNativeFormat = pEDIDBlock[0x03] & 0x0F; + pMonitorAttrib->IsCEA861UnderScan = (pEDIDBlock[0x03] & 0x80) >> 7; + pMonitorAttrib->IsCEA861Audio = (pEDIDBlock[0x03] & 0x40) >> 6; + pMonitorAttrib->IsCEA861YCbCr444 = (pEDIDBlock[0x03] & 0x20) >> 5; + pMonitorAttrib->IsCEA861YCbCr422 = (pEDIDBlock[0x03] & 0x10) >> 4; + + for(i = 4; i < pMonitorAttrib->OffsetOfDetailedTimingBlock;) + { + if (((pEDIDBlock[i] >> 5) & 0x07) == VENDOR_SPECIFIC_DATA_BLOCK_TAG) + { + CBIOS_U8 PayloadLength = pEDIDBlock[i++] & 0x1F; + + if ((pEDIDBlock[i] == 0x03) + && (pEDIDBlock[i + 1] == 0x0C) + && (pEDIDBlock[i + 2] == 0x00)) + { + bIsHDMIDevice = CBIOS_TRUE; + } + + i += PayloadLength; + } + else if (((pEDIDBlock[i] >> 5) & 0x07) == AUDIO_DATA_BLOCK_TAG) + { + //audio data block + CBIOS_U8 PayloadLength = pEDIDBlock[i++] & 0x1F; + SADCnt += PayloadLength/3; // 3bytes makes one audio format + + if (SADCnt > 15) + { + SADCnt = 15; //ELD spec define, at most 15 SADs + } + if (SADCnt > pMonitorAttrib->SAD_Count) + { + cb_memcpy(((CBIOS_U8 *)pMonitorAttrib->CEA_SADs + pMonitorAttrib->SAD_Count * 3), + &pEDIDBlock[i], (SADCnt - pMonitorAttrib->SAD_Count)*3 ); + } + + pMonitorAttrib->SAD_Count = SADCnt; + + i += PayloadLength; + } + else if (((pEDIDBlock[i] >> 5) & 0x07) == SPEAKER_ALLOCATION_DATA_BLOCK_TAG) + { + //This payload is preceded by a Tag Code Byte that includes a tag equal to 4 and a length of 3 + pMonitorAttrib->SpeakerAllocationData = pEDIDBlock[i+1]; + i += 4; + } + else + { + CBIOS_U32 PayloadLength = (pEDIDBlock[i++] & 0x1F); + + i += PayloadLength; + } + } + + if (bIsHDMIDevice + && (pMonitorAttrib->IsCEA861UnderScan + | pMonitorAttrib->IsCEA861Audio + | pMonitorAttrib->IsCEA861YCbCr422 + | pMonitorAttrib->IsCEA861YCbCr444)) + { + pMonitorAttrib->IsCEA861HDMI = CBIOS_TRUE; + } + } + + return pMonitorAttrib->CEA861MonitorCaps; + +} + +/*************************************************************** +Function: cbEDIDModule_GetMonitor3DCaps + +Description: Get monitor 3D capability + +Input: pEDIDStruct, decoded EDID timings and attributes + IsSupport3DVideo, whether the monitor supports 3D video + +Output: p3DCapability, store decoded monitor 3D capabilitys + +Return: +***************************************************************/ +CBIOS_STATUS cbEDIDModule_GetMonitor3DCaps(PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct, + PCBIOS_MONITOR_3D_CAPABILITY_PARA p3DCapability, + CBIOS_U32 IsHWSupportHDMI3DVideo) +{ + PCBIOS_HDMI_FORMAT_DESCRIPTOR pSupportFormat = CBIOS_NULL; + CBIOS_U32 Monitor3DModeNum = 0; + PCBIOS_3D_VIDEO_MODE_LIST pModeList = p3DCapability->pMonitor3DModeList; + CBIOS_U32 i; + + p3DCapability->bStereoViewSupport = pEDIDStruct->Attribute.bStereoViewSupport; + p3DCapability->StereoViewType = pEDIDStruct->Attribute.StereoViewType; + + if (IsHWSupportHDMI3DVideo && pEDIDStruct->Attribute.VSDBData.HDMI3DPresent) + { + p3DCapability->bIsSupport3DVideo = CBIOS_TRUE; + pSupportFormat = pEDIDStruct->HDMIFormat; + + for (i = 0; i < CBIOS_HDMIFORMATCOUNTS; i++) + { + if ((pSupportFormat[i].IsSupported) + && (pSupportFormat[i].Video3DSupportCaps & CBIOS_3D_VIDEO_FORMAT_MASK)) + { + Monitor3DModeNum++; + + if (pModeList != CBIOS_NULL) + { + pModeList->XRes = CEAVideoFormatTable[i].XRes; + pModeList->YRes = CEAVideoFormatTable[i].YRes; + pModeList->RefreshRate = CEAVideoFormatTable[i].RefRate[pSupportFormat[i].RefreshIndex]; + pModeList->bIsInterlace = (CBIOS_BOOL)CEAVideoFormatTable[i].Interlace; + pModeList->SupportCaps = pSupportFormat[i].Video3DSupportCaps & CBIOS_3D_VIDEO_FORMAT_MASK; + pModeList->IsSupport3DOSDDisparity = pEDIDStruct->Attribute.HFVSDBData.IsSupport3DOSDDisparity; + pModeList->IsSupport3DDualView = pEDIDStruct->Attribute.HFVSDBData.IsSupport3DDualView; + pModeList->IsSupport3DIndependentView = pEDIDStruct->Attribute.HFVSDBData.IsSupport3DIndependentView; + pModeList++; + } + + } + } + + //if no 3D mode is supported, set support flags to not support 3D video + if (Monitor3DModeNum == 0) + { + p3DCapability->bIsSupport3DVideo = CBIOS_FALSE; + } + p3DCapability->Monitor3DModeNum = Monitor3DModeNum; + } + else + { + p3DCapability->bIsSupport3DVideo = CBIOS_FALSE; + p3DCapability->Monitor3DModeNum = 0; + } + + return CBIOS_OK; +} + +/*************************************************************** +Function: cbEDIDModule_IsEDIDValid + +Description: if the EDID header is valid + +Input: pEDID, EDID data buffer + +Output: + +Return: CBIOS_TRUE if EDID header vaild + CBIOS_FALSE if EDID header invaild +***************************************************************/ +CBIOS_BOOL cbEDIDModule_IsEDIDHeaderValid(CBIOS_U8 *pEDIDBuffer, CBIOS_U32 ulBufferSize) +{ + CBIOS_U8 EDID1header[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}; + CBIOS_BOOL bRet = CBIOS_FALSE; + + if(ulBufferSize < sizeof(EDID1header)) + return CBIOS_FALSE; + + if((pEDIDBuffer != CBIOS_NULL) && + (!cb_memcmp(pEDIDBuffer, EDID1header, sizeof(EDID1header)))) + bRet = CBIOS_TRUE; + + return bRet; +} + +/*************************************************************** +Function: cbEDIDModule_IsEDIDValid + +Description: if the EDID data is CBIOS_NULL, the header is not correct + or the check sum is not zero, return false; + otherwise return true. + +Input: pEDID, EDID data buffer + +Output: + +Return: CBIOS_TRUE if EDID vaild + CBIOS_FALSE if EDID is null, header is not correct + or check sum is not zero +***************************************************************/ +CBIOS_BOOL cbEDIDModule_IsEDIDValid(CBIOS_U8 *pEDID) +{ + CBIOS_U32 ulBufferSize; + CBIOS_U8 byTemp; + CBIOS_U32 i; + CBIOS_BOOL bRet = CBIOS_FALSE; + + ulBufferSize = 256; + if((pEDID != CBIOS_NULL) && cbEDIDModule_IsEDIDHeaderValid(pEDID, ulBufferSize)) + { + byTemp = 0; + for (i = 0 ; i < ulBufferSize ; i++) + { + byTemp = byTemp + pEDID[i]; + //if checksum of 128 or 256 bytes is 0, success. + if(((i == 127) && (byTemp == 0)) ||((i == 255) && (byTemp == 0))) + { + break; + } + } + + if(byTemp == 0) + { + bRet = CBIOS_TRUE; + } + } + + return bRet; +} + +/*************************************************************** +Function: cbEDIDModule_GetMonitorID + +Description: Get monitor ID manufacturer name + +Input: pEDID, monitor EDID data buffer + +Output: pMnitorID, monitor ID manufacturer name buffer + +Return: CBIOS_TRUE if get monitor ID successfully + CBIOS_FALSE if get monitor ID failed +***************************************************************/ +CBIOS_BOOL cbEDIDModule_GetMonitorID(CBIOS_U8 *pEDID, CBIOS_U8 *pMonitorID) +{ + CBIOS_U8 index[32] = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]^_"; + CBIOS_U8 ProductID[3] = {0}; + CBIOS_BOOL bRet = CBIOS_FALSE; + CBIOS_U8 *pMonitorIDinEDID = pEDID + MONITORIDINDEX; + + if ((pMonitorIDinEDID == CBIOS_NULL) || (pMonitorID == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbEDIDModule_GetMonitorID: input buffer is null!\n")); + return CBIOS_FALSE; + } + + //get manufacturer ID + pMonitorID[0] = index[(pMonitorIDinEDID[0] >> 2) & 0x1F]; + pMonitorID[1] = index[((pMonitorIDinEDID[1] >> 5) & 0x07) | ((pMonitorIDinEDID[0] << 3) & 0x18)]; + pMonitorID[2] = index[pMonitorIDinEDID[1] & 0x1F]; + pMonitorID[3] = '\0'; + + if (cbItoA((CBIOS_U32)pMonitorIDinEDID[3], ProductID, 16, 2)) + { + cbStrCat(pMonitorID, ProductID); + if (cbItoA((CBIOS_U32)pMonitorIDinEDID[2], ProductID, 16, 2)) + { + cbStrCat(pMonitorID, ProductID); + bRet = CBIOS_TRUE; + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "Monitor ID is: %s\n", pMonitorID)); + } + } + + return bRet; + +} + +//For HDMI and DP:Patch to disable 24bit for L_PCM audio format to pass HLK wave test +CBIOS_VOID cbEDIDModule_SADPatch(PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct) +{ + CBIOS_U32 Index = 0; + CBIOS_U8 SADCnt = pEDIDStruct->Attribute.SAD_Count; + CBIOS_U32 HDMIAudioFormatNum = pEDIDStruct->TotalHDMIAudioFormatNum; + PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttrib = &(pEDIDStruct->Attribute); + + //modify SAD to disable 24bit for L_PCM audio format + for (Index = 0; Index < SADCnt; Index++) + { + if (((pMonitorAttrib->CEA_SADs[Index][0] >> 3) & 0xF) == 1) + { + if ((pMonitorAttrib->CEA_SADs[Index][2] >> 2) & 0x1) + { + pMonitorAttrib->CEA_SADs[Index][2] &= 0xFB; + } + } + } + + for (Index = 0; Index < HDMIAudioFormatNum; Index++) + { + if (pEDIDStruct->HDMIAudioFormat[Index].Format == CBIOS_AUDIO_FORMAT_LPCM) + { + pEDIDStruct->HDMIAudioFormat[Index].BitDepth.BD_24bit = 0; + } + } +} + +CBIOS_VOID cbEDIDModule_Patch(CBIOS_U8 *pEDID, CBIOS_U32 TotalBlocks) +{ + PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttrib = CBIOS_NULL; + CBIOS_UCHAR MonitorID[8] = {0}; + + pMonitorAttrib = cb_AllocateNonpagedPool(sizeof(CBIOS_MONITOR_MISC_ATTRIB)); + if (pMonitorAttrib == CBIOS_NULL) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: pMonitorAttrib allocate error.\n", FUNCTION_NAME)); + return; + } + + cbEDIDModule_GetMonitorAttrib(pEDID, pMonitorAttrib, TotalBlocks); + cbEDIDModule_GetMonitorID(pEDID, MonitorID); + + // PHILIPS 24PFL3545 monitor exist a vertical garbage of mode 1920x1080i@50Hz as Hsync offset + // is not correct in EDID CEA extension. Patch this issue by correct EDID data. + if ((!cb_strcmp(MonitorID, (CBIOS_UCHAR*)"PHL0010")) && (!cb_strcmp(pMonitorAttrib->MonitorName, (CBIOS_UCHAR*)"B24PFL3545/T3")) && (pMonitorAttrib->IsCEA861HDMI)) + { + cb_memcpy(pEDID, PHL_24PFL3545_Edid, CBIOS_EDIDDATABYTE); + } + + cb_FreePool(pMonitorAttrib); +} + + +/*************************************************************** +Function: cbEDIDModule_ParseEDID + +Description: parse the whole EDID data + +Input: pEDID, EDID data buffer + ulBufferSize, specify the size of EDID data buffer + +Output: pEDIDStruct, store decoded EDID timings and attributes + +Return: +***************************************************************/ +CBIOS_BOOL cbEDIDModule_ParseEDID(CBIOS_U8 *pEDID, PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct, CBIOS_U32 ulBufferSize) +{ + CBIOS_U32 ulModeNum = 0; + CBIOS_U32 BlockNum = ulBufferSize / EDID_BLOCK_SIZE_SPEC; + CBIOS_BOOL bRet = CBIOS_FALSE; + + + if (cbEDIDModule_IsEDIDValid(pEDID)) + { + cbEDIDModule_Patch(pEDID, BlockNum); + + cb_memset(pEDIDStruct, 0, sizeof(CBIOS_EDID_STRUCTURE_DATA)); + + ulModeNum += cbEDIDModule_GetEstablishMode(pEDID, pEDIDStruct->EstTimings); + ulModeNum += cbEDIDModule_GetStandardMode(pEDID, pEDIDStruct->StdTimings); + ulModeNum += cbEDIDModule_GetDetailedMode(pEDID, pEDIDStruct->DtlTimings, 4); + + cbEDIDModule_GetMonitorAttrib(pEDID, &(pEDIDStruct->Attribute), BlockNum); + + if (ulBufferSize > 128) + { + ulModeNum += cbEDIDModule_GetCEA861Mode(pEDID, pEDIDStruct, BlockNum); + if (pEDIDStruct->Attribute.TotalNumberOfNativeFormat > 0) + { + cbEDIDModule_SetNativeFlag(pEDIDStruct); + } + } + if (ulBufferSize > 128) + { + ulModeNum += cbEDIDModule_GetDisplayIDMode(pEDID, pEDIDStruct); + } + + bRet = CBIOS_TRUE; + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbEDIDModule_ParseEDID: EDID is invalid!\n")); + } + + pEDIDStruct->TotalModeNum = ulModeNum; + + return bRet; +} + +/*************************************************************** +Function: cbEDIDModule_SearchTmInEdidStruct + +Description: Search a specific timing in decoded EDID struct where + stores all the timings in EDID + +Input: XResolution, YResolution, RefreshRate, InterlaceFlag + +Output: pTmBlock, will tell caller in whick block find the timing. + pTmBlock == 0, Establish timing block. + == 1, Standard timing block. + == 2, Detailed timing block. + == 3, HDMI Format timing block. + == 4, Detailed timing descriptor. + pTmIndex will tell caller the index number of responding timing. + +Return: CBIOS_TRUE if found the responding timing, else, return CBIOS_FALSE. +***************************************************************/ +CBIOS_BOOL cbEDIDModule_SearchTmInEdidStruct(CBIOS_U32 XResolution, + CBIOS_U32 YResolution, + CBIOS_U32 RefreshRate, + CBIOS_U32 InterlaceFlag, + PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct, + PCBIOS_U32 pTmBlock, + PCBIOS_U32 pTmIndex) +{ + CBIOS_U8 byRefRateIndex = 0; + CBIOS_BOOL bRet = CBIOS_FALSE; + CBIOS_U32 i = 0; + + for(i=0; iDtlTimings[i].Valid)&& + (pEDIDStruct->DtlTimings[i].XResolution == XResolution)&& + (pEDIDStruct->DtlTimings[i].YResolution == YResolution)&& + (pEDIDStruct->DtlTimings[i].InterLaced == InterlaceFlag)&& + ((pEDIDStruct->DtlTimings[i].Refreshrate >= (RefreshRate - 50))&& + (pEDIDStruct->DtlTimings[i].Refreshrate <= (RefreshRate + 50)))) + { + *pTmIndex = i; + *pTmBlock = 2; + bRet = CBIOS_TRUE; + break; + + } + } + if ((!bRet) && pEDIDStruct->Attribute.IsCEA861Monitor) + { + for (i = 0; i < CBIOS_DTDTIMINGCOUNTS; i++) + { + if ((pEDIDStruct->DTDTimings[i].Valid) && + (pEDIDStruct->DTDTimings[i].XResolution == XResolution) && + (pEDIDStruct->DTDTimings[i].YResolution == YResolution) && + (pEDIDStruct->DTDTimings[i].InterLaced == InterlaceFlag) && + ((pEDIDStruct->DTDTimings[i].Refreshrate >= (RefreshRate - 50)) && + (pEDIDStruct->DTDTimings[i].Refreshrate <= (RefreshRate + 50)))) + { + *pTmIndex = i; + *pTmBlock = 4; + bRet = CBIOS_TRUE; + break; + } + } + } + if((!bRet) && ((pEDIDStruct->Attribute.IsCEA861Monitor)|| + (pEDIDStruct->Attribute.IsCEA861HDMI))) + { + for(i=0; iHDMIFormat[i].RefreshIndex%2; + if((pEDIDStruct->HDMIFormat[i].IsSupported)&& + (CEAVideoFormatTable[i].XRes == XResolution)&& + (CEAVideoFormatTable[i].YRes == YResolution)&& + (CEAVideoFormatTable[i].Interlace == InterlaceFlag)&& + (CEAVideoFormatTable[i].RefRate[byRefRateIndex] == RefreshRate)) + { + *pTmIndex = i; + *pTmBlock = 3; + bRet = CBIOS_TRUE; + break; + } + } + } + if(!bRet) + { + for(i=0; iStdTimings[i].Valid)&& + (pEDIDStruct->StdTimings[i].XResolution == XResolution)&& + (pEDIDStruct->StdTimings[i].YResolution == YResolution)&& + (pEDIDStruct->StdTimings[i].Refreshrate == RefreshRate)) + { + *pTmIndex = i; + *pTmBlock = 1; + bRet = CBIOS_TRUE; + break; + } + } + } + if(!bRet) + { + for(i=0; iEstTimings[i].Valid)&& + (pEDIDStruct->EstTimings[i].XResolution == XResolution)&& + (pEDIDStruct->EstTimings[i].YResolution == YResolution)&& + (pEDIDStruct->EstTimings[i].Refreshrate == RefreshRate)) + { + *pTmIndex = i; + *pTmBlock = 0; + bRet = CBIOS_TRUE; + break; + } + } + } + if(!bRet) + { + for(i=0; iDisplayID_TYPE1_Timings[i].Valid)&& + (pEDIDStruct->DisplayID_TYPE1_Timings[i].XResolution == XResolution)&& + (pEDIDStruct->DisplayID_TYPE1_Timings[i].YResolution == YResolution)&& + (pEDIDStruct->DisplayID_TYPE1_Timings[i].InterLaced == InterlaceFlag)&& + ((pEDIDStruct->DisplayID_TYPE1_Timings[i].Refreshrate >= (RefreshRate - 50))&& + (pEDIDStruct->DisplayID_TYPE1_Timings[i].Refreshrate <= (RefreshRate + 50)))) + { + *pTmIndex = i; + *pTmBlock = 5; + bRet = CBIOS_TRUE; + break; + } + } + } + + return bRet; +} + +/*************************************************************** +Function: cbEDIDModule_FakeDetailedTiming + +Description: Fake Detailed Timing EDID data according to detailed timing. + +Input: pDtlTiming, detailed timing + +Output: pEdid, faked EDID buffer. +***************************************************************/ +static CBIOS_VOID cbEDIDModule_FakeDetailedTiming(CBIOS_U8 *pEdid, PCBIOS_MODE_INFO_EXT pDtlTiming) +{ + CBIOS_U16 HorBlanking = pDtlTiming->HBlank; + CBIOS_U16 VerBlanking = pDtlTiming->VBlank; + CBIOS_U16 HorSyncOffset = pDtlTiming->HSyncOffset; + CBIOS_U16 HorSyncWidth = pDtlTiming->HSyncPulseWidth; + CBIOS_U16 VerSyncOffset = pDtlTiming->VSyncOffset; + CBIOS_U16 VerSyncWidth = pDtlTiming->VSyncPulseWidth; + + pEdid[0x38] = (CBIOS_U8)(pDtlTiming->HActive & 0xFF); + pEdid[0x39] = (CBIOS_U8)(HorBlanking & 0xFF); + pEdid[0x3A] = (CBIOS_U8)(((pDtlTiming->HActive & 0xF00) >> 4) | ((HorBlanking & 0xF00) >> 8)); + pEdid[0x3B] = (CBIOS_U8)(pDtlTiming->VActive & 0xFF); + pEdid[0x3C] = (CBIOS_U8)(VerBlanking & 0xFF); + pEdid[0x3D] = (CBIOS_U8)(((pDtlTiming->VActive & 0xF00) >> 4) | ((VerBlanking & 0xF00) >> 8)); + pEdid[0x3E] = (CBIOS_U8)(HorSyncOffset & 0xFF); + pEdid[0x3F] = (CBIOS_U8)(HorSyncWidth & 0xFF); + pEdid[0x40] = (CBIOS_U8)((VerSyncOffset & 0x0F) << 4 | (VerSyncWidth & 0x0F)); + pEdid[0x41] = (CBIOS_U8)(((HorSyncOffset & 0x300) >> 2) | ((HorSyncWidth & 0x300) >> 4) + | ((VerSyncOffset & 0x30) >> 2) | ((VerSyncWidth & 0x30) >> 4)); + pEdid[0x42] = 0x90; + pEdid[0x43] = 0x2C; + pEdid[0x44] = 0x11; + pEdid[0x47] = 0x18; // Digital Separate + + // H polarity + if (pDtlTiming->HSync == HorPOSITIVE) + { + pEdid[0x47] |= 0x2; + } + + // V polarity + if (pDtlTiming->VSync == VerPOSITIVE) + { + pEdid[0x47] |= 0x4; + } +} + +/*************************************************************** +Function: cbEDIDModule_FakePanelEDID + +Description: Fake EDID data for Panel Device since it doesn't have + EDID data in its local side. + +Input: pFakeEdidParam, params used to fake EDID + EdidBufferLength, the length of edid buffer (currently just support 128 bytes) + +Output: pEdid, faked EDID buffer. + +Return: CBIOS_TRUE if fake panel EDID success, else, CBIOS_FALSE. +***************************************************************/ +CBIOS_BOOL cbEDIDModule_FakePanelEDID(PCBIOS_FAKE_EDID_PARAMS pFakeEdidParam, PCBIOS_U8 pEdid, const CBIOS_U32 EdidBufferLength) +{ + CBIOS_BOOL bRet = CBIOS_FALSE; + CBIOS_U32 i = 0; + CBIOS_U8 CheckSum = 0; + + if ((pFakeEdidParam == CBIOS_NULL) || (pEdid == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: the 1st or 2nd param is NULL!\n", FUNCTION_NAME)); + return bRet; + } + + if (EdidBufferLength != 128) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "%s: currently just support faking 128-byte EDID!\n", FUNCTION_NAME)); + return bRet; + } + + //fake 128 Bytes EDID only + cb_memset(pEdid, 0, EdidBufferLength); + + //EDID header + pEdid[0] = 0x00; + pEdid[1] = 0xFF; + pEdid[2] = 0xFF; + pEdid[3] = 0xFF; + pEdid[4] = 0xFF; + pEdid[5] = 0xFF; + pEdid[6] = 0xFF; + pEdid[7] = 0x00; + + //ID Manufacturer Name. Compressed ASCII. Expands to 'MS_' for Microsoft + pEdid[8] = 0x36; + pEdid[9] = 0x7f; + + //ID Product Code + pEdid[0x0A] = 0x00; + pEdid[0x0B] = 0x00; + + //ID Serial Number + pEdid[0x0C] = 0x00; + pEdid[0x0D] = 0x00; + pEdid[0x0E] = 0x00; + pEdid[0x0F] = 0x00; + + //Week and Year + pEdid[0x10] = 1; + pEdid[0x11] = 10; + + //Version + pEdid[0x12] = 0x01; + pEdid[0x13] = 0x03; + + //Mark LCD as digital device + pEdid[0x14] = 0x80; + + //Max. Horizontal Image Size, cm + pEdid[0x15] = 40; + + //Max. Vertical Image Size, cm + pEdid[0x16] = 30; + + //Display Transfer (gamma) + pEdid[0x17] = 0; + + //Add Preferred Timing Mode flag + pEdid[0x18] |= 0x02; + + //Color Characteristics + pEdid[0x19] = 0x78; + pEdid[0x1A] = 0xA0; + pEdid[0x1B] = 0x56; + pEdid[0x1C] = 0x48; + pEdid[0x1D] = 0x9A; + pEdid[0x1E] = 0x26; + pEdid[0x1F] = 0x12; + pEdid[0x20] = 0x48; + pEdid[0x21] = 0x4C; + pEdid[0x22] = 0xFF; + + //DCLK + pEdid[0x36] = (CBIOS_U8)(pFakeEdidParam->DtlTiming.PixelClock); + pEdid[0x37] = (CBIOS_U8)(pFakeEdidParam->DtlTiming.PixelClock >> 8); + + //detailed timing + if (pFakeEdidParam->bProvideDtlTimingEDID) + { + cb_memcpy(pEdid + 0x38, pFakeEdidParam->DtlTimingEDID, 16); + } + else + { + cbEDIDModule_FakeDetailedTiming(pEdid, &(pFakeEdidParam->DtlTiming)); + } + + //second 18 byte data block, display product name descriptor + //flags and tag + pEdid[0x48] = 0x00; + pEdid[0x49] = 0x00; + pEdid[0x4A] = 0x00; + pEdid[0x4B] = 0xFC; //display product name tag + pEdid[0x4C] = 0x00; + //fake monitor model name, "XXX LCD" + pEdid[0x4D] = 0x5A; + pEdid[0x4E] = 0x58; + pEdid[0x4F] = 0x47; + pEdid[0x50] = 0x20; + pEdid[0x51] = 0x4C; + pEdid[0x52] = 0x43; + pEdid[0x53] = 0x44; + pEdid[0x54] = 0x0A; + pEdid[0x55] = 0x20; + pEdid[0x56] = 0x20; + pEdid[0x57] = 0x20; + pEdid[0x58] = 0x20; + pEdid[0x59] = 0x20; + + //no extension block + pEdid[0x7E] = 0; + + //checksum + for (i = 0; i < EdidBufferLength - 1; i++) + { + CheckSum += pEdid[i]; + } + + CheckSum = 0xFF - CheckSum + 1; + pEdid[0x7F] = CheckSum; + + bRet = CBIOS_TRUE; + return bRet; +} diff --git a/drivers/gpu/drm/arise/cbios/Util/CBiosEDID.h b/drivers/gpu/drm/arise/cbios/Util/CBiosEDID.h new file mode 100644 index 0000000000000..cce1f86d15f2d --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Util/CBiosEDID.h @@ -0,0 +1,526 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + + +/***************************************************************************** +** DESCRIPTION: +** CBios EDID module interface function prototype and parameter definition. +** +** NOTE: +** ONLY EDID related and hw independent function can be added to this file. +******************************************************************************/ + +#ifndef _CBIOS_EDID_H_ +#define _CBIOS_EDID_H_ + +// some data index in base EDID block +#define MONITORIDINDEX 0x08 +#define MONITORIDLENGTH 0x04 +#define ESTABLISH_TIMINGS_INDEX 0x23 +#define STANDARD_TIMINGS_INDEX 0x26 +#define DETAILED_TIMINGS_INDEX 0x36 +#define EXTENSION_FLAG_INDEX 0x7E +#define EXTFLAGCHECKSUMINDEX 126 +#define EXTFLAGCHECKSUMLENTH 2 + +#define EDIDTIMING 0x00 +#define EDIDTIMINGEXIT 0xFF + +// mode or format count +#define CBIOS_ESTABLISHMODECOUNT 17 +#define CBIOS_STDMODECOUNT 8 +#define CBIOS_DTLMODECOUNT 4 +#define CBIOS_DTDTIMINGCOUNTS 6 +#define MAX_SVD_COUNT 31 +#define MAX_EDID_BLOCK_NUM 8 +#define MAX_HDMI_VIC_LEN 7 +#define MAX_HDMI_3D_LEN 31 +#define MAX_HDMI_3D_AUDIO_DESC_NUM 8 +#define MAX_SVR_LEN 31 +#define CBIOS_HDMI_NORMAL_VIC_COUNTS 107 //for normal VICs only +#define CBIOS_HDMI_EXTENED_VIC_COUNTS 4 +#define CBIOS_HDMIFORMATCOUNTS CBIOS_HDMI_NORMAL_VIC_COUNTS + CBIOS_HDMI_EXTENED_VIC_COUNTS +#define CBIOS_HDMI_AUDIO_FORMAT_COUNTS 16 +#define CBIOS_DISPLAYID_TYPE1_MODECOUNT 6 + +/* For support multiple segment EDID data */ +/* Current we only support at most 4 segments */ +#define CBIOS_EDIDSEGMENTCOUNT 4 +#define CBIOS_EDIDMAXBLOCKCOUNT (CBIOS_EDIDSEGMENTCOUNT * 2) +#define CBIOS_EDIDDATABYTE (256*CBIOS_EDIDSEGMENTCOUNT) +#define EDID_BLOCK_SIZE_SPEC 128 /* 128 bytes per EDID spec */ + +#define CBIOS_3D_VIDEO_FORMAT_MASK 0x015D +#define EDID_VIDEO_INPUT_DEF_BYTE_OFFSET 0x14 +#define EDID_VIDEO_INPUT_DEF_DIGITAL BIT7 + +#define DID_TYPE1_TIMING_DESCRIPTOR_LENGTH 20 + +// CEA data block types tags definition +#define CEA_TAG 0x02 +//DisplayID data block types tags definition +#define DISPLAYID_TAG 0x70 + +typedef enum _CBIOS_CEA_BLOCK_TAG +{ + RSVD_CEA_BLOCK_TAG1 = 0x00, + AUDIO_DATA_BLOCK_TAG, + VIDEO_DATA_BLOCK_TAG, + VENDOR_SPECIFIC_DATA_BLOCK_TAG, + SPEAKER_ALLOCATION_DATA_BLOCK_TAG, + VESA_DTC_DATA_BLOCK_TAG, + RSVD_CEA_BLOCK_TAG2, + CEA_EXTENDED_BLOCK_TAG +}CBIOS_CEA_BLOCK_TAG; + +typedef enum _CBIOS_CEA_EXTENDED_BLOCK_TAG +{ + VIDEO_CAPABILITY_DATA_BLOCK_TAG = 0x00, + VENDOR_SPECIFIC_VIDEO_DATA_BLOCK_TAG, + RSVD_VESA_VIDEO_DISPLAY_DEVICE_INFO_DATA_BLOCK_TAG, + RSVD_VESA_VIDEO_DATA_BLOCK_TAG, + RSVD_HDMI_VIDEO_DATA_BLOCK, + COLORIMETRY_DATA_BLOCK_TAG, + //6-12 reserved for video-related blocks + VIDEO_FMT_PREFERENCE_DATA_BLOCK = 0xD, + YCBCR420_VIDEO_DATA_BLOCK, + YCBCR420_CAP_MAP_DATA_BLOCK, + CEA_MISC_AUDIO_FIELDS_TAG, + VENDOR_SPECIFIC_AUDIO_DATA_BLOCK_TAG, + RSVD_HDMI_AUDIO_DATA_BLOCK_TAG, + //19-31 reserved for audio-related blocks + INFOFRAME_DATA_BLOCK = 0x20, + //33-255 reserved for general + MAX_CEA_EXT_DATA_BLOCK_NUM, +}CBIOS_CEA_EXTENDED_BLOCK_TAG; + +typedef enum _CBIOS_DISPLAYID_BLOCK_TAG +{ + PRODUCT_IDENTIFICATION_DATA_BLOCK_TAG = 0x00, + DISPLAY_PARAMETERS_DATA_BLOCK_TAG, + COLOR_CHARACTERISTICS_DATA_BLCOK_TAG, + VIDEO_TIMING_MODES_DATA_BLOCK_TYPE1_TAG, + VIDEO_TIMING_MODES_DATA_BLOCK_TYPE2_TAG, + VIDEO_TIMING_MODES_DATA_BLOCK_TYPE3_TAG, + VIDEO_TIMING_MODES_DATA_BLOCK_TYPE4_TAG, + VESA_TIMING_STANDARD_DATA_BLOCK_TAG, + CEA_TIMING_STANDARD_DATA_BLOCK_TAG, + VIDEO_TIMING_RANGE_LIMITS_DATA_BLOCK_TAG, + PRODUCT_SERIAL_NUMBER_DATA_BLOCK_TAG, + GENERAL_PURPOSE_ASCII_STRING_DATA_BLOCK_TAG, + DISPLAY_DEVICE_DATA_BLOCK_TAG, + INTERFACE_POWER_SEQUENCING_DATA_BLOCK_TAG, + TRANSFER_CHARACTERISTICS_DATA_BLOCK_TAG, + DISPLAY_INTERFACE_DATA_BLOCK_TAG, + STEREO_DISPLAY_INTERFACE_DATA_BLOCK_TAG, + VIDEO_TIMING_MODES_DATA_BLOCK_TYPE5_TAG, + TILED_DISPLAY_TOPOLOGY_DATA_BLOCK_TAG, + VIDEO_TIMING_MODES_DATA_BLOCK_TYPE6_TAG, + DISPLAYID_VENDOR_SPECIFIC_DATA_BLOCK_TAG = 0x7F, +}CBIOS_DISPLAYID_BLOCK_TAG; + +typedef enum _CBIOS_SVR_FLAG +{ + SVR_FLAG_RSVD = 0, + SVR_FLAG_VIC, + SVR_FLAG_DTD_INDEX, +}CBIOS_SVR_FLAG; + +typedef struct _CBIOS_Module_EDID_ESTTIMINGS +{ + CBIOS_U16 XResolution; //Horizontal size + CBIOS_U16 YResolution; //Vertical Size + CBIOS_U16 RefreshRate; //Refresh rate +}CBIOS_Module_EDID_ESTTIMINGS; + +typedef struct _CBIOS_EDID_DETAILEDTIMING_TABLE +{ + CBIOS_U8 type; + CBIOS_U8 index; + CBIOS_U8 mask; +}DETAILEDTIMING_TABLE; + +typedef struct _CBIOS_HDMI_FORMAT_DESCRIPTOR +{ + CBIOS_U8 IsNative; + CBIOS_U8 IsSupported; + CBIOS_U8 BlockIndex; /* Currently support only 4 blocks */ + CBIOS_U8 RefreshIndex; + union + { + HDMI_3D_STUCTURE_ALL Video3DSupportStructs; + CBIOS_U16 Video3DSupportCaps; + }; + struct + { + CBIOS_U8 IsSupportYCbCr420 :1; + CBIOS_U8 IsSupportOtherFormats :1; /* RGB, YCbCr4:4:4, YCbCr4:2:2 */ + CBIOS_U8 RsvdBits :6; + }; + CBIOS_U8 SVDIndexInVideoBlock; +}CBIOS_HDMI_FORMAT_DESCRIPTOR, *PCBIOS_HDMI_FORMAT_DESCRIPTOR; + +typedef struct _CBIOS_HDMI_3D_FORMAT +{ + struct + { + CBIOS_U8 HDMI3DStructure :4; + CBIOS_U8 HDMI2DVICOrder :4; + }; + struct + { + CBIOS_U8 RsvdBits :4; + CBIOS_U8 HDMI3DDetail :4; + }; +}CBIOS_HDMI_3D_FORMAT, *PCBIOS_HDMI_3D_FORMAT; + + +typedef struct _CBIOS_HDMI_VSDB_EXTENTION +{ + struct + { + CBIOS_U8 VSDBLength :5; + CBIOS_U8 VSDBTag :3; + }Tag; + struct + { + CBIOS_U8 RegistrationIDByte0; + CBIOS_U8 RegistrationIDByte1; + CBIOS_U8 RegistrationIDByte2; + CBIOS_U16 SourcePhyAddr; + + }VSDBHeader; + union + { + struct + { + CBIOS_U8 IsSupportDualLink :1; + CBIOS_U8 RsvdBits0 :2; + CBIOS_U8 IsSupportY444 :1; + CBIOS_U8 IsSupport30Bit :1; + CBIOS_U8 IsSupport36Bit :1; + CBIOS_U8 IsSupport48Bit :1; + CBIOS_U8 IsSupportAI :1; + }; + CBIOS_U8 SupportCaps; + }; + CBIOS_U16 MaxTMDSClock; + union + { + struct + { + CBIOS_U8 CNC0_Graphics :1; + CBIOS_U8 CNC1_Photo :1; + CBIOS_U8 CNC2_Cinema :1; + CBIOS_U8 CNC3_Game :1; + CBIOS_U8 RsvdBits1 :1; + CBIOS_U8 HDMIVideoPresent :1; + CBIOS_U8 ILatencyFieldsPresent :1; + CBIOS_U8 LatencyFieldsPresent :1; + }; + CBIOS_U8 PresentFlags; + }; + CBIOS_U8 VideoLatency; + CBIOS_U8 AudioLatency; + CBIOS_U8 InterlacedVideoLatency; + CBIOS_U8 InterlacedAudioLatency; + union + { + struct + { + CBIOS_U8 RsvdBits2 :3; + CBIOS_U8 ImageSize :2; + CBIOS_U8 HDMI3DMultiPresent :2; + CBIOS_U8 HDMI3DPresent :1; + }; + CBIOS_U8 HDMI3DPresentFlags; + }; + struct + { + CBIOS_U8 HDMI3DLen :5; + CBIOS_U8 HDMIVICLen :3; + }; + CBIOS_U8 HDMIVIC[MAX_HDMI_VIC_LEN]; + CBIOS_U16 HDMI3DStructAll; + CBIOS_U16 HDMI3DMask; + CBIOS_HDMI_3D_FORMAT HDMI3DForamt[MAX_HDMI_3D_LEN]; + CBIOS_U32 HDMI3DFormatCount; +}CBIOS_HDMI_VSDB_EXTENTION, *PCBIOS_HDMI_VSDB_EXTENTION; + +typedef struct _CBIOS_HF_HDMI_VSDB_EXTENTION +{ + struct + { + CBIOS_U8 VSDBLength :5; + CBIOS_U8 VSDBTag :3; + }Tag; + struct + { + CBIOS_U8 IEEEOUIByte0; + CBIOS_U8 IEEEOUIByte1; + CBIOS_U8 IEEEOUIByte2; + + }HFVSDBOUI; + CBIOS_U8 Version; + CBIOS_U16 MaxTMDSCharacterRate; + union + { + struct + { + CBIOS_U16 IsSupport3DOSDDisparity :1; + CBIOS_U16 IsSupport3DDualView :1; + CBIOS_U16 IsSupport3DIndependentView :1; + CBIOS_U16 IsSupportLTE340McscScramble :1; + CBIOS_U16 RsvdBits1 :1; + CBIOS_U16 RsvdBits2 :1; + CBIOS_U16 IsRRCapable :1; + CBIOS_U16 IsSCDCPresent :1; + CBIOS_U16 IsSupportDC30Bit420 :1; + CBIOS_U16 IsSupportDC36Bit420 :1; + CBIOS_U16 IsSupportDC48Bit420 :1; + CBIOS_U16 RsvdBits3 :5; + }; + CBIOS_U16 SupportCaps; + }; +}CBIOS_HF_HDMI_VSDB_EXTENTION, *PCBIOS_HF_HDMI_VSDB_EXTENTION; + + +typedef struct _CBIOS_COLORIMETRY_DATA +{ + union + { + struct + { + CBIOS_U8 IsSupportxvYCC601 :1; + CBIOS_U8 IsSupportxvYCC709 :1; + CBIOS_U8 IsSupportsYCC601 :1; + CBIOS_U8 IsSupportAdobeYCC601 :1; + CBIOS_U8 IsSupportAdobeRGB :1; + CBIOS_U8 IsSupportBT2020cYCC :1; + CBIOS_U8 IsSupportBT2020YCC :1; + CBIOS_U8 IsSupportBT2020RGB :1; + }; + CBIOS_U8 ColorimetrySupportFlags; + }; + union + { + struct + { + CBIOS_U8 MetaData0 :1; + CBIOS_U8 MetaData1 :1; + CBIOS_U8 MetaData2 :1; + CBIOS_U8 MetaData3 :1; + CBIOS_U8 RsvdBits2 :4; + }; + CBIOS_U8 ColorimetryMetadataSupportFlags; + }; +}CBIOS_COLORIMETRY_DATA, *PCBIOS_COLORIMETRY_DATA; + +typedef struct _CBIOS_VIDEO_CAPABILITY_DATA +{ + struct + { + CBIOS_U8 CEScanInfo :2; + CBIOS_U8 ITScanInfo :2; + CBIOS_U8 PTScanInfo :2; + CBIOS_U8 bYCCQuantRange :1; + CBIOS_U8 bRGBQuantRange :1; + }; +}CBIOS_VIDEO_CAPABILITY_DATA, *PCBIOS_VIDEO_CAPABILITY_DATA; + +typedef struct _CBIOS_HDMI_AUDIO_INFO +{ + CBIOS_HDMI_AUDIO_FORMAT_TYPE Format; + CBIOS_U32 MaxChannelNum; + union + { + struct + { + CBIOS_U32 SR_32kHz :1; /* Bit0 = 1, support sample rate of 32kHz */ + CBIOS_U32 SR_44_1kHz :1; /* Bit1 = 1, support sample rate of 44.1kHz */ + CBIOS_U32 SR_48kHz :1; /* Bit2 = 1, support sample rate of 48kHz */ + CBIOS_U32 SR_88_2kHz :1; /* Bit3 = 1, support sample rate of 88.2kHz */ + CBIOS_U32 SR_96kHz :1; /* Bit4 = 1, support sample rate of 96kHz */ + CBIOS_U32 SR_176_4kHz :1; /* Bit5 = 1, support sample rate of 176.4kHz */ + CBIOS_U32 SR_192kHz :1; /* Bit6 = 1, support sample rate of 192kHz */ + CBIOS_U32 Reserved :25; + }SampleRate; + + CBIOS_U32 SampleRateUnit; + }; + + union + { + CBIOS_U32 Unit; + + // for audio format: LPCM + struct + { + CBIOS_U32 BD_16bit :1; /* Bit0 = 1, support bit depth of 16 bits */ + CBIOS_U32 BD_20bit :1; /* Bit1 = 1, support bit depth of 20 bits */ + CBIOS_U32 BD_24bit :1; /* Bit2 = 1, support bit depth of 24 bits */ + CBIOS_U32 Reserved :29; + }BitDepth; + + // for audio format: AC-3, MPEG-1, MP3, MPED-2, AAC LC, DTS, ATRAC + CBIOS_U32 MaxBitRate; // unit: kHz + + // for audio format: DSD, E-AC-3, DTS-HD, MLP, DST + CBIOS_U32 AudioFormatDependValue; /* for these audio formats, this value is defined in + it's corresponding format-specific documents*/ + + // for audio format: WMA Pro + struct + { + CBIOS_U32 Value :3; + CBIOS_U32 Reserved :29; + }Profile; + }; +}CBIOS_HDMI_AUDIO_INFO, *PCBIOS_HDMI_AUDIO_INFO; + +typedef struct _CBIOS_HDMI_3D_AUDIO_DATA +{ + CBIOS_U8 MaxStreamCount :2; + CBIOS_U8 SupportsMSNonMixed :1; + CBIOS_U8 Rsvd1 :5; + CBIOS_U8 NumHDMI3DAD :3; + CBIOS_U8 Rsvd2 :5; + + CBIOS_HDMI_AUDIO_INFO HDMI3DAudioDesc[MAX_HDMI_3D_AUDIO_DESC_NUM]; +}CBIOS_HDMI_3D_AUDIO_DATA, *PCBIOS_HDMI_3D_AUDIO_DATA; + + +typedef struct _CBIOS_CEA_EXTENED_BLOCK +{ + CBIOS_U8 BlockLength :5; + CBIOS_U8 BlockTag :3; + CBIOS_U8 ExtTag; + union + { + CBIOS_COLORIMETRY_DATA ColorimetryData; + CBIOS_VIDEO_CAPABILITY_DATA VideoCapabilityData; + CBIOS_HDMI_3D_AUDIO_DATA HDMIAudioData; + }; +}CBIOS_CEA_EXTENED_BLOCK, *PCBIOS_CEA_EXTENED_BLOCK; + +typedef struct _CBIOS_CEA_SVD_DATA +{ + CBIOS_U8 SVDCount; + CBIOS_U8 SVD[MAX_SVD_COUNT]; +}CBIOS_CEA_SVD_DATA, *PCBIOS_CEA_SVD_DATA; + +typedef struct _CBIOS_INFO_FRAME_CAPS +{ + CBIOS_U8 bSupport :1; + CBIOS_U8 Priority :1; +}CBIOS_INFO_FRAME_CAPS, *PCBIOS_INFO_FRAME_CAPS; + +typedef struct _CBIOS_INFO_FRAME_SUPPORT_CAPS +{ + CBIOS_INFO_FRAME_CAPS HDMISpecificInfoFrameCaps; + CBIOS_INFO_FRAME_CAPS HFSpecificInfoFrameCaps; + CBIOS_INFO_FRAME_CAPS AVIInfoFrameCaps; + CBIOS_INFO_FRAME_CAPS SourceProductDescInfoFrameCaps; + CBIOS_INFO_FRAME_CAPS AudioInfoFrameCaps; + CBIOS_INFO_FRAME_CAPS MpegSourceInfoFrameCaps; + CBIOS_INFO_FRAME_CAPS NTSCVBIInfoFrameCaps; +}CBIOS_INFO_FRAME_SUPPORT_CAPS, *PCBIOS_INFO_FRAME_SUPPORT_CAPS; + +typedef struct _CBIOS_SVR_DESC +{ + CBIOS_U8 SVRFlag; + CBIOS_U8 SVRValue; +}CBIOS_SVR_DESC, *PCBIOS_SVR_DESC; + +typedef struct _CBIOS_FAKE_EDID_PARAMS +{ + CBIOS_MODE_INFO_EXT DtlTiming; + CBIOS_BOOL bProvideDtlTimingEDID; + CBIOS_U8 DtlTimingEDID[16]; +}CBIOS_FAKE_EDID_PARAMS, *PCBIOS_FAKE_EDID_PARAMS; + +typedef struct _CBIOS_MONITOR_MISC_ATTRIB +{ + union + { + struct + { + CBIOS_U32 IsCEA861Monitor :1; + CBIOS_U32 IsCEA861RGB :1; + CBIOS_U32 IsCEA861YCbCr422 :1; + CBIOS_U32 IsCEA861YCbCr444 :1; + CBIOS_U32 IsCEA861Audio :1; + CBIOS_U32 IsCEA861UnderScan :1; + CBIOS_U32 IsCEA861HDMI :1; + CBIOS_U32 RsvdBits :25; + }; + CBIOS_U32 CEA861MonitorCaps; + }; + CBIOS_U32 TotalNumberOfNativeFormat; + CBIOS_U8 Tag; + CBIOS_U8 RevisionNumber; + CBIOS_U8 OffsetOfDetailedTimingBlock; + CBIOS_HDMI_VSDB_EXTENTION VSDBData; + CBIOS_HF_HDMI_VSDB_EXTENTION HFVSDBData; + CBIOS_CEA_SVD_DATA SVDData[CBIOS_EDIDMAXBLOCKCOUNT - 1]; + CBIOS_CEA_EXTENED_BLOCK ExtDataBlock[MAX_CEA_EXT_DATA_BLOCK_NUM]; + CBIOS_BOOL bStereoViewSupport; // stereo Viewing Support for row-interlace + CBIOS_STEREO_VIEW StereoViewType; // stereo view type + CBIOS_U8 ManufactureName[2]; + CBIOS_U8 ProductCode[2]; + CBIOS_U8 MonitorName[16]; + CBIOS_U8 SAD_Count; // at most 15 SADs + CBIOS_U8 CEA_SADs[15][3]; + CBIOS_U8 SpeakerAllocationData; + CBIOS_U16 MonitorHorSize; // monitor screen image horizontal size in millimeter(mm) + CBIOS_U16 MonitorVerSize; // monitor screen image vertical size in millimeter(mm) + CBIOS_U8 NumOfAdditionalVSIFs; // Number of additional VSIFs that can be received simultaneously + CBIOS_INFO_FRAME_SUPPORT_CAPS InfoFrameSupCaps; + CBIOS_SVR_DESC ShortVideoRef[MAX_SVR_LEN]; +}CBIOS_MONITOR_MISC_ATTRIB, *PCBIOS_MONITOR_MISC_ATTRIB; + +typedef struct _CBIOS_EDID_STRUCTURE_DATA { + CBIOS_U8 Version; + CBIOS_MODE_INFO EstTimings[CBIOS_ESTABLISHMODECOUNT]; + CBIOS_MODE_INFO StdTimings[CBIOS_STDMODECOUNT]; + CBIOS_MODE_INFO_EXT DtlTimings[CBIOS_DTLMODECOUNT]; + CBIOS_MONITOR_MISC_ATTRIB Attribute; + CBIOS_HDMI_FORMAT_DESCRIPTOR HDMIFormat[CBIOS_HDMIFORMATCOUNTS]; + CBIOS_HDMI_AUDIO_INFO HDMIAudioFormat[CBIOS_HDMI_AUDIO_FORMAT_COUNTS]; + CBIOS_MODE_INFO_EXT DTDTimings[CBIOS_DTDTIMINGCOUNTS*2]; //may meet two CEA data block(edid has 4 block) + CBIOS_U32 TotalModeNum; // total number of modes that supported in EDID + CBIOS_U32 TotalHDMIAudioFormatNum; // total number of hdmi audio formats that supported in EDID + CBIOS_MODE_INFO_EXT DisplayID_TYPE1_Timings[CBIOS_DISPLAYID_TYPE1_MODECOUNT]; +} CBIOS_EDID_STRUCTURE_DATA, *PCBIOS_EDID_STRUCTURE_DATA; + +CBIOS_U32 cbEDIDModule_GetMonitorAttrib(CBIOS_U8 *pEDID, PCBIOS_MONITOR_MISC_ATTRIB pMonitorAttrib, CBIOS_U32 TotalBlocks); +CBIOS_STATUS cbEDIDModule_GetMonitor3DCaps(PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct, + PCBIOS_MONITOR_3D_CAPABILITY_PARA p3DCapability, + CBIOS_U32 IsSupport3DVideo); +CBIOS_BOOL cbEDIDModule_GetMonitorID(CBIOS_U8 *pEDID, CBIOS_U8 *pMonitorID); +CBIOS_BOOL cbEDIDModule_IsEDIDHeaderValid(CBIOS_U8 *pEDIDBuffer, CBIOS_U32 ulBufferSize); +CBIOS_BOOL cbEDIDModule_IsEDIDValid(CBIOS_U8 *pEDID); +CBIOS_BOOL cbEDIDModule_ParseEDID(CBIOS_U8 *pEDID, PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct, CBIOS_U32 ulBufferSize); +CBIOS_VOID cbEDIDModule_SADPatch(PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct); +CBIOS_BOOL cbEDIDModule_SearchTmInEdidStruct(CBIOS_U32 XResolution, + CBIOS_U32 YResolution, + CBIOS_U32 RefreshRate, + CBIOS_U32 InterlaceFlag, + PCBIOS_EDID_STRUCTURE_DATA pEDIDStruct, + PCBIOS_U32 pTmBlock, + PCBIOS_U32 pTmIndex); +CBIOS_BOOL cbEDIDModule_FakePanelEDID(PCBIOS_FAKE_EDID_PARAMS pFakeEdidParam, PCBIOS_U8 pEdid, const CBIOS_U32 EdidBufferLength); + +#endif diff --git a/drivers/gpu/drm/arise/cbios/Util/CBiosGPIO.h b/drivers/gpu/drm/arise/cbios/Util/CBiosGPIO.h new file mode 100644 index 0000000000000..c70a253001006 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Util/CBiosGPIO.h @@ -0,0 +1,970 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios GPIO macro definition. +** +** NOTE: +** ONLY GPIO related and hw independent function can be added to this file. +******************************************************************************/ + +#define GPIO_BASE_ADDR 0x70000 + +#define __GPIO_BASE GPIO_BASE_ADDR + +#define GIRQ_LOW 0x00 /* Input zero generate GPIO_IRQ signal */ +#define GIRQ_HIGH 0x01 /* Input one generate GPIO_IRQ signal */ +#define GIRQ_FALLING 0x02 /* Falling edge generate GPIO_IRQ signal */ +#define GIRQ_RISING 0x03 /* Rising edge generate GPIO_IRQ signal */ +#define GIRQ_BOTHEDGE 0x04 +#define GIRQ_TYPEMASK 0x07 +#define GIRQ_TYPE(idx, type) ((type & GIRQ_TYPEMASK) << (idx * 8)) /* idx must be 0-3 */ +#define GIRQ_EN_STS(idx) ( 1 << ((idx+1)*8-1) ) /* idx must be 0-3 */ + + +#define GPIO_ID_GP0_BYTE_ADDR (__GPIO_BASE + 0x0 ) +#define GPIO_ID_GP1_BYTE_ADDR (__GPIO_BASE + 0x1 ) +#define GPIO_ID_GP2_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0x2 ) +#define GPIO_ID_GP3_SD0CD_BYTE_ADDR (__GPIO_BASE + 0x3 ) +#define GPIO_ID_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0x4 ) +#define GPIO_ID_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0x5 ) +#define GPIO_ID_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0x6 ) +#define GPIO_ID_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0x7 ) +#define GPIO_ID_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0x8 ) +#define GPIO_ID_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0x9 ) +#define GPIO_ID_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0xA ) +#define GPIO_ID_GP11_SPI_BYTE_ADDR (__GPIO_BASE + 0xB ) +#define GPIO_ID_GP14_SD_BYTE_ADDR (__GPIO_BASE + 0xE ) +#define GPIO_ID_GP15_NAND_7_0_BYTE_ADDR (__GPIO_BASE + 0xF ) +#define GPIO_ID_GP16_NAND_15_8_BYTE_ADDR (__GPIO_BASE + 0x10 ) +#define GPIO_ID_GP21_I2C_BYTE_ADDR (__GPIO_BASE + 0x15 ) +#define GPIO_ID_GP22_UART_0_1_BYTE_ADDR (__GPIO_BASE + 0x16 ) +#define GPIO_ID_GP23_UART_2_3_BYTE_ADDR (__GPIO_BASE + 0x17 ) +#define GPIO_ID_GP24_TSDIN_7_0_BYTE_ADDR (__GPIO_BASE + 0x18 ) +#define GPIO_ID_GP25_TS_BYTE_ADDR (__GPIO_BASE + 0x19 ) +#define GPIO_ID_GP26_KPAD_BYTE_ADDR (__GPIO_BASE + 0x1A ) +#define GPIO_ID_GP27_SPDIF_BYTE_ADDR (__GPIO_BASE + 0x1B ) +#define GPIO_ID_GP28_NAND_CFG_0_BYTE_ADDR (__GPIO_BASE + 0x1C ) +#define GPIO_ID_GP29_NAND_CFG_1_BYTE_ADDR (__GPIO_BASE + 0x1D ) +#define GPIO_ID_GP30_SPI_FLASH_BYTE_ADDR (__GPIO_BASE + 0x1E ) +#define GPIO_ID_GP31_PWM_BYTE_ADDR (__GPIO_BASE + 0x1F ) +#define GPIO_ID_GP32_HDMI_BYTE_ADDR (__GPIO_BASE + 0x20 ) +#define GPIO_ID_GP60_USB_BYTE_ADDR (__GPIO_BASE + 0x3C ) +#define GPIO_CTRL_GP0_BYTE_ADDR (__GPIO_BASE + 0x40 ) +#define GPIO_CTRL_GP1_BYTE_ADDR (__GPIO_BASE + 0x41 ) +#define GPIO_CTRL_GP2_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0x42 ) +#define GPIO_CTRL_GP3_SD0CD_BYTE_ADDR (__GPIO_BASE + 0x43 ) +#define GPIO_CTRL_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0x44 ) +#define GPIO_CTRL_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0x45 ) +#define GPIO_CTRL_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0x46 ) +#define GPIO_CTRL_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0x47 ) +#define GPIO_CTRL_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0x48 ) +#define GPIO_CTRL_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0x49 ) +#define GPIO_CTRL_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0x4A ) +#define GPIO_CTRL_GP11_SPI_BYTE_ADDR (__GPIO_BASE + 0x4B ) +#define GPIO_CTRL_GP14_SD_BYTE_ADDR (__GPIO_BASE + 0x4E ) +#define GPIO_CTRL_GP15_NAND_7_0_BYTE_ADDR (__GPIO_BASE + 0x4F ) +#define GPIO_CTRL_GP16_NAND_15_8_BYTE_ADDR (__GPIO_BASE + 0x50 ) +#define GPIO_CTRL_GP18_SD0PWRSW_BYTE_ADDR (__GPIO_BASE + 0x52 ) +#define GPIO_CTRL_GP21_I2C_BYTE_ADDR (__GPIO_BASE + 0x55 ) +#define GPIO_CTRL_GP22_UART_0_1_BYTE_ADDR (__GPIO_BASE + 0x56 ) +#define GPIO_CTRL_GP23_UART_2_3_BYTE_ADDR (__GPIO_BASE + 0x57 ) +#define GPIO_CTRL_GP24_TSDIN_7_0_BYTE_ADDR (__GPIO_BASE + 0x58 ) +#define GPIO_CTRL_GP25_TS_BYTE_ADDR (__GPIO_BASE + 0x59 ) +#define GPIO_CTRL_GP26_KPAD_BYTE_ADDR (__GPIO_BASE + 0x5A ) +#define GPIO_CTRL_GP27_SPDIF_BYTE_ADDR (__GPIO_BASE + 0x5B ) +#define GPIO_CTRL_GP28_NAND_CFG_0_BYTE_ADDR (__GPIO_BASE + 0x5C ) +#define GPIO_CTRL_GP29_NAND_CFG_1_BYTE_ADDR (__GPIO_BASE + 0x5D ) +#define GPIO_CTRL_GP30_SPI_FLASH_BYTE_ADDR (__GPIO_BASE + 0x5E ) +#define GPIO_CTRL_GP31_PWM_BYTE_ADDR (__GPIO_BASE + 0x5F ) +#define GPIO_CTRL_GP32_HDMI_BYTE_ADDR (__GPIO_BASE + 0x60 ) +#define GPIO_CTRL_GP60_USB_BYTE_ADDR (__GPIO_BASE + 0x7C ) +#define GPIO_OC_GP0_BYTE_ADDR (__GPIO_BASE + 0x80 ) +#define GPIO_OC_GP1_BYTE_ADDR (__GPIO_BASE + 0x81 ) +#define GPIO_OC_GP2_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0x82 ) +#define GPIO_OC_GP3_SD0CD_BYTE_ADDR (__GPIO_BASE + 0x83 ) +#define GPIO_OC_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0x84 ) +#define GPIO_OC_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0x85 ) +#define GPIO_OC_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0x86 ) +#define GPIO_OC_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0x87 ) +#define GPIO_OC_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0x88 ) +#define GPIO_OC_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0x89 ) +#define GPIO_OC_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0x8A ) +#define GPIO_OC_GP11_SPI_BYTE_ADDR (__GPIO_BASE + 0x8B ) +#define GPIO_OC_GP14_SD_BYTE_ADDR (__GPIO_BASE + 0x8E ) +#define GPIO_OC_GP15_NAND_7_0_BYTE_ADDR (__GPIO_BASE + 0x8F ) +#define GPIO_OC_GP16_NAND_15_8_BYTE_ADDR (__GPIO_BASE + 0x90 ) +#define GPIO_OC_GP18_SD0PWRSW_BYTE_ADDR (__GPIO_BASE + 0x92 ) +#define GPIO_OC_GP21_I2C_BYTE_ADDR (__GPIO_BASE + 0x95 ) +#define GPIO_OC_GP22_UART_0_1_BYTE_ADDR (__GPIO_BASE + 0x96 ) +#define GPIO_OC_GP23_UART_2_3_BYTE_ADDR (__GPIO_BASE + 0x97 ) +#define GPIO_OC_GP24_TSDIN_7_0_BYTE_ADDR (__GPIO_BASE + 0x98 ) +#define GPIO_OC_GP25_TS_BYTE_ADDR (__GPIO_BASE + 0x99 ) +#define GPIO_OC_GP26_KPAD_BYTE_ADDR (__GPIO_BASE + 0x9A ) +#define GPIO_OC_GP27_SPDIF_BYTE_ADDR (__GPIO_BASE + 0x9B ) +#define GPIO_OC_GP28_NAND_CFG_0_BYTE_ADDR (__GPIO_BASE + 0x9C ) +#define GPIO_OC_GP29_NAND_CFG_1_BYTE_ADDR (__GPIO_BASE + 0x9D ) +#define GPIO_OC_GP30_SPI_FLASH_BYTE_ADDR (__GPIO_BASE + 0x9E ) +#define GPIO_OC_GP31_PWM_BYTE_ADDR (__GPIO_BASE + 0x9F ) +#define GPIO_OC_GP32_HDMI_BYTE_ADDR (__GPIO_BASE + 0xA0 ) +#define GPIO_OC_GP60_USB_BYTE_ADDR (__GPIO_BASE + 0xBC ) +#define GPIO_OD_GP0_BYTE_ADDR (__GPIO_BASE + 0xC0 ) +#define GPIO_OD_GP1_BYTE_ADDR (__GPIO_BASE + 0xC1 ) +#define GPIO_OD_GP2_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0xC2 ) +#define GPIO_OD_GP3_SD0CD_BYTE_ADDR (__GPIO_BASE + 0xC3 ) +#define GPIO_OD_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0xC4 ) +#define GPIO_OD_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0xC5 ) +#define GPIO_OD_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0xC6 ) +#define GPIO_OD_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0xC7 ) +#define GPIO_OD_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0xC8 ) +#define GPIO_OD_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0xC9 ) +#define GPIO_OD_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0xCA ) +#define GPIO_OD_GP11_SPI_BYTE_ADDR (__GPIO_BASE + 0xCB ) +#define GPIO_OD_GP14_SD_BYTE_ADDR (__GPIO_BASE + 0xCE ) +#define GPIO_OD_GP15_NAND_7_0_BYTE_ADDR (__GPIO_BASE + 0xCF ) +#define GPIO_OD_GP16_NAND_15_8_BYTE_ADDR (__GPIO_BASE + 0xD0 ) +#define GPIO_OD_GP18_SD0PWRSW_BYTE_ADDR (__GPIO_BASE + 0xD2 ) +#define GPIO_OD_GP21_I2C_BYTE_ADDR (__GPIO_BASE + 0xD5 ) +#define GPIO_OD_GP22_UART_0_1_BYTE_ADDR (__GPIO_BASE + 0xD6 ) +#define GPIO_OD_GP23_UART_2_3_BYTE_ADDR (__GPIO_BASE + 0xD7 ) +#define GPIO_OD_GP24_TSDIN_7_0_BYTE_ADDR (__GPIO_BASE + 0xD8 ) +#define GPIO_OD_GP25_TS_BYTE_ADDR (__GPIO_BASE + 0xD9 ) +#define GPIO_OD_GP26_KPAD_BYTE_ADDR (__GPIO_BASE + 0xDA ) +#define GPIO_OD_GP27_SPDIF_BYTE_ADDR (__GPIO_BASE + 0xDB ) +#define GPIO_OD_GP28_NAND_CFG_0_BYTE_ADDR (__GPIO_BASE + 0xDC ) +#define GPIO_OD_GP29_NAND_CFG_1_BYTE_ADDR (__GPIO_BASE + 0xDD ) +#define GPIO_OD_GP30_SPI_FLASH_BYTE_ADDR (__GPIO_BASE + 0xDE ) +#define GPIO_OD_GP31_PWM_BYTE_ADDR (__GPIO_BASE + 0xDF ) +#define GPIO_OD_GP32_HDMI_BYTE_ADDR (__GPIO_BASE + 0xE0 ) +#define GPIO_OD_GP60_USB_BYTE_ADDR (__GPIO_BASE + 0xFC ) +#define GPIO_STRAP_STATUS_ADDR (__GPIO_BASE + 0x100 ) +#define GPIO_AHB_CTRL_4BYTE_ADDR (__GPIO_BASE + 0x108 ) +#define GPIO_USB_OP_CTRL_4BYTE_ADDR (__GPIO_BASE + 0x10C ) +#define GPIO_BONDING_OPTION_4BYTE_ADDR (__GPIO_BASE + 0x110 ) +#define GPIO_PIN_SHARING_SEL_4BYTE_ADDR (__GPIO_BASE + 0x200 ) +#define GPIO0_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x300 ) +#define GPIO1_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x301 ) +#define GPIO2_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x302 ) +#define GPIO3_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x303 ) +#define GPIO4_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x304 ) +#define GPIO5_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x305 ) +#define GPIO6_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x306 ) +#define GPIO7_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x307 ) +#define GPIO8_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x308 ) +#define GPIO9_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x309 ) +#define GPIO10_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30A ) +#define GPIO11_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30B ) +#define KPADROW0_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30C ) +#define KPADROW1_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30D ) +#define KPADROW2_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30E ) +#define KPADROW3_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x30F ) +#define KPADCOL0_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x310 ) +#define KPADCOL1_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x311 ) +#define KPADCOL2_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x312 ) +#define KPADCOL3_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x313 ) +#define UART1RTS_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x314 ) +#define UART1TXD_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x315 ) +#define UART1CTS_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x316 ) +#define UART1RXD_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x317 ) +#define UART2RTS_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x318 ) +#define UART2TXD_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x319 ) +#define UART2CTS_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x31A ) +#define UART2RXD_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x31B ) +#define UART3RTS_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x31C ) +#define UART3TXD_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x31D ) +#define UART3CTS_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x31E ) +#define UART3RXD_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x31F ) +#define I2SDACDAT0_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x320 ) +#define I2SDACDAT1_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x321 ) +#define I2SDACDAT2_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x322 ) +#define I2SDACDAT3_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x323 ) +#define I2SADCMCLK_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x324 ) +#define I2SDACLRC_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x325 ) +#define I2SDACBCLK_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x326 ) +#define I2SDACMCLK_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x327 ) +#define SPI0CLK_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x328 ) +#define SPI0MISO_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x329 ) +#define SPI0MOSI_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x32A ) +#define SPI0SS0_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x32B ) +#define PWMOUT1_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x32C ) +#define PWMOUT0_INT_REQ_TYPE_ADDR (__GPIO_BASE + 0x32D ) +#define GPIO0_INT_REQ_STS_ADDR (__GPIO_BASE + 0x360 ) +#define GPIO1_INT_REQ_STS_ADDR (__GPIO_BASE + 0x361 ) +#define GPIO2_INT_REQ_STS_ADDR (__GPIO_BASE + 0x362 ) +#define GPIO3_INT_REQ_STS_ADDR (__GPIO_BASE + 0x363 ) +#define GPIO4_INT_REQ_STS_ADDR (__GPIO_BASE + 0x364 ) +#define GPIO5_INT_REQ_STS_ADDR (__GPIO_BASE + 0x365 ) +#define GPIO_IO_DRV_SD_4BYTE_ADDR (__GPIO_BASE + 0x400 ) +#define GPIO_IO_DRV_VID_4BYTE_ADDR (__GPIO_BASE + 0x404 ) +#define GPIO_IO_DRV_SPI_4BYTE_ADDR (__GPIO_BASE + 0x408 ) +#define GPIO_IO_DRV_NAND_4BYTE_ADDR (__GPIO_BASE + 0x40C ) +#define GPIO_IO_DRV_XD_4BYTE_ADDR (__GPIO_BASE + 0x410 ) +#define GPIO_IO_DRV_TS_4BYTE_ADDR (__GPIO_BASE + 0x414 ) +#define GPIO_IO_DRV_I2S_4BYTE_ADDR (__GPIO_BASE + 0x418 ) +#define GPIO_IO_DRV_PCM_4BYTE_ADDR (__GPIO_BASE + 0x41C ) +#define GPIO_IO_DRV_PWM_4BYTE_ADDR (__GPIO_BASE + 0x420 ) +#define GPIO_IO_DRV_GPIOL_4BYTE_ADDR (__GPIO_BASE + 0x424 ) +#define GPIO_IO_DRV_GPIOH_4BYTE_ADDR (__GPIO_BASE + 0x428 ) +#define GPIO_IO_DRV_HDMI_4BYTE_ADDR (__GPIO_BASE + 0x42C ) +#define GPIO_IO_DRV_KEYPAD_4BYTE_ADDR (__GPIO_BASE + 0x430 ) +#define GPIO_IO_DRV_JTAG_4BYTE_ADDR (__GPIO_BASE + 0x434 ) +#define GPIO_IO_DRV_USB_4BYTE_ADDR (__GPIO_BASE + 0x460 ) +#define GPIO_IO_DRV_SD0CD_4BYTE_ADDR (__GPIO_BASE + 0x464 ) +#define GPIO_PULL_EN_GP0_BYTE_ADDR (__GPIO_BASE + 0x480 ) +#define GPIO_PULL_EN_GP1_BYTE_ADDR (__GPIO_BASE + 0x481 ) +#define GPIO_PULL_EN_GP2_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0x482 ) +#define GPIO_PULL_EN_GP3_SD0CD_BYTE_ADDR (__GPIO_BASE + 0x483 ) +#define GPIO_PULL_EN_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0x484 ) +#define GPIO_PULL_EN_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0x485 ) +#define GPIO_PULL_EN_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0x486 ) +#define GPIO_PULL_EN_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0x487 ) +#define GPIO_PULL_EN_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0x488 ) +#define GPIO_PULL_EN_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0x489 ) +#define GPIO_PULL_EN_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0x48A ) +#define GPIO_PULL_EN_GP11_SPI_BYTE_ADDR (__GPIO_BASE + 0x48B ) +#define GPIO_PULL_EN_GP12_XD_BYTE_ADDR (__GPIO_BASE + 0x48C ) +#define GPIO_PULL_EN_GP13_XDIO_BYTE_ADDR (__GPIO_BASE + 0x48D ) +#define GPIO_PULL_EN_GP14_SD_BYTE_ADDR (__GPIO_BASE + 0x48E ) +#define GPIO_PULL_EN_GP15_NAND_7_0_BYTE_ADDR (__GPIO_BASE + 0x48F ) +#define GPIO_PULL_EN_GP16_NAND_15_8_BYTE_ADDR (__GPIO_BASE + 0x490 ) +#define GPIO_PULL_EN_GP18_SD0PWRSW_BYTE_ADDR (__GPIO_BASE + 0x492 ) +#define GPIO_PULL_EN_GP21_I2C_BYTE_ADDR (__GPIO_BASE + 0x495 ) +#define GPIO_PULL_EN_GP22_UART_0_1_BYTE_ADDR (__GPIO_BASE + 0x496 ) +#define GPIO_PULL_EN_GP23_UART_2_3_BYTE_ADDR (__GPIO_BASE + 0x497 ) +#define GPIO_PULL_EN_GP24_TSDIN_7_0_BYTE_ADDR (__GPIO_BASE + 0x498 ) +#define GPIO_PULL_EN_GP25_TS_BYTE_ADDR (__GPIO_BASE + 0x499 ) +#define GPIO_PULL_EN_GP26_KPAD_BYTE_ADDR (__GPIO_BASE + 0x49A ) +#define GPIO_PULL_EN_GP27_SPDIF_BYTE_ADDR (__GPIO_BASE + 0x49B ) +#define GPIO_PULL_EN_GP28_NAND_CFG_0_BYTE_ADDR (__GPIO_BASE + 0x49C ) +#define GPIO_PULL_EN_GP29_NAND_CFG_1_BYTE_ADDR (__GPIO_BASE + 0x49D ) +#define GPIO_PULL_EN_GP30_SPI_FLASH_BYTE_ADDR (__GPIO_BASE + 0x49E ) +#define GPIO_PULL_EN_GP31_PWM_BYTE_ADDR (__GPIO_BASE + 0x49F ) +#define GPIO_PULL_EN_GP32_HDMI_BYTE_ADDR (__GPIO_BASE + 0x4A0 ) +#define GPIO_PULL_EN_GP60_USB_TYTE_ADDR (__GPIO_BASE + 0x4BC ) +#define GPIO_PULL_CTRL_GP0_BYTE_ADDR (__GPIO_BASE + 0x4C0 ) +#define GPIO_PULL_CTRL_GP1_BYTE_ADDR (__GPIO_BASE + 0x4C1 ) +#define GPIO_PULL_CTRL_GP2_WAKEUP_SUS_BYTE_ADDR (__GPIO_BASE + 0x4C2 ) +#define GPIO_PULL_CTRL_GP3_SD0CD_BYTE_ADDR (__GPIO_BASE + 0x4C3 ) +#define GPIO_PULL_CTRL_GP4_VDOUT_7_0_BYTE_ADDR (__GPIO_BASE + 0x4C4 ) +#define GPIO_PULL_CTRL_GP5_VDOUT_15_8_BYTE_ADDR (__GPIO_BASE + 0x4C5 ) +#define GPIO_PULL_CTRL_GP6_VDOUT_23_16_BYTE_ADDR (__GPIO_BASE + 0x4C6 ) +#define GPIO_PULL_CTRL_GP7_VD_BYTE_ADDR (__GPIO_BASE + 0x4C7 ) +#define GPIO_PULL_CTRL_GP8_VDIN_BYTE_ADDR (__GPIO_BASE + 0x4C8 ) +#define GPIO_PULL_CTRL_GP9_VSYNC_BYTE_ADDR (__GPIO_BASE + 0x4C9 ) +#define GPIO_PULL_CTRL_GP10_I2S_BYTE_ADDR (__GPIO_BASE + 0x4CA ) +#define GPIO_PULL_CTRL_GP11_SPI_BYTE_ADDR (__GPIO_BASE + 0x4CB ) +#define GPIO_PULL_CTRL_GP12_XD_BYTE_ADDR (__GPIO_BASE + 0x4CC ) +#define GPIO_PULL_CTRL_GP13_XDIO_BYTE_ADDR (__GPIO_BASE + 0x4CD ) +#define GPIO_PULL_CTRL_GP14_SD_BYTE_ADDR (__GPIO_BASE + 0x4CE ) +#define GPIO_PULL_CTRL_GP15_NAND_7_0_BYTE_ADDR (__GPIO_BASE + 0x4CF ) +#define GPIO_PULL_CTRL_GP16_NAND_15_8_BYTE_ADDR (__GPIO_BASE + 0x4D0 ) +#define GPIO_PULL_CTRL_GP18_SD0PWRSW_BYTE_ADDR (__GPIO_BASE + 0x4D2 ) +#define GPIO_PULL_CTRL_GP21_I2C_BYTE_ADDR (__GPIO_BASE + 0x4D5 ) +#define GPIO_PULL_CTRL_GP22_UART_0_1_BYTE_ADDR (__GPIO_BASE + 0x4D6 ) +#define GPIO_PULL_CTRL_GP23_UART_2_3_BYTE_ADDR (__GPIO_BASE + 0x4D7 ) +#define GPIO_PULL_CTRL_GP24_TSDIN_7_0_BYTE_ADDR (__GPIO_BASE + 0x4D8 ) +#define GPIO_PULL_CTRL_GP25_TS_BYTE_ADDR (__GPIO_BASE + 0x4D9 ) +#define GPIO_PULL_CTRL_GP26_KPAD_BYTE_ADDR (__GPIO_BASE + 0x4DA ) +#define GPIO_PULL_CTRL_GP27_SPDIF_BYTE_ADDR (__GPIO_BASE + 0x4DB ) +#define GPIO_PULL_CTRL_GP28_NAND_CFG_0_BYTE_ADDR (__GPIO_BASE + 0x4DC ) +#define GPIO_PULL_CTRL_GP29_NAND_CFG_1_BYTE_ADDR (__GPIO_BASE + 0x4DD ) +#define GPIO_PULL_CTRL_GP30_SPI_FLASH_BYTE_ADDR (__GPIO_BASE + 0x4DE ) +#define GPIO_PULL_CTRL_GP31_PWM_BYTE_ADDR (__GPIO_BASE + 0x4DF ) +#define GPIO_PULL_CTRL_GP32_HDMI_BYTE_ADDR (__GPIO_BASE + 0x4DF ) +#define GPIO_PULL_CTRL_GP60_USB_BYTE_ADDR (__GPIO_BASE + 0x4FC ) + + +#define GPIO_ID_GP0_BYTE_REG REG8_PTR(GPIO_ID_GP0_BYTE_ADDR ) +#define GPIO_ID_GP1_BYTE_REG REG8_PTR(GPIO_ID_GP1_BYTE_ADDR ) +#define GPIO_ID_GP2_WAKEUP_SUS_BYTE_REG REG8_PTR(GPIO_ID_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_ID_GP3_SD0CD_BYTE_REG REG8_PTR(GPIO_ID_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_ID_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(GPIO_ID_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_ID_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(GPIO_ID_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_ID_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(GPIO_ID_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_ID_GP7_VD_BYTE_REG REG8_PTR(GPIO_ID_GP7_VD_BYTE_ADDR ) +#define GPIO_ID_GP8_VDIN_BYTE_REG REG8_PTR(GPIO_ID_GP8_VDIN_BYTE_ADDR ) +#define GPIO_ID_GP9_VSYNC_BYTE_REG REG8_PTR(GPIO_ID_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_ID_GP10_I2S_BYTE_REG REG8_PTR(GPIO_ID_GP10_I2S_BYTE_ADDR ) +#define GPIO_ID_GP11_SPI_BYTE_REG REG8_PTR(GPIO_ID_GP11_SPI_BYTE_ADDR ) +#define GPIO_ID_GP14_SD_BYTE_REG REG8_PTR(GPIO_ID_GP14_SD_BYTE_ADDR ) +#define GPIO_ID_GP15_NAND_7_0_BYTE_REG REG8_PTR(GPIO_ID_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_ID_GP16_NAND_15_8_BYTE_REG REG8_PTR(GPIO_ID_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_ID_GP21_I2C_BYTE_REG REG8_PTR(GPIO_ID_GP21_I2C_BYTE_ADDR ) +#define GPIO_ID_GP22_UART_0_1_BYTE_REG REG8_PTR(GPIO_ID_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_ID_GP23_UART_2_3_BYTE_REG REG8_PTR(GPIO_ID_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_ID_GP24_TSDIN_7_0_BYTE_REG REG8_PTR(GPIO_ID_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_ID_GP25_TS_BYTE_REG REG8_PTR(GPIO_ID_GP25_TS_BYTE_ADDR ) +#define GPIO_ID_GP26_KPAD_BYTE_REG REG8_PTR(GPIO_ID_GP26_KPAD_BYTE_ADDR ) +#define GPIO_ID_GP27_SPDIF_BYTE_REG REG8_PTR(GPIO_ID_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_ID_GP28_NAND_CFG_0_BYTE_REG REG8_PTR(GPIO_ID_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_ID_GP29_NAND_CFG_1_BYTE_REG REG8_PTR(GPIO_ID_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_ID_GP30_SPI_FLASH_BYTE_REG REG8_PTR(GPIO_ID_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_ID_GP31_PWM_BYTE_REG REG8_PTR(GPIO_ID_GP31_PWM_BYTE_ADDR ) +#define GPIO_ID_GP31_HDMI_BYTE_REG REG8_PTR(GPIO_ID_GP32_HDMI_BYTE_ADDR ) +#define GPIO_ID_GP60_USB_BYTE_REG REG8_PTR(GPIO_ID_GP60_USB_BYTE_ADDR ) +#define GPIO_CTRL_GP0_BYTE_REG REG8_PTR(GPIO_CTRL_GP0_BYTE_ADDR ) +#define GPIO_CTRL_GP1_BYTE_REG REG8_PTR(GPIO_CTRL_GP1_BYTE_ADDR ) +#define GPIO_CTRL_GP2_WAKEUP_SUS_BYTE_REG REG8_PTR(GPIO_CTRL_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_CTRL_GP3_SD0CD_BYTE_REG REG8_PTR(GPIO_CTRL_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_CTRL_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(GPIO_CTRL_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_CTRL_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(GPIO_CTRL_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_CTRL_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(GPIO_CTRL_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_CTRL_GP7_VD_BYTE_REG REG8_PTR(GPIO_CTRL_GP7_VD_BYTE_ADDR ) +#define GPIO_CTRL_GP8_VDIN_BYTE_REG REG8_PTR(GPIO_CTRL_GP8_VDIN_BYTE_ADDR ) +#define GPIO_CTRL_GP9_VSYNC_BYTE_REG REG8_PTR(GPIO_CTRL_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_CTRL_GP10_I2S_BYTE_REG REG8_PTR(GPIO_CTRL_GP10_I2S_BYTE_ADDR ) +#define GPIO_CTRL_GP11_SPI_BYTE_REG REG8_PTR(GPIO_CTRL_GP11_SPI_BYTE_ADDR ) +#define GPIO_CTRL_GP14_SD_BYTE_REG REG8_PTR(GPIO_CTRL_GP14_SD_BYTE_ADDR ) +#define GPIO_CTRL_GP15_NAND_7_0_BYTE_REG REG8_PTR(GPIO_CTRL_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_CTRL_GP16_NAND_15_8_BYTE_REG REG8_PTR(GPIO_CTRL_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_CTRL_GP18_SD0PWRSW_BYTE_REG REG8_PTR(GPIO_CTRL_GP18_SD0PWRSW_BYTE_ADDR ) +#define GPIO_CTRL_GP21_I2C_BYTE_REG REG8_PTR(GPIO_CTRL_GP21_I2C_BYTE_ADDR ) +#define GPIO_CTRL_GP22_UART_0_1_BYTE_REG REG8_PTR(GPIO_CTRL_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_CTRL_GP23_UART_2_3_BYTE_REG REG8_PTR(GPIO_CTRL_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_CTRL_GP24_TSDIN_7_0_BYTE_REG REG8_PTR(GPIO_CTRL_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_CTRL_GP25_TS_BYTE_REG REG8_PTR(GPIO_CTRL_GP25_TS_BYTE_ADDR ) +#define GPIO_CTRL_GP26_KPAD_BYTE_REG REG8_PTR(GPIO_CTRL_GP26_KPAD_BYTE_ADDR ) +#define GPIO_CTRL_GP27_SPDIF_BYTE_REG REG8_PTR(GPIO_CTRL_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_CTRL_GP28_NAND_CFG_0_BYTE_REG REG8_PTR(GPIO_CTRL_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_CTRL_GP29_NAND_CFG_1_BYTE_REG REG8_PTR(GPIO_CTRL_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_CTRL_GP30_SPI_FLASH_BYTE_REG REG8_PTR(GPIO_CTRL_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_CTRL_GP31_PWM_BYTE_REG REG8_PTR(GPIO_CTRL_GP31_PWM_BYTE_ADDR ) +#define GPIO_CTRL_GP32_HDMI_BYTE_REG REG8_PTR(GPIO_CTRL_GP32_HDMI_BYTE_ADDR ) +#define GPIO_CTRL_GP60_USB_BYTE_REG REG8_PTR(GPIO_CTRL_GP60_USB_BYTE_ADDR ) +#define GPIO_OC_GP0_BYTE_REG REG8_PTR(GPIO_OC_GP0_BYTE_ADDR ) +#define GPIO_OC_GP1_BYTE_REG REG8_PTR(GPIO_OC_GP1_BYTE_ADDR ) +#define GPIO_OC_GP2_WAKEUP_SUS_BYTE_REG REG8_PTR(GPIO_OC_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_OC_GP3_SD0CD_BYTE_REG REG8_PTR(GPIO_OC_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_OC_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(GPIO_OC_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_OC_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(GPIO_OC_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_OC_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(GPIO_OC_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_OC_GP7_VD_BYTE_REG REG8_PTR(GPIO_OC_GP7_VD_BYTE_ADDR ) +#define GPIO_OC_GP8_VDIN_BYTE_REG REG8_PTR(GPIO_OC_GP8_VDIN_BYTE_ADDR ) +#define GPIO_OC_GP9_VSYNC_BYTE_REG REG8_PTR(GPIO_OC_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_OC_GP10_I2S_BYTE_REG REG8_PTR(GPIO_OC_GP10_I2S_BYTE_ADDR ) +#define GPIO_OC_GP11_SPI_BYTE_REG REG8_PTR(GPIO_OC_GP11_SPI_BYTE_ADDR ) +#define GPIO_OC_GP14_SD_BYTE_REG REG8_PTR(GPIO_OC_GP14_SD_BYTE_ADDR ) +#define GPIO_OC_GP15_NAND_7_0_BYTE_REG REG8_PTR(GPIO_OC_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_OC_GP16_NAND_15_8_BYTE_REG REG8_PTR(GPIO_OC_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_OC_GP18_SD0PWRSW_BYTE_REG REG8_PTR(GPIO_OC_GP18_SD0PWRSW_BYTE_ADDR ) +#define GPIO_OC_GP21_I2C_BYTE_REG REG8_PTR(GPIO_OC_GP21_I2C_BYTE_ADDR ) +#define GPIO_OC_GP22_UART_0_1_BYTE_REG REG8_PTR(GPIO_OC_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_OC_GP23_UART_2_3_BYTE_REG REG8_PTR(GPIO_OC_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_OC_GP24_TSDIN_7_0_BYTE_REG REG8_PTR(GPIO_OC_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_OC_GP25_TS_BYTE_REG REG8_PTR(GPIO_OC_GP25_TS_BYTE_ADDR ) +#define GPIO_OC_GP26_KPAD_BYTE_REG REG8_PTR(GPIO_OC_GP26_KPAD_BYTE_ADDR ) +#define GPIO_OC_GP27_SPDIF_BYTE_REG REG8_PTR(GPIO_OC_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_OC_GP28_NAND_CFG_0_BYTE_REG REG8_PTR(GPIO_OC_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_OC_GP29_NAND_CFG_1_BYTE_REG REG8_PTR(GPIO_OC_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_OC_GP30_SPI_FLASH_BYTE_REG REG8_PTR(GPIO_OC_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_OC_GP31_PWM_BYTE_REG REG8_PTR(GPIO_OC_GP31_PWM_BYTE_ADDR ) +#define GPIO_OC_GP32_HDMI_BYTE_REG REG8_PTR(GPIO_OC_GP32_HDMI_BYTE_ADDR ) +#define GPIO_OC_GP60_USB_BYTE_REG REG8_PTR(GPIO_OC_GP60_USB_BYTE_ADDR ) +#define GPIO_OD_GP0_BYTE_REG REG8_PTR(GPIO_OD_GP0_BYTE_ADDR ) +#define GPIO_OD_GP1_BYTE_REG REG8_PTR(GPIO_OD_GP1_BYTE_ADDR ) +#define GPIO_OD_GP2_WAKEUP_SUS_BYTE_REG REG8_PTR(GPIO_OD_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_OD_GP3_SD0CD_BYTE_REG REG8_PTR(GPIO_OD_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_OD_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(GPIO_OD_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_OD_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(GPIO_OD_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_OD_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(GPIO_OD_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_OD_GP7_VD_BYTE_REG REG8_PTR(GPIO_OD_GP7_VD_BYTE_ADDR ) +#define GPIO_OD_GP8_VDIN_BYTE_REG REG8_PTR(GPIO_OD_GP8_VDIN_BYTE_ADDR ) +#define GPIO_OD_GP9_VSYNC_BYTE_REG REG8_PTR(GPIO_OD_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_OD_GP10_I2S_BYTE_REG REG8_PTR(GPIO_OD_GP10_I2S_BYTE_ADDR ) +#define GPIO_OD_GP11_SPI_BYTE_REG REG8_PTR(GPIO_OD_GP11_SPI_BYTE_ADDR ) +#define GPIO_OD_GP14_SD_BYTE_REG REG8_PTR(GPIO_OD_GP14_SD_BYTE_ADDR ) +#define GPIO_OD_GP15_NAND_7_0_BYTE_REG REG8_PTR(GPIO_OD_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_OD_GP16_NAND_15_8_BYTE_REG REG8_PTR(GPIO_OD_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_OD_GP18_SD0PWRSW_BYTE_REG REG8_PTR(GPIO_OD_GP18_SD0PWRSW_BYTE_ADDR ) +#define GPIO_OD_GP21_I2C_BYTE_REG REG8_PTR(GPIO_OD_GP21_I2C_BYTE_ADDR ) +#define GPIO_OD_GP22_UART_0_1_BYTE_REG REG8_PTR(GPIO_OD_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_OD_GP23_UART_2_3_BYTE_REG REG8_PTR(GPIO_OD_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_OD_GP24_TSDIN_7_0_BYTE_REG REG8_PTR(GPIO_OD_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_OD_GP25_TS_BYTE_REG REG8_PTR(GPIO_OD_GP25_TS_BYTE_ADDR ) +#define GPIO_OD_GP26_KPAD_BYTE_REG REG8_PTR(GPIO_OD_GP26_KPAD_BYTE_ADDR ) +#define GPIO_OD_GP27_SPDIF_BYTE_REG REG8_PTR(GPIO_OD_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_OD_GP28_NAND_CFG_0_BYTE_REG REG8_PTR(GPIO_OD_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_OD_GP29_NAND_CFG_1_BYTE_REG REG8_PTR(GPIO_OD_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_OD_GP30_SPI_FLASH_BYTE_REG REG8_PTR(GPIO_OD_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_OD_GP31_PWM_BYTE_REG REG8_PTR(GPIO_OD_GP31_PWM_BYTE_ADDR ) +#define GPIO_OD_GP32_HDMI_BYTE_REG REG8_PTR(GPIO_OD_GP32_HDMI_BYTE_ADDR ) +#define GPIO_OD_GP60_USB_BYTE_REG REG8_PTR(GPIO_OD_GP60_USB_BYTE_ADDR ) +#define GPIO_STRAP_STATUS_REG REG32_PTR(GPIO_STRAP_STATUS_ADDR ) +#define GPIO_AHB_CTRL_4BYTE_REG REG32_PTR(GPIO_AHB_CTRL_4BYTE_ADDR ) +#define GPIO_USB_OP_CTRL_4BYTE_ADDR_REG REG32_PTR(GPIO_USB_OP_CTRL_4BYTE_ADDR ) +#define GPIO_BONDING_OPTION_4BYTE_REG REG32_PTR(GPIO_BONDING_OPTION_4BYTE_ADDR ) +#define GPIO_PIN_SHARING_SEL_4BYTE_REG REG32_PTR(GPIO_PIN_SHARING_SEL_4BYTE_ADDR ) +#define GPIO0_INT_REQ_TYPE_REG REG8_PTR(GPIO0_INT_REQ_TYPE_ADDR) +#define GPIO1_INT_REQ_TYPE_REG REG8_PTR(GPIO1_INT_REQ_TYPE_ADDR) +#define GPIO2_INT_REQ_TYPE_REG REG8_PTR(GPIO2_INT_REQ_TYPE_ADDR) +#define GPIO3_INT_REQ_TYPE_REG REG8_PTR(GPIO3_INT_REQ_TYPE_ADDR) +#define GPIO4_INT_REQ_TYPE_REG REG8_PTR(GPIO4_INT_REQ_TYPE_ADDR) +#define GPIO5_INT_REQ_TYPE_REG REG8_PTR(GPIO5_INT_REQ_TYPE_ADDR) +#define GPIO6_INT_REQ_TYPE_REG REG8_PTR(GPIO6_INT_REQ_TYPE_ADDR) +#define GPIO7_INT_REQ_TYPE_REG REG8_PTR(GPIO7_INT_REQ_TYPE_ADDR) +#define GPIO8_INT_REQ_TYPE_REG REG8_PTR(GPIO8_INT_REQ_TYPE_ADDR) +#define GPIO9_INT_REQ_TYPE_REG REG8_PTR(GPIO9_INT_REQ_TYPE_ADDR) +#define GPIO10_INT_REQ_TYPE_REG REG8_PTR(GPIO10_INT_REQ_TYPE_ADDR) +#define GPIO11_INT_REQ_TYPE_REG REG8_PTR(GPIO11_INT_REQ_TYPE_ADDR) +#define KPADROW0_INT_REQ_TYPE_REG REG8_PTR(KPADROW0_INT_REQ_TYPE_ADDR) +#define KPADROW1_INT_REQ_TYPE_REG REG8_PTR(KPADROW1_INT_REQ_TYPE_ADDR) +#define KPADROW2_INT_REQ_TYPE_REG REG8_PTR(KPADROW2_INT_REQ_TYPE_ADDR) +#define KPADROW3_INT_REQ_TYPE_REG REG8_PTR(KPADROW3_INT_REQ_TYPE_ADDR) +#define KPADCOL0_INT_REQ_TYPE_REG REG8_PTR(KPADCOL0_INT_REQ_TYPE_ADDR) +#define KPADCOL1_INT_REQ_TYPE_REG REG8_PTR(KPADCOL1_INT_REQ_TYPE_ADDR) +#define KPADCOL2_INT_REQ_TYPE_REG REG8_PTR(KPADCOL2_INT_REQ_TYPE_ADDR) +#define KPADCOL3_INT_REQ_TYPE_REG REG8_PTR(KPADCOL3_INT_REQ_TYPE_ADDR) +#define UART1RTS_INT_REQ_TYPE_REG REG8_PTR(UART1RTS_INT_REQ_TYPE_ADDR) +#define UART1TXD_INT_REQ_TYPE_REG REG8_PTR(UART1TXD_INT_REQ_TYPE_ADDR) +#define UART1CTS_INT_REQ_TYPE_REG REG8_PTR(UART1CTS_INT_REQ_TYPE_ADDR) +#define UART1RXD_INT_REQ_TYPE_REG REG8_PTR(UART1RXD_INT_REQ_TYPE_ADDR) +#define UART2RTS_INT_REQ_TYPE_REG REG8_PTR(UART2RTS_INT_REQ_TYPE_ADDR) +#define UART2TXD_INT_REQ_TYPE_REG REG8_PTR(UART2TXD_INT_REQ_TYPE_ADDR) +#define UART2CTS_INT_REQ_TYPE_REG REG8_PTR(UART2CTS_INT_REQ_TYPE_ADDR) +#define UART2RXD_INT_REQ_TYPE_REG REG8_PTR(UART2RXD_INT_REQ_TYPE_ADDR) +#define UART3RTS_INT_REQ_TYPE_REG REG8_PTR(UART3RTS_INT_REQ_TYPE_ADDR) +#define UART3TXD_INT_REQ_TYPE_REG REG8_PTR(UART3TXD_INT_REQ_TYPE_ADDR) +#define UART3CTS_INT_REQ_TYPE_REG REG8_PTR(UART3CTS_INT_REQ_TYPE_ADDR) +#define UART3RXD_INT_REQ_TYPE_REG REG8_PTR(UART3RXD_INT_REQ_TYPE_ADDR) +#define I2SDACDAT0_INT_REQ_TYPE_REG REG8_PTR(I2SDACDAT0_INT_REQ_TYPE_ADDR) +#define I2SDACDAT1_INT_REQ_TYPE_REG REG8_PTR(I2SDACDAT1_INT_REQ_TYPE_ADDR) +#define I2SDACDAT2_INT_REQ_TYPE_REG REG8_PTR(I2SDACDAT2_INT_REQ_TYPE_ADDR) +#define I2SDACDAT3_INT_REQ_TYPE_REG REG8_PTR(I2SDACDAT3_INT_REQ_TYPE_ADDR) +#define I2SADCMCLK_INT_REQ_TYPE_REG REG8_PTR(I2SADCMCLK_INT_REQ_TYPE_ADDR) +#define I2SDACLRC_INT_REQ_TYPE_REG REG8_PTR(I2SDACLRC_INT_REQ_TYPE_ADDR) +#define I2SDACBCLK_INT_REQ_TYPE_REG REG8_PTR(I2SDACBCLK_INT_REQ_TYPE_ADDR) +#define I2SDACMCLK_INT_REQ_TYPE_REG REG8_PTR(I2SDACMCLK_INT_REQ_TYPE_ADDR) +#define SPI0CLK_INT_REQ_TYPE_REG REG8_PTR(SPI0CLK_INT_REQ_TYPE_ADDR) +#define SPI0MISO_INT_REQ_TYPE_REG REG8_PTR(SPI0MISO_INT_REQ_TYPE_ADDR) +#define SPI0MOSI_INT_REQ_TYPE_REG REG8_PTR(SPI0MOSI_INT_REQ_TYPE_ADDR) +#define SPI0SS0_INT_REQ_TYPE_REG REG8_PTR(SPI0SS0_INT_REQ_TYPE_ADDR) +#define PWMOUT1_INT_REQ_TYPE_REG REG8_PTR(PWMOUT1_INT_REQ_TYPE_ADDR) +#define PWMOUT0_INT_REQ_TYPE_REG REG8_PTR(PWMOUT0_INT_REQ_TYPE_ADDR) +#define GPIO0_INT_REQ_STS_REG REG8_PTR(GPIO0_INT_REQ_STS_ADDR) +#define GPIO1_INT_REQ_STS_REG REG8_PTR(GPIO1_INT_REQ_STS_ADDR) +#define GPIO2_INT_REQ_STS_REG REG8_PTR(GPIO2_INT_REQ_STS_ADDR) +#define GPIO3_INT_REQ_STS_REG REG8_PTR(GPIO3_INT_REQ_STS_ADDR) +#define GPIO4_INT_REQ_STS_REG REG8_PTR(GPIO4_INT_REQ_STS_ADDR) +#define GPIO5_INT_REQ_STS_REG REG8_PTR(GPIO5_INT_REQ_STS_ADDR) +#define GPIO_IO_DRV_SD_4BYTE_REG REG32_PTR(GPIO_IO_DRV_SD_4BYTE_ADDR ) +#define GPIO_IO_DRV_VID_4BYTE_REG REG32_PTR(GPIO_IO_DRV_VID_4BYTE_ADDR ) +#define GPIO_IO_DRV_SPI_4BYTE_REG REG32_PTR(GPIO_IO_DRV_SPI_4BYTE_ADDR ) +#define GPIO_IO_DRV_NAND_4BYTE_REG REG32_PTR(GPIO_IO_DRV_NAND_4BYTE_ADDR ) +#define GPIO_IO_DRV_XD_4BYTE_REG REG32_PTR(GPIO_IO_DRV_XD_4BYTE_ADDR ) +#define GPIO_IO_DRV_SF_4BYTE_REG REG32_PTR(GPIO_IO_DRV_SF_4BYTE_ADDR ) +#define GPIO_IO_DRV_I2S_4BYTE_REG REG32_PTR(GPIO_IO_DRV_I2S_4BYTE_ADDR ) +#define GPIO_IO_DRV_PCM_4BYTE_REG REG32_PTR(GPIO_IO_DRV_PCM_4BYTE_ADDR ) +#define GPIO_IO_DRV_PWM_4BYTE_REG REG32_PTR(GPIO_IO_DRV_PWM_4BYTE_ADDR ) +#define GPIO_IO_DRV_GPIOL_4BYTE_REG REG32_PTR(GPIO_IO_DRV_GPIOL_4BYTE_ADDR ) +#define GPIO_IO_DRV_GPIOH_4BYTE_REG REG32_PTR(GPIO_IO_DRV_GPIOH_4BYTE_ADDR ) +#define GPIO_IO_DRV_HDMI_4BYTE_REG REG32_PTR(GPIO_IO_DRV_HDMI_4BYTE_ADDR ) +#define GPIO_IO_DRV_KEYPAD_4BYTE_REG REG32_PTR(GPIO_IO_DRV_KEYPAD_4BYTE_ADDR ) +#define GPIO_IO_DRV_JTAG_4BYTE_REG REG32_PTR(GPIO_IO_DRV_JTAG_4BYTE_ADDR ) +#define GPIO_IO_DRV_USB_4BYTE_REG REG32_PTR(GPIO_IO_DRV_USB_4BYTE_ADDR ) +#define GPIO_IO_DRV_SD0CD_4BYTE_REG REG32_PTR(GPIO_IO_DRV_SD0CD_4BYTE_ADDR ) +#define GPIO_PULL_EN_GP0_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP0_BYTE_ADDR ) +#define GPIO_PULL_EN_GP1_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP1_BYTE_ADDR ) +#define GPIO_PULL_EN_GP2_WAKEUP_SUS_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_PULL_EN_GP3_SD0CD_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_PULL_EN_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_PULL_EN_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_PULL_EN_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_PULL_EN_GP7_VD_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP7_VD_BYTE_ADDR ) +#define GPIO_PULL_EN_GP8_VDIN_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP8_VDIN_BYTE_ADDR ) +#define GPIO_PULL_EN_GP9_VSYNC_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_PULL_EN_GP10_I2S_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP10_I2S_BYTE_ADDR ) +#define GPIO_PULL_EN_GP11_SPI_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP11_SPI_BYTE_ADDR ) +#define GPIO_PULL_EN_GP12_XD_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP12_XD_BYTE_ADDR ) +#define GPIO_PULL_EN_GP13_XDIO_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP13_XDIO_BYTE_ADDR ) +#define GPIO_PULL_EN_GP14_SD_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP14_SD_BYTE_ADDR ) +#define GPIO_PULL_EN_GP15_NAND_7_0_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_PULL_EN_GP16_NAND_15_8_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_PULL_EN_GP18_SD0PWRSW_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP18_SD0PWRSW_BYTE_ADDR ) +#define GPIO_PULL_EN_GP21_I2C_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP21_I2C_BYTE_ADDR ) +#define GPIO_PULL_EN_GP22_UART_0_1_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_PULL_EN_GP23_UART_2_3_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_PULL_EN_GP24_TSDIN_7_0_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_PULL_EN_GP25_TS_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP25_TS_BYTE_ADDR ) +#define GPIO_PULL_EN_GP26_KPAD_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP26_KPAD_BYTE_ADDR ) +#define GPIO_PULL_EN_GP27_SPDIF_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_PULL_EN_GP28_NAND_CFG_0_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_PULL_EN_GP29_NAND_CFG_1_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_PULL_EN_GP30_SPI_FLASH_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_PULL_EN_GP31_PWM_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP31_PWM_BYTE_ADDR ) +#define GPIO_PULL_EN_GP32_HDMI_BYTE_REG REG8_PTR(GPIO_PULL_EN_GP32_HDMI_BYTE_ADDR ) +#define GPIO_PULL_EN_GP60_USB_TYTE_REG REG8_PTR(GPIO_PULL_EN_GP60_USB_TYTE_ADDR ) +#define GPIO_PULL_CTRL_GP0_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP0_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP1_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP1_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP2_WAKEUP_SUS_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP3_SD0CD_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP4_VDOUT_7_0_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP5_VDOUT_15_8_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP6_VDOUT_23_16_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP7_VD_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP7_VD_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP8_VDIN_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP8_VDIN_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP9_VSYNC_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP10_I2S_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP10_I2S_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP11_SPI_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP11_SPI_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP12_XD_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP12_XD_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP13_XDIO_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP13_XDIO_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP14_SD_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP14_SD_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP15_NAND_7_0_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP16_NAND_15_8_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP18_SD0PWRSW_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP18_SD0PWRSW_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP21_I2C_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP21_I2C_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP22_UART_0_1_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP23_UART_2_3_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP24_TSDIN_7_0_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP25_TS_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP25_TS_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP26_KPAD_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP26_KPAD_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP27_SPDIF_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP28_NAND_CFG_0_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP29_NAND_CFG_1_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP30_SPI_FLASH_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP31_PWM_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP31_PWM_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP32_HDMI_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP32_HDMI_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP60_USB_BYTE_REG REG8_PTR(GPIO_PULL_CTRL_GP60_USB_BYTE_ADDR ) + +#define GPIO_ID_GP0_BYTE_VAL REG8_VAL(GPIO_ID_GP0_BYTE_ADDR ) +#define GPIO_ID_GP1_BYTE_VAL REG8_VAL(GPIO_ID_GP1_BYTE_ADDR ) +#define GPIO_ID_GP2_WAKEUP_SUS_BYTE_VAL REG8_VAL(GPIO_ID_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_ID_GP3_SD0CD_BYTE_VAL REG8_VAL(GPIO_ID_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_ID_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(GPIO_ID_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_ID_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(GPIO_ID_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_ID_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(GPIO_ID_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_ID_GP7_VD_BYTE_VAL REG8_VAL(GPIO_ID_GP7_VD_BYTE_ADDR ) +#define GPIO_ID_GP8_VDIN_BYTE_VAL REG8_VAL(GPIO_ID_GP8_VDIN_BYTE_ADDR ) +#define GPIO_ID_GP9_VSYNC_BYTE_VAL REG8_VAL(GPIO_ID_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_ID_GP10_I2S_BYTE_VAL REG8_VAL(GPIO_ID_GP10_I2S_BYTE_ADDR ) +#define GPIO_ID_GP11_SPI_BYTE_VAL REG8_VAL(GPIO_ID_GP11_SPI_BYTE_ADDR ) +#define GPIO_ID_GP14_SD_BYTE_VAL REG8_VAL(GPIO_ID_GP14_SD_BYTE_ADDR ) +#define GPIO_ID_GP15_NAND_7_0_BYTE_VAL REG8_VAL(GPIO_ID_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_ID_GP16_NAND_15_8_BYTE_VAL REG8_VAL(GPIO_ID_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_ID_GP21_I2C_BYTE_VAL REG8_VAL(GPIO_ID_GP21_I2C_BYTE_ADDR ) +#define GPIO_ID_GP22_UART_0_1_BYTE_VAL REG8_VAL(GPIO_ID_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_ID_GP23_UART_2_3_BYTE_VAL REG8_VAL(GPIO_ID_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_ID_GP24_TSDIN_7_0_BYTE_VAL REG8_VAL(GPIO_ID_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_ID_GP25_TS_BYTE_VAL REG8_VAL(GPIO_ID_GP25_TS_BYTE_ADDR ) +#define GPIO_ID_GP26_KPAD_BYTE_VAL REG8_VAL(GPIO_ID_GP26_KPAD_BYTE_ADDR ) +#define GPIO_ID_GP27_SPDIF_BYTE_VAL REG8_VAL(GPIO_ID_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_ID_GP28_NAND_CFG_0_BYTE_VAL REG8_VAL(GPIO_ID_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_ID_GP29_NAND_CFG_1_BYTE_VAL REG8_VAL(GPIO_ID_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_ID_GP30_SPI_FLASH_BYTE_VAL REG8_VAL(GPIO_ID_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_ID_GP31_PWM_BYTE_VAL REG8_VAL(GPIO_ID_GP31_PWM_BYTE_ADDR ) +#define GPIO_ID_GP31_HDMI_BYTE_VAL REG8_VAL(GPIO_ID_GP32_HDMI_BYTE_ADDR ) +#define GPIO_ID_GP60_USB_BYTE_VAL REG8_VAL(GPIO_ID_GP60_USB_BYTE_ADDR ) +#define GPIO_CTRL_GP0_BYTE_VAL REG8_VAL(GPIO_CTRL_GP0_BYTE_ADDR ) +#define GPIO_CTRL_GP1_BYTE_VAL REG8_VAL(GPIO_CTRL_GP1_BYTE_ADDR ) +#define GPIO_CTRL_GP2_WAKEUP_SUS_BYTE_VAL REG8_VAL(GPIO_CTRL_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_CTRL_GP3_SD0CD_BYTE_VAL REG8_VAL(GPIO_CTRL_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_CTRL_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(GPIO_CTRL_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_CTRL_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(GPIO_CTRL_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_CTRL_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(GPIO_CTRL_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_CTRL_GP7_VD_BYTE_VAL REG8_VAL(GPIO_CTRL_GP7_VD_BYTE_ADDR ) +#define GPIO_CTRL_GP8_VDIN_BYTE_VAL REG8_VAL(GPIO_CTRL_GP8_VDIN_BYTE_ADDR ) +#define GPIO_CTRL_GP9_VSYNC_BYTE_VAL REG8_VAL(GPIO_CTRL_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_CTRL_GP10_I2S_BYTE_VAL REG8_VAL(GPIO_CTRL_GP10_I2S_BYTE_ADDR ) +#define GPIO_CTRL_GP11_SPI_BYTE_VAL REG8_VAL(GPIO_CTRL_GP11_SPI_BYTE_ADDR ) +#define GPIO_CTRL_GP14_SD_BYTE_VAL REG8_VAL(GPIO_CTRL_GP14_SD_BYTE_ADDR ) +#define GPIO_CTRL_GP15_NAND_7_0_BYTE_VAL REG8_VAL(GPIO_CTRL_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_CTRL_GP16_NAND_15_8_BYTE_VAL REG8_VAL(GPIO_CTRL_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_CTRL_GP18_SD0PWRSW_BYTE_VAL REG8_VAL(GPIO_CTRL_GP18_SD0PWRSW_BYTE_ADDR ) +#define GPIO_CTRL_GP21_I2C_BYTE_VAL REG8_VAL(GPIO_CTRL_GP21_I2C_BYTE_ADDR ) +#define GPIO_CTRL_GP22_UART_0_1_BYTE_VAL REG8_VAL(GPIO_CTRL_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_CTRL_GP23_UART_2_3_BYTE_VAL REG8_VAL(GPIO_CTRL_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_CTRL_GP24_TSDIN_7_0_BYTE_VAL REG8_VAL(GPIO_CTRL_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_CTRL_GP25_TS_BYTE_VAL REG8_VAL(GPIO_CTRL_GP25_TS_BYTE_ADDR ) +#define GPIO_CTRL_GP26_KPAD_BYTE_VAL REG8_VAL(GPIO_CTRL_GP26_KPAD_BYTE_ADDR ) +#define GPIO_CTRL_GP27_SPDIF_BYTE_VAL REG8_VAL(GPIO_CTRL_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_CTRL_GP28_NAND_CFG_0_BYTE_VAL REG8_VAL(GPIO_CTRL_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_CTRL_GP29_NAND_CFG_1_BYTE_VAL REG8_VAL(GPIO_CTRL_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_CTRL_GP30_SPI_FLASH_BYTE_VAL REG8_VAL(GPIO_CTRL_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_CTRL_GP31_PWM_BYTE_VAL REG8_VAL(GPIO_CTRL_GP31_PWM_BYTE_ADDR ) +#define GPIO_CTRL_GP32_HDMI_BYTE_VAL REG8_VAL(GPIO_CTRL_GP32_HDMI_BYTE_ADDR ) +#define GPIO_CTRL_GP60_USB_BYTE_VAL REG8_VAL(GPIO_CTRL_GP60_USB_BYTE_ADDR ) +#define GPIO_OC_GP0_BYTE_VAL REG8_VAL(GPIO_OC_GP0_BYTE_ADDR ) +#define GPIO_OC_GP1_BYTE_VAL REG8_VAL(GPIO_OC_GP1_BYTE_ADDR ) +#define GPIO_OC_GP2_WAKEUP_SUS_BYTE_VAL REG8_VAL(GPIO_OC_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_OC_GP3_SD0CD_BYTE_VAL REG8_VAL(GPIO_OC_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_OC_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(GPIO_OC_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_OC_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(GPIO_OC_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_OC_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(GPIO_OC_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_OC_GP7_VD_BYTE_VAL REG8_VAL(GPIO_OC_GP7_VD_BYTE_ADDR ) +#define GPIO_OC_GP8_VDIN_BYTE_VAL REG8_VAL(GPIO_OC_GP8_VDIN_BYTE_ADDR ) +#define GPIO_OC_GP9_VSYNC_BYTE_VAL REG8_VAL(GPIO_OC_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_OC_GP10_I2S_BYTE_VAL REG8_VAL(GPIO_OC_GP10_I2S_BYTE_ADDR ) +#define GPIO_OC_GP11_SPI_BYTE_VAL REG8_VAL(GPIO_OC_GP11_SPI_BYTE_ADDR ) +#define GPIO_OC_GP14_SD_BYTE_VAL REG8_VAL(GPIO_OC_GP14_SD_BYTE_ADDR ) +#define GPIO_OC_GP15_NAND_7_0_BYTE_VAL REG8_VAL(GPIO_OC_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_OC_GP16_NAND_15_8_BYTE_VAL REG8_VAL(GPIO_OC_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_OC_GP18_SD0PWRSW_BYTE_VAL REG8_VAL(GPIO_OC_GP18_SD0PWRSW_BYTE_ADDR ) +#define GPIO_OC_GP21_I2C_BYTE_VAL REG8_VAL(GPIO_OC_GP21_I2C_BYTE_ADDR ) +#define GPIO_OC_GP22_UART_0_1_BYTE_VAL REG8_VAL(GPIO_OC_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_OC_GP23_UART_2_3_BYTE_VAL REG8_VAL(GPIO_OC_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_OC_GP24_TSDIN_7_0_BYTE_VAL REG8_VAL(GPIO_OC_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_OC_GP25_TS_BYTE_VAL REG8_VAL(GPIO_OC_GP25_TS_BYTE_ADDR ) +#define GPIO_OC_GP26_KPAD_BYTE_VAL REG8_VAL(GPIO_OC_GP26_KPAD_BYTE_ADDR ) +#define GPIO_OC_GP27_SPDIF_BYTE_VAL REG8_VAL(GPIO_OC_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_OC_GP28_NAND_CFG_0_BYTE_VAL REG8_VAL(GPIO_OC_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_OC_GP29_NAND_CFG_1_BYTE_VAL REG8_VAL(GPIO_OC_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_OC_GP30_SPI_FLASH_BYTE_VAL REG8_VAL(GPIO_OC_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_OC_GP31_PWM_BYTE_VAL REG8_VAL(GPIO_OC_GP31_PWM_BYTE_ADDR ) +#define GPIO_OC_GP32_HDMI_BYTE_VAL REG8_VAL(GPIO_OC_GP32_HDMI_BYTE_ADDR ) +#define GPIO_OC_GP60_USB_BYTE_VAL REG8_VAL(GPIO_OC_GP60_USB_BYTE_ADDR ) +#define GPIO_OD_GP0_BYTE_VAL REG8_VAL(GPIO_OD_GP0_BYTE_ADDR ) +#define GPIO_OD_GP1_BYTE_VAL REG8_VAL(GPIO_OD_GP1_BYTE_ADDR ) +#define GPIO_OD_GP2_WAKEUP_SUS_BYTE_VAL REG8_VAL(GPIO_OD_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_OD_GP3_SD0CD_BYTE_VAL REG8_VAL(GPIO_OD_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_OD_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(GPIO_OD_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_OD_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(GPIO_OD_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_OD_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(GPIO_OD_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_OD_GP7_VD_BYTE_VAL REG8_VAL(GPIO_OD_GP7_VD_BYTE_ADDR ) +#define GPIO_OD_GP8_VDIN_BYTE_VAL REG8_VAL(GPIO_OD_GP8_VDIN_BYTE_ADDR ) +#define GPIO_OD_GP9_VSYNC_BYTE_VAL REG8_VAL(GPIO_OD_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_OD_GP10_I2S_BYTE_VAL REG8_VAL(GPIO_OD_GP10_I2S_BYTE_ADDR ) +#define GPIO_OD_GP11_SPI_BYTE_VAL REG8_VAL(GPIO_OD_GP11_SPI_BYTE_ADDR ) +#define GPIO_OD_GP14_SD_BYTE_VAL REG8_VAL(GPIO_OD_GP14_SD_BYTE_ADDR ) +#define GPIO_OD_GP15_NAND_7_0_BYTE_VAL REG8_VAL(GPIO_OD_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_OD_GP16_NAND_15_8_BYTE_VAL REG8_VAL(GPIO_OD_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_OD_GP18_SD0PWRSW_BYTE_VAL REG8_VAL(GPIO_OD_GP18_SD0PWRSW_BYTE_ADDR ) +#define GPIO_OD_GP21_I2C_BYTE_VAL REG8_VAL(GPIO_OD_GP21_I2C_BYTE_ADDR ) +#define GPIO_OD_GP22_UART_0_1_BYTE_VAL REG8_VAL(GPIO_OD_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_OD_GP23_UART_2_3_BYTE_VAL REG8_VAL(GPIO_OD_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_OD_GP24_TSDIN_7_0_BYTE_VAL REG8_VAL(GPIO_OD_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_OD_GP25_TS_BYTE_VAL REG8_VAL(GPIO_OD_GP25_TS_BYTE_ADDR ) +#define GPIO_OD_GP26_KPAD_BYTE_VAL REG8_VAL(GPIO_OD_GP26_KPAD_BYTE_ADDR ) +#define GPIO_OD_GP27_SPDIF_BYTE_VAL REG8_VAL(GPIO_OD_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_OD_GP28_NAND_CFG_0_BYTE_VAL REG8_VAL(GPIO_OD_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_OD_GP29_NAND_CFG_1_BYTE_VAL REG8_VAL(GPIO_OD_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_OD_GP30_SPI_FLASH_BYTE_VAL REG8_VAL(GPIO_OD_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_OD_GP31_PWM_BYTE_VAL REG8_VAL(GPIO_OD_GP31_PWM_BYTE_ADDR ) +#define GPIO_OD_GP32_HDMI_BYTE_VAL REG8_VAL(GPIO_OD_GP32_HDMI_BYTE_ADDR ) +#define GPIO_OD_GP60_USB_BYTE_VAL REG8_VAL(GPIO_OD_GP60_USB_BYTE_ADDR ) +#define GPIO_STRAP_STATUS_VAL REG32_VAL(GPIO_STRAP_STATUS_ADDR ) +#define GPIO_AHB_CTRL_4BYTE_VAL REG32_VAL(GPIO_AHB_CTRL_4BYTE_ADDR ) +#define GPIO_USB_OP_CTRL_4BYTE_ADDR_VAL REG32_VAL(GPIO_USB_OP_CTRL_4BYTE_ADDR ) +#define GPIO_BONDING_OPTION_4BYTE_VAL REG32_VAL(GPIO_BONDING_OPTION_4BYTE_ADDR ) +#define GPIO_PIN_SHARING_SEL_4BYTE_VAL REG32_VAL(GPIO_PIN_SHARING_SEL_4BYTE_ADDR ) +#define GPIO0_INT_REQ_TYPE_VAL REG8_VAL(GPIO0_INT_REQ_TYPE_ADDR) +#define GPIO1_INT_REQ_TYPE_VAL REG8_VAL(GPIO1_INT_REQ_TYPE_ADDR) +#define GPIO2_INT_REQ_TYPE_VAL REG8_VAL(GPIO2_INT_REQ_TYPE_ADDR) +#define GPIO3_INT_REQ_TYPE_VAL REG8_VAL(GPIO3_INT_REQ_TYPE_ADDR) +#define GPIO4_INT_REQ_TYPE_VAL REG8_VAL(GPIO4_INT_REQ_TYPE_ADDR) +#define GPIO5_INT_REQ_TYPE_VAL REG8_VAL(GPIO5_INT_REQ_TYPE_ADDR) +#define GPIO6_INT_REQ_TYPE_VAL REG8_VAL(GPIO6_INT_REQ_TYPE_ADDR) +#define GPIO7_INT_REQ_TYPE_VAL REG8_VAL(GPIO7_INT_REQ_TYPE_ADDR) +#define GPIO8_INT_REQ_TYPE_VAL REG8_VAL(GPIO8_INT_REQ_TYPE_ADDR) +#define GPIO9_INT_REQ_TYPE_VAL REG8_VAL(GPIO9_INT_REQ_TYPE_ADDR) +#define GPIO10_INT_REQ_TYPE_VAL REG8_VAL(GPIO10_INT_REQ_TYPE_ADDR) +#define GPIO11_INT_REQ_TYPE_VAL REG8_VAL(GPIO11_INT_REQ_TYPE_ADDR) +#define KPADROW0_INT_REQ_TYPE_VAL REG8_VAL(KPADROW0_INT_REQ_TYPE_ADDR) +#define KPADROW1_INT_REQ_TYPE_VAL REG8_VAL(KPADROW1_INT_REQ_TYPE_ADDR) +#define KPADROW2_INT_REQ_TYPE_VAL REG8_VAL(KPADROW2_INT_REQ_TYPE_ADDR) +#define KPADROW3_INT_REQ_TYPE_VAL REG8_VAL(KPADROW3_INT_REQ_TYPE_ADDR) +#define KPADCOL0_INT_REQ_TYPE_VAL REG8_VAL(KPADCOL0_INT_REQ_TYPE_ADDR) +#define KPADCOL1_INT_REQ_TYPE_VAL REG8_VAL(KPADCOL1_INT_REQ_TYPE_ADDR) +#define KPADCOL2_INT_REQ_TYPE_VAL REG8_VAL(KPADCOL2_INT_REQ_TYPE_ADDR) +#define KPADCOL3_INT_REQ_TYPE_VAL REG8_VAL(KPADCOL3_INT_REQ_TYPE_ADDR) +#define UART1RTS_INT_REQ_TYPE_VAL REG8_VAL(UART1RTS_INT_REQ_TYPE_ADDR) +#define UART1TXD_INT_REQ_TYPE_VAL REG8_VAL(UART1TXD_INT_REQ_TYPE_ADDR) +#define UART1CTS_INT_REQ_TYPE_VAL REG8_VAL(UART1CTS_INT_REQ_TYPE_ADDR) +#define UART1RXD_INT_REQ_TYPE_VAL REG8_VAL(UART1RXD_INT_REQ_TYPE_ADDR) +#define UART2RTS_INT_REQ_TYPE_VAL REG8_VAL(UART2RTS_INT_REQ_TYPE_ADDR) +#define UART2TXD_INT_REQ_TYPE_VAL REG8_VAL(UART2TXD_INT_REQ_TYPE_ADDR) +#define UART2CTS_INT_REQ_TYPE_VAL REG8_VAL(UART2CTS_INT_REQ_TYPE_ADDR) +#define UART2RXD_INT_REQ_TYPE_VAL REG8_VAL(UART2RXD_INT_REQ_TYPE_ADDR) +#define UART3RTS_INT_REQ_TYPE_VAL REG8_VAL(UART3RTS_INT_REQ_TYPE_ADDR) +#define UART3TXD_INT_REQ_TYPE_VAL REG8_VAL(UART3TXD_INT_REQ_TYPE_ADDR) +#define UART3CTS_INT_REQ_TYPE_VAL REG8_VAL(UART3CTS_INT_REQ_TYPE_ADDR) +#define UART3RXD_INT_REQ_TYPE_VAL REG8_VAL(UART3RXD_INT_REQ_TYPE_ADDR) +#define I2SDACDAT0_INT_REQ_TYPE_VAL REG8_VAL(I2SDACDAT0_INT_REQ_TYPE_ADDR) +#define I2SDACDAT1_INT_REQ_TYPE_VAL REG8_VAL(I2SDACDAT1_INT_REQ_TYPE_ADDR) +#define I2SDACDAT2_INT_REQ_TYPE_VAL REG8_VAL(I2SDACDAT2_INT_REQ_TYPE_ADDR) +#define I2SDACDAT3_INT_REQ_TYPE_VAL REG8_VAL(I2SDACDAT3_INT_REQ_TYPE_ADDR) +#define I2SADCMCLK_INT_REQ_TYPE_VAL REG8_VAL(I2SADCMCLK_INT_REQ_TYPE_ADDR) +#define I2SDACLRC_INT_REQ_TYPE_VAL REG8_VAL(I2SDACLRC_INT_REQ_TYPE_ADDR) +#define I2SDACBCLK_INT_REQ_TYPE_VAL REG8_VAL(I2SDACBCLK_INT_REQ_TYPE_ADDR) +#define I2SDACMCLK_INT_REQ_TYPE_VAL REG8_VAL(I2SDACMCLK_INT_REQ_TYPE_ADDR) +#define SPI0CLK_INT_REQ_TYPE_VAL REG8_VAL(SPI0CLK_INT_REQ_TYPE_ADDR) +#define SPI0MISO_INT_REQ_TYPE_VAL REG8_VAL(SPI0MISO_INT_REQ_TYPE_ADDR) +#define SPI0MOSI_INT_REQ_TYPE_VAL REG8_VAL(SPI0MOSI_INT_REQ_TYPE_ADDR) +#define SPI0SS0_INT_REQ_TYPE_VAL REG8_VAL(SPI0SS0_INT_REQ_TYPE_ADDR) +#define PWMOUT1_INT_REQ_TYPE_VAL REG8_VAL(PWMOUT1_INT_REQ_TYPE_ADDR) +#define PWMOUT0_INT_REQ_TYPE_VAL REG8_VAL(PWMOUT0_INT_REQ_TYPE_ADDR) +#define GPIO0_INT_REQ_STS_VAL REG8_VAL(GPIO0_INT_REQ_STS_ADDR) +#define GPIO1_INT_REQ_STS_VAL REG8_VAL(GPIO1_INT_REQ_STS_ADDR) +#define GPIO2_INT_REQ_STS_VAL REG8_VAL(GPIO2_INT_REQ_STS_ADDR) +#define GPIO3_INT_REQ_STS_VAL REG8_VAL(GPIO3_INT_REQ_STS_ADDR) +#define GPIO4_INT_REQ_STS_VAL REG8_VAL(GPIO4_INT_REQ_STS_ADDR) +#define GPIO5_INT_REQ_STS_VAL REG8_VAL(GPIO5_INT_REQ_STS_ADDR) +#define GPIO_IO_DRV_SD_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_SD_4BYTE_ADDR ) +#define GPIO_IO_DRV_VID_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_VID_4BYTE_ADDR ) +#define GPIO_IO_DRV_SPI_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_SPI_4BYTE_ADDR ) +#define GPIO_IO_DRV_NAND_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_NAND_4BYTE_ADDR ) +#define GPIO_IO_DRV_XD_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_XD_4BYTE_ADDR ) +#define GPIO_IO_DRV_SF_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_SF_4BYTE_ADDR ) +#define GPIO_IO_DRV_I2S_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_I2S_4BYTE_ADDR ) +#define GPIO_IO_DRV_PCM_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_PCM_4BYTE_ADDR ) +#define GPIO_IO_DRV_PWM_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_PWM_4BYTE_ADDR ) +#define GPIO_IO_DRV_IDE_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_GPIOL_4BYTE_ADDR ) +#define GPIO_IO_DRV_GPIO_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_GPIOH_4BYTE_ADDR ) +#define GPIO_IO_DRV_HDMI_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_HDMI_4BYTE_ADDR ) +#define GPIO_IO_DRV_KEYPAD_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_KEYPAD_4BYTE_ADDR ) +#define GPIO_IO_DRV_JTAG_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_JTAG_4BYTE_ADDR ) +#define GPIO_IO_DRV_USB_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_USB_4BYTE_ADDR ) +#define GPIO_IO_DRV_SD0CD_4BYTE_VAL REG32_VAL(GPIO_IO_DRV_SD0CD_4BYTE_ADDR ) +#define GPIO_PULL_EN_GP0_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP0_BYTE_ADDR ) +#define GPIO_PULL_EN_GP1_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP1_BYTE_ADDR ) +#define GPIO_PULL_EN_GP2_WAKEUP_SUS_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_PULL_EN_GP3_SD0CD_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_PULL_EN_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_PULL_EN_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_PULL_EN_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_PULL_EN_GP7_VD_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP7_VD_BYTE_ADDR ) +#define GPIO_PULL_EN_GP8_VDIN_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP8_VDIN_BYTE_ADDR ) +#define GPIO_PULL_EN_GP9_VSYNC_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_PULL_EN_GP10_I2S_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP10_I2S_BYTE_ADDR ) +#define GPIO_PULL_EN_GP11_SPI_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP11_SPI_BYTE_ADDR ) +#define GPIO_PULL_EN_GP12_XD_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP12_XD_BYTE_ADDR ) +#define GPIO_PULL_EN_GP13_XDIO_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP13_XDIO_BYTE_ADDR ) +#define GPIO_PULL_EN_GP14_SD_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP14_SD_BYTE_ADDR ) +#define GPIO_PULL_EN_GP15_NAND_7_0_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_PULL_EN_GP16_NAND_15_8_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_PULL_EN_GP18_SD0PWRSW_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP18_SD0PWRSW_BYTE_ADDR ) +#define GPIO_PULL_EN_GP21_I2C_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP21_I2C_BYTE_ADDR ) +#define GPIO_PULL_EN_GP22_UART_0_1_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_PULL_EN_GP23_UART_2_3_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_PULL_EN_GP24_TSDIN_7_0_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_PULL_EN_GP25_TS_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP25_TS_BYTE_ADDR ) +#define GPIO_PULL_EN_GP26_KPAD_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP26_KPAD_BYTE_ADDR ) +#define GPIO_PULL_EN_GP27_SPDIF_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_PULL_EN_GP28_NAND_CFG_0_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_PULL_EN_GP29_NAND_CFG_1_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_PULL_EN_GP30_SPI_FLASH_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_PULL_EN_GP31_PWM_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP31_PWM_BYTE_ADDR ) +#define GPIO_PULL_EN_GP32_HDMI_BYTE_VAL REG8_VAL(GPIO_PULL_EN_GP32_HDMI_BYTE_ADDR ) +#define GPIO_PULL_EN_GP60_USB_TYTE_VAL REG8_VAL(GPIO_PULL_EN_GP60_USB_TYTE_ADDR ) +#define GPIO_PULL_CTRL_GP0_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP0_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP1_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP1_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP2_WAKEUP_SUS_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP2_WAKEUP_SUS_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP3_SD0CD_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP3_SD0CD_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP4_VDOUT_7_0_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP4_VDOUT_7_0_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP5_VDOUT_15_8_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP5_VDOUT_15_8_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP6_VDOUT_23_16_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP6_VDOUT_23_16_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP7_VD_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP7_VD_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP8_VDIN_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP8_VDIN_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP9_VSYNC_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP9_VSYNC_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP10_I2S_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP10_I2S_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP11_SPI_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP11_SPI_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP12_XD_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP12_XD_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP13_XDIO_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP13_XDIO_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP14_SD_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP14_SD_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP15_NAND_7_0_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP15_NAND_7_0_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP16_NAND_15_8_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP16_NAND_15_8_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP18_SD0PWRSW_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP18_SD0PWRSW_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP21_I2C_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP21_I2C_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP22_UART_0_1_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP22_UART_0_1_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP23_UART_2_3_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP23_UART_2_3_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP24_TSDIN_7_0_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP24_TSDIN_7_0_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP25_TS_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP25_TS_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP26_KPAD_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP26_KPAD_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP27_SPDIF_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP27_SPDIF_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP28_NAND_CFG_0_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP28_NAND_CFG_0_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP29_NAND_CFG_1_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP29_NAND_CFG_1_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP30_SPI_FLASH_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP30_SPI_FLASH_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP31_PWM_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP31_PWM_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP32_HDMI_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP32_HDMI_BYTE_ADDR ) +#define GPIO_PULL_CTRL_GP60_USB_BYTE_VAL REG8_VAL(GPIO_PULL_CTRL_GP60_USB_BYTE_ADDR ) + + +/* [Rx40] GPIO Enable Control Register for SD,MMC */ +//#define GPIO_SD_DATA 0xF +//#define GPIO_MMC_DATA 0xF0 + +/* [Rx56] GPIO Eanble Control Register for UART */ +#define GPIO_UR0_RTS 0x1 +#define GPIO_UR0_TXD 0x2 +#define GPIO_UR0_CTS 0x4 +#define GPIO_UR0_RXD 0x8 +#define GPIO_UR0_ALL 0xF + +/* [Rx96] GPIO Output Control Register for UARTS */ +#define GPIO_OE_UR0_RTS 0x1 +#define GPIO_OE_UR0_TXD 0x2 +#define GPIO_OE_UR0_CTS 0x4 +#define GPIO_OE_UR0_RXD 0x8 +#define GPIO_OE_UR0_ALL 0xF + +/* [RxD6] GPIO Output Data Register for UARTS */ +#define GPIO_OD_UR0_RTS 0x1 +#define GPIO_OD_UR0_TXD 0x2 +#define GPIO_OD_UR0_CTS 0x4 +#define GPIO_OD_UR0_RXD 0x8 +#define GPIO_OD_UR0_ALL 0xF + +/* [Rx16] GPIO Input Data Register for UARTS */ +#define GPIO_ID_UR0_RTS 0x1 +#define GPIO_ID_UR0_TXD 0x2 +#define GPIO_ID_UR0_CTS 0x4 +#define GPIO_ID_UR0_RXD 0x8 +#define GPIO_ID_UR0_ALL 0xF + +/* [Rx40] GPIO Eanble Control Register for Dedicated GPIO */ +#define GPIO_GPIO_ALL 0xFF +#define GPIO_GPIO_0 0x1 +#define GPIO_GPIO_1 0x2 +#define GPIO_GPIO_2 0x4 +#define GPIO_GPIO_3 0x8 +#define GPIO_GPIO_4 0x10 +#define GPIO_GPIO_5 0x20 +#define GPIO_GPIO_6 0x40 +#define GPIO_GPIO_7 0x80 + +/* [Rx80] GPIO Output Control Register for Dedicated GPIO */ +#define GPIO_OE_GPIO_ALL 0xFF +#define GPIO_OE_GPIO_0 0x1 +#define GPIO_OE_GPIO_1 0x2 +#define GPIO_OE_GPIO_2 0x4 +#define GPIO_OE_GPIO_3 0x8 +#define GPIO_OE_GPIO_4 0x10 +#define GPIO_OE_GPIO_5 0x20 +#define GPIO_OE_GPIO_6 0x40 +#define GPIO_OE_GPIO_7 0x80 + +/* [RxC0] GPIO Output Data Register for Dedicated GPIO */ +#define GPIO_OD_GPIO_ALL 0xFF +#define GPIO_OD_GPIO_0 0x1 +#define GPIO_OD_GPIO_1 0x2 +#define GPIO_OD_GPIO_2 0x4 +#define GPIO_OD_GPIO_3 0x8 +#define GPIO_OD_GPIO_4 0x10 +#define GPIO_OD_GPIO_5 0x20 +#define GPIO_OD_GPIO_6 0x40 +#define GPIO_OD_GPIO_7 0x80 + +/* [Rx00] GPIO Input Data Register for Dedicated GPIO */ +#define GPIO_ID_GPIO_ALL 0xFF +#define GPIO_ID_GPIO_0 0x1 +#define GPIO_ID_GPIO_1 0x2 +#define GPIO_ID_GPIO_2 0x4 +#define GPIO_ID_GPIO_3 0x8 +#define GPIO_ID_GPIO_4 0x10 +#define GPIO_ID_GPIO_5 0x20 +#define GPIO_ID_GPIO_6 0x40 +#define GPIO_ID_GPIO_7 0x80 + +/* [Rx300] GPIO Interrupt Request Type Register */ +#define GPIO_IRQT0_LOW (BIT1 & BIT0) +#define GPIO_IRQT0_HIGH ((~BIT1) & BIT0) +#define GPIO_IRQT0_FALLING (BIT1 & (~BIT0)) +#define GPIO_IRQT0_RISING (BIT1 | BIT0) +#define GPIO_IRQT0_NEGEDGE BIT2 +#define GPIO_IRQT0_EN BIT7 +#define GPIO_IRQT1_LOW (BIT9 & BIT8) +#define GPIO_IRQT1_HIGH ((~BIT9) & BIT8) +#define GPIO_IRQT1_FALLING (BIT9 & (~BIT8)) +#define GPIO_IRQT1_RISING (BIT9 | BIT8) +#define GPIO_IRQT1_NEGEDGE BIT10 +#define GPIO_IRQT1_EN BIT15 +#define GPIO_IRQT2_LOW (BIT17 & BIT16) +#define GPIO_IRQT2_HIGH ((~BIT17) & BIT16) +#define GPIO_IRQT2_FALLING (BIT17 & (~BIT16)) +#define GPIO_IRQT2_RISING (BIT17 | BIT16) +#define GPIO_IRQT2_NEGEDGE BIT18 +#define GPIO_IRQT2_EN BIT23 +#define GPIO_IRQT3_LOW (BIT25 & BIT24) +#define GPIO_IRQT3_HIGH ((~BIT25) & BIT24) +#define GPIO_IRQT3_FALLING (BIT25 & (~BIT24)) +#define GPIO_IRQT3_RISING (BIT25 | BIT24) +#define GPIO_IRQT3_NEGEDGE BIT26 +#define GPIO_IRQT3_EN BIT31 + +/* [Rx318] GPIO Interrupt Request Type Register */ +#define GPIO_IRQT4_LOW (BIT1 & BIT0) +#define GPIO_IRQT4_HIGH ((~BIT1) & BIT0) +#define GPIO_IRQT4_FALLING (BIT1 & (~BIT0)) +#define GPIO_IRQT4_RISING (BIT1 | BIT0) +#define GPIO_IRQT4_NEGEDGE BIT2 +#define GPIO_IRQT4_EN BIT7 +#define GPIO_IRQT5_LOW (BIT9 & BIT8) +#define GPIO_IRQT5_HIGH ((~BIT9) & BIT8) +#define GPIO_IRQT5_FALLING (BIT9 & (~BIT8)) +#define GPIO_IRQT5_RISING (BIT9 | BIT8) +#define GPIO_IRQT5_NEGEDGE BIT10 +#define GPIO_IRQT5_EN BIT15 +#define GPIO_IRQT6_LOW (BIT17 & BIT16) +#define GPIO_IRQT6_HIGH ((~BIT17) & BIT16) +#define GPIO_IRQT6_FALLING (BIT17 & (~BIT16)) +#define GPIO_IRQT6_RISING (BIT17 | BIT16) +#define GPIO_IRQT6_NEGEDGE BIT18 +#define GPIO_IRQT6_EN BIT23 +#define GPIO_IRQT7_LOW (BIT25 & BIT24) +#define GPIO_IRQT7_HIGH ((~BIT25) & BIT24) +#define GPIO_IRQT7_FALLING (BIT25 & (~BIT24)) +#define GPIO_IRQT7_RISING (BIT25 | BIT24) +#define GPIO_IRQT7_NEGEDGE BIT26 +#define GPIO_IRQT7_EN BIT31 + +/* [Rx320] GPIO Interrupt Request Status Register */ +#define GPIO_IRQS0_ACTIVE (BIT0) +#define GPIO_IRQS1_ACTIVE (BIT1) +#define GPIO_IRQS2_ACTIVE (BIT2) +#define GPIO_IRQS3_ACTIVE (BIT3) +#define GPIO_IRQS4_ACTIVE (BIT24) +#define GPIO_IRQS5_ACTIVE (BIT25) +#define GPIO_IRQS6_ACTIVE (BIT26) +#define GPIO_IRQS7_ACTIVE (BIT27) + +/* [Rx55] GPIO Control Register for I2C */ +#define GPIO_I2C0_SCL BIT0 +#define GPIO_I2C0_SDA BIT1 +#define GPIO_I2C1_SCL BIT2 +#define GPIO_I2C1_SDA BIT3 +/* [Rx4D5] */ +#define GPIO_I2C0_SCL_PULL_EN BIT0 +#define GPIO_I2C0_SDA_PULL_EN BIT1 +#define GPIO_I2C1_SCL_PULL_EN BIT2 +#define GPIO_I2C1_SDA_PULL_EN BIT3 + +/* [Rx4E] GPIO Control Register for SD*/ +#define GPIO_SD0_CLK BIT1 +#define GPIO_SD0_CMD BIT2 +#define GPIO_SD0_WP BIT3 +#define GPIO_SD0_DATA0 BIT4 +#define GPIO_SD0_DATA1 BIT5 +#define GPIO_SD0_DATA2 BIT6 +#define GPIO_SD0_DATA3 BIT7 + +/* [Rx4E] GPIO Control Register for SD*/ +#define GPIO_SD0_CLK_PULL_EN BIT1 +#define GPIO_SD0_CMD_PULL_EN BIT2 +#define GPIO_SD0_WP_PULL_EN BIT3 +#define GPIO_SD0_DATA0_PULL_EN BIT4 +#define GPIO_SD0_DATA1_PULL_EN BIT5 +#define GPIO_SD0_DATA2_PULL_EN BIT6 +#define GPIO_SD0_DATA3_PULL_EN BIT7 + +/*[Rx5F] GPIO 31*/ +#define GPIO_PWMOUT0 BIT3 +#define GPIO_C25MHZCLK BIT2 +#define GPIO_C24MHZCLK BIT1 +#define GPIO_CLK_OUT BIT0 + +#define GPIO_PWMOUT0_PULL_EN BIT3 +#define GPIO_C25MHZCLK_PULL_EN BIT2 +#define GPIO_C24MHZCLK_PULL_EN BIT1 +#define GPIO_CLK_OUT_PULL_EN BIT0 + diff --git a/drivers/gpu/drm/arise/cbios/Util/CBiosUtil.c b/drivers/gpu/drm/arise/cbios/Util/CBiosUtil.c new file mode 100644 index 0000000000000..e836126ad98f9 --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/Util/CBiosUtil.c @@ -0,0 +1,1084 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +/***************************************************************************** +** DESCRIPTION: +** CBios sw utility common functions. +** +** NOTE: +** The hw dependent function SHOULD NOT be added to this file. +******************************************************************************/ + +#include "CBiosChipShare.h" + +#define BASEV(b, v) b##v +#define TO_BASE16(a) BASEV(0x, a) +#define CBIOS_TRNAS_VER(CBIOS_VER) TO_BASE16(CBIOS_VER) + + +static CBIOS_U32 cbGetVsyncWidth(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 XRes, CBIOS_U32 YRes) +{ + CBIOS_U32 ulRet = 10; + CBIOS_U32 ulTemp = 0; + + // Prevent being divided by zero + if (YRes == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbCalcCustomizedTiming: fata error -- YRes is ZERO!!!\n")); + return ulRet; + } + ulTemp = XRes*100/YRes; + if((ulTemp<134)&&(ulTemp>132)) + { + ulRet = 4; + } + else if((ulTemp<178)&&(ulTemp>176)) + { + ulRet = 5; + } + else if((ulTemp<161)&&(ulTemp>159)) + { + ulRet = 6; + } + else if((ulTemp<126)&&(ulTemp>125)) + { + ulRet = 7; + } + else if((ulTemp<167)&&(ulTemp>165)) + { + ulRet = 7; + } + else + { + ulRet = 10; + } + return ulRet; +} + + +CBIOS_STATUS cbGetExtensionSize(CBIOS_U32 *pulExtensionSize) +{ + *pulExtensionSize = sizeof(CBIOS_EXTENSION_COMMON); + return CBIOS_OK; +} + + +CBIOS_STATUS cbGetVersion(PCBIOS_EXTENSION_COMMON pcbe, + PCBIOS_VERSION pCbiosVersion) +{ + // Big change such as structure modification + pCbiosVersion->MajorVersionNumber = CBIOS_TRNAS_VER(CBIOS_VERSION_MAJOR); + // Means Trunk driver. + pCbiosVersion->BranchDriverNumber = CBIOS_TRNAS_VER(CBIOS_VERSION_BRANCH); + // If add new feature, increase this version number + pCbiosVersion->MediumVersionNumber = CBIOS_TRNAS_VER(CBIOS_VERSION_FEATURE); + // For bug fixed only. Every release, increase this version number. + pCbiosVersion->MinorVersionNumber = CBIOS_TRNAS_VER(CBIOS_VERSION_MINOR); + + // Genery we directly return the value in pcbe except specific-chip CBIOS. + pCbiosVersion->ChipID = (CBIOS_U16)pcbe->ChipID; + pCbiosVersion->ChipRevID = (CBIOS_U16)pcbe->ChipRevision; + + return CBIOS_OK; +} + + +// Calculate the detailed timing according to the CVT algrithm +// Input X resolution, Y resolution, Refresh. +// Output the CBIOS_TIMING_ATTRIB stucture +CBIOS_BOOL cbCalcCustomizedTiming(PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_U32 XRes, + CBIOS_U32 YRes, + CBIOS_U32 RefreshRate, + PCBIOS_TIMING_ATTRIB pTiming) +{ + + CBIOS_U32 ReqestRefreshRate = RefreshRate; + CBIOS_U32 HorPixels = XRes; + CBIOS_U32 VerticalLines = YRes; + + // result variable + CBIOS_U32 HorTotal; // unit is pixels + CBIOS_U32 HorBlanking; + CBIOS_U32 HorFrontPorch; + CBIOS_U32 HorSync; + CBIOS_U32 HorBackPorch; + + CBIOS_U32 VerTotal; // unit is lines + CBIOS_U32 VerBlanking; + CBIOS_U32 VerFrontPorch; + //CBIOS_U32 VerBackPorch; + CBIOS_U32 VerticalSyncWidth; + + CBIOS_U32 HorFreq; // unit is kHz*100 + CBIOS_U32 ActualVerFreq; + CBIOS_U32 PixelClock; + + // middle temporary variable + CBIOS_U32 HPeriodEst; // unit is kHz + CBIOS_U32 VSyncBP; + CBIOS_U32 Temp; + CBIOS_U32 IdealDutyCycle; + + // For recuced blanking middle temopary variable. + + VerticalSyncWidth = cbGetVsyncWidth(pcbe, XRes, YRes); + + // For standard CRT timing calculation + // Estimate the horizontal period that is multiplied by 100 + // Prevent being divided by zero + if (ReqestRefreshRate == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, WARNING), "cbCalcCustomizedTiming: fata error -- ReqestRefreshRate is ZERO!!!\n")); + ReqestRefreshRate = 6000; + } + HPeriodEst = 100000000/ReqestRefreshRate - MINVBLANKINGPERIOD; + Temp = VerticalLines + MINVBPORCH; + HPeriodEst = cbRound(HPeriodEst*100,Temp, ROUND_NEAREST); + + // Find the number of lines in V sync + back porch + VSyncBP = cbRound(100*MINVBLANKINGPERIOD,HPeriodEst, ROUND_NEAREST)+1; + if(VSyncBP < (VerticalSyncWidth + MINVBPORCH)) + { + VSyncBP = VerticalSyncWidth + MINVBPORCH; + } + // Find the number of lines in V back porch + //VerBackPorch = VSyncBP - VerticalSyncWidth; + // Find the number of lines in V front porch + VerFrontPorch = MINVFPORCH; + // Find total number of lines in Vertical Field Period: + VerTotal = VerticalLines + VSyncBP + MINVFPORCH; + // Find the vertical blanking period + VerBlanking = VerTotal - VerticalLines; + // Find the ideal blanking duty cycle from the blanking duty cycle equation(%) + IdealDutyCycle = 100*CPRIME - MPRIME*HPeriodEst/1000; + + // Find the number of pixels in the horizontal blanking time to the nearest + // double character cell + if(IdealDutyCycle < 2000) + { + HorBlanking = HorPixels*2000; + HorBlanking = HorBlanking/(10000-2000); + HorBlanking = cbRound(HorBlanking,2*CELLGRAN, ROUND_NEAREST); + HorBlanking = HorBlanking*2*CELLGRAN; + } + else + { + HorBlanking = HorPixels*IdealDutyCycle; + // Prevent being divided by zero + if ((10000-IdealDutyCycle) == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbCalcCustomizedTiming: fata error -- (10000-IdealDutyCycle) is ZERO!!!\n")); + return CBIOS_FALSE; + } + HorBlanking = HorBlanking/(10000-IdealDutyCycle); + HorBlanking = cbRound(HorBlanking,2*CELLGRAN, ROUND_NEAREST); + HorBlanking = HorBlanking*2*CELLGRAN; + } + // Find the total number of pixels in a line + HorTotal = HorPixels + HorBlanking; + // Find the Horizontal Sync width, unit is character. + HorSync = cbRound(HorTotal*HSYNCPERCENT,CELLGRAN*100, ROUND_NEAREST); + // Convert the unit of H sync width to pixel unit + HorSync = HorSync*CELLGRAN; + // Find the Horizontal back porch + HorBackPorch = HorBlanking/2; + // Find the H front porch + HorFrontPorch = HorBlanking-HorSync-HorBackPorch; + + // Find pixel clock frequency(MHz) that was multiplied by 100) + PixelClock = cbRound(HorTotal*100*100,HPeriodEst, ROUND_NEAREST); + PixelClock = cbRound(PixelClock,CLOCKSTEP, ROUND_NEAREST); + PixelClock = PixelClock*CLOCKSTEP; + // Find actual Horizonal Frequency (kHz), that is multiplied by 100 + // Prevent being divided by zero + if (HorTotal == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbCalcCustomizedTiming: fata error -- HorTotal is ZERO!!!\n")); + return CBIOS_FALSE; + } + HorFreq = 1000*PixelClock/HorTotal; + // Find the actual refresh rate(Hz), that was multiplied by 100 + // Prevent being divided by zero + if (VerTotal == 0) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "cbCalcCustomizedTiming: fata error -- VerTotal is ZERO!!!\n")); + return CBIOS_FALSE; + } + ActualVerFreq = 1000*HorFreq/VerTotal; + + cb_memset(pTiming, 0, sizeof(CBIOS_TIMING_ATTRIB)); + // Fill in the timing structure + pTiming->XRes = (CBIOS_U16)HorPixels; + pTiming->YRes = (CBIOS_U16)VerticalLines; + pTiming->RefreshRate = (CBIOS_U16)ActualVerFreq; + pTiming->PixelClock = (CBIOS_U32)PixelClock*100; + pTiming->HVPolarity = VerPOSITIVE+HorNEGATIVE; + pTiming->HorTotal = (CBIOS_U16)HorTotal; + pTiming->HorDisEnd = (CBIOS_U16)HorPixels; + pTiming->HorBStart = (CBIOS_U16)HorPixels; + pTiming->HorBEnd = (CBIOS_U16)HorTotal; + pTiming->HorSyncStart = (CBIOS_U16)(HorPixels+HorFrontPorch); + pTiming->HorSyncEnd = (CBIOS_U16)(HorPixels+HorFrontPorch+HorSync); + + pTiming->VerTotal = (CBIOS_U16)(VerTotal); + pTiming->VerDisEnd = (CBIOS_U16)(VerticalLines); + pTiming->VerBStart = (CBIOS_U16)(VerticalLines); + pTiming->VerBEnd = (CBIOS_U16)(VerticalLines+VerBlanking); + pTiming->VerSyncStart = (CBIOS_U16)(VerticalLines+VerFrontPorch); + pTiming->VerSyncEnd = (CBIOS_U16)(VerticalLines+VerFrontPorch+VerticalSyncWidth); + + return CBIOS_TRUE; +} + + +CBIOS_VOID cbConvertEdidTimingToTableTiming(CBIOS_IN PCBIOS_EXTENSION_COMMON pcbe, + CBIOS_IN CBIOS_MODE_INFO_EXT* pEDIDDetailTiming, + CBIOS_OUT PCBIOS_TIMING_ATTRIB pTiming) +{ + cb_memset(pTiming, 0, sizeof(CBIOS_TIMING_ATTRIB)); + + // Fill in the timing structure + pTiming->XRes = (CBIOS_U16)pEDIDDetailTiming->XResolution; + pTiming->YRes = (CBIOS_U16)pEDIDDetailTiming->YResolution; + pTiming->RefreshRate = (CBIOS_U16)pEDIDDetailTiming->Refreshrate; + pTiming->PixelClock = (CBIOS_U32)pEDIDDetailTiming->PixelClock; + pTiming->HVPolarity = pEDIDDetailTiming->HSync+pEDIDDetailTiming->VSync; + + pTiming->HorTotal = pEDIDDetailTiming->HActive+pEDIDDetailTiming->HBlank; + pTiming->HorDisEnd = pEDIDDetailTiming->HActive; + pTiming->HorBStart = pEDIDDetailTiming->HActive; + + pTiming->HorBEnd = pEDIDDetailTiming->HActive+pEDIDDetailTiming->HBlank; + + pTiming->HorSyncStart = pEDIDDetailTiming->HActive + pEDIDDetailTiming->HSyncOffset; + pTiming->HorSyncEnd = pEDIDDetailTiming->HActive + + pEDIDDetailTiming->HSyncOffset + + pEDIDDetailTiming->HSyncPulseWidth; + + pTiming->VerTotal = (CBIOS_U16)(pEDIDDetailTiming->VActive+pEDIDDetailTiming->VBlank); + pTiming->VerDisEnd = (CBIOS_U16)(pEDIDDetailTiming->VActive); + pTiming->VerBStart = (CBIOS_U16)(pEDIDDetailTiming->VActive); + pTiming->VerBEnd = (CBIOS_U16)(pEDIDDetailTiming->VActive+pEDIDDetailTiming->VBlank); + pTiming->VerSyncStart = (CBIOS_U16)(pEDIDDetailTiming->VActive+pEDIDDetailTiming->VSyncOffset); + pTiming->VerSyncEnd = (CBIOS_U16)(pTiming->VerSyncStart+pEDIDDetailTiming->VSyncPulseWidth); + + +} + +CBIOS_U32 cbConvertCBiosDevBit2VBiosDevBit(CBIOS_U32 CBiosDevices) +{ + CBIOS_U32 temp = 0; + + if(CBiosDevices & CBIOS_TYPE_CRT) + { + temp |= VBIOS_TYPE_CRT; + } + + if(CBiosDevices & CBIOS_TYPE_DVO) + { + temp |= VBIOS_TYPE_DVO; + } + + if(CBiosDevices & CBIOS_TYPE_DUOVIEW) + { + temp |= VBIOS_TYPE_DUOVIEW; + } + + if(CBiosDevices & CBIOS_TYPE_DP1) + { + temp |= VBIOS_TYPE_DP1; + } + + if(CBiosDevices & CBIOS_TYPE_DP2) + { + temp |= VBIOS_TYPE_DP2; + } + + if(CBiosDevices & CBIOS_TYPE_DP3) + { + temp |= VBIOS_TYPE_DP3; + } + + if(CBiosDevices & CBIOS_TYPE_DP4) + { + temp |= VBIOS_TYPE_DP4; + } + + return temp; +} + +CBIOS_U32 cbConvertVBiosDevBit2CBiosDevBit(CBIOS_U32 VBiosDevices) +{ + CBIOS_U32 temp = 0; + + if(VBiosDevices & VBIOS_TYPE_CRT) + { + temp |= CBIOS_TYPE_CRT; + } + + if(VBiosDevices & VBIOS_TYPE_DVO) + { + temp |= CBIOS_TYPE_DVO; + } + + if(VBiosDevices & VBIOS_TYPE_DUOVIEW) + { + temp |= CBIOS_TYPE_DUOVIEW; + } + + if(VBiosDevices & VBIOS_TYPE_DP1) + { + temp |= CBIOS_TYPE_DP1; + } + + if(VBiosDevices & VBIOS_TYPE_DP2) + { + temp |= CBIOS_TYPE_DP2; + } + + if(VBiosDevices & VBIOS_TYPE_DP3) + { + temp |= CBIOS_TYPE_DP3; + } + + if(VBiosDevices & VBIOS_TYPE_DP4) + { + temp |= CBIOS_TYPE_DP4; + } + + return temp; +} + + + +// Function name: cbCalcRefreshRate +// Function description: calculate refresh rate from DClock and HActive, HBlank, VActive and VBlank +// Input: DClock -- (0, 65536) * 100; See detailed timing descriptor part of EDID spec. +// HActive, HBlank, VActive and VBlank -- (0, 65536) +CBIOS_U16 cbCalcRefreshRate(CBIOS_U32 PixelClock, CBIOS_U16 HActive, CBIOS_U16 HBlank, CBIOS_U16 VActive, CBIOS_U16 VBlank) +{ + CBIOS_U32 Temp = PixelClock; + + if (((HActive + HBlank) == 0) || + ((VActive + VBlank) == 0)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbCalcRefreshRate: fatal error, divisor is zero!\n")); + return 0; + } + else + { + Temp = (Temp * 100) / (HActive + HBlank); + Temp = (Temp * 100) / (VActive + VBlank); + } + + return (CBIOS_U16)Temp; +} + +CBIOS_U32 cbGetHwDacMode(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_FORMAT Format) +{ + CBIOS_U32 dwDacMode = 0; + + switch(Format) + { + case CBIOS_FMT_P8: + dwDacMode = 0; + break; + case CBIOS_FMT_R5G6B5: + case CBIOS_FMT_A1R5G5B5: + dwDacMode = 1; + break; + case CBIOS_FMT_A8R8G8B8: + case CBIOS_FMT_A8B8G8R8: + case CBIOS_FMT_X8R8G8B8: + case CBIOS_FMT_X8B8G8R8: + dwDacMode = 4; + break; + case CBIOS_FMT_A2R10G10B10: + case CBIOS_FMT_A2B10G10R10: + dwDacMode = 5; + break; + case CBIOS_FMT_CRYCBY422_16BIT: + case CBIOS_FMT_YCRYCB422_16BIT: + dwDacMode = 2; + break; + case CBIOS_FMT_CRYCBY422_32BIT: + case CBIOS_FMT_YCRYCB422_32BIT: + dwDacMode = 6; + break; + case CBIOS_FMT_YCBCR8888_32BIT: + case CBIOS_FMT_CRYCB8888_32BIT: + dwDacMode = 3; + break; + case CBIOS_FMT_YCBCR2101010_32BIT: + case CBIOS_FMT_CRYCB2101010_32BIT: + dwDacMode = 7; + break; + default: + dwDacMode = 4; + break; + } + + return dwDacMode; +} + +CBIOS_U32 cbGetHw3DVideoMode(CBIOS_3D_STRUCTURE VideoFormat) +{ + CBIOS_U32 Hw3DVideoMode = 0; + + switch(VideoFormat) + { + case FRAME_PACKING: + Hw3DVideoMode = 5; + break; + case L_DEPTH: + Hw3DVideoMode = 5; + break; + case L_DEPTH_GRAPHICS: + Hw3DVideoMode = 0; + break; + case LINE_ALTERNATIVE: + Hw3DVideoMode = 6; + break; + case SIDE_BY_SIDE_FULL: + Hw3DVideoMode = 7; + break; + case SIDE_BY_SIDE_HALF: + Hw3DVideoMode = 7; + break; + case TOP_AND_BOTTOM: + Hw3DVideoMode = 4; + break; + case FIELD_ALTERNATIVE: + Hw3DVideoMode = 0; + break; + default: + Hw3DVideoMode = 0; + break; + } + return Hw3DVideoMode; +} + +CBIOS_VOID cbGetStreamAttribute(PCBIOS_STREAM_ATTRIBUTE pStreamAttr) +{ + PCBIOS_SURFACE_ATTRIB pSurfaceAttr = pStreamAttr->pSurfaceAttr; + PCBIOS_WINDOW_PARA pSrcWindow = pStreamAttr->pSrcWinPara; + CBIOS_U32 startX = 0, startY = 0, dwBitCnt = 0;; + + if(pSurfaceAttr->SurfaceFmt == CBIOS_FMT_P8) + { + dwBitCnt = 8; + } + else if(pSurfaceAttr->SurfaceFmt & CBIOS_STREAM_16BPP_FMTS) + { + dwBitCnt = 16; + } + else + { + dwBitCnt = 32; + } + + if(pSrcWindow) //for flip with disable case, no srcWindow para + { + startX = pSrcWindow->Position & 0xFFFF; + startY = (pSrcWindow->Position >> 16) & 0xFFFF; + } + + pStreamAttr->dwStride = (pSurfaceAttr->Pitch)>>5; + + pStreamAttr->dwBaseOffset = startY * pSurfaceAttr->Pitch + startX * dwBitCnt/8; + pStreamAttr->PixelOffset = (pStreamAttr->dwBaseOffset & 0x1f)*8/dwBitCnt; + + pStreamAttr->dwBaseOffset &= ~0x1f; +} + +CBIOS_VOID cbMulti_Matrix_CSC(CBIOS_S64 Multi_A[][3],CBIOS_S64 Multi_B[][3],CBIOS_S64 Multi_C[][3]) +{ + CBIOS_U32 i,j,k; + CBIOS_S64 data; + + for(i=0; i < 3; i++) + { + for(j=0; j < 3; j++) + { + data = 0; + for(k = 0; k < 3; k++) + { + data += Multi_A[i][k] * Multi_B[k][j]; + } + Multi_C[i][j] = data; + } + } +} + +CBIOS_U32 cbTran_CSCm_to_coef_fx(CBIOS_S64 coefX) +{ + CBIOS_U32 Value = 0; + CBIOS_U32 flag = 0; + + if(coefX < 0) + { + flag = 1; + coefX = 0 - coefX; + } + + Value = coefX>>(CSC_TOTAL_MAXTRIX_SHIFT_BITS - 9); + + if(flag == 1) //get negative value's 2's complement + { + Value = (CBIOS_U32)(1<Contrast > CSC_MAX_CONTRAST * CSC_CONTRAST_MATRIX_EXPAND_TIMES) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"CSC Adjust illagal Constract value,!\n")); + return CBIOS_FALSE; + } + if(pAdajust->Saturation > CSC_MAX_SATURATION * CSC_SATURATION_MATRIX_EXPAND_TIMES) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"CSC Adjust illagal Saturation value,!\n")); + return CBIOS_FALSE; + } + if(pAdajust->Hue > CSC_MAX_HUE || pAdajust->Hue < CSC_MIN_HUE) //expand cosHue,not Hue itself. + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"CSC Adjust illagal Hue value %d,!\n",pAdajust->Hue)); + return CBIOS_FALSE; + } + //these Matrix is define by CSC spec. + //set Saturation Matrix,to make sure precision,expand CSC_SATURATION_MATRIX_EXPAND_TIMES times + STRm[0][0] = CSC_SATURATION_MATRIX_EXPAND_TIMES; + STRm[1][1] = pAdajust->Saturation; + STRm[2][2] = pAdajust->Saturation; + + // set Contrast Matrixs,to make sure precision,expand CSC_CONTRAST_MATRIX_EXPAND_TIMES times + CNTm[0][0] = pAdajust->Contrast; + CNTm[1][1] = pAdajust->Contrast; + CNTm[2][2] = pAdajust->Contrast; + + //set Hue Matrixs + //make sure precision,expand CSC_HUE_MATRIX_EXPAND_TIMES times + //map cos/sin (-180',180') to cos [0-360],then we can get cosX by cos[X+180]. X unit is degree + HUEm[0][0] = CSC_HUE_MATRIX_EXPAND_TIMES; + HUEm[1][1] = CSC_cos[pAdajust->Hue + 180]; + HUEm[1][2] = -CSC_sin[pAdajust->Hue + 180]; + HUEm[2][1] = CSC_sin[pAdajust->Hue + 180]; + HUEm[2][2] = CSC_cos[pAdajust->Hue + 180]; + + //Get ADJm = HUEm * STRm * CNTm + ADJm[0][0] = HUEm[0][0] * STRm[0][0] * CNTm[0][0]; + ADJm[1][1] = HUEm[1][1] * STRm[1][1] * CNTm[1][1]; + ADJm[1][2] = HUEm[1][2] * STRm[2][2] * CNTm[2][2]; + ADJm[2][1] = HUEm[2][1] * STRm[1][1] * CNTm[1][1]; + ADJm[2][2] = HUEm[2][2] * STRm[2][2] * CNTm[2][2]; + + // step 2,get CSCm + // construct hash value CscMode use 7*informat + outformat as hash formula + // then we can choose proper method to get CSC Matrixs directly. + CscMode = CSC_MODE_HASH_VALUE * informat + outformat; + + switch(CscMode) + { + case CSC_RGB_TO_RGB: + //RGB->RGB use ycbcr709 as intermediary to get CSCm + cbMulti_Matrix_CSC(ADJm,YCbCr709_fr_RGB,temp_matrix); + //here,to prevent spillage + for(i=0;i<3;i++) + { + for(j = 0 ;j<3 ;j++) + { + temp_matrix[i][j] = temp_matrix[i][j] >> CSC_YCBCR_RGB_MATRIX_SHIFT_BITS; + } + } + cbMulti_Matrix_CSC(RGB_fr_YCbCr709,temp_matrix,CSCm); + break; + case CSC_RGB_TO_YCBCR601: + cbMulti_Matrix_CSC(ADJm,YCbCr601_fr_RGB,CSCm); + break; + case CSC_RGB_TO_YCBCR709: + cbMulti_Matrix_CSC(ADJm,YCbCr709_fr_RGB,CSCm); + break; + case CSC_YCBCR601_TO_RGB: + cbMulti_Matrix_CSC(RGB_fr_YCbCr601,ADJm,CSCm); + break; + case CSC_YCBCR601_TO_YCBCR601: + cbMulti_Matrix_CSC(ADJm,Balance_Times_matrix,CSCm); + break; + case CSC_YCBCR601_TO_YCBCR709: + cbMulti_Matrix_CSC(YCbCr709_fr_YCbCr601,ADJm,CSCm); + cbMulti_Matrix_CSC(ADJm,YCbCr709_fr_YCbCr601,CSCm); + break; + case CSC_YCBCR709_TO_RGB: + cbMulti_Matrix_CSC(RGB_fr_YCbCr709,ADJm,CSCm); + break; + case CSC_YCBCR709_TO_YCBCR601: + cbMulti_Matrix_CSC(YCbCr601_fr_YCbCr709,ADJm,CSCm); + cbMulti_Matrix_CSC(ADJm,YCbCr601_fr_YCbCr709,CSCm); + break; + case CSC_YCBCR709_TO_YCBCR709: + cbMulti_Matrix_CSC(ADJm,Balance_Times_matrix,CSCm); + break; + default : + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"CSC don't support informat %d to outformat %d with Adjust yet!\n",informat,outformat)); + return CBIOS_FALSE; + break; + } + return CBIOS_TRUE; +} + +CBIOS_U32 cbGetHwColorKey(PCBIOS_OVERLAY_INFO pOverlayInfo, PCBIOS_U8 pKs, PCBIOS_U8 pKp) +{ + CBIOS_U32 dwKeyMode = 0; + switch(pOverlayInfo->KeyMode) + { + case CBIOS_WINDOW_KEY: + { + dwKeyMode = 0; + *pKs = pOverlayInfo->WindowKey.Kb; + *pKp = pOverlayInfo->WindowKey.Ka; + } + break; + case CBIOS_ALPHA_KEY: + { + dwKeyMode = (pOverlayInfo->AlphaKey.bAOverB)? 5 : 1; + *pKs = pOverlayInfo->AlphaKey.Kb; + *pKp = pOverlayInfo->AlphaKey.Ka; + } + break; + case CBIOS_COLOR_KEY: + { + dwKeyMode = (pOverlayInfo->ColorKey.bAOverB)? 6 : 2; + // Keep Kp1=0 and Ks1=8. + *pKs = (pOverlayInfo->ColorKey.bAOverB)? 0x00 : 0x08; + *pKp = (pOverlayInfo->ColorKey.bAOverB)? 0x08 : 0x00; + } + break; + case CBIOS_ALPHA_BLENDING: + { + dwKeyMode = (pOverlayInfo->AlphaBlending.bUseAAlpha)? 8 : 12; + *pKs = 0; + *pKp = 0; + } + break; + case CBIOS_CONSTANT_ALPHA: + { + dwKeyMode = 9; + *pKs = pOverlayInfo->ConstantAlphaBlending.ConstantAlpha & 0x0F; + *pKp = (pOverlayInfo->ConstantAlphaBlending.ConstantAlpha >> 4) & 0x0F; + } + break; + case CBIOS_CHROMA_KEY: + { + dwKeyMode = 7; + *pKs = 0; + *pKp = 0x08; + } + break; + case CBIOS_INVALID_KEYING_MODE: + break; + default: + break; + } + return dwKeyMode; +} + + +CBIOS_BOOL cbCECAllocateLogicalAddr(PCBIOS_VOID pvcbe, CBIOS_CEC_INDEX CECIndex) +{ + CBIOS_CEC_MESSAGE CECMessage; + CBIOS_U8 LogicalAddrTable[3] = {4, 8, 11}; + CBIOS_U8 i; + CBIOS_BOOL bGetLogicalAddr = CBIOS_FALSE; + CBIOS_U8 LogicalAddr = CEC_UNREGISTERED_DEVICE; + CBIOS_BOOL bStaus = CBIOS_FALSE; + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + + //try previous address first + if (pcbe->CECPara[CECIndex].LogicalAddr != CEC_UNREGISTERED_DEVICE) + { + cb_memset(&CECMessage, 0, sizeof(CBIOS_CEC_MESSAGE)); + CECMessage.SourceAddr = pcbe->CECPara[CECIndex].LogicalAddr; + CECMessage.DestAddr = pcbe->CECPara[CECIndex].LogicalAddr; + CECMessage.bBroadcast = CBIOS_FALSE; + CECMessage.RetryCnt = 5; + CECMessage.CmdLen = 0; + if (CBIOS_OK != cbHWCECTransmitMessage(pcbe, &CECMessage, CECIndex)) + { + bGetLogicalAddr = CBIOS_TRUE; + LogicalAddr = CECMessage.SourceAddr; + } + } + + + //polling logical address + if (!bGetLogicalAddr) + { + for (i = 0; i < sizeofarray(LogicalAddrTable); i++) + { + cb_memset(&CECMessage, 0, sizeof(CBIOS_CEC_MESSAGE)); + CECMessage.SourceAddr = LogicalAddrTable[i]; + CECMessage.DestAddr = LogicalAddrTable[i]; + CECMessage.bBroadcast = CBIOS_FALSE; + CECMessage.RetryCnt = 5; + CECMessage.CmdLen = 0; + if (CBIOS_OK != cbHWCECTransmitMessage(pcbe, &CECMessage, CECIndex)) + { + bGetLogicalAddr = CBIOS_TRUE; + LogicalAddr = CECMessage.SourceAddr; + break; + } + } + + } + if (bGetLogicalAddr) + { + //broadcast physical address + cb_memset(&CECMessage, 0, sizeof(CBIOS_CEC_MESSAGE)); + CECMessage.SourceAddr = LogicalAddr; + CECMessage.DestAddr = CEC_BROADCAST_ADDRESS; + CECMessage.bBroadcast = CBIOS_TRUE; + CECMessage.RetryCnt = 5; + CECMessage.CmdLen = 4; + //parameter 1: opcode + CECMessage.Command[0] = CEC_REPORT_PHYSCAL_ADDR; + //parameter 2-3: physical address MSB + CECMessage.Command[1] = (CBIOS_U8)((pcbe->CECPara[CECIndex].PhysicalAddr >> 8)& 0xFF); + CECMessage.Command[2] = (CBIOS_U8)(pcbe->CECPara[CECIndex].PhysicalAddr & 0xFF); + //parameter 4: device type + CECMessage.Command[3] = 4; //playback device + + if (CBIOS_OK == cbHWCECTransmitMessage(pcbe, &CECMessage, CECIndex)) + { + bStaus = CBIOS_TRUE; + + } + else + { + bStaus = CBIOS_FALSE; + } + + + } + + if (bStaus) + { + pcbe->CECPara[CECIndex].LogicalAddr = CECMessage.SourceAddr; + } + else + { + cbDebugPrint((MAKE_LEVEL(HDMI, ERROR), "cbCECAllocateLogicalAddr: allocate logical address fail!\n")); + pcbe->CECPara[CECIndex].LogicalAddr = CEC_UNREGISTERED_DEVICE; + } + + return bStaus; + + +} + + +//Convert Device Word to Device Index +CBIOS_U32 cbConvertDeviceBit2Index(CBIOS_U32 DeviceBit) +{ + CBIOS_U32 DevMask = 0x00000001; + CBIOS_U32 i; + + if(cbGetBitsNum(DeviceBit) != 1) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbConvertDeviceBit2Index: Device bit error!\n")); + ASSERT(CBIOS_FALSE); + } + + for(i=0; i>1)&0x55555555); + index = (index&0x33333333)+ ((index>>2)&0x33333333); + index = (index&0x0F0F0F0F)+ ((index>>4)&0x0F0F0F0F); + index = (index&0xFF) + ((index&0xFF00) >> 8) + ((index&0xFF0000) >> 16) + ((index&0xFF000000) >> 24); + return index; +} + + +CBIOS_VOID cbDumpBuffer(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U8 Buffer[], CBIOS_U32 ulLen) +{ + CBIOS_U32 i; + CBIOS_U8 ucChecksum = 0; + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG)," 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f\n\n")); + for (i = 0; (i + 1) * 16 <= ulLen; i++) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG),"%02x: %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x\n", i,\ + Buffer[i*16+0x00], Buffer[i*16+0x01], Buffer[i*16+0x02], Buffer[i*16+0x03],\ + Buffer[i*16+0x04], Buffer[i*16+0x05], Buffer[i*16+0x06], Buffer[i*16+0x07],\ + Buffer[i*16+0x08], Buffer[i*16+0x09], Buffer[i*16+0x0a], Buffer[i*16+0x0b],\ + Buffer[i*16+0x0c], Buffer[i*16+0x0d], Buffer[i*16+0x0e], Buffer[i*16+0x0f])); + } + + for (i = 0; i < ulLen; i++) + { + ucChecksum += Buffer[i]; + } + + cbDebugPrint((MAKE_LEVEL(GENERIC, DEBUG), "cbDumpBuffer: checksum == 0x%02x\n", ucChecksum)); +} + + +CBIOS_BOOL cbIsSameMonitor(CBIOS_U8 *pCurDeviceEDID, CBIOS_U8 *pMonitorID) +{ + CBIOS_BOOL bRet = CBIOS_FALSE; + + if ((pCurDeviceEDID == CBIOS_NULL) || (pMonitorID == CBIOS_NULL)) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR),"cbIsSameMonitor: Null pointer!\n" )); + ASSERT(CBIOS_FALSE); + bRet = CBIOS_FALSE; + return bRet; + } + + if (!cb_strncmp(&pCurDeviceEDID[MONITORIDINDEX], pMonitorID, MONITORIDLENGTH)) + { + bRet = CBIOS_TRUE; + } + else + { + bRet = CBIOS_FALSE; + } + + return bRet; +} + +static CBIOS_BOOL cbU8ToString(CBIOS_U8 Src, CBIOS_U8* buf) +{ + CBIOS_U8 hb; + CBIOS_U8 lb; + + hb=(Src&0xf0)>>4; + if( hb>=0 && hb<=9 ) + hb += 0x30; + else if( hb>=10 &&hb <=15 ) + hb = hb -10 + 'A'; + else + return CBIOS_FALSE; + + lb = Src&0x0f; + if( lb>=0 && lb<=9 ) + lb += 0x30; + else if( lb>=10 && lb<=15 ) + lb = lb - 10 + 'A'; + else + return CBIOS_FALSE; + + buf[0] = hb; + buf[1] = lb; + + return CBIOS_TRUE; +} + + +static CBIOS_BOOL cbHex2String(CBIOS_U8 *pSrc, CBIOS_U8* buf, CBIOS_U32 nL) +{ + CBIOS_U8 Str[2]; + CBIOS_U32 i = 0; + + for(i=0;i> 24), Str); + buf[i*10]= Str[0]; + buf[i*10+1]= Str[1]; + cbU8ToString((CBIOS_U8)( (pSrc[i]&0x00ff0000) >> 16), Str); + buf[i*10+2]= Str[0]; + buf[i*10+3]= Str[1]; + cbU8ToString((CBIOS_U8)( (pSrc[i]&0x0000ff00) >> 8), Str); + buf[i*10+4]= Str[0]; + buf[i*10+5]= Str[1]; + cbU8ToString((CBIOS_U8)( pSrc[i]&0x000000ff), Str); + buf[i*10+6]= Str[0]; + buf[i*10+7]= Str[1]; + buf[i*10+8] = ' '; + buf[i*10+9] = ' '; + + if(0 == (i+1)%4) + { + buf[i*10+9] = '\n'; + } + } + + buf[i*10-1] = '\0'; + + return CBIOS_TRUE; +} + +CBIOS_BOOL cbPrintU8String(CBIOS_U8 *Src,CBIOS_U32 Len,CBIOS_U16 Start) +{ + CBIOS_UCHAR Buf[72]; + CBIOS_U32 n = Len / 16; + CBIOS_U32 m = Len % 16; + CBIOS_U32 nL = 0; + + for(nL = 0;nL < n;nL++) + { + cb_memset(Buf,0,72); + cbHex2String(&Src[nL*16], Buf,16); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "[0x%04x]: %s\n",Start,Buf)); + Start += 16; + } + + if(m) + { + cb_memset(Buf,0,72); + cbHex2String(&Src[nL*16], Buf,m); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "[0x%04x]: %s\n",Start,Buf)); + } + + return CBIOS_TRUE; +} + +CBIOS_BOOL cbPrintU32String(CBIOS_U32 *Src,CBIOS_U32 Len,CBIOS_U16 Start) +{ + CBIOS_UCHAR Buf[56]; + CBIOS_U32 n = Len / 4; + CBIOS_U32 m = Len % 4; + CBIOS_U32 nL = 0; + + for(nL = 0;nL < n;nL++) + { + cb_memset(Buf,0,56); + cbHexDW2String(&Src[nL*4], Buf,4); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "[0x%04x]: %s\n",Start,Buf)); + Start += 16; + } + + if(m) + { + cb_memset(Buf,0,56); + cbHexDW2String(&Src[nL*4], Buf,m); + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "[0x%04x]: %s\n",Start,Buf)); + } + + return CBIOS_TRUE; +} + + +//-------------------------------------------------------------------------- +// cbDbgPrintNull +// This function do nothing but just return, for prevent driver +// pass null function pointer to CBIOS to use +//-------------------------------------------------------------------------- +CBIOS_VOID cbDbgPrintNull(CBIOS_U32 DebugPrintLevel, PCBIOS_CHAR DebugMessage, ...) +{ + return; +} + +CBIOS_BOOL cbGetFakeEdidFlag(PCBIOS_VOID pvcbe) +{ + PCBIOS_EXTENSION_COMMON pcbe = (PCBIOS_EXTENSION_COMMON)pvcbe; + CBIOS_U32 FakeEdidFlag = CBIOS_TRUE; + + if (cbGetPlatformConfigurationU32(pcbe, (CBIOS_UCHAR*)"fake_hdmi_edid", &FakeEdidFlag, 1)) + { + if ((FakeEdidFlag != 0) && (FakeEdidFlag != 1)) + { + FakeEdidFlag = CBIOS_TRUE; + cbDebugPrint((MAKE_LEVEL(GENERIC, ERROR), "Invalid fake edid flag, fake edid by default!\n")); + } + else + { + if(FakeEdidFlag) + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Use fake edid\n")); + } + else + { + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Don't use fake edid\n")); + } + } + } + else + { + FakeEdidFlag = CBIOS_TRUE; + cbDebugPrint((MAKE_LEVEL(GENERIC, INFO), "Can't get hdmi fake edid flag, fake edid by default\n")); + } + + return (FakeEdidFlag)? CBIOS_TRUE : CBIOS_FALSE; +} diff --git a/drivers/gpu/drm/arise/cbios/cbios.mk b/drivers/gpu/drm/arise/cbios/cbios.mk new file mode 100644 index 0000000000000..26c3ab960dcff --- /dev/null +++ b/drivers/gpu/drm/arise/cbios/cbios.mk @@ -0,0 +1,64 @@ + +ccflags-y += \ + -I$(GFGPU_FULL_PATH)/cbios \ + -I$(GFGPU_FULL_PATH)/cbios/Callback \ + -I$(GFGPU_FULL_PATH)/cbios/Device \ + -I$(GFGPU_FULL_PATH)/cbios/Device/Port \ + -I$(GFGPU_FULL_PATH)/cbios/Device/Monitor \ + -I$(GFGPU_FULL_PATH)/cbios/Device/Monitor/DSIPanel \ + -I$(GFGPU_FULL_PATH)/cbios/Device/Monitor/EDPPanel \ + -I$(GFGPU_FULL_PATH)/cbios/Display \ + -I$(GFGPU_FULL_PATH)/cbios/Init \ + -I$(GFGPU_FULL_PATH)/cbios/Util + +cbios-objs := \ + Interface/CBios.o \ + Callback/CBiosCallbacks.o \ + Init/CBiosInit.o \ + Util/CBiosUtil.o \ + Util/CBiosEDID.o \ + Display/CBiosDisplayManager.o \ + Display/CBiosPathManager.o \ + Display/CBiosMode.o \ + Device/CBiosShare.o \ + Device/CBiosDeviceShare.o \ + Device/CBiosDevice.o \ + Device/Port/CBiosCRT.o \ + Device/Port/CBiosDP.o \ + Device/Port/CBiosDSI.o \ + Device/Port/CBiosDVO.o \ + Device/Monitor/CBiosCRTMonitor.o \ + Device/Monitor/CBiosDPMonitor.o \ + Device/Monitor/CBiosHDMIMonitor.o \ + Device/Monitor/CBiosEDPPanel.o \ + Device/Monitor/EDPPanel/CBiosITN156.o \ + Device/Monitor/DSIPanel/CBiosDSIPanel.o \ + Device/Monitor/DSIPanel/CBiosHX8392A.o \ + Device/Monitor/DSIPanel/CBiosNT35595.o \ + Device/Monitor/DSIPanel/CBiosR63319.o \ + Device/Monitor/DSIPanel/CBiosR63417.o \ + Hw/CBiosChipFunc.o \ + Hw/HwInit/CBiosInitHw.o \ + Hw/HwCallback/CBiosCallbacksHw.o \ + Hw/HwInterface/CBiosHwInterface.o \ + Hw/HwUtil/CBiosI2C.o \ + Hw/HwUtil/CBiosUtilHw.o \ + Hw/Interrupt/CBiosISR.o \ + Hw/HwBlock/CBiosScaler.o \ + Hw/HwBlock/CBiosIGA_Timing.o \ + Hw/HwBlock/CBiosDIU_HDTV.o \ + Hw/HwBlock/CBiosDIU_HDAC.o \ + Hw/HwBlock/CBiosDIU_HDCP.o \ + Hw/HwBlock/CBiosDIU_HDMI.o \ + Hw/HwBlock/CBiosDIU_DP.o \ + Hw/HwBlock/CBiosDIU_CRT.o \ + Hw/HwBlock/CBiosDIU_DVO.o \ + Hw/HwBlock/CBiosDIU_VIP.o \ + Hw/HwBlock/CBiosDIU_CSC.o \ + Hw/HwBlock/CBiosDIU_VIP.o \ + Hw/HwBlock/CBiosPHY_DP.o \ + Hw/Arise/CBios_Arise.o \ + Hw/Arise/CBiosVCP_Arise.o + +$(PRO_DRIVER_NAME)-objs += $(addprefix cbios/, $(cbios-objs)) + diff --git a/drivers/gpu/drm/arise/core/Makefile b/drivers/gpu/drm/arise/core/Makefile new file mode 100644 index 0000000000000..8a17bf8c5e4f1 --- /dev/null +++ b/drivers/gpu/drm/arise/core/Makefile @@ -0,0 +1,65 @@ +ccflags-y += \ + -I${GFGPU_FULL_PATH}/core/include \ + -I${GFGPU_FULL_PATH}/core/context \ + -I${GFGPU_FULL_PATH}/core/global \ + -I${GFGPU_FULL_PATH}/core/powermgr \ + -I${GFGPU_FULL_PATH}/core/vidmm \ + -I${GFGPU_FULL_PATH}/core/vidsch \ + -I${GFGPU_FULL_PATH}/core/util \ + -I${GFGPU_FULL_PATH}/core/isr \ + -I${GFGPU_FULL_PATH}/core/perfevent \ + -I${GFGPU_FULL_PATH}/shared + +CORE_OBJ := kernel_interface.o + +UTIL_OBJ := \ + util/util.o \ + util/handle_manager.o \ + util/heap_manager.o \ + util/queue.o \ + util/ring_buffer.o + +VIDMM_OBJ := \ + vidmm/vidmm.o \ + vidmm/vidmm_allocate.o \ + vidmm/vidmm_paging.o \ + vidmm/vidmm_lock.o + +VIDSCH_OBJ := \ + vidsch/vidsch.o \ + vidsch/vidsch_task.o \ + vidsch/vidsch_submit.o \ + vidsch/vidsch_workerthread.o \ + vidsch/vidsch_render.o \ + vidsch/vidsch_sync.o \ + vidsch/vidsch_gating.o \ + vidsch/vidsch_daemon_thread.o + +PERF_EVENT_OBJ := \ + perfevent/perfevent.o + +GLOBAL_OBJ := global/global.o + +CONTEXT_OBJ := \ + context/context.o \ + context/di_context.o + +POWERMGR_OBJ := powermgr/powermgr.o + +core-objs := \ + $(UTIL_OBJ) \ + $(SHAREDAREA_OBJ) \ + $(GLOBAL_OBJ) \ + $(CONTEXT_OBJ) \ + $(POWERMGR_OBJ) \ + $(VIDMM_OBJ) \ + $(VIDSCH_OBJ) \ + $(SOFT_FLOAT_OBJ) \ + $(CORE_OBJ) \ + $(PERF_EVENT_OBJ) + +$(PRO_DRIVER_NAME)-objs += $(addprefix core/, $(core-objs)) + +ifeq ($(CHIP), E3k) + include $(GFGPU_FULL_PATH)/core/e3k/Makefile +endif diff --git a/drivers/gpu/drm/arise/core/context/context.c b/drivers/gpu/drm/arise/core/context/context.c new file mode 100644 index 0000000000000..5d147f9c856ad --- /dev/null +++ b/drivers/gpu/drm/arise/core/context/context.c @@ -0,0 +1,743 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "context.h" +#include "vidsch.h" +#include "vidmm.h" +#include "vidmmi.h" + +static unsigned long long gf_get_current_time(void) +{ + long time_sec = 0, time_usec = 0; + unsigned long long ts = 0; + + gf_getsecs(&time_sec, &time_usec); + + ts = time_sec * 1000 + gf_do_div(time_usec, 1000); + + return ts; +} + +gpu_device_t* cm_create_device(adapter_t *adapter, void *filp) +{ + gpu_device_t *device; + + device = gf_calloc(sizeof(gpu_device_t)); + + if(device == NULL) + { + gf_error("create gpu device: alloc memory failed!\n"); + return NULL; + } + + device->adapter = adapter; + device->filp = filp; + device->pid = gf_get_current_pid(); + device->tid = gf_get_current_tid(); + device->handle = add_handle(&adapter->hdl_mgr, HDL_TYPE_DEVICE, device); + device->lock = gf_create_mutex(); + device->sync_obj_count = gf_create_atomic(0); + + gf_get_current_pname(device->pname, GF_MAX_PNAME_LEN); + + list_init_head(&device->context_list); + list_init_head(&device->hwctx_list); + list_init_head(&device->sync_obj_list); + list_init_head(&device->allocation_open_instance_list); + list_init_head(&device->display_stream_list); + list_init_head(&device->di_context_list); + + cm_device_create_num_inc(device); + + /* add device to adapter device list */ + gf_mutex_lock(adapter->device_list_lock); + + list_add_tail(&device->list_node, &adapter->device_list); + + gf_mutex_unlock(adapter->device_list_lock); + + return device; +} + +void cm_destroy_device(adapter_t *adapter, gpu_device_t *device) +{ + gpu_context_t *context = NULL, *context_next; + hw_ctxbuf_t *hwctx = NULL, *hwctx_next; + di_context_t *dictx = NULL, *dictx_next; + + /* put destory_context first, since destroy context default need wait chip idle + * so no need call wait chip idle here. + */ + /* destroy exist context */ + list_for_each_entry_safe(context, context_next, &device->context_list, list_node) + { + cm_destroy_context(device, context); + } + + /* destroy exist hwctx */ + list_for_each_entry_safe(hwctx, hwctx_next, &device->hwctx_list, list_node) + { + cm_remove_hwctx_buffer(device, NULL, hwctx->index); + } + + /* destroy exist di_context */ + list_for_each_entry_safe(dictx, dictx_next, &device->di_context_list, list_node) + { + cm_destroy_di_context(device, dictx); + } + + /* destroy exist allocation */ + + /* NOTE: + * here can not use list_for_each_entry_safe, + * but always get node in head because destroy allocation, not only free itself + * but also try to free renamed allocation, so the list->next, maybe freed + * after destroy curr allocation. + */ +#if 0 + gf_assert(list_empty(&device->allocation_open_instance_list), "instance_list not empty"); + while(!list_empty(&device->allocation_open_instance_list)) + { + vidmm_destroy_allocatin_arg_t destroy = {0}; + + cm_allocation_open_instance_t *instance = list_entry(device->allocation_open_instance_list.next, + cm_allocation_open_instance_t, + list_node); + vidmm_allocation_t *allocation = instance->allocation; + + destroy.allocation_count = 1; + destroy.allocation_list = &allocation; + + //this allocation only be opened in current device, force destroy it + cm_device_lock_allocation(device, allocation); + allocation->ref_count = allocation->ref_count - instance->ref_cnt + 1; + cm_device_unlock_allocation(device, allocation); + + + + // reset allocation reference count to 1, so will delete this instance when destory allocation. + instance->ref_cnt = 1; + +#if 0 + /* if want trace user mode allocation leak pls open code, all allocation freed here is leak */ + gf_info("allocation:%x, open device:%x, create device:%x, perferred_segment:%x, size: %d. AT:%d\n", + allocation->handle, device->handle, allocation->device->handle, allocation->preferred_segment.value, + allocation->orig_size, allocation->at_type); +#endif + vidmm_destroy_allocation(device, &destroy); + } +#endif + + vidmm_destroy_defer_allocation(adapter); + + /* destroy exist sync_obj */ + vidsch_destroy_remained_sync_obj(device); + + /* remove device from adapter device list */ + gf_mutex_lock(adapter->device_list_lock); + + list_del(&device->list_node); + + gf_mutex_unlock(adapter->device_list_lock); + + cm_device_create_num_dec(device); + +} + +void cm_destroy_remained_device(adapter_t *adapter) +{ + gpu_device_t *device = NULL; + gpu_device_t *device_next = NULL; + + //destroy exist device when deinit adapter + list_for_each_entry_safe(device, device_next, &adapter->device_list, list_node) + { + cm_destroy_device(adapter, device); + } +} + +inline int cm_get_hw_ringbuffer_index(adapter_t *adapter, unsigned int node_ordinal) +{ + int i; + + for(i = 0; i < adapter->active_engine_count; i++) + { + if(adapter->engine_index_table[i].node_ordinal == node_ordinal) + { + break; + } + } + + gf_assert(i < adapter->active_engine_count, "i < adapter->active_engine_count"); + return i; +} + +void cm_reset_command_header(gpu_context_t *context) +{ +} + +gpu_context_t* cm_create_context(gpu_device_t *device, create_context_t *create_context, int is_kernel) +{ + gpu_context_t *context = gf_calloc(sizeof(gpu_context_t)); + + if(context == NULL) + { + gf_error("create gpu context fail: out of memory!\n"); + return NULL; + } + + context->device = device; + context->pid = gf_get_current_pid(); + context->tid = gf_get_current_tid(); + gf_get_current_pname(context->pname, GF_MAX_PNAME_LEN); + context->handle = add_handle(&device->adapter->hdl_mgr, HDL_TYPE_CONTEXT, context); + context->ref_cnt = gf_create_atomic(0); + context->engine_index = cm_get_hw_ringbuffer_index(device->adapter, create_context->node_ordinal); + context->is_kernel = is_kernel; + + context->context_ctrl = 1; + if(context->context_ctrl) + { + context->context_sema = gf_create_sema(CONTEXT_TASK_QUEUE_LENGTH); + } + + + cm_device_lock(device); + + list_add(&context->list_node, &device->context_list); + + cm_device_unlock(device); + + cm_reset_command_header(context); + + return context; +} + +void cm_wait_context_idle(gpu_context_t *context) +{ + adapter_t * adapter = context->device->adapter; + int times = 0, idle = FALSE; + + while(times++ < adapter->context_destroy_timeout) + { + if(gf_atomic_read(context->ref_cnt) != 0) + { + vidsch_release_completed_tasks(adapter, context->engine_index, NULL); + + gf_msleep(10); + } + else + { + idle = TRUE; + break; + } + } + + /* if not idle, seems something wrong, maybe sync wait a never returned value, set task dropped skip wait */ + if(!idle) + { + context->device->task_dropped = TRUE; + + for(times = 0; times < 1000; times++) + { + /* notify a INT_FENCE to let vidsch reschedule the task. since we + * set task_dropped here then, schedule will dropped the task not submitted + */ + vidsch_notify_interrupt(context->device->adapter, 0); + + gf_msleep(10); + + if(gf_atomic_read(context->ref_cnt) == 0) + { + idle = TRUE; + break; + } + } + + if(!idle) + { + vidsch_dump(NULL,adapter); + } + gf_assert(idle, "context not idle"); + } +} + + +void cm_destroy_context(gpu_device_t *device, gpu_context_t *context) +{ + cm_wait_context_idle(context); + + remove_handle(&device->adapter->hdl_mgr, context->handle); + if(context->context_ctrl) + { + gf_destroy_sema(context->context_sema); + } + + + cm_device_lock(device); + + list_del(&context->list_node); + + cm_device_unlock(device); + + context->device = NULL; + + gf_destroy_atomic(context->ref_cnt); + + gf_free(context); +} + +inline static unsigned int cmi_acquire_physical_context_index(adapter_t *adapter) +{ + unsigned char* context_mask = adapter->context_buffer_inuse; + unsigned int mask_num = 0xFFFF/8; + unsigned int i,j; + unsigned int physical_context_index = 0xFFFF;//no phys contex index, no using deferred context + + for( i=0; icontext_buffer_inuse[i] &= ~(1<adapter; + hw_ctxbuf_t *hw_ctx_buffer = gf_calloc(sizeof(hw_ctxbuf_t)); + + if(hw_ctx_buffer == NULL) + { + return E_OUTOFMEMORY; + } + + hw_ctx_buffer->index = hw_buf_index; + hw_ctx_buffer->phys_index = cmi_acquire_physical_context_index(adapter); + + cm_device_lock(device); + + list_add(&hw_ctx_buffer->list_node, &device->hwctx_list); + + cm_device_unlock(device); + + return S_OK; +} + +int cm_remove_hwctx_buffer(gpu_device_t *device, gpu_context_t *context, unsigned int hwctx_index) +{ + hw_ctxbuf_t *hw_ctx = NULL; + int status = E_FAIL; + + cm_device_lock(device); + + list_for_each_entry(hw_ctx, &device->hwctx_list, list_node) + { + if(hw_ctx->index == hwctx_index) + { + list_del(&hw_ctx->list_node); + + status = S_OK; + + break; + } + } + + cm_device_unlock(device); + + if(status == S_OK) + { + cmi_release_physical_context_index(device->adapter, hw_ctx->phys_index); + + gf_free(hw_ctx); + } + + return status; +} + +hw_ctxbuf_t *cm_get_hwctx_buffer(gpu_device_t *device, gpu_context_t *context, unsigned int hwctx_index) +{ + hw_ctxbuf_t *hw_ctx = NULL; + hw_ctxbuf_t *match_hwctx = NULL; + + if(hwctx_index == 0) + { + return &context->hw_ctx; + } + + cm_device_lock(device); + + list_for_each_entry(hw_ctx, &device->hwctx_list, list_node) + { + if(hw_ctx->index == hwctx_index) + { + match_hwctx = hw_ctx; + break; + } + } + + cm_device_unlock(device); + + return match_hwctx; +} + +int cm_save(adapter_t *adapter, int need_save_memory) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = NULL; + unsigned int idx, priority; + int i = 0; + int result = S_OK; + + unsigned int allocation_cnt = 0; + unsigned long long ts_enter = gf_get_current_time(); + unsigned long long ts_leave = 0; + + /* not add lock to protect device list here, since save only used in suspend, + * no multi-thread issue here + */ + for(i = 0; i < adapter->active_engine_count; i++) + { + vidsch_wait_engine_idle(adapter, i); + } + + for (idx = 1; idx < mm_mgr->segment_cnt; idx++) + { + segment = &mm_mgr->segment[idx]; + if (!segment->flags.require_system_pages) + { + vidmm_allocation_t *allocation = NULL; + + for (priority = PDISCARD; priority < PALL; priority++) + { + list_for_each_entry(allocation, &segment->pagable_resident_list[priority], list_item) + { + allocation_cnt++; + + result = vidmm_save_allocation(allocation->device, allocation); + if (result) + { + return result; + } + } + } + + list_for_each_entry(allocation, &segment->unpagable_resident_list, list_item) + { + allocation_cnt++; + + result = vidmm_save_allocation(allocation->device, allocation); + if (result) + { + return result; + } + } + } + } + + + ts_leave = gf_get_current_time(); + + gf_info("%s() total cost %llums, allocation_cnt-%d\n", __func__, ts_leave -ts_enter, allocation_cnt); + + return result; +} + +void cm_restore(adapter_t *adapter) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = NULL; + unsigned int idx, priority; + + unsigned int allocation_cnt = 0; + unsigned long long ts_enter = gf_get_current_time(); + unsigned long long ts_leave = 0; + + /* not add lock to protect device list here, since save only used in resume, + * no multi-thread issue here + */ + + if (adapter->suspend_blt_mode == 2) + { + /* TODO: remove this */ + gf_msleep(500); + gf_info("pending sleep finish\n"); + } + + for (idx = 1; idx < mm_mgr->segment_cnt; idx++) + { + segment = &mm_mgr->segment[idx]; + if (!segment->flags.require_system_pages) + { + vidmm_allocation_t *allocation = NULL; + + for (priority = PDISCARD; priority < PALL; priority++) + { + list_for_each_entry(allocation, &segment->pagable_resident_list[priority], list_item) + { + allocation_cnt++; + vidmm_restore_allocation(allocation->device, allocation); + } + } + + list_for_each_entry(allocation, &segment->unpagable_resident_list, list_item) + { + allocation_cnt++; + vidmm_restore_allocation(allocation->device, allocation); + } + } + } + + ts_leave = gf_get_current_time(); + + gf_info("%s() total cost %llums, allocation_cnt-%d\n", __func__, ts_leave -ts_enter, allocation_cnt); +} + +int cm_device_add_reference(gpu_device_t *device, struct _vidmm_allocation *allocation) +{ + cm_allocation_open_instance_t *instance = gf_calloc(sizeof(cm_allocation_open_instance_t)); + cm_allocation_open_instance_t *reference = NULL, *ite_instance = NULL; + + instance->allocation = allocation; + instance->device = device; + + cm_device_lock_allocation(device, allocation); + + list_for_each_entry(ite_instance, &allocation->device_ref_list, device_ref_node) + { + if(ite_instance->device == device) + { + reference = ite_instance; + break; + } + } + + if(reference != NULL) + { + reference->ref_cnt ++; + } + else + { + instance->ref_cnt = 1; + + list_add_tail(&instance->device_ref_node, &allocation->device_ref_list); + + list_add_tail(&instance->list_node, &device->allocation_open_instance_list); + } + + cm_device_unlock_allocation(device, allocation); + + if(reference != NULL) + { + gf_free(instance); + } + + return S_OK; + +} + +int cm_device_del_reference(gpu_device_t *device, struct _vidmm_allocation *allocation) +{ + cm_allocation_open_instance_t *instance = NULL, *reference = NULL; + + int result = E_FAIL; + + cm_device_lock_allocation(device, allocation); + + list_for_each_entry(instance, &allocation->device_ref_list, device_ref_node) + { + if(instance->device == device) + { + reference = instance; + + break; + } + } + + if(reference != NULL) + { + reference->ref_cnt--; + + if(reference->ref_cnt == 0) + { + list_del(&reference->list_node); + + list_del(&reference->device_ref_node); + } + else + { + reference = NULL; + } + + result = S_OK; + } + + cm_device_unlock_allocation(device, allocation); + + if(reference != NULL) + { + gf_free(reference); + } + + return result; +} + +void cm_device_create_num_inc(gpu_device_t *device) +{ + cm_device_lock(device); + + device->create_num++; + + cm_device_unlock(device); +} + +void cm_device_create_num_dec(gpu_device_t *device) +{ + int free_device = FALSE; + + cm_device_lock(device); + + device->create_num--; + + if(device->create_num == 0) + { + free_device = TRUE; + } + + cm_device_unlock(device); + + if(free_device) + { + gf_destroy_mutex(device->lock); + gf_destroy_atomic(device->sync_obj_count); + + remove_handle(&device->adapter->hdl_mgr, device->handle); + + gf_free(device); + } +} + +void cm_device_lock_allocation(gpu_device_t *device, struct _vidmm_allocation *allocation) +{ + cm_device_lock(device); + + gf_spin_lock(allocation->lock); +} + +void cm_device_unlock_allocation(gpu_device_t *device, struct _vidmm_allocation *allocation) +{ + gf_spin_unlock(allocation->lock); + + cm_device_unlock(device); +} + +void cm_dump_resource(adapter_t *adapter) +{ + gpu_device_t *device = NULL, *device_next; + gpu_context_t *context = NULL, *context_next; + + gf_info("-----------current device info & context info.------------------\n"); + + list_for_each_entry_safe(device, device_next, &adapter->device_list, list_node) + { + gf_info("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); + gf_info("**device: %x, pid: %ld, create tid: %ld, create allocation num: %4d, sync obj count %d.\n", + device->handle, device->pid, device->tid, device->create_num - 1, gf_atomic_read(device->sync_obj_count)); + + list_for_each_entry_safe(context, context_next, &device->context_list, list_node) + { + gf_info("context: %x, on engine: %d, tid: %ld, device: %x", context->handle, context->engine_index, context->tid, device->handle); + } + +#if 0 + gf_info("## device %x opened allocation list.\n", device->handle); + + list_for_each_entry_safe(instance, instance_next, &device->allocation_open_instance_list, list_node) + { + gf_info("allocation:%x, open device:%x, create device:%x\n", + instance->allocation->handle, device->handle, instance->allocation->device->handle); + } +#endif + gf_info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"); + } +} + +void cm_dump_device_alloctions(struct os_seq_file *seq_file, adapter_t *adapter, gpu_device_t *device) +{ + cm_allocation_open_instance_t *instance = NULL, *instance_next; + int i = 0; + int cnt = vidmm_get_segment_count(adapter); + + gf_seq_printf(seq_file, " pid dev client\n"); + gf_seq_printf(seq_file, " %10d %8x %s \n", device->pid, device->handle, device->pname); + + cm_device_lock(device); + + for(i = 0; i < cnt; i++) + { + unsigned int num=0, size=0; + gf_seq_printf(seq_file, "----------------------------------------------------------------------\n"); + list_for_each_entry_safe(instance, instance_next, &device->allocation_open_instance_list, list_node) + { + vidmm_allocation_t *allocation = instance->allocation; + + if(allocation->segment_id != i) + { + continue; + } + + gf_seq_printf(seq_file, "allo: %x, dev: %x, fmt: %8d-%8d-%d-%3d, W-H-P: %8d-%8d-%8d, size: %6dk, gvm: %llx, AT:0x%02x, status: %8x, ref_cnt: %d. pid: %d, tid: %d, proc: %s\n", + allocation->handle, allocation->device->handle, + allocation->hw_format, allocation->compress_format, allocation->flag.swizzled, allocation->bit_count, + allocation->width, allocation->height, allocation->pitch, + util_align(allocation->orig_size, util_max(allocation->alignment, adapter->os_page_size)) >> 10, + allocation->phys_addr, allocation->at_type, + allocation->status.temp_unpagable, instance->ref_cnt, + allocation->device->pid, allocation->device->tid, allocation->device->pname); + + num++; + size += util_align(allocation->orig_size, util_max(allocation->alignment, adapter->os_page_size)); + } + + gf_seq_printf(seq_file, "\n"); + gf_seq_printf(seq_file, "heap%d allocation num:%.8d, total size %.8dk\n", i, num, size >> 10); + } + + gf_seq_printf(seq_file, "----------------------------------------------------------------------\n"); + + cm_device_unlock(device); +} + diff --git a/drivers/gpu/drm/arise/core/context/context.h b/drivers/gpu/drm/arise/core/context/context.h new file mode 100644 index 0000000000000..d215ebb50b429 --- /dev/null +++ b/drivers/gpu/drm/arise/core/context/context.h @@ -0,0 +1,198 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __CONTEXT_H__ +#define __CONTEXT_H__ +#include "core_import.h" +#include "util.h" +#include "list.h" + +#define USER_MODE_DMA_SIZE 64 * 1024 /* Set to 64KB to pass MaxContexts test */ +#define SYNCOBJECTLIST_SIZE 256 +#define ALLOCATIONLIST_SIZE (USER_MODE_DMA_SIZE / 64) * 4 /* Set to 2KB for every 64KB of command buffer to pass MaxContexts test */ +#define PATCHLOCATIONLIST_SIZE (USER_MODE_DMA_SIZE / 64) * 16 /* Set to 2KB for every 64KB of command buffer to pass MaxContexts test */ +#define MAX_SYNC_OBJECT_SIZE_PER_DEVICE 512*4 +#define CONTEXT_TASK_QUEUE_LENGTH 8 + +#ifdef GFX_ONLY_FPGA +#define CM_DESTROY_TIMEOUT 20000 +#else +#define CM_DESTROY_TIMEOUT 9000 +#endif + +#define CM_DESTROY_TIMEOUT_ON_QT 200000 + +typedef struct +{ + unsigned int node_ordinal; + unsigned int engine_affinity; + unsigned int flags; +}create_context_t; + +typedef struct hw_ctxbuf +{ + struct list_head list_node; + + int index; + int phys_index;//global context index, adapter function region + int is_initialized; + int is_invalid; + + unsigned long long context_buffer_address; + unsigned int *context_buffer; +}hw_ctxbuf_t; + +typedef struct gpu_device gpu_device_t; + +#define GF_MAX_PNAME_LEN 64 +typedef struct gpu_context +{ + struct list_head list_node; + char pname[GF_MAX_PNAME_LEN]; + + unsigned int handle; + int engine_index; + gpu_device_t *device; + unsigned long pid; + unsigned long tid; + + unsigned long long task_id; + unsigned long long last_submit_to_sw; + unsigned long long render_counter; + + unsigned long long wait_delta_check_start; //use for server wait timeout + unsigned long long wait_delta_check_end; + + int is_kernel; + unsigned int context_ctrl; + struct os_sema *context_sema; + + struct os_atomic *ref_cnt; //dma_ref_cnt + + /* for OGL context, one context can use multi-hwctx. + * OGL will explictly call add_hwctx to support multi-hwctx, + * for D3D context == hwctx, no need to add_hwctx, + * future will refine vpm code, let video go ogl way to intergate code + * and delete this per context hw_ctx. + * now this only for video client use, OGL use hwctx in device + */ + hw_ctxbuf_t hw_ctx; +}gpu_context_t; + +typedef struct __di_context +{ + struct list_head list_node; + + gpu_device_t *device; + + unsigned int handle; + + int hw_idx; + int stream_id; /* video stream id for debug */ +}di_context_t; + + + +struct gpu_device +{ + struct list_head list_node; + + adapter_t *adapter; + void *filp; + + unsigned int handle; + unsigned long pid; + unsigned long tid; + + char pname[GF_MAX_PNAME_LEN]; + + struct os_mutex *lock; + + /* resource used in this device */ + struct list_head context_list; + struct list_head hwctx_list; + struct list_head sync_obj_list; + struct list_head allocation_open_instance_list; + struct list_head display_stream_list; + struct list_head di_context_list; /* deinterlace hwctx list */ + + int create_num; // device create resource (device, context, hwctx, sync_obj, allocation) num + // since all resource use device ptr and device->lock so device struct and + // lock only can be free when this num = 0, note we also treat device itself as a num, + // when destroy_device called num--, then other resource destroy only can free struct after + // destroy deivce called when num-- lead num == 0. currently only for allocation, device + + int task_dropped; //if any context in this device dropped task. + //if so, need force set wait fence sync obj signal to avoid dead lock + //since fence obj signal cmd always put in gerneal dma task. + + struct os_atomic *sync_obj_count; //for limit sync object size per device + unsigned char video_seq_index[16]; + unsigned char video_core_index_cnt[2]; +}; + + +typedef struct +{ + struct list_head list_node; //allocation mode link in device->allocation_open_instance_list + struct list_head device_ref_node; //ref device node linked in allocation->device_ref_list; + gpu_device_t *device; //reference device, which device reference this allocation, or which device call this open. + struct _vidmm_allocation *allocation; + unsigned int ref_cnt; //record how many times this device open this allocation. +}cm_allocation_open_instance_t; + +static inline void cm_device_lock(gpu_device_t *device) +{ + gf_mutex_lock(device->lock); +} + +static inline void cm_device_unlock(gpu_device_t *device) +{ + gf_mutex_unlock(device->lock); +} + +extern gpu_device_t* cm_create_device(adapter_t *adapter, void *process_context); +extern void cm_destroy_device(adapter_t *adapter, gpu_device_t *device); +extern void cm_destroy_remained_device(adapter_t *adapter); +extern gpu_context_t* cm_create_context(gpu_device_t *device, create_context_t *create_context, int is_kernel); +extern void cm_destroy_context(gpu_device_t *device, gpu_context_t *context); +extern void cm_wait_context_idle(gpu_context_t *context); +extern int cm_add_hwctx_buffer(gpu_device_t *device, gpu_context_t *context, unsigned int hw_buf_index); +extern int cm_remove_hwctx_buffer(gpu_device_t *device, gpu_context_t *context, unsigned int hw_buf_index); +extern hw_ctxbuf_t *cm_get_hwctx_buffer(gpu_device_t *device, gpu_context_t *context, unsigned int index); + +extern void cm_reset_command_header(gpu_context_t *context); + +extern int cm_create_di_mgr(adapter_t *adapter); +extern void cm_destroy_di_mgr(adapter_t *adapter); + +extern di_context_t *cm_create_di_context(gpu_device_t *device, gf_create_di_context_t *create); +extern void cm_destroy_di_context(gpu_device_t *device, di_context_t *context); + +extern int cm_save(adapter_t *adapter, int need_save_memory); +extern void cm_restore(adapter_t *adapter); + +extern int cm_device_add_reference(gpu_device_t *device, struct _vidmm_allocation *allocation); +extern int cm_device_del_reference(gpu_device_t *device, struct _vidmm_allocation *allocation); + +extern void cm_device_lock_allocation(gpu_device_t *device, struct _vidmm_allocation *allocation); +extern void cm_device_unlock_allocation(gpu_device_t *device, struct _vidmm_allocation *allocation); + +extern void cm_device_create_num_inc(gpu_device_t *device); +extern void cm_device_create_num_dec(gpu_device_t *device); + +extern void cm_dump_resource(adapter_t *adapter); +extern void cm_dump_device_alloctions(struct os_seq_file *seq_file, adapter_t *adapter, gpu_device_t *device); +#endif + diff --git a/drivers/gpu/drm/arise/core/context/di_context.c b/drivers/gpu/drm/arise/core/context/di_context.c new file mode 100644 index 0000000000000..ef6620c943432 --- /dev/null +++ b/drivers/gpu/drm/arise/core/context/di_context.c @@ -0,0 +1,147 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "context.h" + +struct di_mgr +{ + adapter_t *adapter; + + struct os_spinlock *lock; + + unsigned int ctx_bitmap; + unsigned int free_start; + + unsigned int max_ctx; + unsigned int ctx_inuse_num; /* for debug*/ +}; + + +/* deinterlace dev manager */ + +int cm_create_di_mgr(adapter_t *adapter) +{ + struct di_mgr *dmgr = NULL; + + if(adapter->dmgr != NULL) return S_OK; + + dmgr = gf_calloc(sizeof(struct di_mgr)); + + dmgr->adapter = adapter; + dmgr->lock = gf_create_spinlock(0); + dmgr->ctx_bitmap = 0x0; + + dmgr->ctx_inuse_num = 0; + dmgr->max_ctx = 4; // Elite2000 VPP Di: fd_index max number + dmgr->free_start = 0; + + adapter->dmgr = dmgr; + + return S_OK; +} + +void cm_destroy_di_mgr(adapter_t *adapter) +{ + struct di_mgr *dmgr = adapter->dmgr; + + if(dmgr == NULL) return; + + adapter->dmgr = NULL; + + dmgr->ctx_bitmap = 0xFFFFFFFF; + dmgr->max_ctx = 0; + + if(dmgr->lock != NULL) + { + gf_destroy_spinlock(dmgr->lock); + + dmgr->lock = NULL; + } + + gf_free(dmgr); +} + +di_context_t *cm_create_di_context(gpu_device_t *device, gf_create_di_context_t *create) +{ + adapter_t *adapter = device->adapter; + struct di_mgr *dmgr = adapter->dmgr; + di_context_t *context = NULL; + + int idx = 0; + + gf_spin_lock(dmgr->lock); + + idx = gf_find_next_zero_bit(&dmgr->ctx_bitmap, dmgr->max_ctx, dmgr->free_start); + + if(idx < dmgr->max_ctx) + { + gf_set_bit(idx, &dmgr->ctx_bitmap); + dmgr->free_start = (idx + 1) % dmgr->max_ctx; + } + + gf_spin_unlock(dmgr->lock); + + if(idx < dmgr->max_ctx) + { + context = gf_calloc(sizeof(di_context_t)); + + context->device = device; + context->hw_idx = idx; + context->handle = add_handle(&adapter->hdl_mgr, HDL_TYPE_DI_CONTEXT, context); + context->stream_id = create->stream_id; + + //gf_info("create DI: :%x, idx: %d.\n", context->handle, context->hw_idx); + + cm_device_lock(device); + + list_add(&context->list_node, &device->di_context_list); + + cm_device_unlock(device); + } + + return context; +} + +void cm_destroy_di_context(gpu_device_t *device, di_context_t *context) +{ + adapter_t *adapter = device->adapter; + struct di_mgr *dmgr = adapter->dmgr; + + if(context->hw_idx < dmgr->max_ctx) + { + gf_spin_lock(dmgr->lock); + + gf_clear_bit(context->hw_idx, &dmgr->ctx_bitmap); + + dmgr->ctx_inuse_num--; + + gf_spin_unlock(dmgr->lock); + } + + //gf_info("destroy DI: :%x, idx: %d.\n", context->handle, context->hw_idx); + + remove_handle(&adapter->hdl_mgr, context->handle); + + cm_device_lock(device); + + list_del(&context->list_node); + + cm_device_unlock(device); + + gf_free(context); +} + + diff --git a/drivers/gpu/drm/arise/core/e3k/Makefile b/drivers/gpu/drm/arise/core/e3k/Makefile new file mode 100644 index 0000000000000..86b00c06997b7 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/Makefile @@ -0,0 +1,38 @@ +# +# Makefile for GF kernel driver +# + +ccflags-y += \ + -I$(GFGPU_FULL_PATH)/core/e3k/include + +VIDMM_OBJ := \ + vidmm/vidmm_allocate_e3k.o \ + vidmm/vidmm_build_page_buffer_e3k.o \ + vidmm/vidmm_e3k.o \ + vidmm/vidmm_gart_table_e3k.o \ + +VIDSCH_OBJ := \ + vidsch/vidsch_setup_e3k.o \ + vidsch/vidsch_patch_e3k.o \ + vidsch/vidsch_render_e3k.o \ + vidsch/vidsch_blt_e3k.o \ + vidsch/vidsch_engine_submit_e3k.o \ + vidsch/vidsch_engine_setup_e3k.o \ + vidsch/ContextSwitch_e3k.o \ + vidsch/vidsch_debug_hang_e3k.o \ + vidsch/vidsch_debug_hang_compatible_e3k.o \ + vidsch/vidsch_dfs_e3k.o + +PERFEVENT_OBJ := \ + perfevent/perfevent_e3k.o + +GLOBAL_OBJ := \ + global/global_e3k.o + +core_e3k-objs := \ + $(VIDMM_OBJ) \ + $(VIDSCH_OBJ) \ + $(PERFEVENT_OBJ) \ + $(GLOBAL_OBJ) + +$(PRO_DRIVER_NAME)-objs += $(addprefix core/e3k/, $(core_e3k-objs)) diff --git a/drivers/gpu/drm/arise/core/e3k/global/global_e3k.c b/drivers/gpu/drm/arise/core/e3k/global/global_e3k.c new file mode 100644 index 0000000000000..f2d153f59116e --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/global/global_e3k.c @@ -0,0 +1,28 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "register_e3k.h" + +void glb_init_chip_interface(adapter_t *adapter) +{ + write_reg_e3k(adapter->mmio, CR_C, 0x01, 0xFF, 0x00); //ensure power on + gf_info("init engine power status: 0x%x\n", read_reg_e3k(adapter->mmio, CR_C, 0x01)); +} + +void glb_init_power_caps(adapter_t *adapter) +{ + gf_warning("%s(): is blank, maybe implemented in other function()\n", util_remove_name_suffix(__func__)); +} diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/BlockID.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/BlockID.h new file mode 100644 index 0000000000000..f86f6f046166a --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/BlockID.h @@ -0,0 +1,262 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _REGISTER_BLOCKID_H +#define _REGISTER_BLOCKID_H + + + +#ifndef CSP_GLOBAL_BLOCKBASE_INF + #define CSP_GLOBAL_BLOCKBASE_INF + #define BLOCK_CSP_GLOBAL_VERSION 1 + #define BLOCK_CSP_GLOBAL_TIMESTAMP "8/27/2018 4:50:23 PM" + #define CSP_GLOBAL_BLOCK 0x0 + #define CSP_GLOBAL_REG_START 0x0 + #define CSP_GLOBAL_REG_END 0x3C0 + #define CSP_GLOBAL_REG_LIMIT 0x3C0 +#endif + +#ifndef GPCPFE_BLOCKBASE_INF + #define GPCPFE_BLOCKBASE_INF + #define BLOCK_GPCPFE_VERSION 1 + #define BLOCK_GPCPFE_TIMESTAMP "2018/1/4 16:28:55" + #define GPCPFE_BLOCK 0x1 + #define GPCPFE_REG_START 0x0 + #define GPCPFE_REG_END 0x28 + #define GPCPFE_REG_LIMIT 0x28 +#endif + + +#ifndef SPIN_BLOCKBASE_INF + #define SPIN_BLOCKBASE_INF + #define BLOCK_SPIN_VERSION 1 + #define BLOCK_SPIN_TIMESTAMP "2017/9/27 15:04:28" + #define SPIN_BLOCK 0x2 + #define SPIN_REG_START 0x0 + #define SPIN_REG_END 0x8 + #define SPIN_REG_LIMIT 0x8 +#endif + +#ifndef EU_FS_BLOCKBASE_INF + #define EU_FS_BLOCKBASE_INF + #define BLOCK_EU_FS_VERSION 1 + #define BLOCK_EU_FS_TIMESTAMP "2018/8/27 15:59:05" + #define EU_FS_BLOCK 0x3 + #define EU_FS_REG_START 0x0 + #define EU_FS_REG_END 0x900 + #define EU_FS_REG_LIMIT 0xAC0 +#endif + +#ifndef TASFE_BLOCKBASE_INF + #define TASFE_BLOCKBASE_INF + #define BLOCK_TASFE_VERSION 1 + #define BLOCK_TASFE_TIMESTAMP "10/13/2017 10:19:20 AM" + #define TASFE_BLOCK 0x4 + #define TASFE_REG_START 0x0 + #define TASFE_REG_END 0xC0 + #define TASFE_REG_LIMIT 0xC0 +#endif + +#ifndef TASBE_BLOCKBASE_INF +#define TASBE_BLOCKBASE_INF +#define BLOCK_TASBE_VERSION 1 +#define BLOCK_TASBE_TIMESTAMP "10/13/2017 10:19:33 AM" +#define TASBE_BLOCK 0x5 +#define TASBE_REG_START 0x0 +#define TASBE_REG_END 0x8 +#define TASBE_REG_LIMIT 0x8 +#endif + + +#ifndef FF_BLOCKBASE_INF + #define FF_BLOCKBASE_INF + #define BLOCK_FF_VERSION 1 + #define BLOCK_FF_TIMESTAMP "2018/9/12 14:42:10" + #define FF_BLOCK 0x6 + #define FF_REG_START 0x0 + #define FF_REG_END 0xD0 + #define FF_REG_LIMIT 0xD0 +#endif + +#ifndef IU_BLOCKBASE_INF + #define IU_BLOCKBASE_INF + #define BLOCK_IU_VERSION 1 + #define BLOCK_IU_TIMESTAMP "2018/6/13 9:55:34" + #define IU_BLOCK 0x7 + #define IU_REG_START 0x0 + #define IU_REG_END 0x40 + #define IU_REG_LIMIT 0x40 +#endif + +#ifndef WLS_FE_BLOCKBASE_INF +#define WLS_FE_BLOCKBASE_INF +#define BLOCK_WLS_FE_VERSION 1 +#define BLOCK_WLS_FE_TIMESTAMP "2017-09-27 15:40:09" +#define WLS_FE_BLOCK 0x8 +#define WLS_FE_REG_START 0x0 +#define WLS_FE_REG_END 0x418 +#define WLS_FE_REG_LIMIT 0x418 +#endif + +#ifndef EU_PS_BLOCKBASE_INF + #define EU_PS_BLOCKBASE_INF + #define BLOCK_EU_PS_VERSION 1 + #define BLOCK_EU_PS_TIMESTAMP "2018/8/2 16:58:57" + #define EU_PS_BLOCK 0x9 + #define EU_PS_REG_START 0x0 + #define EU_PS_REG_END 0x900 + #define EU_PS_REG_LIMIT 0x900 +#endif + +#ifndef TUFE_BLOCKBASE_INF + #define TUFE_BLOCKBASE_INF + #define BLOCK_TUFE_VERSION 1 + #define BLOCK_TUFE_TIMESTAMP "2017-08-18 15:00:40" + #define TUFE_BLOCK 0xA + #define TUFE_REG_START 0x0 + #define TUFE_REG_END 0x580 + #define TUFE_REG_LIMIT 0x580 +#endif + +#ifndef L2_BLOCKBASE_INF +#define L2_BLOCKBASE_INF +#define BLOCK_L2_VERSION 1 +#define BLOCK_L2_TIMESTAMP "2017-08-17 15:47:22" +#define L2_BLOCK 0xB +#define L2_REG_START 0x0 +#define L2_REG_END 0x8 +#define L2_REG_LIMIT 0x0 +#endif + +#ifndef MXU_BLOCKBASE_INF +#define MXU_BLOCKBASE_INF +#define BLOCK_MXU_VERSION 1 +#define BLOCK_MXU_TIMESTAMP "2017-08-17 15:47:22" +#define MXU_BLOCK 0xC +#define MXU_REG_START 0x0 +#define MXU_REG_END 0xD +#define MXU_REG_LIMIT 0xD +#endif + + +#ifndef MCE_BLOCKBASE_INF + #define MCE_BLOCKBASE_INF + #define BLOCK_MCE_VERSION 1 + #define BLOCK_MCE_TIMESTAMP "2017/11/20 9:05:57" + #define MCE_BLOCK 0xD + #define MCE_REG_START 0x0 + #define MCE_REG_END 0x18 + #define MCE_REG_LIMIT 0x18 +#endif + +#ifndef EU_CS_BLOCKBASE_INF + #define EU_CS_BLOCKBASE_INF + #define BLOCK_EU_CS_VERSION 1 + #define BLOCK_EU_CS_TIMESTAMP "2018/8/2 16:58:57" + #define EU_CS_BLOCK 0xE + #define EU_CS_REG_START 0x0 + #define EU_CS_REG_END 0x900 + #define EU_CS_REG_LIMIT 0x900 +#endif + + + + + + + + + + + +#ifndef VPP_BLOCKBASE_INF +#define VPP_BLOCKBASE_INF +#define BLOCK_VPP_VERSION 1 +#define BLOCK_VPP_TIMESTAMP "2017-08-10 13:57:28" +#define VPP_BLOCK 0x10 +#define VPP_REG_START 0x0 +#define VPP_REG_END 0x0 +#define VPP_REG_LIMIT 0x0 +#endif + +#ifndef ISP_BLOCKBASE_INF +#define ISP_BLOCKBASE_INF +#define BLOCK_ISP_VERSION 1 +#define BLOCK_ISP_TIMESTAMP "2017-08-10 13:57:28" +#define ISP_BLOCK 0x11 +#define ISP_REG_START 0x0 +#define ISP_REG_END 0x0 +#define ISP_REG_LIMIT 0x0 +#endif + +#ifndef MMU_BLOCKBASE_INF +#define MMU_BLOCKBASE_INF +#define BLOCK_MMU_VERSION 1 +#define BLOCK_MMU_TIMESTAMP "2017-08-17 16:42:23" +#define MMU_BLOCK 0x12 +#define MMU_REG_START 0x0 +#define MMU_REG_END 0x1000 +#define MMU_REG_LIMIT 0x1000 +#endif + +#ifndef WLS_BE_BLOCKBASE_INF + #define WLS_BE_BLOCKBASE_INF + #define BLOCK_WLS_BE_VERSION 1 + #define BLOCK_WLS_BE_TIMESTAMP "2017-08-31 12:06:11" + #define WLS_BE_BLOCK 0x13 + #define WLS_BE_REG_START 0x0 + #define WLS_BE_REG_END 0x418 + #define WLS_BE_REG_LIMIT 0x418 +#endif + +#ifndef TUBE_BLOCKBASE_INF + #define TUBE_BLOCKBASE_INF + #define BLOCK_TUBE_VERSION 1 + #define BLOCK_TUBE_TIMESTAMP "2017-08-17 16:42:23" + #define TUBE_BLOCK 0x14 + #define TUBE_REG_START 0x0 + #define TUBE_REG_END 0x580 + #define TUBE_REG_LIMIT 0x580 +#endif + +#ifndef GPCPBE_BLOCKBASE_INF + #define GPCPBE_BLOCKBASE_INF + #define BLOCK_GPCPBE_VERSION 1 + #define BLOCK_GPCPBE_TIMESTAMP "2018/5/4 10:06:54" + #define GPCPBE_BLOCK 0x15 + #define GPCPBE_REG_START 0x0 + #define GPCPBE_REG_END 0x1C8 + #define GPCPBE_REG_LIMIT 0x1C8 +#endif + + +#ifndef SPOUT_BLOCKBASE_INF + #define SPOUT_BLOCKBASE_INF + #define BLOCK_SPOUT_VERSION 1 + #define BLOCK_SPOUT_TIMESTAMP "2017/12/8 16:13:49" + #define SPOUT_BLOCK 0x16 + #define SPOUT_REG_START 0x0 + #define SPOUT_REG_END 0x20 + #define SPOUT_REG_LIMIT 0x20 +#endif + +typedef struct _TimeStampTable_Struct +{ + char BlockName[96]; + char TimeStamp[96]; +} TimeStampTable_Struct; + +extern TimeStampTable_Struct TimeStampTable[]; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/CSP_GLOBAL_Register.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/CSP_GLOBAL_Register.h new file mode 100644 index 0000000000000..a992e7d98d3ea --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/CSP_GLOBAL_Register.h @@ -0,0 +1,1549 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _CSP_GLOBAL_REGISTER_H +#define _CSP_GLOBAL_REGISTER_H + + +#ifndef CSP_GLOBAL_BLOCKBASE_INF + #define CSP_GLOBAL_BLOCKBASE_INF + #define BLOCK_CSP_GLOBAL_VERSION 1 + #define BLOCK_CSP_GLOBAL_TIMESTAMP "11/1/2018 1:59:10 PM" + #define CSP_GLOBAL_BLOCK 0x0 + #define CSP_GLOBAL_REG_START 0x0 + #define CSP_GLOBAL_REG_END 0x380 + #define CSP_GLOBAL_REG_LIMIT 0x380 +#endif + + +#define Reg_Block_Busy_Bits_Top_Offset 0x0 +#define Reg_Block_Busy_Bits_Gpc0_0_Offset 0x1 +#define Reg_Block_Busy_Bits_Gpc0_1_Offset 0x2 +#define Reg_Block_Busy_Bits_Gpc1_0_Offset 0x3 +#define Reg_Block_Busy_Bits_Gpc1_1_Offset 0x4 +#define Reg_Block_Busy_Bits_Gpc2_0_Offset 0x5 +#define Reg_Block_Busy_Bits_Gpc2_1_Offset 0x6 +#define Reg_Ring_Buf_Offset 0x7 +#define Reg_Preempt_Cmd_Process_Offset 0x23 +#define Reg_Cpu_Set_Offset 0x24 +#define Reg_Fence_Mask_Offset 0x25 +#define Reg_Reserved_Dw_0_Offset 0x26 +#define Reg_Pfb_Partition_3d_Cfg_Offset 0x27 +#define Reg_Pfb_Partition_Cs_Cfg_Offset 0x28 +#define Reg_Csp_Ms_Total_Gpu_Timestamp_Offset 0x29 +#define Reg_Csp_Ms_Total_Busy_Time_Offset 0x2B +#define Reg_Csp_Ref_Total_Gpu_Timestamp_Offset_Arise1020 0x2d +#define Reg_Csp_Ms_Query_Occlusion_Offset 0x2D +#define Reg_Ia_Vertices_Cnt_Offset 0x2F +#define Reg_Ia_Primitives_Cnt_Offset 0x31 +#define Reg_Ia_Ogl_Cut_Flag_32_Offset 0x33 +#define Reg_Ia_Vb0_Offset_Offset 0x34 +#define Reg_Ia_Vb0_Stride_Offset 0x35 +#define Reg_Ia_Bufferfilledsize_Offset 0x36 +#define Reg_Ia_Batch_Cfg_Offset 0x37 +#define Reg_Predicate_Status_Offset 0x38 +#define Reg_Csp_Misc_Control_Offset 0x39 +#define Reg_Tbr_Render_Mode_Ctrl_Offset 0x3A +#define Reg_Tbr_Frametimestamp_Lth_Offset 0x3B +#define Reg_Tbr_Frametimestamp_Hth_Offset 0x3C +#define Reg_Tbr_Traffic_Th_Offset 0x3D +#define Reg_Tbr_Event_Count_Ref_Offset 0x3E +#define Reg_Descriptor_Base_Addr_Offset 0x3F +#define Reg_Csp_Fence_Counter_Offset 0x47 +#define Reg_Ila_Counters_Offset 0x57 +#define Reg_Gpc_Signature_Offset 0x7F +#define Reg_Sto_Signature_Offset 0xE5 +#define Reg_Csp_Slice_Status_Offset 0xED +#define Reg_Cur_L1_Dma_Cmd_Offset 0xEE +#define Reg_Cur_L2_Dma_Cmd_Offset 0xEF +#define Reg_Cur_3d_Rbuf_Cmd_Offset 0xF0 +#define Reg_Cur_3d_Hrbuf_Cmd_Offset 0xF1 +#define Reg_Cur_Csh_Rbuf_Cmd_Offset 0xF2 +#define Reg_Cur_Cs0_Rbuf_Cmd_Offset 0xF3 +#define Reg_Cur_Cs1_Rbuf_Cmd_Offset 0xF4 +#define Reg_Cur_Cs2_Rbuf_Cmd_Offset 0xF5 +#define Reg_Cur_Cs3_Rbuf_Cmd_Offset 0xF6 +#define Reg_C3d_Eng_Workload_Offset 0xF7 +#define Reg_C3d_Eng_Alu_Workload_Offset 0xF8 +#define Reg_C3d_Mem_Workload_Offset 0xF9 +#define Reg_Vpp_Workload_Offset 0xFA +#define Reg_Vcp0_Workload_Offset 0xFB +#define Reg_Vcp1_Workload_Offset 0xFC +#define Reg_Vcp_Ring_Buf_Offset 0x180 +#define Reg_Vpp_Ring_Buf_Offset 0x188 +#define Reg_Vcp_Vpp_Block_Busy_Bits_Offset 0x18C +#define Reg_Csp_Skip1_Offset 0x18D +#define Reg_Cmodel_Hl_Switch_Offset 0x1FF +#define Reg_Eu_Dbg_Reg_Offset 0x200 + +#define Reg_Pwr_Mgr_Cfg_En_Offset 0xFD +#define Reg_Pwr_Mgr_Wait_Cnt_Offset 0xFE +#define Reg_Pwr_Mgr_Status0_Offset 0xFF +#define Reg_Csp_Skip0_Offset 0x100 +#define Reg_Csp_ReadSlickMask_Offset 0x100 + +typedef enum +{ + CSP_MISC_CONTROL_PROVOKEMODE_FIRST_VTX = 0, + CSP_MISC_CONTROL_PROVOKEMODE_LAST_VTX = 1, +} CSP_MISC_CONTROL_PROVOKEMODE; +typedef enum +{ + CMODEL_HL_SWITCH_CMD_TYPE_NO_SWITCH = 0, + CMODEL_HL_SWITCH_CMD_TYPE_DIP = 1, + CMODEL_HL_SWITCH_CMD_TYPE_GP = 2, + CMODEL_HL_SWITCH_CMD_TYPE_FAST_CLEAR = 3, + CMODEL_HL_SWITCH_CMD_TYPE_BIT_BLT = 4, + CMODEL_HL_SWITCH_CMD_TYPE_IMAGE_TRANSFER= 5, + CMODEL_HL_SWITCH_CMD_TYPE_INDICATOR_OFF = 6, +} CMODEL_HL_SWITCH_CMD_TYPE; +typedef enum +{ + EU_DBG_CFG_EXEC_EN_DISABLED = 0, + + + EU_DBG_CFG_EXEC_EN_ENABLED = 1, + +} EU_DBG_CFG_EXEC_EN; +typedef enum +{ + EU_DBG_CFG_TH_MODE_SINGLE = 0, + + EU_DBG_CFG_TH_MODE_ALL = 1, +} EU_DBG_CFG_TH_MODE; +typedef enum +{ + EU_DBG_CFG_INT_EN_DISABLED = 0, + + EU_DBG_CFG_INT_EN_ENABLED = 1, + + +} EU_DBG_CFG_INT_EN; +typedef enum +{ + EU_DBG_CFG_RES_EN_DISABLED = 0, + + EU_DBG_CFG_RES_EN_ENABLED = 1, + + +} EU_DBG_CFG_RES_EN; +typedef enum +{ + EU_DBG_BP_STAT_BP_HIT_DISABLED = 0, + + EU_DBG_BP_STAT_BP_HIT_ENABLED = 1, + + +} EU_DBG_BP_STAT_BP_HIT; +typedef enum +{ + EU_DBG_BP_PC_BP_VALID_DISABLED = 0, + EU_DBG_BP_PC_BP_VALID_ENABLED = 1, +} EU_DBG_BP_PC_BP_VALID; +typedef enum +{ + EU_DBG_BP_PC_SHADER_VS = 0, + EU_DBG_BP_PC_SHADER_HS = 1, + EU_DBG_BP_PC_SHADER_DS = 2, + EU_DBG_BP_PC_SHADER_GS = 3, + EU_DBG_BP_PC_SHADER_PS = 4, + EU_DBG_BP_PC_SHADER_CS = 5, +} EU_DBG_BP_PC_SHADER; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Csp_Busy : 1; + unsigned int Mxua_Busy : 1; + unsigned int Mxub_Busy : 1; + unsigned int L2_Busy : 1; + unsigned int Gpcpfe_Busy : 1; + unsigned int Gpcpbe_Busy : 1; + unsigned int Sg_Busy : 3; + unsigned int Tasfe_Busy : 3; + unsigned int Tasbe_Busy : 3; + unsigned int Hub_Busy : 3; + unsigned int Reserved : 14; + } reg; +} Reg_Block_Busy_Bits_Top; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Tgz_Busy : 4; + unsigned int Iu_Busy : 4; + unsigned int Wbu_Busy : 4; + unsigned int Wls_Busy : 4; + unsigned int Ffc_Busy : 4; + unsigned int Tu_Busy : 4; + unsigned int Reserved : 8; + } reg; +} Reg_Block_Busy_Bits_Gpc0_0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Eu_Constructor_Busy : 4; + unsigned int Euvs_Busy : 4; + unsigned int Euhs_Busy : 4; + unsigned int Eufe_Busy : 4; + unsigned int Euds_Busy : 4; + unsigned int Eugs_Busy : 4; + unsigned int Eups_Busy : 4; + unsigned int Eucs_Busy : 4; + } reg; +} Reg_Block_Busy_Bits_Gpc0_1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Tgz_Busy : 4; + unsigned int Iu_Busy : 4; + unsigned int Wbu_Busy : 4; + unsigned int Wls_Busy : 4; + unsigned int Ffc_Busy : 4; + unsigned int Tu_Busy : 4; + unsigned int Reserved : 8; + } reg; +} Reg_Block_Busy_Bits_Gpc1_0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Eu_Constructor_Busy : 4; + unsigned int Euvs_Busy : 4; + unsigned int Euhs_Busy : 4; + unsigned int Eufe_Busy : 4; + unsigned int Euds_Busy : 4; + unsigned int Eugs_Busy : 4; + unsigned int Eups_Busy : 4; + unsigned int Eucs_Busy : 4; + } reg; +} Reg_Block_Busy_Bits_Gpc1_1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Tgz_Busy : 4; + unsigned int Iu_Busy : 4; + unsigned int Wbu_Busy : 4; + unsigned int Wls_Busy : 4; + unsigned int Ffc_Busy : 4; + unsigned int Tu_Busy : 4; + unsigned int Reserved : 8; + } reg; +} Reg_Block_Busy_Bits_Gpc2_0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Eu_Constructor_Busy : 4; + unsigned int Euvs_Busy : 4; + unsigned int Euhs_Busy : 4; + unsigned int Eufe_Busy : 4; + unsigned int Euds_Busy : 4; + unsigned int Eugs_Busy : 4; + unsigned int Eups_Busy : 4; + unsigned int Eucs_Busy : 4; + } reg; +} Reg_Block_Busy_Bits_Gpc2_1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Addr : 28; + + unsigned int L2_Cachable : 1; + + + + + unsigned int Reserved : 2; + unsigned int Kickoff : 1; + } reg; +} Reg_Run_List_Ctx_Addr1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rb_Size : 32; + } reg; +} Reg_Ring_Buf_Size; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rb_Head : 32; + } reg; +} Reg_Ring_Buf_Head; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rb_Tail : 32; + } reg; +} Reg_Ring_Buf_Tail; + +typedef struct _Group_Ring_Buf +{ + Reg_Run_List_Ctx_Addr1 reg_Run_List_Ctx_Addr1; + Reg_Ring_Buf_Size reg_Ring_Buf_Size; + Reg_Ring_Buf_Head reg_Ring_Buf_Head; + Reg_Ring_Buf_Tail reg_Ring_Buf_Tail; +} Reg_Ring_Buf_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Preempt : 1; + + unsigned int Reserved : 31; + } reg; +} Reg_Preempt_Cmd_Process; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Cpu_Set : 1; + unsigned int Reserved : 31; + } reg; +} Reg_Cpu_Set; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Mask : 32; + + } reg; +} Reg_Fence_Mask; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reesrved : 32; + } reg; +} Reg_Reserved_Dw_0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Lrb_Size : 4; + + unsigned int L1dma_Size : 4; + unsigned int L2dma_Size : 4; + unsigned int L1buf_Size : 4; + unsigned int Lib_Size : 4; + unsigned int Hrb_Size : 4; + unsigned int Hl1buf_Size : 4; + unsigned int Hib_Size : 4; + } reg; +} Reg_Pfb_Partition_3d_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Csh_Rb_Size : 4; + unsigned int Csl0_Rb_Size : 4; + unsigned int Csl1_Rb_Size : 4; + unsigned int Csl2_Rb_Size : 4; + unsigned int Csl3_Rb_Size : 4; + unsigned int L1dma_Size : 4; + unsigned int L2dma_Size : 4; + unsigned int Csl_L1buf_Size : 4; + } reg; +} Reg_Pfb_Partition_Cs_Cfg; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Csp_Ms_Total_Gpu_Timestamp; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Csp_Ms_Total_Busy_Time; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Csp_Ms_Query_Occlusion; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Ia_Vertices_Cnt; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Ia_Primitives_Cnt; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ogl_Cut_Flag_32 : 32; + + } reg; +} Reg_Ia_Ogl_Cut_Flag_32; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Offset : 32; + } reg; +} Reg_Ia_Vb0_Offset; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Stride : 32; + } reg; +} Reg_Ia_Vb0_Stride; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Bufferfilledsize : 32; + } reg; +} Reg_Ia_Bufferfilledsize; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Batchprimnum : 32; + + + } reg; +} Reg_Ia_Batch_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Predicate_En : 1; + unsigned int Reserved : 31; + } reg; +} Reg_Predicate_Status; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Triangle_Cut_Index_Enable : 1; + + unsigned int Gs_On : 1; + unsigned int Ila_Mode : 4; + unsigned int Fe_Cnt_Disable : 1; + unsigned int Ila_Gpc_Sel : 2; + + unsigned int Provokemode : 1; + + unsigned int Dump_3d_Signature_Zero : 1; + + + unsigned int Flat_Quad : 1; + + unsigned int Reserved1 : 20; + } reg; +} Reg_Csp_Misc_Control; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Render_Mode_Switch_En : 1; + unsigned int Render_Mode : 1; + + unsigned int Render_Irq_Mode : 1; + + + + + unsigned int Event_Counter_Reset : 1; + + unsigned int Frame_Begin : 1; + unsigned int Frame_End : 1; + unsigned int Reserved1 : 10; + unsigned int Frame_Check_Window : 16; + + } reg; +} Reg_Tbr_Render_Mode_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Frametimestamp_Low_Threshold : 32; + + + + } reg; +} Reg_Tbr_Frametimestamp_Lth; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Frametimestamp_High_Threshold : 32; + + + + + } reg; +} Reg_Tbr_Frametimestamp_Hth; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Traffic_Threshold : 32; + + + + } reg; +} Reg_Tbr_Traffic_Th; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Tbr_Irq_Ref : 16; + + unsigned int Imr_Irq_Ref : 16; + + } reg; +} Reg_Tbr_Event_Count_Ref; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Base_Addr; + +typedef struct _Group_Descriptor_Base_Addr +{ + Reg_Base_Addr reg_Base_Addr; +} Reg_Descriptor_Base_Addr_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Counter0 : 16; + unsigned int Counter1 : 16; + } reg; +} Reg_Fence_Counter; + +typedef struct _Group_Csp_Fence_Counter +{ + Reg_Fence_Counter reg_Fence_Counter; +} Reg_Csp_Fence_Counter_Group; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Ila_Counters; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Sg_Sig_Low; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Sg_Sig_High; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_D_Sig_Low_S0; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_D_Sig_High_S0; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_D_Sig_Low_S1; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_D_Sig_High_S1; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_D_Sig_Low_S2; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_D_Sig_High_S2; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_D_Sig_Low_S3; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_D_Sig_High_S3; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Z_Sig_Low_S0; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Z_Sig_High_S0; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Z_Sig_Low_S1; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Z_Sig_High_S1; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Z_Sig_Low_S2; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Z_Sig_High_S2; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Z_Sig_Low_S3; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Z_Sig_High_S3; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_U_Sig_Low_S0; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_U_Sig_High_S0; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_U_Sig_Low_S1; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_U_Sig_High_S1; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_U_Sig_Low_S2; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_U_Sig_High_S2; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_U_Sig_Low_S3; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_U_Sig_High_S3; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Eu_Sig_Low_S0; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Eu_Sig_High_S0; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Eu_Sig_Low_S1; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Eu_Sig_High_S1; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Eu_Sig_Low_S2; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Eu_Sig_High_S2; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Eu_Sig_Low_S3; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Eu_Sig_High_S3; + +typedef struct _Group_Gpc_Signature +{ + Reg_Sg_Sig_Low reg_Sg_Sig_Low; + Reg_Sg_Sig_High reg_Sg_Sig_High; + Reg_D_Sig_Low_S0 reg_D_Sig_Low_S0; + Reg_D_Sig_High_S0 reg_D_Sig_High_S0; + Reg_D_Sig_Low_S1 reg_D_Sig_Low_S1; + Reg_D_Sig_High_S1 reg_D_Sig_High_S1; + Reg_D_Sig_Low_S2 reg_D_Sig_Low_S2; + Reg_D_Sig_High_S2 reg_D_Sig_High_S2; + Reg_D_Sig_Low_S3 reg_D_Sig_Low_S3; + Reg_D_Sig_High_S3 reg_D_Sig_High_S3; + Reg_Z_Sig_Low_S0 reg_Z_Sig_Low_S0; + Reg_Z_Sig_High_S0 reg_Z_Sig_High_S0; + Reg_Z_Sig_Low_S1 reg_Z_Sig_Low_S1; + Reg_Z_Sig_High_S1 reg_Z_Sig_High_S1; + Reg_Z_Sig_Low_S2 reg_Z_Sig_Low_S2; + Reg_Z_Sig_High_S2 reg_Z_Sig_High_S2; + Reg_Z_Sig_Low_S3 reg_Z_Sig_Low_S3; + Reg_Z_Sig_High_S3 reg_Z_Sig_High_S3; + Reg_U_Sig_Low_S0 reg_U_Sig_Low_S0; + Reg_U_Sig_High_S0 reg_U_Sig_High_S0; + Reg_U_Sig_Low_S1 reg_U_Sig_Low_S1; + Reg_U_Sig_High_S1 reg_U_Sig_High_S1; + Reg_U_Sig_Low_S2 reg_U_Sig_Low_S2; + Reg_U_Sig_High_S2 reg_U_Sig_High_S2; + Reg_U_Sig_Low_S3 reg_U_Sig_Low_S3; + Reg_U_Sig_High_S3 reg_U_Sig_High_S3; + Reg_Eu_Sig_Low_S0 reg_Eu_Sig_Low_S0; + Reg_Eu_Sig_High_S0 reg_Eu_Sig_High_S0; + Reg_Eu_Sig_Low_S1 reg_Eu_Sig_Low_S1; + Reg_Eu_Sig_High_S1 reg_Eu_Sig_High_S1; + Reg_Eu_Sig_Low_S2 reg_Eu_Sig_Low_S2; + Reg_Eu_Sig_High_S2 reg_Eu_Sig_High_S2; + Reg_Eu_Sig_Low_S3 reg_Eu_Sig_Low_S3; + Reg_Eu_Sig_High_S3 reg_Eu_Sig_High_S3; +} Reg_Gpc_Signature_Group; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Sto_Sig_Low; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Sto_Sig_High; + +typedef struct _Group_Sto_Signature +{ + Reg_Sto_Sig_Low reg_Sto_Sig_Low; + Reg_Sto_Sig_High reg_Sto_Sig_High; +} Reg_Sto_Signature_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Slice_Mask : 16; + unsigned int Reserved1 : 16; + } reg; +} Reg_Csp_Slice_Status; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Cur_L1_Dma_Cmd; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Cur_L2_Dma_Cmd; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Cur_3d_Rbuf_Cmd; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Cur_3d_Hrbuf_Cmd; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Cur_Csh_Rbuf_Cmd; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Cur_Cs0_Rbuf_Cmd; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Cur_Cs1_Rbuf_Cmd; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Cur_Cs2_Rbuf_Cmd; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Cur_Cs3_Rbuf_Cmd; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_C3d_Eng_Workload; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_C3d_Eng_Alu_Workload; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_C3d_Mem_Workload; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Vpp_Workload; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Vcp0_Workload; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Vcp1_Workload; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int En_Clkgate_3d : 1; + unsigned int En_Clkgate_Vcp : 1; + unsigned int En_Clkgate_Vpp : 1; + unsigned int Reserved : 24; + unsigned int Cg_Stable_Wait_Shift : 2; + unsigned int Cg_Th_Shift : 3; + } reg; +} Reg_Pwr_Mgr_Cfg_En; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Cg_Wait_Cnt_3d : 8; + unsigned int Cg_Wait_Cnt_Vcp : 8; + unsigned int Cg_Wait_Cnt_Vpp : 8; + unsigned int Cg_Stable_Wait_Cnt : 8; + } reg; +} Reg_Pwr_Mgr_Wait_Cnt; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Csp_Pwm_3d_Clken : 1; + unsigned int Csp_Pwm_Vcp_Clken : 1; + unsigned int Csp_Pwm_Vpp_Clken : 1; + unsigned int Reserved : 29; + } reg; +} Reg_Pwr_Mgr_Status0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Csp_Skip0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Addr : 28; + + unsigned int Reserved : 3; + unsigned int Kickoff : 1; + } reg; +} Reg_Vcp_Run_List_Ctx_Addr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rb_Size : 32; + } reg; +} Reg_Vcp_Ring_Buf_Size; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rb_Head : 32; + } reg; +} Reg_Vcp_Ring_Buf_Head; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rb_Tail : 32; + } reg; +} Reg_Vcp_Ring_Buf_Tail; + +typedef struct _Group_Vcp_Ring_Buf +{ + Reg_Vcp_Run_List_Ctx_Addr reg_Vcp_Run_List_Ctx_Addr; + Reg_Vcp_Ring_Buf_Size reg_Vcp_Ring_Buf_Size; + Reg_Vcp_Ring_Buf_Head reg_Vcp_Ring_Buf_Head; + Reg_Vcp_Ring_Buf_Tail reg_Vcp_Ring_Buf_Tail; +} Reg_Vcp_Ring_Buf_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Addr : 28; + + unsigned int Reserved : 3; + unsigned int Kickoff : 1; + } reg; +} Reg_Vpp_Run_List_Ctx_Addr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rb_Size : 32; + } reg; +} Reg_Vpp_Ring_Buf_Size; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rb_Head : 32; + } reg; +} Reg_Vpp_Ring_Buf_Head; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rb_Tail : 32; + } reg; +} Reg_Vpp_Ring_Buf_Tail; + +typedef struct _Group_Vpp_Ring_Buf +{ + Reg_Vpp_Run_List_Ctx_Addr reg_Vpp_Run_List_Ctx_Addr; + Reg_Vpp_Ring_Buf_Size reg_Vpp_Ring_Buf_Size; + Reg_Vpp_Ring_Buf_Head reg_Vpp_Ring_Buf_Head; + Reg_Vpp_Ring_Buf_Tail reg_Vpp_Ring_Buf_Tail; +} Reg_Vpp_Ring_Buf_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vcp0_Busy : 1; + unsigned int Vcp1_Busy : 1; + unsigned int Vpp_Busy : 1; + unsigned int Reserved : 29; + } reg; +} Reg_Vcp_Vpp_Block_Busy_Bits; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Csp_Skip1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Cmd_Type : 3; + unsigned int Cmd_Cnt : 5; + unsigned int Draw_Cnt : 5; + unsigned int Reserved : 19; + } reg; +} Reg_Cmodel_Hl_Switch; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Exec_En : 1; + unsigned int Th_Mode : 1; + unsigned int Int_En : 1; + unsigned int Res_En : 1; + unsigned int Dbg_Th_Id : 5; + + + unsigned int Reserved : 23; + } reg; +} Reg_Eu_Dbg_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Bp_Hit : 1; + + unsigned int Bp_Id : 3; + unsigned int Hit_Th_Id : 5; + + unsigned int Reserved : 23; + } reg; +} Reg_Eu_Dbg_Bp_Stat; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Bp_Valid : 1; + unsigned int Shader : 3; + unsigned int Offset : 16; + + + unsigned int Reserved : 12; + } reg; +} Reg_Eu_Dbg_Bp_Pc; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Offset : 16; + + unsigned int Reserved : 16; + } reg; +} Reg_Eu_Dbg_Int_Instr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Offset : 16; + + unsigned int Reserved : 16; + } reg; +} Reg_Eu_Dbg_Res_Instr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Value : 32; + + } reg; +} Reg_Eu_Dbg_Time_Stamp; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Eu_Dbg_Reversed; + +typedef struct _Group_Eu_Dbg_Reg +{ + Reg_Eu_Dbg_Cfg reg_Eu_Dbg_Cfg; + Reg_Eu_Dbg_Bp_Stat reg_Eu_Dbg_Bp_Stat; + Reg_Eu_Dbg_Bp_Pc reg_Eu_Dbg_Bp_Pc[8]; + Reg_Eu_Dbg_Int_Instr reg_Eu_Dbg_Int_Instr; + Reg_Eu_Dbg_Res_Instr reg_Eu_Dbg_Res_Instr; + Reg_Eu_Dbg_Time_Stamp reg_Eu_Dbg_Time_Stamp[2]; + Reg_Eu_Dbg_Reversed reg_Eu_Dbg_Reversed[2]; +} Reg_Eu_Dbg_Reg_Group; + +typedef struct _Csp_Global_regs +{ + Reg_Block_Busy_Bits_Top reg_Block_Busy_Bits_Top; + Reg_Block_Busy_Bits_Gpc0_0 reg_Block_Busy_Bits_Gpc0_0; + Reg_Block_Busy_Bits_Gpc0_1 reg_Block_Busy_Bits_Gpc0_1; + Reg_Block_Busy_Bits_Gpc1_0 reg_Block_Busy_Bits_Gpc1_0; + Reg_Block_Busy_Bits_Gpc1_1 reg_Block_Busy_Bits_Gpc1_1; + Reg_Block_Busy_Bits_Gpc2_0 reg_Block_Busy_Bits_Gpc2_0; + Reg_Block_Busy_Bits_Gpc2_1 reg_Block_Busy_Bits_Gpc2_1; + Reg_Ring_Buf_Group reg_Ring_Buf[7]; + Reg_Preempt_Cmd_Process reg_Preempt_Cmd_Process; + Reg_Cpu_Set reg_Cpu_Set; + Reg_Fence_Mask reg_Fence_Mask; + Reg_Reserved_Dw_0 reg_Reserved_Dw_0; + Reg_Pfb_Partition_3d_Cfg reg_Pfb_Partition_3d_Cfg; + Reg_Pfb_Partition_Cs_Cfg reg_Pfb_Partition_Cs_Cfg; + Reg_Csp_Ms_Total_Gpu_Timestamp reg_Csp_Ms_Total_Gpu_Timestamp[2]; + Reg_Csp_Ms_Total_Busy_Time reg_Csp_Ms_Total_Busy_Time[2]; + Reg_Csp_Ms_Query_Occlusion reg_Csp_Ms_Query_Occlusion[2]; + Reg_Ia_Vertices_Cnt reg_Ia_Vertices_Cnt[2]; + Reg_Ia_Primitives_Cnt reg_Ia_Primitives_Cnt[2]; + Reg_Ia_Ogl_Cut_Flag_32 reg_Ia_Ogl_Cut_Flag_32; + Reg_Ia_Vb0_Offset reg_Ia_Vb0_Offset; + Reg_Ia_Vb0_Stride reg_Ia_Vb0_Stride; + Reg_Ia_Bufferfilledsize reg_Ia_Bufferfilledsize; + Reg_Ia_Batch_Cfg reg_Ia_Batch_Cfg; + Reg_Predicate_Status reg_Predicate_Status; + Reg_Csp_Misc_Control reg_Csp_Misc_Control; + Reg_Tbr_Render_Mode_Ctrl reg_Tbr_Render_Mode_Ctrl; + Reg_Tbr_Frametimestamp_Lth reg_Tbr_Frametimestamp_Lth; + Reg_Tbr_Frametimestamp_Hth reg_Tbr_Frametimestamp_Hth; + Reg_Tbr_Traffic_Th reg_Tbr_Traffic_Th; + Reg_Tbr_Event_Count_Ref reg_Tbr_Event_Count_Ref; + Reg_Descriptor_Base_Addr_Group reg_Descriptor_Base_Addr[8]; + Reg_Csp_Fence_Counter_Group reg_Csp_Fence_Counter[16]; + Reg_Ila_Counters reg_Ila_Counters[40]; + Reg_Gpc_Signature_Group reg_Gpc_Signature[3]; + Reg_Sto_Signature_Group reg_Sto_Signature[4]; + Reg_Csp_Slice_Status reg_Csp_Slice_Status; + Reg_Cur_L1_Dma_Cmd reg_Cur_L1_Dma_Cmd; + Reg_Cur_L2_Dma_Cmd reg_Cur_L2_Dma_Cmd; + Reg_Cur_3d_Rbuf_Cmd reg_Cur_3d_Rbuf_Cmd; + Reg_Cur_3d_Hrbuf_Cmd reg_Cur_3d_Hrbuf_Cmd; + Reg_Cur_Csh_Rbuf_Cmd reg_Cur_Csh_Rbuf_Cmd; + Reg_Cur_Cs0_Rbuf_Cmd reg_Cur_Cs0_Rbuf_Cmd; + Reg_Cur_Cs1_Rbuf_Cmd reg_Cur_Cs1_Rbuf_Cmd; + Reg_Cur_Cs2_Rbuf_Cmd reg_Cur_Cs2_Rbuf_Cmd; + Reg_Cur_Cs3_Rbuf_Cmd reg_Cur_Cs3_Rbuf_Cmd; + Reg_C3d_Eng_Workload reg_C3d_Eng_Workload; + Reg_C3d_Eng_Alu_Workload reg_C3d_Eng_Alu_Workload; + Reg_C3d_Mem_Workload reg_C3d_Mem_Workload; + Reg_Vpp_Workload reg_Vpp_Workload; + Reg_Vcp0_Workload reg_Vcp0_Workload; + Reg_Vcp1_Workload reg_Vcp1_Workload; + Reg_Pwr_Mgr_Cfg_En reg_Pwr_Mgr_Cfg_En; + Reg_Pwr_Mgr_Wait_Cnt reg_Pwr_Mgr_Wait_Cnt; + Reg_Pwr_Mgr_Status0 reg_Pwr_Mgr_Status0; + Reg_Csp_Skip0 reg_Csp_Skip0[128]; + Reg_Vcp_Ring_Buf_Group reg_Vcp_Ring_Buf[2]; + Reg_Vpp_Ring_Buf_Group reg_Vpp_Ring_Buf; + Reg_Vcp_Vpp_Block_Busy_Bits reg_Vcp_Vpp_Block_Busy_Bits; + Reg_Csp_Skip1 reg_Csp_Skip1[114]; + Reg_Cmodel_Hl_Switch reg_Cmodel_Hl_Switch; + Reg_Eu_Dbg_Reg_Group reg_Eu_Dbg_Reg[24]; +} Csp_Global_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/CSP_OPCODE.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/CSP_OPCODE.h new file mode 100644 index 0000000000000..54120592f1c6b --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/CSP_OPCODE.h @@ -0,0 +1,1770 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _CSP_OPCODE_H +#define _CSP_OPCODE_H + +#ifndef COMMAND_OPCODES_BLOCKBASE_INF + #define COMMAND_OPCODES_BLOCKBASE_INF + #define BLOCK_COMMAND_OPCODES_VERSION 1 + #define BLOCK_COMMAND_OPCODES_TIMESTAMP "3/5/2019 6:26:53 PM" +#endif + + +#define CSP_OPCODE_Skip 0x0 +#define CSP_OPCODE_Dma 0x1 +#define CSP_OPCODE_Wait 0x2 +#define CSP_OPCODE_Query_Dump 0x3 + +#define CSP_OPCODE_Set_Register 0x4 + +#define CSP_OPCODE_Set_Object 0x6 +#define CSP_OPCODE_Dip 0x7 +#define CSP_OPCODE_Fence 0x8 + + + + +#define CSP_OPCODE_Block_Command_Template 0x9 + + +#define CSP_OPCODE_Block_Command_Tas 0x9 +#define CSP_OPCODE_Block_Command_Sg 0x9 +#define CSP_OPCODE_Block_Command_Img_Trn 0x9 +#define CSP_OPCODE_Block_Command_Flush 0x9 +#define CSP_OPCODE_Block_Command_Eu 0x9 +#define CSP_OPCODE_Block_Command_Tu 0x9 +#define CSP_OPCODE_Block_Command_L2 0x9 +#define CSP_OPCODE_Block_Command_Mxu 0x9 +#define CSP_OPCODE_Block_Command_Csp 0x9 +#define CSP_OPCODE_Blk_Cmd_Csp_Blc 0x9 +#define CSP_OPCODE_Blk_Cmd_Csp_Save_Rsto 0x9 +#define CSP_OPCODE_Blk_Cmd_Csp_Indicator 0x9 +#define CSP_OPCODE_Blk_Cmd_Csp_Ld_Des 0x9 +#define CSP_OPCODE_Block_Command_Video 0x9 +#define CSP_OPCODE_Gp 0xB + +#define CSP_OPCODE_Tbr_Indicator 0xF +#define CSP_OPCODE_Vpp 0xC + + + +typedef enum +{ + DMA_SPECIAL_DMA_TYPE_SAVE_REST_CMD = 0, + DMA_SPECIAL_DMA_TYPE_QUERY_SETREG_CMD = 1, +} DMA_SPECIAL_DMA_TYPE; +typedef enum +{ + DMA_MODE_NORMAL = 0, + DMA_MODE_SAVE = 1, + DMA_MODE_RESTORE = 2, + DMA_MODE_FLUSH = 3, +} DMA_MODE; +typedef enum +{ + WAIT_WAIT_MODE_NORMAL_WAIT = 0, + WAIT_WAIT_MODE_KKK_WAIT = 1, + WAIT_WAIT_MODE_WAIT_CHIP_IDLE = 2, + WAIT_WAIT_MODE_EXTERNAL_WAIT = 3, +} WAIT_WAIT_MODE; +typedef enum +{ + WAIT_METHOD_BIGEQUAL = 0, + WAIT_METHOD_EQUAL = 1, +} WAIT_METHOD; +typedef enum +{ + WAIT_STATION_ID_MAIN_PARSER = 0, + WAIT_STATION_ID_PRE_PARSER = 1, + +} WAIT_STATION_ID; +typedef enum +{ + QUERY_DUMP_ADDRESS_MODE_ADDRESS = 0, + + QUERY_DUMP_ADDRESS_MODE_OFFSET = 1, + + +} QUERY_DUMP_ADDRESS_MODE; +typedef enum +{ + QUERY_DUMP_CMD_TYPE_NORMAL_QUERY = 0, + QUERY_DUMP_CMD_TYPE_CPY_QRY_RES = 1, +} QUERY_DUMP_CMD_TYPE; +typedef enum +{ + QUERY_DUMP_BLOCK_ID_CSP = 0, + QUERY_DUMP_BLOCK_ID_GPCPFE = 1, + QUERY_DUMP_BLOCK_ID_SPIN = 2, + QUERY_DUMP_BLOCK_ID_EU_FS = 3, + QUERY_DUMP_BLOCK_ID_TAS_FE = 4, + QUERY_DUMP_BLOCK_ID_TAS_BE = 5, + QUERY_DUMP_BLOCK_ID_FF = 6, + QUERY_DUMP_BLOCK_ID_IU = 7, + QUERY_DUMP_BLOCK_ID_WLS_FE = 8, + QUERY_DUMP_BLOCK_ID_EU_PS = 9, + QUERY_DUMP_BLOCK_ID_TUFE = 10, + QUERY_DUMP_BLOCK_ID_L2 = 11, + QUERY_DUMP_BLOCK_ID_MXU = 12, + QUERY_DUMP_BLOCK_ID_MCE = 13, + QUERY_DUMP_BLOCK_ID_EU_CS = 14, + QUERY_DUMP_BLOCK_ID_VCP = 15, + QUERY_DUMP_BLOCK_ID_VPP = 16, + QUERY_DUMP_BLOCK_ID_ISP = 17, + QUERY_DUMP_BLOCK_ID_MMU = 18, + QUERY_DUMP_BLOCK_ID_WLS_BE = 19, + QUERY_DUMP_BLOCK_ID_TUBE = 20, + QUERY_DUMP_BLOCK_ID_GPCPBE = 21, + QUERY_DUMP_BLOCK_ID_SPOUT = 22, + QUERY_DUMP_BLOCK_ID_MIU = 23, + QUERY_DUMP_BLOCK_ID_GPCTOP = 24, +} QUERY_DUMP_BLOCK_ID; +typedef enum +{ + SET_REGISTER_ADDRESS_MODE_ADDRESS = 0, + + SET_REGISTER_ADDRESS_MODE_OFFSET = 1, + + +} SET_REGISTER_ADDRESS_MODE; +typedef enum +{ + SET_OBJECT_OBJECT_TYPE_OCCLUSION_PREDICATE= 0, + + + + SET_OBJECT_OBJECT_TYPE_SO_OVERFLOW_PREDICATE_STREAMI= 1, + + + + + SET_OBJECT_OBJECT_TYPE_SO_OVERFLOW_PREDICATE= 2, + + +} SET_OBJECT_OBJECT_TYPE; +typedef enum +{ + DIP_MODE_DRAW_IMM = 0, + + DIP_MODE_IB_8 = 1, + + + DIP_MODE_IB_16 = 2, + DIP_MODE_IB_32 = 3, + DIP_MODE_DRAW_AUTO = 4, +} DIP_MODE; +typedef enum +{ + DIP_INSTANCE_EN_DISABLED = 0, + DIP_INSTANCE_EN_ENABLED = 1, +} DIP_INSTANCE_EN; +typedef enum +{ + DIP_P_TYPE_POINTLIST = 0, + DIP_P_TYPE_LINELIST = 1, + DIP_P_TYPE_LINESTRIP = 2, + DIP_P_TYPE_TRIANGLELIST = 3, + DIP_P_TYPE_TRIANGLESTRIP = 4, + DIP_P_TYPE_LINELIST_ADJ = 5, + DIP_P_TYPE_LINESTRIP_ADJ = 6, + DIP_P_TYPE_TRIANGLELIST_ADJ = 7, + DIP_P_TYPE_TRIANGLESTRIP_ADJ = 8, + DIP_P_TYPE_LINELOOP = 9, + DIP_P_TYPE_TRIANGLEFAN_OGL = 10, + DIP_P_TYPE_TRIANGLEFAN_D3D_VULKAN = 11, + DIP_P_TYPE_PATCHLIST = 12, + DIP_P_TYPE_QUADLIST_OGL = 13, + DIP_P_TYPE_QUADSTRIP_OGL = 14, + DIP_P_TYPE_POLYGON_OGL = 15, + DIP_P_TYPE_AXIS_ALIGNED_RECTANGLELIST = 16, +} DIP_P_TYPE; +typedef enum +{ + FENCE_IRQ_NOP = 0, + FENCE_IRQ_INTERRUPT_CPU = 1, + FENCE_IRQ_INTERRUPT_GPU = 2, + + + + +} FENCE_IRQ; +typedef enum +{ + FENCE_FENCE_TYPE_INTERNAL = 0, + FENCE_FENCE_TYPE_EXTERNAL32 = 2, + FENCE_FENCE_TYPE_EXTERNAL64 = 3, + + +} FENCE_FENCE_TYPE; +typedef enum +{ + FENCE_FENCE_UPDATE_MODE_COPY = 0, + FENCE_FENCE_UPDATE_MODE_OR = 1, +} FENCE_FENCE_UPDATE_MODE; +typedef enum +{ + FENCE_RB_TYPE_3DFE = 0, + FENCE_RB_TYPE_3DBE = 1, + FENCE_RB_TYPE_CSL = 2, + FENCE_RB_TYPE_CSH = 3, +} FENCE_RB_TYPE; +typedef enum +{ + FENCE_ROUTE_ID_CSP_FENCE = 0, + + FENCE_ROUTE_ID_Z_FENCE = 1, + + + + + + + FENCE_ROUTE_ID_D_FENCE = 2, + + + + FENCE_ROUTE_ID_UAVFE_FENCE = 3, + + + + + + + FENCE_ROUTE_ID_UAVBE_FENCE = 4, + + + + + + + FENCE_ROUTE_ID_FS_STO_FENCE = 5, + + + FENCE_ROUTE_ID_MCE_FENCE = 6, + + FENCE_ROUTE_ID_L2_FENCE = 7, + + FENCE_ROUTE_ID_VCP_FENCE = 8, + FENCE_ROUTE_ID_VPP_FENCE = 9, + FENCE_ROUTE_ID_ISP_FENCE = 10, +} FENCE_ROUTE_ID; +typedef enum +{ + BLOCK_COMMAND_TEMPLATE_TYPE_FLUSH = 0, + BLOCK_COMMAND_TEMPLATE_TYPE_INVALIDATE_CACHE= 1, + BLOCK_COMMAND_TEMPLATE_TYPE_SG = 2, + BLOCK_COMMAND_TEMPLATE_TYPE_IMAGE_TRANSFER= 3, +} BLOCK_COMMAND_TEMPLATE_TYPE; +typedef enum +{ + BLOCK_COMMAND_TAS_TYPE_COLOR_EXCLUDED = 0, + + BLOCK_COMMAND_TAS_TYPE_COLOR_INCLUDED = 1, + + +} BLOCK_COMMAND_TAS_TYPE; +typedef enum +{ + BLOCK_COMMAND_TAS_COMMAND_SPECIFIC_FIELD_DP_LINE= 0, + +} BLOCK_COMMAND_TAS_COMMAND_SPECIFIC_FIELD; +typedef enum +{ + BLOCK_COMMAND_SG_AREA_TARGET_Z = 0, + BLOCK_COMMAND_SG_AREA_TARGET_S = 1, + BLOCK_COMMAND_SG_AREA_TARGET_D = 2, + BLOCK_COMMAND_SG_AREA_TARGET_U = 3, +} BLOCK_COMMAND_SG_AREA_TARGET; +typedef enum +{ + BLOCK_COMMAND_SG_ACTION_TYPE_FAST_CLEAR_TILE= 0, + BLOCK_COMMAND_SG_ACTION_TYPE_FAST_CLEAR_LINEAR= 1, + + + BLOCK_COMMAND_SG_ACTION_TYPE_BIT_BLT = 2, + BLOCK_COMMAND_SG_ACTION_TYPE_GRADIENT_FILL= 3, + BLOCK_COMMAND_SG_ACTION_TYPE_ROTATION = 4, + BLOCK_COMMAND_SG_ACTION_TYPE_RESERVED = 7, +} BLOCK_COMMAND_SG_ACTION_TYPE; +typedef enum +{ + BLOCK_COMMAND_SG_TBR_LOOP_STATUS_PERTBRTILE= 0, + BLOCK_COMMAND_SG_TBR_LOOP_STATUS_ONCE = 1, + + + +} BLOCK_COMMAND_SG_TBR_LOOP_STATUS; +typedef enum +{ + BLOCK_COMMAND_SG_BLT_OVERLAP_NON_OVERLAP= 0, + + BLOCK_COMMAND_SG_BLT_OVERLAP_OVERLAP = 1, +} BLOCK_COMMAND_SG_BLT_OVERLAP; +typedef enum +{ + BLOCK_COMMAND_SG_ROT_DWORD0_CW_CW = 0, + BLOCK_COMMAND_SG_ROT_DWORD0_CW_CCW = 1, +} BLOCK_COMMAND_SG_ROT_DWORD0_CW; +typedef enum +{ + BLOCK_COMMAND_IMG_TRN_DATA_FMT_1BPP = 0, + + + BLOCK_COMMAND_IMG_TRN_DATA_FMT_4BPP = 1, + + + + BLOCK_COMMAND_IMG_TRN_DATA_FMT_8BPP = 2, + BLOCK_COMMAND_IMG_TRN_DATA_FMT_16BPP = 3, + BLOCK_COMMAND_IMG_TRN_DATA_FMT_32BPP = 4, + BLOCK_COMMAND_IMG_TRN_DATA_FMT_64BPP = 5, + BLOCK_COMMAND_IMG_TRN_DATA_FMT_128BPP = 6, +} BLOCK_COMMAND_IMG_TRN_DATA_FMT; +typedef enum +{ + BLOCK_COMMAND_IMG_TRN_TBR_LOOP_STATUS_PERTBRTILE= 0, + + BLOCK_COMMAND_IMG_TRN_TBR_LOOP_STATUS_ONCE= 1, + + + +} BLOCK_COMMAND_IMG_TRN_TBR_LOOP_STATUS; +typedef enum +{ + BLOCK_COMMAND_FLUSH_TYPE_FLUSH = 0, + BLOCK_COMMAND_FLUSH_TYPE_INVALIDATE_CACHE= 1, + BLOCK_COMMAND_FLUSH_TYPE_SG = 2, + BLOCK_COMMAND_FLUSH_TYPE_IMAGE_TRANSFER = 3, +} BLOCK_COMMAND_FLUSH_TYPE; +typedef enum +{ + BLOCK_COMMAND_FLUSH_TARGET_ALL_C = 0, + + BLOCK_COMMAND_FLUSH_TARGET_Z_C = 1, + + + BLOCK_COMMAND_FLUSH_TARGET_S_C = 2, + + + BLOCK_COMMAND_FLUSH_TARGET_D_C = 3, + + + BLOCK_COMMAND_FLUSH_TARGET_UAV_C = 4, + + BLOCK_COMMAND_FLUSH_TARGET_USHARP_DESC = 5, + + BLOCK_COMMAND_FLUSH_TARGET_2D_ONLY = 6, + + + + BLOCK_COMMAND_FLUSH_TARGET_D_SIG_BUF = 7, + + + +} BLOCK_COMMAND_FLUSH_TARGET; +typedef enum +{ + BLOCK_COMMAND_FLUSH_UAV_TYPE_3DFE = 0, + + + BLOCK_COMMAND_FLUSH_UAV_TYPE_3DBE = 1, + + + BLOCK_COMMAND_FLUSH_UAV_TYPE_CSL = 2, + + + BLOCK_COMMAND_FLUSH_UAV_TYPE_CSH = 3, + + +} BLOCK_COMMAND_FLUSH_UAV_TYPE; +typedef enum +{ + BLOCK_COMMAND_EU_TYPE_INVALIDATE_L1I = 0, + BLOCK_COMMAND_EU_TYPE_DRAIN_EU = 1, + + + + + + +} BLOCK_COMMAND_EU_TYPE; +typedef enum +{ + BLOCK_COMMAND_TU_TYPE_INVALIDATE_L1 = 0, + + + + + + + + + + + + + + + + + + +} BLOCK_COMMAND_TU_TYPE; +typedef enum +{ + BLOCK_COMMAND_L2_TYPE_FLUSH_L2 = 0, + BLOCK_COMMAND_L2_TYPE_INVALIDATE_L2 = 1, + + BLOCK_COMMAND_L2_TYPE_FLUSH_L1 = 4, + +} BLOCK_COMMAND_L2_TYPE; +typedef enum +{ + BLOCK_COMMAND_L2_USAGE_ALL = 0, + BLOCK_COMMAND_L2_USAGE_TU = 1, + BLOCK_COMMAND_L2_USAGE_UAV = 2, + BLOCK_COMMAND_L2_USAGE_DZ = 3, + BLOCK_COMMAND_L2_USAGE_IC = 4, + BLOCK_COMMAND_L2_USAGE_CSP = 5, + BLOCK_COMMAND_L2_USAGE_DESC = 6, +} BLOCK_COMMAND_L2_USAGE; +typedef enum +{ + BLOCK_COMMAND_MXU_CMD_TYPE_FLUSH_CACHE = 0, + BLOCK_COMMAND_MXU_CMD_TYPE_INVALIDATE_CACHE= 1, + BLOCK_COMMAND_MXU_CMD_TYPE_INVALIDATE_UTLB_CACHE= 2, + + BLOCK_COMMAND_MXU_CMD_TYPE_INVALIDATE_DTLB_CACHE= 3, + +} BLOCK_COMMAND_MXU_CMD_TYPE; +typedef enum +{ + BLOCK_COMMAND_MXU_BLC_DWORD1_USAGE_ALL = 0, + BLOCK_COMMAND_MXU_BLC_DWORD1_USAGE_TU = 1, + BLOCK_COMMAND_MXU_BLC_DWORD1_USAGE_UAV = 2, + BLOCK_COMMAND_MXU_BLC_DWORD1_USAGE_DZ = 3, + BLOCK_COMMAND_MXU_BLC_DWORD1_USAGE_IC = 4, + BLOCK_COMMAND_MXU_BLC_DWORD1_USAGE_DMA = 5, + BLOCK_COMMAND_MXU_BLC_DWORD1_USAGE_DESC = 6, +} BLOCK_COMMAND_MXU_BLC_DWORD1_USAGE; +typedef enum +{ + BLOCK_COMMAND_CSP_TYPE_INDICATOR = 0, + + BLOCK_COMMAND_CSP_TYPE_CLEAR_MXU_BLC = 1, + + BLOCK_COMMAND_CSP_TYPE_SAVE = 2, + + BLOCK_COMMAND_CSP_TYPE_RESTORE = 3, + + BLOCK_COMMAND_CSP_TYPE_LOAD_DESCRIPTOR = 4, + +} BLOCK_COMMAND_CSP_TYPE; +typedef enum +{ + BLK_CMD_CSP_SAVE_RSTO_ADDRESS_MODE_ADDRESS= 0, + + BLK_CMD_CSP_SAVE_RSTO_ADDRESS_MODE_OFFSET= 1, + + +} BLK_CMD_CSP_SAVE_RSTO_ADDRESS_MODE; +typedef enum +{ + BLK_CMD_CSP_INDICATOR_INFO_OFF_MODE = 0, + BLK_CMD_CSP_INDICATOR_INFO_MCE_MODE = 1, + + + BLK_CMD_CSP_INDICATOR_INFO_CS_MODE = 2, + BLK_CMD_CSP_INDICATOR_INFO_3D_MODE = 3, + BLK_CMD_CSP_INDICATOR_INFO_VCP_MODE = 4, +} BLK_CMD_CSP_INDICATOR_INFO; +typedef enum +{ + BLK_CMD_CSP_LD_DES_ADDRESS_MODE_ADDRESS = 0, + BLK_CMD_CSP_LD_DES_ADDRESS_MODE_OFFSET = 1, + +} BLK_CMD_CSP_LD_DES_ADDRESS_MODE; +typedef enum +{ + BLK_CMD_CSP_LD_DES_DESC_TYPE_T = 0, + + BLK_CMD_CSP_LD_DES_DESC_TYPE_S = 1, + + BLK_CMD_CSP_LD_DES_DESC_TYPE_U = 2, + + BLK_CMD_CSP_LD_DES_DESC_TYPE_S_T = 3, + +} BLK_CMD_CSP_LD_DES_DESC_TYPE; +typedef enum +{ + BLOCK_COMMAND_VIDEO_IRQ_NOP = 0, + BLOCK_COMMAND_VIDEO_IRQ_INTERRUPT = 1, +} BLOCK_COMMAND_VIDEO_IRQ; +typedef enum +{ + BLOCK_COMMAND_VIDEO_EXTERNAL_FENCE_NOP = 0, + BLOCK_COMMAND_VIDEO_EXTERNAL_FENCE_EXTERNAL_FENCE= 1, + + +} BLOCK_COMMAND_VIDEO_EXTERNAL_FENCE; +typedef enum +{ + GP_DW_TYPE_GROUP_NUMBER = 0, + GP_DW_TYPE_GLOBAL_SIZE = 1, +} GP_DW_TYPE; +typedef enum +{ + GP_MINOR_OPCODE_NORMAL_GP = 0, + GP_MINOR_OPCODE_CS_FULL_CTX_END = 1, + + + +} GP_MINOR_OPCODE; +typedef enum +{ + TBR_INDICATOR_INDICATOR_INFO_BEGIN = 0, + TBR_INDICATOR_INDICATOR_INFO_FORCE_KICKOFF= 1, + + + + TBR_INDICATOR_INDICATOR_INFO_END = 2, +} TBR_INDICATOR_INDICATOR_INFO; + + + + + +typedef struct _Cmd_Skip +{ + unsigned int Dwc : 16; + + unsigned int Reserved : 12; + unsigned int Major_Opcode : 4; +} Cmd_Skip; + +typedef struct _Cmd_Dma +{ + unsigned int Dw_Num : 16; + unsigned int Reserved : 8; + unsigned int Special_Dma_Type : 1; + + + + + + unsigned int Reset_Dma : 1; + + unsigned int Mode : 2; + + unsigned int Major_Opcode : 4; +} Cmd_Dma; + + + typedef struct _Cmd_Dma_Address_Dword1 + { + unsigned int Address_Low32 : 32; + } Cmd_Dma_Address_Dword1; + typedef struct _Cmd_Dma_Address_Dword2 + { + unsigned int Address_High8 : 8; + unsigned int L2_Cachable : 1; + + unsigned int Reserved : 23; + } Cmd_Dma_Address_Dword2; + typedef struct _Cmd_Ctx_Address_Dword3 + { + unsigned int Ctx_Base_Addr : 29; + unsigned int Reserved : 3; + } Cmd_Ctx_Address_Dword3; + + + + +typedef struct _Cmd_Wait +{ + unsigned int Dwc : 16; + + + + unsigned int Wait_Mode : 2; + unsigned int Method : 1; + unsigned int Station_Id : 3; + unsigned int Slot_Id : 5; + + unsigned int Reserved : 1; + unsigned int Major_Opcode : 4; +} Cmd_Wait; + + + typedef struct _Cmd_Wait_Kkk_Dword1 + { + unsigned int Event_Flag_Idx1 : 16; + + + + unsigned int Event_Flag_Idx2 : 16; + } Cmd_Wait_Kkk_Dword1; + typedef struct _Cmd_Wait_External_Dword1 + { + unsigned int Address_Low32 : 16; + + } Cmd_Wait_External_Dword1; + typedef struct _Cmd_Wait_External_Dword2 + { + unsigned int Address_High8 : 8; + unsigned int Reserved : 24; + } Cmd_Wait_External_Dword2; + typedef struct _Cmd_Wait_External_Dword3 + { + unsigned int Event_Cnt_Ref_Low32 : 32; + } Cmd_Wait_External_Dword3; + typedef struct _Cmd_Wait_External_Dword4 + { + unsigned int Event_Cnt_Ref_High32 : 32; + } Cmd_Wait_External_Dword4; + + + + +typedef struct _Cmd_Query_Dump + +{ + unsigned int Dwc : 3; + + + unsigned int Reserved : 1; + unsigned int Query_Ready_En : 1; + + + unsigned int Channle_Id : 2; + unsigned int Dwc_To_Dump : 13; + + unsigned int Address_Mode : 1; + unsigned int Timestamp_En : 1; + unsigned int Cmd_Type : 1; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Query_Dump; + + + typedef struct _Cmd_Query_Dump_Address_Dword1 + { + unsigned int Address_Low32 : 32; + + + } Cmd_Query_Dump_Address_Dword1; + typedef struct _Cmd_Query_Dump_Address_Dword2 + { + unsigned int Address_High8 : 8; + unsigned int Reserved : 11; + unsigned int Reg_Offset : 13; + } Cmd_Query_Dump_Address_Dword2; + typedef struct _Cmd_Query_Dump_Offset_Dword1 + { + unsigned int Offset_Low32 : 32; + } Cmd_Query_Dump_Offset_Dword1; + typedef struct _Cmd_Query_Dump_Offset_Dword2 + { + unsigned int Offset_High8 : 8; + unsigned int Reserved : 11; + unsigned int Reg_Offset : 13; + } Cmd_Query_Dump_Offset_Dword2; + typedef struct _Cmd_Cpy_Qry_Res_Dword1 + { + unsigned int Begin_Query_Addr_Low32 + : 32; + + } Cmd_Cpy_Qry_Res_Dword1; + typedef struct _Cmd_Cpy_Qry_Res_Dword2 + { + unsigned int Begin_Query_Addr_High5 + : 5; + + unsigned int L2_Cachable : 1; + + unsigned int Bit64_En : 1; + unsigned int Avaliability_Bit : 1; + unsigned int Partial_Bit : 1; + unsigned int Slice_Num : 4; + + unsigned int Reserved : 3; + unsigned int End_Query_Ddw_Offs : 8; + + unsigned int End_Query_Ava_Ddw_Offs + : 8; + + + } Cmd_Cpy_Qry_Res_Dword2; + typedef struct _Cmd_Cpy_Qry_Res_Dword3 + { + unsigned int Dest_Addr_Low32 : 32; + + } Cmd_Cpy_Qry_Res_Dword3; + typedef struct _Cmd_Cpy_Qry_Res_Dword4 + { + unsigned int Dest_Addr_High8 : 8; + + unsigned int Reserved : 24; + } Cmd_Cpy_Qry_Res_Dword4; + + + + +typedef struct _Cmd_Set_Register + +{ + unsigned int Dwc : 7; + + + + + + unsigned int Address_Mode : 1; + unsigned int Addr_En : 1; + + + + unsigned int Mask_En : 1; + + + unsigned int Start_Offset : 13; + unsigned int Block_Id : 5; + + unsigned int Major_Opcode : 4; +} Cmd_Set_Register; + + + typedef struct _Cmd_Set_Register_Addr_Dword1 + { + unsigned int Address_Low32 : 32; + } Cmd_Set_Register_Addr_Dword1; + typedef struct _Cmd_Set_Register_Addr_Dword2 + { + unsigned int Address_High8 : 8; + unsigned int L2_Cachable : 1; + unsigned int If_Physical : 1; + unsigned int Reserved : 9; + unsigned int Reg_Cnt : 13; + } Cmd_Set_Register_Addr_Dword2; + typedef struct _Cmd_Set_Register_Offset_Dword1 + + + { + unsigned int Offset_Low32 : 32; + } Cmd_Set_Register_Offset_Dword1; + typedef struct _Cmd_Set_Register_Offset_Dword2 + + + { + unsigned int Offset_High8 : 8; + unsigned int Reserved : 11; + unsigned int Reg_Cnt : 13; + } Cmd_Set_Register_Offset_Dword2; + + + + +typedef struct _Cmd_Set_Object +{ + unsigned int Dwc : 2; + unsigned int Object_Type : 2; + unsigned int Reserved : 22; + unsigned int Predicate_Not : 1; + unsigned int Hint : 1; + unsigned int Major_Opcode : 4; +} Cmd_Set_Object; + + + typedef struct _Cmd_Set_Object_Dword1 + { + unsigned int Address_Low32 : 32; + } Cmd_Set_Object_Dword1; + typedef struct _Cmd_Set_Object_Dword2 + { + unsigned int Address_High8 : 8; + unsigned int Reserved : 24; + } Cmd_Set_Object_Dword2; + + + + +typedef struct _Cmd_Dip +{ + unsigned int Predicate_En : 1; + unsigned int Indirect : 1; + + unsigned int Mode : 3; + unsigned int Instance_En : 1; + unsigned int Start_Index_Valid : 1; + + + + + + + unsigned int Start_Vertex_Valid : 1; + + + + + + + + unsigned int Start_Instance_Valid : 1; + + + + + + + unsigned int P_Type : 5; + unsigned int Indirect_Drawcnt_En : 1; + + + + + + unsigned int Reserved1 : 1; + unsigned int Patch_Vertex_Count : 6; + unsigned int Reserved : 6; + unsigned int Major_Opcode : 4; +} Cmd_Dip; + + + typedef struct _Cmd_Dip_Dword1 + { + unsigned int Draw_Count : 32; + + + + + } Cmd_Dip_Dword1; + typedef struct _Cmd_Dip_Dword2 + { + unsigned int Drawcount_Addr_Low32 : 32; + + + + + } Cmd_Dip_Dword2; + typedef struct _Cmd_Dip_Dword3 + { + unsigned int Drawcount_Addr_High8 : 8; + + + + + unsigned int L2_Cachable : 1; + unsigned int Reserved : 23; + } Cmd_Dip_Dword3; + typedef struct _Cmd_Dip_Dword4 + { + unsigned int Start_Instance : 32; + + + + + } Cmd_Dip_Dword4; + typedef struct _Cmd_Dip_Dword5 + { + unsigned int Instance_Count : 32; + + + + } Cmd_Dip_Dword5; + typedef struct _Cmd_Dip_Dword6 + { + unsigned int Index_Count : 32; + + + + } Cmd_Dip_Dword6; + typedef struct _Cmd_Dip_Dword7 + { + unsigned int Ib_Base_Addr_Low32 : 32; + + + + + } Cmd_Dip_Dword7; + typedef struct _Cmd_Dip_Dword8 + { + unsigned int Ib_Base_Addr_High8 : 8; + + + + + unsigned int L2_Cachable : 1; + + unsigned int Outofbound_Mode : 1; + + unsigned int Reserved : 22; + } Cmd_Dip_Dword8; + typedef struct _Cmd_Dip_Dword9 + { + unsigned int Ib_Offset : 32; + + + + + } Cmd_Dip_Dword9; + typedef struct _Cmd_Dip_Dword10 + { + unsigned int Ib_Byte_Size : 32; + + + + + } Cmd_Dip_Dword10; + typedef struct _Cmd_Dip_Dword11 + { + unsigned int Start_Vertex : 32; + + + + + } Cmd_Dip_Dword11; + typedef struct _Cmd_Dip_Dword12 + { + unsigned int Start_Index : 32; + + + + + } Cmd_Dip_Dword12; + typedef struct _Cmd_Dip_Dword13 + { + unsigned int Para_Base_Addr_Low32 : 32; + + + } Cmd_Dip_Dword13; + typedef struct _Cmd_Dip_Dword14 + { + unsigned int Para_Base_Addr_High8 : 8; + + + unsigned int L2_Cachable : 1; + + unsigned int Reserved : 23; + } Cmd_Dip_Dword14; + typedef struct _Cmd_Dip_Dword15 + { + unsigned int Para_Stride : 32; + + + + + + + + + } Cmd_Dip_Dword15; + typedef struct _Cmd_Dip_Insdrawauto_Dword1 + { + unsigned int Instance_Count : 32; + + + + + } Cmd_Dip_Insdrawauto_Dword1; + + + + +typedef struct _Cmd_Fence + + + + +{ + unsigned int Dwc : 3; + + unsigned int Irq : 2; + unsigned int Fence_Type : 2; + unsigned int Slot_Id : 5; + + + + unsigned int Reserved : 1; + unsigned int Fence_Update_Mode : 1; + unsigned int Reserved1 : 8; + unsigned int Rb_Type : 2; + + unsigned int Route_Id : 4; + + + unsigned int Major_Opcode : 4; + +} Cmd_Fence; + + + typedef struct _Cmd_Fence_Internal_Dword1 + { + unsigned int Update_Value : 16; + unsigned int Slice_Mask : 16; + + + + } Cmd_Fence_Internal_Dword1; + typedef struct _Cmd_Fence_External_Addr_Dword1 + + + { + unsigned int External_Addr_Low32 : 32; + } Cmd_Fence_External_Addr_Dword1; + typedef struct _Cmd_Fence_External_Addr_Dword2 + + + { + unsigned int External_Addr_High8 : 8; + unsigned int Reserved : 23; + unsigned int Fence_Update_Timing : 1; + + } Cmd_Fence_External_Addr_Dword2; + typedef struct _Cmd_Fence_External_Data_Dword3 + + + { + unsigned int External_Data1 : 32; + } Cmd_Fence_External_Data_Dword3; + typedef struct _Cmd_Fence_External_Data_Dword4 + + + { + unsigned int External_Data2 : 32; + } Cmd_Fence_External_Data_Dword4; + + + + +typedef struct _Cmd_Block_Command_Template + + +{ + unsigned int Dwc : 12; + + + + unsigned int Type : 2; + unsigned int Command_Specific_Field + : 7; + unsigned int Reserved0 : 2; + unsigned int Block_Id : 5; + + unsigned int Major_Opcode : 4; + +} Cmd_Block_Command_Template; + +typedef struct _Cmd_Block_Command_Tas +{ + unsigned int Dwc : 12; + unsigned int Type : 2; + unsigned int Command_Specific_Field + : 6; + unsigned int Reserved0 : 3; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Block_Command_Tas; + +typedef struct _Cmd_Block_Command_Sg +{ + unsigned int Dwc : 12; + unsigned int Type : 2; + unsigned int Area_Target : 2; + unsigned int Action_Type : 3; + unsigned int Tbr_Loop_Status : 1; + + + + + unsigned int Reserved0 : 1; + unsigned int Blt_Overlap : 1; + + unsigned int Predicate_En : 1; + unsigned int Block_Id : 5; + + + + + + unsigned int Major_Opcode : 4; + +} Cmd_Block_Command_Sg; + + + typedef struct _Cmd_Block_Command_Sg_Dword0 + + { + unsigned int Xmin : 16; + unsigned int Xmax : 16; + } Cmd_Block_Command_Sg_Dword0; + typedef struct _Cmd_Block_Command_Sg_Rot_Dword0 + + { + unsigned int Cw : 1; + unsigned int Reserved0 : 31; + } Cmd_Block_Command_Sg_Rot_Dword0; + typedef struct _Cmd_Block_Command_Sg_Dword1 + + { + unsigned int Ymin : 16; + unsigned int Ymax : 16; + } Cmd_Block_Command_Sg_Dword1; + typedef struct _Cmd_Block_Command_Sg_Blt_Dword2 + + { + unsigned int Dx : 15; + unsigned int Reserved0 : 1; + unsigned int Dy : 15; + unsigned int Reserved1 : 1; + } Cmd_Block_Command_Sg_Blt_Dword2; + typedef struct _Cmd_Block_Command_Sg_Gradient_Fill_Dword + + { + unsigned int Color : 28; + unsigned int Reserved : 4; + } Cmd_Block_Command_Sg_Gradient_Fill_Dword; + + + + +typedef struct _Cmd_Block_Command_Img_Trn +{ + unsigned int Dwc : 12; + unsigned int Type : 2; + unsigned int Is_Dword_Aligned : 1; + + + + + + unsigned int Data_Fmt : 3; + unsigned int Tbr_Loop_Status : 1; + + + + unsigned int Reserved : 3; + unsigned int Predicate_En : 1; + unsigned int Block_Id : 5; + + + unsigned int Major_Opcode : 4; + +} Cmd_Block_Command_Img_Trn; + + + typedef struct _Cmd_Block_Command_Img_Trn_Dword0 + + { + unsigned int Xmin : 16; + unsigned int Xmax : 16; + } Cmd_Block_Command_Img_Trn_Dword0; + typedef struct _Cmd_Block_Command_Img_Trn_Dword1 + + { + unsigned int Ymin : 16; + unsigned int Ymax : 16; + } Cmd_Block_Command_Img_Trn_Dword1; + + + + +typedef struct _Cmd_Block_Command_Flush +{ + unsigned int Dwc : 12; + + unsigned int Type : 2; + + unsigned int Target : 5; + + unsigned int Uav_Type : 2; + + + + unsigned int Reserved : 2; + unsigned int Block_Id : 5; + + + unsigned int Major_Opcode : 4; + +} Cmd_Block_Command_Flush; + +typedef struct _Cmd_Block_Command_Eu +{ + unsigned int Dwc : 12; + unsigned int Type : 2; + unsigned int Command_Specific_Field + : 7; + + + + + + + + unsigned int Reserved : 2; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Block_Command_Eu; + +typedef struct _Cmd_Block_Command_Tu +{ + unsigned int Dwc : 12; + unsigned int Type : 2; + unsigned int Command_Specific_Field + : 7; + + + + + + + + unsigned int Reserved : 2; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Block_Command_Tu; + +typedef struct _Cmd_Block_Command_L2 +{ + unsigned int Dwc : 12; + + unsigned int Type : 3; + unsigned int Usage : 3; + unsigned int Reserved : 5; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Block_Command_L2; + + + typedef struct _Cmd_Block_Command_L2_Dword0 + { + unsigned int Start_Address_Low32 : 32; + } Cmd_Block_Command_L2_Dword0; + typedef struct _Cmd_Block_Command_L2_Dword1 + { + unsigned int Start_Address_High8 : 8; + + unsigned int Reserved : 24; + } Cmd_Block_Command_L2_Dword1; + typedef struct _Cmd_Block_Command_L2_Dword2 + { + unsigned int Address_Byte_Mask_Low32 + : 32; + } Cmd_Block_Command_L2_Dword2; + typedef struct _Cmd_Block_Command_L2_Dword3 + { + unsigned int Address_Byte_Mask_High8 + : 8; + + + unsigned int Reserved : 24; + } Cmd_Block_Command_L2_Dword3; + + + + +typedef struct _Cmd_Block_Command_Mxu +{ + unsigned int Dwc : 12; + + + + + + + + unsigned int Cmd_Type : 2; + unsigned int Reserved : 4; + unsigned int Proc_Id : 4; + unsigned int Reserved1 : 1; + + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Block_Command_Mxu; + + + typedef struct _Cmd_Block_Command_Mxu_Blc_Dword0 + + { + unsigned int Start_Address_Low32 : 32; + } Cmd_Block_Command_Mxu_Blc_Dword0; + typedef struct _Cmd_Block_Command_Mxu_Blc_Dword1 + + { + unsigned int Start_Address_High8 : 8; + + unsigned int Usage : 3; + unsigned int Reserved : 21; + } Cmd_Block_Command_Mxu_Blc_Dword1; + typedef struct _Cmd_Block_Command_Mxu_Blc_Dword2 + + { + unsigned int Address_Byte_Mask_Low32 + : 32; + } Cmd_Block_Command_Mxu_Blc_Dword2; + typedef struct _Cmd_Block_Command_Mxu_Blc_Dword3 + + { + unsigned int Address_Byte_Mask_High8 + : 8; + + unsigned int Reserved : 24; + } Cmd_Block_Command_Mxu_Blc_Dword3; + typedef struct _Cmd_Block_Command_Mxu_Ptc_Dword0 + + { + unsigned int Reserved : 12; + unsigned int Start_Address_L : 20; + } Cmd_Block_Command_Mxu_Ptc_Dword0; + typedef struct _Cmd_Block_Command_Mxu_Ptc_Dword1 + + { + unsigned int Start_Address_High8 : 8; + + unsigned int Reserved : 24; + } Cmd_Block_Command_Mxu_Ptc_Dword1; + typedef struct _Cmd_Block_Command_Mxu_Ptc_Dword2 + + { + unsigned int Reserved : 12; + unsigned int Address_Byte_Mask_L : 20; + } Cmd_Block_Command_Mxu_Ptc_Dword2; + typedef struct _Cmd_Block_Command_Mxu_Ptc_Dword3 + + { + unsigned int Address_Byte_Mask_High8 + : 8; + + unsigned int Reserved : 24; + } Cmd_Block_Command_Mxu_Ptc_Dword3; + typedef struct _Cmd_Block_Command_Mxu_L2_Dword0 + + { + unsigned int Address_Low32 : 32; + } Cmd_Block_Command_Mxu_L2_Dword0; + typedef struct _Cmd_Block_Command_Mxu_L2_Dword1 + + { + unsigned int Address_High8 : 8; + + unsigned int Reserved : 24; + } Cmd_Block_Command_Mxu_L2_Dword1; + typedef struct _Cmd_Block_Command_Mxu_L2_Dword2 + + { + unsigned int Mask_Low32 : 32; + } Cmd_Block_Command_Mxu_L2_Dword2; + typedef struct _Cmd_Block_Command_Mxu_L2_Dword3 + + { + unsigned int Mask_High8 : 8; + + + unsigned int Reserved : 24; + } Cmd_Block_Command_Mxu_L2_Dword3; + + + + +typedef struct _Cmd_Block_Command_Csp +{ + unsigned int Dwc : 3; + + unsigned int Header : 17; + unsigned int Type : 3; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Block_Command_Csp; + +typedef struct _Cmd_Blk_Cmd_Csp_Blc +{ + unsigned int Dwc : 3; + unsigned int Counter : 17; + + + + unsigned int Type : 3; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Blk_Cmd_Csp_Blc; + + + typedef struct _Cmd_Blk_Cmd_Csp_Blc_Dword1 + { + unsigned int Start_Address_Low32 : 32; + } Cmd_Blk_Cmd_Csp_Blc_Dword1; + typedef struct _Cmd_Blk_Cmd_Csp_Blc_Dword2 + { + unsigned int Start_Address_High8 : 8; + + unsigned int Reserved : 16; + unsigned int Clear_Value1 : 4; + + + unsigned int Clear_Value0 : 4; + + + } Cmd_Blk_Cmd_Csp_Blc_Dword2; + typedef struct _Cmd_Blk_Cmd_Csp_Blc_Dword3 + { + unsigned int Blc_Mask : 32; + + } Cmd_Blk_Cmd_Csp_Blc_Dword3; + + + + +typedef struct _Cmd_Blk_Cmd_Csp_Save_Rsto +{ + unsigned int Dwc : 3; + + unsigned int Reserved : 16; + unsigned int Address_Mode : 1; + unsigned int Type : 3; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Blk_Cmd_Csp_Save_Rsto; + + + typedef struct _Cmd_Blk_Cmd_Csp_Save_Rsto_Addr_Dword1 + + + { + unsigned int Start_Address_Low32 : 32; + } Cmd_Blk_Cmd_Csp_Save_Rsto_Addr_Dword1; + typedef struct _Cmd_Blk_Cmd_Csp_Save_Rsto_Addr_Dword2 + + + { + unsigned int Start_Address_High8 : 8; + unsigned int L2_Cachable : 1; + + unsigned int Reserved : 23; + } Cmd_Blk_Cmd_Csp_Save_Rsto_Addr_Dword2; + typedef struct _Cmd_Blk_Cmd_Csp_Save_Rsto_Offset_Dword1 + + + { + unsigned int Offset_Low32 : 32; + } Cmd_Blk_Cmd_Csp_Save_Rsto_Offset_Dword1; + typedef struct _Cmd_Blk_Cmd_Csp_Save_Rsto_Offset_Dword2 + + + { + unsigned int Offset_High8 : 8; + unsigned int Reserved : 24; + } Cmd_Blk_Cmd_Csp_Save_Rsto_Offset_Dword2; + + + + +typedef struct _Cmd_Blk_Cmd_Csp_Indicator +{ + unsigned int Dwc : 3; + + unsigned int Reserved : 10; + unsigned int Process_Id : 4; + unsigned int Info : 3; + unsigned int Type : 3; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Blk_Cmd_Csp_Indicator; + + + typedef struct _Cmd_Blk_Cmd_Csp_Indicator_Dword1 + + { + unsigned int Slice_Mask : 12; + unsigned int Reserved : 20; + } Cmd_Blk_Cmd_Csp_Indicator_Dword1; + + + + +typedef struct _Cmd_Blk_Cmd_Csp_Ld_Des +{ + unsigned int Dwc : 3; + unsigned int Des_Block_Id : 5; + unsigned int Reserved1 : 1; + unsigned int Pack_En : 1; + + + + unsigned int Heap_Idx : 3; + + unsigned int Address_Mode : 1; + unsigned int Reserved : 2; + unsigned int Desc_Buffer_En : 1; + + + + unsigned int Desc_Type : 3; + unsigned int Type : 3; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Blk_Cmd_Csp_Ld_Des; + + + typedef struct _Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword1 + + + { + unsigned int Desc_Base_Addr_Low32 : 32; + } Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword1; + typedef struct _Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword2 + + + { + unsigned int Desc_Base_Addr_High8 : 8; + unsigned int L2_Cachable : 1; + + unsigned int Reserved : 16; + unsigned int Desc_Num : 7; + + + } Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword2; + typedef struct _Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword3 + + + { + unsigned int Buf_Full_Range : 28; + + + unsigned int Reserved : 4; + } Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword3; + typedef struct _Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword4 + + + { + unsigned int Desc_Origin_Offset : 28; + + unsigned int Reserved : 4; + } Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword4; + typedef struct _Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword5 + + + { + unsigned int Desc_Dynamic_Offset : 28; + + unsigned int Reserved : 4; + } Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword5; + typedef struct _Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword6 + + + { + unsigned int Reg_Offset1 : 13; + + unsigned int Reg_Offset2 : 13; + unsigned int Reserved : 6; + } Cmd_Blk_Cmd_Csp_Ld_Des_T_Dword6; + + + + +typedef struct _Cmd_Block_Command_Video +{ + unsigned int Dwc : 15; + unsigned int Irq : 1; + unsigned int External_Fence : 1; + unsigned int Reserved_1 : 2; + unsigned int Fence_Update_Timing : 1; + + unsigned int Reserved_2 : 3; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; + +} Cmd_Block_Command_Video; + + + typedef struct _Cmd_Block_Command_Video_Dword0 + + { + unsigned int Address_Low32 : 32; + } Cmd_Block_Command_Video_Dword0; + typedef struct _Cmd_Block_Command_Video_Dword1 + + { + unsigned int Address_High8 : 8; + + unsigned int Reserved : 24; + } Cmd_Block_Command_Video_Dword1; + typedef struct _Cmd_Block_Command_Video_Dword2 + + { + unsigned int Value : 32; + } Cmd_Block_Command_Video_Dword2; + typedef struct _Cmd_Block_Command_Video_Dword3 + + { + unsigned int Value : 32; + } Cmd_Block_Command_Video_Dword3; + + + + +typedef struct _Cmd_Gp + +{ + unsigned int Dwc : 4; + + unsigned int Wait_Done_En : 1; + + unsigned int Predicate_En : 1; + unsigned int Reserved : 14; + unsigned int Indirect_En : 1; + unsigned int Dw_Type : 1; + unsigned int Minor_Opcode : 1; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; +} Cmd_Gp; + + + typedef struct _Cmd_Gp_Dword1 + { + unsigned int Global_Size_X : 32; + + } Cmd_Gp_Dword1; + typedef struct _Cmd_Gp_Dword2 + { + unsigned int Global_Size_Y : 32; + } Cmd_Gp_Dword2; + typedef struct _Cmd_Gp_Dword3 + { + unsigned int Global_Size_Z : 32; + } Cmd_Gp_Dword3; + typedef struct _Cmd_Gp_Dword4 + { + unsigned int Work_Group_Size_X : 32; + } Cmd_Gp_Dword4; + typedef struct _Cmd_Gp_Dword5 + { + unsigned int Work_Group_Size_Y : 32; + } Cmd_Gp_Dword5; + typedef struct _Cmd_Gp_Dword6 + { + unsigned int Work_Group_Size_Z : 32; + } Cmd_Gp_Dword6; + typedef struct _Cmd_Gp_Dword7 + { + unsigned int Global_Id_Offset_X : 32; + } Cmd_Gp_Dword7; + typedef struct _Cmd_Gp_Dword8 + { + unsigned int Global_Id_Offset_Y : 32; + } Cmd_Gp_Dword8; + typedef struct _Cmd_Gp_Dword9 + { + unsigned int Global_Id_Offset_Z : 32; + } Cmd_Gp_Dword9; + typedef struct _Cmd_Gp_Dword10 + { + unsigned int Shader_Offset : 32; + } Cmd_Gp_Dword10; + typedef struct _Cmd_Gp_Dword11 + { + unsigned int Shader_Range : 32; + } Cmd_Gp_Dword11; + typedef struct _Cmd_Gp_Dword12 + { + unsigned int Argumentaddr_X : 32; + } Cmd_Gp_Dword12; + typedef struct _Cmd_Gp_Dword13 + { + unsigned int Argumentaddr_Y : 32; + } Cmd_Gp_Dword13; + typedef struct _Cmd_Indirect_Gp_Dword1 + { + unsigned int Address_Low32 : 32; + } Cmd_Indirect_Gp_Dword1; + typedef struct _Cmd_Indirect_Gp_Dword2 + { + unsigned int Address_High8 : 8; + unsigned int L2_Cachable : 1; + + unsigned int Reserved : 23; + } Cmd_Indirect_Gp_Dword2; + + + + +typedef struct _Cmd_Tbr_Indicator +{ + unsigned int Reserved : 20; + unsigned int Skip_En : 1; + + + unsigned int Indicator_Info : 2; + unsigned int Block_Id : 5; + unsigned int Major_Opcode : 4; +} Cmd_Tbr_Indicator; + +typedef struct _Cmd_Vpp + +{ + unsigned int Dwf : 3; + unsigned int Reserved : 7; + unsigned int Clear_Mode : 3; + unsigned int Color_Mode : 1; + unsigned int Counter : 11; + unsigned int Auto_Clear : 1; + unsigned int Flush_Blc : 1; + unsigned int Invalidate_Blc : 1; + unsigned int Major_Opcode : 4; +} Cmd_Vpp; + +typedef union Csp_Opcodes_cmds +{ + Cmd_Skip cmd_Skip; + Cmd_Dma cmd_Dma; + Cmd_Wait cmd_Wait; + Cmd_Query_Dump cmd_Query_Dump; + Cmd_Set_Register cmd_Set_Register; + Cmd_Set_Object cmd_Set_Object; + Cmd_Dip cmd_Dip; + Cmd_Fence cmd_Fence; + Cmd_Block_Command_Template cmd_Block_Command_Template; + Cmd_Block_Command_Tas cmd_Block_Command_Tas; + Cmd_Block_Command_Sg cmd_Block_Command_Sg; + Cmd_Block_Command_Img_Trn cmd_Block_Command_Img_Trn; + Cmd_Block_Command_Flush cmd_Block_Command_Flush; + Cmd_Block_Command_Eu cmd_Block_Command_Eu; + Cmd_Block_Command_Tu cmd_Block_Command_Tu; + Cmd_Block_Command_L2 cmd_Block_Command_L2; + Cmd_Block_Command_Mxu cmd_Block_Command_Mxu; + Cmd_Block_Command_Csp cmd_Block_Command_Csp; + Cmd_Blk_Cmd_Csp_Blc cmd_Blk_Cmd_Csp_Blc; + Cmd_Blk_Cmd_Csp_Save_Rsto cmd_Blk_Cmd_Csp_Save_Rsto; + Cmd_Blk_Cmd_Csp_Indicator cmd_Blk_Cmd_Csp_Indicator; + Cmd_Blk_Cmd_Csp_Ld_Des cmd_Blk_Cmd_Csp_Ld_Des; + Cmd_Block_Command_Video cmd_Block_Command_Video; + Cmd_Gp cmd_Gp; + Cmd_Tbr_Indicator cmd_Tbr_Indicator; + Cmd_Vpp cmd_Vpp; + unsigned int uint ; +}Csp_Opcodes_cmd; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/ChipRegisters.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/ChipRegisters.h new file mode 100644 index 0000000000000..a8ece1299c91a --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/ChipRegisters.h @@ -0,0 +1,24 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _CHIPREGISTER_H_ +#define _CHIPREGISTER_H_ + +#include "BlockID.h" +#include "CSP_OPCODE.h" +#include "registerDef.h" +#include "surface_format.h" +#include "registercommands.h" + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/EU_CS_reg.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/EU_CS_reg.h new file mode 100644 index 0000000000000..9c1914832c459 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/EU_CS_reg.h @@ -0,0 +1,505 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _EU_CS_REG_H +#define _EU_CS_REG_H + + +#ifndef EU_CS_BLOCKBASE_INF + #define EU_CS_BLOCKBASE_INF + #define BLOCK_EU_CS_VERSION 1 + #define BLOCK_EU_CS_TIMESTAMP "2018/8/16 16:25:12" + #define EU_CS_BLOCK 0xE + #define EU_CS_REG_START 0x0 + #define EU_CS_REG_END 0x900 + #define EU_CS_REG_LIMIT 0x900 +#endif + + + +#define Reg_Eu_Cs_Glb_Offset 0x1 +#define Reg_Cs_Cfg_Offset 0x2 +#define Reg_Cs_Sm_Cfg_Offset 0x3 +#define Reg_Cs_Pm_Cfg_Offset 0x4 +#define Reg_Cs_Pm_Id_Offset 0x5 +#define Reg_Cs_Pm_Range_Offset 0x6 +#define Reg_Cs_U_Enable_Offset 0x7 +#define Reg_Cs_U_Fmt_Offset 0x9 +#define Reg_Cs_U_Layout_Offset 0x11 +#define Reg_Cs_U_Cfg_Offset 0x13 +#define Reg_Cs_Instr0_Offset 0x14 +#define Reg_Cs_Instr1_Offset 0x15 +#define Reg_Cs_Instr_Range_Offset 0x16 +#define Reg_Cs_Cb_Cfg_Offset 0x17 +#define Reg_Cs_Rev_8aligned_Offset 0x18 +#define Reg_Cs_Rev_Cb_Offset 0x20 +#define Reg_Cs_Cb_Data_Offset 0x100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +typedef enum +{ + CS_CFG_AND_V_MASK_DISABLED = 0, + CS_CFG_AND_V_MASK_ENABLED = 1, + +} CS_CFG_AND_V_MASK; +typedef enum +{ + CS_CFG_RD_MODE_NEAR = 0, + CS_CFG_RD_MODE_ZERO = 1, + CS_CFG_RD_MODE_POS = 2, + CS_CFG_RD_MODE_NEG = 3, +} CS_CFG_RD_MODE; +typedef enum +{ + CS_CFG_FP_MODE_STD_IEEE = 0, + CS_CFG_FP_MODE_NSTD_IEEE = 1, + CS_CFG_FP_MODE_MS_ALT = 2, + CS_CFG_FP_MODE_RESERVED = 3, +} CS_CFG_FP_MODE; +typedef enum +{ + CS_CFG_DENORM_EN_DISABLED = 0, + CS_CFG_DENORM_EN_ENABLED = 1, +} CS_CFG_DENORM_EN; +typedef enum +{ + CS_CFG_THREAD_MODE_SIMD32 = 0, + CS_CFG_THREAD_MODE_SIMD64 = 1, +} CS_CFG_THREAD_MODE; +typedef enum +{ + CS_CFG_PATTERN_MODE_FLAT = 0, + CS_CFG_PATTERN_MODE_LINEAR = 1, + CS_CFG_PATTERN_MODE_TILE = 2, + CS_CFG_PATTERN_MODE_RESERVED = 3, +} CS_CFG_PATTERN_MODE; +typedef enum +{ + CS_CFG_U_SHARP_CACHED_DISABLED = 0, + + CS_CFG_U_SHARP_CACHED_ENABLED = 1, + +} CS_CFG_U_SHARP_CACHED; +typedef enum +{ + CS_SM_CFG_SM_EN_OFF = 0, + CS_SM_CFG_SM_EN_ON = 1, + +} CS_SM_CFG_SM_EN; +typedef enum +{ + CS_PM_CFG_PM_EN_DISABLED = 0, + CS_PM_CFG_PM_EN_ENABLED = 1, +} CS_PM_CFG_PM_EN; +typedef enum +{ + CS_PM_CFG_TH_PM_SIZE_8KDW = 0, + + CS_PM_CFG_TH_PM_SIZE_16KDW = 1, + CS_PM_CFG_TH_PM_SIZE_32KDW = 2, + CS_PM_CFG_TH_PM_SIZE_64KDW = 3, + CS_PM_CFG_TH_PM_SIZE_128KDW = 4, + CS_PM_CFG_TH_PM_SIZE_256KDW = 5, + CS_PM_CFG_TH_PM_SIZE_512KDW = 6, + CS_PM_CFG_TH_PM_SIZE_1024KDW = 7, + CS_PM_CFG_TH_PM_SIZE_1040KDW = 8, +} CS_PM_CFG_TH_PM_SIZE; +typedef enum +{ + CS_U_ENABLE_U0_EN_DISABLE = 0, + CS_U_ENABLE_U0_EN_ENABLE = 1, +} CS_U_ENABLE_U0_EN; +typedef enum +{ + CS_U_FMT_U0_DATA_FMT_FP32 = 0, + CS_U_FMT_U0_DATA_FMT_FP16 = 1, + CS_U_FMT_U0_DATA_FMT_SINT32 = 2, + CS_U_FMT_U0_DATA_FMT_SINT16 = 3, + CS_U_FMT_U0_DATA_FMT_UINT32 = 4, + CS_U_FMT_U0_DATA_FMT_UINT16 = 5, + CS_U_FMT_U0_DATA_FMT_UNORM24 = 6, + CS_U_FMT_U0_DATA_FMT_UNORM16 = 7, + CS_U_FMT_U0_DATA_FMT_UNORM10 = 8, + CS_U_FMT_U0_DATA_FMT_UNORM8 = 9, + CS_U_FMT_U0_DATA_FMT_SINT8 = 10, + CS_U_FMT_U0_DATA_FMT_UINT8 = 11, + CS_U_FMT_U0_DATA_FMT_SNORM8 = 12, + CS_U_FMT_U0_DATA_FMT_SNORM16 = 13, + CS_U_FMT_U0_DATA_FMT_UINT64 = 14, + CS_U_FMT_U0_DATA_FMT_RESERVED = 15, +} CS_U_FMT_U0_DATA_FMT; +typedef enum +{ + CS_U_LAYOUT_U0_LAYOUT_VERTICAL = 0, + CS_U_LAYOUT_U0_LAYOUT_HORIZONTAL = 1, +} CS_U_LAYOUT_U0_LAYOUT; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U_Csh_Base : 5; + + unsigned int Cb_Csh_Base : 6; + + + unsigned int Max_Threads : 8; + + unsigned int Reserved : 13; + } reg; +} Reg_Eu_Cs_Glb; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Crf_Size : 6; + + + unsigned int And_V_Mask : 1; + unsigned int Rd_Mode : 2; + unsigned int Fp_Mode : 2; + unsigned int Denorm_En : 1; + unsigned int Thread_Mode : 1; + + unsigned int Pattern_Mode : 3; + unsigned int Th_Num_In_Group : 6; + + + unsigned int U_Sharp_Cached : 1; + unsigned int Reserved : 9; + } reg; +} Reg_Cs_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Sm_En : 1; + + unsigned int Group_Sm_Size : 16; + + unsigned int Reserved : 15; + } reg; +} Reg_Cs_Sm_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Pm_En : 1; + unsigned int Th_Pm_Size : 4; + + + unsigned int Reserved : 27; + } reg; +} Reg_Cs_Pm_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Pm_U_Id : 32; + + + + } reg; +} Reg_Cs_Pm_Id; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Cs_Idx_Ele_Range : 14; + + + + unsigned int Reserved : 18; + } reg; +} Reg_Cs_Pm_Range; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U0_En : 1; + unsigned int U1_En : 1; + unsigned int U2_En : 1; + unsigned int U3_En : 1; + unsigned int U4_En : 1; + unsigned int U5_En : 1; + unsigned int U6_En : 1; + unsigned int U7_En : 1; + unsigned int U8_En : 1; + unsigned int U9_En : 1; + unsigned int U10_En : 1; + unsigned int U11_En : 1; + unsigned int U12_En : 1; + unsigned int U13_En : 1; + unsigned int U14_En : 1; + unsigned int U15_En : 1; + unsigned int U16_En : 1; + unsigned int U17_En : 1; + unsigned int U18_En : 1; + unsigned int U19_En : 1; + unsigned int U20_En : 1; + unsigned int U21_En : 1; + unsigned int U22_En : 1; + unsigned int U23_En : 1; + unsigned int U24_En : 1; + unsigned int U25_En : 1; + unsigned int U26_En : 1; + unsigned int U27_En : 1; + unsigned int U28_En : 1; + unsigned int U29_En : 1; + unsigned int U30_En : 1; + unsigned int U31_En : 1; + } reg; +} Reg_Cs_U_Enable; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U0_Data_Fmt : 4; + + unsigned int U1_Data_Fmt : 4; + unsigned int U2_Data_Fmt : 4; + unsigned int U3_Data_Fmt : 4; + unsigned int U4_Data_Fmt : 4; + unsigned int U5_Data_Fmt : 4; + unsigned int U6_Data_Fmt : 4; + unsigned int U7_Data_Fmt : 4; + } reg; +} Reg_Cs_U_Fmt; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U0_Layout : 1; + unsigned int U1_Layout : 1; + unsigned int U2_Layout : 1; + unsigned int U3_Layout : 1; + unsigned int U4_Layout : 1; + unsigned int U5_Layout : 1; + unsigned int U6_Layout : 1; + unsigned int U7_Layout : 1; + unsigned int U8_Layout : 1; + unsigned int U9_Layout : 1; + unsigned int U10_Layout : 1; + unsigned int U11_Layout : 1; + unsigned int U12_Layout : 1; + unsigned int U13_Layout : 1; + unsigned int U14_Layout : 1; + unsigned int U15_Layout : 1; + unsigned int U16_Layout : 1; + unsigned int U17_Layout : 1; + unsigned int U18_Layout : 1; + unsigned int U19_Layout : 1; + unsigned int U20_Layout : 1; + unsigned int U21_Layout : 1; + unsigned int U22_Layout : 1; + unsigned int U23_Layout : 1; + unsigned int U24_Layout : 1; + unsigned int U25_Layout : 1; + unsigned int U26_Layout : 1; + unsigned int U27_Layout : 1; + unsigned int U28_Layout : 1; + unsigned int U29_Layout : 1; + unsigned int U30_Layout : 1; + unsigned int U31_Layout : 1; + } reg; +} Reg_Cs_U_Layout; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Cs_U_Range : 8; + + unsigned int Reserved : 24; + } reg; +} Reg_Cs_U_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_Low : 32; + + } reg; +} Reg_Cs_Instr0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_High : 8; + + unsigned int Reserved : 24; + } reg; +} Reg_Cs_Instr1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ins_Range : 16; + + unsigned int Reserved : 16; + } reg; +} Reg_Cs_Instr_Range; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Cs_Cb_Range : 9; + + unsigned int Reserved : 23; + } reg; +} Reg_Cs_Cb_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Cs_Rev_8aligned; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Cs_Rev_Cb; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Const : 32; + } reg; +} Reg_Cs_Cb_Data; + +typedef struct _Eu_Cs_regs +{ + Reg_Eu_Full_Glb reg_Eu_Full_Glb; + Reg_Eu_Cs_Glb reg_Eu_Cs_Glb; + Reg_Cs_Cfg reg_Cs_Cfg; + Reg_Cs_Sm_Cfg reg_Cs_Sm_Cfg; + Reg_Cs_Pm_Cfg reg_Cs_Pm_Cfg; + Reg_Cs_Pm_Id reg_Cs_Pm_Id; + Reg_Cs_Pm_Range reg_Cs_Pm_Range; + Reg_Cs_U_Enable reg_Cs_U_Enable[2]; + Reg_Cs_U_Fmt reg_Cs_U_Fmt[8]; + Reg_Cs_U_Layout reg_Cs_U_Layout[2]; + Reg_Cs_U_Cfg reg_Cs_U_Cfg; + Reg_Cs_Instr0 reg_Cs_Instr0; + Reg_Cs_Instr1 reg_Cs_Instr1; + Reg_Cs_Instr_Range reg_Cs_Instr_Range; + Reg_Cs_Cb_Cfg reg_Cs_Cb_Cfg; + Reg_Cs_Rev_8aligned reg_Cs_Rev_8aligned[8]; + Reg_Cs_Rev_Cb reg_Cs_Rev_Cb[224]; + Reg_Cs_Cb_Data reg_Cs_Cb_Data[2048]; +} Eu_Cs_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/EU_FS_reg.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/EU_FS_reg.h new file mode 100644 index 0000000000000..8cba7d5b9e7ce --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/EU_FS_reg.h @@ -0,0 +1,1657 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _EU_FS_REG_H +#define _EU_FS_REG_H + + +#ifndef EU_FS_BLOCKBASE_INF + #define EU_FS_BLOCKBASE_INF + #define BLOCK_EU_FS_VERSION 1 + #define BLOCK_EU_FS_TIMESTAMP "2018/8/27 15:59:05" + #define EU_FS_BLOCK 0x3 + #define EU_FS_REG_START 0x0 + #define EU_FS_REG_END 0x900 + #define EU_FS_REG_LIMIT 0xAC0 +#endif + + +#define Reg_Eu_Full_Glb_Offset 0x0 +#define Reg_Eu_3d_Glb_Offset 0x1 +#define Reg_Eu_Fe_Glb_Offset 0x2 +#define Reg_Mv_Cfg_Offset 0x3 +#define Reg_Vc_Size_Cfg0_Offset 0x4 +#define Reg_Vc_Size_Cfg1_Offset 0x5 +#define Reg_Vc_Base_Cfg0_Offset 0x6 +#define Reg_Vc_Base_Cfg1_Offset 0x7 +#define Reg_Fs_Cfg_Offset 0x8 +#define Reg_Max_Threads_Cfg_Offset 0x9 +#define Reg_Antilock_Cfg_Offset 0xA +#define Reg_Vs_Ctrl_Offset 0xB +#define Reg_Hs_Ctrl_Offset 0xC +#define Reg_Hs_In_Cfg_Offset 0xD +#define Reg_Hs_Out_Cfg_Offset 0xE +#define Reg_Ds_Ctrl_Offset 0xF +#define Reg_Ds_In_Cfg_Offset 0x10 +#define Reg_Gs_Ctrl_Offset 0x11 +#define Reg_Gs_In_Cfg_Offset 0x12 +#define Reg_Gs_Out_Cfg_Offset 0x13 +#define Reg_Ts_Ctrl_Offset 0x14 +#define Reg_Ts_Input_Mapping0_Offset 0x15 +#define Reg_Ts_Input_Mapping1_Offset 0x16 +#define Reg_Ts_Factors_Const_Offset 0x17 +#define Reg_Fs_Cs_Ctrl_Offset 0x1D +#define Reg_Fs_Cs_Sm_Cfg_Offset 0x1E +#define Reg_Fs_Out_Loc0_Offset 0x1F +#define Reg_Fs_Out_Loc1_Offset 0x20 +#define Reg_Fs_Out_Mapping_Offset 0x21 +#define Reg_Fs_Out_Comp_Offset 0x2D +#define Reg_Fs_Out_Mask_Offset 0x30 +#define Reg_Fs_Pm_Cfg_Offset 0x36 +#define Reg_Fs_Pm_Id_Offset 0x37 +#define Reg_Vgs_Pm_Range_Offset 0x38 +#define Reg_Hds_Pm_Range_Offset 0x39 +#define Reg_Fs_U_Enable_Offset 0x3A +#define Reg_Fs_U_Fmt_Offset 0x3E +#define Reg_Fs_U_Layout_Offset 0x4E +#define Reg_Vcs_U_Cfg_Offset 0x52 +#define Reg_Hs_U_Cfg_Offset 0x53 +#define Reg_Ds_U_Cfg_Offset 0x54 +#define Reg_Gs_U_Cfg_Offset 0x55 +#define Reg_Vcs_Instr0_Offset 0x56 +#define Reg_Vcs_Instr1_Offset 0x57 +#define Reg_Vcs_Instr_Range_Offset 0x58 +#define Reg_Hs_Instr0_Offset 0x59 +#define Reg_Hs_Instr1_Offset 0x5A +#define Reg_Hs_Instr_Range_Offset 0x5B +#define Reg_Ds_Instr0_Offset 0x5C +#define Reg_Ds_Instr1_Offset 0x5D +#define Reg_Ds_Instr_Range_Offset 0x5E +#define Reg_Gs_Instr0_Offset 0x5F +#define Reg_Gs_Instr1_Offset 0x60 +#define Reg_Gs_Instr_Range_Offset 0x61 +#define Reg_Vcs_Cb_Cfg_Offset 0x62 +#define Reg_Hs_Cb_Cfg_Offset 0x63 +#define Reg_Ds_Cb_Cfg_Offset 0x64 +#define Reg_Gs_Cb_Cfg_Offset 0x65 +#define Reg_Fs_Cb_Cfg_Offset 0x66 +#define Reg_Fs_Rev_8aligned_Offset 0x67 +#define Reg_Fs_Rev_Cb_Offset 0x68 +#define Reg_Fs_Cb_Data_Offset 0x100 +#define Reg_Dbg_Cfg_Offset 0x900 +#define Reg_Dbg_Bp_Stat_Offset 0x920 +#define Reg_Dbg_Bp_Pc_Offset 0x940 +#define Reg_Dbg_Int_Instr_Offset 0xA40 +#define Reg_Dbg_Res_Instr_Offset 0xA60 +#define Reg_Dbg_Time_Stamp_Offset 0xA80 + + +typedef enum +{ + EU_FULL_GLB_SHADER_DBG_EN_DISABLED = 0, + EU_FULL_GLB_SHADER_DBG_EN_ENABLED = 1, + +} EU_FULL_GLB_SHADER_DBG_EN; +typedef enum +{ + EU_FULL_GLB_THD_SLOT_SIZE_8THD_SLOT = 0, + EU_FULL_GLB_THD_SLOT_SIZE_4THD_SLOT = 1, + EU_FULL_GLB_THD_SLOT_SIZE_2THD_SLOT = 2, + EU_FULL_GLB_THD_SLOT_SIZE_RESERVED = 3, +} EU_FULL_GLB_THD_SLOT_SIZE; +typedef enum +{ + EU_FULL_GLB_UAV_CONTINUE_CHK_DISABLED = 0, + + EU_FULL_GLB_UAV_CONTINUE_CHK_ENABLED = 1, + +} EU_FULL_GLB_UAV_CONTINUE_CHK; +typedef enum +{ + EU_FULL_GLB_UAV_BUF_SIZE_0LINES = 0, + EU_FULL_GLB_UAV_BUF_SIZE_16LINES = 4, + EU_FULL_GLB_UAV_BUF_SIZE_32LINES = 5, + EU_FULL_GLB_UAV_BUF_SIZE_64LINES = 6, + EU_FULL_GLB_UAV_BUF_SIZE_128LINES = 7, +} EU_FULL_GLB_UAV_BUF_SIZE; +typedef enum +{ + EU_FULL_GLB_IC_TO_L2_DISABLED = 0, + EU_FULL_GLB_IC_TO_L2_ENABLED = 1, + +} EU_FULL_GLB_IC_TO_L2; +typedef enum +{ + EU_3D_GLB_U_SHARP_CACHED_DISABLED = 0, + + EU_3D_GLB_U_SHARP_CACHED_ENABLED = 1, + +} EU_3D_GLB_U_SHARP_CACHED; +typedef enum +{ + EU_FE_GLB_CS_ON_OFF = 0, + EU_FE_GLB_CS_ON_ON = 1, +} EU_FE_GLB_CS_ON; +typedef enum +{ + EU_FE_GLB_VS_ON_OFF = 0, + EU_FE_GLB_VS_ON_ON = 1, +} EU_FE_GLB_VS_ON; +typedef enum +{ + EU_FE_GLB_TESS_ON_OFF = 0, + EU_FE_GLB_TESS_ON_ON = 1, +} EU_FE_GLB_TESS_ON; +typedef enum +{ + EU_FE_GLB_GS_ON_OFF = 0, + EU_FE_GLB_GS_ON_ON = 1, +} EU_FE_GLB_GS_ON; +typedef enum +{ + EU_FE_GLB_FS_LAST_VS = 0, + EU_FE_GLB_FS_LAST_HS = 1, + EU_FE_GLB_FS_LAST_DS = 2, + EU_FE_GLB_FS_LAST_GS = 3, + EU_FE_GLB_FS_LAST_PS = 4, + EU_FE_GLB_FS_LAST_CS = 5, +} EU_FE_GLB_FS_LAST; +typedef enum +{ + EU_FE_GLB_OUT_RAST_EN_DISABLE = 0, + EU_FE_GLB_OUT_RAST_EN_ENABLE = 1, +} EU_FE_GLB_OUT_RAST_EN; +typedef enum +{ + EU_FE_GLB_STO_EN_DISABLED = 0, + EU_FE_GLB_STO_EN_ENABLED = 1, + +} EU_FE_GLB_STO_EN; +typedef enum +{ + EU_FE_GLB_OGL_EN_DX = 0, + EU_FE_GLB_OGL_EN_OGL = 1, +} EU_FE_GLB_OGL_EN; +typedef enum +{ + EU_FE_GLB_TAS_AB_SIZE_CFG_HOLD_8VTX = 0, + EU_FE_GLB_TAS_AB_SIZE_CFG_HOLD_16VTX = 1, +} EU_FE_GLB_TAS_AB_SIZE_CFG; +typedef enum +{ + MV_CFG_MV_EN_DISABLE = 0, + MV_CFG_MV_EN_ENABLE = 1, +} MV_CFG_MV_EN; +typedef enum +{ + FS_CFG_AND_V_MASK_DISABLED = 0, + FS_CFG_AND_V_MASK_ENABLED = 1, + +} FS_CFG_AND_V_MASK; +typedef enum +{ + FS_CFG_RD_MODE_NEAR = 0, + FS_CFG_RD_MODE_ZERO = 1, + FS_CFG_RD_MODE_POS = 2, + FS_CFG_RD_MODE_NEG = 3, +} FS_CFG_RD_MODE; +typedef enum +{ + FS_CFG_FP_MODE_STD_IEEE = 0, + FS_CFG_FP_MODE_NSTD_IEEE = 1, + FS_CFG_FP_MODE_MS_ALT = 2, + FS_CFG_FP_MODE_RESERVED = 3, +} FS_CFG_FP_MODE; +typedef enum +{ + FS_CFG_DENORM_EN_DISABLED = 0, + FS_CFG_DENORM_EN_ENABLED = 1, +} FS_CFG_DENORM_EN; +typedef enum +{ + ANTILOCK_CFG_ANTILOCK_TO_EN_DISABLED = 0, + ANTILOCK_CFG_ANTILOCK_TO_EN_ENABLED = 1, + +} ANTILOCK_CFG_ANTILOCK_TO_EN; +typedef enum +{ + ANTILOCK_CFG_ACCUR_KICKOFF_EN_DISABLED = 0, + + ANTILOCK_CFG_ACCUR_KICKOFF_EN_ENABLED = 1, + +} ANTILOCK_CFG_ACCUR_KICKOFF_EN; +typedef enum +{ + VS_CTRL_VID_EN_VID_NONE = 0, + VS_CTRL_VID_EN_VID_AV = 1, +} VS_CTRL_VID_EN; +typedef enum +{ + VS_CTRL_IID_EN_IID_NONE = 0, + VS_CTRL_IID_EN_IID_AV = 1, +} VS_CTRL_IID_EN; +typedef enum +{ + VS_CTRL_HITTEST_DISABLE_ENABLED = 0, + + VS_CTRL_HITTEST_DISABLE_DISABLED = 1, + VS_CTRL_HITTEST_DISABLE_RESERVED = 2, +} VS_CTRL_HITTEST_DISABLE; +typedef enum +{ + VS_CTRL_SIMD_NUM_1_LANE = 0, + VS_CTRL_SIMD_NUM_2_LANE = 1, + VS_CTRL_SIMD_NUM_4_LANE = 2, + VS_CTRL_SIMD_NUM_8_LANE = 3, + VS_CTRL_SIMD_NUM_16_LANE = 4, + VS_CTRL_SIMD_NUM_32_LANE = 5, +} VS_CTRL_SIMD_NUM; +typedef enum +{ + HS_CTRL_PID_EN_PID_NONE = 0, + HS_CTRL_PID_EN_PID_AV = 1, +} HS_CTRL_PID_EN; +typedef enum +{ + HS_CTRL_SIMD_NUM_1_LANE = 0, + HS_CTRL_SIMD_NUM_2_LANE = 1, + HS_CTRL_SIMD_NUM_4_LANE = 2, + HS_CTRL_SIMD_NUM_8_LANE = 3, + HS_CTRL_SIMD_NUM_16_LANE = 4, + HS_CTRL_SIMD_NUM_32_LANE = 5, +} HS_CTRL_SIMD_NUM; +typedef enum +{ + HS_CTRL_CPPC_OUT_MODE_BOTH_ON = 0, + HS_CTRL_CPPC_OUT_MODE_CP_OFF_PC_ON = 1, + + HS_CTRL_CPPC_OUT_MODE_BOTH_OFF = 2, + + HS_CTRL_CPPC_OUT_MODE_RESERVED = 3, +} HS_CTRL_CPPC_OUT_MODE; +typedef enum +{ + DS_CTRL_DOM_EN_DOM_NONE = 0, + DS_CTRL_DOM_EN_DOM_AV = 1, +} DS_CTRL_DOM_EN; +typedef enum +{ + DS_CTRL_PID_EN_PID_NONE = 0, + DS_CTRL_PID_EN_PID_AV = 1, +} DS_CTRL_PID_EN; +typedef enum +{ + DS_CTRL_HITTEST_DIS_ENABLED = 0, + + DS_CTRL_HITTEST_DIS_DISABLED = 1, + DS_CTRL_HITTEST_DIS_RESERVED = 2, +} DS_CTRL_HITTEST_DIS; +typedef enum +{ + DS_CTRL_SIMD_NUM_1_LANE = 0, + DS_CTRL_SIMD_NUM_2_LANE = 1, + DS_CTRL_SIMD_NUM_4_LANE = 2, + DS_CTRL_SIMD_NUM_8_LANE = 3, + DS_CTRL_SIMD_NUM_16_LANE = 4, + DS_CTRL_SIMD_NUM_32_LANE = 5, +} DS_CTRL_SIMD_NUM; +typedef enum +{ + GS_CTRL_PID_EN_PID_NONE = 0, + GS_CTRL_PID_EN_PID_AV = 1, +} GS_CTRL_PID_EN; +typedef enum +{ + GS_CTRL_INST_EN_INST_NONE = 0, + GS_CTRL_INST_EN_INST_AV = 1, +} GS_CTRL_INST_EN; +typedef enum +{ + GS_CTRL_SIMD_NUM_1_LANE = 0, + GS_CTRL_SIMD_NUM_2_LANE = 1, + GS_CTRL_SIMD_NUM_4_LANE = 2, + GS_CTRL_SIMD_NUM_8_LANE = 3, + GS_CTRL_SIMD_NUM_16_LANE = 4, + GS_CTRL_SIMD_NUM_32_LANE = 5, +} GS_CTRL_SIMD_NUM; +typedef enum +{ + GS_OUT_CFG_OUT_PRIM_TYPE_POINTLIST = 0, + GS_OUT_CFG_OUT_PRIM_TYPE_LINESTRIP = 1, + GS_OUT_CFG_OUT_PRIM_TYPE_TRIANGLESTRIP = 2, + GS_OUT_CFG_OUT_PRIM_TYPE_LINESTRIP_ADJ = 3, + GS_OUT_CFG_OUT_PRIM_TYPE_TRIANGLESTRIP_ADJ= 4, + GS_OUT_CFG_OUT_PRIM_TYPE_TRIANGLELIST_ADJ= 5, + GS_OUT_CFG_OUT_PRIM_TYPE_PATCHLIST = 6, + GS_OUT_CFG_OUT_PRIM_TYPE_AA_RECT = 7, +} GS_OUT_CFG_OUT_PRIM_TYPE; +typedef enum +{ + TS_CTRL_DOMAIN_TRIANGLE = 0, + TS_CTRL_DOMAIN_QUAD = 1, + TS_CTRL_DOMAIN_ISOLINE = 2, + TS_CTRL_DOMAIN_RESERVED = 3, +} TS_CTRL_DOMAIN; +typedef enum +{ + TS_CTRL_PARTITIONING_INTEGER = 0, + TS_CTRL_PARTITIONING_POW2 = 1, + TS_CTRL_PARTITIONING_FRAC_ODD = 2, + TS_CTRL_PARTITIONING_FRAC_EVEN = 3, +} TS_CTRL_PARTITIONING; +typedef enum +{ + TS_CTRL_TF_REDU_MODE_REV_MIN = 0, + TS_CTRL_TF_REDU_MODE_REV_MAX = 1, + TS_CTRL_TF_REDU_MODE_REV_AVG = 2, + TS_CTRL_TF_REDU_MODE_REV_RESERVED = 3, +} TS_CTRL_TF_REDU_MODE_REV; +typedef enum +{ + TS_CTRL_TF_REDU_AXIS_REV_1_AXIS = 0, + TS_CTRL_TF_REDU_AXIS_REV_2_AXIS = 1, +} TS_CTRL_TF_REDU_AXIS_REV; +typedef enum +{ + TS_CTRL_TOPOLOGY_POINT = 0, + TS_CTRL_TOPOLOGY_LINE = 1, + TS_CTRL_TOPOLOGY_TRIANGLE_CW = 2, + TS_CTRL_TOPOLOGY_TRIANGLE_CCW = 3, +} TS_CTRL_TOPOLOGY; +typedef enum +{ + TS_INPUT_MAPPING0_TF0_EN_DISABLED = 0, + TS_INPUT_MAPPING0_TF0_EN_ENABLED = 1, +} TS_INPUT_MAPPING0_TF0_EN; +typedef enum +{ + TS_INPUT_MAPPING0_TF1_EN_DISABLED = 0, + TS_INPUT_MAPPING0_TF1_EN_ENABLED = 1, +} TS_INPUT_MAPPING0_TF1_EN; +typedef enum +{ + TS_INPUT_MAPPING0_TF2_EN_DISABLED = 0, + TS_INPUT_MAPPING0_TF2_EN_ENABLED = 1, +} TS_INPUT_MAPPING0_TF2_EN; +typedef enum +{ + TS_INPUT_MAPPING1_TF3_EN_DISABLED = 0, + TS_INPUT_MAPPING1_TF3_EN_ENABLED = 1, +} TS_INPUT_MAPPING1_TF3_EN; +typedef enum +{ + TS_INPUT_MAPPING1_TF4_EN_DISABLED = 0, + TS_INPUT_MAPPING1_TF4_EN_ENABLED = 1, +} TS_INPUT_MAPPING1_TF4_EN; +typedef enum +{ + TS_INPUT_MAPPING1_TF5_EN_DISABLED = 0, + TS_INPUT_MAPPING1_TF5_EN_ENABLED = 1, +} TS_INPUT_MAPPING1_TF5_EN; +typedef enum +{ + FS_CS_CTRL_THREAD_MODE_SIMD32 = 0, + FS_CS_CTRL_THREAD_MODE_SIMD64 = 1, +} FS_CS_CTRL_THREAD_MODE; +typedef enum +{ + FS_CS_CTRL_PATTERN_MODE_FLAT = 0, + FS_CS_CTRL_PATTERN_MODE_LINEAR = 1, + FS_CS_CTRL_PATTERN_MODE_TILE = 2, + FS_CS_CTRL_PATTERN_MODE_RESERVED = 3, +} FS_CS_CTRL_PATTERN_MODE; +typedef enum +{ + FS_CS_SM_CFG_SM_EN_OFF = 0, + FS_CS_SM_CFG_SM_EN_ON = 1, + +} FS_CS_SM_CFG_SM_EN; +typedef enum +{ + FS_OUT_LOC0_OUT_LOC_SEPARATED = 0, + + FS_OUT_LOC0_OUT_LOC_SHARED = 1, + +} FS_OUT_LOC0_OUT_LOC; +typedef enum +{ + FS_OUT_LOC1_OUT_LOC_SEPARATED = 0, + + FS_OUT_LOC1_OUT_LOC_SHARED = 1, + +} FS_OUT_LOC1_OUT_LOC; +typedef enum +{ + FS_PM_CFG_PM_EN_DISABLED = 0, + + FS_PM_CFG_PM_EN_ENABLED = 1, +} FS_PM_CFG_PM_EN; +typedef enum +{ + FS_PM_CFG_TH_PM_SIZE_8KDW = 0, + + FS_PM_CFG_TH_PM_SIZE_16KDW = 1, + FS_PM_CFG_TH_PM_SIZE_32KDW = 2, + FS_PM_CFG_TH_PM_SIZE_64KDW = 3, + FS_PM_CFG_TH_PM_SIZE_128KDW = 4, + FS_PM_CFG_TH_PM_SIZE_256KDW = 5, + FS_PM_CFG_TH_PM_SIZE_512KDW = 6, + FS_PM_CFG_TH_PM_SIZE_1024KDW = 7, + FS_PM_CFG_TH_PM_SIZE_1040KDW = 8, +} FS_PM_CFG_TH_PM_SIZE; +typedef enum +{ + FS_U_ENABLE_U0_EN_DISABLE = 0, + FS_U_ENABLE_U0_EN_ENABLE = 1, +} FS_U_ENABLE_U0_EN; +typedef enum +{ + FS_U_FMT_U0_DATA_FMT_FP32 = 0, + FS_U_FMT_U0_DATA_FMT_FP16 = 1, + FS_U_FMT_U0_DATA_FMT_SINT32 = 2, + FS_U_FMT_U0_DATA_FMT_SINT16 = 3, + FS_U_FMT_U0_DATA_FMT_UINT32 = 4, + FS_U_FMT_U0_DATA_FMT_UINT16 = 5, + FS_U_FMT_U0_DATA_FMT_UNORM24 = 6, + FS_U_FMT_U0_DATA_FMT_UNORM16 = 7, + FS_U_FMT_U0_DATA_FMT_UNORM10 = 8, + FS_U_FMT_U0_DATA_FMT_UNORM8 = 9, + FS_U_FMT_U0_DATA_FMT_SINT8 = 10, + FS_U_FMT_U0_DATA_FMT_UINT8 = 11, + FS_U_FMT_U0_DATA_FMT_SNORM8 = 12, + FS_U_FMT_U0_DATA_FMT_SNORM16 = 13, + FS_U_FMT_U0_DATA_FMT_UINT64 = 14, + FS_U_FMT_U0_DATA_FMT_RESERVED = 15, +} FS_U_FMT_U0_DATA_FMT; +typedef enum +{ + FS_U_LAYOUT_U0_LAYOUT_VERTICAL = 0, + FS_U_LAYOUT_U0_LAYOUT_HORIZONTAL = 1, +} FS_U_LAYOUT_U0_LAYOUT; +typedef enum +{ + DBG_CFG_EXEC_EN_DISABLED = 0, + + + DBG_CFG_EXEC_EN_ENABLED = 1, + +} DBG_CFG_EXEC_EN; +typedef enum +{ + DBG_CFG_TH_MODE_SINGLE = 0, + + DBG_CFG_TH_MODE_ALL = 1, +} DBG_CFG_TH_MODE; +typedef enum +{ + DBG_CFG_INT_EN_DISABLED = 0, + + DBG_CFG_INT_EN_ENABLED = 1, + + +} DBG_CFG_INT_EN; +typedef enum +{ + DBG_CFG_RES_EN_DISABLED = 0, + + DBG_CFG_RES_EN_ENABLED = 1, + + +} DBG_CFG_RES_EN; +typedef enum +{ + DBG_BP_STAT_BP_HIT_DISABLED = 0, + + DBG_BP_STAT_BP_HIT_ENABLED = 1, + + +} DBG_BP_STAT_BP_HIT; +typedef enum +{ + DBG_BP_PC_BP_VALID_DISABLED = 0, + DBG_BP_PC_BP_VALID_ENABLED = 1, +} DBG_BP_PC_BP_VALID; +typedef enum +{ + DBG_BP_PC_SHADER_VS = 0, + DBG_BP_PC_SHADER_HS = 1, + DBG_BP_PC_SHADER_DS = 2, + DBG_BP_PC_SHADER_GS = 3, + DBG_BP_PC_SHADER_PS = 4, + DBG_BP_PC_SHADER_CS = 5, +} DBG_BP_PC_SHADER; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Shader_Dbg_En : 1; + unsigned int Thd_Slot_Size : 2; + + unsigned int Uav_En : 1; + + unsigned int Uav_Continue_Chk : 1; + unsigned int Uav_Buf_Size : 4; + + + + unsigned int U_3d_Base : 5; + + + + unsigned int Cb_3d_Base : 6; + + + + unsigned int Ic_To_L2 : 1; + + unsigned int Reserved : 11; + } reg; +} Reg_Eu_Full_Glb; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U_Ps_Base : 5; + + unsigned int Cb_Ps_Base : 6; + + + unsigned int U_Sharp_Cached : 1; + unsigned int Reserved : 20; + } reg; +} Reg_Eu_3d_Glb; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Cs_On : 1; + unsigned int Vs_On : 1; + unsigned int Tess_On : 1; + unsigned int Gs_On : 1; + unsigned int Fs_Last : 3; + + unsigned int Out_Rast_En : 1; + unsigned int Sto_En : 1; + unsigned int Rast_Sel : 2; + + unsigned int Ogl_En : 1; + + unsigned int Tas_Ab_Size_Cfg : 1; + + unsigned int Reserved : 19; + } reg; +} Reg_Eu_Fe_Glb; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Mv_En : 1; + unsigned int Mv_Num : 4; + + unsigned int Mv_Shared_Size : 6; + + unsigned int Reserved : 21; + } reg; +} Reg_Mv_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vs_Vc_Size : 16; + + unsigned int Hs_Vc_Size : 16; + + } reg; +} Reg_Vc_Size_Cfg0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ds_Vc_Size : 16; + + unsigned int Gs_Vc_Size : 16; + + } reg; +} Reg_Vc_Size_Cfg1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vs_Vc_Base : 16; + + unsigned int Hs_Vc_Base : 16; + + } reg; +} Reg_Vc_Base_Cfg0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ds_Vc_Base : 16; + + unsigned int Gs_Vc_Base : 16; + + } reg; +} Reg_Vc_Base_Cfg1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int And_V_Mask : 1; + unsigned int Rd_Mode : 2; + unsigned int Fp_Mode : 2; + unsigned int Denorm_En : 1; + unsigned int Reserved : 26; + } reg; +} Reg_Fs_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vcs_Max_Threads : 8; + + + unsigned int Hs_Max_Threads : 8; + + unsigned int Ds_Max_Threads : 8; + + unsigned int Gs_Max_Threads : 8; + + } reg; +} Reg_Max_Threads_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vs_Antilock_Timeout : 4; + + + + + + unsigned int Hs_Antilock_Timeout : 4; + + + + + + unsigned int Ds_Antilock_Timeout : 4; + + + + + + unsigned int Gs_Antilock_Timeout : 4; + + + + + + unsigned int Antilock_To_En : 1; + + unsigned int Accur_Kickoff_En : 1; + + unsigned int Reserved : 14; + } reg; +} Reg_Antilock_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Crf_Size : 6; + + + unsigned int In_Size : 6; + + unsigned int Out_Size : 6; + + unsigned int Vid_En : 1; + + + unsigned int Iid_En : 1; + + + unsigned int Hittest_Disable : 2; + + unsigned int Simd_Num : 3; + unsigned int Reserved : 7; + } reg; +} Reg_Vs_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Crf_Size : 6; + + + unsigned int Pid_En : 1; + + + unsigned int Simd_Num : 3; + unsigned int Cppc_Out_Mode : 2; + unsigned int Reserved : 20; + } reg; +} Reg_Hs_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Input_Cp_Num : 6; + + unsigned int Input_Cp_Size : 6; + + unsigned int Reserved : 20; + } reg; +} Reg_Hs_In_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Output_Cp_Num : 6; + + unsigned int Output_Cp_Size : 6; + + unsigned int Output_Pc_Size : 6; + + unsigned int Out_Patch_Size : 11; + + + unsigned int Reserved : 3; + } reg; +} Reg_Hs_Out_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Crf_Size : 6; + + + unsigned int Out_Size : 6; + + unsigned int Dom_En : 1; + + + unsigned int Pid_En : 1; + + + unsigned int Hittest_Dis : 2; + + unsigned int Simd_Num : 3; + unsigned int Reserved : 13; + } reg; +} Reg_Ds_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Input_Cp_Num : 6; + + unsigned int Input_Cp_Size : 6; + + unsigned int Input_Pc_Size : 6; + + unsigned int Reserved : 14; + } reg; +} Reg_Ds_In_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Crf_Size : 6; + + + unsigned int Pid_En : 1; + + + unsigned int Inst_En : 1; + + + unsigned int Instance_Cnt : 6; + + + + unsigned int Simd_Num : 3; + unsigned int Reserved : 13; + } reg; +} Reg_Gs_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int In_Size : 6; + + unsigned int In_Vtx_Num : 6; + + unsigned int Reserved : 20; + } reg; +} Reg_Gs_In_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Out_Size : 6; + + unsigned int Out_Vtx_Num : 11; + + + unsigned int Out_Prim_Size : 9; + + + unsigned int Out_Prim_Type : 4; + + unsigned int Reserved : 2; + } reg; +} Reg_Gs_Out_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vtx_Split_Cnt : 6; + unsigned int Domain : 2; + unsigned int Partitioning : 2; + unsigned int Tf_Redu_Mode_Rev : 2; + unsigned int Tf_Redu_Axis_Rev : 1; + + unsigned int Topology : 2; + unsigned int Reserved : 17; + } reg; +} Reg_Ts_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Tf0_Addr : 6; + + unsigned int Tf0_Comp_Addr : 2; + + unsigned int Tf0_En : 1; + unsigned int Tf1_Addr : 6; + + unsigned int Tf1_Comp_Addr : 2; + + unsigned int Tf1_En : 1; + unsigned int Tf2_Addr : 6; + + unsigned int Tf2_Comp_Addr : 2; + + unsigned int Tf2_En : 1; + unsigned int Reserved : 5; + } reg; +} Reg_Ts_Input_Mapping0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Tf3_Addr : 6; + + unsigned int Tf3_Comp_Addr : 2; + + unsigned int Tf3_En : 1; + unsigned int Tf4_Addr : 6; + + unsigned int Tf4_Comp_Addr : 2; + + unsigned int Tf4_En : 1; + unsigned int Tf5_Addr : 6; + + unsigned int Tf5_Comp_Addr : 2; + + unsigned int Tf5_En : 1; + unsigned int Reserved : 5; + } reg; +} Reg_Ts_Input_Mapping1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Factor : 32; + + } reg; +} Reg_Ts_Factors_Const; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Crf_Size : 6; + + + unsigned int Reserved0 : 6; + + unsigned int Thread_Mode : 1; + + unsigned int Pattern_Mode : 3; + unsigned int Th_Num_In_Group : 6; + + + unsigned int Reserved : 10; + } reg; +} Reg_Fs_Cs_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Sm_En : 1; + + unsigned int Group_Sm_Size : 16; + + unsigned int Reserved : 15; + } reg; +} Reg_Fs_Cs_Sm_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Out_Loc : 32; + + + } reg; +} Reg_Fs_Out_Loc0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Out_Loc : 16; + + + unsigned int Reserved : 16; + } reg; +} Reg_Fs_Out_Loc1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int O0_Addr : 6; + + + unsigned int O1_Addr : 6; + unsigned int O2_Addr : 6; + unsigned int O3_Addr : 6; + unsigned int Reserved : 8; + } reg; +} Reg_Fs_Out_Mapping; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int O0_Comp_Id : 2; + + + unsigned int O1_Comp_Id : 2; + unsigned int O2_Comp_Id : 2; + unsigned int O3_Comp_Id : 2; + unsigned int O4_Comp_Id : 2; + unsigned int O5_Comp_Id : 2; + unsigned int O6_Comp_Id : 2; + unsigned int O7_Comp_Id : 2; + unsigned int O8_Comp_Id : 2; + unsigned int O9_Comp_Id : 2; + unsigned int O10_Comp_Id : 2; + unsigned int O11_Comp_Id : 2; + unsigned int O12_Comp_Id : 2; + unsigned int O13_Comp_Id : 2; + unsigned int O14_Comp_Id : 2; + unsigned int O15_Comp_Id : 2; + } reg; +} Reg_Fs_Out_Comp; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int O0_Mask : 4; + + unsigned int O1_Mask : 4; + unsigned int O2_Mask : 4; + unsigned int O3_Mask : 4; + unsigned int O4_Mask : 4; + unsigned int O5_Mask : 4; + unsigned int O6_Mask : 4; + unsigned int O7_Mask : 4; + } reg; +} Reg_Fs_Out_Mask; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Pm_En : 1; + unsigned int Th_Pm_Size : 4; + + + unsigned int Reserved : 27; + } reg; +} Reg_Fs_Pm_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Pm_U_Id : 32; + + + + } reg; +} Reg_Fs_Pm_Id; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vcs_Idx_Ele_Range : 14; + + + + unsigned int Gs_Idx_Ele_Range : 14; + + unsigned int Reserved : 4; + } reg; +} Reg_Vgs_Pm_Range; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Hs_Idx_Ele_Range : 14; + + unsigned int Ds_Idx_Ele_Range : 14; + + unsigned int Reserved : 4; + } reg; +} Reg_Hds_Pm_Range; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U0_En : 1; + unsigned int U1_En : 1; + unsigned int U2_En : 1; + unsigned int U3_En : 1; + unsigned int U4_En : 1; + unsigned int U5_En : 1; + unsigned int U6_En : 1; + unsigned int U7_En : 1; + unsigned int U8_En : 1; + unsigned int U9_En : 1; + unsigned int U10_En : 1; + unsigned int U11_En : 1; + unsigned int U12_En : 1; + unsigned int U13_En : 1; + unsigned int U14_En : 1; + unsigned int U15_En : 1; + unsigned int U16_En : 1; + unsigned int U17_En : 1; + unsigned int U18_En : 1; + unsigned int U19_En : 1; + unsigned int U20_En : 1; + unsigned int U21_En : 1; + unsigned int U22_En : 1; + unsigned int U23_En : 1; + unsigned int U24_En : 1; + unsigned int U25_En : 1; + unsigned int U26_En : 1; + unsigned int U27_En : 1; + unsigned int U28_En : 1; + unsigned int U29_En : 1; + unsigned int U30_En : 1; + unsigned int U31_En : 1; + } reg; +} Reg_Fs_U_Enable; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U0_Data_Fmt : 4; + + unsigned int U1_Data_Fmt : 4; + unsigned int U2_Data_Fmt : 4; + unsigned int U3_Data_Fmt : 4; + unsigned int U4_Data_Fmt : 4; + unsigned int U5_Data_Fmt : 4; + unsigned int U6_Data_Fmt : 4; + unsigned int U7_Data_Fmt : 4; + } reg; +} Reg_Fs_U_Fmt; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U0_Layout : 1; + unsigned int U1_Layout : 1; + unsigned int U2_Layout : 1; + unsigned int U3_Layout : 1; + unsigned int U4_Layout : 1; + unsigned int U5_Layout : 1; + unsigned int U6_Layout : 1; + unsigned int U7_Layout : 1; + unsigned int U8_Layout : 1; + unsigned int U9_Layout : 1; + unsigned int U10_Layout : 1; + unsigned int U11_Layout : 1; + unsigned int U12_Layout : 1; + unsigned int U13_Layout : 1; + unsigned int U14_Layout : 1; + unsigned int U15_Layout : 1; + unsigned int U16_Layout : 1; + unsigned int U17_Layout : 1; + unsigned int U18_Layout : 1; + unsigned int U19_Layout : 1; + unsigned int U20_Layout : 1; + unsigned int U21_Layout : 1; + unsigned int U22_Layout : 1; + unsigned int U23_Layout : 1; + unsigned int U24_Layout : 1; + unsigned int U25_Layout : 1; + unsigned int U26_Layout : 1; + unsigned int U27_Layout : 1; + unsigned int U28_Layout : 1; + unsigned int U29_Layout : 1; + unsigned int U30_Layout : 1; + unsigned int U31_Layout : 1; + } reg; +} Reg_Fs_U_Layout; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vcs_U_Base : 8; + + unsigned int Vcs_U_Range : 8; + + unsigned int Reserved : 16; + } reg; +} Reg_Vcs_U_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Hs_U_Base : 8; + + unsigned int Hs_U_Range : 8; + + unsigned int Reserved : 16; + } reg; +} Reg_Hs_U_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ds_U_Base : 8; + + unsigned int Ds_U_Range : 8; + + unsigned int Reserved : 16; + } reg; +} Reg_Ds_U_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Gs_U_Base : 8; + + unsigned int Gs_U_Range : 8; + + unsigned int Reserved : 16; + } reg; +} Reg_Gs_U_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_Low : 32; + + } reg; +} Reg_Vcs_Instr0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_High : 8; + + unsigned int Reserved : 24; + } reg; +} Reg_Vcs_Instr1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ins_Range : 16; + + unsigned int Reserved : 16; + } reg; +} Reg_Vcs_Instr_Range; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_Low : 32; + + } reg; +} Reg_Hs_Instr0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_High : 8; + + unsigned int Reserved : 24; + } reg; +} Reg_Hs_Instr1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ins_Range : 16; + + unsigned int Reserved : 16; + } reg; +} Reg_Hs_Instr_Range; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_Low : 32; + + } reg; +} Reg_Ds_Instr0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_High : 8; + + unsigned int Reserved : 24; + } reg; +} Reg_Ds_Instr1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ins_Range : 16; + + unsigned int Reserved : 16; + } reg; +} Reg_Ds_Instr_Range; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_Low : 32; + + } reg; +} Reg_Gs_Instr0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_High : 8; + + unsigned int Reserved : 24; + } reg; +} Reg_Gs_Instr1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ins_Range : 16; + + unsigned int Reserved : 16; + } reg; +} Reg_Gs_Instr_Range; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vcs_Cb_Base : 9; + + unsigned int Vcs_Cb_Range : 9; + + unsigned int Reserved : 14; + } reg; +} Reg_Vcs_Cb_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Hs_Cb_Base : 9; + + unsigned int Hs_Cb_Range : 9; + + unsigned int Reserved : 14; + } reg; +} Reg_Hs_Cb_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ds_Cb_Base : 9; + + unsigned int Ds_Cb_Range : 9; + + unsigned int Reserved : 14; + } reg; +} Reg_Ds_Cb_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Gs_Cb_Base : 9; + + unsigned int Gs_Cb_Range : 9; + + unsigned int Reserved : 14; + } reg; +} Reg_Gs_Cb_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Fs_Cb_Range : 9; + + unsigned int Reserved : 23; + } reg; +} Reg_Fs_Cb_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Fs_Rev_8aligned; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Fs_Rev_Cb; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Const : 32; + } reg; +} Reg_Fs_Cb_Data; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Exec_En : 1; + unsigned int Th_Mode : 1; + unsigned int Int_En : 1; + unsigned int Res_En : 1; + unsigned int Dbg_Th_Id : 5; + + + unsigned int Reserved : 23; + } reg; +} Reg_Dbg_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Bp_Hit : 1; + + unsigned int Bp_Id : 3; + unsigned int Hit_Th_Id : 5; + + unsigned int Reserved : 23; + } reg; +} Reg_Dbg_Bp_Stat; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Bp_Valid : 1; + unsigned int Shader : 3; + unsigned int Offset : 16; + + + unsigned int Reserved : 12; + } reg; +} Reg_Dbg_Bp_Pc; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Offset : 16; + + unsigned int Reserved : 16; + } reg; +} Reg_Dbg_Int_Instr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Offset : 16; + + unsigned int Reserved : 16; + } reg; +} Reg_Dbg_Res_Instr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Value : 32; + + } reg; +} Reg_Dbg_Time_Stamp; + +typedef struct _Eu_Fs_regs +{ + Reg_Eu_Full_Glb reg_Eu_Full_Glb; + Reg_Eu_3d_Glb reg_Eu_3d_Glb; + Reg_Eu_Fe_Glb reg_Eu_Fe_Glb; + Reg_Mv_Cfg reg_Mv_Cfg; + Reg_Vc_Size_Cfg0 reg_Vc_Size_Cfg0; + Reg_Vc_Size_Cfg1 reg_Vc_Size_Cfg1; + Reg_Vc_Base_Cfg0 reg_Vc_Base_Cfg0; + Reg_Vc_Base_Cfg1 reg_Vc_Base_Cfg1; + Reg_Fs_Cfg reg_Fs_Cfg; + Reg_Max_Threads_Cfg reg_Max_Threads_Cfg; + Reg_Antilock_Cfg reg_Antilock_Cfg; + Reg_Vs_Ctrl reg_Vs_Ctrl; + Reg_Hs_Ctrl reg_Hs_Ctrl; + Reg_Hs_In_Cfg reg_Hs_In_Cfg; + Reg_Hs_Out_Cfg reg_Hs_Out_Cfg; + Reg_Ds_Ctrl reg_Ds_Ctrl; + Reg_Ds_In_Cfg reg_Ds_In_Cfg; + Reg_Gs_Ctrl reg_Gs_Ctrl; + Reg_Gs_In_Cfg reg_Gs_In_Cfg; + Reg_Gs_Out_Cfg reg_Gs_Out_Cfg; + Reg_Ts_Ctrl reg_Ts_Ctrl; + Reg_Ts_Input_Mapping0 reg_Ts_Input_Mapping0; + Reg_Ts_Input_Mapping1 reg_Ts_Input_Mapping1; + Reg_Ts_Factors_Const reg_Ts_Factors_Const[6]; + Reg_Fs_Cs_Ctrl reg_Fs_Cs_Ctrl; + Reg_Fs_Cs_Sm_Cfg reg_Fs_Cs_Sm_Cfg; + Reg_Fs_Out_Loc0 reg_Fs_Out_Loc0; + Reg_Fs_Out_Loc1 reg_Fs_Out_Loc1; + Reg_Fs_Out_Mapping reg_Fs_Out_Mapping[12]; + Reg_Fs_Out_Comp reg_Fs_Out_Comp[3]; + Reg_Fs_Out_Mask reg_Fs_Out_Mask[6]; + Reg_Fs_Pm_Cfg reg_Fs_Pm_Cfg; + Reg_Fs_Pm_Id reg_Fs_Pm_Id; + Reg_Vgs_Pm_Range reg_Vgs_Pm_Range; + Reg_Hds_Pm_Range reg_Hds_Pm_Range; + Reg_Fs_U_Enable reg_Fs_U_Enable[4]; + Reg_Fs_U_Fmt reg_Fs_U_Fmt[16]; + Reg_Fs_U_Layout reg_Fs_U_Layout[4]; + Reg_Vcs_U_Cfg reg_Vcs_U_Cfg; + Reg_Hs_U_Cfg reg_Hs_U_Cfg; + Reg_Ds_U_Cfg reg_Ds_U_Cfg; + Reg_Gs_U_Cfg reg_Gs_U_Cfg; + Reg_Vcs_Instr0 reg_Vcs_Instr0; + Reg_Vcs_Instr1 reg_Vcs_Instr1; + Reg_Vcs_Instr_Range reg_Vcs_Instr_Range; + Reg_Hs_Instr0 reg_Hs_Instr0; + Reg_Hs_Instr1 reg_Hs_Instr1; + Reg_Hs_Instr_Range reg_Hs_Instr_Range; + Reg_Ds_Instr0 reg_Ds_Instr0; + Reg_Ds_Instr1 reg_Ds_Instr1; + Reg_Ds_Instr_Range reg_Ds_Instr_Range; + Reg_Gs_Instr0 reg_Gs_Instr0; + Reg_Gs_Instr1 reg_Gs_Instr1; + Reg_Gs_Instr_Range reg_Gs_Instr_Range; + Reg_Vcs_Cb_Cfg reg_Vcs_Cb_Cfg; + Reg_Hs_Cb_Cfg reg_Hs_Cb_Cfg; + Reg_Ds_Cb_Cfg reg_Ds_Cb_Cfg; + Reg_Gs_Cb_Cfg reg_Gs_Cb_Cfg; + Reg_Fs_Cb_Cfg reg_Fs_Cb_Cfg; + Reg_Fs_Rev_8aligned reg_Fs_Rev_8aligned; + Reg_Fs_Rev_Cb reg_Fs_Rev_Cb[152]; + Reg_Fs_Cb_Data reg_Fs_Cb_Data[2048]; + Reg_Dbg_Cfg reg_Dbg_Cfg[32]; + Reg_Dbg_Bp_Stat reg_Dbg_Bp_Stat[32]; + Reg_Dbg_Bp_Pc reg_Dbg_Bp_Pc[256]; + Reg_Dbg_Int_Instr reg_Dbg_Int_Instr[32]; + Reg_Dbg_Res_Instr reg_Dbg_Res_Instr[32]; + Reg_Dbg_Time_Stamp reg_Dbg_Time_Stamp[64]; +} Eu_Fs_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/EU_PS_reg.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/EU_PS_reg.h new file mode 100644 index 0000000000000..7fcf49a5ef82f --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/EU_PS_reg.h @@ -0,0 +1,641 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _EU_PS_REG_H +#define _EU_PS_REG_H + + +#ifndef EU_PS_BLOCKBASE_INF + #define EU_PS_BLOCKBASE_INF + #define BLOCK_EU_PS_VERSION 1 + #define BLOCK_EU_PS_TIMESTAMP "2018/8/16 16:25:12" + #define EU_PS_BLOCK 0x9 + #define EU_PS_REG_START 0x0 + #define EU_PS_REG_END 0x900 + #define EU_PS_REG_LIMIT 0x900 +#endif + + +#define Reg_Ps_Cfg_Offset 0x0 +#define Reg_Ps_Ctrl_Offset 0x1 +#define Reg_Ps_Out_Cfg_Offset 0x2 +#define Reg_Ps_Doutbuf_Cfg_Offset 0x3 +#define Reg_Ps_Pm_Cfg_Offset 0x4 +#define Reg_Ps_Pm_Id_Offset 0x5 +#define Reg_Ps_Pm_Range_Offset 0x6 +#define Reg_Ps_Out_Mapping_Offset 0x7 +#define Reg_Ps_Out_Fmt_Offset 0x8 +#define Reg_Ps_U_Enable_Offset 0x9 +#define Reg_Ps_U_Fmt_Offset 0xB +#define Reg_Ps_U_Layout_Offset 0x13 +#define Reg_Ps_U_Cfg_Offset 0x15 +#define Reg_Ps_Instr0_Offset 0x16 +#define Reg_Ps_Instr1_Offset 0x17 +#define Reg_Ps_Instr_Range_Offset 0x18 +#define Reg_Ps_Cb_Cfg_Offset 0x19 +#define Reg_Ps_Rev_8aligned_Offset 0x1A +#define Reg_Ps_Rev_Cb_Offset 0x20 +#define Reg_Ps_Cb_Data_Offset 0x100 + + +typedef enum +{ + PS_CFG_PS_ON_OFF = 0, + PS_CFG_PS_ON_ON = 1, +} PS_CFG_PS_ON; +typedef enum +{ + PS_CTRL_AND_V_MASK_DISABLED = 0, + PS_CTRL_AND_V_MASK_ENABLED = 1, + +} PS_CTRL_AND_V_MASK; +typedef enum +{ + PS_CTRL_RD_MODE_NEAR = 0, + PS_CTRL_RD_MODE_ZERO = 1, + PS_CTRL_RD_MODE_POS = 2, + PS_CTRL_RD_MODE_NEG = 3, +} PS_CTRL_RD_MODE; +typedef enum +{ + PS_CTRL_FP_MODE_STD_IEEE = 0, + PS_CTRL_FP_MODE_NSTD_IEEE = 1, + PS_CTRL_FP_MODE_MS_ALT = 2, + PS_CTRL_FP_MODE_RESERVED = 3, +} PS_CTRL_FP_MODE; +typedef enum +{ + PS_CTRL_DENORM_EN_DISABLED = 0, + PS_CTRL_DENORM_EN_ENABLED = 1, +} PS_CTRL_DENORM_EN; +typedef enum +{ + PS_CTRL_THREAD_MODE_SIMD32 = 0, + PS_CTRL_THREAD_MODE_SIMD64 = 1, +} PS_CTRL_THREAD_MODE; +typedef enum +{ + PS_CTRL_CUST_BLEND_EN_DISABLED = 0, + + PS_CTRL_CUST_BLEND_EN_ENABLED = 1, + +} PS_CTRL_CUST_BLEND_EN; +typedef enum +{ + PS_CTRL_ROV_EN_DISABLED = 0, + PS_CTRL_ROV_EN_ENABLED = 1, +} PS_CTRL_ROV_EN; +typedef enum +{ + PS_OUT_CFG_CLR_OUT_EN_OFF = 0, + PS_OUT_CFG_CLR_OUT_EN_ON = 1, +} PS_OUT_CFG_CLR_OUT_EN; +typedef enum +{ + PS_OUT_CFG_Z_OUT_EN_OFF = 0, + PS_OUT_CFG_Z_OUT_EN_ON = 1, +} PS_OUT_CFG_Z_OUT_EN; +typedef enum +{ + PS_OUT_CFG_ALPHA_OUT_EN_OFF = 0, + PS_OUT_CFG_ALPHA_OUT_EN_ON = 1, +} PS_OUT_CFG_ALPHA_OUT_EN; +typedef enum +{ + PS_OUT_CFG_STENCIL_OUT_EN_OFF = 0, + PS_OUT_CFG_STENCIL_OUT_EN_ON = 1, +} PS_OUT_CFG_STENCIL_OUT_EN; +typedef enum +{ + PS_OUT_CFG_MASK_OUT_EN_OFF = 0, + PS_OUT_CFG_MASK_OUT_EN_ON = 1, +} PS_OUT_CFG_MASK_OUT_EN; +typedef enum +{ + PS_OUT_CFG_DUAL_SRC_EN_OFF = 0, + PS_OUT_CFG_DUAL_SRC_EN_ON = 1, +} PS_OUT_CFG_DUAL_SRC_EN; +typedef enum +{ + PS_OUT_CFG_Z_DATA_FMT_FP32 = 0, + PS_OUT_CFG_Z_DATA_FMT_UNORM24 = 6, + PS_OUT_CFG_Z_DATA_FMT_UNORM16 = 7, +} PS_OUT_CFG_Z_DATA_FMT; +typedef enum +{ + PS_OUT_CFG_DUAL_SRC_FMT_FP16 = 1, + PS_OUT_CFG_DUAL_SRC_FMT_UNORM10 = 8, + PS_OUT_CFG_DUAL_SRC_FMT_UNORM8 = 9, + PS_OUT_CFG_DUAL_SRC_FMT_SNORM8 = 12, +} PS_OUT_CFG_DUAL_SRC_FMT; +typedef enum +{ + PS_OUT_CFG_MASK_OUT_MODE_BIT1 = 0, + PS_OUT_CFG_MASK_OUT_MODE_BIT2 = 1, + + PS_OUT_CFG_MASK_OUT_MODE_BIT4 = 2, + + PS_OUT_CFG_MASK_OUT_MODE_BIT8 = 3, + + PS_OUT_CFG_MASK_OUT_MODE_BIT16 = 4, + + +} PS_OUT_CFG_MASK_OUT_MODE; +typedef enum +{ + PS_DOUTBUF_CFG_ZL3_SIZE_0LINES = 0, + PS_DOUTBUF_CFG_ZL3_SIZE_16LINES = 4, + + PS_DOUTBUF_CFG_ZL3_SIZE_32LINES = 5, + PS_DOUTBUF_CFG_ZL3_SIZE_64LINES = 6, + PS_DOUTBUF_CFG_ZL3_SIZE_128LINES = 7, +} PS_DOUTBUF_CFG_ZL3_SIZE; +typedef enum +{ + PS_DOUTBUF_CFG_CLR_SIZE_0LINES = 0, + PS_DOUTBUF_CFG_CLR_SIZE_32LINES = 5, + + PS_DOUTBUF_CFG_CLR_SIZE_64LINES = 6, + PS_DOUTBUF_CFG_CLR_SIZE_128LINES = 7, +} PS_DOUTBUF_CFG_CLR_SIZE; +typedef enum +{ + PS_PM_CFG_PM_EN_DISABLED = 0, + PS_PM_CFG_PM_EN_ENABLED = 1, +} PS_PM_CFG_PM_EN; +typedef enum +{ + PS_PM_CFG_TH_PM_SIZE_8KDW = 0, + + PS_PM_CFG_TH_PM_SIZE_16KDW = 1, + PS_PM_CFG_TH_PM_SIZE_32KDW = 2, + PS_PM_CFG_TH_PM_SIZE_64KDW = 3, + PS_PM_CFG_TH_PM_SIZE_128KDW = 4, + PS_PM_CFG_TH_PM_SIZE_256KDW = 5, + PS_PM_CFG_TH_PM_SIZE_512KDW = 6, + PS_PM_CFG_TH_PM_SIZE_1024KDW = 7, + PS_PM_CFG_TH_PM_SIZE_1040KDW = 8, +} PS_PM_CFG_TH_PM_SIZE; +typedef enum +{ + PS_OUT_MAPPING_O0_EN_DISABLED = 0, + PS_OUT_MAPPING_O0_EN_ENABLED = 1, +} PS_OUT_MAPPING_O0_EN; +typedef enum +{ + PS_OUT_MAPPING_O1_EN_DISABLED = 0, + PS_OUT_MAPPING_O1_EN_ENABLED = 1, +} PS_OUT_MAPPING_O1_EN; +typedef enum +{ + PS_OUT_MAPPING_O2_EN_DISABLED = 0, + PS_OUT_MAPPING_O2_EN_ENABLED = 1, +} PS_OUT_MAPPING_O2_EN; +typedef enum +{ + PS_OUT_MAPPING_O3_EN_DISABLED = 0, + PS_OUT_MAPPING_O3_EN_ENABLED = 1, +} PS_OUT_MAPPING_O3_EN; +typedef enum +{ + PS_OUT_MAPPING_O4_EN_DISABLED = 0, + PS_OUT_MAPPING_O4_EN_ENABLED = 1, +} PS_OUT_MAPPING_O4_EN; +typedef enum +{ + PS_OUT_MAPPING_O5_EN_DISABLED = 0, + PS_OUT_MAPPING_O5_EN_ENABLED = 1, +} PS_OUT_MAPPING_O5_EN; +typedef enum +{ + PS_OUT_MAPPING_O6_EN_DISABLED = 0, + PS_OUT_MAPPING_O6_EN_ENABLED = 1, +} PS_OUT_MAPPING_O6_EN; +typedef enum +{ + PS_OUT_MAPPING_O7_EN_DISABLED = 0, + PS_OUT_MAPPING_O7_EN_ENABLED = 1, +} PS_OUT_MAPPING_O7_EN; +typedef enum +{ + PS_OUT_FMT_O0_DATA_FMT_FP32 = 0, + PS_OUT_FMT_O0_DATA_FMT_FP16 = 1, + PS_OUT_FMT_O0_DATA_FMT_SINT32 = 2, + PS_OUT_FMT_O0_DATA_FMT_SINT16 = 3, + PS_OUT_FMT_O0_DATA_FMT_UINT32 = 4, + PS_OUT_FMT_O0_DATA_FMT_UINT16 = 5, + PS_OUT_FMT_O0_DATA_FMT_UNORM24 = 6, + PS_OUT_FMT_O0_DATA_FMT_UNORM16 = 7, + PS_OUT_FMT_O0_DATA_FMT_UNORM10 = 8, + PS_OUT_FMT_O0_DATA_FMT_UNORM8 = 9, + PS_OUT_FMT_O0_DATA_FMT_SINT8 = 10, + PS_OUT_FMT_O0_DATA_FMT_UINT8 = 11, + PS_OUT_FMT_O0_DATA_FMT_SNORM8 = 12, + PS_OUT_FMT_O0_DATA_FMT_SNORM16 = 13, + PS_OUT_FMT_O0_DATA_FMT_UINT64 = 14, + PS_OUT_FMT_O0_DATA_FMT_RESERVED = 15, +} PS_OUT_FMT_O0_DATA_FMT; +typedef enum +{ + PS_U_ENABLE_U0_EN_DISABLE = 0, + PS_U_ENABLE_U0_EN_ENABLE = 1, +} PS_U_ENABLE_U0_EN; +typedef enum +{ + PS_U_FMT_U0_DATA_FMT_FP32 = 0, + PS_U_FMT_U0_DATA_FMT_FP16 = 1, + PS_U_FMT_U0_DATA_FMT_SINT32 = 2, + PS_U_FMT_U0_DATA_FMT_SINT16 = 3, + PS_U_FMT_U0_DATA_FMT_UINT32 = 4, + PS_U_FMT_U0_DATA_FMT_UINT16 = 5, + PS_U_FMT_U0_DATA_FMT_UNORM24 = 6, + PS_U_FMT_U0_DATA_FMT_UNORM16 = 7, + PS_U_FMT_U0_DATA_FMT_UNORM10 = 8, + PS_U_FMT_U0_DATA_FMT_UNORM8 = 9, + PS_U_FMT_U0_DATA_FMT_SINT8 = 10, + PS_U_FMT_U0_DATA_FMT_UINT8 = 11, + PS_U_FMT_U0_DATA_FMT_SNORM8 = 12, + PS_U_FMT_U0_DATA_FMT_SNORM16 = 13, + PS_U_FMT_U0_DATA_FMT_UINT64 = 14, + PS_U_FMT_U0_DATA_FMT_RESERVED = 15, +} PS_U_FMT_U0_DATA_FMT; +typedef enum +{ + PS_U_LAYOUT_U0_LAYOUT_VERTICAL = 0, + PS_U_LAYOUT_U0_LAYOUT_HORIZONTAL = 1, +} PS_U_LAYOUT_U0_LAYOUT; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ps_On : 1; + unsigned int Max_Threads : 8; + + + unsigned int In_Size : 6; + + unsigned int Reserved1 : 17; + } reg; +} Reg_Ps_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Crf_Size : 6; + + + unsigned int And_V_Mask : 1; + unsigned int Rd_Mode : 2; + unsigned int Fp_Mode : 2; + unsigned int Denorm_En : 1; + unsigned int Thread_Mode : 1; + + unsigned int Cust_Blend_En : 1; + + unsigned int Rov_En : 1; + + unsigned int Cust_Crf_Addr : 6; + + + unsigned int Reserved : 11; + } reg; +} Reg_Ps_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Clr_Out_En : 1; + unsigned int Z_Out_En : 1; + + unsigned int Alpha_Out_En : 1; + + unsigned int Stencil_Out_En : 1; + + unsigned int Mask_Out_En : 1; + unsigned int Dual_Src_En : 1; + + + + unsigned int Clr_Out_Num : 4; + + unsigned int Z_Data_Fmt : 4; + unsigned int Dual_Src_Fmt : 4; + + unsigned int Mask_Out_Mode : 3; + + unsigned int Reserved : 11; + } reg; +} Reg_Ps_Out_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Zl3_Size : 4; + + unsigned int Clr_Size : 4; + unsigned int Reserved : 24; + } reg; +} Reg_Ps_Doutbuf_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Pm_En : 1; + unsigned int Th_Pm_Size : 4; + + + unsigned int Reserved : 27; + } reg; +} Reg_Ps_Pm_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Pm_U_Id : 32; + + + + } reg; +} Reg_Ps_Pm_Id; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ps_Idx_Ele_Range : 14; + + unsigned int Reserved : 18; + } reg; +} Reg_Ps_Pm_Range; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int O0_En : 1; + unsigned int O0_Addr : 3; + unsigned int O1_En : 1; + unsigned int O1_Addr : 3; + unsigned int O2_En : 1; + unsigned int O2_Addr : 3; + unsigned int O3_En : 1; + unsigned int O3_Addr : 3; + unsigned int O4_En : 1; + unsigned int O4_Addr : 3; + unsigned int O5_En : 1; + unsigned int O5_Addr : 3; + unsigned int O6_En : 1; + unsigned int O6_Addr : 3; + unsigned int O7_En : 1; + unsigned int O7_Addr : 3; + } reg; +} Reg_Ps_Out_Mapping; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int O0_Data_Fmt : 4; + unsigned int O1_Data_Fmt : 4; + unsigned int O2_Data_Fmt : 4; + unsigned int O3_Data_Fmt : 4; + unsigned int O4_Data_Fmt : 4; + unsigned int O5_Data_Fmt : 4; + unsigned int O6_Data_Fmt : 4; + unsigned int O7_Data_Fmt : 4; + } reg; +} Reg_Ps_Out_Fmt; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U0_En : 1; + unsigned int U1_En : 1; + unsigned int U2_En : 1; + unsigned int U3_En : 1; + unsigned int U4_En : 1; + unsigned int U5_En : 1; + unsigned int U6_En : 1; + unsigned int U7_En : 1; + unsigned int U8_En : 1; + unsigned int U9_En : 1; + unsigned int U10_En : 1; + unsigned int U11_En : 1; + unsigned int U12_En : 1; + unsigned int U13_En : 1; + unsigned int U14_En : 1; + unsigned int U15_En : 1; + unsigned int U16_En : 1; + unsigned int U17_En : 1; + unsigned int U18_En : 1; + unsigned int U19_En : 1; + unsigned int U20_En : 1; + unsigned int U21_En : 1; + unsigned int U22_En : 1; + unsigned int U23_En : 1; + unsigned int U24_En : 1; + unsigned int U25_En : 1; + unsigned int U26_En : 1; + unsigned int U27_En : 1; + unsigned int U28_En : 1; + unsigned int U29_En : 1; + unsigned int U30_En : 1; + unsigned int U31_En : 1; + } reg; +} Reg_Ps_U_Enable; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U0_Data_Fmt : 4; + + unsigned int U1_Data_Fmt : 4; + unsigned int U2_Data_Fmt : 4; + unsigned int U3_Data_Fmt : 4; + unsigned int U4_Data_Fmt : 4; + unsigned int U5_Data_Fmt : 4; + unsigned int U6_Data_Fmt : 4; + unsigned int U7_Data_Fmt : 4; + } reg; +} Reg_Ps_U_Fmt; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U0_Layout : 1; + unsigned int U1_Layout : 1; + unsigned int U2_Layout : 1; + unsigned int U3_Layout : 1; + unsigned int U4_Layout : 1; + unsigned int U5_Layout : 1; + unsigned int U6_Layout : 1; + unsigned int U7_Layout : 1; + unsigned int U8_Layout : 1; + unsigned int U9_Layout : 1; + unsigned int U10_Layout : 1; + unsigned int U11_Layout : 1; + unsigned int U12_Layout : 1; + unsigned int U13_Layout : 1; + unsigned int U14_Layout : 1; + unsigned int U15_Layout : 1; + unsigned int U16_Layout : 1; + unsigned int U17_Layout : 1; + unsigned int U18_Layout : 1; + unsigned int U19_Layout : 1; + unsigned int U20_Layout : 1; + unsigned int U21_Layout : 1; + unsigned int U22_Layout : 1; + unsigned int U23_Layout : 1; + unsigned int U24_Layout : 1; + unsigned int U25_Layout : 1; + unsigned int U26_Layout : 1; + unsigned int U27_Layout : 1; + unsigned int U28_Layout : 1; + unsigned int U29_Layout : 1; + unsigned int U30_Layout : 1; + unsigned int U31_Layout : 1; + } reg; +} Reg_Ps_U_Layout; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ps_U_Range : 8; + + unsigned int Reserved : 24; + } reg; +} Reg_Ps_U_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_Low : 32; + + } reg; +} Reg_Ps_Instr0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address_High : 8; + + unsigned int Reserved : 24; + } reg; +} Reg_Ps_Instr1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ins_Range : 16; + + unsigned int Reserved : 16; + } reg; +} Reg_Ps_Instr_Range; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ps_Cb_Range : 9; + + unsigned int Reserved : 23; + } reg; +} Reg_Ps_Cb_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Ps_Rev_8aligned; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Ps_Rev_Cb; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Const : 32; + } reg; +} Reg_Ps_Cb_Data; + +typedef struct _Eu_Ps_regs +{ + Reg_Ps_Cfg reg_Ps_Cfg; + Reg_Ps_Ctrl reg_Ps_Ctrl; + Reg_Ps_Out_Cfg reg_Ps_Out_Cfg; + Reg_Ps_Doutbuf_Cfg reg_Ps_Doutbuf_Cfg; + Reg_Ps_Pm_Cfg reg_Ps_Pm_Cfg; + Reg_Ps_Pm_Id reg_Ps_Pm_Id; + Reg_Ps_Pm_Range reg_Ps_Pm_Range; + Reg_Ps_Out_Mapping reg_Ps_Out_Mapping; + Reg_Ps_Out_Fmt reg_Ps_Out_Fmt; + Reg_Ps_U_Enable reg_Ps_U_Enable[2]; + Reg_Ps_U_Fmt reg_Ps_U_Fmt[8]; + Reg_Ps_U_Layout reg_Ps_U_Layout[2]; + Reg_Ps_U_Cfg reg_Ps_U_Cfg; + Reg_Ps_Instr0 reg_Ps_Instr0; + Reg_Ps_Instr1 reg_Ps_Instr1; + Reg_Ps_Instr_Range reg_Ps_Instr_Range; + Reg_Ps_Cb_Cfg reg_Ps_Cb_Cfg; + Reg_Ps_Rev_8aligned reg_Ps_Rev_8aligned[6]; + Reg_Ps_Rev_Cb reg_Ps_Rev_Cb[224]; + Reg_Ps_Cb_Data reg_Ps_Cb_Data[2048]; +} Eu_Ps_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/FF_registers.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/FF_registers.h new file mode 100644 index 0000000000000..e3604ebc863eb --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/FF_registers.h @@ -0,0 +1,1250 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _FF_REGISTERS_H +#define _FF_REGISTERS_H + + +#ifndef FF_BLOCKBASE_INF + #define FF_BLOCKBASE_INF + #define BLOCK_FF_VERSION 1 + #define BLOCK_FF_TIMESTAMP "11/22/2018 3:03:21 PM" + #define FF_BLOCK 0x6 + #define FF_REG_START 0x0 + #define FF_REG_END 0xD0 + #define FF_REG_LIMIT 0xD0 +#endif + + +#define Reg_Ff_Glb_Ctrl_Offset 0x0 +#define Reg_Reserved_1_Offset 0x1 +#define Reg_Reserved_2_Offset 0x2 +#define Reg_Reserved_3_Offset 0x3 +#define Reg_Resolution_Ctrl_Offset 0x4 +#define Reg_Dzs_Ctrl_Offset 0x5 +#define Reg_Zs_View_Ctrl_Offset 0x6 +#define Reg_Zs_Mipmap_Offset 0x7 +#define Reg_Zv_Size_Offset 0x8 +#define Reg_Zv_Depth_Offset 0x9 +#define Reg_Zv_Desc_Base0_Offset 0xA +#define Reg_Sv_Desc_Base0_Offset 0xB +#define Reg_Sv_Bl_Slot_Idx_Offset 0xC +#define Reg_Ffc_Config_Offset 0xD +#define Reg_Ffc_Global_Range_Config_Offset 0xE +#define Reg_Reserved_4_Offset 0xF +#define Reg_Ffc_Dsig_Base_Addr_Offset 0x10 +#define Reg_Rt_Addr_Ctrl_Offset 0x18 +#define Reg_Rt_Ctrl_Offset 0x30 +#define Reg_Rast_Ctrl_Offset 0x48 +#define Reg_Sg_Ctrl_Offset 0x49 +#define Reg_Zs_Req_Ctrl_Offset 0x4A +#define Reg_Zs_Ctl_Offset 0x4B +#define Reg_Ff_Stencil_Group_Offset 0x4C +#define Reg_Depth_Bound_Start_Offset 0x4E +#define Reg_Depth_Bound_End_Offset 0x4F +#define Reg_Viewport_Zmin_Offset 0x50 +#define Reg_Viewport_Zmax_Offset 0x60 +#define Reg_User_Msaa_Pattern_Group_Offset 0x70 +#define Reg_Multi_Res_Blk_Group_Offset 0x74 +#define Reg_Vr_Zrange_Group_Offset 0xAA +#define Reg_Blend_Ctl_Offset 0xB0 +#define Reg_Fast_Clear_Color_Offset 0xC8 +#define Reg_Tasbe_Ctrl_Offset 0xCC +#define Reg_Reserved_5_Offset 0xCD +#define Reg_Reserved_6_Offset 0xCE +#define Reg_Reserved_7_Offset 0xCF + + +typedef enum +{ + FF_GLB_CTRL_TBR_EN_DISABLE = 0, + FF_GLB_CTRL_TBR_EN_ENABLE = 1, +} FF_GLB_CTRL_TBR_EN; +typedef enum +{ + FF_GLB_CTRL_TBR_MODE_PER_DRAW = 0, + FF_GLB_CTRL_TBR_MODE_PER_FRAME = 1, +} FF_GLB_CTRL_TBR_MODE; +typedef enum +{ + FF_GLB_CTRL_TILE_SIZE_256X128 = 0, + FF_GLB_CTRL_TILE_SIZE_128X128 = 1, + FF_GLB_CTRL_TILE_SIZE_128X64 = 2, + FF_GLB_CTRL_TILE_SIZE_64X64 = 3, + FF_GLB_CTRL_TILE_SIZE_64X32 = 4, + FF_GLB_CTRL_TILE_SIZE_32X32 = 5, + FF_GLB_CTRL_TILE_SIZE_32X16 = 6, + FF_GLB_CTRL_TILE_SIZE_16X16 = 7, + FF_GLB_CTRL_TILE_SIZE_16X8 = 8, + FF_GLB_CTRL_TILE_SIZE_8X8 = 9, +} FF_GLB_CTRL_TILE_SIZE; +typedef enum +{ + FF_GLB_CTRL_FFC_CONFIG_MODE_ZS_D_U = 0, + + + + FF_GLB_CTRL_FFC_CONFIG_MODE_D_ONLY = 1, + FF_GLB_CTRL_FFC_CONFIG_MODE_ZS_ONLY = 2, + FF_GLB_CTRL_FFC_CONFIG_MODE_UAV_ONLY = 3, + FF_GLB_CTRL_FFC_CONFIG_MODE_ZS_D = 4, + FF_GLB_CTRL_FFC_CONFIG_MODE_ZS_U = 5, + + + + FF_GLB_CTRL_FFC_CONFIG_MODE_D_U = 6, + + + FF_GLB_CTRL_FFC_CONFIG_MODE_SW_CONFIG = 7, + + +} FF_GLB_CTRL_FFC_CONFIG_MODE; +typedef enum +{ + RESOLUTION_CTRL_DST_RESOLUTION_MODE_1X = 0, + RESOLUTION_CTRL_DST_RESOLUTION_MODE_2X = 1, + RESOLUTION_CTRL_DST_RESOLUTION_MODE_4X = 2, + RESOLUTION_CTRL_DST_RESOLUTION_MODE_8X = 3, + RESOLUTION_CTRL_DST_RESOLUTION_MODE_16X = 4, +} RESOLUTION_CTRL_DST_RESOLUTION_MODE; +typedef enum +{ + RESOLUTION_CTRL_MSAA_MODE_MSAA_1X = 0, + RESOLUTION_CTRL_MSAA_MODE_MSAA_2X = 1, + RESOLUTION_CTRL_MSAA_MODE_MSAA_4X = 2, + RESOLUTION_CTRL_MSAA_MODE_MSAA_8X = 3, + RESOLUTION_CTRL_MSAA_MODE_MSAA_16X = 4, +} RESOLUTION_CTRL_MSAA_MODE; +typedef enum +{ + RESOLUTION_CTRL_MULTI_RES_EN_DISABLED = 0, + RESOLUTION_CTRL_MULTI_RES_EN_ENABLED = 1, +} RESOLUTION_CTRL_MULTI_RES_EN; +typedef enum +{ + RESOLUTION_CTRL_PS_SAMPLE_FREQ_EN_DISABLED= 0, + RESOLUTION_CTRL_PS_SAMPLE_FREQ_EN_ENABLED= 1, +} RESOLUTION_CTRL_PS_SAMPLE_FREQ_EN; +typedef enum +{ + DZS_CTRL_SRC_BITS_MODE_NORMAL = 0, + + DZS_CTRL_SRC_BITS_MODE_IS_1BPP = 1, + + + DZS_CTRL_SRC_BITS_MODE_IS_4BPP = 2, + + + + DZS_CTRL_SRC_BITS_MODE_UNUSED = 3, +} DZS_CTRL_SRC_BITS_MODE; +typedef enum +{ + DZS_CTRL_THREAD_MODE_SIMD32 = 0, + DZS_CTRL_THREAD_MODE_SIMD64 = 1, +} DZS_CTRL_THREAD_MODE; +typedef enum +{ + ZS_MIPMAP_RESOURCE_TYPE_1D_BUFFER = 0, + ZS_MIPMAP_RESOURCE_TYPE_1D_TEXTURE = 1, + ZS_MIPMAP_RESOURCE_TYPE_2D_TEXTURE = 2, + ZS_MIPMAP_RESOURCE_TYPE_3D_TEXTURE = 3, + ZS_MIPMAP_RESOURCE_TYPE_CUBIC_TEXTURE = 4, + ZS_MIPMAP_RESOURCE_TYPE_1D_TEXTURE_ARRAY= 5, + ZS_MIPMAP_RESOURCE_TYPE_2D_TEXTURE_ARRAY= 6, + ZS_MIPMAP_RESOURCE_TYPE_CUBE_TEXTURE_ARRAY= 7, + ZS_MIPMAP_RESOURCE_TYPE_RAW_BUFFER = 8, + ZS_MIPMAP_RESOURCE_TYPE_STRUCTURED_BUFFER= 9, +} ZS_MIPMAP_RESOURCE_TYPE; +typedef enum +{ + ZV_DEPTH_FORMAT_Z16 = 0, + ZV_DEPTH_FORMAT_Z24 = 1, + ZV_DEPTH_FORMAT_Z32F = 2, +} ZV_DEPTH_FORMAT; +typedef enum +{ + ZV_DEPTH_L1CACHABLE_DISABLE = 0, + ZV_DEPTH_L1CACHABLE_ENABLE = 1, +} ZV_DEPTH_L1CACHABLE; +typedef enum +{ + ZV_DEPTH_L2CACHABLE_DISABLE = 0, + ZV_DEPTH_L2CACHABLE_ENABLE = 1, +} ZV_DEPTH_L2CACHABLE; +typedef enum +{ + FFC_CONFIG_FFC_ACK_DELAY_DISABLE = 0, + FFC_CONFIG_FFC_ACK_DELAY_HALF = 1, + FFC_CONFIG_FFC_ACK_DELAY_QUARTER = 2, +} FFC_CONFIG_FFC_ACK_DELAY; +typedef enum +{ + RT_DEPTH_CRF_MODE_FP = 0, + RT_DEPTH_CRF_MODE_HP = 1, +} RT_DEPTH_CRF_MODE; +typedef enum +{ + RT_MISC_DITHER_EN_DISABLE = 0, + RT_MISC_DITHER_EN_ENABLE = 1, +} RT_MISC_DITHER_EN; +typedef enum +{ + RT_MISC_EU_BLEND_ENABLE_DISABLE = 0, + RT_MISC_EU_BLEND_ENABLE_ENABLE = 1, +} RT_MISC_EU_BLEND_ENABLE; +typedef enum +{ + RT_MISC_EU_EMIT_COLOR_DISABLE = 0, + RT_MISC_EU_EMIT_COLOR_ENABLE = 1, +} RT_MISC_EU_EMIT_COLOR; +typedef enum +{ + RT_MISC_EUB_FORMAT_UNORM8 = 0, + RT_MISC_EUB_FORMAT_SNORM8 = 1, + RT_MISC_EUB_FORMAT_UINT8 = 2, + RT_MISC_EUB_FORMAT_SINT8 = 3, + RT_MISC_EUB_FORMAT_UINT8_SCALED = 4, + RT_MISC_EUB_FORMAT_SINT8_SCALED = 5, + RT_MISC_EUB_FORMAT_UNORM16 = 6, + RT_MISC_EUB_FORMAT_SNORM16 = 7, + RT_MISC_EUB_FORMAT_FP16 = 8, + RT_MISC_EUB_FORMAT_UINT16 = 9, + RT_MISC_EUB_FORMAT_SINT16 = 10, + RT_MISC_EUB_FORMAT_UINT16_SCALED = 11, + RT_MISC_EUB_FORMAT_SINT16_SCALED = 12, + RT_MISC_EUB_FORMAT_FP32 = 13, + RT_MISC_EUB_FORMAT_FIXED = 14, + RT_MISC_EUB_FORMAT_UNORM10 = 15, + RT_MISC_EUB_FORMAT_UNORM12 = 16, + RT_MISC_EUB_FORMAT_FP24 = 17, + RT_MISC_EUB_FORMAT_UNORM8_8 = 18, + RT_MISC_EUB_FORMAT_SNORM8_8 = 19, + RT_MISC_EUB_FORMAT_SNORM10 = 20, + RT_MISC_EUB_FORMAT_UNORM24 = 21, + RT_MISC_EUB_FORMAT_UNORM10_6 = 22, + RT_MISC_EUB_FORMAT_SNORM10_6 = 23, + RT_MISC_EUB_FORMAT_UINT32 = 24, + RT_MISC_EUB_FORMAT_UINT64 = 25, + RT_MISC_EUB_FORMAT_SINT32 = 26, +} RT_MISC_EUB_FORMAT; +typedef enum +{ + RT_MISC_SWIZZLE_3D_EN_DISABLE = 0, + RT_MISC_SWIZZLE_3D_EN_ENABLE = 1, +} RT_MISC_SWIZZLE_3D_EN; +typedef enum +{ + RT_MISC_MIPMAP_EN_DISABLE = 0, + RT_MISC_MIPMAP_EN_ENABLE = 1, +} RT_MISC_MIPMAP_EN; +typedef enum +{ + RT_MISC_RESOURCE_TYPE_1D_BUFFER = 0, + RT_MISC_RESOURCE_TYPE_1D_TEXTURE = 1, + RT_MISC_RESOURCE_TYPE_2D_TEXTURE = 2, + RT_MISC_RESOURCE_TYPE_3D_TEXTURE = 3, + RT_MISC_RESOURCE_TYPE_CUBIC_TEXTURE = 4, + RT_MISC_RESOURCE_TYPE_1D_TEXTURE_ARRAY = 5, + RT_MISC_RESOURCE_TYPE_2D_TEXTURE_ARRAY = 6, + RT_MISC_RESOURCE_TYPE_CUBE_TEXTURE_ARRAY= 7, + RT_MISC_RESOURCE_TYPE_RAW_BUFFER = 8, + RT_MISC_RESOURCE_TYPE_STRUCTURED_BUFFER = 9, +} RT_MISC_RESOURCE_TYPE; +typedef enum +{ + RT_MISC_L1CACHABLE_DISABLE = 0, + RT_MISC_L1CACHABLE_ENABLE = 1, +} RT_MISC_L1CACHABLE; +typedef enum +{ + RT_MISC_L2CACHABLE_DISABLE = 0, + RT_MISC_L2CACHABLE_ENABLE = 1, +} RT_MISC_L2CACHABLE; +typedef enum +{ + RAST_CTRL_RASTER_MODE_NORMAL = 0, + RAST_CTRL_RASTER_MODE_CONSERVATIVE = 1, +} RAST_CTRL_RASTER_MODE; +typedef enum +{ + RAST_CTRL_CHECK_BOARD_256X32 = 0, + RAST_CTRL_CHECK_BOARD_128X32 = 1, + RAST_CTRL_CHECK_BOARD_64X32 = 2, + RAST_CTRL_CHECK_BOARD_32X32 = 3, + RAST_CTRL_CHECK_BOARD_XX32 = 4, + RAST_CTRL_CHECK_BOARD_256X64 = 5, + RAST_CTRL_CHECK_BOARD_128X64 = 6, + RAST_CTRL_CHECK_BOARD_64X64 = 7, + RAST_CTRL_CHECK_BOARD_32X64 = 8, + RAST_CTRL_CHECK_BOARD_16X64 = 9, + RAST_CTRL_CHECK_BOARD_256X16 = 10, + RAST_CTRL_CHECK_BOARD_128X16 = 11, + RAST_CTRL_CHECK_BOARD_64X16 = 12, + RAST_CTRL_CHECK_BOARD_32X16 = 13, + RAST_CTRL_CHECK_BOARD_16X16 = 14, +} RAST_CTRL_CHECK_BOARD; +typedef enum +{ + RAST_CTRL_API_VERSION_OGL = 0, + RAST_CTRL_API_VERSION_DX9 = 1, + RAST_CTRL_API_VERSION_DX10 = 2, + RAST_CTRL_API_VERSION_DX11 = 3, + RAST_CTRL_API_VERSION_DX12 = 4, +} RAST_CTRL_API_VERSION; +typedef enum +{ + RAST_CTRL_ROV_EN_DISABLED = 0, + RAST_CTRL_ROV_EN_ENABLED = 1, +} RAST_CTRL_ROV_EN; +typedef enum +{ + RAST_CTRL_EUB_EN_DISABLED = 0, + RAST_CTRL_EUB_EN_ENABLED = 1, +} RAST_CTRL_EUB_EN; +typedef enum +{ + RAST_CTRL_MSAA_EN_MSAA_OFF = 0, + RAST_CTRL_MSAA_EN_MSAA_DEFALUT = 1, + RAST_CTRL_MSAA_EN_MSAA_USER_DEFINE = 2, + RAST_CTRL_MSAA_EN_MSAA_CENTER_SAMPLE = 3, +} RAST_CTRL_MSAA_EN; +typedef enum +{ + RAST_CTRL_AA_EN_NORMAL = 0, + RAST_CTRL_AA_EN_AA = 1, +} RAST_CTRL_AA_EN; +typedef enum +{ + SG_CTRL_RULE_FOR_TRIANGLE_TOP_LEFT = 0, + SG_CTRL_RULE_FOR_TRIANGLE_TOP_RIGHT = 1, + SG_CTRL_RULE_FOR_TRIANGLE_BOTTOM_LEFT = 2, + SG_CTRL_RULE_FOR_TRIANGLE_BOTTON_RIGHT = 3, +} SG_CTRL_RULE_FOR_TRIANGLE; +typedef enum +{ + SG_CTRL_STIPPLE_EN_DISABLE = 0, + SG_CTRL_STIPPLE_EN_ENABLE = 1, +} SG_CTRL_STIPPLE_EN; +typedef enum +{ + SG_CTRL_COMPRESS_EN_DISABLE = 0, + SG_CTRL_COMPRESS_EN_ENABLE = 1, +} SG_CTRL_COMPRESS_EN; +typedef enum +{ + SG_CTRL_EVALUATE_MODE_EN_DISABLE = 0, + SG_CTRL_EVALUATE_MODE_EN_ENABLE = 1, +} SG_CTRL_EVALUATE_MODE_EN; +typedef enum +{ + SG_CTRL_DISABLE_GPC_SPLIT_FALSE = 0, + SG_CTRL_DISABLE_GPC_SPLIT_TRUE = 1, +} SG_CTRL_DISABLE_GPC_SPLIT; +typedef enum +{ + SG_CTRL_DISABLE_SLICE_SPLIT_FALSE = 0, + SG_CTRL_DISABLE_SLICE_SPLIT_TRUE = 1, +} SG_CTRL_DISABLE_SLICE_SPLIT; +typedef enum +{ + ZS_REQ_CTRL_PS_OUTPUT_OMASK_DISABLE = 0, + ZS_REQ_CTRL_PS_OUTPUT_OMASK_ENABLE = 1, +} ZS_REQ_CTRL_PS_OUTPUT_OMASK; +typedef enum +{ + ZS_REQ_CTRL_D_ALLOCATION_MODULE_ZL2 = 0, + ZS_REQ_CTRL_D_ALLOCATION_MODULE_ZL3 = 1, +} ZS_REQ_CTRL_D_ALLOCATION_MODULE; +typedef enum +{ + ZS_REQ_CTRL_A2C_EN_DISABLE = 0, + ZS_REQ_CTRL_A2C_EN_ENABLE = 1, +} ZS_REQ_CTRL_A2C_EN; +typedef enum +{ + ZS_REQ_CTRL_D_ALLOC_EN_DISABLE = 0, + ZS_REQ_CTRL_D_ALLOC_EN_ENABLE = 1, +} ZS_REQ_CTRL_D_ALLOC_EN; +typedef enum +{ + ZS_REQ_CTRL_OROMASK_DISABLE = 0, + ZS_REQ_CTRL_OROMASK_ENABLE = 1, +} ZS_REQ_CTRL_OROMASK; +typedef enum +{ + ZS_CTL_Z_CMP_MODE_NEVER = 0, + ZS_CTL_Z_CMP_MODE_LESS = 1, + ZS_CTL_Z_CMP_MODE_EQUAL = 2, + ZS_CTL_Z_CMP_MODE_LESSEQUAL = 3, + ZS_CTL_Z_CMP_MODE_GREATER = 4, + ZS_CTL_Z_CMP_MODE_NOTEQUAL = 5, + ZS_CTL_Z_CMP_MODE_GREATEREQUAL = 6, + ZS_CTL_Z_CMP_MODE_ALWAYS = 7, +} ZS_CTL_Z_CMP_MODE; +typedef enum +{ + ZS_CTL_Z_16_OPTIMIZED_EN_DISABLE = 0, + ZS_CTL_Z_16_OPTIMIZED_EN_ENABLE = 1, +} ZS_CTL_Z_16_OPTIMIZED_EN; +typedef enum +{ + STENCIL_STATE_ST_OP_SFAIL_KEEP = 0, + STENCIL_STATE_ST_OP_SFAIL_ZERO = 1, + STENCIL_STATE_ST_OP_SFAIL_REPLACE = 2, + STENCIL_STATE_ST_OP_SFAIL_INCRSAT = 3, + STENCIL_STATE_ST_OP_SFAIL_DECRSAT = 4, + STENCIL_STATE_ST_OP_SFAIL_INVERT = 5, + STENCIL_STATE_ST_OP_SFAIL_INCRSAT1 = 6, + STENCIL_STATE_ST_OP_SFAIL_DECRSAT1 = 7, +} STENCIL_STATE_ST_OP_SFAIL; +typedef enum +{ + RES_BLK_REF_RESOLUTION_PS_REF_LEVEL_RES16X= 0, + RES_BLK_REF_RESOLUTION_PS_REF_LEVEL_RES8X= 1, + RES_BLK_REF_RESOLUTION_PS_REF_LEVEL_RES4X= 2, + RES_BLK_REF_RESOLUTION_PS_REF_LEVEL_RES2X= 3, + RES_BLK_REF_RESOLUTION_PS_REF_LEVEL_RES1X= 4, + RES_BLK_REF_RESOLUTION_PS_REF_LEVEL_RES1_2X= 5, + RES_BLK_REF_RESOLUTION_PS_REF_LEVEL_RES1_4X= 6, + RES_BLK_REF_RESOLUTION_PS_REF_LEVEL_RES1_8X= 7, + RES_BLK_REF_RESOLUTION_PS_REF_LEVEL_RES1_16X= 8, +} RES_BLK_REF_RESOLUTION_PS_REF_LEVEL; +typedef enum +{ + BS_BLEND_CTL_RGB_SBLEND_ZERO = 0, + BS_BLEND_CTL_RGB_SBLEND_ONE = 1, + BS_BLEND_CTL_RGB_SBLEND_SRCCOLOR = 2, + BS_BLEND_CTL_RGB_SBLEND_INVSRCCOLOR = 3, + + BS_BLEND_CTL_RGB_SBLEND_SRCALPHA = 4, + BS_BLEND_CTL_RGB_SBLEND_INVSRCALPHA = 5, + + BS_BLEND_CTL_RGB_SBLEND_DESTALPHA = 6, + BS_BLEND_CTL_RGB_SBLEND_INVDESTALPHA = 7, + + BS_BLEND_CTL_RGB_SBLEND_DESTCOLOR = 8, + BS_BLEND_CTL_RGB_SBLEND_INVDESTCOLOR = 9, + + BS_BLEND_CTL_RGB_SBLEND_SRCALPHASAT = 10, + + BS_BLEND_CTL_RGB_SBLEND_CONSTANTCOLOR = 11, + + BS_BLEND_CTL_RGB_SBLEND_INVCONSTANTCOLOR= 12, + + BS_BLEND_CTL_RGB_SBLEND_CONSTANTALPHA = 13, + + BS_BLEND_CTL_RGB_SBLEND_INVCONSTANTALPHA= 14, + + BS_BLEND_CTL_RGB_SBLEND_SRCCONSTANTALPHA= 15, + + BS_BLEND_CTL_RGB_SBLEND_SRC1_COLOR = 16, + BS_BLEND_CTL_RGB_SBLEND_INVSRC1_COLOR = 17, + BS_BLEND_CTL_RGB_SBLEND_SRC1_ALPHA = 18, + BS_BLEND_CTL_RGB_SBLEND_INVSRC1_ALPHA = 19, +} BS_BLEND_CTL_RGB_SBLEND; +typedef enum +{ + BS_BLEND_CTL_RGB_BLEND_OP_ADD = 0, + BS_BLEND_CTL_RGB_BLEND_OP_SUBTRACT = 1, + BS_BLEND_CTL_RGB_BLEND_OP_REVSUBTRACT = 2, + BS_BLEND_CTL_RGB_BLEND_OP_MAX_OP = 3, + BS_BLEND_CTL_RGB_BLEND_OP_MIN_OP = 4, +} BS_BLEND_CTL_RGB_BLEND_OP; +typedef enum +{ + TASBE_CTRL_MSAA_STATE_MSAA_1X = 0, + TASBE_CTRL_MSAA_STATE_MSAA_2X = 1, + TASBE_CTRL_MSAA_STATE_MSAA_4X = 2, + TASBE_CTRL_MSAA_STATE_MSAA_8X = 3, + TASBE_CTRL_MSAA_STATE_MSAA_16X = 4, +} TASBE_CTRL_MSAA_STATE; +typedef enum +{ + TASBE_CTRL_AA_EN_FALSE = 0, + TASBE_CTRL_AA_EN_TRUE = 1, +} TASBE_CTRL_AA_EN; +typedef enum +{ + TASBE_CTRL_RASTER_MODE_NORMAL = 0, + TASBE_CTRL_RASTER_MODE_CONSERVATIVE = 1, +} TASBE_CTRL_RASTER_MODE; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Tbr_En : 1; + unsigned int Tbr_Mode : 1; + unsigned int Tile_Size : 4; + unsigned int Ffc_Config_Mode : 3; + unsigned int Ffc_U_Start : 5; + + unsigned int Reserved : 18; + } reg; +} Reg_Ff_Glb_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Reserved_1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Reserved_2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Reserved_3; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Dst_Resolution_Mode : 3; + unsigned int Msaa_Mode : 3; + unsigned int Multi_Res_En : 1; + + + + unsigned int Ps_Sample_Freq_En : 1; + unsigned int Reserved : 24; + } reg; +} Reg_Resolution_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Src_Read_Alloc_En : 1; + unsigned int Fc_St_Wr_Mask : 8; + unsigned int L2l_Blit_Optimization_En : 1; + + unsigned int Src_Bits_Mode : 2; + unsigned int Color_Key_En : 1; + + unsigned int S_Read_En : 1; + unsigned int Thread_Mode : 1; + unsigned int Reserved : 17; + } reg; +} Reg_Dzs_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Arraysize : 12; + unsigned int First_Array_Idx : 11; + unsigned int Reserved : 9; + } reg; +} Reg_Zs_View_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Zs_Mip_En : 1; + unsigned int Zs_Lod : 4; + unsigned int Z_Bl_Slot_Idx : 18; + unsigned int Resource_Type : 4; + unsigned int Reserved : 5; + } reg; +} Reg_Zs_Mipmap; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Width : 15; + unsigned int Height : 15; + unsigned int Reserved : 2; + } reg; +} Reg_Zv_Size; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Depth_Or_Arraysize : 12; + unsigned int Z_Range_Type : 6; + unsigned int Format : 2; + unsigned int L1cachable : 1; + unsigned int L2cachable : 1; + unsigned int S_Range_Type : 6; + unsigned int Z_Discard_En : 1; + + + unsigned int S_Discard_En : 1; + + + unsigned int Z_Msaa_Opt_En : 1; + + + unsigned int S_Msaa_Opt_En : 1; + + + } reg; +} Reg_Zv_Depth; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Addr : 32; + + } reg; +} Reg_Zv_Desc_Base0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Addr : 32; + + } reg; +} Reg_Sv_Desc_Base0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Bl_Slot_Idx : 18; + unsigned int Reserved : 14; + } reg; +} Reg_Sv_Bl_Slot_Idx; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Tbr_Dsig_En : 1; + + + + unsigned int Ffc_Ack_Delay : 2; + unsigned int En_4kb_Mem_Swizzle : 1; + unsigned int En_Decompressed_Data_Reorder : 1; + + unsigned int Slot_Swz_Enable : 1; + + unsigned int Reserved : 26; + } reg; +} Reg_Ffc_Config; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Global_Offset : 8; + unsigned int Global_Size : 8; + + unsigned int Reserved : 16; + } reg; +} Reg_Ffc_Global_Range_Config; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Reserved_4; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Addr : 32; + } reg; +} Reg_Addr; + +typedef struct _Group_Ffc_Dsig_Base_Addr +{ + Reg_Addr reg_Addr; +} Reg_Ffc_Dsig_Base_Addr_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Addr : 32; + } reg; +} Reg_Rt_Addr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Depth_Or_Arraysize : 12; + unsigned int Lod : 4; + unsigned int Range_Type : 6; + unsigned int Discard_En : 1; + + + unsigned int Crf_Addr : 6; + unsigned int Crf_Mode : 1; + unsigned int Msaa_Opt_En : 1; + + + unsigned int Reserved : 1; + } reg; +} Reg_Rt_Depth; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Arraysize : 12; + unsigned int First_Array_Idx : 11; + unsigned int Reserved : 9; + } reg; +} Reg_Rt_View_Ctrl; + +typedef struct _Group_Rt_Addr_Ctrl +{ + Reg_Rt_Addr reg_Rt_Addr; + Reg_Rt_Depth reg_Rt_Depth; + Reg_Rt_View_Ctrl reg_Rt_View_Ctrl; +} Reg_Rt_Addr_Ctrl_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Format : 9; + unsigned int Bl_Slot_Idx : 18; + unsigned int Reserved : 5; + } reg; +} Reg_Rt_Fmt; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Width : 15; + unsigned int Height : 15; + unsigned int Reserved : 2; + } reg; +} Reg_Rt_Size; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rt_Enable : 1; + unsigned int Is_Tiling : 1; + unsigned int Rt_Write_Mask : 4; + unsigned int Dither_En : 1; + unsigned int D_Read_En : 1; + + + + unsigned int Resolve_Write_En : 1; + unsigned int Blend_Enable : 1; + unsigned int Eu_Blend_Enable : 1; + unsigned int Eu_Emit_Color : 1; + + unsigned int Eub_Format : 5; + unsigned int Dual_Source_En : 1; + unsigned int Swizzle_3d_En : 1; + unsigned int Mipmap_En : 1; + unsigned int Resource_Type : 4; + unsigned int Rop : 5; + + + + + + + + + + + + + + + + + + + + unsigned int L1cachable : 1; + unsigned int L2cachable : 1; + unsigned int Reserved : 1; + } reg; +} Reg_Rt_Misc; + +typedef struct _Group_Rt_Ctrl +{ + Reg_Rt_Fmt reg_Rt_Fmt; + Reg_Rt_Size reg_Rt_Size; + Reg_Rt_Misc reg_Rt_Misc; +} Reg_Rt_Ctrl_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Raster_Mode : 1; + unsigned int Check_Board : 4; + + unsigned int Api_Version : 3; + + + unsigned int Rov_En : 1; + unsigned int Eub_En : 1; + unsigned int Msaa_En : 2; + unsigned int Aa_En : 1; + unsigned int Msaa_Mask : 16; + unsigned int Reserved : 3; + } reg; +} Reg_Rast_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rule_For_Triangle : 2; + unsigned int Rule_For_A_Line : 2; + unsigned int Rule_For_Msaa_Line : 2; + unsigned int Stipple_En : 1; + unsigned int Compress_En : 1; + unsigned int Evaluate_Mode_En : 1; + unsigned int Disable_Gpc_Split : 1; + unsigned int Disable_Slice_Split : 1; + unsigned int Reserved : 21; + } reg; +} Reg_Sg_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Z_Read_En : 1; + unsigned int Zl1_Zrange_Update_En : 1; + unsigned int Z_Alloc_En : 1; + unsigned int S_Alloc_En : 1; + unsigned int Zl2_End_Pipe_En : 1; + unsigned int Zl3_End_Pipe_En : 1; + unsigned int Zl1_Depth_Bound_Test_En : 1; + unsigned int Zl2_Depth_Bound_Test_En : 1; + unsigned int Zl3_Depth_Bound_Test_En : 1; + unsigned int Zl1_Range_Test_En : 1; + unsigned int Zl2_Z_Test_En : 1; + unsigned int Zl3_Z_Test_En : 1; + unsigned int Zl2_S_Test_En : 1; + unsigned int Zl3_S_Test_En : 1; + unsigned int Zl2_Z_Update_En : 1; + unsigned int Zl3_Z_Update_En : 1; + unsigned int Zl2_S_Update_En : 1; + unsigned int Zl3_S_Update_En : 1; + unsigned int Zl1_Clip_En : 1; + unsigned int Zl2_Clip_En : 1; + unsigned int Zl3_Clip_En : 1; + unsigned int Ps_Output_Stencil_Ref : 1; + unsigned int Ps_Output_Alpha_En : 1; + unsigned int Ps_Output_Depth : 1; + unsigned int Ps_Output_Omask : 1; + unsigned int Eu_Kill_Pixel : 1; + unsigned int D_Allocation_Module : 1; + unsigned int A2c_En : 1; + unsigned int D_Alloc_En : 1; + unsigned int Oromask : 1; + unsigned int Z_Resolved_Read_En : 1; + + + + unsigned int S_Resolved_Read_En : 1; + + + } reg; +} Reg_Zs_Req_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Z_Cmp_Mode : 3; + unsigned int Z_16_Optimized_En : 1; + + + + + + unsigned int Z_Occlusion_Counting_Enable : 1; + unsigned int St_Ref_Front : 8; + unsigned int St_Ref_Back : 8; + unsigned int Z_Is_Read_Only : 1; + unsigned int S_Is_Read_Only : 1; + unsigned int Zl1_Pass_Optimized : 1; + unsigned int Is_Alpha_Reorder : 1; + + unsigned int Reserved : 7; + } reg; +} Reg_Zs_Ctl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int St_Cmp_Mode : 3; + unsigned int Reserved1 : 1; + unsigned int St_Op_Sfail : 3; + + unsigned int Reserved2 : 1; + unsigned int St_Op_Zfail : 3; + + unsigned int Reserved3 : 1; + unsigned int St_Op_Pass : 3; + + unsigned int Reserved4 : 1; + unsigned int St_Cmp_Mask : 8; + unsigned int St_Wr_Mask : 8; + } reg; +} Reg_Stencil_State; + +typedef struct _Group_Ff_Stencil_Group +{ + Reg_Stencil_State reg_Stencil_State; +} Reg_Ff_Stencil_Group_Group; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Depth_Bound_Start; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Depth_Bound_End; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Viewport_Zmin; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int uint; + } reg; +} Reg_Viewport_Zmax; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int S0_Xy : 8; + unsigned int S1_Xy : 8; + unsigned int S2_Xy : 8; + unsigned int S3_Xy : 8; + } reg; +} Reg_User_Msaa_Pattern_Xy; + +typedef struct _Group_User_Msaa_Pattern_Group +{ + Reg_User_Msaa_Pattern_Xy reg_User_Msaa_Pattern_Xy; +} Reg_User_Msaa_Pattern_Group_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Top_Left_X : 15; + unsigned int Top_Left_Y : 15; + unsigned int Reserved : 2; + } reg; +} Reg_Res_Blk_Topleft_Coord; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Width : 15; + unsigned int Height : 15; + unsigned int Reserved : 2; + } reg; +} Reg_Res_Blk_Size; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ps_Ref_Level : 4; + unsigned int Reserved : 28; + } reg; +} Reg_Res_Blk_Ref_Resolution; + +typedef struct _Group_Multi_Res_Blk_Group +{ + Reg_Res_Blk_Topleft_Coord reg_Res_Blk_Topleft_Coord; + Reg_Res_Blk_Size reg_Res_Blk_Size; + Reg_Res_Blk_Ref_Resolution reg_Res_Blk_Ref_Resolution; +} Reg_Multi_Res_Blk_Group_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vr_Znear : 32; + } reg; +} Reg_Vr_Znear; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vr_Zfar : 32; + } reg; +} Reg_Vr_Zfar; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vr_Znear_Level : 4; + unsigned int Vr_Zfar_Level : 4; + unsigned int Move_Adjust_Level : 4; + + unsigned int Reserved : 20; + } reg; +} Reg_Vr_Z_Level; + +typedef struct _Group_Vr_Zrange_Group +{ + Reg_Vr_Znear reg_Vr_Znear; + Reg_Vr_Zfar reg_Vr_Zfar; + Reg_Vr_Z_Level reg_Vr_Z_Level; +} Reg_Vr_Zrange_Group_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rgb_Sblend : 5; + unsigned int Rgb_Dblend : 5; + + unsigned int Rgb_Blend_Op : 3; + unsigned int Alpha_Blend_Op : 3; + + unsigned int Alpha_Sblend : 5; + + unsigned int Alpha_Dblend : 5; + + unsigned int Reserved : 6; + } reg; +} Reg_Bs_Blend_Ctl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int C_G : 16; + unsigned int C_R : 16; + } reg; +} Reg_Blend_Color_Rg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int C_A : 16; + unsigned int C_B : 16; + } reg; +} Reg_Blend_Color_Ba; + +typedef struct _Group_Blend_Ctl +{ + Reg_Bs_Blend_Ctl reg_Bs_Blend_Ctl; + Reg_Blend_Color_Rg reg_Blend_Color_Rg; + Reg_Blend_Color_Ba reg_Blend_Color_Ba; +} Reg_Blend_Ctl_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Color : 32; + } reg; +} Reg_Fast_Clear_Color; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr_Num : 6; + unsigned int Msaa_State : 3; + + unsigned int Aa_En : 1; + unsigned int Raster_Mode : 1; + unsigned int Reserved : 21; + } reg; +} Reg_Tasbe_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Per_Draw_Sig_En : 1; + unsigned int Reserved : 3; + unsigned int Sig_Base_Addr : 28; + } reg; +} Reg_Signature_Ctrl; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Reserved_5; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Reserved_6; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Reserved_7; + +typedef struct _Ff_regs +{ + Reg_Ff_Glb_Ctrl reg_Ff_Glb_Ctrl; + Reg_Reserved_1 reg_Reserved_1; + Reg_Reserved_2 reg_Reserved_2; + Reg_Reserved_3 reg_Reserved_3; + Reg_Resolution_Ctrl reg_Resolution_Ctrl; + Reg_Dzs_Ctrl reg_Dzs_Ctrl; + Reg_Zs_View_Ctrl reg_Zs_View_Ctrl; + Reg_Zs_Mipmap reg_Zs_Mipmap; + Reg_Zv_Size reg_Zv_Size; + Reg_Zv_Depth reg_Zv_Depth; + Reg_Zv_Desc_Base0 reg_Zv_Desc_Base0; + Reg_Sv_Desc_Base0 reg_Sv_Desc_Base0; + Reg_Sv_Bl_Slot_Idx reg_Sv_Bl_Slot_Idx; + Reg_Ffc_Config reg_Ffc_Config; + Reg_Ffc_Global_Range_Config reg_Ffc_Global_Range_Config; + Reg_Reserved_4 reg_Reserved_4; + Reg_Ffc_Dsig_Base_Addr_Group reg_Ffc_Dsig_Base_Addr[8]; + Reg_Rt_Addr_Ctrl_Group reg_Rt_Addr_Ctrl[8]; + Reg_Rt_Ctrl_Group reg_Rt_Ctrl[8]; + Reg_Rast_Ctrl reg_Rast_Ctrl; + Reg_Sg_Ctrl reg_Sg_Ctrl; + Reg_Zs_Req_Ctrl reg_Zs_Req_Ctrl; + Reg_Zs_Ctl reg_Zs_Ctl; + Reg_Ff_Stencil_Group_Group reg_Ff_Stencil_Group[2]; + Reg_Depth_Bound_Start reg_Depth_Bound_Start; + Reg_Depth_Bound_End reg_Depth_Bound_End; + Reg_Viewport_Zmin reg_Viewport_Zmin[16]; + Reg_Viewport_Zmax reg_Viewport_Zmax[16]; + Reg_User_Msaa_Pattern_Group_Group + reg_User_Msaa_Pattern_Group[4]; + Reg_Multi_Res_Blk_Group_Group reg_Multi_Res_Blk_Group[18]; + Reg_Vr_Zrange_Group_Group reg_Vr_Zrange_Group[2]; + Reg_Blend_Ctl_Group reg_Blend_Ctl[8]; + Reg_Fast_Clear_Color reg_Fast_Clear_Color[4]; + Reg_Tasbe_Ctrl reg_Tasbe_Ctrl; + Reg_Reserved_5 reg_Reserved_5; + Reg_Reserved_6 reg_Reserved_6; + Reg_Reserved_7 reg_Reserved_7; +} Ff_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/GPCPBE_register.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/GPCPBE_register.h new file mode 100644 index 0000000000000..50df4caf94f08 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/GPCPBE_register.h @@ -0,0 +1,359 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _GPCPBE_REGISTER_H +#define _GPCPBE_REGISTER_H + + +#ifndef GPCPBE_BLOCKBASE_INF +#define GPCPBE_BLOCKBASE_INF +#define BLOCK_GPCPBE_VERSION 1 +#define BLOCK_GPCPBE_TIMESTAMP "2018/6/8 17:55:28" +#define GPCPBE_BLOCK 0x15 +#define GPCPBE_REG_START 0x0 +#define GPCPBE_REG_END 0x1C8 +#define GPCPBE_REG_LIMIT 0x1C8 +#endif + + +#define Reg_Sto_Cfg_Offset 0x0 +#define Reg_Sto_Prim_Info_Offset 0x1 +#define Reg_Sto_Cnt_Cfg_Offset 0x2 +#define Reg_Sto_Stm_Buf_Mask_Offset 0x3 +#define Reg_Sto_Reserved0_Offset 0x4 +#define Reg_Sto_Buf_Offset 0x8 +#define Reg_Sto_Stm_Cnt_Offset 0x38 +#define Reg_Sto_Stm_Map_Offset 0x48 + + +typedef enum +{ + STO_CFG_STO_EN_DISABLED = 0, + STO_CFG_STO_EN_ENABLED = 1, + +} STO_CFG_STO_EN; +typedef enum +{ + STO_CFG_STREAM0_EN_DISABLE = 0, + STO_CFG_STREAM0_EN_ENABLE = 1, +} STO_CFG_STREAM0_EN; +typedef enum +{ + STO_CFG_STREAM1_EN_DISABLE = 0, + STO_CFG_STREAM1_EN_ENABLE = 1, +} STO_CFG_STREAM1_EN; +typedef enum +{ + STO_CFG_STREAM2_EN_DISABLE = 0, + STO_CFG_STREAM2_EN_ENABLE = 1, +} STO_CFG_STREAM2_EN; +typedef enum +{ + STO_CFG_STREAM3_EN_DISABLE = 0, + STO_CFG_STREAM3_EN_ENABLE = 1, +} STO_CFG_STREAM3_EN; +typedef enum +{ + STO_CFG_BUFFER0_EN_DISABLE = 0, + STO_CFG_BUFFER0_EN_ENABLE = 1, +} STO_CFG_BUFFER0_EN; +typedef enum +{ + STO_CFG_BUFFER1_EN_DISABLE = 0, + STO_CFG_BUFFER1_EN_ENABLE = 1, +} STO_CFG_BUFFER1_EN; +typedef enum +{ + STO_CFG_BUFFER2_EN_DISABLE = 0, + STO_CFG_BUFFER2_EN_ENABLE = 1, +} STO_CFG_BUFFER2_EN; +typedef enum +{ + STO_CFG_BUFFER3_EN_DISABLE = 0, + STO_CFG_BUFFER3_EN_ENABLE = 1, +} STO_CFG_BUFFER3_EN; +typedef enum +{ + STO_CNT_CFG_STM0_PRIM_CNT_OFF = 0, + STO_CNT_CFG_STM0_PRIM_CNT_ON = 1, +} STO_CNT_CFG_STM0_PRIM_CNT; +typedef enum +{ + STO_CNT_CFG_STM1_PRIM_CNT_OFF = 0, + STO_CNT_CFG_STM1_PRIM_CNT_ON = 1, +} STO_CNT_CFG_STM1_PRIM_CNT; +typedef enum +{ + STO_CNT_CFG_STM2_PRIM_CNT_OFF = 0, + STO_CNT_CFG_STM2_PRIM_CNT_ON = 1, +} STO_CNT_CFG_STM2_PRIM_CNT; +typedef enum +{ + STO_CNT_CFG_STM3_PRIM_CNT_OFF = 0, + STO_CNT_CFG_STM3_PRIM_CNT_ON = 1, +} STO_CNT_CFG_STM3_PRIM_CNT; +typedef enum +{ + STO_CNT_CFG_OFFSET0_W_EN_OFF = 0, + STO_CNT_CFG_OFFSET0_W_EN_ON = 1, +} STO_CNT_CFG_OFFSET0_W_EN; +typedef enum +{ + STO_CNT_CFG_OFFSET1_W_EN_OFF = 0, + STO_CNT_CFG_OFFSET1_W_EN_ON = 1, +} STO_CNT_CFG_OFFSET1_W_EN; +typedef enum +{ + STO_CNT_CFG_OFFSET2_W_EN_OFF = 0, + STO_CNT_CFG_OFFSET2_W_EN_ON = 1, +} STO_CNT_CFG_OFFSET2_W_EN; +typedef enum +{ + STO_CNT_CFG_OFFSET3_W_EN_OFF = 0, + STO_CNT_CFG_OFFSET3_W_EN_ON = 1, +} STO_CNT_CFG_OFFSET3_W_EN; +typedef enum +{ + STO_STM_MAPPING_C0_V_INVALID = 0, + STO_STM_MAPPING_C0_V_VALID = 1, +} STO_STM_MAPPING_C0_V; +typedef enum +{ + STO_STM_MAPPING_C1_V_INVALID = 0, + STO_STM_MAPPING_C1_V_VALID = 1, +} STO_STM_MAPPING_C1_V; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Sto_En : 1; + unsigned int Stream0_En : 1; + unsigned int Stream1_En : 1; + unsigned int Stream2_En : 1; + unsigned int Stream3_En : 1; + unsigned int Buffer0_En : 1; + unsigned int Buffer1_En : 1; + unsigned int Buffer2_En : 1; + unsigned int Buffer3_En : 1; + unsigned int Reserved : 23; + } reg; +} Reg_Sto_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Prim_Vtx_Num : 6; + + unsigned int Vtx_Out_Size : 6; + + unsigned int Reserved : 20; + } reg; +} Reg_Sto_Prim_Info; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Stm0_Prim_Cnt : 1; + unsigned int Stm1_Prim_Cnt : 1; + unsigned int Stm2_Prim_Cnt : 1; + unsigned int Stm3_Prim_Cnt : 1; + unsigned int Offset0_W_En : 1; + unsigned int Offset1_W_En : 1; + unsigned int Offset2_W_En : 1; + unsigned int Offset3_W_En : 1; + unsigned int Reserved : 24; + } reg; +} Reg_Sto_Cnt_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Stm0_Buf_Mask : 4; + + unsigned int Stm1_Buf_Mask : 4; + + unsigned int Stm2_Buf_Mask : 4; + + unsigned int Stm3_Buf_Mask : 4; + + unsigned int Reserved : 16; + } reg; +} Reg_Sto_Stm_Buf_Mask; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Sto_Reserved0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Addr_Low : 32; + + } reg; +} Reg_Sto_Buf_Addr0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Addr_High : 8; + + unsigned int Reserved : 24; + } reg; +} Reg_Sto_Buf_Addr1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Range : 32; + } reg; +} Reg_Sto_Buf_Range; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Stride : 12; + + unsigned int Reserved : 20; + } reg; +} Reg_Sto_Buf_Stride; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Offset : 32; + + } reg; +} Reg_Sto_Buf_Start; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Line_Num : 4; + + + unsigned int Reserved : 28; + } reg; +} Reg_Sto_Buf_Map_Usage; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Comp_Mask : 32; + + } reg; +} Reg_Sto_Buf_Map_Mask; + +typedef struct _Group_Sto_Buf +{ + Reg_Sto_Buf_Addr0 reg_Sto_Buf_Addr0; + Reg_Sto_Buf_Addr1 reg_Sto_Buf_Addr1; + Reg_Sto_Buf_Range reg_Sto_Buf_Range; + Reg_Sto_Buf_Stride reg_Sto_Buf_Stride; + Reg_Sto_Buf_Start reg_Sto_Buf_Start; + Reg_Sto_Buf_Map_Usage reg_Sto_Buf_Map_Usage; + Reg_Sto_Buf_Map_Mask reg_Sto_Buf_Map_Mask[6]; +} Reg_Sto_Buf_Group; + +typedef union +{ + unsigned int uint[2]; + struct + { + unsigned long long Count : 64; + + } reg; +} Reg_Sto_Prim_Written_Total; + +typedef union +{ + unsigned int uint[2]; + struct + { + unsigned long long Count : 64; + + + } reg; +} Reg_Sto_Prim_Needed_Total; + +typedef struct _Group_Sto_Stm_Cnt +{ + Reg_Sto_Prim_Written_Total reg_Sto_Prim_Written_Total; + Reg_Sto_Prim_Needed_Total reg_Sto_Prim_Needed_Total; +} Reg_Sto_Stm_Cnt_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int C0_V : 1; + unsigned int C0_Buf : 2; + unsigned int C0_Addr : 8; + unsigned int Reserved0 : 5; + unsigned int C1_V : 1; + unsigned int C1_Buf : 2; + unsigned int C1_Addr : 8; + unsigned int Reserved1 : 5; + } reg; +} Reg_Sto_Stm_Mapping; + +typedef struct _Group_Sto_Stm_Map +{ + Reg_Sto_Stm_Mapping reg_Sto_Stm_Mapping[96]; +} Reg_Sto_Stm_Map_Group; + +typedef struct _Gpcpbe_regs +{ + Reg_Sto_Cfg reg_Sto_Cfg; + Reg_Sto_Prim_Info reg_Sto_Prim_Info; + Reg_Sto_Cnt_Cfg reg_Sto_Cnt_Cfg; + Reg_Sto_Stm_Buf_Mask reg_Sto_Stm_Buf_Mask; + Reg_Sto_Reserved0 reg_Sto_Reserved0[4]; + Reg_Sto_Buf_Group reg_Sto_Buf[4]; + Reg_Sto_Stm_Cnt_Group reg_Sto_Stm_Cnt[4]; + Reg_Sto_Stm_Map_Group reg_Sto_Stm_Map[4]; +} Gpcpbe_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/GPCPFE_register.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/GPCPFE_register.h new file mode 100644 index 0000000000000..fe22bec749b22 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/GPCPFE_register.h @@ -0,0 +1,241 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _GPCPFE_REGISTER_H +#define _GPCPFE_REGISTER_H + + +#ifndef GPCPFE_BLOCKBASE_INF + #define GPCPFE_BLOCKBASE_INF + #define BLOCK_GPCPFE_VERSION 1 + #define BLOCK_GPCPFE_TIMESTAMP "2018/9/7 14:21:01" + #define GPCPFE_BLOCK 0x1 + #define GPCPFE_REG_START 0x0 + #define GPCPFE_REG_END 0x70 + #define GPCPFE_REG_LIMIT 0x70 +#endif + + +#define Reg_Gpcpfe_Instance_Offset 0x0 +#define Reg_Gpcpfe_Inst_Mask_Offset 0x20 +#define Reg_Gpcpfe_Scheduler_Ctrl_Offset 0x21 +#define Reg_Gpcpfe_Reserved_Offset 0x22 +#define Reg_Gpcpfe_Iidcnt_Offset 0x28 +#define Reg_Gpcpfe_Iid_Offset 0x68 +#define Reg_Gpcpfe_Pid_Offset 0x69 +#define Reg_Gpcpfe_Gp_Global_Offset 0x6A +#define Reg_Gpcpfe_Gp_Group_Offset 0x6D + + +typedef enum +{ + GPCPFE_SCHEDULER_CTRL_SCHEDULER_MODE_SLICE_FIRST_LOOP= 0, + + GPCPFE_SCHEDULER_CTRL_SCHEDULER_MODE_GPC_FIRST_LOOP= 1, + +} GPCPFE_SCHEDULER_CTRL_SCHEDULER_MODE; +typedef enum +{ + GPCPFE_SCHEDULER_CTRL_SCHEDULER_CAPACITY_CTRL_DISABLE= 0, + + GPCPFE_SCHEDULER_CTRL_SCHEDULER_CAPACITY_CTRL_ENABLE= 1, + +} GPCPFE_SCHEDULER_CTRL_SCHEDULER_CAPACITY_CTRL; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Step_Rate : 26; + + unsigned int Reserved : 6; + } reg; +} Reg_Gpcpfe_Instance_Ctl; + +typedef struct _Group_Gpcpfe_Instance +{ + Reg_Gpcpfe_Instance_Ctl reg_Gpcpfe_Instance_Ctl; +} Reg_Gpcpfe_Instance_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Mask : 32; + + + + } reg; +} Reg_Gpcpfe_Inst_Mask; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Scheduler_Mode : 1; + unsigned int Reserved_0 : 3; + + unsigned int Scheduler_Capacity_Ctrl : 1; + + unsigned int Reserved_1 : 11; + unsigned int Fifolimit : 8; + + + + + + unsigned int Reserved_2 : 8; + } reg; +} Reg_Gpcpfe_Scheduler_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Gpcpfe_Reserved; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Quotient : 32; + } reg; +} Reg_Cnt0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Remainder : 32; + } reg; +} Reg_Cnt1; + +typedef struct _Group_Gpcpfe_Iidcnt +{ + Reg_Cnt0 reg_Cnt0; + Reg_Cnt1 reg_Cnt1; +} Reg_Gpcpfe_Iidcnt_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Iid : 32; + } reg; +} Reg_Gpcpfe_Iid; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Pid : 32; + } reg; +} Reg_Gpcpfe_Pid; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int X : 32; + } reg; +} Reg_Globalx; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Y : 32; + } reg; +} Reg_Globaly; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Z : 32; + } reg; +} Reg_Globalz; + +typedef struct _Group_Gpcpfe_Gp_Global +{ + Reg_Globalx reg_Globalx; + Reg_Globaly reg_Globaly; + Reg_Globalz reg_Globalz; +} Reg_Gpcpfe_Gp_Global_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int X : 32; + } reg; +} Reg_Groupx; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Y : 32; + } reg; +} Reg_Groupy; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Z : 32; + } reg; +} Reg_Groupz; + +typedef struct _Group_Gpcpfe_Gp_Group +{ + Reg_Groupx reg_Groupx; + Reg_Groupy reg_Groupy; + Reg_Groupz reg_Groupz; +} Reg_Gpcpfe_Gp_Group_Group; + +typedef struct _Gpcpfe_regs +{ + Reg_Gpcpfe_Instance_Group reg_Gpcpfe_Instance[32]; + Reg_Gpcpfe_Inst_Mask reg_Gpcpfe_Inst_Mask; + Reg_Gpcpfe_Scheduler_Ctrl reg_Gpcpfe_Scheduler_Ctrl; + Reg_Gpcpfe_Reserved reg_Gpcpfe_Reserved[6]; + Reg_Gpcpfe_Iidcnt_Group reg_Gpcpfe_Iidcnt[32]; + Reg_Gpcpfe_Iid reg_Gpcpfe_Iid; + Reg_Gpcpfe_Pid reg_Gpcpfe_Pid; + Reg_Gpcpfe_Gp_Global_Group reg_Gpcpfe_Gp_Global; + Reg_Gpcpfe_Gp_Group_Group reg_Gpcpfe_Gp_Group; +} Gpcpfe_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/IU_reg.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/IU_reg.h new file mode 100644 index 0000000000000..e8bdacd1ed587 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/IU_reg.h @@ -0,0 +1,497 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _IU_REG_H +#define _IU_REG_H + + +#ifndef IU_BLOCKBASE_INF + #define IU_BLOCKBASE_INF + #define BLOCK_IU_VERSION 1 + #define BLOCK_IU_TIMESTAMP "2018/10/25 14:55:35" + #define IU_BLOCK 0x7 + #define IU_REG_START 0x0 + #define IU_REG_END 0x40 + #define IU_REG_LIMIT 0x40 +#endif + + +#define Reg_Iu_Ctrl_Offset 0x0 +#define Reg_Iu_Ctrl_Ex_Offset 0x1 +#define Reg_Iu_Rt_Size_Offset 0x2 +#define Reg_Iu_Mapping_Offset 0x3 +#define Reg_Iu_Intp_Mode_Offset 0xD +#define Reg_Iu_Clip_Distance_Offset 0x12 +#define Reg_Iu_Crf_Baseaddr_Offset 0x14 +#define Reg_Iu_Pxpy_Crf_Baseaddr_Offset 0x1E +#define Reg_Iu_Pxpy_Lowhigh_Offset 0x28 +#define Reg_Iu_Output_Format_Offset 0x2A +#define Reg_Iu_Viewportzvalue_Offset 0x2C +#define Reg_Iu_Builtin_Attr_Packing_Offset 0x3C +#define Reg_Iu_Reserved_Dw_Offset 0x3D + + +typedef enum +{ + IU_CTRL_INSERT_POS_DISABLED = 0, + IU_CTRL_INSERT_POS_ENABLED = 1, +} IU_CTRL_INSERT_POS; +typedef enum +{ + IU_CTRL_INSERT_FACE_DISABLED = 0, + IU_CTRL_INSERT_FACE_ENABLED = 1, + +} IU_CTRL_INSERT_FACE; +typedef enum +{ + IU_CTRL_INSERT_ARRAY_ID_DISABLE = 0, + IU_CTRL_INSERT_ARRAY_ID_ENABLED = 1, +} IU_CTRL_INSERT_ARRAY_ID; +typedef enum +{ + IU_CTRL_INSERT_RASTER_MASK_DISABLED = 0, + IU_CTRL_INSERT_RASTER_MASK_ENABLED = 1, + +} IU_CTRL_INSERT_RASTER_MASK; +typedef enum +{ + IU_CTRL_INSERT_SAMPLE_ID_DISABLED = 0, + IU_CTRL_INSERT_SAMPLE_ID_ENABLED = 1, + +} IU_CTRL_INSERT_SAMPLE_ID; +typedef enum +{ + IU_CTRL_INSERT_SAMPLE_OFFSET_DISABLED = 0, + IU_CTRL_INSERT_SAMPLE_OFFSET_ENABLED = 1, + +} IU_CTRL_INSERT_SAMPLE_OFFSET; +typedef enum +{ + IU_CTRL_INSERT_CONSERVATIVE_INNER_MASK_DISABLED= 0, + + IU_CTRL_INSERT_CONSERVATIVE_INNER_MASK_ENABLED= 1, + +} IU_CTRL_INSERT_CONSERVATIVE_INNER_MASK; +typedef enum +{ + IU_CTRL_QUAD_2X2_MODE_EN_4X1 = 0, + IU_CTRL_QUAD_2X2_MODE_EN_2X2 = 1, + +} IU_CTRL_QUAD_2X2_MODE_EN; +typedef enum +{ + IU_CTRL_RAST_RULE_TOP_LEFT = 0, + IU_CTRL_RAST_RULE_BOTTOM_LEFT = 1, + IU_CTRL_RAST_RULE_TOP_RIGHT = 2, + IU_CTRL_RAST_RULE_BOTTOM_RIGHT = 3, +} IU_CTRL_RAST_RULE; +typedef enum +{ + IU_CTRL_SIMD_MODE_SIMD32 = 0, + + IU_CTRL_SIMD_MODE_SIMD64 = 1, + +} IU_CTRL_SIMD_MODE; +typedef enum +{ + IU_CTRL_EX_EU_BLENDING_EN_DISABLED = 0, + IU_CTRL_EX_EU_BLENDING_EN_ENABLED = 1, +} IU_CTRL_EX_EU_BLENDING_EN; +typedef enum +{ + IU_CTRL_EX_Y_INVERT_EN_DISABLED = 0, + IU_CTRL_EX_Y_INVERT_EN_ENABLED = 1, +} IU_CTRL_EX_Y_INVERT_EN; +typedef enum +{ + IU_CTRL_EX_PRE_ROTATE_EN_DISABLED = 0, + IU_CTRL_EX_PRE_ROTATE_EN_ENABLED = 1, +} IU_CTRL_EX_PRE_ROTATE_EN; +typedef enum +{ + IU_CTRL_EX_PRE_ROTATE_TYPE_CCW_0 = 0, + IU_CTRL_EX_PRE_ROTATE_TYPE_CCW_90 = 1, + IU_CTRL_EX_PRE_ROTATE_TYPE_CCW_90_H = 2, + IU_CTRL_EX_PRE_ROTATE_TYPE_CCW_90_V = 3, + IU_CTRL_EX_PRE_ROTATE_TYPE_CCW_180 = 4, + IU_CTRL_EX_PRE_ROTATE_TYPE_CCW_270 = 5, +} IU_CTRL_EX_PRE_ROTATE_TYPE; +typedef enum +{ + IU_CTRL_EX_RAST_RESOLUTION_MSAA_1X = 0, + IU_CTRL_EX_RAST_RESOLUTION_MSAA_2X = 1, + IU_CTRL_EX_RAST_RESOLUTION_MSAA_4X = 2, + IU_CTRL_EX_RAST_RESOLUTION_MSAA_8X = 3, + IU_CTRL_EX_RAST_RESOLUTION_MSAA_16X = 4, +} IU_CTRL_EX_RAST_RESOLUTION; +typedef enum +{ + IU_CTRL_EX_API_VERSION_OGL = 0, + IU_CTRL_EX_API_VERSION_DX9 = 1, + IU_CTRL_EX_API_VERSION_DX10 = 2, + IU_CTRL_EX_API_VERSION_DX11 = 3, + IU_CTRL_EX_API_VERSION_DX12 = 4, +} IU_CTRL_EX_API_VERSION; +typedef enum +{ + IU_INTP_MODE_ATTR0_MODE_CENTER = 0, + IU_INTP_MODE_ATTR0_MODE_SAMPLE = 1, + IU_INTP_MODE_ATTR0_MODE_CENTROID = 2, + + IU_INTP_MODE_ATTR0_MODE_CONSTANT_NORMAL = 3, + + IU_INTP_MODE_ATTR0_MODE_CONSTANT_BYPASS = 4, + + + IU_INTP_MODE_ATTR0_MODE_EU_INTP_PXPY = 5, + IU_INTP_MODE_ATTR0_MODE__EU_INTP_PXINVPY= 6, + +} IU_INTP_MODE_ATTR0_MODE; +typedef enum +{ + IU_CLIP_DISTANCE_ATTR0_CLIP_DISTANCE_EN_DISABLED= 0, + + IU_CLIP_DISTANCE_ATTR0_CLIP_DISTANCE_EN_ENABLED= 1, + +} IU_CLIP_DISTANCE_ATTR0_CLIP_DISTANCE_EN; +typedef enum +{ + IU_PXPY_LOWHIGH_ATTR0_LOWHIGH_LOW_RG = 0, + IU_PXPY_LOWHIGH_ATTR0_LOWHIGH_HIGH_BA = 1, +} IU_PXPY_LOWHIGH_ATTR0_LOWHIGH; +typedef enum +{ + IU_OUTPUT_FORMAT_ATTR0_FMT_FP = 0, + IU_OUTPUT_FORMAT_ATTR0_FMT_HP = 1, +} IU_OUTPUT_FORMAT_ATTR0_FMT; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ps_Attr_Num : 6; + + + unsigned int Ab_Attr_Num : 6; + + + unsigned int Insert_Pos : 1; + unsigned int Insert_Face : 1; + unsigned int Insert_Array_Id : 1; + unsigned int Insert_Raster_Mask : 1; + + + unsigned int Insert_Sample_Id : 1; + unsigned int Insert_Sample_Offset : 1; + + + unsigned int Insert_Conservative_Inner_Mask : 1; + + + unsigned int Pack_Z : 1; + unsigned int Pack_W : 1; + unsigned int Quad_2x2_Mode_En : 1; + unsigned int Rast_Rule : 2; + unsigned int Rule_For_Msaa_Line : 2; + + unsigned int Rule_For_A_Line : 2; + + + unsigned int Simd_Mode : 1; + unsigned int Pack_Face : 1; + unsigned int Pack_Sample_Id : 1; + unsigned int Post_Depth_Coverage_En : 1; + + } reg; +} Reg_Iu_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Eu_Blending_En : 1; + unsigned int Y_Invert_En : 1; + unsigned int Pre_Rotate_En : 1; + + unsigned int Pre_Rotate_Type : 3; + unsigned int Rast_Resolution : 3; + unsigned int Api_Version : 3; + + unsigned int Pixel_Center_Integer_En : 1; + + unsigned int Fragcoord_Invert_En : 1; + + unsigned int Msaa_Center_Sample_En : 1; + unsigned int Mrt_En : 1; + + unsigned int First_Valid_Sample : 5; + + + + + + + unsigned int Reserved : 11; + } reg; +} Reg_Iu_Ctrl_Ex; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rt_Height : 15; + unsigned int Rt_Width : 15; + unsigned int Reserved : 2; + } reg; +} Reg_Iu_Rt_Size; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr0_Id : 6; + unsigned int Attr1_Id : 6; + unsigned int Attr2_Id : 6; + unsigned int Attr3_Id : 6; + unsigned int Attr4_Id : 6; + unsigned int Reserved : 2; + } reg; +} Reg_Iu_Mapping; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr0_Mode : 3; + unsigned int Attr1_Mode : 3; + unsigned int Attr2_Mode : 3; + unsigned int Attr3_Mode : 3; + unsigned int Attr4_Mode : 3; + unsigned int Attr5_Mode : 3; + unsigned int Attr6_Mode : 3; + unsigned int Attr7_Mode : 3; + unsigned int Attr8_Mode : 3; + unsigned int Attr9_Mode : 3; + unsigned int Reserved : 2; + } reg; +} Reg_Iu_Intp_Mode; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr0_Clip_Distance_En : 1; + unsigned int Attr1_Clip_Distance_En : 1; + unsigned int Attr2_Clip_Distance_En : 1; + unsigned int Attr3_Clip_Distance_En : 1; + unsigned int Attr4_Clip_Distance_En : 1; + unsigned int Attr5_Clip_Distance_En : 1; + unsigned int Attr6_Clip_Distance_En : 1; + unsigned int Attr7_Clip_Distance_En : 1; + unsigned int Attr8_Clip_Distance_En : 1; + unsigned int Attr9_Clip_Distance_En : 1; + unsigned int Attr10_Clip_Distance_En : 1; + unsigned int Attr11_Clip_Distance_En : 1; + unsigned int Attr12_Clip_Distance_En : 1; + unsigned int Attr13_Clip_Distance_En : 1; + unsigned int Attr14_Clip_Distance_En : 1; + unsigned int Attr15_Clip_Distance_En : 1; + unsigned int Attr16_Clip_Distance_En : 1; + unsigned int Attr17_Clip_Distance_En : 1; + unsigned int Attr18_Clip_Distance_En : 1; + unsigned int Attr19_Clip_Distance_En : 1; + unsigned int Attr20_Clip_Distance_En : 1; + unsigned int Attr21_Clip_Distance_En : 1; + unsigned int Attr22_Clip_Distance_En : 1; + unsigned int Attr23_Clip_Distance_En : 1; + unsigned int Attr24_Clip_Distance_En : 1; + unsigned int Attr25_Clip_Distance_En : 1; + unsigned int Attr26_Clip_Distance_En : 1; + unsigned int Attr27_Clip_Distance_En : 1; + unsigned int Attr28_Clip_Distance_En : 1; + unsigned int Attr29_Clip_Distance_En : 1; + unsigned int Attr30_Clip_Distance_En : 1; + unsigned int Attr31_Clip_Distance_En : 1; + } reg; +} Reg_Iu_Clip_Distance; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr0_Crf_Addr : 6; + unsigned int Attr1_Crf_Addr : 6; + unsigned int Attr2_Crf_Addr : 6; + unsigned int Attr3_Crf_Addr : 6; + unsigned int Attr4_Crf_Addr : 6; + unsigned int Reserved : 2; + } reg; +} Reg_Iu_Crf_Baseaddr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr0_Pxpy_Crf_Addr : 6; + unsigned int Attr1_Pxpy_Crf_Addr : 6; + unsigned int Attr2_Pxpy_Crf_Addr : 6; + unsigned int Attr3_Pxpy_Crf_Addr : 6; + unsigned int Attr4_Pxpy_Crf_Addr : 6; + unsigned int Reserved : 2; + } reg; +} Reg_Iu_Pxpy_Crf_Baseaddr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr0_Lowhigh : 1; + unsigned int Attr1_Lowhigh : 1; + unsigned int Attr2_Lowhigh : 1; + unsigned int Attr3_Lowhigh : 1; + unsigned int Attr4_Lowhigh : 1; + unsigned int Attr5_Lowhigh : 1; + unsigned int Attr6_Lowhigh : 1; + unsigned int Attr7_Lowhigh : 1; + unsigned int Attr8_Lowhigh : 1; + unsigned int Attr9_Lowhigh : 1; + unsigned int Attr10_Lowhigh : 1; + unsigned int Attr11_Lowhigh : 1; + unsigned int Attr12_Lowhigh : 1; + unsigned int Attr13_Lowhigh : 1; + unsigned int Attr14_Lowhigh : 1; + unsigned int Attr15_Lowhigh : 1; + unsigned int Attr16_Lowhigh : 1; + unsigned int Attr17_Lowhigh : 1; + unsigned int Attr18_Lowhigh : 1; + unsigned int Attr19_Lowhigh : 1; + unsigned int Attr20_Lowhigh : 1; + unsigned int Attr21_Lowhigh : 1; + unsigned int Attr22_Lowhigh : 1; + unsigned int Attr23_Lowhigh : 1; + unsigned int Attr24_Lowhigh : 1; + unsigned int Attr25_Lowhigh : 1; + unsigned int Attr26_Lowhigh : 1; + unsigned int Attr27_Lowhigh : 1; + unsigned int Attr28_Lowhigh : 1; + unsigned int Attr29_Lowhigh : 1; + unsigned int Attr30_Lowhigh : 1; + unsigned int Attr31_Lowhigh : 1; + } reg; +} Reg_Iu_Pxpy_Lowhigh; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr0_Fmt : 1; + unsigned int Attr1_Fmt : 1; + unsigned int Attr2_Fmt : 1; + unsigned int Attr3_Fmt : 1; + unsigned int Attr4_Fmt : 1; + unsigned int Attr5_Fmt : 1; + unsigned int Attr6_Fmt : 1; + unsigned int Attr7_Fmt : 1; + unsigned int Attr8_Fmt : 1; + unsigned int Attr9_Fmt : 1; + unsigned int Attr10_Fmt : 1; + unsigned int Attr11_Fmt : 1; + unsigned int Attr12_Fmt : 1; + unsigned int Attr13_Fmt : 1; + unsigned int Attr14_Fmt : 1; + unsigned int Attr15_Fmt : 1; + unsigned int Attr16_Fmt : 1; + unsigned int Attr17_Fmt : 1; + unsigned int Attr18_Fmt : 1; + unsigned int Attr19_Fmt : 1; + unsigned int Attr20_Fmt : 1; + unsigned int Attr21_Fmt : 1; + unsigned int Attr22_Fmt : 1; + unsigned int Attr23_Fmt : 1; + unsigned int Attr24_Fmt : 1; + unsigned int Attr25_Fmt : 1; + unsigned int Attr26_Fmt : 1; + unsigned int Attr27_Fmt : 1; + unsigned int Attr28_Fmt : 1; + unsigned int Attr29_Fmt : 1; + unsigned int Attr30_Fmt : 1; + unsigned int Attr31_Fmt : 1; + } reg; +} Reg_Iu_Output_Format; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Viewportzmin : 32; + } reg; +} Reg_Iu_Viewportzvalue; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Faceid_Dst_Crfaddr : 9; + + + unsigned int Sampleid_Dst_Crfaddr : 9; + + + unsigned int Reserved : 14; + } reg; +} Reg_Iu_Builtin_Attr_Packing; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Iu_Reserved_Dw; + +typedef struct _Iu_regs +{ + Reg_Iu_Ctrl reg_Iu_Ctrl; + Reg_Iu_Ctrl_Ex reg_Iu_Ctrl_Ex; + Reg_Iu_Rt_Size reg_Iu_Rt_Size; + Reg_Iu_Mapping reg_Iu_Mapping[10]; + Reg_Iu_Intp_Mode reg_Iu_Intp_Mode[5]; + Reg_Iu_Clip_Distance reg_Iu_Clip_Distance[2]; + Reg_Iu_Crf_Baseaddr reg_Iu_Crf_Baseaddr[10]; + Reg_Iu_Pxpy_Crf_Baseaddr reg_Iu_Pxpy_Crf_Baseaddr[10]; + Reg_Iu_Pxpy_Lowhigh reg_Iu_Pxpy_Lowhigh[2]; + Reg_Iu_Output_Format reg_Iu_Output_Format[2]; + Reg_Iu_Viewportzvalue reg_Iu_Viewportzvalue[16]; + Reg_Iu_Builtin_Attr_Packing reg_Iu_Builtin_Attr_Packing; + Reg_Iu_Reserved_Dw reg_Iu_Reserved_Dw[3]; +} Iu_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/L2_Register.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/L2_Register.h new file mode 100644 index 0000000000000..1d20ec9d3957c --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/L2_Register.h @@ -0,0 +1,164 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _L2_REGISTER_H +#define _L2_REGISTER_H + + +#ifndef L2_BLOCKBASE_INF + #define L2_BLOCKBASE_INF + #define BLOCK_L2_VERSION 1 + #define BLOCK_L2_TIMESTAMP "2019/3/1 9:46:22" + #define L2_BLOCK 0xB + #define L2_REG_START 0x0 + #define L2_REG_END 0x10 + #define L2_REG_LIMIT 0x10 +#endif + + +#define Reg_Rb0_Offset 0x0 +#define Reg_Rb1_Offset 0x1 +#define Reg_Rb2_Offset 0x2 +#define Reg_Argument_Offset 0x3 +#define Reg_L2_Performance_Offset 0x4 +#define Reg_L2_Reserved_Offset 0x5 +#define Reg_L2_Reserved1_Offset 0xC + + + + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved_0 : 20; + unsigned int Reserved_1 : 12; + } reg; +} Reg_Rb0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved_0 : 20; + unsigned int Reserved_1 : 12; + } reg; +} Reg_Rb1; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved_0 : 20; + unsigned int Reserved_1 : 12; + } reg; +} Reg_Rb2; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved_0 : 20; + unsigned int Reserved_1 : 12; + } reg; +} Reg_Argument; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int L2_Dist_Ctrl : 1; + + + + + unsigned int Reserved0 : 1; + unsigned int L2_Latency_Buf_Dist_Ctrl : 1; + + + + + + + + + unsigned int Reserved1 : 1; + unsigned int L2_Slc_Osd_Num_Ctrl : 4; + + + + + unsigned int L2_Tu_Block_By_Refcnt : 1; + + + + + + + + + + unsigned int L2_Fully_W_Opt : 1; + + + + + + + unsigned int Reserved2 : 22; + } reg; +} Reg_L2_Performance; + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_L2_Reserved; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_L2_Reserved1; + +typedef struct _L2_regs +{ + Reg_Rb0 reg_Rb0; + Reg_Rb1 reg_Rb1; + Reg_Rb2 reg_Rb2; + Reg_Argument reg_Argument; + Reg_L2_Performance reg_L2_Performance; + Reg_L2_Reserved reg_L2_Reserved[7]; + Reg_L2_Reserved1 reg_L2_Reserved1[4]; +} L2_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/MMU_registers.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/MMU_registers.h new file mode 100644 index 0000000000000..6ccc5a2c8c721 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/MMU_registers.h @@ -0,0 +1,54 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _MMU_REGISTERS_H +#define _MMU_REGISTERS_H + +#ifndef MMU_BLOCKBASE_INF + #define MMU_BLOCKBASE_INF + #define BLOCK_MMU_VERSION 1 + #define BLOCK_MMU_TIMESTAMP "2017/8/17 15:52:06" + #define MMU_BLOCK 0x12 + #define MMU_REG_START 0x0 + #define MMU_REG_END 0x1000 + #define MMU_REG_LIMIT 0x1000 +#endif + +#define Reg_Mmu_Ttbr_Offset 0x0 + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Valid : 1; + unsigned int Ns : 1; + unsigned int Snoop : 1; + unsigned int Segment : 1; + unsigned int Addr : 24; + unsigned int Reserved : 4; + } reg; +} Reg_Ttbr; + +typedef struct _Group_Mmu_Ttbr +{ + Reg_Ttbr reg_Ttbr; +} Reg_Mmu_Ttbr_Group; + +typedef struct _Mmu_regs +{ + Reg_Mmu_Ttbr_Group reg_Mmu_Ttbr[4096]; +} Mmu_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/MXU_registers.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/MXU_registers.h new file mode 100644 index 0000000000000..c48136da602ba --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/MXU_registers.h @@ -0,0 +1,541 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _MXU_REGISTERS_H +#define _MXU_REGISTERS_H + + +#ifndef MXU_BLOCKBASE_INF + #define MXU_BLOCKBASE_INF + #define BLOCK_MXU_VERSION 1 + #define BLOCK_MXU_TIMESTAMP "2019/1/25 14:57:16" + #define MXU_BLOCK 0xC + #define MXU_REG_START 0x0 + #define MXU_REG_END 0x1FFF + #define MXU_REG_LIMIT 0x1FFF +#endif + + +#define Reg_Fb_Ctrl_Offset 0x0 +#define Reg_Mmu_Mode_Offset 0x1 +#define Reg_Rserved_0_Offset 0x2 +#define Reg_Bl_Size_Offset 0x3 +#define Reg_Gart_Base_Offset 0x4 +#define Reg_Proc_Sec_Offset 0x5 +#define Reg_Pt_Inv_Addr_Offset 0x6 +#define Reg_Pt_Inv_Mask_Offset 0x7 +#define Reg_Pt_Inv_Trig_Offset 0x8 +#define Reg_Mxu_Channel_Control_Offset 0x9 +#define Reg_Mxu_Dec_Ctrl_Offset 0xA +#define Reg_Bus_Id_Mode_Offset 0xB +#define Reg_Mxu_Ctrl_0_Offset 0xC +#define Reg_Mxu_Ila_Reg_Offset 0xD +#define Reg_Mxu_Int_Status_Offset 0xE +#define Reg_Mxu_Int_Mask_Offset 0xF +#define Reg_Mxu_Page_Fault_Status0_Offset 0x10 +#define Reg_Mxu_Page_Fault_Status1_Offset 0x11 +#define Reg_Mem_Addr_For_Page_Fault_Offset 0x12 +#define Reg_Level_1_Fault_Page_Addr_Offset 0x13 +#define Reg_Level_2_Fault_Page_Addr_Offset 0x14 +#define Reg_Rb0_Fl2_Offset 0x15 +#define Reg_Rb1_Fl2_Offset 0x16 +#define Reg_Rb2_Fl2_Offset 0x17 +#define Reg_Argument_Fl2_Offset 0x18 +#define Reg_L2_Performance_Redundancy_Offset 0x19 +#define Reg_Page_Fault_Level_Offset 0x1A +#define Reg_Pending_Buf_Ctrl_0_Offset 0x1B +#define Reg_Pending_Buf_Ctrl_1_Offset 0x1C +#define Reg_Rdata_Buf_Ctrl_0_Offset 0x1D +#define Reg_Diu_Reserve_Ctrl_Offset 0x1E +#define Reg_Bium_Hdr_Num_Offset 0x1F +#define Reg_Mxu_Reserved_Offset 0x20 +#define Reg_Mxu_Resvered_For_Sila_Offset 0x7FF + + +typedef enum +{ + BL_SIZE_BUFFER_SIZE_8MB = 0, + BL_SIZE_BUFFER_SIZE_16MB = 1, + BL_SIZE_BUFFER_SIZE_32MB = 2, + BL_SIZE_BUFFER_SIZE_64MB = 3, + BL_SIZE_BUFFER_SIZE_128MB = 4, + BL_SIZE_BUFFER_SIZE_256MB = 5, + BL_SIZE_BUFFER_SIZE_RESERVED1 = 6, + BL_SIZE_BUFFER_SIZE_RESERVED2 = 7, +} BL_SIZE_BUFFER_SIZE; +typedef enum +{ + PT_INV_TRIG_TARGET_OFF = 0, + PT_INV_TRIG_TARGET_UTLB = 1, + PT_INV_TRIG_TARGET_DTLB = 2, + PT_INV_TRIG_TARGET_RESERVED = 3, +} PT_INV_TRIG_TARGET; +typedef enum +{ + MXU_CHANNEL_CONTROL_CH_SIZE_256B = 0, + MXU_CHANNEL_CONTROL_CH_SIZE_512B = 1, + MXU_CHANNEL_CONTROL_CH_SIZE_1KB = 2, + MXU_CHANNEL_CONTROL_CH_SIZE_RESERVED0 = 3, + MXU_CHANNEL_CONTROL_CH_SIZE_RESERVED1 = 4, + MXU_CHANNEL_CONTROL_CH_SIZE_RESERVED2 = 5, + MXU_CHANNEL_CONTROL_CH_SIZE_RESERVED3 = 6, + MXU_CHANNEL_CONTROL_CH_SIZE_RESERVED4 = 7, +} MXU_CHANNEL_CONTROL_CH_SIZE; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Fb_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vmen : 1; + + unsigned int Reserved0 : 3; + unsigned int Bius_Va_En : 1; + + + + unsigned int Reserved1 : 3; + unsigned int Video_Size : 8; + + + + unsigned int Legacy_Size : 8; + + + unsigned int Legacy_Offset : 8; + + + + } reg; +} Reg_Mmu_Mode; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Rserved_0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Buffer_Size : 3; + unsigned int Reserved : 1; + unsigned int Buffer_Offset : 19; + + + + unsigned int Reserved0 : 1; + unsigned int Invalid_Bl_To_Rf_En : 1; + unsigned int Reserved1 : 7; + } reg; +} Reg_Bl_Size; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 8; + unsigned int Addr : 24; + + } reg; +} Reg_Gart_Base; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Sec_Status : 16; + unsigned int Reserved : 16; + } reg; +} Reg_Proc_Sec; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Address : 28; + + unsigned int Proc_Id : 4; + + } reg; +} Reg_Pt_Inv_Addr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Mask : 28; + + unsigned int Proc_Id : 4; + + } reg; +} Reg_Pt_Inv_Mask; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Proc_Id : 4; + + unsigned int Addr_Valid : 1; + + + unsigned int Target : 2; + unsigned int Reserved : 25; + } reg; +} Reg_Pt_Inv_Trig; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Miu_Channel0_Disable : 1; + unsigned int Miu_Channel1_Disable : 1; + unsigned int Miu_Channel2_Disable : 1; + unsigned int Ch_Size : 3; + + unsigned int Reserved : 26; + } reg; +} Reg_Mxu_Channel_Control; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ddec_Antilock_Time_Threshold : 3; + + + + + + unsigned int Ddec_Antilock : 1; + + + + unsigned int Reserved : 28; + } reg; +} Reg_Mxu_Dec_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Biu_Axi_Id_Mode : 1; + + unsigned int Reserved0 : 31; + + } reg; +} Reg_Bus_Id_Mode; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved0 : 1; + unsigned int Reseved1 : 2; + + + + unsigned int Reserved3 : 2; + + + + unsigned int Reserved2 : 27; + } reg; +} Reg_Mxu_Ctrl_0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Latency : 10; + + unsigned int Reserve : 22; + } reg; +} Reg_Mxu_Ila_Reg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Page_Fault : 30; + unsigned int Reserved1 : 1; + unsigned int Reserved0 : 1; + } reg; +} Reg_Mxu_Int_Status; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved0 : 30; + unsigned int Reserved1 : 1; + unsigned int Reserved2 : 1; + } reg; +} Reg_Mxu_Int_Mask; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 18; + unsigned int Fault_Level : 2; + + + + + unsigned int Proc_Id : 4; + unsigned int Va : 8; + + } reg; +} Reg_Mxu_Page_Fault_Status0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Va : 32; + } reg; +} Reg_Mxu_Page_Fault_Status1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 2; + unsigned int Va : 30; + + } reg; +} Reg_Mem_Addr_For_Page_Fault; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 2; + unsigned int Va : 30; + } reg; +} Reg_Level_1_Fault_Page_Addr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 2; + unsigned int Va : 30; + } reg; +} Reg_Level_2_Fault_Page_Addr; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Addr : 20; + unsigned int Size : 12; + } reg; +} Reg_Rb0_Fl2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Addr : 20; + unsigned int Size : 12; + } reg; +} Reg_Rb1_Fl2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Addr : 20; + unsigned int Size : 12; + } reg; +} Reg_Rb2_Fl2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Addr : 20; + unsigned int Size : 12; + } reg; +} Reg_Argument_Fl2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 22; + } reg; +} Reg_L2_Performance_Redundancy; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Mmu_L1_Invalid : 2; + unsigned int Mmu_L2_Invalid : 30; + unsigned int Reserved : 30; + } reg; +} Reg_Page_Fault_Level; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ctrl_0 : 32; + } reg; +} Reg_Pending_Buf_Ctrl_0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Ctrl_1 : 32; + } reg; +} Reg_Pending_Buf_Ctrl_1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rdata_Ctrl_0 : 32; + } reg; +} Reg_Rdata_Buf_Ctrl_0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Wr_Entry_Reserve_For_Diu : 2; + unsigned int Diu_Rdata_Buf_Cnt_Ctrl_En : 3; + unsigned int Rdata_Ctrl_0 : 31; + + } reg; +} Reg_Diu_Reserve_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserve0 : 15; + unsigned int Read_Out_Of_Order_Output : 1; + unsigned int Reserve1 : 15; + } reg; +} Reg_Bium_Hdr_Num; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Mxu_Reserved; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Mxu_Resvered_For_Sila; + +typedef struct _Mxu_regs +{ + Reg_Fb_Ctrl reg_Fb_Ctrl; + Reg_Mmu_Mode reg_Mmu_Mode; + Reg_Rserved_0 reg_Rserved_0; + Reg_Bl_Size reg_Bl_Size; + Reg_Gart_Base reg_Gart_Base; + Reg_Proc_Sec reg_Proc_Sec; + Reg_Pt_Inv_Addr reg_Pt_Inv_Addr; + Reg_Pt_Inv_Mask reg_Pt_Inv_Mask; + Reg_Pt_Inv_Trig reg_Pt_Inv_Trig; + Reg_Mxu_Channel_Control reg_Mxu_Channel_Control; + Reg_Mxu_Dec_Ctrl reg_Mxu_Dec_Ctrl; + Reg_Bus_Id_Mode reg_Bus_Id_Mode; + Reg_Mxu_Ctrl_0 reg_Mxu_Ctrl_0; + Reg_Mxu_Ila_Reg reg_Mxu_Ila_Reg; + Reg_Mxu_Int_Status reg_Mxu_Int_Status; + Reg_Mxu_Int_Mask reg_Mxu_Int_Mask; + Reg_Mxu_Page_Fault_Status0 reg_Mxu_Page_Fault_Status0; + Reg_Mxu_Page_Fault_Status1 reg_Mxu_Page_Fault_Status1; + Reg_Mem_Addr_For_Page_Fault reg_Mem_Addr_For_Page_Fault; + Reg_Level_1_Fault_Page_Addr reg_Level_1_Fault_Page_Addr; + Reg_Level_2_Fault_Page_Addr reg_Level_2_Fault_Page_Addr; + Reg_Rb0_Fl2 reg_Rb0_Fl2; + Reg_Rb1_Fl2 reg_Rb1_Fl2; + Reg_Rb2_Fl2 reg_Rb2_Fl2; + Reg_Argument_Fl2 reg_Argument_Fl2; + Reg_L2_Performance_Redundancy reg_L2_Performance; + Reg_Page_Fault_Level reg_Page_Fault_Level; + Reg_Pending_Buf_Ctrl_0 reg_Pending_Buf_Ctrl_0; + Reg_Pending_Buf_Ctrl_1 reg_Pending_Buf_Ctrl_1; + Reg_Rdata_Buf_Ctrl_0 reg_Rdata_Buf_Ctrl_0; + Reg_Diu_Reserve_Ctrl reg_Diu_Reserve_Ctrl; + Reg_Bium_Hdr_Num reg_Bium_Hdr_Num; + Reg_Mxu_Reserved reg_Mxu_Reserved[2015]; + Reg_Mxu_Resvered_For_Sila reg_Mxu_Resvered_For_Sila[6144]; +} Mxu_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/SPIN_register.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/SPIN_register.h new file mode 100644 index 0000000000000..9637203af4dae --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/SPIN_register.h @@ -0,0 +1,74 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _SPIN_REGISTER_H +#define _SPIN_REGISTER_H + + +#ifndef SPIN_BLOCKBASE_INF + #define SPIN_BLOCKBASE_INF + #define BLOCK_SPIN_VERSION 1 + #define BLOCK_SPIN_TIMESTAMP "2017/9/27 15:04:28" + #define SPIN_BLOCK 0x2 + #define SPIN_REG_START 0x0 + #define SPIN_REG_END 0x8 + #define SPIN_REG_LIMIT 0x8 +#endif + + +#define Reg_Sp_Dummy1_Offset 0x0 +#define Reg_Sp_Dummy2_Offset 0x1 +#define Reg_Sp_Reserved_Offset 0x2 + + + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Sp_Dummy1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Sp_Dummy2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Sp_Reserved; + +typedef struct _Spin_regs +{ + Reg_Sp_Dummy1 reg_Sp_Dummy1; + Reg_Sp_Dummy2 reg_Sp_Dummy2; + Reg_Sp_Reserved reg_Sp_Reserved[6]; +} Spin_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/SPOUT_register.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/SPOUT_register.h new file mode 100644 index 0000000000000..050c74d5ca9b0 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/SPOUT_register.h @@ -0,0 +1,284 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _SPOUT_REGISTER_H +#define _SPOUT_REGISTER_H + + +#ifndef SPOUT_BLOCKBASE_INF +#define SPOUT_BLOCKBASE_INF +#define BLOCK_SPOUT_VERSION 1 +#define BLOCK_SPOUT_TIMESTAMP "2018/6/11 22:15:55" +#define SPOUT_BLOCK 0x16 +#define SPOUT_REG_START 0x0 +#define SPOUT_REG_END 0x20 +#define SPOUT_REG_LIMIT 0x20 +#endif + + +#define Reg_Spout_Cfg_Offset 0x0 +#define Reg_Spout_Idx_Ch_Offset 0x1 +#define Reg_Pos_Read_Loc_Offset 0x2 +#define Reg_Attr_Read_Loc0_Offset 0x3 +#define Reg_Attr_Read_Loc1_Offset 0x4 +#define Reg_Pos_Read_Id_Offset 0x5 +#define Reg_Attr_Read_Id_Offset 0x6 +#define Reg_Pos_Def_Value_Offset 0x12 +#define Reg_Attr_Def_Value_Offset 0x13 +#define Reg_Spout_Reserved_Offset 0x1F + + +typedef enum +{ + SPOUT_CFG_OUT_RAST_EN_DISABLE = 0, + SPOUT_CFG_OUT_RAST_EN_ENABLE = 1, +} SPOUT_CFG_OUT_RAST_EN; +typedef enum +{ + SPOUT_CFG_STO_EN_DISABLED = 0, + SPOUT_CFG_STO_EN_ENABLED = 1, + +} SPOUT_CFG_STO_EN; +typedef enum +{ + SPOUT_CFG_RTARRAY_IDX_OUT_EN_DISABLE = 0, + SPOUT_CFG_RTARRAY_IDX_OUT_EN_ENABLE = 1, + +} SPOUT_CFG_RTARRAY_IDX_OUT_EN; +typedef enum +{ + SPOUT_CFG_VIEWPORT_MASK_OUT_EN_DISABLE = 0, + SPOUT_CFG_VIEWPORT_MASK_OUT_EN_ENABLE = 1, + +} SPOUT_CFG_VIEWPORT_MASK_OUT_EN; +typedef enum +{ + SPOUT_CFG_CULLCLIP_FLAG_OUT_EN_DISABLE = 0, + SPOUT_CFG_CULLCLIP_FLAG_OUT_EN_ENABLE = 1, + +} SPOUT_CFG_CULLCLIP_FLAG_OUT_EN; +typedef enum +{ + SPOUT_CFG_PRIMID_APPEND_EN_DISABLE = 0, + SPOUT_CFG_PRIMID_APPEND_EN_ENABLE = 1, +} SPOUT_CFG_PRIMID_APPEND_EN; +typedef enum +{ + POS_READ_LOC_POS_LOC_SEPARATED = 0, + + POS_READ_LOC_POS_LOC_SHARED = 1, + +} POS_READ_LOC_POS_LOC; +typedef enum +{ + ATTR_READ_LOC0_ATTR_LOC_SEPARATED = 0, + + ATTR_READ_LOC0_ATTR_LOC_SHARED = 1, + +} ATTR_READ_LOC0_ATTR_LOC; +typedef enum +{ + ATTR_READ_LOC1_ATTR_LOC_SEPARATED = 0, + + ATTR_READ_LOC1_ATTR_LOC_SHARED = 1, + +} ATTR_READ_LOC1_ATTR_LOC; +typedef enum +{ + POS_DEF_VALUE_P0_X_DEF_DISABLED = 0, + POS_DEF_VALUE_P0_X_DEF_ZERO = 1, + POS_DEF_VALUE_P0_X_DEF_FP_ONE = 2, + POS_DEF_VALUE_P0_X_DEF_RESERVED = 3, +} POS_DEF_VALUE_P0_X_DEF; +typedef enum +{ + ATTR_DEF_VALUE_A0_X_DEF_DISABLED = 0, + ATTR_DEF_VALUE_A0_X_DEF_ZERO = 1, + ATTR_DEF_VALUE_A0_X_DEF_FP_ONE = 2, + ATTR_DEF_VALUE_A0_X_DEF_RESERVED = 3, +} ATTR_DEF_VALUE_A0_X_DEF; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Out_Rast_En : 1; + unsigned int Sto_En : 1; + unsigned int Out_Size : 6; + + unsigned int Shared_Size : 6; + + unsigned int Vtx_Pos_Size : 2; + + + unsigned int Vtx_Attr_Size : 6; + + + unsigned int Rtarray_Idx_Out_En : 1; + unsigned int Viewport_Mask_Out_En : 1; + unsigned int Cullclip_Flag_Out_En : 1; + + unsigned int Vtx_Idx_Id : 6; + + + unsigned int Primid_Append_En : 1; + + + } reg; +} Reg_Spout_Cfg; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Rtarray_Idx_Ch : 2; + unsigned int Viewport_Mask_Ch : 2; + unsigned int Cullclip_Flag_Ch : 2; + unsigned int Reserved : 26; + } reg; +} Reg_Spout_Idx_Ch; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Pos_Loc : 2; + + + unsigned int Reserved : 30; + } reg; +} Reg_Pos_Read_Loc; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr_Loc : 32; + + + } reg; +} Reg_Attr_Read_Loc0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr_Loc : 16; + + + unsigned int Reserved : 16; + } reg; +} Reg_Attr_Read_Loc1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int P0_Addr : 6; + + + unsigned int P1_Addr : 6; + unsigned int Reserved : 20; + } reg; +} Reg_Pos_Read_Id; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int A0_Addr : 6; + + unsigned int A1_Addr : 6; + unsigned int A2_Addr : 6; + unsigned int A3_Addr : 6; + unsigned int Reserved : 8; + } reg; +} Reg_Attr_Read_Id; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int P0_X_Def : 2; + unsigned int P0_Y_Def : 2; + unsigned int P0_Z_Def : 2; + unsigned int P0_W_Def : 2; + unsigned int P1_X_Def : 2; + unsigned int P1_Y_Def : 2; + unsigned int P1_Z_Def : 2; + unsigned int P1_W_Def : 2; + unsigned int Reserved : 16; + } reg; +} Reg_Pos_Def_Value; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int A0_X_Def : 2; + unsigned int A0_Y_Def : 2; + unsigned int A0_Z_Def : 2; + unsigned int A0_W_Def : 2; + unsigned int A1_X_Def : 2; + unsigned int A1_Y_Def : 2; + unsigned int A1_Z_Def : 2; + unsigned int A1_W_Def : 2; + unsigned int A2_X_Def : 2; + unsigned int A2_Y_Def : 2; + unsigned int A2_Z_Def : 2; + unsigned int A2_W_Def : 2; + unsigned int A3_X_Def : 2; + unsigned int A3_Y_Def : 2; + unsigned int A3_Z_Def : 2; + unsigned int A3_W_Def : 2; + } reg; +} Reg_Attr_Def_Value; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Spout_Reserved; + +typedef struct _Spout_regs +{ + Reg_Spout_Cfg reg_Spout_Cfg; + Reg_Spout_Idx_Ch reg_Spout_Idx_Ch; + Reg_Pos_Read_Loc reg_Pos_Read_Loc; + Reg_Attr_Read_Loc0 reg_Attr_Read_Loc0; + Reg_Attr_Read_Loc1 reg_Attr_Read_Loc1; + Reg_Pos_Read_Id reg_Pos_Read_Id; + Reg_Attr_Read_Id reg_Attr_Read_Id[12]; + Reg_Pos_Def_Value reg_Pos_Def_Value; + Reg_Attr_Def_Value reg_Attr_Def_Value[12]; + Reg_Spout_Reserved reg_Spout_Reserved; +} Spout_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/TASBE_reg.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/TASBE_reg.h new file mode 100644 index 0000000000000..e766e81d2160a --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/TASBE_reg.h @@ -0,0 +1,87 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _TASBE_REG_H +#define _TASBE_REG_H + + +#ifndef TASBE_BLOCKBASE_INF +#define TASBE_BLOCKBASE_INF +#define BLOCK_TASBE_VERSION 1 +#define BLOCK_TASBE_TIMESTAMP "10/13/2017 10:19:33 AM" +#define TASBE_BLOCK 0x5 +#define TASBE_REG_START 0x0 +#define TASBE_REG_END 0x8 +#define TASBE_REG_LIMIT 0x8 +#endif + + +#define Reg_Tasbe_Reserved_Offset 0x1 + + +typedef enum +{ + TASBE_CTRL_TBR_EN_DISABLE = 0, + TASBE_CTRL_TBR_EN_ENABLE = 1, +} TASBE_CTRL_TBR_EN; +typedef enum +{ + TASBE_CTRL_TBR_MODE_PER_DRAW = 0, + TASBE_CTRL_TBR_MODE_PER_FRAME = 1, +} TASBE_CTRL_TBR_MODE; +typedef enum +{ + TASBE_CTRL_TILE_SIZE_256X128 = 0, + TASBE_CTRL_TILE_SIZE_128X128 = 1, + TASBE_CTRL_TILE_SIZE_128X64 = 2, + TASBE_CTRL_TILE_SIZE_64X64 = 3, + TASBE_CTRL_TILE_SIZE_64X32 = 4, + TASBE_CTRL_TILE_SIZE_32X32 = 5, + TASBE_CTRL_TILE_SIZE_32X16 = 6, + TASBE_CTRL_TILE_SIZE_16X16 = 7, + TASBE_CTRL_TILE_SIZE_16X8 = 8, + TASBE_CTRL_TILE_SIZE_8X8 = 9, +} TASBE_CTRL_TILE_SIZE; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Tasbe_Reserved; + +typedef struct _Tasbe_regs +{ + struct + { + unsigned int Tbr_En : 1; + unsigned int Tbr_Mode : 1; + unsigned int Tile_Size : 4; + unsigned int Attr_Num : 6; + unsigned int Msaa_State : 3; + + unsigned int Aa_En : 1; + unsigned int Raster_Mode : 1; + unsigned int Reserved : 15; + } reg_Tasbe_Ctrl; + Reg_Tasbe_Reserved reg_Tasbe_Reserved[7]; +} Tasbe_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/TASFE_reg.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/TASFE_reg.h new file mode 100644 index 0000000000000..5351281fa39aa --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/TASFE_reg.h @@ -0,0 +1,709 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _TASFE_REG_H +#define _TASFE_REG_H + + +#ifndef TASFE_BLOCKBASE_INF + #define TASFE_BLOCKBASE_INF + #define BLOCK_TASFE_VERSION 1 + #define BLOCK_TASFE_TIMESTAMP "7/18/2018 12:13:43 PM" + #define TASFE_BLOCK 0x4 + #define TASFE_REG_START 0x0 + #define TASFE_REG_END 0xC0 + #define TASFE_REG_LIMIT 0xC0 +#endif + + +#define Reg_Tasfe_Ctrl_Offset 0x0 +#define Reg_Tasfe_Ctrl_Misc_Offset 0x1 +#define Reg_Pre_Setup_Ctrl_Offset 0x2 +#define Reg_Gb_Exp_Offset 0x3 +#define Reg_Scissor_X_Offset 0xB +#define Reg_Scissor_Y_Offset 0x1B +#define Reg_Viewport_Xscale_Offset 0x2B +#define Reg_Viewport_Xoffset_Offset 0x3B +#define Reg_Viewport_Yscale_Offset 0x4B +#define Reg_Viewport_Yoffset_Offset 0x5B +#define Reg_Viewport_Zscale_Offset 0x6B +#define Reg_Viewport_Zoffset_Offset 0x7B +#define Reg_Wscaling_Xcoeff_Offset 0x8B +#define Reg_Wscaling_Ycoeff_Offset 0x9B +#define Reg_Viewport_Swizzle_Offset 0xAB +#define Reg_Point_Size_Offset 0xB3 +#define Reg_Line_Width_Offset 0xB4 +#define Reg_Z_Bias_Offset 0xB5 +#define Reg_Z_Scale_Factor_Offset 0xB6 +#define Reg_Z_Bias_Clamp_Offset 0xB7 +#define Reg_Attr_Const_Persp_Offset 0xB8 +#define Reg_Tasfe_Reserved_Offset 0xBB + + +typedef enum +{ + TASFE_CTRL_AS_EN_DISABLED = 0, + TASFE_CTRL_AS_EN_ENABLED = 1, +} TASFE_CTRL_AS_EN; +typedef enum +{ + TASFE_CTRL_ZERO_DET_MODE_FORCE_REJECT = 0, + TASFE_CTRL_ZERO_DET_MODE_BACK_FACE = 1, +} TASFE_CTRL_ZERO_DET_MODE; +typedef enum +{ + TASFE_CTRL_CULL_EN_DISABLED = 0, + TASFE_CTRL_CULL_EN_ENABLED = 1, +} TASFE_CTRL_CULL_EN; +typedef enum +{ + TASFE_CTRL_CULL_MODE_CULL_BACK = 0, + TASFE_CTRL_CULL_MODE_CULL_FRONT = 1, +} TASFE_CTRL_CULL_MODE; +typedef enum +{ + TASFE_CTRL_WINDING_FRONT_CW = 0, + TASFE_CTRL_WINDING_FRONT_CCW = 1, +} TASFE_CTRL_WINDING; +typedef enum +{ + TASFE_CTRL_ZCLIP_EN_DISABLED = 0, + TASFE_CTRL_ZCLIP_EN_ENABLED = 1, +} TASFE_CTRL_ZCLIP_EN; +typedef enum +{ + TASFE_CTRL_ZOFFSET_FILL_EN_DISABLED = 0, + TASFE_CTRL_ZOFFSET_FILL_EN_ENABLED = 1, +} TASFE_CTRL_ZOFFSET_FILL_EN; +typedef enum +{ + TASFE_CTRL_ZOFFSET_LINE_EN_DISABLED = 0, + TASFE_CTRL_ZOFFSET_LINE_EN_ENABLED = 1, +} TASFE_CTRL_ZOFFSET_LINE_EN; +typedef enum +{ + TASFE_CTRL_ZOFFSET_POINT_EN_DISABLED = 0, + TASFE_CTRL_ZOFFSET_POINT_EN_ENABLED = 1, +} TASFE_CTRL_ZOFFSET_POINT_EN; +typedef enum +{ + TASFE_CTRL_STRICT_LINE_EN_DISABLED = 0, + TASFE_CTRL_STRICT_LINE_EN_ENABLED = 1, +} TASFE_CTRL_STRICT_LINE_EN; +typedef enum +{ + TASFE_CTRL_NON_PERSPECTIVE_EN_DISABLED = 0, + TASFE_CTRL_NON_PERSPECTIVE_EN_ENABLED = 1, +} TASFE_CTRL_NON_PERSPECTIVE_EN; +typedef enum +{ + TASFE_CTRL_PTTRI_EN_DISABLE = 0, + TASFE_CTRL_PTTRI_EN_ENABLE = 1, +} TASFE_CTRL_PTTRI_EN; +typedef enum +{ + TASFE_CTRL_POINT_SIZE_EN_DISABLED = 0, + + TASFE_CTRL_POINT_SIZE_EN_ENABLED = 1, +} TASFE_CTRL_POINT_SIZE_EN; +typedef enum +{ + TASFE_CTRL_LAST_PIXEL_DISABLED = 0, + TASFE_CTRL_LAST_PIXEL_ENABLED = 1, +} TASFE_CTRL_LAST_PIXEL; +typedef enum +{ + TASFE_CTRL_LEADING_VTX_VTX0 = 0, + + TASFE_CTRL_LEADING_VTX_VTX1 = 1, + +} TASFE_CTRL_LEADING_VTX; +typedef enum +{ + TASFE_CTRL_Z32F_EN_DISABLED = 0, + TASFE_CTRL_Z32F_EN_ENABLED = 1, +} TASFE_CTRL_Z32F_EN; +typedef enum +{ + TASFE_CTRL_Z_SETUP_MODE_LINE_BASED = 0, + TASFE_CTRL_Z_SETUP_MODE_TRIANGLE_BASED = 1, +} TASFE_CTRL_Z_SETUP_MODE; +typedef enum +{ + TASFE_CTRL_RHW_SETUP_MODE_LINE_BASED = 0, + TASFE_CTRL_RHW_SETUP_MODE_TRIANGLE_BASED= 1, +} TASFE_CTRL_RHW_SETUP_MODE; +typedef enum +{ + TASFE_CTRL_FRONT_POLYGON_MODE_SOLID = 0, + TASFE_CTRL_FRONT_POLYGON_MODE_WIREFRAME = 1, + TASFE_CTRL_FRONT_POLYGON_MODE_POINT = 2, +} TASFE_CTRL_FRONT_POLYGON_MODE; +typedef enum +{ + TASFE_CTRL_BACK_POLYGON_MODE_SOLID = 0, + TASFE_CTRL_BACK_POLYGON_MODE_WIREFRAME = 1, + TASFE_CTRL_BACK_POLYGON_MODE_POINT = 2, +} TASFE_CTRL_BACK_POLYGON_MODE; +typedef enum +{ + TASFE_CTRL_DEPTH_MODE_ZERO_TO_ONE = 0, + TASFE_CTRL_DEPTH_MODE_NEGATIVE_ONE_TO_ONE= 1, +} TASFE_CTRL_DEPTH_MODE; +typedef enum +{ + TASFE_CTRL_FORCE_Z_GBC_FALSE = 0, + TASFE_CTRL_FORCE_Z_GBC_TRUE = 1, +} TASFE_CTRL_FORCE_Z_GBC; +typedef enum +{ + TASFE_CTRL_API_VERSION_OGL = 0, + TASFE_CTRL_API_VERSION_DX9 = 1, + TASFE_CTRL_API_VERSION_DX10 = 2, + TASFE_CTRL_API_VERSION_DX11 = 3, + TASFE_CTRL_API_VERSION_DX12 = 4, +} TASFE_CTRL_API_VERSION; +typedef enum +{ + TASFE_CTRL_MSAA_STATE_MSAA_1X = 0, + TASFE_CTRL_MSAA_STATE_MSAA_2X = 1, + TASFE_CTRL_MSAA_STATE_MSAA_4X = 2, + TASFE_CTRL_MSAA_STATE_MSAA_8X = 3, + TASFE_CTRL_MSAA_STATE_MSAA_16X = 4, +} TASFE_CTRL_MSAA_STATE; +typedef enum +{ + TASFE_CTRL_AA_EN_FALSE = 0, + TASFE_CTRL_AA_EN_TRUE = 1, +} TASFE_CTRL_AA_EN; +typedef enum +{ + TASFE_CTRL_RASTER_MODE_NORMAL = 0, + TASFE_CTRL_RASTER_MODE_CONSERVATIVE = 1, +} TASFE_CTRL_RASTER_MODE; +typedef enum +{ + TASFE_CTRL_MISC_VIEWPORT_IDX_EN_DISABLED= 0, + TASFE_CTRL_MISC_VIEWPORT_IDX_EN_ENABLED = 1, +} TASFE_CTRL_MISC_VIEWPORT_IDX_EN; +typedef enum +{ + TASFE_CTRL_MISC_STO_EN_DISABLED = 0, + TASFE_CTRL_MISC_STO_EN_ENABLED = 1, +} TASFE_CTRL_MISC_STO_EN; +typedef enum +{ + TASFE_CTRL_MISC_POINT_SPRITE_EN_DISABLED= 0, + TASFE_CTRL_MISC_POINT_SPRITE_EN_ENABLED = 1, + +} TASFE_CTRL_MISC_POINT_SPRITE_EN; +typedef enum +{ + TASFE_CTRL_MISC_TILE_SIZE_256X128 = 0, + TASFE_CTRL_MISC_TILE_SIZE_128X128 = 1, + TASFE_CTRL_MISC_TILE_SIZE_128X64 = 2, + TASFE_CTRL_MISC_TILE_SIZE_64X64 = 3, + TASFE_CTRL_MISC_TILE_SIZE_64X32 = 4, + TASFE_CTRL_MISC_TILE_SIZE_32X32 = 5, + TASFE_CTRL_MISC_TILE_SIZE_32X16 = 6, + TASFE_CTRL_MISC_TILE_SIZE_16X16 = 7, + TASFE_CTRL_MISC_TILE_SIZE_16X8 = 8, + TASFE_CTRL_MISC_TILE_SIZE_8X8 = 9, +} TASFE_CTRL_MISC_TILE_SIZE; +typedef enum +{ + TASFE_CTRL_MISC_SPECIAL_ROTATE_FALSE = 0, + TASFE_CTRL_MISC_SPECIAL_ROTATE_TRUE = 1, +} TASFE_CTRL_MISC_SPECIAL_ROTATE; +typedef enum +{ + TASFE_CTRL_MISC_PRIMID_APPEND_EN_FALSE = 0, + TASFE_CTRL_MISC_PRIMID_APPEND_EN_TRUE = 1, +} TASFE_CTRL_MISC_PRIMID_APPEND_EN; +typedef enum +{ + TASFE_CTRL_MISC_RULE_FOR_TRIANGLE_TOP_LEFT= 0, + TASFE_CTRL_MISC_RULE_FOR_TRIANGLE_TOP_RIGHT= 1, + TASFE_CTRL_MISC_RULE_FOR_TRIANGLE_BOTTOM_LEFT= 2, + + TASFE_CTRL_MISC_RULE_FOR_TRIANGLE_BOTTON_RIGHT= 3, + +} TASFE_CTRL_MISC_RULE_FOR_TRIANGLE; +typedef enum +{ + TASFE_CTRL_MISC_QUAD_LINE_EN_FALSE = 0, + TASFE_CTRL_MISC_QUAD_LINE_EN_TRUE = 1, +} TASFE_CTRL_MISC_QUAD_LINE_EN; +typedef enum +{ + PRE_SETUP_CTRL_PRIMID_PACK_EN_FALSE = 0, + PRE_SETUP_CTRL_PRIMID_PACK_EN_TRUE = 1, +} PRE_SETUP_CTRL_PRIMID_PACK_EN; +typedef enum +{ + PRE_SETUP_CTRL_PTSPRITE_PERSP_FALSE = 0, + PRE_SETUP_CTRL_PTSPRITE_PERSP_TRUE = 1, +} PRE_SETUP_CTRL_PTSPRITE_PERSP; +typedef enum +{ + PRE_SETUP_CTRL_EDGE_FLAG_EN_FALSE = 0, + PRE_SETUP_CTRL_EDGE_FLAG_EN_TRUE = 1, +} PRE_SETUP_CTRL_EDGE_FLAG_EN; +typedef enum +{ + PRE_SETUP_CTRL_VIEWPORT_MASK_EN_FALSE = 0, + PRE_SETUP_CTRL_VIEWPORT_MASK_EN_TRUE = 1, +} PRE_SETUP_CTRL_VIEWPORT_MASK_EN; +typedef enum +{ + PRE_SETUP_CTRL_VIEWPORT_SWIZZLE_EN_FALSE= 0, + PRE_SETUP_CTRL_VIEWPORT_SWIZZLE_EN_TRUE = 1, +} PRE_SETUP_CTRL_VIEWPORT_SWIZZLE_EN; +typedef enum +{ + PRE_SETUP_CTRL_VIEWPORT_RELATIVE_FALSE = 0, + PRE_SETUP_CTRL_VIEWPORT_RELATIVE_TRUE = 1, +} PRE_SETUP_CTRL_VIEWPORT_RELATIVE; +typedef enum +{ + PRE_SETUP_CTRL_W_SCALING_EN_FALSE = 0, + PRE_SETUP_CTRL_W_SCALING_EN_TRUE = 1, +} PRE_SETUP_CTRL_W_SCALING_EN; +typedef enum +{ + PRE_SETUP_CTRL_TRANSFORM_EN_FALSE = 0, + PRE_SETUP_CTRL_TRANSFORM_EN_TRUE = 1, +} PRE_SETUP_CTRL_TRANSFORM_EN; +typedef enum +{ + PRE_SETUP_CTRL_DO_CLIPPING_FOR_POINT_FALSE= 0, + PRE_SETUP_CTRL_DO_CLIPPING_FOR_POINT_TRUE= 1, +} PRE_SETUP_CTRL_DO_CLIPPING_FOR_POINT; +typedef enum +{ + PRE_SETUP_CTRL_PTSPRITE_INVERT_POSITIVE_U_POSITIVE_V= 0, + + PRE_SETUP_CTRL_PTSPRITE_INVERT_POSITIVE_U_NEGATIVE_V= 1, + + PRE_SETUP_CTRL_PTSPRITE_INVERT_NEGATIVE_U_POSITIVE_V= 2, + + PRE_SETUP_CTRL_PTSPRITE_INVERT_NEGATIVE_U_NEGATIVE_V= 3, + + PRE_SETUP_CTRL_PTSPRITE_INVERT_POSITIVE_V_POSITIVE_U= 4, + + PRE_SETUP_CTRL_PTSPRITE_INVERT_POSITIVE_V_NEGATIVE_U= 5, + + PRE_SETUP_CTRL_PTSPRITE_INVERT_NEGATIVE_V_POSITIVE_U= 6, + + PRE_SETUP_CTRL_PTSPRITE_INVERT_NEGATIVE_V_NEGATIVE_U= 7, + +} PRE_SETUP_CTRL_PTSPRITE_INVERT; +typedef enum +{ + PRE_SETUP_CTRL_SKIP_FRUSTUM_REJ_FALSE = 0, + PRE_SETUP_CTRL_SKIP_FRUSTUM_REJ_TRUE = 1, +} PRE_SETUP_CTRL_SKIP_FRUSTUM_REJ; +typedef enum +{ + PRE_SETUP_CTRL_SKIP_SMALLTRI_REJ_FALSE = 0, + PRE_SETUP_CTRL_SKIP_SMALLTRI_REJ_TRUE = 1, +} PRE_SETUP_CTRL_SKIP_SMALLTRI_REJ; +typedef enum +{ + VIEWPORT_SWIZZLE_X_SWIZZLE0__POSITIVE_X = 0, + VIEWPORT_SWIZZLE_X_SWIZZLE0_NEGATIVE_X = 1, + VIEWPORT_SWIZZLE_X_SWIZZLE0__POSITIVE_Y = 2, + VIEWPORT_SWIZZLE_X_SWIZZLE0_NEGATIVE_Y = 3, + VIEWPORT_SWIZZLE_X_SWIZZLE0__POSITIVE_Z = 4, + VIEWPORT_SWIZZLE_X_SWIZZLE0_NEGATIVE_Z = 5, + VIEWPORT_SWIZZLE_X_SWIZZLE0__POSITIVE_W = 6, + VIEWPORT_SWIZZLE_X_SWIZZLE0_NEGATIVE_W = 7, +} VIEWPORT_SWIZZLE_X_SWIZZLE0; +typedef enum +{ + VIEWPORT_SWIZZLE_Y_SWIZZLE0__POSITIVE_X = 0, + VIEWPORT_SWIZZLE_Y_SWIZZLE0_NEGATIVE_X = 1, + VIEWPORT_SWIZZLE_Y_SWIZZLE0__POSITIVE_Y = 2, + VIEWPORT_SWIZZLE_Y_SWIZZLE0_NEGATIVE_Y = 3, + VIEWPORT_SWIZZLE_Y_SWIZZLE0__POSITIVE_Z = 4, + VIEWPORT_SWIZZLE_Y_SWIZZLE0_NEGATIVE_Z = 5, + VIEWPORT_SWIZZLE_Y_SWIZZLE0__POSITIVE_W = 6, + VIEWPORT_SWIZZLE_Y_SWIZZLE0_NEGATIVE_W = 7, +} VIEWPORT_SWIZZLE_Y_SWIZZLE0; +typedef enum +{ + VIEWPORT_SWIZZLE_Z_SWIZZLE0__POSITIVE_X = 0, + VIEWPORT_SWIZZLE_Z_SWIZZLE0_NEGATIVE_X = 1, + VIEWPORT_SWIZZLE_Z_SWIZZLE0__POSITIVE_Y = 2, + VIEWPORT_SWIZZLE_Z_SWIZZLE0_NEGATIVE_Y = 3, + VIEWPORT_SWIZZLE_Z_SWIZZLE0__POSITIVE_Z = 4, + VIEWPORT_SWIZZLE_Z_SWIZZLE0_NEGATIVE_Z = 5, + VIEWPORT_SWIZZLE_Z_SWIZZLE0__POSITIVE_W = 6, + VIEWPORT_SWIZZLE_Z_SWIZZLE0_NEGATIVE_W = 7, +} VIEWPORT_SWIZZLE_Z_SWIZZLE0; +typedef enum +{ + VIEWPORT_SWIZZLE_W_SWIZZLE0__POSITIVE_X = 0, + VIEWPORT_SWIZZLE_W_SWIZZLE0_NEGATIVE_X = 1, + VIEWPORT_SWIZZLE_W_SWIZZLE0__POSITIVE_Y = 2, + VIEWPORT_SWIZZLE_W_SWIZZLE0_NEGATIVE_Y = 3, + VIEWPORT_SWIZZLE_W_SWIZZLE0__POSITIVE_Z = 4, + VIEWPORT_SWIZZLE_W_SWIZZLE0_NEGATIVE_Z = 5, + VIEWPORT_SWIZZLE_W_SWIZZLE0__POSITIVE_W = 6, + VIEWPORT_SWIZZLE_W_SWIZZLE0_NEGATIVE_W = 7, +} VIEWPORT_SWIZZLE_W_SWIZZLE0; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int As_En : 1; + unsigned int Zero_Det_Mode : 1; + unsigned int Cull_En : 1; + unsigned int Cull_Mode : 1; + unsigned int Winding : 1; + unsigned int Zclip_En : 1; + unsigned int Zoffset_Fill_En : 1; + unsigned int Zoffset_Line_En : 1; + unsigned int Zoffset_Point_En : 1; + unsigned int Strict_Line_En : 1; + unsigned int Non_Perspective_En : 1; + unsigned int Pttri_En : 1; + unsigned int Point_Size_En : 1; + unsigned int Last_Pixel : 1; + unsigned int Leading_Vtx : 1; + unsigned int Z32f_En : 1; + unsigned int Z_Setup_Mode : 1; + unsigned int Rhw_Setup_Mode : 1; + unsigned int Front_Polygon_Mode : 2; + unsigned int Back_Polygon_Mode : 2; + unsigned int Depth_Mode : 1; + unsigned int Force_Z_Gbc : 1; + unsigned int Api_Version : 3; + + + unsigned int Msaa_State : 3; + + unsigned int Aa_En : 1; + unsigned int Raster_Mode : 1; + } reg; +} Reg_Tasfe_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr_Num : 6; + unsigned int Viewport_Idx_En : 1; + unsigned int Sto_En : 1; + unsigned int Point_Sprite_En : 1; + unsigned int Tile_Size : 4; + unsigned int Special_Rotate : 1; + unsigned int Primid_Append_En : 1; + + + + + unsigned int Pos_End_Ptr : 10; + unsigned int Rule_For_Triangle : 2; + unsigned int Rule_For_A_Line : 2; + unsigned int Rule_For_Point : 2; + unsigned int Quad_Line_En : 1; + } reg; +} Reg_Tasfe_Ctrl_Misc; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Primid_Pack_En : 1; + unsigned int Primid_Pack_Attr : 6; + + unsigned int Primid_Pack_Channel : 2; + + unsigned int Ptsprite_Persp : 1; + unsigned int Edge_Flag_En : 1; + unsigned int Reserved : 5; + unsigned int Viewport_Mask_En : 1; + unsigned int Viewport_Swizzle_En : 1; + unsigned int Viewport_Relative : 1; + unsigned int W_Scaling_En : 1; + unsigned int Transform_En : 1; + unsigned int Do_Clipping_For_Point : 1; + unsigned int Ptsprite_Invert : 3; + unsigned int Skip_Frustum_Rej : 1; + unsigned int Gb_Size : 5; + unsigned int Skip_Smalltri_Rej : 1; + } reg; +} Reg_Pre_Setup_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int X_Gb_Exp0 : 8; + + unsigned int Y_Gb_Exp0 : 8; + + unsigned int X_Gb_Exp1 : 8; + + unsigned int Y_Gb_Exp1 : 8; + + } reg; +} Reg_Gb_Exp; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int X_Min : 16; + unsigned int X_Max : 16; + } reg; +} Reg_Scissor_X; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Y_Min : 16; + + unsigned int Y_Max : 16; + + } reg; +} Reg_Scissor_Y; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int X_Scale : 32; + } reg; +} Reg_Viewport_Xscale; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int X_Offset : 32; + } reg; +} Reg_Viewport_Xoffset; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Y_Scale : 32; + } reg; +} Reg_Viewport_Yscale; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Y_Offset : 32; + } reg; +} Reg_Viewport_Yoffset; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Z_Scale : 32; + } reg; +} Reg_Viewport_Zscale; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Z_Offset : 32; + } reg; +} Reg_Viewport_Zoffset; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int X_Coeff : 32; + } reg; +} Reg_Wscaling_Xcoeff; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Y_Coeff : 32; + } reg; +} Reg_Wscaling_Ycoeff; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int X_Swizzle0 : 3; + unsigned int Y_Swizzle0 : 3; + unsigned int Z_Swizzle0 : 3; + unsigned int W_Swizzle0 : 3; + unsigned int X_Swizzle1 : 3; + unsigned int Y_Swizzle1 : 3; + unsigned int Z_Swizzle1 : 3; + unsigned int W_Swizzle1 : 3; + unsigned int Reserved : 8; + } reg; +} Reg_Viewport_Swizzle; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Point_Size : 27; + + unsigned int Reserved : 5; + } reg; +} Reg_Point_Size; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Line_Width : 27; + unsigned int Reserved : 5; + } reg; +} Reg_Line_Width; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Zbias : 32; + } reg; +} Reg_Z_Bias; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Factor : 32; + } reg; +} Reg_Z_Scale_Factor; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Zbias_Clamp : 32; + + } reg; +} Reg_Z_Bias_Clamp; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Attr0_Const_Persp : 2; + + unsigned int Attr1_Const_Persp : 2; + + unsigned int Attr2_Const_Persp : 2; + + unsigned int Attr3_Const_Persp : 2; + + unsigned int Attr4_Const_Persp : 2; + + unsigned int Attr5_Const_Persp : 2; + + unsigned int Attr6_Const_Persp : 2; + + unsigned int Attr7_Const_Persp : 2; + + unsigned int Attr8_Const_Persp : 2; + + unsigned int Attr9_Const_Persp : 2; + + unsigned int Attr10_Const_Persp : 2; + + unsigned int Attr11_Const_Persp : 2; + + unsigned int Attr12_Const_Persp : 2; + + unsigned int Attr13_Const_Persp : 2; + + unsigned int Attr14_Const_Persp : 2; + + unsigned int Attr15_Const_Persp : 2; + + } reg; +} Reg_Attr_Const_Persp; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Tasfe_Reserved; + +typedef struct _Tasfe_regs +{ + Reg_Tasfe_Ctrl reg_Tasfe_Ctrl; + Reg_Tasfe_Ctrl_Misc reg_Tasfe_Ctrl_Misc; + Reg_Pre_Setup_Ctrl reg_Pre_Setup_Ctrl; + Reg_Gb_Exp reg_Gb_Exp[8]; + Reg_Scissor_X reg_Scissor_X[16]; + Reg_Scissor_Y reg_Scissor_Y[16]; + Reg_Viewport_Xscale reg_Viewport_Xscale[16]; + Reg_Viewport_Xoffset reg_Viewport_Xoffset[16]; + Reg_Viewport_Yscale reg_Viewport_Yscale[16]; + Reg_Viewport_Yoffset reg_Viewport_Yoffset[16]; + Reg_Viewport_Zscale reg_Viewport_Zscale[16]; + Reg_Viewport_Zoffset reg_Viewport_Zoffset[16]; + Reg_Wscaling_Xcoeff reg_Wscaling_Xcoeff[16]; + Reg_Wscaling_Ycoeff reg_Wscaling_Ycoeff[16]; + Reg_Viewport_Swizzle reg_Viewport_Swizzle[8]; + Reg_Point_Size reg_Point_Size; + Reg_Line_Width reg_Line_Width; + Reg_Z_Bias reg_Z_Bias; + Reg_Z_Scale_Factor reg_Z_Scale_Factor; + Reg_Z_Bias_Clamp reg_Z_Bias_Clamp; + Reg_Attr_Const_Persp reg_Attr_Const_Persp[3]; + Reg_Tasfe_Reserved reg_Tasfe_Reserved[5]; +} Tasfe_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/TU_Reg.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/TU_Reg.h new file mode 100644 index 0000000000000..4d40145b5166b --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/TU_Reg.h @@ -0,0 +1,913 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _TUFE_REGISTER_H +#define _TUFE_REGISTER_H + + +#ifndef TU_BLOCKBASE_INF +#define TU_BLOCKBASE_INF +#define BLOCK_TU_VERSION 1 +#define BLOCK_TU_TIMESTAMP "7/10/2018 2:50:05 PM" +#define TUFE_BLOCK 0xA +#define TUBE_BLOCK 0x14 +#define TU_REG_START 0x0 +#define TU_REG_END 0x580 +#define TU_REG_LIMIT 0x580 +#endif + + +#define Reg_Tu_Tssharp_Ctrl_Offset 0x0 +#define Reg_Tu_Tssharp_3d_Ctrl_Offset 0x1 +#define Reg_Tu_Tssharp_Heap_Base0_Offset 0x2 +#define Reg_Tu_Tssharp_Heap_Base1_Offset 0x3 +#define Reg_Tu_Tssharp_Heap_Base2_Offset 0x4 +#define Reg_Tu_Tssharp_Heap_Base3_Offset 0x5 +#define Reg_Tu_Tssharp_Heap_Base4_Offset 0x6 +#define Reg_Tu_Tssharp_Heap_Base5_Offset 0x7 +#define Reg_Tu_Tssharp_Heap_Base6_Offset 0x8 +#define Reg_Tu_Tssharp_Heap_Base7_Offset 0x9 +#define Reg_Tu_Reserved1_Offset 0xA +#define Reg_Tu_Control_Fe_Offset 0x10 +#define Reg_Tu_Si_Ctl_Offset 0x11 +#define Reg_Tu_Vs_Tsharp_Ctrl_Offset 0x12 +#define Reg_Tu_Vs_Ssharp_Ctrl_Offset 0x13 +#define Reg_Tu_Hs_Tsharp_Ctrl_Offset 0x14 +#define Reg_Tu_Hs_Ssharp_Ctrl_Offset 0x15 +#define Reg_Tu_Ds_Tsharp_Ctrl_Offset 0x16 +#define Reg_Tu_Ds_Ssharp_Ctrl_Offset 0x17 +#define Reg_Tu_Gs_Tsharp_Ctrl_Offset 0x18 +#define Reg_Tu_Gs_Ssharp_Ctrl_Offset 0x19 +#define Reg_Tu_Reserved2_Offset 0x1A +#define Reg_Tu_Vb_Offset 0x20 +#define Reg_Tu_Ve_Offset 0xA0 +#define Reg_Tu_Instance_Offset 0xC0 +#define Reg_Tu_Control_Be_Offset 0xE0 +#define Reg_Tu_Ps_Tsharp_Ctrl_Offset 0xE1 +#define Reg_Tu_Ps_Ssharp_Ctrl_Offset 0xE2 +#define Reg_Tu_Reserved3_Offset 0xE3 +#define Reg_Tu_Tssharp_Cs_Ctrl_Offset 0xE8 +#define Reg_Tu_Csl_Tsharp_Ctrl_Offset 0xE9 +#define Reg_Tu_Csl_Ssharp_Ctrl_Offset 0xEA +#define Reg_Tu_Csh_Tsharp_Ctrl_Offset 0xEB +#define Reg_Tu_Csh_Ssharp_Ctrl_Offset 0xEC +#define Reg_Tu_Reserved4_Offset 0xED +#define Reg_Tu_Ts_Sharp_Offset 0x100 + + + + +typedef enum +{ + TU_CONTROL_FE_SECTOR_MODE_512B = 0, + TU_CONTROL_FE_SECTOR_MODE_1K = 1, + TU_CONTROL_FE_SECTOR_MODE_2K = 2, + TU_CONTROL_FE_SECTOR_MODE_RESERVED = 3, +} TU_CONTROL_FE_SECTOR_MODE; +typedef enum +{ + TU_CONTROL_FE_API_MODE_FE_DX = 0, + TU_CONTROL_FE_API_MODE_FE_DX9 = 1, + TU_CONTROL_FE_API_MODE_FE_VULKAN = 2, + TU_CONTROL_FE_API_MODE_FE_OGL = 3, + TU_CONTROL_FE_API_MODE_FE_OES = 4, + TU_CONTROL_FE_API_MODE_FE_OCL = 5, +} TU_CONTROL_FE_API_MODE_FE; +typedef enum +{ + TU_SI_CTL_API_MODE_DX = 0, + TU_SI_CTL_API_MODE_DX9 = 1, + TU_SI_CTL_API_MODE_VULKAN = 2, + TU_SI_CTL_API_MODE_OGL = 3, + TU_SI_CTL_API_MODE_OES = 4, + TU_SI_CTL_API_MODE_OCL = 5, +} TU_SI_CTL_API_MODE; +typedef enum +{ + TU_CONTROL_BE_SECTOR_MODE_512B = 0, + TU_CONTROL_BE_SECTOR_MODE_1K = 1, + TU_CONTROL_BE_SECTOR_MODE_2K = 2, + TU_CONTROL_BE_SECTOR_MODE_RESERVED = 3, +} TU_CONTROL_BE_SECTOR_MODE; +typedef enum +{ + TU_CONTROL_BE_API_MODE_BE_DX = 0, + TU_CONTROL_BE_API_MODE_BE_DX9 = 1, + TU_CONTROL_BE_API_MODE_BE_VULKAN = 2, + TU_CONTROL_BE_API_MODE_BE_OGL = 3, + TU_CONTROL_BE_API_MODE_BE_OES = 4, + TU_CONTROL_BE_API_MODE_BE_OCL = 5, +} TU_CONTROL_BE_API_MODE_BE; +typedef enum +{ + TU_T_SHARP_REG2_MSAA_MODE_MSAA_1X = 0, + TU_T_SHARP_REG2_MSAA_MODE_MSAA_2X = 1, + TU_T_SHARP_REG2_MSAA_MODE_MSAA_4X = 2, + TU_T_SHARP_REG2_MSAA_MODE_MSAA_8X = 3, + TU_T_SHARP_REG2_MSAA_MODE_MSAA_16X = 4, +} TU_T_SHARP_REG2_MSAA_MODE; +typedef enum +{ + TU_T_SHARP_REG2_RES_TYPE_1D_BUFFER = 0, + TU_T_SHARP_REG2_RES_TYPE_1D_TEXTURE = 1, + TU_T_SHARP_REG2_RES_TYPE_2D_TEXTURE = 2, + TU_T_SHARP_REG2_RES_TYPE_3D_TEXTURE = 3, + TU_T_SHARP_REG2_RES_TYPE_CUBE_TEXTURE = 4, + TU_T_SHARP_REG2_RES_TYPE_1D_TEXTURE_ARRAY= 5, + TU_T_SHARP_REG2_RES_TYPE_2D_TEXTURE_ARRAY= 6, + TU_T_SHARP_REG2_RES_TYPE_CUBE_TEXTURE_ARRAY= 7, + TU_T_SHARP_REG2_RES_TYPE_RAW_BUFFER = 8, + TU_T_SHARP_REG2_RES_TYPE_STRUCTURED_BUFFER= 9, + TU_T_SHARP_REG2_RES_TYPE_VERTEX_BUFFER = 10, +} TU_T_SHARP_REG2_RES_TYPE; +typedef enum +{ + TU_T_SHARP_REG5_COMPONENT_MAPPING_R_COMPONENT_0= 0, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_R_COMPONENT_1= 1, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_R_COMPONENT_2= 2, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_R_COMPONENT_3= 3, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_R_VALUE_0= 4, + TU_T_SHARP_REG5_COMPONENT_MAPPING_R_VALUE_1= 5, +} TU_T_SHARP_REG5_COMPONENT_MAPPING_R; +typedef enum +{ + TU_T_SHARP_REG5_COMPONENT_MAPPING_G_COMPONENT_0= 0, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_G_COMPONENT_1= 1, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_G_COMPONENT_2= 2, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_G_COMPONENT_3= 3, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_G_VALUE_0= 4, + TU_T_SHARP_REG5_COMPONENT_MAPPING_G_VALUE_1= 5, +} TU_T_SHARP_REG5_COMPONENT_MAPPING_G; +typedef enum +{ + TU_T_SHARP_REG5_COMPONENT_MAPPING_B_COMPONENT_0= 0, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_B_COMPONENT_1= 1, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_B_COMPONENT_2= 2, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_B_COMPONENT_3= 3, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_B_VALUE_0= 4, + TU_T_SHARP_REG5_COMPONENT_MAPPING_B_VALUE_1= 5, +} TU_T_SHARP_REG5_COMPONENT_MAPPING_B; +typedef enum +{ + TU_T_SHARP_REG5_COMPONENT_MAPPING_A_COMPONENT_0= 0, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_A_COMPONENT_1= 1, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_A_COMPONENT_2= 2, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_A_COMPONENT_3= 3, + + TU_T_SHARP_REG5_COMPONENT_MAPPING_A_VALUE_0= 4, + TU_T_SHARP_REG5_COMPONENT_MAPPING_A_VALUE_1= 5, +} TU_T_SHARP_REG5_COMPONENT_MAPPING_A; +typedef enum +{ + TU_S_SHARP_REG0_COMPARE_FUNC_NEVER = 0, + TU_S_SHARP_REG0_COMPARE_FUNC_LESS = 1, + TU_S_SHARP_REG0_COMPARE_FUNC_EQUAL = 2, + TU_S_SHARP_REG0_COMPARE_FUNC_LESSEQUAL = 3, + TU_S_SHARP_REG0_COMPARE_FUNC_GREATER = 4, + TU_S_SHARP_REG0_COMPARE_FUNC_NOTEQUAL = 5, + TU_S_SHARP_REG0_COMPARE_FUNC_GREATEREQUAL= 6, + TU_S_SHARP_REG0_COMPARE_FUNC_ALWAYS = 7, +} TU_S_SHARP_REG0_COMPARE_FUNC; +typedef enum +{ + TU_S_SHARP_REG0_LOD_BRILINEAR_THRESHOLD_BRI_0= 0, + + TU_S_SHARP_REG0_LOD_BRILINEAR_THRESHOLD_BRI_DOT_0625= 1, + + TU_S_SHARP_REG0_LOD_BRILINEAR_THRESHOLD_BRI_DOT_125= 2, + + TU_S_SHARP_REG0_LOD_BRILINEAR_THRESHOLD_BRI_DOT_1875= 3, + +} TU_S_SHARP_REG0_LOD_BRILINEAR_THRESHOLD; +typedef enum +{ + TU_S_SHARP_REG0_DEPTH_MODE_NORMAL = 0, + TU_S_SHARP_REG0_DEPTH_MODE_AMODE = 1, + TU_S_SHARP_REG0_DEPTH_MODE_IMODE = 2, + TU_S_SHARP_REG0_DEPTH_MODE_LMODE = 3, + TU_S_SHARP_REG0_DEPTH_MODE_LAMODE = 4, + TU_S_SHARP_REG0_DEPTH_MODE_RAMODE = 5, +} TU_S_SHARP_REG0_DEPTH_MODE; +typedef enum +{ + TU_S_SHARP_REG0_FILTER_REDU_TYPE_STANDARD= 0, + TU_S_SHARP_REG0_FILTER_REDU_TYPE_COMPARISON= 1, + TU_S_SHARP_REG0_FILTER_REDU_TYPE_MIN = 2, + + TU_S_SHARP_REG0_FILTER_REDU_TYPE_MAX = 3, + +} TU_S_SHARP_REG0_FILTER_REDU_TYPE; +typedef enum +{ + TU_S_SHARP_REG1_ADDR_U_WRAP = 0, + + TU_S_SHARP_REG1_ADDR_U_MIRROR = 1, + + TU_S_SHARP_REG1_ADDR_U_CLAMP = 2, + + + TU_S_SHARP_REG1_ADDR_U_BORDER = 3, + TU_S_SHARP_REG1_ADDR_U_MIRROR_ONCE = 4, + TU_S_SHARP_REG1_ADDR_U_HALF_BORDER = 5, + TU_S_SHARP_REG1_ADDR_U_CUBE_WRAP = 6, +} TU_S_SHARP_REG1_ADDR_U; +typedef enum +{ + TU_S_SHARP_REG3_YUV_SELECT_CHANNEL_Y = 0, + TU_S_SHARP_REG3_YUV_SELECT_CHANNEL_U = 1, + + TU_S_SHARP_REG3_YUV_SELECT_CHANNEL_V = 2, + TU_S_SHARP_REG3_YUV_SELECT_CHANNEL_ALL = 3, +} TU_S_SHARP_REG3_YUV_SELECT; +typedef enum +{ + TU_S_SHARP_REG3_MAG_FILTER_POINT = 0, + TU_S_SHARP_REG3_MAG_FILTER_LINEAR = 1, + TU_S_SHARP_REG3_MAG_FILTER_ANISOPOINT = 2, + TU_S_SHARP_REG3_MAG_FILTER_ANISO = 3, +} TU_S_SHARP_REG3_MAG_FILTER; +typedef enum +{ + TU_S_SHARP_REG3_MIN_FILTER_POINT = 0, + TU_S_SHARP_REG3_MIN_FILTER_LINEAR = 1, + TU_S_SHARP_REG3_MIN_FILTER_ANISOPOINT = 2, + TU_S_SHARP_REG3_MIN_FILTER_ANISO = 3, +} TU_S_SHARP_REG3_MIN_FILTER; +typedef enum +{ + TU_S_SHARP_REG3_MIP_FILTER_NONE = 0, + TU_S_SHARP_REG3_MIP_FILTER_POINT = 1, + TU_S_SHARP_REG3_MIP_FILTER_LINEAR = 2, + TU_S_SHARP_REG3_MIP_FILTER_RESERVED = 3, +} TU_S_SHARP_REG3_MIP_FILTER; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address_3d : 8; + + unsigned int Reserved : 24; + } reg; +} Reg_Tu_Tssharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address_Be : 8; + + unsigned int Is_3d_Cachemode : 1; + unsigned int Reserved : 23; + } reg; +} Reg_Tu_Tssharp_3d_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 32; + } reg; +} Reg_Tu_Tssharp_Heap_Base0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 32; + } reg; +} Reg_Tu_Tssharp_Heap_Base1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 32; + } reg; +} Reg_Tu_Tssharp_Heap_Base2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 32; + } reg; +} Reg_Tu_Tssharp_Heap_Base3; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 32; + } reg; +} Reg_Tu_Tssharp_Heap_Base4; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 32; + } reg; +} Reg_Tu_Tssharp_Heap_Base5; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 32; + } reg; +} Reg_Tu_Tssharp_Heap_Base6; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 32; + } reg; +} Reg_Tu_Tssharp_Heap_Base7; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Tu_Reserved1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Sector_Mode : 2; + unsigned int Vb_Sector_Mode : 2; + unsigned int Reserved_0 : 1; + unsigned int Enable_Vb_Bank_Swizzle : 1; + unsigned int Enable_3dtex_Qswizzle : 1; + + unsigned int Api_Mode_Fe : 3; + unsigned int Reserved_1 : 22; + } reg; +} Reg_Tu_Control_Fe; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Element_Num : 7; + unsigned int Vid_En : 1; + unsigned int Iid_En : 1; + unsigned int Api_Mode : 3; + unsigned int Did_En : 1; + unsigned int Base_Vertex_En : 1; + + unsigned int Base_Instance_En : 1; + + unsigned int Reserved : 17; + } reg; +} Reg_Tu_Si_Ctl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Vs_Tsharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Vs_Ssharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Hs_Tsharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Hs_Ssharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Ds_Tsharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Ds_Ssharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Gs_Tsharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Gs_Ssharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Tu_Reserved2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Resource_Address : 32; + } reg; +} Reg_Tu_Vb0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vb_Size_Inbyte : 28; + unsigned int Reserved : 4; + } reg; +} Reg_Tu_Vb1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vb_Start_Offset : 32; + } reg; +} Reg_Tu_Vb2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Vb_Stride_Inbyte : 12; + } reg; +} Reg_Tu_Vb3; + +typedef struct _Group_Tu_Vb +{ + Reg_Tu_Vb0 reg_Tu_Vb0; + Reg_Tu_Vb1 reg_Tu_Vb1; + Reg_Tu_Vb2 reg_Tu_Vb2; + Reg_Tu_Vb3 reg_Tu_Vb3; +} Reg_Tu_Vb_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Res_Format : 9; + unsigned int Valid : 1; + unsigned int Element_Offset : 11; + + unsigned int Vb_Id : 5; + unsigned int Instance_En : 1; + unsigned int Reserved : 5; + } reg; +} Reg_Tu_Ve; + +typedef struct _Group_Tu_Ve +{ + Reg_Tu_Ve reg_Tu_Ve; +} Reg_Tu_Ve_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Step_Rate : 26; + + unsigned int Reserved : 6; + } reg; +} Reg_Tu_Instance_Ctl; + +typedef struct _Group_Tu_Instance +{ + Reg_Tu_Instance_Ctl reg_Tu_Instance_Ctl; +} Reg_Tu_Instance_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Sector_Mode : 2; + unsigned int Reserved_0 : 4; + unsigned int Enable_3dtex_Qswizzle : 1; + + unsigned int Api_Mode_Be : 3; + unsigned int Reserved_1 : 22; + } reg; +} Reg_Tu_Control_Be; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Ps_Tsharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Ps_Ssharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Tu_Reserved3; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address_Csh : 8; + + unsigned int Is_Csl_Cachemode : 1; + unsigned int Is_Csh_Cachemode : 1; + unsigned int Reserved : 22; + } reg; +} Reg_Tu_Tssharp_Cs_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Csl_Tsharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Csl_Ssharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Csh_Tsharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Base_Address : 8; + unsigned int Count : 8; + unsigned int Reserved : 16; + } reg; +} Reg_Tu_Csh_Ssharp_Ctrl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Tu_Reserved4_Ctl; + +typedef struct _Group_Tu_Reserved4 +{ + Reg_Tu_Reserved4_Ctl reg_Tu_Reserved4_Ctl; +} Reg_Tu_Reserved4_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Res_Address : 32; + } reg; +} Reg_Tu_T_Sharp_Reg0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Res_Width : 15; + unsigned int Res_Height : 15; + unsigned int Is_Compression : 1; + unsigned int Is_Data_Matrix : 1; + } reg; +} Reg_Tu_T_Sharp_Reg1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Res_Depth : 12; + + unsigned int Res_Format : 9; + unsigned int Msaa_Mode : 3; + unsigned int Res_Type : 4; + unsigned int Reserved : 4; + } reg; +} Reg_Tu_T_Sharp_Reg2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Is_Mipmap : 1; + unsigned int Is_Linear_Texture : 1; + unsigned int View_Lod_Start : 4; + unsigned int View_Lod_End : 4; + unsigned int View_Array_Slice_Start : 11; + unsigned int View_Array_Slice_End : 11; + } reg; +} Reg_Tu_T_Sharp_Reg3; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Bl_Start : 18; + + unsigned int Lod_Clamp : 12; + + + + unsigned int Reserved : 1; + + unsigned int Is_Bdr_Added : 1; + } reg; +} Reg_Tu_T_Sharp_Reg4; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Component_Mapping_R : 3; + unsigned int Component_Mapping_G : 3; + unsigned int Component_Mapping_B : 3; + unsigned int Component_Mapping_A : 3; + unsigned int Range_Type : 6; + unsigned int Is_Sparse : 1; + unsigned int Valid : 1; + unsigned int Reserved : 12; + } reg; +} Reg_Tu_T_Sharp_Reg5; + +typedef struct _Group_Tu_T_Sharp +{ + Reg_Tu_T_Sharp_Reg0 reg_Tu_T_Sharp_Reg0; + Reg_Tu_T_Sharp_Reg1 reg_Tu_T_Sharp_Reg1; + Reg_Tu_T_Sharp_Reg2 reg_Tu_T_Sharp_Reg2; + Reg_Tu_T_Sharp_Reg3 reg_Tu_T_Sharp_Reg3; + Reg_Tu_T_Sharp_Reg4 reg_Tu_T_Sharp_Reg4; + Reg_Tu_T_Sharp_Reg5 reg_Tu_T_Sharp_Reg5; +} Reg_Tu_T_Sharp_Group; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Sample_C_Fail_Value : 8; + + unsigned int Compare_Func : 3; + + unsigned int Reserved_0 : 3; + unsigned int Lod_Brilinear_Threshold : 2; + unsigned int Uv_Brilinear_Threshold : 2; + unsigned int Q_Brilinear_Threshold : 2; + unsigned int Depth_Mode : 3; + unsigned int Max_Aniso_Ratio : 4; + unsigned int Is_Unnormalized_Coord : 1; + unsigned int Filter_Redu_Type : 2; + unsigned int Degamma_En : 1; + unsigned int Reserved_1 : 1; + } reg; +} Reg_Tu_S_Sharp_Reg0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Mip_Bias : 16; + + unsigned int Addr_U : 3; + unsigned int Addr_V : 3; + unsigned int Addr_R : 3; + unsigned int Is_Non_Seamless_Cube : 1; + unsigned int Reserved : 6; + } reg; +} Reg_Tu_S_Sharp_Reg1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Bc_Address : 32; + } reg; +} Reg_Tu_S_Sharp_Reg2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Min_Lod : 12; + unsigned int Max_Lod : 12; + unsigned int Yuv_Select : 2; + + unsigned int Mag_Filter : 2; + unsigned int Min_Filter : 2; + unsigned int Mip_Filter : 2; + } reg; +} Reg_Tu_S_Sharp_Reg3; + +typedef struct _Group_Tu_S_Sharp +{ + Reg_Tu_S_Sharp_Reg0 reg_Tu_S_Sharp_Reg0; + Reg_Tu_S_Sharp_Reg1 reg_Tu_S_Sharp_Reg1; + Reg_Tu_S_Sharp_Reg2 reg_Tu_S_Sharp_Reg2; + Reg_Tu_S_Sharp_Reg3 reg_Tu_S_Sharp_Reg3; +} Reg_Tu_S_Sharp_Group; + + typedef union +{ + Reg_Tu_T_Sharp_Group reg_tsharp; + Reg_Tu_S_Sharp_Group reg_ssharp; +} Reg_Tu_Ts_Sharp_Group; + +typedef struct _Tu_regs +{ + Reg_Tu_Tssharp_Ctrl reg_Tu_Tssharp_Ctrl; + Reg_Tu_Tssharp_3d_Ctrl reg_Tu_Tssharp_3d_Ctrl; + Reg_Tu_Tssharp_Heap_Base0 reg_Tu_Tssharp_Heap_Base0; + Reg_Tu_Tssharp_Heap_Base1 reg_Tu_Tssharp_Heap_Base1; + Reg_Tu_Tssharp_Heap_Base2 reg_Tu_Tssharp_Heap_Base2; + Reg_Tu_Tssharp_Heap_Base3 reg_Tu_Tssharp_Heap_Base3; + Reg_Tu_Tssharp_Heap_Base4 reg_Tu_Tssharp_Heap_Base4; + Reg_Tu_Tssharp_Heap_Base5 reg_Tu_Tssharp_Heap_Base5; + Reg_Tu_Tssharp_Heap_Base6 reg_Tu_Tssharp_Heap_Base6; + Reg_Tu_Tssharp_Heap_Base7 reg_Tu_Tssharp_Heap_Base7; + Reg_Tu_Reserved1 reg_Tu_Reserved1[6]; + Reg_Tu_Control_Fe reg_Tu_Control_Fe; + Reg_Tu_Si_Ctl reg_Tu_Si_Ctl; + Reg_Tu_Vs_Tsharp_Ctrl reg_Tu_Vs_Tsharp_Ctrl; + Reg_Tu_Vs_Ssharp_Ctrl reg_Tu_Vs_Ssharp_Ctrl; + Reg_Tu_Hs_Tsharp_Ctrl reg_Tu_Hs_Tsharp_Ctrl; + Reg_Tu_Hs_Ssharp_Ctrl reg_Tu_Hs_Ssharp_Ctrl; + Reg_Tu_Ds_Tsharp_Ctrl reg_Tu_Ds_Tsharp_Ctrl; + Reg_Tu_Ds_Ssharp_Ctrl reg_Tu_Ds_Ssharp_Ctrl; + Reg_Tu_Gs_Tsharp_Ctrl reg_Tu_Gs_Tsharp_Ctrl; + Reg_Tu_Gs_Ssharp_Ctrl reg_Tu_Gs_Ssharp_Ctrl; + Reg_Tu_Reserved2 reg_Tu_Reserved2[6]; + Reg_Tu_Vb_Group reg_Tu_Vb[32]; + Reg_Tu_Ve_Group reg_Tu_Ve[32]; + Reg_Tu_Instance_Group reg_Tu_Instance[32]; + Reg_Tu_Control_Be reg_Tu_Control_Be; + Reg_Tu_Ps_Tsharp_Ctrl reg_Tu_Ps_Tsharp_Ctrl; + Reg_Tu_Ps_Ssharp_Ctrl reg_Tu_Ps_Ssharp_Ctrl; + Reg_Tu_Reserved3 reg_Tu_Reserved3[5]; + Reg_Tu_Tssharp_Cs_Ctrl reg_Tu_Tssharp_Cs_Ctrl; + Reg_Tu_Csl_Tsharp_Ctrl reg_Tu_Csl_Tsharp_Ctrl; + Reg_Tu_Csl_Ssharp_Ctrl reg_Tu_Csl_Ssharp_Ctrl; + Reg_Tu_Csh_Tsharp_Ctrl reg_Tu_Csh_Tsharp_Ctrl; + Reg_Tu_Csh_Ssharp_Ctrl reg_Tu_Csh_Ssharp_Ctrl; + Reg_Tu_Reserved4_Group reg_Tu_Reserved4[19]; + Reg_Tu_Ts_Sharp_Group reg_Tu_Ts_Sharp[192]; +} Tu_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/VCP_OPCODE_DECOUPLE.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/VCP_OPCODE_DECOUPLE.h new file mode 100644 index 0000000000000..026395bb89111 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/VCP_OPCODE_DECOUPLE.h @@ -0,0 +1,611 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _VCP_OPCODE_DECOUPLE_H +#define _VCP_OPCODE_DECOUPLE_H + +#ifndef COMMAND_OPCODES_BLOCKBASE_INF + #define COMMAND_OPCODES_BLOCKBASE_INF + #define BLOCK_COMMAND_OPCODES_VERSION 1 + #define BLOCK_COMMAND_OPCODES_TIMESTAMP "2019/2/18 17:08:36" +#endif + + +#define VCP_OPCODE_Vcp_Skip 0x0 +#define VCP_OPCODE_Vcp_Set_Data_Buf 0x1 +#define VCP_OPCODE_Vcp_Internal_Wait 0x2 +#define VCP_OPCODE_Vcp_Query_Dump 0x3 +#define VCP_OPCODE_Vcp_Set_Register 0x4 +#define VCP_OPCODE_Vcp_Set_Register_Short 0x5 +#define VCP_OPCODE_Vcp_Kickoff 0x7 +#define VCP_OPCODE_Vcp_Fence 0x8 +#define VCP_OPCODE_Vcp_Indicator 0x9 +#define VCP_OPCODE_Vcp_Autoclear 0xC +#define VCP_OPCODE_Vcp_Init 0xD +#define VCP_OPCODE_Vcp_Aes 0xE + + +typedef enum +{ + VCP_SET_DATA_BUF_DATA_EXCH_TYPE_MEM = 0, + VCP_SET_DATA_BUF_DATA_EXCH_TYPE_FIFO = 1, +} VCP_SET_DATA_BUF_DATA_EXCH_TYPE; +typedef enum +{ + VCP_INTERNAL_WAIT_WAIT_MODE_NORMAL_WAIT = 0, + VCP_INTERNAL_WAIT_WAIT_MODE_KKK_WAIT = 1, + VCP_INTERNAL_WAIT_WAIT_MODE_WAIT_CHIP_IDLE= 2, + VCP_INTERNAL_WAIT_WAIT_MODE_EXTERNAL_WAIT= 3, +} VCP_INTERNAL_WAIT_WAIT_MODE; +typedef enum +{ + VCP_INTERNAL_WAIT_METHOD_BIGEQUAL = 0, + VCP_INTERNAL_WAIT_METHOD_EQUAL = 1, +} VCP_INTERNAL_WAIT_METHOD; +typedef enum +{ + VCP_INTERNAL_WAIT_STATION_ID_MAIN_PARSER= 0, + VCP_INTERNAL_WAIT_STATION_ID_PRE_PARSER = 1, + +} VCP_INTERNAL_WAIT_STATION_ID; +typedef enum +{ + VCP_INTERNAL_WAIT_SLOT_ID_TO_WAIT_VCP0_BE= 8, + VCP_INTERNAL_WAIT_SLOT_ID_TO_WAIT_VCP0_FE= 9, + VCP_INTERNAL_WAIT_SLOT_ID_TO_WAIT_VCP1_BE= 11, + VCP_INTERNAL_WAIT_SLOT_ID_TO_WAIT_VCP1_FE= 12, +} VCP_INTERNAL_WAIT_SLOT_ID; +typedef enum +{ + VCP_INTERNAL_WAIT_FE_BE_FLAG_VCP_FE = 0, + VCP_INTERNAL_WAIT_FE_BE_FLAG_VCP_BE = 1, +} VCP_INTERNAL_WAIT_FE_BE_FLAG; +typedef enum +{ + VCP_QUERY_DUMP_IRQ_NOP = 0, + VCP_QUERY_DUMP_IRQ_INTERRUPT = 1, +} VCP_QUERY_DUMP_IRQ; +typedef enum +{ + VCP_QUERY_DUMP_DATA_TYPE_SIGNATURE = 0, + VCP_QUERY_DUMP_DATA_TYPE_COUNTER = 1, + VCP_QUERY_DUMP_DATA_TYPE_OTHERS = 2, +} VCP_QUERY_DUMP_DATA_TYPE; +typedef enum +{ + VCP_QUERY_DUMP_BLOCK_ID_VCP_FE = 0, + VCP_QUERY_DUMP_BLOCK_ID_VCP_BE = 1, +} VCP_QUERY_DUMP_BLOCK_ID; +typedef enum +{ + VCP_SET_REGISTER_SHORT_SET_WHOLE_BYTE_SET_NIBBLE_MASK= 0, + + VCP_SET_REGISTER_SHORT_SET_WHOLE_BYTE_SET_WHOLE_BYTE= 1, + +} VCP_SET_REGISTER_SHORT_SET_WHOLE_BYTE; +typedef enum +{ + VCP_KICKOFF_KICKOFF_MODE_START = 0, + + VCP_KICKOFF_KICKOFF_MODE_EXECUTE = 1, +} VCP_KICKOFF_KICKOFF_MODE; +typedef enum +{ + VCP_FENCE_IRQ_NOP = 0, + VCP_FENCE_IRQ_INTERRUPT = 1, + VCP_FENCE_IRQ_INTERRUPT_GPU = 2, + + + + +} VCP_FENCE_IRQ; +typedef enum +{ + VCP_FENCE_FENCE_TYPE_INTERNAL = 0, + VCP_FENCE_FENCE_TYPE_EXTERNAL32 = 2, + VCP_FENCE_FENCE_TYPE_EXTERNAL64 = 3, + + +} VCP_FENCE_FENCE_TYPE; +typedef enum +{ + VCP_FENCE_SLOT_ID_INTERNAL_FENCE_VCP0_BE= 8, + VCP_FENCE_SLOT_ID_INTERNAL_FENCE_VCP0_FE= 9, + VCP_FENCE_SLOT_ID_INTERNAL_FENCE_VCP1_BE= 11, + VCP_FENCE_SLOT_ID_INTERNAL_FENCE_VCP1_FE= 12, +} VCP_FENCE_SLOT_ID; +typedef enum +{ + VCP_FENCE_FENCE_UPDATE_MODE_COPY = 0, + VCP_FENCE_FENCE_UPDATE_MODE_OR = 1, +} VCP_FENCE_FENCE_UPDATE_MODE; +typedef enum +{ + VCP_FENCE_RB_TYPE_3DFE = 0, + VCP_FENCE_RB_TYPE_3DBE = 1, + VCP_FENCE_RB_TYPE_CSL = 2, + VCP_FENCE_RB_TYPE_CSH = 3, +} VCP_FENCE_RB_TYPE; +typedef enum +{ + VCP_FENCE_BLOCK_ID_VCP_FE = 0, + VCP_FENCE_BLOCK_ID_VCP_BE = 1, +} VCP_FENCE_BLOCK_ID; +typedef enum +{ + VCP_AES_MODE_NONE = 0, + VCP_AES_MODE_XOR = 1, + VCP_AES_MODE_AES_CTR = 2, + VCP_AES_MODE_CIPHER = 3, +} VCP_AES_MODE; + + + + + +typedef struct _Cmd_Vcp_Skip +{ + unsigned int Dwc : 22; + unsigned int Reserved : 2; + unsigned int Block_Id : 4; + unsigned int Major_Opcode : 4; +} Cmd_Vcp_Skip; + +typedef struct _Cmd_Vcp_Set_Data_Buf +{ + unsigned int Dwc : 4; + unsigned int Reset_Buf_Base_En : 1; + unsigned int Reserved1 : 1; + unsigned int Bandwidth_Limit_En : 1; + unsigned int Data_Exch_Type : 1; + unsigned int Reserved2 : 16; + unsigned int Block_Id : 4; + unsigned int Major_Opcode : 4; +} Cmd_Vcp_Set_Data_Buf; + + + typedef struct _Cmd_Vcp_Buf_Base_Addr_L32 + { + unsigned int Reserved : 5; + unsigned int Buf_Base_L : 27; + } Cmd_Vcp_Buf_Base_Addr_L32; + typedef struct _Cmd_Vcp_Buf_Base_Addr_H32 + { + unsigned int Address_H8 : 8; + unsigned int Bl_Slot_Index : 18; + unsigned int Reserved : 6; + } Cmd_Vcp_Buf_Base_Addr_H32; + typedef struct _Cmd_Vcp_Buf_Size + { + unsigned int Reserved : 5; + unsigned int Buf_Size : 27; + } Cmd_Vcp_Buf_Size; + typedef struct _Cmd_Vcp_Bandwidth_Size + { + unsigned int Reserved : 5; + unsigned int Bandwdith_Size : 27; + } Cmd_Vcp_Bandwidth_Size; + + + + +typedef struct _Cmd_Vcp_Internal_Wait +{ + unsigned int Ref_Value : 16; + unsigned int Wait_Mode : 2; + + + + unsigned int Method : 1; + unsigned int Station_Id : 3; + unsigned int Slot_Id : 5; + + unsigned int Fe_Be_Flag : 1; + unsigned int Major_Opcode : 4; +} Cmd_Vcp_Internal_Wait; + + + typedef struct _Cmd_Vcp_Internal_Wait_Dword1 + { + unsigned int Event_Flag_Idx1 : 16; + + + + unsigned int Event_Flag_Idx2 : 16; + } Cmd_Vcp_Internal_Wait_Dword1; + + + + +typedef struct _Cmd_Vcp_Query_Dump +{ + unsigned int Dwc : 13; + unsigned int Irq : 1; + unsigned int Data_Type : 2; + unsigned int Reg_Offset : 8; + unsigned int Block_Id : 4; + unsigned int Major_Opcode : 4; + +} Cmd_Vcp_Query_Dump; + + + typedef struct _Cmd_Vcp_Query_Dump_Address_Dword_L32 + + { + unsigned int Reserved : 2; + unsigned int Address_L : 30; + } Cmd_Vcp_Query_Dump_Address_Dword_L32; + typedef struct _Cmd_Vcp_Query_Dump_Address_Dword_H32 + + { + unsigned int Address_H8 : 8; + unsigned int Bl_Slot_Index : 18; + unsigned int Reserved : 6; + } Cmd_Vcp_Query_Dump_Address_Dword_H32; + + + + +typedef struct _Cmd_Vcp_Set_Register +{ + unsigned int Dwc : 7; + + unsigned int Reserved : 9; + unsigned int Start_Offset : 8; + unsigned int Block_Id : 4; + unsigned int Major_Opcode : 4; +} Cmd_Vcp_Set_Register; + + + typedef struct _Cmd_Vcp_Set_Register_Value_Dword + + { + unsigned int Reg_Val : 32; + } Cmd_Vcp_Set_Register_Value_Dword; + + + + +typedef struct _Cmd_Vcp_Set_Register_Short +{ + unsigned int Register_Value : 8; + + + + unsigned int Nibble_Mask : 4; + unsigned int Set_Whole_Byte : 1; + unsigned int Nibble_Offset : 3; + unsigned int Reserved : 8; + unsigned int Block_Id : 4; + unsigned int Major_Opcode : 4; +} Cmd_Vcp_Set_Register_Short; + + + typedef struct _Cmd_Vcp_Set_Register_Short_Offset_Dword + + { + unsigned int Register_Offset : 13; + unsigned int Reserved : 19; + } Cmd_Vcp_Set_Register_Short_Offset_Dword; + + + + +typedef struct _Cmd_Vcp_Kickoff +{ + unsigned int Dwc : 4; + unsigned int Kickoff_Mode : 1; + unsigned int Set_Dma_Flag : 1; + unsigned int Sub_Frame_End : 1; + unsigned int Secure_Video : 1; + unsigned int Slice_Group_Idx : 2; + unsigned int Frame_Idx : 6; + unsigned int Sequence_Idx : 7; + unsigned int Stop_Reset_Enable : 1; + unsigned int Block_Id : 4; + unsigned int Major_Opcode : 4; +} Cmd_Vcp_Kickoff; + + + typedef struct _Cmd_Vcp_Data_Address_L32 + { + unsigned int Address_L : 32; + } Cmd_Vcp_Data_Address_L32; + typedef struct _Cmd_Vcp_Data_Address_H32 + { + unsigned int Address_H8 : 8; + unsigned int Bl_Slot_Index : 18; + unsigned int Reserved : 6; + } Cmd_Vcp_Data_Address_H32; + typedef struct _Cmd_Vcp_Output_Address_L32 + { + unsigned int Address_L : 32; + + } Cmd_Vcp_Output_Address_L32; + typedef struct _Cmd_Vcp_Output_Address_H32 + { + unsigned int Address_H8 : 8; + unsigned int Bl_Slot_Index : 18; + unsigned int Reserved : 6; + } Cmd_Vcp_Output_Address_H32; + typedef struct _Cmd_Vcp_Pc_L32 + { + unsigned int Pc_Value : 24; + + unsigned int Reserved : 8; + } Cmd_Vcp_Pc_L32; + typedef struct _Cmd_Vcp_Pc_H32 + { + unsigned int Address_H8 : 8; + unsigned int Bl_Slot_Index : 18; + unsigned int Reserved : 6; + } Cmd_Vcp_Pc_H32; + typedef struct _Cmd_Vcp_Top_Mvd_Surf_L32 + { + unsigned int Address_L : 32; + + } Cmd_Vcp_Top_Mvd_Surf_L32; + typedef struct _Cmd_Vcp_Top_Mvd_Surf_H32 + { + unsigned int Address_H8 : 8; + unsigned int Bl_Slot_Index : 18; + unsigned int Reserved : 6; + } Cmd_Vcp_Top_Mvd_Surf_H32; + + + + +typedef struct _Cmd_Vcp_Fence +{ + unsigned int Dwc : 3; + + unsigned int Irq : 2; + unsigned int Fence_Type : 2; + unsigned int Slot_Id : 5; + unsigned int Reserved : 1; + unsigned int Fence_Update_Mode : 1; + unsigned int Reserved1 : 8; + unsigned int Rb_Type : 2; + + unsigned int Block_Id : 4; + + unsigned int Major_Opcode : 4; + +} Cmd_Vcp_Fence; + + + typedef struct _Cmd_Vcp_Fence_Internal_Dword1 + { + unsigned int Update_Value : 16; + unsigned int Slice_Mask : 16; + + + + } Cmd_Vcp_Fence_Internal_Dword1; + typedef struct _Cmd_Vcp_External_Fence_Command_Dword0 + + + { + unsigned int External_Addr_Low32 : 32; + } Cmd_Vcp_External_Fence_Command_Dword0; + typedef struct _Cmd_Vcp_External_Fence_Command_Dword1 + + + { + unsigned int External_Addr_High8 : 8; + unsigned int Reserved : 23; + unsigned int Fence_Update_Timing : 1; + + } Cmd_Vcp_External_Fence_Command_Dword1; + typedef struct _Cmd_Vcp_External_Fence_Command_Dword2 + + + { + unsigned int External_Data1 : 32; + } Cmd_Vcp_External_Fence_Command_Dword2; + typedef struct _Cmd_Vcp_External_Fence_Command_Dword3 + + + { + unsigned int External_Data2 : 32; + } Cmd_Vcp_External_Fence_Command_Dword3; + + + + +typedef struct _Cmd_Vcp_Indicator +{ + unsigned int Dwc : 3; + unsigned int Reserved : 10; + unsigned int Process_Id : 4; + unsigned int Reserved1 : 7; + unsigned int Block_Id : 4; + unsigned int Major_Opcode : 4; +} Cmd_Vcp_Indicator; + +typedef struct _Cmd_Vcp_Autoclear +{ + unsigned int Dwc : 3; + unsigned int Counter : 17; + + unsigned int Reserved : 4; + unsigned int Block_Id : 4; + unsigned int Major_Opcode : 4; +} Cmd_Vcp_Autoclear; + + + typedef struct _Cmd_Vcp_Autoclear_Dword0 + { + unsigned int Reserved : 5; + unsigned int Start_Address_L : 27; + + } Cmd_Vcp_Autoclear_Dword0; + typedef struct _Cmd_Vcp_Autoclear_Dword1 + { + unsigned int Address_H8 : 8; + unsigned int Bl_Slot_Index : 18; + + unsigned int Reserved : 6; + } Cmd_Vcp_Autoclear_Dword1; + typedef struct _Cmd_Vcp_Autoclear_Dword2 + { + unsigned int Reserved : 24; + unsigned int Clear_Value1 : 4; + unsigned int Clear_Value0 : 4; + } Cmd_Vcp_Autoclear_Dword2; + typedef struct _Cmd_Vcp_Autoclear_Dword3 + { + unsigned int Clear_Mask0 : 32; + + + + + + } Cmd_Vcp_Autoclear_Dword3; + typedef struct _Cmd_Vcp_Autoclear_Dword4 + { + unsigned int Clear_Mask1 : 32; + + + + + + } Cmd_Vcp_Autoclear_Dword4; + typedef struct _Cmd_Vcp_Autoclear_Dword5 + { + unsigned int Clear_Mask2 : 32; + + + + + + } Cmd_Vcp_Autoclear_Dword5; + typedef struct _Cmd_Vcp_Autoclear_Dword6 + { + unsigned int Clear_Mask3 : 32; + + + + + + } Cmd_Vcp_Autoclear_Dword6; + + + + +typedef struct _Cmd_Vcp_Init +{ + unsigned int Dbg_Shader_Load_En : 1; + unsigned int Cmodel_Mem_Check_En : 1; + + unsigned int Hw_Cross_Mem_Check_En : 1; + unsigned int Codec_Type : 8; + unsigned int Reserved : 2; + unsigned int Flush_Blc : 1; + unsigned int Invalidate_Blc : 1; + unsigned int Timeout_Reset : 1; + unsigned int Vcp_Reset : 1; + unsigned int Flush : 1; + unsigned int Invalidate_Ic : 1; + unsigned int Invalidate_Dc : 1; + unsigned int Dwc : 4; + unsigned int Block_Id : 4; + unsigned int Major_Opcode : 4; +} Cmd_Vcp_Init; + + + typedef struct _Cmd_Vcp_Blc_Surface_Addr_L32 + { + unsigned int Surf_Addr_L : 32; + } Cmd_Vcp_Blc_Surface_Addr_L32; + typedef struct _Cmd_Vcp_Blc_Surface_Addr_H32 + { + unsigned int Address_H8 : 8; + unsigned int Bl_Slot_Index : 18; + unsigned int Reserved : 6; + } Cmd_Vcp_Blc_Surface_Addr_H32; + typedef struct _Cmd_Vcp_Blc_Surface_Size + { + unsigned int Byte_Size : 32; + } Cmd_Vcp_Blc_Surface_Size; + typedef struct _Cmd_Vcp_Timeout_Reset_Value + { + unsigned int Cycle_Count : 32; + } Cmd_Vcp_Timeout_Reset_Value; + + + + +typedef struct _Cmd_Vcp_Aes +{ + unsigned int Mode : 2; + unsigned int Remove003_En : 1; + unsigned int Remove002_En : 1; + + unsigned int To_Memory : 1; + unsigned int Secure_Video : 1; + unsigned int Reserved : 15; + + unsigned int Dwc : 3; + + unsigned int Block_Id : 4; + unsigned int Major_Opcode : 4; +} Cmd_Vcp_Aes; + + + typedef struct _Cmd_Vcp_Aes_Source_Addr_L32 + { + unsigned int Start_Byte : 5; + unsigned int Aes_Source_Addr_L : 27; + } Cmd_Vcp_Aes_Source_Addr_L32; + typedef struct _Cmd_Vcp_Aes_Source_Addr_H32 + { + unsigned int Address_H8 : 8; + unsigned int Bl_Slot_Index : 18; + unsigned int Reserved : 6; + } Cmd_Vcp_Aes_Source_Addr_H32; + typedef struct _Cmd_Vcp_Aes_Size + { + unsigned int Byte_Size : 32; + } Cmd_Vcp_Aes_Size; + typedef struct _Cmd_Vcp_Aes_Dst_Addr_L32 + { + unsigned int Start_Byte : 5; + unsigned int Aes_Dst_Addr_L : 27; + } Cmd_Vcp_Aes_Dst_Addr_L32; + typedef struct _Cmd_Vcp_Aes_Dst_Addr_H32 + { + unsigned int Address_H8 : 8; + unsigned int Bl_Slot_Index : 18; + unsigned int Reserved : 6; + } Cmd_Vcp_Aes_Dst_Addr_H32; + +typedef union Vcp_Decouple_Opcodes_cmds +{ + unsigned int uint ; + Cmd_Vcp_Skip cmd_Vcp_Skip; + Cmd_Vcp_Set_Data_Buf cmd_Vcp_Set_Data_Buf; + Cmd_Vcp_Internal_Wait cmd_Vcp_Internal_Wait; + Cmd_Vcp_Query_Dump cmd_Vcp_Query_Dump; + Cmd_Vcp_Set_Register cmd_Vcp_Set_Register; + Cmd_Vcp_Set_Register_Short cmd_Vcp_Set_Register_Short; + Cmd_Vcp_Kickoff cmd_Vcp_Kickoff; + Cmd_Vcp_Fence cmd_Vcp_Fence; + Cmd_Vcp_Indicator cmd_Vcp_Indicator; + Cmd_Vcp_Autoclear cmd_Vcp_Autoclear; + Cmd_Vcp_Init cmd_Vcp_Init; + Cmd_Vcp_Aes cmd_Vcp_Aes; +}Vcp_Decouple_Opcodes_cmd; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/Vcp_Registers.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/Vcp_Registers.h new file mode 100644 index 0000000000000..c43dffd16b379 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/Vcp_Registers.h @@ -0,0 +1,2421 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _VCP_REGISTERS_H +#define _VCP_REGISTERS_H + +#ifndef VCP_BLOCKBASE_INF + #define VCP_BLOCKBASE_INF + #define BLOCK_VCP_VERSION 1 + #define BLOCK_VCP_TIMESTAMP "2019/1/16 11:01:18" + #define VCP_BLOCK 0xC + #define VCP_REG_LIMIT 0x10 +#endif + + +#define Reg_Vcp_Mmio_Regs_Offset 0x0 +#define Reg_Fe_Ila_Counter_Video_Offset 0x12 +#define Reg_Fe_Signature_Video_Offset 0x16 +#define Reg_Fe_Framelvl_Memcount_Offset 0x1A +#define Reg_Fe_Framelvl_Perf_Offset 0x1F +#define Reg_Fe_Framelvl_Cmp_Memcount_Offset 0x28 +#define Reg_Fe_Qeury_Reg_End_Offset 0x2A +#define Reg_Be_Ila_Counter_Video_Offset 0x12 +#define Reg_Be_Signature_Video_Offset 0x19 +#define Reg_Be_S3vd_Enc_Avg_Dist_Offset 0x2D +#define Reg_Be_Framelvl_Memcount_Offset 0x2E +#define Reg_Be_Framelvl_Perf_Offset 0x33 +#define Reg_Be_Framelvl_Cmp_Memcount_Offset 0x5B +#define Reg_Be_Framelvl_Perf_New_Added_Offset 0x5D +#define Reg_Be_Qeury_Reg_End_Offset 0x7C +#define Reg_Vcp_Set_Regs_Offset 0x0 + + + + + + + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Risc_Act_Cnt_Fe; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Risc_Idle_Cnt_Fe; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Risc_First_Cmd_Fe; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Risc_Act_Cnt_Be; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Risc_Idle_Cnt_Be; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Risc_First_Cmd_Be; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Risc_Debug_Bus_Be; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Misc_Init; + +typedef union +{ + struct + { + unsigned int Wroutofrange : 1; + unsigned int Dont_Kickoff_Be_Flag : 1; + + unsigned int Reserved : 30; + } reg; + unsigned int uint; +} Reg_Mmio_S3vd_Status; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Me_Gpuw_Cpur_Cnt; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Iqtdbk_Cpuw_Gpur_Cnt; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Vp8enc_Mxu_En; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Vle_Debug_Bus_Be_0t13; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Jpg_Debug_Bus_Fe_0t1; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Reserved_Space_Frm43; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Dcp_Debug_Bus_0t5; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Reserved_Space_Frm56; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Dbg_Intr_Pc; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Vcp_Sig_Cnt_En; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Vld_Debug_Bus_Fe_8t13; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Jpg_Debug_Bus_Be_0t1; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Prd_Debug_Bus_18t26; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Avs2_Tu_Debug_Bus_0t1; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Avs2_Qtree_Debug_Bus; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Avs2_Cunit_Debug_Bus_0t1; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Enc_Debug_Bus_19t26; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Reserved_Space_Frm286; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Cal_Debug_Bus_0t2; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Vcp_Signature_Out; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Vcp_Debug_Bus_Stall; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Vcptop_Debug_Bus; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Enc_Debug_Bus_0t18; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Prd_Debug_Bus_0t17; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Risc_Debug_Bus_Fe_0t18; + +typedef union +{ + struct + { + unsigned int Errrecvoerflag : 1; + unsigned int Errframeidx : 31; + } reg; + unsigned int uint; +} Reg_Mmio_Err_Interrupt_Fe_Frame; + +typedef union +{ + struct + { + unsigned int Errblkstart : 16; + unsigned int Errblknum : 16; + } reg; + unsigned int uint; +} Reg_Mmio_Err_Interrupt_Fe_Blk_Addr; + +typedef union +{ + struct + { + unsigned int Errtag : 8; + unsigned int Errlvl : 3; + unsigned int Bfirsterrfe : 1; + unsigned int Reservedfe : 20; + } reg; + unsigned int uint; +} Reg_Mmio_Err_Interrupt_Fe_Info; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Err_Interrupt_Fe_Rsv; + +typedef union +{ + struct + { + unsigned int Reserved : 1; + unsigned int Errframeidx : 31; + } reg; + unsigned int uint; +} Reg_Mmio_Err_Interrupt_Be_Frame; + +typedef union +{ + struct + { + unsigned int Errblkstart : 16; + unsigned int Reserved : 16; + } reg; + unsigned int uint; +} Reg_Mmio_Err_Interrupt_Be_Blk_Addr; + +typedef union +{ + struct + { + unsigned int Errtag : 8; + unsigned int Errlvl : 3; + unsigned int Bfirsterrbe : 1; + unsigned int Reservedbe : 20; + } reg; + unsigned int uint; +} Reg_Mmio_Err_Interrupt_Be_Info; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Err_Interrupt_Be_Rsv; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Reserved_Space_Frm503; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Vld_Debug_Bus_Fe_0t7; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Mmio_Aes_Debug_Bus_0t1; + +typedef struct _Group_Vcp_Mmio_Regs +{ + Reg_Mmio_Risc_Act_Cnt_Fe reg_Mmio_Risc_Act_Cnt_Fe; + Reg_Mmio_Risc_Idle_Cnt_Fe reg_Mmio_Risc_Idle_Cnt_Fe; + Reg_Mmio_Risc_First_Cmd_Fe reg_Mmio_Risc_First_Cmd_Fe; + Reg_Mmio_Risc_Act_Cnt_Be reg_Mmio_Risc_Act_Cnt_Be; + Reg_Mmio_Risc_Idle_Cnt_Be reg_Mmio_Risc_Idle_Cnt_Be; + Reg_Mmio_Risc_First_Cmd_Be reg_Mmio_Risc_First_Cmd_Be; + Reg_Mmio_Risc_Debug_Bus_Be reg_Mmio_Risc_Debug_Bus_Be[18]; + Reg_Mmio_Misc_Init reg_Mmio_Misc_Init; + Reg_Mmio_S3vd_Status reg_Mmio_S3vd_Status; + Reg_Mmio_Me_Gpuw_Cpur_Cnt reg_Mmio_Me_Gpuw_Cpur_Cnt; + Reg_Mmio_Iqtdbk_Cpuw_Gpur_Cnt reg_Mmio_Iqtdbk_Cpuw_Gpur_Cnt; + Reg_Mmio_Vp8enc_Mxu_En reg_Mmio_Vp8enc_Mxu_En; + Reg_Mmio_Vle_Debug_Bus_Be_0t13 reg_Mmio_Vle_Debug_Bus_Be_0t13[11]; + Reg_Mmio_Jpg_Debug_Bus_Fe_0t1 reg_Mmio_Jpg_Debug_Bus_Fe_0t1[2]; + Reg_Mmio_Reserved_Space_Frm43 reg_Mmio_Reserved_Space_Frm43[8]; + Reg_Mmio_Dcp_Debug_Bus_0t5 reg_Mmio_Dcp_Debug_Bus_0t5[6]; + Reg_Mmio_Reserved_Space_Frm56 reg_Mmio_Reserved_Space_Frm56[200]; + Reg_Mmio_Dbg_Intr_Pc reg_Mmio_Dbg_Intr_Pc; + Reg_Mmio_Vcp_Sig_Cnt_En reg_Mmio_Vcp_Sig_Cnt_En; + Reg_Mmio_Vld_Debug_Bus_Fe_8t13 reg_Mmio_Vld_Debug_Bus_Fe_8t13[5]; + Reg_Mmio_Jpg_Debug_Bus_Be_0t1 reg_Mmio_Jpg_Debug_Bus_Be_0t1[2]; + Reg_Mmio_Prd_Debug_Bus_18t26 reg_Mmio_Prd_Debug_Bus_18t26[9]; + Reg_Mmio_Avs2_Tu_Debug_Bus_0t1 reg_Mmio_Avs2_Tu_Debug_Bus_0t1[2]; + Reg_Mmio_Avs2_Qtree_Debug_Bus reg_Mmio_Avs2_Qtree_Debug_Bus; + Reg_Mmio_Avs2_Cunit_Debug_Bus_0t1 + reg_Mmio_Avs2_Cunit_Debug_Bus_0t1[2]; + Reg_Mmio_Enc_Debug_Bus_19t26 reg_Mmio_Enc_Debug_Bus_19t26[7]; + Reg_Mmio_Reserved_Space_Frm286 reg_Mmio_Reserved_Space_Frm286[150]; + Reg_Mmio_Cal_Debug_Bus_0t2 reg_Mmio_Cal_Debug_Bus_0t2[3]; + Reg_Mmio_Vcp_Signature_Out reg_Mmio_Vcp_Signature_Out[2]; + Reg_Mmio_Vcp_Debug_Bus_Stall reg_Mmio_Vcp_Debug_Bus_Stall; + Reg_Mmio_Vcptop_Debug_Bus reg_Mmio_Vcptop_Debug_Bus; + Reg_Mmio_Enc_Debug_Bus_0t18 reg_Mmio_Enc_Debug_Bus_0t18[17]; + Reg_Mmio_Prd_Debug_Bus_0t17 reg_Mmio_Prd_Debug_Bus_0t17[17]; + Reg_Mmio_Risc_Debug_Bus_Fe_0t18 reg_Mmio_Risc_Debug_Bus_Fe_0t18[18]; + Reg_Mmio_Err_Interrupt_Fe_Frame reg_Mmio_Err_Interrupt_Fe_Frame; + Reg_Mmio_Err_Interrupt_Fe_Blk_Addr + reg_Mmio_Err_Interrupt_Fe_Blk_Addr; + Reg_Mmio_Err_Interrupt_Fe_Info reg_Mmio_Err_Interrupt_Fe_Info; + Reg_Mmio_Err_Interrupt_Fe_Rsv reg_Mmio_Err_Interrupt_Fe_Rsv; + Reg_Mmio_Err_Interrupt_Be_Frame reg_Mmio_Err_Interrupt_Be_Frame; + Reg_Mmio_Err_Interrupt_Be_Blk_Addr + reg_Mmio_Err_Interrupt_Be_Blk_Addr; + Reg_Mmio_Err_Interrupt_Be_Info reg_Mmio_Err_Interrupt_Be_Info; + Reg_Mmio_Err_Interrupt_Be_Rsv reg_Mmio_Err_Interrupt_Be_Rsv; + Reg_Mmio_Reserved_Space_Frm503 reg_Mmio_Reserved_Space_Frm503; + Reg_Mmio_Vld_Debug_Bus_Fe_0t7 reg_Mmio_Vld_Debug_Bus_Fe_0t7[6]; + Reg_Mmio_Aes_Debug_Bus_0t1 reg_Mmio_Aes_Debug_Bus_0t1[2]; +} Reg_Vcp_Mmio_Regs_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Vcp_Fe_Total_Busy_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Risc_Fe_Total_Stall_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Fe_Write_Backpress_Bymemory_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Vcp_Fe_Total_Backpress_Cycle; + +typedef struct _Group_Fe_Ila_Counter_Video +{ + Reg_S3vd_Vcp_Fe_Total_Busy_Cycle reg_S3vd_Vcp_Fe_Total_Busy_Cycle; + Reg_S3vd_Risc_Fe_Total_Stall_Cycle + reg_S3vd_Risc_Fe_Total_Stall_Cycle; + Reg_S3vd_Fe_Write_Backpress_Bymemory_Cycle + reg_S3vd_Fe_Write_Backpress_Bymemory_Cycle; + Reg_S3vd_Vcp_Fe_Total_Backpress_Cycle + reg_S3vd_Vcp_Fe_Total_Backpress_Cycle; +} Reg_Fe_Ila_Counter_Video_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Aesin_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Aesin_Signature_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Fe_Dma_Write_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Fe_Dma_Write_Signature_High; + +typedef struct _Group_Fe_Signature_Video +{ + Reg_S3vd_Bci_Aesin_Signature_Low reg_S3vd_Bci_Aesin_Signature_Low; + Reg_S3vd_Bci_Aesin_Signature_High + reg_S3vd_Bci_Aesin_Signature_High; + Reg_S3vd_Bci_Fe_Dma_Write_Signature_Low + reg_S3vd_Bci_Fe_Dma_Write_Signature_Low; + Reg_S3vd_Bci_Fe_Dma_Write_Signature_High + reg_S3vd_Bci_Fe_Dma_Write_Signature_High; +} Reg_Fe_Signature_Video_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Fe_Memory_Read_Latency_Count_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Fe_Memory_Read_Latency_Count_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Fe_Total_Memory_Read_Count; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Fe_Total_Memory_Write_Count; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Fe_Dma_Write_Out_Count; + +typedef struct _Group_Fe_Framelvl_Memcount +{ + Reg_S3vd_Fe_Memory_Read_Latency_Count_Low + reg_S3vd_Fe_Memory_Read_Latency_Count_Low; + Reg_S3vd_Fe_Memory_Read_Latency_Count_High + reg_S3vd_Fe_Memory_Read_Latency_Count_High; + Reg_S3vd_Fe_Total_Memory_Read_Count + reg_S3vd_Fe_Total_Memory_Read_Count; + Reg_S3vd_Fe_Total_Memory_Write_Count + reg_S3vd_Fe_Total_Memory_Write_Count; + Reg_S3vd_Fe_Dma_Write_Out_Count reg_S3vd_Fe_Dma_Write_Out_Count; +} Reg_Fe_Framelvl_Memcount_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Risc_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Vld_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Vld_Total_Useful_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Vld_Total_Backpressure_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Vld_Total_Waitmemory_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Nonvldrisc_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Nonvldrisc_Total_Useful_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Nonvldrisc_Total_Backpressure_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Nonvldrisc_Total_Waitmemory_Cycle; + +typedef struct _Group_Fe_Framelvl_Perf +{ + Reg_S3vd_Risc_Total_Cycle reg_S3vd_Risc_Total_Cycle; + Reg_S3vd_Vld_Total_Cycle reg_S3vd_Vld_Total_Cycle; + Reg_S3vd_Vld_Total_Useful_Cycle reg_S3vd_Vld_Total_Useful_Cycle; + Reg_S3vd_Vld_Total_Backpressure_Cycle + reg_S3vd_Vld_Total_Backpressure_Cycle; + Reg_S3vd_Vld_Total_Waitmemory_Cycle + reg_S3vd_Vld_Total_Waitmemory_Cycle; + Reg_S3vd_Nonvldrisc_Total_Cycle reg_S3vd_Nonvldrisc_Total_Cycle; + Reg_S3vd_Nonvldrisc_Total_Useful_Cycle + reg_S3vd_Nonvldrisc_Total_Useful_Cycle; + Reg_S3vd_Nonvldrisc_Total_Backpressure_Cycle + reg_S3vd_Nonvldrisc_Total_Backpressure_Cycle; + Reg_S3vd_Nonvldrisc_Total_Waitmemory_Cycle + reg_S3vd_Nonvldrisc_Total_Waitmemory_Cycle; +} Reg_Fe_Framelvl_Perf_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Fe_Memory_Read_Cmp_Count; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Fe_Memory_Write_Cmp_Count; + +typedef struct _Group_Fe_Framelvl_Cmp_Memcount +{ + Reg_S3vd_Fe_Memory_Read_Cmp_Count + reg_S3vd_Fe_Memory_Read_Cmp_Count; + Reg_S3vd_Fe_Memory_Write_Cmp_Count + reg_S3vd_Fe_Memory_Write_Cmp_Count; +} Reg_Fe_Framelvl_Cmp_Memcount_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Fe_Qeury_Reserved; + +typedef struct _Group_Fe_Qeury_Reg_End +{ + Reg_Fe_Qeury_Reserved reg_Fe_Qeury_Reserved; +} Reg_Fe_Qeury_Reg_End_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Vcp_Be_Total_Busy_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Rsic_Be_Total_Stall_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Write_Backpress_Bymemory_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Vcp_Be_Total_Backpress_Bytb_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Total_Busy_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Wait_Data_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Mxu_Back_Qtm_Cycle; + +typedef struct _Group_Be_Ila_Counter_Video +{ + Reg_S3vd_Vcp_Be_Total_Busy_Cycle reg_S3vd_Vcp_Be_Total_Busy_Cycle; + Reg_S3vd_Rsic_Be_Total_Stall_Cycle + reg_S3vd_Rsic_Be_Total_Stall_Cycle; + Reg_S3vd_Be_Write_Backpress_Bymemory_Cycle + reg_S3vd_Be_Write_Backpress_Bymemory_Cycle; + Reg_S3vd_Vcp_Be_Total_Backpress_Bytb_Cycle + reg_S3vd_Vcp_Be_Total_Backpress_Bytb_Cycle; + Reg_S3vd_Qtm_Total_Busy_Cycle reg_S3vd_Qtm_Total_Busy_Cycle; + Reg_S3vd_Qtm_Wait_Data_Cycle reg_S3vd_Qtm_Wait_Data_Cycle; + Reg_S3vd_Mxu_Back_Qtm_Cycle reg_S3vd_Mxu_Back_Qtm_Cycle; +} Reg_Be_Ila_Counter_Video_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Dec_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Dec_Signature_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Enc_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Enc_Signature_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Cmg0_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Cmg0_Signature_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Cmg1_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Cmg1_Signature_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Tbich0_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Tbich0_Signature_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Tbich1_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Tbich1_Signature_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Sadin_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Sadin_Signature_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Mcfin_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Mcfin_Signature_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Srcimg_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Srcimg_Signature_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Be_Dma_Read_Signature_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Bci_Be_Dma_Read_Signature_High; + +typedef struct _Group_Be_Signature_Video +{ + Reg_S3vd_Bci_Dec_Signature_Low reg_S3vd_Bci_Dec_Signature_Low; + Reg_S3vd_Bci_Dec_Signature_High reg_S3vd_Bci_Dec_Signature_High; + Reg_S3vd_Bci_Enc_Signature_Low reg_S3vd_Bci_Enc_Signature_Low; + Reg_S3vd_Bci_Enc_Signature_High reg_S3vd_Bci_Enc_Signature_High; + Reg_S3vd_Bci_Cmg0_Signature_Low reg_S3vd_Bci_Cmg0_Signature_Low; + Reg_S3vd_Bci_Cmg0_Signature_High reg_S3vd_Bci_Cmg0_Signature_High; + Reg_S3vd_Bci_Cmg1_Signature_Low reg_S3vd_Bci_Cmg1_Signature_Low; + Reg_S3vd_Bci_Cmg1_Signature_High reg_S3vd_Bci_Cmg1_Signature_High; + Reg_S3vd_Bci_Tbich0_Signature_Low + reg_S3vd_Bci_Tbich0_Signature_Low; + Reg_S3vd_Bci_Tbich0_Signature_High + reg_S3vd_Bci_Tbich0_Signature_High; + Reg_S3vd_Bci_Tbich1_Signature_Low + reg_S3vd_Bci_Tbich1_Signature_Low; + Reg_S3vd_Bci_Tbich1_Signature_High + reg_S3vd_Bci_Tbich1_Signature_High; + Reg_S3vd_Bci_Sadin_Signature_Low reg_S3vd_Bci_Sadin_Signature_Low; + Reg_S3vd_Bci_Sadin_Signature_High + reg_S3vd_Bci_Sadin_Signature_High; + Reg_S3vd_Bci_Mcfin_Signature_Low reg_S3vd_Bci_Mcfin_Signature_Low; + Reg_S3vd_Bci_Mcfin_Signature_High + reg_S3vd_Bci_Mcfin_Signature_High; + Reg_S3vd_Bci_Srcimg_Signature_Low + reg_S3vd_Bci_Srcimg_Signature_Low; + Reg_S3vd_Bci_Srcimg_Signature_High + reg_S3vd_Bci_Srcimg_Signature_High; + Reg_S3vd_Bci_Be_Dma_Read_Signature_Low + reg_S3vd_Bci_Be_Dma_Read_Signature_Low; + Reg_S3vd_Bci_Be_Dma_Read_Signature_High + reg_S3vd_Bci_Be_Dma_Read_Signature_High; +} Reg_Be_Signature_Video_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Enc_Avg_Dist; + +typedef struct _Group_Be_S3vd_Enc_Avg_Dist +{ + Reg_S3vd_Enc_Avg_Dist reg_S3vd_Enc_Avg_Dist; +} Reg_Be_S3vd_Enc_Avg_Dist_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Memory_Latency_Count_Low; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Memory_Latency_Count_High; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Total_Memory_Read_Count; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Total_Memory_Write_Count; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Dma_Read_Count; + +typedef struct _Group_Be_Framelvl_Memcount +{ + Reg_S3vd_Be_Memory_Latency_Count_Low + reg_S3vd_Be_Memory_Latency_Count_Low; + Reg_S3vd_Be_Memory_Latency_Count_High + reg_S3vd_Be_Memory_Latency_Count_High; + Reg_S3vd_Be_Total_Memory_Read_Count + reg_S3vd_Be_Total_Memory_Read_Count; + Reg_S3vd_Be_Total_Memory_Write_Count + reg_S3vd_Be_Total_Memory_Write_Count; + Reg_S3vd_Be_Dma_Read_Count reg_S3vd_Be_Dma_Read_Count; +} Reg_Be_Framelvl_Memcount_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Mc_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Mc_Total_Useful_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Mc_Total_Backpressure_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Mc_Total_Waitmemory_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Mc_Total_Waitcmd_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Mcidct_Total_Backpressure_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Mcidct_Total_Waitcmd_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Idct_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Idct_Total_Useful_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Idct_Total_Backpressure_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Idct_Total_Waitmemory_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Idct_Total_Waitcmd_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Dbk_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Dbk_Total_Useful_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Dbk_Total_Backpressure_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Dbk_Total_Waitmemory_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Dbk_Total_Waitcmd_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Dbk_Total_Waitidctmcdata_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Dbk_Total_Waitidctdata_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Qtm_Dbk_Total_Waitmcdata_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Cmg_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Cmg_Total_Useful_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Cmg_Total_Backpressure_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Cmg_Total_Waitcmd_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Cmg_Total_Ch0waitch1_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Cmg_Total_Waitbufferfull_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Prd_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Prd_Total_Useful_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Prd_Vcp_Ch0_Total_Backpressure_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Prd_Vcp_Ch1_Total_Backpressure_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Prd_Total_Waitmemory_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Prd_Total_Waitcmd_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Risc_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Risc_Vle_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Risc_Vle_Useful_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Risc_Blkbymem_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Risc_Vle_Waitformee_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Risc_Nonvle_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Risc_Nonvle_Useful_Cycle; + +typedef struct _Group_Be_Framelvl_Perf +{ + Reg_S3vd_Qtm_Mc_Total_Cycle reg_S3vd_Qtm_Mc_Total_Cycle; + Reg_S3vd_Qtm_Mc_Total_Useful_Cycle + reg_S3vd_Qtm_Mc_Total_Useful_Cycle; + Reg_S3vd_Qtm_Mc_Total_Backpressure_Cycle + reg_S3vd_Qtm_Mc_Total_Backpressure_Cycle; + Reg_S3vd_Qtm_Mc_Total_Waitmemory_Cycle + reg_S3vd_Qtm_Mc_Total_Waitmemory_Cycle; + Reg_S3vd_Qtm_Mc_Total_Waitcmd_Cycle + reg_S3vd_Qtm_Mc_Total_Waitcmd_Cycle; + Reg_S3vd_Qtm_Total_Cycle reg_S3vd_Qtm_Total_Cycle; + Reg_S3vd_Qtm_Mcidct_Total_Backpressure_Cycle + reg_S3vd_Qtm_Mcidct_Total_Backpressure_Cycle; + Reg_S3vd_Qtm_Mcidct_Total_Waitcmd_Cycle + reg_S3vd_Qtm_Mcidct_Total_Waitcmd_Cycle; + Reg_S3vd_Qtm_Idct_Total_Cycle reg_S3vd_Qtm_Idct_Total_Cycle; + Reg_S3vd_Qtm_Idct_Total_Useful_Cycle + reg_S3vd_Qtm_Idct_Total_Useful_Cycle; + Reg_S3vd_Qtm_Idct_Total_Backpressure_Cycle + reg_S3vd_Qtm_Idct_Total_Backpressure_Cycle; + Reg_S3vd_Qtm_Idct_Total_Waitmemory_Cycle + reg_S3vd_Qtm_Idct_Total_Waitmemory_Cycle; + Reg_S3vd_Qtm_Idct_Total_Waitcmd_Cycle + reg_S3vd_Qtm_Idct_Total_Waitcmd_Cycle; + Reg_S3vd_Qtm_Dbk_Total_Cycle reg_S3vd_Qtm_Dbk_Total_Cycle; + Reg_S3vd_Qtm_Dbk_Total_Useful_Cycle + reg_S3vd_Qtm_Dbk_Total_Useful_Cycle; + Reg_S3vd_Qtm_Dbk_Total_Backpressure_Cycle + reg_S3vd_Qtm_Dbk_Total_Backpressure_Cycle; + Reg_S3vd_Qtm_Dbk_Total_Waitmemory_Cycle + reg_S3vd_Qtm_Dbk_Total_Waitmemory_Cycle; + Reg_S3vd_Qtm_Dbk_Total_Waitcmd_Cycle + reg_S3vd_Qtm_Dbk_Total_Waitcmd_Cycle; + Reg_S3vd_Qtm_Dbk_Total_Waitidctmcdata_Cycle + reg_S3vd_Qtm_Dbk_Total_Waitidctmcdata_Cycle; + Reg_S3vd_Qtm_Dbk_Total_Waitidctdata_Cycle + reg_S3vd_Qtm_Dbk_Total_Waitidctdata_Cycle; + Reg_S3vd_Qtm_Dbk_Total_Waitmcdata_Cycle + reg_S3vd_Qtm_Dbk_Total_Waitmcdata_Cycle; + Reg_S3vd_Cmg_Total_Cycle reg_S3vd_Cmg_Total_Cycle; + Reg_S3vd_Cmg_Total_Useful_Cycle reg_S3vd_Cmg_Total_Useful_Cycle; + Reg_S3vd_Cmg_Total_Backpressure_Cycle + reg_S3vd_Cmg_Total_Backpressure_Cycle; + Reg_S3vd_Cmg_Total_Waitcmd_Cycle reg_S3vd_Cmg_Total_Waitcmd_Cycle; + Reg_S3vd_Cmg_Total_Ch0waitch1_Cycle + reg_S3vd_Cmg_Total_Ch0waitch1_Cycle; + Reg_S3vd_Cmg_Total_Waitbufferfull_Cycle + reg_S3vd_Cmg_Total_Waitbufferfull_Cycle; + Reg_S3vd_Prd_Total_Cycle reg_S3vd_Prd_Total_Cycle; + Reg_S3vd_Prd_Total_Useful_Cycle reg_S3vd_Prd_Total_Useful_Cycle; + Reg_S3vd_Prd_Vcp_Ch0_Total_Backpressure_Cycle + reg_S3vd_Prd_Vcp_Ch0_Total_Backpressure_Cycle; + Reg_S3vd_Prd_Vcp_Ch1_Total_Backpressure_Cycle + reg_S3vd_Prd_Vcp_Ch1_Total_Backpressure_Cycle; + Reg_S3vd_Prd_Total_Waitmemory_Cycle + reg_S3vd_Prd_Total_Waitmemory_Cycle; + Reg_S3vd_Prd_Total_Waitcmd_Cycle reg_S3vd_Prd_Total_Waitcmd_Cycle; + Reg_S3vd_Be_Risc_Total_Cycle reg_S3vd_Be_Risc_Total_Cycle; + Reg_S3vd_Be_Risc_Vle_Total_Cycle reg_S3vd_Be_Risc_Vle_Total_Cycle; + Reg_S3vd_Be_Risc_Vle_Useful_Cycle + reg_S3vd_Be_Risc_Vle_Useful_Cycle; + Reg_S3vd_Be_Risc_Blkbymem_Cycle reg_S3vd_Be_Risc_Blkbymem_Cycle; + Reg_S3vd_Be_Risc_Vle_Waitformee_Cycle + reg_S3vd_Be_Risc_Vle_Waitformee_Cycle; + Reg_S3vd_Be_Risc_Nonvle_Total_Cycle + reg_S3vd_Be_Risc_Nonvle_Total_Cycle; + Reg_S3vd_Be_Risc_Nonvle_Useful_Cycle + reg_S3vd_Be_Risc_Nonvle_Useful_Cycle; +} Reg_Be_Framelvl_Perf_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Memory_Read_Cmp_Count; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Memory_Write_Cmp_Count; + +typedef struct _Group_Be_Framelvl_Cmp_Memcount +{ + Reg_S3vd_Be_Memory_Read_Cmp_Count + reg_S3vd_Be_Memory_Read_Cmp_Count; + Reg_S3vd_Be_Memory_Write_Cmp_Count + reg_S3vd_Be_Memory_Write_Cmp_Count; +} Reg_Be_Framelvl_Cmp_Memcount_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Useful_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Idle_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Backpressbycmg_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Backpressbysadin_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Backpressbymcfin_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Intrapredsearch_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Inp_Idle_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Inp_Waitfordata_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Getsearchcenter_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Skiptest_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Coarsesearch_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Finesearch_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Interintrasel_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Frcsearch_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Updatemv_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Encoder_Mc_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Encoder_Mc_Waitfordata_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Encoder_Ftqiqt_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Encoder_Ftqiqt_Waitfordata_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Encoder_Backpressbyvlesram_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Qtm_Sad_Total_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S4vd_Be_Qtm_Sad_Useful_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S5vd_Be_Qtm_Sad_Backpress_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S6vd_Be_Qtm_Sad_Waitformem_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S7vd_Be_Qtm_Sad_Waitcmd_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S8vd_Be_Qtm_Sao_Compensation_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S9vd_Be_Qtm_Sdh_Delta_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Cusplit_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Getmergemv_Cycle; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_S3vd_Be_Mee_Dealwithresi_Cycle; + +typedef struct _Group_Be_Framelvl_Perf_New_Added +{ + Reg_S3vd_Be_Mee_Total_Cycle reg_S3vd_Be_Mee_Total_Cycle; + Reg_S3vd_Be_Mee_Useful_Cycle reg_S3vd_Be_Mee_Useful_Cycle; + Reg_S3vd_Be_Mee_Idle_Cycle reg_S3vd_Be_Mee_Idle_Cycle; + Reg_S3vd_Be_Mee_Backpressbycmg_Cycle + reg_S3vd_Be_Mee_Backpressbycmg_Cycle; + Reg_S3vd_Be_Mee_Backpressbysadin_Cycle + reg_S3vd_Be_Mee_Backpressbysadin_Cycle; + Reg_S3vd_Be_Mee_Backpressbymcfin_Cycle + reg_S3vd_Be_Mee_Backpressbymcfin_Cycle; + Reg_S3vd_Be_Mee_Intrapredsearch_Cycle + reg_S3vd_Be_Mee_Intrapredsearch_Cycle; + Reg_S3vd_Be_Mee_Inp_Idle_Cycle reg_S3vd_Be_Mee_Inp_Idle_Cycle; + Reg_S3vd_Be_Mee_Inp_Waitfordata_Cycle + reg_S3vd_Be_Mee_Inp_Waitfordata_Cycle; + Reg_S3vd_Be_Mee_Getsearchcenter_Cycle + reg_S3vd_Be_Mee_Getsearchcenter_Cycle; + Reg_S3vd_Be_Mee_Skiptest_Cycle reg_S3vd_Be_Mee_Skiptest_Cycle; + Reg_S3vd_Be_Mee_Coarsesearch_Cycle + reg_S3vd_Be_Mee_Coarsesearch_Cycle; + Reg_S3vd_Be_Mee_Finesearch_Cycle reg_S3vd_Be_Mee_Finesearch_Cycle; + Reg_S3vd_Be_Mee_Interintrasel_Cycle + reg_S3vd_Be_Mee_Interintrasel_Cycle; + Reg_S3vd_Be_Mee_Frcsearch_Cycle reg_S3vd_Be_Mee_Frcsearch_Cycle; + Reg_S3vd_Be_Mee_Updatemv_Cycle reg_S3vd_Be_Mee_Updatemv_Cycle; + Reg_S3vd_Be_Encoder_Mc_Total_Cycle + reg_S3vd_Be_Encoder_Mc_Total_Cycle; + Reg_S3vd_Be_Encoder_Mc_Waitfordata_Cycle + reg_S3vd_Be_Encoder_Mc_Waitfordata_Cycle; + Reg_S3vd_Be_Encoder_Ftqiqt_Total_Cycle + reg_S3vd_Be_Encoder_Ftqiqt_Total_Cycle; + Reg_S3vd_Be_Encoder_Ftqiqt_Waitfordata_Cycle + reg_S3vd_Be_Encoder_Ftqiqt_Waitfordata_Cycle; + Reg_S3vd_Be_Encoder_Backpressbyvlesram_Cycle + reg_S3vd_Be_Encoder_Backpressbyvlesram_Cycle; + Reg_S3vd_Be_Qtm_Sad_Total_Cycle reg_S3vd_Be_Qtm_Sad_Total_Cycle; + Reg_S4vd_Be_Qtm_Sad_Useful_Cycle reg_S4vd_Be_Qtm_Sad_Useful_Cycle; + Reg_S5vd_Be_Qtm_Sad_Backpress_Cycle + reg_S5vd_Be_Qtm_Sad_Backpress_Cycle; + Reg_S6vd_Be_Qtm_Sad_Waitformem_Cycle + reg_S6vd_Be_Qtm_Sad_Waitformem_Cycle; + Reg_S7vd_Be_Qtm_Sad_Waitcmd_Cycle + reg_S7vd_Be_Qtm_Sad_Waitcmd_Cycle; + Reg_S8vd_Be_Qtm_Sao_Compensation_Cycle + reg_S8vd_Be_Qtm_Sao_Compensation_Cycle; + Reg_S9vd_Be_Qtm_Sdh_Delta_Cycle reg_S9vd_Be_Qtm_Sdh_Delta_Cycle; + Reg_S3vd_Be_Mee_Cusplit_Cycle reg_S3vd_Be_Mee_Cusplit_Cycle; + Reg_S3vd_Be_Mee_Getmergemv_Cycle reg_S3vd_Be_Mee_Getmergemv_Cycle; + Reg_S3vd_Be_Mee_Dealwithresi_Cycle + reg_S3vd_Be_Mee_Dealwithresi_Cycle; +} Reg_Be_Framelvl_Perf_New_Added_Group; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Be_Qeury_Reserved; + +typedef struct _Group_Be_Qeury_Reg_End +{ + Reg_Be_Qeury_Reserved reg_Be_Qeury_Reserved; +} Reg_Be_Qeury_Reg_End_Group; + +typedef union +{ + struct + { + unsigned int Hang_Wait_Cnt : 24; + unsigned int Error_Detect_Enable : 1; + unsigned int Power_Gating_Enable : 1; + unsigned int Reserved : 2; + unsigned int Swhalt_Enable : 1; + unsigned int Hang_Notran_Reset_En : 1; + unsigned int Sig_Clear_Disable : 1; + unsigned int Hang_Auto_Reset_En : 1; + } reg; + unsigned int uint; +} Reg_Set_Reg_0; + +typedef union +{ + struct + { + unsigned int Sig_Sel : 4; + unsigned int Sig_Mode : 1; + unsigned int Sig_Lock_Dec : 1; + unsigned int Sig_Lock_Enc : 1; + unsigned int Mem_Check_Enable : 1; + unsigned int Sig_Lock_Cnt : 24; + } reg; + unsigned int uint; +} Reg_Set_Reg_1; + +typedef union +{ + struct + { + unsigned int Dec_Sig_Fail_Bk : 1; + unsigned int Enc_Sig_Fail_Bk : 1; + unsigned int Mmio_Nout : 1; + unsigned int Mmio_Qlp : 1; + unsigned int Tile_Swizzle_En : 1; + unsigned int Vcp_Clear_En : 1; + unsigned int Vcp_Int_En : 1; + unsigned int Tb_Int_En : 1; + unsigned int Qtm_Int_En : 1; + unsigned int Hang_Rst_Int_En : 1; + unsigned int Sw_Rst_Int_En : 1; + unsigned int Sw_Rst_Idle_Cnt_En : 1; + unsigned int S3vd_Enc_Clk_Disable : 1; + unsigned int Vcp_Always_Busy : 1; + unsigned int Vp9_Partitionprob_Select + : 1; + unsigned int Reserved1 : 17; + } reg; + unsigned int uint; +} Reg_Set_Reg_2; + +typedef union +{ + struct + { + unsigned int Codec_Type : 8; + unsigned int Reserved : 24; + } reg; + unsigned int uint; +} Reg_Set_Reg_3; + +typedef union +{ + struct + { + unsigned int Baseaddr_L : 32; + } reg; + unsigned int uint; +} Reg_Set_Reg_4; + +typedef union +{ + struct + { + unsigned int Baseaddr_H : 8; + unsigned int Bl_Slot_Idx : 18; + unsigned int Reserved1 : 6; + } reg; + unsigned int uint; +} Reg_Set_Reg_5; + +typedef union +{ + struct + { + unsigned int Rangesize : 32; + } reg; + unsigned int uint; +} Reg_Set_Reg_6; + +typedef union +{ + struct + { + unsigned int Bnewframestart : 1; + unsigned int Udrawid_L : 2; + unsigned int Reserved0 : 4; + unsigned int Udrawid_H : 4; + unsigned int Reserved1 : 21; + } reg; + unsigned int uint; +} Reg_Set_Reg_7; + +typedef union +{ + struct + { + unsigned int Error_Level : 4; + unsigned int Syntax_Max_Value : 28; + } reg; + unsigned int uint; +} Reg_Syntax_Max_Value; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Constant_Key; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Wrap_Ctr; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Content_Key; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Content_Ctr; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Frame_Distortion; + +typedef union +{ + struct + { + unsigned int Count_Mb_Perf_Flag : 1; + unsigned int Reserved : 5; + unsigned int Vld_Mb_Perf_Base_L : 26; + } reg; + unsigned int uint; +} Reg_Set_Mb_Perf_Base_Addr_L; + +typedef union +{ + struct + { + unsigned int Vld_Mb_Perf_Base_H : 8; + unsigned int Bl_Slot_Idx : 18; + unsigned int Reserved1 : 6; + } reg; + unsigned int uint; +} Reg_Set_Mb_Perf_Base_Addr_H; + +typedef union +{ + struct + { + unsigned int Count_Mb_Perf_Flag : 1; + unsigned int Reserved : 31; + } reg; + unsigned int uint; +} Reg_Set_Mb_Perf_Control_Flag; + +typedef union +{ + struct + { + unsigned int Count_Mb_Perf_Flag : 1; + unsigned int Reserved : 5; + unsigned int Vle_Mb_Perf_Base_L : 26; + } reg; + unsigned int uint; +} Reg_Set_Vle_Mb_Perf_Base_Addr_L; + +typedef union +{ + struct + { + unsigned int Vle_Mb_Perf_Base_H : 8; + unsigned int Bl_Slot_Idx : 18; + unsigned int Reserved1 : 6; + } reg; + unsigned int uint; +} Reg_Set_Vle_Mb_Perf_Base_Addr_H; + +typedef union +{ + struct + { + unsigned int Count_Mb_Perf_Flag : 1; + unsigned int Reserved : 5; + unsigned int Encoder_Mb_Perf_Base_L + : 26; + } reg; + unsigned int uint; +} Reg_Set_Encoder_Mb_Perf_Base_Addr_L; + +typedef union +{ + struct + { + unsigned int Encoder_Mb_Perf_Base_H + : 8; + + unsigned int Bl_Slot_Idx : 18; + + unsigned int Reserved1 : 6; + } reg; + unsigned int uint; +} Reg_Set_Encoder_Mb_Perf_Base_Addr_H; + +typedef union +{ + struct + { + unsigned int Count_Mb_Perf_Flag : 1; + unsigned int Reserved : 5; + unsigned int Ftq_Mb_Perf_Base_L : 26; + } reg; + unsigned int uint; +} Reg_Set_Ftq_Mb_Perf_Base_Addr_L; + +typedef union +{ + struct + { + unsigned int Ftq_Mb_Perf_Base_H : 8; + + unsigned int Bl_Slot_Idx : 18; + + unsigned int Reserved1 : 6; + } reg; + unsigned int uint; +} Reg_Set_Ftq_Mb_Perf_Base_Addr_H; + +typedef union +{ + struct + { + unsigned int Ftq_Mb_Perf_Slice_Offset + : 32; + + } reg; + unsigned int uint; +} Reg_Set_Ftq_Mb_Perf_Slice_Offset; + +typedef union +{ + struct + { + unsigned int Enable_Bypass_1cycperbit + : 1; + + unsigned int Enabe_Nonzerolvl_Puttb2cyc + : 1; + + unsigned int Enable_Residual_Coding_Change + : 1; + + unsigned int Enable_Cunit_Intra_Change + : 1; + + unsigned int Enable_Sao_Change : 1; + + unsigned int Enable_Cunit_Change : 1; + + unsigned int Enable_Codingquadtree_Change + : 1; + + unsigned int Reserved : 25; + } reg; + unsigned int uint; +} Reg_Set_Hevc_Perf_Count_Mode; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Set_Regreserv1; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Lambda_Table_Data_Intra; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Lambda_Table_Data_Inter; + +typedef union +{ + struct + { + unsigned int Insert_Dma_Error : 1; + unsigned int Reserved : 7; + unsigned int Error_Interval : 24; + } reg; + unsigned int uint; +} Reg_Dma_Cmd_Fuzzy_Test; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Set_Regreserv2; + +typedef union +{ + struct + { + unsigned int Reserved : 5; + unsigned int Base_Addr_L : 27; + } reg; + unsigned int uint; +} Reg_Be_Bci_Mem_Base_Addr_L; + +typedef union +{ + struct + { + unsigned int Base_Addr_H : 8; + unsigned int Bl_Slot_Idx : 18; + unsigned int Reserved : 6; + } reg; + unsigned int uint; +} Reg_Be_Bci_Mem_Base_Addr_H; + +typedef union +{ + struct + { + unsigned int uint; + } reg; + unsigned int uint; +} Reg_Be_Bci_Mem_Size; + +typedef struct _Group_Vcp_Set_Regs +{ + Reg_Set_Reg_0 reg_Set_Reg_0; + Reg_Set_Reg_1 reg_Set_Reg_1; + Reg_Set_Reg_2 reg_Set_Reg_2; + Reg_Set_Reg_3 reg_Set_Reg_3; + Reg_Set_Reg_4 reg_Set_Reg_4; + Reg_Set_Reg_5 reg_Set_Reg_5; + Reg_Set_Reg_6 reg_Set_Reg_6; + Reg_Set_Reg_7 reg_Set_Reg_7; + Reg_Syntax_Max_Value reg_Syntax_Max_Value[25]; + Reg_Constant_Key reg_Constant_Key[4]; + Reg_Wrap_Ctr reg_Wrap_Ctr[4]; + Reg_Content_Key reg_Content_Key[4]; + Reg_Content_Ctr reg_Content_Ctr[4]; + Reg_Frame_Distortion reg_Frame_Distortion; + Reg_Set_Mb_Perf_Base_Addr_L reg_Set_Mb_Perf_Base_Addr_L; + Reg_Set_Mb_Perf_Base_Addr_H reg_Set_Mb_Perf_Base_Addr_H; + Reg_Set_Mb_Perf_Control_Flag reg_Set_Mb_Perf_Control_Flag; + Reg_Set_Vle_Mb_Perf_Base_Addr_L reg_Set_Vle_Mb_Perf_Base_Addr_L; + Reg_Set_Vle_Mb_Perf_Base_Addr_H reg_Set_Vle_Mb_Perf_Base_Addr_H; + Reg_Set_Encoder_Mb_Perf_Base_Addr_L + reg_Set_Encoder_Mb_Perf_Base_Addr_L; + Reg_Set_Encoder_Mb_Perf_Base_Addr_H + reg_Set_Encoder_Mb_Perf_Base_Addr_H; + Reg_Set_Ftq_Mb_Perf_Base_Addr_L reg_Set_Ftq_Mb_Perf_Base_Addr_L; + Reg_Set_Ftq_Mb_Perf_Base_Addr_H reg_Set_Ftq_Mb_Perf_Base_Addr_H; + Reg_Set_Ftq_Mb_Perf_Slice_Offset reg_Set_Ftq_Mb_Perf_Slice_Offset; + Reg_Set_Hevc_Perf_Count_Mode reg_Set_Hevc_Perf_Count_Mode; + Reg_Set_Regreserv1 reg_Set_Regreserv1[5]; + Reg_Lambda_Table_Data_Intra reg_Lambda_Table_Data_Intra[13]; + Reg_Lambda_Table_Data_Inter reg_Lambda_Table_Data_Inter[13]; + Reg_Dma_Cmd_Fuzzy_Test reg_Dma_Cmd_Fuzzy_Test; + Reg_Set_Regreserv2 reg_Set_Regreserv2[160]; + Reg_Be_Bci_Mem_Base_Addr_L reg_Be_Bci_Mem_Base_Addr_L; + Reg_Be_Bci_Mem_Base_Addr_H reg_Be_Bci_Mem_Base_Addr_H; + Reg_Be_Bci_Mem_Size reg_Be_Bci_Mem_Size; +} Reg_Vcp_Set_Regs_Group; + +typedef struct _Vcp_regs +{ + Reg_Vcp_Mmio_Regs_Group reg_Vcp_Mmio_Regs; + Reg_Fe_Ila_Counter_Video_Group reg_Fe_Ila_Counter_Video; + Reg_Fe_Signature_Video_Group reg_Fe_Signature_Video; + Reg_Fe_Framelvl_Memcount_Group reg_Fe_Framelvl_Memcount; + Reg_Fe_Framelvl_Perf_Group reg_Fe_Framelvl_Perf; + Reg_Fe_Framelvl_Cmp_Memcount_Group + reg_Fe_Framelvl_Cmp_Memcount; + Reg_Fe_Qeury_Reg_End_Group reg_Fe_Qeury_Reg_End; + Reg_Be_Ila_Counter_Video_Group reg_Be_Ila_Counter_Video; + Reg_Be_Signature_Video_Group reg_Be_Signature_Video; + Reg_Be_S3vd_Enc_Avg_Dist_Group reg_Be_S3vd_Enc_Avg_Dist; + Reg_Be_Framelvl_Memcount_Group reg_Be_Framelvl_Memcount; + Reg_Be_Framelvl_Perf_Group reg_Be_Framelvl_Perf; + Reg_Be_Framelvl_Cmp_Memcount_Group + reg_Be_Framelvl_Cmp_Memcount; + Reg_Be_Framelvl_Perf_New_Added_Group + reg_Be_Framelvl_Perf_New_Added; + Reg_Be_Qeury_Reg_End_Group reg_Be_Qeury_Reg_End; + Reg_Vcp_Set_Regs_Group reg_Vcp_Set_Regs; +} Vcp_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/WLS_Registers.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/WLS_Registers.h new file mode 100644 index 0000000000000..d2ecce3c86ee4 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/WLS_Registers.h @@ -0,0 +1,363 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _WLS_REGISTERS_H +#define _WLS_REGISTERS_H + + +#ifndef WLS_FE_BLOCKBASE_INF + #define WLS_FE_BLOCKBASE_INF + #define BLOCK_WLS_FE_VERSION 1 + #define BLOCK_WLS_FE_TIMESTAMP "2018-10-12 10:15:13" + #define WLS_FE_BLOCK 0x8 + #define WLS_FE_REG_START 0x0 + #define WLS_FE_REG_END 0x418 + #define WLS_FE_REG_LIMIT 0x418 +#endif + +#ifndef WLS_BE_BLOCKBASE_INF + #define WLS_BE_BLOCKBASE_INF + #define BLOCK_WLS_BE_VERSION 1 + #define BLOCK_WLS_BE_TIMESTAMP "2017-08-31 12:06:11" + #define WLS_BE_BLOCK 0x13 + #define WLS_BE_REG_START 0x0 + #define WLS_BE_REG_END 0x418 + #define WLS_BE_REG_LIMIT 0x418 +#endif + + +#define Reg_Ffc_Ubuf_Golbalconfig_Offset 0x0 +#define Reg_Ffc_Ubuf_3dconfig_Offset 0x1 +#define Reg_Descriptor_Heap_Base_Offset 0x2 +#define Reg_Wls_Reserved0_Offset 0xA +#define Reg_Wls_Reserved1_Offset 0xB +#define Reg_Wls_Reserved2_Offset 0xC +#define Reg_Wls_Reserved3_Offset 0xD +#define Reg_Wls_Reserved4_Offset 0xE +#define Reg_Wls_Reserved5_Offset 0xF +#define Reg_Ffc_Ubuf_Csconfig_Offset 0x10 +#define Reg_Wls_Reserved6_Offset 0x11 +#define Reg_Uav_Group_Offset 0x18 + + +typedef enum +{ + FFC_UBUF_3DCONFIG_D3D_U_SHARP_CACHED_DISABLED= 0, + + + FFC_UBUF_3DCONFIG_D3D_U_SHARP_CACHED_ENABLED= 1, + +} FFC_UBUF_3DCONFIG_D3D_U_SHARP_CACHED; +typedef enum +{ + FFC_UBUF_CSCONFIG_CSL_U_SHARP_CACHED_DISABLED= 0, + + + FFC_UBUF_CSCONFIG_CSL_U_SHARP_CACHED_ENABLED= 1, + +} FFC_UBUF_CSCONFIG_CSL_U_SHARP_CACHED; +typedef enum +{ + FFC_UBUF_CSCONFIG_CSH_U_SHARP_CACHED_DISABLED= 0, + + + FFC_UBUF_CSCONFIG_CSH_U_SHARP_CACHED_ENABLED= 1, + +} FFC_UBUF_CSCONFIG_CSH_U_SHARP_CACHED; +typedef enum +{ + UAV_CTL_U_SHARP_EN_DISABLE = 0, + UAV_CTL_U_SHARP_EN_ENABLE = 1, +} UAV_CTL_U_SHARP_EN; +typedef enum +{ + UAV_CTL_RESOURCE_TYPE_1D_BUFFER = 0, + UAV_CTL_RESOURCE_TYPE_1D_TEXTURE = 1, + UAV_CTL_RESOURCE_TYPE_2D_TEXTURE = 2, + UAV_CTL_RESOURCE_TYPE_3D_TEXTURE = 3, + UAV_CTL_RESOURCE_TYPE_1D_TEXTURE_ARRAY = 5, + UAV_CTL_RESOURCE_TYPE_2D_TEXTURE_ARRAY = 6, + UAV_CTL_RESOURCE_TYPE_STRUCTURED_BUFFER = 9, + UAV_CTL_RESOURCE_TYPE_UNTYPED = 11, +} UAV_CTL_RESOURCE_TYPE; +typedef enum +{ + UAV_CTL_UAV_LAYOUT_HORZ_LINEAR = 0, + + UAV_CTL_UAV_LAYOUT_VERT_TILED = 1, + +} UAV_CTL_UAV_LAYOUT; +typedef enum +{ + UAV_CTL_OUT_OF_BOUND_MODE_DEFAULT = 0, + UAV_CTL_OUT_OF_BOUND_MODE_CLAMP = 1, + + UAV_CTL_OUT_OF_BOUND_MODE_WRAP = 2, +} UAV_CTL_OUT_OF_BOUND_MODE; +typedef enum +{ + UAV_CTL_MIPMAP_EN_DISABLE = 0, + UAV_CTL_MIPMAP_EN_ENABLE = 1, +} UAV_CTL_MIPMAP_EN; +typedef enum +{ + UAV_CTL_L1CACHABLE_DISABLE = 0, + UAV_CTL_L1CACHABLE_ENABLE = 1, +} UAV_CTL_L1CACHABLE; +typedef enum +{ + UAV_CTL_L2CACHABLE_DISABLE = 0, + UAV_CTL_L2CACHABLE_ENABLE = 1, +} UAV_CTL_L2CACHABLE; +typedef enum +{ + UAV_CTL_KKK_INFO_NORMAL_UAV = 0, + UAV_CTL_KKK_INFO_KKK_UAV = 1, +} UAV_CTL_KKK_INFO; + + + + + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U_3d_Base : 5; + + + + unsigned int Reserved : 27; + } reg; +} Reg_Ffc_Ubuf_Golbalconfig; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U_Ps_Base : 5; + + + + unsigned int D3d_U_Sharp_Cached : 1; + unsigned int Reserved : 26; + } reg; +} Reg_Ffc_Ubuf_3dconfig; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Heap_Addr : 32; + } reg; +} Reg_Descriptor_Heap_Base; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Wls_Reserved0; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Wls_Reserved1; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Wls_Reserved2; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Wls_Reserved3; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Wls_Reserved4; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Wls_Reserved5; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U_Csh_Base : 5; + + + + unsigned int Csl_U_Sharp_Cached : 1; + unsigned int Csh_U_Sharp_Cached : 1; + unsigned int Reserved : 25; + } reg; +} Reg_Ffc_Ubuf_Csconfig; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Reserved : 32; + } reg; +} Reg_Wls_Reserved6; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Uav_Base : 32; + } reg; +} Reg_Uav_Base; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Width : 15; + unsigned int Height : 15; + unsigned int Reserved : 2; + } reg; +} Reg_Resource_Size; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Bytestride_Or_Depth : 32; + } reg; +} Reg_Resource_Stride; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int First_Element : 32; + } reg; +} Reg_View_Offset; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Num_Element : 32; + } reg; +} Reg_View_Size; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int U_Sharp_En : 1; + unsigned int Resource_Type : 4; + unsigned int Uav_Layout : 1; + unsigned int Out_Of_Bound_Mode : 2; + unsigned int Format : 9; + unsigned int Mipmap_En : 1; + unsigned int Lod : 4; + unsigned int L1cachable : 1; + unsigned int L2cachable : 1; + unsigned int Kkk_Info : 2; + + unsigned int Range_Type : 6; + } reg; +} Reg_Uav_Ctl; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Bl_Slot_Idx : 18; + unsigned int Reserved : 14; + } reg; +} Reg_Bl_Slot_Idx; + +typedef union +{ + unsigned int uint; + struct + { + unsigned int Continuous_Optimize : 1; + + unsigned int Reserved : 31; + } reg; +} Reg_Wls_Config; + +typedef struct _Group_Uav_Group +{ + Reg_Uav_Base reg_Uav_Base; + Reg_Resource_Size reg_Resource_Size; + Reg_Resource_Stride reg_Resource_Stride; + Reg_View_Offset reg_View_Offset; + Reg_View_Size reg_View_Size; + Reg_Uav_Ctl reg_Uav_Ctl; + Reg_Bl_Slot_Idx reg_Bl_Slot_Idx; + Reg_Wls_Config reg_Wls_Config; +} Reg_Uav_Group_Group; + +typedef struct _Wls_Fe_regs +{ + Reg_Ffc_Ubuf_Golbalconfig reg_Ffc_Ubuf_Golbalconfig; + Reg_Ffc_Ubuf_3dconfig reg_Ffc_Ubuf_3dconfig; + Reg_Descriptor_Heap_Base reg_Descriptor_Heap_Base[8]; + Reg_Wls_Reserved0 reg_Wls_Reserved0; + Reg_Wls_Reserved1 reg_Wls_Reserved1; + Reg_Wls_Reserved2 reg_Wls_Reserved2; + Reg_Wls_Reserved3 reg_Wls_Reserved3; + Reg_Wls_Reserved4 reg_Wls_Reserved4; + Reg_Wls_Reserved5 reg_Wls_Reserved5; + Reg_Ffc_Ubuf_Csconfig reg_Ffc_Ubuf_Csconfig; + Reg_Wls_Reserved6 reg_Wls_Reserved6[7]; + Reg_Uav_Group_Group reg_Uav_Group[128]; +} Wls_Fe_regs; + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/registerDef.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/registerDef.h new file mode 100644 index 0000000000000..131360935b23e --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/registerDef.h @@ -0,0 +1,100 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _REGISTER_DEF_H +#define _REGISTER_DEF_H + +#include "BlockID.h" +#include "CSP_GLOBAL_Register.h" +#include "CSP_OPCODE.h" +#include "TASFE_reg.h" +#include "TASBE_reg.h" +#include "EU_FS_reg.h" +#include "EU_CS_reg.h" +#include "IU_reg.h" +#include "SPIN_register.h" +#include "SPOUT_register.h" +#include "EU_PS_reg.h" +#include "FF_registers.h" +#include "TU_Reg.h" +#include "GPCPBE_register.h" +#include "GPCPFE_register.h" +#include "MMU_registers.h" +#include "MXU_registers.h" +#include "Vcp_Registers.h" +#include "WLS_Registers.h" +#include "L2_Register.h" +#include "VCP_OPCODE_DECOUPLE.h" + +#define MMIO_FLAG 0x000FF000 +#define MMIO_MIU_START_ADDRESS 0x00008000 +#define MMIO_MIU_DYNAMIC_FB_START_ADDRESS 0x00008B00 +#define MMIO_VPP_START_ADDRESS 0x0000B000 +#define MMIO_CSP_START_ADDRESS 0x00030000 +#define MMIO_MMU_START_ADDRESS 0x00050000 +#define MMIO_MXU_START_ADDRESS 0x00049000 +#define MMIO_VCP0_START_ADDRESS 0x0004C000 +#define MMIO_VCP1_START_ADDRESS 0x0004A000 + + +#define MMIO_EU_START_ADDRESS (MMIO_CSP_START_ADDRESS|(Reg_Eu_Dbg_Cfg_Offset<<2)) +#define MMIO_EU_END_ADDRESS (MMIO_CSP_START_ADDRESS|(CSP_GLOBAL_REG_LIMIT<<2)) + +#define MMIO_PMU_START_ADDRESS (0x00080000) +#define PMU_SW_C3D_PVAL_ADDR_OFFSET (0x50) +#define PMU_SW_C3D_VAL_ADDR_OFFSET (0x34) +#define PMU_SW_PLL_LOCK_ADDR (0x48) + +#define MMIO_MXU_RANGETBL_MASK 0xC00 +#define MMIO_MXU_RANGETBL_VALUE 0x400 + +#define MMIO_MXU_PAGEKEY_START 0x400 +#define MMIO_MXU_PAGEKEY_MASK 0xC00 + +#define MIU_DYNAMIC_FB_ENTRY_SIZE 0x200000 + + +#define FF_ZCLIPMIN_OFFSET 0 +#define FF_ZCLIPMAX_OFFSET 1 + +#define FF_SFRONTFACE_OFFSET 0 +#define FF_SBACKFACE_OFFSET 1 + +#define FF_RT_ADDR_OFFSET 0 +#define FF_RT_DEPTH_OFFSET 1 +#define FF_RT_VIEW_CTRL_OFFSET 3 + +#define FF_RT_DESC_OFFSET 0 +#define FF_RT_FMT_OFFSET 0 +#define FF_RT_SIZE_OFFSET 1 +#define FF_RT_MISC_OFFSET 2 + + +#define FF_BS_BLEND_CTL_OFFSET 6 + +#define FF_RT_CTRL_REG_SIZE (sizeof(Reg_Rt_Ctrl_Group)>>2) +#define FF_RT_ADDR_CTRL_REG_SIZE (sizeof(Reg_Rt_Addr_Ctrl_Group)>>2) +#define FF_RT_DST 0 +#define FF_RT_SRC 1 + +#define FF_16FL_COLOR_OFFSET 0 +#define FF_16FH_COLOR_OFFSET 1 +#define FF_8888_COLOR_OFFSET 2 +#define FF_2101010L_COLOR_OFFSET 3 +#define FF_2101010H_COLOR_OFFSET 4 + +#define FF_FG_COLOR_OFFSET 0 +#define FF_BG_COLOR_OFFSET 1 + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/registercommands.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/registercommands.h new file mode 100644 index 0000000000000..f910263704b06 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/registercommands.h @@ -0,0 +1,1375 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _REGISTERCOMMANDS_H_ +#define _REGISTERCOMMANDS_H_ + +/*********************** + Commands +************************/ +#include "registerDef.h" +#include "surface_format.h" + +#define REG_CHANNEL_MAX_MASK 0xFFFFFFFF + +#define OFFSETOF(s,m) (unsigned long)&(((s *)0)->m) + +#define SLOT_OFFSET_OF_GROUP(Offset, RegGrpClassName, Slot) (Offset + (sizeof(RegGrpClassName) / sizeof(DWORD)) * Slot) +#define REG_OFFSET_OF_GROUP(Offset, RegGrpClassName, Reg, Slot) (Offset + (sizeof(RegGrpClassName) / sizeof(DWORD)) * Slot + OFFSETOF(RegGrpClassName, Reg) / sizeof(DWORD)) + +typedef struct HW_SET_REGISTER_MASK_CMD_E3K +{ + DWORD dwOpCode; + DWORD dwValue; + DWORD dwMask; +}HW_SET_REGISTER_MASK_CMD_E3K; + + +typedef struct +{ + union + { + unsigned int uint; + struct + { + unsigned int Valid : 1; + unsigned int NStable : 1; + unsigned int Snoop : 1; + unsigned int Segment : 1; + unsigned int Addr : 28; + } pte; + }; +}PTE_L1_t; + + +typedef struct +{ + union + { + unsigned int uint; + struct + { + unsigned int Valid : 1; + unsigned int NStable : 1; + unsigned int Snoop : 1; + unsigned int Segment : 1; + unsigned int Addr : 27; + unsigned int LargePage : 1; + } _4k_d; + struct + { + unsigned int Valid : 1; + unsigned int NS : 1; + unsigned int Snoop : 1; + unsigned int Segment : 1; + unsigned int Addr : 27; + unsigned int LargePage : 1; + } _64k_d; + }; +}PTE_L2_t; + + +typedef struct +{ + union + { + unsigned int uint; + struct + { + unsigned int Valid : 1; + unsigned int NS : 1; + unsigned int Snoop : 1; + unsigned int Segment : 1; + unsigned int Addr : 28; + } pte_4k; + struct + { + unsigned int Valid : 1; + unsigned int NS : 1; + unsigned int Snoop : 1; + unsigned int Segment : 1; + unsigned int Resrved0 : 4; + unsigned int Addr : 24; + } pte_64k; + }; +}PTE_L3_t; + +typedef union +{ + struct + { + unsigned int SWRST_0 :1; + unsigned int MIU_SwRst :1; + unsigned int SwRst_3D :1; + unsigned int SwRst_3D1 :1; + unsigned int SwRst_3D2 :1; + unsigned int SwRst_3D3 :1; + unsigned int VPP_SwRst :1; + unsigned int S3VD0_SwRst :1; + unsigned int S3VD1_SwRst :1; + unsigned int mmio_timer_SwRst :1; + unsigned int m0pll_div_SwRst :1; + unsigned int m1pll_div_SwRst :1; + unsigned int m2pll_div_SwRst :1; + unsigned int epll_div_SwRst :1; + unsigned int vpll_div_SwRst :1; + unsigned int Reserved0 :1; + unsigned int IGA1_SwRst :1; + unsigned int IGA2_SwRst :1; + unsigned int IGA3_SwRst :1; + unsigned int IGA4_SwRst :1; + unsigned int DIUREG_SwRst :1; + unsigned int MDI_SwRst :1; + unsigned int SLV_SwRst :1; + unsigned int TLM_SwRst :1; + unsigned int Reserved1 :8; + }; + unsigned int uint; +} Reg_HWReset_E3K; + +typedef union +{ + struct + { + unsigned int Wait : 1; + unsigned int PrintFence : 1; + unsigned int ResetHW : 1; + unsigned int PreHangDump : 1; + unsigned int PostHangDump : 1; + unsigned int PerFBHangDump : 1; + unsigned int DuplicateHang : 1; + unsigned int DuplicateHangPerFB: 1; + unsigned int InternalDumpHW : 1; + unsigned int InternalBlockSubmit: 1; + unsigned int QTDevice : 1; + unsigned int LogMemoryUsage : 1; + unsigned int DumpDebugBus : 1; + unsigned int DumpDebugBusToFile : 1; + unsigned int InternalDumpDebugBus : 1; + unsigned int DmaNum : 6; + unsigned int DumpHangDma : 1; + unsigned int InternalDumpHangDma : 1; + unsigned int Reserved : 9; + }; + unsigned int uint; +} Reg_DebugMode_E3K; + +typedef struct _Hang_Record +{ + struct _info + { + void* DeviceHandle; + unsigned int Fence_Id; + DWORD dwDmaAddress; + DWORD dwDmaSize; + DWORD dwRingbufferAddr; + DWORD dwDMAFlag; + } info[3]; + unsigned int dwCurIndex; +}Hang_Record; + +typedef struct _EngineSatus_e3k +{ + Reg_Block_Busy_Bits_Top Top; + Reg_Block_Busy_Bits_Gpc0_0 Gpc0_0; + Reg_Block_Busy_Bits_Gpc0_1 Gpc0_1; + Reg_Block_Busy_Bits_Gpc1_0 Gpc1_0; + Reg_Block_Busy_Bits_Gpc1_1 Gpc1_1; + Reg_Block_Busy_Bits_Gpc2_0 Gpc2_0; + Reg_Block_Busy_Bits_Gpc2_1 Gpc2_1; + Reg_Vcp_Vpp_Block_Busy_Bits ES_VCP_VPP; +} EngineSatus_e3k; + +__inline DWORD SET_REGISTER_FD_E3K(DWORD Block, DWORD Offset, DWORD Dwf) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Set_Register.Major_Opcode = CSP_OPCODE_Set_Register; + Cmd.cmd_Set_Register.Block_Id = Block; + Cmd.cmd_Set_Register.Start_Offset = Offset; + Cmd.cmd_Set_Register.Dwc = Dwf; + + return Cmd.uint; +} + +__inline DWORD SET_REGISTER_MH_E3K(DWORD Block, + DWORD Offset) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Set_Register.Major_Opcode = CSP_OPCODE_Set_Register; + Cmd.cmd_Set_Register.Block_Id = Block; + Cmd.cmd_Set_Register.Start_Offset = Offset; + Cmd.cmd_Set_Register.Addr_En = 0; + Cmd.cmd_Set_Register.Mask_En = 1; + Cmd.cmd_Set_Register.Dwc = 2; + + return Cmd.uint; +} + +__inline DWORD SET_REGISTER_MASK_E3K(DWORD Block, + DWORD Offset, + DWORD RegValue, + DWORD Mask, + DWORD* pCmd) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Set_Register.Major_Opcode = CSP_OPCODE_Set_Register; + Cmd.cmd_Set_Register.Block_Id = Block; + Cmd.cmd_Set_Register.Start_Offset = Offset; + Cmd.cmd_Set_Register.Addr_En = 0; + Cmd.cmd_Set_Register.Mask_En = 1; + Cmd.cmd_Set_Register.Dwc = 2; + + *pCmd++ = Cmd.uint; + *pCmd++ = RegValue; + *pCmd++ = Mask; + + return 3; +} + +__inline DWORD SET_REGISTER_ADDR_E3K(DWORD Block, DWORD Offset,BOOL AddressMode) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Set_Register.Major_Opcode = CSP_OPCODE_Set_Register; + Cmd.cmd_Set_Register.Block_Id = Block; + Cmd.cmd_Set_Register.Start_Offset = Offset; + Cmd.cmd_Set_Register.Addr_En = 1; + Cmd.cmd_Set_Register.Mask_En = 0; + Cmd.cmd_Set_Register.Address_Mode = AddressMode; + Cmd.cmd_Set_Register.Dwc = 2; + + return Cmd.uint; +} + +__inline DWORD SET_REGISTER_ADDR_LOW_E3K(DWORD LowAddress) +{ + Cmd_Set_Register_Addr_Dword1 Cmd = {0}; + + Cmd.Address_Low32 = LowAddress & ~0x3; + + return *(DWORD*)&Cmd; +} + +__inline DWORD SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(DWORD HighAddress, DWORD RegCnt) +{ + Cmd_Set_Register_Addr_Dword2 Cmd = {0}; + + Cmd.Address_High8 = HighAddress; + Cmd.Reg_Cnt = RegCnt; + return *(DWORD*)&Cmd; +} + +__inline DWORD SET_REGISTER_ADDR_HIGH_AND_REGCNT_AND_L2_E3K(DWORD HighAddress, DWORD RegCnt, DWORD L2cacheable) +{ + Cmd_Set_Register_Addr_Dword2 Cmd = {0}; + + Cmd.Address_High8 = HighAddress; + Cmd.Reg_Cnt = RegCnt; + Cmd.L2_Cachable = L2cacheable; + return *(DWORD*)&Cmd; +} + +__inline DWORD SEND_SKIP_E3K(DWORD SkipCount) +{ + Csp_Opcodes_cmd SkipCmd = {0}; + SkipCmd.cmd_Skip.Dwc = (DWORD)(SkipCount - 1); + SkipCmd.cmd_Skip.Major_Opcode = CSP_OPCODE_Skip; + + return SkipCmd.uint; +} + +__inline DWORD SEND_TBR_INDICATOR_COMMAND_E3K(DWORD value) +{ + Csp_Opcodes_cmd indicator = {0}; + + indicator.cmd_Tbr_Indicator.Block_Id = TASBE_BLOCK; + indicator.cmd_Tbr_Indicator.Major_Opcode = CSP_OPCODE_Tbr_Indicator; + indicator.cmd_Tbr_Indicator.Indicator_Info = value; + + return *((DWORD*)&indicator); +} + +__inline DWORD SEND_FFCACHE_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Inv = {0}; + + Inv.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Inv.cmd_Block_Command_Flush.Block_Id = FF_BLOCK; + + Inv.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_ALL_C; + Inv.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_INVALIDATE_CACHE; + Inv.cmd_Block_Command_Flush.Dwc = 0; + + return Inv.uint; +} + +__inline DWORD SEND_UCACHE_3DFE_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Inv = {0}; + + Inv.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Inv.cmd_Block_Command_Flush.Block_Id = WLS_FE_BLOCK; + Inv.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_UAV_C; + Inv.cmd_Block_Command_Flush.Uav_Type = BLOCK_COMMAND_FLUSH_UAV_TYPE_3DFE; + Inv.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_INVALIDATE_CACHE; + Inv.cmd_Block_Command_Flush.Dwc = 0; + + return Inv.uint; +} + +__inline DWORD SEND_UCACHE_3DBE_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Inv = {0}; + + Inv.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Inv.cmd_Block_Command_Flush.Block_Id = WLS_BE_BLOCK; + Inv.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_UAV_C; + Inv.cmd_Block_Command_Flush.Uav_Type = BLOCK_COMMAND_FLUSH_UAV_TYPE_3DBE; + Inv.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_INVALIDATE_CACHE; + Inv.cmd_Block_Command_Flush.Dwc = 0; + + return Inv.uint; +} + +__inline DWORD SEND_UCACHE_CSL_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Inv = {0}; + + Inv.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Inv.cmd_Block_Command_Flush.Block_Id = WLS_FE_BLOCK; + Inv.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_UAV_C; + Inv.cmd_Block_Command_Flush.Uav_Type = BLOCK_COMMAND_FLUSH_UAV_TYPE_CSL; + Inv.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_INVALIDATE_CACHE; + Inv.cmd_Block_Command_Flush.Dwc = 0; + + return Inv.uint; +} + +__inline DWORD SEND_UCACHE_CSH_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Inv = {0}; + + Inv.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Inv.cmd_Block_Command_Flush.Block_Id = WLS_FE_BLOCK; + Inv.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_UAV_C; + Inv.cmd_Block_Command_Flush.Uav_Type = BLOCK_COMMAND_FLUSH_UAV_TYPE_CSH; + Inv.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_INVALIDATE_CACHE; + Inv.cmd_Block_Command_Flush.Dwc = 0; + + return Inv.uint; +} + +__inline DWORD SEND_DCACHE_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Inv = {0}; + + Inv.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Inv.cmd_Block_Command_Flush.Block_Id = FF_BLOCK; + Inv.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_D_C; + Inv.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_INVALIDATE_CACHE; + Inv.cmd_Block_Command_Flush.Dwc = 0; + + return Inv.uint; +} + +__inline DWORD SEND_2D_ONLY_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Inv = {0}; + + Inv.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Inv.cmd_Block_Command_Flush.Block_Id = FF_BLOCK; + Inv.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_2D_ONLY; + Inv.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_INVALIDATE_CACHE; + Inv.cmd_Block_Command_Flush.Dwc = 0; + + return Inv.uint; +} + +__inline DWORD SEND_DEPTH_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Inv = {0}; + + Inv.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Inv.cmd_Block_Command_Flush.Block_Id = FF_BLOCK; + Inv.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_Z_C; + Inv.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_INVALIDATE_CACHE; + Inv.cmd_Block_Command_Flush.Dwc = 0; + + return Inv.uint; +} + +__inline DWORD SEND_STENCIL_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Inv = {0}; + + Inv.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Inv.cmd_Block_Command_Flush.Block_Id = FF_BLOCK; + Inv.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_S_C; + Inv.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_INVALIDATE_CACHE; + Inv.cmd_Block_Command_Flush.Dwc = 0; + + return Inv.uint; +} + +__inline DWORD SEND_FLAGBUFFER_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd FbInvCmd = {0}; + + FbInvCmd.cmd_Block_Command_Mxu.Major_Opcode = CSP_OPCODE_Block_Command_Mxu; + FbInvCmd.cmd_Block_Command_Mxu.Block_Id = MXU_BLOCK; + FbInvCmd.cmd_Block_Command_Mxu.Cmd_Type = BLOCK_COMMAND_MXU_CMD_TYPE_INVALIDATE_CACHE; + FbInvCmd.cmd_Block_Command_Mxu.Dwc = 4; + + return FbInvCmd.uint; +} + +__inline DWORD SEND_GMCACHE_INVALIDATE_COMMAND_E3K(void) +{ + return 0; +} + +__inline DWORD SEND_TUFE_CSL_L1CACHE_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd TexInvCmd = {0}; + + TexInvCmd.cmd_Block_Command_Template.Major_Opcode = CSP_OPCODE_Block_Command_Tu; + TexInvCmd.cmd_Block_Command_Template.Block_Id = TUFE_BLOCK; + TexInvCmd.cmd_Block_Command_Template.Command_Specific_Field = 2; + TexInvCmd.cmd_Block_Command_Template.Type = BLOCK_COMMAND_TU_TYPE_INVALIDATE_L1; + TexInvCmd.cmd_Block_Command_Template.Dwc = 0; + + return TexInvCmd.uint; +} + +__inline DWORD SEND_TUFE_CSH_L1CACHE_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd TexInvCmd = {0}; + + TexInvCmd.cmd_Block_Command_Template.Major_Opcode = CSP_OPCODE_Block_Command_Tu; + TexInvCmd.cmd_Block_Command_Template.Block_Id = TUFE_BLOCK; + TexInvCmd.cmd_Block_Command_Template.Command_Specific_Field = 3; + TexInvCmd.cmd_Block_Command_Template.Type = BLOCK_COMMAND_TU_TYPE_INVALIDATE_L1; + TexInvCmd.cmd_Block_Command_Template.Dwc = 0; + + return TexInvCmd.uint; +} + +__inline DWORD SEND_TUFE_L1CACHE_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd TexInvCmd = {0}; + + TexInvCmd.cmd_Block_Command_Template.Major_Opcode = CSP_OPCODE_Block_Command_Tu; + TexInvCmd.cmd_Block_Command_Template.Block_Id = TUFE_BLOCK; + TexInvCmd.cmd_Block_Command_Template.Command_Specific_Field = 0; + TexInvCmd.cmd_Block_Command_Template.Type = BLOCK_COMMAND_TU_TYPE_INVALIDATE_L1; + TexInvCmd.cmd_Block_Command_Template.Dwc = 0; + + return TexInvCmd.uint; +} + +__inline DWORD SEND_TUBE_L1CACHE_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd TexInvCmd = {0}; + + TexInvCmd.cmd_Block_Command_Template.Major_Opcode = CSP_OPCODE_Block_Command_Tu; + TexInvCmd.cmd_Block_Command_Template.Block_Id = TUBE_BLOCK; + TexInvCmd.cmd_Block_Command_Template.Command_Specific_Field = 1; + TexInvCmd.cmd_Block_Command_Template.Type = BLOCK_COMMAND_TU_TYPE_INVALIDATE_L1; + TexInvCmd.cmd_Block_Command_Template.Dwc = 0; + + return TexInvCmd.uint; +} + +__inline DWORD SEND_FFCACHE_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Flush = {0}; + + Flush.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Flush.cmd_Block_Command_Flush.Block_Id = FF_BLOCK; + + Flush.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_ALL_C; + Flush.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_FLUSH; + Flush.cmd_Block_Command_Flush.Dwc = 0; + + return Flush.uint; +} + +__inline DWORD SEND_DSIGBUF_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd DSigBufFlushCmd = {0}; + + DSigBufFlushCmd.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + DSigBufFlushCmd.cmd_Block_Command_Flush.Block_Id = FF_BLOCK; + DSigBufFlushCmd.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_D_SIG_BUF; + DSigBufFlushCmd.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_TEMPLATE_TYPE_FLUSH; + DSigBufFlushCmd.cmd_Block_Command_Flush.Dwc = 0; + + return DSigBufFlushCmd.uint; +} + +__inline DWORD SEND_UCACHE_3DFE_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Flush = {0}; + + Flush.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Flush.cmd_Block_Command_Flush.Block_Id = WLS_FE_BLOCK; + Flush.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_UAV_C; + Flush.cmd_Block_Command_Flush.Uav_Type = BLOCK_COMMAND_FLUSH_UAV_TYPE_3DFE; + Flush.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_FLUSH; + Flush.cmd_Block_Command_Flush.Dwc = 0; + + return Flush.uint; +} + +__inline DWORD SEND_UCACHE_3DBE_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Flush = {0}; + + Flush.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Flush.cmd_Block_Command_Flush.Block_Id = WLS_BE_BLOCK; + Flush.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_UAV_C; + Flush.cmd_Block_Command_Flush.Uav_Type = BLOCK_COMMAND_FLUSH_UAV_TYPE_3DBE; + Flush.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_FLUSH; + Flush.cmd_Block_Command_Flush.Dwc = 0; + + return Flush.uint; +} + +__inline DWORD SEND_UCACHE_CSL_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Flush = {0}; + + Flush.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Flush.cmd_Block_Command_Flush.Block_Id = WLS_FE_BLOCK; + Flush.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_UAV_C; + Flush.cmd_Block_Command_Flush.Uav_Type = BLOCK_COMMAND_FLUSH_UAV_TYPE_CSL; + Flush.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_FLUSH; + Flush.cmd_Block_Command_Flush.Dwc = 0; + + return Flush.uint; +} + +__inline DWORD SEND_UCACHE_CSH_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Flush = {0}; + + Flush.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Flush.cmd_Block_Command_Flush.Block_Id = WLS_FE_BLOCK; + Flush.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_UAV_C; + Flush.cmd_Block_Command_Flush.Uav_Type = BLOCK_COMMAND_FLUSH_UAV_TYPE_CSH; + Flush.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_FLUSH; + Flush.cmd_Block_Command_Flush.Dwc = 0; + + return Flush.uint; +} + +__inline DWORD SEND_UCACHE_3DL_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Flush = {0}; + + Flush.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Flush.cmd_Block_Command_Flush.Block_Id = WLS_FE_BLOCK; + Flush.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_USHARP_DESC; + Flush.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_FLUSH; + Flush.cmd_Block_Command_Flush.Dwc = 0; + + return Flush.uint; +} + +__inline DWORD SEND_DCACHE_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Flush = {0}; + + Flush.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Flush.cmd_Block_Command_Flush.Block_Id = FF_BLOCK; + Flush.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_D_C; + Flush.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_FLUSH; + Flush.cmd_Block_Command_Flush.Dwc = 0; + + return Flush.uint; +} + +__inline DWORD SEND_2D_ONLY_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Flush = {0}; + + Flush.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Flush.cmd_Block_Command_Flush.Block_Id = FF_BLOCK; + Flush.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_2D_ONLY; + Flush.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_FLUSH; + Flush.cmd_Block_Command_Flush.Dwc = 0; + + return Flush.uint; +} + +__inline DWORD SEND_DEPTH_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Flush = {0}; + + Flush.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Flush.cmd_Block_Command_Flush.Block_Id = FF_BLOCK; + Flush.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_Z_C; + Flush.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_FLUSH; + Flush.cmd_Block_Command_Flush.Dwc = 0; + + return Flush.uint; +} + +__inline DWORD SEND_STENCIL_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Flush = {0}; + + Flush.cmd_Block_Command_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + Flush.cmd_Block_Command_Flush.Block_Id = FF_BLOCK; + Flush.cmd_Block_Command_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_S_C; + Flush.cmd_Block_Command_Flush.Type = BLOCK_COMMAND_FLUSH_TYPE_FLUSH; + Flush.cmd_Block_Command_Flush.Dwc = 0; + + return Flush.uint; +} + +__inline DWORD SEND_FLAGBUFFER_FLUSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd FbInvCmd = {0}; + + FbInvCmd.cmd_Block_Command_Mxu.Major_Opcode = CSP_OPCODE_Block_Command_Mxu; + FbInvCmd.cmd_Block_Command_Mxu.Block_Id = MXU_BLOCK; + FbInvCmd.cmd_Block_Command_Mxu.Cmd_Type = BLOCK_COMMAND_MXU_CMD_TYPE_FLUSH_CACHE; + FbInvCmd.cmd_Block_Command_Mxu.Dwc = 4; + + return FbInvCmd.uint; +} + +__inline DWORD SEND_GMCACHE_FLUSH_COMMAND_E3K(void) +{ + return 0; +} + +__inline DWORD SEND_BL_CLEAR_COMMAND_E3K(DWORD dwCounter) +{ + Csp_Opcodes_cmd clearCmd={0}; + + clearCmd.cmd_Blk_Cmd_Csp_Blc.Type = BLOCK_COMMAND_CSP_TYPE_CLEAR_MXU_BLC; + clearCmd.cmd_Blk_Cmd_Csp_Blc.Counter = dwCounter; + clearCmd.cmd_Blk_Cmd_Csp_Blc.Block_Id = CSP_GLOBAL_BLOCK; + clearCmd.cmd_Blk_Cmd_Csp_Blc.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Blc; + clearCmd.cmd_Blk_Cmd_Csp_Blc.Dwc = 3; + + return (DWORD)clearCmd.uint; +} +__inline DWORD SEND_RT_CLEAR_COMMAND_E3K(BOOL bPredicate,BOOL bTiled) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Block_Command_Sg.Major_Opcode = CSP_OPCODE_Block_Command_Sg; + Cmd.cmd_Block_Command_Sg.Block_Id = FF_BLOCK; + Cmd.cmd_Block_Command_Sg.Predicate_En = bPredicate; + Cmd.cmd_Block_Command_Sg.Action_Type = (bTiled) + ? BLOCK_COMMAND_SG_ACTION_TYPE_FAST_CLEAR_TILE + : BLOCK_COMMAND_SG_ACTION_TYPE_FAST_CLEAR_LINEAR; + + Cmd.cmd_Block_Command_Sg.Area_Target = BLOCK_COMMAND_SG_AREA_TARGET_D; + Cmd.cmd_Block_Command_Sg.Type = BLOCK_COMMAND_TEMPLATE_TYPE_SG; + Cmd.cmd_Block_Command_Sg.Dwc = 2; + + return (DWORD)Cmd.uint; +} + +__inline DWORD SEND_DEPTH_CLEAR_COMMAND_E3K(BOOL bPredicate) +{ + Csp_Opcodes_cmd Zc={0}; + + Zc.cmd_Block_Command_Sg.Major_Opcode = CSP_OPCODE_Block_Command_Sg; + Zc.cmd_Block_Command_Sg.Block_Id = FF_BLOCK; + Zc.cmd_Block_Command_Sg.Predicate_En = bPredicate; + Zc.cmd_Block_Command_Sg.Action_Type = BLOCK_COMMAND_SG_ACTION_TYPE_FAST_CLEAR_TILE; + Zc.cmd_Block_Command_Sg.Area_Target = BLOCK_COMMAND_SG_AREA_TARGET_Z; + Zc.cmd_Block_Command_Sg.Type = BLOCK_COMMAND_TEMPLATE_TYPE_SG; + Zc.cmd_Block_Command_Sg.Dwc = 2; + + return (DWORD)Zc.uint; +} + +__inline DWORD SEND_STENCIL_CLEAR_COMMAND_E3K(BOOL bPredicate) +{ + Csp_Opcodes_cmd Sc={0}; + + Sc.cmd_Block_Command_Sg.Major_Opcode = CSP_OPCODE_Block_Command_Sg; + Sc.cmd_Block_Command_Sg.Block_Id = FF_BLOCK; + Sc.cmd_Block_Command_Sg.Predicate_En = bPredicate; + Sc.cmd_Block_Command_Sg.Action_Type = BLOCK_COMMAND_SG_ACTION_TYPE_FAST_CLEAR_TILE; + Sc.cmd_Block_Command_Sg.Area_Target = BLOCK_COMMAND_SG_AREA_TARGET_S; + Sc.cmd_Block_Command_Sg.Type = BLOCK_COMMAND_TEMPLATE_TYPE_SG; + Sc.cmd_Block_Command_Sg.Dwc = 2; + + return (DWORD)Sc.uint; +} + +__inline DWORD SEND_MCE_RT_CLEAR_COMMAND_E3K(BOOL bTiled) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Block_Command_Sg.Major_Opcode = CSP_OPCODE_Block_Command_Sg; + Cmd.cmd_Block_Command_Sg.Block_Id = MCE_BLOCK; + Cmd.cmd_Block_Command_Sg.Predicate_En = 0; + Cmd.cmd_Block_Command_Sg.Action_Type = (bTiled) + ? BLOCK_COMMAND_SG_ACTION_TYPE_FAST_CLEAR_TILE + : BLOCK_COMMAND_SG_ACTION_TYPE_FAST_CLEAR_LINEAR; + + Cmd.cmd_Block_Command_Sg.Area_Target = BLOCK_COMMAND_SG_AREA_TARGET_D; + Cmd.cmd_Block_Command_Sg.Type = BLOCK_COMMAND_TEMPLATE_TYPE_SG; + Cmd.cmd_Block_Command_Sg.Dwc = 2; + + return (DWORD)Cmd.uint; +} + +__inline DWORD SEND_MCE_DEPTH_CLEAR_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Zc={0}; + + Zc.cmd_Block_Command_Sg.Major_Opcode = CSP_OPCODE_Block_Command_Sg; + Zc.cmd_Block_Command_Sg.Block_Id = MCE_BLOCK; + Zc.cmd_Block_Command_Sg.Predicate_En = 0; + Zc.cmd_Block_Command_Sg.Action_Type = BLOCK_COMMAND_SG_ACTION_TYPE_FAST_CLEAR_TILE; + Zc.cmd_Block_Command_Sg.Area_Target = BLOCK_COMMAND_SG_AREA_TARGET_Z; + Zc.cmd_Block_Command_Sg.Type = BLOCK_COMMAND_TEMPLATE_TYPE_SG; + Zc.cmd_Block_Command_Sg.Dwc = 2; + + return (DWORD)Zc.uint; +} + +__inline DWORD SEND_MCE_STENCIL_CLEAR_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Sc={0}; + + Sc.cmd_Block_Command_Sg.Major_Opcode = CSP_OPCODE_Block_Command_Sg; + Sc.cmd_Block_Command_Sg.Block_Id = MCE_BLOCK; + Sc.cmd_Block_Command_Sg.Predicate_En = 0; + Sc.cmd_Block_Command_Sg.Action_Type = BLOCK_COMMAND_SG_ACTION_TYPE_FAST_CLEAR_TILE; + Sc.cmd_Block_Command_Sg.Area_Target = BLOCK_COMMAND_SG_AREA_TARGET_S; + Sc.cmd_Block_Command_Sg.Type = BLOCK_COMMAND_TEMPLATE_TYPE_SG; + Sc.cmd_Block_Command_Sg.Dwc = 2; + + return (DWORD)Sc.uint; +} + +__inline DWORD SEND_2DCOPY_COMMAND_E3K(BOOL bPredicate, BOOL bOverlay) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Block_Command_Sg.Major_Opcode = CSP_OPCODE_Block_Command_Sg; + Cmd.cmd_Block_Command_Sg.Block_Id = FF_BLOCK; + Cmd.cmd_Block_Command_Sg.Predicate_En = bPredicate; + Cmd.cmd_Block_Command_Sg.Blt_Overlap = bOverlay; + Cmd.cmd_Block_Command_Sg.Action_Type = BLOCK_COMMAND_SG_ACTION_TYPE_BIT_BLT; + Cmd.cmd_Block_Command_Sg.Area_Target = BLOCK_COMMAND_SG_AREA_TARGET_D; + Cmd.cmd_Block_Command_Sg.Type = BLOCK_COMMAND_TEMPLATE_TYPE_SG; + Cmd.cmd_Block_Command_Sg.Dwc = 3; + + return (DWORD)Cmd.uint; +} + + +__inline DWORD SEND_GRADIENTFILL_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Block_Command_Sg.Major_Opcode = CSP_OPCODE_Block_Command_Sg; + Cmd.cmd_Block_Command_Sg.Block_Id = FF_BLOCK; + Cmd.cmd_Block_Command_Sg.Predicate_En = 0; + Cmd.cmd_Block_Command_Sg.Action_Type = BLOCK_COMMAND_SG_ACTION_TYPE_GRADIENT_FILL; + Cmd.cmd_Block_Command_Sg.Area_Target = BLOCK_COMMAND_SG_AREA_TARGET_D; + Cmd.cmd_Block_Command_Sg.Type = BLOCK_COMMAND_TEMPLATE_TYPE_SG; + Cmd.cmd_Block_Command_Sg.Dwc = 14; + + return (DWORD)Cmd.uint; +} + +__inline DWORD SEND_2D_ROTATION_E3K(void) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Block_Command_Sg.Major_Opcode = CSP_OPCODE_Block_Command_Sg; + Cmd.cmd_Block_Command_Sg.Block_Id = FF_BLOCK; + Cmd.cmd_Block_Command_Sg.Predicate_En = 0; + Cmd.cmd_Block_Command_Sg.Action_Type = BLOCK_COMMAND_SG_ACTION_TYPE_ROTATION; + Cmd.cmd_Block_Command_Sg.Area_Target = BLOCK_COMMAND_SG_AREA_TARGET_D; + Cmd.cmd_Block_Command_Sg.Type = BLOCK_COMMAND_TEMPLATE_TYPE_SG; + Cmd.cmd_Block_Command_Sg.Dwc = 1; + + return (DWORD)Cmd.uint; +} + +__inline DWORD SEND_STRETCHBLT_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Block_Command_Sg.Major_Opcode = CSP_OPCODE_Block_Command_Sg; + Cmd.cmd_Block_Command_Sg.Block_Id = FF_BLOCK; + Cmd.cmd_Block_Command_Sg.Predicate_En = 0; + Cmd.cmd_Block_Command_Sg.Action_Type = BLOCK_COMMAND_SG_ACTION_TYPE_BIT_BLT; + Cmd.cmd_Block_Command_Sg.Area_Target = BLOCK_COMMAND_SG_AREA_TARGET_D; + Cmd.cmd_Block_Command_Sg.Type = BLOCK_COMMAND_TEMPLATE_TYPE_SG; + Cmd.cmd_Block_Command_Sg.Dwc = 9; + + return (DWORD)Cmd.uint; +} + + +_inline DWORD SEND_COPY_IMM_COMMAND_E3K(DWORD Dwf, BOOL bPredicate) +{ + Csp_Opcodes_cmd CopyImm={0}; + + CopyImm.cmd_Block_Command_Img_Trn.Major_Opcode = CSP_OPCODE_Block_Command_Img_Trn; + CopyImm.cmd_Block_Command_Img_Trn.Block_Id = FF_BLOCK; + CopyImm.cmd_Block_Command_Img_Trn.Type = BLOCK_COMMAND_TEMPLATE_TYPE_IMAGE_TRANSFER; + CopyImm.cmd_Block_Command_Img_Trn.Predicate_En = bPredicate; + CopyImm.cmd_Block_Command_Img_Trn.Dwc = Dwf; + + return (DWORD)CopyImm.uint; +} + +__inline DWORD SEND_DP_LINE_COMMAND_E3K(BOOL ColorIncluded, DWORD lineNum) +{ + Csp_Opcodes_cmd DPLine={0}; + DWORD dwc = ColorIncluded ? (1 + lineNum*2) : (lineNum*2); + + DPLine.cmd_Block_Command_Tas.Major_Opcode = CSP_OPCODE_Block_Command_Tas; + DPLine.cmd_Block_Command_Tas.Type = ColorIncluded; + DPLine.cmd_Block_Command_Tas.Command_Specific_Field = BLOCK_COMMAND_TAS_COMMAND_SPECIFIC_FIELD_DP_LINE; + DPLine.cmd_Block_Command_Tas.Block_Id = TASFE_BLOCK; + DPLine.cmd_Block_Command_Tas.Dwc = dwc; + + return (DWORD)DPLine.uint; +} + +__inline DWORD SEND_DRAWAUTO_COMMAND_E3K(DWORD P_Type, BOOL bInstanceMode, BOOL bPredicate) +{ + Csp_Opcodes_cmd DIPCmd={0}; + + DIPCmd.cmd_Dip.Major_Opcode = CSP_OPCODE_Dip; + DIPCmd.cmd_Dip.P_Type = P_Type; + DIPCmd.cmd_Dip.Mode = DIP_MODE_DRAW_IMM; + DIPCmd.cmd_Dip.Instance_En = bInstanceMode; + DIPCmd.cmd_Dip.Predicate_En = bPredicate; + + return (DWORD)DIPCmd.uint; +} + +__inline DWORD SEND_DRAW_COMMAND_E3K(DWORD P_Type, DWORD IndexSize, BOOL bInstanceMode) +{ + Csp_Opcodes_cmd DIPCmd={0}; + DWORD Index_Mode; + + switch (IndexSize) + { + case 1: + Index_Mode = DIP_MODE_IB_8; + break; + case 2: + Index_Mode = DIP_MODE_IB_16; + break; + case 4: + Index_Mode = DIP_MODE_IB_32; + break; + default: +#ifndef __linux__ + /*only for win32 can use _asm keywords*/ +#if ((_WIN32) && (!_WIN64) && (!_ARM_)) + _asm int 3; +#endif +#endif + Index_Mode = DIP_MODE_IB_32; + break; + } + + DIPCmd.cmd_Dip.Major_Opcode = CSP_OPCODE_Dip; + DIPCmd.cmd_Dip.P_Type = P_Type; + DIPCmd.cmd_Dip.Mode = Index_Mode; + DIPCmd.cmd_Dip.Instance_En = bInstanceMode; + + return (DWORD)DIPCmd.uint; +} + + +__inline DWORD SEND_INTERNAL_WRITEFENCE_E3K(DWORD Route, DWORD RbType, DWORD Slot) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Fence.Major_Opcode = CSP_OPCODE_Fence; + Cmd.cmd_Fence.Fence_Type = FENCE_FENCE_TYPE_INTERNAL; + Cmd.cmd_Fence.Slot_Id = Slot; + Cmd.cmd_Fence.Route_Id = Route; + Cmd.cmd_Fence.Rb_Type = RbType; + Cmd.cmd_Fence.Fence_Update_Mode = FENCE_FENCE_UPDATE_MODE_COPY; + Cmd.cmd_Fence.Dwc = 1; + return (DWORD)Cmd.uint; +} + + +__inline DWORD SEND_INTERNAL_FENCE_VALUE_E3K(DWORD FenceId) +{ + Cmd_Fence_Internal_Dword1 Cmd = {0}; + Cmd.Update_Value = (FenceId & 0xFFFF); + Cmd.Slice_Mask = 0; + return *(DWORD*) &Cmd; +} + + +__inline DWORD SEND_INTERNAL_WAIT_E3K(DWORD Slot, DWORD WaitMethod, DWORD WaitValue) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Wait.Major_Opcode = CSP_OPCODE_Wait; + Cmd.cmd_Wait.Slot_Id = Slot; + Cmd.cmd_Wait.Station_Id = WAIT_STATION_ID_PRE_PARSER; + Cmd.cmd_Wait.Wait_Mode = WAIT_WAIT_MODE_NORMAL_WAIT; + Cmd.cmd_Wait.Method = WaitMethod; + Cmd.cmd_Wait.Dwc = WaitValue; + return (DWORD)Cmd.uint; + } + +__inline DWORD SEND_INTERNAL_WAIT_MAIN_E3K(DWORD Slot, + DWORD WaitMethod, + DWORD WaitValue) +{ + Csp_Opcodes_cmd WaitCmd = {0}; + + WaitCmd.cmd_Wait.Major_Opcode = CSP_OPCODE_Wait; + WaitCmd.cmd_Wait.Slot_Id = Slot; + WaitCmd.cmd_Wait.Station_Id = WAIT_STATION_ID_MAIN_PARSER; + WaitCmd.cmd_Wait.Wait_Mode = WAIT_WAIT_MODE_NORMAL_WAIT; + WaitCmd.cmd_Wait.Method = WaitMethod; + WaitCmd.cmd_Wait.Dwc = WaitValue; + + return (DWORD)WaitCmd.uint; +} + +__inline DWORD SEND_INTERNAL_WAIT_VALUE_E3K(DWORD FenceId) +{ + Cmd_Fence_Internal_Dword1 Cmd = {0}; + + Cmd.Update_Value = (FenceId & 0xFFFF); + Cmd.Slice_Mask = 0; + return *(DWORD*)&Cmd; +} + +typedef enum RBTYPE_E3K +{ + _RBT_3DFE = 0, + _RBT_3DBE = 1, + _RBT_CSL = 2, + _RBT_CSH = 3, +}RBTYPE_E3K; + +__inline DWORD SEND_RING_BUFFER_SWAP_INTERNALFENCE_E3K(RBTYPE_E3K RbType, + DWORD RouteID, + DWORD Slot, + DWORD Value, + DWORD* pCmd) +{ + Csp_Opcodes_cmd FenceCmd = {0}; + + FenceCmd.cmd_Fence.Major_Opcode = CSP_OPCODE_Fence; + FenceCmd.cmd_Fence.Fence_Type = FENCE_FENCE_TYPE_INTERNAL; + FenceCmd.cmd_Fence.Dwc = 1; + + FenceCmd.cmd_Fence.Route_Id = RouteID; + FenceCmd.cmd_Fence.Slot_Id = Slot; + FenceCmd.cmd_Fence.Fence_Update_Mode = FENCE_FENCE_UPDATE_MODE_COPY; + FenceCmd.cmd_Fence.Rb_Type = RbType; + + *pCmd++ = FenceCmd.uint; + *pCmd++ = Value; + + return 2; +} + +__inline DWORD UPDATE_INTERNAL_WRITEFENCE_E3K(RBTYPE_E3K RbType, + DWORD RouteID, + DWORD Slot, + DWORD Value, + DWORD* pCmd) +{ + Csp_Opcodes_cmd FenceCmd = {0}; + + FenceCmd.cmd_Fence.Major_Opcode = CSP_OPCODE_Fence; + FenceCmd.cmd_Fence.Fence_Type = FENCE_FENCE_TYPE_INTERNAL; + FenceCmd.cmd_Fence.Dwc = 1; + + FenceCmd.cmd_Fence.Route_Id = RouteID; + FenceCmd.cmd_Fence.Slot_Id = Slot; + FenceCmd.cmd_Fence.Fence_Update_Mode = FENCE_FENCE_UPDATE_MODE_OR; + FenceCmd.cmd_Fence.Rb_Type = RbType; + + *pCmd++ = FenceCmd.uint; + *pCmd++ = Value; + + return 2; +} + +__inline DWORD SEND_QUERY_DUMP_E3K(DWORD BlockId, DWORD DumpSize, BOOL AddressMode) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Query_Dump.Major_Opcode = CSP_OPCODE_Query_Dump; + Cmd.cmd_Query_Dump.Block_Id = BlockId; + Cmd.cmd_Query_Dump.Address_Mode = AddressMode; + Cmd.cmd_Query_Dump.Cmd_Type = QUERY_DUMP_CMD_TYPE_NORMAL_QUERY; + Cmd.cmd_Query_Dump.Dwc_To_Dump = DumpSize; + Cmd.cmd_Query_Dump.Dwc = 2; + return (DWORD)Cmd.uint; +} + +__inline DWORD SEND_QUERY_ADDR1_E3K(DWORD Address1) +{ + Cmd_Query_Dump_Address_Dword1 DumpAddr1 = {0}; + + DumpAddr1.Address_Low32 = Address1; + return *(DWORD*)&DumpAddr1; +} + +__inline DWORD SEND_QUERY_ADDR2_AND_OFFSET_E3K(DWORD Address2, DWORD Offset, BOOL Gart_En, BOOL Top256T) +{ + Cmd_Query_Dump_Address_Dword2 DumpAddr2 = {0}; + + DumpAddr2.Address_High8 = Address2; + DumpAddr2.Reg_Offset = Offset; + return *(DWORD*)&DumpAddr2; +} + +__inline DWORD SEND_EXTERNAL_FENCE_E3K(DWORD IrqType) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Fence.Major_Opcode = CSP_OPCODE_Fence; + Cmd.cmd_Fence.Fence_Type = FENCE_FENCE_TYPE_EXTERNAL64; + Cmd.cmd_Fence.Irq = IrqType; + Cmd.cmd_Fence.Dwc = 4; + return (DWORD)Cmd.uint; +} + + +__inline DWORD SEND_EXTERNAL_FENCE_ADDR1_E3K(DWORD Address1) +{ + Cmd_Fence_External_Addr_Dword1 Cmd = {0}; + + Cmd.External_Addr_Low32 = Address1; + return *(DWORD*)&Cmd; +} + + +__inline DWORD SEND_EXTERNAL_FENCE_ADDR2_E3K(DWORD Address2) +{ + Cmd_Fence_External_Addr_Dword2 Cmd = {0}; + + Cmd.External_Addr_High8 = Address2; + return *(DWORD*)&Cmd; +} + + +__inline DWORD SEND_EXTERNAL_WAIT_E3K(DWORD Slot, + DWORD Value, + DWORD* pCmd) +{ + Csp_Opcodes_cmd WaitCmd = {0}; + + WaitCmd.cmd_Wait.Major_Opcode = CSP_OPCODE_Wait; + WaitCmd.cmd_Wait.Slot_Id = Slot; + WaitCmd.cmd_Wait.Dwc = 1; + WaitCmd.cmd_Wait.Wait_Mode = WAIT_WAIT_MODE_EXTERNAL_WAIT; + + *pCmd++ = WaitCmd.uint; + *pCmd++ = Value; + + return 2; +} + +__inline DWORD DISABLE_FF_SHADOW_E3K(void) +{ + return 0; +} + + +__inline DWORD RESTORE_AND_ENABLE_FF_SHADOW_E3K(void) +{ + return 0; +} + +__inline DWORD SEND_CONTEXT_DUMP_E3K(DWORD Block, DWORD Offset, DWORD DumpSize, DWORD address, DWORD* pCmd) +{ + return 0; +} + +__inline DWORD SEND_QUERY_STATUS_E3K(DWORD BlockId, DWORD Offset, DWORD DumpSize, DWORD address, DWORD* pCmd) +{ + Csp_Opcodes_cmd DumpCmd={0}; + DWORD* pCmd0 = pCmd; + + DumpCmd.cmd_Query_Dump.Major_Opcode = CSP_OPCODE_Query_Dump; + DumpCmd.cmd_Query_Dump.Block_Id = BlockId; + DumpCmd.cmd_Query_Dump.Cmd_Type = QUERY_DUMP_CMD_TYPE_NORMAL_QUERY; + DumpCmd.cmd_Query_Dump.Dwc_To_Dump = DumpSize; + DumpCmd.cmd_Query_Dump.Dwc = 2; + + *pCmd++ = DumpCmd.uint; + + *pCmd++ = address; + + *pCmd++ = Offset << 19; + + return (DWORD)(pCmd - pCmd0); +} + +__inline DWORD SEND_QUERY_COPY_RESULT_E3K(DWORD BlockId, + BOOL b64Bit, + BOOL bAvail, + BOOL bPartial, + BOOL bTwoSlice, + BOOL bTimestamp, + DWORD Offset, + DWORD AvailOffset, + DWORD srcAddress, + DWORD dstAddress, + DWORD* pCmd) +{ + return 0; +} + +__inline DWORD SEND_QUERY_STATUS_E3K_VIDEO(DWORD Offset, DWORD DumpSize, DWORD address, DWORD* pCmd) +{ + return 0; +} + +__inline DWORD SEND_GP_COMMAND_E3K(BOOL bPredicateEn, BOOL bWaitDoneEn,DWORD DwType) +{ + Csp_Opcodes_cmd GpCmd={0}; + + GpCmd.cmd_Gp.Major_Opcode = CSP_OPCODE_Gp; + GpCmd.cmd_Gp.Block_Id = EU_CS_BLOCK; + GpCmd.cmd_Gp.Dw_Type = DwType; + GpCmd.cmd_Gp.Dwc = 13; + GpCmd.cmd_Gp.Indirect_En = 0; + GpCmd.cmd_Gp.Predicate_En = bPredicateEn ? 1 : 0; + GpCmd.cmd_Gp.Wait_Done_En = bWaitDoneEn; + + return (DWORD)GpCmd.uint; +} + +__inline DWORD SEND_GP_OCL_COMMAND_E3K(BOOL bWaitDoneEn) +{ + Csp_Opcodes_cmd GpCmd={0}; + + GpCmd.cmd_Gp.Major_Opcode = CSP_OPCODE_Gp; + GpCmd.cmd_Gp.Block_Id = EU_CS_BLOCK; + GpCmd.cmd_Gp.Dw_Type = GP_DW_TYPE_GLOBAL_SIZE; + GpCmd.cmd_Gp.Dwc = 13; + GpCmd.cmd_Gp.Wait_Done_En = bWaitDoneEn; + GpCmd.cmd_Gp.Indirect_En = 0; + + return (DWORD)GpCmd.uint; +} + +__inline DWORD SEND_GP_COMMAND_WITH_INDIRECT_BUFFER_E3K(BOOL bPredicateEn, BOOL bWaitDoneEn) +{ + Csp_Opcodes_cmd GpCmd={0}; + + GpCmd.cmd_Gp.Major_Opcode = CSP_OPCODE_Gp; + GpCmd.cmd_Gp.Block_Id = EU_CS_BLOCK; + GpCmd.cmd_Gp.Dw_Type = GP_DW_TYPE_GROUP_NUMBER; + GpCmd.cmd_Gp.Dwc = 12; + GpCmd.cmd_Gp.Indirect_En = 1; + GpCmd.cmd_Gp.Predicate_En = bPredicateEn ? 1 : 0; + GpCmd.cmd_Gp.Wait_Done_En = bWaitDoneEn; + + return (DWORD)GpCmd.uint; +} + +__inline DWORD SEND_DRAIN_FS_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Block_Command_Eu.Major_Opcode = CSP_OPCODE_Block_Command_Eu; + Cmd.cmd_Block_Command_Eu.Block_Id = EU_FS_BLOCK; + Cmd.cmd_Block_Command_Eu.Command_Specific_Field = 0; + Cmd.cmd_Block_Command_Eu.Type = BLOCK_COMMAND_EU_TYPE_DRAIN_EU; + Cmd.cmd_Block_Command_Eu.Dwc = 0; + return Cmd.uint; +} + +__inline DWORD SEND_DRAIN_CS_COMMAND_E3K(void) +{ + return 0; +} + +__inline DWORD SEND_DRAIN_CSL_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Block_Command_Eu.Major_Opcode = CSP_OPCODE_Block_Command_Eu; + Cmd.cmd_Block_Command_Eu.Block_Id = EU_CS_BLOCK; + Cmd.cmd_Block_Command_Eu.Command_Specific_Field = 2; + Cmd.cmd_Block_Command_Eu.Type = BLOCK_COMMAND_EU_TYPE_DRAIN_EU; + Cmd.cmd_Block_Command_Eu.Dwc = 0; + + return Cmd.uint; +} + +__inline DWORD SEND_DRAIN_CSH_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Block_Command_Eu.Major_Opcode = CSP_OPCODE_Block_Command_Eu; + Cmd.cmd_Block_Command_Eu.Block_Id = EU_CS_BLOCK; + Cmd.cmd_Block_Command_Eu.Command_Specific_Field = 3; + Cmd.cmd_Block_Command_Eu.Type = BLOCK_COMMAND_EU_TYPE_DRAIN_EU; + Cmd.cmd_Block_Command_Eu.Dwc = 0; + + return Cmd.uint; +} + +__inline DWORD SEND_DRAIN_PS_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd Cmd = {0}; + + Cmd.cmd_Block_Command_Eu.Major_Opcode = CSP_OPCODE_Block_Command_Eu; + Cmd.cmd_Block_Command_Eu.Block_Id = EU_PS_BLOCK; + Cmd.cmd_Block_Command_Eu.Command_Specific_Field = 1; + Cmd.cmd_Block_Command_Eu.Type = BLOCK_COMMAND_EU_TYPE_DRAIN_EU; + Cmd.cmd_Block_Command_Eu.Dwc = 0; + + return Cmd.uint; +} + +__inline DWORD SEND_FS_CFG_COMMAND_E3K(DWORD* pCmd) +{ + return 0; +} + +__inline DWORD SEND_FS_L1I_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd BlockCommandEu = {0}; + + BlockCommandEu.cmd_Block_Command_Eu.Major_Opcode = CSP_OPCODE_Block_Command_Eu; + BlockCommandEu.cmd_Block_Command_Eu.Block_Id = EU_FS_BLOCK; + BlockCommandEu.cmd_Block_Command_Eu.Command_Specific_Field = 0; + BlockCommandEu.cmd_Block_Command_Eu.Type = BLOCK_COMMAND_EU_TYPE_INVALIDATE_L1I; + BlockCommandEu.cmd_Block_Command_Eu.Dwc = 0; + + return (DWORD)BlockCommandEu.uint; +} + +__inline DWORD SEND_CS_L1I_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd BlockCommandEu = {0}; + + BlockCommandEu.cmd_Block_Command_Eu.Major_Opcode = CSP_OPCODE_Block_Command_Eu; + BlockCommandEu.cmd_Block_Command_Eu.Block_Id = EU_CS_BLOCK; + BlockCommandEu.cmd_Block_Command_Eu.Command_Specific_Field = 2; + BlockCommandEu.cmd_Block_Command_Eu.Type = BLOCK_COMMAND_EU_TYPE_INVALIDATE_L1I; + BlockCommandEu.cmd_Block_Command_Eu.Dwc = 0; + + return (DWORD)BlockCommandEu.uint; +} + +__inline DWORD SEND_PS_CFG_COMMAND_E3K(DWORD* pCmd) +{ + return 0; +} + +__inline DWORD SEND_PS_L1I_INVALIDATE_COMMAND_E3K(void) +{ + Csp_Opcodes_cmd BlockCommandEu = {0}; + + BlockCommandEu.cmd_Block_Command_Eu.Major_Opcode = CSP_OPCODE_Block_Command_Eu; + BlockCommandEu.cmd_Block_Command_Eu.Block_Id = EU_PS_BLOCK; + BlockCommandEu.cmd_Block_Command_Eu.Command_Specific_Field = 1; + BlockCommandEu.cmd_Block_Command_Eu.Type = BLOCK_COMMAND_EU_TYPE_INVALIDATE_L1I; + BlockCommandEu.cmd_Block_Command_Eu.Dwc = 0; + + return (DWORD)BlockCommandEu.uint; +} + +__inline DWORD SEND_L2_INVALIDATE_COMMAND_E3K(DWORD usage) +{ + Csp_Opcodes_cmd InvalidateCmd={0}; + + InvalidateCmd.cmd_Block_Command_L2.Major_Opcode = CSP_OPCODE_Block_Command_L2; + InvalidateCmd.cmd_Block_Command_L2.Block_Id = QUERY_DUMP_BLOCK_ID_L2; + + + InvalidateCmd.cmd_Block_Command_L2.Type = BLOCK_COMMAND_L2_TYPE_INVALIDATE_L2; + InvalidateCmd.cmd_Block_Command_L2.Usage = usage; + InvalidateCmd.cmd_Block_Command_L2.Dwc = 0; + + return (DWORD)InvalidateCmd.uint; +} + +__inline DWORD SEND_L2_FLUSH_COMMAND_E3K(DWORD usage, BOOL bInternalFlush) +{ + Csp_Opcodes_cmd InvalidateCmd={0}; + + InvalidateCmd.cmd_Block_Command_L2.Major_Opcode = CSP_OPCODE_Block_Command_L2; + InvalidateCmd.cmd_Block_Command_L2.Block_Id = QUERY_DUMP_BLOCK_ID_L2; + + + InvalidateCmd.cmd_Block_Command_L2.Type = bInternalFlush ? BLOCK_COMMAND_L2_TYPE_FLUSH_L1 : BLOCK_COMMAND_L2_TYPE_FLUSH_L2; + InvalidateCmd.cmd_Block_Command_L2.Usage = usage; + InvalidateCmd.cmd_Block_Command_L2.Dwc = 0; + + return (DWORD)InvalidateCmd.uint; +} + +__inline DWORD SET_ONE_SLICE_CMD_E3K(BOOL bElt1K, DWORD* pCmd) +{ + return 0; +} + +__inline DWORD SEND_CSP_RESV_CACHE_SIZE_CMD_E3K(DWORD staticSize, DWORD dynamic0Size, DWORD dynamic1Size) +{ + return 0; +} + +__inline DWORD SEND_DIP_CMD_E3K(BOOL bPredicate, + DWORD DipMode, + BOOL bInstance, + BOOL bIbOffset, + BOOL bVbOffset, + BOOL bInstanceOffset, + DWORD PrimitiveType, + DWORD PatchVetexCount, + BOOL bIndirect) +{ + Csp_Opcodes_cmd DIPcmd = {0}; + + DIPcmd.cmd_Dip.Major_Opcode = CSP_OPCODE_Dip; + DIPcmd.cmd_Dip.Predicate_En = bPredicate; + DIPcmd.cmd_Dip.Mode = DipMode; + DIPcmd.cmd_Dip.Instance_En = bInstance; + DIPcmd.cmd_Dip.Start_Index_Valid = bIbOffset; + DIPcmd.cmd_Dip.Start_Vertex_Valid = bVbOffset; + DIPcmd.cmd_Dip.Start_Instance_Valid = bIndirect ? 1 : bInstanceOffset; + DIPcmd.cmd_Dip.P_Type = PrimitiveType; + DIPcmd.cmd_Dip.Patch_Vertex_Count = PatchVetexCount; + + DIPcmd.cmd_Dip.Indirect = bIndirect; + + return DIPcmd.uint; +} + +#endif + diff --git a/drivers/gpu/drm/arise/core/e3k/include/Chip/surface_format.h b/drivers/gpu/drm/arise/core/e3k/include/Chip/surface_format.h new file mode 100644 index 0000000000000..a8bd17991da61 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/Chip/surface_format.h @@ -0,0 +1,2436 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _SURFACE_FORMAT_H +#define _SURFACE_FORMAT_H + + +#define SURFACE_FORMAT_TIMESTAMP "2015-09-16 16:40:28" +typedef enum +{ + HSF_UNKNOWN = 0, + HSF_R64G64B64A64_FLOAT = 1, + HSF_R64G64B64_FLOAT = 2, + HSF_R32G32B32A32_TYPELESS = 3, + HSF_R32G32B32A32_FLOAT = 4, //128bpp RGBA + HSF_R32G32B32A32_UINT = 5, + HSF_R32G32B32A32_SINT = 6, + HSF_R32G32B32A32_SNORM = 7, + HSF_R32G32B32A32_SCALE = 8, + HSF_R32G32B32A32_UNORM = 9, + HSF_R32G32B32A32_USCALE = 10, + HSF_R32G32B32A32_FIX = 11, + HSF_R64G64_FLOAT = 12, + HSF_R32G32B32_TYPELESS = 13, + HSF_R32G32B32_FLOAT = 14, //128bpp RGB + HSF_R32G32B32_UINT = 15, + HSF_R32G32B32_SINT = 16, + HSF_R32G32B32_UNORM = 17, + HSF_R32G32B32_USCALE = 18, + HSF_R32G32B32_SNORM = 19, + HSF_R32G32B32_SCALE = 20, + HSF_R32G32B32_FIX = 21, + HSF_R16G16B16A16_TYPELESS = 22, //64bpp RGBA + HSF_R16G16B16A16_FLOAT = 23, + HSF_R16G16B16A16_UNORM = 24, + HSF_R16G16B16A16_UINT = 25, + HSF_R16G16B16A16_SNORM = 26, + HSF_R16G16B16A16_SINT = 27, + HSF_R16G16B16A16_SCALE = 28, + HSF_R16G16B16A16_USCALE = 29, + HSF_R16G16B16A16_SSCALE = 30, + HSF_R12G12B12A12_UNORM = 31, + HSF_R16G16B16_FLOAT = 32, //64bpp RGB + HSF_R16G16B16_SINT = 33, + HSF_R16G16B16_SNORM = 34, + HSF_R16G16B16_SCALE = 35, + HSF_R16G16B16_UINT = 36, + HSF_R16G16B16_UNORM = 37, + HSF_R16G16B16_USCALE = 38, + HSF_R32G32_TYPELESS = 39, + HSF_R32G32_FLOAT = 40, //64bpp RG + HSF_R32G32_UINT = 41, + HSF_R32G32_SINT = 42, + HSF_R32G32_SNORM = 43, + HSF_R32G32_SCALE = 44, + HSF_R32G32_UNORM = 45, + HSF_R32G32_USCALE = 46, + HSF_R32G32_FIX = 47, + HSF_R32G8X24_TYPELESS = 48, + HSF_D32_FLOAT_S8X24_UINT = 49, + HSF_R32_FLOAT_X8X24_TYPELESS = 50, + HSF_X32_TYPELESS_G8X24_UINT = 51, + HSF_R64_FLOAT = 52, + HSF_R12G12B12_UNORM = 53, + HSF_R10G10B10A2_TYPELESS = 54, + HSF_R10G10B10A2_UNORM = 55, //32bpp RGBA + HSF_R10G10B10A2_UINT = 56, + HSF_R10G10B10X2_UINT = 57, //32bpp RGBA + HSF_R10G10B10X2_USCALE = 58, + HSF_R10G10B10A2_SNORM = 59, + HSF_R10G10B10A2_SINT = 60, + HSF_R10G10B10X2_SNORM = 61, + HSF_B10G10R10A2_SNORM = 62, + HSF_B10G10R10A2_UNORM = 63, + HSF_B10G10R10X2_UNORM = 64, + HSF_A2B10G10R10_UNORM = 65, + HSF_A2B10G10R10_SNORM = 66, + HSF_A2B10G10R10_USCALE = 67, + HSF_A2B10G10R10_SSCALE = 68, + HSF_R10G10B10_SINT = 69, + HSF_R10G10B10_SNORM = 70, + HSF_R10G10B10_SCALE = 71, + HSF_R10G10B10_UNIT = 72, + HSF_R10G10B10_UNORM = 73, + HSF_R10G10B10_USCALE = 74, + HSF_R10G10_SINT = 75, + HSF_R10G10_SNORM = 76, + HSF_R10G10_SCALE = 77, + HSF_R10G10_UINT = 78, + HSF_R10G10_UNORM = 79, + HSF_R10G10_USCALE = 80, + HSF_R10G10B10_FLOAT_A2_UNORM = 81, + HSF_R11G11B10_FLOAT = 82, //32bpp RGB + HSF_B10G11R11_FLOAT = 83, + HSF_R11G11_FLOAT = 84, + HSF_R8G8B8A8_TYPELESS = 85, + HSF_R8G8B8A8_UNORM = 86, //32bpp RGBA + HSF_R8G8B8A8_UNORM_SRGB = 87, + HSF_R8G8B8X8_UNORM = 88, //32bpp RGBA + HSF_B8G8R8A8_UNORM = 89, + HSF_B8G8R8A8_UNORM_SRGB = 90, + HSF_B8G8R8X8_UNORM = 91, + HSF_B8G8R8X8_UNORM_SRGB = 92, + HSF_X8R8G8B8_UNORM = 93, + HSF_X8B8G8R8_UNORM = 94, + HSF_A8R8G8B8_UNORM = 95, + HSF_A8B8G8R8_UNORM = 96, + HSF_R8G8B8A8_UINT = 97, + HSF_R8G8B8A8_SNORM = 98, + HSF_R8G8B8A8_SINT = 99, + HSF_B8G8R8A8_XNORM = 100, + HSF_R8G8B8A8_SSCALE = 101, + HSF_R8G8B8A8_USCALE = 102, + HSF_R8G8B8_SINT = 103, + HSF_R8G8B8_SNORM = 104, + HSF_R8G8B8_SCALE = 105, + HSF_R8G8B8_UINT = 106, + HSF_R8G8B8_UNORM = 107, + HSF_R8G8B8_USCALE = 108, + HSF_R16G16_TYPELESS = 109, + HSF_R16G16_FLOAT = 110, //32bpp RG + HSF_R16G16_UNORM = 111, + HSF_R16G16_UINT = 112, + HSF_R16G16_SNORM = 113, + HSF_R16G16_SINT = 114, + HSF_R16G16_SCALE = 115, + HSF_R16G16_USCALE = 116, + HSF_R16G16_SSCALE = 117, + HSF_R32_TYPELESS = 118, + HSF_D32_FLOAT = 119, + HSF_D32_UNORM = 120, //32bpp R + HSF_R32_FLOAT = 121, + HSF_R32_UINT = 122, + HSF_R32_SINT = 123, + HSF_R32_UNORM = 124, + HSF_R32_USCALE = 125, + HSF_R32_SNORM = 126, + HSF_R32_SCALE = 127, + HSF_R32_FIX = 128, + HSF_R24G8_TYPELESS = 129, + HSF_D32_FLOAT_S8_UINT = 130, + + HSF_R24_UNORM_X8_TYPELESS = 132, + HSF_X24_TYPELESS_G8_UINT = 133, + HSF_D24_UNORM = 134, + HSF_R24_FLOAT = 135, + HSF_R8G8_TYPELESS = 136, + HSF_R8G8_UNORM = 137, + HSF_R8G8_UINT = 138, + HSF_R8G8_SNORM = 139, + HSF_R8G8_SINT = 140, + HSF_R8G8_USCALE = 141, + HSF_R8G8_SSCALE = 142, + HSF_R16_TYPELESS = 143, + HSF_R16_FLOAT = 144, //16bpp R + HSF_D16_UNORM = 145, + HSF_R16_UNORM = 146, + HSF_R16_UINT = 147, + HSF_R16_SNORM = 148, + HSF_R16_SINT = 149, + HSF_R16_USCALE = 150, + HSF_R16_SSCALE = 151, + HSF_A16_UNORM = 152, + HSF_B5G6R5_UNORM = 153, + HSF_R5G6B5_UNORM = 154, + HSF_B5G5R5X1_UNORM = 155, //16bpp RGBA + HSF_B5G5R5A1_UNORM = 156, //16bpp RGBA + HSF_R5G5B5A1_UNORM = 157, + HSF_A1B5G5R5_UNORM = 158, + HSF_A1R5G5B5_UNORM = 159, + HSF_B4G4R4A4_UNORM = 160, + HSF_B4G4R4X4_UNORM = 161, //16bpp BGRA + HSF_R4G4B4A4_UNORM = 162, //16bpp RGBA + HSF_A4B4G4R4_UNORM = 163, + HSF_A4R4G4B4_UNORM = 164, + HSF_R4G4B4_UNORM = 165, + HSF_R5G5B5_UNORM = 166, + HSF_U5V5L6_XNORM = 167, + HSF_L16_UNORM = 168, //16bpp + HSF_L8_A8_UNORM = 169, + HSF_R10_SINT = 170, + HSF_R10_SNORM = 171, + HSF_R10_SCALE = 172, + HSF_R10_UINT = 173, + HSF_R10_UNORM = 174, + HSF_R10_USCALE = 175, + HSF_R2G2B2A2_UNORM = 176, + HSF_R8_TYPELESS = 177, + HSF_R8_UNORM = 178, + HSF_R8_UINT = 179, + HSF_R8_SNORM = 180, + HSF_R8_SINT = 181, + HSF_R8_USCALE = 182, + HSF_R8_SSCALE = 183, + HSF_A8_UNORM = 184, + HSF_L8_UNORM = 185, + HSF_A12_UNORM = 186, + HSF_A4_UNORM = 187, + HSF_R1_UNORM = 188, + HSF_R3G3B2_UNORM = 189, + HSF_L4A4_UNORM = 190, //8bpp RA + HSF_A4L4_UNORM = 191, + HSF_L4A4_VIDEO = 192, + HSF_AYUV_VIDEO = 193, //32bpp + HSF_YUYV = 194, //16bpp + HSF_NV12 = 195, //16bpp + HSF_P010 = 196, //32bpp + HSF_P016 = 197, //32bpp + HSF_R9G9B9E5_SHAREDEXP = 198, + HSF_R8G8_B8G8_UNORM = 199, + HSF_G8R8_G8B8_UNORM = 200, + HSF_BC1_UNORM = 201, + HSF_BC1_UNORM_SRGB = 202, + HSF_BC2_UNORM = 203, + HSF_BC2_UNORM_SRGB = 204, + HSF_BC3_UNORM = 205, + HSF_BC3_UNORM_SRGB = 206, + HSF_BC4_UNORM = 207, + HSF_BC4_SNORM = 208, + HSF_BC4_UNORM_L = 209, + HSF_BC4_SNORM_L = 210, + HSF_BC5_UNORM = 211, + HSF_BC5_SNORM = 212, + HSF_BC5_UNORM_LA = 213, + HSF_BC5_SNORM_LA = 214, + HSF_BC6H_UF16 = 215, + HSF_BC6H_SF16 = 216, + HSF_BC7_UNORM = 217, + HSF_BC7_UNORM_SRGB = 218, + HSF_G8_UINT = 219, + HSF_3DC_UNORM = 220, + HSF_YUY2 = 221, //16bpp + HSF_Y216_VIDEO = 222, + HSF_Y210_VIDEO = 223, + HSF_A4I4_VIDEO = 224, + HSF_A8L8_UNORM = 225, + HSF_L8A8_UNORM = 226, + HSF_ZL1 = 227, + HSF_R16G16B16A16_UNORM_SRGB = 228, // only used for TU border color format, internal use, added by peng@2018.01.04 + HSF_YCRCB_MB_8_422 = 229, + HSF_YCRCB_MB_8_420 = 230, + HSF_YCRCB_MB_16_422 = 231, + + HSF_UYVA1010102_VIDEO = 233, + HSF_UYVY = 234, + HSF_BAYER_12 = 235, + HSF_BAYER = 236, + HSF_L8_SNORM = 237, // SLUMINANCE; channel_mask =0x1; bpt =8 + + HSF_YV12 = 238, + HSF_L8A8_SNORM = 239, // SLUMINANCE_ALPHA8; channel_mask =0x3; bpt =16 + + HSF_S1_UINT = 240, + HSF_S16_UINT = 241, + HSF_S4_UINT = 242, + HSF_S8_UINT = 243, + HSF_I12_UNORM = 244, + HSF_I16_UNORM = 245, + HSF_I4_UNORM = 246, + HSF_I8_UNORM = 247, + HSF_L12_UNORM = 248, + HSF_L12_A12_UNORM = 249, + HSF_L12_A4_UNORM = 250, + HSF_L4_UNORM = 252, + HSF_L4_A4_UNORM = 253, + HSF_L6_A2_UNORM = 254, + HSF_RGB8_ETC2 = 255, + HSF_SRGB8_ETC2 = 256, + HSF_RGBA8_ETC2_EAC = 257, + HSF_SRGB8_ALPHA8_ETC2_EAC = 258, + HSF_R11_EAC = 259, + HSF_RG11_EAC = 260, + HSF_SIGNED_R11_EAC = 261, + HSF_SIGNED_RG11_EAC = 262, + HSF_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 263, + HSF_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 264, + HSF_COMPRESSED_ALPHA = 265, + HSF_COMPRESSED_INTENSITY = 266, + HSF_COMPRESSED_LUMINANCE = 267, + HSF_COMPRESSED_RED = 268, + HSF_COMPRESSED_RED_RGTC1 = 269, + HSF_COMPRESSED_RG = 270, + HSF_COMPRESSED_RG_RGTC2 = 271, + HSF_COMPRESSED_RGB = 272, + HSF_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 273, + HSF_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 274, + HSF_COMPRESSED_RGBA = 275, + HSF_COMPRESSED_RGBA_BPTC_UNORM = 276, + HSF_COMPRESSED_SIGNED_RED_RGTC1 = 277, + HSF_COMPRESSED_SIGNED_RG_RGTC2 = 278, + HSF_COMPRESSED_SLUMINANCE = 279, + HSF_COMPRESSED_SLUMINANCE_ALPHA = 280, + HSF_COMPRESSED_SRGB = 281, + HSF_COMPRESSED_SRGB_ALPHA = 282, + HSF_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 283, + HSF_R10G10B10A2_USCALE = 284, + HSF_R10G10B10A2_SSCALE = 285, + HSF_R32G32B32A32_SSCALE = 286, + HSF_R32G32B32_SSCALE = 287, + HSF_R32G32_SSCALE = 288, + HSF_R16G16B16_SSCALE = 289, + HSF_R32_SSCALE = 290, + HSF_R8G8B8_SSCALE = 291, + + + HSF_RGBA_ASTC_4X4 = 321, + HSF_RGBA_ASTC_5X4 = 322, + HSF_RGBA_ASTC_5X5 = 323, + HSF_RGBA_ASTC_6X5 = 324, + HSF_RGBA_ASTC_6X6 = 325, + HSF_RGBA_ASTC_8X5 = 326, + HSF_RGBA_ASTC_8X6 = 327, + HSF_RGBA_ASTC_8X8 = 328, + HSF_RGBA_ASTC_10X5 = 329, + HSF_RGBA_ASTC_10X6 = 330, + HSF_RGBA_ASTC_10X8 = 331, + HSF_RGBA_ASTC_10X10 = 332, + HSF_RGBA_ASTC_12X10 = 333, + HSF_RGBA_ASTC_12X12 = 334, + HSF_ASTC_RESERVED0 = 335, + HSF_ASTC_RESERVED1 = 336, + HSF_RGBA_ASTC_4X4_SRGB = 337, + HSF_RGBA_ASTC_5X4_SRGB = 338, + HSF_RGBA_ASTC_5X5_SRGB = 339, + HSF_RGBA_ASTC_6X5_SRGB = 340, + HSF_RGBA_ASTC_6X6_SRGB = 341, + HSF_RGBA_ASTC_8X5_SRGB = 342, + HSF_RGBA_ASTC_8X6_SRGB = 343, + HSF_RGBA_ASTC_8X8_SRGB = 344, + HSF_RGBA_ASTC_10X5_SRGB = 345, + HSF_RGBA_ASTC_10X6_SRGB = 346, + HSF_RGBA_ASTC_10X8_SRGB = 347, + HSF_RGBA_ASTC_10X10_SRGB = 348, + HSF_RGBA_ASTC_12X10_SRGB = 349, + HSF_RGBA_ASTC_12X12_SRGB = 350, + HSF_R8G8B8_SRGB = 351, //only used for TU border color format, internal use, added by Jenna@20180326 + HSF_ASTC_RESERVED3 = 352, + HSF_RGBA_ASTC_3x3x3 = 353, + HSF_RGBA_ASTC_4x3x3 = 354, + HSF_RGBA_ASTC_4x4x3 = 355, + HSF_RGBA_ASTC_4x4x4 = 356, + HSF_RGBA_ASTC_5x4x4 = 357, + HSF_RGBA_ASTC_5x5x4 = 358, + HSF_RGBA_ASTC_5x5x5 = 359, + HSF_RGBA_ASTC_6x5x5 = 360, + HSF_RGBA_ASTC_6x6x5 = 361, + HSF_RGBA_ASTC_6x6x6 = 362, + HSF_L16A16_UNORM = 363, // ; channel_mask =0x3; bpt =32 + HSF_L16A16_SNORM = 364, // ; channel_mask =0x3; bpt =32 + HSF_ASTC_RESERVED6 = 365, + HSF_ASTC_RESERVED7 = 366, + HSF_ASTC_RESERVED8 = 367, + HSF_ASTC_RESERVED9 = 368, + HSF_RGBA_ASTC_3x3x3_SRGB = 369, + HSF_RGBA_ASTC_4x3x3_SRGB = 370, + HSF_RGBA_ASTC_4x4x3_SRGB = 371, + HSF_RGBA_ASTC_4x4x4_SRGB = 372, + HSF_RGBA_ASTC_5x4x4_SRGB = 373, + HSF_RGBA_ASTC_5x5x4_SRGB = 374, + HSF_RGBA_ASTC_5x5x5_SRGB = 375, + HSF_RGBA_ASTC_6x5x5_SRGB = 376, + HSF_RGBA_ASTC_6x6x5_SRGB = 377, + HSF_RGBA_ASTC_6x6x6_SRGB = 378, + HSF_R64_UINT = 379, + HSF_R64G64_UINT = 380, + HSF_R64G64B64_UINT = 381, + HSF_R64G64B64A64_UINT = 382, + HSF_R64_SINT = 383, + HSF_R64G64_SINT = 384, + HSF_R64G64B64_SINT = 385, + HSF_R64G64B64A64_SINT = 386, + HSF_R4G4B4X4_UNORM = 387, + HSF_R5G5B5X1_UNORM = 388, + HSF_R8G8B8X8_SNORM = 389, + HSF_R8G8B8X8_UINT = 390, + HSF_R8G8B8X8_SINT = 391, + HSF_R8G8B8X8_UNORM_SRGB = 392, + HSF_R10G10B10X2_UNORM = 393, + HSF_R16G16B16X16_UNORM = 394, + HSF_R16G16B16X16_SNORM = 395, + HSF_R16G16B16X16_FLOAT = 396, + HSF_R16G16B16X16_UINT = 397, + HSF_R16G16B16X16_SINT = 398, + HSF_R32G32B32X32_FLOAT = 399, + HSF_R32G32B32X32_UINT = 400, + HSF_R32G32B32X32_SINT = 401, + + HSF_S8_UINT_D24_UNORM = 402, + HSF_D24_UNORM_S8_UINT = 403, + HSF_S8_UINT_D32_FLOAT = 404, + + HSF_R24_UNORM = 405, + HSF_R24G24_UNORM = 406, + HSF_R24G24B24A24_UNORM = 407, + HSF_R10G10B10A10_UNORM = 408, + HSF_BC1_TYPELESS = 409, + + HSF_B8G8R8A8_TYPELESS = 410, + HSF_B8G8R8X8_TYPELESS = 411, + HSF_BC2_TYPELESS = 412, + HSF_BC3_TYPELESS = 413, + HSF_BC4_TYPELESS = 414, + HSF_BC5_TYPELESS = 415, + HSF_BC6H_TYPELESS = 416 + +} Hw_Surf_Format; + +typedef enum COMPRESS_MXUFORMAT +{ + CP_OFF = 0, + CP_R8G8B8A8_T = 1, + CP_R8G8B8A8_L = 2, + CP_A8R8G8B8_T = 3, + CP_A8R8G8B8_L = 4, + CP_R10G10B10A2 = 5, + CP_A2B10G10R10 = 6, + CP_R11G11B10 = 7, + CP_R5G6B5 = 8, + CP_NV12 = 9, + CP_YUYV = 10, + CP_UYVY = 11, + CP_R10G10B10A2_T = 12, + CP_A2B10G10R10_T = 13, + CP_NV12_10 = 14, + CP_Z32 = 15, + CP_R16G16B16A16_T = 16, + CP_Z16 = 17, + CP_Z24 = 18, + CP_R11G11B10_T = 19, + CP_RGBAX8888_TILE_4X = 20, + CP_XARGB8888_TILE_4X = 21, + CP_Z16_4X = 22, + CP_Z24_4X = 23, + CP_Z32_4X = 24, + CP_RGBAX8888_TILE_2X = 25, + CP_XARGB8888_TILE_2X = 26, + CP_Z16_2X = 27, + CP_Z24_2X = 28, + CP_Z32_2X = 29, + CP_RGBAX8888_TILE_8X = 30, + CP_XARGB8888_TILE_8X = 31, + CP_Z16_8X = 32, + CP_Z24_8X = 33, + CP_Z32_8X = 34, + CP_BAYER = 35, + CP_R32G32B32A32_TILE = 36, + CP_RGBAX8888_TILE_16X = 37, + CP_XARGB8888_TILE_16X = 38, + CP_Z16_16X = 39, + CP_Z24_16X = 40, + CP_Z32_16X = 41, + CP_TOTAL_RANGE = 42, +}COMPRESS_MXUFORMAT; + +#define BIT_COUNT_TABLE \ +{\ + 8, /*HSF_UNKNOWN = 0*/\ + 256, /*HSF_R64G64B64A64_FLOAT = 1*/\ + 192, /*HSF_R64G64B64_FLOAT = 2*/\ + 128, /*HSF_R32G32B32A32_TYPELESS = 3*/\ + 128, /*HSF_R32G32B32A32_FLOAT = 4*/\ + 128, /*HSF_R32G32B32A32_UINT = 5*/\ + 128, /*HSF_R32G32B32A32_SINT = 6*/\ + 128, /*HSF_R32G32B32A32_SNORM = 7*/\ + 128, /*HSF_R32G32B32A32_SCALE = 8*/\ + 128, /*HSF_R32G32B32A32_UNORM = 9*/\ + 128, /*HSF_R32G32B32A32_USCALE = 10*/\ + 128, /*HSF_R32G32B32A32_FIX = 11*/\ + 128, /*HSF_R64G64_FLOAT = 12*/\ + 128, /*HSF_R32G32B32_TYPELESS = 13*/\ + 128, /*HSF_R32G32B32_FLOAT = 14*/\ + 128, /*HSF_R32G32B32_UINT = 15*/\ + 128, /*HSF_R32G32B32_SINT = 16*/\ + 128, /*HSF_R32G32B32_UNORM = 17*/\ + 128, /*HSF_R32G32B32_USCALE = 18*/\ + 128, /*HSF_R32G32B32_SNORM = 19*/\ + 128, /*HSF_R32G32B32_SCALE = 20*/\ + 128, /*HSF_R32G32B32_FIX = 21*/\ + 64, /*HSF_R16G16B16A16_TYPELESS = 22*/\ + 64, /*HSF_R16G16B16A16_FLOAT = 23*/\ + 64, /*HSF_R16G16B16A16_UNORM = 24*/\ + 64, /*HSF_R16G16B16A16_UINT = 25*/\ + 64, /*HSF_R16G16B16A16_SNORM = 26*/\ + 64, /*HSF_R16G16B16A16_SINT = 27*/\ + 64, /*HSF_R16G16B16A16_SCALE = 28*/\ + 64, /*HSF_R16G16B16A16_USCALE = 29*/\ + 64, /*HSF_R16G16B16A16_SSCALE = 30*/\ + 48, /*HSF_R12G12B12A12_UNORM = 31*/\ + 48, /*HSF_R16G16B16_FLOAT = 32*/\ + 48, /*HSF_R16G16B16_SINT = 33*/\ + 48, /*HSF_R16G16B16_SNORM = 34*/\ + 48, /*HSF_R16G16B16_SCALE = 35*/\ + 48, /*HSF_R16G16B16_UINT = 36*/\ + 48, /*HSF_R16G16B16_UNORM = 37*/\ + 48, /*HSF_R16G16B16_USCALE = 38*/\ + 64, /*HSF_R32G32_TYPELESS = 39*/\ + 64, /*HSF_R32G32_FLOAT = 40*/\ + 64, /*HSF_R32G32_UINT = 41*/\ + 64, /*HSF_R32G32_SINT = 42*/\ + 64, /*HSF_R32G32_SNORM = 43*/\ + 64, /*HSF_R32G32_SCALE = 44*/\ + 64, /*HSF_R32G32_UNORM = 45*/\ + 64, /*HSF_R32G32_USCALE = 46*/\ + 64, /*HSF_R32G32_FIX = 47*/\ + 64, /*HSF_R32G8X24_TYPELESS = 48*/\ + 64, /*HSF_D32_FLOAT_S8X24_UINT = 49*/\ + 64, /*HSF_R32_FLOAT_X8X24_TYPELESS = 50*/\ + 64, /*HSF_X32_TYPELESS_G8X24_UINT = 51*/\ + 64, /*HSF_R64_FLOAT = 52*/\ + 36, /*HSF_R12G12B12_UNORM = 53*/\ + 32, /*HSF_R10G10B10A2_TYPELESS = 54*/\ + 32, /*HSF_R10G10B10A2_UNORM = 55*/\ + 32, /*HSF_R10G10B10A2_UINT = 56*/\ + 32, /*HSF_R10G10B10X2_UINT = 57*/\ + 32, /*HSF_R10G10B10X2_USCALE = 58*/\ + 32, /*HSF_R10G10B10A2_SNORM = 59*/\ + 32, /*HSF_R10G10B10A2_SINT = 60*/\ + 32, /*HSF_R10G10B10X2_SNORM = 61*/\ + 32, /*HSF_B10G10R10A2_SNORM = 62*/\ + 32, /*HSF_B10G10R10A2_UNORM = 63*/\ + 32, /*HSF_B10G10R10X2_UNORM = 64*/\ + 32, /*HSF_A2B10G10R10_UNORM = 65*/\ + 32, /*HSF_A2B10G10R10_SNORM = 66*/\ + 32, /*HSF_A2B10G10R10_USCALE = 67*/\ + 32, /*HSF_A2B10G10R10_SSCALE = 68*/\ + 30, /*HSF_R10G10B10_SINT = 69*/\ + 30, /*HSF_R10G10B10_SNORM = 70*/\ + 30, /*HSF_R10G10B10_SCALE = 71*/\ + 30, /*HSF_R10G10B10_UNIT = 72*/\ + 30, /*HSF_R10G10B10_UNORM = 73*/\ + 30, /*HSF_R10G10B10_USCALE = 74*/\ + 20, /*HSF_R10G10_SINT = 75*/\ + 20, /*HSF_R10G10_SNORM = 76*/\ + 20, /*HSF_R10G10_SCALE = 77*/\ + 20, /*HSF_R10G10_UINT = 78*/\ + 20, /*HSF_R10G10_UNORM = 79*/\ + 20, /*HSF_R10G10_USCALE = 80*/\ + 32, /*HSF_R10G10B10_FLOAT_A2_UNORM = 81*/\ + 32, /*HSF_R11G11B10_FLOAT = 82*/\ + 32, /*HSF_B10G11R11_FLOAT = 83*/\ + 22, /*HSF_R11G11_FLOAT = 84*/\ + 32, /*HSF_R8G8B8A8_TYPELESS = 85*/\ + 32, /*HSF_R8G8B8A8_UNORM = 86*/\ + 32, /*HSF_R8G8B8A8_UNORM_SRGB = 87*/\ + 32, /*HSF_R8G8B8X8_UNORM = 88*/\ + 32, /*HSF_B8G8R8A8_UNORM = 89*/\ + 32, /*HSF_B8G8R8A8_UNORM_SRGB = 90*/\ + 32, /*HSF_B8G8R8X8_UNORM = 91*/\ + 32, /*HSF_B8G8R8X8_UNORM_SRGB = 92*/\ + 32, /*HSF_X8R8G8B8_UNORM = 93*/\ + 32, /*HSF_X8B8G8R8_UNORM = 94*/\ + 32, /*HSF_A8R8G8B8_UNORM = 95*/\ + 32, /*HSF_A8B8G8R8_UNORM = 96*/\ + 32, /*HSF_R8G8B8A8_UINT = 97*/\ + 32, /*HSF_R8G8B8A8_SNORM = 98*/\ + 32, /*HSF_R8G8B8A8_SINT = 99*/\ + 32, /*HSF_B8G8R8A8_XNORM = 100*/\ + 32, /*HSF_R8G8B8A8_SSCALE = 101*/\ + 32, /*HSF_R8G8B8A8_USCALE = 102*/\ + 24, /*HSF_R8G8B8_SINT = 103*/\ + 24, /*HSF_R8G8B8_SNORM = 104*/\ + 24, /*HSF_R8G8B8_SCALE = 105*/\ + 24, /*HSF_R8G8B8_UINT = 106*/\ + 24, /*HSF_R8G8B8_UNORM = 107*/\ + 24, /*HSF_R8G8B8_USCALE = 108*/\ + 32, /*HSF_R16G16_TYPELESS = 109*/\ + 32, /*HSF_R16G16_FLOAT = 110*/\ + 32, /*HSF_R16G16_UNORM = 111*/\ + 32, /*HSF_R16G16_UINT = 112*/\ + 32, /*HSF_R16G16_SNORM = 113*/\ + 32, /*HSF_R16G16_SINT = 114*/\ + 32, /*HSF_R16G16_SCALE = 115*/\ + 32, /*HSF_R16G16_USCALE = 116*/\ + 32, /*HSF_R16G16_SSCALE = 117*/\ + 32, /*HSF_R32_TYPELESS = 118*/\ + 32, /*HSF_D32_FLOAT = 119*/\ + 32, /*HSF_D32_UNORM = 120*/\ + 32, /*HSF_R32_FLOAT = 121*/\ + 32, /*HSF_R32_UINT = 122*/\ + 32, /*HSF_R32_SINT = 123*/\ + 32, /*HSF_R32_UNORM = 124*/\ + 32, /*HSF_R32_USCALE = 125*/\ + 32, /*HSF_R32_SNORM = 126*/\ + 32, /*HSF_R32_SCALE = 127*/\ + 32, /*HSF_R32_FIX = 128*/\ + 32, /*HSF_R24G8_TYPELESS = 129*/\ + 40, /*HSF_D32_FLOAT_S8_UINT = 130*/\ + 32, /*HSF_D24_UNORM_S8_UINT = 131*/\ + 32, /*HSF_R24_UNORM_X8_TYPELESS = 132*/\ + 32, /*HSF_X24_TYPELESS_G8_UINT = 133*/\ + 32, /*HSF_D24_UNORM = 134*/\ + 32, /*HSF_R24_FLOAT = 135*/\ + 16, /*HSF_R8G8_TYPELESS = 136*/\ + 16, /*HSF_R8G8_UNORM = 137*/\ + 16, /*HSF_R8G8_UINT = 138*/\ + 16, /*HSF_R8G8_SNORM = 139*/\ + 16, /*HSF_R8G8_SINT = 140*/\ + 16, /*HSF_R8G8_USCALE = 141*/\ + 16, /*HSF_R8G8_SSCALE = 142*/\ + 16, /*HSF_R16_TYPELESS = 143*/\ + 16, /*HSF_R16_FLOAT = 144*/\ + 16, /*HSF_D16_UNORM = 145*/\ + 16, /*HSF_R16_UNORM = 146*/\ + 16, /*HSF_R16_UINT = 147*/\ + 16, /*HSF_R16_SNORM = 148*/\ + 16, /*HSF_R16_SINT = 149*/\ + 16, /*HSF_R16_USCALE = 150*/\ + 16, /*HSF_R16_SSCALE = 151*/\ + 16, /*HSF_A16_UNORM = 152*/\ + 16, /*HSF_B5G6R5_UNORM = 153*/\ + 16, /*HSF_R5G6B5_UNORM = 154*/\ + 16, /*HSF_B5G5R5X1_UNORM = 155*/\ + 16, /*HSF_B5G5R5A1_UNORM = 156*/\ + 16, /*HSF_R5G5B5A1_UNORM = 157*/\ + 16, /*HSF_A1B5G5R5_UNORM = 158*/\ + 16, /*HSF_A1R5G5B5_UNORM = 159*/\ + 16, /*HSF_B4G4R4A4_UNORM = 160*/\ + 16, /*HSF_B4G4R4X4_UNORM = 161*/\ + 16, /*HSF_R4G4B4A4_UNORM = 162*/\ + 16, /*HSF_A4B4G4R4_UNORM = 163*/\ + 16, /*HSF_A4R4G4B4_UNORM = 164*/\ + 12, /*HSF_R4G4B4_UNORM = 165*/\ + 15, /*HSF_R5G5B5_UNORM = 166*/\ + 16, /*HSF_U5V5L6_XNORM = 167*/\ + 16, /*HSF_L16_UNORM = 168*/\ + 16, /*HSF_L8_A8_UNORM = 169*/\ + 10, /*HSF_R10_SINT = 170*/\ + 10, /*HSF_R10_SNORM = 171*/\ + 10, /*HSF_R10_SCALE = 172*/\ + 10, /*HSF_R10_UINT = 173*/\ + 10, /*HSF_R10_UNORM = 174*/\ + 10, /*HSF_R10_USCALE = 175*/\ + 8, /*HSF_R2G2B2A2_UNORM = 176*/\ + 8, /*HSF_R8_TYPELESS = 177*/\ + 8, /*HSF_R8_UNORM = 178*/\ + 8, /*HSF_R8_UINT = 179*/\ + 8, /*HSF_R8_SNORM = 180*/\ + 8, /*HSF_R8_SINT = 181*/\ + 8, /*HSF_R8_USCALE = 182*/\ + 8, /*HSF_R8_SSCALE = 183*/\ + 8, /*HSF_A8_UNORM = 184*/\ + 8, /*HSF_L8_UNORM = 185*/\ + 12, /*HSF_A12_UNORM = 186*/\ + 4, /*HSF_A4_UNORM = 187*/\ + 1, /*HSF_R1_UNORM = 188*/\ + 8, /*HSF_R3G3B2_UNORM = 189*/\ + 8, /*HSF_L4A4_UNORM = 190*/\ + 8, /*HSF_A4L4_UNORM = 191*/\ + 8, /*HSF_L4A4_VIDEO = 192*/\ + 32, /*HSF_AYUV_VIDEO = 193*/\ + 16, /*HSF_YUYV = 194*/\ + 8, /*HSF_NV12 = 195*/\ + 16, /*HSF_P010 = 196*/\ + 16, /*HSF_P016 = 197*/\ + 32, /*HSF_R9G9B9E5_SHAREDEXP = 198*/\ + 16, /*HSF_R8G8_B8G8_UNORM/ treate as UYVY = 199*/\ + 16, /*HSF_G8R8_G8B8_UNORM/ treate as YUYV = 200*/\ + 64, /*HSF_BC1_UNORM = 201*/\ + 64, /*HSF_BC1_UNORM_SRGB = 202*/\ + 128, /*HSF_BC2_UNORM = 203*/\ + 128, /*HSF_BC2_UNORM_SRGB = 204*/\ + 128, /*HSF_BC3_UNORM = 205*/\ + 128, /*HSF_BC3_UNORM_SRGB = 206*/\ + 64, /*HSF_BC4_UNORM = 207*/\ + 64, /*HSF_BC4_SNORM = 208*/\ + 64, /*HSF_BC4_UNORM_L = 209*/\ + 64, /*HSF_BC4_SNORM_L = 210*/\ + 128, /*HSF_BC5_UNORM = 211*/\ + 128, /*HSF_BC5_SNORM = 212*/\ + 128, /*HSF_BC5_UNORM_LA = 213*/\ + 128, /*HSF_BC5_SNORM_LA = 214*/\ + 128, /*HSF_BC6H_UF16 = 215*/\ + 128, /*HSF_BC6H_SF16 = 216*/\ + 128, /*HSF_BC7_UNORM = 217*/\ + 128, /*HSF_BC7_UNORM_SRGB = 218*/\ + 8, /*HSF_G8_UINT = 219*/\ + 128, /*HSF_3DC_UNORM = 220*/\ + 16, /*HSF_YUY2 = 221*/\ + 32, /*HSF_Y216_VIDEO = 222*/\ + 32, /*HSF_Y210_VIDEO = 223*/\ + 8, /*HSF_A4I4_VIDEO = 224*/\ + 16, /*HSF_A8L8_UNORM = 225*/\ + 16, /*HSF_L8A8_UNORM = 226*/\ + 0, /*HSF_ZL1 = 227*/\ + 64, /*HSF_R16G16B16A16_UNORM_SRGB = 228*/\ + 8, /*HSF_YCRCB_MB_8_422 = 229*/\ + 8, /*HSF_YCRCB_MB_8_420 = 230*/\ + 0, /*HSF_YCRCB_MB_16_422 = 231*/\ + 16, /*HSF_P016T = 232*/\ + 32, /*HSF_UYVA1010102_VIDEO = 233*/\ + 16, /*HSF_UYVY = 234*/\ + 16, /*HSF_BAYER_12 = 235*/\ + 16, /*HSF_BAYER = 236*/\ + 16, /*HSF_P016L = 237*/\ + 8, /*HSF_YV12 = 238*/\ + 16, /*HSF_L8A8_SNORM = 239*/\ + 1, /*HSF_S1_UINT = 240*/\ + 16, /*HSF_S16_UINT = 241*/\ + 4, /*HSF_S4_UINT = 242*/\ + 8, /*HSF_S8_UINT = 243*/\ + 0, /*HSF_I12_UNORM = 244*/\ + 16, /*HSF_I16_UNORM = 245*/\ + 0, /*HSF_I4_UNORM = 246*/\ + 8, /*HSF_I8_UNORM = 247*/\ + 0, /*HSF_L12_UNORM = 248*/\ + 0, /*HSF_L12_A12_UNORM = 249*/\ + 0, /*HSF_L12_A4_UNORM = 250*/\ + 32, /*HSF_L16_A16_UNORM = 251*/\ + 0, /*HSF_L4_UNORM = 252*/\ + 0, /*HSF_L4_A4_UNORM = 253*/\ + 0, /*HSF_L6_A2_UNORM = 254*/\ + 64, /*HSF_RGB8_ETC2 = 255*/\ + 64, /*HSF_SRGB8_ETC2 = 256*/\ + 128, /*HSF_RGBA8_ETC2_EAC = 257*/\ + 128, /*HSF_SRGB8_ALPHA8_ETC2_EAC = 258*/\ + 64, /*HSF_R11_EAC = 259*/\ + 128, /*HSF_RG11_EAC = 260*/\ + 64, /*HSF_SIGNED_R11_EAC = 261*/\ + 128, /*HSF_SIGNED_RG11_EAC = 262*/\ + 64, /*HSF_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 263*/\ + 64, /*HSF_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 264*/\ + 0, /*HSF_COMPRESSED_ALPHA = 265*/\ + 0, /*HSF_COMPRESSED_INTENSITY = 266*/\ + 0, /*HSF_COMPRESSED_LUMINANCE = 267*/\ + 0, /*HSF_COMPRESSED_RED = 268*/\ + 64, /*HSF_COMPRESSED_RED_RGTC1 = 269*/\ + 0, /*HSF_COMPRESSED_RG = 270*/\ + 128, /*HSF_COMPRESSED_RG_RGTC2 = 271*/\ + 0, /*HSF_COMPRESSED_RGB = 272*/\ + 128, /*HSF_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 273*/\ + 128, /*HSF_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 274*/\ + 0, /*HSF_COMPRESSED_RGBA = 275*/\ + 128, /*HSF_COMPRESSED_RGBA_BPTC_UNORM = 276*/\ + 64, /*HSF_COMPRESSED_SIGNED_RED_RGTC1 = 277*/\ + 128, /*HSF_COMPRESSED_SIGNED_RG_RGTC2 = 27*/\ + 0, /*HSF_COMPRESSED_SLUMINANCE = 279*/\ + 0, /*HSF_COMPRESSED_SLUMINANCE_ALPHA = 280*/\ + 0, /*HSF_COMPRESSED_SRGB = 281*/\ + 0, /*HSF_COMPRESSED_SRGB_ALPHA = 282*/\ + 128, /*HSF_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 283*/\ + 32, /*HSF_R10G10B10A2_USCALE = 284*/\ + 32, /*HSF_R10G10B10A2_SSCALE = 285*/\ + 128, /*HSF_R32G32B32A32_SSCALE = 286*/\ + 128, /*HSF_R32G32B32_SSCALE = 287*/\ + 64, /*HSF_R32G32_SSCALE = 288*/\ + 48, /*HSF_R16G16B16_SSCALE = 289*/\ + 32, /*HSF_R32_SSCALE = 290*/\ + 24, /*HSF_R8G8B8_SSCALE = 291*/\ + 0, /*HSF_UNKOWN = 292*/\ + 0, /*HSF_UNKOWN = 293*/\ + 0, /*HSF_UNKOWN = 294*/\ + 0, /*HSF_UNKOWN = 295*/\ + 0, /*HSF_UNKOWN = 296*/\ + 0, /*HSF_UNKOWN = 297*/\ + 0, /*HSF_UNKOWN = 298*/\ + 0, /*HSF_UNKOWN = 299*/\ + 0, /*HSF_UNKOWN = 300*/\ + 0, /*HSF_UNKOWN = 301*/\ + 0, /*HSF_UNKOWN = 302*/\ + 0, /*HSF_UNKOWN = 303*/\ + 0, /*HSF_UNKOWN = 304*/\ + 0, /*HSF_UNKOWN = 305*/\ + 0, /*HSF_UNKOWN = 306*/\ + 0, /*HSF_UNKOWN = 307*/\ + 0, /*HSF_UNKOWN = 308*/\ + 0, /*HSF_UNKOWN = 309*/\ + 0, /*HSF_UNKOWN = 310*/\ + 0, /*HSF_UNKOWN = 311*/\ + 0, /*HSF_UNKOWN = 312*/\ + 0, /*HSF_UNKOWN = 313*/\ + 0, /*HSF_UNKOWN = 314*/\ + 0, /*HSF_UNKOWN = 315*/\ + 0, /*HSF_UNKOWN = 316*/\ + 0, /*HSF_UNKOWN = 317*/\ + 0, /*HSF_UNKOWN = 318*/\ + 0, /*HSF_UNKOWN = 319*/\ + 0, /*HSF_UNKOWN = 320*/\ + 128, /*HSF_RGBA_ASTC_4X4 = 321*/\ + 128, /*HSF_RGBA_ASTC_5X4 = 322*/\ + 128, /*HSF_RGBA_ASTC_5X5 = 323*/\ + 128, /*HSF_RGBA_ASTC_6X5 = 324*/\ + 128, /*HSF_RGBA_ASTC_6X6 = 325*/\ + 128, /*HSF_RGBA_ASTC_8X5 = 326*/\ + 128, /*HSF_RGBA_ASTC_8X6 = 327*/\ + 128, /*HSF_RGBA_ASTC_8X8 = 328*/\ + 128, /*HSF_RGBA_ASTC_10X5 = 329*/\ + 128, /*HSF_RGBA_ASTC_10X6 = 330*/\ + 128, /*HSF_RGBA_ASTC_10X8 = 331*/\ + 128, /*HSF_RGBA_ASTC_10X10 = 332*/\ + 128, /*HSF_RGBA_ASTC_12X10 = 333*/\ + 128, /*HSF_RGBA_ASTC_12X12 = 334*/\ + 0, /*HSF_RESERVED0 = 335*/\ + 0, /*HSF_RESERVED1 = 336*/\ + 128, /*HSF_RGBA_ASTC_4X4_SRGB = 337*/\ + 128, /*HSF_RGBA_ASTC_5X4_SRGB = 338*/\ + 128, /*HSF_RGBA_ASTC_5X5_SRGB = 339*/\ + 128, /*HSF_RGBA_ASTC_6X5_SRGB = 340*/\ + 128, /*HSF_RGBA_ASTC_6X6_SRGB = 341*/\ + 128, /*HSF_RGBA_ASTC_8X5_SRGB = 342*/\ + 128, /*HSF_RGBA_ASTC_8X6_SRGB = 343*/\ + 128, /*HSF_RGBA_ASTC_8X8_SRGB = 344*/\ + 128, /*HSF_RGBA_ASTC_10X5_SRGB = 345*/\ + 128, /*HSF_RGBA_ASTC_10X6_SRGB = 346*/\ + 128, /*HSF_RGBA_ASTC_10X8_SRGB = 347*/\ + 128, /*HSF_RGBA_ASTC_10X10_SRGB = 348*/\ + 128, /*HSF_RGBA_ASTC_12X10_SRGB = 349*/\ + 128, /*HSF_RGBA_ASTC_12X12_SRGB = 350*/\ + 0, /*HSF_RESERVED2 = 351*/\ + 0, /*HSF_RESERVED3 = 352*/\ + 128, /*HSF_RGBA_ASTC_3x3x3 = 353,*/\ + 128, /*HSF_RGBA_ASTC_4x3x3 = 354,*/\ + 128, /*HSF_RGBA_ASTC_4x4x3 = 355,*/\ + 128, /*HSF_RGBA_ASTC_4x4x4 = 356,*/\ + 128, /*HSF_RGBA_ASTC_5x4x4 = 357,*/\ + 128, /*HSF_RGBA_ASTC_5x5x4 = 358,*/\ + 128, /*HSF_RGBA_ASTC_5x5x5 = 359,*/\ + 128, /*HSF_RGBA_ASTC_6x5x5 = 360,*/\ + 128, /*HSF_RGBA_ASTC_6x6x5 = 361,*/\ + 128, /*HSF_RGBA_ASTC_6x6x6 = 362,*/\ + 32, /*HSF_L16A16_UNORM = 363,*/\ + 32, /*HSF_L16A16_SNORM = 364,*/\ + 0, /*HSF_ASTC_RESERVED6 = 365,*/\ + 0, /*HSF_ASTC_RESERVED7 = 366,*/\ + 0, /*HSF_ASTC_RESERVED8 = 367,*/\ + 0, /*HSF_ASTC_RESERVED9 = 368,*/\ + 128, /*HSF_RGBA_ASTC_3x3x3_SRGB = 369, */\ + 128, /*HSF_RGBA_ASTC_4x3x3_SRGB = 370, */\ + 128, /*HSF_RGBA_ASTC_4x4x3_SRGB = 371, */\ + 128, /*HSF_RGBA_ASTC_4x4x4_SRGB = 372, */\ + 128, /*HSF_RGBA_ASTC_5x4x4_SRGB = 373, */\ + 128, /*HSF_RGBA_ASTC_5x5x4_SRGB = 374,*/\ + 128, /*HSF_RGBA_ASTC_5x5x5_SRGB = 375, */\ + 128, /*HSF_RGBA_ASTC_6x5x5_SRGB = 376, */\ + 128, /*HSF_RGBA_ASTC_6x6x5_SRGB = 377, */\ + 128, /*HSF_RGBA_ASTC_6x6x6_SRGB = 378,*/\ + 64, /*HSF_R64_UINT = 379,*/\ + 128, /*HSF_R64G64_UINT = 380,*/\ + 192, /*HSF_R64G64B64_UINT = 381,*/\ + 256, /*HSF_R64G64B64A64_UINT = 382,*/\ + 64, /*HSF_R64_SINT = 383,*/\ + 128, /*HSF_R64G64_SINT = 384,*/\ + 192, /*HSF_R64G64B64_SINT = 385,*/\ + 256, /*HSF_R64G64B64A64_SINT = 386,*/\ + 16, /*HSF_R4G4B4X4_UNORM = 387,*/\ + 16, /*HSF_R5G5B5X1_UNORM = 388,*/\ + 32, /*HSF_R8G8B8X8_SNORM = 389,*/\ + 32, /*HSF_R8G8B8X8_UINT = 390,*/\ + 32, /*HSF_R8G8B8X8_SINT = 391,*/\ + 32, /*HSF_R8G8B8X8_UNORM_SRGB = 392,*/\ + 32, /*HSF_R10G10B10X2_UNORM = 393,*/\ + 64, /*HSF_R16G16B16X16_UNORM = 394,*/\ + 64, /*HSF_R16G16B16X16_SNORM = 395,*/\ + 64, /*HSF_R16G16B16X16_FLOAT = 396,*/\ + 64, /*HSF_R16G16B16X16_UINT = 397,*/\ + 64, /*HSF_R16G16B16X16_SINT = 398,*/\ + 128, /*HSF_R32G32B32X32_FLOAT = 399,*/\ + 128, /*HSF_R32G32B32X32_UINT = 400,*/\ + 128, /*HSF_R32G32B32X32_SINT = 401,*/\ + 32, /*HSF_S8_UINT_D24_UNORM = 402,*/\ + 32, /*HSF_D24_UNORM_S8_UINT = 403,*/\ + 64, /*HSF_S8_UINT_D32_FLOAT = 404,*/\ + 32, /*HSF_R24_UNORM = 405,*/\ + 64, /*HSF_R24G24_UNORM = 406,*/\ + 128, /*HSF_R24G24B24A24_UNORM = 407,*/\ + 64, /*HSF_R10G10B10A10_UNORM = 408,*/\ + 64, /*HSF_BC1_TYPELESS = 409,*/\ + 32, /*HSF_B8G8R8A8_TYPELESS = 410,*/\ + 32, /*HSF_B8G8R8X8_TYPELESS = 411,*/\ + 128, /*HSF_BC2_TYPELESS = 412,*/\ + 128, /*HSF_BC3_TYPELESS = 413,*/\ + 64, /*HSF_BC4_TYPELESS = 414,*/\ + 128, /*HSF_BC5_TYPELESS = 415,*/\ + 128, /*HSF_BC6H_TYPELESS = 416,*/\ + }\ + + + + +#define SURFACE_FORMAT_MODE \ + {\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_UNKNOWN = 0, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R64G64B64A64_FLOAT = 1, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R64G64B64_FLOAT = 2, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32A32_TYPELESS = 3, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32A32_FLOAT = 4, */\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /* HSF_R32G32B32A32_UINT = 5, */\ + PS_OUT_FMT_O0_DATA_FMT_SINT32, /* HSF_R32G32B32A32_SINT = 6, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32A32_SNORM = 7, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32A32_SCALE = 8, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32A32_UNORM = 9, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32A32_USCALE = 10, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32A32_FIX = 11, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R64G64_FLOAT = 12, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32_TYPELESS = 13, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32_FLOAT = 14, */\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /* HSF_R32G32B32_UINT = 15, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32_SINT = 16, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32_UNORM = 17, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32_USCALE = 18, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32_SNORM = 19, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32_SCALE = 20, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32B32_FIX = 21, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /* HSF_R16G16B16A16_TYPELESS = 22, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /* HSF_R16G16B16A16_FLOAT = 23, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM16, /* HSF_R16G16B16A16_UNORM = 24, */\ + PS_OUT_FMT_O0_DATA_FMT_UINT16, /* HSF_R16G16B16A16_UINT = 25, */\ + PS_OUT_FMT_O0_DATA_FMT_SNORM16, /* HSF_R16G16B16A16_SNORM = 26, */\ + PS_OUT_FMT_O0_DATA_FMT_SINT16, /* HSF_R16G16B16A16_SINT = 27, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R16G16B16A16_SCALE = 28, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R16G16B16A16_USCALE = 29, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R16G16B16A16_SSCALE = 30, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM16, /* HSF_R12G12B12A12_UNORM = 31, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /* HSF_R16G16B16_FLOAT = 32, */\ + PS_OUT_FMT_O0_DATA_FMT_SINT16, /* HSF_R16G16B16_SINT = 33, */\ + PS_OUT_FMT_O0_DATA_FMT_SNORM16, /* HSF_R16G16B16_SNORM = 34, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R16G16B16_SCALE = 35, */\ + PS_OUT_FMT_O0_DATA_FMT_UINT16, /* HSF_R16G16B16_UINT = 36, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM16, /* HSF_R16G16B16_UNORM = 37, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R16G16B16_USCALE = 38, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32_TYPELESS = 39, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32_FLOAT = 40, */\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /* HSF_R32G32_UINT = 41, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32_SINT = 42, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32_SNORM = 43, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32_SCALE = 44, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32_UNORM = 45, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32_USCALE = 46, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G32_FIX = 47, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32G8X24_TYPELESS = 48, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_D32_FLOAT_S8X24_UINT = 49, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R32_FLOAT_X8X24_TYPELESS = 50, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_X32_TYPELESS_G8X24_UINT = 51, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R64_FLOAT = 52, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R12G12B12_UNORM = 53, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10B10A2_TYPELESS = 54, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10B10A2_UNORM = 55, */\ + PS_OUT_FMT_O0_DATA_FMT_UINT16, /* HSF_R10G10B10A2_UINT = 56, */\ + PS_OUT_FMT_O0_DATA_FMT_UINT16, /* HSF_R10G10B10X2_UINT = 57, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10B10X2_USCALE = 58, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10B10A2_SNORM = 59, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10B10A2_SINT = 60, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10B10X2_SNORM = 61, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_B10G10R10A2_SNORM = 62, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_B10G10R10A2_UNORM = 63, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_B10G10R10X2_UNORM = 64, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_A2B10G10R10_UNORM = 65, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_A2B10G10R10_SNORM = 66, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_A2B10G10R10_USCALE = 67, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_A2B10G10R10_SSCALE = 68, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10B10_SINT = 69, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10B10_SNORM = 70, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R10G10B10_SCALE = 71, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10B10_UNIT = 72, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10B10_UNORM = 73, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R10G10B10_USCALE = 74, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10_SINT = 75, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10_SNORM = 76, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R10G10_SCALE = 77, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10_UINT = 78, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /* HSF_R10G10_UNORM = 79, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R10G10_USCALE = 80, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_R10G10B10_FLOAT_A2_UNORM = 81, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /* HSF_R11G11B10_FLOAT = 82, */\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /* HSF_B10G11R11_FLOAT = 83, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /* HSF_R11G11_FLOAT = 84, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /* HSF_R8G8B8A8_TYPELESS = 85, */\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /* HSF_R8G8B8A8_UNORM = 86, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_R8G8B8A8_UNORM_SRGB = 87*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R8G8B8X8_UNORM = 88*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_B8G8R8A8_UNORM = 89*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_B8G8R8A8_UNORM_SRGB = 90*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_B8G8R8X8_UNORM = 91*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_B8G8R8X8_UNORM_SRGB = 92*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_X8R8G8B8_UNORM = 93*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_X8B8G8R8_UNORM = 94*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_A8R8G8B8_UNORM = 95*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_A8B8G8R8_UNORM = 96*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT8, /*HSF_R8G8B8A8_UINT = 97*/\ + PS_OUT_FMT_O0_DATA_FMT_SNORM8, /*HSF_R8G8B8A8_SNORM = 98*/\ + PS_OUT_FMT_O0_DATA_FMT_SINT8, /*HSF_R8G8B8A8_SINT = 99*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_B8G8R8A8_XNORM = 100?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R8G8B8A8_SSCALE = 101?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R8G8B8A8_USCALE = 102*/\ + PS_OUT_FMT_O0_DATA_FMT_SINT8, /*HSF_R8G8B8_SINT = 103*/\ + PS_OUT_FMT_O0_DATA_FMT_SNORM8, /*HSF_R8G8B8_SNORM = 104*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R8G8B8_SCALE = 105?*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT8, /*HSF_R8G8B8_UINT = 106*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R8G8B8_UNORM = 107*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R8G8B8_USCALE = 108?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_R16G16_TYPELESS = 109?0*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_R16G16_FLOAT = 110*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM16, /*HSF_R16G16_UNORM = 111*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT16, /*HSF_R16G16_UINT = 112*/\ + PS_OUT_FMT_O0_DATA_FMT_SNORM16, /*HSF_R16G16_SNORM = 113*/\ + PS_OUT_FMT_O0_DATA_FMT_SINT16, /*HSF_R16G16_SINT = 114*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R16G16_SCALE = 115?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R16G16_USCALE = 116?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R16G16_SSCALE = 117?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32_TYPELESS = 118?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_D32_FLOAT = 119*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_D32_UNORM = 120?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32_FLOAT = 121*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32_UINT = 122?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32_SINT = 123?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32_UNORM = 124?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32_USCALE = 125*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32_SNORM = 126*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32_SCALE = 127*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32_FIX = 128*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R24G8_TYPELESS = 129*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_D32_FLOAT_S8_UINT = 130*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_D24_UNORM_S8_UINT = 131*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R24_UNORM_X8_TYPELESS = 132*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_X24_TYPELESS_G8_UINT = 133*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM24, /*HSF_D24_UNORM = 134*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R24_FLOAT = 135*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R8G8_TYPELESS = 136?0*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R8G8_UNORM = 137*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT8, /*HSF_R8G8_UINT = 138*/\ + PS_OUT_FMT_O0_DATA_FMT_SNORM8, /*HSF_R8G8_SNORM = 139*/\ + PS_OUT_FMT_O0_DATA_FMT_SINT8, /*HSF_R8G8_SINT = 140*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R8G8_USCALE = 141*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R8G8_SSCALE = 142*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R16_TYPELESS = 143*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_R16_FLOAT = 144*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM16, /*HSF_D16_UNORM = 145*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM16, /*HSF_R16_UNORM = 146*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT16, /*HSF_R16_UINT = 147*/\ + PS_OUT_FMT_O0_DATA_FMT_SNORM16, /*HSF_R16_SNORM = 148*/\ + PS_OUT_FMT_O0_DATA_FMT_SINT16, /*HSF_R16_SINT = 149*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R16_USCALE = 150?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R16_SSCALE = 151?*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM16, /*HSF_A16_UNORM = 152*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_B5G6R5_UNORM = 153*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R5G6B5_UNORM = 154*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_B5G5R5X1_UNORM = 155*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_B5G5R5A1_UNORM = 156*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R5G5B5A1_UNORM = 157*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_A1B5G5R5_UNORM = 158*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_A1R5G5B5_UNORM = 159*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_B4G4R4A4_UNORM = 160*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_B4G4R4X4_UNORM = 161*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R4G4B4A4_UNORM = 162*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_A4B4G4R4_UNORM = 163*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_A4R4G4B4_UNORM = 164*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R4G4B4_UNORM = 165*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R5G5B5_UNORM = 166*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_U5V5L6_XNORM = 167?0*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM16, /*HSF_L16_UNORM = 168*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_L8_A8_UNORM = 169*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R10_SINT = 170?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R10_SNORM = 171?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R10_SCALE = 172?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R10_UINT = 173?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R10_UNORM = 174?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R10_USCALE = 175?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R2G2B2A2_UNORM = 176?*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R8_TYPELESS = 177?0*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R8_UNORM = 178*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT8, /*HSF_R8_UINT = 179*/\ + PS_OUT_FMT_O0_DATA_FMT_SNORM8, /*HSF_R8_SNORM = 180*/\ + PS_OUT_FMT_O0_DATA_FMT_SINT8, /*HSF_R8_SINT = 181*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R8_USCALE = 182?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R8_SSCALE = 183?*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_A8_UNORM = 184*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_L8_UNORM = 185*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_A12_UNORM = 186*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_A4_UNORM = 187*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R1_UNORM = 188*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R3G3B2_UNORM = 189*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_L4A4_UNORM = 190*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_A4L4_UNORM = 191*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_L4A4_VIDEO = 192*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /*HSF_AYUV_VIDEO = 193*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_YUYV = 194*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_NV12 = 195?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_P010 = 196?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_P016 = 197?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R9G9B9E5_SHAREDEXP = 198?UINT16*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R8G8_B8G8_UNORM = 199*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_G8R8_G8B8_UNORM = 200*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC1_UNORM = 201*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC1_UNORM_SRGB = 202*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_BC2_UNORM = 203*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC2_UNORM_SRGB = 204*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_BC3_UNORM = 205*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC3_UNORM_SRGB = 206*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC4_UNORM = 207*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC4_SNORM = 208*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC4_UNORM_L = 209*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC4_SNORM_L = 210*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_BC5_UNORM = 211*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_BC5_SNORM = 212*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_BC5_UNORM_LA = 213*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_BC5_SNORM_LA = 214*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_BC6H_UF16 = 215*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_BC6H_SF16 = 216*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_BC7_UNORM = 217*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC7_UNORM_SRGB = 218*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT8, /*HSF_G8_UINT = 219?0?UNORM8*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_3DC_UNORM = 220*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_YUY2 = 221*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_Y216_VIDEO = 222*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_Y210_VIDEO = 223*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_A4I4_VIDEO = 224?0*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_A8L8_UNORM = 225*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_L8A8_UNORM = 226*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_ZL1 = 227*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R16G16B16A16_UNORM_SRGB = 228*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_YCRCB_MB_8_422 = 229*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_YCRCB_MB_8_420 = 230*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_YCRCB_MB_16_422 = 231*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_P016T = 232?*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /*HSF_UYVA1010102_VIDEO = 233?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_UYVY = 234?PS_OUT_FMT_O0_DATA_FMT_UNORM10*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM16, /*HSF_BAYER_12 = 235?0*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM16, /*HSF_BAYER = 236?0*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_P016L = 237?*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_YV12 = 238*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_NV12T = 239*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_S1_UINT = 240*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_S16_UINT = 241*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_S4_UINT = 242*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_S8_UINT = 243*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_I12_UNORM = 244*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_I16_UNORM = 245*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_I4_UNORM = 246*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_I8_UNORM = 247*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_L12_UNORM = 248*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_L12_A12_UNORM = 249*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_L12_A4_UNORM = 250*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_L16_A16_UNORM = 251*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_L4_UNORM = 252*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_L4_A4_UNORM = 253*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_L6_A2_UNORM = 254*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGB8_ETC2 = 255?0*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_SRGB8_ETC2 = 256?0*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA8_ETC2_EAC = 257*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_SRGB8_ALPHA8_ETC2_EAC = 258*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_R11_EAC = 259?0*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RG11_EAC = 260*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_SIGNED_R11_EAC = 261*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_SIGNED_RG11_EAC = 262*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 263*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 264*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_ALPHA = 265*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_INTENSITY = 266*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_LUMINANCE = 267*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_RED = 268*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_RED_RGTC1 = 269*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_RG = 270*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_RG_RGTC2 = 271*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_RGB = 272*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 273*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 274*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_RGBA = 275*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_RGBA_BPTC_UNORM = 276*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_SIGNED_RED_RGTC1 = 277*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_SIGNED_RG_RGTC2 = 27*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_SLUMINANCE = 279*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_SLUMINANCE_ALPHA = 280*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_COMPRESSED_SRGB = 281*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_SRGB_ALPHA = 282*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 283*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R10G10B10A2_USCALE = 284?0*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R10G10B10A2_SSCALE = 285*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32G32B32A32_SSCALE = 286,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32G32B32_SSCALE = 287,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32G32_SSCALE = 288,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R16G16B16_SSCALE = 289,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32_SSCALE = 290,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R8G8B8_SSCALE = 291,*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 292*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 293*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 294*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 295*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 296*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 297*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 298*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 299*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 300*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 301*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 302*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 303*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 304*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 305*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 306*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 307*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 308*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 309*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 310*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 311*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 312*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 313*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 314*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 315*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 316*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 317*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 318*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 319*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 320*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_4X4 = 321*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_5X4 = 322*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_5X5 = 323*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_6X5 = 324*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_6X6 = 325*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_8X5 = 326*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_8X6 = 327*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_8X8 = 328*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_10X5 = 329*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_10X6 = 330*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_10X8 = 331*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_10X10 = 332*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_12X10 = 333*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_12X12 = 334*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_RESERVED0 = 335*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_RESERVED1 = 336*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_4X4_SRGB = 337*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_5X4_SRGB = 338*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_5X5_SRGB = 339*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_6X5_SRGB = 340*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_6X6_SRGB = 341*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_8X5_SRGB = 342*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_8X6_SRGB = 343*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_8X8_SRGB = 344*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_10X5_SRGB = 345*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_10X6_SRGB = 346*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_10X8_SRGB = 347*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_10X10_SRGB = 348*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_12X10_SRGB = 349*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_12X12_SRGB = 350*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_RESERVED2 = 351*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_RESERVED3 = 352*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_3x3x3 = 353,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_4x3x3 = 354,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_4x4x3 = 355,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_4x4x4 = 356,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_5x4x4 = 357,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_5x5x4 = 358,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_5x5x5 = 359,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_6x5x5 = 360,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_6x6x5 = 361,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_RGBA_ASTC_6x6x6 = 362,*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED4 = 363,*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED5 = 364,*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED6 = 365,*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED7 = 366,*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED8 = 367,*/\ + PS_OUT_FMT_O0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED9 = 368,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_3x3x3_SRGB = 369, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_4x3x3_SRGB = 370, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_4x4x3_SRGB = 371, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_4x4x4_SRGB = 372, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_5x4x4_SRGB = 373, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_5x5x4_SRGB = 374,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_5x5x5_SRGB = 375, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_6x5x5_SRGB = 376, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_6x6x5_SRGB = 377, */\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_RGBA_ASTC_6x6x6_SRGB = 378,*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /*HSF_R64_UINT = 379,*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /*HSF_R64G64_UINT = 380,*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /*HSF_R64G64B64_UINT = 381,*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /*HSF_R64G64B64A64_UINT = 382,*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /*HSF_R64_SINT = 383,*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /*HSF_R64G64_SINT = 384,*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /*HSF_R64G64B64_SINT = 385,*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /*HSF_R64G64B64A64_SINT = 386,*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R4G4B4X4_UNORM = 387,*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R5G5B5X1_UNORM = 388,*/\ + PS_OUT_FMT_O0_DATA_FMT_SNORM8, /*HSF_R8G8B8X8_SNORM = 389,*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT8, /*HSF_R8G8B8X8_UINT = 390,*/\ + PS_OUT_FMT_O0_DATA_FMT_SINT8, /*HSF_R8G8B8X8_SINT = 391,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_R8G8B8X8_UNORM_SRGB = 392,*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_R10G10B10X2_UNORM = 393,*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM16, /*HSF_R16G16B16X16_UNORM = 394,*/\ + PS_OUT_FMT_O0_DATA_FMT_SNORM16, /*HSF_R16G16B16X16_SNORM = 395,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_R16G16B16X16_FLOAT = 396,*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT16, /*HSF_R16G16B16X16_UINT = 397,*/\ + PS_OUT_FMT_O0_DATA_FMT_SINT16, /*HSF_R16G16B16X16_SINT = 398,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_R32G32B32X32_FLOAT = 399,*/\ + PS_OUT_FMT_O0_DATA_FMT_UINT32, /*HSF_R32G32B32X32_UINT = 400,*/\ + PS_OUT_FMT_O0_DATA_FMT_SINT32, /*HSF_R32G32B32X32_SINT = 401,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_S8_UINT_D24_UNORM = 402,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_D24_UNORM_S8_UINT = 403,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_S8_UINT_D32_FLOAT = 404,*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM24, /*HSF_R24_UNORM = 405,*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM24, /*HSF_R24G24_UNORM = 406,*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM24, /*HSF_R24G24B24A24_UNORM = 407,*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM10, /*HSF_R10G10B10A10_UNORM = 408,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC1_TYPELESS = 409,*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_B8G8R8A8_TYPELESS = 410,*/\ + PS_OUT_FMT_O0_DATA_FMT_UNORM8, /*HSF_B8G8R8X8_TYPELESS = 411,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC2_TYPELESS = 412,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC3_TYPELESS = 413,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP16, /*HSF_BC4_TYPELESS = 414,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*HSF_BC5_TYPELESS = 415,*/\ + PS_OUT_FMT_O0_DATA_FMT_FP32, /*DXGI_FORMAT_BC6H_TYPELESS = 416,*/\ + } + + +#define UAV_FORMAT \ +{\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_UNKNOWN = 0, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R64G64B64A64_FLOAT = 1, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R64G64B64_FLOAT = 2, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32A32_TYPELESS = 3, */\ + CS_U_FMT_U0_DATA_FMT_FP32, /* HSF_R32G32B32A32_FLOAT = 4, */\ + CS_U_FMT_U0_DATA_FMT_UINT32, /* HSF_R32G32B32A32_UINT = 5, */\ + CS_U_FMT_U0_DATA_FMT_SINT32, /* HSF_R32G32B32A32_SINT = 6, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32A32_SNORM = 7, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32A32_SCALE = 8, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32A32_UNORM = 9, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32A32_USCALE = 10, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32A32_FIX = 11, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R64G64_FLOAT = 12, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32_TYPELESS = 13, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32_FLOAT = 14, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32_UINT = 15, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32_SINT = 16, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32_UNORM = 17, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32_USCALE = 18, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32_SNORM = 19, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32_SCALE = 20, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32B32_FIX = 21, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R16G16B16A16_TYPELESS = 22, */\ + CS_U_FMT_U0_DATA_FMT_FP16, /* HSF_R16G16B16A16_FLOAT = 23, */\ + CS_U_FMT_U0_DATA_FMT_UNORM16, /* HSF_R16G16B16A16_UNORM = 24, */\ + CS_U_FMT_U0_DATA_FMT_UINT16, /* HSF_R16G16B16A16_UINT = 25, */\ + CS_U_FMT_U0_DATA_FMT_SNORM16, /* HSF_R16G16B16A16_SNORM = 26, */\ + CS_U_FMT_U0_DATA_FMT_SINT16, /* HSF_R16G16B16A16_SINT = 27, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R16G16B16A16_SCALE = 28, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R16G16B16A16_USCALE = 29, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R16G16B16A16_SSCALE = 30, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R12G12B12A12_UNORM = 31, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R16G16B16_FLOAT = 32, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R16G16B16_SINT = 33, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R16G16B16_SNORM = 34, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R16G16B16_SCALE = 35, */\ + CS_U_FMT_U0_DATA_FMT_UINT16, /* HSF_R16G16B16_UINT = 36, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R16G16B16_UNORM = 37, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R16G16B16_USCALE = 38, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32_TYPELESS = 39, */\ + CS_U_FMT_U0_DATA_FMT_FP32, /* HSF_R32G32_FLOAT = 40, */\ + CS_U_FMT_U0_DATA_FMT_UINT32, /* HSF_R32G32_UINT = 41, */\ + CS_U_FMT_U0_DATA_FMT_SINT32, /* HSF_R32G32_SINT = 42, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32_SNORM = 43, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32_SCALE = 44, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32_UNORM = 45, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32_USCALE = 46, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G32_FIX = 47, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32G8X24_TYPELESS = 48, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_D32_FLOAT_S8X24_UINT = 49, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R32_FLOAT_X8X24_TYPELESS = 50, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_X32_TYPELESS_G8X24_UINT = 51, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R64_FLOAT = 52, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R12G12B12_UNORM = 53, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10A2_TYPELESS = 54, */\ + CS_U_FMT_U0_DATA_FMT_UNORM10, /* HSF_R10G10B10A2_UNORM = 55, */\ + CS_U_FMT_U0_DATA_FMT_UINT16, /* HSF_R10G10B10A2_UINT = 56, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10X2_UINT = 57, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10X2_USCALE = 58, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10A2_SNORM = 59, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10A2_SINT = 60, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10X2_SNORM = 61, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_B10G10R10A2_SNORM = 62, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_B10G10R10A2_UNORM = 63, */\ + CS_U_FMT_U0_DATA_FMT_UNORM10, /* HSF_B10G10R10X2_UNORM = 64, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_A2B10G10R10_UNORM = 65, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_A2B10G10R10_SNORM = 66, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_A2B10G10R10_USCALE = 67, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_A2B10G10R10_SSCALE = 68, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10_SINT = 69, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10_SNORM = 70, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10_SCALE = 71, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10_UNIT = 72, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10_UNORM = 73, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10_USCALE = 74, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10_SINT = 75, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10_SNORM = 76, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10_SCALE = 77, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10_UINT = 78, */\ + CS_U_FMT_U0_DATA_FMT_UNORM10, /* HSF_R10G10_UNORM = 79, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10_USCALE = 80, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R10G10B10_FLOAT_A2_UNORM = 81, */\ + CS_U_FMT_U0_DATA_FMT_FP16, /* HSF_R11G11B10_FLOAT = 82, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_B10G11R11_FLOAT = 83, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R11G11_FLOAT = 84, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /* HSF_R8G8B8A8_TYPELESS = 85, */\ + CS_U_FMT_U0_DATA_FMT_UNORM8, /* HSF_R8G8B8A8_UNORM = 86, */\ + CS_U_FMT_U0_DATA_FMT_UNORM8, /*HSF_R8G8B8A8_UNORM_SRGB = 87*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8X8_UNORM = 88*/\ + CS_U_FMT_U0_DATA_FMT_UNORM8, /*HSF_B8G8R8A8_UNORM = 89*/\ + CS_U_FMT_U0_DATA_FMT_UNORM8, /*HSF_B8G8R8A8_UNORM_SRGB = 90*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_B8G8R8X8_UNORM = 91*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_B8G8R8X8_UNORM_SRGB = 92*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_X8R8G8B8_UNORM = 93*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_X8B8G8R8_UNORM = 94*/\ + CS_U_FMT_U0_DATA_FMT_UNORM8, /*HSF_A8R8G8B8_UNORM = 95*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_A8B8G8R8_UNORM = 96*/\ + CS_U_FMT_U0_DATA_FMT_UINT8, /*HSF_R8G8B8A8_UINT = 97*/\ + CS_U_FMT_U0_DATA_FMT_SNORM8, /*HSF_R8G8B8A8_SNORM = 98*/\ + CS_U_FMT_U0_DATA_FMT_SINT8, /*HSF_R8G8B8A8_SINT = 99*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_B8G8R8A8_XNORM = 100?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8A8_SSCALE = 101?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8A8_USCALE = 102*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8_SINT = 103*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8_SNORM = 104*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8_SCALE = 105?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8_UINT = 106*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8_UNORM = 107*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8_USCALE = 108?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16G16_TYPELESS = 109?0*/\ + CS_U_FMT_U0_DATA_FMT_FP16, /*HSF_R16G16_FLOAT = 110*/\ + CS_U_FMT_U0_DATA_FMT_UNORM16, /*HSF_R16G16_UNORM = 111*/\ + CS_U_FMT_U0_DATA_FMT_UINT16, /*HSF_R16G16_UINT = 112*/\ + CS_U_FMT_U0_DATA_FMT_SNORM16, /*HSF_R16G16_SNORM = 113*/\ + CS_U_FMT_U0_DATA_FMT_SINT16, /*HSF_R16G16_SINT = 114*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16G16_SCALE = 115?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16G16_USCALE = 116?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16G16_SSCALE = 117?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32_TYPELESS = 118?*/\ + CS_U_FMT_U0_DATA_FMT_FP32, /*HSF_D32_FLOAT = 119*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_D32_UNORM = 120?*/\ + CS_U_FMT_U0_DATA_FMT_FP32, /*HSF_R32_FLOAT = 121*/\ + CS_U_FMT_U0_DATA_FMT_UINT32, /*HSF_R32_UINT = 122?*/\ + CS_U_FMT_U0_DATA_FMT_SINT32, /*HSF_R32_SINT = 123?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32_UNORM = 124?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32_USCALE = 125*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32_SNORM = 126*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32_SCALE = 127*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32_FIX = 128*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R24G8_TYPELESS = 129*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_D32_FLOAT_S8_UINT = 130*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_D24_UNORM_S8_UINT = 131*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R24_UNORM_X8_TYPELESS = 132*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_X24_TYPELESS_G8_UINT = 133*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_D24_UNORM = 134*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R24_FLOAT = 135*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8_TYPELESS = 136?0*/\ + CS_U_FMT_U0_DATA_FMT_UNORM8, /*HSF_R8G8_UNORM = 137*/\ + CS_U_FMT_U0_DATA_FMT_UINT8, /*HSF_R8G8_UINT = 138*/\ + CS_U_FMT_U0_DATA_FMT_SNORM8, /*HSF_R8G8_SNORM = 139*/\ + CS_U_FMT_U0_DATA_FMT_SINT8, /*HSF_R8G8_SINT = 140*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8_USCALE = 141*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8_SSCALE = 142*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16_TYPELESS = 143*/\ + CS_U_FMT_U0_DATA_FMT_FP16, /*HSF_R16_FLOAT = 144*/\ + CS_U_FMT_U0_DATA_FMT_UNORM16, /*HSF_D16_UNORM = 145*/\ + CS_U_FMT_U0_DATA_FMT_UNORM16, /*HSF_R16_UNORM = 146*/\ + CS_U_FMT_U0_DATA_FMT_UINT16, /*HSF_R16_UINT = 147*/\ + CS_U_FMT_U0_DATA_FMT_SNORM16, /*HSF_R16_SNORM = 148*/\ + CS_U_FMT_U0_DATA_FMT_SINT16, /*HSF_R16_SINT = 149*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16_USCALE = 150?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16_SSCALE = 151?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_A16_UNORM = 152*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_B5G6R5_UNORM = 153*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R5G6B5_UNORM = 154*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_B5G5R5X1_UNORM = 155*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_B5G5R5A1_UNORM = 156*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R5G5B5A1_UNORM = 157*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_A1B5G5R5_UNORM = 158*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_A1R5G5B5_UNORM = 159*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_B4G4R4A4_UNORM = 160*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_B4G4R4X4_UNORM = 161*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R4G4B4A4_UNORM = 162*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_A4B4G4R4_UNORM = 163*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_A4R4G4B4_UNORM = 164*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R4G4B4_UNORM = 165*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R5G5B5_UNORM = 166*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_U5V5L6_XNORM = 167?0*/\ + CS_U_FMT_U0_DATA_FMT_UNORM16, /*HSF_L16_UNORM = 168*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_L8_A8_UNORM = 169*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R10_SINT = 170?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R10_SNORM = 171?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R10_SCALE = 172?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R10_UINT = 173?*/\ + CS_U_FMT_U0_DATA_FMT_UNORM10, /*HSF_R10_UNORM = 174?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R10_USCALE = 175?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R2G2B2A2_UNORM = 176?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8_TYPELESS = 177?0*/\ + CS_U_FMT_U0_DATA_FMT_UNORM8, /*HSF_R8_UNORM = 178*/\ + CS_U_FMT_U0_DATA_FMT_UINT8, /*HSF_R8_UINT = 179*/\ + CS_U_FMT_U0_DATA_FMT_SNORM8, /*HSF_R8_SNORM = 180*/\ + CS_U_FMT_U0_DATA_FMT_SINT8, /*HSF_R8_SINT = 181*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8_USCALE = 182?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8_SSCALE = 183?*/\ + CS_U_FMT_U0_DATA_FMT_UNORM8, /*HSF_A8_UNORM = 184*/\ + CS_U_FMT_U0_DATA_FMT_UNORM8, /*HSF_L8_UNORM = 185*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_A12_UNORM = 186*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_A4_UNORM = 187*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R1_UNORM = 188*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R3G3B2_UNORM = 189*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_L4A4_UNORM = 190*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_A4L4_UNORM = 191*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_L4A4_VIDEO = 192*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_AYUV_VIDEO = 193*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_YUYV = 194*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_NV12 = 195?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_P010 = 196?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_P016 = 197?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R9G9B9E5_SHAREDEXP = 198?UINT16*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8_B8G8_UNORM = 199*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_G8R8_G8B8_UNORM = 200*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC1_UNORM = 201*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC1_UNORM_SRGB = 202*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC2_UNORM = 203*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC2_UNORM_SRGB = 204*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC3_UNORM = 205*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC3_UNORM_SRGB = 206*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC4_UNORM = 207*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC4_SNORM = 208*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC4_UNORM_L = 209*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC4_SNORM_L = 210*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC5_UNORM = 211*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC5_SNORM = 212*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC5_UNORM_LA = 213*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC5_SNORM_LA = 214*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC6H_UF16 = 215*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC6H_SF16 = 216*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC7_UNORM = 217*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC7_UNORM_SRGB = 218*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_G8_UINT = 219?0?UNORM8*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_3DC_UNORM = 220*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_YUY2 = 221*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_Y216_VIDEO = 222*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_Y210_VIDEO = 223*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_A4I4_VIDEO = 224?0*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_A8L8_UNORM = 225*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_L8A8_UNORM = 226*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_ZL1 = 227*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16G16B16A16_UNORM_SRGB = 228*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_YCRCB_MB_8_422 = 229*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_YCRCB_MB_8_420 = 230*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_YCRCB_MB_16_422 = 231*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_P016T = 232?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UYVA1010102_VIDEO = 233?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UYVY = 234?CS_U_FMT_U0_DATA_FMT_RESERVED*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BAYER_12 = 235?0*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BAYER = 236?0*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_P016L = 237?*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_YV12 = 238*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_NV12T = 239*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_S1_UINT = 240*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_S16_UINT = 241*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_S4_UINT = 242*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_S8_UINT = 243*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_I12_UNORM = 244*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_I16_UNORM = 245*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_I4_UNORM = 246*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_I8_UNORM = 247*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_L12_UNORM = 248*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_L12_A12_UNORM = 249*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_L12_A4_UNORM = 250*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_L16_A16_UNORM = 251*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_L4_UNORM = 252*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_L4_A4_UNORM = 253*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_L6_A2_UNORM = 254*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGB8_ETC2 = 255?0*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_SRGB8_ETC2 = 256?0*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA8_ETC2_EAC = 257*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_SRGB8_ALPHA8_ETC2_EAC = 258*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R11_EAC = 259?0*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RG11_EAC = 260*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_SIGNED_R11_EAC = 261*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_SIGNED_RG11_EAC = 262*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 263*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 264*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_ALPHA = 265*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_INTENSITY = 266*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_LUMINANCE = 267*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_RED = 268*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_RED_RGTC1 = 269*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_RG = 270*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_RG_RGTC2 = 271*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_RGB = 272*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 273*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 274*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_RGBA = 275*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_RGBA_BPTC_UNORM = 276*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_SIGNED_RED_RGTC1 = 277*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_SIGNED_RG_RGTC2 = 27*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_SLUMINANCE = 279*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_SLUMINANCE_ALPHA = 280*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_SRGB = 281*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_SRGB_ALPHA = 282*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 283*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R10G10B10A2_USCALE = 284?0*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R10G10B10A2_SSCALE = 285*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32G32B32A32_SSCALE = 286,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32G32B32_SSCALE = 287,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32G32_SSCALE = 288,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16G16B16_SSCALE = 289,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32_SSCALE = 290,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8_SSCALE = 291,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 292*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 293*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 294*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 295*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 296*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 297*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 298*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 299*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 300*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 301*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 302*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 303*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 304*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 305*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 306*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 307*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 308*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 309*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 310*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 311*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 312*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 313*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 314*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 315*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 316*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 317*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 318*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 319*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_UNKOWN = 320*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_4X4 = 321*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_5X4 = 322*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_5X5 = 323*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_6X5 = 324*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_6X6 = 325*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_8X5 = 326*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_8X6 = 327*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_8X8 = 328*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_10X5 = 329*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_10X6 = 330*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_10X8 = 331*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_10X10 = 332*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_12X10 = 333*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_12X12 = 334*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RESERVED0 = 335*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RESERVED1 = 336*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_4X4_SRGB = 337*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_5X4_SRGB = 338*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_5X5_SRGB = 339*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_6X5_SRGB = 340*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_6X6_SRGB = 341*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_8X5_SRGB = 342*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_8X6_SRGB = 343*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_8X8_SRGB = 344*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_10X5_SRGB = 345*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_10X6_SRGB = 346*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_10X8_SRGB = 347*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_10X10_SRGB = 348*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_12X10_SRGB = 349*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_12X12_SRGB = 350*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RESERVED2 = 351*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RESERVED3 = 352*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_3x3x3 = 353,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_4x3x3 = 354,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_4x4x3 = 355,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_4x4x4 = 356,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_5x4x4 = 357,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_5x5x4 = 358,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_5x5x5 = 359,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_6x5x5 = 360,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_6x6x5 = 361,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_6x6x6 = 362,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED4 = 363,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED5 = 364,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED6 = 365,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED7 = 366,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED8 = 367,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_ASTC_RESERVED9 = 368,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_3x3x3_SRGB = 369, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_4x3x3_SRGB = 370, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_4x4x3_SRGB = 371, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_4x4x4_SRGB = 372, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_5x4x4_SRGB = 373, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_5x5x4_SRGB = 374,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_5x5x5_SRGB = 375, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_6x5x5_SRGB = 376, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_6x6x5_SRGB = 377, */\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_RGBA_ASTC_6x6x6_SRGB = 378,*/\ + CS_U_FMT_U0_DATA_FMT_UINT64, /*HSF_R64_UINT = 379,*/\ + CS_U_FMT_U0_DATA_FMT_UINT64, /*HSF_R64G64_UINT = 380,*/\ + CS_U_FMT_U0_DATA_FMT_UINT64, /*HSF_R64G64B64_UINT = 381,*/\ + CS_U_FMT_U0_DATA_FMT_UINT64, /*HSF_R64G64B64A64_UINT = 382,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R64_SINT = 383,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R64G64_SINT = 384,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R64G64B64_SINT = 385,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R64G64B64A64_SINT = 386,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R4G4B4X4_UNORM = 387,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R5G5B5X1_UNORM = 388,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8X8_SNORM = 389,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8X8_UINT = 390,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8X8_SINT = 391,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R8G8B8X8_UNORM_SRGB = 392,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R10G10B10X2_UNORM = 393,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16G16B16X16_UNORM = 394,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16G16B16X16_SNORM = 395,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16G16B16X16_FLOAT = 396,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16G16B16X16_UINT = 397,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R16G16B16X16_SINT = 398,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32G32B32X32_FLOAT = 399,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32G32B32X32_UINT = 400,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_R32G32B32X32_SINT = 401,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_S8_UINT_D24_UNORM = 402,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_D24_UNORM_S8_UINT = 403,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_S8_UINT_D32_FLOAT = 404,*/\ + CS_U_FMT_U0_DATA_FMT_UNORM24, /*HSF_R24_UNORM = 405,*/\ + CS_U_FMT_U0_DATA_FMT_UNORM24, /*HSF_R24G24_UNORM = 406,*/\ + CS_U_FMT_U0_DATA_FMT_UNORM24, /*HSF_R24G24B24A24_UNORM = 407,*/\ + CS_U_FMT_U0_DATA_FMT_UNORM10, /*HSF_R10G10B10A10_UNORM = 408,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC1_TYPELESS = 409,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_B8G8R8A8_TYPELESS = 410,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_B8G8R8X8_TYPELESS = 411,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC2_TYPELESS = 412,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC3_TYPELESS = 413,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC4_TYPELESS = 414,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*HSF_BC5_TYPELESS = 415,*/\ + CS_U_FMT_U0_DATA_FMT_RESERVED, /*DXGI_FORMAT_BC6H_TYPELESS = 416,*/\ +} + + +typedef enum +{ + DS_NONE = 0, + S8_UINT = 0x1, + D16_UNORM = 0x2, + D24_UNORM = 0x4, + D32_FLOAT = 0x8, + D24_UNORM_S8_UINT = D24_UNORM | S8_UINT, + D32_FLOAT_S8_UINT = D32_FLOAT | S8_UINT, +} DEPTH_STENCIL_FORMAT; + +#define CHANNEL_MASK_R 1 +#define CHANNEL_MASK_G 2 +#define CHANNEL_MASK_B 4 +#define CHANNEL_MASK_A 8 +#define CHANNEL_MASK_X 16 + +typedef enum CHANNEL_MASK +{ + C_NONE = 0, + C_R = CHANNEL_MASK_R, + C_A = CHANNEL_MASK_A, + C_GR = CHANNEL_MASK_G | CHANNEL_MASK_R, + C_BGR = CHANNEL_MASK_B | CHANNEL_MASK_G | CHANNEL_MASK_R, + C_BGRA = CHANNEL_MASK_B | CHANNEL_MASK_G | CHANNEL_MASK_R | CHANNEL_MASK_A, + C_RGBX = CHANNEL_MASK_R | CHANNEL_MASK_G | CHANNEL_MASK_B | CHANNEL_MASK_X, +} CHANNEL_MASK; + +typedef struct HWFORMAT_TABLE_ENTRY_E3K +{ + Hw_Surf_Format MappedDstFormat; + Hw_Surf_Format SuppressAlphaFormat; + DEPTH_STENCIL_FORMAT CompatibleDsFmt; + COMPRESS_MXUFORMAT CompressFmt; + int ChannelMask; + int bRtSupport; + int bBlockCompressed; + int bYUY2; + int b96bpp; + int bUnorm; + int bSnorm; + int bSrgb; + int bTypeless; + int bFP32Mode; + int bASTC; + int BlockWidth; + int BlockHeight; + int BlockDepth; + int ClrLineNum; +} HWFORMAT_TABLE_ENTRY_E3K; + +extern const HWFORMAT_TABLE_ENTRY_E3K g_HwFormatTable[]; + +#define HWFORMAT_TABLE \ +{\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*HSF_UNKNOWN = 0, */\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R64G64B64A64_FLOAT = 1, */\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R64G64B64_FLOAT = 2, */\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,/*HSF_R32G32B32A32_TYPELESS = 3, */\ + HSF_R32G32B32A32_FLOAT, HSF_R32G32B32X32_FLOAT,DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32B32A32_FLOAT = 4, */\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32B32A32_UINT = 5, */\ + HSF_R32G32B32A32_SINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32B32A32_SINT = 6, */\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32B32A32_SNORM = 7, */\ + HSF_R32G32B32A32_SCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32B32A32_SCALE = 8, */\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32B32A32_UNORM = 9, */\ + HSF_R32G32B32A32_USCALE,HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R32G32B32A32_USCALE = 10, */\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32B32A32_FIX = 11, */\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R64G64_FLOAT = 12, */\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGR, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32B32_TYPELESS = 13, */\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGR, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32B32_FLOAT = 14, */\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGR, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32B32_UINT = 15, */\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGR, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32B32_SINT = 16, */\ + HSF_R32G32B32_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGR, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32B32_UNORM = 17, */\ + HSF_R32G32B32_USCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32B32_USCALE = 18, */\ + HSF_R32G32B32_SNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32B32_SNORM = 19, */\ + HSF_R32G32B32_SCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32B32_SCALE = 20, */\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGR, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32B32_FIX = 21, */\ + HSF_R16G16B16A16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_BGRA, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16A16_TYPELESS = 22, */\ + HSF_R16G16B16A16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_BGRA, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16B16A16_FLOAT = 23, */\ + HSF_R16G16B16A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16B16A16_UNORM = 24, */\ + HSF_R16G16B16A16_UINT, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_BGRA, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16B16A16_UINT = 25, */\ + HSF_R16G16B16A16_SNORM, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_BGRA, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16B16A16_SNORM = 26, */\ + HSF_R16G16B16A16_SINT, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_BGRA, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16B16A16_SINT = 27, */\ + HSF_R16G16B16A16_SCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16A16_SCALE = 28, */\ + HSF_R16G16B16A16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16A16_USCALE = 29, */\ + HSF_R16G16B16A16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16A16_SSCALE = 30, */\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_R16G16B16A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R12G12B12A12_UNORM = 31, */\ + HSF_R16G16B16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16_FLOAT = 32, */\ + HSF_R16G16B16_SINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16_SINT = 33, */\ + HSF_R16G16B16_SNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16_SNORM = 34, */\ + HSF_R16G16B16_SCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16_SCALE = 35, */\ + HSF_R16G16B16_UINT, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16_UINT = 36, */\ + HSF_R16G16B16_UNORM, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_BGR, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16_UNORM = 37, */\ + HSF_R16G16B16_USCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16_USCALE = 38, */\ + HSF_R32G32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32_TYPELESS = 39, */\ + HSF_R32G32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32_FLOAT = 40, */\ + HSF_R32G32_UINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32_UINT = 41, */\ + HSF_R32G32_SINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32_SINT = 42, */\ + HSF_R32G32_SINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32_SNORM = 43, */\ + HSF_R32G32_SCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32_SCALE = 44, */\ + HSF_R32G32_UINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32_UNORM = 45, */\ + HSF_R32G32_USCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32_USCALE = 46, */\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32G32_FIX = 47, */\ + HSF_R32_FLOAT, HSF_UNKNOWN, D32_FLOAT_S8_UINT, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R32G8X24_TYPELESS = 48, */\ + HSF_R32_FLOAT, HSF_UNKNOWN, D32_FLOAT_S8_UINT, CP_Z32, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_D32_FLOAT_S8X24_UINT = 49, */\ + HSF_R32G32_FLOAT, HSF_UNKNOWN, D32_FLOAT_S8_UINT, CP_Z32, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R32_FLOAT_X8X24_TYPELESS = 50, */\ + HSF_UNKNOWN, HSF_UNKNOWN, D32_FLOAT_S8_UINT, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_X32_TYPELESS_G8X24_UINT = 51, */\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R64_FLOAT = 52, */\ + HSF_R16G16B16X16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_RGBX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R12G12B12_UNORM = 53, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10A2_TYPELESS = 54, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R10G10B10A2_UNORM = 55, */\ + HSF_R10G10B10A2_UINT, HSF_R10G10B10X2_UINT, DS_NONE, CP_R10G10B10A2, C_BGRA, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R10G10B10A2_UINT = 56, */\ + HSF_R10G10B10A2_UINT, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10X2_UINT = 57, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10X2_USCALE = 58, */\ + HSF_R10G10B10A2_UNORM, HSF_R10G10B10X2_SNORM,DS_NONE, CP_R10G10B10A2, C_BGRA, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10A2_SNORM = 59, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10A2_SINT = 60, */\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGR, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10X2_SNORM = 61, */\ + HSF_B10G10R10A2_SNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGRA, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_B10G10R10A2_SNORM = 62, */\ + HSF_B10G10R10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_B10G10R10A2_UNORM = 63, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGR, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_B10G10R10X2_UNORM = 64, */\ + HSF_A2B10G10R10_UNORM, HSF_UNKNOWN, DS_NONE, CP_A2B10G10R10, C_BGRA, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A2B10G10R10_UNORM = 65, */\ + HSF_A2B10G10R10_UNORM, HSF_UNKNOWN, DS_NONE, CP_A2B10G10R10, C_BGRA, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A2B10G10R10_SNORM = 66, */\ + HSF_A2B10G10R10_USCALE, HSF_UNKNOWN, DS_NONE, CP_A2B10G10R10, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A2B10G10R10_USCALE = 67, */\ + HSF_A2B10G10R10_SSCALE, HSF_UNKNOWN, DS_NONE, CP_A2B10G10R10, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A2B10G10R10_SSCALE = 68, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10_SINT = 69, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGR, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10_SNORM = 70, */\ + HSF_R10G10B10_SCALE, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10_SCALE = 71, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10_UNIT = 72, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10_UNORM = 73, */\ + HSF_R10G10B10_USCALE, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10_USCALE = 74, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10_SINT = 75, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_GR, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10_SNORM = 76, */\ + HSF_R10G10_SCALE, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10_SCALE = 77, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10_UINT = 78, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10_UNORM = 79, */\ + HSF_R10G10_SCALE, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10_USCALE = 80, */\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10_FLOAT_A2_UNORM = 81, */\ + HSF_R11G11B10_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R11G11B10, C_BGR, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R11G11B10_FLOAT = 82, */\ + HSF_B10G11R11_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_B10G11R11_FLOAT = 83, */\ + HSF_R11G11B10_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R11G11B10, C_GR, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R11G11_FLOAT = 84, */\ + HSF_R8G8B8A8_UNORM, HSF_R8G8B8X8_UNORM, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8B8A8_TYPELESS = 85, */\ + HSF_R8G8B8A8_UNORM, HSF_R8G8B8X8_UNORM, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8B8A8_UNORM = 86, */\ + HSF_R8G8B8A8_UNORM_SRGB,HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8B8A8_UNORM_SRGB = 87, */\ + HSF_R8G8B8X8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8B8X8_UNORM = 88, */\ + HSF_B8G8R8A8_UNORM, HSF_B8G8R8X8_UNORM, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_B8G8R8A8_UNORM = 89, */\ + HSF_B8G8R8A8_UNORM_SRGB,HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 4,/*HSF_B8G8R8A8_UNORM_SRGB = 90, */\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_B8G8R8X8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_B8G8R8X8_UNORM = 91, */\ + HSF_B8G8R8X8_UNORM_SRGB,HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 4,/*HSF_B8G8R8X8_UNORM_SRGB = 92, */\ + HSF_X8R8G8B8_UNORM, HSF_UNKNOWN, DS_NONE, CP_A8R8G8B8_L, C_RGBX, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_X8R8G8B8_UNORM = 93, */\ + HSF_X8B8G8R8_UNORM, HSF_UNKNOWN, DS_NONE, CP_A8R8G8B8_L, C_RGBX, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_X8B8G8R8_UNORM = 94, */\ + HSF_R8G8B8A8_UNORM, HSF_X8R8G8B8_UNORM, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A8R8G8B8_UNORM = 95, */\ + HSF_A8B8G8R8_UNORM, HSF_X8B8G8R8_UNORM, DS_NONE, CP_A8R8G8B8_L, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_A8B8G8R8_UNORM = 96, */\ + HSF_R8G8B8A8_UINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8B8A8_UINT = 97, */\ + HSF_R8G8B8A8_SNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8B8A8_SNORM = 98, */\ + HSF_R8G8B8A8_SINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8B8A8_SINT = 99, */\ + HSF_R8G8B8A8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_B8G8R8A8_XNORM = 100,*/\ + HSF_R8G8B8A8_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8B8A8_SSCALE = 101,*/\ + HSF_R8G8B8A8_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8B8A8_USCALE = 102,*/\ + HSF_R8G8B8_SINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8B8_SINT = 103,*/\ + HSF_R8G8B8_SNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8B8_SNORM = 104,*/\ + HSF_R8G8B8_SCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8B8_SCALE = 105,*/\ + HSF_R8G8B8_UINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8B8_UINT = 106,*/\ + HSF_R8G8B8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGR, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8B8_UNORM = 107,*/\ + HSF_R8G8B8_USCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8B8_USCALE = 108,*/\ + HSF_R16G16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16_TYPELESS = 109,*/\ + HSF_R16G16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16_FLOAT = 110,*/\ + HSF_R16G16_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16_UNORM = 111,*/\ + HSF_R16G16_UINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16_UINT = 112,*/\ + HSF_R16G16_SNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16_SNORM = 113,*/\ + HSF_R16G16_SINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16_SINT = 114,*/\ + HSF_R16G16_SCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16_SCALE = 115,*/\ + HSF_R16G16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16_USCALE = 116,*/\ + HSF_R16G16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16_SSCALE = 117,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, D32_FLOAT, CP_Z32, C_R, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,/*HSF_R32_TYPELESS = 118,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, D32_FLOAT, CP_Z32, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_D32_FLOAT = 119,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, D32_FLOAT, CP_Z32, C_R, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_D32_UNORM = 120,*/\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_R32_FLOAT, HSF_UNKNOWN, D32_FLOAT, CP_Z32, C_R, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32_FLOAT = 121,*/\ + HSF_R32_UINT, HSF_UNKNOWN, DS_NONE, CP_Z32, C_R, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32_UINT = 122,*/\ + HSF_R32_SINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32_SINT = 123,*/\ + HSF_R32_UINT, HSF_UNKNOWN, DS_NONE, CP_Z32, C_R, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R32_UNORM = 124,*/\ + HSF_R32_USCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R32_USCALE = 125,*/\ + HSF_R32_SINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R32_SNORM = 126,*/\ + HSF_R32_SCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R32_SCALE = 127,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R32_FIX = 128,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, D24_UNORM_S8_UINT, CP_Z24, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R24G8_TYPELESS = 129,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, D32_FLOAT_S8_UINT, CP_Z32, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_D32_FLOAT_S8_UINT = 130,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, D24_UNORM_S8_UINT, CP_Z24, C_R, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_D24_UNORM_S8_UINT = 131,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_Z24, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R24_UNORM_X8_TYPELESS = 132,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_X24_TYPELESS_G8_UINT = 133,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, D24_UNORM, CP_Z24, C_R, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_D24_UNORM = 134,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_Z24, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R24_FLOAT = 135,*/\ + HSF_R8G8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8_TYPELESS = 136,*/\ + HSF_R8G8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8_UNORM = 137,*/\ + HSF_R8G8_UINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8_UINT = 138,*/\ + HSF_R8G8_SNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8_SNORM = 139,*/\ + HSF_R8G8_SINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_GR, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8_SINT = 140,*/\ + HSF_R8G8_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8_USCALE = 141,*/\ + HSF_R8G8_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8_SSCALE = 142,*/\ + HSF_R16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_Z16, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16_TYPELESS = 143,*/\ + HSF_R16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_Z16, C_R, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16_FLOAT = 144,*/\ + HSF_R16_UNORM, HSF_UNKNOWN, D16_UNORM, CP_Z16, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_D16_UNORM = 145,*/\ + HSF_R16_UNORM, HSF_UNKNOWN, D16_UNORM, CP_Z16, C_R, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16_UNORM = 146,*/\ + HSF_R16_UINT, HSF_UNKNOWN, DS_NONE, CP_Z16, C_R, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16_UINT = 147,*/\ + HSF_R16_SNORM, HSF_UNKNOWN, DS_NONE, CP_Z16, C_R, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16_SNORM = 148,*/\ + HSF_R16_SINT, HSF_UNKNOWN, DS_NONE, CP_Z16, C_R, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16_SINT = 149,*/\ + HSF_R16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16_USCALE = 150,*/\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_R16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16_SSCALE = 151,*/\ + HSF_A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_A, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A16_UNORM = 152,*/\ + HSF_B5G6R5_UNORM, HSF_UNKNOWN, DS_NONE, CP_R5G6B5, C_BGR, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_B5G6R5_UNORM = 153,*/\ + HSF_R5G6B5_UNORM, HSF_UNKNOWN, DS_NONE, CP_R5G6B5, C_BGR, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R5G6B5_UNORM = 154,*/\ + HSF_B5G5R5A1_UNORM, HSF_UNKNOWN, DS_NONE, CP_R5G6B5, C_BGR, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_B5G5R5X1_UNORM = 155,*/\ + HSF_B5G5R5A1_UNORM, HSF_B5G5R5X1_UNORM, DS_NONE, CP_R5G6B5, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_B5G5R5A1_UNORM = 156,*/\ + HSF_R5G5B5A1_UNORM, HSF_UNKNOWN, DS_NONE, CP_R5G6B5, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R5G5B5A1_UNORM = 157,*/\ + HSF_A1B5G5R5_UNORM, HSF_UNKNOWN, DS_NONE, CP_R5G6B5, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_A1B5G5R5_UNORM = 158,*/\ + HSF_A1R5G5B5_UNORM, HSF_UNKNOWN, DS_NONE, CP_R5G6B5, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_A1R5G5B5_UNORM = 159,*/\ + HSF_B4G4R4A4_UNORM, HSF_B4G4R4X4_UNORM, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_B4G4R4A4_UNORM = 160,*/\ + HSF_B4G4R4A4_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGR, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_B4G4R4X4_UNORM = 161,*/\ + HSF_R4G4B4A4_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R4G4B4A4_UNORM = 162,*/\ + HSF_A4B4G4R4_UNORM, HSF_UNKNOWN, DS_NONE, CP_A8R8G8B8_L, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_A4B4G4R4_UNORM = 163,*/\ + HSF_R4G4B4A4_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A4R4G4B4_UNORM = 164,*/\ + HSF_R4G4B4A4_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGR, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R4G4B4_UNORM = 165,*/\ + HSF_R5G5B5_UNORM, HSF_UNKNOWN, DS_NONE, CP_R5G6B5, C_BGR, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R5G5B5_UNORM = 166,*/\ + HSF_B5G6R5_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_U5V5L6_XNORM = 167,*/\ + HSF_R16_UNORM, HSF_UNKNOWN, DS_NONE, CP_Z16, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L16_UNORM = 168,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L8_A8_UNORM = 169,*/\ + HSF_R10_SINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10_SINT = 170,*/\ + HSF_R10_SNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10_SNORM = 171,*/\ + HSF_R10_SCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10_SCALE = 172,*/\ + HSF_R10_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10_UINT = 173,*/\ + HSF_R10_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10_UNORM = 174,*/\ + HSF_R10_USCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10_USCALE = 175,*/\ + HSF_R4G4B4A4_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R2G2B2A2_UNORM = 176,*/\ + HSF_R8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8_TYPELESS = 177,*/\ + HSF_R8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_R, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8_UNORM = 178,*/\ + HSF_R8_UINT, HSF_UNKNOWN, S8_UINT, CP_R8G8B8A8_L, C_R, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8_UINT = 179,*/\ + HSF_R8_SNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_R, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8_SNORM = 180,*/\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_R8_SINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_R, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8_SINT = 181,*/\ + HSF_R8_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8_USCALE = 182,*/\ + HSF_R8_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8_SSCALE = 183,*/\ + HSF_A8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_A, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_A8_UNORM = 184,*/\ + HSF_R8_UNORM, HSF_UNKNOWN, S8_UINT, CP_R8G8B8A8_L, C_BGRA, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L8_UNORM = 185,*/\ + HSF_A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A12_UNORM = 186,*/\ + HSF_A8_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A4_UNORM = 187,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R1_UNORM = 188,*/\ + HSF_R4G4B4X4_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R3G3B2_UNORM = 189,*/\ + HSF_L4A4_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_L4A4_UNORM = 190,*/\ + HSF_L4A4_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A4L4_UNORM = 191,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L4A4_VIDEO = 192,*/\ + HSF_R8G8B8A8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_AYUV_VIDEO = 193,*/\ + HSF_YUYV, HSF_UNKNOWN, DS_NONE, CP_YUYV, C_BGRA, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_YUYV = 194,*/\ + HSF_NV12, HSF_UNKNOWN, DS_NONE, CP_NV12, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_NV12 = 195,*/\ + HSF_P010, HSF_UNKNOWN, DS_NONE, CP_NV12_10, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_P010 = 196,*/\ + HSF_P016, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_P016 = 197,*/\ + HSF_R8G8B8A8_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R9G9B9E5_SHAREDEXP = 198,*/\ + HSF_UYVY, HSF_UNKNOWN, DS_NONE, CP_UYVY, C_BGRA, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8_B8G8_UNORM = 199,*/ /*!< we treat these two(199/200) as UYVY/YUYV*/\ + HSF_YUYV, HSF_UNKNOWN, DS_NONE, CP_YUYV, C_BGRA, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_G8R8_G8B8_UNORM = 200,*/\ + HSF_R16G16B16A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC1_UNORM = 201,*/\ + HSF_R16G16B16A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC1_UNORM_SRGB = 202,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC2_UNORM = 203,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC2_UNORM_SRGB = 204,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC3_UNORM = 205,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC3_UNORM_SRGB = 206,*/\ + HSF_R16G16B16A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC4_UNORM = 207,*/\ + HSF_R16G16B16A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC4_SNORM = 208,*/\ + HSF_R16G16B16A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC4_UNORM_L = 209,*/\ + HSF_R16G16B16A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC4_SNORM_L = 210,*/\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC5_UNORM = 211,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC5_SNORM = 212,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC5_UNORM_LA = 213,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC5_SNORM_LA = 214,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC6H_UF16 = 215,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC6H_SF16 = 216,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC7_UNORM = 217,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 4, 4, 1, 0,/*HSF_BC7_UNORM_SRGB = 218,*/\ + HSF_R8_UNORM, HSF_UNKNOWN, S8_UINT, CP_R8G8B8A8_L, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_G8_UINT = 219,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_3DC_UNORM = 220,*/\ + HSF_YUYV, HSF_UNKNOWN, DS_NONE, CP_YUYV, C_NONE, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_YUY2 = 221,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_Y216_VIDEO = 222,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_Y210_VIDEO = 223,*/\ + HSF_A4I4_VIDEO, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A4I4_VIDEO = 224,*/\ + HSF_A8L8_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_A8L8_UNORM = 225,*/\ + HSF_L8A8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_BGRA, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L8A8_UNORM = 226,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_ZL1 = 227,*/\ + HSF_R16G16B16A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_NONE, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16A16_UNORM_SRGB = 228*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_YCRCB_MB_8_422 = 229,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_YCRCB_MB_16_420 = 230,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_YCRCB_MB_16_422 = 231,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_P016T = 232,*/\ + HSF_UYVA1010102_VIDEO, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_UYVA1010102_VIDEO = 233,*/\ + HSF_UYVY, HSF_UNKNOWN, DS_NONE, CP_UYVY, C_BGRA, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_UYVY = 234,*/\ + HSF_R16_UNORM, HSF_UNKNOWN, DS_NONE, CP_BAYER, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_BAYER_12 = 235,*/\ + HSF_R16_UNORM, HSF_UNKNOWN, DS_NONE, CP_BAYER, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_BAYER = 236,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_P016L = 237,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_YUYV, C_NONE, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_YV12 = 238,*/\ + HSF_L8A8_SNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_NONE, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_L8A8_SNORM = 239,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_S1_UINT = 240,*/\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_S16_UINT = 241,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_S4_UINT = 242,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_S8_UINT = 243,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_I12_UNORM = 244,*/\ + HSF_R16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_I16_UNORM = 245,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_I4_UNORM = 246,*/\ + HSF_R8_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_I8_UNORM = 247,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L12_UNORM = 248,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L12_A12_UNORM = 249,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L12_A4_UNORM = 250,*/\ + HSF_R16G16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L16_A16_UNORM = 251,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L4_UNORM = 252,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L4_A4_UNORM = 253,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L6_A2_UNORM = 254,*/\ + HSF_R16G16B16A16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_RGB8_ETC2 = 255,*/\ + HSF_R16G16B16A16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 4, 4, 1, 0,/*HSF_SRGB8_ETC2 = 256,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_RGBA8_ETC2_EAC = 257,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 4, 4, 1, 0,/*HSF_SRGB8_ALPHA8_ETC2_EAC = 258,*/\ + HSF_R16G16B16A16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_R11_EAC = 259,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_RG11_EAC = 260,*/\ + HSF_R16G16B16A16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_SIGNED_R11_EAC = 261,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_SIGNED_RG11_EAC = 262,*/\ + HSF_R16G16B16A16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 263,*/\ + HSF_R16G16B16A16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 4, 4, 1, 0,/*HSF_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 264,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_ALPHA = 265,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_INTENSITY = 266,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_LUMINANCE = 267,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_RED = 268,*/\ + HSF_R16G16B16A16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_COMPRESSED_RED_RGTC1 = 269,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_RG = 270,*/\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_COMPRESSED_RG_RGTC2 = 271,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_RGB = 272,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 273,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 274,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_RGBA = 275,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_RGBA_BPTC_UNORM = 276,*/\ + HSF_R16G16B16A16_SINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_COMPRESSED_SIGNED_RED_RGTC1 = 277,*/\ + HSF_R32G32B32A32_SINT , HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 0,/*HSF_COMPRESSED_SIGNED_RG_RGTC2 = 278,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_SLUMINANCE = 279,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_SLUMINANCE_ALPHA = 280,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_SRGB = 281,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_SRGB_ALPHA = 282,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,/*HSF_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 283,*/\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10A2_USCALE = 284,*/\ + HSF_R10G10B10A2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10A2_SSCALE = 285,*/\ + HSF_R32G32B32A32_SSCALE,HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R32G32B32A32_SSCALE = 286,*/\ + HSF_R32G32B32_SSCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R32G32B32_SSCALE = 287,*/\ + HSF_R32G32_SSCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R32G32_SSCALE = 288,*/\ + HSF_R16G16B16_SSCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R16G16B16_SSCALE = 289,*/\ + HSF_R32_SSCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R32_SSCALE = 290,*/\ + HSF_R8G8B8_SSCALE, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R8G8B8_SSCALE = 291,*/\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 292,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 293,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 294,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 295,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 296,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 297,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 298,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 299,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 300,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 301,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 302,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 303,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 304,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 305,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 306,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 307,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 308,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 309,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 310,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 311,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 312,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 313,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 314,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 315,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 316,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 317,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 318,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 319,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*hold place = 320,*/\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 1, 0,/*HSF_RGBA_ASTC_4X4 = 321,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 4, 1, 0,/*HSF_RGBA_ASTC_5X4 = 322,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 5, 1, 0,/*HSF_RGBA_ASTC_5X5 = 323,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 5, 1, 0,/*HSF_RGBA_ASTC_6X5 = 324,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 6, 1, 0,/*HSF_RGBA_ASTC_6X6 = 325,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 5, 1, 0,/*HSF_RGBA_ASTC_8X5 = 326,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 6, 1, 0,/*HSF_RGBA_ASTC_8X6 = 327,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 8, 1, 0,/*HSF_RGBA_ASTC_8X8 = 328,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 5, 1, 0,/*HSF_RGBA_ASTC_10X5 = 329,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 6, 1, 0,/*HSF_RGBA_ASTC_10X6 = 330,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 8, 1, 0,/*HSF_RGBA_ASTC_10X8 = 331,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 10, 1, 0,/*HSF_RGBA_ASTC_10X10 = 332,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 10, 1, 0,/*HSF_RGBA_ASTC_12X10 = 333,*/\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 12, 1, 0,/*HSF_RGBA_ASTC_12X12 = 334,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_RESERVED2 = 335,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_RESERVED3 = 336,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 4, 4, 1, 0,/*HSF_RGBA_ASTC_4X4_SRGB = 337,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 5, 4, 1, 0,/*HSF_RGBA_ASTC_5X4_SRGB = 338,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 5, 5, 1, 0,/*HSF_RGBA_ASTC_5X5_SRGB = 339,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 6, 5, 1, 0,/*HSF_RGBA_ASTC_6X5_SRGB = 340,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 6, 6, 1, 0,/*HSF_RGBA_ASTC_6X6_SRGB = 341,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 8, 5, 1, 0,/*HSF_RGBA_ASTC_8X5_SRGB = 342,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 8, 6, 1, 0,/*HSF_RGBA_ASTC_8X6_SRGB = 343,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 8, 8, 1, 0,/*HSF_RGBA_ASTC_8X8_SRGB = 344,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 10, 5, 1, 0,/*HSF_RGBA_ASTC_10X5_SRGB = 345,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 10, 6, 1, 0,/*HSF_RGBA_ASTC_10X6_SRGB = 346,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 10, 8, 1, 0,/*HSF_RGBA_ASTC_10X8_SRGB = 347,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 10, 10, 1, 0,/*HSF_RGBA_ASTC_10X10_SRGB = 348,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 12, 10, 1, 0,/*HSF_RGBA_ASTC_12X10_SRGB = 349,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 12, 12, 1, 0,/*HSF_RGBA_ASTC_12X12_SRGB = 350,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_RESERVED4 = 351,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_RESERVED5 = 352,*/\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + /*the following new added by Martina ASTC 3D*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 0,/*HSF_RGBA_ASTC_3x3x3 = 353,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 3, 3, 0,/*HSF_RGBA_ASTC_4x3x3 = 354,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 3, 0,/*HSF_RGBA_ASTC_4x4x3 = 355,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 0,/*HSF_RGBA_ASTC_4x4x4 = 356,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 4, 4, 0,/*HSF_RGBA_ASTC_5x4x4 = 357,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 5, 4, 0,/*HSF_RGBA_ASTC_5x5x4 = 358,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 5, 5, 0,/*HSF_RGBA_ASTC_5x5x5 = 359,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 5, 5, 0,/*HSF_RGBA_ASTC_6x5x5 = 360,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 6, 5, 0,/*HSF_RGBA_ASTC_6x6x5 = 361,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 6, 6, 0,/*HSF_RGBA_ASTC_6x6x6 = 362,*/\ + HSF_R16G16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L16A16_UNORM = 363,*/\ + HSF_R16G16_SNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_L16A16_SNORM = 364,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_ASTC_RESERVED6 = 365,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_ASTC_RESERVED7 = 366,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_ASTC_RESERVED8 = 367,*/\ + HSF_UNKNOWN, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_ASTC_RESERVED9 = 368,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 3, 3, 3, 0,/*HSF_RGBA_ASTC_3x3x3_SRGB = 369,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 4, 3, 3, 0,/*HSF_RGBA_ASTC_4x3x3_SRGB = 370,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 4, 4, 3, 0,/*HSF_RGBA_ASTC_4x4x3_SRGB = 371,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 4, 4, 4, 0,/*HSF_RGBA_ASTC_4x4x4_SRGB = 372,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 5, 4, 4, 0,/*HSF_RGBA_ASTC_5x4x4_SRGB = 373,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 5, 5, 4, 0,/*HSF_RGBA_ASTC_5x5x4_SRGB = 374,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 5, 5, 5, 0,/*HSF_RGBA_ASTC_5x5x5_SRGB = 375,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 6, 5, 5, 0,/*HSF_RGBA_ASTC_6x5x5_SRGB = 376,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 6, 6, 5, 0,/*HSF_RGBA_ASTC_6x6x5_SRGB = 377,*/\ + HSF_R32G32B32A32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 6, 6, 6, 0,/*HSF_RGBA_ASTC_6x6x6_SRGB = 378,*/\ + HSF_R64_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R64_UINT = 379,*/\ + HSF_R64G64_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R64G64_UINT = 380,*/\ + /* ChannelMask */\ + /* | bRtSupport */\ + /* | | bBlockCompressed */\ + /* | | | bYUY2 */\ + /* | | | | b96bpp */\ + /* | | | | | bUnorm */\ + /* | | | | | | bSnorm */\ + /* | | | | | | | bSrgb */\ + /* | | | | | | | | bTypeless */\ + /* MappedDstFormat SuppressAlphaFormat CompatibleDsFmt CompressFmt | | | | | | | | | bFP32Mode */\ + /* | | | | | | | | | | | | | | bASTC */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | |BlockWidth */\ + /*..|.......................|.....................|...............|...............| | | | | | | | | | | | |BlockHeight */\ + /* | | | | | | | | | | | | | | | | | |BlockDepth */\ + /* | | | | | | | | | | | | | | | | | | |ClrLineNum */\ + HSF_R64G64B64_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R64G64B64_UINT = 381,*/\ + HSF_R64G64B64A64_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R64G64B64A64_UINT = 382,*/\ + HSF_R64_SINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R64_SINT = 383,*/\ + HSF_R64G64_SINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R64G64_SINT = 384,*/\ + HSF_R64G64B64_SINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGR, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R64G64B64_SINT = 385,*/\ + HSF_R64G64B64A64_SINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_R64G64B64A64_SINT = 386,*/\ + HSF_R4G4B4X4_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R4G4B4X4_UNORM = 387,*/\ + HSF_R5G5B5X1_UNORM, HSF_UNKNOWN, DS_NONE, CP_R5G6B5, C_RGBX, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R5G5B5X1_UNORM = 388,*/\ + HSF_R8G8B8X8_SNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8B8X8_SNORM = 389,*/\ + HSF_R8G8B8X8_UINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8B8X8_UINT = 390,*/\ + HSF_R8G8B8X8_SINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8B8X8_SINT = 391,*/\ + HSF_R8G8B8X8_UNORM_SRGB,HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 4,/*HSF_R8G8B8X8_UNORM_SRGB = 392,*/\ + HSF_R10G10B10X2_UNORM, HSF_UNKNOWN, DS_NONE, CP_R10G10B10A2, C_RGBX, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R10G10B10X2_UNORM = 393,*/\ + HSF_R16G16B16X16_UNORM, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_RGBX, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16B16X16_UNORM = 394,*/\ + HSF_R16G16B16X16_SNORM, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_RGBX, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16B16X16_SNORM = 395,*/\ + HSF_R16G16B16X16_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R16G16B16A16_T,C_RGBX, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16B16X16_FLOAT = 396,*/\ + HSF_R16G16B16X16_UINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16B16X16_UINT = 397,*/\ + HSF_R16G16B16X16_SINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,/*HSF_R16G16B16X16_SINT = 398,*/\ + HSF_R32G32B32X32_FLOAT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32B32X32_FLOAT = 399,*/\ + HSF_R32G32B32X32_UINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32B32X32_UINT = 400,*/\ + HSF_R32G32B32X32_SINT, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_RGBX, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 16,/*HSF_R32G32B32X32_SINT = 401,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, D24_UNORM_S8_UINT, CP_Z24, C_R, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_S8_UINT_D24_UNORM = 402,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, D24_UNORM_S8_UINT, CP_Z24, C_R, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,/*HSF_D24_UNORM_S8_UINT = 403,*/\ + HSF_R32_FLOAT, HSF_UNKNOWN, D32_FLOAT_S8_UINT, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_S8_UINT_D32_FLOAT = 404,*/\ + HSF_R24_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_R, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R24_UNORM = 405,*/\ + HSF_R24G24_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_GR, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R24G24_UNORM = 406,*/\ + HSF_R24G24B24A24_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R24G24B24A24_UNORM = 407,*/\ + HSF_R10G10B10A10_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_BGRA, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,/*HSF_R10G10B10A10_UNORM = 408,*/\ + HSF_R16G16B16A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 4, 4, 1, 0,/*HSF_BC1_TYPELESS = 409,*/\ + HSF_B8G8R8A8_UNORM, HSF_UNKNOWN, DS_NONE, CP_R8G8B8A8_L, C_NONE, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,/*HSF_B8G8R8A8_TYPELESS = 410,*/\ + HSF_B8G8R8X8_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,/*HSF_B8G8R8X8_TYPELESS = 411,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 4, 4, 1, 0,/*HSF_BC2_TYPELESS = 412,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 4, 4, 1, 0,/*HSF_BC3_TYPELESS = 413,*/\ + HSF_R16G16B16A16_UNORM, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 4, 4, 1, 0,/*HSF_BC4_TYPELESS = 414,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 4, 4, 1, 0,/*HSF_BC5_TYPELESS = 415,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 4, 4, 1, 0,/*DXGI_FORMAT_BC6H_TYPELESS = 416,*/\ + HSF_R32G32B32A32_UINT, HSF_UNKNOWN, DS_NONE, CP_OFF, C_NONE, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 4, 4, 1, 0,/*HSF_BC7_TYPELESS = 417,*/\ +} + +#endif + diff --git a/drivers/gpu/drm/arise/core/e3k/include/chip_include_e3k.h b/drivers/gpu/drm/arise/core/e3k/include/chip_include_e3k.h new file mode 100644 index 0000000000000..19fde4fb076f0 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/chip_include_e3k.h @@ -0,0 +1,473 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __CHIP_INCLUDE_E3K_H__ +#define __CHIP_INCLUDE_E3K_H__ + +#undef __inline +#undef _inline +#undef __int64 + +#define __inline static __inline__ +#define _inline static __inline__ +#define __int64 long long + +#if !defined(XFree86Server) + +/* why define ULONG/DWORD as unsigned int in linux ? + * long is 32-bit type in window, and window use ULONG/DWORD as a 32-bit value, + * but in linux its size equal to OS ptr size. different between 32/64-bit OS, + * So we can not define ULONG to unsigned long in linux, but define it as unsigned int for compatible + */ +typedef unsigned int ULONG; +typedef unsigned int DWORD; +typedef int BOOL; +typedef unsigned char BYTE; +typedef unsigned int UINT; +typedef unsigned short WORD; +typedef unsigned int U32; +typedef void VOID; +typedef float FLOAT; +typedef unsigned long long UINT64; + +#endif + +#include "./Chip/surface_format.h" +#include "./Chip/registerDef.h" +#include "./Chip/registercommands.h" +#include "stm_context_e3k.h" + +typedef enum +{ + HWM_SYNC_VS_SLOT = 0, + HWM_SYNC_STO_SLOT = 1, + HWM_SYNC_Z_SLOT = 2, + HWM_SYNC_PS_SLOT = 3, + HWM_SYNC_WBU_SLOT = 4, + HWM_SYNC_MXU_SLOT = 5, + HWM_SYNC_L2_SLOT = 6, + HWM_SYNC_MAX_SLOT = HWM_SYNC_L2_SLOT + 1, + HWM_SYNC_CONTEXT_LAST = HWM_SYNC_MAX_SLOT, + HWM_SYNC_UMD_FLUSH_SLOT = 7, + HWM_SYNC_DRAIN_3DPIPE_SLOT = 8, + // Above are slots used by 3D UMD + HWM_SYNC_KMD_SLOT = 9, + HWM_SYNC_SWITCH_SLOT = 10, + // Above are stored in context buffer + + //Slot used by video + HWM_SYNC_VCP0_FE_SLOT = 11, + HWM_SYNC_VCP0_BE_SLOT = 12, + HWM_SYNC_VCP1_FE_SLOT = 13, + HWM_SYNC_VCP1_BE_SLOT = 14, + HWM_SYNC_VPP_SLOT = 15, + +} HWM_SYNC_SLOT_E3K; + + +#define FENCE_VALUE_RESET 0x000000FF +#define FENCE_VALUE_BEGIN_DMA 0x00000010 +#define FENCE_VALUE_END_DMA_CSPFENCE 0x00000021 +#define FENCE_VALUE_END_DMA_STOFENCE 0x00000022 +#define FENCE_VALUE_CACHE_DMA_DFENCE 0x00000031 +#define FENCE_VALUE_CACHE_DMA_ZFENCE 0x00000032 +#define FENCE_VALUE_CACHE_DMA_UAVFEFENCE 0x00000033 +#define FENCE_VALUE_CACHE_DMA_UAVBEFENCE 0x00000034 +#define FENCE_VALUE_CACHE_DMA_PRECSPFENCE 0x00000035 +#define FENCE_VALUE_CACHE_DMA_POSTCSPFENCE 0x00000036 +#define FENCE_VALUE_CACHE_DMA_STOFENCE 0x00000037 +#define FENCE_VALUE_CACHE_DMA_L2C_FENCE 0x00000038 + +#define FENCE_VALUE_INIT 0x00000006 +#define FENCE_VALUE_DUMMY_RB 0x00000007 +#define FENCE_VALUE_RANGESET 0x00000003 + +#define FENCE_VALUE_FFC_D_FECNE (0x00000050) +#define FENCE_VALUE_2D_BLT_DST (0x00000060) +#define FENCE_VALUE_3D_BLT_DST (0x00000070) +#define FENCE_VALUE_3D_BLT_SRC (0x00000071) + + + + +#define REG_FS_OUT_MAX_ATTRIBUTES_NUM 48 + +#define REG_FS_OUT_MAPPING_ATTRIBUTES_BITS 6 +#define REG_FS_OUT_MAPPING_ATTRIBUTE_NUM 4 +#define REG_FS_OUT_MAPPING_REGS_NUM 12 + +#define REG_FS_OUT_MASK_ATTRIBUTES_BITS 4 +#define REG_FS_OUT_MASK_ATTRIBUTES_NUM 8 +#define REG_FS_OUT_MASK_REGS_NUM 6 + +#define REG_FS_OUT_COMP_ATTRIBUTES_BITS 2 +#define REG_FS_OUT_COMP_ATTRIBUTES_NUM 16 +#define REG_FS_OUT_COMP_REGS_NUM 3 + + +typedef enum ELITE_SHADER_STAGE +{ + ELITE_VS_STAGE = 1, + ELITE_HS_STAGE , + ELITE_DS_STAGE , + ELITE_GS_STAGE , + ELITE_PS_STAGE , +}ELITE_SHADER_STAGE; + +#define NEW_DUMP 1 +#define MAX_T_SHARP_NUMBER 128 +#define MAX_S_SHARP_NUMBER 16 +#define MAX_TS_SHARP_NUMBER 32 +#define MAX_U_SHARP_NUMBER 32 + +//********************************************************************************************** +// +// RingBuffer command layout: +// +// common pwm header and tail: +// header: indicate which block/slice following dma will use +// pwmIndicatorPair0 +// +// tail: indicate that this dma is finished +// pwmIndicator3DPair1 +// +// Case 0 (From Render): +// [offset] [command] +// 0x00-0x01: Restore DMA/Restore CMD +// 0x02-0x03: CommandDMA +// 0x04-0x05: CacheFlushDMA +// 0x06-0x07: Save DMA/Save CMD +// 0x08-0x0B: Fence +// 0x0C-0x0E: Skip for RB size 512bit +// 0x0F : Special Fence for possible switch to High Rb +// +// Case 1(From Present/BuildPagingBuffer/RenderKM): +// [offset] [command] +// 0x00-0x01: Skip +// 0x02-0x03: CommandDMA +// 0x04-0x05: CacheFlushDMA +// 0x06-0x07: Skip +// 0x08-0x0B: Fence +// 0x0C-0x0E: Skip for RB size 512bit +// 0x0F : Special Fence for possible switch to High Rb +// +// Case 2 (Fence only, from Preempt or NullRendering): +// [offset] [command] +// 0x00-0x07: Skip +// 0x08-0x0B: Fence +// 0x0C-0x0E: Skip for RB size 512bit +// 0x0F : Special Fence for possible switch to High Rb +//********************************************************************************************** +typedef union RINGBUFFER_COMMANDS_E3K +{ + // Case 0 + struct + { + // 0x00-0x01: PWM Indicator Head and PWM Adj Trigger, and 1 followed dw for slice mask + Cmd_Blk_Cmd_Csp_Indicator pwmTrigger; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 trigger_Dw; +#if NEW_DUMP + // 0x2-0x06: Skip_1 //According to HW's request, when slice_mask changed, driver should insert 8dw skip cmd after indicator cmd + DWORD Skip_1[5]; + + // 0x07-0x0A: InitDMA when slice switch, refer to SLICESWITCH_INIT_COMMANDS_E3K.c0 + DWORD SliceSwitchInitCommands[4]; + + // 0x0B-0x0E: Restore DMA + Cmd_Dma RestoreDMA; + DWORD RestoreDMA_Address_L; + DWORD RestoreDMA_Address_H; + DWORD RestoreContext_Address; + + //0x0F-0x12:HangDumpDMA + Cmd_Dma HangDumpContextSaveDMA; + DWORD HangDumpContextSaveDMA_Address_L; + DWORD HangDumpContextSaveDMA_Address_H; + DWORD HangDumpContextSaveContext_Address; +#else + // 0x2-0x0A: Skip_1 + DWORD Skip_1[9]; + + // 0x0B-0x0E: InitDMA when slice switch, refer to SLICESWITCH_INIT_COMMANDS_E3K.c0 + DWORD SliceSwitchInitCommands[4]; + + // 0x0F-0x12: Restore DMA + Cmd_Dma RestoreDMA; + DWORD RestoreDMA_Address_L; + DWORD RestoreDMA_Address_H; + DWORD RestoreContext_Address; + +#endif + // 0x13-0x15: CommandDMA + Cmd_Dma CommandDMA; + DWORD CommandDMA_Address_L; + DWORD CommandDMA_Address_H; + + // 0x16-0x18: CacheFlushDMA + Cmd_Dma CacheFlushDMA; + DWORD CacheFlushDMA_Address_L; + DWORD CacheFlushDMA_Address_H; + + // 0x19-0x1C: Save DMA + Cmd_Dma SaveDMA; + DWORD SaveDMA_Address_L; + DWORD SaveDMA_Address_H; + DWORD SaveContext_Address; + + // 0x1D-0x21: ExternalFence + Cmd_Fence Fence; + DWORD Fence_Address_L; + DWORD Fence_Address_H; + DWORD Fence_Data_L; + DWORD Fence_Data_H; + + // 0x22-0x26: ExternalFence + Cmd_Fence Fence_1; + DWORD Fence_Address_L_1; + DWORD Fence_Address_H_1; + DWORD Fence_Data_L_1; + DWORD Fence_Data_H_1; + + // 0x27-0x3B: ExternalFence + Cmd_Fence Fence_2; + DWORD Fence_Address_L_2; + DWORD Fence_Address_H_2; + DWORD Fence_Data_L_2; + DWORD Fence_Data_H_2; + + // 0x3C-0x40: ExternalFence + Cmd_Fence Fence_3; + DWORD Fence_Address_L_3; + DWORD Fence_Address_H_3; + DWORD Fence_Data_L_3; + DWORD Fence_Data_H_3; + + // 0x41-0x45: ExternalFence + Cmd_Fence Fence_4; + DWORD Fence_Address_L_4; + DWORD Fence_Address_H_4; + DWORD Fence_Data_L_4; + DWORD Fence_Data_H_4; + + // 0x46-0x4A: ExternalFence + Cmd_Fence Fence_5; + DWORD Fence_Address_L_5; + DWORD Fence_Address_H_5; + DWORD Fence_Data_L_5; + DWORD Fence_Data_H_5; + + // 0x27 - 0x31 + DWORD Skip_2[11]; + + // 0x32-0x33: PWM Indicator Tail, and followed dw + Cmd_Blk_Cmd_Csp_Indicator pwmTriggerOff; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 triggerOff_Dw; + } c0; + // Case 1 + struct + { + // 0x00-0x01: PWM Indicator Head and PWM Adj Trigger, and 1 followed dw for slice mask + Cmd_Blk_Cmd_Csp_Indicator pwmTrigger; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 trigger_Dw; + + // 0x02-0x06: Skip_1 + DWORD Skip_1[5]; + + // 0x07-0x12: InitDMA when slice switch, refer to SLICESWITCH_INIT_COMMANDS_E3K.c1 + DWORD SliceSwitchInitCommands[12]; + + // 0x13-0x15: CommandDMA + Cmd_Dma CommandDMA; + DWORD CommandDMA_Address_L; + DWORD CommandDMA_Address_H; + + // 0x16-0x18: CacheFlushDMA + Cmd_Dma CacheFlushDMA; + DWORD CacheFlushDMA_Address_L; + DWORD CacheFlushDMA_Address_H; + + // 0x19-0x1C: Skip_2 + Cmd_Skip Skip_2; + DWORD Dummy_2[3]; + + // 0x1D-0x21: ExternalFence + Cmd_Fence Fence; + DWORD Fence_Address_L; + DWORD Fence_Address_H; + DWORD Fence_Data_L; + DWORD Fence_Data_H; + + // 0x22-0x26: ExternalFence + Cmd_Fence Fence_1; + DWORD Fence_Address_L_1; + DWORD Fence_Address_H_1; + DWORD Fence_Data_L_1; + DWORD Fence_Data_H_1; + + // 0x27-0x3B: ExternalFence + Cmd_Fence Fence_2; + DWORD Fence_Address_L_2; + DWORD Fence_Address_H_2; + DWORD Fence_Data_L_2; + DWORD Fence_Data_H_2; + + // 0x22-0x26: ExternalFence + Cmd_Fence Fence_3; + DWORD Fence_Address_L_3; + DWORD Fence_Address_H_3; + DWORD Fence_Data_L_3; + DWORD Fence_Data_H_3; + + // 0x27-0x3B: ExternalFence + Cmd_Fence Fence_4; + DWORD Fence_Address_L_4; + DWORD Fence_Address_H_4; + DWORD Fence_Data_L_4; + DWORD Fence_Data_H_4; + + // 0x22-0x26: ExternalFence + Cmd_Fence Fence_5; + DWORD Fence_Address_L_5; + DWORD Fence_Address_H_5; + DWORD Fence_Data_L_5; + DWORD Fence_Data_H_5; + + // 0x27 - 0x31 + DWORD Skip_3[11]; + + // 0x32-0x33: PWM Indicator Tail, and followed dw + Cmd_Blk_Cmd_Csp_Indicator pwmTriggerOff; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 triggerOff_Dw; + } c1; + // Case 2 + struct + { + // 0x00-0x01: PWM Indicator Head and PWM Adj Trigger, and 1 followed dw for slice mask + Cmd_Blk_Cmd_Csp_Indicator pwmTrigger; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 trigger_Dw; + + // 0x02-0x1C: Skip_1 + DWORD Skip_1[0x1B]; + + // 0x1D-0x21: ExternalFence + Cmd_Fence Fence; + DWORD Fence_Address_L; + DWORD Fence_Address_H; + DWORD Fence_Data_L; + DWORD Fence_Data_H; + + // 0x22-0x26: ExternalFence + Cmd_Fence Fence_1; + DWORD Fence_Address_L_1; + DWORD Fence_Address_H_1; + DWORD Fence_Data_L_1; + DWORD Fence_Data_H_1; + + // 0x27-0x3B: ExternalFence + Cmd_Fence Fence_2; + DWORD Fence_Address_L_2; + DWORD Fence_Address_H_2; + DWORD Fence_Data_L_2; + DWORD Fence_Data_H_2; + + // 0x22-0x26: ExternalFence + Cmd_Fence Fence_3; + DWORD Fence_Address_L_3; + DWORD Fence_Address_H_3; + DWORD Fence_Data_L_3; + DWORD Fence_Data_H_3; + + // 0x27-0x3B: ExternalFence + Cmd_Fence Fence_4; + DWORD Fence_Address_L_4; + DWORD Fence_Address_H_4; + DWORD Fence_Data_L_4; + DWORD Fence_Data_H_4; + + // 0x22-0x26: ExternalFence + Cmd_Fence Fence_5; + DWORD Fence_Address_L_5; + DWORD Fence_Address_H_5; + DWORD Fence_Data_L_5; + DWORD Fence_Data_H_5; + + // 0x27 - 0x31 + DWORD Skip_2[11]; + + // 0x32-0x33: PWM Indicator Tail, and followed dw + Cmd_Blk_Cmd_Csp_Indicator pwmTriggerOff; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 triggerOff_Dw; + } c2; +}RINGBUFFER_COMMANDS_E3K; + +typedef union SLICESWITCH_INIT_COMMANDS_E3K +{ + // Case 0 + struct + { + Cmd_Dma RestoreShadowDMA; + DWORD RestoreShadowDMA_Address_L; + DWORD RestoreShadowDMA_Address_H; + DWORD RestoreShadowContext_Address; + } c0; + // Case 1 + struct + { + Cmd_Dma SaveDMA; + DWORD SaveDMA_Address_L; + DWORD SaveDMA_Address_H; + DWORD SaveContext_Address; + + Cmd_Dma RestoreShadowDMA; + DWORD RestoreShadowDMA_Address_L; + DWORD RestoreShadowDMA_Address_H; + DWORD RestoreShadowContext_Address; + + Cmd_Dma RestoreDMA; + DWORD RestoreDMA_Address_L; + DWORD RestoreDMA_Address_H; + DWORD RestoreContext_Address; + } c1; +} SLICESWITCH_INIT_COMMANDS_E3K; + +#define HWM_SYNC_2DBLT_DST 0x2180000A +#define HWM_SYNC_EU_FE 0x31b10002 +#define HWM_SYNC_EU_BE 0x31b20006 +#define HWM_SYNC_D 0x31b30008 +#define HWM_SYNC_Z 0x31b4000C +#define HWM_SYNC_STO 0x01110007 + +#define HWM_SYNC_USAGETYPE_MASK 0x000000FF +#define HwmUsageType(Usage) (Usage&HWM_SYNC_USAGETYPE_MASK) + +#define BCI_MAX_COORD_E3K 0x3fff + +#define HWM_SYNC_USAGETYPE_MASK 0x000000FF +#define HWM_SYNC_MAX_TYPE 0x10 // must be consistent with the following definitions +#define HWM_SYNC_MAX_READTYPE 0x10 // must be consistent with the following definitions + +#define HWM_SYNC_READ 0x00000000 +#define HWM_SYNC_WRITE 0x01000000 + +#define HWM_SYNC_MODE_MASK 0xF0000000 +#define HWM_SYNC_ACCESS_MASK 0x0F000000 +#define HWM_SYNC_USAGEID_MASK 0x00FF0000 + +#define HWM_SYNC_INVALIDATE_L2_CACHE 0x011A000E +#define HWM_SYNC_FFC_D_FLUSH 0x01160008 +#define HWM_SYNC_QUERY_DUMP 0x218e000D +#define HWM_SYNC_AUTOCLEAR 0x218c000D + +#endif /*__CHIP_INCLUDE_E3K_H__*/ + diff --git a/drivers/gpu/drm/arise/core/e3k/include/mm_e3k.h b/drivers/gpu/drm/arise/core/e3k/include/mm_e3k.h new file mode 100644 index 0000000000000..102ae7ccc01bd --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/mm_e3k.h @@ -0,0 +1,518 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __MM_E3K_H +#define __MM_E3K_H + +#define MAX_WIDTH_2DBLT (16 * 1024) //16K +#define MAX_HEIGHT_2DBLT (16 * 1024) //16K + +typedef struct HWM_TILE_INFO_E3K +{ + int bTileSupported; // Display & Render target tiled support + int bTileTexSupported; // Texture tiled support + int bTileZWSupported; // Z write tiled support + unsigned int tileSizeInBytes; + unsigned int dwTileSizeX[7]; + unsigned int dwTileSizeY[7]; +} HWM_TILE_INFO_E3K; + +//[TODO: need refine +//should be as same as hwm_caps_e3k.cpp +static HWM_TILE_INFO_E3K hwmTileInfo_e3k = +{ + TRUE, // bTileSupported + TRUE, // bTileTexSupported + TRUE, // bTileZWSupported + 1024*64, // tileSizeInBytes = 16k + + // dwTileSizeX + { + 256, // 0 8bit or less + 256, // 1 16bit + 128, // 2 32bit + 128, // 3 64bit + 64, // 4 128bit + 64, // 5 256bit + 32, // 6 512bit + }, + + // dwTileSizeY + { + 256, // 0 8bit or less + 128, // 1 16bit + 128, // 2 32bit + 64, // 3 64bit + 64, // 4 128bit + 32, // 5 256bit + 32, // 6 512bit + }, +}; + +#define UNIT_SIZE_E3K 8 + +static inline unsigned int cacl_log2(unsigned int s) +{ + unsigned int iter = (unsigned int)-1; + switch (s) + { + case 1: + iter = 0; + break; + case 2: + iter = 1; + break; + case 4: + iter = 2; + break; + case 8: + iter = 3; + break; + case 16: + iter = 4; + break; + case 32: + iter = 5; + break; + case 64: + iter = 6; + break; + case 128: + iter = 7; + break; + case 256: + iter = 8; + break; + case 512: + iter = 9; + break; + case 1024: + iter = 10; + break; + default: + { + unsigned int d = 1; + do { + d *= 2; + iter++; + } while (d < s); + iter += ((s << 1) != d); + } + } + return iter; +} + +static inline unsigned int getTileSizeInBytes(void) +{ + return hwmTileInfo_e3k.tileSizeInBytes; +} + +static inline unsigned int calcTileWidth_e3k (unsigned int bit_cnt) +{ + unsigned int bpp = cacl_log2(bit_cnt); + unsigned int idx = (bit_cnt > 8) ? (bpp - 3) : 0; + + return hwmTileInfo_e3k.dwTileSizeX[idx]; +} + +static inline unsigned int calcTileHeight_e3k (unsigned int bit_cnt) +{ + unsigned int bpp = cacl_log2(bit_cnt); + unsigned int idx = (bit_cnt > 8) ? (bpp - 3) : 0; + + return hwmTileInfo_e3k.dwTileSizeY[idx]; +} + +static inline unsigned int calcWidthInTiles_e3k (unsigned int width, unsigned int bit_cnt) +{ + unsigned int tsize = calcTileWidth_e3k(bit_cnt); + + return (width + tsize - 1) / tsize; +} + +static inline unsigned int calcHeightInTiles_e3k (unsigned int height, unsigned int bit_cnt) +{ + unsigned int tsize = calcTileHeight_e3k(bit_cnt); + + return (height + tsize - 1) / tsize; +} + +static inline unsigned int calcUnitWidth_e3k (unsigned int bit_cnt) +{ + unsigned int bpp = cacl_log2(bit_cnt); + unsigned int idx = (bit_cnt > 8) ? (bpp - 3) : 0; + + return (1 << ((UNIT_SIZE_E3K - idx + 1) / 2)); +} + +static inline unsigned int calcUnitHeight_e3k (unsigned int bit_cnt) +{ + unsigned int bpp = cacl_log2(bit_cnt); + unsigned int idx = (bit_cnt > 8) ? (bpp - 3) : 0; + + return (1 << ((UNIT_SIZE_E3K - idx) / 2)); +} + +typedef enum MM_ALLOCATION_TYPE_E3K +{ + MM_AT_GENERIC_E3K = 0, + MM_AT_VERTEXBUFFER_E3K, + MM_AT_INDEXBUFFER_E3K, + MM_AT_CSHARP_E3K, + MM_AT_TEXTURE_E3K, + MM_AT_TSHARP_E3K, + MM_AT_SSHARP_E3K, + MM_AT_BCSHARP_E3K, + MM_AT_RT_TEXTURE_E3K, + MM_AT_DS_TEXTURE_E3K, + MM_AT_RENDERTARGET_E3K, + MM_AT_RENDERTARGET_SSB_E3K, + MM_AT_DEPTHBUFFER_E3K, + MM_AT_DEPTHBUFFER_SSB_E3K, + MM_AT_STENCILBUFFER_E3K, + MM_AT_STENCILBUFFER_SSB_E3K, + MM_AT_SO_BUFFER_E3K, + MM_AT_SO_DESC_E3K, + MM_AT_EUPFSHADER_E3K, + MM_AT_EUPBSHADER_E3K, + MM_AT_THREADSPACE_E3K, + MM_AT_BACKBUFFER_E3K, + MM_AT_CONTEXT_E3K, + MM_AT_FENCE_E3K, + MM_AT_FLAGBUFFER_E3K, + MM_AT_2D_E3K, + MM_AT_VIDEO_RESERVEDMEM_E3K, + MM_AT_VIDEO_DECODE_RT_E3K, + MM_AT_VIDEO_DECODE_COMPBUFF_E3K, + MM_AT_VIDEO_VIDEOPROCESS_RT_E3K, + MM_AT_ISP_BACKLIGHT_CTRL_BUFF_E3K, + MM_AT_HEAP, + MM_AT_SECOND_BUFFER_ADDRESS, + MM_AT_DESCRIPTOR_HEAP, + MM_AT_QUERYPOOL_E3K, + MM_AT_TBR_SIGNATURE_BUFFER_ADDRESS_E3K, + MM_AT_MIUCOUNTER_E3K, + MM_AT_SIGNATURE_PER_DRAW_E3K, + MM_AT_SVM_POINTER_E3K, + MM_AT_OCL_SPECIAL_BUFFER_E3K, + MM_AT_LAST_E3K, +} MM_ALLOCATION_TYPE_E3K; + + +typedef enum MM_DRIVERID_E3K +{ + MM_DRIVERID_INVALID = 0, + // 2D + MM_DRIVERID_2D_SOURCE, + MM_DRIVERID_2D_DESTINATION, + // 3D + // IA + MM_DRIVERID_VERTEXBUFFER_ADDRESS,// 32 + MM_DRIVERID_INDEXBUFFER_ADDRESS, + // STO + MM_DRIVERID_SO_BUFFER_ADDRESS, + MM_DRIVERID_SO_BUFFER_BOUND, + // VS + MM_DRIVERID_VS_SHADER, + MM_DRIVERID_VS_TEXTURE, // 128 + MM_DRIVERID_VS_TSHARP, // 8 + MM_DRIVERID_VS_SSHARP, // 8 + MM_DRIVERID_VS_BCSHARP, + + // HS + MM_DRIVERID_HS_SHADER, + MM_DRIVERID_HS_TEXTURE, // 128 + MM_DRIVERID_HS_TSHARP, // 8 + MM_DRIVERID_HS_SSHARP, // 8 + MM_DRIVERID_HS_BCSHARP, + + // DS + MM_DRIVERID_DS_SHADER, + MM_DRIVERID_DS_TEXTURE, // 128 + MM_DRIVERID_DS_TSHARP, // 8 + MM_DRIVERID_DS_SSHARP, // 8 + MM_DRIVERID_DS_BCSHARP, + + // GS + MM_DRIVERID_GS_SHADER, + MM_DRIVERID_GS_TEXTURE, // 128 + MM_DRIVERID_GS_TSHARP, // 8 + MM_DRIVERID_GS_SSHARP, // 8 + MM_DRIVERID_GS_BCSHARP, + + // PS + MM_DRIVERID_PS_SHADER, + MM_DRIVERID_PS_TEXTURE, // 128 + MM_DRIVERID_PS_TSHARP, // 8 + MM_DRIVERID_PS_SSHARP, // 8 + MM_DRIVERID_PS_BCSHARP, + + // OM + MM_DRIVERID_RENDERTARGET, // 8 + MM_DRIVERID_DEPTHBUFFER, + MM_DRIVERID_STENCILBUFFER, + + // EU ThreadSpace + MM_DRIVERID_THREADSPACE, + MM_DRIVERID_CSHARP, + + MM_DRIVERID_RANGE_FLAGBUFFER, // 32 + MM_DRIVERID_RANGE, // 32 + MM_DRIVERID_RANGE_BOUND, // 32 + + // CS + MM_DRIVERID_CS_SHADER, + MM_DRIVERID_CS_TEXTURE, // 128 + MM_DRIVERID_CS_TSHARP, // 8 + MM_DRIVERID_CS_SSHARP, // 8 + MM_DRIVERID_CSUNORDEREDACCESS, // 8 + + MM_DRIVERID_CSL1, + MM_DRIVERID_CSL2, + MM_DRIVERID_CSL3, + + MM_DRIVERID_3D_LAST, // All above are state related + + // RM 3DBLT,Clear,MASS,AutoGen + MM_DRIVERID_RM_DEPTHBUFFER, + MM_DRIVERID_RM_STENCILBUFFER, + MM_DRIVERID_RM_PS_TEXTURE, + MM_DRIVERID_RM_RENDERTARGET, + MM_DRIVERID_RM_VERTEXBUFFER, + + + // MISC + MM_DRIVERID_CONTEXT, + MM_DRIVERID_FENCE, + MM_DRIVERID_SIGNATURE, + MM_DRIVERID_SIGNATURE_PER_DRAW, + MM_DRIVERID_DIP_PARAM_BUFFER_ADDRESS, + MM_DRIVERID_DIP_INDIRECT_BUFFER_ADDRESS, + MM_DRIVERID_DISPATCH_INDIRECT_BUFFER_ADDRESS, + MM_DRIVERID_SO_BUFFER_FILL_SIZE_POOL, + MM_DRIVERID_UA_APPEND_FILLED_SIZE_POOL, + MM_DRIVERID_FLAGBUFFER, + MM_DRIVERID_CMDBUFFER, + MM_DRIVERID_SVM_POINTER, + MM_DRIVERID_MIUCOUNTER, + // Video + MM_DRIVERID_VIDEO_RESERVEDMEM, // 16 + MM_DRIVERID_VIDEO_SIGNATURE, // 8 + MM_DRIVERID_VIDEO_FENCE, // 1 + MM_DRIVERID_VIDEO_PATCH, // 8 + MM_DRIVERID_VIDEO_DECODE_COMPBUFF, // 1 + MM_DRIVERID_VIDEO_DECODE_MSVD, // 20 + MM_DRIVERID_VIDEO_DECODE_CMD, // 1 + MM_DRIVERID_VIDEO_DECODE_INS, // 1 + MM_DRIVERID_VIDEO_DECODE_VCPDMA, + MM_DRIVERID_VIDEO_DECODE_VCPSBDMA, + MM_DRIVERID_VIDEO_DECODE_QTMDMA, + MM_DRIVERID_VIDEO_DECODE_DRVDMA, + MM_DRIVERID_VIDEO_DRAWID, + + // DIU + MM_DRIVERID_VIDEO_PS1_ADDR0, + MM_DRIVERID_VIDEO_PS2_ADDR0, + MM_DRIVERID_VIDEO_SS1_ADDR0, + MM_DRIVERID_VIDEO_SS2_ADDR0, + MM_DRIVERID_VIDEO_SS1_MMIOUPDATE_ADDR0, + MM_DRIVERID_VIDEO_SS2_MMIOUPDATE_ADDR0, + MM_DRIVERID_VIDEO_SS1_MMIOFLIP_ADDR0, + MM_DRIVERID_VIDEO_SS2_MMIOFLIP_ADDR0, + MM_DRIVERID_VIDEO_BACKLIGHT_CTRL_VALUE, + + //ISP + MM_DRIVERID_ISP_VPP_SRC, + MM_DRIVERID_ISP_VPP_DST, + MM_DRIVERID_ISP_CAPTURE, + MM_DRIVERID_ISP_BACKLIGHT_CTRL_BUFF, + + // Cache invalidate + MM_DRIVERID_INVALID_STREAMCACHE_VS_ADDRESS, + MM_DRIVERID_INVALID_STREAMCACHE_HS_ADDRESS, + MM_DRIVERID_INVALID_STREAMCACHE_DS_ADDRESS, + MM_DRIVERID_INVALID_STREAMCACHE_GS_ADDRESS, + MM_DRIVERID_INVALID_STREAMCACHE_PS_ADDRESS, + MM_DRIVERID_INVALID_STREAMCACHE_CS_ADDRESS, + MM_DRIVERID_INVALID_L2_CACHE_ADDRESS, + MM_DRIVERID_INVALID_L2_CACHE_MASK, + + // split 32 bits address to two 16 bits address in ppmode + MM_DRIVERID_PPMODE_SPLIT_ADDR, + + // only for model extension SetBufferAddrToCB + MM_DRIVERID_VERTEXBUFFER_40BIT_ADDRESS, + + MM_DRIVERID_HEAP, + MM_DRIVERID_SECOND_BUFFER_ADDRESS, + MM_DRIVERID_DESCRIPTOR_HEAP, + MM_DRIVERID_QUERYPOOL, + MM_DRIVERID_TBR_SIGNATURE_BUFFER_ADDRESS, + MM_DRIVERID_LAST, + +} MM_DRIVERID_E3K; + + +typedef struct MM_ALLOCATION_DESC MM_ALLOCATION_DESC_E3K; + + +typedef struct +{ + int bTileSupport; + unsigned int tileSizeInBytes; + unsigned int dwTileSizeX[10]; + unsigned int dwTileSizeY[10]; +}KMDTILEINFO_E3K; + +extern const KMDTILEINFO_E3K hwKMDTileInfo_e3k; + +#define HW_KMD_TILE_INFO_E3K \ +{\ + TRUE, /* bTileSupported */ \ + 0x10000, /* tileSizeInBytes = 64KB */ \ + /* dwTileSizeX */ \ + 0x200, /* dwTileSizeX - 1bit, E1 not support */ \ + 0xFFFFFFFF, /*dummy item for Nearestlog2() */ \ + 0x0, /* dwTileSizeX - 4bit, E1 not support */ \ + 0x100, /* dwTileSizeX - 8bit,*/ \ + 0x100, /* dwTileSizeX - 16bit */ \ + 0x80, /* dwTileSizeX - 32bit */ \ + 0x80, /* dwTileSizeX - 64bit,*/ \ + 0x40, /* dwTileSizeX - 128bit,*/ \ + 0x40, /* dwTileSizeX - 256bit,*/ \ + 0x20, /* dwTileSizeX - 512bit,*/ \ + /* dwTileSizeY */ \ + 0x100, /* dwTileSizeY - 1bit, E1 not support */ \ + 0xFFFFFFFF, /* dummy item for Nearestlog2() */ \ + 0x0, /* dwTileSizeY - 4bit, E1 not support */ \ + 0x100, /* dwTileSizeY - 8bit, */ \ + 0x80, /* dwTileSizeY - 16bit */ \ + 0x80, /* dwTileSizeY - 32bit */ \ + 0x40, /* dwTileSizeY - 64bit, */ \ + 0x40, /* dwTileSizeX - 128bit, */ \ + 0x20, /* dwTileSizeX - 256bit, */ \ + 0x20, /* dwTileSizeX - 512bit, */ \ +} + +static inline int IsPow2(unsigned int value) +{ + return (!(value & (value-1))); +} + +/*---------------------------------------------------------------------------*/ +/* NearestLog2() */ +/* */ +/* Finds the closest integer base-2 log of a value. */ +/* (0 will return 0xFFFFFFFF) */ +/*---------------------------------------------------------------------------*/ +static inline unsigned int NearestLog2(unsigned int val) +{ + unsigned int result = 0xFFFFFFFF; + unsigned int input = val; + + while (val & 0xFFFFFFF0) + { + val >>= 4; + result += 4; + } + + while (val) + { + val >>= 1; + result++; + } + + // + // if val is not a pow2, increment by one, since + // this function floors + // + + if (IsPow2(input) == 0) + { + result++; + } + + return(result); +} +#define ALIGNED_2KBits(Value) (((Value) + 0xFF) & ~0xFF) +#define ALIGNED_128KBYTE(Value) (((Value) + 0x1FFFF) & ~0x1FFFF) + + +#define TILE_SIZE_IN_BYTES (hwKMDTileInfo_e3k.tileSizeInBytes) +#define TILE_SIZE_X(bpp) (hwKMDTileInfo_e3k.dwTileSizeX[NearestLog2(bpp)]) +#define TILE_SIZE_Y(bpp) (hwKMDTileInfo_e3k.dwTileSizeY[NearestLog2(bpp)]) +#define ALIGN_TO_X_TILE_SIZE(value,bpp) (((value) + TILE_SIZE_X(bpp) - 1) & ~(TILE_SIZE_X(bpp) - 1)) +#define ALIGN_TO_Y_TILE_SIZE(value,bpp) (((value) + TILE_SIZE_Y(bpp) - 1) & ~(TILE_SIZE_Y(bpp) - 1)) +#define NUM_OF_X_TILES(value,bpp) (ALIGN_TO_X_TILE_SIZE((value),(bpp)) / TILE_SIZE_X(bpp)) +#define NUM_OF_Y_TILES(value,bpp) (ALIGN_TO_Y_TILE_SIZE((value),(bpp)) / TILE_SIZE_Y(bpp)) + + +/* + * definition segment assocated + */ +typedef enum _SEGMENT_ID_E3K +{ + SEGMENT_ID_INVALID_E3K = 0x0, + SEGMENT_ID_LOCAL_E3K = 0x1, + SEGMENT_ID_GART_UNSNOOPABLE_E3K = 0x2, + SEGMENT_ID_GART_SNOOPABLE_E3K = 0x3, + SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K = 0x4, + SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K_1 = 0x5, + SEGMENT_ID_SECURE_RANGE_E3K = 0x6, + SEGMENT_ID_SECURE_RANGE_E3K_1 = 0x7, + SEGMENT_ID_MAX_E3K = 0x8, +} SEGMENT_ID_E3K; + +#define SMALL_HEAP_SIZE_E3K (4*1024*1024) //4M +#define SMALL_HEAP_MAX_ALLOCATE_SIZE_E3K (32*1024) //32K +#define SMALL_HEAP_MAX_ALLOCATE_SIZE_GART_E3K (64*1024) //64K + +// hang dump define +#define E3K_RINGBUFFER_FOR_HANG_SIZE (0x4000) // include DH_COMMON_INFO +#define E3K_DMABUFFER_FOR_HANG_SIZE (0x400000) +#define E3K_CONTEXTBUFFER_FOR_HANG_SIZE (0x160000) +#define E3K_TRANSFERBUFFER_FOR_HANG_SIZE (0x1000000) //16M +#define E3K_RANGE_FORMAT_BUFFER_SIZE (0x10000) + +#define E3K_LOCAL_MEMORY_MAX_ADDR_FOR_HANG_DUMP (252*1024*1024) + +#define GPU_PAGE_SIZE_E3K (4*1024) //4K +// should use ULL instead of U as suffix, since 2G * 3 > 4G, the maximum of 32bit +#define GART_MEMORY_SIZE_E3K (8*1024*1024*1024ULL) //8G, actually this is pcie memory +#define PAGING_SEGMENT_SIZE_E3K (1*1024*1024*1024ULL) //1G +#define SNOOPABLE_SEGMENT_RATION_E3K(size) ((adapter->hw_caps.snoop_only)?(size):(((size)*1/2)&~15)) + +//secure range +#define SECURE_RANGE_NUM 8 +#define SECURE_RANGE_BUFFER_SIZE (32*1024*1024) +#define SECURE_RANGE_ENCRYPTEN_ADDRESS (0xD3F0) +#define SECURE_RANGE_SCRAMBLE_PATTEN_ADDRESS (0xD300) + +#define MIU0_RANGE_BASE_ADDRESS (0xD390) +#define MIU1_RANGE_BASE_ADDRESS (0xD790) + +//Burst length buffer + +#define BL_BUFFER_SIZE 0x2000000 //32M +#define BL_BUFFER_ALIGN 0x10000 //64K +//from spec, current bl index bit using 18bit plan. +#define BL_INDEX_BITS 18 +//from spec, 1byte slot map to 512byte allocation +#define BL_MAPPING_RATIO 512 + +#define BL_SLOT_SIZE (BL_BUFFER_SIZE >> BL_INDEX_BITS) +#define BL_SLICE_ALIGNMENT (BL_BUFFER_SIZE >> BL_INDEX_BITS) + +#endif + diff --git a/drivers/gpu/drm/arise/core/e3k/include/register_e3k.h b/drivers/gpu/drm/arise/core/e3k/include/register_e3k.h new file mode 100644 index 0000000000000..17798a065c28c --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/register_e3k.h @@ -0,0 +1,144 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __REGISTER_E3K_H__ +#define __REGISTER_E3K_H__ + +#include "core_import.h" + +#define AR_INIT_REG 0x83DA +#define AR_INDEX 0x83C0 +#define AR_DATA 0x83C1 +#define CR_INDEX 0x83D4 +#define CR_DATA 0x83D5 +#define SR_INDEX 0x83C4 +#define SR_DATA 0x83C5 + +//mmioOffset of registers +#define MMIO_OFFSET_SR_GROUP_A_E3K 0x8600 +#define MMIO_OFFSET_SR_GROUP_B_E3K 0x8700 +#define MMIO_OFFSET_CR_GROUP_A_E3K 0x8800 +#define MMIO_OFFSET_CR_GROUP_B_E3K 0x8900 +#define MMIO_OFFSET_CR_GROUP_C_E3K 0x8A00 +#define MMIO_OFFSET_CR_GROUP_D_E3K 0x8B00 // for 4-channel MIU CR_D registers +#define MMIO_OFFSET_CR_GROUP_D0_E3K 0x8C00 // MIU channel 0 CR_D registers +#define MMIO_OFFSET_CR_GROUP_D1_E3K 0x8D00 // MIU channel 1 CR_D registers +#define MMIO_OFFSET_CR_GROUP_D2_E3K 0x8E00 // MIU channel 2 CR_D registers +#define MMIO_OFFSET_CR_GROUP_D3_E3K 0x8F00 // MIU channel 3 CR_D registers +#define MMIO_OFFSET_SR_GROUP_T_E3K 0x9400 +#define MMIO_OFFSET_CR_GROUP_T_E3K 0x9500 + +/* same to CBIOS_REGISTER_TYPE */ +enum +{ + /* CR_SET = 0, //CR registers to be set, used in s3postreg */ + /* SR_SET, //SR registers to be set */ + /* GR_SET, //GR registers to be set */ + CR=0, /*CR registers */ + SR, /*SR registers */ + AR, + GR, + MISC, + CR_X, + SR_X, + CR_B, /* B-set of CR */ + CR_C, /* C-set of CR */ + CR_D, /* D-set of CR */ + CR_T, /* CR on IGA3 */ + SR_T, /* SR on IGA3 */ + SR_B, + CR_D_0, + CR_D_1, + CR_D_2, + CR_D_3, + RESERVED=0xFF +}; + +static __inline__ void write_reg_e3k(unsigned char *mmio, int type, unsigned char index, unsigned char value, unsigned char mask) +{ + unsigned int offset = 0; + unsigned char temp = 0; + + switch(type) + { + case CR: + offset = MMIO_OFFSET_CR_GROUP_A_E3K + index; + break; + case CR_B: + offset = MMIO_OFFSET_CR_GROUP_B_E3K + index; + break; + case CR_C: + offset = MMIO_OFFSET_CR_GROUP_C_E3K + index; + break; + case SR: + offset = MMIO_OFFSET_SR_GROUP_A_E3K + index; + break; + case SR_B: + offset = MMIO_OFFSET_SR_GROUP_B_E3K + index; + break; + case SR_T: + offset = MMIO_OFFSET_SR_GROUP_T_E3K + index; + break; + case CR_T: + offset = MMIO_OFFSET_CR_GROUP_T_E3K + index; + break; + default: + gf_assert(0, NULL); + break; + } + + temp = gf_read8(mmio + offset); + temp = (temp & mask) | (value & ~mask); + + gf_write8(mmio + offset, temp); +} + +static __inline__ unsigned char read_reg_e3k(unsigned char *mmio, int type, unsigned char index) +{ + unsigned int offset = 0; + unsigned char temp = 0; + + switch(type) + { + case CR: + offset = MMIO_OFFSET_CR_GROUP_A_E3K + index; + break; + case CR_B: + offset = MMIO_OFFSET_CR_GROUP_B_E3K + index; + break; + case CR_C: + offset = MMIO_OFFSET_CR_GROUP_C_E3K + index; + break; + case SR: + offset = MMIO_OFFSET_SR_GROUP_A_E3K + index; + break; + case SR_B: + offset = MMIO_OFFSET_SR_GROUP_B_E3K + index; + break; + case AR: + gf_read8(mmio + AR_INIT_REG); + gf_write8(mmio + AR_INDEX, index); + temp = gf_read8(mmio + AR_DATA); + return temp; + default: + gf_assert(0, NULL); + break; + } + + temp = gf_read8(mmio + offset); + + return temp; +} +#endif + diff --git a/drivers/gpu/drm/arise/core/e3k/include/stm_context_e3k.h b/drivers/gpu/drm/arise/core/e3k/include/stm_context_e3k.h new file mode 100644 index 0000000000000..02146158f6c7f --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/include/stm_context_e3k.h @@ -0,0 +1,514 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _STM_CONTEXT_E3K_H +#define _STM_CONTEXT_E3K_H + +#ifndef __linux__ +#define CACHE_ALIGN __declspec(align(64)) +#else +#define CACHE_ALIGN __attribute__((aligned(64))) +#endif + +#include "./Chip/registerDef.h" + +typedef struct _Mxu_Context_regs +{ + Reg_Fb_Ctrl reg_Fb_Ctrl; + Reg_Mmu_Mode reg_Mmu_Mode; +// Reg_Vbl_Base reg_Vbl_Base; +// Reg_Pbl_Base reg_Pbl_Base; + Reg_Gart_Base reg_Gart_Base; + Reg_Proc_Sec reg_Proc_Sec; + Reg_Pt_Inv_Addr reg_Pt_Inv_Addr; + Reg_Pt_Inv_Mask reg_Pt_Inv_Mask; + Reg_Pt_Inv_Trig reg_Pt_Inv_Trig; + Reg_Mxu_Channel_Control reg_Mxu_Channel_Control; + Reg_Mxu_Dec_Ctrl reg_Mxu_Dec_Ctrl; + Reg_Bus_Id_Mode reg_Bus_Id_Mode; + Reg_Mxu_Ctrl_0 reg_Mxu_Ctrl_0; +} Mxu_Context_regs; + +typedef struct CONTEXT_REGISTER_BUFFER_E3K +{ + int todo; +} CONTEXT_REGISTER_BUFFER_E3K; + +#define MAX_HW_SLICE_NUM 8 +#define SLICE_ILA_COUNTERS_ALIGN_SIZE 32 +#define FENCE_COUNTER_NUM 16 + +#define HW_MAX_GPC_NUM_E3K 3 + +typedef struct _CSP_CONTEXTBUFFER_REGS +{ + Reg_Csp_Ms_Total_Gpu_Timestamp reg_Csp_Ms_Total_Gpu_Timestamp[2]; + Reg_Csp_Ms_Total_Busy_Time reg_Csp_Ms_Total_Busy_Time[2]; + Reg_Csp_Ms_Query_Occlusion reg_Csp_Ms_Query_Occlusion[2]; + Reg_Ia_Vertices_Cnt reg_Ia_Vertices_Cnt[2]; + Reg_Ia_Primitives_Cnt reg_Ia_Primitives_Cnt[2]; + Reg_Ia_Ogl_Cut_Flag_32 reg_Ia_Ogl_Cut_Flag_32; + Reg_Ia_Vb0_Offset reg_Ia_Vb0_Offset; + Reg_Ia_Vb0_Stride reg_Ia_Vb0_Stride; + Reg_Ia_Bufferfilledsize reg_Ia_Bufferfilledsize; + Reg_Ia_Batch_Cfg reg_Ia_Batch_Cfg; + Reg_Predicate_Status reg_Predicate_Status; + Reg_Csp_Misc_Control reg_Csp_Misc_Control; + Reg_Tbr_Render_Mode_Ctrl reg_Tbr_Render_Mode_Ctrl; + Reg_Tbr_Frametimestamp_Lth reg_Tbr_Frametimestamp_Lth; + Reg_Tbr_Frametimestamp_Hth reg_Tbr_Frametimestamp_Hth; + Reg_Tbr_Traffic_Th reg_Tbr_Traffic_Th; + Reg_Tbr_Event_Count_Ref reg_Tbr_Event_Count_Ref; + Reg_Descriptor_Base_Addr_Group reg_Descriptor_Base_Addr[8]; + Reg_Csp_Fence_Counter_Group reg_Csp_Fence_Counter[FENCE_COUNTER_NUM]; +} CSP_CONTEXTBUFFER_REGS; +/**********************************here is the definition for all the state registers**************************************/ +// Gpcpfe_Shadow_Reg + GPCPFE_CONTEXTBUFFER_REGS = full Gpcpfe_regs +typedef struct _Gpcpfe_Shadow_Reg +{ + Reg_Gpcpfe_Instance_Group reg_Gpcpfe_Instance[32]; + Reg_Gpcpfe_Inst_Mask reg_Gpcpfe_Inst_Mask; + Reg_Gpcpfe_Reserved reg_Gpcpfe_Reserved[7]; +} Gpcpfe_Shadow_Reg; + +typedef struct _GPCPFE_CONTEXTBUFFER_REGS +{ + Reg_Gpcpfe_Iidcnt_Group reg_Gpcpfe_Iidcnt[32]; + Reg_Gpcpfe_Iid reg_Gpcpfe_Iid; + Reg_Gpcpfe_Pid reg_Gpcpfe_Pid; + Reg_Gpcpfe_Gp_Global_Group reg_Gpcpfe_Gp_Global; + Reg_Gpcpfe_Gp_Group_Group reg_Gpcpfe_Gp_Group; +}GPCPFE_CONTEXTBUFFER_REGS; + +typedef struct _EUFS_State_Reg +{ + Reg_Eu_Full_Glb reg_Eu_Full_Glb; + Reg_Eu_3d_Glb reg_Eu_3d_Glb; + Reg_Eu_Fe_Glb reg_Eu_Fe_Glb; + Reg_Mv_Cfg reg_Mv_Cfg; + Reg_Vc_Size_Cfg0 reg_Vc_Size_Cfg0; + Reg_Vc_Size_Cfg1 reg_Vc_Size_Cfg1; + Reg_Vc_Base_Cfg0 reg_Vc_Base_Cfg0; + Reg_Vc_Base_Cfg1 reg_Vc_Base_Cfg1; + Reg_Fs_Cfg reg_Fs_Cfg; + Reg_Max_Threads_Cfg reg_Max_Threads_Cfg; + Reg_Antilock_Cfg reg_Antilock_Cfg; + Reg_Vs_Ctrl reg_Vs_Ctrl; + Reg_Hs_Ctrl reg_Hs_Ctrl; + Reg_Hs_In_Cfg reg_Hs_In_Cfg; + Reg_Hs_Out_Cfg reg_Hs_Out_Cfg; + Reg_Ds_Ctrl reg_Ds_Ctrl; + Reg_Ds_In_Cfg reg_Ds_In_Cfg; + Reg_Gs_Ctrl reg_Gs_Ctrl; + Reg_Gs_In_Cfg reg_Gs_In_Cfg; + Reg_Gs_Out_Cfg reg_Gs_Out_Cfg; + Reg_Ts_Ctrl reg_Ts_Ctrl; + Reg_Ts_Input_Mapping0 reg_Ts_Input_Mapping0; + Reg_Ts_Input_Mapping1 reg_Ts_Input_Mapping1; + Reg_Ts_Factors_Const reg_Ts_Factors_Const[6]; + Reg_Fs_Cs_Ctrl reg_Fs_Cs_Ctrl; + Reg_Fs_Cs_Sm_Cfg reg_Fs_Cs_Sm_Cfg; + Reg_Fs_Out_Loc0 reg_Fs_Out_Loc0; + Reg_Fs_Out_Loc1 reg_Fs_Out_Loc1; + Reg_Fs_Out_Mapping reg_Fs_Out_Mapping[12]; + Reg_Fs_Out_Comp reg_Fs_Out_Comp[3]; + Reg_Fs_Out_Mask reg_Fs_Out_Mask[6]; + Reg_Fs_Pm_Cfg reg_Fs_Pm_Cfg; + Reg_Fs_Pm_Id reg_Fs_Pm_Id; + Reg_Vgs_Pm_Range reg_Vgs_Pm_Range; + Reg_Hds_Pm_Range reg_Hds_Pm_Range; + Reg_Fs_U_Enable reg_Fs_U_Enable[4]; + Reg_Fs_U_Fmt reg_Fs_U_Fmt[16]; + Reg_Fs_U_Layout reg_Fs_U_Layout[4]; + Reg_Vcs_U_Cfg reg_Vcs_U_Cfg; + Reg_Hs_U_Cfg reg_Hs_U_Cfg; + Reg_Ds_U_Cfg reg_Ds_U_Cfg; + Reg_Gs_U_Cfg reg_Gs_U_Cfg; + Reg_Vcs_Instr0 reg_Vcs_Instr0; + Reg_Vcs_Instr1 reg_Vcs_Instr1; + Reg_Vcs_Instr_Range reg_Vcs_Instr_Range; + Reg_Hs_Instr0 reg_Hs_Instr0; + Reg_Hs_Instr1 reg_Hs_Instr1; + Reg_Hs_Instr_Range reg_Hs_Instr_Range; + Reg_Ds_Instr0 reg_Ds_Instr0; + Reg_Ds_Instr1 reg_Ds_Instr1; + Reg_Ds_Instr_Range reg_Ds_Instr_Range; + Reg_Gs_Instr0 reg_Gs_Instr0; + Reg_Gs_Instr1 reg_Gs_Instr1; + Reg_Gs_Instr_Range reg_Gs_Instr_Range; + Reg_Vcs_Cb_Cfg reg_Vcs_Cb_Cfg; + Reg_Hs_Cb_Cfg reg_Hs_Cb_Cfg; + Reg_Ds_Cb_Cfg reg_Ds_Cb_Cfg; + Reg_Gs_Cb_Cfg reg_Gs_Cb_Cfg; + Reg_Fs_Cb_Cfg reg_Fs_Cb_Cfg; + Reg_Fs_Rev_8aligned reg_Fs_Rev_8aligned; + +} EUFS_State_Reg; + +typedef struct _EU_CB_Reg +{ + Reg_Fs_Cb_Data reg_Fs_Cb_Data[2048]; +} EU_CB_Reg; + +typedef struct _EUPS_State_Reg +{ + Reg_Ps_Cfg reg_Ps_Cfg; + Reg_Ps_Ctrl reg_Ps_Ctrl; + Reg_Ps_Out_Cfg reg_Ps_Out_Cfg; + Reg_Ps_Doutbuf_Cfg reg_Ps_Doutbuf_Cfg; + Reg_Ps_Pm_Cfg reg_Ps_Pm_Cfg; + Reg_Ps_Pm_Id reg_Ps_Pm_Id; + Reg_Ps_Pm_Range reg_Ps_Pm_Range; + Reg_Ps_Out_Mapping reg_Ps_Out_Mapping; + Reg_Ps_Out_Fmt reg_Ps_Out_Fmt; + Reg_Ps_U_Enable reg_Ps_U_Enable[2]; + Reg_Ps_U_Fmt reg_Ps_U_Fmt[8]; + Reg_Ps_U_Layout reg_Ps_U_Layout[2]; + Reg_Ps_U_Cfg reg_Ps_U_Cfg; + Reg_Ps_Instr0 reg_Ps_Instr0; + Reg_Ps_Instr1 reg_Ps_Instr1; + Reg_Ps_Instr_Range reg_Ps_Instr_Range; + Reg_Ps_Cb_Cfg reg_Ps_Cb_Cfg; + Reg_Ps_Rev_8aligned reg_Ps_Rev_8aligned[6]; + //add reserve reg to algin each each block's shadow to 8dword per line +} EUPS_State_Reg; + +typedef struct _WLS_Usharp_Reg +{ + Reg_Uav_Group_Group reg_Uav_Group[128]; + +} WLS_Usharp_Reg; + +typedef struct _WLS_State_Reg +{ + Reg_Ffc_Ubuf_Golbalconfig reg_Ffc_Ubuf_Golbalconfig; + Reg_Ffc_Ubuf_3dconfig reg_Ffc_Ubuf_3dconfig; + Reg_Descriptor_Heap_Base reg_Descriptor_Heap_Base[8]; + Reg_Wls_Reserved0 reg_Wls_Reserved0; + Reg_Wls_Reserved1 reg_Wls_Reserved1; + Reg_Wls_Reserved2 reg_Wls_Reserved2; + Reg_Wls_Reserved3 reg_Wls_Reserved3; + Reg_Wls_Reserved4 reg_Wls_Reserved4; + Reg_Wls_Reserved5 reg_Wls_Reserved5; + +} WLS_State_Reg; + +typedef struct _TU_State_Reg +{ + Reg_Tu_Tssharp_Ctrl reg_Tu_Tssharp_Ctrl; + Reg_Tu_Tssharp_3d_Ctrl reg_Tu_Tssharp_3d_Ctrl; + Reg_Tu_Tssharp_Heap_Base0 reg_Tu_Tssharp_Heap_Base0; + Reg_Tu_Tssharp_Heap_Base1 reg_Tu_Tssharp_Heap_Base1; + Reg_Tu_Tssharp_Heap_Base2 reg_Tu_Tssharp_Heap_Base2; + Reg_Tu_Tssharp_Heap_Base3 reg_Tu_Tssharp_Heap_Base3; + Reg_Tu_Tssharp_Heap_Base4 reg_Tu_Tssharp_Heap_Base4; + Reg_Tu_Tssharp_Heap_Base5 reg_Tu_Tssharp_Heap_Base5; + Reg_Tu_Tssharp_Heap_Base6 reg_Tu_Tssharp_Heap_Base6; + Reg_Tu_Tssharp_Heap_Base7 reg_Tu_Tssharp_Heap_Base7; + Reg_Tu_Reserved1 reg_Tu_Reserved1[6]; + Reg_Tu_Control_Fe reg_Tu_Control_Fe; + Reg_Tu_Si_Ctl reg_Tu_Si_Ctl; + Reg_Tu_Vs_Tsharp_Ctrl reg_Tu_Vs_Tsharp_Ctrl; + Reg_Tu_Vs_Ssharp_Ctrl reg_Tu_Vs_Ssharp_Ctrl; + Reg_Tu_Hs_Tsharp_Ctrl reg_Tu_Hs_Tsharp_Ctrl; + Reg_Tu_Hs_Ssharp_Ctrl reg_Tu_Hs_Ssharp_Ctrl; + Reg_Tu_Ds_Tsharp_Ctrl reg_Tu_Ds_Tsharp_Ctrl; + Reg_Tu_Ds_Ssharp_Ctrl reg_Tu_Ds_Ssharp_Ctrl; + Reg_Tu_Gs_Tsharp_Ctrl reg_Tu_Gs_Tsharp_Ctrl; + Reg_Tu_Gs_Ssharp_Ctrl reg_Tu_Gs_Ssharp_Ctrl; + Reg_Tu_Reserved2 reg_Tu_Reserved2[6]; + Reg_Tu_Vb_Group reg_Tu_Vb[32]; + Reg_Tu_Ve_Group reg_Tu_Ve[32]; + Reg_Tu_Instance_Group reg_Tu_Instance[32]; + Reg_Tu_Control_Be reg_Tu_Control_Be; + Reg_Tu_Ps_Tsharp_Ctrl reg_Tu_Ps_Tsharp_Ctrl; + Reg_Tu_Ps_Ssharp_Ctrl reg_Tu_Ps_Ssharp_Ctrl; + Reg_Tu_Reserved3 reg_Tu_Reserved3[5]; + + +} TU_State_Reg; + +typedef struct _Tsharp_Reg +{ + Reg_Tu_Ts_Sharp_Group reg_Tu_Ts_Sharp[192]; + +} Tsharp_Reg; + +typedef struct CSP_REG_FLAG +{ + DWORD dirty_flag : 1; +}CSP_REG_FLAG; + +/*****************************************here is the definition for flag buffer*******************************************/ +typedef struct _Shadow_FE_BE_Flag +{ + CSP_REG_FLAG ff_regs_flag[FF_REG_END]; + CSP_REG_FLAG gpcpfe_regs_flag[GPCPFE_REG_END]; + CSP_REG_FLAG spin_regs_flag[SPIN_REG_END]; + CSP_REG_FLAG eu_fs_regs_flag[Reg_Fs_Rev_Cb_Offset]; + CSP_REG_FLAG eu_ps_regs_flag[Reg_Ps_Rev_Cb_Offset]; + CSP_REG_FLAG eu_cb_regs_flag[Reg_Dbg_Cfg_Offset - Reg_Fs_Cb_Data_Offset]; + CSP_REG_FLAG tasfe_regs_flag[TASFE_REG_END]; + CSP_REG_FLAG iu_regs_flag[IU_REG_END]; + CSP_REG_FLAG wls_regs_flag[Reg_Ffc_Ubuf_Csconfig_Offset]; + CSP_REG_FLAG wls_usharp_flag[WLS_FE_REG_END - Reg_Uav_Group_Offset]; + CSP_REG_FLAG tu_regs_flag[Reg_Tu_Tssharp_Cs_Ctrl_Offset]; + CSP_REG_FLAG tu_tsharp_flag[TUFE_REG_END - Reg_Tu_Ts_Sharp_Offset]; + //CSP_REG_FLAG gpcpbe_regs_flag[GPCPBE_REG_END]; + CSP_REG_FLAG spout_regs_flag[SPOUT_REG_END]; + CSP_REG_FLAG l2_regs_flag[L2_REG_END]; +} Shadow_FE_BE_Flag; + +typedef struct _Shadow_FE_BE_Reg +{ + Ff_regs ff_regs; + Gpcpfe_Shadow_Reg gpcpfe_regs; + Spin_regs spin_regs; + EUFS_State_Reg eufs_regs; + EUPS_State_Reg eups_regs; + EU_CB_Reg eucb_regs; + Tasfe_regs tasfe_regs; + Iu_regs iu_regs; + WLS_State_Reg wls_regs; + WLS_Usharp_Reg usharp_regs; + TU_State_Reg tu_regs; + Tsharp_Reg tsharp_regs; + //Gpcpbe_regs gpcpbe_regs; + Spout_regs spout_regs; + L2_regs l2_regs; +} Shadow_FE_BE_Reg; + +typedef struct _CSP_3D_ShadowBuf +{ + Shadow_FE_BE_Reg fe_be_regs; +} CSP_3D_ShadowBuf; + +typedef struct _CSP_3D_FlagBuf// for 3D shadow buffer, when update, should compare with the original value to see whether to set the dirty into true +{ + Shadow_FE_BE_Flag fe_be_flag; +} CSP_3D_FlagBuf; + +typedef struct _CSP_3D_ContextBuf +{ + CSP_3D_ShadowBuf shadow_buf_3D; + CSP_3D_FlagBuf flag_buf_3D; + +}CSP_3D_ContextBuf; + +typedef CACHE_ALIGN struct _CONTEXT_BUFFER_E3K +{ + CACHE_ALIGN CSP_3D_ContextBuf HWContextbuffer; + /*CACHE_ALIGN*/ CSP_CONTEXTBUFFER_REGS CSPRegs; + /*CACHE_ALIGN*/ GPCPFE_CONTEXTBUFFER_REGS GpcpFeRegs; + /*CACHE_ALIGN*/ Gpcpbe_regs GpcpBeRegs; + DWORD GpcTopRegs[HW_MAX_GPC_NUM_E3K][40]; +}CONTEXT_BUFFER_E3K; + +#undef CACHE_ALIGN + +#define CONTEXT_BUFFER_ALIGN (0x4000) // Align to 16K for HW requirement +#define CONTEXT_BUFFER_SIZE \ + ((sizeof(CONTEXT_BUFFER_E3K) + (CONTEXT_BUFFER_ALIGN -1)) & (~(CONTEXT_BUFFER_ALIGN -1))) + +#define REGISTER_BUFFER_SIZE sizeof(CONTEXT_REGISTER_BUFFER_E3K) + +#define GPCPBE_QUERY_REGISTERS (sizeof(Gpcpbe_regs) % 0x40 ? (sizeof(Gpcpbe_regs) / 0x40) + 1 :(sizeof(Gpcpbe_regs) / 0x40)) + +#define SAVE_RESTORE_DMA_SIZE (sizeof(RB_PREDEFINE_DMA) + (0x1000 - 1) & (~(0x1000 -1))) + +typedef struct _CONTEXT_RESTORE_DMA_E3K +{ + Cmd_Blk_Cmd_Csp_Save_Rsto RestoreContext; + DWORD ContextBufferOffset_L; + DWORD ContextBufferOffset_H; + + Csp_Opcodes_cmd RestoreEuFullGlb; + DWORD EuFullGlbOffset_L; + DWORD EuFullGlbOffset_H; + + Csp_Opcodes_cmd RestoreTsSharpCtrl; + DWORD TsSharpCtrlOffset_L; + DWORD TsSharpCtrlOffset_H; + + Csp_Opcodes_cmd RestoreFFCUbufConfig; + DWORD FFCUbufConfigOffset_L; + DWORD FFCUbufConfigOffset_H; + + Csp_Opcodes_cmd RestoreCsp; + DWORD CSPOffset_L; + DWORD CSPOffset_H; + + Csp_Opcodes_cmd RestoreGpcpFe; + DWORD GpcpFeOffset_L; + DWORD GpcpFeOffset_H; + + Csp_Opcodes_cmd RestoreGpcpBe; + DWORD GpcpBeOffset_L; + DWORD GpcpBeOffset_H; + + struct + { + Csp_Opcodes_cmd RestoreGpcTopCmd; + DWORD GpcTopOffset_L; + DWORD GpcTopOffset_H; + }RestoreGpcTop[HW_MAX_GPC_NUM_E3K]; + + Csp_Opcodes_cmd EUFSL1Invalidate; + Csp_Opcodes_cmd EUPSL1Invalidate; + + //Add csp fence to make sure csp registers restore finish before csp pre-parser. + Csp_Opcodes_cmd CspFenceCmd; + DWORD CspFenceValue; + Csp_Opcodes_cmd CspWaitCmd; + Csp_Opcodes_cmd CspWaitMainCmd; +} CONTEXT_RESTORE_DMA_E3K; + +typedef struct _GPCPBE_SAVE{ + Csp_Opcodes_cmd SaveGpcpbe; + DWORD GpcpbeOffset_L; + DWORD GpcpbeOffset_H; +}GPCPBE_SAVE; + +typedef struct _CONTEXT_SAVE_DMA_E3K +{ + Cmd_Blk_Cmd_Csp_Save_Rsto SaveContext; + DWORD ContextBufferOffset_L; + DWORD ContextBufferOffset_H; + + Csp_Opcodes_cmd SaveCSPRegister; + DWORD CSPOffset_L; + DWORD CSPOffset_H; + + Csp_Opcodes_cmd SaveGpcpFeRegister; + DWORD GpcpFeOffset_L; + DWORD GpcpFeOffset_H; + + Csp_Opcodes_cmd SaveGpcpBeRegister; + DWORD GpcpBeOffset_L; + DWORD GpcpBeOffset_H; + + struct + { + Csp_Opcodes_cmd SaveGpcTopRegister; + DWORD GpcTopOffset_L; + DWORD GpcTopOffset_H; + }SaveGpcTop[HW_MAX_GPC_NUM_E3K]; + + Csp_Opcodes_cmd CspFenceCmd; + DWORD CspFenceValue; + Csp_Opcodes_cmd CspWaitCmd; + Csp_Opcodes_cmd CspWaitMainCmd; + + Csp_Opcodes_cmd GpcpBeFenceCmd; + DWORD GpcpBeFenceValue; + Csp_Opcodes_cmd GpcpBeWaitCmd; + Csp_Opcodes_cmd GpcpBeWaitMainCmd; +}CONTEXT_SAVE_DMA_E3K; + +typedef struct _CACHEFLUSH_DMA_E3K +{ + //Fence/Wait to make sure FFC finish; + Csp_Opcodes_cmd PreUAVFEFenceCmd; //CS only need this + DWORD PreUAVFEFenceValue; + Csp_Opcodes_cmd PreUAVFEWaitCmd; + Csp_Opcodes_cmd PreUAVFEWaitMainCmd; + + Csp_Opcodes_cmd PreUAVBEFenceCmd; + DWORD PreUAVBEFenceValue; + Csp_Opcodes_cmd PreUAVBEWaitCmd; + Csp_Opcodes_cmd PreUAVBEWaitMainCmd; + + Csp_Opcodes_cmd PreDFenceCmd; + DWORD PreDFenceValue; + Csp_Opcodes_cmd PreDWaitCmd; + Csp_Opcodes_cmd PreDWaitMainCmd; + + Csp_Opcodes_cmd PreZFenceCmd; + DWORD PreZFenceValue; + Csp_Opcodes_cmd PreZWaitCmd; + Csp_Opcodes_cmd PreZWaitMainCmd; + + Cmd_Block_Command_Flush DZS_Flush; + Cmd_Block_Command_Flush DZS_Invalidate; + Csp_Opcodes_cmd UAVFE_Flush; + Csp_Opcodes_cmd UAVFE_Invalidate; + Csp_Opcodes_cmd UAVBE_Flush; + Csp_Opcodes_cmd UAVBE_Invalidate; + + //used to make sure all FFC and BLC flush/inv and above have been all finished. + Csp_Opcodes_cmd PostUAVFEFenceCmd; //CS only need this + DWORD PostUAVFEFenceValue; + Csp_Opcodes_cmd PostUAVFEWaitCmd; + Csp_Opcodes_cmd PostUAVFEWaitMainCmd; + + Csp_Opcodes_cmd PostUAVBEFenceCmd; + DWORD PostUAVBEFenceValue; + Csp_Opcodes_cmd PostUAVBEWaitCmd; + Csp_Opcodes_cmd PostUAVBEWaitMainCmd; + + Csp_Opcodes_cmd PostDFenceCmd; + DWORD PostDFenceValue; + Csp_Opcodes_cmd PostDWaitCmd; + Csp_Opcodes_cmd PostDWaitMainCmd; + + Csp_Opcodes_cmd PostZFenceCmd; + DWORD PostZFenceValue; + Csp_Opcodes_cmd PostZWaitCmd; + Csp_Opcodes_cmd PostZWaitMainCmd; + + Csp_Opcodes_cmd StoFenceCmd; + DWORD StoFenceValue; + Csp_Opcodes_cmd StoWaitCmd; + Csp_Opcodes_cmd StoWaitMainCmd; + + //Fence/Wait to make sure L2 path finish. + + Cmd_Block_Command_L2 L2Flush; + Cmd_Block_Command_L2 L2Invalidate; + Csp_Opcodes_cmd L2FenceCmd; + DWORD L2FenceValue; + Csp_Opcodes_cmd L2WaitCmd; + Csp_Opcodes_cmd L2WaitMainCmd; + + //Invalidate TU,EU L1 cache + Csp_Opcodes_cmd TUFEL1Invalidate; //TUL1 doesn't need fence, hw will handle by itself. + Csp_Opcodes_cmd TUBEL1Invalidate; + Csp_Opcodes_cmd EUFSL1Invalidate; + Csp_Opcodes_cmd EUPSL1Invalidate; + + //Fence/Wait to make sure BLC path finish + Csp_Opcodes_cmd PreCspFenceCmd; + DWORD PreCspFenceValue; + Csp_Opcodes_cmd PreCspWaitCmd; + Csp_Opcodes_cmd PreCspWaitMainCmd; + Cmd_Block_Command_Mxu BLC_Flush; + DWORD FlushAddr_L; + DWORD FlushAddr_H; + DWORD FlushMask_L; + DWORD FlushMask_H; + Csp_Opcodes_cmd PostCspFenceCmd; + DWORD PostCspFenceValue; + Csp_Opcodes_cmd PostCspWaitCmd; + Csp_Opcodes_cmd PostCspWaitMainCmd; +}CACHEFLUSH_DMA_E3K; + +typedef struct _RB_PREDEFINE_DMA +{ + CONTEXT_RESTORE_DMA_E3K RestoreDMA; + CACHEFLUSH_DMA_E3K FlushDMA3DL; + CONTEXT_SAVE_DMA_E3K SaveDMA; + CONTEXT_RESTORE_DMA_E3K RestoreShadowDMA; +}RB_PREDEFINE_DMA; + +#endif // diff --git a/drivers/gpu/drm/arise/core/e3k/perfevent/perfevent_e3k.c b/drivers/gpu/drm/arise/core/e3k/perfevent/perfevent_e3k.c new file mode 100644 index 0000000000000..004598eb0018f --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/perfevent/perfevent_e3k.c @@ -0,0 +1,118 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "perfeventi.h" +#include "perfevent.h" +#include "../vidsch/vidsch_engine_e3k.h" + + +static int perf_direct_get_counter_e3k(adapter_t *adapter, gf_miu_list_item_t *miu_table, unsigned int miu_table_length,int force_read) +{ + gf_assert(0, NULL); + return 0; +} + +static int perf_calculate_engine_usage_e3k(adapter_t * adapter, gf_hwq_info * phwq_info) +{ + unsigned int engine = 0; + hwq_event_mgr_t *hwq_event_mgr = adapter->hwq_event_mgr; + hwq_event_info *p_hwq_event = NULL; + unsigned int usage = 0; + + for(engine = 0; engine < adapter->active_engine_count; engine++) + { + + p_hwq_event = (hwq_event_info*)(hwq_event_mgr->hwq_event)+engine; + usage=p_hwq_event->engine_usage; + //gf_info(" EngineNum=%d usage %d \n", engine, usage); + if(engine==RB_INDEX_GFXL || engine==RB_INDEX_GFXH) + { + if(usage > phwq_info->Usage_3D) + { + phwq_info->Usage_3D=usage; + } + } + + if(engine==RB_INDEX_VCP0 || engine==RB_INDEX_VCP1) + { + if(usage > phwq_info->Usage_VCP) + { + phwq_info->Usage_VCP=usage; + } + } + + if(engine==RB_INDEX_VPP) + { + if(usage > phwq_info->Usage_VPP) + { + phwq_info->Usage_VPP=usage; + } + } + } + return 0; +} + + +static int perf_calculate_engine_usage_ext_e3k(adapter_t * adapter, gfx_hwq_info_ext *phwq_info_ext) +{ + unsigned int usage = 0; + unsigned int engine = 0; + hwq_event_info *p_hwq_event; + hwq_event_mgr_t *hwq_event_mgr = adapter->hwq_event_mgr; + + if( !(adapter->ctl_flags.hwq_event_enable) || !(adapter->hwq_event_mgr) ) + { + return -1; + } + + gf_memset(phwq_info_ext,0,sizeof(gfx_hwq_info_ext)); + for(engine = 0; engine < adapter->active_engine_count; engine++) + { + + p_hwq_event = (hwq_event_info*)(hwq_event_mgr->hwq_event)+engine; + usage=p_hwq_event->engine_usage; + //gf_info(" EngineNum=%d usage %d \n", engine, usage); + switch(engine) + { + case RB_INDEX_GFXL: + phwq_info_ext->Usage_3D=usage; + break; + case RB_INDEX_GFXH: + phwq_info_ext->Usage_3D_High=usage; + break; + case RB_INDEX_VCP0: + phwq_info_ext->Usage_VCP0=usage; + break; + case RB_INDEX_VCP1: + phwq_info_ext->Usage_VCP1=usage; + break; + case RB_INDEX_VPP: + phwq_info_ext->Usage_VPP=usage; + break; + default: + break; + } + } + return 0; +} + + +perf_chip_func_t perf_chip_func = +{ + .direct_get_miu_counter = perf_direct_get_counter_e3k, + .calculate_engine_usage = perf_calculate_engine_usage_e3k, + .calculate_engine_usage_ext = perf_calculate_engine_usage_ext_e3k, +}; + diff --git a/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_allocate_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_allocate_e3k.c new file mode 100644 index 0000000000000..72b0327e90265 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_allocate_e3k.c @@ -0,0 +1,756 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "vidmm.h" +#include "vidmmi.h" +#include "mm_e3k.h" +#include "chip_include_e3k.h" +#include "vidmmi_e3k.h" + +unsigned int __BitCountTable_e3k[] = BIT_COUNT_TABLE; +const HWFORMAT_TABLE_ENTRY_E3K g_HwFormatTable_e3k[]= HWFORMAT_TABLE; +const HWFORMAT_TABLE_ENTRY_E3K *g_pHwFormatTable_e3k = g_HwFormatTable_e3k; +const KMDTILEINFO_E3K hwKMDTileInfo_e3k = HW_KMD_TILE_INFO_E3K; + +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) + +#define E3K_VRAM_LOCAL_USAGES (GF_USAGE_DISPLAY_SURFACE | \ + GF_USAGE_OVERLAY_SURFACE | \ + GF_USAGE_CURSOR_SURFACE | \ + GF_USAGE_SHADOW_SURFACE | \ + GF_USAGE_RENDER_TARGET | \ + GF_USAGE_TEXTURE_BUFFER | \ + GF_USAGE_SHADER_BUFFER) + +#define E3K_VRAM_NONLOCAL_USAGES (GF_USAGE_DATA_BUFFER | \ + GF_USAGE_TEMP_BUFFER) + +/* if such usage set, this allocation must use for display */ +#define E3K_DIU_DISPLAY_USAGES (GF_USAGE_DISPLAY_SURFACE | \ + GF_USAGE_OVERLAY_SURFACE | \ + GF_USAGE_CURSOR_SURFACE) + +static int vidmmi_update_segment_id_e3k(adapter_t *adapter, vidmm_allocation_t *allocation, int segment_id) +{ + int segment_id_new = segment_id; + + //valid secure range segment, now id 4~10 stand for secure range1~7 in rm. + //kmd only reserved 2 secure range mem. + if(segment_id >= 4 && segment_id <= 10 && allocation->flag.secured) + { + segment_id_new = adapter->hw_caps.secure_range_enable ? + ((segment_id == 4)?SEGMENT_ID_SECURE_RANGE_E3K: SEGMENT_ID_SECURE_RANGE_E3K_1): SEGMENT_ID_LOCAL_E3K; + } + +//validate here for both (escapse,ioctl) umd should not know the details of memory of different platform + switch(segment_id) + { + case 1: + //for local, if cpu visible + no-compress + linear, must be in local. but aarm64 has alignment + //requirement for local memory.(by aarch64, device memory). + if(allocation->flag.cpu_visible && allocation->compress_format == 0 && allocation->flag.swizzled == 0) + { + segment_id_new = SEGMENT_ID_LOCAL_E3K; + } + else + { + segment_id_new = SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K_1; + } + + break; + case 2: + segment_id_new = adapter->hw_caps.snoop_only ? 0 : SEGMENT_ID_GART_UNSNOOPABLE_E3K; + break; + case 3: + segment_id_new = adapter->hw_caps.support_snooping ? SEGMENT_ID_GART_SNOOPABLE_E3K: SEGMENT_ID_GART_UNSNOOPABLE_E3K; + break; + + default: + //escape mm alloc call does not set any prefer. + if(allocation->flag.cpu_visible && allocation->compress_format == 0 && allocation->flag.swizzled == 0) + { + segment_id_new = SEGMENT_ID_LOCAL_E3K; + } + else + { + segment_id_new = SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K_1; + } + + break; + } + + + if (segment_id_new == SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K_1) + { + vidmm_segment_t *segment = adapter->mm_mgr->segment + SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K_1; + if (segment->gpu_vm_size == 0) + { + segment_id_new = SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K; + } + } + + return segment_id_new; +} + + +#define vaildate_segment_id(id) do { \ + segment_id = allocation->preferred_segment_raw.segment_id_##id; \ + if(segment_id <= SEGMENT_ID_MAX_E3K) \ + { \ + segment_id = vidmmi_update_segment_id_e3k(adapter, allocation, segment_id); \ + if(segment_id > 0) \ + { \ + segment_bit = 1 << segment_id; \ + if(!(segment_mask & segment_bit)) \ + { \ + segments[num] = segment_id; \ + segment_mask |= segment_bit; \ + num++; \ + } \ + } \ + } \ + }while(0); + +#define preferred_segment_id(id) allocation->preferred_segment.segment_id_##id +#define preferred_segment_id_raw(id) allocation->preferred_segment_raw.segment_id_##id + + +static void vidmmi_validate_allocation_info_e3k(vidmm_mgr_t *mm_mgr, vidmm_allocation_t *allocation) +{ + adapter_t *adapter = mm_mgr->adapter; + + int segments[MAX_SEGMENT_ID] = {0}; + int segment_id = 0; + int segment_bit = 0; + int segment_mask= 0; + int num = 0; + + //only using prefer 0/1 from upper. update prefer sement id by prefer raw's pool type + vaildate_segment_id(0); + segments[0] = segment_id; + vaildate_segment_id(1); + segments[1] = segment_id; + + if (!allocation->flag.cpu_visible) + { + segments[2] = SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K; + } + else + { + segments[2] = SEGMENT_ID_LOCAL_E3K; + } + + //cannot be PCIE memory when allocation is compressed or allocation is used for display + if(allocation->compress_format != 0 || allocation->flag.primary == 1) + { + segments[3] = SEGMENT_ID_LOCAL_E3K; + } + else + { +#ifdef __mips64__ + segments[3] = SEGMENT_ID_GART_UNSNOOPABLE_E3K; +#else + segments[3] = SEGMENT_ID_GART_SNOOPABLE_E3K; +#endif + } + segments[4] = SEGMENT_ID_LOCAL_E3K; + + //following code is used as force segemnt id case: as hw limitation, debug and etc. + //local only must case + if(allocation->flag.primary || allocation->flag.bVideoInternal|| + adapter->hw_caps.local_only +#ifdef __aarch64__ + || allocation->flag.bHwctxBuffer +#endif + ) + { + if(allocation->flag.cpu_visible) + { + segments[0] = SEGMENT_ID_LOCAL_E3K; + segments[1] = 0; + } + else//cpu unvisible + { + if(allocation->flag.bVideoInternal)//video must <4G + { + segments[0] = SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K; + segments[1] = SEGMENT_ID_LOCAL_E3K; + } + else//3d prefer >4G first, than <4G + { + if (mm_mgr->segment[SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K_1].gpu_vm_size > 0) + { + segments[0] = SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K_1; + segments[1] = SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K; + segments[2] = SEGMENT_ID_LOCAL_E3K; + } + else + { + segments[0] = SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K; + segments[1] = SEGMENT_ID_LOCAL_E3K; + } + } + } + } + + preferred_segment_id(0) = segments[0]; + preferred_segment_id(1) = segments[1]; + preferred_segment_id(2) = segments[2]; + preferred_segment_id(3) = segments[3]; + preferred_segment_id(4) = segments[4]; + + if (allocation->flag.primary) + { + allocation->alignment = max(0x8000, allocation->alignment); + } +} + +static void vidmmi_check_allocation_flag_e3k(adapter_t *adapter, vidmm_allocation_t *allocation, gf_create_allocation_t *hint, unsigned char compress) +{ + unsigned int usage_mask = hint->usage_mask; + gf_access_hint access_hint = hint->access_hint; + + allocation->flag.swizzled = hint->tiled; + + if(usage_mask & (E3K_DIU_DISPLAY_USAGES)) + { + allocation->flag.primary = 1; + if(hint->tiled) + { + gf_warning("%s(): display surface must be linear. but setting as tiled.\n", util_remove_name_suffix(__func__)); + } + } + + allocation->flag.cpu_visible = (access_hint != GF_ACCESS_GPU_ONLY); + allocation->flag.unpagable = (hint->unpagable || !adapter->ctl_flags.paging_enable); + + if(allocation->flag.secured) + { + allocation->flag.unpagable = 1; + } + + if (hint->usage_mask & (GF_USAGE_DISPLAY_SURFACE | GF_USAGE_RENDER_TARGET)) + { + allocation->flag.force_clear = TRUE; + } +#ifdef __aarch64__ + if (hint->usage_mask & GF_USAGE_HWCTX_BUFFER) + { + allocation->flag.bHwctxBuffer = 1; + } +#endif +} + +static inline unsigned int vidmmi_get_allocation_hw_format_e3k(gf_format format) +{ + Hw_Surf_Format hw_format = 0; + + switch(format) + { + case GF_FORMAT_A8_UNORM: + hw_format = HSF_A8_UNORM; + break; + + case GF_FORMAT_B5G6R5_UNORM: + hw_format = HSF_B5G6R5_UNORM; + break; + + case GF_FORMAT_B8G8R8A8_UNORM: + hw_format = HSF_B8G8R8A8_UNORM; + break; + + case GF_FORMAT_B8G8R8X8_UNORM: + hw_format = HSF_B8G8R8X8_UNORM; + break; + + case GF_FORMAT_R8G8B8A8_UNORM: + hw_format = HSF_R8G8B8A8_UNORM; + break; + + case GF_FORMAT_A8R8G8B8_UNORM: + hw_format = HSF_A8R8G8B8_UNORM; + break; + + case GF_FORMAT_R8G8B8X8_UNORM: + hw_format = HSF_R8G8B8X8_UNORM; + break; + + case GF_FORMAT_YUY2: + hw_format = HSF_YUY2; + break; + + case GF_FORMAT_NV12_LINEAR: + hw_format = HSF_NV12; + break; + + case GF_FORMAT_NV12_TILED: + hw_format = HSF_NV12; + break; + + case GF_FORMAT_NV21_LINEAR: + hw_format = HSF_NV12; + break; + + case GF_FORMAT_YV12: + hw_format = HSF_YV12; + break; + + case GF_FORMAT_FLOAT32: + hw_format = HSF_D32_FLOAT; + break; + + case GF_FORMAT_UINT32: + hw_format = HSF_R32_UINT; + break; + + case GF_FORMAT_INT32: + hw_format = HSF_R32_SINT; + break; + case GF_FORMAT_R8G8_UNORM: + hw_format = HSF_R8G8_UNORM; + break; + case GF_FORMAT_R8_UNORM: + hw_format = HSF_R8_UNORM; + break; + + case GF_FORMAT_B10G10R10A2_UNORM: + hw_format = HSF_A2B10G10R10_UNORM; + break; + + case GF_FORMAT_P010: + hw_format = HSF_P010; + break; + + case GF_FORMAT_L8_UNORM: + hw_format = HSF_L8_UNORM; + break; + + case GF_FORMAT_L8A8_UNORM: + hw_format = HSF_L8A8_UNORM; + break; + + case GF_FORMAT_R8G8B8_UNORM: + hw_format = HSF_R8G8B8_UNORM; + break; + + case GF_FORMAT_R4G4B4A4_UNORM: + hw_format = HSF_A4B4G4R4_UNORM; + break; + + case GF_FORMAT_R5G5B5A1_UNORM: + hw_format = HSF_A1B5G5R5_UNORM; + break; + + case GF_FORMAT_D16_UNORM: + hw_format = HSF_D16_UNORM; + break; + + case GF_FORMAT_S8_UINT: + hw_format = HSF_R8_UINT; + break; + + default: + gf_warning("unknow gfx format :%d.\n", format); + //gf_assert(0, "vidmmi_get_allocation_hw_format unknown gfx format "); + break; + } + + return hw_format; +} + +static void vidmmi_set_allocation_compress_format_e3k(adapter_t *adapter, vidmm_allocation_t *allocation, gf_create_allocation_t *create_hint) +{ + COMPRESS_MXUFORMAT compress_format = CP_OFF; + int can_compress = FALSE; + + if(create_hint->compressed) + { + switch (allocation->at_type) + { + case MM_AT_TEXTURE_E3K: + case MM_AT_RENDERTARGET_E3K: + can_compress = TRUE; + break; + + default: + break; + } + } + + if(can_compress) + { + compress_format = g_pHwFormatTable_e3k[allocation->hw_format].CompressFmt; + } + + switch(compress_format) + { + case CP_R8G8B8A8_L: + if(allocation->flag.swizzled) + { + compress_format = CP_R8G8B8A8_T; + } + break; + + case CP_A8R8G8B8_L: + if(allocation->flag.swizzled) + { + compress_format = CP_A8R8G8B8_T; + if (allocation->hw_format == HSF_B8G8R8A8_UNORM) + { + compress_format = CP_R8G8B8A8_T; + } + } + break; + + case CP_TOTAL_RANGE: + compress_format = CP_OFF; + break; + + default: + break; + } + + allocation->compress_format = compress_format; +} + + +#define E3K_32K_ALIGNMENT_USAGES (GF_USAGE_DISPLAY_SURFACE | \ + GF_USAGE_SHADOW_SURFACE | \ + GF_USAGE_OVERLAY_SURFACE | \ + GF_USAGE_CURSOR_SURFACE | \ + GF_USAGE_RENDER_TARGET) + +#define E3K_4K_ALIGNMENT_USAGES (GF_USAGE_DATA_BUFFER | \ + GF_USAGE_SHADER_BUFFER) + +//port from mmGetAllocationAlingment_e3k +static unsigned int vidmmi_get_allocation_alignment_e3k(adapter_t *adapter, vidmm_allocation_t *allocation, unsigned int at_type) +{ + unsigned int alignment = 0; + + switch (at_type) + { + case MM_AT_TEXTURE_E3K: + case MM_AT_RENDERTARGET_E3K: + if(allocation->compress_format) + { + alignment = 0x8000; + } + else if(allocation->flag.swizzled) + { + alignment= 0x10000; + } + else + { + alignment = 0x100; + } + break; + case MM_AT_VERTEXBUFFER_E3K: + case MM_AT_EUPFSHADER_E3K: + alignment = 0x0100; + break; + case MM_AT_GENERIC_E3K: + alignment = 0x8000; + break; + case MM_AT_MIUCOUNTER_E3K: + alignment = 0x10000; + break; + default: + alignment = 0x8000; + gf_info("unknown at_type. set default aligned to 32K.\n"); + break; + } + + return alignment; +} + + +static inline unsigned int vidmmi_get_allocation_pool_type_e3k(adapter_t *adapter, unsigned int usage_mask, gf_access_hint access_hint, int try_secure) +{ + vidmm_segment_preference_t segment = {0}; + + //to same as cil2 mm logic + //1 means to allocate in local video memory + //2 means to allocate in non-local non-snoop video memory + //3 means to allocate in non-local snoop video memory. + + if(try_secure && adapter->hw_caps.secure_range_enable) + { + segment.segment_id_0 = SEGMENT_ID_SECURE_RANGE_E3K; + } + else if(usage_mask & GF_USAGE_FORCE_PCIE) + { + segment.segment_id_0 = SEGMENT_ID_GART_SNOOPABLE_E3K; // snoop for cpu fast access + } + //local video memory case + else if(usage_mask & E3K_VRAM_LOCAL_USAGES) + { + segment.segment_id_0 = SEGMENT_ID_LOCAL_E3K; + } + //non local video memory case + else if(usage_mask & E3K_VRAM_NONLOCAL_USAGES) + { + if(access_hint == GF_ACCESS_CPU_ALMOST) + { + segment.segment_id_0 = SEGMENT_ID_GART_SNOOPABLE_E3K; + } + else + { + segment.segment_id_0 = adapter->hw_caps.snoop_only ? SEGMENT_ID_GART_SNOOPABLE_E3K : SEGMENT_ID_GART_UNSNOOPABLE_E3K; + } + } + //default: not care memory location case + else + { + //2d not considering cacheable case, only set to non local. + segment.segment_id_0 = SEGMENT_ID_GART_SNOOPABLE_E3K; + if (!adapter->hw_caps.snoop_only) + { + segment.segment_id_1 = SEGMENT_ID_GART_UNSNOOPABLE_E3K; + } + } + + return segment.value; +} + +//port from rmiCalcResourcePitch_e3k() and rmiCalcHwLinearPittch_e3k() +static void vidmmi_calc_allocation_pitch_e3k(vidmm_allocation_t *allocation) +{ + unsigned int BitCount; + unsigned int Width0, Height0; + unsigned int TileWidth, TileHeight; + unsigned int UnitWidth, UnitHeight; + unsigned int P2Width0, P2Height0; + unsigned int UnitSize; + unsigned int Pitch; + unsigned int WidthAligned; + unsigned int HeightAligned; + + BitCount = allocation->bit_count; + TileWidth = calcTileWidth_e3k(BitCount); + TileHeight = calcTileHeight_e3k(BitCount); + UnitSize = UNIT_SIZE_E3K; + UnitWidth = calcUnitWidth_e3k(BitCount); + UnitHeight = calcUnitHeight_e3k(BitCount); + + Width0 = allocation->width; + Height0 = allocation->height; + + // overflow check + if ( Width0 >= (0xFFFFFFFF / Height0) || + (Width0 * Height0) >= (0xFFFFFFFF / BitCount)) + { + gf_error("invlad argument, width or height too big. width:%d, height:%d.\n", Width0, Height0); + return; + } + + if (allocation->flag.swizzled) + { + P2Width0 = (Width0 & (Width0 - 1)) ? + util_get_msb_position(Width0) + 1: + util_get_msb_position(Width0); + P2Width0 = 1 << P2Width0; + + P2Height0 = (Height0&(Height0-1))? + util_get_msb_position(Height0) + 1: + util_get_msb_position(Height0); + P2Height0 = 1 << P2Height0; + + P2Width0 = max(P2Width0, UnitWidth); + P2Height0 = max(P2Height0, UnitHeight); + + //Folding is disabled for NV12 tiled surface, we need make NV12 surface tiled aligned. + if (allocation->hw_format == HSF_NV12 || allocation->hw_format == HSF_P010) + { + P2Width0 = P2Width0 >= TileWidth ? P2Width0 : TileWidth; + P2Height0 = P2Height0 >= TileHeight ? P2Height0 : TileHeight; + } + + if ((P2Width0 >= TileWidth) && (P2Height0 >= TileHeight)) + { + //pResource->Flags.TileAligned = 1; + + WidthAligned = calcWidthInTiles_e3k(Width0, BitCount) * TileWidth; + HeightAligned = calcHeightInTiles_e3k(Height0, BitCount) * TileHeight; + } + // P2 Aligned + else + { + //pResource->Flags.TileAligned = 0; + WidthAligned = P2Width0; + HeightAligned = P2Height0; + } + Pitch =((WidthAligned * BitCount +7)/8); + } + else + { + //port rmiCalcHwLinearPitch_e3k() + // TODO: how to calc the pitch for linear source + WidthAligned = (Width0) ? Width0 : 1; + Pitch = ALIGNED_2KBits((WidthAligned * BitCount + 7)/8); + + WidthAligned = Pitch * 8 / BitCount; + HeightAligned = allocation->height; + } + + //Get Pitch Size + allocation->tiled_width = TileWidth; + allocation->tiled_height = TileHeight; + allocation->aligned_width = WidthAligned; + allocation->aligned_height = HeightAligned; + + allocation->orig_size = Pitch * HeightAligned; + + //allocation->orig_size = ALIGNED_2KBits( allocation->orig_size); + allocation->pitch = Pitch; +} + +static unsigned int vidmmi_get_allocation_type_e3k(unsigned int usage_mask) +{ + unsigned int at_type = MM_AT_GENERIC_E3K; + + if(usage_mask & GF_USAGE_MIU_COUNTER) + { + at_type = MM_AT_MIUCOUNTER_E3K; + } + else if(usage_mask & (GF_USAGE_DISPLAY_SURFACE | + GF_USAGE_OVERLAY_SURFACE | + GF_USAGE_SHADOW_SURFACE | + GF_USAGE_CURSOR_SURFACE | + GF_USAGE_RENDER_TARGET)) + { + at_type = MM_AT_RENDERTARGET_E3K; + } + else if(usage_mask & GF_USAGE_TEXTURE_BUFFER) + { + at_type = MM_AT_TEXTURE_E3K; + } + else if(usage_mask & GF_USAGE_SHADER_BUFFER) + { + at_type = MM_AT_EUPFSHADER_E3K; + } + else if(usage_mask & GF_USAGE_DATA_BUFFER) + { + at_type = MM_AT_VERTEXBUFFER_E3K; + } + else if(usage_mask & GF_USAGE_TEMP_BUFFER) + { + at_type = MM_AT_GENERIC_E3K; + } + + return at_type; +} + +int vidmm_describe_allocation_e3k(adapter_t *adapter, vidmm_describe_allocation_t *desc_info) +{ + vidmm_allocation_t *allocation = desc_info->allocation; + + int y_tile = 0; + int status = S_OK; + + if(desc_info->create_info != NULL) + { + gf_create_alloc_info_t *desc = desc_info->create_info; + + y_tile = TILE_SIZE_Y(allocation->bit_count); + allocation->aligned_width = (allocation->pitch * 8)/allocation->bit_count; + allocation->tiled_width = NUM_OF_X_TILES(allocation->aligned_width, allocation->bit_count);//tile num of x + allocation->aligned_height = (allocation->height + y_tile -1) & ~(y_tile - 1); + allocation->tiled_height = NUM_OF_Y_TILES(allocation->height, allocation->bit_count); + allocation->compress_format= desc->HWCompressFormat; + allocation->flag.secured = desc->bSecurity; + allocation->flag.bVideoInternal = desc->bVideoInternal; + + vidmmi_validate_allocation_info_e3k(adapter->mm_mgr, allocation); + + if(allocation->at_type == MM_AT_RT_TEXTURE_E3K || + allocation->at_type == MM_AT_RENDERTARGET_E3K || + allocation->at_type == MM_AT_STENCILBUFFER_E3K || + allocation->at_type == MM_AT_DEPTHBUFFER_E3K || + allocation->at_type == MM_AT_OCL_SPECIAL_BUFFER_E3K) + { + allocation->flag.force_clear = 1; + } + + vidmm_trace("create_allocation: allocation:%p, handle: %x, width:%x, height:%x,pitch: %x. y_tile:%x, size:%x\n", + allocation, allocation->handle, allocation->width, allocation->height, allocation->pitch, y_tile, allocation->orig_size); + } + else if(desc_info->create_gf != NULL) + { + gf_create_allocation_t *create_hint = desc_info->create_gf->create_data; + + allocation->width = create_hint->width; + allocation->height = create_hint->height; + allocation->priority = PMAX; + allocation->at_type = vidmmi_get_allocation_type_e3k(create_hint->usage_mask); + allocation->hw_format = vidmmi_get_allocation_hw_format_e3k(create_hint->format); + allocation->alignment = vidmmi_get_allocation_alignment_e3k(adapter, allocation, allocation->at_type); + allocation->bit_count = __BitCountTable_e3k[allocation->hw_format]; + + /****************************************************************** + * 1. modify allocation flags according usage, such as cpu visible * + * 2. check confict about usage and create flags. * + ******************************************************************/ + vidmmi_check_allocation_flag_e3k(adapter, allocation, create_hint, allocation->compress_format); + + //calc pitch according to tile or linear. + vidmmi_calc_allocation_pitch_e3k(allocation); + + //if compress, set compress format, e3k only setting rgba_compress now + vidmmi_set_allocation_compress_format_e3k(adapter, allocation, create_hint);//set compress format + + /*********************************************************************** + * get allocation's pool type according to usage,access hint and hw caps* + * pool type 1 means local video memory * + * pool type 2 means non-local non-snoop video memory * + * pool type 3 means non-local snoop video memory. * + ***********************************************************************/ + allocation->preferred_segment_raw.value = + vidmmi_get_allocation_pool_type_e3k(adapter, create_hint->usage_mask, create_hint->access_hint, create_hint->secured); + + + /********************************************************************* + * 1. update segment id accoding to pool type, no usage/hint will * + be used, only considering allocation flags and hw caps to update* + * 2. validate segment id according by hw limitation and etc * + *********************************************************************/ + vidmmi_validate_allocation_info_e3k(adapter->mm_mgr, allocation); + + vidmm_trace("gf_create_allocation: allocation:%p, handle: %x, width:%x, height:%x,pitch: %x. y_tile:%x, ori size:%x\n", + allocation, allocation->handle, allocation->width, allocation->height, allocation->pitch, y_tile, allocation->orig_size); + } + else + { + status = E_INVALIDARG; + } + + return status; +} + +int vidmm_get_allocation_info_e3k(adapter_t *adapter, vidmm_get_allocation_info_t *info) +{ + vidmm_allocation_t *allocation = info->allocation; + + info->ForceLocal = (allocation->preferred_segment.segment_id_0 == SEGMENT_ID_LOCAL_E3K) && + (allocation->preferred_segment.segment_id_1 == 0 || allocation->preferred_segment.segment_id_1 == SEGMENT_ID_LOCAL_E3K) && + (allocation->preferred_segment.segment_id_2 == 0 || allocation->preferred_segment.segment_id_2 == SEGMENT_ID_LOCAL_E3K) && + (allocation->preferred_segment.segment_id_3 == 0 || allocation->preferred_segment.segment_id_3 == SEGMENT_ID_LOCAL_E3K) && + (allocation->preferred_segment.segment_id_4 == 0 || allocation->preferred_segment.segment_id_4 == SEGMENT_ID_LOCAL_E3K); + info->snoop = (allocation->segment_id == SEGMENT_ID_GART_SNOOPABLE_E3K) ? 1 : 0; + return S_OK; +} + diff --git a/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_build_page_buffer_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_build_page_buffer_e3k.c new file mode 100644 index 0000000000000..5cf53e28680f6 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_build_page_buffer_e3k.c @@ -0,0 +1,453 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "vidmm.h" +#include "vidmmi.h" +#include "mm_e3k.h" +#include "vidmmi_e3k.h" +#include "bit_op.h" +#include "chip_include_e3k.h" +#include "../vidsch/vidsch_blt_e3k.h" +#include "../vidsch/vidsch_engine_e3k.h" +#include "../vidsch/vidsch_debug_hang_e3k.h" + +extern void vidsch_duplicate_hang_e3k(adapter_t * adapter); +extern reg_debug_mode_e3k debug_mode_e3k; + +static unsigned int vidmmi_invalidate_bl_slot_e3k(vidmm_mgr_t *mm_mgr, vidmm_allocation_t *allocation, unsigned int **ppDma) +{ + adapter_t *adapter = mm_mgr->adapter; + heap_t *slot_buffer = &mm_mgr->blheap; + unsigned long long start_addr = 0llu; + unsigned long long end_addr = 0llu; + unsigned long long mid_addr = 0llu; + unsigned long long inv_addr = 0llu; + unsigned int bl_range = util_align((allocation->size / BL_MAPPING_RATIO), slot_buffer->alignment); + unsigned int slot_mask_idx = 0; + unsigned int *pDma = *ppDma; + + + start_addr = (allocation->slot_index * BL_SLOT_SIZE) + slot_buffer->start; + end_addr = start_addr + bl_range; + mid_addr = start_addr ^ end_addr; + _BitScanReverse_64(&slot_mask_idx, mid_addr); + mid_addr = end_addr & (~((1<< slot_mask_idx)-1)); + + //gf_info("allocatoin: %x, start=%x,end=%x,mid=%x.\n", allocation->handle, start_addr, end_addr, mid_addr); + + bl_range = end_addr - mid_addr; + inv_addr = mid_addr; + while(bl_range) + { + _BitScanReverse(&slot_mask_idx, bl_range); + _bittestandreset(&bl_range, slot_mask_idx); + + //gf_info("allocatoin: %x, addr=%x,mask=%x.\n", allocation->handle, inv_addr, ~((1<> 32; + *pDma++ = ~((1<handle, inv_addr, ~((1<> 32; + *pDma++ = ~((1<hw_caps.video_only)//video only hasn't 3d module. + { + *pDma++ = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_CSP_FENCE,_RBT_3DFE, HWM_SYNC_KMD_SLOT); + *pDma++ = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_PRECSPFENCE); + *pDma++ = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_PRECSPFENCE); + *pDma++ = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_PRECSPFENCE); + } + + *ppDma = pDma; + + return S_OK; +} + +static unsigned int vidmmi_clear_bl_slot_e3k(adapter_t *adapter, vidmm_private_build_paging_buffer_arg_t *data) +{ + vidmm_allocation_t *allocation = data->allocation; + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + unsigned int *pDma = data->dma_buffer; + unsigned int bl_byte = allocation->size >> 9; + int cmd_loop = bl_byte/0x1FFFF + ((bl_byte % 0x1FFFF)?1:0);//max size of once clear should be 0x1FFFF + large_inter start_addr; + unsigned int clear_value = 0xFFFFFFFF; + unsigned int clear_size = 0; + int i=0; + + Cmd_Blk_Cmd_Csp_Blc_Dword1 clearAddrL = {0}; + Cmd_Blk_Cmd_Csp_Blc_Dword2 clearAddrHAndValue = {0}; + Cmd_Blk_Cmd_Csp_Blc_Dword3 clearMask = {0}; + + + start_addr.quad64 = allocation->slot_index << 7; + + vidmmi_invalidate_bl_slot_e3k(mm_mgr, allocation, &pDma); + + clearAddrHAndValue.Clear_Value0 = clear_value & 0xD; + clearMask.Blc_Mask = 0; + + for (i = 0; i < cmd_loop; ++i) + { + start_addr.quad64 += i*0x1FFFF; + clear_size = ((cmd_loop == (i + 1)) && (bl_byte%0x1FFFF) )?(bl_byte%0x1FFFF):0x1FFFF; + clearAddrL.Start_Address_Low32 = start_addr.low32; + clearAddrHAndValue.Start_Address_High8 =( start_addr.high32) & 0xFF ;//actual PA is 36bits, maybe 0xF + + *pDma++ = SEND_BL_CLEAR_COMMAND_E3K(clear_size);//clear max byte: 2^17 + *pDma++ = *(DWORD*)&clearAddrL; + *pDma++ = *(DWORD*)&clearAddrHAndValue; + *pDma++ = *(DWORD*)&clearMask; + } + + if (data->dma_size < ( (unsigned char *)data->dma_buffer - (unsigned char *)pDma)) + { + gf_info("%s:%d,dma buffer not enough,request:%d, actual:%d\n", util_remove_name_suffix(__func__), __LINE__, ((unsigned char *)data->dma_buffer - (unsigned char *)pDma), data->dma_size); + return E_INSUFFICIENT_DMA_BUFFER; + } + + data->dma_buffer = (void *)pDma; + + return S_OK; +} + +static int vidmmi_fast_clear_e3k(adapter_t *adapter, vidmm_private_build_paging_buffer_arg_t *data) +{ + engine_share_e3k_t *share = adapter->private_data; + RB_PREDEFINE_DMA* pTemplate = (RB_PREDEFINE_DMA*) share->begin_end_vma->virt_addr; + CACHEFLUSH_DMA_E3K *pCacheFlushDMA3DL = &(pTemplate->FlushDMA3DL); + FASTCLEAR_REGSETTING_E3K* pClearCmd0 = NULL; + FASTCLEAR_REGSETTING_E3K ClearCmd1 = {0}; + FASTCLEAR_REGSETTING_E3K* pClearCmd = &ClearCmd1; + vidmm_allocation_t *allocation = data->allocation; + unsigned int fill_size = data->fill.fill_size; + unsigned int fill_pattern = data->fill.fill_pattern; + large_inter fill_addr; + unsigned int *pDma = data->dma_buffer; + DWORD max_fill_cmd_count = 0; + DWORD Format = HSF_B8G8R8A8_UNORM; + DWORD dma_space_left = (DWORD)data->dma_size; + large_inter dstAddress,dstAddrAligned; + unsigned int NumBytes,dstStartX; + unsigned int stride = MAX_WIDTH_2DBLT; //in pixel,32bpp + unsigned int Height = 0; + unsigned int fill_count = 0; + int result = S_OK; + int multi_pass = FALSE; + + Reg_Proc_Sec reg_Proc_Sec = {0}; + reg_Proc_Sec.reg.Sec_Status = 1; + + fill_addr.quad64 = data->fill.phy_addr; + + gf_assert((fill_addr.quad64 & 0xFF) == 0, NULL);//actual all allocation PA will be ensured at least 4k aligned in kmd + + dma_space_left = data->dma_size - util_get_ptr_span(pDma, data->dma_buffer) ; + + if(allocation->flag.secured) + { + gf_memcpy(pDma, pCacheFlushDMA3DL, sizeof(CACHEFLUSH_DMA_E3K)); + pDma += sizeof(CACHEFLUSH_DMA_E3K)/sizeof(DWORD); + *pDma ++ = SET_REGISTER_FD_E3K(MXU_BLOCK, Reg_Proc_Sec_Offset, 1); + *pDma++ = reg_Proc_Sec.uint; + + //reserve more for reset 3d engine to non-secure status. + dma_space_left = data->dma_size - util_get_ptr_span(pDma, data->dma_buffer) -sizeof(CACHEFLUSH_DMA_E3K) - sizeof(DWORD); + } + + max_fill_cmd_count = dma_space_left / sizeof(FASTCLEAR_REGSETTING_E3K); + + if(0 == max_fill_cmd_count) + { + result = E_INSUFFICIENT_DMA_BUFFER; + goto exit; + } + + dstAddress.quad64 = fill_addr.quad64 + data->multi_pass_offset; + dstAddrAligned.quad64 = dstAddress.quad64 & ~0xFFll;//2kbits align + dstStartX = (dstAddress.quad64 - dstAddrAligned.quad64) >> 2;//shift to 32bpp pixel + + pClearCmd0 = (FASTCLEAR_REGSETTING_E3K*)pDma; + do + { + gf_memcpy(pClearCmd, &share->fast_clear_cmd_e3k, sizeof(FASTCLEAR_REGSETTING_E3K)); + + pClearCmd->DstFormat.reg.Format = Format; + pClearCmd->DstFormat.reg.Bl_Slot_Idx = 0; + pClearCmd->DstDepth.reg.Depth_Or_Arraysize= 1; + pClearCmd->DstDepth.reg.Range_Type = 0; + pClearCmd->DstViewCtrl.reg.Arraysize = 1; + pClearCmd->DstViewCtrl.reg.First_Array_Idx = 0; + + pClearCmd->DstMisc.reg.Is_Tiling = 0; //Always treate it as linear. + pClearCmd->DstMisc.reg.Rt_Enable = 1; + pClearCmd->DstMisc.reg.Rt_Write_Mask = 0xF; + pClearCmd->DstMisc.reg.Resource_Type = RT_MISC_RESOURCE_TYPE_2D_TEXTURE; + pClearCmd->DstMisc.reg.Eu_Blend_Enable = 0; //Always treate it as linear. + + pClearCmd->Dzs_Ctrl.reg.Src_Read_Alloc_En = 0; + + pClearCmd->Rast_Ctrl.reg.Check_Board = RAST_CTRL_CHECK_BOARD_64X16; + pClearCmd->Rast_Ctrl.reg.Eub_En = 0; + + pClearCmd->reg_Iu_Ctrl_Ex.reg.Eu_Blending_En = 0; + + pClearCmd->Zs_Req_Ctrl.reg.D_Alloc_En = 1; + + pClearCmd->Fast_Clear_Color0.reg.Color = fill_pattern; + pClearCmd->Fast_Clear_Color1.reg.Color = fill_pattern; + pClearCmd->Fast_Clear_Color2.reg.Color = fill_pattern; + pClearCmd->Fast_Clear_Color3.reg.Color = fill_pattern; + + pClearCmd->DstAddr.reg.Base_Addr = (fill_addr.quad64 + data->multi_pass_offset) >> 8; + + // the first partial line + if(0 != dstStartX) + { + //consider total size is small than MAX_WIDTH_2DBLT + unsigned int width = ((fill_size - data->multi_pass_offset) < ((stride - dstStartX) << 2)) ? ((fill_size - data->multi_pass_offset) >> 2): (stride - dstStartX); + + pClearCmd->DstSize.reg.Width = width; + pClearCmd->DstSize.reg.Height = 1; + pClearCmd->RectX.Xmin = dstStartX -1; + pClearCmd->RectX.Xmax =stride - dstStartX -1; + pClearCmd->RectY.Ymin = 0; + pClearCmd->RectY.Ymax = 1-1; + + NumBytes = width << 2; + dstStartX = 0; + } + // The last partial line + else if((fill_size - data->multi_pass_offset) < (stride << 2)) + { + pClearCmd->DstSize.reg.Width = (fill_size - data->multi_pass_offset) >> 2; + pClearCmd->DstSize.reg.Height = 1; + pClearCmd->RectX.Xmin = 0; + pClearCmd->RectX.Xmax = ((fill_size - data->multi_pass_offset) >> 2) -1; + pClearCmd->RectY.Ymin = 0; + pClearCmd->RectY.Ymax = 1 -1; + + NumBytes = (fill_size - data->multi_pass_offset); + } + // block fill + else + { + Height = (fill_size - data->multi_pass_offset) / (stride << 2); + + if ( Height > MAX_HEIGHT_2DBLT ) + { + Height = MAX_HEIGHT_2DBLT; + } + + pClearCmd->DstSize.reg.Width = stride; + pClearCmd->DstSize.reg.Height = Height; + pClearCmd->RectX.Xmin = 0; + pClearCmd->RectX.Xmax = stride -1; + pClearCmd->RectY.Ymin = 0; + pClearCmd->RectY.Ymax = Height -1; + + NumBytes = Height * (stride << 2); + } + gf_memcpy(pClearCmd0, pClearCmd, sizeof(FASTCLEAR_REGSETTING_E3K)); + pClearCmd0++; + fill_count++; + data->multi_pass_offset += NumBytes; + + if(fill_count >= max_fill_cmd_count) + { + if(data->multi_pass_offset < data->fill.fill_size) + { + multi_pass = TRUE; + } + break; + } + + }while(data->multi_pass_offset < data->fill.fill_size); + + + if(multi_pass) + { + result = E_INSUFFICIENT_DMA_BUFFER; + } + else + { + data->multi_pass_offset = 0; + } + +exit: + + pDma = (unsigned int*)pClearCmd0; + + if(allocation->flag.secured) + { + reg_Proc_Sec.reg.Sec_Status = 0; + gf_assert((data->dma_size - util_get_ptr_span(pDma, data->dma_buffer)) >= (sizeof(CACHEFLUSH_DMA_E3K)/sizeof(DWORD) + sizeof(DWORD)), "buf not enough for fast clear cmd"); + gf_memcpy(pDma, pCacheFlushDMA3DL, sizeof(CACHEFLUSH_DMA_E3K)); + pDma += sizeof(CACHEFLUSH_DMA_E3K)/sizeof(DWORD); + *pDma ++ = SET_REGISTER_FD_E3K(MXU_BLOCK, Reg_Proc_Sec_Offset, 1); + *pDma++ = reg_Proc_Sec.uint; + } + data->dma_buffer = (void *)pDma; + return result; +} + +//video only is for fpga validation, will not enable gfx engine, just skip it. +int vidmm_build_page_buffer_e3k(adapter_t *adapter, vidmm_private_build_paging_buffer_arg_t *data) +{ + vidmm_allocation_t *allocation = data->allocation; + int result = S_OK; + + if(debug_mode_e3k.internal_dump_hw) + { + gf_info("vidmm_build_page_buffer_e3k start dump image, need skip this function...\n"); + return 0; + } + + //secure mem should not page out, since content in range not allowed write to non-sec mem. + if(!adapter->hw_caps.video_only && (BUILDING_PAGING_OPERATION_TRANSFER == data->operation)) + { + engine_share_e3k_t *share = adapter->private_data; + BITBLT_REGSETTING_E3K* p2DBltCmd = NULL; + unsigned int *pDma = data->dma_buffer; + DWORD max_transfer_cmd_count = 0; + DWORD start_offset = data->multi_pass_offset; + DWORD StartX = 0; + DWORD Format = HSF_B8G8R8A8_UNORM; + DWORD dma_space_left = data->dma_size; + unsigned int Height = 0; + unsigned int Width = 0; + unsigned int transfer_size = data->transfer.transfer_size; + + gf_assert(((data->transfer.transfer_size&0x3) == 0) && //align to 4. driver will ensure it when buffer allocate. + ((data->transfer.dst.phy_addr & 0xFF) ==0) &&//hw need addr 2kb aligned + ((data->transfer.src.phy_addr & 0xFF) ==0), NULL); + + dma_space_left = data->dma_size - util_get_ptr_span(pDma, data->dma_buffer); + max_transfer_cmd_count = dma_space_left / sizeof(BITBLT_REGSETTING_E3K); + + if(0 == max_transfer_cmd_count) + { + return E_INSUFFICIENT_DMA_BUFFER; + } + + p2DBltCmd =(BITBLT_REGSETTING_E3K*)pDma; + + while(transfer_size > 0 && max_transfer_cmd_count > 0) + { + Width = MAX_WIDTH_2DBLT;//in pixel + Height = transfer_size/(Width << 2); + Height = Height > MAX_HEIGHT_2DBLT ? MAX_HEIGHT_2DBLT : Height; + + if(transfer_size < (MAX_WIDTH_2DBLT << 2)) + { + Width = transfer_size >> 2; + Height = 1; + } + + StartX = (start_offset -(start_offset&~0xFF)) >>2; + start_offset = start_offset&~0xFF; + + gf_memcpy(p2DBltCmd, &share->_2dblt_cmd_e3k, sizeof(BITBLT_REGSETTING_E3K)); + + p2DBltCmd->SrcAddr.reg.Base_Addr = (data->transfer.src.phy_addr + start_offset) >> 8; + p2DBltCmd->DstAddr.reg.Base_Addr = (data->transfer.dst.phy_addr + start_offset) >> 8; + + p2DBltCmd->SrcFormat.reg.Format = Format; + p2DBltCmd->SrcFormat.reg.Bl_Slot_Idx = 0; + p2DBltCmd->SrcSize.reg.Width = Width; + p2DBltCmd->SrcSize.reg.Height = Height; + p2DBltCmd->SrcDepth.reg.Depth_Or_Arraysize= 1; + p2DBltCmd->SrcDepth.reg.Range_Type = 0; + p2DBltCmd->SrcViewCtrl.reg.Arraysize = 1; + p2DBltCmd->SrcViewCtrl.reg.First_Array_Idx = 0; + + p2DBltCmd->DstFormat = p2DBltCmd->SrcFormat; + p2DBltCmd->DstSize = p2DBltCmd->SrcSize; + p2DBltCmd->DstDepth = p2DBltCmd->SrcDepth; + p2DBltCmd->DstViewCtrl = p2DBltCmd->SrcViewCtrl; + + p2DBltCmd->SrcMisc.reg.Is_Tiling = 0; + p2DBltCmd->SrcMisc.reg.Rt_Enable = 1; + p2DBltCmd->SrcMisc.reg.Resource_Type = RT_MISC_RESOURCE_TYPE_2D_TEXTURE; + p2DBltCmd->SrcMisc.reg.Eu_Blend_Enable = 0; + + p2DBltCmd->DstMisc.reg.Is_Tiling = 0; + p2DBltCmd->DstMisc.reg.Rt_Enable = 1; + p2DBltCmd->DstMisc.reg.Rt_Write_Mask = 0xF; + p2DBltCmd->DstMisc.reg.Resource_Type = RT_MISC_RESOURCE_TYPE_2D_TEXTURE; + p2DBltCmd->DstMisc.reg.Eu_Blend_Enable = 0; + + p2DBltCmd->Rast_Ctrl.reg.Eub_En = 0; + p2DBltCmd->reg_Iu_Ctrl_Ex.reg.Eu_Blending_En = 0; + + p2DBltCmd->Dzs_Ctrl.reg.Src_Read_Alloc_En = 0; + + p2DBltCmd->RectX.Xmin = StartX; + p2DBltCmd->RectX.Xmax = Width - 1; + p2DBltCmd->RectY.Ymin = 0; + p2DBltCmd->RectY.Ymax = Height - 1; + p2DBltCmd->SrcDxDy.Dx = 0; + p2DBltCmd->SrcDxDy.Dy = 0; + + start_offset += (Width * Height) << 2; + transfer_size -=((Width * Height) << 2) + (StartX << 2); + + max_transfer_cmd_count--; + p2DBltCmd++; + } + + if(transfer_size > 0) + { + data->multi_pass_offset = start_offset; + result = E_INSUFFICIENT_DMA_BUFFER; + } + + data->dma_buffer = (VOID*)p2DBltCmd; + } + else if(BUILDING_PAGING_OPERATION_FILL == data->operation) + { + if(allocation->compress_format != CP_OFF)//video only still need invalidate bl, BL is managed by MXU. + { + return vidmmi_clear_bl_slot_e3k(adapter, data); + } + else if(!adapter->hw_caps.video_only)//video only hasn't 3d module. + { + return vidmmi_fast_clear_e3k(adapter, data); + } + } + return result; +} diff --git a/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_e3k.c new file mode 100644 index 0000000000000..598b5fa44f9d3 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_e3k.c @@ -0,0 +1,459 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "gf_def.h" +#include "vidmm.h" +#include "vidsch.h" +#include "vidmmi.h" +#include "mm_e3k.h" +#include "vidmmi_e3k.h" +#include "register_e3k.h" +#include "chip_include_e3k.h" + +extern int vidmmi_copy_data(struct _vidmm_mgr *mm_mgr, task_paging_t *paging_task,vidmm_allocation_t *dst_allocation, + unsigned long long src_addr, unsigned long long dst_addr, + unsigned int src_compress, unsigned int dst_compress, unsigned int size); + +int vidmm_segment_memory_transfer_e3k(adapter_t *adapter, vidmm_segment_memory_t **dst_pointer, vidmm_segment_memory_t *src, int to_local); + +void vidmm_init_mem_settings_e3k(adapter_t *adapter) +{ + Reg_Mmu_Mode reg_Mmu_Mode = {0}; + Reg_Mxu_Dec_Ctrl reg_Mxu_Dec_Ctrl = {0}; + Reg_Mxu_Channel_Control reg_Mxu_Channel_Control = {0}; + Reg_Ttbr reg_Ttbr = {0}; + unsigned char * pRegAddr = NULL; + unsigned int pending_buf_len = (adapter->chip_id < CHIP_ARISE1020) ? 0x4 : 0x40; + + //vcp0 decouple disable 0x4c910 0x1 + //if miu numble is larger than 1, we enable decouple, others disable. + if(adapter->chip_id >= CHIP_ARISE1020 && adapter->chip_id != CHIP_ARISE2030) + { + pRegAddr = adapter->mmio + 0x4c910; + gf_write32(pRegAddr, 0x1); + } + + //CHIP_ARISE1020 only has one vcp core + //if(adapter->chip_id < CHIP_ARISE1020) + //{ + //vcp1 decouple disable 0x4a910 0x1 + // pRegAddr = adapter->mmio + 0x4a910; + // gf_write32(pRegAddr, 0x1); + //} + + reg_Mmu_Mode.reg.Vmen = 0;//use PA mode + reg_Mmu_Mode.reg.Video_Size = (adapter->Real_vram_size>> 28) - 1; + + pRegAddr = adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Mmu_Mode_Offset*4; + gf_write32(pRegAddr, reg_Mmu_Mode.uint); + //gf_info(" reg_Mmu_Mode.uint 0x%x readvalue: 0x%x \n", reg_Mmu_Mode.uint, gf_read32(pRegAddr)); + + reg_Mxu_Dec_Ctrl.reg.Ddec_Antilock = 1; + pRegAddr = adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Mxu_Dec_Ctrl_Offset*4; + gf_write32(pRegAddr, reg_Mxu_Dec_Ctrl.uint); + gf_info("reg_Mxu_Dec_Ctrl.uint 0x%x readvalue: 0x%x \n", reg_Mxu_Dec_Ctrl.uint, gf_read32(pRegAddr)); + +#ifndef GF_HW_NULL + // if(!adapter->hw_caps.local_only) + { + unsigned int i = 0; + unsigned int ttbrn_for_total = (adapter->Real_vram_size + adapter->gart_ram_size)%0x100000000? + ((adapter->Real_vram_size + adapter->gart_ram_size)/0x100000000 +1) : (adapter->Real_vram_size + adapter->gart_ram_size)/0x100000000;//per ttbr can index 4G mem, total has 256 ttbr regs for pa mode. + + gf_assert(ttbrn_for_total <= 256,"total ttbr number excced"); + + for(i = 0; i < ttbrn_for_total; i++) + { + reg_Ttbr.reg.Segment = 1; + reg_Ttbr.reg.Valid = 1; + reg_Ttbr.reg.Addr = (adapter->gart_table_L2->phys_addr + 4096 * i) >> 12; + pRegAddr = adapter->mmio + MMIO_MMU_START_ADDRESS + (Reg_Mmu_Ttbr_Offset + i)*4; + gf_write32(pRegAddr, reg_Ttbr.uint); + } + } +#endif + + if (adapter->hw_caps.miu_channel_num == 1) + { + reg_Mxu_Channel_Control.reg.Miu_Channel0_Disable = 0; + reg_Mxu_Channel_Control.reg.Miu_Channel1_Disable = 1; + reg_Mxu_Channel_Control.reg.Miu_Channel2_Disable = 1; + + pRegAddr = adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Diu_Reserve_Ctrl_Offset*4; + gf_write32(pRegAddr, 0x1200003); + }else if (adapter->hw_caps.miu_channel_num == 2) + { + reg_Mxu_Channel_Control.reg.Miu_Channel0_Disable = 0; + reg_Mxu_Channel_Control.reg.Miu_Channel1_Disable = 0; + reg_Mxu_Channel_Control.reg.Miu_Channel2_Disable = 1; + + pRegAddr = adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Diu_Reserve_Ctrl_Offset*4; + gf_write32(pRegAddr, 0x1300003); + }else if (adapter->hw_caps.miu_channel_num == 3) + { + reg_Mxu_Channel_Control.reg.Miu_Channel0_Disable = 0; + reg_Mxu_Channel_Control.reg.Miu_Channel1_Disable = 0; + reg_Mxu_Channel_Control.reg.Miu_Channel2_Disable = 0; + + pRegAddr = adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Diu_Reserve_Ctrl_Offset*4; + gf_write32(pRegAddr, 0x1360003); + }else + { + gf_assert(0,"bad miu channel num\n"); + } + + pRegAddr = adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Pending_Buf_Ctrl_0_Offset*4; + gf_write32(pRegAddr, pending_buf_len); + + reg_Mxu_Channel_Control.reg.Ch_Size = adapter->hw_caps.miu_channel_size; + + pRegAddr =adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Mxu_Channel_Control_Offset*4; + gf_write32(pRegAddr, reg_Mxu_Channel_Control.uint); + //gf_info(" reg_Mxu_Channel_Control.uint 0x%x readvalue: 0x%x \n", reg_Mxu_Channel_Control.uint, gf_read32(pRegAddr)); + + //mxu vcp priority higher 0x4908c 0x11000202 + pRegAddr = adapter->mmio + 0x4908c; + gf_write32(pRegAddr, 0x11000202); + + if (adapter->hw_caps.gf_backdoor_enable) + { +#if defined(__i386__) || defined(__x86_64__) + pRegAddr = adapter->mmio + 0x8a70; + gf_write32(pRegAddr, 0x001a4000); + pRegAddr = adapter->mmio + 0x8a6c; + gf_write32(pRegAddr, 0x00000000); +#elif defined (__aarch64__) + pRegAddr = adapter->mmio + 0x8a70; + gf_write32(pRegAddr, 0x001a4000); + pRegAddr = adapter->mmio + 0x8a6c; + gf_write32(pRegAddr, 0x10000000); +#elif defined (__mips64__) || defined (__loongarch__) + pRegAddr = adapter->mmio + 0x8a70; + gf_write32(pRegAddr, 0x001a4000); + pRegAddr = adapter->mmio + 0x8a6c; + gf_write32(pRegAddr, 0x20000000); +#endif + } + else + { +#if defined (__mips64__) || defined (__loongarch__) + // default upstream read length (2048 bit) will cause hang when playing video, + // set to 512 bit on 1020 when backdoor is off + if(adapter->chip_id >= CHIP_ARISE1020) + { + pRegAddr = adapter->mmio + 0x8a6c; + gf_write32(pRegAddr, 0x20000000); + } +#endif + } +} + + +void vidmm_query_segment_info_e3k(adapter_t *adapter, vidmm_chip_segment_info_t *info) +{ + vidmm_segment_desc_t *segments_desc = NULL; + vidmm_segment_desc_t *segment_desc = NULL; + unsigned long long boundry_for_unvisible_segment_low=0llu; + int size_for_secure_range = 0; + + //use default memory size + if(adapter->gart_ram_size == 0) + { + adapter->gart_ram_size = GART_MEMORY_SIZE_E3K; + } + + size_for_secure_range = + adapter->Visible_vram_size - ((adapter->Visible_vram_size - 2 * SECURE_RANGE_BUFFER_SIZE)&~0xFFFFll); //secure range should be 64k aligned + + info->cpu_visible_vidmm_size = adapter->Visible_vram_size; + info->cpu_unvisible_vidmm_size = adapter->Real_vram_size - adapter->Visible_vram_size; + info->segment_cnt = SEGMENT_ID_MAX_E3K; + segments_desc = info->segment_desc; + + /* GPU Memory Layout + ------------------------- + | L | + | O cpu visiable | + | C ----------------------> Visible_vram_size + | A cpu unvisiable | + | L | + +-----------------------+--> Real_vram_size + | P | + | C none-snoop | + | -------------------| + | I snoop | + | E | + +-----------------------+ + */ + + /* init local cpu visiable segment*/ + segment_desc = &segments_desc[SEGMENT_ID_LOCAL_E3K]; + segment_desc->segment_id = SEGMENT_ID_LOCAL_E3K; + segment_desc->segment_name = "Segment Local"; + segment_desc->gpu_vm_start = 0; + segment_desc->gpu_vm_size = + adapter->hw_caps.secure_range_enable ? (adapter->Visible_vram_size -size_for_secure_range):adapter->Visible_vram_size; + + segment_desc->reserved_vm_size = 0; + segment_desc->small_heap_size = SMALL_HEAP_SIZE_E3K; + segment_desc->small_heap_max_allocate_size = SMALL_HEAP_MAX_ALLOCATE_SIZE_E3K; + segment_desc->segment_alignment = adapter->os_page_size;//drm_gem_private_object_init has PAGE_SIZE check. + segment_desc->flags.cpu_visible = 1; + segment_desc->flags.support_aperture = 0; + segment_desc->flags.mtrr = 1; + segment_desc->flags.small_heap_available = 1; + segment_desc->flags.system_pages_reserved = 0; + segment_desc->flags.chip_phys_mem_reserved = 1; + + + /*hack secure range from local cpu visiable end*/ + segment_desc = &segments_desc[SEGMENT_ID_SECURE_RANGE_E3K]; + segment_desc->segment_id = SEGMENT_ID_SECURE_RANGE_E3K; + segment_desc->segment_name = "Segment Secure range"; + segment_desc->gpu_vm_start = adapter->hw_caps.secure_range_enable ? (adapter->Visible_vram_size - size_for_secure_range):0; + segment_desc->gpu_vm_size = adapter->hw_caps.secure_range_enable ? SECURE_RANGE_BUFFER_SIZE:0; + segment_desc->segment_alignment = adapter->os_page_size;//drm_gem_private_object_init has PAGE_SIZE check. + segment_desc->flags.cpu_visible = 1; + segment_desc->flags.support_aperture = 0; + segment_desc->flags.mtrr = 1; + segment_desc->flags.secure_range = 1; + segment_desc->flags.chip_phys_mem_reserved = 1; + + segment_desc = &segments_desc[SEGMENT_ID_SECURE_RANGE_E3K_1]; + segment_desc->segment_id = SEGMENT_ID_SECURE_RANGE_E3K_1; + segment_desc->segment_name = "Segment Secure range 1"; + segment_desc->gpu_vm_start = adapter->hw_caps.secure_range_enable ? (adapter->Visible_vram_size - size_for_secure_range + SECURE_RANGE_BUFFER_SIZE):0; + segment_desc->gpu_vm_size = adapter->hw_caps.secure_range_enable ? SECURE_RANGE_BUFFER_SIZE:0; + segment_desc->segment_alignment = adapter->os_page_size;//drm_gem_private_object_init has PAGE_SIZE check. + segment_desc->flags.cpu_visible = 1; + segment_desc->flags.support_aperture = 0; + segment_desc->flags.mtrr = 1; + segment_desc->flags.secure_range = 1; + segment_desc->flags.chip_phys_mem_reserved = 1; + + /* init pcie unsnoopable segment */ + segment_desc = &segments_desc[SEGMENT_ID_GART_UNSNOOPABLE_E3K]; + segment_desc->segment_id = SEGMENT_ID_GART_UNSNOOPABLE_E3K; + segment_desc->segment_name = "Segment Unsnoopable"; + segment_desc->gpu_vm_start = adapter->Real_vram_size; + segment_desc->gpu_vm_size = adapter->gart_ram_size - SNOOPABLE_SEGMENT_RATION_E3K(adapter->gart_ram_size); + segment_desc->reserved_vm_size = 0; + segment_desc->small_heap_size = SMALL_HEAP_SIZE_E3K; + segment_desc->small_heap_max_allocate_size = SMALL_HEAP_MAX_ALLOCATE_SIZE_GART_E3K; + + segment_desc->segment_alignment = adapter->os_page_size; + segment_desc->flags.require_system_pages = 1; + segment_desc->flags.cpu_visible = 1; + if(adapter->hw_caps.snoop_only) + { + segment_desc->flags.support_snoop = 1; + } + else + { + segment_desc->flags.support_snoop = 0; + } + + segment_desc->flags.small_heap_available = 1; + + /* init pcie snoopable segment */ + segment_desc = &segments_desc[SEGMENT_ID_GART_SNOOPABLE_E3K]; + segment_desc->segment_id = SEGMENT_ID_GART_SNOOPABLE_E3K; + segment_desc->segment_name = "Segment Snoopable"; + segment_desc->gpu_vm_start = adapter->Real_vram_size + segments_desc[SEGMENT_ID_GART_UNSNOOPABLE_E3K].gpu_vm_size; + segment_desc->gpu_vm_size = SNOOPABLE_SEGMENT_RATION_E3K(adapter->gart_ram_size); + segment_desc->reserved_vm_size = 0; + segment_desc->small_heap_size = SMALL_HEAP_SIZE_E3K; + segment_desc->small_heap_max_allocate_size = SMALL_HEAP_MAX_ALLOCATE_SIZE_GART_E3K; + + segment_desc->segment_alignment = adapter->os_page_size; + segment_desc->flags.require_system_pages = 1; + segment_desc->flags.cpu_visible = 1; + segment_desc->flags.support_snoop = 1; + segment_desc->flags.small_heap_available = 1; + + /*init local cpu unvisiable segment*/ + boundry_for_unvisible_segment_low = (adapter->Real_vram_size > 0x100000000) ? 0x100000000 : adapter->Real_vram_size;//patch for video limit to 4G issue. + gf_assert(boundry_for_unvisible_segment_low >= adapter->Visible_vram_size, "boundry_for_unvisible_segment_low > adapter->Visible_vram_size"); + + segment_desc = &segments_desc[SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K]; + segment_desc->segment_id = SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K; + segment_desc->segment_name = "Segment Local CPU unvisiable"; + segment_desc->gpu_vm_start = adapter->Visible_vram_size; + segment_desc->gpu_vm_size = boundry_for_unvisible_segment_low - adapter->Visible_vram_size; + + segment_desc->segment_alignment = adapter->os_page_size;//drm_gem_private_object_init has PAGE_SIZE check. + segment_desc->flags.cpu_visible = 0; + segment_desc->flags.support_aperture = 0; + segment_desc->flags.mtrr = 0; + segment_desc->flags.small_heap_available = 0; + segment_desc->flags.system_pages_reserved = 0; + segment_desc->flags.chip_phys_mem_reserved = 1; + + /*init local cpu unvisiable segment 1*/ + segment_desc = &segments_desc[SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K_1]; + segment_desc->segment_id = SEGMENT_ID_LOCAL_CPU_UNVISIABLE_E3K_1; + segment_desc->segment_name = "Segment Local CPU unvisiable 1"; + segment_desc->gpu_vm_start = boundry_for_unvisible_segment_low; + segment_desc->gpu_vm_size = adapter->Real_vram_size - boundry_for_unvisible_segment_low; + + segment_desc->segment_alignment = adapter->os_page_size;//drm_gem_private_object_init has PAGE_SIZE check. + segment_desc->flags.cpu_visible = 0; + segment_desc->flags.support_aperture = 0; + segment_desc->flags.mtrr = 0; + segment_desc->flags.small_heap_available = 0; + segment_desc->flags.system_pages_reserved = 0; + segment_desc->flags.chip_phys_mem_reserved = 1; + + /* init paging segment */ + if(!adapter->hw_caps.snoop_only) + info->paging_segment_id = SEGMENT_ID_GART_UNSNOOPABLE_E3K; + else + info->paging_segment_id = SEGMENT_ID_GART_SNOOPABLE_E3K; + info->paging_segment_size = PAGING_SEGMENT_SIZE_E3K; +} + +static int vidmm_query_segment_mem_e3k(struct _vidmm_mgr *mm_mgr, gf_query_info_t *info) +{ + adapter_t* adapter=mm_mgr->adapter; + unsigned int id = (info->argu & 0xFF); + unsigned int is_kernel = (info->argu & 0x80000000); + vidmm_segment_t* segment=NULL; + unsigned long long total_size=0,used_size=0; + unsigned int alloc_num=0; + gf_segment_mem_t seg_mem={}; + + int cnt = vidmm_get_segment_count(adapter); + if (id > cnt - 1) + { + gf_info("invalid segment id %x\n", id); + return -1; + } + segment = &mm_mgr->segment[id]; + gf_mutex_lock(segment->lock); + total_size= segment->gpu_vm_size >> 10; + used_size= (segment->pagable_size + segment->unpagable_size + segment->reserved_size) >> 10; + alloc_num=(segment->pagable_num + segment->unpagable_num); + gf_mutex_unlock(segment->lock); + + switch (info->type) + { + case GF_QUERY_SEGMENT_FREE_SIZE: + info->value=total_size-used_size; + break; + case GF_QUERY_SEGMENT_MEM_INFO: + if(info->buf==NULL) + { + gf_info("query buffer is null \n"); + return -1; + } + + seg_mem.segment_id = id; + seg_mem.segment_total_size = total_size; + seg_mem.segment_used_size = used_size; + seg_mem.segment_alloc_num = alloc_num; + + if(is_kernel) + { + gf_memcpy(info->buf, &seg_mem, sizeof(gf_segment_mem_t)); + } + else + { + gf_copy_to_user(info->buf, &seg_mem, sizeof(gf_segment_mem_t)); + } + break; + default: + break; + } + return 0; +} + +int vidmm_segment_memory_transfer_e3k(adapter_t *adapter, vidmm_segment_memory_t **dst_pointer, vidmm_segment_memory_t *src, int to_local) +{ + int alloc_new_segment = 0, result = S_OK; + unsigned int need_copy_size = 0; + task_paging_t *paging_task = NULL; + vidmm_segment_memory_t *dst = NULL; + + if (!src || !dst_pointer) + goto error; + + if (!(*dst_pointer)) + { + // If dst_pointer not point a vaild segment_memory, we will alloc a new segment memory to *dst_pointer + *dst_pointer = vidmm_allocate_segment_memory(adapter, to_local ? SEGMENT_ID_LOCAL_E3K : SEGMENT_ID_GART_UNSNOOPABLE_E3K, src->list_node->aligned_size, 0); + if (!(*dst_pointer)) + { + result = E_OUTOFMEMORY; + goto error; + } + alloc_new_segment = 1; + } + + dst = *dst_pointer; + //We check segment memory size here. + need_copy_size = src->list_node->aligned_size > dst->list_node->aligned_size ? + dst->list_node->aligned_size : src->list_node->aligned_size; + //gf_info("segment_memory_transfers src size:0x%llx, dst size:0x%llx\n", src->list_node->aligned_size, dst->list_node->aligned_size); + + paging_task = vidsch_allocate_paging_task(adapter, 8*1024, 0); + paging_task->paging_allocation_num = 0; + paging_task->paging_type = 2; + result = vidmmi_copy_data(adapter->mm_mgr, + paging_task, + NULL, + src->gpu_virt_addr, + dst->gpu_virt_addr, + CP_OFF, + CP_OFF, + need_copy_size); + if(result) + goto error; + + vidsch_task_inc_reference(adapter, adapter->paging_engine_index, &paging_task->desc); + vidsch_submit_paging_task(adapter, paging_task); + vidsch_wait_fence_back(adapter, adapter->paging_engine_index, paging_task->desc.fence_id); + vidsch_task_dec_reference(adapter, adapter->paging_engine_index, &paging_task->desc); + + return result; + +error: + if (alloc_new_segment) + { + vidmm_release_segment_memory(adapter, dst); + *dst_pointer = NULL; + } + return result; + +} + +vidmm_chip_func_t vidmm_chip_func = +{ + .query_segment_info = vidmm_query_segment_info_e3k, + .mem_setting = vidmm_init_mem_settings_e3k, + .init_gart_table = vidmm_init_gart_table_e3k, + .deinit_gart_table = vidmm_deinit_gart_table_e3k, + .query_gart_table_info = vidmm_query_gart_table_info_e3k, + .describe_allocation = vidmm_describe_allocation_e3k, + .build_paging_buffer = vidmm_build_page_buffer_e3k, + .map_gart_table = vidmm_map_gart_table_e3k, + .unmap_gart_table = vidmm_unmap_gart_table_e3k, + .set_snooping = vidmm_gart_table_set_snoop_e3k, + .get_allocation_info = vidmm_get_allocation_info_e3k, + .query_info = vidmm_query_segment_mem_e3k, + .segment_memory_transfer = vidmm_segment_memory_transfer_e3k, +}; + + + diff --git a/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_gart_table_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_gart_table_e3k.c new file mode 100644 index 0000000000000..aaf669a01e098 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidmm/vidmm_gart_table_e3k.c @@ -0,0 +1,306 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "vidmm.h" +#include "vidmmi.h" +#include "register_e3k.h" +#include "mm_e3k.h" +#include "chip_include_e3k.h" +#include "vidmmi_e3k.h" + +static unsigned long long vidmmi_get_allocation_page_offset_e3k(adapter_t *adapter, vidmm_gart_table_info_t *gart_table, vidmm_allocation_t *allocation) +{ + unsigned long long page_offset = 0; + + gf_assert(allocation->phys_addr >= gart_table->gart_start_addr, "vidmmi_get_allocation_page_offset"); + page_offset = (allocation->phys_addr - gart_table->gart_start_addr)/GPU_PAGE_SIZE_E3K; + + return page_offset; +} + +int vidmm_query_gart_table_info_e3k(adapter_t *adapter) +{ + int result = S_OK; + vidmm_gart_table_info_t *gart_table_L3 = adapter->gart_table_L3; + vidmm_gart_table_info_t *gart_table_L2 = adapter->gart_table_L2; + + gart_table_L3->size =(adapter->gart_ram_size / GPU_PAGE_SIZE_E3K) * sizeof(int); + gart_table_L2->size =((adapter->gart_ram_size + adapter->Real_vram_size)/(4*1024*1024)) * sizeof(int); + +#ifndef GF_HW_NULL + gart_table_L3->segment_id = + gart_table_L2->segment_id = SEGMENT_ID_LOCAL_E3K; +#else + gart_table_L3->segment_id = + gart_table_L2->segment_id = SEGMENT_ID_GART_UNSNOOPABLE_E3K; +#endif + + return result; +} + +void vidmm_init_gart_table_e3k(adapter_t *adapter) +{ + vidmm_gart_table_info_t *gart_table_L3 = adapter->gart_table_L3; + vidmm_gart_table_info_t *gart_table_L2 = adapter->gart_table_L2; + unsigned int L2EntryNumForL3 = gart_table_L3->size/(4*1024); + unsigned int L2EntryNumForLoal = adapter->Real_vram_size/(4*1024*1024); + unsigned int L3EntryNum = gart_table_L3->size/4; + unsigned int *pte_list = NULL; + PTE_L2_t page_entry = {0}; + PTE_L3_t page_entry_L3 = {0}; + int i; + unsigned long long page_phy_addr = adapter->dummy_page_addr; + + page_phy_addr >>= 12; + page_entry_L3.pte_4k.Valid =1; + page_entry_L3.pte_4k.Addr = page_phy_addr & 0xFFFFFFF; + + + if(gart_table_L3->virt_addr) + { + pte_list = gart_table_L3->virt_addr; + + gart_table_L3->pcie_addr = gart_table_L3->virt_addr; + + for(i = 0; i < L3EntryNum; i++) + { + pte_list[i] = page_entry_L3.uint; + } + + gart_table_L3->gart_start_addr = adapter->Real_vram_size; + gart_table_L3->dirty = TRUE; + } + + if(gart_table_L2->virt_addr) + { + page_entry._4k_d.Valid = TRUE; + page_entry._4k_d.Segment= 1; // 1 means this pte point to local mem + page_entry._4k_d.Addr= 0; + + pte_list = gart_table_L2->virt_addr; + + gart_table_L2->pcie_addr = gart_table_L2->virt_addr; + + for(i = 0; i < L2EntryNumForLoal; i++) + { + pte_list[i] = page_entry.uint; + } + + for(i = 0; i < L2EntryNumForL3; i++) + { + page_entry._4k_d.Addr = ((gart_table_L3->phys_addr >> 12) + i) &0xFFFFFF; + pte_list[i + L2EntryNumForLoal] = page_entry.uint; + } + gart_table_L2->dirty = TRUE; + } +} + +void vidmm_deinit_gart_table_e3k(adapter_t *adapter) +{ + +} + +struct fill_garttable_arg +{ + adapter_t *adapter; + unsigned long long page_offset; + unsigned long long base_index; + unsigned int *gart_pages; + PTE_L3_t page_entry; + unsigned long long mask; + unsigned long long addr; + unsigned long long boundary; + + //duplicate hang only: + //To restore gart-table, only need to update pte.Addr fields + int update_addr_only; +}; + +static int vidmm_fill_garttable_e3k(void *arg, int pg_start, int pg_cnt, unsigned long long dma_addr) +{ + int i, j; + struct fill_garttable_arg *fga = arg; + unsigned long long page_phy_addr = dma_addr >> 12; + unsigned int GPUPAGES_PER_CPUPAGE = fga->adapter->os_page_size/ GPU_PAGE_SIZE_E3K; + + for (i = 0; i < pg_cnt; i++) + { + for (j = 0; j < GPUPAGES_PER_CPUPAGE; j++) + { + + if(fga->update_addr_only) + { + fga->page_entry.uint = fga->gart_pages[fga->base_index + (i + pg_start) * GPUPAGES_PER_CPUPAGE + j]; + } + + fga->page_entry.pte_4k.Addr = (page_phy_addr + i * GPUPAGES_PER_CPUPAGE + j) & 0xFFFFFFF; + fga->gart_pages[fga->base_index + (i + pg_start) * GPUPAGES_PER_CPUPAGE + j] = fga->page_entry.uint; + fga->mask |= fga->addr ^ (((fga->page_offset + (i + pg_start) * GPUPAGES_PER_CPUPAGE + j) << 12) + fga->boundary); + } + } + + return 0; +} + + +void vidmm_map_gart_table_e3k(adapter_t *adapter, vidmm_allocation_t *allocation, int snooping) +{ + vidmm_gart_table_info_t *gart_table_L3 = adapter->gart_table_L3; + struct os_pages_memory *pages_mem = allocation->pages_mem; + unsigned int *gart_pages = gart_table_L3->pcie_addr; + struct fill_garttable_arg arg = {0, }; + + arg.adapter = adapter; + arg.gart_pages = gart_pages; + arg.boundary = gart_table_L3->gart_start_addr; + arg.page_entry.pte_4k.Valid = 1; + arg.page_entry.pte_4k.Segment = 0; + arg.page_entry.pte_4k.NS = 1; + arg.page_entry.pte_4k.Snoop = snooping? TRUE: FALSE; + arg.page_offset = vidmmi_get_allocation_page_offset_e3k(adapter, gart_table_L3, allocation); + arg.base_index = arg.page_offset; + arg.addr = (arg.page_offset << 12) + arg.boundary; + arg.mask = 0; + +#ifdef VMI_MODE + gf_set_pages_addr(pages_mem, arg.page_offset * GPU_PAGE_SIZE_E3K); +#endif + + gf_pages_memory_for_each_continues(pages_mem, &arg, vidmm_fill_garttable_e3k); + + gf_mutex_lock(adapter->gart_table_lock); + + // Mask will be the or of old mask and new mask and + // the diff between static part of old address and new address + if (gart_table_L3->dirty) + { + gart_table_L3->gart_table_dirty_mask = + (gart_table_L3->gart_table_dirty_mask | arg.mask | + (gart_table_L3->gart_table_dirty_addr ^ (arg.addr & ~arg.mask))); + gart_table_L3->gart_table_dirty_addr = + gart_table_L3->gart_table_dirty_addr & ~gart_table_L3->gart_table_dirty_mask; + } + else + { + gart_table_L3->gart_table_dirty_mask = arg.mask; + gart_table_L3->gart_table_dirty_addr = arg.addr & ~arg.mask; + } + + /* flush write_combine buffer */ + gf_flush_wc(); + + gart_table_L3->dirty = TRUE; + + gf_mutex_unlock(adapter->gart_table_lock); +} + +/* + * when unmap gart table, fill the corresponding gart table entry with dumy page addr + */ +void vidmm_unmap_gart_table_e3k(adapter_t *adapter, vidmm_allocation_t *allocation) +{ + vidmm_gart_table_info_t *gart_table_L3 = adapter->gart_table_L3; + unsigned int *gart_pages = gart_table_L3->pcie_addr; + unsigned long long boundary = gart_table_L3->gart_start_addr; + unsigned int page_count = allocation->size / adapter->os_page_size; + unsigned long long page_offset = 0; + unsigned long long page_phy_addr; + unsigned long long addr = 0; + unsigned long long mask = 0; + + int i = 0, j = 0; + int gart_page_num_per_kernel_page = adapter->os_page_size / GPU_PAGE_SIZE_E3K; + + PTE_L3_t page_entry = {0}; + + page_entry.pte_4k.Valid = 1; + page_entry.pte_4k.Segment = 0; + page_entry.pte_4k.NS = 1; + + page_offset = vidmmi_get_allocation_page_offset_e3k(adapter, gart_table_L3, allocation); + addr = (page_offset << 12) + boundary; + + for(i = 0; i < page_count; i++) + { + page_phy_addr = adapter->dummy_page_addr; + page_phy_addr >>= 12; + +#if defined(__mips64__) || defined(__loongarch__) + gf_assert(!(page_phy_addr & 0xFFFFFFFFF0000000), "cpu PA need under 36bits"); + gf_assert(!(page_phy_addr &0x3), "page_phy_addr not 16k"); +#endif + + for(j = 0; j < gart_page_num_per_kernel_page; j++) + { + //set sys page PA + page_entry.pte_4k.Addr = (page_phy_addr + j) & 0xFFFFFFF; //how could we ensure cpu PA is under 36bits? + + gart_pages[page_offset + i * gart_page_num_per_kernel_page + j] = page_entry.uint; + + mask |= addr ^ (((i * gart_page_num_per_kernel_page + j + page_offset) << 12) + boundary); + } + } + + gf_mutex_lock(adapter->gart_table_lock); + // Mask will be the or of old mask and new mask and + // the diff between static part of old address and new address + if (gart_table_L3->dirty) + { + gart_table_L3->gart_table_dirty_mask = + (gart_table_L3->gart_table_dirty_mask | mask | + (gart_table_L3->gart_table_dirty_addr ^ (addr & ~mask))); + gart_table_L3->gart_table_dirty_addr = + gart_table_L3->gart_table_dirty_addr & ~gart_table_L3->gart_table_dirty_mask; + } + else + { + gart_table_L3->gart_table_dirty_mask = mask; + gart_table_L3->gart_table_dirty_addr = addr & ~mask; + } + + /* flush write_combine buffer */ + gf_flush_wc(); + gart_table_L3->dirty = TRUE; + gf_mutex_unlock(adapter->gart_table_lock); +} + +void vidmm_gart_table_set_snoop_e3k(adapter_t *adapter, vidmm_allocation_t *allocation, int snooping) +{ + +} + +void vidmm_update_gart_table_pte_e3k(adapter_t *adapter, struct os_pages_memory *memory, unsigned int *gart_table_L3, unsigned long gpu_va) +{ + struct fill_garttable_arg arg = {0, }; + + arg.adapter = adapter; + arg.gart_pages = gart_table_L3; + arg.boundary = adapter->Real_vram_size; + arg.page_offset = (gpu_va - adapter->Real_vram_size)/GPU_PAGE_SIZE_E3K; + arg.base_index = arg.page_offset; + arg.addr = (arg.page_offset << 12) + arg.boundary; + arg.mask = 0; + arg.update_addr_only = 1; + +#ifdef VMI_MODE + gf_set_pages_addr(memory, arg.page_offset * GPU_PAGE_SIZE_E3K); +#endif + + gf_pages_memory_for_each_continues(memory, + &arg, + vidmm_fill_garttable_e3k); +} + diff --git a/drivers/gpu/drm/arise/core/e3k/vidmm/vidmmi_e3k.h b/drivers/gpu/drm/arise/core/e3k/vidmm/vidmmi_e3k.h new file mode 100644 index 0000000000000..9b60e358f9968 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidmm/vidmmi_e3k.h @@ -0,0 +1,34 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __VIDMMI_E3K_H__ +#define __VIDMMI_E3K_H__ + +extern void vidmm_query_segment_info_e3k(adapter_t *, vidmm_chip_segment_info_t *); +extern int vidmm_describe_allocation_e3k(adapter_t*, vidmm_describe_allocation_t*); +extern int vidmm_build_page_buffer_e3k(adapter_t*, vidmm_private_build_paging_buffer_arg_t*); +extern int vidmm_query_gart_table_info_e3k(adapter_t*); +extern void vidmm_init_mem_settings_e3k(adapter_t *); +extern void vidmm_init_gart_table_e3k(adapter_t*); +extern void vidmm_deinit_gart_table_e3k(adapter_t*); +extern void vidmm_map_gart_table_e3k(adapter_t*, vidmm_allocation_t *allocation, int snooping); +extern void vidmm_unmap_gart_table_e3k(adapter_t*, vidmm_allocation_t *allocation); +extern void vidmm_gart_table_set_snoop_e3k(adapter_t *adapter, vidmm_allocation_t *allocation, int snooping); +extern void vidmm_update_gart_table_pte_e3k(adapter_t *adapter, struct os_pages_memory *memory, unsigned int *gart_table_L3, unsigned long gpu_va); +extern int vidmm_get_allocation_info_e3k(adapter_t *adapter, vidmm_get_allocation_info_t *info); +extern int vidmm_segment_transfer_e3k(adapter_t *adapter, vidmm_segment_memory_t **dst_pointer, vidmm_segment_memory_t *src, int to_local); + + +#endif + diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/ContextSwitch_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidsch/ContextSwitch_e3k.c new file mode 100644 index 0000000000000..fcf191ae8a9ee --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/ContextSwitch_e3k.c @@ -0,0 +1,503 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_engine_e3k.h" +#include "chip_include_e3k.h" +#include "bit_op.h" + +void enginei_init_context_save_restore_dma_e3k(engine_gfx_e3k_t *engine) +{ + engine_share_e3k_t *share = engine->common.share; + adapter_t *adapter = engine->common.vidsch->adapter; + RB_PREDEFINE_DMA* pCmdBuf = NULL; + CONTEXT_RESTORE_DMA_E3K *pRestoreDMA = NULL; + CONTEXT_RESTORE_DMA_E3K *pRestoreShadowDMA = NULL; + + CONTEXT_SAVE_DMA_E3K *pSaveDMA = NULL; + CACHEFLUSH_DMA_E3K *pCacheFlushDMA3DL = NULL; + + DWORD regValue = 0; + + + gf_map_argu_t map_argu = {0}; + gf_vm_area_t *vma = NULL; + + unsigned int slice_mask = adapter->hw_caps.chip_slice_mask; + unsigned int gpc_bit_mask = 0, shift_num = 1, bit_mask = 0; + + while(slice_mask) + { + if(slice_mask & 0xf) + { + gpc_bit_mask |= shift_num; + } + slice_mask >>= 4; + shift_num <<= 1; + } + + + + map_argu.flags.cache_type = GF_MEM_WRITE_COMBINED; + map_argu.flags.mem_space = GF_MEM_KERNEL; + map_argu.flags.mem_type = GF_SYSTEM_IO; + map_argu.phys_addr = adapter->vidmm_bus_addr + share->begin_end_buffer_phy_addr; + map_argu.size = BEGIN_END_BUF_SIZE_E3K; + + vma = gf_map_io_memory(NULL, &map_argu); + + gf_memset(vma->virt_addr, 0, vma->size); + + pCmdBuf = (RB_PREDEFINE_DMA*) vma->virt_addr; + + pRestoreDMA = &(pCmdBuf->RestoreDMA); + + pSaveDMA = &(pCmdBuf->SaveDMA); + pCacheFlushDMA3DL = &(pCmdBuf->FlushDMA3DL); + + + pRestoreDMA->RestoreContext.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Save_Rsto; + pRestoreDMA->RestoreContext.Block_Id = CSP_GLOBAL_BLOCK; + pRestoreDMA->RestoreContext.Type = BLOCK_COMMAND_CSP_TYPE_RESTORE; + pRestoreDMA->RestoreContext.Address_Mode = SET_REGISTER_ADDRESS_MODE_OFFSET; + pRestoreDMA->RestoreContext.Dwc = 2; + + pRestoreDMA->ContextBufferOffset_H = 0; + + pRestoreDMA->RestoreEuFullGlb.uint = SET_REGISTER_ADDR_E3K(EU_FS_BLOCK, Reg_Eu_Full_Glb_Offset, SET_REGISTER_ADDRESS_MODE_OFFSET); + pRestoreDMA->EuFullGlbOffset_L = SET_REGISTER_ADDR_LOW_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->HWContextbuffer.shadow_buf_3D.fe_be_regs.eufs_regs.reg_Eu_Full_Glb))); + pRestoreDMA->EuFullGlbOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(0x0, 1); + + pRestoreDMA->RestoreTsSharpCtrl.uint = SET_REGISTER_ADDR_E3K(TUFE_BLOCK, Reg_Tu_Tssharp_Ctrl_Offset, SET_REGISTER_ADDRESS_MODE_OFFSET); + pRestoreDMA->TsSharpCtrlOffset_L = SET_REGISTER_ADDR_LOW_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->HWContextbuffer.shadow_buf_3D.fe_be_regs.tu_regs.reg_Tu_Tssharp_Ctrl))); + pRestoreDMA->TsSharpCtrlOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(0x0, 1); + + pRestoreDMA->RestoreFFCUbufConfig.uint = SET_REGISTER_ADDR_E3K(WLS_FE_BLOCK, Reg_Ffc_Ubuf_Golbalconfig_Offset, SET_REGISTER_ADDRESS_MODE_OFFSET); + pRestoreDMA->FFCUbufConfigOffset_L = SET_REGISTER_ADDR_LOW_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->HWContextbuffer.shadow_buf_3D.fe_be_regs.wls_regs.reg_Ffc_Ubuf_Golbalconfig))); + pRestoreDMA->FFCUbufConfigOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(0x0, 1); + + pRestoreDMA->RestoreCsp.uint = SET_REGISTER_ADDR_E3K(CSP_GLOBAL_BLOCK, Reg_Csp_Ms_Total_Gpu_Timestamp_Offset,SET_REGISTER_ADDRESS_MODE_OFFSET); + pRestoreDMA->CSPOffset_L = SET_REGISTER_ADDR_LOW_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->CSPRegs))); + pRestoreDMA->CSPOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(0x0, sizeof(CSP_CONTEXTBUFFER_REGS) >> 2); + + pRestoreDMA->RestoreGpcpFe.uint = SET_REGISTER_ADDR_E3K(GPCPFE_BLOCK, Reg_Gpcpfe_Iidcnt_Offset, SET_REGISTER_ADDRESS_MODE_OFFSET); + pRestoreDMA->GpcpFeOffset_L = SET_REGISTER_ADDR_LOW_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpFeRegs))); + pRestoreDMA->GpcpFeOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(0x0, sizeof(GPCPFE_CONTEXTBUFFER_REGS) >> 2); + + pRestoreDMA->RestoreGpcpBe.uint = SET_REGISTER_ADDR_E3K(GPCPBE_BLOCK, Reg_Sto_Cfg_Offset, SET_REGISTER_ADDRESS_MODE_OFFSET); + pRestoreDMA->GpcpBeOffset_L = SET_REGISTER_ADDR_LOW_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpBeRegs))); + pRestoreDMA->GpcpBeOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(0x0, sizeof(Gpcpbe_regs)>>2); + + bit_mask = gpc_bit_mask; + while(bit_mask) + { + unsigned int gpc_index = 0; + _BitScanForward(&gpc_index, bit_mask); + _bittestandreset((int *)&bit_mask, gpc_index); + pRestoreDMA->RestoreGpcTop[gpc_index].RestoreGpcTopCmd.uint = SET_REGISTER_ADDR_E3K(24, 0+ gpc_index *40, SET_REGISTER_ADDRESS_MODE_OFFSET); + pRestoreDMA->RestoreGpcTop[gpc_index].GpcTopOffset_L = SET_REGISTER_ADDR_LOW_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcTopRegs[gpc_index]))); + pRestoreDMA->RestoreGpcTop[gpc_index].GpcTopOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(0x0, 40); + } + + pRestoreDMA->CspFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_CSP_FENCE, _RBT_3DFE, HWM_SYNC_KMD_SLOT); + pRestoreDMA->CspFenceValue = FENCE_VALUE_BEGIN_DMA; + + pRestoreDMA->CspWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_BEGIN_DMA); + pRestoreDMA->CspWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_BEGIN_DMA); + + pRestoreDMA->EUFSL1Invalidate.uint = SEND_FS_L1I_INVALIDATE_COMMAND_E3K(); + pRestoreDMA->EUPSL1Invalidate.uint = SEND_PS_L1I_INVALIDATE_COMMAND_E3K(); + + pSaveDMA->SaveContext.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Save_Rsto; + pSaveDMA->SaveContext.Block_Id = CSP_GLOBAL_BLOCK; + pSaveDMA->SaveContext.Type = BLOCK_COMMAND_CSP_TYPE_SAVE; + pSaveDMA->SaveContext.Address_Mode = SET_REGISTER_ADDRESS_MODE_OFFSET; + pSaveDMA->SaveContext.Dwc = 2; + pSaveDMA->ContextBufferOffset_L = 0; + + pSaveDMA->ContextBufferOffset_H = 0; + + pSaveDMA->SaveCSPRegister.uint = SEND_QUERY_DUMP_E3K(CSP_GLOBAL_BLOCK, sizeof(CSP_CONTEXTBUFFER_REGS)>>2, QUERY_DUMP_ADDRESS_MODE_OFFSET); + pSaveDMA->CSPOffset_L = SEND_QUERY_ADDR1_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->CSPRegs))); + pSaveDMA->CSPOffset_H = SEND_QUERY_ADDR2_AND_OFFSET_E3K(0x0,Reg_Csp_Ms_Total_Gpu_Timestamp_Offset, TRUE, FALSE); + + pSaveDMA->SaveGpcpFeRegister.uint = SEND_QUERY_DUMP_E3K(GPCPFE_BLOCK, sizeof(GPCPFE_CONTEXTBUFFER_REGS)>>2, QUERY_DUMP_ADDRESS_MODE_OFFSET); + pSaveDMA->GpcpFeOffset_L = SEND_QUERY_ADDR1_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpFeRegs))); + pSaveDMA->GpcpFeOffset_H = SEND_QUERY_ADDR2_AND_OFFSET_E3K(0x0,Reg_Gpcpfe_Iidcnt_Offset, TRUE, FALSE); + + pSaveDMA->SaveGpcpBeRegister.uint = SEND_QUERY_DUMP_E3K(GPCPBE_BLOCK, sizeof(Gpcpbe_regs)>>2, QUERY_DUMP_ADDRESS_MODE_OFFSET); + pSaveDMA->GpcpBeOffset_L = SEND_QUERY_ADDR1_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpBeRegs))); + pSaveDMA->GpcpBeOffset_H = SEND_QUERY_ADDR2_AND_OFFSET_E3K(0x0,Reg_Sto_Cfg_Offset, TRUE, FALSE); + + bit_mask = gpc_bit_mask; + while(bit_mask) + { + DWORD gpc_index = 0; + _BitScanForward(&gpc_index, bit_mask); + _bittestandreset((int *)&bit_mask, gpc_index); + pSaveDMA->SaveGpcTop[gpc_index].SaveGpcTopRegister.uint = SEND_QUERY_DUMP_E3K(24, 40, SET_REGISTER_ADDRESS_MODE_OFFSET); + pSaveDMA->SaveGpcTop[gpc_index].GpcTopOffset_L = SEND_QUERY_ADDR1_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcTopRegs[gpc_index]))); + pSaveDMA->SaveGpcTop[gpc_index].GpcTopOffset_H = SEND_QUERY_ADDR2_AND_OFFSET_E3K(0x0, 40* gpc_index, TRUE, FALSE); + } + + pSaveDMA->CspFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_CSP_FENCE, _RBT_3DFE, HWM_SYNC_KMD_SLOT); + pSaveDMA->CspFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_END_DMA_CSPFENCE); + pSaveDMA->CspWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_END_DMA_CSPFENCE); + pSaveDMA->CspWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_END_DMA_CSPFENCE); + + pSaveDMA->GpcpBeFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_FS_STO_FENCE, _RBT_3DFE, HWM_SYNC_KMD_SLOT); + pSaveDMA->GpcpBeFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_END_DMA_STOFENCE); + pSaveDMA->GpcpBeWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_END_DMA_STOFENCE); + pSaveDMA->GpcpBeWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_END_DMA_STOFENCE); + + pCacheFlushDMA3DL->DZS_Flush.Type = BLOCK_COMMAND_TEMPLATE_TYPE_FLUSH; + pCacheFlushDMA3DL->DZS_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_ALL_C; + pCacheFlushDMA3DL->DZS_Flush.Block_Id = FF_BLOCK; + pCacheFlushDMA3DL->DZS_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + + pCacheFlushDMA3DL->DZS_Invalidate.Type = BLOCK_COMMAND_TEMPLATE_TYPE_INVALIDATE_CACHE; + pCacheFlushDMA3DL->DZS_Invalidate.Target = BLOCK_COMMAND_FLUSH_TARGET_ALL_C; + pCacheFlushDMA3DL->DZS_Invalidate.Block_Id = FF_BLOCK; + pCacheFlushDMA3DL->DZS_Invalidate.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + + pCacheFlushDMA3DL->UAVFE_Flush.uint = SEND_UCACHE_3DFE_FLUSH_COMMAND_E3K(); + pCacheFlushDMA3DL->UAVFE_Invalidate.uint = SEND_UCACHE_3DFE_INVALIDATE_COMMAND_E3K(); + pCacheFlushDMA3DL->UAVBE_Flush.uint = SEND_UCACHE_3DBE_FLUSH_COMMAND_E3K(); + pCacheFlushDMA3DL->UAVBE_Invalidate.uint = SEND_UCACHE_3DBE_INVALIDATE_COMMAND_E3K(); + + + pCacheFlushDMA3DL->L2Flush.Block_Id = L2_BLOCK; + pCacheFlushDMA3DL->L2Flush.Usage = BLOCK_COMMAND_L2_USAGE_ALL; + pCacheFlushDMA3DL->L2Flush.Type = BLOCK_COMMAND_L2_TYPE_FLUSH_L2; + pCacheFlushDMA3DL->L2Flush.Major_Opcode = CSP_OPCODE_Block_Command_L2; + pCacheFlushDMA3DL->L2Flush.Dwc = 0; + + pCacheFlushDMA3DL->L2Invalidate.Block_Id = L2_BLOCK; + pCacheFlushDMA3DL->L2Invalidate.Usage = BLOCK_COMMAND_L2_USAGE_ALL; + pCacheFlushDMA3DL->L2Invalidate.Type = BLOCK_COMMAND_L2_TYPE_INVALIDATE_L2; + pCacheFlushDMA3DL->L2Invalidate.Major_Opcode = CSP_OPCODE_Block_Command_L2; + pCacheFlushDMA3DL->L2Invalidate.Dwc = 0; + + pCacheFlushDMA3DL->TUFEL1Invalidate.uint = SEND_TUFE_L1CACHE_INVALIDATE_COMMAND_E3K(); + pCacheFlushDMA3DL->TUBEL1Invalidate.uint = SEND_TUBE_L1CACHE_INVALIDATE_COMMAND_E3K(); + + pCacheFlushDMA3DL->EUFSL1Invalidate.uint = SEND_FS_L1I_INVALIDATE_COMMAND_E3K(); + pCacheFlushDMA3DL->EUPSL1Invalidate.uint = SEND_PS_L1I_INVALIDATE_COMMAND_E3K(); + + pCacheFlushDMA3DL->PreUAVFEFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_UAVFE_FENCE, _RBT_3DFE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->PreUAVFEFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_UAVFEFENCE); + pCacheFlushDMA3DL->PreUAVFEWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_UAVFEFENCE); + pCacheFlushDMA3DL->PreUAVFEWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_UAVFEFENCE); + + pCacheFlushDMA3DL->PreUAVBEFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_UAVBE_FENCE, _RBT_3DBE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->PreUAVBEFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_UAVBEFENCE); + pCacheFlushDMA3DL->PreUAVBEWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_UAVBEFENCE); + pCacheFlushDMA3DL->PreUAVBEWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_UAVBEFENCE); + + pCacheFlushDMA3DL->PreDFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_D_FENCE, _RBT_3DBE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->PreDFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_DFENCE); + pCacheFlushDMA3DL->PreDWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_DFENCE); + pCacheFlushDMA3DL->PreDWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_DFENCE); + + + pCacheFlushDMA3DL->PreZFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_Z_FENCE, _RBT_3DBE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->PreZFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_ZFENCE); + pCacheFlushDMA3DL->PreZWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_ZFENCE); + pCacheFlushDMA3DL->PreZWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_ZFENCE); + + //post is totally same as pre ones. + pCacheFlushDMA3DL->PostUAVFEFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_UAVFE_FENCE,_RBT_3DFE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->PostUAVFEFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_UAVFEFENCE); + pCacheFlushDMA3DL->PostUAVFEWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_UAVFEFENCE); + pCacheFlushDMA3DL->PostUAVFEWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_UAVFEFENCE); + + pCacheFlushDMA3DL->PostUAVBEFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_UAVBE_FENCE,_RBT_3DBE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->PostUAVBEFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_UAVBEFENCE); + pCacheFlushDMA3DL->PostUAVBEWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_UAVBEFENCE); + pCacheFlushDMA3DL->PostUAVBEWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_UAVBEFENCE); + + pCacheFlushDMA3DL->PostDFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_D_FENCE,_RBT_3DBE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->PostDFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_DFENCE); + pCacheFlushDMA3DL->PostDWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_DFENCE); + pCacheFlushDMA3DL->PostDWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_DFENCE); + + pCacheFlushDMA3DL->PostZFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_Z_FENCE,_RBT_3DBE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->PostZFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_ZFENCE); + pCacheFlushDMA3DL->PostZWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_ZFENCE); + pCacheFlushDMA3DL->PostZWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_ZFENCE); + + //sto + pCacheFlushDMA3DL->StoFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_FS_STO_FENCE, _RBT_3DFE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->StoFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_STOFENCE); + pCacheFlushDMA3DL->StoWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_STOFENCE); + pCacheFlushDMA3DL->StoWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_STOFENCE); + + pCacheFlushDMA3DL->L2FenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_L2_FENCE,_RBT_3DBE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->L2FenceValue = FENCE_VALUE_CACHE_DMA_L2C_FENCE; + + pCacheFlushDMA3DL->L2WaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_L2C_FENCE); + pCacheFlushDMA3DL->L2WaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_L2C_FENCE); + + + /*we need first flush the cache, ensure last write will flush out to memory*/ + pCacheFlushDMA3DL->PreCspFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_CSP_FENCE, _RBT_3DFE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->PreCspFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_PRECSPFENCE); + pCacheFlushDMA3DL->PreCspWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_PRECSPFENCE); + pCacheFlushDMA3DL->PreCspWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_PRECSPFENCE); + + regValue = SEND_FLAGBUFFER_FLUSH_COMMAND_E3K(); + pCacheFlushDMA3DL->BLC_Flush = *(Cmd_Block_Command_Mxu*)®Value; + pCacheFlushDMA3DL->FlushAddr_L = 0; + pCacheFlushDMA3DL->FlushAddr_H = 0; + pCacheFlushDMA3DL->FlushMask_L = 0; + pCacheFlushDMA3DL->FlushMask_H = 0; + + pCacheFlushDMA3DL->PostCspFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_CSP_FENCE,_RBT_3DFE, HWM_SYNC_KMD_SLOT); + pCacheFlushDMA3DL->PostCspFenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_POSTCSPFENCE); + pCacheFlushDMA3DL->PostCspWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_POSTCSPFENCE); + pCacheFlushDMA3DL->PostCspWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_POSTCSPFENCE); + + + pRestoreShadowDMA = &(pCmdBuf->RestoreShadowDMA); + + pRestoreShadowDMA->RestoreContext.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Save_Rsto; + pRestoreShadowDMA->RestoreContext.Block_Id = CSP_GLOBAL_BLOCK; + pRestoreShadowDMA->RestoreContext.Type = BLOCK_COMMAND_CSP_TYPE_RESTORE; + pRestoreShadowDMA->RestoreContext.Address_Mode = SET_REGISTER_ADDRESS_MODE_OFFSET; + pRestoreShadowDMA->RestoreContext.Dwc = 2; + pRestoreShadowDMA->ContextBufferOffset_L = 0; + pRestoreShadowDMA->ContextBufferOffset_H = 0; + + pRestoreShadowDMA->RestoreEuFullGlb.uint = SET_REGISTER_ADDR_E3K(EU_FS_BLOCK, Reg_Eu_Full_Glb_Offset, SET_REGISTER_ADDRESS_MODE_OFFSET); + pRestoreShadowDMA->EuFullGlbOffset_L = SET_REGISTER_ADDR_LOW_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->HWContextbuffer.shadow_buf_3D.fe_be_regs.eufs_regs.reg_Eu_Full_Glb))); + pRestoreShadowDMA->EuFullGlbOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(0x0, 1); + + pRestoreShadowDMA->RestoreTsSharpCtrl.uint = SET_REGISTER_ADDR_E3K(TUFE_BLOCK, Reg_Tu_Tssharp_Ctrl_Offset, SET_REGISTER_ADDRESS_MODE_OFFSET); + pRestoreShadowDMA->TsSharpCtrlOffset_L = SET_REGISTER_ADDR_LOW_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->HWContextbuffer.shadow_buf_3D.fe_be_regs.tu_regs.reg_Tu_Tssharp_Ctrl))); + pRestoreShadowDMA->TsSharpCtrlOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(0x0, 1); + + pRestoreShadowDMA->RestoreFFCUbufConfig.uint = SET_REGISTER_ADDR_E3K(WLS_FE_BLOCK, Reg_Ffc_Ubuf_Golbalconfig_Offset, SET_REGISTER_ADDRESS_MODE_OFFSET); + pRestoreShadowDMA->FFCUbufConfigOffset_L = SET_REGISTER_ADDR_LOW_E3K((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->HWContextbuffer.shadow_buf_3D.fe_be_regs.wls_regs.reg_Ffc_Ubuf_Golbalconfig))); + pRestoreShadowDMA->FFCUbufConfigOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(0x0, 1); + + pRestoreShadowDMA->CspFenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_CSP_FENCE, _RBT_3DFE, HWM_SYNC_KMD_SLOT); + pRestoreShadowDMA->CspFenceValue = FENCE_VALUE_BEGIN_DMA; + + pRestoreShadowDMA->CspWaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_BEGIN_DMA); + pRestoreShadowDMA->CspWaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_BEGIN_DMA); + + pRestoreShadowDMA->EUFSL1Invalidate.uint = SEND_FS_L1I_INVALIDATE_COMMAND_E3K(); + pRestoreShadowDMA->EUPSL1Invalidate.uint = SEND_PS_L1I_INVALIDATE_COMMAND_E3K(); + + + share->begin_end_vma = vma; + +} + +void enginei_init_ring_buffer_commands_e3k(engine_gfx_e3k_t *engine) +{ + engine_share_e3k_t *share = engine->common.share; + RB_PREDEFINE_DMA *pCmdBuf = share->begin_end_vma->virt_addr; + large_inter dwSaveRestoreGPUBaseAddr; + Cmd_Dma_Address_Dword2 cmd_dma_address_dword2 = {0}; + RINGBUFFER_COMMANDS_E3K* pRingBufferCommands = (RINGBUFFER_COMMANDS_E3K*)share->RingBufferCommands; + RINGBUFFER_COMMANDS_E3K* p0 = &pRingBufferCommands[SUBMIT_CMD_HWCONTEX_SWITCH]; + RINGBUFFER_COMMANDS_E3K* p1 = &pRingBufferCommands[SUBMIT_CMD_NO_HWCONTEXT_SWITCH]; + RINGBUFFER_COMMANDS_E3K* p2 = &pRingBufferCommands[SUBMIT_CMD_FENCE_ONLY]; + SLICESWITCH_INIT_COMMANDS_E3K* s0 = &share->SliceSwitchInitCommands[SUBMIT_CMD_HWCONTEX_SWITCH]; + SLICESWITCH_INIT_COMMANDS_E3K* s1 = &share->SliceSwitchInitCommands[SUBMIT_CMD_NO_HWCONTEXT_SWITCH]; + int i = 0; + large_inter TempAddr; + + dwSaveRestoreGPUBaseAddr.quad64 = share->begin_end_buffer_phy_addr; + + + gf_memset( p0, 0, sizeof(*p0) ); + gf_memset( p1, 0, sizeof(*p1) ); + gf_memset( p2, 0, sizeof(*p2) ); + + //case 0 + p0->c0.pwmTrigger.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Indicator; + p0->c0.pwmTrigger.Block_Id = CSP_GLOBAL_BLOCK; + p0->c0.pwmTrigger.Type = BLOCK_COMMAND_CSP_TYPE_INDICATOR; + p0->c0.pwmTrigger.Info = BLK_CMD_CSP_INDICATOR_INFO_3D_MODE; + p0->c0.pwmTrigger.Dwc = 1; + + p0->c0.RestoreDMA.Major_Opcode = CSP_OPCODE_Dma; + p0->c0.RestoreDMA.Special_Dma_Type = DMA_SPECIAL_DMA_TYPE_SAVE_REST_CMD; + p0->c0.RestoreDMA.Mode = DMA_MODE_RESTORE; + p0->c0.RestoreDMA.Dw_Num = sizeof(CONTEXT_RESTORE_DMA_E3K) >> 2; + p0->c0.RestoreDMA.Reset_Dma = 1; + + TempAddr.quad64 = dwSaveRestoreGPUBaseAddr.quad64 + ((BYTE*)&(pCmdBuf->RestoreDMA) - (BYTE*)pCmdBuf); + p0->c0.RestoreDMA_Address_L = TempAddr.low32; + + cmd_dma_address_dword2.Address_High8 = TempAddr.high32 & 0xFF; + cmd_dma_address_dword2.L2_Cachable = 1; + + p0->c0.RestoreDMA_Address_H = *(DWORD*)&cmd_dma_address_dword2; +#if NEW_DUMP + p0->c0.HangDumpContextSaveDMA.Major_Opcode = CSP_OPCODE_Dma; + p0->c0.HangDumpContextSaveDMA.Dw_Num = sizeof(CONTEXT_SAVE_DMA_E3K) >> 2; + p0->c0.HangDumpContextSaveDMA.Mode = DMA_MODE_SAVE; + p0->c0.HangDumpContextSaveDMA.Special_Dma_Type = DMA_SPECIAL_DMA_TYPE_SAVE_REST_CMD; + p0->c0.HangDumpContextSaveDMA.Reset_Dma = 1; + + TempAddr.quad64 = dwSaveRestoreGPUBaseAddr.quad64 + ((BYTE*)&(pCmdBuf->SaveDMA) - (BYTE*)pCmdBuf); + cmd_dma_address_dword2.Address_High8 = TempAddr.high32 & 0xFF; + cmd_dma_address_dword2.L2_Cachable = 1; + p0->c0.HangDumpContextSaveDMA_Address_L = TempAddr.low32; + p0->c0.HangDumpContextSaveDMA_Address_H = *(DWORD*)&cmd_dma_address_dword2; +#endif + p0->c0.CommandDMA.Major_Opcode = CSP_OPCODE_Dma; + p0->c0.CommandDMA.Mode = DMA_MODE_NORMAL; + p0->c0.CacheFlushDMA.Major_Opcode = CSP_OPCODE_Dma; + p0->c0.CacheFlushDMA.Dw_Num = sizeof(CACHEFLUSH_DMA_E3K) >> 2; + p0->c0.CacheFlushDMA.Mode = DMA_MODE_FLUSH; + p0->c0.CacheFlushDMA.Reset_Dma = 1; + + TempAddr.quad64 = dwSaveRestoreGPUBaseAddr.quad64 + ((BYTE*)(&(pCmdBuf->FlushDMA3DL)) - (BYTE*)pCmdBuf); + p0->c0.CacheFlushDMA_Address_L = TempAddr.low32 ; + p0->c0.CacheFlushDMA_Address_H = TempAddr.high32 & 0xFF; + + p0->c0.SaveDMA.Major_Opcode = CSP_OPCODE_Dma; + p0->c0.SaveDMA.Dw_Num = sizeof(CONTEXT_SAVE_DMA_E3K) >> 2; + p0->c0.SaveDMA.Mode = DMA_MODE_SAVE; + p0->c0.SaveDMA.Special_Dma_Type = DMA_SPECIAL_DMA_TYPE_SAVE_REST_CMD; + p0->c0.SaveDMA.Reset_Dma = 1; + + TempAddr.quad64 = dwSaveRestoreGPUBaseAddr.quad64 + ((BYTE*)&(pCmdBuf->SaveDMA) - (BYTE*)pCmdBuf); + + cmd_dma_address_dword2.Address_High8 = TempAddr.high32 & 0xFF; + cmd_dma_address_dword2.L2_Cachable = 1; + + p0->c0.SaveDMA_Address_L = TempAddr.low32; + p0->c0.SaveDMA_Address_H = *(DWORD*)&cmd_dma_address_dword2; + + for(i = 0;ic0.Skip_1)/sizeof(DWORD);i++) + { + p0->c0.Skip_1[i] = SEND_SKIP_E3K(1); + } + + for(i = 0;ic0.SliceSwitchInitCommands)/sizeof(DWORD);i++) + { + p0->c0.SliceSwitchInitCommands[i] = SEND_SKIP_E3K(1); + } + + *(DWORD*)(&p0->c0.Fence) = SEND_EXTERNAL_FENCE_E3K(FENCE_IRQ_INTERRUPT_CPU); + *(DWORD*)(&p0->c0.Fence_1) = SEND_EXTERNAL_FENCE_E3K(FENCE_IRQ_INTERRUPT_CPU); + *(DWORD*)(&p0->c0.Fence_2) = SEND_EXTERNAL_FENCE_E3K(FENCE_IRQ_NOP); + *(DWORD*)(&p0->c0.Fence_3) = SEND_EXTERNAL_FENCE_E3K(FENCE_IRQ_NOP); + *(DWORD*)(&p0->c0.Fence_4) = SEND_EXTERNAL_FENCE_E3K(FENCE_IRQ_NOP); + *(DWORD*)(&p0->c0.Fence_5) = SEND_EXTERNAL_FENCE_E3K(FENCE_IRQ_NOP); + + p0->c0.pwmTriggerOff.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Indicator; + p0->c0.pwmTriggerOff.Block_Id = CSP_GLOBAL_BLOCK; + p0->c0.pwmTriggerOff.Type = BLOCK_COMMAND_CSP_TYPE_INDICATOR; + p0->c0.pwmTriggerOff.Info = BLK_CMD_CSP_INDICATOR_INFO_OFF_MODE; + p0->c0.pwmTriggerOff.Dwc = 1; + + for (i = 0; i < sizeof(p0->c0.Skip_2) / sizeof(DWORD); i++) + { + p0->c0.Skip_2[i] = SEND_SKIP_E3K(1); + } + + //util_dump_memory(p0,sizeof(RINGBUFFER_COMMANDS_E3K),"ring buffer template"); + //case 1 + p1->c1.pwmTrigger = p0->c0.pwmTrigger; + p1->c1.Fence = p0->c0.Fence; + p1->c1.Fence_1 = p0->c0.Fence_1; + p1->c1.Fence_2 = p0->c0.Fence_2; + p1->c1.Fence_3 = p0->c0.Fence_3; + p1->c1.Fence_4 = p0->c0.Fence_4; + p1->c1.Fence_5 = p0->c0.Fence_5; + + for(i = 0;ic1.Skip_1)/sizeof(DWORD);i++) + { + p1->c1.Skip_1[i] = SEND_SKIP_E3K(1); + } + + for(i = 0;ic1.SliceSwitchInitCommands)/sizeof(DWORD);i++) + { + p1->c1.SliceSwitchInitCommands[i] = SEND_SKIP_E3K(1); + } + + p1->c1.CommandDMA = p0->c0.CommandDMA; + + p1->c1.CacheFlushDMA = p0->c0.CacheFlushDMA; + p1->c1.CacheFlushDMA_Address_L = p0->c0.CacheFlushDMA_Address_L; + p1->c1.CacheFlushDMA_Address_H = p0->c0.CacheFlushDMA_Address_H; + + p1->c1.Skip_2.Major_Opcode = CSP_OPCODE_Skip; + p1->c1.Skip_2.Dwc = sizeof(p1->c1.Dummy_2)/sizeof(DWORD); + + p1->c1.pwmTriggerOff = p0->c0.pwmTriggerOff; + + for (i = 0; i < sizeof(p1->c1.Skip_3) / sizeof(DWORD); i++) + { + p1->c1.Skip_3[i] = SEND_SKIP_E3K(1); + } + + //case 2 + p2->c2.pwmTrigger = p1->c1.pwmTrigger; + + for(i = 0;ic2.Skip_1)/sizeof(DWORD);i++) + { + p2->c2.Skip_1[i] = SEND_SKIP_E3K(1); + } + + p2->c2.Fence = p1->c1.Fence; + p2->c2.Fence_1 = p1->c1.Fence_1; + p2->c2.Fence_2 = p1->c1.Fence_2; + p2->c2.Fence_3 = p1->c1.Fence_3; + p2->c2.Fence_4 = p1->c1.Fence_4; + p2->c2.Fence_5 = p1->c1.Fence_5; + + p2->c2.pwmTriggerOff = p1->c1.pwmTriggerOff; + + for (i = 0; i < sizeof(p2->c2.Skip_2) / sizeof(DWORD); i++) + { + p2->c2.Skip_2[i] = SEND_SKIP_E3K(1); + } + + s0->c0.RestoreShadowDMA.Major_Opcode = CSP_OPCODE_Dma; + s0->c0.RestoreShadowDMA.Special_Dma_Type = DMA_SPECIAL_DMA_TYPE_SAVE_REST_CMD; + s0->c0.RestoreShadowDMA.Mode = DMA_MODE_RESTORE; + s0->c0.RestoreShadowDMA.Dw_Num = sizeof(CONTEXT_RESTORE_DMA_E3K) >> 2; + s0->c0.RestoreShadowDMA.Reset_Dma = 1; + TempAddr.quad64 = dwSaveRestoreGPUBaseAddr.quad64 + ((BYTE*)&(pCmdBuf->RestoreShadowDMA) - (BYTE*)pCmdBuf); + s0->c0.RestoreShadowDMA_Address_L = TempAddr.low32; + cmd_dma_address_dword2.Address_High8 = TempAddr.high32 & 0xFF; + cmd_dma_address_dword2.L2_Cachable = 1; + s0->c0.RestoreShadowDMA_Address_H = *(DWORD*)&cmd_dma_address_dword2; + s0->c0.RestoreShadowContext_Address = engine->shadow_context_buf_phy_addr >> 11; + + s1->c1.SaveDMA = p0->c0.SaveDMA; + s1->c1.SaveDMA_Address_L = p0->c0.SaveDMA_Address_L; + s1->c1.SaveDMA_Address_H = p0->c0.SaveDMA_Address_H; + s1->c1.SaveContext_Address = engine->temp_context_buf_phy_addr >> 11; + s1->c1.RestoreShadowDMA = s0->c0.RestoreShadowDMA; + s1->c1.RestoreShadowDMA_Address_L = s0->c0.RestoreShadowDMA_Address_L; + s1->c1.RestoreShadowDMA_Address_H = s0->c0.RestoreShadowDMA_Address_H; + s1->c1.RestoreShadowContext_Address = s0->c0.RestoreShadowContext_Address; + s1->c1.RestoreDMA = p0->c0.RestoreDMA; + s1->c1.RestoreDMA_Address_L = p0->c0.RestoreDMA_Address_L; + s1->c1.RestoreDMA_Address_H = p0->c0.RestoreDMA_Address_H; + s1->c1.RestoreContext_Address = engine->temp_context_buf_phy_addr >> 11; +} + + + diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_blt_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_blt_e3k.c new file mode 100644 index 0000000000000..7f38a7fdacb4f --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_blt_e3k.c @@ -0,0 +1,107 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_blt_e3k.h" +#include "vidsch_engine_e3k.h" + +static void vidschi_init_2dblt_cmd_e3k(engine_share_e3k_t *share) +{ + BITBLT_REGSETTING_E3K *pKmdBitBltCmd = &share->_2dblt_cmd_e3k; + FASTCLEAR_REGSETTING_E3K *pKmdFastClearCmd = &share->fast_clear_cmd_e3k; + + int RtIdx; + + gf_memset(pKmdBitBltCmd, 0, sizeof(BITBLT_REGSETTING_E3K)); + gf_memset(pKmdFastClearCmd, 0, sizeof(FASTCLEAR_REGSETTING_E3K)); + + //Init BitBlt structure + pKmdBitBltCmd->SetDstRTAddrCtrl = SET_REGISTER_FD_E3K(FF_BLOCK, + REG_OFFSET_OF_GROUP(Reg_Rt_Addr_Ctrl_Offset, Reg_Rt_Addr_Ctrl_Group, reg_Rt_Addr, FF_RT_DST), + sizeof(Reg_Rt_Addr_Ctrl_Group)>> 2); + + pKmdBitBltCmd->SetDstRTCtrl = SET_REGISTER_FD_E3K(FF_BLOCK, + REG_OFFSET_OF_GROUP(Reg_Rt_Ctrl_Offset, Reg_Rt_Ctrl_Group, reg_Rt_Fmt, FF_RT_DST), + sizeof(Reg_Rt_Ctrl_Group)>>2); + + pKmdBitBltCmd->SetSrcRTAddrCtrl = SET_REGISTER_FD_E3K(FF_BLOCK, + REG_OFFSET_OF_GROUP(Reg_Rt_Addr_Ctrl_Offset, Reg_Rt_Addr_Ctrl_Group, reg_Rt_Addr, FF_RT_SRC), + sizeof(Reg_Rt_Addr_Ctrl_Group)>> 2); + + pKmdBitBltCmd->SetSrcRTCtrl = SET_REGISTER_FD_E3K(FF_BLOCK, + REG_OFFSET_OF_GROUP(Reg_Rt_Ctrl_Offset, Reg_Rt_Ctrl_Group, reg_Rt_Fmt, FF_RT_SRC), + sizeof(Reg_Rt_Ctrl_Group)>>2); + + pKmdBitBltCmd->Set_Rast_Ctrl = SET_REGISTER_FD_E3K(FF_BLOCK, Reg_Rast_Ctrl_Offset, 1); + pKmdBitBltCmd->Set_Iu_Ctrl_Ex = SET_REGISTER_FD_E3K(IU_BLOCK, Reg_Iu_Ctrl_Ex_Offset, 1); + pKmdBitBltCmd->Set_Tasfe_Ctrl = SET_REGISTER_FD_E3K(TASFE_BLOCK, Reg_Tasfe_Ctrl_Offset, 1); + pKmdBitBltCmd->Set_Resolution_Ctrl = SET_REGISTER_FD_E3K(FF_BLOCK, Reg_Resolution_Ctrl_Offset, 1); + pKmdBitBltCmd->Set_Dzs_Ctrl = SET_REGISTER_FD_E3K(FF_BLOCK, Reg_Dzs_Ctrl_Offset, 1); + pKmdBitBltCmd->Set_Zs_Req_Ctrl = SET_REGISTER_FD_E3K(FF_BLOCK, Reg_Zs_Req_Ctrl_Offset, 1); + pKmdBitBltCmd->Set_Blend_Ctrl = SET_REGISTER_FD_E3K(FF_BLOCK, Reg_Blend_Ctl_Offset, sizeof(Reg_Blend_Ctl_Group) >>2); + + + pKmdBitBltCmd->BitBltCmd.Major_Opcode = CSP_OPCODE_Block_Command_Sg; + pKmdBitBltCmd->BitBltCmd.Block_Id = FF_BLOCK; + pKmdBitBltCmd->BitBltCmd.Predicate_En = 0; + pKmdBitBltCmd->BitBltCmd.Action_Type = BLOCK_COMMAND_SG_ACTION_TYPE_BIT_BLT; + pKmdBitBltCmd->BitBltCmd.Area_Target = BLOCK_COMMAND_SG_AREA_TARGET_D; + pKmdBitBltCmd->BitBltCmd.Type = BLOCK_COMMAND_TEMPLATE_TYPE_SG; + pKmdBitBltCmd->BitBltCmd.Dwc = 3; + + pKmdBitBltCmd->D_Flush.Type = BLOCK_COMMAND_TEMPLATE_TYPE_FLUSH; + pKmdBitBltCmd->D_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_D_C; + pKmdBitBltCmd->D_Flush.Block_Id = FF_BLOCK; + pKmdBitBltCmd->D_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + + pKmdBitBltCmd->D_Invalidate.Type = BLOCK_COMMAND_TEMPLATE_TYPE_INVALIDATE_CACHE; + pKmdBitBltCmd->D_Invalidate.Target = BLOCK_COMMAND_FLUSH_TARGET_D_C; + pKmdBitBltCmd->D_Invalidate.Block_Id = FF_BLOCK; + pKmdBitBltCmd->D_Invalidate.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + + //perhaps fastclear cmd initialize should not put in this func.... + //Init fastclear cmd + pKmdFastClearCmd->SetDstRTAddrCtrl = pKmdBitBltCmd->SetDstRTAddrCtrl; + pKmdFastClearCmd->SetDstRTCtrl = pKmdBitBltCmd->SetDstRTCtrl; + + pKmdFastClearCmd->Set_Rast_Ctrl = pKmdBitBltCmd->Set_Rast_Ctrl; + pKmdFastClearCmd->Set_Iu_Ctrl_Ex = pKmdBitBltCmd->Set_Iu_Ctrl_Ex; + pKmdFastClearCmd->Set_Tasfe_Ctrl = pKmdBitBltCmd->Set_Tasfe_Ctrl; + pKmdFastClearCmd->Set_Resolution_Ctrl = pKmdBitBltCmd->Set_Resolution_Ctrl; + pKmdFastClearCmd->Set_Dzs_Ctrl = pKmdBitBltCmd->Set_Dzs_Ctrl; + pKmdFastClearCmd->Set_Zs_Req_Ctrl = SET_REGISTER_FD_E3K(FF_BLOCK, Reg_Zs_Req_Ctrl_Offset, 1); + + //disable RT1~7 + for(RtIdx = 1; RtIdx < 8; RtIdx++) + { + pKmdFastClearCmd->SetOtherRTDisable[(RtIdx-1) * 2] = SET_REGISTER_FD_E3K(FF_BLOCK, + REG_OFFSET_OF_GROUP(Reg_Rt_Ctrl_Offset, Reg_Rt_Ctrl_Group, reg_Rt_Misc, RtIdx), + 1); + } + + pKmdFastClearCmd->Set_Fast_Clear_Color = SET_REGISTER_FD_E3K(FF_BLOCK, Reg_Fast_Clear_Color_Offset, 4); + + *(DWORD*)&pKmdFastClearCmd->FastClearCmd = *(DWORD*)&pKmdBitBltCmd->BitBltCmd; + pKmdFastClearCmd->FastClearCmd.Action_Type = BLOCK_COMMAND_SG_ACTION_TYPE_FAST_CLEAR_LINEAR; + pKmdFastClearCmd->FastClearCmd.Dwc = 2; + +} + +void vidschi_init_blt_cmd_e3k(engine_share_e3k_t *share) +{ + vidschi_init_2dblt_cmd_e3k(share); +} + diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_blt_e3k.h b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_blt_e3k.h new file mode 100644 index 0000000000000..22d2a3fe14e9c --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_blt_e3k.h @@ -0,0 +1,158 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __VIDSCH_3DBLT_E3K_H +#define __VIDSCH_3DBLT_E3K_H + +#include "vidmm.h" +#include "context.h" +#include "chip_include_e3k.h" +#include "util.h" + +typedef struct _BITBLT_REGSETTING_E3K +{ + DWORD SetDstRTAddrCtrl; // set Dst RT Addr Ctrl Register 3 DWORD + Reg_Rt_Addr DstAddr; + Reg_Rt_Depth DstDepth; + Reg_Rt_View_Ctrl DstViewCtrl; + DWORD SetDstRTCtrl; // set Dst RT Ctrl Register 3 DWORD + Reg_Rt_Fmt DstFormat; + Reg_Rt_Size DstSize; + Reg_Rt_Misc DstMisc; // might need disable D_Read_En, disable alphablend, need to disable Rop + + DWORD SetSrcRTAddrCtrl; // set Dst RT Addr Ctrl Register 3 DWORD + Reg_Rt_Addr SrcAddr; + Reg_Rt_Depth SrcDepth; + Reg_Rt_View_Ctrl SrcViewCtrl; + DWORD SetSrcRTCtrl; // set Dst RT Ctrl Register 3 DWORD + Reg_Rt_Fmt SrcFormat; + Reg_Rt_Size SrcSize; + Reg_Rt_Misc SrcMisc; + + DWORD Set_Rast_Ctrl; + Reg_Rast_Ctrl Rast_Ctrl; + + DWORD Set_Iu_Ctrl_Ex; + Reg_Iu_Ctrl_Ex reg_Iu_Ctrl_Ex; + + DWORD Set_Tasfe_Ctrl; + Reg_Tasfe_Ctrl reg_Tasfe_Ctrl; + + DWORD Set_Resolution_Ctrl; + Reg_Resolution_Ctrl reg_Resolution_Ctrl; + + DWORD Set_Dzs_Ctrl; + Reg_Dzs_Ctrl Dzs_Ctrl; + + DWORD Set_Zs_Req_Ctrl; + Reg_Zs_Req_Ctrl Zs_Req_Ctrl; + + DWORD Set_Blend_Ctrl; + Reg_Blend_Ctl_Group reg_Blend_Ctl; + + Cmd_Block_Command_Sg BitBltCmd; + Cmd_Block_Command_Sg_Dword0 RectX; + Cmd_Block_Command_Sg_Dword1 RectY; + Cmd_Block_Command_Sg_Blt_Dword2 SrcDxDy; + + Cmd_Block_Command_Flush D_Flush; + Cmd_Block_Command_Flush D_Invalidate; + + Csp_Opcodes_cmd FenceCmd; + DWORD FenceValue; + Csp_Opcodes_cmd WaitCmd; + Csp_Opcodes_cmd WaitMainCmd; +} BITBLT_REGSETTING_E3K; + +typedef struct _IMMBLT_REGSETTING_E3K +{ + DWORD SetDstRTAddrCtrl; // set Dst RT Addr Ctrl Register 3 DWORD + Reg_Rt_Addr DstAddr; + Reg_Rt_Depth DstDepth; + Reg_Rt_View_Ctrl DstViewCtrl; + DWORD SetDstRTCtrl; // set Dst RT Ctrl Register 3 DWORD + Reg_Rt_Fmt DstFormat; + Reg_Rt_Size DstSize; + Reg_Rt_Misc DstMisc; // might need disable D_Read_En, disable alphablend, need to disable Rop + + DWORD Set_Zs_Req_Ctrl; + Reg_Zs_Req_Ctrl Zs_Req_Ctrl; // might need disable Zl2_End_Pipe_En + + DWORD Set_Rast_Ctrl; + Reg_Rast_Ctrl Rast_Ctrl; + + DWORD Set_Tasfe_Ctrl; + Reg_Tasfe_Ctrl reg_Tasfe_Ctrl; + + DWORD Set_Resolution_Ctrl; + Reg_Resolution_Ctrl reg_Resolution_Ctrl; + + DWORD Set_Dzs_Ctrl; + Reg_Dzs_Ctrl Dzs_Ctrl; + + DWORD Set_Ff_Glb_Ctrl; + Reg_Ff_Glb_Ctrl Ff_Glb_Ctrl; + + Cmd_Block_Command_Img_Trn IMMBltCmd; + Cmd_Block_Command_Img_Trn_Dword0 RectX; + Cmd_Block_Command_Img_Trn_Dword1 RectY; +} IMMBLT_REGSETTING_E3K; + +typedef struct _FASTCLEAR_REGSETTING_E3K +{ + DWORD SetDstRTAddrCtrl; // set Dst RT Addr Ctrl Register 3 DWORD + Reg_Rt_Addr DstAddr; + Reg_Rt_Depth DstDepth; + Reg_Rt_View_Ctrl DstViewCtrl; + DWORD SetDstRTCtrl; // set Dst RT Ctrl Register 3 DWORD + Reg_Rt_Fmt DstFormat; + Reg_Rt_Size DstSize; + Reg_Rt_Misc DstMisc; // might need disable D_Read_En, disable alphablend, need to disable Rop + + DWORD SetOtherRTDisable[14]; + + DWORD Set_Zs_Req_Ctrl; + Reg_Zs_Req_Ctrl Zs_Req_Ctrl; // might need disable Zl2_End_Pipe_En + + DWORD Set_Rast_Ctrl; + Reg_Rast_Ctrl Rast_Ctrl; + + DWORD Set_Iu_Ctrl_Ex; + Reg_Iu_Ctrl_Ex reg_Iu_Ctrl_Ex; + + DWORD Set_Tasfe_Ctrl; + Reg_Tasfe_Ctrl reg_Tasfe_Ctrl; + + DWORD Set_Resolution_Ctrl; + Reg_Resolution_Ctrl reg_Resolution_Ctrl; + + DWORD Set_Dzs_Ctrl; + Reg_Dzs_Ctrl Dzs_Ctrl; + + DWORD Set_Ff_Glb_Ctrl; + Reg_Ff_Glb_Ctrl Ff_Glb_Ctrl; + + DWORD Set_Fast_Clear_Color; + Reg_Fast_Clear_Color Fast_Clear_Color0; + Reg_Fast_Clear_Color Fast_Clear_Color1; + Reg_Fast_Clear_Color Fast_Clear_Color2; + Reg_Fast_Clear_Color Fast_Clear_Color3; + + Cmd_Block_Command_Sg FastClearCmd; + Cmd_Block_Command_Sg_Dword0 RectX; + Cmd_Block_Command_Sg_Dword1 RectY; +} FASTCLEAR_REGSETTING_E3K; + +#endif + diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_compatible_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_compatible_e3k.c new file mode 100644 index 0000000000000..3ec82f162502d --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_compatible_e3k.c @@ -0,0 +1,1004 @@ +#include "gf_adapter.h" +#include "vidmm.h" +#include "vidsch.h" +#include "vidschi.h" +#include "chip_include_e3k.h" +#include "vidsch_debug_hang_e3k.h" +#include "vidsch_engine_e3k.h" +#include "mm_e3k.h" +#include "context.h" +#include "global.h" + +typedef enum dump_data_type{ + HANG_DUMP_NONE, + HANG_DUMP_CONTEXT_BUFFER, + HANG_DUMP_DMA_BUFFER, + HANG_DUMP_RING_BUFFER, + HANG_DUMP_COMMON_INFO, + + HANG_DUMP_GART_TABLE_L2, + HANG_DUMP_GART_TABLE_L3, + HANG_DUMP_KICKOFF_RING_BUFFER, + HANG_DUMP_FENCE_BUFFER, + HANG_DUMP_FLUSH_FIFO_BUFFER, + HANG_DUMP_BL_BUFFER, + HANG_DUMP_CPU_UNVISIBLE_MEMORY +} dump_data_type; + +#if 0 +static void _get_engine_status(adapter_t *adapter) +{ + EngineSatus_e3k status = {0}; + unsigned int *p = (unsigned int *)&status; + int i = 0; + + for(i=0; i<7; i++) + { + *(p + i) = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + (Reg_Block_Busy_Bits_Top_Offset + i)*4); + } + + gf_info("[Duplicate] engine 0x%x, Duplicated Hang Status:Top=%x,Gpc0_0=%x,Gpc0_1=%x,Gpc1_0=%x, Gpc1_1=%x,Gpc2_0=%x,Gpc2_1=%x\n", + 0, + status.Top.uint, + status.Gpc0_0.uint, + status.Gpc0_1.uint, + status.Gpc1_0.uint, + status.Gpc1_1.uint, + status.Gpc2_0.uint, + status.Gpc2_1.uint); +} +#endif + +static void _set_fence_id(dup_hang_ctx_t *dup_hang_ctx, unsigned long long fence_id) +{ + submit_info_t *submit_info = &(dup_hang_ctx->submit_info); + void *fence_cpu_va = submit_info->fence_buffer_cpu_va; + + *(unsigned int *)fence_cpu_va = fence_id & 0xffffffff; + *(((unsigned int *)fence_cpu_va) + 1) = (fence_id >> 32) & 0xffffffff; + +} + +static unsigned long long _get_fence_id(dup_hang_ctx_t *dup_hang_ctx) +{ + submit_info_t *submit_info = &(dup_hang_ctx->submit_info); + void *fence_cpu_va = submit_info->fence_buffer_cpu_va; + unsigned long long fence_id = 0; + + fence_id = *(unsigned long long *)fence_cpu_va; + + return fence_id; +} + +static unsigned long long _get_dump_data_gpu_va(dup_hang_ctx_t *dup_hang_ctx, int type, int index) +{ + unsigned long long offset = 0; + + switch(type) + { + case HANG_DUMP_CONTEXT_BUFFER: + offset = dup_hang_ctx->context_buffer_offset + index * dup_hang_ctx->single_context_buffer_size_in_byte; + break; + + case HANG_DUMP_DMA_BUFFER: + offset = dup_hang_ctx->dma_buffer_offset + index * dup_hang_ctx->single_dma_size_in_byte; + break; + + case HANG_DUMP_RING_BUFFER: + offset = dup_hang_ctx->ring_buffer_offset + index * dup_hang_ctx->single_ring_buffer_size_in_byte; + break; + + case HANG_DUMP_COMMON_INFO: + offset = dup_hang_ctx->ring_buffer_offset + MAX_HANG_DUMP_DATA_POOL_NUMBER * dup_hang_ctx->single_ring_buffer_size_in_byte; + break; + + case HANG_DUMP_GART_TABLE_L2: + offset = dup_hang_ctx->gart_table_l2_offset; + break; + + case HANG_DUMP_GART_TABLE_L3: + offset = dup_hang_ctx->gart_table_l3_offset; + break; + + case HANG_DUMP_FENCE_BUFFER: + { + dh_common_info_e3k dummy_common_info = {0}; + unsigned long long common_info_offset = 0; + unsigned long long fence_buffer_offset = 0; + + common_info_offset = _get_dump_data_gpu_va(dup_hang_ctx, HANG_DUMP_COMMON_INFO, index); + + fence_buffer_offset = common_info_offset + OFFSETOF(dh_common_info_e3k, fence_buffer)/sizeof(DWORD); + + offset = fence_buffer_offset; + } + break; + + case HANG_DUMP_KICKOFF_RING_BUFFER: + { + dh_common_info_e3k dummy_common_info = {0}; + unsigned long long common_info_offset = 0; + unsigned long long kick_off_ring_buffer_offset = 0; + unsigned long long kick_off_ring_buffer_offset_4k_aligned = 0; + + common_info_offset = _get_dump_data_gpu_va(dup_hang_ctx, HANG_DUMP_COMMON_INFO, index); + + kick_off_ring_buffer_offset = common_info_offset + OFFSETOF(dh_common_info_e3k, ring_buffer)/sizeof(DWORD); + + kick_off_ring_buffer_offset_4k_aligned = (kick_off_ring_buffer_offset + 0xfffULL) & (~0xfffULL); + + offset = kick_off_ring_buffer_offset_4k_aligned; + } + break; + + case HANG_DUMP_FLUSH_FIFO_BUFFER: + { + dh_common_info_e3k dummy_common_info = {0}; + unsigned long long common_info_offset = 0; + unsigned long long flush_fifo_buffer_offset = 0; + + common_info_offset = _get_dump_data_gpu_va(dup_hang_ctx, HANG_DUMP_COMMON_INFO, index); + + flush_fifo_buffer_offset = common_info_offset + OFFSETOF(dh_common_info_e3k, flush_fifo_buffer)/sizeof(DWORD); + + offset = flush_fifo_buffer_offset; + } + break; + + case HANG_DUMP_BL_BUFFER: + offset = dup_hang_ctx->bl_buffer_offset; + break; + + case HANG_DUMP_CPU_UNVISIBLE_MEMORY: + offset = dup_hang_ctx->local_visible_size; + break; + + default: + gf_assert(0, "invalid type"); + } + + return offset; +} + +static void* _get_dump_data_cpu_va(dup_hang_ctx_t *dup_hang_ctx, int type, int index) +{ + void *virt_addr = 0; + unsigned long long gpu_va = 0; + + gpu_va = _get_dump_data_gpu_va(dup_hang_ctx, type, index); + + switch(type) + { + case HANG_DUMP_CONTEXT_BUFFER: + case HANG_DUMP_DMA_BUFFER: + case HANG_DUMP_RING_BUFFER: + case HANG_DUMP_COMMON_INFO: + case HANG_DUMP_GART_TABLE_L2: + case HANG_DUMP_GART_TABLE_L3: + case HANG_DUMP_FENCE_BUFFER: + case HANG_DUMP_KICKOFF_RING_BUFFER: + case HANG_DUMP_FLUSH_FIFO_BUFFER: + case HANG_DUMP_BL_BUFFER: + virt_addr = dup_hang_ctx->local_visible_memory_cpu_va + gpu_va; + break; + + case HANG_DUMP_CPU_UNVISIBLE_MEMORY: +#ifdef VMI_MODE + adapter_t *adapter = dup_hang_ctx->adapter; + virt_addr = ((void *)adapter->vidmm_bus_addr) + gpu_va; +#else + gf_assert(0, "cannot get virt_addr for CPU_UNVISIBLE_MEMORY"); +#endif + break; + + default: + gf_assert(0, "invalid type"); + break; + } + + return virt_addr; +} + +static void _fill_and_write_file_header(adapter_t *adapter, HangDumpFileHeader *file_header_info, struct os_file *file) +{ + engine_share_e3k_t *share = adapter->private_data; + + gf_memset(file_header_info, 0, sizeof(HangDumpFileHeader)); + + gf_info("[DUMP HANG] ................................Start dump cpu file header................................\n"); + + file_header_info->nHeaderVersion = 0x0001; + file_header_info->nDeviceID = adapter->bus_config.device_id; + file_header_info->nSliceMask = adapter->hw_caps.chip_slice_mask; + file_header_info->nHangDumpFileHeaderSizeInByte = sizeof(HangDumpFileHeader); + file_header_info->nAdapterMemorySizeInByte = adapter->Real_vram_size; + file_header_info->nPCIEMemorySizeInByte = adapter->gart_ram_size; + file_header_info->nRecordNums = 6; + + gf_info("%s() verion-0x%x, device_id-0x%x, slice_mask-0x%x, header_size-%d, local_size-0x%llx, pcie_size-0x%llx\n", __func__, + file_header_info->nHeaderVersion, + file_header_info->nDeviceID, + file_header_info->nSliceMask, + file_header_info->nHangDumpFileHeaderSizeInByte, + file_header_info->nAdapterMemorySizeInByte, + file_header_info->nPCIEMemorySizeInByte); + + file_header_info->nDmaOffset = share->dma_buffer_for_hang->gpu_virt_addr;//hAdapter->HangDumpInfo.DMAForHang.GPUVirtualAddress.QuadPart; + file_header_info->nSingleDmaSizeInByte = HangDump_SingleDmaBufferSize;//HangDump_SingleDmaBufferSize; + + file_header_info->nRingBufferOffset = share->ring_buffer_for_hang->gpu_virt_addr; + file_header_info->nSingleRingBufferSizeInByte = HangDump_RingBufferBlockSize; + + file_header_info->nContextOffset = share->context_buffer_for_hang->gpu_virt_addr; + file_header_info->nSingleContextSizeInByte = HangDump_ContextBufferBlockSize; + + file_header_info->nGartTableL2Offset = adapter->gart_table_L2->phys_addr;//hAdapter->GartTableL2.GPUVirtualAddress.QuadPart; + file_header_info->nGartTableL3Offset = adapter->gart_table_L3->phys_addr;//hAdapter->GartTableL3.GPUVirtualAddress.QuadPart; + + file_header_info->nTransferBufferOffsetInFBFile = share->transfer_buffer_for_hang->gpu_virt_addr;//hAdapter->HangDumpInfo.TransferBuffer.GPUVirtualAddress.QuadPart; + + file_header_info->dummyPageEntry = adapter->dummy_page_addr;//dummyPageEntry.uint; + + file_header_info->nBlBufferOffset = share->bl_buffer->gpu_virt_addr; + + gf_file_write(file, file_header_info, sizeof(HangDumpFileHeader)); + + gf_info("[DUMP HANG] ................................End dump cpu file header................................\n"); + + return; +} + +static void _write_local_to_file(adapter_t *adapter, struct os_file *file) +{ + engine_share_e3k_t *share = adapter->private_data; + unsigned long long total_size = adapter->Real_vram_size; + unsigned long long left_size = total_size; + unsigned long long src_gpu_va = 0; + unsigned long long blit_size = 0; + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[RB_INDEX_GFXL]; + task_desc_t *task = NULL; + task_dma_t *dma_task; + unsigned char *dma_copy_src; + gf_info("[DUMP HANG] ................................Start dump local memory................................\n"); + +#if NEW_DUMP + gf_mutex_lock(sch_mgr->task_list_lock); + list_for_each_entry(task, &sch_mgr->submitted_task_list, list_item) + { + dma_task = (task_dma_t *)task; + if(dma_task->dma_type != PAGING_DMA && task->hang_index >= 0 && task->hang_index < 5) + { + gf_info("the line is %d\n", __LINE__); + dma_copy_src = vidschi_get_dump_data_cpu_virt_addr_e3k(adapter, HANG_DUMP_DMA_BUFFER_OFFSET, task->hang_index); + gf_info("the dma_task->hang_index is %d\n" , task->hang_index); + gf_info("the dma_task address is 0x%x\n", dma_task); + gf_info("the size is 0x%x\n", dma_task->dma_buffer_node->cmd_size); + gf_memcpy(dma_copy_src, dma_task->dma_buffer_node->virt_base_addr, dma_task->dma_buffer_node->cmd_size); + } + } + gf_mutex_unlock(sch_mgr->task_list_lock); +#endif + + while(left_size) + { + blit_size = left_size > E3K_TRANSFERBUFFER_FOR_HANG_SIZE ? E3K_TRANSFERBUFFER_FOR_HANG_SIZE : left_size; + + vidschi_copy_mem_e3k(adapter, + share->transfer_buffer_for_hang->gpu_virt_addr, + NULL, + src_gpu_va, + NULL, + blit_size); + + gf_file_write(file, share->transfer_buffer_for_hang->vma->virt_addr, blit_size); + + src_gpu_va += blit_size; + left_size -= blit_size; + + gf_info("[DUMP HANG] ................................End dump local memory %lldM / %lldM................................\n", (total_size - left_size) >> 20, total_size >> 20); + } + + gf_info("[DUMP HANG] ................................End dump local memory................................\n"); + + return; +} + +static void _write_pcie_to_file(adapter_t *adapter, struct os_file *file) +{ + engine_share_e3k_t *share = adapter->private_data; + unsigned long long total_size = adapter->gart_ram_size; + unsigned long long left_size = total_size; + unsigned long long src_gpu_va = adapter->Real_vram_size; + unsigned long long blit_size = 0; + + gf_info("[DUMP HANG] ................................Start dump pcie memory................................\n"); + + while(left_size) + { + blit_size = left_size > E3K_TRANSFERBUFFER_FOR_HANG_SIZE ? E3K_TRANSFERBUFFER_FOR_HANG_SIZE : left_size; + + vidschi_copy_mem_e3k(adapter, + share->transfer_buffer_for_hang->gpu_virt_addr, + NULL, + src_gpu_va, + NULL, + blit_size); + + gf_file_write(file, share->transfer_buffer_for_hang->vma->virt_addr, blit_size); + + src_gpu_va += blit_size; + left_size -= blit_size; + + gf_info("[DUMP HANG] ................................End dump pcie memory %lldM / %lldM................................\n", (total_size - left_size) >> 20, total_size >> 20); + } + + gf_info("[DUMP HANG] ................................End dump pcie memory................................\n"); + + return; +} + +void vidsch_dump_hang_compatible_e3k(adapter_t *adapter) +{ + struct os_file *file; + HangDumpFileHeader file_header_info = {0}; + + if(!debug_mode_e3k.post_hang_dump) + { + gf_error("vidsch_dump_hang_e3k skip this function, status error...\n"); + return; + } + + debug_mode_e3k.internal_dump_hw = 1; + + + file = gf_file_open("/var/fb.FB", OS_RDWR | OS_CREAT | OS_APPEND | OS_LARGEFILE, 0666); + if(!file) + { + gf_info("create file: create file /var/fb.FB fail!\n"); + return; + } + + _fill_and_write_file_header(adapter, &file_header_info, file); + + _write_local_to_file(adapter, file); + + _write_pcie_to_file(adapter, file); + + gf_file_close(file); + + gf_info("[DUMP HANG] ................................End dump ................................\n"); + + gf_msleep(50000); + gf_assert(0, NULL); +} + +static void _load_file_header(dup_hang_ctx_t *dup_hang_ctx) +{ + struct os_file *file = dup_hang_ctx->file; + adapter_t *adapter = dup_hang_ctx->adapter; + HangDumpFileHeader file_header_info = {0}; + unsigned long long len = 0; + + len = gf_file_read(file, &file_header_info, sizeof(file_header_info), NULL); + + gf_assert(len == sizeof(file_header_info), ""); + gf_assert(file_header_info.nHeaderVersion == 0x0001, "head version is wrong"); + gf_assert(file_header_info.nDeviceID == adapter->bus_config.device_id, "device id is wrong"); + gf_assert(file_header_info.nSliceMask == adapter->hw_caps.chip_slice_mask, "slice_mask is wrong"); + gf_assert(file_header_info.nHangDumpFileHeaderSizeInByte == sizeof(HangDumpFileHeader), "hang dump file header is wrong"); + gf_assert(file_header_info.nAdapterMemorySizeInByte == adapter->Real_vram_size, "local memory size is wrong"); + gf_assert(file_header_info.nPCIEMemorySizeInByte == adapter->gart_ram_size, "pcie memory size is wrong"); + + dup_hang_ctx->device_id = file_header_info.nDeviceID; + dup_hang_ctx->slice_mask = file_header_info.nSliceMask; + dup_hang_ctx->local_memory_size = file_header_info.nAdapterMemorySizeInByte; + dup_hang_ctx->pcie_memory_size = file_header_info.nPCIEMemorySizeInByte; + dup_hang_ctx->record_number = file_header_info.nRecordNums; + dup_hang_ctx->dma_buffer_offset = file_header_info.nDmaOffset; + dup_hang_ctx->single_dma_size_in_byte = file_header_info.nSingleDmaSizeInByte; + dup_hang_ctx->context_buffer_offset = file_header_info.nContextOffset; + dup_hang_ctx->single_context_buffer_size_in_byte = file_header_info.nSingleContextSizeInByte; + dup_hang_ctx->ring_buffer_offset = file_header_info.nRingBufferOffset; + dup_hang_ctx->single_ring_buffer_size_in_byte = file_header_info.nSingleRingBufferSizeInByte; + dup_hang_ctx->gart_table_l3_offset = file_header_info.nGartTableL3Offset; + dup_hang_ctx->gart_table_l2_offset = file_header_info.nGartTableL2Offset; + dup_hang_ctx->dummy_page_entry = file_header_info.dummyPageEntry; + dup_hang_ctx->bl_buffer_offset = file_header_info.nBlBufferOffset; + + dup_hang_ctx->local_visible_size = 512*1024*1024; + dup_hang_ctx->local_unvisible_size = dup_hang_ctx->local_memory_size - dup_hang_ctx->local_visible_size; +} + +static void _load_local_unvisible_from_file(dup_hang_ctx_t *dup_hang_ctx) +{ + struct os_file *file = dup_hang_ctx->file; + adapter_t *adapter = dup_hang_ctx->adapter; + engine_share_e3k_t *share = adapter->private_data; + unsigned long long local_visible_size = dup_hang_ctx->local_visible_size; + unsigned long long local_unvisible_size = dup_hang_ctx->local_unvisible_size; + unsigned long long total_size = local_unvisible_size; + unsigned long long left_size = total_size; + unsigned long long dst_gpu_va = local_visible_size; + unsigned int blit_size = 0; + unsigned int len = 0; + unsigned long long pos = sizeof(HangDumpFileHeader) + local_visible_size; +#ifdef VMI_MODE + void *virt_addr = _get_dump_data_cpu_va(dup_hang_ctx, HANG_DUMP_CPU_UNVISIBLE_MEMORY, 0); +#endif + + gf_info("[Duplicate] ................................Start load invisible local mem................................\n"); + + while(left_size) + { + blit_size = left_size > E3K_TRANSFERBUFFER_FOR_HANG_SIZE ? E3K_TRANSFERBUFFER_FOR_HANG_SIZE : left_size; + +#ifdef VMI_MODE + len = gf_file_read(file, virt_addr, blit_size, &pos); + gf_assert(blit_size == len, ""); + + virt_addr += blit_size; +#else + //1. read out to transfer buffer + len = gf_file_read(file, share->transfer_buffer_for_hang->vma->virt_addr, blit_size, &pos); + gf_assert(blit_size == len, ""); + + //2. + vidschi_copy_mem_e3k(adapter, + dst_gpu_va, + NULL, + share->transfer_buffer_for_hang->gpu_virt_addr, + NULL, + blit_size); + + dst_gpu_va += blit_size; +#endif + left_size -= blit_size; + + gf_info("[Duplicate] ................................End load local invisible memory %lldM / %lldM................................\n", (total_size - left_size) >> 20, total_size >> 20); + } + + gf_info("[Duplicate] ................................End load invisible local mem................................\n"); +} + +static void _load_local_visible_from_file(dup_hang_ctx_t *dup_hang_ctx) +{ + struct os_file *file = dup_hang_ctx->file; + adapter_t *adapter = dup_hang_ctx->adapter; + gf_map_argu_t map = {0}; + gf_vm_area_t *vm_area = NULL; + void *addr = NULL; + unsigned long long total_size = dup_hang_ctx->local_visible_size; + unsigned long long left_size = total_size; + unsigned int blit_size = 0; + unsigned int len = 0; + unsigned long long pos = sizeof(HangDumpFileHeader); + + gf_info("[Duplicate] ................................Start load local mem................................\n"); + + + //1. map local + //Note: + // following mapping always fail in one disk with "conflicting" error, but pass in another disk, both of them are ubuntu2004 + map.flags.cache_type= GF_MEM_UNCACHED; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = adapter->vidmm_bus_addr; + map.size = total_size; + + vm_area = gf_map_io_memory(NULL, &map); + + addr = vm_area->virt_addr; + while(left_size) + { + blit_size = left_size > E3K_TRANSFERBUFFER_FOR_HANG_SIZE ? E3K_TRANSFERBUFFER_FOR_HANG_SIZE : left_size; + + //1. copy + len = gf_file_read(file, addr, blit_size, &pos); + gf_assert(blit_size == len, "size of read out is wrong"); + + //2. update pointer + addr += blit_size; + left_size -= blit_size; + + gf_info("[Duplicate] ................................End load local visible memory %lldM / %lldM................................\n", (total_size - left_size) >> 20, total_size >> 20); + } + + gf_info("[Duplicate] ................................End load local mem................................\n"); + + //save cpu visible memory cpu va + dup_hang_ctx->local_visible_memory_cpu_va = vm_area->virt_addr; +} + +static void _restore_ttbr(dup_hang_ctx_t *dup_hang_ctx) +{ + adapter_t *adapter = dup_hang_ctx->adapter; + unsigned char *pRegAddr = 0; + Reg_Ttbr reg_Ttbr = {0}; + unsigned long long gart_table_l2_offset = dup_hang_ctx->gart_table_l2_offset; + unsigned int ttbrn_for_total = (dup_hang_ctx->local_memory_size + dup_hang_ctx->pcie_memory_size + 0x100000000 - 1) / 0x100000000;//per ttbr can index 4G mem, total has 256 ttbr regs for pa mode. + unsigned int i = 0; + + gf_assert(ttbrn_for_total <= 256,"total ttbr number excced"); + + for(i = 0; i < ttbrn_for_total; i++) + { + reg_Ttbr.reg.Segment = 1; + reg_Ttbr.reg.Valid = 1; + reg_Ttbr.reg.Addr = (gart_table_l2_offset + 4096 * i) >> 12; + pRegAddr = adapter->mmio + MMIO_MMU_START_ADDRESS + (Reg_Mmu_Ttbr_Offset + i)*4; + + gf_write32(pRegAddr, reg_Ttbr.uint); + //gf_info(" ttbr %d set 0x%x, readvalue: 0x%x \n", i,reg_Ttbr.uint, zxg_read32(pRegAddr)); + } +} + +static void _restore_gart_table_l2(dup_hang_ctx_t *dup_hang_ctx) +{ + unsigned long long gart_table_l3_offset = dup_hang_ctx->gart_table_l3_offset; + void *gart_table_l2_cpu_va = _get_dump_data_cpu_va(dup_hang_ctx, HANG_DUMP_GART_TABLE_L2, 0); + unsigned int *pte_list = NULL; + PTE_L2_t page_entry = {0}; + unsigned long long L2EntryNumForL3 = dup_hang_ctx->pcie_memory_size/(4*1024*1024); + unsigned long long L2EntryNumForLocal = dup_hang_ctx->local_memory_size/(4*1024*1024); + unsigned long long i=0; + + //1. update pte + page_entry._4k_d.Valid = TRUE; + page_entry._4k_d.Segment= 1; // 1 means this pte point to local mem + page_entry._4k_d.Addr= 0; + + pte_list = gart_table_l2_cpu_va; + + for(i = 0; i < L2EntryNumForLocal; i++) + { + pte_list[i] = page_entry.uint; + } + + for(i = 0; i < L2EntryNumForL3; i++) + { + page_entry._4k_d.Addr = ((gart_table_l3_offset >> 12) + i) &0xFFFFFF; + pte_list[i + L2EntryNumForLocal] = page_entry.uint; + } +} + +static void _restore_gart_table_l3_and_pcie_memory_ext(dup_hang_ctx_t *dup_hang_ctx) +{ + struct os_file *file = dup_hang_ctx->file; + struct os_pages_memory *memory = NULL; + gf_vm_area_t *vma = NULL; + adapter_t *adapter = dup_hang_ctx->adapter; + void *gart_table_l3_cpu_va = _get_dump_data_cpu_va(dup_hang_ctx, HANG_DUMP_GART_TABLE_L3, 0); + unsigned long long pcie_mem_size = dup_hang_ctx->pcie_memory_size; + unsigned long long total_size = pcie_mem_size; + unsigned long long left_size = 0; + unsigned long long dst_gpu_va = 0; + unsigned long long pos = sizeof(HangDumpFileHeader) + dup_hang_ctx->local_memory_size; + unsigned int blit_size = 0; + unsigned int len = 0; + + Reg_Pt_Inv_Trig reg_Pt_Inv_Trig = {0}; + Reg_Pt_Inv_Addr reg_Pt_Inv_Addr = {0}; + Reg_Pt_Inv_Mask reg_Pt_Inv_Mask = {0}; + + + dst_gpu_va = dup_hang_ctx->local_memory_size; + left_size = total_size; + + gf_info("[Duplicate] ................................Start load pcie mem................................\n"); + + while(left_size) + { + blit_size = left_size > E3K_TRANSFERBUFFER_FOR_HANG_SIZE ? E3K_TRANSFERBUFFER_FOR_HANG_SIZE : left_size; + + //1. allocate pages + { + alloc_pages_flags_t alloc_flags = {0}; + + alloc_flags.dma32 = FALSE; + alloc_flags.need_zero = TRUE; + alloc_flags.fixed_page = TRUE; + alloc_flags.need_dma_map = FALSE; + alloc_flags.need_flush = FALSE; + + memory = gf_allocate_pages_memory(adapter->os_device.pdev, blit_size, 1 << 12, alloc_flags); + + gf_assert(memory != NULL, "fail to allocate pages"); + } + + //2. update gart-table + { + vidmm_update_gart_table_pte_e3k(adapter, memory, gart_table_l3_cpu_va, dst_gpu_va); + } + + //3. map pcie memory + { + gf_map_argu_t map = {0}; + + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.cache_type = GF_MEM_WRITE_COMBINED; + map.flags.mem_type = GF_SYSTEM_RAM; + map.size = blit_size; + map.memory = memory; + +#ifdef VMI_MODE + gf_set_pages_addr(memory, adapter->vidmm_bus_addr + dst_gpu_va); +#endif + vma = gf_map_pages_memory(NULL, &map); + } + + //4. copy pcie memory + { + len = gf_file_read(file, vma->virt_addr, blit_size, &pos); + gf_assert(len==blit_size, ""); + } + + //5. unmap pcie memory + { + gf_unmap_pages_memory(vma); + } + + dst_gpu_va += blit_size; + left_size -= blit_size; + + + gf_info("[Duplicate] ................................End load pcie memory %dM / %dM................................\n", (total_size - left_size) >> 20, total_size >> 20); + } + + gf_info("[Duplicate] ................................Start load pcie mem................................\n"); + + + // invalidate gart_table + reg_Pt_Inv_Addr.uint = 0x0; + reg_Pt_Inv_Mask.reg.Mask = 0x0; + reg_Pt_Inv_Trig.reg.Target = PT_INV_TRIG_TARGET_DTLB; + + gf_write32(adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Pt_Inv_Addr_Offset*4 , reg_Pt_Inv_Addr.uint); + gf_write32(adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Pt_Inv_Mask_Offset*4, reg_Pt_Inv_Mask.uint); + gf_write32(adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Pt_Inv_Trig_Offset*4, reg_Pt_Inv_Trig.uint); + } + +static void _restore_gart_table_and_pcie_memory(dup_hang_ctx_t *dup_hang_ctx) +{ + //1. ttbr + //actually no need to restore, if local/pcie is the same between dump image and the duplicate machine + _restore_ttbr(dup_hang_ctx); + + //2. l2 + //actually seems no need to restore too, because l3 is in local + _restore_gart_table_l2(dup_hang_ctx); + + //3. l3 + //_restore_gart_table_l3_and_pcie_memory(adapter, file, dh_file_info); + _restore_gart_table_l3_and_pcie_memory_ext(dup_hang_ctx); +} + +static void _load_data_from_file(dup_hang_ctx_t *dup_hang_ctx) +{ + struct os_file *file; + file = gf_file_open("/var/fb.FB", OS_RDWR | OS_LARGEFILE, 0666); + + if(!file) + { + gf_error("open file: open file /var/fb.FB fail.\n"); + return; + } + + dup_hang_ctx->file = file; + _load_file_header(dup_hang_ctx); + + if(dup_hang_ctx->local_unvisible_size) + { + _load_local_unvisible_from_file(dup_hang_ctx); + } + + _load_local_visible_from_file(dup_hang_ctx); + + _restore_gart_table_and_pcie_memory(dup_hang_ctx); +} + +static void _enable_new_ring_buffer(dup_hang_ctx_t *dup_hang_ctx) +{ + adapter_t *adapter = dup_hang_ctx->adapter; + submit_info_t *submit_info = &(dup_hang_ctx->submit_info); + Reg_Run_List_Ctx_Addr1 reg_Run_List_Ctx_Addr1 = { 0 }; + Reg_Ring_Buf_Size reg_Ring_Buf_Size = { 0 }; + Reg_Ring_Buf_Head reg_Ring_Buf_Head = { 0 }; + Reg_Ring_Buf_Tail reg_Ring_Buf_Tail = { 0 }; + unsigned long long ring_buffer_gpu_va = submit_info->kickoff_ring_buffer_gpu_va; + int RbIndex = submit_info->rb_index; + unsigned int RegRbOffset = EngineRbOffset(RbIndex); + + reg_Ring_Buf_Tail.reg.Rb_Tail = + reg_Ring_Buf_Head.reg.Rb_Head = 0; + reg_Ring_Buf_Size.reg.Rb_Size = RING_BUFFER_SIZE_E3K; + + reg_Run_List_Ctx_Addr1.reg.Addr = (ring_buffer_gpu_va >> 12) & 0xFFFFFFF; + reg_Run_List_Ctx_Addr1.reg.Kickoff = 0; + + gf_write32(adapter->mmio + RegRbOffset * 4 + MMIO_CSP_START_ADDRESS, reg_Run_List_Ctx_Addr1.uint ); + gf_write32(adapter->mmio + (RegRbOffset+1) * 4 + MMIO_CSP_START_ADDRESS, reg_Ring_Buf_Size.uint ); + gf_write32(adapter->mmio + (RegRbOffset+2) * 4 + MMIO_CSP_START_ADDRESS, reg_Ring_Buf_Head.uint ); + gf_write32(adapter->mmio + (RegRbOffset+3) * 4 + MMIO_CSP_START_ADDRESS, reg_Ring_Buf_Tail.uint ); + + reg_Run_List_Ctx_Addr1.reg.Kickoff = 1; + + gf_write32( adapter->mmio + RegRbOffset * 4 + MMIO_CSP_START_ADDRESS, reg_Run_List_Ctx_Addr1.uint ); +} + +static void _fill_ring_buffer_and_cmd(dup_hang_ctx_t *dup_hang_ctx, unsigned long long fence_value) +{ + submit_info_t *submit_info = &(dup_hang_ctx->submit_info); + unsigned long long context_buffer_gpu_va = submit_info->context_buffer_gpu_va; + unsigned long long dma_buffer_gpu_va = submit_info->dma_buffer_gpu_va; + unsigned long long fence_buffer_gpu_va = submit_info->fence_buffer_gpu_va; + void* ring_buffer_cpu_va = submit_info->ring_buffer_cpu_va; + RINGBUFFER_COMMANDS_E3K *submit_cmd = submit_info->kickoff_ring_buffer_cpu_va; + + gf_memcpy(submit_cmd, ring_buffer_cpu_va, sizeof(RINGBUFFER_COMMANDS_E3K)); + + //patch restore dma address + if(submit_cmd->c0.RestoreContext_Address != 0) + { + submit_cmd->c0.RestoreContext_Address = (context_buffer_gpu_va >> 11); + } + + //patch dma adress + submit_cmd->c0.CommandDMA_Address_L = (dma_buffer_gpu_va & 0xFFFFFFFF); + submit_cmd->c0.CommandDMA_Address_H = ((dma_buffer_gpu_va >>32) & 0xFF); + + //patch save dma address. + //Assume the hang task dma not the first dma, since the context_buffer_pa for save will overwrite the template. + gf_memset(&submit_cmd->c0.SaveDMA, 0, 4*sizeof(DWORD)); + + *(unsigned int*)&submit_cmd->c0.Fence = SEND_EXTERNAL_FENCE_E3K(FENCE_IRQ_INTERRUPT_CPU); + submit_cmd->c0.Fence_Data_L = (fence_value) & 0xFFFFFFFF; + submit_cmd->c0.Fence_Data_H = ((fence_value) >>32) & 0xFFFFFFFF; + submit_cmd->c0.Fence_Address_L = (fence_buffer_gpu_va) & 0xFFFFFFFF; + submit_cmd->c0.Fence_Address_H = (fence_buffer_gpu_va >> 32) & 0xFFFFFFFF; + + //util_dump_memory(NULL, submit_cmd, sizeof(*submit_cmd), "duplicate ring buffer"); + //util_dump_memory(NULL, submit_info->dma_buffer_cpu_va, (submit_cmd->c0.CommandDMA.Dw_Num)<<2, "duplicate dma buffer"); + +} + +static void _kick_off_cmd(dup_hang_ctx_t *dup_hang_ctx, unsigned long long last_send_fence_id) +{ + adapter_t *adapter = dup_hang_ctx->adapter; + submit_info_t *submit_info = &(dup_hang_ctx->submit_info); + void *flush_fifo_buffer_cpu_va = _get_dump_data_cpu_va(dup_hang_ctx, HANG_DUMP_FLUSH_FIFO_BUFFER, 0); + unsigned int RbIndex = submit_info->rb_index; + unsigned int RegRbOffset = EngineRbOffset(RbIndex); + unsigned int offset = 0; + unsigned int tail = sizeof(RINGBUFFER_COMMANDS_E3K); + + gf_mb(); + + { + *((volatile unsigned int*)flush_fifo_buffer_cpu_va + RbIndex) = (unsigned int)last_send_fence_id; + + while(*((volatile unsigned int*)flush_fifo_buffer_cpu_va + RbIndex) != (unsigned int)last_send_fence_id) + { + gf_error("flush fifo issue index:%x\n",RbIndex); + gf_error("krnl virt addr: %p, write value: %x, read value: %x\n", + ((volatile unsigned int*)flush_fifo_buffer_cpu_va + RbIndex), + (unsigned int)last_send_fence_id, + *((volatile unsigned int*)flush_fifo_buffer_cpu_va + RbIndex)); + // gf_assert(0, NULL); + } + } + + gf_mb(); + + gf_write32(adapter->mmio + (RegRbOffset+3) * 4 + MMIO_CSP_START_ADDRESS, tail); + + gf_mb(); + + do{ + offset = gf_read32(adapter->mmio + (RegRbOffset+3) * 4 + MMIO_CSP_START_ADDRESS); + if(offset != tail) + { + gf_error("idx:%d, kick off:%x, read:%x\n", RbIndex, tail, offset); + } + }while(tail != offset); +} + +static void _check_hang(dup_hang_ctx_t *dup_hang_ctx, int pool_index, unsigned long long fence_value) +{ + adapter_t *adapter = dup_hang_ctx->adapter; + submit_info_t *submit_info = &(dup_hang_ctx->submit_info); + EngineSatus_e3k status_after = {0}; + EngineSatus_e3k *status_before = &submit_info->status; + int i = 0; + + unsigned long long start_time = 0, current_time, delta_time; + long temp_sec, temp_usec; + + gf_getsecs(&temp_sec, &temp_usec); + start_time = temp_sec; + + gf_info("%s() start_time-%lld, send_fence-0x%llx, read_fence-0x%llx\n", __func__, start_time, fence_value, _get_fence_id(dup_hang_ctx)); + + while(fence_value > _get_fence_id(dup_hang_ctx)) + { + + gf_getsecs(&temp_sec, &temp_usec); + current_time = temp_sec; + delta_time = current_time - start_time; + + /* wait 60s, if fence still not back seems something wrong */ + if(delta_time > DUPLICATE_TIME_OUT) + { + unsigned int *status = (unsigned int *)&status_after; + + gf_info("%s() fail, current_time-%lld, delta_time-%lld, send_fence-0x%llx, read_fence-0x%llx\n", __func__, current_time, delta_time, fence_value, _get_fence_id(dup_hang_ctx)); + + //get status + for(i=0; i<7; i++) + { + *(status + i) = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + (Reg_Block_Busy_Bits_Top_Offset + i)*4); + } + gf_info("[Duplicate] engine 0x%x, Duplicated Hang Status:Top=%x,Gpc0_0=%x,Gpc0_1=%x,Gpc1_0=%x, Gpc1_1=%x,Gpc2_0=%x,Gpc2_1=%x\n", + submit_info->rb_index, + status_after.Top.uint, + status_after.Gpc0_0.uint, + status_after.Gpc0_1.uint, + status_after.Gpc1_0.uint, + status_after.Gpc1_1.uint, + status_after.Gpc2_0.uint, + status_after.Gpc2_1.uint); + + //vidsch_display_debugbus_info_e3k(adapter, NULL, FALSE); + + if((status_before->Top.uint & 0xFFFFFFF9) == (status_after.Top.uint & 0xFFFFFFF9) && //exclude mxua/b, diu will use it, even 3d hang. + (status_before->Gpc0_0.uint == status_after.Gpc0_0.uint) && + (status_before->Gpc0_1.uint == status_after.Gpc0_1.uint) && + (status_before->Gpc1_0.uint == status_after.Gpc1_0.uint) && + (status_before->Gpc1_1.uint == status_after.Gpc1_1.uint) && + (status_before->Gpc2_0.uint == status_after.Gpc2_0.uint) && + (status_before->Gpc2_1.uint == status_after.Gpc2_1.uint)) + { + gf_info("[Duplicate] <<-------------------:) Good job!, Status is same.------------------------>>.\n"); + gf_assert(0, "[Duplicate] <<-------------------:) Congratulation!! ------------------------>>\n"); + } + else + { + gf_info("[Duplicate]<<------------------:( Sorry, Status is different.-------------------------->>.\n"); + + gf_info("[Duplicate]engine 0x%x, Org Status: Top=%x,Gpc0_0=%x,Gpc0_1=%x,Gpc1_0=%x, Gpc1_1=%x,Gpc2_0=%x,Gpc2_1=%x\n", + submit_info->rb_index, + status_before->Top.uint, + status_before->Gpc0_0.uint, + status_before->Gpc0_1.uint, + status_before->Gpc1_0.uint, + status_before->Gpc1_1.uint, + status_before->Gpc2_0.uint, + status_before->Gpc2_1.uint); + gf_assert(0, "[Duplicate] <<-------------------:( Do more check !! ------------------------>>\n"); + } + } + } + + gf_info("%s() pass, send_fence-0x%llx, read_fence-0x%llx\n", __func__, fence_value, _get_fence_id(dup_hang_ctx)); + + return; +} + +static void _get_submit_info(dup_hang_ctx_t *dup_hang_ctx, int pool_index) +{ + submit_info_t *submit_info = &(dup_hang_ctx->submit_info); + void *ring_buffer_block = NULL; + dh_rb_info_e3k *rb_info = NULL; + + submit_info->ring_buffer_gpu_va = _get_dump_data_gpu_va(dup_hang_ctx, HANG_DUMP_RING_BUFFER, pool_index) + sizeof(dh_rb_info_e3k); + submit_info->context_buffer_gpu_va = _get_dump_data_gpu_va(dup_hang_ctx, HANG_DUMP_CONTEXT_BUFFER, pool_index); + submit_info->dma_buffer_gpu_va = _get_dump_data_gpu_va(dup_hang_ctx, HANG_DUMP_DMA_BUFFER, pool_index); + + ring_buffer_block = _get_dump_data_cpu_va(dup_hang_ctx, HANG_DUMP_RING_BUFFER, pool_index); + rb_info = (dh_rb_info_e3k *)ring_buffer_block; + + submit_info->ring_buffer_cpu_va = ring_buffer_block + sizeof(dh_rb_info_e3k); + submit_info->context_buffer_cpu_va = (void *)_get_dump_data_cpu_va(dup_hang_ctx, HANG_DUMP_CONTEXT_BUFFER, pool_index); + submit_info->dma_buffer_cpu_va = (void *)_get_dump_data_cpu_va(dup_hang_ctx, HANG_DUMP_DMA_BUFFER, pool_index); + + submit_info->fence_buffer_gpu_va = _get_dump_data_gpu_va(dup_hang_ctx, HANG_DUMP_FENCE_BUFFER, pool_index); + submit_info->fence_buffer_cpu_va = _get_dump_data_cpu_va(dup_hang_ctx, HANG_DUMP_FENCE_BUFFER, pool_index); + submit_info->kickoff_ring_buffer_gpu_va = _get_dump_data_gpu_va(dup_hang_ctx, HANG_DUMP_KICKOFF_RING_BUFFER, pool_index); + submit_info->kickoff_ring_buffer_cpu_va = _get_dump_data_cpu_va(dup_hang_ctx, HANG_DUMP_KICKOFF_RING_BUFFER, pool_index); + + gf_memcpy(&submit_info->status, &rb_info->status, sizeof(submit_info->status)); + + submit_info->rb_index = rb_info->last_rb_index; + +} + + +static void _duplicate_hang(dup_hang_ctx_t *dup_hang_ctx) +{ + int record_number = dup_hang_ctx->record_number; + int pool_index = 0; + unsigned long long fence_value = 0xff123456ff000001; + dh_common_info_e3k *dh_common_info = _get_dump_data_cpu_va(dup_hang_ctx, HANG_DUMP_COMMON_INFO, 0); + submit_info_t *submit_info = &(dup_hang_ctx->submit_info); + + //pool_index = dh_common_info->current_hang_dump_index; + pool_index = dh_common_info->hang_dma_index; // Arise is differen to CHX004: arise will store the exact dma_index of the hang pool + + do + { + pool_index = pool_index < record_number ? pool_index : 0; + + gf_info("[Duplicate] pool_index=%d, count=%d, dump_index=0x%x\n", + pool_index, dh_common_info->hang_dump_counter, dh_common_info->current_hang_dump_index); + + gf_memset(submit_info, 0, sizeof(submit_info_t)); + + //0. get info about submit + _get_submit_info(dup_hang_ctx, pool_index); + + _set_fence_id(dup_hang_ctx, fence_value -1); + + switch(submit_info->rb_index) + { + case RB_INDEX_GFXL: + { + + //1. setup ringbuffer + _enable_new_ring_buffer(dup_hang_ctx); + + //2. reproduce cmd + _fill_ring_buffer_and_cmd(dup_hang_ctx, fence_value); + + //3. kick off cmd + _kick_off_cmd(dup_hang_ctx, fence_value-1); + + break; + } + + case RB_INDEX_GFXH: + default: + break; + } + + //3. check hang + _check_hang(dup_hang_ctx, pool_index, fence_value); + + pool_index++; + fence_value++; + } + while (debug_mode_e3k.duplicate_hang); +} + +void vidsch_duplicate_hang_compatible_e3k(adapter_t * adapter) +{ + dup_hang_ctx_t dup_hang_ctx = {0}; + + if(!debug_mode_e3k.duplicate_hang) + { + return; + } + + //block any other submit: + debug_mode_e3k.internal_block_submit = 1; + + + gf_memset(&dup_hang_ctx, 0, sizeof(dup_hang_ctx)); + + dup_hang_ctx.adapter = adapter; + + //1. restore image to memory + _load_data_from_file(&dup_hang_ctx); + + //2. duplicate hang + _duplicate_hang(&dup_hang_ctx); + + debug_mode_e3k.internal_block_submit = 0; +} + +void vidsch_trigger_duplicate_hang_e3k(adapter_t *adapter) +{ + debug_mode_e3k.duplicate_hang = 1; + + vidsch_duplicate_hang_e3k(adapter); + + debug_mode_e3k.duplicate_hang = 0; +} diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_e3k.c new file mode 100644 index 0000000000000..fce1231d5046f --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_e3k.c @@ -0,0 +1,1228 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidmm.h" +#include "vidsch.h" +#include "vidschi.h" +#include "chip_include_e3k.h" +#include "vidsch_debug_hang_e3k.h" +#include "vidsch_engine_e3k.h" +#include "mm_e3k.h" +#include "context.h" +#include "global.h" +#include "bit_op.h" + +#define WRITE_DUMP_FILE_CHECK(request_size, returned_size) do {\ + if(returned_size != request_size) \ + { \ + gf_error("write error @%d. request: %d, actual: %d\n", __LINE__, request_size, returned_size); \ + }\ + else \ + { \ + gf_info("write file ok, len: 0x%x\n", returned_size); \ + } }while(0) + +#define READ_DUMP_FILE_CHECK(request_size, returned_size) do {\ + if(returned_size != request_size) \ + { \ + gf_error("read error @%d. request: %d, actual: %d\n", __LINE__, request_size, returned_size); \ + }\ + else \ + { \ + gf_info("read file ok, len: 0x%x\n", returned_size); \ + }}while(0) + +#define PRINT_DEBUG_BUS_INFO(adapter, printer, info) do {\ + gf_printf(printer, info); \ + if(adapter->ctl_flags.dump_hang_info_to_file) \ + { \ + util_write_to_file(info, gf_strlen(info) , "", HW_HANG_LOG_FILE);\ + }}while(0) + +#define DEBUG_BUS_VERSION "0.0.1" + +void vidsch_dump_debugbus_label(adapter_t *adapter, struct os_printer *p) +{ + unsigned char debug_bus_label[256]; + + gf_memset(debug_bus_label, 0, sizeof(debug_bus_label)); + gf_vsprintf(debug_bus_label, "OS: linux\n"); + PRINT_DEBUG_BUS_INFO(adapter, p, debug_bus_label); + + gf_memset(debug_bus_label, 0, sizeof(debug_bus_label)); + gf_vsprintf(debug_bus_label, "Debugbus version:"DEBUG_BUS_VERSION"\n"); + PRINT_DEBUG_BUS_INFO(adapter, p, debug_bus_label); + + gf_memset(debug_bus_label, 0, sizeof(debug_bus_label)); + if(adapter->chip_id < CHIP_ARISE1020) + { + gf_vsprintf(debug_bus_label, "Project: ARISE 10C0\n"); + } + else if (adapter->chip_id == CHIP_ARISE1020) + { + gf_vsprintf(debug_bus_label, "Project: ARISE 1020\n"); + } + else if (adapter->chip_id == CHIP_ARISE2020) + { + gf_vsprintf(debug_bus_label, "Project: ARISE 2020\n"); + } + else if (adapter->chip_id == CHIP_ARISE2030) + { + gf_vsprintf(debug_bus_label, "Project: ARISE 2030\n"); + } + + PRINT_DEBUG_BUS_INFO(adapter, p, debug_bus_label); +} + +void vidsch_display_debugbus_info_e3k(adapter_t *adapter, struct os_printer *p, int video) +{ + unsigned char sr1a = 0; + unsigned char debug_bus_buffer[256]; + + vidsch_dump_debugbus_label(adapter, p); + + gf_vsprintf(debug_bus_buffer, "\n~~~~~~~~~~~~~~debug bus info~~~~~~~~~~~~~~\n"); + PRINT_DEBUG_BUS_INFO(adapter, p, debug_bus_buffer); + + //enable read debug bus from diu + sr1a = gf_read8(adapter->mmio + 0x861a); + gf_write8(adapter->mmio + 0x861a, sr1a | 0x10); + + if(video) + { + int k = 0; + int i = 0; + unsigned char * video_mmio = NULL; + for(k = 0; k <= 0x1ff; k++) + { + video_mmio = adapter->mmio + 0x4C000 + k*4; + i = gf_read32(video_mmio); + gf_vsprintf(debug_bus_buffer,"%08x: %08x\n", video_mmio, i); + gf_info(debug_bus_buffer); + } + + for(k = 0; k <= 0x1ff; k++) + { + video_mmio = adapter->mmio + 0x4A000 + k*4; + i = gf_read32(video_mmio); + gf_vsprintf(debug_bus_buffer,"%08x: %08x\n", video_mmio, i); + gf_info(debug_bus_buffer); + } + + } + + //3D + { + debug_bus_info *debugbus_info = NULL; + unsigned int debugbus_info_block_size = 0; + unsigned int block_index = 0; + int current_gpc = 0xFFFFFFFF; + + switch (adapter->chip_id) + { + case CHIP_ARISE1020: + case CHIP_ARISE1010: + debugbus_info = (debug_bus_info *)debug_bus_info_Arise1020; + debugbus_info_block_size = sizeof(debug_bus_info_Arise1020) / sizeof(debug_bus_info); + break; + case CHIP_ARISE2030: + case CHIP_ARISE2020: + debugbus_info = (debug_bus_info *)debug_bus_info_Arise2030; + debugbus_info_block_size = sizeof(debug_bus_info_Arise2030) / sizeof(debug_bus_info); + break; + case CHIP_ARISE: + default: + debugbus_info = (debug_bus_info *)debug_bus_info_E3K; + debugbus_info_block_size = sizeof(debug_bus_info_E3K) / sizeof(debug_bus_info); + break; + } + + gf_info("debugbus_info_block_size %d\n", debugbus_info_block_size); + for (block_index = 0; block_index < debugbus_info_block_size; block_index++) + { + unsigned int reg_start = 0; + unsigned int reg_end = 0; + unsigned int reg_index = 0; + + //GPC Title + if ((debugbus_info[block_index].gpcIndex) != current_gpc) + { + current_gpc = debugbus_info[block_index].gpcIndex; + + gf_vsprintf(debug_bus_buffer, "-----------------GPC%d----------------\n", current_gpc); + PRINT_DEBUG_BUS_INFO(adapter, p, debug_bus_buffer); + } + + gf_vsprintf(debug_bus_buffer, "-----------------%s----------------\n", debugbus_info[block_index].group_name); + PRINT_DEBUG_BUS_INFO(adapter, p, debug_bus_buffer); + + reg_start = debugbus_info[block_index].regOpinfo.debugBusWrite.group_start_offset; + reg_end = debugbus_info[block_index].regOpinfo.debugBusWrite.group_end_offset; + for (reg_index = reg_start; reg_index <= reg_end; reg_index++) + { + //Write Register + unsigned int write_reg_count = 0; + + for (write_reg_count = 0; write_reg_count < debugbus_info[block_index].regOpinfo.debugBusWrite.write_reg_number; write_reg_count++) + { + unsigned int mask = 0; + unsigned int mask_last_bit_index = 0; + unsigned int write_value = 0; + int mmio_offset = 0; + + mask = debugbus_info[block_index].regOpinfo.debugBusWrite.write_reg_mask[write_reg_count]; + _BitScanForward(&mask_last_bit_index, mask); + write_value = (reg_index&mask) >> (mask_last_bit_index/4)*4; + + mmio_offset = debugbus_info[block_index].regOpinfo.debugBusWrite.write_reg_offset[write_reg_count]; + + //1020/2020/2030 BIU select need special write 0xA01F0 31bit as 1 + if ((adapter->chip_id >= CHIP_ARISE1020) && mmio_offset == 0xA01F0) + { + gf_write32((unsigned int *)(adapter->mmio + mmio_offset), write_value | 0x80000000); + } + else + { + gf_write8((unsigned char *)(adapter->mmio + mmio_offset), (unsigned char)write_value); + } + } + + //Read Register + { + int value0 = 0; + int value1 = 0; + int value2 = 0; + int value3 = 0; + int mmio_offset = 0; + + mmio_offset = debugbus_info[block_index].regOpinfo.debugBusReadback.mmio_offset_0; + value0 = gf_read8((unsigned char *)(adapter->mmio + mmio_offset)); + mmio_offset = debugbus_info[block_index].regOpinfo.debugBusReadback.mmio_offset_1; + value1 = gf_read8((unsigned char *)(adapter->mmio + mmio_offset)); + mmio_offset = debugbus_info[block_index].regOpinfo.debugBusReadback.mmio_offset_2; + value2 = gf_read8((unsigned char *)(adapter->mmio + mmio_offset)); + mmio_offset = debugbus_info[block_index].regOpinfo.debugBusReadback.mmio_offset_3; + value3 = gf_read8((unsigned char *)(adapter->mmio + mmio_offset)); + + gf_vsprintf(debug_bus_buffer, "%08x: %08x\n", reg_index, (value0 << 24 | value1 << 16 | value2 << 8 | value3)); + PRINT_DEBUG_BUS_INFO(adapter, p, debug_bus_buffer); + } + } + } + } + + gf_vsprintf(debug_bus_buffer, "~~~~~~~~~~~~~~end of debug bus info~~~~~~~~~~~~~~"); + PRINT_DEBUG_BUS_INFO(adapter, p, debug_bus_buffer); +} + +void vidsch_dump_hang_info_e3k(vidsch_mgr_t *sch_mgr) +{ + adapter_t *adapter = sch_mgr->adapter; + engine_e3k_t *engine = sch_mgr->private_data; + unsigned int engine_index = sch_mgr->engine_index; + unsigned int RegRbOffset = EngineRbOffset(engine_index); + unsigned int engine_status_offset = MMIO_CSP_START_ADDRESS + Reg_Block_Busy_Bits_Top_Offset*4; + unsigned int cur_rb_head_offset = MMIO_CSP_START_ADDRESS + (RegRbOffset + 2)*4; + unsigned int cur_rb_tail_offset = MMIO_CSP_START_ADDRESS + (RegRbOffset + 3)*4; + unsigned int cur_rb_cmd_offset = MMIO_CSP_START_ADDRESS + (Reg_Cur_3d_Rbuf_Cmd_Offset + engine_index)*4; + unsigned int cur_l1_dma_cmd_offset = MMIO_CSP_START_ADDRESS + Reg_Cur_L1_Dma_Cmd_Offset*4; + unsigned int cur_l2_dma_cmd_offset = MMIO_CSP_START_ADDRESS + Reg_Cur_L2_Dma_Cmd_Offset*4; + unsigned int cur_rb_cmd = gf_read32(adapter->mmio + cur_rb_cmd_offset); + unsigned int cur_rb_head = gf_read32(adapter->mmio + cur_rb_head_offset); + unsigned int cur_rb_tail = gf_read32(adapter->mmio + cur_rb_tail_offset); + unsigned int cur_l1_dma_cmd = gf_read32(adapter->mmio + cur_l1_dma_cmd_offset); + unsigned int cur_l2_dma_cmd = gf_read32(adapter->mmio + cur_l2_dma_cmd_offset); + unsigned int last_returned_fence_id = *(volatile unsigned int *)engine->fence_buffer_virt_addr; + EngineSatus_e3k *engine_status=&engine->dumped_engine_status; + unsigned int *status = (unsigned int *)&engine->dumped_engine_status; + unsigned int *video_engine_status = (unsigned int *)&engine_status->ES_VCP_VPP; + int i; + + if(last_returned_fence_id == (unsigned int)sch_mgr->last_send_fence_id) + { + return; + } + + for( i = 0; i <7; i++) + { + *(status + i) = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + (Reg_Block_Busy_Bits_Top_Offset + i)*4); + } + + *video_engine_status = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + Reg_Vcp_Vpp_Block_Busy_Bits_Offset*4); + + if(adapter->display_debugbus_flag) + { + gf_info("Engine timeout and Status: %08x,%08x,%08x,%08x,%08x,%08x,%08x\n", + status[0], status[1], status[2], status[3], status[4], status[5], status[6]); + + gf_info("pid=%d, tid=%d, engine %x is busy. \n", gf_get_current_pid(), gf_get_current_tid(), engine_index); + gf_info("last_send_fence_id:0x%x, returned_fence_id:0x%x, fence in mem:0x%x\n", (unsigned int)sch_mgr->last_send_fence_id, + (unsigned int)sch_mgr->returned_fence_id, (unsigned int)last_returned_fence_id); + gf_info("current rb cmd(0x%x): 0x%08x, rb head(0x%x): 0x%08x, rb tail(0x%x): 0x%08x\n", + cur_rb_cmd_offset, cur_rb_cmd, cur_rb_head_offset, cur_rb_head, cur_rb_tail_offset, cur_rb_tail); + gf_info("current L1 dma cmd(%x):%x, L2 cmd(%x):%x\n", cur_l1_dma_cmd_offset, cur_l1_dma_cmd, cur_l2_dma_cmd_offset, cur_l2_dma_cmd); + } + + /* dump to file */ + if(adapter->ctl_flags.dump_hang_info_to_file) + { + util_dump_memory_to_file(&engine_status_offset, 4, "Engine status offset: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&engine_status, 28, "Engine status: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&engine_index, 4, "Engine index: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&last_returned_fence_id, 4, "current returned fence: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&sch_mgr->last_send_fence_id, 4, "last send fence: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&cur_rb_cmd_offset, 4, "current rb cmd offset: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&cur_rb_cmd, 4, "current rb cmd: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&cur_rb_head_offset, 4, "current rb head offset: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&cur_rb_head, 4, "current rb head: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&cur_rb_tail_offset, 4, "current rb tail offset: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&cur_rb_tail, 4, "current rb tail: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&cur_l1_dma_cmd_offset, 4, "current l1 dma cmd offset: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&cur_l2_dma_cmd_offset, 4, "current l2 dma cmd offset: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&cur_l1_dma_cmd, 4, "current l1 dma cmd: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(&cur_l2_dma_cmd, 4, "current l2 dma cmd: ", HW_HANG_LOG_FILE); + util_dump_memory_to_file(engine->ring_buf_virt_addr, RING_BUFFER_SIZE_E3K, "RING buffer", HW_HANG_LOG_FILE); + } + + //gf_info("<<----^^^^^^^^^-----[HANG DETECTED] Current HW Hang Status-----^^^^^^^^^^^--->>\n"); + gf_info("ChipSliceMask: %08x\r\n", adapter->hw_caps.chip_slice_mask); + gf_info("Engine timeout and Status: %08x,%08x,%08x,%08x,%08x,%08x,%08x,VCP0 = %x,VCP1 = %x,VPP = %x.\n", + engine_status->Top.uint, engine_status->Gpc0_0.uint, engine_status->Gpc0_1.uint, + engine_status->Gpc1_0.uint, engine_status->Gpc1_1.uint, engine_status->Gpc2_0.uint, engine_status->Gpc2_1.uint, + ((*video_engine_status)&0x1), + ((*video_engine_status)&0x2), + ((*video_engine_status)&0x4)); + + /*dump debug bus*/ + if(adapter->display_debugbus_flag) + { + vidsch_display_debugbus_info_e3k(adapter, NULL, (engine_index >= RB_INDEX_VCP0)); + } +} + +void vidschi_map_e3k(adapter_t *adapter) +{ + engine_share_e3k_t *share = adapter->private_data; + gf_map_argu_t map = {0}; + + if(share->ring_buffer_for_hang->vma == NULL) + { + map.size = E3K_RINGBUFFER_FOR_HANG_SIZE; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.read_only = 0; + map.flags.write_only = 0; + map.flags.cache_type = GF_MEM_WRITE_COMBINED; + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = adapter->vidmm_bus_addr + share->ring_buffer_for_hang->gpu_virt_addr; + map.offset = 0; + + share->ring_buffer_for_hang->vma = gf_map_io_memory(NULL, &map); + + gf_info("ring_buffer_for_hang->vma->virt_addr 0x%x, size 0x%x \n", share->ring_buffer_for_hang->vma->virt_addr, map.size); + gf_memset(share->ring_buffer_for_hang->vma->virt_addr, 0, share->ring_buffer_for_hang->vma->size); + } + + if(share->context_buffer_for_hang->vma == NULL) + { + map.size = E3K_CONTEXTBUFFER_FOR_HANG_SIZE; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.read_only = 0; + map.flags.write_only = 0; + map.flags.cache_type = GF_MEM_WRITE_COMBINED; + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = adapter->vidmm_bus_addr + share->context_buffer_for_hang->gpu_virt_addr; + map.offset = 0; + + share->context_buffer_for_hang->vma = gf_map_io_memory(NULL, &map); + gf_info("context_buffer_for_hang->vma->virt_addr 0x%x size 0x%x \n", share->context_buffer_for_hang->vma->virt_addr, map.size); + gf_memset(share->context_buffer_for_hang->vma->virt_addr, 0, share->context_buffer_for_hang->vma->size); + } + + if(share->dma_buffer_for_hang->vma == NULL) + { + map.size = E3K_DMABUFFER_FOR_HANG_SIZE; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.read_only = 0; + map.flags.write_only = 0; + map.flags.cache_type = GF_MEM_WRITE_COMBINED; + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = adapter->vidmm_bus_addr + share->dma_buffer_for_hang->gpu_virt_addr; + map.offset = 0; + + share->dma_buffer_for_hang->vma = gf_map_io_memory(NULL, &map); + gf_info("dma_buffer_for_hang->vma->virt_addr 0x%x, size 0x%x \n", share->dma_buffer_for_hang->vma->virt_addr, map.size); + gf_memset(share->dma_buffer_for_hang->vma->virt_addr, 0, share->dma_buffer_for_hang->vma->size); + } + + if(share->transfer_buffer_for_hang->vma == NULL) + { + vidmm_map_flags_t flags = {0}; + + gf_memset(&flags, 0, sizeof(flags)); + flags.write_only = 1; + flags.mem_space = GF_MEM_KERNEL; + + vidmm_map_segment_memory(adapter, NULL, share->transfer_buffer_for_hang, &flags); + + if(share->transfer_buffer_for_hang->vma != NULL) + { + gf_memset(share->transfer_buffer_for_hang->vma->virt_addr, 0, E3K_TRANSFERBUFFER_FOR_HANG_SIZE); + } + } +} + +static int vidschi_get_dump_data_gpu_offset_e3k(adapter_t *adapter, unsigned int type, unsigned int index) +{ + engine_share_e3k_t *share = adapter->private_data; + vidmm_segment_memory_t *dma_buffer_for_hang = share->dma_buffer_for_hang; + vidmm_segment_memory_t *context_buffer_for_hang = share->context_buffer_for_hang; + vidmm_segment_memory_t *ring_buffer_for_hang = share->ring_buffer_for_hang; + + unsigned int dma_buffer_block_size = 64 * 1024; + unsigned int context_buffer_block_size = HW_CONTEXT_SIZE_E3K; + unsigned int ring_buffer_block_size = sizeof(RINGBUFFER_COMMANDS_E3K) + sizeof(dh_rb_info_e3k); + unsigned int buffer_gpu_offset = 0; + + index = index % MAX_HANG_DUMP_DATA_POOL_NUMBER; + + switch (type) + { + case HANG_DUMP_CONTEXT_BUFFER_OFFSET: + buffer_gpu_offset = context_buffer_for_hang->gpu_virt_addr + index * context_buffer_block_size; + break; + case HANG_DUMP_DMA_BUFFER_OFFSET: + buffer_gpu_offset = dma_buffer_for_hang->gpu_virt_addr + index * dma_buffer_block_size; + break; + case HANG_DUMP_RING_BUFFER_OFFSET: + buffer_gpu_offset = ring_buffer_for_hang->gpu_virt_addr + index * ring_buffer_block_size; + break; + case HANG_DUMP_DH_COMMON_INFO_OFFSET: + buffer_gpu_offset = ring_buffer_for_hang->gpu_virt_addr + MAX_HANG_DUMP_DATA_POOL_NUMBER * ring_buffer_block_size; + break; + default: + break; + } + return buffer_gpu_offset; +} + +unsigned char *vidschi_get_dump_data_cpu_virt_addr_e3k(adapter_t *adapter, unsigned int type, unsigned int index) +{ + engine_share_e3k_t *share = adapter->private_data; + vidmm_segment_memory_t *dma_buffer_for_hang = share->dma_buffer_for_hang; + vidmm_segment_memory_t *context_buffer_for_hang = share->context_buffer_for_hang; + vidmm_segment_memory_t *ring_buffer_for_hang = share->ring_buffer_for_hang; + unsigned int dma_buffer_block_size = 64 * 1024; + unsigned int context_buffer_block_size = HW_CONTEXT_SIZE_E3K; + unsigned int ring_buffer_block_size = sizeof(RINGBUFFER_COMMANDS_E3K) + sizeof(dh_rb_info_e3k); + unsigned char *virt_addr = NULL; + + index = index % MAX_HANG_DUMP_DATA_POOL_NUMBER; + + switch (type) + { + case HANG_DUMP_CONTEXT_BUFFER_OFFSET: + virt_addr = context_buffer_for_hang->vma->virt_addr + index * context_buffer_block_size; + break; + case HANG_DUMP_DMA_BUFFER_OFFSET: + virt_addr = dma_buffer_for_hang->vma->virt_addr + index * dma_buffer_block_size; + break; + case HANG_DUMP_RING_BUFFER_OFFSET: + virt_addr = ring_buffer_for_hang->vma->virt_addr + index * ring_buffer_block_size; + break; + case HANG_DUMP_DH_COMMON_INFO_OFFSET: + virt_addr = ring_buffer_for_hang->vma->virt_addr + MAX_HANG_DUMP_DATA_POOL_NUMBER * ring_buffer_block_size; + break; + default: + break; + } + + return virt_addr; +} + +void vidschi_copy_mem_e3k(adapter_t *adapter, unsigned long long dst_phys_addr,void *dst_virt_addr,unsigned long long src_phys_addr, void *src_virt_addr,unsigned int total_size) +{ + unsigned int RbIndex = RB_INDEX_GFXL; + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[RbIndex]; + engine_share_e3k_t *share = adapter->private_data; + engine_e3k_t *engine = sch_mgr->private_data; + vidschedule_t *schedule = adapter->schedule; + + Hw_Surf_Format Format = HSF_R8G8B8A8_UNORM; + DWORD Width = MAX_WIDTH_2DBLT; + DWORD Height = 0; + DWORD Length = total_size; + unsigned long long oldFence= 0; + DWORD i = 0; + DWORD StartX = 0; + DWORD CmdLength; + DWORD AddrOffset = 0; + static int bHwCopyEn = TRUE; + unsigned long long Count = 0; + unsigned long long DstAddr = dst_phys_addr; + unsigned long long SrcAddr = src_phys_addr; + + + Cmd_Blk_Cmd_Csp_Indicator pwmTrigger = {0}; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 trigger_Dw = {0}; + BITBLT_REGSETTING_E3K CopyCmd = {0}; + BITBLT_REGSETTING_E3K* p2DBltCmd = &CopyCmd; + DWORD* pRB; + DWORD* pRB0; + + gf_assert(total_size % 4 == 0, NULL); + + // SrcAddr and DstAddr should be aligned to 2kbit. + gf_assert((SrcAddr & ~0xFFll) == 0, NULL); + gf_assert((DstAddr & ~0xFFll) == 0, NULL); + + gf_memcpy(p2DBltCmd, &share->_2dblt_cmd_e3k, sizeof(BITBLT_REGSETTING_E3K)); + p2DBltCmd->BitBltCmd.Blt_Overlap = 1; + + if(!adapter->hw_caps.local_only) + { + enginei_invalidate_gart_e3k(engine); + } + + //current not consider seperate engine. + if(schedule->hw_hang) + { + return; + } + + // HW copy + if (bHwCopyEn) + { + pwmTrigger.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Indicator; + pwmTrigger.Block_Id = CSP_GLOBAL_BLOCK; + pwmTrigger.Type = BLOCK_COMMAND_CSP_TYPE_INDICATOR; + pwmTrigger.Info = BLK_CMD_CSP_INDICATOR_INFO_3D_MODE; + pwmTrigger.Dwc = 1; + trigger_Dw.Slice_Mask = adapter->hw_caps.chip_slice_mask; + + // save fence need more check + oldFence = *(unsigned long long*)(engine->fence_buffer_virt_addr + DH_FENCE_OFFSET); + *(engine->fence_buffer_virt_addr + DH_FENCE_OFFSET) = 0; + + while(Length && !schedule->hw_hang) + { + Width = MAX_WIDTH_2DBLT; + Height = Length/(Width << 2); + Height = Height > MAX_HEIGHT_2DBLT ? MAX_HEIGHT_2DBLT : Height; + + if(Length < (MAX_WIDTH_2DBLT << 2)) + { + Width = Length >> 2; + Height = 1; + } + + StartX = AddrOffset & 0xFF; + AddrOffset = AddrOffset - StartX; + + p2DBltCmd->SrcAddr.reg.Base_Addr = (SrcAddr + AddrOffset) >> 8; + p2DBltCmd->DstAddr.reg.Base_Addr = (DstAddr + AddrOffset) >> 8; + + p2DBltCmd->SrcFormat.reg.Format = Format; + p2DBltCmd->SrcFormat.reg.Bl_Slot_Idx = 0; + p2DBltCmd->SrcSize.reg.Width = Width; + p2DBltCmd->SrcSize.reg.Height = Height; + p2DBltCmd->SrcDepth.reg.Depth_Or_Arraysize = 1; + p2DBltCmd->SrcDepth.reg.Range_Type = 0; + p2DBltCmd->SrcViewCtrl.reg.Arraysize = 1; + p2DBltCmd->SrcViewCtrl.reg.First_Array_Idx = 0; + + p2DBltCmd->DstFormat = p2DBltCmd->SrcFormat; + p2DBltCmd->DstSize = p2DBltCmd->SrcSize; + p2DBltCmd->DstDepth = p2DBltCmd->SrcDepth; + p2DBltCmd->DstViewCtrl = p2DBltCmd->SrcViewCtrl; + + p2DBltCmd->SrcMisc.reg.Is_Tiling = 0; + p2DBltCmd->SrcMisc.reg.Rt_Enable = 1; + p2DBltCmd->SrcMisc.reg.Resource_Type = RT_MISC_RESOURCE_TYPE_2D_TEXTURE; + + p2DBltCmd->DstMisc.reg.Is_Tiling = 0; + p2DBltCmd->DstMisc.reg.Rt_Enable = 1; + p2DBltCmd->DstMisc.reg.Rt_Write_Mask = 0xF; + p2DBltCmd->DstMisc.reg.Resource_Type = RT_MISC_RESOURCE_TYPE_2D_TEXTURE; + p2DBltCmd->DstMisc.reg.Eu_Blend_Enable = 0; + + p2DBltCmd->Rast_Ctrl.reg.Eub_En = 0; + p2DBltCmd->reg_Iu_Ctrl_Ex.reg.Eu_Blending_En = 0; + p2DBltCmd->SrcMisc.reg.Eu_Blend_Enable = 0; + + p2DBltCmd->Dzs_Ctrl.reg.Src_Read_Alloc_En = 0; + + p2DBltCmd->RectX.Xmin = StartX >> 2;//in pixel + p2DBltCmd->RectX.Xmax = Width - 1; + p2DBltCmd->RectY.Ymin = 0; + p2DBltCmd->RectY.Ymax = Height - 1; + p2DBltCmd->SrcDxDy.Dx = 0; + p2DBltCmd->SrcDxDy.Dy = 0; + + p2DBltCmd->D_Flush.Type = BLOCK_COMMAND_TEMPLATE_TYPE_FLUSH; + p2DBltCmd->D_Flush.Target = BLOCK_COMMAND_FLUSH_TARGET_D_C; + p2DBltCmd->D_Flush.Block_Id = FF_BLOCK; + p2DBltCmd->D_Flush.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + + p2DBltCmd->D_Invalidate.Type = BLOCK_COMMAND_TEMPLATE_TYPE_INVALIDATE_CACHE; + p2DBltCmd->D_Invalidate.Target = BLOCK_COMMAND_FLUSH_TARGET_D_C; + p2DBltCmd->D_Invalidate.Block_Id = FF_BLOCK; + p2DBltCmd->D_Invalidate.Major_Opcode = CSP_OPCODE_Block_Command_Flush; + + p2DBltCmd->FenceCmd.uint = SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_D_FENCE,_RBT_3DBE, HWM_SYNC_KMD_SLOT); + p2DBltCmd->FenceValue = SEND_INTERNAL_FENCE_VALUE_E3K(FENCE_VALUE_CACHE_DMA_DFENCE); + p2DBltCmd->WaitCmd.uint = SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_DFENCE); + p2DBltCmd->WaitMainCmd.uint = SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_DFENCE); + + CmdLength = sizeof(BITBLT_REGSETTING_E3K)/sizeof(DWORD); + CmdLength = (((CmdLength + 5 + 4 + 8) + 15) & ~15); + + pRB = enginei_get_ring_buffer_space_e3k(engine, CmdLength); + pRB0 = pRB; + + gf_memset(pRB, 0, CmdLength << 2); + + *pRB++ = *(DWORD*)&pwmTrigger; + *pRB++ = *(DWORD*)&trigger_Dw; + pRB += 8; // skip 8dw for hw block sync + + gf_memcpy(pRB, p2DBltCmd, sizeof(BITBLT_REGSETTING_E3K)); + pRB =pRB + sizeof(BITBLT_REGSETTING_E3K)/sizeof(DWORD); + + *pRB++ = SEND_EXTERNAL_FENCE_E3K(FENCE_IRQ_INTERRUPT_CPU); + *pRB++ = (engine->fence_buffer_phy_addr + DH_FENCE_OFFSET * sizeof(unsigned long long)) & 0xFFFFFFFF; + *pRB++ = ((engine->fence_buffer_phy_addr + DH_FENCE_OFFSET * sizeof(unsigned long long)) >> 32 )& 0xFF; + + *pRB++ = (DH_FENCE_VALUE + i)&0xFFFFFFFF; + *pRB++ = (((unsigned long long)(DH_FENCE_VALUE + i)) >>32) &0xFFFFFFFF; + + *pRB++ = *(DWORD*)&pwmTrigger; + *pRB++ = *(DWORD*)&trigger_Dw; + + //to ensure cmd write in mem + if(adapter->ctl_flags.run_on_qt) + { + util_crc32((unsigned char*)pRB0, CmdLength << 2); + } + + sch_mgr->hang_hw_copy_mem = 1; + enginei_do_kickoff_cmd_e3k(engine); + + while((*(unsigned long long*)(engine->fence_buffer_virt_addr + DH_FENCE_OFFSET) + 2)<= (DH_FENCE_VALUE + i))//max kick 2 dma to hw + { + if(schedule->hw_hang) + { + sch_mgr->hang_hw_copy_mem = 0; + return; + } + else if(++Count < 0x20) + { + gf_msleep(10); + } + else + { + gf_info("%s, i:%d, fence not back, expect:%llx, fence in mem:%llx, hw queue dma num:%d\n",util_remove_name_suffix(__func__), i, (DH_FENCE_VALUE + i), *(unsigned long long*)(engine->fence_buffer_virt_addr + DH_FENCE_OFFSET), 2); + Count = 0; + sch_mgr->hang_hw_copy_mem = 0; + return; + } + } + + sch_mgr->hang_hw_copy_mem = 0; + i++; + + AddrOffset +=((Width * Height) << 2); + Length -=((Width * Height) << 2) + StartX; + } + + Count = 0; + + while(*(unsigned long long*)(engine->fence_buffer_virt_addr + DH_FENCE_OFFSET) != (DH_FENCE_VALUE + i -1)) + { + if(schedule->hw_hang) + { + return; + } + else if(++Count < 0x20) + { + gf_msleep(10); + } + else + { + gf_info("%s, i:%d, fence not back, expect:%llx, fence in mem:%llx, out of loop\n",util_remove_name_suffix(__func__), i, (DH_FENCE_VALUE + i), *(unsigned long long*)(engine->fence_buffer_virt_addr + DH_FENCE_OFFSET)); + Count = 0; + return; + } + } + + // restore fence + *(unsigned long long*)(engine->fence_buffer_virt_addr + DH_FENCE_OFFSET) = oldFence; + } + else if(src_virt_addr !=NULL && dst_virt_addr != NULL) + { + gf_memcpy(dst_virt_addr, src_virt_addr, total_size); + } + else + { + gf_error("hw copy not enable, VA is null\n"); + gf_assert(0, NULL); + } +} + +void vidsch_duplicate_hang_e3k(adapter_t *adapter) +{ + engine_share_e3k_t *share = adapter->private_data; + vidsch_mgr_t *sch_mgr = NULL; + engine_e3k_t *engine = NULL; + + dh_file_info_e3k dh_file_info = {0}; + dh_common_info_e3k *dh_common_info = NULL; + dh_rb_info_e3k *dh_rb_info = NULL; + unsigned int *rb = NULL; + unsigned char *ring_buffer = NULL; + RINGBUFFER_COMMANDS_E3K *submit_cmd = NULL; + + EngineSatus_e3k status_save = {0}, status_run = {0}; + unsigned int *status = NULL; + unsigned long long sent_counter = 0, returned_counter = 0; + unsigned long long *pReturnCounter = NULL; + gf_vm_area_t *fb_vma = NULL; + gf_map_argu_t map = {0}; + unsigned long long Dst_PA = 0; + unsigned long long Src_PA = 0; + int i = 0; + long long length = 0; + int len = 0; + + struct os_file *file = NULL; + unsigned long long pos = 0; + + int pool_index = 0; + unsigned int rb_index = 0; + unsigned long long dma_buffer_pa = 0; + unsigned long long context_buffer_pa = 0; + void *dma_buffer_va = NULL; + void *context_buffer_va = NULL; + RINGBUFFER_COMMANDS_E3K *rb_va = NULL; + + unsigned long long start_time = 0, current_time, delta_time; + long temp_sec, temp_usec; + unsigned long long batch_size = 0; + +#if COMPATIBLE_TO_WINDOW + vidsch_duplicate_hang_compatible_e3k(adapter); + return; +#endif + + if(!debug_mode_e3k.duplicate_hang) + { + return; + } + debug_mode_e3k.duplicate_hang = 0; + + file = gf_file_open("/var/fb.FB", OS_RDWR | OS_LARGEFILE, 0666); + if(!file) + { + gf_error("vidsch_duplicate_hang_e3k open file /var/fb.FB fail.\n"); + return; + } + + //1. load file info in file header + len = gf_file_read(file, &dh_file_info, sizeof(dh_file_info_e3k), &pos); + READ_DUMP_FILE_CHECK(sizeof(dh_file_info_e3k), len); + gf_assert(share->dma_buffer_for_hang->gpu_virt_addr >= dh_file_info.FbCpuVisibleSize, NULL); + gf_info("vidsch_duplicate_hang_e3k visible_size:0x%llx, invisible_size:0x%llx, dma_size:0x%llx, context_size:0x%llx, rb_size:0x%llx\n", dh_file_info.FbCpuVisibleSize, dh_file_info.FbNotCpuVisibleSize.quad64, dh_file_info.dma_for_hang_size, dh_file_info.context_for_hang_size, dh_file_info.ring_for_hang_size); + + //2. load dma buffer + len = gf_file_read(file, share->dma_buffer_for_hang->vma->virt_addr, E3K_DMABUFFER_FOR_HANG_SIZE, &pos); + READ_DUMP_FILE_CHECK(E3K_DMABUFFER_FOR_HANG_SIZE, len); + + //3. load context buffer + len = gf_file_read(file, share->context_buffer_for_hang->vma->virt_addr, E3K_CONTEXTBUFFER_FOR_HANG_SIZE, &pos); + READ_DUMP_FILE_CHECK(E3K_CONTEXTBUFFER_FOR_HANG_SIZE, len); + + //4. load ring buffer + len = gf_file_read(file, share->ring_buffer_for_hang->vma->virt_addr, E3K_RINGBUFFER_FOR_HANG_SIZE, &pos); + READ_DUMP_FILE_CHECK(E3K_RINGBUFFER_FOR_HANG_SIZE, len); + + //5 load cpu invisible segment mem + gf_info("vidsch_duplicate_hang_e3k start load cpu invisible memory...\n"); + length = dh_file_info.FbNotCpuVisibleSize.quad64; + Src_PA = share->transfer_buffer_for_hang->gpu_virt_addr; + Dst_PA = adapter->Visible_vram_size; + batch_size = (adapter->ctl_flags.run_on_qt)?(E3K_TRANSFERBUFFER_FOR_HANG_SIZE>>8) : E3K_TRANSFERBUFFER_FOR_HANG_SIZE; + while(length > 0) + { + unsigned long long copy_size = (length > batch_size)?batch_size : length; + len = gf_file_read(file, share->transfer_buffer_for_hang->vma->virt_addr, copy_size, &pos); + READ_DUMP_FILE_CHECK(copy_size, len); + vidschi_copy_mem_e3k(adapter,Dst_PA,NULL,Src_PA,NULL,copy_size); + Dst_PA += copy_size; + length -= copy_size; + + gf_info("vidsch_duplicate_hang_e3k left cpu invisible segment mem:0x%llx\n", length); + } + gf_info("vidsch_duplicate_hang_e3k end load cpu invisible memory...\n"); + + //1.6 load cpu visible segment mem + gf_info("vidsch_duplicate_hang_e3k start load cpu visible memory...\n"); + length = dh_file_info.FbCpuVisibleSize; + while(length > 0) + { + map.size = (length >= MIU_DYNAMIC_FB_ENTRY_SIZE) ? MIU_DYNAMIC_FB_ENTRY_SIZE : length; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.read_only = 0; + map.flags.write_only = 0; + map.flags.mem_type = GF_SYSTEM_IO; + map.flags.cache_type = GF_MEM_UNCACHED; + map.phys_addr = adapter->vidmm_bus_addr + i*MIU_DYNAMIC_FB_ENTRY_SIZE; + + fb_vma = gf_map_io_memory(NULL, &map); + gf_assert(fb_vma != NULL, NULL); + + gf_file_read(file, fb_vma->virt_addr, map.size, &pos); + gf_unmap_io_memory(fb_vma); + fb_vma = NULL; + + i++; + + length -= map.size; + gf_info("vidsch_duplicate_hang_e3k left cpu visible segment mem:%llx\n", length); + } + gf_info("vidsch_duplicate_hang_e3k end load cpu visible memory...\n"); + gf_file_close(file); + + dh_common_info = (dh_common_info_e3k*)(vidschi_get_dump_data_cpu_virt_addr_e3k(adapter, HANG_DUMP_DH_COMMON_INFO_OFFSET, 0)); + pool_index = dh_common_info->hang_dma_index; + gf_info("vidsch_duplicate_hang_e3k hang_dma_fence_id:%d, hang_dma_index:%d\n", dh_common_info->hang_dma_fence_id, dh_common_info->hang_dma_index); + + dma_buffer_pa = vidschi_get_dump_data_gpu_offset_e3k(adapter, HANG_DUMP_DMA_BUFFER_OFFSET, pool_index); + dma_buffer_va = vidschi_get_dump_data_cpu_virt_addr_e3k(adapter, HANG_DUMP_DMA_BUFFER_OFFSET, pool_index); + context_buffer_pa = vidschi_get_dump_data_gpu_offset_e3k(adapter, HANG_DUMP_CONTEXT_BUFFER_OFFSET, pool_index); + context_buffer_va = vidschi_get_dump_data_cpu_virt_addr_e3k(adapter, HANG_DUMP_CONTEXT_BUFFER_OFFSET, pool_index); + ring_buffer = vidschi_get_dump_data_cpu_virt_addr_e3k(adapter, HANG_DUMP_RING_BUFFER_OFFSET, pool_index); + dh_rb_info = (dh_rb_info_e3k*)ring_buffer; + ring_buffer += sizeof(dh_rb_info_e3k); + rb_va = (RINGBUFFER_COMMANDS_E3K*)ring_buffer; + util_dump_memory(NULL, rb_va, sizeof(RINGBUFFER_COMMANDS_E3K), "vidsch_duplicate_hang_e3k ring buffer"); + gf_info("vidsch_duplicate_hang_e3k slice mask:0x%x\n", rb_va->c1.trigger_Dw.Slice_Mask); + util_dump_memory(NULL, dma_buffer_va, 64*1024, "vidsch_duplicate_hang_e3k dma buffer"); + + sch_mgr = adapter->sch_mgr[dh_rb_info->last_rb_index]; + engine = sch_mgr->private_data; + rb_index = dh_rb_info->last_rb_index; + status_save = dh_rb_info->status; + length = dh_rb_info->last_rb_size >>2; + + sent_counter = DH_FENCE_VALUE; + pReturnCounter = engine->fence_buffer_virt_addr + DH_FENCE_OFFSET; + *pReturnCounter = DH_FENCE_VALUE; + returned_counter = *pReturnCounter; + + status = (unsigned int *)&status_run; + for(i = 0; i < 7; i++) + { + *(status + i) = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + (Reg_Block_Busy_Bits_Top_Offset + i)*4); + } + gf_info("vidsch_duplicate_hang_e3k before do kickoff status: %08x,%08x,%08x,%08x,%08x,%08x,%08x\n",status_run.Top.uint,status_run.Gpc0_0.uint,status_run.Gpc0_1.uint,status_run.Gpc1_0.uint,status_run.Gpc1_1.uint,status_run.Gpc2_0.uint,status_run.Gpc2_1.uint); + + switch(rb_index) + { + case RB_INDEX_GFXL: + { + rb = enginei_get_ring_buffer_space_e3k(engine, length); + gf_memcpy((void*)rb, (void*)ring_buffer, length << 2 ); + submit_cmd = (RINGBUFFER_COMMANDS_E3K*)rb; + //patch restore dma address + if(submit_cmd->c0.RestoreContext_Address != 0) + { + submit_cmd->c0.RestoreContext_Address = (context_buffer_pa >> 11); + } + + //patch dma adress + submit_cmd->c0.CommandDMA_Address_L = (dma_buffer_pa & 0xFFFFFFFF); + submit_cmd->c0.CommandDMA_Address_H = ((dma_buffer_pa >>32) & 0xFF); + + //patch save dma address. + //Assume the hang task dma not the first dma, since the context_buffer_pa for save will overwrite the template. + gf_memset(&submit_cmd->c0.SaveDMA, 0, 4*sizeof(DWORD)); + sent_counter++; + *(unsigned int*)&submit_cmd->c0.Fence = SEND_EXTERNAL_FENCE_E3K(FENCE_IRQ_INTERRUPT_CPU); + submit_cmd->c0.Fence_Data_L = (sent_counter) & 0xFFFFFFFF; + submit_cmd->c0.Fence_Data_H = ((sent_counter) >>32) & 0xFFFFFFFF; + submit_cmd->c0.Fence_Address_L = (engine->fence_buffer_phy_addr + DH_FENCE_OFFSET * sizeof(unsigned long long)) & 0xFFFFFFFF; + submit_cmd->c0.Fence_Address_H = ((engine->fence_buffer_phy_addr + DH_FENCE_OFFSET * sizeof(unsigned long long)) >> 32) & 0xFFFFFFFF; + + enginei_do_kickoff_cmd_e3k(engine); + break; + } + case RB_INDEX_GFXH: + gf_error("vidsch_duplicate_hang_e3k RB_INDEX_GFXH not supported...\n"); + break; + } + + //wait for hang + gf_getsecs(&temp_sec, &temp_usec); + start_time = temp_sec; + for(;;) + { + gf_getsecs(&temp_sec, &temp_usec); + current_time = temp_sec; + delta_time = current_time - start_time; + + /* wait 10s, if fence still not back seems something wrong */ + if(delta_time > DUPLICATE_TIME_OUT) + { + break; + } + } + returned_counter = *pReturnCounter; + gf_info("vidsch_duplicate_hang_e3k after wait sent_counter=0x%llx, return_counter=0x%llx\n", sent_counter, returned_counter); + + status = (unsigned int *)&status_run; + for( i = 0; i <7; i++) + { + *(status + i) = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + (Reg_Block_Busy_Bits_Top_Offset + i)*4); + } + + gf_info("vidsch_duplicate_hang_e3k after do kickoff status: %08x,%08x,%08x,%08x,%08x,%08x,%08x\n",status_run.Top.uint,status_run.Gpc0_0.uint,status_run.Gpc0_1.uint,status_run.Gpc1_0.uint,status_run.Gpc1_1.uint,status_run.Gpc2_0.uint,status_run.Gpc2_1.uint); + gf_info("vidsch_duplicate_hang_e3k hang dump save status: %08x,%08x,%08x,%08x,%08x,%08x,%08x\n",status_save.Top.uint,status_save.Gpc0_0.uint,status_save.Gpc0_1.uint,status_save.Gpc1_0.uint,status_save.Gpc1_1.uint,status_save.Gpc2_0.uint,status_save.Gpc2_1.uint); + + vidsch_display_debugbus_info_e3k(adapter, NULL, FALSE); + + if((status_save.Top.uint & 0xFFFFFFF9) == (status_run.Top.uint & 0xFFFFFFF9) && //exclude mxua/b, diu will use it, even 3d hang. + (status_save.Gpc0_0.uint == status_run.Gpc0_0.uint) && + (status_save.Gpc0_1.uint == status_run.Gpc0_1.uint) && + (status_save.Gpc1_0.uint == status_run.Gpc1_0.uint) && + (status_save.Gpc1_1.uint == status_run.Gpc1_1.uint) && + (status_save.Gpc2_0.uint == status_run.Gpc2_0.uint) && + (status_save.Gpc2_1.uint == status_run.Gpc2_1.uint)) + { + if (status_save.Top.uint == 0 && status_run.Top.uint == 0) + { + gf_info("vidsch_duplicate_hang_e3k <<-------------------:) not duplicate hang, Status is same but not hang------------------------>>.\n"); + gf_assert(0, "vidsch_duplicate_hang_e3k <<-------------------:( Do more check !! ------------------------>>\n"); + } + else + { + gf_info("vidsch_duplicate_hang_e3k <<-------------------:) Good job!, Status is same.------------------------>>.\n"); + gf_assert(0, "vidsch_duplicate_hang_e3k <<-------------------:) Congratulation!! ------------------------>>\n"); + } + } + else + { + gf_info("vidsch_duplicate_hang_e3k <<------------------:( Sorry, Status is different.-------------------------->>.\n"); + gf_assert(0, "vidsch_duplicate_hang_e3k <<-------------------:( Do more check !! ------------------------>>\n"); + } +} + +void vidsch_dump_hang_e3k(adapter_t *adapter) +{ + engine_share_e3k_t *share = adapter->private_data; + + vidmm_segment_memory_t *dma_buffer_for_hang = share->dma_buffer_for_hang; + vidmm_segment_memory_t *context_buffer_for_hang = share->context_buffer_for_hang; + vidmm_segment_memory_t *ring_buffer_for_hang = share->ring_buffer_for_hang; + + struct os_file *file = NULL; + long long length = 0; + dh_file_info_e3k dh_file_info; + unsigned long long Dst_PA = 0; + unsigned long long Src_PA = 0; + + int len = 0; + EngineSatus_e3k current_status = {0}; + unsigned int *status = NULL; + int i = 0; + + dh_common_info_e3k *dh_common_info = NULL; + +#if COMPATIBLE_TO_WINDOW + vidsch_dump_hang_compatible_e3k(adapter); + + return; +#endif + + if(!debug_mode_e3k.post_hang_dump) + { + gf_error("vidsch_dump_hang_e3k skip this function, status error...\n"); + return; + } + + debug_mode_e3k.internal_dump_hw = 1; + + if(!file) + { + file = gf_file_open("/var/fb.FB", OS_RDWR | OS_CREAT | OS_LARGEFILE, 0666); + if(!file) + { + gf_error("vidsch_dump_hang_e3k create file: create file /var/fb.FB fail!\n"); + return; + } + } + + dh_file_info.FbCpuVisibleSize = dma_buffer_for_hang->gpu_virt_addr; + dh_file_info.FbNotCpuVisibleSize.quad64 = adapter->Real_vram_size - adapter->Visible_vram_size + adapter->gart_ram_size; + dh_file_info.dma_for_hang_size = E3K_DMABUFFER_FOR_HANG_SIZE; + dh_file_info.context_for_hang_size = E3K_CONTEXTBUFFER_FOR_HANG_SIZE; + dh_file_info.ring_for_hang_size = E3K_RINGBUFFER_FOR_HANG_SIZE; + gf_info("vidsch_dump_hang_e3k visible_size:0x%llx, invisible_size:0x%llx, dma_size:0x%llx, context_size:0x%llx, rb_size:0x%llx\n", dh_file_info.FbCpuVisibleSize, dh_file_info.FbNotCpuVisibleSize.quad64, dh_file_info.dma_for_hang_size, dh_file_info.context_for_hang_size, dh_file_info.ring_for_hang_size); + + //1. save file info + len = gf_file_write(file, &dh_file_info, sizeof(dh_file_info_e3k)); + WRITE_DUMP_FILE_CHECK(sizeof(dh_file_info_e3k), len); + + status = (unsigned int *)¤t_status; + for(i = 0; i < 7; i++) + { + *(status + i) = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + (Reg_Block_Busy_Bits_Top_Offset + i)*4); + } + gf_info("vidsch_dump_hang_e3k current status: %08x,%08x,%08x,%08x,%08x,%08x,%08x\n",current_status.Top.uint,current_status.Gpc0_0.uint,current_status.Gpc0_1.uint,current_status.Gpc1_0.uint,current_status.Gpc1_1.uint,current_status.Gpc2_0.uint,current_status.Gpc2_1.uint); + + dh_common_info = (dh_common_info_e3k*)(vidschi_get_dump_data_cpu_virt_addr_e3k(adapter, HANG_DUMP_DH_COMMON_INFO_OFFSET, 0)); + gf_info("vidsch_dump_hang_e3k hang_dma_fence_id:%d, hang_dma_index:%d\n", dh_common_info->hang_dma_fence_id, dh_common_info->hang_dma_index); + + //2. save dma buffer + len = gf_file_write(file, dma_buffer_for_hang->vma->virt_addr, E3K_DMABUFFER_FOR_HANG_SIZE); + WRITE_DUMP_FILE_CHECK(E3K_DMABUFFER_FOR_HANG_SIZE, len); + // util_dump_memory(NULL, dma_buffer_for_hang->vma->virt_addr + dh_common_info->hang_dma_index*dma_buffer_block_size, dma_buffer_block_size, "vidsch_dump_hang_e3k dma buffer"); + + //3. save context buffer + len = gf_file_write(file, context_buffer_for_hang->vma->virt_addr, E3K_CONTEXTBUFFER_FOR_HANG_SIZE); + WRITE_DUMP_FILE_CHECK(E3K_CONTEXTBUFFER_FOR_HANG_SIZE, len); + // util_dump_memory(NULL, context_buffer_for_hang->vma->virt_addr+ dh_common_info->hang_dma_index*context_buffer_block_size, context_buffer_block_size, "vidsch_dump_hang_e3k context buffer"); + + //4. save ring buffer + len = gf_file_write(file, ring_buffer_for_hang->vma->virt_addr, E3K_RINGBUFFER_FOR_HANG_SIZE); + WRITE_DUMP_FILE_CHECK(E3K_RINGBUFFER_FOR_HANG_SIZE, len); + // util_dump_memory(NULL, ring_buffer_for_hang->vma->virt_addr+ dh_common_info->hang_dma_index*ring_buffer_block_size, ring_buffer_block_size, "vidsch_dump_hang_e3k ring buffer"); + + //5. save cpu invisible segment mem. + gf_info("vidsch_dump_hang_e3k start dump invisible memory...\n"); + length = dh_file_info.FbNotCpuVisibleSize.quad64; + Dst_PA = share->transfer_buffer_for_hang->gpu_virt_addr; + Src_PA = adapter->Visible_vram_size; + while(length > adapter->gart_ram_size) + { + unsigned long long copy_size = (length > E3K_TRANSFERBUFFER_FOR_HANG_SIZE)?E3K_TRANSFERBUFFER_FOR_HANG_SIZE : length; + + vidschi_copy_mem_e3k(adapter, Dst_PA, NULL, Src_PA, NULL, copy_size); + + len = gf_file_write(file, share->transfer_buffer_for_hang->vma->virt_addr, copy_size); + WRITE_DUMP_FILE_CHECK(copy_size, len); + + Src_PA += copy_size; + length -= copy_size; + + gf_info("vidsch_dump_hang_e3k left cpu invisible segment mem:0x%llx\n", length - adapter->gart_ram_size); + } + + //5.1 snoop/non-snoop segment mem. + Src_PA = adapter->Real_vram_size; + while(length > 0) + { + unsigned long long copy_size = (length > E3K_TRANSFERBUFFER_FOR_HANG_SIZE)?E3K_TRANSFERBUFFER_FOR_HANG_SIZE : length; + + vidschi_copy_mem_e3k(adapter, + Dst_PA, + NULL, + Src_PA, + NULL, + copy_size); + + len = gf_file_write(file, share->transfer_buffer_for_hang->vma->virt_addr, copy_size); + WRITE_DUMP_FILE_CHECK(copy_size, len); + + Src_PA += copy_size; + length -= copy_size; + + gf_info("vidsch_dump_hang_e3k left snoop/non-snoop segment mem:%llx\n", length); + } + + gf_info("vidsch_dump_hang_e3k end dump invisible memory...\n"); + + //6. save cpu visible segment memory. + gf_info("vidsch_dump_hang_e3k start dump visible memory...\n"); + length = dh_file_info.FbCpuVisibleSize; + Src_PA = 0; + Dst_PA = share->transfer_buffer_for_hang->gpu_virt_addr; + while(length > 0) + { + unsigned long long copy_size = (length > E3K_TRANSFERBUFFER_FOR_HANG_SIZE)?E3K_TRANSFERBUFFER_FOR_HANG_SIZE : length; + + vidschi_copy_mem_e3k(adapter, + Dst_PA, + NULL, + Src_PA, + NULL, + copy_size); + + len = gf_file_write(file, share->transfer_buffer_for_hang->vma->virt_addr, copy_size); + WRITE_DUMP_FILE_CHECK(copy_size, len); + + Src_PA += copy_size; + length -= copy_size; + + gf_info("vidsch_dump_hang_e3k left cpu visiable segment mem:%llx\n", length); + } +#if 0 + while(length > 0) + { + map.size = (length >= MIU_DYNAMIC_FB_ENTRY_SIZE) ? MIU_DYNAMIC_FB_ENTRY_SIZE : length; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.cache_type = GF_MEM_UNCACHED; + map.phys_addr = adapter->vidmm_bus_addr + i*MIU_DYNAMIC_FB_ENTRY_SIZE; + map.flags.mem_type = GF_SYSTEM_IO; + fb_vma = gf_map_io_memory(NULL, &map); + + gf_assert(fb_vma != NULL, NULL); + + //gf_info(" save fb vidmm base 0x%x, fb phys 0x%x, fb virt addr 0x%x \n", adapter->vidmm_bus_addr, map.phys_addr, fb_vma->virt_addr); + + len = gf_file_write(file, fb_vma->virt_addr, map.size); + WRITE_DUMP_FILE_CHECK(map.size, len); + + gf_unmap_io_memory(fb_vma); + fb_vma = NULL; + i++; + length -= map.size; + gf_info("[DUMP HANG] left cpu visible segment mem:%llx\n", length); + } +#endif + gf_info("vidsch_dump_hang_e3k end dump visible memory...\n"); + gf_file_close(file); + gf_msleep(50000); + gf_assert(0, "vidsch_dump_hang_e3k save to file successed"); +} + +int vidsch_save_misc_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr, unsigned int what_to_save) +{ + engine_e3k_t *engine = sch_mgr->private_data; + + dh_common_info_e3k *dh_common_info; + + dh_common_info = (dh_common_info_e3k*)(vidschi_get_dump_data_cpu_virt_addr_e3k(adapter, HANG_DUMP_DH_COMMON_INFO_OFFSET, 0)); + + //save dma buffer and context buffer + if(what_to_save == SAVE_BEFORE_POSTHANG) + { + dh_common_info->current_hang_dump_index = (dh_common_info->current_hang_dump_index + 1) % MAX_HANG_DUMP_DATA_POOL_NUMBER; + dh_common_info->hang_dump_counter++; +#if NEW_DUMP + +#else + + unsigned long long buffer_phys_addr; + unsigned char* buffer_virt_addr; + + if(engine->last_dma_buffer) + { + buffer_virt_addr = vidschi_get_dump_data_cpu_virt_addr_e3k(adapter, HANG_DUMP_DMA_BUFFER_OFFSET, dh_common_info->current_hang_dump_index); + gf_memcpy((void*)buffer_virt_addr, engine->last_dma_buffer, engine->last_dma_buffer_size_uint<<2); + } + + if(engine->context_buffer_to_restore_addr) + { + buffer_phys_addr = vidschi_get_dump_data_gpu_offset_e3k(adapter, HANG_DUMP_CONTEXT_BUFFER_OFFSET, dh_common_info->current_hang_dump_index); + buffer_virt_addr = vidschi_get_dump_data_cpu_virt_addr_e3k(adapter, HANG_DUMP_CONTEXT_BUFFER_OFFSET, dh_common_info->current_hang_dump_index); + + vidschi_copy_mem_e3k(adapter, + buffer_phys_addr, + buffer_virt_addr, + engine->context_buffer_to_restore_addr, + NULL, + CONTEXT_BUFFER_SIZE); + } +#endif + } + + else if(what_to_save == SAVE_AFTER_POSTHANG) + { + dh_rb_info_e3k *dh_rb_info; + unsigned char *ring_buffer = NULL; + + //save hang info to common info + dh_common_info->hang_dma_fence_id = sch_mgr->hang_fence_id; + dh_common_info->hang_dma_index = sch_mgr->hang_index; + gf_info("vidsch_save_misc_e3k hang fence id:%d index:%d\n", dh_common_info->hang_dma_fence_id, dh_common_info->hang_dma_index); + //save status + ring_buffer = vidschi_get_dump_data_cpu_virt_addr_e3k(adapter, HANG_DUMP_RING_BUFFER_OFFSET, dh_common_info->hang_dma_index); + dh_rb_info = (dh_rb_info_e3k*)ring_buffer; + ring_buffer += sizeof(dh_rb_info_e3k); + dh_rb_info->status = engine->dumped_engine_status; + + gf_info("vidsch_save_misc_e3k save status: %08x,%08x,%08x,%08x,%08x,%08x,%08x\n", + dh_rb_info->status.Top.uint,dh_rb_info->status.Gpc0_0.uint,dh_rb_info->status.Gpc0_1.uint, + dh_rb_info->status.Gpc1_0.uint,dh_rb_info->status.Gpc1_1.uint,dh_rb_info->status.Gpc2_0.uint,dh_rb_info->status.Gpc2_1.uint); + } + else if(what_to_save == SAVE_RING_BUFFER) + { + dh_rb_info_e3k *dh_rb_info; + unsigned char *ring_buffer = NULL; + EngineSatus_e3k status = {0}; + + //save ring buffer + ring_buffer = vidschi_get_dump_data_cpu_virt_addr_e3k(adapter, HANG_DUMP_RING_BUFFER_OFFSET, dh_common_info->current_hang_dump_index); + dh_rb_info = (dh_rb_info_e3k*)ring_buffer; + ring_buffer += sizeof(dh_rb_info_e3k); + dh_rb_info->status = status; + dh_rb_info->last_rb_index = sch_mgr->engine_index; + + switch(sch_mgr->engine_index) + { + case RB_INDEX_GFXL: + dh_rb_info->last_rb_size = engine->last_ring_buffer_size; + gf_memcpy((void*)ring_buffer, engine->last_ring_buffer, engine->last_ring_buffer_size); + break; + case RB_INDEX_GFXH: + case RB_INDEX_VCP0: + case RB_INDEX_VCP1: + case RB_INDEX_VPP: + default: + gf_error("Not yet add support engine hang..., engine:%d\n", sch_mgr->engine_index); + } + } + return dh_common_info->current_hang_dump_index; +} + +void vidsch_handle_dbg_hang_dump_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr, task_dma_t *task_dma) +{ + engine_e3k_t *engine = sch_mgr->private_data; + engine_share_e3k_t *share = engine->share; + hw_ctxbuf_t *hwctx_info = task_dma->hw_ctx_info; + + if(debug_mode_e3k.post_hang_dump) + { + if (task_dma->need_hwctx_switch) + { + if (!hwctx_info->is_initialized) + { + engine->context_buffer_to_restore_addr = share->context_buf_phy_addr; + } + else + { + engine->context_buffer_to_restore_addr = hwctx_info->context_buffer_address; + } + } + else + { + engine->context_buffer_to_restore_addr = 0; + } + task_dma->desc.hang_index = vidsch_save_misc_e3k(adapter, sch_mgr, SAVE_BEFORE_POSTHANG); + if (task_dma->need_hwctx_switch) + { + task_dma->desc.hang_context = vidschi_get_dump_data_gpu_offset_e3k(adapter, HANG_DUMP_CONTEXT_BUFFER_OFFSET, task_dma->desc.hang_index); + } + } +} diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_e3k.h b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_e3k.h new file mode 100644 index 0000000000000..71d789a772971 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_debug_hang_e3k.h @@ -0,0 +1,405 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __VIDSCH_DEBUG_HANG_E3K_H__ +#define __VIDSCH_DEBUG_HANG_E3K_H__ + +#include "vidsch_engine_e3k.h" +#include "vidsch_dump_image_e3k.h" + +typedef enum DEBUG_BUS_SCOPE { + WHOLE_SCOPE_DEBUG_BUS = 0, + CHIP1_SCOPE_DEBUG_BUS = 1, + CHIP2_SCOPE_DEBUG_BUS = 2, + CHIP3_SCOPE_DEBUG_BUS = 3, +}DEBUG_BUS_SCOPE; + +typedef struct debug_bus_write_reg +{ + unsigned int group_start_offset; + unsigned int group_end_offset; + //Now Arise and Arise1020 max only need write 3 register + //most case only need write 2 + unsigned int write_reg_number; + unsigned int write_reg_offset[3]; + unsigned int write_reg_mask[3]; +}debug_bus_write_reg; + +typedef struct debug_bus_readback_reg +{ + unsigned int mmio_offset_0; + unsigned int mmio_offset_1; + unsigned int mmio_offset_2; + unsigned int mmio_offset_3; +}debug_bus_readback_reg; + +typedef struct reg_write_readback_info +{ + debug_bus_write_reg debugBusWrite; + debug_bus_readback_reg debugBusReadback; +}reg_write_readback_info; + +typedef struct debug_bus_info +{ + char group_name[50]; + DEBUG_BUS_SCOPE scope; + unsigned int gpcIndex; + reg_write_readback_info regOpinfo; +}debug_bus_info; + +static const debug_bus_info debug_bus_info_E3K[] = +{ + //group_name scope gpcIndex {{group_start_offset,group_start_offset,write_reg_number,write_reg_offset[3],write_reg_mask[3]}, + // {mmio_offset_0,mmio_offset_1,mmio_offset_2,mmio_offset_3}} + + //GPC0 + "GFVD0 group" ,CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x2000,0x201F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "CMU group" ,CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x2800,0x29FF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "MIU2 group" ,CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x3000,0x301F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "BIU0 group" ,CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x3800,0x3809,3,0x88C8,0x88CC,0x88CF,0x3800,0x0700,0x00FF },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "BIU1 group" ,CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x3C00,0x3F7F,3,0x88C8,0x88CC,0x88CF,0x3800,0x0700,0x00FF },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "SLICE0 EUC group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0000,0x00FF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 PEA group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0100,0x017F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 PEB group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0180,0x01FF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 TU group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0200,0x023F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 FFU group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0280,0x02FF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "SLICE1 EUC group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0400,0x04FF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 PEA group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0500,0x057F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 PEB group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0580,0x05FF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 TU group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0600,0x063F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 FFU group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0680,0x06FF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "SLICE2 EUC group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0800,0x08FF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE2 PEA group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0900,0x097F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE2 PEB group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0980,0x09FF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE2 TU group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0A00,0x0A3F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE2 FFU group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0A80,0x0AFF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "SLICE3 EUC group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0C00,0x0CFF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE3 PEA group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0D00,0x0D7F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE3 PEB group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0D80,0x0DFF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE3 TU group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0E00,0x0E3F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE3 FFU group",CHIP1_SCOPE_DEBUG_BUS, 0,{ { 0x0E80,0x0EFF,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "GPC CENTRAL SPTFE group", CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x1000,0x103F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "GPC CENTRAL SGTBE group", CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x1800,0x183F,2,0x88C8,0x88C9,0,0x3F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + //GPC1 + "GFVD1 group" ,CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x2000,0x201F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "MXUB group" ,CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x2800,0x28FF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "MIU1 group" ,CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x3000,0x301F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "L2 group" ,CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x3800,0x387F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + + "SLICE0 EUC group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0000,0x00FF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE0 PEA group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0100,0x017F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE0 PEB group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0180,0x01FF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE0 TU group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0200,0x023F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE0 FFU group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0280,0x02FF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + + "SLICE1 EUC group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0400,0x04FF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE1 PEA group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0500,0x057F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE1 PEB group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0580,0x05FF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE1 TU group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0600,0x063F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE1 FFU group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0680,0x06FF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + + "SLICE2 EUC group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0800,0x08FF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE2 PEA group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0900,0x097F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE2 PEB group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0980,0x09FF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE2 TU group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0A00,0x0A3F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE2 FFU group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0A80,0x0AFF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + + "SLICE3 EUC group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0C00,0x0CFF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE3 PEA group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0D00,0x0D7F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE3 PEB group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0D80,0x0DFF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE3 TU group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0E00,0x0E3F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "SLICE3 FFU group",CHIP2_SCOPE_DEBUG_BUS, 1,{ { 0x0E80,0x0EFF,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + + "GPC CENTRAL SPTFE group", CHIP2_SCOPE_DEBUG_BUS,1,{ { 0x1000,0x103F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + "GPC CENTRAL SGTBE group", CHIP2_SCOPE_DEBUG_BUS,1,{ { 0x1800,0x183F,2,0x88CA,0x88CB,0,0x3F00,0x00FF,0 },{ 0x88C4,0x88C5,0x88C6,0x88C7 } }, + + //GPC2 + "VPP group" ,CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x2000,0x207F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "MIU0 group" ,CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x2800,0x281F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "DIU group" ,CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x3000,0x3EE6,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + + "SLICE0 EUC group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0000,0x00FF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE0 PEA group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0100,0x017F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE0 PEB group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0180,0x01FF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE0 TU group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0200,0x023F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE0 FFU group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0280,0x02FF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + + "SLICE1 EUC group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0400,0x04FF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE1 PEA group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0500,0x057F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE1 PEB group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0580,0x05FF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE1 TU group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0600,0x063F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE1 FFU group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0680,0x06FF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + + "SLICE2 EUC group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0800,0x08FF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE2 PEA group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0900,0x097F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE2 PEB group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0980,0x09FF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE2 TU group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0A00,0x0A3F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE2 FFU group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0A80,0x0AFF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + + "SLICE3 EUC group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0C00,0x0CFF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE3 PEA group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0D00,0x0D7F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE3 PEB group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0D80,0x0DFF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE3 TU group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0E00,0x0E3F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "SLICE3 FFU group",CHIP3_SCOPE_DEBUG_BUS, 2,{ { 0x0E80,0x0EFF,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + + "GPC CENTRAL SPTFE group", CHIP3_SCOPE_DEBUG_BUS,2,{ { 0x1000,0x103F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, + "GPC CENTRAL SGTBE group", CHIP3_SCOPE_DEBUG_BUS,2,{ { 0x1800,0x183F,2,0x88CC,0x88CF,0,0x3F00,0x00FF,0 },{ 0x88FC,0x88FD,0x88FE,0x88FF } }, +}; + +static const debug_bus_info debug_bus_info_Arise1020[] = +{ + //group_name scope gpcIndex {{group_start_offset,group_start_offset,write_reg_number,write_reg_offset[3],write_reg_mask[3]}, + // {mmio_offset_0,mmio_offset_1,mmio_offset_2,mmio_offset_3}} + + //GPC0 + "GFVD0 group" ,CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x2000,0x27FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "CMU group" ,CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x2800,0x2FFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + //BIU need keep 0xA01F0[31] = 1, so change 0x3800 to 0x80003800 fit this + "BIU Peri group" ,CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x3800,0x3809,3,0x88C8,0x88C9,0xA01F0,0x7F00,0x00FF,0x7FFF},{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "BIU PCIE group" ,CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x3C00,0x3F7F,3,0x88C8,0x88C9,0xA01F0,0x7F00,0x00FF,0x7FFF},{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "MIU0 group" ,CHIP2_SCOPE_DEBUG_BUS,0,{ { 0x3000,0x37FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "VPP group" ,CHIP2_SCOPE_DEBUG_BUS,0,{ { 0x4000,0x47FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "DIU group" ,CHIP2_SCOPE_DEBUG_BUS,0,{ { 0x5000,0x5FFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "MXUB group" ,CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x6800,0x68BF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "L2 group" ,CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x7800,0x7FFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "SLICE0 EUC group",CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x0000,0x00FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 PEA group",CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x0100,0x017F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 PEB group",CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x0180,0x01FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 TU group",CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x0200,0x027F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 FFU group",CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x0280,0x02FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "SLICE1 EUC group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0400,0x04FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 PEA group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0500,0x057F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 PEB group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0580,0x05FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 TU group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0600,0x067F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 FFU group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0680,0x06FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "GPC CENTRAL SPTFE group", CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x1000,0x13FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "GPC CENTRAL SGTBE group", CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x1800,0x1FFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, +}; + +static const debug_bus_info debug_bus_info_Arise2030[] = +{ + //group_name scope gpcIndex {{group_start_offset,group_end_offset,write_reg_number,write_reg_offset[3],write_reg_mask[3]}, + // {mmio_offset_0,mmio_offset_1,mmio_offset_2,mmio_offset_3}} + + //GPC0 + "S3VD0 group" ,CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x2000,0x27FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "CMU group" ,CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x2800,0x2FFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + //BIU need keep 0xA01F0[31] = 1, so change 0x3800 to 0x80003800 fit this + "BIU Peri group" ,CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x3800,0x3809,3,0x88C8,0x88C9,0xA01F0,0x7F00,0x00FF,0x7FFF},{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "BIU PCIE group" ,CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x3C00,0x3F7F,3,0x88C8,0x88C9,0xA01F0,0x7F00,0x00FF,0x7FFF},{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "MIU0 group" ,CHIP2_SCOPE_DEBUG_BUS,0,{ { 0x3000,0x37FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "VPP group" ,CHIP2_SCOPE_DEBUG_BUS,0,{ { 0x4000,0x47FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "DIU group" ,CHIP2_SCOPE_DEBUG_BUS,0,{ { 0x5000,0x5FFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "MXUB group" ,CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x6800,0x6FFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "MIU1 group" ,CHIP2_SCOPE_DEBUG_BUS,0,{ { 0x7000,0x77FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "L2 group" ,CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x7800,0x7FFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "SLICE0 EUC group",CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x0000,0x00FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 PEA group",CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x0100,0x017F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 PEB group",CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x0180,0x01FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 TU group",CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x0200,0x027F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE0 FFU group",CHIP1_SCOPE_DEBUG_BUS,0,{ { 0x0280,0x02FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "SLICE1 EUC group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0400,0x04FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 PEA group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0500,0x057F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 PEB group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0580,0x05FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 TU group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0600,0x067F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE1 FFU group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0680,0x06FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "SLICE2 EUC group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0800,0x08FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE2 PEA group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0900,0x097F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE2 PEB group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0980,0x09FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE2 TU group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0A00,0x0A7F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE2 FFU group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0A80,0x0AFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "SLICE3 EUC group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0C00,0x0CFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE3 PEA group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0D00,0x0D7F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE3 PEB group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0D80,0x0DFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE3 TU group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0E00,0x0E7F,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "SLICE3 FFU group",CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x0E80,0x0EFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + + "GPC CENTRAL SPTFE group", CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x1000,0x13FF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, + "GPC CENTRAL SGTBE group", CHIP3_SCOPE_DEBUG_BUS,0,{ { 0x1800,0x1BFF,2,0x88C8,0x88C9,0,0x7F00,0x00FF,0 },{ 0x88C0,0x88C1,0x88C2,0x88C3 } }, +}; + +#define COMPATIBLE_TO_WINDOW 1 + +#define SAVE_BEFORE_PREHANG 1 //for prehangdump:save resource,DMA,CONTEXT +#define SAVE_AFTER_PREHANG 2 //for prehangdump:save ringbuffer and modify DMA.context restore,fence commands +#define SAVE_BEFORE_POSTHANG 3 //for posthangdump:save CONTEXT +#define SAVE_AFTER_POSTHANG 4 //for posthangdump:save resource,DMA,ringbuffer and modify DMA.context restore,fence commands +#define SAVE_RING_BUFFER 5 //save ringbuffer only. +#define SAVE_FORMAT_BUFFER 6 //save formatbuffer only. + + +// Debug hang fence offset +#define DH_FENCE_OFFSET (0x40) +#define DH_FENCE_VALUE (0x12345678) +#define DH_XBUFFER_SIZE (0x10000) +#define DUPLICATE_TIME_OUT (10) //10s + +//multi dma number + +#define MAX_HANG_DUMP_DATA_POOL_NUMBER 5 +#define HANG_DUMP_CONTEXT_BUFFER_OFFSET 1 +#define HANG_DUMP_DMA_BUFFER_OFFSET 2 +#define HANG_DUMP_RING_BUFFER_OFFSET 3 +#define HANG_DUMP_DH_COMMON_INFO_OFFSET 4 +#define HANG_DUMP_FORMAT_BUFFER_OFFSET 5 + +typedef struct dh_file_info_e3k +{ + large_inter FbNotCpuVisibleSize; + unsigned int FbCpuVisibleSize; + unsigned int dma_for_hang_size; + unsigned int context_for_hang_size; + unsigned int ring_for_hang_size; +}dh_file_info_e3k; + +typedef struct dh_common_info_e3k +{ + unsigned int current_hang_dump_index; + unsigned int hang_dump_counter; + unsigned int hang_dma_index; + unsigned long long hang_dma_fence_id; + unsigned int hang_rb_index; + unsigned long long fence_id[MAX_HANG_DUMP_DATA_POOL_NUMBER]; + unsigned int rb_index[MAX_HANG_DUMP_DATA_POOL_NUMBER]; + + //reserved for ringbuffer/fence_buffer/flush_fifo_buffer when real kickoff + unsigned int ring_buffer[2048]; + unsigned long long fence_buffer; + unsigned long long flush_fifo_buffer; +}dh_common_info_e3k; + + +typedef struct dh_rb_info_e3k +{ + EngineSatus_e3k status; + unsigned int last_rb_size; + unsigned int last_rb_index; +}dh_rb_info_e3k; + +//this will replace above dh_file_info_e3k for compatible mode +typedef struct submit_info +{ + unsigned long long ring_buffer_gpu_va; + unsigned long long kickoff_ring_buffer_gpu_va; + unsigned long long dma_buffer_gpu_va; + unsigned long long context_buffer_gpu_va; + unsigned long long fence_buffer_gpu_va; + + void* ring_buffer_cpu_va; + void* kickoff_ring_buffer_cpu_va; + void* dma_buffer_cpu_va; + void* context_buffer_cpu_va; + void* fence_buffer_cpu_va; + + int rb_index; + + EngineSatus_e3k status; +} submit_info_t; + +typedef struct _dup_hang_ctx +{ + struct os_file *file; + adapter_t *adapter; + unsigned int device_id; + unsigned int slice_mask; + unsigned long long local_memory_size; + unsigned long long pcie_memory_size; + unsigned long long local_visible_size; + unsigned long long local_unvisible_size; + + unsigned long long record_number; + + unsigned long long dma_buffer_offset; + unsigned long long single_dma_size_in_byte; + + unsigned long long context_buffer_offset; + unsigned long long single_context_buffer_size_in_byte; + + unsigned long long ring_buffer_offset; + unsigned long long single_ring_buffer_size_in_byte; + + unsigned long long gart_table_l3_offset; + unsigned long long gart_table_l2_offset; + unsigned long long dummy_page_entry; + unsigned long long bl_buffer_offset; + + void *local_visible_memory_cpu_va; + + submit_info_t submit_info; +}dup_hang_ctx_t; + +#define HangDump_SingleDmaBufferSize (64 * 1024) // 64k +#define HangDump_ContextBufferBlockSize (CONTEXT_BUFFER_SIZE) // 0xc000 +// Ringbuffer size;0x30 DWORD, RingBufferBlockSize = 0xA4 Byte +#define HangDump_RingBufferBlockSize ((sizeof(dh_rb_info_e3k)) + sizeof(RINGBUFFER_COMMANDS_E3K)) + +extern int use_hw_dump; + +extern void vidsch_duplicate_hang_e3k(adapter_t *adapter); +extern void vidsch_dump_hang_e3k(adapter_t *adapter); +extern int vidsch_save_misc_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr, unsigned int what_to_save); +extern void vidsch_handle_dbg_hang_dump_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr, task_dma_t *task_dma); + +typedef union +{ + struct + { + unsigned int wait : 1; // wait after submit. + unsigned int print_hang : 1; // print out logged hang info. + unsigned int reset_hw : 1; // reset hardware. + unsigned int pre_hang_dump : 1; // before hang,Save DMA,RingBuffer,context and all resources into framebuffer mirror + unsigned int post_hang_dump : 1; // After hang,Save DMA,RingBuffer,context and all resources into framebuffer mirror + unsigned int duplicate_hang : 1; // resore the enviroment saved by PreHangDump/PostHangDump to duplcate the hang + unsigned int internal_dump_hw : 1; // Dump framebuffer mirror to file so that duplicat the hang . + unsigned int internal_block_submit : 1; // block sumbit during replaying + unsigned int print_debug_bus : 1; // print out debug bus info. + unsigned int start_test_dump : 1; // start to test hang dump code + unsigned int multi_dma_number : 5; // 0-single dma + unsigned int Reserved : 17; + }; + unsigned int uint; +} reg_debug_mode_e3k; + +extern reg_debug_mode_e3k debug_mode_e3k; +extern void vidsch_display_debugbus_info_e3k(adapter_t *adapter, struct os_printer *p, int video); +extern void vidsch_dump_hang_compatible_e3k(adapter_t *adapter); +extern void vidsch_duplicate_hang_compatible_e3k(adapter_t * adapter); +extern unsigned char *vidschi_get_dump_data_cpu_virt_addr_e3k(adapter_t *adapter, unsigned int type, unsigned int index); +extern void vidschi_copy_mem_e3k(adapter_t *adapter, + unsigned long long dst_phys_addr, + void *dst_virt_addr, + unsigned long long src_phys_addr, + void *src_virt_addr, + unsigned int total_size); + +void vidsch_trigger_duplicate_hang_e3k(adapter_t *adapter); + +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dfs_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dfs_e3k.c new file mode 100644 index 0000000000000..4454b7ea825f6 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dfs_e3k.c @@ -0,0 +1,171 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "vidsch_dfs_e3k.h" +#include "vidsch.h" +#include "vidschi.h" +#include "chip_include_e3k.h" +#include "vidsch_engine_e3k.h" +#include "register_e3k.h" + +#define GFX_ENGINE_MASK (1 << RB_INDEX_GFXL | 1 << RB_INDEX_GFXH) + +static unsigned char vidsch_cacl_available_gpc_bit(adapter_t * adapter) +{ + unsigned char bits = 0; + + if(adapter->hw_caps.chip_slice_mask &0xF00) bits |=0x10; + if(adapter->hw_caps.chip_slice_mask &0x0F0) bits |=0x20; + if(adapter->hw_caps.chip_slice_mask &0x00F) bits |=0x40; + + return bits; +} + +int vidsch_power_clock_on_off_e3k(vidsch_mgr_t *sch_mgr, unsigned int off) +{ + adapter_t * adapter = sch_mgr->adapter; + vidschedule_t *schedule = adapter->schedule; + unsigned char used_gpc_mask_bit = vidsch_cacl_available_gpc_bit(adapter); + unsigned long flags = 0; + + flags = gf_spin_lock_irqsave(schedule->power_status_lock); + //power_trace("[CG] used_gpc_mask_bit:%x\n", used_gpc_mask_bit); + + if(off) + { + switch(sch_mgr->engine_index) + { + case RB_INDEX_GFXL: + case RB_INDEX_GFXH: + write_reg_e3k(adapter->mmio, CR_C, 0x01, 0, 0x8F); + break; + case RB_INDEX_VCP0: + write_reg_e3k(adapter->mmio, CR_C, 0x01, 0, 0xF7); + break; + case RB_INDEX_VCP1: + write_reg_e3k(adapter->mmio, CR_C, 0x01, 0, 0xFB); + break; + case RB_INDEX_VPP: + write_reg_e3k(adapter->mmio, CR_C, 0x01, 0, 0xFD); + break; + default: + break; + } + power_trace("[CG] engine %d do cg power off, CR01:%x\n", sch_mgr->engine_index, read_reg_e3k(adapter->mmio, CR_C, 0x01)); + } + else + { + switch(sch_mgr->engine_index) + { + case RB_INDEX_GFXL: + case RB_INDEX_GFXH: + write_reg_e3k(adapter->mmio, CR_C, 0x01, (0x70 & used_gpc_mask_bit), 0x8F); + break; + case RB_INDEX_VCP0: + write_reg_e3k(adapter->mmio, CR_C, 0x01, 8, 0xF7); + break; + case RB_INDEX_VCP1: + write_reg_e3k(adapter->mmio, CR_C, 0x01, 4, 0xFB); + break; + case RB_INDEX_VPP: + write_reg_e3k(adapter->mmio, CR_C, 0x01, 2, 0xFD); + break; + default: + break; + } + power_trace("[CG] engine %d do cg power on, CR01:%x\n", sch_mgr->engine_index, read_reg_e3k(adapter->mmio, CR_C, 0x01)); + } + + gf_spin_unlock_irqrestore(schedule->power_status_lock, flags); + + return S_OK; +} + +int vidsch_power_clock_on_off_vcp(vidsch_mgr_t *sch_mgr, unsigned int off) +{ + adapter_t * adapter = sch_mgr->adapter; + vidschedule_t *schedule = adapter->schedule; + unsigned long flags = 0; + + flags = gf_spin_lock_irqsave(schedule->power_status_lock); + //power_trace("[CG] used_gpc_mask_bit:%x\n", used_gpc_mask_bit); + + if(off) + { + write_reg_e3k(adapter->mmio, CR_C, 0x01, 0, 0xF7);//VCP0 + if(adapter->chip_id < CHIP_ARISE1020)//CHIP_ARISE1020 only has one vcp core + { + write_reg_e3k(adapter->mmio, CR_C, 0x01, 0, 0xFB);//VCP1 + } + power_trace("[CG] engine %d do cg power off, CR01:%x\n", sch_mgr->engine_index, read_reg_e3k(adapter->mmio, CR_C, 0x01)); + } + else + { + write_reg_e3k(adapter->mmio, CR_C, 0x01, 8, 0xF7);//VCP0 + if(adapter->chip_id < CHIP_ARISE1020)//CHIP_ARISE1020 only has one vcp core + { + write_reg_e3k(adapter->mmio, CR_C, 0x01, 4, 0xFB);//VCP1 + } + power_trace("[CG] engine %d do cg power on, CR01:%x\n", sch_mgr->engine_index, read_reg_e3k(adapter->mmio, CR_C, 0x01)); + } + + gf_spin_unlock_irqrestore(schedule->power_status_lock, flags); + + return S_OK; +} + +void vidsch_power_tuning_e3k(adapter_t *adapter, unsigned int gfx_only) +{ + vidschedule_t *schedule = adapter->schedule; + vidsch_mgr_t *sch_mgr = NULL; + int engine_index; + unsigned int engine_mask = gfx_only ? GFX_ENGINE_MASK : ALL_ENGINE_MASK; + + if (!adapter->pwm_level.EnableClockGating) + { + return; + } + + for (engine_index = adapter->active_engine_count-1; engine_index >= 0; engine_index--) + { + int ret = S_OK; + unsigned long flags=0; + + if ((engine_mask & (1<sch_mgr[engine_index]; + + if (sch_mgr == NULL) continue; + + vidsch_update_engine_idle_status(adapter, (1 << engine_index)); + if (sch_mgr->completely_idle) + { + flags = gf_spin_lock_irqsave(sch_mgr->power_status_lock); + if (sch_mgr->chip_func->power_clock && + sch_mgr->engine_dvfs_power_on && + vidsch_is_fence_back(sch_mgr->adapter, sch_mgr->engine_index, sch_mgr->last_send_fence_id)) + { + if(ret == S_OK) + { + //gf_info("power off: last_send_fence_id=%d. \n", sch_mgr->last_send_fence_id); + sch_mgr->chip_func->power_clock(sch_mgr, TRUE); + sch_mgr->engine_dvfs_power_on = FALSE; + } + } + gf_spin_unlock_irqrestore(sch_mgr->power_status_lock, flags); + } + } +} + + diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dfs_e3k.h b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dfs_e3k.h new file mode 100644 index 0000000000000..5ea64dac26a61 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dfs_e3k.h @@ -0,0 +1,24 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __PM_DFS_E3K_H__ + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" + +int vidsch_power_clock_on_off_e3k(vidsch_mgr_t *sch_mgr, unsigned int off); +int vidsch_power_clock_on_off_vcp(vidsch_mgr_t *sch_mgr, unsigned int off); +void vidsch_power_tuning_e3k(adapter_t *adapter, unsigned int gfx_only); +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dump_image_e3k.h b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dump_image_e3k.h new file mode 100644 index 0000000000000..4767f548b4620 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_dump_image_e3k.h @@ -0,0 +1,36 @@ +#ifndef VIDSCH_DUMP_IMAGE_E3K_H +#define VIDSCH_DUMP_IMAGE_E3K_H +typedef struct _HangDumpFileHeader +{ + unsigned int nHeaderVersion; + unsigned int nDeviceID; + unsigned int nSliceMask; + unsigned int nHangDumpFileHeaderSizeInByte; + unsigned int reserved0[4]; + + unsigned long long nAdapterMemorySizeInByte; + unsigned long long nPCIEMemorySizeInByte; // default 3G + + unsigned long long nRecordNums; // the DMA/Context/Ring Buffer numbers which DUMP file include. + + // DMA + unsigned long long nDmaOffset; + unsigned long long nSingleDmaSizeInByte; // nRecordNums*nSingleDmaSizeInByte = 0x40000 + + // Context + unsigned long long nContextOffset; + unsigned long long nSingleContextSizeInByte; // nRecordNums*nSingleContextSizeInByte = 0x160000 + + // Ring Buffer + unsigned long long nRingBufferOffset; + unsigned long long nSingleRingBufferSizeInByte; // nRecordNums*nSingleRingBufferSizeInByte + + unsigned long long nTransferBufferOffsetInFBFile; // useless, remove it + unsigned long long nGartTableL3Offset; + unsigned long long nGartTableL2Offset; + unsigned long long dummyPageEntry; + + unsigned long long nBlBufferOffset; + unsigned long long reserved1[0x20]; +} HangDumpFileHeader; +#endif diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_e3k.h b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_e3k.h new file mode 100644 index 0000000000000..901ee14691e98 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_e3k.h @@ -0,0 +1,276 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __VIDSCH_ENGINE_E3K_H +#define __VIDSCH_ENGINE_E3K_H + +#include "vidsch.h" +#include "vidschi.h" +#include "ring_buffer.h" +#include "chip_include_e3k.h" +#include "vidsch_blt_e3k.h" + +#define EXTERNAL_FENCE_DWSIZE (5) +#define ALIGNED_8(Value) (((Value) + 7) & ~7) +#define ALIGNMENT_4K (0x1000 - 1) +#define BEGIN_END_BUF_SIZE_E3K \ + ((sizeof(RB_PREDEFINE_DMA) + ALIGNMENT_4K) & (~ ALIGNMENT_4K)) + +#define RING_BUFFER_SIZE_E3K (64 * 4096) //need align to 4K? +#define KKK_ARGUMENT_BUFFER_SIZE (0x10000) +#define FENCE_BUFFER_SIZE_E3K (0x00001000) + +#define VIDEO_BRIDGE_BUF_SIZE (0x800000) //reserve 8M bridge buffer used as video FE output for one video core + + +#define HW_CONTEXT_COUNT_E3K (2) +#define HW_CONTEXT_E3K_ALIGN (0x4000 -1)//Align to 16K for HW requirement +#define HW_CONTEXT_SIZE_E3K \ + ( ( sizeof(CONTEXT_BUFFER_E3K) + HW_CONTEXT_E3K_ALIGN ) &( ~HW_CONTEXT_E3K_ALIGN ) ) + +#define E3K_ENGINE_HW_QUEUE_SIZE 5 + +#define _3DBLT_DATA_RESERVE_SIZE (1024 * 16) + +typedef enum +{ + RB_INDEX_GFXL = 0, //Graphics High Ring Buffer Index; + RB_INDEX_GFXH = 1, //Graphics Low Ring Buffer Index; + RB_INDEX_CSH = 2, //CS High Ring Buffer Index + RB_INDEX_CSL0 = 3, //CS No1 RingBuffer Index + RB_INDEX_CSL1 = 4, //CS No2 RingBuffer Index + RB_INDEX_CSL2 = 5, //CS No3 RingBuffer Index + RB_INDEX_CSL3 = 6, //CS No4 RingBuffer Index + RB_INDEX_VCP0 = 7, + RB_INDEX_VCP1 = 8, + RB_INDEX_VPP = 9, + RB_NUM = 10, +} RB_NODE_E3K; + +typedef enum +{ + SUBMIT_CMD_HWCONTEX_SWITCH = 0, + SUBMIT_CMD_NO_HWCONTEXT_SWITCH = 1, + SUBMIT_CMD_FENCE_ONLY = 2, + SUBMIT_CMD_LAST = 3, +}SUBMIT_CMD_TYPE; + + _inline int EngineRbOffset(DWORD RbIndex) +{ + unsigned int RegRbOffset = 0; + + if ( RbIndex == RB_INDEX_VCP0 || RbIndex == RB_INDEX_VCP1 ||RbIndex == RB_INDEX_VPP) + { + RegRbOffset = Reg_Vcp_Ring_Buf_Offset + (RbIndex -RB_INDEX_VCP0) * 4; + } + else + { + RegRbOffset = Reg_Ring_Buf_Offset + RbIndex * 4; + } + return RegRbOffset; +} + +typedef struct +{ + vidsch_mgr_t *vidsch; + + unsigned long long *fence_buffer_virt_addr; /*fence buffer addr */ + unsigned long long fence_buffer_phy_addr; /* fence buffer addr */ + + unsigned long long *fence_buffer_virt_addr_fake; /*fence buffer addr, patch for fence isr lost issue*/ + unsigned long long fence_buffer_phy_addr_fake; /* fence buffer addr, patch for fence isr lost issue*/ + + unsigned long long *fence_buffer_virt_addr_local; /*fence buffer addr, patch for fence value not update*/ + unsigned long long fence_buffer_phy_addr_local; /* fence buffer addr, patch for fence value not update*/ + + unsigned long long *fence_buffer_virt_addr_local_fake; /*fence buffer addr, patch for fence value not update*/ + unsigned long long fence_buffer_phy_addr_local_fake; /* fence buffer addr, patch for fence value not update*/ + + unsigned long long *fence_buffer_virt_addr_snoop; /*fence buffer addr, patch for fence value not update*/ + unsigned long long fence_buffer_phy_addr_snoop; /* fence buffer addr, patch for fence value not update*/ + + unsigned long long *fence_buffer_virt_addr_snoop_fake; /*fence buffer addr, patch for fence value not update*/ + unsigned long long fence_buffer_phy_addr_snoop_fake; /* fence buffer addr, patch for fence value not update*/ + + unsigned int *ring_buf_virt_addr; + unsigned long long ring_buf_phys_addr; + + ring_buffer_t ring; + +#if 1//GF_TRACE_HW_HANG + unsigned int *last_ring_buffer; + unsigned int last_ring_buffer_size; +#endif + + void *share; + + EngineSatus_e3k dumped_engine_status; // save status to dump to file //common + + unsigned long long dma_for_hang; // Start Offset of DMA reserved for Hang //common + unsigned long long context_for_hang; // Start Offset of Context reserved for Hang //common + unsigned char *last_ring_buffer_for_begin_dma; // point to RB where context resotre CMD is saved + unsigned char *last_ring_buffer_for_end_dma; // point to RB where context save CMD is saved + unsigned long long context_buffer_to_restore_addr; // the address of context to restore + unsigned long long ring_buffer_for_hang; // Start Offset of RingBuffer reserved for Hang + + unsigned int last_ring_buffer_engine_index; + unsigned char *last_ring_buffer_for_dma; // point to RingBuffer where DMA kicked off CMD is saved + unsigned char *last_ring_buffer_for_fence; // point to RingBuffer where Fence CMD is saved + unsigned char *last_dma_buffer; // last dma buffer location + unsigned int last_dma_buffer_size_uint; + +}engine_e3k_t; + +typedef struct +{ + engine_e3k_t common; + unsigned int is_high_engine; + + unsigned long long context_buf_phy_addr; //for low, it's template buffer for high/low, for High it's hwctx for low save/restore + + unsigned long long shadow_context_buf_phy_addr; // restore shadow buffer in init DMA when switch slice + unsigned long long temp_context_buf_phy_addr; // when switch slice without context switch, save context before init DMA, and restore after init DMA +}engine_gfx_e3k_t; + +typedef struct +{ + engine_e3k_t common; + + unsigned int AddrTblUpdateCECMD[10]; + + unsigned int addr_table_phys_addr; + + unsigned int FreeIdxSize; + unsigned int *FreeIdxList; +}engine_paging_e3k_t; + + +typedef struct engine_share_e3k +{ + unsigned int ref_cnt; + + gf_vm_area_t *begin_end_vma; //save restore dma vma struct, high rb needs memcopy to rb cmd, so keep this vm struct. + unsigned long long begin_end_buffer_phy_addr; + unsigned long long context_buf_phy_addr;//high and low use same hwctx template + + struct os_mutex *_3dblt_data_lock; + void *_3dblt_data_shadow; // it's an system memory cache, used for restore + unsigned int _3dblt_data_size; + unsigned long long _3dblt_data_phy_addr; + + //CSLx patch need ringbuffer phy addr + unsigned long long ring_buffer_phy_addr[RB_NUM]; + + BITBLT_REGSETTING_E3K _2dblt_cmd_e3k; + FASTCLEAR_REGSETTING_E3K fast_clear_cmd_e3k; + + RINGBUFFER_COMMANDS_E3K RingBufferCommands[SUBMIT_CMD_LAST]; + SLICESWITCH_INIT_COMMANDS_E3K SliceSwitchInitCommands[SUBMIT_CMD_LAST]; + unsigned int internal_fence_value[8]; //patch video engine issue. + + struct _vidmm_segment_memory *ring_buffer_for_hang; + struct _vidmm_segment_memory *dma_buffer_for_hang; + struct _vidmm_segment_memory *context_buffer_for_hang; + struct _vidmm_segment_memory *mirror_buffer_for_hang; + struct _vidmm_segment_memory *transfer_buffer_for_hang; + struct _vidmm_segment_memory *flush_fifo_buffer; + struct _vidmm_segment_memory *bl_buffer; + void * bl_buffer_backup; + gf_vm_area_t *fb_vma; + + struct os_spinlock *lock; //use for pretect internal fence value; + +}engine_share_e3k_t; + +typedef engine_e3k_t engine_vcp_e3k_t; +typedef engine_e3k_t engine_vpp_e3k_t; + + +typedef struct _GF_RINGBUFFER_HEADER_E3K +{ + UINT TailOffset; // rb tail pointer, byte offset to tail. + UINT HeadOffset; // rb head pointer, byte offset to head. + UINT Size; + UINT ContextSaveBase; // the context save area base address. + UINT Reserved[12]; // The whole header is 512-bits, 16DW. Make sure to update +} GF_RINGBUFFER_HEADER_E3K; + +extern int engine_gfx_low_init_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr); +extern int engine_gfx_high_init_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr); +extern int engine_gfx_high_init_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr); +extern int engine_vcp_init_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr); +extern int engine_vpp_init_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr); +extern void engine_gfx_low_restore_e3k(vidsch_mgr_t *sch_mgr, unsigned int pm); +extern void engine_gfx_high_restore_e3k(vidsch_mgr_t *sch_mgr, unsigned int pm); +extern void enginei_init_ring_buffer_commands_e3k(engine_gfx_e3k_t *engine); + +extern void enginei_enable_ring_buffer_e3k(engine_e3k_t *engine); +extern unsigned int *enginei_get_ring_buffer_space_e3k(engine_e3k_t *engine, int size); +extern void enginei_do_kickoff_cmd_e3k(engine_e3k_t *engine); +extern int enginei_init_hardware_context_e3k(engine_gfx_e3k_t *engine); + +extern unsigned long long engine_update_fence_id_e3k(vidsch_mgr_t *sch_mgr); +extern unsigned long long engine_update_vpp_fence_id_e3k(vidsch_mgr_t *sch_mgr); +extern unsigned long long engine_update_vcp_fence_id_e3k(vidsch_mgr_t *sch_mgr); +extern int engine_submit_task_dma_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr, task_dma_t *task_dma); +extern int engine_destroy_e3k(vidsch_mgr_t *vidsch); +extern int engine_cil2_misc_e3k(vidsch_mgr_t *sch_mgr, krnl_cil2_misc_t *misc); + +extern int engine_save_e3k(vidsch_mgr_t *vidsch); +extern void engine_restore_e3k(vidsch_mgr_t *vidsch, unsigned int pm); + +extern void vidschi_reset_adapter_e3k(adapter_t *adapter); +extern int vidsch_reset_hw_e3k(vidsch_mgr_t * sch_mgr); +extern void vidschi_init_hw_settings_e3k(adapter_t *adapter); +extern int vidschi_get_slot_count_e3k(adapter_t *adapter); +extern int vidsch_patch_e3k(adapter_t *adapter, task_dma_t *task_dma); +extern int vidsch_render_e3k(gpu_context_t *context, task_dma_t *task_dma); +extern void vidschi_map_e3k(adapter_t *adapter); +extern void enginei_init_context_save_restore_dma_e3k(engine_gfx_e3k_t *engine); +extern void enginei_invalidate_gart_e3k(engine_e3k_t *engine); +extern void vidschi_init_blt_cmd_e3k(engine_share_e3k_t *share); +extern void vidmm_init_mem_settings_e3k(adapter_t *); +extern int vidmmi_copy_data(struct _vidmm_mgr *mm_mgr, task_paging_t *paging_task,vidmm_allocation_t *dst_allocation, + unsigned long long src_addr, unsigned long long dst_addr, + unsigned int src_compress, unsigned int dst_compress, unsigned int size); +extern int vidmm_segment_memory_transfer_e3k(adapter_t *adapter, vidmm_segment_memory_t **dst_pointer, + vidmm_segment_memory_t *src, int to_local); +extern void vidmm_update_gart_table_pte_e3k(adapter_t *adapter, struct os_pages_memory *memory, unsigned int *gart_table_L3, unsigned long gpu_va); + + +extern void vidsch_dump_hang_info_e3k(vidsch_mgr_t * sch_mgr); +extern void vidsch_dump_hang_e3k(adapter_t *adapter); +extern void vidsch_display_debugbus_info_e3k(adapter_t *adapter, struct os_printer *p, int video); + +extern int enginei_init_pwm_reg_e3k(engine_e3k_t *engine); + +#ifdef GF_HW_NULL +void engine_set_fence_id_e3k(vidsch_mgr_t *sch_mgr, unsigned long long fence_id); +#endif + +#endif //#ifndef __VIDSCH_ENGINE_E3K_H + + + + + + + + + + + + + + diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_setup_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_setup_e3k.c new file mode 100644 index 0000000000000..85754a2c36ead --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_setup_e3k.c @@ -0,0 +1,1042 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_engine_e3k.h" +#include "chip_include_e3k.h" +#include "vidsch_dfs_e3k.h" +#include "bit_op.h" +#include "kernel_interface.h" +#include "mm_e3k.h" +#include "vidsch_debug_hang_e3k.h" + +static int enginei_common_share_init_e3k(engine_e3k_t *engine) +{ + engine_share_e3k_t *share = engine->share; + + vidschi_init_blt_cmd_e3k(share); + + return S_OK; +} + +static int enginei_common_init_e3k(vidsch_mgr_t *sch_mgr, engine_e3k_t *engine, + unsigned int *current_pcie_offset, unsigned int *current_low_offset) +{ + engine_share_e3k_t *share = sch_mgr->adapter->private_data; + vidmm_segment_memory_t *pcie_reserved_memory = sch_mgr->pcie_reserved_memory; + int status = S_OK; + + engine->vidsch = sch_mgr; + + /* allocate fence buffer */ + status = vidsch_request_fence_space(sch_mgr->adapter, sch_mgr->adapter->fence_buf, &engine->fence_buffer_virt_addr, &engine->fence_buffer_phy_addr); + //gf_info("%s:engine:%d,fence buf phy addr:%x\n",util_remove_name_suffix(__func__), sch_mgr->engine_index, engine->fence_buffer_phy_addr);//for debug + status = vidsch_request_fence_space(sch_mgr->adapter, sch_mgr->adapter->fence_buf, &engine->fence_buffer_virt_addr_fake, &engine->fence_buffer_phy_addr_fake); + //gf_info("%s:engine:%d,fence buf phy addr fake:%x\n",util_remove_name_suffix(__func__), sch_mgr->engine_index, engine->fence_buffer_phy_addr_fake);//for debug + + status = vidsch_request_fence_space(sch_mgr->adapter, sch_mgr->adapter->fence_buf_local, &engine->fence_buffer_virt_addr_local, &engine->fence_buffer_phy_addr_local); + status = vidsch_request_fence_space(sch_mgr->adapter, sch_mgr->adapter->fence_buf_local, &engine->fence_buffer_virt_addr_local_fake, &engine->fence_buffer_phy_addr_local_fake); + + status = vidsch_request_fence_space(sch_mgr->adapter, sch_mgr->adapter->fence_buf_snoop, &engine->fence_buffer_virt_addr_snoop, &engine->fence_buffer_phy_addr_snoop); + status = vidsch_request_fence_space(sch_mgr->adapter, sch_mgr->adapter->fence_buf_snoop, &engine->fence_buffer_virt_addr_snoop_fake, &engine->fence_buffer_phy_addr_snoop_fake); + + gf_assert(status == S_OK, "enginei_common_init"); + + *engine->fence_buffer_virt_addr = 0x0ll; + *engine->fence_buffer_virt_addr_fake = 0x0ll; + + *engine->fence_buffer_virt_addr_local = 0x0ll; + *engine->fence_buffer_virt_addr_local_fake = 0x0ll; + + *engine->fence_buffer_virt_addr_snoop = 0x0ll; + *engine->fence_buffer_virt_addr_snoop_fake = 0x0ll; + + /* allocate ring buffer from pcie reserved */ + engine->ring_buf_virt_addr = pcie_reserved_memory->vma->virt_addr; + engine->ring_buf_virt_addr += *current_pcie_offset; + + share->ring_buffer_phy_addr[sch_mgr->engine_index] = + engine->ring_buf_phys_addr = pcie_reserved_memory->gpu_virt_addr + *current_pcie_offset; + + //gf_info("%s:engine:%d, ring_buffer_phy_addr:%x, need 4k aligned!!!!\n",util_remove_name_suffix(__func__), sch_mgr->engine_index, engine->ring_buf_phys_addr);//for debug + + *current_pcie_offset += RING_BUFFER_SIZE_E3K; + + enginei_enable_ring_buffer_e3k(engine); + + sch_mgr->slot_count = vidschi_get_slot_count_e3k(sch_mgr->adapter); + sch_mgr->private_data = engine; + + share->ref_cnt++; + engine->share = share; + + return S_OK; +} + +int engine_save_e3k(vidsch_mgr_t *vidsch) +{ + adapter_t *adapter = vidsch->adapter; + engine_e3k_t *engine = vidsch->private_data; + engine_share_e3k_t *share = engine->share; + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[vidsch->engine_index]; + int result = 0; + + if (adapter->suspend_blt_mode) + { + if(share->bl_buffer && share->bl_buffer->list_node->size && !share->bl_buffer_backup) + { + struct _vidmm_segment_memory *segment = NULL; + result = vidmm_segment_memory_transfer_e3k(adapter, &segment, share->bl_buffer, 0); + share->bl_buffer_backup = segment; + } + } + else + { + if(share->bl_buffer && !share->bl_buffer->vma &&!share->bl_buffer_backup ) + { + vidmm_map_flags_t flags = {0}; + flags.mem_space = GF_MEM_KERNEL; + flags.cache_type = GF_MEM_UNCACHED; + + vidmm_map_segment_memory(adapter, NULL, share->bl_buffer, &flags); + + share->bl_buffer_backup = gf_calloc(share->bl_buffer->list_node->size); + if (share->bl_buffer_backup && share->bl_buffer->vma) + { + //gf_info("engine_save_e3k: start mem copy bl_buffer size %d (engine %d)\n",share->bl_buffer->list_node->size, vidsch->engine_index); + gf_memcpy(share->bl_buffer_backup, share->bl_buffer->vma->virt_addr, share->bl_buffer->list_node->size); + //gf_info("engine_save_e3k: end save memcpy engine (engine %d)\n",vidsch->engine_index); + } + else + { + result = E_OUTOFMEMORY; + } + //util_dump_memory(share->bl_buffer->vma->virt_addr, 4*1024, "first 4k bl"); + } + } + + if(share->begin_end_vma) + { + gf_unmap_io_memory(share->begin_end_vma); + share->begin_end_vma = NULL; + } + + gf_info("%s: engine index: %d, last send: %lld, last_return: %lld\n", util_remove_name_suffix(__func__), + vidsch->engine_index, sch_mgr->last_send_fence_id, sch_mgr->returned_fence_id); + + return result; +} + +void engine_restore_e3k(vidsch_mgr_t *vidsch, unsigned int pm) +{ + engine_e3k_t *engine = vidsch->private_data; + + enginei_enable_ring_buffer_e3k(engine); +} + +int engine_destroy_e3k(vidsch_mgr_t *vidsch) +{ + adapter_t *adapter = vidsch->adapter; + engine_e3k_t *engine = vidsch->private_data; + + vidsch->private_data = NULL; + + if(adapter->private_data) + { + engine_share_e3k_t *share = adapter->private_data; + + if(share->flush_fifo_buffer) + { + vidmm_unmap_segment_memory(adapter, share->flush_fifo_buffer, GF_MEM_KERNEL); + + vidmm_release_segment_memory(adapter, share->flush_fifo_buffer); + + share->flush_fifo_buffer = NULL; + } + + if(share->bl_buffer) + { + heap_t *heap = NULL; + + heap = vidmm_get_burst_length_heap(adapter); + + vidmm_release_segment_memory(adapter, share->bl_buffer); + + share->bl_buffer = NULL; + + heap_destroy(heap); + + heap = NULL; + } + + if(share->ring_buffer_for_hang) + { + vidmm_release_segment_memory(adapter, share->ring_buffer_for_hang); + + share->ring_buffer_for_hang = NULL; + } + + if(share->dma_buffer_for_hang) + { + vidmm_release_segment_memory(adapter, share->dma_buffer_for_hang); + + share->dma_buffer_for_hang = NULL; + } + + if(share->context_buffer_for_hang) + { + vidmm_release_segment_memory(adapter, share->context_buffer_for_hang); + + share->context_buffer_for_hang = NULL; + } + if(share->transfer_buffer_for_hang) + { + vidmm_release_segment_memory(adapter, share->transfer_buffer_for_hang); + + share->transfer_buffer_for_hang = NULL; + } + + if(share->mirror_buffer_for_hang) + { + vidmm_release_segment_memory(adapter, share->mirror_buffer_for_hang); + + share->mirror_buffer_for_hang = NULL; + } + + if(share->begin_end_vma) + { + gf_unmap_io_memory(share->begin_end_vma); + share->begin_end_vma = NULL; + } + } + + if(engine->share != NULL) + { + engine_share_e3k_t *share = engine->share; + + share->ref_cnt--; + + if(share->ref_cnt == 0) + { + gf_destroy_spinlock(share->lock); + + share->lock = NULL; + + gf_destroy_mutex(share->_3dblt_data_lock); + + share->_3dblt_data_lock = NULL; + + gf_free(share); + + engine->share = NULL; + vidsch->adapter->private_data = NULL; + } + } + + gf_free(engine); + + return S_OK; +} + +unsigned long long engine_update_fence_id_e3k(vidsch_mgr_t *sch_mgr) +{ + unsigned long long fence_id = 0, fence_id_fake = 0, fence_id_max = 0; + engine_e3k_t *engine = sch_mgr->private_data; + + fence_id = *(volatile unsigned long long *)engine->fence_buffer_virt_addr; + fence_id_fake = *(volatile unsigned long long *)engine->fence_buffer_virt_addr_fake; + + fence_id_max = fence_id > fence_id_fake ? fence_id:fence_id_fake; + + fence_id = *(volatile unsigned long long *)engine->fence_buffer_virt_addr_local; + fence_id_fake = *(volatile unsigned long long *)engine->fence_buffer_virt_addr_local_fake; + + if (fence_id_max < fence_id || fence_id_max < fence_id_fake) + fence_id_max = fence_id > fence_id_fake ? fence_id:fence_id_fake; + + fence_id = *(volatile unsigned long long *)engine->fence_buffer_virt_addr_snoop; + fence_id_fake = *(volatile unsigned long long *)engine->fence_buffer_virt_addr_snoop_fake; + + if (fence_id_max < fence_id || fence_id_max < fence_id_fake) + fence_id_max = fence_id > fence_id_fake ? fence_id:fence_id_fake; + + return fence_id_max; +} + +unsigned long long engine_update_vpp_fence_id_e3k(vidsch_mgr_t *sch_mgr) +{ + unsigned long long fence_id = 0; + engine_e3k_t *engine = sch_mgr->private_data; + fence_id = *(volatile unsigned long long *)engine->fence_buffer_virt_addr; + + return fence_id; +} + +unsigned long long engine_update_vcp_fence_id_e3k(vidsch_mgr_t *sch_mgr) +{ + unsigned long long fence_fe, fence_be; + unsigned int i = 0,j = 0; + engine_e3k_t *engine = sch_mgr->private_data; + fence_be = *(volatile unsigned long long *)engine->fence_buffer_virt_addr; + fence_fe = *(volatile unsigned long long *)engine->fence_buffer_virt_addr_fake; + + if(sch_mgr->adapter->ctl_flags.hwq_event_enable && sch_mgr->last_returned_fence_id != sch_mgr->returned_fence_id) + { + for(i = 0; i < VCP_INFO_COUNT; i++) + { + if(sch_mgr->returned_fence_id == sch_mgr->adapter->vcp_task_info[i].vcp_fence_id) + { + for(j = 0; j < VCP_INFO_COUNT; j++) + { + if(sch_mgr->adapter->vcp_task_info[i].vcp_pid == sch_mgr->adapter->vcp_info[j].pid) + { + unsigned long long update_timestamp; /* THE time update fence id */ + unsigned long long time_interval; + gf_get_nsecs(&update_timestamp); + time_interval = (update_timestamp - \ + sch_mgr->adapter->vcp_task_info[i].vcp_inc_timestamp)/1000000; + sch_mgr->adapter->vcp_info[j].TotalDecodetime += time_interval; + sch_mgr->adapter->vcp_info[j].TotalDecodeFrameNum++; + sch_mgr->last_returned_fence_id = sch_mgr->returned_fence_id; + break; + } + } + break; + } + } + } + + return fence_fe > fence_be ? fence_be: fence_fe; +} + +static int enginei_restore_3dblt_data_e3k(engine_gfx_e3k_t *engine) +{ + adapter_t *adapter = engine->common.vidsch->adapter; + engine_share_e3k_t *share = engine->common.share; + gf_map_argu_t map_argu = {0}; + gf_vm_area_t *vma = NULL; + + if (!share->_3dblt_data_shadow) + return S_OK; + + map_argu.flags.cache_type = GF_MEM_WRITE_COMBINED; + map_argu.flags.mem_space = GF_MEM_KERNEL; + map_argu.flags.mem_type = GF_SYSTEM_IO; + map_argu.phys_addr = adapter->vidmm_bus_addr + share->_3dblt_data_phy_addr; + map_argu.size = share->_3dblt_data_size; + + vma = gf_map_io_memory(NULL, &map_argu); + + gf_memcpy(vma->virt_addr, share->_3dblt_data_shadow, share->_3dblt_data_size); + + gf_unmap_io_memory(vma); + + return S_OK; +} + +int enginei_init_hardware_context_e3k(engine_gfx_e3k_t *engine) +{ + CONTEXT_BUFFER_E3K *pContext = NULL; + engine_e3k_t *engine_common = &engine->common; + unsigned int* pRB; + unsigned int RbSize; + BOOL b3dSigZero = FALSE; + + Reg_Eu_Full_Glb reg_Eu_Full_Glb = {0}; + Reg_Tu_Tssharp_Ctrl reg_Tu_Tssharp_Ctrl = {0}; + Reg_Ffc_Ubuf_Golbalconfig reg_Ffc_Ubuf_Golbalconfig = {0}; + Reg_Fence_Mask reg_Fence_Mask = {0}; + Reg_L2_Performance_Redundancy reg_L2_Performance = {0}; + Cmd_Blk_Cmd_Csp_Indicator pwmTrigger = {0}; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 trigger_Dw = {0}; + Cmd_Blk_Cmd_Csp_Indicator pwmTriggerOff = {0}; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 triggerOff_Dw = {0}; + + engine_share_e3k_t *share = engine_common->share; + adapter_t *adapter = engine_common->vidsch->adapter; + RB_PREDEFINE_DMA *pcmBuf = share->begin_end_vma->virt_addr; + CONTEXT_RESTORE_DMA_E3K *pRestoreDMA = NULL; + + gf_map_argu_t map_argu = {0}; + gf_vm_area_t *vma = NULL; + + unsigned int slice_mask = adapter->hw_caps.chip_slice_mask; + unsigned int gpc_bit_mask = 0, shift_num = 1; + + while (slice_mask) + { + if (slice_mask & 0xf) + { + gpc_bit_mask |= shift_num; + } + slice_mask >>= 4; + shift_num <<= 1; + } + + if(!adapter->hw_caps.local_only) + { + enginei_invalidate_gart_e3k(engine_common); + } + + pwmTrigger.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Indicator; + pwmTrigger.Block_Id = CSP_GLOBAL_BLOCK; + pwmTrigger.Type = BLOCK_COMMAND_CSP_TYPE_INDICATOR; + pwmTrigger.Info = BLK_CMD_CSP_INDICATOR_INFO_3D_MODE; + pwmTrigger.Dwc = 1; + trigger_Dw.Slice_Mask = adapter->hw_caps.chip_slice_mask; + + pwmTriggerOff.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Indicator; + pwmTriggerOff.Block_Id = CSP_GLOBAL_BLOCK; + pwmTriggerOff.Type = BLOCK_COMMAND_CSP_TYPE_INDICATOR; + pwmTriggerOff.Info = BLK_CMD_CSP_INDICATOR_INFO_OFF_MODE; + pwmTriggerOff.Dwc = 1; + + reg_Eu_Full_Glb.uint = 0; + reg_Eu_Full_Glb.reg.Uav_En = 1; + reg_Eu_Full_Glb.reg.Uav_Continue_Chk = 1; + reg_Eu_Full_Glb.reg.Uav_Buf_Size = EU_FULL_GLB_UAV_BUF_SIZE_128LINES; + reg_Eu_Full_Glb.reg.U_3d_Base = 6;//U_SHARP_3D_SLOT_START / 8; + reg_Eu_Full_Glb.reg.Cb_3d_Base = 8;//CB_3D_SLOT_START >> 4; + + reg_Tu_Tssharp_Ctrl.uint = 0; + + reg_Ffc_Ubuf_Golbalconfig.uint = 0; + reg_Ffc_Ubuf_Golbalconfig.reg.U_3d_Base = 6;//U_SHARP_3D_SLOT_START / 8; + reg_Fence_Mask.reg.Mask = 0xFFFFFFFF;//init this reg as 0xffffffff per Wenni + + map_argu.flags.cache_type = GF_MEM_WRITE_COMBINED; + map_argu.flags.mem_space = GF_MEM_KERNEL; + map_argu.flags.mem_type = GF_SYSTEM_IO; + map_argu.phys_addr = adapter->vidmm_bus_addr + engine->context_buf_phy_addr; + map_argu.size = HW_CONTEXT_SIZE_E3K; + + vma = gf_map_io_memory(NULL, &map_argu); + gf_memset(vma->virt_addr, 0, vma->size); + pContext = vma->virt_addr; + pContext->CSPRegs.reg_Csp_Misc_Control.reg.Dump_3d_Signature_Zero = b3dSigZero; + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.ff_regs.reg_Ff_Glb_Ctrl.reg.Ffc_Config_Mode = FF_GLB_CTRL_FFC_CONFIG_MODE_ZS_D_U; + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.eufs_regs.reg_Eu_3d_Glb.reg.Cb_Ps_Base = reg_Eu_Full_Glb.reg.Cb_3d_Base; // umd will set it again, here is just for HW init check. + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.eufs_regs.reg_Eu_3d_Glb.reg.U_Ps_Base = reg_Eu_Full_Glb.reg.U_3d_Base; // umd will set it again, here is just for HW init check. + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.wls_regs.reg_Ffc_Ubuf_3dconfig.reg.U_Ps_Base = reg_Eu_Full_Glb.reg.U_3d_Base; // umd will set it again, here is just for HW init check. + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.tu_regs.reg_Tu_Tssharp_3d_Ctrl.reg.Base_Address_Be = reg_Tu_Tssharp_Ctrl.reg.Base_Address_3d; // umd will set it again, here is just for HW init check. + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.ff_regs.reg_Ffc_Config.reg.En_Decompressed_Data_Reorder = 0x1; + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.ff_regs.reg_Ffc_Config.reg.Slot_Swz_Enable = 0x1; + gf_unmap_io_memory(vma); + + if (engine->shadow_context_buf_phy_addr) + { + gf_map_argu_t map_argu = {0}; + gf_vm_area_t *vma = NULL; + + map_argu.flags.cache_type = GF_MEM_WRITE_COMBINED; + map_argu.flags.mem_space = GF_MEM_KERNEL; + map_argu.flags.mem_type = GF_SYSTEM_IO; + map_argu.phys_addr = adapter->vidmm_bus_addr + engine->shadow_context_buf_phy_addr; + map_argu.size = HW_CONTEXT_SIZE_E3K; + + vma = gf_map_io_memory(NULL, &map_argu); + gf_memset(vma->virt_addr, 0xcd, vma->size); + pContext = vma->virt_addr; + + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.eufs_regs.reg_Eu_Full_Glb.uint = 0; + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.eufs_regs.reg_Eu_3d_Glb.uint = 0; + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.eufs_regs.reg_Fs_Cb_Cfg.uint = 0; + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.eups_regs.reg_Ps_Cb_Cfg.uint = 0; + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.wls_regs.reg_Ffc_Ubuf_3dconfig.uint = 0; + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.wls_regs.reg_Ffc_Ubuf_Golbalconfig.uint = 0; + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.tu_regs.reg_Tu_Tssharp_Ctrl.uint = 0; + pContext->HWContextbuffer.shadow_buf_3D.fe_be_regs.tu_regs.reg_Tu_Tssharp_3d_Ctrl.uint = 0; + gf_unmap_io_memory(vma); + } + + if(!engine->is_high_engine) + { + RbSize = 22 + (sizeof(CONTEXT_RESTORE_DMA_E3K) >> 2); + RbSize = (((RbSize) + 15) & ~15);//RB should 16 dw align + pRB = enginei_get_ring_buffer_space_e3k(engine_common, RbSize); + gf_memset(pRB, 0, (RbSize << 2)); + + *pRB++ = *(DWORD*)&pwmTrigger; + *pRB++ = *(DWORD*)&trigger_Dw; + // skip 8dw for hw block sync + pRB += 8; + *pRB++ = SET_REGISTER_FD_E3K(EU_FS_BLOCK,Reg_Eu_Full_Glb_Offset,1); + *pRB++ = reg_Eu_Full_Glb.uint; + *pRB++ = SET_REGISTER_FD_E3K(TUFE_BLOCK,Reg_Tu_Tssharp_Ctrl_Offset,1); + *pRB++ = reg_Tu_Tssharp_Ctrl.uint; + *pRB++ = SET_REGISTER_FD_E3K(WLS_FE_BLOCK,Reg_Ffc_Ubuf_Golbalconfig_Offset,1); + *pRB++ = reg_Ffc_Ubuf_Golbalconfig.uint; + *pRB++ = SET_REGISTER_FD_E3K(CSP_GLOBAL_BLOCK, Reg_Fence_Mask_Offset, 1); + *pRB++ = reg_Fence_Mask.uint; + *pRB++ = SET_REGISTER_FD_E3K(L2_BLOCK, Reg_L2_Performance_Offset, 1); + *pRB++ = reg_L2_Performance.uint; + + pRestoreDMA = (CONTEXT_RESTORE_DMA_E3K *)pRB; + + gf_memcpy(pRestoreDMA, &(pcmBuf->RestoreDMA), sizeof(CONTEXT_RESTORE_DMA_E3K)); + + pRestoreDMA->RestoreContext.Address_Mode = SET_REGISTER_ADDRESS_MODE_ADDRESS; + pRestoreDMA->ContextBufferOffset_L = engine->context_buf_phy_addr & 0xFFFFFFFF; + pRestoreDMA->ContextBufferOffset_H = (engine->context_buf_phy_addr >> 32) & 0xFF; + + //Csp will initinal its registers by itself, no need driver to do it. + pRestoreDMA->RestoreCsp.uint = 0; + pRestoreDMA->CSPOffset_H = 0; + pRestoreDMA->CSPOffset_L = 0; + + pRestoreDMA->RestoreEuFullGlb.uint = 0; + pRestoreDMA->EuFullGlbOffset_L = 0; + pRestoreDMA->EuFullGlbOffset_H = 0; + + pRestoreDMA->RestoreTsSharpCtrl.uint = 0; + pRestoreDMA->TsSharpCtrlOffset_L= 0; + pRestoreDMA->TsSharpCtrlOffset_H= 0; + + pRestoreDMA->RestoreFFCUbufConfig.uint = 0; + pRestoreDMA->FFCUbufConfigOffset_L = 0; + pRestoreDMA->FFCUbufConfigOffset_H = 0; + + pRestoreDMA->RestoreGpcpFe.uint = SET_REGISTER_ADDR_E3K(GPCPFE_BLOCK, Reg_Gpcpfe_Iidcnt_Offset, SET_REGISTER_ADDRESS_MODE_ADDRESS); + pRestoreDMA->GpcpFeOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K((engine->context_buf_phy_addr >> 32) & 0xFF, sizeof(GPCPFE_CONTEXTBUFFER_REGS) >> 2); + pRestoreDMA->GpcpFeOffset_L = SET_REGISTER_ADDR_LOW_E3K((engine->context_buf_phy_addr & 0xFFFFFFFF) + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpFeRegs))); + + pRestoreDMA->RestoreGpcpBe.uint = SET_REGISTER_ADDR_E3K(GPCPBE_BLOCK, Reg_Sto_Cfg_Offset, SET_REGISTER_ADDRESS_MODE_ADDRESS); + pRestoreDMA->GpcpBeOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K((engine->context_buf_phy_addr >> 32) & 0xFF, sizeof(Gpcpbe_regs) >> 2);; + pRestoreDMA->GpcpBeOffset_L = SET_REGISTER_ADDR_LOW_E3K((engine->context_buf_phy_addr & 0xFFFFFFFF) + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpBeRegs))); + + while (gpc_bit_mask) + { + unsigned int gpc_index = 0; + _BitScanForward(&gpc_index, gpc_bit_mask); + _bittestandreset((int *)&gpc_bit_mask, gpc_index); + pRestoreDMA->RestoreGpcTop[gpc_index].RestoreGpcTopCmd.uint = SET_REGISTER_ADDR_E3K(24, 0 + gpc_index * 40, SET_REGISTER_ADDRESS_MODE_ADDRESS); + pRestoreDMA->RestoreGpcTop[gpc_index].GpcTopOffset_L = SET_REGISTER_ADDR_LOW_E3K((engine->context_buf_phy_addr & 0xFFFFFFFF) + + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcTopRegs[gpc_index]))); + pRestoreDMA->RestoreGpcTop[gpc_index].GpcTopOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(0x0, 40); + } + + pRB = pRB + (sizeof(CONTEXT_RESTORE_DMA_E3K)>> 2); + + *pRB++ = *(DWORD*)&pwmTriggerOff; + *pRB++ = *(DWORD*)&triggerOff_Dw; + + enginei_do_kickoff_cmd_e3k(engine_common); + } + + return S_OK; +} + +int enginei_init_pwm_reg_e3k(engine_e3k_t *engine) +{ + adapter_t * adapter = engine->vidsch->adapter; + unsigned int cmd_mmio = 1; + + Reg_Pwr_Mgr_Cfg_En pwr_mgr_cfg_en = { .uint = 0x0 }; + unsigned int cg_wait_cnt = 0x08202020;//default value + + pwr_mgr_cfg_en.reg.En_Clkgate_3d = adapter->pm_caps.gfx_cg_auto; + pwr_mgr_cfg_en.reg.En_Clkgate_Vcp = adapter->pm_caps.vcp_cg_auto; + pwr_mgr_cfg_en.reg.En_Clkgate_Vpp = adapter->pm_caps.vpp_cg_auto; + + //Command mode + if (cmd_mmio == 0) + { + unsigned int *pRB = NULL; + unsigned int *pRB0 = NULL; + unsigned int rb_size_uint = 21; + unsigned int align_rb_size_uint = util_align(rb_size_uint, 16); + + Cmd_Blk_Cmd_Csp_Indicator pwmTrigger = { 0 }; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 trigger_Dw = { 0 }; + Cmd_Blk_Cmd_Csp_Indicator pwmTriggerOff = { 0 }; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 triggerOff_Dw = { 0 }; + + pwmTrigger.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Indicator; + pwmTrigger.Block_Id = CSP_GLOBAL_BLOCK; + pwmTrigger.Type = BLOCK_COMMAND_CSP_TYPE_INDICATOR; + pwmTrigger.Info = BLK_CMD_CSP_INDICATOR_INFO_3D_MODE; + pwmTrigger.Dwc = 1; + trigger_Dw.Slice_Mask = adapter->hw_caps.chip_slice_mask; + + pwmTriggerOff.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Indicator; + pwmTriggerOff.Block_Id = CSP_GLOBAL_BLOCK; + pwmTriggerOff.Type = BLOCK_COMMAND_CSP_TYPE_INDICATOR; + pwmTriggerOff.Info = BLK_CMD_CSP_INDICATOR_INFO_OFF_MODE; + pwmTriggerOff.Dwc = 1; + + pRB = pRB0 = (unsigned int *)enginei_get_ring_buffer_space_e3k(engine, align_rb_size_uint); + gf_memset(pRB, 0, (align_rb_size_uint << 2)); + + *pRB++ = *(unsigned int *)&pwmTrigger; + *pRB++ = *(unsigned int *)&trigger_Dw; + // skip 8dw for hw block sync + pRB += 8; + + *pRB++ = SET_REGISTER_FD_E3K(CSP_GLOBAL_BLOCK, Reg_Pwr_Mgr_Cfg_En_Offset, 1); + *pRB++ = pwr_mgr_cfg_en.uint; + + *pRB++ = SET_REGISTER_FD_E3K(CSP_GLOBAL_BLOCK, Reg_Pwr_Mgr_Wait_Cnt_Offset, 1); + *pRB++ = cg_wait_cnt; + + *pRB++ = SEND_EXTERNAL_FENCE_E3K(FENCE_IRQ_INTERRUPT_CPU); + *pRB++ = (engine->fence_buffer_phy_addr + DH_FENCE_OFFSET * sizeof(unsigned long long)) & 0xFFFFFFFF; + *pRB++ = ((engine->fence_buffer_phy_addr + DH_FENCE_OFFSET * sizeof(unsigned long long)) >> 32) & 0xFF; + *pRB++ = (DH_FENCE_VALUE)&0xFFFFFFFF; + *pRB++ = (((unsigned long long)(DH_FENCE_VALUE)) >> 32) & 0xFFFFFFFF; + *pRB++ = *(unsigned int *)&pwmTriggerOff; + *pRB++ = *(unsigned int *)&triggerOff_Dw; + + enginei_do_kickoff_cmd_e3k(engine); + } + else if (cmd_mmio == 1) + { + gf_write32(adapter->mmio + MMIO_CSP_START_ADDRESS + Reg_Pwr_Mgr_Cfg_En_Offset * 4, pwr_mgr_cfg_en.uint); + gf_write32(adapter->mmio + MMIO_CSP_START_ADDRESS + Reg_Pwr_Mgr_Wait_Cnt_Offset * 4, cg_wait_cnt); + } + + gf_info("init pwm auto mode %d done\n", pwr_mgr_cfg_en.uint); + + return S_OK; +} + +int engine_gfx_low_init_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr) +{ + vidmm_segment_memory_t *local_reserved_memory = sch_mgr->local_reserved_memory; + engine_gfx_e3k_t *engine = gf_calloc(sizeof(engine_gfx_e3k_t)); + engine_share_e3k_t *share = NULL; + unsigned long long local_reserved_start; + unsigned int current_pcie_offset = 0; + unsigned int current_low_offset = 0; + unsigned int start_align; + + local_reserved_start = local_reserved_memory->gpu_virt_addr; + + if (engine == NULL) + { + gf_error("%s, out of mem.\n", util_remove_name_suffix(__func__)); + gf_assert(0, "engine_gfx_low_init"); + return S_OK; + } + + start_align = ((local_reserved_start + HW_CONTEXT_E3K_ALIGN)& ~HW_CONTEXT_E3K_ALIGN) - local_reserved_start; + current_low_offset += start_align; + + enginei_common_init_e3k(sch_mgr, &engine->common, ¤t_pcie_offset, ¤t_low_offset); + + share = engine->common.share; + + share->context_buf_phy_addr = //high and low use same hwctx template + engine->context_buf_phy_addr = local_reserved_start + current_low_offset; + + //gf_info("%s:context_buf_phy_addr:%x, need 0x4000 align\n",util_remove_name_suffix(__func__), engine->context_buf_phy_addr);//for debug + + current_low_offset += HW_CONTEXT_SIZE_E3K * HW_CONTEXT_COUNT_E3K; + + engine->shadow_context_buf_phy_addr = local_reserved_start + current_low_offset; + current_low_offset += HW_CONTEXT_SIZE_E3K; + + engine->temp_context_buf_phy_addr = local_reserved_start + current_low_offset; + current_low_offset += HW_CONTEXT_SIZE_E3K; + + /* allocate begin end buffer from low reserved */ + share->begin_end_buffer_phy_addr = local_reserved_start + current_low_offset; + + //gf_assert((share->begin_end_buffer_phy_addr & 0xFFF) == 0, NULL); + //gf_info("%s:begin_end_buffer_phy_addr:%x, need 4k align\n",util_remove_name_suffix(__func__), share->begin_end_buffer_phy_addr);//for debug + + enginei_init_context_save_restore_dma_e3k(engine); + current_low_offset += BEGIN_END_BUF_SIZE_E3K; + + enginei_init_ring_buffer_commands_e3k(engine); + + share->_3dblt_data_lock = gf_create_mutex(); + + /* 3d blt Initialize */ + share->_3dblt_data_phy_addr = local_reserved_start + current_low_offset; + + share->_3dblt_data_size = 0; + + share->_3dblt_data_shadow = NULL; + + current_low_offset += _3DBLT_DATA_RESERVE_SIZE; + + engine->is_high_engine = 0; + + if (!adapter->hw_caps.video_only) + { + enginei_init_hardware_context_e3k(engine); + } + + if (adapter->chip_id >= CHIP_ARISE2030 && adapter->pm_caps.pwm_auto) + { + enginei_init_pwm_reg_e3k(&engine->common); + } + + enginei_common_share_init_e3k(&engine->common); + + gf_assert(current_low_offset <= local_reserved_memory->list_node->aligned_size, "current_low_offset <= local_reserved_memory->list_node->aligned_size"); + + return S_OK; +} + +int engine_gfx_high_init_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr) +{ + vidmm_segment_memory_t *local_reserved_memory = sch_mgr->local_reserved_memory; + engine_gfx_e3k_t *engine = gf_calloc(sizeof(engine_gfx_e3k_t)); + unsigned long long local_reserved_start; + unsigned int current_pcie_offset = 0; + unsigned int current_low_offset = 0; + unsigned int start_align; + + local_reserved_start = local_reserved_memory->gpu_virt_addr; + + if(engine == NULL) + { + gf_error("%s, out of mem.\n", util_remove_name_suffix(__func__)); + gf_assert(0, "engine_gfx_high_init"); + return S_OK; + } + + start_align = ((local_reserved_start + HW_CONTEXT_E3K_ALIGN)& ~HW_CONTEXT_E3K_ALIGN) - local_reserved_start; + current_low_offset += start_align; + + engine->context_buf_phy_addr = local_reserved_start + current_low_offset; + //gf_info("%s:context_buf_phy_addr:%x, need 0x4000 align\n", util_remove_name_suffix(__func__), engine->context_buf_phy_addr);//for debug + + current_low_offset += HW_CONTEXT_SIZE_E3K * HW_CONTEXT_COUNT_E3K; + + enginei_common_init_e3k(sch_mgr, &engine->common, ¤t_pcie_offset, ¤t_low_offset); + + engine->is_high_engine = 1; + + if (!adapter->hw_caps.video_only) + { + enginei_init_hardware_context_e3k(engine); + } + + gf_assert(current_low_offset <= local_reserved_memory->list_node->aligned_size, "current_low_offset <= local_reserved_memory->list_node->aligned_size"); + + return S_OK; +} + +int engine_vcp_init_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr) +{ + engine_vcp_e3k_t *engine = gf_calloc(sizeof(engine_vcp_e3k_t)); + unsigned int current_pcie_offset = 0; + unsigned int current_low_offset = 0; + + if(engine == NULL) + { + gf_error("%s, out of mem.\n", util_remove_name_suffix(__func__)); + gf_assert(0, "engine_vcp_init"); + } + + enginei_common_init_e3k(sch_mgr, engine, ¤t_pcie_offset, ¤t_low_offset); + + return S_OK; +} + +int engine_vpp_init_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr) +{ + engine_vpp_e3k_t *engine = gf_calloc(sizeof(engine_vpp_e3k_t)); + unsigned int current_pcie_offset = 0; + unsigned int current_low_offset = 0; + + if(engine == NULL) + { + gf_error("%s, out of mem.\n", util_remove_name_suffix(__func__)); + gf_assert(0, "engine_vpp_init"); + } + + enginei_common_init_e3k(sch_mgr, engine, ¤t_pcie_offset, ¤t_low_offset); + + return S_OK; +} + +void engine_gfx_low_restore_e3k(vidsch_mgr_t *sch_mgr, unsigned int pm) +{ + adapter_t *adapter = sch_mgr->adapter; + engine_gfx_e3k_t *engine = sch_mgr->private_data; + engine_share_e3k_t *share = engine->common.share; + + vidschi_reset_adapter_e3k(sch_mgr->adapter); + + //fix issue 18315, before system sleep, vcp clk is off, + //when resume, open vcp clk before disable vcp decouple in vidmm_init_mem_settings_e3k + vidsch_power_clock_on_off_vcp(sch_mgr, FALSE); + vidmm_init_mem_settings_e3k(sch_mgr->adapter); + + vidschi_init_hw_settings_e3k(sch_mgr->adapter); + + enginei_enable_ring_buffer_e3k(&engine->common); + + /* re-initialize video memory resource */ + enginei_init_context_save_restore_dma_e3k(engine); + + enginei_restore_3dblt_data_e3k(engine); + + if (!adapter->hw_caps.video_only) + { + enginei_init_hardware_context_e3k(engine); + } + + if (adapter->chip_id >= CHIP_ARISE2030 && adapter->pm_caps.pwm_auto) + { + enginei_init_pwm_reg_e3k(&engine->common); + } + + if (adapter->suspend_blt_mode == 1) + { + // In arm64, memcpy 32MB from Physical memory to IO memory will cost about 3S. + // So we use vidmm_segment_memory_transfer_e3k() to submit a page task help us copy memory faster. + if (share->bl_buffer_backup) + { + struct _vidmm_segment_memory *segment = (struct _vidmm_segment_memory *)share->bl_buffer_backup; + vidmm_segment_memory_transfer_e3k(adapter, &share->bl_buffer, segment, 1); + vidmm_release_segment_memory(adapter, segment); + share->bl_buffer_backup = NULL; + } + } + else if (adapter->suspend_blt_mode == 2) + { + if(pm && share->bl_buffer && share->bl_buffer->list_node->size && share->bl_buffer_backup) + { + + struct _vidmm_segment_memory *segment = (struct _vidmm_segment_memory *)share->bl_buffer_backup; + + vidmm_map_flags_t flags = {0}; + flags.mem_space = GF_MEM_KERNEL; + flags.cache_type = GF_MEM_UNCACHED; + vidmm_map_segment_memory(adapter, NULL, share->bl_buffer, &flags); + gf_memset(&flags, 0, sizeof(flags)); + flags.write_only = 1; + flags.mem_space = GF_MEM_KERNEL; + vidmm_map_segment_memory(adapter, NULL, segment, &flags); + + //gf_info("engine_gfx_low_restore_e3k: start restore bl_buffer size %d (engine %d)\n",share->bl_buffer->list_node->size, sch_mgr->engine_index); + gf_memcpy(share->bl_buffer->vma->virt_addr, segment->vma->virt_addr, share->bl_buffer->list_node->size); + //gf_info("engine_gfx_low_restore_e3k: end restore bl_buffer\n"); + vidmm_unmap_segment_memory(adapter, segment, GF_MEM_KERNEL); + vidmm_release_segment_memory(adapter, segment); + vidmm_unmap_segment_memory(adapter, share->bl_buffer, GF_MEM_KERNEL); + share->bl_buffer_backup = NULL; + } + } + else + { + if(pm && share->bl_buffer &&share->bl_buffer->vma && share->bl_buffer_backup) + { + gf_memcpy(share->bl_buffer->vma->virt_addr, share->bl_buffer_backup, share->bl_buffer->list_node->size); + + //util_dump_memory(share->bl_buffer->vma->virt_addr, 4*1024, "first 4k bl"); + + vidmm_unmap_segment_memory(adapter, share->bl_buffer, GF_MEM_KERNEL); + + gf_free(share->bl_buffer_backup); + share->bl_buffer_backup = NULL; + } + } +} + +void engine_gfx_high_restore_e3k(vidsch_mgr_t *sch_mgr, unsigned int pm) +{ + engine_gfx_e3k_t *engine = sch_mgr->private_data; + adapter_t *adapter = sch_mgr->adapter; + + enginei_enable_ring_buffer_e3k(&engine->common); + + if (!adapter->hw_caps.video_only) + { + enginei_init_hardware_context_e3k(engine); + } +} + +int engine_cil2_misc_e3k(vidsch_mgr_t *sch_mgr, krnl_cil2_misc_t *misc) +{ + int hRet = S_OK; + engine_e3k_t *engine = sch_mgr->private_data; + engine_share_e3k_t *share = engine->share; + gf_cil2_misc_t *gf_misc = misc->gf_misc; + + switch(gf_misc->op_code) + { + case GF_MISC_GET_3DBLT_CODE: + { + gf_mutex_lock(share->_3dblt_data_lock); + gf_misc->get_3dblt_code.size = share->_3dblt_data_size; + gf_misc->get_3dblt_code.capacity = _3DBLT_DATA_RESERVE_SIZE; + gf_misc->get_3dblt_code.base = share->_3dblt_data_phy_addr; + gf_mutex_unlock(share->_3dblt_data_lock); + break; + } + case GF_MISC_SET_3DBLT_CODE: + { + gf_map_argu_t map_argu = {0}; + gf_vm_area_t *vma = NULL; + + gf_mutex_lock(share->_3dblt_data_lock); + if (share->_3dblt_data_size == 0) + { + gf_assert(gf_misc->set_3dblt_code.size <= _3DBLT_DATA_RESERVE_SIZE, "3dblt_data overflow"); + + map_argu.flags.cache_type = GF_MEM_WRITE_COMBINED; + map_argu.flags.mem_space = GF_MEM_KERNEL; + map_argu.flags.mem_type = GF_SYSTEM_IO; + map_argu.phys_addr = sch_mgr->adapter->vidmm_bus_addr + share->_3dblt_data_phy_addr; + map_argu.size = gf_misc->set_3dblt_code.size; + + vma = gf_map_io_memory(NULL, &map_argu); + if (vma) + { + share->_3dblt_data_size = gf_misc->set_3dblt_code.size; + share->_3dblt_data_shadow = gf_malloc(share->_3dblt_data_size); + gf_copy_from_user(share->_3dblt_data_shadow, ptr64_to_ptr(gf_misc->set_3dblt_code.data), share->_3dblt_data_size); + + gf_memcpy(vma->virt_addr, share->_3dblt_data_shadow, share->_3dblt_data_size); + + gf_unmap_io_memory(vma); + } + else + { + gf_error("map 3dblt_data_phy_addr failed.\n"); + hRet = E_FAIL; + } + } + gf_mutex_unlock(share->_3dblt_data_lock); + } + break; + case GF_MISC_VIDEO_FENCE_GET: + { + if (gf_misc->video_fence_get.index < 8) + { + gf_spin_lock(share->lock); + gf_misc->video_fence_get.fence = share->internal_fence_value[gf_misc->video_fence_get.index]++; + gf_spin_unlock(share->lock); + } + else + { + hRet = E_FAIL; + gf_error("VIDEO_FENCE_GET wrong index value: %d.\n", gf_misc->video_fence_get.index); + } + } + break; + case GF_MISC_VIDEO_FENCE_CLEAR: + { + if (gf_misc->video_fence_clear.index < 8) + { + gf_spin_lock(share->lock); + share->internal_fence_value[gf_misc->video_fence_clear.index] = 0; + gf_spin_unlock(share->lock); + } + else + { + hRet = E_FAIL; + gf_error("VIDEO_FENCE_CLEAR wrong index value: %d.\n", gf_misc->video_fence_clear.index); + } + } + break; + case GF_MISC_MAP_GPUVA: + break; + default: + hRet = E_INVALIDARG; + } + + return hRet; +} + +int vidsch_reset_hw_e3k(vidsch_mgr_t *sch_mgr) +{ + adapter_t *adapter = sch_mgr->adapter; + EngineSatus_e3k engine_status = {0}; + unsigned int index = 0; + unsigned int fence_back_engine_count = 0; + engine_e3k_t *engine; + unsigned int *status =(unsigned int*) &engine_status; + int i; + + for( i = 0; i <7; i++) + { + *(status + i) = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + (Reg_Block_Busy_Bits_Top_Offset + i)*4); + } + + //gf_info("<<----^^^^^^^^^-----[Before reset hw] Current HW status -----^^^^^^^^^^^--->>\n"); + gf_info("current submit engine is 0x%x, Engine Hang and Status: %08x,%08x,%08x,%08x,%08x,%08x,%08x\n", + sch_mgr->engine_index, engine_status.Top.uint,engine_status.Gpc0_0.uint,engine_status.Gpc0_1.uint, + engine_status.Gpc1_0.uint,engine_status.Gpc1_1.uint,engine_status.Gpc2_0.uint,engine_status.Gpc2_1.uint); + + if(adapter->ctl_flags.hang_dump) + { + vidsch_save_misc_e3k(adapter, sch_mgr, SAVE_AFTER_POSTHANG);//save engine status. + } + /* reset hardware engine by engine */ + for(index=0; index< adapter->active_engine_count; index++) + { + unsigned int last_returned_fence_id; + vidsch_mgr_t *tmp_sch_mgr = adapter->sch_mgr[index]; + + if(tmp_sch_mgr == NULL) + { + fence_back_engine_count++; + continue; + } + + engine = tmp_sch_mgr->private_data; + last_returned_fence_id = *(volatile unsigned int *)engine->fence_buffer_virt_addr; + + if(last_returned_fence_id == (unsigned int)tmp_sch_mgr->last_send_fence_id) + { + //this engine is running normally + fence_back_engine_count++; + } + } + + /* return fake engine hang */ + if(engine_status.Top.uint == 0 && fence_back_engine_count == adapter->active_engine_count) + { + gf_error("fake timeout detected\n"); + return E_FAIL; + } + + /* update fence id skip the dead dma */ + for(index=0; indexactive_engine_count; index++) + { + vidsch_mgr_t *tmp_sch_mgr = adapter->sch_mgr[index]; + + if(tmp_sch_mgr) + { + engine_e3k_t *engine_tmp = tmp_sch_mgr->private_data; + + *(volatile unsigned int *)engine_tmp->fence_buffer_virt_addr = tmp_sch_mgr->last_send_fence_id & 0xFFFFFFFF; + *((volatile unsigned int *)engine_tmp->fence_buffer_virt_addr + 1) = (tmp_sch_mgr->last_send_fence_id >> 32)& 0xFFFFFFFF; + + tmp_sch_mgr->chip_func->restore(tmp_sch_mgr, FALSE); + + tmp_sch_mgr->init_submit = TRUE; + } + } + + return S_OK; +} + +#ifdef GF_HW_NULL +void engine_set_fence_id_e3k(vidsch_mgr_t *sch_mgr, unsigned long long fence_id) +{ + engine_e3k_t *engine = sch_mgr->private_data; + *(engine->fence_buffer_virt_addr) = fence_id; + gf_info("fake set fence id: %lld, at engine %d\n", fence_id, sch_mgr->engine_index); +} +#endif + diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_submit_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_submit_e3k.c new file mode 100644 index 0000000000000..69f6b44c01e8d --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_engine_submit_e3k.c @@ -0,0 +1,1053 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_engine_e3k.h" +#include "vidsch_debug_hang_e3k.h" +#include "ring_buffer.h" +#include "context.h" +#include "perfevent.h" + +reg_debug_mode_e3k debug_mode_e3k = {0}; +extern void test_manual_mode(adapter_t * adapter); + +static int enginei_ring_buffer_wrap_e3k(ring_buffer_t *ring, int skip_cnt, void *argu) +{ + engine_e3k_t *engine = argu; + unsigned int RbIndex = engine->vidsch->engine_index; + adapter_t *adapter = engine->vidsch->adapter; + unsigned int head_reg_off = EngineRbOffset(RbIndex); + unsigned int *cmd = engine->ring_buf_virt_addr + (ring->tail >> 2); + + if(0 && (skip_cnt > 7*4) && RbIndex != RB_INDEX_VCP0 && + RbIndex != RB_INDEX_VCP1 && RbIndex != RB_INDEX_VPP)//For raw skip cmd need add pwdIndicator, for High need add TBR indicator. + { + Csp_Opcodes_cmd skip_cmd = {0}; + Csp_Opcodes_cmd cmdTbr = {0}; + Cmd_Blk_Cmd_Csp_Indicator cmdPwmTrigger = {0}; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 cmdTrigger_Dw = {0}; + unsigned int dwSkip = (RbIndex == RB_INDEX_GFXH)?((skip_cnt >> 2) - 7):((skip_cnt >> 2) - 5); + + cmdPwmTrigger.Major_Opcode = CSP_OPCODE_Blk_Cmd_Csp_Indicator; + cmdPwmTrigger.Block_Id = CSP_GLOBAL_BLOCK; + cmdPwmTrigger.Type = BLOCK_COMMAND_CSP_TYPE_INDICATOR; + cmdPwmTrigger.Info = BLK_CMD_CSP_INDICATOR_INFO_3D_MODE; + cmdPwmTrigger.Dwc = 1; + + cmdTrigger_Dw.Slice_Mask = adapter->hw_caps.chip_slice_mask; + + skip_cmd.cmd_Skip.Dwc = dwSkip; + skip_cmd.cmd_Skip.Major_Opcode = CSP_OPCODE_Skip; + + if(RbIndex == RB_INDEX_GFXH)//add TBR indicator for high + { + cmdTbr.cmd_Tbr_Indicator.Skip_En = 1; + cmdTbr.cmd_Tbr_Indicator.Indicator_Info = TBR_INDICATOR_INDICATOR_INFO_END; + cmdTbr.cmd_Tbr_Indicator.Block_Id = TASBE_BLOCK; + cmdTbr.cmd_Tbr_Indicator.Major_Opcode = 0xF; + + *cmd++ = cmdTbr.uint; + } + + *cmd++ = *(DWORD*)&cmdPwmTrigger; + *cmd++ = *(DWORD*)&cmdTrigger_Dw; + + *cmd++ = skip_cmd.uint; + cmd += dwSkip; + + if(RbIndex != RB_INDEX_GFXH)// only high leave with pwd indicator on. + { + cmdPwmTrigger.Info = BLK_CMD_CSP_INDICATOR_INFO_OFF_MODE; + cmdTrigger_Dw.Slice_Mask = 0; + } + + *cmd++ = *(DWORD*)&cmdPwmTrigger; + *cmd++ = *(DWORD*)&cmdTrigger_Dw; + + if(RbIndex == RB_INDEX_GFXH) + { + cmdTbr.cmd_Tbr_Indicator.Indicator_Info = TBR_INDICATOR_INDICATOR_INFO_BEGIN; + + *cmd++ = cmdTbr.uint; + } + } + else if(skip_cnt > 0)//not enough for store indicators. + { + gf_memset(cmd, 0, skip_cnt); + } + + return gf_read32(adapter->mmio + (head_reg_off + 2)*4 + MMIO_CSP_START_ADDRESS); +} + +void enginei_enable_ring_buffer_e3k(engine_e3k_t *engine) +{ + adapter_t *adapter = engine->vidsch->adapter; + unsigned int RbIndex = engine->vidsch->engine_index; + Reg_Run_List_Ctx_Addr1 reg_Run_List_Ctx_Addr1 = { 0 }; + Reg_Ring_Buf_Size reg_Ring_Buf_Size = { 0 }; + Reg_Ring_Buf_Head reg_Ring_Buf_Head = { 0 }; + Reg_Ring_Buf_Tail reg_Ring_Buf_Tail = { 0 }; + unsigned int RegRbOffset = EngineRbOffset(RbIndex); + + ring_buffer_init(&engine->ring, RING_BUFFER_SIZE_E3K, 0, enginei_ring_buffer_wrap_e3k, engine); + + reg_Ring_Buf_Tail.reg.Rb_Tail = + reg_Ring_Buf_Head.reg.Rb_Head = 0; + reg_Ring_Buf_Size.reg.Rb_Size = RING_BUFFER_SIZE_E3K; + + reg_Run_List_Ctx_Addr1.reg.Addr = (engine->ring_buf_phys_addr >> 12) & 0xFFFFFFF; + reg_Run_List_Ctx_Addr1.reg.Kickoff = 0; + + gf_write32(adapter->mmio + RegRbOffset * 4 + MMIO_CSP_START_ADDRESS, reg_Run_List_Ctx_Addr1.uint); + gf_write32(adapter->mmio + (RegRbOffset+1) * 4 + MMIO_CSP_START_ADDRESS, reg_Ring_Buf_Size.uint ); + gf_write32(adapter->mmio + (RegRbOffset+2) * 4 + MMIO_CSP_START_ADDRESS, reg_Ring_Buf_Head.uint ); + gf_write32(adapter->mmio + (RegRbOffset+3) * 4 + MMIO_CSP_START_ADDRESS, reg_Ring_Buf_Tail.uint ); + + reg_Run_List_Ctx_Addr1.reg.Kickoff = 1; + + gf_write32( adapter->mmio + RegRbOffset * 4 + MMIO_CSP_START_ADDRESS, reg_Run_List_Ctx_Addr1.uint ); +} + +unsigned int *enginei_get_ring_buffer_space_e3k(engine_e3k_t *engine, int size_uint) +{ + unsigned int *ring_buffer = engine->ring_buf_virt_addr; + int offset = -1; + + while(offset == -1) + { + offset = ring_buffer_get_space(&engine->ring, size_uint << 2); + } + +#if GF_TRACE_HW_HANG + engine->last_ring_buffer = ring_buffer + (offset >> 2); + engine->last_ring_buffer_size = (size_uint << 2); +#endif + + // gf_info("idx:%d, offset:%x, end:%x\n", engine->vidsch->engine_index, offset, offset + (size_uint <<2)); + return ring_buffer + (offset >> 2); +} + +void enginei_do_kickoff_cmd_e3k(engine_e3k_t *engine) +{ + adapter_t *adapter = engine->vidsch->adapter; + engine_share_e3k_t *share = (engine_share_e3k_t*)adapter->private_data; + unsigned int RbIndex = engine->vidsch->engine_index; + unsigned int RegRbOffset = EngineRbOffset(RbIndex); + unsigned int offset = 0; + vidsch_mgr_t *sch_mgr = engine->vidsch; + int g_count = 0; + static int print_once[2] = {0, 0}; + + gf_mb(); + + { + vidsch_mgr_t *vidsch = engine->vidsch; + + *((volatile unsigned int*)share->flush_fifo_buffer->vma->virt_addr + RbIndex) = (unsigned int)vidsch->last_send_fence_id; + + while(*((volatile unsigned int*)share->flush_fifo_buffer->vma->virt_addr + RbIndex) != (unsigned int)vidsch->last_send_fence_id) + { + if (print_once[0] == 0) + { +#ifdef _DEBUG_ + //gf_warning("flush fifo index:%x\n",RbIndex); + gf_warning("krnl virt addr: %p, write value: %x, read value: %x\n", + ((volatile unsigned int*)share->flush_fifo_buffer->vma->virt_addr + RbIndex), + (unsigned int)vidsch->last_send_fence_id, + *((volatile unsigned int*)share->flush_fifo_buffer->vma->virt_addr + RbIndex)); +#endif + print_once[0] = 1; + } + + adapter->kickoff_error.error |= 0x1; + adapter->kickoff_error.RbIndex = RbIndex; + adapter->kickoff_error.last_send_fence_id = (unsigned int)vidsch->last_send_fence_id; + adapter->kickoff_error.flush_fifo_buffer_value = *((volatile unsigned int*)share->flush_fifo_buffer->vma->virt_addr + RbIndex); + + // gf_assert(0, NULL); + if (g_count++ > 10) + { + break; + } + } + } + + gf_mb(); + + if (adapter->pwm_level.EnableClockGating) + { + unsigned long flags; + flags = gf_spin_lock_irqsave(sch_mgr->power_status_lock); + + { + if(sch_mgr->chip_func->power_clock) + { + //gf_info("power on: last_send_fence_id=%d. \n", sch_mgr->last_send_fence_id); + sch_mgr->chip_func->power_clock(sch_mgr, FALSE); + sch_mgr->engine_dvfs_power_on = TRUE; + } + } + + gf_write32(adapter->mmio + (RegRbOffset+3) * 4 + MMIO_CSP_START_ADDRESS, engine->ring.tail); + + gf_spin_unlock_irqrestore(sch_mgr->power_status_lock, flags); + } + else + { + gf_write32(adapter->mmio + (RegRbOffset+3) * 4 + MMIO_CSP_START_ADDRESS, engine->ring.tail); + } + + gf_mb(); + + g_count = 0; + do{ + offset = gf_read32(adapter->mmio + (RegRbOffset+3) * 4 + MMIO_CSP_START_ADDRESS); + + if(offset != engine->ring.tail) + { + if (print_once[1] == 0) + { +#ifdef _DEBUG_ + gf_warning("idx:%d, kick off:%x, read:%x\n", RbIndex, engine->ring.tail, offset); +#endif + print_once[1] = 1; + } + adapter->kickoff_error.error |= 0x2; + adapter->kickoff_error.RbIndex = RbIndex; + adapter->kickoff_error.tail = engine->ring.tail; + adapter->kickoff_error.offset = offset; + } + + if (g_count++ > 10) + { + break; + } + }while(engine->ring.tail != offset); +} + +void enginei_invalidate_gart_e3k(engine_e3k_t *engine) +{ + adapter_t *adapter = engine->vidsch->adapter; + vidmm_gart_table_info_t *gart_table = adapter->gart_table_L3; + Reg_Pt_Inv_Trig reg_Pt_Inv_Trig = {0}; + Reg_Pt_Inv_Addr reg_Pt_Inv_Addr = {0}; + Reg_Pt_Inv_Mask reg_Pt_Inv_Mask = {0}; + + DWORD DtlbShift = 0x10; //Per HW, one Dtlb Cachelline is 512bit, one cache line size maps to 16*4KB virtual address. + reg_Pt_Inv_Trig.reg.Target = PT_INV_TRIG_TARGET_DTLB; + + gf_mutex_lock(adapter->gart_table_lock); + + if(gart_table->dirty == FALSE) + { + gf_mutex_unlock(adapter->gart_table_lock); + return; + } + + reg_Pt_Inv_Addr.reg.Address = (gart_table->gart_table_dirty_addr>>DtlbShift)<<4; + reg_Pt_Inv_Mask.reg.Mask = ((~gart_table->gart_table_dirty_mask )>>DtlbShift)<<4; + + gf_write32(adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Pt_Inv_Addr_Offset*4 , reg_Pt_Inv_Addr.uint); + gf_write32(adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Pt_Inv_Mask_Offset*4, reg_Pt_Inv_Mask.uint); + gf_write32(adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Pt_Inv_Trig_Offset*4, reg_Pt_Inv_Trig.uint); + + gart_table->gart_table_dirty_mask = 0; + gart_table->gart_table_dirty_addr = 0; + gart_table->dirty = FALSE; + + gf_mutex_unlock(adapter->gart_table_lock); +} + +static int enginei_submit_to_gfx_high_e3k(engine_e3k_t *engine, task_dma_t *task) +{ + engine_gfx_e3k_t *engine_gfx = (engine_gfx_e3k_t*) engine; + engine_share_e3k_t *share = engine->share; + adapter_t *adapter = engine->vidsch->adapter; + hw_ctxbuf_t *hwctx = task->hw_ctx_info; + unsigned int dwDmaBufferSize = (task->submit_end_offset - task->submit_start_offset) >> 2; + large_inter fence_offset; + large_inter fence_offset_fake; + + large_inter fence_offset_local; + large_inter fence_offset_local_fake; + + large_inter fence_offset_snoop; + large_inter fence_offset_snoop_fake; + + large_inter fence_id; + large_inter context_buf_phy_addr; + large_inter context_buf_phy_addr_for_low; + unsigned int * pRB = NULL; + unsigned int * pRB0 = NULL; + unsigned int * pRB1 = NULL; + Cmd_Blk_Cmd_Csp_Indicator_Dword1 trigger_Dw = {0}; + Csp_Opcodes_cmd cmd = {0}; + unsigned int dwRealRBSize; + RINGBUFFER_COMMANDS_E3K *pRingBufferCommands = (RINGBUFFER_COMMANDS_E3K*)share->RingBufferCommands; + RB_PREDEFINE_DMA *pPredefine = (RB_PREDEFINE_DMA*)share->begin_end_vma->virt_addr; + CONTEXT_RESTORE_DMA_E3K *pRestoreDMA = &(pPredefine->RestoreDMA); + CONTEXT_SAVE_DMA_E3K *pSaveDMA = &(pPredefine->SaveDMA); + CACHEFLUSH_DMA_E3K *pCacheFlushDMA3DL = &(pPredefine->FlushDMA3DL); + + // TBR indicator + pwmTrigger followed + saveLowRBContext + restore high + dwDmaSize + dwCacheFlush + save high+ dwRestoreLowRBContext+ dwFence + pwmOff followed + TBR indicator; + unsigned int dwRbSize = 2 + + + (sizeof(CONTEXT_SAVE_DMA_E3K) / sizeof(DWORD)) //for low + + dwDmaBufferSize + + (sizeof(CACHEFLUSH_DMA_E3K) / sizeof(DWORD)) //for high + + (sizeof(CONTEXT_RESTORE_DMA_E3K) / sizeof(DWORD)) //for low + + 5*6 //double fence cmd + + 2 + + 2; + + if(task->need_hwctx_switch) + { + dwRbSize += (sizeof(CONTEXT_SAVE_DMA_E3K) / sizeof(DWORD)) + + (sizeof(CONTEXT_RESTORE_DMA_E3K) / sizeof(DWORD)); + + if (hwctx->is_initialized) + { + context_buf_phy_addr.quad64 = hwctx->context_buffer_address; + } + else + { + context_buf_phy_addr.quad64 = share->context_buf_phy_addr; + hwctx->is_initialized = TRUE; + } + } + + fence_offset.quad64 = engine->fence_buffer_phy_addr; + fence_offset_fake.quad64 = engine->fence_buffer_phy_addr_fake; + + fence_offset_local.quad64 = engine->fence_buffer_phy_addr_local; + fence_offset_local_fake.quad64 = engine->fence_buffer_phy_addr_local_fake; + + fence_offset_snoop.quad64 = engine->fence_buffer_phy_addr_snoop; + fence_offset_snoop_fake.quad64 = engine->fence_buffer_phy_addr_snoop_fake; + + fence_id.quad64 = task->desc.fence_id; + + context_buf_phy_addr_for_low.quad64 = engine_gfx->context_buf_phy_addr; + dwRbSize = ((dwRbSize + 15) & ~15); + + pRB0 = + pRB = gf_calloc((dwRbSize <<2)); + gf_memset(pRB0, 0, dwRbSize << 2); + + if(!pRB) + { + gf_info("mem calloc failed for high engine\n"); + gf_assert(0, NULL); + return S_OK; + } + + pRB1 = enginei_get_ring_buffer_space_e3k(engine, dwRbSize); + gf_memset(pRB1, 0, dwRbSize << 2); + + cmd.cmd_Tbr_Indicator.Skip_En = 1; + cmd.cmd_Tbr_Indicator.Indicator_Info = TBR_INDICATOR_INDICATOR_INFO_END; + cmd.cmd_Tbr_Indicator.Block_Id = TASBE_BLOCK; + cmd.cmd_Tbr_Indicator.Major_Opcode = 0xF; + + //1. pwmTrigger; + trigger_Dw.Slice_Mask = adapter->hw_caps.chip_slice_mask; + + *pRB++ = cmd.uint; + *pRB++ = *(DWORD*)&pRingBufferCommands->c1.pwmTrigger; + *pRB++ = *(DWORD*)&trigger_Dw; + + //2. Save LowRB context; + gf_memcpy(pRB, pSaveDMA, sizeof(CONTEXT_SAVE_DMA_E3K)); + + ((CONTEXT_SAVE_DMA_E3K*)pRB)->SaveContext.Address_Mode = SET_REGISTER_ADDRESS_MODE_ADDRESS; + ((CONTEXT_SAVE_DMA_E3K*)pRB)->ContextBufferOffset_H = context_buf_phy_addr_for_low.high32 & 0xFF; + ((CONTEXT_SAVE_DMA_E3K*)pRB)->ContextBufferOffset_L = context_buf_phy_addr_for_low.low32; + + ((CONTEXT_SAVE_DMA_E3K*)pRB)->SaveCSPRegister.uint = SEND_QUERY_DUMP_E3K(CSP_GLOBAL_BLOCK, sizeof(CSP_CONTEXTBUFFER_REGS)>>2, QUERY_DUMP_ADDRESS_MODE_ADDRESS); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->CSPOffset_L = SEND_QUERY_ADDR1_E3K(context_buf_phy_addr_for_low.low32 + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->CSPRegs))); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->CSPOffset_H = SEND_QUERY_ADDR2_AND_OFFSET_E3K(context_buf_phy_addr_for_low.high32 & 0xFF, Reg_Csp_Ms_Total_Gpu_Timestamp_Offset, TRUE, FALSE); + + ((CONTEXT_SAVE_DMA_E3K*)pRB)->SaveGpcpFeRegister.uint = SEND_QUERY_DUMP_E3K(GPCPFE_BLOCK, sizeof(GPCPFE_CONTEXTBUFFER_REGS)>>2, QUERY_DUMP_ADDRESS_MODE_ADDRESS); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->GpcpFeOffset_L = SEND_QUERY_ADDR1_E3K(context_buf_phy_addr_for_low.low32 + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpFeRegs))); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->GpcpFeOffset_H = SEND_QUERY_ADDR2_AND_OFFSET_E3K(context_buf_phy_addr_for_low.high32 & 0xFF, Reg_Gpcpfe_Iidcnt_Offset, TRUE, FALSE); + + ((CONTEXT_SAVE_DMA_E3K*)pRB)->SaveGpcpBeRegister.uint = SEND_QUERY_DUMP_E3K(GPCPBE_BLOCK, sizeof(Gpcpbe_regs)>>2, QUERY_DUMP_ADDRESS_MODE_ADDRESS); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->GpcpBeOffset_L = SEND_QUERY_ADDR1_E3K(context_buf_phy_addr_for_low.low32 + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpBeRegs))); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->GpcpBeOffset_H = SEND_QUERY_ADDR2_AND_OFFSET_E3K(context_buf_phy_addr_for_low.high32 & 0xFF, Reg_Sto_Cfg_Offset, TRUE, FALSE); + + pRB += sizeof(CONTEXT_SAVE_DMA_E3K) >> 2; + + //3. restore high context + if(task->need_hwctx_switch) + { + gf_memcpy(pRB, pRestoreDMA, sizeof(CONTEXT_RESTORE_DMA_E3K)); + + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->RestoreContext.Address_Mode = SET_REGISTER_ADDRESS_MODE_ADDRESS; + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->ContextBufferOffset_H = context_buf_phy_addr.high32 & 0xFF; + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->ContextBufferOffset_L = context_buf_phy_addr.low32; + + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->RestoreCsp.uint = SET_REGISTER_ADDR_E3K(CSP_GLOBAL_BLOCK,Reg_Csp_Ms_Total_Gpu_Timestamp_Offset,SET_REGISTER_ADDRESS_MODE_ADDRESS); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->CSPOffset_L = SET_REGISTER_ADDR_LOW_E3K(context_buf_phy_addr.low32 + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->CSPRegs))); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->CSPOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(context_buf_phy_addr.high32 & 0xFF, sizeof(CSP_CONTEXTBUFFER_REGS) >> 2); + + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->RestoreGpcpFe.uint = SET_REGISTER_ADDR_E3K(GPCPFE_BLOCK,Reg_Gpcpfe_Iidcnt_Offset,SET_REGISTER_ADDRESS_MODE_ADDRESS); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->GpcpFeOffset_L = SET_REGISTER_ADDR_LOW_E3K(context_buf_phy_addr.low32 + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpFeRegs))); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->GpcpFeOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(context_buf_phy_addr.high32 & 0xFF, sizeof(GPCPFE_CONTEXTBUFFER_REGS) >> 2); + + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->RestoreGpcpBe.uint = SET_REGISTER_ADDR_E3K(GPCPBE_BLOCK, Reg_Sto_Cfg_Offset, QUERY_DUMP_ADDRESS_MODE_ADDRESS); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->GpcpBeOffset_L = SET_REGISTER_ADDR_LOW_E3K(context_buf_phy_addr.low32+ ((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpBeRegs)))); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->GpcpBeOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(context_buf_phy_addr.high32 & 0xFF, sizeof(Gpcpbe_regs)>>2); + + pRB += sizeof(CONTEXT_RESTORE_DMA_E3K) >> 2; + } + + //4. DmaCommand + gf_memcpy(pRB, task->dma_buffer_node->virt_base_addr + task->submit_start_offset, dwDmaBufferSize << 2); + pRB += dwDmaBufferSize; + + //5. CacheFlush, all pipe line + gf_memcpy(pRB, pCacheFlushDMA3DL, sizeof(CACHEFLUSH_DMA_E3K)); + pRB += sizeof(CACHEFLUSH_DMA_E3K) >> 2; + + //6 save high context. + if(task->need_hwctx_switch) + { + gf_memcpy(pRB, pSaveDMA, sizeof(CONTEXT_SAVE_DMA_E3K)); + + ((CONTEXT_SAVE_DMA_E3K*)pRB)->SaveContext.Address_Mode = SET_REGISTER_ADDRESS_MODE_ADDRESS; + ((CONTEXT_SAVE_DMA_E3K*)pRB)->ContextBufferOffset_H = (hwctx->context_buffer_address >>32) & 0xFF; + ((CONTEXT_SAVE_DMA_E3K*)pRB)->ContextBufferOffset_L = hwctx->context_buffer_address & 0xFFFFFFFF; + + ((CONTEXT_SAVE_DMA_E3K*)pRB)->SaveCSPRegister.uint = SEND_QUERY_DUMP_E3K(CSP_GLOBAL_BLOCK, sizeof(CSP_CONTEXTBUFFER_REGS)>>2, QUERY_DUMP_ADDRESS_MODE_ADDRESS); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->CSPOffset_L = SEND_QUERY_ADDR1_E3K((hwctx->context_buffer_address & 0xFFFFFFFF) + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->CSPRegs))); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->CSPOffset_H = SEND_QUERY_ADDR2_AND_OFFSET_E3K((hwctx->context_buffer_address >>32) & 0xFF, Reg_Csp_Ms_Total_Gpu_Timestamp_Offset, TRUE, FALSE); + + ((CONTEXT_SAVE_DMA_E3K*)pRB)->SaveGpcpFeRegister.uint = SEND_QUERY_DUMP_E3K(GPCPFE_BLOCK, sizeof(GPCPFE_CONTEXTBUFFER_REGS)>>2, QUERY_DUMP_ADDRESS_MODE_ADDRESS); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->GpcpFeOffset_L = SEND_QUERY_ADDR1_E3K((hwctx->context_buffer_address & 0xFFFFFFFF) + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpFeRegs))); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->GpcpFeOffset_H = SEND_QUERY_ADDR2_AND_OFFSET_E3K((hwctx->context_buffer_address >>32) & 0xFF, Reg_Gpcpfe_Iidcnt_Offset, TRUE, FALSE); + + ((CONTEXT_SAVE_DMA_E3K*)pRB)->SaveGpcpBeRegister.uint = SEND_QUERY_DUMP_E3K(GPCPBE_BLOCK, sizeof(Gpcpbe_regs)>>2, QUERY_DUMP_ADDRESS_MODE_ADDRESS); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->GpcpBeOffset_L = SEND_QUERY_ADDR1_E3K((hwctx->context_buffer_address & 0xFFFFFFFF) + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpBeRegs))); + ((CONTEXT_SAVE_DMA_E3K*)pRB)->GpcpBeOffset_H = SEND_QUERY_ADDR2_AND_OFFSET_E3K((hwctx->context_buffer_address >> 32) & 0xFF, Reg_Sto_Cfg_Offset, TRUE, FALSE); + + pRB += sizeof(CONTEXT_SAVE_DMA_E3K) >> 2; + } + + //7. Restore LowRB context; + gf_memcpy(pRB, pRestoreDMA, sizeof(CONTEXT_RESTORE_DMA_E3K)); + + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->RestoreContext.Address_Mode = SET_REGISTER_ADDRESS_MODE_ADDRESS; + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->ContextBufferOffset_H = context_buf_phy_addr_for_low.high32 & 0xFF; + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->ContextBufferOffset_L = context_buf_phy_addr_for_low.low32; + + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->RestoreCsp.uint = SET_REGISTER_ADDR_E3K(CSP_GLOBAL_BLOCK,Reg_Csp_Ms_Total_Gpu_Timestamp_Offset,SET_REGISTER_ADDRESS_MODE_ADDRESS); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->CSPOffset_L = SET_REGISTER_ADDR_LOW_E3K(context_buf_phy_addr_for_low.low32 + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->CSPRegs))); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->CSPOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(context_buf_phy_addr_for_low.high32 & 0xFF, sizeof(CSP_CONTEXTBUFFER_REGS) >> 2); + + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->RestoreGpcpFe.uint = SET_REGISTER_ADDR_E3K(GPCPFE_BLOCK,Reg_Gpcpfe_Iidcnt_Offset,SET_REGISTER_ADDRESS_MODE_ADDRESS); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->GpcpFeOffset_L = SET_REGISTER_ADDR_LOW_E3K(context_buf_phy_addr_for_low.low32 + (unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpFeRegs))); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->GpcpFeOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(context_buf_phy_addr_for_low.high32 & 0xFF, sizeof(GPCPFE_CONTEXTBUFFER_REGS) >> 2); + + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->RestoreGpcpBe.uint = SET_REGISTER_ADDR_E3K(GPCPBE_BLOCK, Reg_Sto_Cfg_Offset, QUERY_DUMP_ADDRESS_MODE_ADDRESS); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->GpcpBeOffset_L = SET_REGISTER_ADDR_LOW_E3K(context_buf_phy_addr_for_low.low32 + ((unsigned long)(&(((CONTEXT_BUFFER_E3K*)0)->GpcpBeRegs)))); + ((CONTEXT_RESTORE_DMA_E3K*)pRB)->GpcpBeOffset_H = SET_REGISTER_ADDR_HIGH_AND_REGCNT_E3K(context_buf_phy_addr_for_low.high32 & 0xFF, sizeof(Gpcpbe_regs)>>2); + + pRB += sizeof(CONTEXT_RESTORE_DMA_E3K) >> 2; + + //8.external Fence + *pRB++ = *(DWORD*)&pRingBufferCommands->c1.Fence; + *pRB++ = fence_offset.low32; //FenceAddr_Low; + *pRB++ = fence_offset.high32 &0xFF; //FenceAddr_High + *pRB++ = fence_id.low32; //FenceId_Low; + *pRB++ = fence_id.high32; //FenceId_High; + + *pRB++ = *(DWORD*)&pRingBufferCommands->c1.Fence_1; + *pRB++ = fence_offset_fake.low32; //FenceAddr_Low; + *pRB++ = fence_offset_fake.high32 &0xFF; //FenceAddr_High + *pRB++ = fence_id.low32; //FenceId_Low; + *pRB++ = fence_id.high32; //FenceId_High; + + *pRB++ = *(DWORD*)&pRingBufferCommands->c1.Fence_2; + *pRB++ = fence_offset_local.low32; //FenceAddr_Low; + *pRB++ = fence_offset_local.high32 &0xFF; //FenceAddr_High + *pRB++ = fence_id.low32; //FenceId_Low; + *pRB++ = fence_id.high32; //FenceId_High; + + *pRB++ = *(DWORD*)&pRingBufferCommands->c1.Fence_3; + *pRB++ = fence_offset_local_fake.low32; //FenceAddr_Low; + *pRB++ = fence_offset_local_fake.high32 &0xFF; //FenceAddr_High + *pRB++ = fence_id.low32; //FenceId_Low; + *pRB++ = fence_id.high32; //FenceId_High; + + + *pRB++ = *(DWORD*)&pRingBufferCommands->c1.Fence_4; + *pRB++ = fence_offset_snoop.low32; //FenceAddr_Low; + *pRB++ = fence_offset_snoop.high32 &0xFF; //FenceAddr_High + *pRB++ = fence_id.low32; //FenceId_Low; + *pRB++ = fence_id.high32; //FenceId_High; + + *pRB++ = *(DWORD*)&pRingBufferCommands->c1.Fence_5; + *pRB++ = fence_offset_snoop_fake.low32; //FenceAddr_Low; + *pRB++ = fence_offset_snoop_fake.high32 &0xFF; //FenceAddr_High + *pRB++ = fence_id.low32; //FenceId_Low; + *pRB++ = fence_id.high32; //FenceId_High; + + //9.pwmOff; + *pRB++ = *(DWORD*)&pRingBufferCommands->c1.pwmTrigger; + *pRB++ = *(DWORD*)&trigger_Dw; + + cmd.cmd_Tbr_Indicator.Indicator_Info = TBR_INDICATOR_INDICATOR_INFO_BEGIN; + *pRB++ = cmd.uint; + + dwRealRBSize = pRB - pRB0; + +// dwAlignRBSize = (((dwRealRBSize) + 15) & ~15); +// if (dwAlignRBSize != dwRbSize) +// { +// *pRB++ = SEND_SKIP_E3K(dwRbSize - dwRealRBSize); +// } + + gf_memcpy(pRB1, pRB0, (dwRbSize<<2)); + //util_dump_memory(pRB1, dwRbSize<<2, "high dma in rb"); + + if(pRB0) gf_free(pRB0); + + enginei_do_kickoff_cmd_e3k(engine); + + return S_OK; +} + +static void enginei_idle_ring_buffer_e3k(engine_e3k_t *engine) +{ + vidsch_mgr_t *sch_mgr = engine->vidsch; + adapter_t *adapter = sch_mgr->adapter; + unsigned int engine_index = sch_mgr->engine_index; + EngineSatus_e3k engine_status; + unsigned int status_offset = MMIO_CSP_START_ADDRESS + Reg_Block_Busy_Bits_Top_Offset*4; + unsigned int rb_head_offset = MMIO_CSP_START_ADDRESS + (Reg_Ring_Buf_Offset + engine_index * 4 +2) * 4; + unsigned int rb_tail_offset = MMIO_CSP_START_ADDRESS + (Reg_Ring_Buf_Offset + engine_index * 4 +3) * 4; + unsigned int RBHead = 0, RBTail=0; + unsigned int current_rb_dma =0; + unsigned int i=0; + + gf_msleep(5000); + + while(1) + { + engine_status.Top.uint = gf_read32(adapter->mmio + status_offset + 0); + engine_status.Gpc0_0.uint = gf_read32(adapter->mmio + status_offset + 4); + engine_status.Gpc0_1.uint = gf_read32(adapter->mmio + status_offset + 8); + engine_status.Gpc1_0.uint = gf_read32(adapter->mmio + status_offset + 12); + engine_status.Gpc1_1.uint = gf_read32(adapter->mmio + status_offset + 16); + engine_status.Gpc2_0.uint = gf_read32(adapter->mmio + status_offset + 20); + engine_status.Gpc2_1.uint = gf_read32(adapter->mmio + status_offset + 24); + RBHead = gf_read32(adapter->mmio + rb_head_offset); + RBTail = gf_read32(adapter->mmio + rb_tail_offset); + current_rb_dma = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS +(Reg_Cur_3d_Rbuf_Cmd_Offset + engine_index)*4); + + gf_info("engine index:%x,rb head(%x):%x,cur rb dma:%x tail(%x):%x,Engine Status: %08x,%08x,%08x,%08x,%08x,%08x,%08x,\n", + engine_index, rb_head_offset, RBHead, current_rb_dma, rb_tail_offset, RBTail,engine_status.Top.uint, + engine_status.Gpc0_0.uint, engine_status.Gpc0_1.uint, engine_status.Gpc1_0.uint, engine_status.Gpc1_1.uint, engine_status.Gpc2_0.uint, engine_status.Gpc2_1.uint); + + if(((RBTail != RBHead) || (engine_status.Top.uint !=0)) && (i++ < 10)) + { + gf_msleep(5000); + } + else + { + break; + } + } +} + +#define DBG_HW_RING_BUFFER 0 +static int enginei_common_submit_e3k(engine_e3k_t *engine, task_dma_t *task) +{ + engine_share_e3k_t *share = engine->share; + adapter_t *adapter = engine->vidsch->adapter; + hw_ctxbuf_t *hwctx = task->hw_ctx_info; + unsigned int RbIndex = engine->vidsch->engine_index; + unsigned int dwDmaBufferSize = (task->submit_end_offset - task->submit_start_offset) >> 2; + RINGBUFFER_COMMANDS_E3K *pRingBufferCommands = (RINGBUFFER_COMMANDS_E3K*)share->RingBufferCommands; + RB_PREDEFINE_DMA *pPredefine = (RB_PREDEFINE_DMA*)share->begin_end_vma->virt_addr; + + RINGBUFFER_COMMANDS_E3K *pRbCmds = NULL; + large_inter fence_offset; + large_inter fence_offset_fake; + + large_inter fence_offset_local; + large_inter fence_offset_local_fake; + + large_inter fence_offset_snoop; + large_inter fence_offset_snoop_fake; + + large_inter fence_id; + large_inter dma_phy_addr; + large_inter cacheflush3d_phy_addr; + + unsigned int dwRbSize; + RINGBUFFER_COMMANDS_E3K *pRb = NULL; + unsigned int RbCase; + Cmd_Dma *p; + unsigned int slice_mask = 0; + +#if DBG_HW_RING_BUFFER + enginei_idle_ring_buffer_e3k(engine); +#endif + + fence_offset.quad64 = engine->fence_buffer_phy_addr; + fence_offset_fake.quad64 = engine->fence_buffer_phy_addr_fake; + + fence_offset_local.quad64 = engine->fence_buffer_phy_addr_local; + fence_offset_local_fake.quad64 = engine->fence_buffer_phy_addr_local_fake; + + fence_offset_snoop.quad64 = engine->fence_buffer_phy_addr_snoop; + fence_offset_snoop_fake.quad64 = engine->fence_buffer_phy_addr_snoop_fake; + + fence_id.quad64 = task->desc.fence_id; + dma_phy_addr.quad64= task->dma_buffer_node->gpu_phy_base_addr + task->submit_start_offset; + cacheflush3d_phy_addr.quad64 = share->begin_end_buffer_phy_addr + ((BYTE*)(&(pPredefine->FlushDMA3DL)) - (BYTE*)pPredefine); + + dwRbSize = sizeof(RINGBUFFER_COMMANDS_E3K)/sizeof(DWORD); + + dwRbSize = (((dwRbSize) + 15) & ~15); + pRb = (RINGBUFFER_COMMANDS_E3K *)enginei_get_ring_buffer_space_e3k(engine, dwRbSize); + + gf_memset(pRb, 0, (dwRbSize << 2)); + + if( !dwDmaBufferSize ) + { + RbCase = 2; + } + else if(task->need_hwctx_switch && RbIndex == RB_INDEX_GFXL) + { + RbCase = 0; + } + else + { + RbCase = 1; + } + + gf_memcpy(pRb, &pRingBufferCommands[RbCase], sizeof(RINGBUFFER_COMMANDS_E3K)); + pRbCmds = pRb; + if(RbCase == 0) + { + if (hwctx->is_initialized) + { + pRbCmds->c0.RestoreContext_Address = hwctx->context_buffer_address >> 11;//_Cmd_Ctx_Address_Dword3, hwctx addr need 512dw align. + } + else + { + pRbCmds->c0.RestoreContext_Address = share->context_buf_phy_addr >> 11; + hwctx->is_initialized = TRUE; + } + pRbCmds->c0.SaveContext_Address = hwctx->context_buffer_address >> 11; +#if NEW_DUMP + if(adapter->ctl_flags.hang_dump == 2 && !task->null_rendering) + { + pRbCmds->c0.HangDumpContextSaveContext_Address = task->desc.hang_context >> 11; + } + else + { + p = &pRbCmds->c0.HangDumpContextSaveDMA; + gf_memset(p, 0, sizeof(Cmd_Dma)); + pRbCmds->c0.HangDumpContextSaveContext_Address = 0;//task->desc.hang_context; + pRbCmds->c0.HangDumpContextSaveDMA_Address_L = 0; + pRbCmds->c0.HangDumpContextSaveDMA_Address_H = 0; + } +#endif + } + + // All cases + pRbCmds->c0.Fence_Data_L = fence_id.low32; //FenceId_Low; + pRbCmds->c0.Fence_Data_H = fence_id.high32; //FenceId_High; + pRbCmds->c0.Fence_Address_L = fence_offset.low32; //FenceAddr_Low; + pRbCmds->c0.Fence_Address_H = fence_offset.high32&0xFF; //FenceAddr_High + + pRbCmds->c0.Fence_Data_L_1 = fence_id.low32; //FenceId_Low; + pRbCmds->c0.Fence_Data_H_1 = fence_id.high32; //FenceId_High; + pRbCmds->c0.Fence_Address_L_1 = fence_offset_fake.low32; //FenceAddr_Low; + pRbCmds->c0.Fence_Address_H_1 = fence_offset_fake.high32&0xFF; //FenceAddr_High + + pRbCmds->c0.Fence_Data_L_2 = fence_id.low32; //FenceId_Low; + pRbCmds->c0.Fence_Data_H_2 = fence_id.high32; //FenceId_High; + pRbCmds->c0.Fence_Address_L_2 = fence_offset_local.low32; //FenceAddr_Low; + pRbCmds->c0.Fence_Address_H_2 = fence_offset_local.high32&0xFF; //FenceAddr_High + + pRbCmds->c0.Fence_Data_L_3 = fence_id.low32; //FenceId_Low; + pRbCmds->c0.Fence_Data_H_3 = fence_id.high32; //FenceId_High; + pRbCmds->c0.Fence_Address_L_3 = fence_offset_local_fake.low32; //FenceAddr_Low; + pRbCmds->c0.Fence_Address_H_3 = fence_offset_local_fake.high32&0xFF; //FenceAddr_High + + pRbCmds->c0.Fence_Data_L_4 = fence_id.low32; //FenceId_Low; + pRbCmds->c0.Fence_Data_H_4 = fence_id.high32; //FenceId_High; + pRbCmds->c0.Fence_Address_L_4 = fence_offset_snoop.low32; //FenceAddr_Low; + pRbCmds->c0.Fence_Address_H_4 = fence_offset_snoop.high32&0xFF; //FenceAddr_High + + pRbCmds->c0.Fence_Data_L_5 = fence_id.low32; //FenceId_Low; + pRbCmds->c0.Fence_Data_H_5 = fence_id.high32; //FenceId_High; + pRbCmds->c0.Fence_Address_L_5 = fence_offset_snoop_fake.low32; //FenceAddr_Low; + pRbCmds->c0.Fence_Address_H_5 = fence_offset_snoop_fake.high32&0xFF; //FenceAddr_High + + // Case 0/1 + if (RbCase != 2) + { + pRbCmds->c0.CommandDMA.Dw_Num = dwDmaBufferSize; + pRbCmds->c0.CommandDMA_Address_L = dma_phy_addr.low32; + pRbCmds->c0.CommandDMA_Address_H = dma_phy_addr.high32 & 0xFF; + } + + //when move RT to PCIE and open backdoor , 2 slice's performance is better than 1 slice +#if 0 + if (adapter->vcp_index_cnt[VCP0_INDEX] || adapter->vcp_index_cnt[VCP1_INDEX]) { + slice_mask = adapter->min_slice_mask; + } else { + slice_mask = adapter->hw_caps.chip_slice_mask; + } +#endif + + //force 2 slice for occlusion query counter limitation +#if 1 + if (adapter->chip_id >= CHIP_ARISE2030) + { + slice_mask = task->desc.Flags.ForceSlice ? 0x3 : adapter->hw_caps.chip_slice_mask; + + if (adapter->current_slice_mask != slice_mask) { + adapter->current_slice_mask = slice_mask; + if (RbCase == 0) { + gf_memcpy(&pRbCmds->c0.SliceSwitchInitCommands, &share->SliceSwitchInitCommands[0].c0, sizeof(pRbCmds->c0.SliceSwitchInitCommands)); + } else if (RbCase == 1) { + gf_memcpy(&pRbCmds->c1.SliceSwitchInitCommands, &share->SliceSwitchInitCommands[1].c1, sizeof(pRbCmds->c1.SliceSwitchInitCommands)); + } + //gf_info("switch slice mask to 0x%x\n", adapter->current_slice_mask); + } + } +#endif + pRbCmds->c1.trigger_Dw.Slice_Mask = adapter->current_slice_mask; + + if (!dwDmaBufferSize || + (task->dma_type == PAGING_DMA)) + { + pRbCmds->c0.pwmTrigger.Info = BLK_CMD_CSP_INDICATOR_INFO_3D_MODE; + } + + if(RbIndex == RB_INDEX_GFXL) + { + pRbCmds->c0.CacheFlushDMA_Address_L = cacheflush3d_phy_addr.low32; + pRbCmds->c0.CacheFlushDMA_Address_H = cacheflush3d_phy_addr.high32 & 0xFF; + } + +#if DBG_HW_RING_BUFFER + util_dump_memory(NULL, task->dma_buffer_node->virt_base_addr,(task->submit_end_offset - task->submit_start_offset),"dma cmd "); + gf_info("rb case:%d,dma type:%x,rb get size:%x\n",RbCase,task->dma_type,dwRbSize<<2); + util_dump_memory(NULL, pRb,dwRbSize<<2,"rb cmd"); +#else + //when compress on, haps alway meet random hang, should be rb cmd not really write in mem due to hw busy. + //add a crc check here. + //perhaps dump value is same but crc is diff, since read buf will trigger mem write back in mem. + if(adapter->ctl_flags.run_on_qt && util_crc32((unsigned char*)pRb, sizeof(RINGBUFFER_COMMANDS_E3K)) != util_crc32((unsigned char*)pRbCmds, sizeof(RINGBUFFER_COMMANDS_E3K))) + { + gf_info("rb case:%d,dma type:%x,rb get size:%x, fence:%llx\n",RbCase,task->dma_type,dwRbSize<<2, fence_id.quad64); + util_dump_memory(NULL, pRb, dwRbSize<<2, "rb cmd in mem"); + util_dump_memory(NULL, pRbCmds, sizeof(RINGBUFFER_COMMANDS_E3K), "template rb cmd"); + } +#endif + if(debug_mode_e3k.pre_hang_dump || debug_mode_e3k.post_hang_dump) + { + unsigned int offset = 0; + engine->last_ring_buffer_size = dwRbSize << 2; + engine->last_ring_buffer = (unsigned int *)pRb; +#if 0 + if(dwDmaBufferSize) + { + offset = (unsigned int *)&pRb->c0.CommandDMA_Address_L - (unsigned int *)pRb; + engine->last_ring_buffer_for_dma =(unsigned char *)((unsigned int*)pRb + offset); + } + else + { + engine->last_ring_buffer_for_dma = NULL; + } +#endif + offset = (unsigned int *)&pRb->c0.Fence - (unsigned int *)pRb; + engine->last_ring_buffer_for_fence = (unsigned char *)((unsigned int*)pRb + offset); +#if 0 + if(pRb->c0.RestoreDMA.Major_Opcode == CSP_OPCODE_Dma) + { + offset = (unsigned int *)&pRb->c0.RestoreDMA - (unsigned int *)pRb; + engine->last_ring_buffer_for_begin_dma = (unsigned char *)((unsigned int *)pRb + offset); + + offset = (unsigned int *)&pRb->c0.SaveDMA - (unsigned int *)pRb; + engine->last_ring_buffer_for_end_dma = (unsigned char *)((unsigned int *)pRb + offset); + } + else + { + engine->last_ring_buffer_for_begin_dma = NULL; + engine->last_ring_buffer_for_end_dma = NULL; + } +#endif + // gf_info("enginei_common_submit_e3k fence_id:%lld", fence_id.quad64); + } + + enginei_do_kickoff_cmd_e3k(engine); + + return S_OK; +} + +static int enginei_write_commands_to_hw_e3k(engine_e3k_t *engine, task_dma_t *task) +{ + switch (engine->vidsch->engine_index) { + case RB_INDEX_GFXH: + enginei_submit_to_gfx_high_e3k(engine, task); + break; + default: + enginei_common_submit_e3k(engine, task); + } + return S_OK; +} + +static int enginei_write_commands_to_hw_video_e3k(engine_e3k_t *engine, task_dma_t *task) +{ + adapter_t *adapter = engine->vidsch->adapter; + unsigned long long FenceOffset = engine->fence_buffer_phy_addr; + unsigned long long FenceOffsetfake = engine->fence_buffer_phy_addr_fake; + unsigned long long FenceId = task->desc.fence_id; + unsigned int dwDmasize = (task->submit_end_offset - task->submit_start_offset)>>2; + unsigned int SubmitSize = 0, dwCmdSize = 0; + unsigned int RbIndex = engine->vidsch->engine_index; + unsigned int *pRb = NULL; + Cmd_Vcp_Fence Cmd_Vcp_Fence={ 0 }; + + if(adapter->ctl_flags.hwq_event_enable && (RbIndex == RB_INDEX_VCP0 || RbIndex == RB_INDEX_VCP1)) //vcp + { + static int i = -1; + i++; + if(i >= VCP_INFO_COUNT) i = 0; + gf_get_nsecs(&adapter->vcp_task_info[i].vcp_inc_timestamp); + adapter->vcp_task_info[i].vcp_fence_id = FenceId; + adapter->vcp_task_info[i].vcp_pid = task->desc.context->pid; + } + + dwCmdSize = dwDmasize + EXTERNAL_FENCE_DWSIZE*2; // 4 is for external fence; + dwCmdSize = ((dwCmdSize +15)&~15); + + pRb = enginei_get_ring_buffer_space_e3k(engine, dwCmdSize); + gf_memset(pRb, 0, (dwCmdSize << 2)); + gf_memcpy(pRb, (void *)task->dma_buffer_node->virt_base_addr, (dwDmasize << 2)); + + pRb += dwDmasize; + + if ((RbIndex == RB_INDEX_VCP0) || (RbIndex == RB_INDEX_VCP1)) + { + Cmd_Vcp_Fence.Major_Opcode = VCP_OPCODE_Vcp_Fence; // 0x8 + Cmd_Vcp_Fence.Fence_Type = VCP_FENCE_FENCE_TYPE_EXTERNAL64; + Cmd_Vcp_Fence.Fence_Update_Mode = FENCE_FENCE_UPDATE_MODE_COPY; + Cmd_Vcp_Fence.Dwc = 4; + Cmd_Vcp_Fence.Irq = 1; +#if 0 + //On E3K chip, encoding use BE only, decoding use decouple mode, so always use BE to send external fence. + if(EnableVcpDecouple) + { + Cmd_Vcp_Fence.Block_Id = VCP_QUERY_DUMP_BLOCK_ID_VCP_BE; + Cmd_Vcp_Fence.Major_Opcode = VCP_OPCODE_Vcp_Fence; //0x8 + } + else + { + //To do: for encoding, still needs BE to send external fence, but we need a flag to know it's encoding. + Cmd_Vcp_Fence.Block_Id = VCP_QUERY_DUMP_BLOCK_ID_VCP_FE; + Cmd_Vcp_Fence.Major_Opcode = VCP_OPCODE_Vcp_Fence; //0x8 + } +#endif + + Cmd_Vcp_Fence.Block_Id = VCP_QUERY_DUMP_BLOCK_ID_VCP_BE; + *pRb++ = *(DWORD*)&Cmd_Vcp_Fence; + *pRb++ = (FenceOffset & 0xFFFFFFFF); + *pRb++ = ((FenceOffset >> 32) &0xFFFFFFFF); + *pRb++ = (FenceId & 0xFFFFFFFF); + *pRb++ = ((FenceId >> 32) &0xFFFFFFFF); + + Cmd_Vcp_Fence.Block_Id = VCP_QUERY_DUMP_BLOCK_ID_VCP_FE; + *pRb++ = *(DWORD*)&Cmd_Vcp_Fence; + *pRb++ = (FenceOffsetfake & 0xFFFFFFFF); + *pRb++ = ((FenceOffsetfake >> 32) &0xFFFFFFFF); + *pRb++ = (FenceId & 0xFFFFFFFF); + *pRb++ = ((FenceId >> 32) &0xFFFFFFFF); + } + else if (RbIndex == RB_INDEX_VPP) + { + // VPP using the same fence struct as VCP. + Cmd_Vcp_Fence.Major_Opcode = CSP_OPCODE_Fence; + Cmd_Vcp_Fence.Fence_Type = FENCE_FENCE_TYPE_EXTERNAL64; + Cmd_Vcp_Fence.Block_Id = FENCE_ROUTE_ID_VPP_FENCE; + Cmd_Vcp_Fence.Fence_Update_Mode = FENCE_FENCE_UPDATE_MODE_COPY; + Cmd_Vcp_Fence.Dwc = 4; + Cmd_Vcp_Fence.Irq = 1; + + *pRb++ = *(DWORD*)&Cmd_Vcp_Fence; + *pRb++ = (FenceOffset & 0xFFFFFFFF); + *pRb++ = ((FenceOffset >> 32) &0xFFFFFFFF); + *pRb++ = (FenceId & 0xFFFFFFFF); + *pRb++ = ((FenceId >> 32) &0xFFFFFFFF); + + *pRb++ = *(DWORD*)&Cmd_Vcp_Fence; + *pRb++ = (FenceOffsetfake & 0xFFFFFFFF); + *pRb++ = ((FenceOffsetfake >> 32) &0xFFFFFFFF); + *pRb++ = (FenceId & 0xFFFFFFFF); + *pRb++ = ((FenceId >> 32) &0xFFFFFFFF); + } + else + { + gf_error("%s() should not enter here, engine_index-%d\n", util_remove_name_suffix(__func__), RbIndex); + } + + SubmitSize = ALIGNED_8(dwCmdSize); + if (dwCmdSize < SubmitSize) + { + DWORD dwSkipSize = SubmitSize - dwCmdSize - 1; + Cmd_Vcp_Skip cmd_Vcp_Skip = { 0 }; + + if (dwSkipSize) + { + cmd_Vcp_Skip.Dwc = dwSkipSize; + cmd_Vcp_Skip.Major_Opcode = VCP_OPCODE_Vcp_Skip; + } + + *pRb++ = *(DWORD*)&cmd_Vcp_Skip; + } + + enginei_do_kickoff_cmd_e3k(engine); + + return S_OK; +} + +int engine_submit_task_dma_e3k(adapter_t *adapter, vidsch_mgr_t *sch_mgr, task_dma_t *task_dma) +{ + unsigned long long timestamp = 0; + gf_perf_event_t perf_event = {0}; + engine_e3k_t *engine = sch_mgr->private_data; + + if(debug_mode_e3k.internal_dump_hw) + { + gf_info("engine_submit_task_dma_e3k start dump image, need skip this function...\n"); + return 0; + } + + if(sch_mgr->init_submit) + { +#if GF_TRACE_HW_HANG + debug_mode_e3k.print_debug_bus = 1; +#endif + + if(adapter->ctl_flags.hang_dump == 0) + { + debug_mode_e3k.pre_hang_dump = 0; + debug_mode_e3k.post_hang_dump = 0; + debug_mode_e3k.duplicate_hang = 0; + } + else if(adapter->ctl_flags.hang_dump == 1) + { + debug_mode_e3k.pre_hang_dump = 1; + debug_mode_e3k.post_hang_dump = 0; + debug_mode_e3k.duplicate_hang = 0; + } + else if(adapter->ctl_flags.hang_dump == 2) + { + debug_mode_e3k.pre_hang_dump = 0; + debug_mode_e3k.post_hang_dump = 1; + debug_mode_e3k.duplicate_hang = 0; + } + if(adapter->ctl_flags.hang_dump == 3) + { + debug_mode_e3k.pre_hang_dump = 0; + debug_mode_e3k.post_hang_dump = 0; + debug_mode_e3k.duplicate_hang = 1; + } + + sch_mgr->init_submit = 0; + } + + if(!adapter->hw_caps.local_only) + { + enginei_invalidate_gart_e3k(engine); + } + + if(adapter->ctl_flags.hang_dump && !task_dma->null_rendering && sch_mgr->engine_index == RB_INDEX_GFXL) + { + engine->last_dma_buffer_size_uint = (task_dma->submit_end_offset - task_dma->submit_start_offset) >> 2; + engine->last_dma_buffer = (unsigned char*)(task_dma->dma_buffer_node->virt_base_addr + task_dma->submit_start_offset); + + //util_dump_memory(sch_mgr->last_dma_buffer, sch_mgr->last_dma_buffer_size_uint, "LAST DMA Buffer"); + if(task_dma->dma_type != PAGING_DMA) + { + vidsch_handle_dbg_hang_dump_e3k( adapter, sch_mgr, task_dma); + } + } + + if(adapter->ctl_flags.hwq_event_enable) + { + if(timestamp==0) + { + gf_get_nsecs(×tamp); + } + hwq_process_submit_event(adapter,timestamp,task_dma->desc.fence_id & 0xffffffff,sch_mgr->engine_index); + } + + switch (sch_mgr->engine_index) { + case RB_INDEX_GFXL: + case RB_INDEX_GFXH: + enginei_write_commands_to_hw_e3k(engine, task_dma); + break; + case RB_INDEX_VCP0: + case RB_INDEX_VCP1: + case RB_INDEX_VPP: + enginei_write_commands_to_hw_video_e3k(engine, task_dma); + break; + default: + gf_error("submit unsupport engine type\n"); + gf_assert(0, "submit unsupport engine type"); + } + + if(adapter->ctl_flags.perf_event_enable) + { + gf_get_nsecs(×tamp); + perf_event.header.timestamp_high = timestamp >> 32; + perf_event.header.timestamp_low = (timestamp) & 0xffffffff; + perf_event.header.size = sizeof(gf_perf_event_dma_buffer_submitted_t); + perf_event.header.type = GF_PERF_EVENT_DMA_BUFFER_SUBMITTED; + perf_event.dma_buffer_submitted.dma_type = task_dma->dma_type; + perf_event.dma_buffer_submitted.gpu_context = (task_dma->desc.context ? task_dma->desc.context->handle : 0); + perf_event.dma_buffer_submitted.dma_idx_low = task_dma->render_counter & 0xffffffff; + perf_event.dma_buffer_submitted.dma_idx_high = (task_dma->render_counter >> 32) & 0xffffffff; + perf_event.dma_buffer_submitted.engine_idx = sch_mgr->engine_index; + perf_event.dma_buffer_submitted.fence_id_low = task_dma->desc.fence_id & 0xffffffff; + perf_event.dma_buffer_submitted.fence_id_high = (task_dma->desc.fence_id >> 32) & 0xffffffff; + + perf_event_add_event(adapter, &perf_event); + } + + if(adapter->ctl_flags.hang_dump && (debug_mode_e3k.pre_hang_dump || debug_mode_e3k.post_hang_dump) && sch_mgr->engine_index == RB_INDEX_GFXL) + { + if(task_dma->dma_type != PAGING_DMA) + { + vidsch_save_misc_e3k(adapter, sch_mgr, SAVE_RING_BUFFER); + } + } + +#ifdef VMI_MODE + vidschi_notify_fence_interrupt(adapter, ~0x0); +#endif + + return S_OK; +} + diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_patch_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_patch_e3k.c new file mode 100644 index 0000000000000..b4af478baf5d8 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_patch_e3k.c @@ -0,0 +1,205 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_engine_e3k.h" +#include "chip_include_e3k.h" +#include "global.h" +#include "mm_e3k.h" + +int vidschi_get_slot_count_e3k(adapter_t *adapter) +{ + unsigned int slot_cnt = 0; + + //gf_info("%s, driver id slot count is not already yet, needs for split dma usage!!\n", util_remove_name_suffix(__func__)); + + //for(i = 0; i < mm_driver_last; i++) + //{ + //} + + return slot_cnt; +} + +static void vidschi_patch_allocation_e3k(adapter_t *adapter, + task_dma_t *task, + gf_patchlocation_list_t *patch_location, + vidsch_allocation_t *sch_allocation) +{ + large_inter address; + unsigned int *patch_offset; + static unsigned int videoDrawId_FE = 0; + static unsigned int videoDrawId_BE = 0; + unsigned int *pVideoDrawID = NULL; + engine_share_e3k_t *share = (engine_share_e3k_t *)adapter->private_data; + + // We use AllocationOffset=-1 to pass HardwareContext. We don't need a patch for it. + // Problem: AllocationIndex is unsigned int , it's alwayls >= 0 ), needing confirm + if(patch_location->AllocationOffset == -1 || patch_location->AllocationOffset == 0xFFFFFFFE) + { + return; + } + + patch_offset = (unsigned int *)(task->dma_buffer_node->virt_base_addr + patch_location->PatchOffset); + address.quad64 = sch_allocation->phy_addr + patch_location->AllocationOffset; + + //need add video patch code later + switch (patch_location->DriverId) + { + case MM_DRIVERID_SIGNATURE: + case MM_DRIVERID_VS_SHADER: + case MM_DRIVERID_HS_SHADER: + case MM_DRIVERID_DS_SHADER: + case MM_DRIVERID_GS_SHADER: + case MM_DRIVERID_PS_SHADER: + case MM_DRIVERID_CS_SHADER: + case MM_DRIVERID_INDEXBUFFER_ADDRESS: + case MM_DRIVERID_CONTEXT: + case MM_DRIVERID_SO_BUFFER_ADDRESS: + case MM_DRIVERID_DIP_INDIRECT_BUFFER_ADDRESS: + case MM_DRIVERID_DISPATCH_INDIRECT_BUFFER_ADDRESS: + case MM_DRIVERID_DIP_PARAM_BUFFER_ADDRESS: + case MM_DRIVERID_CSHARP: + case MM_DRIVERID_FENCE: + case MM_DRIVERID_MIUCOUNTER: + case MM_DRIVERID_SO_BUFFER_FILL_SIZE_POOL: + patch_offset[0] = address.low32; + patch_offset[1] = (patch_offset[1] & 0xFFFFFF00) | (address.high32 &0xFF); + break; + + case MM_DRIVERID_VERTEXBUFFER_40BIT_ADDRESS: + patch_offset[0] = address.low32; + patch_offset[1] = address.high32 & 0xFF; + break; + /* video start*/ + case MM_DRIVERID_VIDEO_RESERVEDMEM: + case MM_DRIVERID_VIDEO_FENCE: + case MM_DRIVERID_VIDEO_PATCH: + case MM_DRIVERID_VIDEO_DECODE_CMD: + case MM_DRIVERID_VIDEO_DECODE_VCPDMA: + case MM_DRIVERID_VIDEO_DECODE_VCPSBDMA: + case MM_DRIVERID_VIDEO_DECODE_QTMDMA: + case MM_DRIVERID_VIDEO_DECODE_DRVDMA: + case MM_DRIVERID_VIDEO_SIGNATURE: + case MM_DRIVERID_VIDEO_DECODE_COMPBUFF: + patch_offset[0] = address.low32; + patch_offset[1] = (patch_offset[1] & 0xFFFFFF00) | (address.high32 & 0xFF); + break; + case MM_DRIVERID_VIDEO_DECODE_MSVD: + patch_offset[0] = (address.low32 & 0xFFFFFFE0) | (patch_offset[0] & 0x1F); + patch_offset[1] = (patch_offset[1] & 0xFFFFFF00) | (address.high32 & 0xFF); + break; + case MM_DRIVERID_VIDEO_DECODE_INS: + patch_offset[0] = address.low32 >> 8; + patch_offset[1] = (patch_offset[1] & 0xFFFFFF00) | (address.high32 & 0xFF); + break; + case MM_DRIVERID_ISP_VPP_SRC: + case MM_DRIVERID_ISP_VPP_DST: + address.quad64 = address.quad64 >> 8; + patch_offset[0] = address.low32; + break; + case MM_DRIVERID_VIDEO_DRAWID: + pVideoDrawID = (address.quad64 & 0x1) == 0? &videoDrawId_FE : &videoDrawId_BE; + patch_offset[0] = (((*pVideoDrawID) & 3) << 1) | // bit[2:1], drawID low + (((*pVideoDrawID) & 0x3c) << 5)| // bit[10:7], drawID high + patch_offset[0]; + (*pVideoDrawID) = ((*pVideoDrawID) + 1) & 0x3F; + break; + /* video end*/ + + case MM_DRIVERID_CSL1: + patch_offset[0] = (share->ring_buffer_phy_addr[RB_INDEX_CSL1] >> 8); + break; + case MM_DRIVERID_CSL2: + patch_offset[0] = (share->ring_buffer_phy_addr[RB_INDEX_CSL2] >> 8); + break; + case MM_DRIVERID_CSL3: + patch_offset[0] = (share->ring_buffer_phy_addr[RB_INDEX_CSL3] >> 8); + break; + case MM_DRIVERID_SVM_POINTER: + address.low32 = patch_offset[0] + address.low32; + address.high32 = patch_offset[1] + address.high32; + patch_offset[0] = address.low32; + patch_offset[1] = address.high32; + break; + default: + //case MM_DRIVERID_CSUNORDEREDACCESS: Uav_Base should be alined to 2kb(>>8) + patch_offset[0] = address.low32 >> 8; + patch_offset[0] |= (address.high32 << 24); + //gf_info("set driver id patch:%x, real PA:%x\n", patch_offset[0], address.quad64); + break; + } +} + +/* only do patch after paging/mirgate */ +int vidsch_patch_e3k(adapter_t *adapter, task_dma_t *task_dma) +{ + hw_ctxbuf_t *hwctx_buf = task_dma->hw_ctx_info; + gf_patchlocation_list_t *patch_location = task_dma->patch_location_list; + vidsch_allocation_t *sch_allocation = task_dma->sch_allocation_list; + unsigned int ret = S_OK; + int i; + + if(task_dma->need_hwctx_switch) + { + if(patch_location[0].DriverId == MM_DRIVERID_CONTEXT) + { + hwctx_buf->context_buffer_address = sch_allocation[patch_location[0].AllocationIndex].phy_addr; + } + else + { + gf_warning("## need do hwctx switch, but no hwctx allocation found in patch list, patch: offset[%d, %d], [index-0x%x, DriverId-0x%x].\n", + task_dma->patch_start_offset, task_dma->patch_end_offset, patch_location[0].AllocationIndex, patch_location[0].DriverId); + } + } + + for(i = task_dma->patch_start_offset; i < task_dma->patch_end_offset; i++) + { + patch_location = &task_dma->patch_location_list[i]; + + // Problem: AllocationIndex is unsigned int , it's alwayls >= 0 ), needing confirm + if (patch_location->AllocationIndex < 0 || + patch_location->AllocationIndex > task_dma->allocation_list_size) + { + ret = E_FAIL; + goto exit; + } + + // Problem: AllocationIndex is unsigned int , it's alwayls != 0 ), needing confirm + if (patch_location->PatchOffset > task_dma->dma_buffer_node->size && + patch_location->AllocationOffset != -1) + { + ret = E_FAIL; + goto exit; + } + + sch_allocation = task_dma->sch_allocation_list + patch_location->AllocationIndex; + + if (sch_allocation->segment_id) + { + vidschi_patch_allocation_e3k(adapter,task_dma, patch_location, sch_allocation); + } + } + +exit: + return ret; +} + + + + + + + diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_render_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_render_e3k.c new file mode 100644 index 0000000000000..ea37e668aaed4 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_render_e3k.c @@ -0,0 +1,103 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_render.h" +#include "vidsch_engine_e3k.h" +#include "vidsch_debug_hang_e3k.h" + +int vidsch_render_e3k(gpu_context_t *gpu_context, task_dma_t *task_dma) +{ + int result = S_OK; + gpu_device_t *gpu_device = gpu_context->device; + adapter_t *adapter = gpu_device->adapter; + +#if TEST_HW_RESET + /* + ** test code for force hang/reset, only enable it when reset enable + ** trigger hang and reset cycle in every 15 minutes when dma type is present + */ + { + unsigned long long current_time, delta_time; + unsigned int init_time = 0; + long temp_sec, temp_usec; + static unsigned int start_hang_reset_cycle = 1; + static unsigned long long start_time = 0; + /* I saw many small garbage flash in screen after reset about 10? times when use wrong cmd, so add this counter and notes */ + static unsigned int hang_reset_counters = 0; + static unsigned int max_hang_reset_counters = 99999999; + + /* only reset twice and need reboot to restart reset. */ + if (/*adapter->ctl_flags.recovery_enable &&*/ (hang_reset_counters < max_hang_reset_counters)) + { + if (start_hang_reset_cycle) + { + gf_getsecs(&temp_sec, &temp_usec); + start_time = temp_sec * 1000000 + temp_usec; + + start_hang_reset_cycle = 0; + + gf_info("====== reset test: start hang counters %d ====== \n", hang_reset_counters); + } + + gf_getsecs(&temp_sec, &temp_usec); + + current_time = temp_sec * 1000000 + temp_usec; + delta_time = current_time - start_time; + + /* if 900s, trigger hang reset */ + if (delta_time > TEST_HW_RESET_TIME_STEP) + { + gf_info("hang_reset triggerred \n"); + gf_info("hang_reset triggerred \n"); + gf_info("hang_reset triggerred \n"); + gf_info("hang_reset triggerred \n"); + + *(unsigned int*)task_dma->dma_buffer_node->virt_base_addr = + SEND_INTERNAL_WRITEFENCE_E3K(FENCE_ROUTE_ID_D_FENCE,_RBT_3DBE, HWM_SYNC_KMD_SLOT); + *((unsigned int*)task_dma->dma_buffer_node->virt_base_addr + 1) = + SEND_INTERNAL_FENCE_VALUE_E3K(0xFFFE); + *((unsigned int*)task_dma->dma_buffer_node->virt_base_addr + 2) = + SEND_INTERNAL_WAIT_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_DFENCE); + *((unsigned int*)task_dma->dma_buffer_node->virt_base_addr + 3) = + SEND_INTERNAL_WAIT_MAIN_E3K(HWM_SYNC_KMD_SLOT, WAIT_METHOD_EQUAL, FENCE_VALUE_CACHE_DMA_DFENCE); + + gf_info("vidsch_render_e3k reset command value:0x%x, 0x%x, 0x%x, 0x%x\n", *(unsigned int*)task_dma->dma_buffer_node->virt_base_addr + , *((unsigned int*)task_dma->dma_buffer_node->virt_base_addr + 1), *((unsigned int*)task_dma->dma_buffer_node->virt_base_addr + 2) + , *((unsigned int*)task_dma->dma_buffer_node->virt_base_addr + 3)); + + gf_info("hang_reset triggerred \n"); + gf_info("hang_reset triggerred \n"); + + /* start next cycle */ + start_hang_reset_cycle = 1; + hang_reset_counters++; + } + } + } + +#endif + + if(adapter->ctl_flags.hang_dump == 3) + { + if(debug_mode_e3k.duplicate_hang == 1) + { + vidsch_duplicate_hang_e3k(adapter); + } + } + + return result; +} diff --git a/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_setup_e3k.c b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_setup_e3k.c new file mode 100755 index 0000000000000..d7e7aff728797 --- /dev/null +++ b/drivers/gpu/drm/arise/core/e3k/vidsch/vidsch_setup_e3k.c @@ -0,0 +1,714 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "chip_include_e3k.h" +#include "vidsch_engine_e3k.h" +#include "stm_context_e3k.h" +#include "vidsch_blt_e3k.h" +#include "mm_e3k.h" +#include "vidsch_dfs_e3k.h" + +static vidsch_chip_func_t engine_gfx_low_chip_func_e3k; +static vidsch_chip_func_t engine_gfx_high_chip_func_e3k; +static vidsch_chip_func_t engine_vcp_low0_chip_func_e3k; +static vidsch_chip_func_t engine_vcp_low1_chip_func_e3k; +static vidsch_chip_func_t engine_vpp_chip_func_e3k; + + +//***************************************************************************** +// +// vidschi_init_hw_settings_e3k +// +// function to init HW MXU register, so that PCIe Ring Buffer can +// work properly. +// +//***************************************************************************** +void vidschi_init_hw_settings_e3k(adapter_t *adapter) +{ + Reg_Bl_Size reg_Bl_Size = {0}; + unsigned char * pRegAddr = NULL; + vidmm_segment_t *segment = NULL; + heap_t *heap = NULL; + Reg_Rb0_Fl2 KKKRb0 = {0}; + Reg_Rb1_Fl2 KKKRb1 = {0}; + Reg_Rb2_Fl2 KKKRb2 = {0}; + Reg_Argument_Fl2 ArgumentBuffer = {0}; + + heap = vidmm_get_burst_length_heap(adapter); + reg_Bl_Size.reg.Buffer_Offset = heap->start >> util_log2(BL_BUFFER_ALIGN); + reg_Bl_Size.reg.Buffer_Size = util_log2(BL_BUFFER_SIZE >> 23); + reg_Bl_Size.reg.Invalid_Bl_To_Rf_En = 1; + pRegAddr = adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Bl_Size_Offset*4; + gf_write32(pRegAddr, reg_Bl_Size.uint); + + gf_info("reg_Bl_Size.uint 0x%x readvalue: 0x%x, Invalid BL enable:%d \n", reg_Bl_Size.uint, gf_read32(pRegAddr), reg_Bl_Size.reg.Invalid_Bl_To_Rf_En); + + KKKRb0.reg.Size = RING_BUFFER_SIZE_E3K >> 16; + KKKRb1.reg.Size = RING_BUFFER_SIZE_E3K >> 16; + KKKRb2.reg.Size = RING_BUFFER_SIZE_E3K >> 16; + ArgumentBuffer.reg.Size = KKK_ARGUMENT_BUFFER_SIZE >> 16; + + pRegAddr = adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Rb0_Fl2_Offset*4; + gf_write32(pRegAddr, KKKRb0.uint); + pRegAddr = adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Rb1_Fl2_Offset*4; + gf_write32(pRegAddr, KKKRb1.uint); + pRegAddr = adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Rb2_Fl2_Offset*4; + gf_write32(pRegAddr, KKKRb2.uint); + pRegAddr = adapter->mmio + MMIO_MXU_START_ADDRESS + Reg_Argument_Fl2_Offset*4; + gf_write32(pRegAddr, ArgumentBuffer.uint); + + { + // TODO: secure range regs is 64k aligned, needs align shift?? seems yes!! + //per Xinzhao, secure regs can't be access through mmio, pending for refine to PMP. + //BL set to secure range 0 + //Per Baldwin, driver should cfg each miu about secure info. + int i = 0; + + for (i = 0; i < adapter->hw_caps.miu_channel_num; i++) + { + gf_write32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000, ((heap->start >> 16) << 12)); + gf_write32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000 + 4, (((heap->start + heap->size) >> 16) << 12)); + + //gf_info("BL:exp:%x,read:%x, exp:%x,read:%x\n", ((heap->start >> 16) << 12), gf_read32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000), (((heap->start + heap->size) >> 16) << 12), gf_read32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000 +4)); + + if(adapter->hw_caps.secure_range_enable) + { + //set secure range1, secure range + segment = vidmm_get_segment_by_id(adapter, SEGMENT_ID_SECURE_RANGE_E3K); + gf_write32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000 + 1*8, ((segment->gpu_vm_start >> 16) << 12)); + gf_write32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000 + 1*8 +4, (((segment->gpu_vm_start + segment->gpu_vm_size) >> 16) << 12)); + gf_info("SEC[1]exp:%x,read:%x, exp:%x,read:%x\n", ((segment->gpu_vm_start >> 16) << 12), gf_read32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000 +8 ), (((segment->gpu_vm_start + segment->gpu_vm_size) >> 16) << 12), gf_read32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000 +0xc)); + + //set secure range2, non-secure range + segment = vidmm_get_segment_by_id(adapter, SEGMENT_ID_SECURE_RANGE_E3K_1); + gf_write32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000 + 2*8, ((segment->gpu_vm_start >> 16) << 12)); + gf_write32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000 + 2*8 +4, (((segment->gpu_vm_start + segment->gpu_vm_size) >> 16) << 12)); + gf_info("SEC[2]exp:%x,read:%x, exp:%x,read:%x\n", ((segment->gpu_vm_start >> 16) << 12), gf_read32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000 +2*8 ), (((segment->gpu_vm_start + segment->gpu_vm_size) >> 16) << 12), gf_read32(adapter->mmio + MIU0_RANGE_BASE_ADDRESS + i*0x1000 + 2*8 +4)); + + //set scramble bits[8,15]: range0~7; bit[0]:1 means enable scramble. Rang0 for BL, should not enable scramble + gf_write32(adapter->mmio + SECURE_RANGE_ENCRYPTEN_ADDRESS + i*0x1000, ((1 << 9) | (1 << 0))); + + // set the scramble pattern for later scramble/descramble use. + gf_write32(adapter->mmio + SECURE_RANGE_SCRAMBLE_PATTEN_ADDRESS + i*0x1000 , 0xFFFFFFFF); + gf_write32(adapter->mmio + SECURE_RANGE_SCRAMBLE_PATTEN_ADDRESS + i*0x1000 + 0x4, 0xFFFFFFFF); + gf_write32(adapter->mmio + SECURE_RANGE_SCRAMBLE_PATTEN_ADDRESS + i*0x1000 + 0x8, 0xFFFFFFFF); + gf_write32(adapter->mmio + SECURE_RANGE_SCRAMBLE_PATTEN_ADDRESS + i*0x1000 + 0xc, 0xFFFFFFFF); + } + } + } +} +/* +assign SWRST[7:0] = REG_CRA3 | REG8524[7:0]; +assign SWRST[15:8] = REG_CRA4 | REG8524[15:8]; +assign SWRST[23:16] = REG_CRA5 | REG8524[23:16]; +assign SWRST[31:24] = REG_CRA6 | REG8524[31:24]; +assign SWRST[39:32] = REG_CRB4 | REG85B4[7:0]; +assign SWRST[47:40] = REG_CRB5 | REG85B4[15:8]; +assign SWRST[55:48] = REG_CRB6 | REG85B4[23:16]; +assign SWRST[63:56] = REG_CRB7 | REG85B4[31:24]; + +The following is the detail for SWRST[23:0] +MIU_SwRst = SWRST[1] | SWRST[0]; +For_3D_SwRst = SWRST[2] | SWRST[0]; +For_3D1_SwRst = SWRST[3] | SWRST[0]; +For_3D2_SwRst = SWRST[4] | SWRST[0]; +For_3D3_SwRst = SWRST[5] | SWRST[0]; +VPP_SwRst = SWRST[6] | SWRST[0]; +GFVD0_SwRst = SWRST[7] | SWRST[0]; +GFVD1_SwRst = SWRST[8] | SWRST[0]; +mmio_timer_SwRst = SWRST[9] | SWRST[0]; +m0pll_div_SwRst = SWRST[10] | SWRST[0]; +m1pll_div_SwRst = SWRST[11] | SWRST[0]; +m2pll_div_SwRst = SWRST[12] | SWRST[0]; +epll_div_SwRst = SWRST[13] | SWRST[0]; +vpll_div_SwRst = SWRST[14] | SWRST[0]; +IGA1_SwRst = SWRST[16] | SWRST[0]; +IGA2_SwRst = SWRST[17] | SWRST[0]; +IGA3_SwRst = SWRST[18] | SWRST[0]; + +If hang, just need reset 3D,3D1,3D2,3D3,VPP,GFVD0,GFVD1,so set 8524 to 0x01FC. +or we can set CRA3 and CRA4, the mmio offset is 0x8aa3,0x8aa4. +*/ +void vidschi_reset_adapter_e3k(adapter_t *adapter) +{ + Reg_HWReset_E3K dwResetHW = {0}; + volatile unsigned int i, j; + + gf_disp_wait_idle(adapter->disp_info); + + dwResetHW.uint = 0x01FC; + gf_write32(adapter->mmio + 0x8524, dwResetHW.uint); + + //wait a while + j=0; + for (i=0;i<0x10000;i++){j++;}; + + dwResetHW.uint = 0; //clear reset value. + gf_write32(adapter->mmio + 0x8524, dwResetHW.uint); + + //wait a while + for (i=0;i<0x10000;i++) {j--;}; + + { + EngineSatus_e3k engine_status = {0}; + unsigned int *status = (unsigned int *)&engine_status; + int i; + + for( i = 0; i <7; i++) + { + *(status + i) = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + (Reg_Block_Busy_Bits_Top_Offset + i)*4); + } + + //gf_info("after reset......\n"); + gf_info("current engine Status: %08x,%08x,%08x,%08x,%08x,%08x,%08x\n", + engine_status.Top.uint,engine_status.Gpc0_0.uint,engine_status.Gpc0_1.uint, + engine_status.Gpc1_0.uint,engine_status.Gpc1_1.uint,engine_status.Gpc2_0.uint,engine_status.Gpc2_1.uint); + //gf_info("done......\n"); + } +} + + +//***************************************************************************** +// +// vidschi_init_lookup_table_e3k +// +// Init ring buffer lookup table, this table map from node_ordinal and +// engine_affinity to specific engine index +// +//***************************************************************************** +static void vidschi_init_lookup_table_e3k(adapter_t *adapter, vidsch_query_private_t *query) +{ + int i, total_size = 0; + + query->engine_count = RB_NUM; + + if(adapter->hw_caps.local_only) + { + query->pcie_segment_id = SEGMENT_ID_LOCAL_E3K; + query->local_segment_id = SEGMENT_ID_LOCAL_E3K; +#if defined(__mips64__) || defined(__loongarch__) + //PCIE cfg 0x68[14:12] defualt value is 010b, which means 512 Bytes maximum Read Request size + //mips system BIOS(loonson PMON) modify this value to 000b, which means 128 Bytes maximum Read Request size + //if fence buffer is in LOCAL, BIU will receive 8*256 bits Dummy Fence Read Request, which exceed 128 Bytes, + //and BIU should split this Dummy Fence Request to two Dummy Fence Request, + //but BIU has a bug which leads to the second Dummy Fence Read Request as a normal request + query->fence_buffer_segment_id = SEGMENT_ID_GART_UNSNOOPABLE_E3K; +#else + query->fence_buffer_segment_id = SEGMENT_ID_LOCAL_E3K; +#endif + } + else + { + query->local_segment_id = SEGMENT_ID_LOCAL_E3K; + + if (adapter->hw_caps.snoop_only) + { + query->fence_buffer_segment_id = SEGMENT_ID_GART_SNOOPABLE_E3K; + query->pcie_segment_id = SEGMENT_ID_GART_SNOOPABLE_E3K; + } + else + { +#if defined(__mips64__) || defined(__loongarch__) + //In mips or loongarch system, arise(1020,10C0), because of the HW issue, the FE/BE fence value may be not updated when fence buffer + // is in pcie memory. + query->fence_buffer_segment_id = SEGMENT_ID_LOCAL_E3K; +#else + query->fence_buffer_segment_id = SEGMENT_ID_GART_UNSNOOPABLE_E3K; +#endif + query->pcie_segment_id = SEGMENT_ID_GART_UNSNOOPABLE_E3K; + } + + } + + for ( i = 0; i < query->engine_count; i++) + { + //query->local_memory_size[i]= HW_CONTEXT_SIZE_E3K; // for hw context buffer start addr align requirement + //query->local_memory_size[i] += E3K_3DBLT_RESERVED_SIZE; //kernel 3D blt buffer size + query->engine_hw_queue_size[i] = E3K_ENGINE_HW_QUEUE_SIZE; + + switch(i) + { + case RB_INDEX_GFXL: + adapter->engine_index_table[i].node_ordinal = 0; + adapter->engine_index_table[i].engine_affinity = 1; + + query->engine_caps[i] = ENGINE_CAPS_PAGING | ENGINE_CAPS_PRESENT_ALL | + ENGINE_CAPS_2D_GRAPHICS | ENGINE_CAPS_3D_GRAPHICS; + query->engine_ctrl[i] = ENGINE_CTRL_THREAD_ENABLE; + query->dma_buffer_size[i] = 2*1024*1024; + query->pcie_memory_size[i] = RING_BUFFER_SIZE_E3K; + query->local_memory_size[i]= (HW_CONTEXT_SIZE_E3K * (HW_CONTEXT_COUNT_E3K + 3)) + + BEGIN_END_BUF_SIZE_E3K; + total_size += _3DBLT_DATA_RESERVE_SIZE; + + query->local_memory_size[i] += total_size; + query->engine_func[i] = &engine_gfx_low_chip_func_e3k; + break; + + case RB_INDEX_GFXH: + adapter->engine_index_table[i].node_ordinal = 1; + adapter->engine_index_table[i].engine_affinity = 1; + + query->engine_caps[i] = ENGINE_CAPS_PRESENT_ALL | ENGINE_CAPS_2D_GRAPHICS | ENGINE_CAPS_3D_GRAPHICS; + query->engine_ctrl[i] = ENGINE_CTRL_DISABLE; + query->dma_buffer_size[i] = 1*1024*1024; + query->pcie_memory_size[i] = RING_BUFFER_SIZE_E3K; + + query->local_memory_size[i]= (HW_CONTEXT_SIZE_E3K * (HW_CONTEXT_COUNT_E3K + 1)); + query->engine_func[i] = &engine_gfx_high_chip_func_e3k; + break; + case RB_INDEX_CSH: + case RB_INDEX_CSL0: + case RB_INDEX_CSL1: + case RB_INDEX_CSL2: + case RB_INDEX_CSL3: + adapter->engine_index_table[i].node_ordinal = i; + adapter->engine_index_table[i].engine_affinity = 1; + query->engine_ctrl[i] = ENGINE_CTRL_DISABLE; + break; + case RB_INDEX_VCP0: + adapter->engine_index_table[i].node_ordinal = 7; + adapter->engine_index_table[i].engine_affinity = 1; + + query->engine_caps[i] = ENGINE_CAPS_VIDEO_DECODE | ENGINE_CAPS_VIDEO_ENCODE | ENGINE_CAPS_NO_HWCTX; + query->engine_ctrl[i] = ENGINE_CTRL_THREAD_ENABLE; + query->dma_buffer_size[i] = 1*1024*1024; + query->pcie_memory_size[i] = RING_BUFFER_SIZE_E3K; + query->local_memory_size[i]= VIDEO_BRIDGE_BUF_SIZE; + query->engine_func[i] = &engine_vcp_low0_chip_func_e3k; + break; + case RB_INDEX_VCP1: + adapter->engine_index_table[i].node_ordinal = 8; + adapter->engine_index_table[i].engine_affinity = 1; + + query->engine_caps[i] = ENGINE_CAPS_VIDEO_DECODE | ENGINE_CAPS_VIDEO_ENCODE | ENGINE_CAPS_NO_HWCTX; + query->engine_ctrl[i] = ENGINE_CTRL_THREAD_ENABLE; + query->dma_buffer_size[i] = 1*1024*1024; + query->pcie_memory_size[i] = RING_BUFFER_SIZE_E3K; + query->local_memory_size[i]= VIDEO_BRIDGE_BUF_SIZE; + query->engine_func[i] = &engine_vcp_low1_chip_func_e3k; + break; + case RB_INDEX_VPP: + adapter->engine_index_table[i].node_ordinal = 9; + adapter->engine_index_table[i].engine_affinity = 1; + + query->engine_caps[i] = ENGINE_CAPS_VIDEO_VPP | ENGINE_CAPS_NO_HWCTX; + query->engine_ctrl[i] = ENGINE_CTRL_THREAD_ENABLE; + query->dma_buffer_size[i] = 1*1024*1024; + query->pcie_memory_size[i] = RING_BUFFER_SIZE_E3K; + query->local_memory_size[i]= 0; + query->engine_func[i] = &engine_vpp_chip_func_e3k; + break; + + default: + break; + } + + if(adapter->hw_caps.local_only) + { + query->dma_segment[i] = SEGMENT_ID_LOCAL_E3K; + } + else + { + query->dma_segment[i] = SEGMENT_ID_GART_SNOOPABLE_E3K; + + if(! adapter->hw_caps.snoop_only) + { +#if !ENABLE_UNSNOOPABLE_WROKAROUND + query->dma_segment[i] = SEGMENT_ID_GART_UNSNOOPABLE_E3K; +#endif + } + } + } + + if(adapter->ctl_flags.hang_dump) + { + engine_share_e3k_t *share = adapter->private_data; + unsigned int segment_id = SEGMENT_ID_LOCAL_E3K; + + /* reserve ring buffer for hang */ + share->ring_buffer_for_hang = vidmm_allocate_segment_memory(adapter, segment_id, E3K_RINGBUFFER_FOR_HANG_SIZE, 1); + gf_info("ringbuffer: gpu virt=%x, size=%x\n", share->ring_buffer_for_hang->gpu_virt_addr, share->ring_buffer_for_hang->list_node->aligned_size); + + /* reserve context buffer for hang */ + share->context_buffer_for_hang = vidmm_allocate_segment_memory(adapter, segment_id, E3K_CONTEXTBUFFER_FOR_HANG_SIZE, 1); + gf_info("contextbuffer: gpu virt=%x, size=%x\n", share->context_buffer_for_hang->gpu_virt_addr, share->context_buffer_for_hang->list_node->aligned_size); + + /* reserve dma buffer for hang */ + share->dma_buffer_for_hang = vidmm_allocate_segment_memory(adapter, segment_id, E3K_DMABUFFER_FOR_HANG_SIZE, 1); + gf_info("dmabuffer: gpu virt=%x, size=%x\n", share->dma_buffer_for_hang->gpu_virt_addr, share->dma_buffer_for_hang->list_node->aligned_size); + + /* reserve pcie buffer for copy cpu invisble segment out*/ + segment_id = SEGMENT_ID_GART_UNSNOOPABLE_E3K; + share->transfer_buffer_for_hang = vidmm_allocate_segment_memory(adapter, segment_id, E3K_TRANSFERBUFFER_FOR_HANG_SIZE, 0); + gf_info("transfer buffer for hang: gpu virt=%x, size=%x\n", share->transfer_buffer_for_hang->gpu_virt_addr, share->transfer_buffer_for_hang->list_node->aligned_size); + + vidschi_map_e3k(adapter); + } +} + +static int vidschi_init_engine_share_e3k(adapter_t *adapter) +{ + engine_share_e3k_t *share = gf_calloc(sizeof(engine_share_e3k_t)); + + share->lock = gf_create_spinlock(0); + + adapter->private_data = share; + + //allocate burst length buffer in local reserved + { + heap_t *heap = NULL; + unsigned long long heap_size, heap_start; + + heap = vidmm_get_burst_length_heap(adapter); + + gf_assert(BL_SLICE_ALIGNMENT <= adapter->os_page_size, "slot buffer alignment is less than page size alignment."); + + share->bl_buffer = vidmm_allocate_segment_memory(adapter, SEGMENT_ID_LOCAL_E3K, (BL_BUFFER_SIZE + BL_BUFFER_ALIGN), 0); + + gf_info("bl_buffer: gpu_virt_addr=0x%llx, size=0x%llx\n", share->bl_buffer->gpu_virt_addr, share->bl_buffer->list_node->aligned_size); + + heap_start = (share->bl_buffer->gpu_virt_addr + BL_BUFFER_ALIGN - 1) & (~(BL_BUFFER_ALIGN-1));//align + heap_size = BL_BUFFER_SIZE; + + gf_info("bl_buffer aligned: gpu_virt_addr=0x%llx, size=0x%llx\n", heap_start, heap_size); + + heap_init(heap, 1, heap_start, heap_size, BL_SLICE_ALIGNMENT); + } + + { + vidmm_map_flags_t flags = {0}; + unsigned int segment_id = + adapter->hw_caps.local_only ? SEGMENT_ID_LOCAL_E3K: (adapter->hw_caps.snoop_only ? SEGMENT_ID_GART_SNOOPABLE_E3K : SEGMENT_ID_GART_UNSNOOPABLE_E3K); + + flags.mem_space = GF_MEM_KERNEL; + flags.cache_type = GF_MEM_UNCACHED; + + share->flush_fifo_buffer = vidmm_allocate_segment_memory(adapter, segment_id, 0x1000, 0); + + vidmm_map_segment_memory(adapter, NULL, share->flush_fifo_buffer, &flags); + + gf_info("flush_fifo_buffer: gpu_virt_addr=%x, kmd_virt_addr=%p\n", share->flush_fifo_buffer->gpu_virt_addr, share->flush_fifo_buffer->vma->virt_addr); + } + + return S_OK; +} + +static int vidschi_init_engine_schedule_profile_e3k(adapter_t *adapter, vidsch_query_private_t *query) +{ + int i; + + for ( i = 0; i < query->engine_count; i++) + { + switch(i) + { + case RB_INDEX_GFXL: + //case RB_INDEX_GFXH: + case RB_INDEX_VCP0: + case RB_INDEX_VCP1: + case RB_INDEX_VPP: + query->schedule_serialize[i] = 1; + break; + default: + query->schedule_serialize[i] = 0; + break; + } + } + + return 0; +} + +int vidsch_query_chip(adapter_t *adapter, vidsch_query_private_t *query) +{ + //enable reset for qt/HAPS test + if(adapter->ctl_flags.run_on_qt) + { + //vidschi_reset_adapter_e3k(adapter); + } + + vidschi_init_engine_share_e3k(adapter); + + vidschi_init_lookup_table_e3k(adapter, query); + + vidschi_init_hw_settings_e3k(adapter); + + vidschi_init_engine_schedule_profile_e3k(adapter, query); + + return S_OK; +} + +static void vidsch_get_set_reg_e3k(adapter_t *adapter, gf_query_info_t *info) +{ + unsigned int *buf; + int i=0; + + switch(info->type) + { + case GF_QUERY_GPU_TIME_STAMP: + { + unsigned int reg_offset = 0; + unsigned long long time_stamp_hi, time_stamp_lo; + + reg_offset = (CHIP_ARISE1020 <= adapter->chip_id) ? Reg_Csp_Ref_Total_Gpu_Timestamp_Offset_Arise1020 : Reg_Csp_Ms_Total_Gpu_Timestamp_Offset; + +#ifdef __aarch64__ + time_stamp_lo = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + reg_offset * 4); + time_stamp_hi = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + reg_offset * 4 + 4); + info->value64 = time_stamp_lo | (time_stamp_hi << 32); +#else + info->value64 = gf_read64(adapter->mmio + MMIO_CSP_START_ADDRESS + reg_offset * 4); +#endif + } + break; + + case GF_QUERY_REGISTER_U32: + buf=gf_calloc(info->buf_len*sizeof(unsigned int)); + if(buf) + { + for(i=0;ibuf_len;i++) + { + *(buf+i)=gf_read32(adapter->mmio+info->argu+i*sizeof(unsigned int)); + } + } + gf_copy_to_user(info->buf, buf, info->buf_len*sizeof(unsigned int)); + gf_free(buf); + break; + + case GF_SET_REGISTER_U32: + gf_write32(adapter->mmio+info->argu, info->value); + break; + default: + break; + } +} + +static void vidsch_set_miu_reg_e3k(adapter_t *adapter,gf_query_info_t *info) +{ + gf_write32(adapter->mmio+info->argu, info->value); +} + +static void vidsch_read_miu_reg_e3k(adapter_t *adapter,gf_query_info_t *info) +{ + info->value=gf_read32(adapter->mmio+info->argu); +} + +static void vidsch_dump_info_e3k(struct os_seq_file *seq_file, adapter_t *adapter) +{ + EngineSatus_e3k engine_status = {0}; + unsigned int *status =(unsigned int*) &engine_status; + unsigned int power_status = 0; + unsigned int gpc_count = (CHIP_ARISE1020 <= adapter->chip_id) ? 1 : 3; + int i; + + power_status = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + Reg_Pwr_Mgr_Status0_Offset *4); + + gf_seq_printf(seq_file, "engine power/clock status:0x%x\n", power_status); + + for( i = 0; i <7; i++) + { + *(status + i) = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + (Reg_Block_Busy_Bits_Top_Offset + i)*4); + } + //print the engine status + gf_seq_printf(seq_file, "E3K engine status:\n"); + gf_seq_printf(seq_file,"Top: 0x%x \n", engine_status.Top.uint); + gf_seq_printf(seq_file,"\t Csp_Busy :%d \n", engine_status.Top.reg.Csp_Busy); + gf_seq_printf(seq_file,"\t Mxua_Busy :%d \n", engine_status.Top.reg.Mxua_Busy); + gf_seq_printf(seq_file,"\t Mxub_Busy :%d \n", engine_status.Top.reg.Mxub_Busy); + gf_seq_printf(seq_file,"\t L2_Busy :%d \n", engine_status.Top.reg.L2_Busy); + gf_seq_printf(seq_file,"\t Gpcpfe_Busy :%d \n", engine_status.Top.reg.Gpcpfe_Busy); + gf_seq_printf(seq_file,"\t Gpcpbe_Busy :%d \n", engine_status.Top.reg.Gpcpbe_Busy); + gf_seq_printf(seq_file,"\t Sg_Busy :%d \n", engine_status.Top.reg.Sg_Busy); + gf_seq_printf(seq_file,"\t Tasfe_Busy :%d \n", engine_status.Top.reg.Tasfe_Busy); + gf_seq_printf(seq_file,"\t Tasbe_Busy :%d \n", engine_status.Top.reg.Tasbe_Busy); + gf_seq_printf(seq_file,"\t Hub_Busy :%d \n", engine_status.Top.reg.Hub_Busy); + + for (i = 0; i < gpc_count; i++) + { + Reg_Block_Busy_Bits_Gpc0_0 *s0 = (Reg_Block_Busy_Bits_Gpc0_0 *)(status + i * 2 + 1); + Reg_Block_Busy_Bits_Gpc0_1 *s1 = (Reg_Block_Busy_Bits_Gpc0_1 *)(status + i * 2 + 2); + + gf_seq_printf(seq_file,"GPC : %d HEX: 0x%x 0x%x\n",i, s0->uint, s1->uint); + gf_seq_printf(seq_file,"\t Tgz_Busy :0x%x \n", s0->reg.Tgz_Busy); + gf_seq_printf(seq_file,"\t Iu_Busy :0x%x \n", s0->reg.Iu_Busy); + gf_seq_printf(seq_file,"\t Wbu_Busy :0x%x \n", s0->reg.Wbu_Busy); + gf_seq_printf(seq_file,"\t Wls_Busy :0x%x \n", s0->reg.Wls_Busy); + gf_seq_printf(seq_file,"\t Ffc_Busy :0x%x \n", s0->reg.Ffc_Busy); + gf_seq_printf(seq_file,"\t Tu_Busy :0x%x \n", s0->reg.Tu_Busy); + + gf_seq_printf(seq_file,"\t Eu_Constructor_Busy :0x%x \n", s1->reg.Eu_Constructor_Busy); + gf_seq_printf(seq_file,"\t Euvs_Busy :0x%x \n", s1->reg.Euvs_Busy); + gf_seq_printf(seq_file,"\t Euhs_Busy :0x%x \n", s1->reg.Euhs_Busy); + gf_seq_printf(seq_file,"\t Eufe_Busy :0x%x \n", s1->reg.Eufe_Busy); + gf_seq_printf(seq_file,"\t Euds_Busy :0x%x \n", s1->reg.Euds_Busy); + gf_seq_printf(seq_file,"\t Eugs_Busy :0x%x \n", s1->reg.Eugs_Busy); + gf_seq_printf(seq_file,"\t Eups_Busy :0x%x \n", s1->reg.Eups_Busy); + gf_seq_printf(seq_file,"\t Eucs_Busy :0x%x \n", s1->reg.Eucs_Busy); + } +} + +static void vidsch_dump_debugbus_e3k(struct os_printer *p, adapter_t *adapter) +{ + EngineSatus_e3k engine_status; + unsigned int *status = (unsigned int *)&engine_status; + int i; + + /*dump debug bus*/ + if(!adapter->display_debugbus_flag) + { + return; + } + + for( i = 0; i <7; i++) + { + *(status + i) = gf_read32(adapter->mmio + MMIO_CSP_START_ADDRESS + (Reg_Block_Busy_Bits_Top_Offset + i)*4); + } + + gf_printf(p, "ChipSliceMask: %08x\n", adapter->hw_caps.chip_slice_mask); + gf_printf(p, "Engine Hang and Status: %08x,%08x,%08x,%08x,%08x,%08x,%08x.\n", + engine_status.Top.uint, engine_status.Gpc0_0.uint, engine_status.Gpc0_1.uint, + engine_status.Gpc1_0.uint, engine_status.Gpc1_1.uint, engine_status.Gpc2_0.uint, engine_status.Gpc2_1.uint); + + vidsch_display_debugbus_info_e3k(adapter, p, FALSE); +} + +static vidsch_chip_func_t engine_gfx_low_chip_func_e3k = +{ + .initialize = engine_gfx_low_init_e3k, + .destroy = engine_destroy_e3k, + + .submit = engine_submit_task_dma_e3k, + .update_fence_id = engine_update_fence_id_e3k, +#ifdef GF_HW_NULL + .set_fence_id = engine_set_fence_id_e3k, +#endif + + .cil2_misc = engine_cil2_misc_e3k, + + .save = engine_save_e3k, + .restore = engine_gfx_low_restore_e3k, + + .render = vidsch_render_e3k, + .patch = vidsch_patch_e3k, + + .reset_hw = vidsch_reset_hw_e3k, + .dump_hang_info = vidsch_dump_hang_info_e3k, + .dump_hang = vidsch_dump_hang_e3k, + + .set_miu_reg = vidsch_set_miu_reg_e3k, + .read_miu_reg = vidsch_read_miu_reg_e3k, + .power_clock = vidsch_power_clock_on_off_e3k, +}; + +static vidsch_chip_func_t engine_gfx_high_chip_func_e3k = +{ + .initialize = engine_gfx_high_init_e3k, + .destroy = engine_destroy_e3k, + + .submit = engine_submit_task_dma_e3k, + .update_fence_id = engine_update_fence_id_e3k, + + .cil2_misc = engine_cil2_misc_e3k, + + .save = engine_save_e3k, + .restore = engine_gfx_high_restore_e3k, + + .render = vidsch_render_e3k, + .patch = vidsch_patch_e3k, + + .reset_hw = vidsch_reset_hw_e3k, + .dump_hang_info = vidsch_dump_hang_info_e3k, + .dump_hang = vidsch_dump_hang_e3k, + + .power_clock = vidsch_power_clock_on_off_e3k, +}; + +static vidsch_chip_func_t engine_vcp_low0_chip_func_e3k = +{ + .initialize = engine_vcp_init_e3k, + .destroy = engine_destroy_e3k, + + .submit = engine_submit_task_dma_e3k, + .update_fence_id = engine_update_vcp_fence_id_e3k, + + .cil2_misc = engine_cil2_misc_e3k, + + .save = engine_save_e3k, + .restore = engine_restore_e3k, + + .render = vidsch_render_e3k, + .patch = vidsch_patch_e3k, + + .reset_hw = vidsch_reset_hw_e3k, + .dump_hang_info = vidsch_dump_hang_info_e3k, + .dump_hang = vidsch_dump_hang_e3k, + + .power_clock = vidsch_power_clock_on_off_e3k, +}; + +static vidsch_chip_func_t engine_vcp_low1_chip_func_e3k = +{ + .initialize = engine_vcp_init_e3k, + .destroy = engine_destroy_e3k, + + .submit = engine_submit_task_dma_e3k, + .update_fence_id = engine_update_vcp_fence_id_e3k, + + .cil2_misc = engine_cil2_misc_e3k, + + .save = engine_save_e3k, + .restore = engine_restore_e3k, + + .render = vidsch_render_e3k, + .patch = vidsch_patch_e3k, + + .reset_hw = vidsch_reset_hw_e3k, + .dump_hang_info = vidsch_dump_hang_info_e3k, + .dump_hang = vidsch_dump_hang_e3k, + + .power_clock = vidsch_power_clock_on_off_e3k, +}; + +static vidsch_chip_func_t engine_vpp_chip_func_e3k = +{ + .initialize = engine_vpp_init_e3k, + .destroy = engine_destroy_e3k, + + .submit = engine_submit_task_dma_e3k, + .update_fence_id = engine_update_vpp_fence_id_e3k, + + .cil2_misc = engine_cil2_misc_e3k, + + .save = engine_save_e3k, + .restore = engine_restore_e3k, + + .render = vidsch_render_e3k, + .patch = vidsch_patch_e3k, + + .reset_hw = vidsch_reset_hw_e3k, + .dump_hang_info = vidsch_dump_hang_info_e3k, + .dump_hang = vidsch_dump_hang_e3k, + + .power_clock = vidsch_power_clock_on_off_e3k, +}; + +vidschedule_chip_func_t vidschedule_chip_func = +{ + .dump_info = vidsch_dump_info_e3k, + .dump_debugbus = vidsch_dump_debugbus_e3k, + .power_tuning = vidsch_power_tuning_e3k, + .get_set_reg = vidsch_get_set_reg_e3k, +}; + + diff --git a/drivers/gpu/drm/arise/core/global/global.c b/drivers/gpu/drm/arise/core/global/global.c new file mode 100644 index 0000000000000..cc2c1a6530adb --- /dev/null +++ b/drivers/gpu/drm/arise/core/global/global.c @@ -0,0 +1,302 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "kernel_interface.h" + +void glb_init_chip_id(adapter_t *adapter, krnl_adapter_init_info_t *info) +{ + adapter->hw_caps.support_snooping = TRUE; + adapter->pm_caps.pwm_mode = info->gf_pwm_mode; + + { + adapter->family_id = FAMILY_ELT; + adapter->generic_id= PCI_ID_ARISE; + + adapter->hw_caps.support_snooping = TRUE; + //from loongson, loonson 3A3000 not support snoop +#if defined(__mips64__) || defined(__loongarch__) + adapter->hw_caps.support_snooping = FALSE; +#endif + adapter->hw_caps.page_4k_enable = TRUE; + + adapter->hw_caps.hw_patch_enable = FALSE; +#ifndef GF_HW_NULL + adapter->hw_caps.local_only = FALSE; +#else + adapter->hw_caps.local_only = FALSE; +#endif + +#ifdef VIDEO_ONLY_FPGA + adapter->hw_caps.video_only = TRUE; +#else + adapter->hw_caps.video_only = FALSE; +#endif + +#ifdef GFX_ONLY_FPGA + adapter->hw_caps.gfx_only = TRUE; +#else + adapter->hw_caps.gfx_only = FALSE; +#endif + + if(info->gf_dfs_mode == 1) + { + adapter->hw_caps.dfs_enable = TRUE; + } + + if (adapter->hw_caps.video_only) + { + adapter->ctl_flags.paging_enable = FALSE; + adapter->ctl_flags.worker_thread_enable = FALSE; + } + else + { + adapter->ctl_flags.paging_enable = TRUE; + adapter->ctl_flags.worker_thread_enable = info->gf_worker_thread_enable; + } + + adapter->ctl_flags.split_enable = FALSE; + + adapter->ctl_flags.vesa_tempbuffer_enable = info->gf_vesa_tempbuffer_enable ? TRUE : FALSE; + + if((adapter->bus_config.device_id & CHIP_MASK) == CHIP_MASK_ARISE1020) + adapter->chip_id = CHIP_ARISE1020; + else if((adapter->bus_config.device_id & CHIP_MASK) == CHIP_MASK_ARISE1040) + adapter->chip_id = CHIP_ARISE1040; + else if((adapter->bus_config.device_id & CHIP_MASK) == CHIP_MASK_ARISE1010) + adapter->chip_id = CHIP_ARISE1010; + else if((adapter->bus_config.device_id & CHIP_MASK) == CHIP_MASK_ARISE10C0T) + adapter->chip_id = CHIP_ARISE10C0T; + else if((adapter->bus_config.device_id & CHIP_MASK) == CHIP_MASK_ARISE2030) + adapter->chip_id = CHIP_ARISE2030; + else if((adapter->bus_config.device_id & CHIP_MASK) == CHIP_MASK_ARISE2020) + adapter->chip_id = CHIP_ARISE2020; + else + adapter->chip_id = CHIP_ARISE; + + adapter->hw_patch_mask0 |= PATCH_FENCE_INTERRUPT_LOST; + + adapter->pm_caps.pwm_manual = FALSE; + + //for elite3000, only cg manual mode is supported. + //gf_pwm_mode == 1 means enable cg manual mode. + if (info->gf_pwm_mode) + { + unsigned int cg_manual_mode = info->gf_pwm_mode & 0x1; + unsigned int cg_auto_mode = (info->gf_pwm_mode >> 4) & 0x7; + + if (adapter->chip_id < CHIP_ARISE2030) + { + adapter->pwm_level.EnableClockGating = cg_manual_mode ? 1 : 0; + } + else + { + adapter->pm_caps.pwm_auto = cg_auto_mode; + adapter->pwm_level.EnableClockGating = cg_auto_mode ? 0 : (cg_manual_mode ? 1 : 0); + } + } + } + + adapter->ctl_flags.recovery_enable = info->gf_recovery_enable; + adapter->ctl_flags.run_on_qt = info->gf_run_on_qt; + // qemu will set default subsystem id to PCI_SUBVENDOR_ID_REDHAT_QUMRANET:PCI_SUBDEVICE_ID_QEMU + adapter->ctl_flags.run_on_qemu_device = adapter->bus_config.sub_sys_vendor_id == 0x1AF4 && adapter->bus_config.sub_sys_id == 0x1100; + adapter->ctl_flags.hang_dump = info->gf_hang_dump; + + if(info->gf_hang_dump) + { + adapter->ctl_flags.recovery_enable = TRUE; + adapter->ctl_flags.flag_buffer_verify = info->gf_flag_buffer_verify; + + if (info->gf_hang_dump == 3) + { + adapter->ctl_flags.paging_enable = FALSE; + } + + adapter->Real_vram_size = ((unsigned long long)info->gf_local_size_g << 30) + ((unsigned long long)info->gf_local_size_m << 20); + adapter->gart_ram_size = ((unsigned long long)info->gf_pcie_size_g << 30) + ((unsigned long long)info->gf_pcie_size_m << 20); + gf_info("hang dump avaiable, set local vram size: %d M, visible vram size: %d M , pcie vram size:%d M\n", adapter->Real_vram_size >> 20, adapter->Visible_vram_size >> 20, adapter->gart_ram_size >> 20); + } +#ifndef VMI_MODE + else + { + adapter->Real_vram_size = 0; + adapter->gart_ram_size = 0; + } +#endif + + if(adapter->sys_caps.secure_on) + { + adapter->hw_caps.secure_range_enable = TRUE; + } + else + { + adapter->hw_caps.secure_range_enable = FALSE; + } + + adapter->hw_caps.miu_channel_size = info->miu_channel_size; +#if defined(__mips64__) || defined(__loongarch__) + adapter->hw_caps.gf_backdoor_enable = info->gf_backdoor_enable && adapter->chip_id < CHIP_ARISE1020 && adapter->link_speed != 1; +#else + adapter->hw_caps.gf_backdoor_enable = info->gf_backdoor_enable && adapter->chip_id < CHIP_ARISE1020 && adapter->link_speed != 1 && adapter->link_speed != 2; +#endif + adapter->hw_caps.chip_slice_mask = info->chip_slice_mask; +#if defined(VMI_MODE) + adapter->hw_caps.miu_channel_num = 1; +#endif + + adapter->debugfs_mask = info->debugfs_mask; + + gf_info("%s() debugfs_mask-0x%x\n", __func__, adapter->debugfs_mask); + + //gf_info("adapter->ctl_flags.worker_thread_enable %x\n", adapter->ctl_flags.worker_thread_enable); + //gf_info("hw caps: secure:%d, snoop:%d, 4K_page:%d, Paging:%d, local_only:%d, CG:%d, DFS:%d.\n", + // adapter->hw_caps.secure_range_enable, adapter->hw_caps.support_snooping, adapter->hw_caps.page_4k_enable, + // adapter->ctl_flags.paging_enable, + // adapter->hw_caps.local_only, adapter->pwm_level.EnableClockGating, adapter->hw_caps.dfs_enable); + + glb_init_chip_interface(adapter); +} + +void glb_get_pci_config_info(adapter_t *adapter) +{ + unsigned long long mmio; + unsigned long long fb; + unsigned long claim_fb_size; + bus_config_t* bus_config = &adapter->bus_config; + gf_map_argu_t map = {0}; + + gf_get_bus_config(adapter->os_device.pdev, bus_config); + + gf_info("bus_command: 0x%x, device id: 0x%x\n", bus_config->command, bus_config->device_id); + + adapter->sys_caps.secure_on = bus_config->secure_on; + + claim_fb_size = bus_config->mem_end_addr[0] - bus_config->mem_start_addr[0] + 1; + +// gf_info("bus claimed cpu access-able vram size: 0x%x, %dM, secure_on: %d\n", +// claim_fb_size, claim_fb_size >> 20, adapter->sys_caps.secure_on); + +#if defined(__i386__) || defined(__x86_64__) || defined(__mips64__) || defined(__loongarch__) + adapter->primary = (bus_config->command & 0x01) ? 1 : 0; +#else + adapter->primary = 0; +#endif + + adapter->link_width = (bus_config->link_status>>4) & 0x1F; + adapter->link_speed = bus_config->link_status & 0xF; + + mmio = bus_config->reg_start_addr[0]; + fb = bus_config->mem_start_addr[0] & (~0xFF);/*The base address not right under QNX*/ + +#if defined(VMI_MODE) + adapter->mmio = 0; //mmio is set 0, because cmodel knows virt_addr of mmio + adapter->bci_base = (unsigned int*)(adapter->mmio + 0x10000); + + adapter->vidmm_bus_addr = fb; + + adapter->physical_bus_base_length[0] = bus_config->reg_end_addr[0] - bus_config->reg_start_addr[0]; + adapter->physical_bus_base_length[1] = claim_fb_size; + adapter->Visible_vram_size = adapter->physical_bus_base_length[1]; + + //Real_vram_size is transferred to core, by mem_start_addr[1]/mem_end_addr[1] + adapter->Real_vram_size = bus_config->mem_end_addr[1] - bus_config->mem_start_addr[1] + 1; + + gf_info("video memory size: %dM.\n", adapter->Visible_vram_size >> 20); +#elif defined(GF_PCIE_BUS) + map.flags.cache_type = GF_MEM_UNCACHED; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = mmio; + map.size = bus_config->reg_end_addr[0] - bus_config->reg_start_addr[0]; + + adapter->mmio_vma = gf_map_io_memory(NULL, &map); + + adapter->mmio = adapter->mmio_vma->virt_addr; + adapter->bci_base = (unsigned int*)(adapter->mmio + 0x10000); + + adapter->vidmm_bus_addr = fb; + + adapter->physical_bus_base_length[0] = bus_config->reg_end_addr[0] - bus_config->reg_start_addr[0]; + adapter->physical_bus_base_length[1] = claim_fb_size; + + /*adapter->Real_vram_size will setup later by update adapter info*/ + adapter->Visible_vram_size = adapter->physical_bus_base_length[1]; +#elif defined(GF_HW_NULL) + //cache_type = GF_MEM_UNCACHED; + //alloc_flags.cache_type = cache_type; + alloc_pages_flags_t alloc_flags = {0}; + + alloc_flags.need_flush = 1; + alloc_flags.need_zero = 1; + alloc_flags.fixed_page = 1; + + map.memory = gf_allocate_pages_memory(0x80000, adapter->os_page_size, alloc_flags); + + if(map.memory == NULL) + { + gf_error("allocate command buffer fail: out of memory!\n"); + } + + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.mem_type = GF_SYSTEM_RAM; + map.size = 0x80000; + + adapter->mmio_vma = gf_map_pages_memory(NULL, &map); + adapter->mmio_mem = map.memory; + + adapter->mmio = adapter->mmio_vma->virt_addr; + adapter->bci_base = (unsigned int*)(adapter->mmio + 0x10000); + adapter->vidmm_bus_addr = fb; + + adapter->physical_bus_base_length[0] = 0x80000; + adapter->physical_bus_base_length[1] = claim_fb_size; + + adapter->Visible_vram_size = + adapter->Real_vram_size = claim_fb_size; + + gf_info("video memory size: %dM.\n", claim_fb_size >> 20); + gf_info("mmio virt addr: %x.\n", adapter->mmio); + +#else + //engine mmio + map.flags.cache_type = GF_MEM_UNCACHED; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = mmio; + map.size = bus_config->reg_end_addr[0] - bus_config->reg_start_addr[0]; + + adapter->mmio_vma = gf_map_io_memory(NULL, &map); + adapter->mmio = adapter->mmio_vma->virt_addr; + adapter->bci_base = (unsigned int*)(adapter->mmio + 0x10000); + adapter->vidmm_bus_addr = fb; + + adapter->physical_bus_base_length[0] = 0x80000; + adapter->physical_bus_base_length[1] = claim_fb_size; + + gf_info("sys_secure_on: %d, mmio: %x-%d-%p\n", + bus_config->secure_on, + bus_config->reg_end_addr[0], bus_config->reg_end_addr[0] - bus_config->reg_start_addr[0], adapter->mmio); + +#endif +} +void glb_fini_bus_config(adapter_t *adapter) +{ + if(adapter->mmio_vma) + { + gf_unmap_io_memory(adapter->mmio_vma); + } +} + diff --git a/drivers/gpu/drm/arise/core/global/global.h b/drivers/gpu/drm/arise/core/global/global.h new file mode 100644 index 0000000000000..3d60688f8595c --- /dev/null +++ b/drivers/gpu/drm/arise/core/global/global.h @@ -0,0 +1,26 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GLOBAL_H__ +#define __GLOBAL_H__ + +#include "gf_chip_id.h" +struct krnl_adapter_init_info_s; +extern void glb_init_chip_id(adapter_t *adapter, struct krnl_adapter_init_info_s *info); +extern void glb_get_pci_config_info(adapter_t *adapter); +extern void glb_init_chip_interface(adapter_t *adapter); +extern void glb_fini_bus_config(adapter_t *adapter); + +extern void glb_init_power_caps(adapter_t *adapter); +#endif diff --git a/drivers/gpu/drm/arise/core/include/core_errno.h b/drivers/gpu/drm/arise/core/include/core_errno.h new file mode 100644 index 0000000000000..a185169791296 --- /dev/null +++ b/drivers/gpu/drm/arise/core/include/core_errno.h @@ -0,0 +1,33 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __ERRNO_H_ +#define __ERRNO_H_ + +#define S_OK 0x00000000 +#define E_OUTOFMEMORY 0x80000002 +#define E_NOIMPL 0x80004001 +#define E_INVALIDARG 0x80070057 +#define E_NOINTERFACE 0x80004002 +#define E_POINTER 0x80004003 +#define E_UNEXPECTED 0x8000FFFF +#define E_FAIL 0x10004005 +#define E_UNSWIZZLING_APERTURE_UNSUPPORTED 0x10004006 +/*page out allocation but allocation still used by GPU hw*/ +#define E_PAGEOUT_ALLOCATION_BUSY 0x10004007 +#define E_INSUFFICIENT_DMA_BUFFER 0xFFFF0001 + + +#endif + diff --git a/drivers/gpu/drm/arise/core/include/core_import.h b/drivers/gpu/drm/arise/core/include/core_import.h new file mode 100644 index 0000000000000..282f3dfc08ca9 --- /dev/null +++ b/drivers/gpu/drm/arise/core/include/core_import.h @@ -0,0 +1,219 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __CORE_IMPORT_H__ +#define __CORE_IMPORT_H__ + +#include "kernel_import.h" + +#define GF_PAGE_64KB_SIZE 0x10000 + +extern krnl_import_func_list_t *gf; + +/* CORE referenced funcs list */ + +#define gf_udelay gf->udelay +#define gf_do_div gf->do_div +#define gf_msleep gf->msleep +#define gf_getsecs gf->getsecs +#define gf_get_nsecs gf->get_nsecs +#define gf_assert gf->assert +#define gf_copy_from_user gf->copy_from_user +#define gf_copy_to_user gf->copy_to_user +#define gf_memset gf->memset +#define gf_memcpy gf->memcpy +#define gf_memcmp gf->memcmp_priv +#define gf_byte_copy gf->byte_copy +#define gf_strcmp gf->strcmp +#define gf_strcpy gf->strcpy +#define gf_strncmp gf->strncmp +#define gf_strncpy gf->strncpy +#define gf_strlen gf->strlen +#define gf_read64 gf->read64 +#define gf_read32 gf->read32 +#define gf_read16 gf->read16 +#define gf_read8 gf->read8 +#define gf_write32 gf->write32 +#define gf_write16 gf->write16 +#define gf_write8 gf->write8 +#define gf_file_open gf->file_open +#define gf_file_close gf->file_close +#define gf_file_read gf->file_read +#define gf_file_write gf->file_write +#define gf_vsprintf gf->vsprintf +#define gf_vsnprintf gf->vsnprintf +#define gf_sscanf gf->sscanf +#define gf_printk gf->printk +#define gf_cb_printk gf->cb_printk +#define gf_seq_printf gf->seq_printf +#define gf_printf gf->os_printf +#define gf_find_first_zero_bit gf->find_first_zero_bit +#define gf_find_next_zero_bit gf->find_next_zero_bit +#define gf_set_bit gf->set_bit +#define gf_clear_bit gf->clear_bit +#define gf_getsecs gf->getsecs +#define gf_get_nsecs gf->get_nsecs +#define gf_create_thread gf->create_thread +#define gf_destroy_thread gf->destroy_thread +#define gf_thread_should_stop gf->thread_should_stop +#define gf_create_atomic gf->create_atomic +#define gf_destroy_atomic gf->destroy_atomic +#define gf_atomic_read gf->atomic_read +#define gf_atomic_inc gf->atomic_inc +#define gf_atomic_dec gf->atomic_dec +#define gf_atomic_add gf->atomic_add +#define gf_atomic_sub gf->atomic_sub +#define gf_create_mutex gf->create_mutex +#define gf_destroy_mutex gf->destroy_mutex +#define gf_mutex_lock gf->mutex_lock +#define gf_mutex_lock_killable gf->mutex_lock_killable +#define gf_mutex_trylock gf->mutex_trylock +#define gf_mutex_unlock gf->mutex_unlock +#define gf_create_sema gf->create_sema +#define gf_destroy_sema gf->destroy_sema +#define gf_down gf->down +#define gf_down_trylock gf->down_trylock +#define gf_up gf->up +#define gf_create_rwsema gf->create_rwsema +#define gf_destroy_rwsema gf->destroy_rwsema +#define gf_down_read gf->down_read +#define gf_down_write gf->down_write +#define gf_up_read gf->up_read +#define gf_up_write gf->up_write +#define gf_create_spinlock gf->create_spinlock +#define gf_destroy_spinlock gf->destroy_spinlock +#define gf_spin_lock gf->spin_lock +#define gf_spin_try_lock gf->spin_try_lock +#define gf_spin_unlock gf->spin_unlock +#define gf_spin_lock_irqsave gf->spin_lock_irqsave +#define gf_spin_unlock_irqrestore gf->spin_unlock_irqrestore +#define gf_create_event gf->create_event +#define gf_destroy_event gf->destroy_event +#define gf_wait_event_thread_safe gf->wait_event_thread_safe +#define gf_wait_event gf->wait_event +#define gf_wake_up_event gf->wake_up_event +#define gf_thread_wait gf->thread_wait +#define gf_create_wait_queue gf->create_wait_queue +#define gf_thread_wake_up gf->thread_wake_up +#define gf_dump_stack gf->dump_stack +#define gf_try_to_freeze gf->try_to_freeze +#define gf_freezable gf->freezable +#define gf_clear_freezable gf->clear_freezable +#define gf_set_freezable gf->set_freezable +#define gf_freezing gf->freezing +#define gf_get_current_pid gf->get_current_pid +#define gf_get_current_tid gf->get_current_tid +#define gf_get_current_pname gf->get_current_pname +#define gf_flush_cache gf->flush_cache +#define gf_inv_cache gf->inv_cache +#define gf_pages_memory_for_each_continues gf->pages_memory_for_each_continues +#define gf_get_page_count gf->get_page_count +#define gf_fill_continues_page_memory gf->fill_continues_page_memory +#define gf_allocate_pages_memory_dynamic gf->allocate_pages_memory_dynamic +#define gf_fill_pages_memory_dynamic gf->fill_pages_memory_dynamic +#define gf_free_pages_memory_dynamic gf->free_pages_memory_dynamic +#define gf_ioremap gf->ioremap +#define gf_iounmap gf->iounmap_priv +#define gf_mtrr_add gf->mtrr_add +#define gf_mtrr_del gf->mtrr_del +#define gf_get_mem_info gf->get_mem_info +#define gf_pages_memory_swapout gf->pages_memory_swapout +#define gf_pages_memory_swapin gf->pages_memory_swapin +#define gf_release_file_storage gf->release_file_storage +#define gf_get_bus_config gf->get_bus_config +#define gf_get_platform_config gf->get_platform_config +#define gf_disp_wait_idle gf->disp_wait_idle + +#define gf_enable_interrupt gf->enable_interrupt +#define gf_disable_interrupt gf->disable_interrupt + +#define gf_mb gf->mb +#define gf_rmb gf->rmb +#define gf_wmb gf->wmb +#define gf_flush_wc gf->flush_wc +#define gf_dsb gf->dsb +#define gf_is_own_pages gf->is_own_pages + +#if GF_MALLOC_TRACK +#define gf_malloc(size) gf->malloc_track(size, __FILE__, __LINE__) +#define gf_calloc(size) gf->calloc_track(size, __FILE__, __LINE__) +#define gf_free(addr) gf->free_track(addr, __FILE__, __LINE__) +#else +#define gf_malloc(size) gf->malloc_priv(size) +#define gf_calloc(size) gf->calloc_priv(size) +#define gf_free(addr) gf->free_priv(addr) +#endif + +#if GF_ALLOC_PAGE_TRACK +#define gf_allocate_pages_memory(pdev, size, page_size, flag) \ + gf->allocate_pages_memory_track(pdev, size, page_size, flag, __FILE__, __LINE__) +#define gf_free_pages_memory(pdev, memory) \ + gf->free_pages_memory_track(pdev, memory, __FILE__, __LINE__) +#else +#define gf_allocate_pages_memory(pdev, size, page_size, flag) \ + gf->allocate_pages_memory_priv(pdev, size, page_size, flag) +#define gf_free_pages_memory(pdev, memory) \ + gf->free_pages_memory_priv(pdev, memory) +#endif + +#if GF_MAP_PAGES_TRACK +#define gf_map_pages_memory(priv, argu) \ + gf->map_pages_memory_track(priv, argu, __FILE__, __LINE__) +#define gf_unmap_pages_memory(map) \ + gf->unmap_pages_memory_track(map, __FILE__, __LINE__) +#else +#define gf_map_pages_memory(priv, argu) \ + gf->map_pages_memory_priv(priv, argu) +#define gf_unmap_pages_memory(vma) \ + gf->unmap_pages_memory_priv(vma) +#endif + +#if GF_MAP_IO_TRACK +#define gf_map_io_memory(priv, argu) \ + gf->map_io_memory_track(priv, argu, __FILE__, __LINE__) +#define gf_unmap_io_memory(argu) \ + gf->unmap_io_memory_track(argu, __FILE__, __LINE__) +#else +#define gf_map_io_memory(priv, argu) \ + gf->map_io_memory_priv(priv, argu) +#define gf_unmap_io_memory(argu) \ + gf->unmap_io_memory_priv(argu) +#endif + +#ifdef _DEBUG_ +#define GF_MSG_LEVEL GF_DRV_DEBUG +#define gf_debug(args...) gf_printk(GF_DRV_DEBUG, ##args) +#else +#define GF_MSG_LEVEL GF_DRV_INFO +#define gf_debug(args...) +#endif + +#define gf_emerg(args...) gf->printk(GF_DRV_EMERG, ##args) +#define gf_error(args...) gf->printk(GF_DRV_ERROR, ##args) +#define gf_info(args...) gf->printk(GF_DRV_INFO, ##args) +#define gf_warning(args...) gf->printk(GF_DRV_WARNING, ##args) + +#define gf_register_trace_events gf->register_trace_events +#define gf_unregister_trace_events gf->unregister_trace_events +#define gf_task_create_trace_event gf->task_create_trace_event +#define gf_task_submit_trace_event gf->task_submit_trace_event +#define gf_fence_back_trace_event gf->fence_back_trace_event +#define gf_begin_section_trace_event gf->begin_section_trace_event +#define gf_end_section_trace_event gf->end_section_trace_event +#define gf_counter_trace_event gf->counter_trace_event + +#define gf_query_platform_caps gf->query_platform_caps +#define gf_console_lock gf->console_lock +#endif /*__CORE_IMPORT_H__*/ + diff --git a/drivers/gpu/drm/arise/core/include/gf_adapter.h b/drivers/gpu/drm/arise/core/include/gf_adapter.h new file mode 100644 index 0000000000000..832ca9d28117f --- /dev/null +++ b/drivers/gpu/drm/arise/core/include/gf_adapter.h @@ -0,0 +1,388 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_ADAPTER_H__ +#define __GF_ADAPTER_H__ + +#include "handle_manager.h" +#include "heap_manager.h" +#include "core_errno.h" +#include "util.h" +#include "list.h" +#include "core_import.h" +#include "gf_chip_id.h" +#include "gf_types.h" +#include "gf_def.h" + +//#define ENABLE_UNSNOOPABLE_PCIE 0 +#define ENABLE_UNSNOOPABLE_WROKAROUND 0 + +#define VIDMM_TRACE_ENABLE 0 +#define VIDSCH_TRACE_ENABLE 0 +#define MISC_DEBUG_INFO_ENABLE 0 +#define SEGMENT_TRACE_ENABLE 0 +#define VIDSCH_SYNC_TRACE_ENABLE 0 +#define VIDSCH_POWER_DEBUG 0 + +#define GF_TRACE_HW_HANG 0 +#define DEBUG_TEST 0 +#define DEBUG_HIGH_4G_MEM 0 +#define HIGH_4G_MEM_RESERVE_SIZE (0x10000000) //64M +#define TEST_VIDEO_RING_BUFFER 0 +#define TEST_POWER_MANAGE 0 + +#if VIDMM_TRACE_ENABLE +#define vidmm_trace gf_info +#else +#define vidmm_trace(args...) +#endif + +#if VIDSCH_TRACE_ENABLE +#define vidsch_trace gf_info +#else +#define vidsch_trace(args...) +#endif + +#if SEGMENT_TRACE_ENABLE +#define segment_trace gf_info +#else +#define segment_trace(args...) +#endif + +#if VIDSCH_SYNC_TRACE_ENABLE +#define sync_trace gf_info +#else +#define sync_trace(args...) +#endif + +#if VIDSCH_POWER_DEBUG +#define power_trace gf_info +#else +#define power_trace(args...) +#endif + +#define VCP0_INDEX 0 +#define VCP1_INDEX 1 +#define VCP_INDEX_COUNT 2 +#define VCP_INFO_COUNT 17 +#define MAX_VIDEO_SEQ_INDEX_ADD1 128 +#define MIN_VIDEO_SEQ_INDEX 0 +//it's from RB_INDEX_VCP0 +#define RB_INDEX_VIDEO_START 7 + +typedef struct engine_index_info +{ + unsigned int node_ordinal; + unsigned int engine_affinity; +} engine_index_info_t; + +/* our hw feature put here*/ +typedef struct hw_caps +{ + /* hw general features*/ + unsigned int fence_interrupt_enable: 1; + unsigned int support_snooping :1; + unsigned int address_mode_64bit :1; + unsigned int hw_patch_enable :1; + + unsigned int video_only :1; // fpga option + unsigned int gfx_only :1; // fpga option + unsigned int local_only :1; // only has local memory + unsigned int snoop_only :1; //without non-snoopy path + + unsigned int page_64k_enable :1; + unsigned int page_4k_enable :1; + unsigned int secure_range_enable:1; + unsigned int anti_hang_enable :1; //anti hang + + unsigned int svm_enable :1; //OCL share virtual memory + unsigned int dfs_enable :1; + unsigned int fb_hdaudio_enable :1; + unsigned int non_simul_chip :1; + unsigned int gf_backdoor_enable :1; + unsigned int reserved :15; + + int miu_channel_num; //should be 1~3 + int miu_channel_size; + unsigned int chip_slice_mask; +}hw_caps_t; + +/* our system feature put here*/ +typedef struct sys_caps +{ + unsigned int bus_pcie_inuse :1; + unsigned int bus_ahb_inuse :1; + unsigned int secure_on :1; + unsigned int iommu_enabled :1; + unsigned int reserved :28; +}sys_caps_t; + +/* our power feature put here*/ +typedef struct power_caps +{ + union + { + unsigned int pwm_auto; + struct + { + unsigned int gfx_cg_auto :1; + unsigned int vcp_cg_auto :1; + unsigned int vpp_cg_auto :1; + unsigned int gfx_pg_auto :1; + unsigned int vcp_pg_auto :1; + unsigned int vpp_pg_auto :1; + unsigned int auto_resv :26; + }; + + }; + union + { + unsigned int pwm_manual; + struct + { + unsigned int gfx_cg_manual :1; + unsigned int vcp_cg_manual :1; + unsigned int vpp_cg_manual :1; + unsigned int gfx_pg_manual :1; + unsigned int vcp_pg_manual :1; + unsigned int vpp_pg_manual :1; + unsigned int manual_rsv :26; + }; + }; + unsigned int pwm_mode; + union + { + unsigned int dvfs_auto; + struct + { + unsigned int gfx_dvfs_auto :1; + unsigned int vcp_dvfs_auto :1; + unsigned int vpp_dvfs_auto :1; + unsigned int dvfs_auto_rsv :29; + }; + }; + union + { + unsigned int dvfs_force; + struct + { + unsigned int gfx_dvfs_force :1; + unsigned int vcp_dvfs_force :1; + unsigned int vpp_dvfs_force :1; + unsigned int dvfs_force_rsv :29; + }; + }; + unsigned int dvfs_interrupt; + union + { + unsigned int slice_balance; + struct + { + unsigned int slice_balance_auto :1;//auto mode + unsigned int slice_balance_force :1;//simulate auto mode + unsigned int slice_force_enable :1;//force mode + unsigned int slice_force_value :1;//force mode value + unsigned int slice_rsv :28; + }; + }; +}power_caps_t; + + +/* adapter control flag put here */ +typedef struct ctl_flags +{ + unsigned int paging_enable :1; + unsigned int swap_enable :1; /* swap pages to shmem */ + unsigned int split_enable :1; + unsigned int worker_thread_enable :1; + unsigned int recovery_enable :1; /* reset hw if hang, must disable it if debug hang */ + unsigned int manual_flush_cache :1; /* if this flag set, default use wb for none snoop segment, and flush cache before GPU use manual, + for ARM use since arm snoop performance not good */ + unsigned int dump_hang_info_to_file :1; + unsigned int hang_dump :2; + unsigned int perf_event_enable :1; + unsigned int miu_counter_enable :1; + unsigned int flag_buffer_verify :1; + unsigned int local_for_display_only :1; + unsigned int submit_to_queue :1; /* if true, submit task to queue directly. only used when worker thread enable!!! */ + unsigned int run_on_qt :1; + unsigned int vesa_tempbuffer_enable :1; + unsigned int hwq_event_enable :1; + unsigned int run_on_qemu_device :1; + unsigned int reserved :14; +}ctl_flags_t; + +#define PATCH_E2UMA_FENCE_ID_LOST (1 << 0) +#define PATCH_FENCE_INTERRUPT_LOST (1 << 1) +#define PATCH_E2UMA_HW66 (1<<2) + +typedef struct +{ + int EnableClockGating; + int EnablePowerGating; + int DonotInitPowerSet; +}pwm_level_t; + + +typedef struct _kickoff_error_t +{ + unsigned int error; + unsigned int RbIndex; + unsigned int flush_fifo_buffer_value; + unsigned int last_send_fence_id; + unsigned int tail; + unsigned int offset; +}kickoff_error_t; + +typedef struct +{ + unsigned long long vcp_fence_id; + unsigned long long vcp_inc_timestamp; + unsigned int vcp_pid; +}gf_vcp_task_info; + +typedef struct +{ + ctl_flags_t ctl_flags; + sys_caps_t sys_caps; + hw_caps_t hw_caps; + pwm_level_t pwm_level; + power_caps_t pm_caps; + unsigned int hw_patch_mask0; + unsigned int hw_patch_mask1; + + void *post_event_argu; + int (*post_event)(void *argu, unsigned int event_mask); + + void *post_sync_event_argu; + int (*post_sync_event)(void *argu, unsigned int arg0, unsigned long long time); + + gf_drm_callback_t *drm_cb; + void *drm_cb_argu; + + os_device_t os_device; + + unsigned char *mmio; + unsigned int *bci_base; + gf_vm_area_t *mmio_vma; + struct os_pages_memory *mmio_mem; + + bus_config_t bus_config; + handle_mgr_t hdl_mgr; + unsigned int primary; + unsigned int index; + + unsigned int family_id; + unsigned int chip_id; + unsigned int generic_id; + unsigned short link_width; + unsigned short link_speed; + + unsigned long long physical_bus_base_length[2]; + unsigned long long vidmm_bus_addr; + + unsigned int os_page_size; + unsigned int os_page_shift; + + /* total memory size in gpu, include reserved */ + /* when hang dump is on, this is half of orignal value */ + unsigned long long Visible_vram_size; //only cpu visiable size + + unsigned char context_buffer_inuse[0xFFFF]; + + struct os_mutex *paging_lock; /* lock for paging */ + + struct os_mutex *device_list_lock; /* lock for paging */ + + struct os_spinlock *lock; /* adapter lock for device list and sync_obj list */ + + struct list_head sync_obj_list; /* defer destroy sync obj list */ + struct list_head device_list; /* device create in this adapter*/ + + struct di_mgr *dmgr; /* deinterlace mgr */ + struct _vidmm_mgr *mm_mgr; + + int paging_engine_index; + + struct vidsch_fence_buffer *fence_buf; + struct vidsch_fence_buffer *fence_buf_local; + struct vidsch_fence_buffer *fence_buf_snoop; + + struct _vidsch_mgr *sch_mgr[MAX_ENGINE_COUNT]; + struct vidschedule *schedule; + int active_engine_count; + engine_index_info_t engine_index_table[MAX_ENGINE_COUNT]; + + struct os_mutex *hw_reset_lock; + unsigned int hw_reset_times; + + //since e3k has 3 level page table, L3 is on chip 16*256*32bit. + struct _vidmm_gart_table_info *gart_table_L3; + struct _vidmm_gart_table_info *gart_table_L2; + + unsigned long long dummy_page_addr; /*dummy page addr for gart table*/ + + struct _perf_event_mgr *perf_event_mgr; + struct _hwq_event_mgr *hwq_event_mgr; + unsigned int usage_3d; + unsigned int usage_vcp; + unsigned int usage_vpp; + + unsigned long long Real_vram_size; // Total Video Mem + unsigned long long UnAval_vram_size; // for 3 miu, need dig out some mem from end of vram. + unsigned int fb_phy_addr; // for DUMA + + void *private_data; + + void *flag_buffer_virt_addr; // for elite flag buffer debug + + struct os_mutex *gart_table_lock; + + void *vesafb_tempbuffer; + void *mem_unavailable_for_3miu; //AVAILABLE + + unsigned long long low_top_address; + + + int vcp_index_cnt[VCP_INDEX_COUNT]; + gf_vcp_info vcp_info[VCP_INFO_COUNT]; + gf_vcp_task_info vcp_task_info[VCP_INFO_COUNT]; + unsigned char bVideoSeqIndex[MAX_VIDEO_SEQ_INDEX_ADD1]; + int start_index; + int end_index; + +#if DEBUG_HIGH_4G_MEM + void *Reserve_Buffer; +#endif + + void *disp_info; + unsigned long long gart_ram_size; //set pcie memory size + + int current_slice_mask; + int min_slice_mask; + + void *reserve_16m_buffer; + int display_debugbus_flag; + kickoff_error_t kickoff_error; + int in_suspend_resume; + int suspend_blt_mode; // bl_buffer 0: save + restore use cpu copy. 1: save + restore use gpu copy. 2: save use gpu copy, restore use cpu copy. + int debugfs_mask; + int context_destroy_timeout; + unsigned long long hw_hang_max_timeout_ns; + unsigned long long hw_hang_fast_timeout_ns; + unsigned long long sync_max_server_wait_time_ns; +} adapter_t; + +#endif + diff --git a/drivers/gpu/drm/arise/core/include/gf_chip_id.h b/drivers/gpu/drm/arise/core/include/gf_chip_id.h new file mode 100644 index 0000000000000..9b85a4e5e3ae2 --- /dev/null +++ b/drivers/gpu/drm/arise/core/include/gf_chip_id.h @@ -0,0 +1,123 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_CHIP_ID_H +#define __GF_CHIP_ID_H + + +#define PCI_ID_EXC2UMA 0x3A01 +#define PCI_ID_ELT1K 0x3200 +#define PCI_ID_ELT2K 0x330F // Elite2000, TBD for real HW ID +//#define PCI_ID_ZX2000 0x322F // ZaoXin2000, TBD for real HW ID +#define PCI_ID_ZX2000 0x3600 //fpga read value +#define PCI_ID_EXC2CHX001 0x3A03 +#define PCI_ID_EXC2CHX002 0x3A04 +#define PCI_ID_ELT3K 0x3D00 //Elite3000 +#define PCI_ID_ARISE 0x3D00 //ARISE10C0 +#define PCI_ID_ARISE10C0T 0x3D06 //ARISE10C0T +#define PCI_ID_ARISE1020 0x3D02 //ARISE1020 +#define PCI_ID_ARISE1040 0x3D03 //ARISE1040 +#define PCI_ID_ARISE1010 0x3D04 //ARISE1010 +#define PCI_ID_ARISE2030 0x3D07 //ARISE2030 +#define PCI_ID_ARISE2020 0x3D08 //ARISE2020 + +#define PCI_ID_GENERIC_EXCALIBUR PCI_ID_EXC2UMA +#define PCI_ID_GENERIC_ELITE PCI_ID_ELT +#define PCI_ID_GENERIC_ELITE3K PCI_ID_ELT3K + +#define DEVICE_MASK 0xFF00 +#define CHIP_MASK 0x00FF +#define DEVICE_ZX2000 (PCI_ID_ZX2000 & DEVICE_MASK) + +#define DEVICE_EXC2UMA (PCI_ID_EXC2UMA & DEVICE_MASK) +#define DEVICE_ELITE (PCI_ID_ELT & DEVICE_MASK) +#define DEVICE_ELITE1K (PCI_ID_ELT1K & DEVICE_MASK) +#define DEVICE_ELITE2K (PCI_ID_ELT2K & DEVICE_MASK) +#define DEVICE_CHX001 (PCI_ID_EXC2CHX001 & DEVICE_MASK) +#define DEVICE_CHX002 (PCI_ID_EXC2CHX002 & DEVICE_MASK) +#define DEVICE_ELITE3K (PCI_ID_ELT3K & DEVICE_MASK) + +#define CHIP_ELITE (PCI_ID_ELT & CHIP_MASK) +#define CHIP_ELITE1K (PCI_ID_ELT1K & CHIP_MASK) +#define CHIP_ELITE2K (PCI_ID_ELT2K & CHIP_MASK) +#define CHIP_ZHAOXIN2000 (PCI_ID_ZX2000 & CHIP_MASK) + +#define CHIP_EXCALIBUR2_UMA (PCI_ID_EXC2UMA & CHIP_MASK) +#define CHIP_EXCALIBUR2_CHX001 (PCI_ID_EXC2CHX001 & CHIP_MASK) +#define CHIP_EXCALIBUR2_CHX002 (PCI_ID_EXC2CHX002 & CHIP_MASK) +#define CHIP_ELITE3K (PCI_ID_ELT3K & CHIP_MASK) +#define CHIP_MASK_ARISE1020 (PCI_ID_ARISE1020 & CHIP_MASK) +#define CHIP_MASK_ARISE1040 (PCI_ID_ARISE1040 & CHIP_MASK) +#define CHIP_MASK_ARISE1010 (PCI_ID_ARISE1010 & CHIP_MASK) +#define CHIP_MASK_ARISE10C0T (PCI_ID_ARISE10C0T & CHIP_MASK) +#define CHIP_MASK_ARISE2030 (PCI_ID_ARISE2030 & CHIP_MASK) +#define CHIP_MASK_ARISE2020 (PCI_ID_ARISE2020 & CHIP_MASK) + +enum +{ + FAMILY_CMODEL, + FAMILY_CLB, + FAMILY_DST, + FAMILY_CSR, + FAMILY_INV, + FAMILY_EXC, + FAMILY_ELT, + FAMILY_LAST, +}; + +enum +{ + CHIP_CMODEL, + CHIP_CLB, + CHIP_DST, + CHIP_CSR, + CHIP_INV, + CHIP_H5, + CHIP_H5S1, + CHIP_H6S2, + CHIP_CMS, + CHIP_METRO, + CHIP_MANHATTAN, + CHIP_MATRIX, + CHIP_DST2, + CHIP_DST3, + CHIP_DUMA, + CHIP_H6S1, + CHIP_DST4, + CHIP_EXC1, //Excalibur-1 + CHIP_E2UMA, //E2UMA + CHIP_ELT, //Elite + CHIP_ELT1K, //Elite1k + CHIP_ELT2K, //Elite2k + CHIP_ELT2K5, //Elite2500 + CHIP_ZX2000, //ZX2000 + CHIP_ELT3K, //ELITE3K + CHIP_ARISE=CHIP_ELT3K, //ARISE10C0 + CHIP_ARISE10C0T, //ARISE10C0T + CHIP_ARISE1040, //ARISE1040 + CHIP_ARISE1020, //ARISE1020 + CHIP_ARISE1010, //ARISE1010 + CHIP_ARISE2030, //ARISE2030 + CHIP_ARISE2020, //ARISE2020 + CHIP_CHX001, //CHX001 + CHIP_CHX002, //CHX002 + CHIP_ZX2100, //ZX2100 + CHIP_LAST, //Maximum number of chips supported. +}; + + +#endif /*__GF_CHIP_ID_H*/ + + + diff --git a/drivers/gpu/drm/arise/core/include/kernel_import.h b/drivers/gpu/drm/arise/core/include/kernel_import.h new file mode 100644 index 0000000000000..18eda0c079811 --- /dev/null +++ b/drivers/gpu/drm/arise/core/include/kernel_import.h @@ -0,0 +1,440 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __KERNEL_IMPORT_H__ +#define __KERNEL_IMPORT_H__ +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL ((void *)0) +#endif + +//enable/disable mem track +#define GF_MALLOC_TRACK 0 +#define GF_ALLOC_PAGE_TRACK 0 +#define GF_MAP_PAGES_TRACK 0 +#define GF_MAP_IO_TRACK 0 +#define GF_MEM_TRACK_RESULT_TO_FILE 0 + + +#define OS_ACCMODE 0x00000003 +#define OS_RDONLY 0x00000000 +#define OS_WRONLY 0x00000001 +#define OS_RDWR 0x00000002 +#define OS_CREAT 0x00000100 +#define OS_APPEND 0x00002000 +#define OS_LARGEFILE 0x00100000 + +#define DEBUGFS_NODE_DEVICE 1 +#define DEBUGFS_NODE_HEAP 2 +#define DEBUGFS_NODE_INFO 3 +#define DEBUGFS_NODE_MEMTRACK 4 +#define DEBUGFS_NODE_DVFS 5 +#define DEBUGFS_NODE_VIDSCH 6 +#define DEBUGFS_NODE_CG 7 +#define DEBUGFS_NODE_DEBUGBUS 8 +#define DEBUGFS_NODE_SWAP 9 + + +struct os_seq_file; + +typedef struct +{ + unsigned short vendor_id; + unsigned short device_id; + unsigned short command; + unsigned short status; + unsigned char revision_id; + unsigned char prog_if; + unsigned char sub_class; + unsigned char base_class; + unsigned char cache_line_size; + unsigned char latency_timer; + unsigned char header_type; + unsigned char bist; + unsigned short sub_sys_vendor_id; + unsigned short sub_sys_id; + unsigned short link_status; + /*force set to unsigned long long*/ + unsigned long long reg_start_addr[5]; + unsigned long long reg_end_addr[5]; + unsigned long long mem_start_addr[5]; + unsigned long long mem_end_addr[5]; + unsigned long long secure_start_addr[5]; + unsigned long long secure_end_addr[5]; + int secure_on; +} bus_config_t; + +typedef struct +{ + unsigned long totalram; //gf can used system pages num + unsigned long freeram; +}mem_info_t; + +#define GF_CPU_CACHE_UNKNOWN 0 +#define GF_CPU_CACHE_VIVT 1 +#define GF_CPU_CACHE_VIPT_ALIASING 2 +#define GF_CPU_CACHE_VIPT_NONALIASING 3 +#define GF_CPU_CACHE_PIPT 4 + +typedef struct +{ + unsigned int dcache_type; + unsigned int icache_type; + unsigned int iommu_support; + unsigned int page_size; + unsigned int page_shift; + unsigned int system_need_dma32; + unsigned int suspend_blt_mode; +}platform_caps_t; + + +/*****************************************************************************/ +typedef struct +{ + void *pdev; +}os_device_t; + +typedef int (*condition_func_t)(void *argu); + +enum gf_mem_type +{ + GF_SYSTEM_IO = 0x01, + GF_SYSTEM_RAM = 0x02, +}; + +enum gf_mem_space +{ + GF_MEM_KERNEL = 0x01, + GF_MEM_USER = 0x02, +}; + +enum gf_mem_attribute +{ + GF_MEM_WRITE_BACK = 0x01, + GF_MEM_WRITE_THROUGH = 0x02, + GF_MEM_WRITE_COMBINED = 0x03, + GF_MEM_UNCACHED = 0x04, +}; + +typedef struct +{ + unsigned int dma32 :1; + unsigned int need_flush :1; + unsigned int need_zero :1; + unsigned int fixed_page :1; /*fixed page size*/ + unsigned int page_4K_64K :1; /*page can allocate 64k*4k, perfer 64k*/ + unsigned int need_dma_map:1; + + int page_size; /*page size when fixed page flags set*/ +}alloc_pages_flags_t; + +typedef struct +{ + union + { + struct + { + unsigned char mem_type; + unsigned char mem_space; + unsigned char cache_type; + unsigned char read_only :1; + unsigned char write_only :1; + }; + unsigned int value; + }; +}gf_map_flags_t; + +typedef struct +{ + gf_map_flags_t flags; + union + { + struct os_pages_memory *memory; + unsigned long long phys_addr; + }; + unsigned int offset; + unsigned long size; +}gf_map_argu_t; + +typedef struct __gf_vm_area +{ + gf_map_flags_t flags; + unsigned int ref_cnt; + unsigned int size; + unsigned long owner; + unsigned int need_flush_cache; + void *virt_addr; + struct __gf_vm_area *next; +}gf_vm_area_t; + +#define GF_LOCKED 0 +#define GF_LOCK_FAILED 1 + +typedef enum +{ + GF_EVENT_UNKNOWN = 0, + GF_EVENT_BACK = 1, /* condtion meet event back */ + GF_EVENT_TIMEOUT = 2, /* wait timeout */ + GF_EVENT_SIGNAL = 3, /* wait interrupt by a signal */ +}gf_event_status_t; + + +typedef enum +{ + WAIT_EVENT0 = 0, + WAIT_EVENT1 = 1, + WAIT_EVENT2 = 2, + WAIT_EVENT3 = 3, + WAIT_EVENT_MAX = 4, +}wakeup_event; + +typedef struct +{ + gf_event_status_t status; + wakeup_event event; +}event_wait_status; + +struct general_wait_event +{ + int need_queue; + unsigned int event; + struct os_spinlock* event_lock; +}; + +typedef int (*util_event_handler_u)(void *data, event_wait_status state); + +typedef int (*gf_thread_func_t)(void *data); + + +typedef struct gf_drm_callback +{ + struct { + void* (*create)(void *argu, unsigned int engine_index, unsigned long long initialize_value); + void (*attach_buffer)(void *argu, void *buffer, void *fence, int readonly); + void (*update_value)(void *argu, void *fence, unsigned long long value); + void (*release)(void *argu, void *fence); + void (*notify_event)(void *argu); + + void* (*dma_sync_object_create)(void *driver, void *bo, int write, int engine, void (*callback)(void*), void* arg); + long (*dma_sync_object_wait)(void *driver, void *sync_obj, unsigned long long timeout); + void (*dma_sync_object_release)(void *sync_obj); + int (*dma_sync_object_is_signaled)(void *sync_obj); + void (*dma_sync_object_dump)(void *sync_obj); + } fence; + + struct { + unsigned int (*get_from_handle)(void *file, unsigned int handle); + } gem; +} gf_drm_callback_t; + +struct os_printer; +typedef struct +{ + void (*udelay)(unsigned long long usecs_num); + unsigned long long (*do_div)(unsigned long long x, unsigned long long y); + void (*msleep)(int num); + void (*getsecs)(long *secs, long *usecs); + void (*get_nsecs)(unsigned long long *nsecs); + void (*assert)(int match, const char *msg); + void (*dump_stack)(void); + int (*copy_from_user)(void* to, const void* from, unsigned long size); + int (*copy_to_user)(void* to, const void* from, unsigned long size); + void* (*memset)(void* s, int c, unsigned long count); + void* (*memcpy)(void* d, const void* s, unsigned long count); + int (*memcmp_priv)(const void *s1, const void *s2, unsigned long count); + void (*byte_copy)(char* dst, char* src, int len); + int (*strcmp)(const char *s1, const char *s2); + char* (*strcpy)(char *d, const char *s); + int (*strncmp)(const char *s1, const char *s2, unsigned long count); + char* (*strncpy)(char *d, const char *s, unsigned long count); + unsigned long (*strlen)(char *s); + +/****************************** IO access functions*********************************/ + unsigned long long (*read64)(void* addr); + unsigned int (*read32)(void* addr); + unsigned short (*read16)(void* addr); + unsigned char (*read8)(void* addr); + + void (*write32)(void* addr, unsigned int val); + void (*write16)(void* addr, unsigned short val); + void (*write8)(void* addr, unsigned char val); + + struct os_file* (*file_open)(const char *path, int flags, unsigned short mode); + void (*file_close)(struct os_file *file); + int (*file_read)(struct os_file *file, void *buf, unsigned long size, unsigned long long *read_pos); + int (*file_write)(struct os_file *file, void *buf, unsigned long size); + +/*****************************************************************************/ + int (*vsprintf)(char *buf, const char *fmt, ...); + int (*vsnprintf)(char *buf, unsigned long size, const char *fmt, ...); + int (*sscanf)(char *buf, char *fmt, ...); + void (*printk)(unsigned int msglevel, const char* fmt, ...); + void (*cb_printk)(const char* msg); + + int (*seq_printf)(struct os_seq_file* file, const char *f, ...); + + void (*os_printf)(struct os_printer *p, const char *f, ...); + + void* (*malloc_priv)(unsigned long size); + void* (*calloc_priv)(unsigned long size); + void (*free_priv)(void* addr); + + void* (*malloc_track)(unsigned long size, const char *file, unsigned int line); + void* (*calloc_track)(unsigned long size, const char *file, unsigned int line); + void (*free_track)(void* addr, const char *file, unsigned int line); + +/* bit ops */ + int (*find_first_zero_bit)(void *buf, unsigned int size); + int (*find_next_zero_bit)(void *buf, unsigned int size, int offset); + void (*set_bit)(unsigned int nr, void *buf); + void (*clear_bit)(unsigned int nr, void *buf); + + struct os_atomic* (*create_atomic)(int val); + void (*destroy_atomic)(struct os_atomic *atomic); + int (*atomic_read)(struct os_atomic *atomic); + void (*atomic_inc)(struct os_atomic *atomic); + void (*atomic_dec)(struct os_atomic *atomic); + int (*atomic_add)(struct os_atomic *atomic, int v); + int (*atomic_sub)(struct os_atomic *atomic, int v); + + struct os_mutex* (*create_mutex)(void); + void (*destroy_mutex)(struct os_mutex *mutex); + void (*mutex_lock)(struct os_mutex *mutex); + int (*mutex_lock_killable)(struct os_mutex *mutex); + int (*mutex_trylock)(struct os_mutex *mutex); + void (*mutex_unlock)(struct os_mutex *mutex); + + struct os_sema* (*create_sema)(int val); + void (*destroy_sema)(struct os_sema *sem); + void (*down)(struct os_sema *sem); + int (*down_trylock)(struct os_sema *sem); + void (*up)(struct os_sema *sem); + + struct os_rwsema *(*create_rwsema)(void); + void (*destroy_rwsema)(struct os_rwsema *sem); + void (*down_read)(struct os_rwsema *sem); + void (*down_write)(struct os_rwsema *sem); + void (*up_read)(struct os_rwsema *sem); + void (*up_write)(struct os_rwsema *sem); + + struct os_spinlock* (*create_spinlock)(int type); + void (*destroy_spinlock)(struct os_spinlock *spin); + void (*spin_lock)(struct os_spinlock *spin); + int (*spin_try_lock)(struct os_spinlock *spin); + void (*spin_unlock)(struct os_spinlock *spin); + unsigned long (*spin_lock_irqsave)(struct os_spinlock *spin); + void (*spin_unlock_irqrestore)(struct os_spinlock *spin, unsigned long flags); + + struct os_wait_event* (*create_event)(int task_id); + void (*destroy_event)(void *event); + gf_event_status_t (*wait_event_thread_safe)(struct os_wait_event *event, condition_func_t condition, void *argu, int msec); + gf_event_status_t (*wait_event)(struct os_wait_event *event, int msec); + void (*wake_up_event)(struct os_wait_event *event); + + void* (*create_thread)(gf_thread_func_t func, void *data, const char *thread_name); + void (*destroy_thread)(void* thread); + int (*thread_should_stop)(void); + struct os_wait_queue* (*create_wait_queue)(void); + + gf_event_status_t (*thread_wait)(struct os_wait_event *event, int msec); + void (*thread_wake_up)(struct os_wait_event *event); + + int (*try_to_freeze)(void); + int (*freezable)(void); + void (*clear_freezable)(void); + + void (*set_freezable)(void); + int (*freezing)(void); + unsigned long (*get_current_pid)(void); + unsigned long (*get_current_tid)(void); + void (*get_current_pname)(char *, int); + + void (*flush_cache)(void *pdev, gf_vm_area_t *vma, struct os_pages_memory* memory, unsigned int offset, unsigned int size); + void (*inv_cache)(void *pdev, gf_vm_area_t *vma, struct os_pages_memory* memory, unsigned int offset, unsigned int size); + struct os_pages_memory* (*allocate_pages_memory_priv)(void *pdev, int size, int page_size, alloc_pages_flags_t alloc_flags); + void (*free_pages_memory_priv)(void *pdev, struct os_pages_memory *memory); + + struct os_pages_memory* (*allocate_pages_memory_track)(void *pdev, int size, int page_size, alloc_pages_flags_t alloc_flags, const char *file, unsigned int line); + void (*free_pages_memory_track)(void *pdev, struct os_pages_memory *memory, const char *file, unsigned int line); + void (*pages_memory_for_each_continues)(struct os_pages_memory *memory, void *arg, + int (*cb)(void *arg, int page_start, int page_cnt, unsigned long long dma_addr)); + + gf_vm_area_t *(*map_pages_memory_priv)(void *filp, gf_map_argu_t *map_argu); + void (*unmap_pages_memory_priv)(gf_vm_area_t *vm_area); + gf_vm_area_t *(*map_io_memory_priv)(void *filp, gf_map_argu_t *map_argu); + void (*unmap_io_memory_priv)(gf_vm_area_t *vm_area); + gf_vm_area_t *(*map_pages_memory_track)(void *filp, gf_map_argu_t *map_argu, const char *file, unsigned int line); + void (*unmap_pages_memory_track)(gf_vm_area_t *vm_area, const char *file, unsigned int line); + gf_vm_area_t *(*map_io_memory_track)(void *filp, gf_map_argu_t *map_argu, const char *file, unsigned int line); + void (*unmap_io_memory_track)(gf_vm_area_t *vm_area, const char *file, unsigned int line); + void* (*ioremap)(unsigned int io_base, unsigned int size); + void (*iounmap_priv)(void *map_address); + + int (*mtrr_add)(unsigned long start, unsigned long size); + int (*mtrr_del)(int reg, unsigned long base, unsigned long size); + + int (*get_mem_info)(mem_info_t *mem); + + int (*is_own_pages)(struct os_pages_memory *pages_memory); + void* (*pages_memory_swapout)(struct os_pages_memory *pages_memory); + int (*pages_memory_swapin)(struct os_pages_memory *pages_memory, void *file); + void (*release_file_storage)(void *file); + + void (*get_bus_config)(void *dev, bus_config_t *bus); + int (*get_platform_config)(void *dev, const char* config_name, int *buffer, int length); + + void (*register_trace_events)(void); + void (*unregister_trace_events)(void); + void (*task_create_trace_event)(int engine_index, unsigned int context, + unsigned long long task_id, unsigned int task_type); + void (*task_submit_trace_event)(int engine_index, unsigned int context, + unsigned long long task_id, unsigned int task_type, + unsigned long long fence_id, unsigned int args); + void (*fence_back_trace_event)(int engine_index, unsigned long long fence_id); + void (*begin_section_trace_event)(const char* desc); + void (*end_section_trace_event)(int result); + void (*counter_trace_event)(const char* desc, unsigned long long value); + + int (*query_platform_caps)(void *pdev, platform_caps_t *caps); + + void (*enable_interrupt)(void *pdev); + void (*disable_interrupt)(void *pdev); + void (*console_lock)(int); + int (*disp_wait_idle)(void *disp_info); + + /* barrier */ + void (*mb)(void); + void (*rmb)(void); + void (*wmb)(void); + void (*flush_wc)(void); + void (*dsb)(void); + +#ifdef VMI_MODE + void (*set_pages_addr)(struct os_pages_memory *mem, unsigned long long addr); +#endif +}krnl_import_func_list_t; + + +#define GF_DRV_DEBUG 0x00 +#define GF_DRV_WARNING 0x01 +#define GF_DRV_INFO 0x02 +#define GF_DRV_ERROR 0x03 +#define GF_DRV_EMERG 0x04 + +#endif /*__KERNEL_IMPORT_H__*/ + diff --git a/drivers/gpu/drm/arise/core/include/kernel_interface.h b/drivers/gpu/drm/arise/core/include/kernel_interface.h new file mode 100644 index 0000000000000..e0b4da82336c8 --- /dev/null +++ b/drivers/gpu/drm/arise/core/include/kernel_interface.h @@ -0,0 +1,171 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __KERNEL_INTERFACE_H__ +#define __KERNEL_INTERFACE_H__ + +#include "gf_def.h" +#include "gf_types.h" +#include "core_errno.h" +#include "kernel_import.h" + +typedef struct +{ + struct gpu_device *device; + struct gpu_context *context; + gf_cil2_misc_t *gf_misc; +} krnl_cil2_misc_t; + +struct krnl_adapter_init_info_s +{ + int minor_index; +/* init control parmetes */ + int gf_pwm_mode ;/* control pwm of gf */ + int gf_dfs_mode ;/* control dvfs of gf */ + int gf_worker_thread_enable;/* control worker thread on/off */ + int gf_recovery_enable ; /* enable recovery when hw hang */ + int gf_hang_dump;/*0-disable, 1-pre hang, 2-post hang, 3-duplicate hang */ + int gf_run_on_qt; /* control wether run on QT */ + int gf_flag_buffer_verify ;/*0 - disable, 1 - enable */ + int gf_vesa_tempbuffer_enable ; /* control wether reserve memory during boot */ + + int miu_channel_size;//0/1/2 for 256B/512B/1kb Swizzle + int gf_backdoor_enable; + //gpc/slice setting + unsigned int chip_slice_mask;//// CHIP_SLICE_MASK own 12 bits(should be set 0x001 ~ 0xfff), driver use this to set the Slice_Mask which HW used. + + int gf_local_size_g; + int gf_local_size_m; + int gf_pcie_size_g; + int gf_pcie_size_m; + int debugfs_mask; +}; +typedef struct krnl_adapter_init_info_s krnl_adapter_init_info_t; + +typedef struct +{ + struct //get from adapter + { + unsigned int ven_dev; + unsigned int family_id; + unsigned int generic_id; + unsigned int chip_id; + unsigned char* mmio; + unsigned int mmio_size; + unsigned int primary; + unsigned long long fb_bus_addr; + unsigned int fb_total_size; + unsigned int patch_fence_intr_lost:1; + unsigned int init_render:1; + union + { + unsigned int adp_flags; + struct + { + unsigned int run_on_qt:1; + unsigned int Reserved:31; + }; + }; + }; + struct //set to adapter + { + unsigned int low_top_addr; + unsigned int snoop_only; + unsigned int chan_num; + unsigned int avai_mem_size_mb; //in Mega Bytes + unsigned int total_mem_size_mb; //in Mega Bytes + unsigned int chip_slice_mask; + unsigned int hdaudio_to_local; + unsigned int non_simul_chip; + }; +}adapter_info_t; + +/* +** misc things +*/ +#define OS_CALLBACK_POST_EVENT 1 +#define OS_CALLBACK_POST_SYNCOBJ_EVENT 2 +#define OS_CALLBACK_DRM_CB 3 + +typedef struct +{ + void* (*pre_init_adapter)(void *pdev, krnl_adapter_init_info_t *info, krnl_import_func_list_t *import); + void (*init_adapter)(void *adp, int reserved_vmem, void *disp_info); + void (*deinit_adapter)(void *data); + void (*get_adapter_info)(void* adp, adapter_info_t* adapter_info); + void (*update_adapter_info)(void* adp, adapter_info_t* adapter_info, krnl_adapter_init_info_t* a_info); + void (*dump_resource)(struct os_printer *p, void *data, int index, int iga_index); + void (*debugfs_dump)(struct os_seq_file *seq_file, void *data, int type, void* arg); + void (*final_cleanup)(void *data, unsigned int gpu_device); + void (*wait_chip_idle)(void *adapter); + void (*wait_allocation_idle)(void *data, gf_wait_allocation_idle_t *wait_allocation); + int (*get_allocation_state)(void *data, gf_get_allocation_state_t *state); + int (*save_state)(void *adapter, int need_save_memory); + int (*restore_state)(void *adapter); + void (*get_map_allocation_info)(void *data, unsigned int hAllocation, gf_map_argu_t *map); + + int (*query_info)(void* data, gf_query_info_t *info); + int (*create_device)(void *data, void *filp, unsigned int *hDevice); + void (*update_device_name)(void *data, unsigned int device); + void (*destroy_device)(void *data, unsigned int hDevice); + int (*create_allocation)(void *data, gf_create_allocation_t *create_data, void *bo); + int (*create_allocation_list)(void *data, gf_create_resource_t *create_data, void **bos); + int (*create_allocation_from_pages)(void *data, gf_create_allocation_t *create_data, struct os_pages_memory *pages, void *bo); + void (*destroy_allocation)(void *data, gf_destroy_allocation_t *destroy_data); + void (*prepare_and_mark_unpagable)(void *data, unsigned int handle, gf_open_allocation_t *info); + void (*mark_pagable)(void *data, unsigned int handle); + int (*set_callback_func)(void *data, int type, void *func, void *argu); + int (*begin_perf_event)(void *data, gf_begin_perf_event_t *begin_perf_event); + int (*end_perf_event)(void *data, gf_end_perf_event_t *end_perf_event); + int (*get_perf_event)(void *data, gf_get_perf_event_t *get_event); + int (*send_perf_event)(void *data, gf_perf_event_t *perf_event); + int (*get_perf_status)(void *data, gf_perf_status_t *perf_status); + int (*begin_miu_dump_perf_event)(void *data, gf_begin_miu_dump_perf_event_t *begin_miu_perf_event); + int (*end_miu_dump_perf_event)(void *data, gf_end_miu_dump_perf_event_t *end_miu_perf_event); + int (*set_miu_reg_list_perf_event)(void *data, gf_miu_reg_list_perf_event_t *miu_reg_list); + int (*get_miu_dump_perf_event)(void *data, gf_get_miu_dump_perf_event_t *get_miu_dump); + int (*direct_get_miu_dump_perf_event)(void *data, gf_direct_get_miu_dump_perf_event_t *direct_get_miu); + int (*create_context)(void *data, gf_create_context_t *create_context, enum gf_mem_space mem_space); + int (*destroy_context)(void *data, gf_destroy_context_t *destroy_context); + int (*render)(void *data, gf_render_t *render); + int (*create_di_context)(void *data, gf_create_di_context_t *create); + int (*destroy_di_context)(void *data, gf_destroy_di_context_t *destroy); + int (*create_fence_sync_object)(void *data, gf_create_fence_sync_object_t *gf_create, int binding); + int (*destroy_fence_sync_object)(void *data, gf_destroy_fence_sync_object_t *gf_destroy); + int (*wait_fence_sync_object)(void *data, gf_wait_fence_sync_object_t *gf_wait); + int (*fence_value)(void *data, gf_fence_value_t *gf_value); + int (*is_fence_object_signaled)(void *data, unsigned int fence_sync_object, unsigned long long wait_value); + int (*is_fence_back)(void *data, unsigned char engine_index, unsigned long long fence_id); + int (*add_hw_ctx_buf)(void *data, gf_add_hw_ctx_buf_t *add); + int (*rm_hw_ctx_buf)(void *data, gf_rm_hw_ctx_buf_t *rm); + int (*cil2_misc)(void *data, gf_cil2_misc_t *misc); + struct os_pages_memory* (*get_allocation_pages)(void *data, int handle); + + int (*notify_interrupt)(void *data, unsigned int interrupt_event); + void (*perf_event_add_isr_event)(void *data, gf_perf_event_t *perf_event); + void (*perf_event_add_event)(void *data, gf_perf_event_t *perf_event); + + void (*dump_hang_info_flag)(void *data, int flag); + void (*ctl_flags_set)(void *data,unsigned int num,unsigned int mask,unsigned int value); + int (*hwq_process_vsync_event)(void *data, unsigned long long time); + void (*task_timeout_update)(void* data, unsigned long long *value, int update); + void (*reset_dvfs_power_flag)(void* data); +} core_interface_t; + +extern core_interface_t *gf_core_interface; + +#endif + + + diff --git a/drivers/gpu/drm/arise/core/kernel_interface.c b/drivers/gpu/drm/arise/core/kernel_interface.c new file mode 100644 index 0000000000000..24fe055c47b01 --- /dev/null +++ b/drivers/gpu/drm/arise/core/kernel_interface.c @@ -0,0 +1,1387 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "kernel_interface.h" +#include "gf_adapter.h" +#include "context.h" +#include "global.h" +#include "powermgr.h" +#include "vidmm.h" +#include "vidsch.h" +#include "perfevent.h" + +krnl_import_func_list_t *gf = NULL; + +static int krnl_create_device(void *data, void *filp, unsigned int *hDevice); +static int krnl_create_context(void *data, gf_create_context_t *create_context, enum gf_mem_space mem_space); +static void krnl_destroy_device(void *data, unsigned int hDevice); + +static int krnl_cil2_misc(void *data, gf_cil2_misc_t* gf_misc) +{ + adapter_t *adapter = data; + krnl_cil2_misc_t misc; + + misc.gf_misc = gf_misc; + misc.context = get_from_handle(&adapter->hdl_mgr, gf_misc->context); + misc.device = get_from_handle(&adapter->hdl_mgr, gf_misc->device); + + return vidsch_cil2_misc(misc.device, &misc); +} + +static void* krnl_pre_init_adapter(void *pdev, krnl_adapter_init_info_t *info, krnl_import_func_list_t *import) +{ + adapter_t *adapter = NULL; + platform_caps_t caps = {0}; + + gf = import; + + util_init_log(); + + adapter = gf_calloc(sizeof(adapter_t)); + + if(adapter == NULL) + { + gf_error("allocate adapter fail!\n"); + + return NULL; + } + + adapter->paging_lock = gf_create_mutex(); + adapter->device_list_lock = gf_create_mutex(); + adapter->gart_table_lock = gf_create_mutex(); + adapter->lock = gf_create_spinlock(0); + + adapter->vcp_index_cnt[VCP0_INDEX] = 0; + adapter->vcp_index_cnt[VCP1_INDEX] = 0; + adapter->start_index = MIN_VIDEO_SEQ_INDEX; + adapter->end_index = MAX_VIDEO_SEQ_INDEX_ADD1; + gf_memset((void*)(adapter->bVideoSeqIndex), 0, sizeof(adapter->bVideoSeqIndex)); + + list_init_head(&adapter->device_list); + list_init_head(&adapter->sync_obj_list); + + adapter->index = info->minor_index; + adapter->os_device.pdev = pdev; + + adapter->ctl_flags.worker_thread_enable = TRUE; + adapter->ctl_flags.split_enable = TRUE; + adapter->hw_caps.fence_interrupt_enable = TRUE; + adapter->ctl_flags.recovery_enable = FALSE; + adapter->ctl_flags.dump_hang_info_to_file = FALSE; + adapter->ctl_flags.swap_enable = FALSE; + adapter->ctl_flags.perf_event_enable = FALSE; + adapter->ctl_flags.hwq_event_enable = FALSE; + adapter->ctl_flags.local_for_display_only = TRUE; + + gf_query_platform_caps(pdev, &caps); + + adapter->sys_caps.iommu_enabled = caps.iommu_support; + adapter->hw_caps.address_mode_64bit = !caps.system_need_dma32; + adapter->os_page_size = caps.page_size; + adapter->os_page_shift = caps.page_shift; + adapter->suspend_blt_mode = caps.suspend_blt_mode; + + glb_get_pci_config_info(adapter); + + glb_init_chip_id(adapter,info); + + handle_mgr_create(&adapter->hdl_mgr); + + return adapter; +} + +static void krnl_init_adapter(void* adp, int reserved_vmem, void *disp_info) +{ + adapter_t * adapter = (adapter_t*)adp; + + adapter->disp_info = disp_info; + + vidmm_init(adapter, reserved_vmem); + + vidsch_create(adapter); + + cm_create_di_mgr(adapter); + + gf_register_trace_events(); + + perf_event_init(adapter); + + gf_hwq_event_init(adapter); + + gf_info("adapter->ctl_flags.worker_thread_enable %x\n", adapter->ctl_flags.worker_thread_enable); + + gf_info("sys caps: os page size :0x%x, os page shift:0x%x, iommu_support:%x\n", + adapter->os_page_size, adapter->os_page_shift, + adapter->sys_caps.iommu_enabled); + + gf_info("hw cfg: chip slice mask :%x, miu channel index:%x, miu channel size index:%x, backdoor:%d\n", + adapter->hw_caps.chip_slice_mask, adapter->hw_caps.miu_channel_num, + adapter->hw_caps.miu_channel_size, adapter->hw_caps.gf_backdoor_enable); + + gf_info("hw caps: secure:%d, snoop:%d, 4K_page:%d, 64K_page:%d, Paging:%d, CG:%d, DFS:%d\n", + adapter->hw_caps.secure_range_enable, adapter->hw_caps.support_snooping, adapter->hw_caps.page_4k_enable, + adapter->hw_caps.page_64k_enable, adapter->ctl_flags.paging_enable, + adapter->pwm_level.EnableClockGating, adapter->hw_caps.dfs_enable); + + gf_info("power caps: ClockGating:%d, PowerGating:%d\n", + adapter->pwm_level.EnableClockGating, adapter->pwm_level.EnablePowerGating); + + gf_info("Ctrl: Recovery:%d, WK-thread:%d, Hang-Dump:%d, RunOnQT:%d, PwmMode:0x%x, NonsnoopEnable:%d\n", + adapter->ctl_flags.recovery_enable, adapter->ctl_flags.worker_thread_enable, + adapter->ctl_flags.hang_dump, adapter->ctl_flags.run_on_qt, adapter->pm_caps.pwm_mode, adapter->hw_caps.snoop_only ? 0 : 1); + +} + +static void krnl_deinit_adapter(void *data) +{ + adapter_t *adapter = data; + + perf_event_deinit(adapter); + gf_hwq_event_deinit(adapter); + gf_unregister_trace_events(); + + cm_destroy_remained_device(adapter); + + vidsch_destroy(adapter); + + vidmm_destroy(adapter); + + cm_destroy_di_mgr(adapter); + + handle_mgr_destroy(&adapter->hdl_mgr); + + gf_destroy_mutex(adapter->gart_table_lock); + + gf_destroy_mutex(adapter->paging_lock); + + gf_destroy_mutex(adapter->device_list_lock); + + gf_destroy_spinlock(adapter->lock); + + glb_fini_bus_config(adapter); + + gf_free(adapter); +} + + +static void krnl_get_adapter_info(void* adp, adapter_info_t* adapter_info) +{ + adapter_t *adapter = (adapter_t *)adp; + if(adapter && adapter_info) + { + adapter_info->ven_dev = (((unsigned int)adapter->bus_config.vendor_id) << 16 ) + adapter->bus_config.device_id; + adapter_info->family_id = adapter->family_id; + adapter_info->generic_id = adapter->generic_id; + adapter_info->chip_id = adapter->chip_id; + adapter_info->mmio = adapter->mmio; + adapter_info->mmio_size = adapter->mmio_vma->size; + adapter_info->primary = adapter->primary; + adapter_info->fb_bus_addr = adapter->vidmm_bus_addr; + adapter_info->fb_total_size = adapter->Visible_vram_size; + adapter_info->run_on_qt = adapter->ctl_flags.run_on_qt; + adapter_info->patch_fence_intr_lost = (adapter->hw_patch_mask0 & PATCH_FENCE_INTERRUPT_LOST) ? 1 : 0; + } +} + +static void krnl_update_adapter_info(void* adp, adapter_info_t* adapter_info, krnl_adapter_init_info_t* a_info) +{ + adapter_t *adapter = (adapter_t *)adp; + if(adapter && adapter_info) + { + adapter->hw_caps.snoop_only = (adapter_info->snoop_only)? 1 : 0; + adapter->low_top_address = adapter_info->low_top_addr; + adapter->hw_caps.miu_channel_num = adapter_info->chan_num; + adapter->hw_caps.chip_slice_mask = adapter_info->chip_slice_mask; + adapter->hw_caps.fb_hdaudio_enable = (adapter_info->hdaudio_to_local)? 1 : 0; + adapter->hw_caps.non_simul_chip = (adapter_info->non_simul_chip)? 1 : 0; + + //use default memory size + if(adapter->Real_vram_size == 0) + { + adapter->Real_vram_size = adapter_info->total_mem_size_mb; + adapter->Real_vram_size <<= 20; + gf_info("use total_mem_size_mb as local memory\n"); + } + else if((adapter->Real_vram_size>>20) > adapter_info->total_mem_size_mb) + { + gf_info("use gf_local_size as local memory, Real_vram_size:%lldM, total_mem_size_mb:%lldM\n", (adapter->Real_vram_size>>20), adapter_info->total_mem_size_mb); + gf_warning("set local memory out range actual memory size, force adjust actual memory"); + adapter->Real_vram_size = adapter_info->total_mem_size_mb; + adapter->Real_vram_size <<= 20; + } + else + { + gf_info("use params gf_local_size_g to set local memory, not total_mem_size_mb\n"); + } + + adapter->UnAval_vram_size = (adapter_info->total_mem_size_mb - adapter_info->avai_mem_size_mb); + adapter->UnAval_vram_size <<= 20; + gf_info("video memory size: %lldM.\n", adapter->Real_vram_size >> 20); + gf_info("video unav size: %lldM.\n", adapter->UnAval_vram_size >> 20); + + //slice mask setting from kmd module para, for debug use. + if(a_info->chip_slice_mask) + { + adapter->hw_caps.chip_slice_mask = a_info->chip_slice_mask; + } + //if hang dump , force set slice mask is 0x01 + if (adapter->ctl_flags.hang_dump) + { + adapter->hw_caps.chip_slice_mask = 0x01; + } + gf_info("krnl_update_adapter_info chip_slice_mask: 0x%x\n", adapter->hw_caps.chip_slice_mask); + } +} + +static void krnl_dump_resource(struct os_printer *p, void *data, int dump_index, int iga_index) +{ + adapter_t *adapter = data; + + switch(dump_index) + { + case 0: + util_print_log(); + break; + case 1: + vidmm_dump_resource(adapter); + break; + case 2: + break; + case 3: + vidsch_dump(p, adapter); + break; + case 4: + cm_dump_resource(adapter); + break; + case 5: + util_print_log(); + vidmm_dump_resource(adapter); + vidsch_dump(p,adapter); + cm_dump_resource(adapter); + break; + case 6: + adapter->display_debugbus_flag = !adapter->display_debugbus_flag; + gf_info("adapter->display_debugbus_flag = %d\n", adapter->display_debugbus_flag); + break; + case 7: + if (adapter->kickoff_error.error & 0x1) + { + gf_error("flush fifo issue index:%x\n", adapter->kickoff_error.RbIndex); + gf_error("write value: %x, read value: %x\n", adapter->kickoff_error.last_send_fence_id, + adapter->kickoff_error.flush_fifo_buffer_value); + adapter->kickoff_error.error &= ~0x1; + } + + if (adapter->kickoff_error.error & 0x2) + { + gf_error("idx:%d, kick off:%x, read:%x\n", adapter->kickoff_error.RbIndex, + adapter->kickoff_error.tail, adapter->kickoff_error.offset); + adapter->kickoff_error.error &= ~0x2; + } + break; + case 0x7000: + vidsch_force_wakup(adapter); + break; + default: + break; + } +} + +static void krnl_debugfs_dump(struct os_seq_file *seq_file, void *data, int type, void* arg) +{ + adapter_t *adapter = data; + switch(type) + { + case DEBUGFS_NODE_DEVICE: + { + unsigned int handle = *((unsigned int*)arg); + + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, handle); + + if(device != NULL) + { + cm_dump_device_alloctions(seq_file, adapter, device); + } + break; + } + + case DEBUGFS_NODE_HEAP: + { + int id = *((int*)arg); + + vidmm_dump_heap(seq_file, adapter, id); + break; + } + case DEBUGFS_NODE_INFO: + vidsch_dump_info(seq_file, adapter); + break; + + case DEBUGFS_NODE_MEMTRACK: + { + int pid = *((int *)arg); + vidmm_dump_memtrack(seq_file, adapter, pid); + break; + } + + case DEBUGFS_NODE_VIDSCH: + { + struct os_printer *p = (struct os_printer *) arg; + vidsch_dump(p, adapter); + break; + } + + case DEBUGFS_NODE_DEBUGBUS: + { + struct os_printer *p = (struct os_printer *) arg; + vidsch_dump_debugbus(p, adapter); + break; + } + default: + break; + } +} + + +static int krnl_create_device(void *data, void *filp, unsigned int *hDevice) +{ + adapter_t *adapter = data; + gpu_device_t *device; + + int status = E_INVALIDARG; + + device = cm_create_device(adapter, filp); + + if((device != NULL) && (hDevice != NULL)) + { + *hDevice = device->handle; + gf_memset((void*)(device->video_core_index_cnt), 0, sizeof(device->video_core_index_cnt)); + gf_memset((void*)(device->video_seq_index), 0, sizeof(device->video_seq_index)); + status = S_OK; + } + + return status; +} + +static void krnl_destroy_device(void *data, unsigned int hDevice) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, hDevice); + int i, j; + if(device != NULL) + { + if(device->video_core_index_cnt[VCP0_INDEX]) + adapter->vcp_index_cnt[VCP0_INDEX] -= device->video_core_index_cnt[VCP0_INDEX]; + if(device->video_core_index_cnt[VCP1_INDEX]) + adapter->vcp_index_cnt[VCP1_INDEX] -= device->video_core_index_cnt[VCP1_INDEX]; + + for(i = 0; i < 16; i++) + { + if(device->video_seq_index[i] == 0) + continue; + + for (j = 0; j < 8; j++) + { + if((device->video_seq_index[i] & (0x1 << j)) != 0) + adapter->bVideoSeqIndex[i * 8 + j] = 0; + } + device->video_seq_index[i] = 0; + } + cm_destroy_device(adapter, device); + } + else + { + gf_error("%s: invalid device handle %x.\n", __func__, hDevice); + } + +} + +static void krnl_final_cleanup(void *data, unsigned int gpu_device) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, gpu_device); + int i, j; + if(device != NULL) + { + if(device->video_core_index_cnt[VCP0_INDEX]) + adapter->vcp_index_cnt[VCP0_INDEX] -= device->video_core_index_cnt[VCP0_INDEX]; + if(device->video_core_index_cnt[VCP1_INDEX]) + adapter->vcp_index_cnt[VCP1_INDEX] -= device->video_core_index_cnt[VCP1_INDEX]; + + for(i = 0; i < 16; i++) + { + if(device->video_seq_index[i] == 0) + continue; + + for (j = 0; j < 8; j++) + { + if((device->video_seq_index[i] & (0x1 << j)) != 0) + adapter->bVideoSeqIndex[i * 8 + j] = 0; + } + device->video_seq_index[i] = 0; + } + } + cm_destroy_device(adapter, device); +} + +static void krnl_wait_chip_idle(void *data) +{ + adapter_t *adapter = data; + + vidsch_wait_chip_idle(adapter, ALL_ENGINE_MASK); +} + +static int krnl_create_allocation(void *data, gf_create_allocation_t *create_data, void *bo) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, create_data->device); + vidmm_create_allocation_arg_t create = {0}; + vidmm_rename_create_t rename_create = {0,}; + vidmm_gf_create_t gf_create = {0, }; + int result = S_OK; + + if(device == NULL) + { + gf_error("%s: invalid device handle %x.\n", __func__, create_data->device); + + result = E_INVALIDARG; + + return result; + } + + if (create_data->reference) + { + vidmm_allocation_t *reference = get_from_handle(&adapter->hdl_mgr, create_data->reference); + + rename_create.reference = reference; + create.allocation_count = 1; + create.create_type = VIDMM_CREATE_TYPE_RENAME; + create.rename_list = &rename_create; + } + else + { + gf_create.create_data = create_data; + create.allocation_count = 1; + create.create_type = VIDMM_CREATE_TYPE_GF; + create.create_list = &gf_create; + } + + create.bos = &bo; + + result = vidmm_create_allocation(device, &create); + + if (create.create_type == VIDMM_CREATE_TYPE_RENAME) + { + create_data->size = rename_create.Size; + create_data->allocation = rename_create.hAllocation; + } + + return result; +} + +static int krnl_create_allocation_from_pages(void *data, gf_create_allocation_t *create_data, struct os_pages_memory *pages, void *bo) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, create_data->device); + vidmm_create_allocation_arg_t create = {0}; + vidmm_gf_create_t gf_create = {0, }; + int result = S_OK; + + if(device == NULL) + { + gf_error("%s: invalid device handle %x.\n", __func__, create_data->device); + + result = E_INVALIDARG; + + return result; + } + + gf_create.create_data = create_data; + gf_create.import_pages_mem = pages; + + create.create_type = VIDMM_CREATE_TYPE_GF; + create.allocation_count = 1; + create.create_list = &gf_create; + create.bos = &bo; + + result = vidmm_create_allocation(device, &create); + + return result; +} + +static int krnl_create_allocation_list(void *data, gf_create_resource_t *create_data, void **bos) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, create_data->device); + vidmm_create_allocation_arg_t create = {0}; + + create.create_type = VIDMM_CREATE_TYPE_ESCAPE; + create.allocation_count = create_data->NumAllocations; + create.info_list = ptr64_to_ptr(create_data->pAllocationInfo); + create.bos = bos; + + return vidmm_create_allocation(device, &create); +} + +static void krnl_destroy_allocation(void *data, gf_destroy_allocation_t *destroy_data) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, destroy_data->device); + vidmm_allocation_t *allocation = get_from_handle(&adapter->hdl_mgr, destroy_data->allocation); + + vidmm_destroy_allocatin_arg_t destroy = {0}; + + if (device == NULL && allocation != NULL) + { + device = allocation->device; + } + + if(device == NULL) + { + gf_error("%s: invalid device handle %x.\n", __func__, destroy_data->device); + + return; + } + + if(allocation == NULL) + { + gf_error("%s: invalid allocation handle %x.\n", __func__, destroy_data->allocation); + + return; + } + + destroy.allocation_count = 1; + destroy.allocation_list = &allocation; + + vidmm_destroy_allocation(device, &destroy); +} + +static void krnl_get_map_allocation_info(void *data, unsigned int hAllocation, gf_map_argu_t *map) +{ + adapter_t *adapter = data; + vidmm_allocation_t *allocation = get_from_handle(&adapter->hdl_mgr, hAllocation); + + return vidmm_get_map_allocation_info(adapter, allocation, map); +} + +static void krnl_wait_allocation_idle(void *data, gf_wait_allocation_idle_t *wait_allocation) +{ + adapter_t *adapter = data; + vidmm_allocation_t *allocation = get_from_handle(&adapter->hdl_mgr, wait_allocation->hAllocation); + + gf_begin_section_trace_event("wait_allocation_idle"); + gf_counter_trace_event("arg_allocation", wait_allocation->hAllocation); + + vidsch_wait_allocation_idle(adapter, wait_allocation->engine_mask, 0, allocation); + + gf_end_section_trace_event(0); +} + +static int krnl_save_state(void *data, int need_save_memory) +{ + adapter_t *adapter = data; + return pm_save_state(adapter, need_save_memory); +} + +static int krnl_restore_state(void *data) +{ + adapter_t *adapter = data; + int result = S_OK; + + result = pm_restore_state(adapter); + + return result; +} + +static int krnl_query_info(void* data, gf_query_info_t *info) +{ + adapter_t *adapter = data; + int status = 0; + int search_num = 0; + gpu_device_t *device = NULL; + + switch (info->type) + { + case GF_QUERY_TOTAL_VRAM_SIZE: + case GF_QUERY_RESERV_VRAM_SIZE: + case GF_QUERY_CPU_VISIBLE_VRAM_SIZE: + case GF_QUERY_LOCAL_VRAM_TYPE: + case GF_QUERY_HEIGHT_ALIGN: + case GF_QUERY_SEGMENT_FREE_SIZE: + case GF_QUERY_SEGMENT_MEM_INFO: + case GF_QUERY_ALLOCATION_INFO: + case GF_QUERY_ALLOCATION_INFO_KMD: + case GF_QUERY_LOCAL_ALLOCATION_MAX_SIZE: + case GF_SET_PERF_SWAP_HINT: + case GF_GET_PERF_SWAP_HINT: + status = vidmm_query_info(adapter, info); + break; + case GF_QUERY_ENGINE_USAGE_STATUS: + { + gf_hwq_info hwq_info_info={0} ; + hwq_info_info.Usage_3D=adapter->usage_3d; + hwq_info_info.Usage_VCP=adapter->usage_vcp; + hwq_info_info.Usage_VPP=adapter->usage_vpp; + gf_copy_to_user(info->buf, &hwq_info_info, sizeof(gf_hwq_info)); + } + break; + case GF_QUERY_ENGINE_USAGE_STATUS_EXT: + { + gfx_hwq_info_ext tmp_hwq_info_ext={0} ; + hwq_get_hwq_info_ext(adapter,&tmp_hwq_info_ext); + gf_copy_to_user(info->buf, &tmp_hwq_info_ext, sizeof(gfx_hwq_info_ext)); + } + break; + case GF_QUERY_HW_HANG: + case GF_QUERY_PENDING_FRAME_NUM: + case GF_QUERY_GET_VIDEO_BRIDGE_BUFFER: + case GF_QUERY_GPU_TIME_STAMP: + case GF_SET_MIU_REGISTER_U32: + case GF_QUERY_MIU_REGISTER_U32: + case GF_QUERY_REGISTER_U32: + case GF_SET_REGISTER_U32: + case GF_QUERY_VCP_INDEX: + case GF_QUERY_PROCESS_INFO: + status = vidsch_query_info(adapter, info); + break; + + case GF_QUERY_PAGE_SWIZZLE_SUPPORT: + info->value = 0; + break; + + case GF_QUERY_CHIP_ID: + info->value = adapter->chip_id; + break; + + case GF_QUERY_VENDOR_ID: + info->value = adapter->bus_config.vendor_id; + break; + + case GF_QUERY_DEVICE_ID: + info->value = adapter->bus_config.device_id; + break; + + case GF_QUERY_REVISION_ID: + info->value = adapter->bus_config.revision_id; + break; + + case GF_QUERY_CHIP_SLICE_MASK: + info->value = adapter->hw_caps.chip_slice_mask; + break; + + case GF_QUERY_SECURED_ON: + info->value = adapter->sys_caps.secure_on; + break; + + case GF_QUERY_RET_VCP_INDEX: + if (info->value > VCP1_INDEX || info->value < VCP0_INDEX) + { + gf_error("unknown arg (%d) for GF_QUERY_RET_VCP_INDEX\n", info->argu); + status = -1; + } + else + { + adapter->vcp_index_cnt[info->value]--; + device = get_from_handle(&adapter->hdl_mgr, info->argu); + if(device) + device->video_core_index_cnt[info->value]--; + } + break; + + case GF_QUERY_VIDEO_SEQ_INDEX: + while(adapter->start_index < adapter->end_index) + { + if(adapter->bVideoSeqIndex[adapter->start_index] == 0) + { + info->value = adapter->start_index; + adapter->bVideoSeqIndex[adapter->start_index] = 1; + device = get_from_handle(&adapter->hdl_mgr, info->argu); + if(device) + { + device->video_seq_index[adapter->start_index / 8] |= 0x1 << (adapter->start_index % 8); + adapter->start_index = (adapter->start_index + 1) % MAX_VIDEO_SEQ_INDEX_ADD1; + } + status = 0; + break; + } + + adapter->start_index++; + if(adapter->start_index == adapter->end_index) + { + search_num++; + adapter->start_index = MIN_VIDEO_SEQ_INDEX; + } + + if(search_num == 2) + { + status = -1; + break; + } + } + break; + + case GF_QUERY_RET_VIDEO_SEQ_INDEX: + if(info->value >= MIN_VIDEO_SEQ_INDEX && (info->value < MAX_VIDEO_SEQ_INDEX_ADD1)) + { + adapter->bVideoSeqIndex[info->value] = 0; + device = get_from_handle(&adapter->hdl_mgr, info->argu); + if(device) + device->video_seq_index[info->value/8] &= ~(0x1 << (info->value % 8)); + } + break; + + case GF_QUERY_ADAPTER_INFO: + { + adapter_t *adapter = data; + gf_adapter_info_t adapter_info = {0}; + bus_config_t *bus_info = &adapter->bus_config; + + adapter_info.bus_config.DeviceID = bus_info->device_id; + adapter_info.bus_config.VendorID = bus_info->vendor_id; + adapter_info.bus_config.Command = bus_info->command; + adapter_info.bus_config.Status = bus_info->status; + adapter_info.bus_config.RevisionID = bus_info->revision_id; + adapter_info.bus_config.ProgIf = bus_info->prog_if; + adapter_info.bus_config.SubClass = bus_info->sub_class; + adapter_info.bus_config.BaseClass = bus_info->base_class; + adapter_info.bus_config.LatencyTimer= bus_info->latency_timer; + adapter_info.bus_config.HeaderType = bus_info->header_type; + adapter_info.bus_config.BIST = bus_info->bist; + adapter_info.bus_config.LinkStatus = bus_info->link_status; + + adapter_info.bus_config.ulBaseAddresses[0] = 0; + adapter_info.bus_config.ulBaseAddresses[1] = 0; + adapter_info.bus_config.ulBaseAddresses[2] = 0; + adapter_info.bus_config.ulBaseAddresses[3] = 0; + adapter_info.bus_config.ulBaseAddresses[4] = 0; + adapter_info.bus_config.ulBaseAddresses[5] = 0; + + adapter_info.bus_config.CacheLineSize = bus_info->cache_line_size; + adapter_info.bus_config.SubsystemVendorID = bus_info->sub_sys_vendor_id; + + adapter_info.bus_config.memorySize = adapter->Real_vram_size - adapter->UnAval_vram_size; + adapter_info.chipslicemask = adapter->hw_caps.chip_slice_mask; + adapter_info.gpucount = 1; + adapter_info.osversion = 0; + adapter_info.bVideoOnly = adapter->hw_caps.video_only; + adapter_info.bCTEDumpEnable = 0; + adapter_info.non_simul_chip = adapter->hw_caps.non_simul_chip; + + adapter_info.segmentMapTable[0] = 0; + adapter_info.segmentMapTable[1] = 1;//fb low + adapter_info.segmentMapTable[4] = 2;//non-snoop + adapter_info.segmentMapTable[3] = 3;//snoop + adapter_info.segmentMapTable[2] = 4;//fb high + + gf_copy_to_user(info->buf, &adapter_info, sizeof(gf_adapter_info_t)); + } + + break; + + case GF_QUERY_ACTIVE_ENGINE_COUNT: + info->value = adapter->active_engine_count; + break; + + case GF_QUERY_VCP_INFO: + { + int index = (info->argu << 16) >> 16; + int op = (info->argu >> 16); + + if(index < 0 || index >= VCP_INFO_COUNT) { + gf_error("invalid index-%d\n", index); + return -1; + } + + switch(op) { + case 0: + { + int i; + for(i=0; ivcp_info[i].enable == 0) { + gf_copy_from_user(&adapter->vcp_info[i], info->buf, sizeof(gf_vcp_info)); + adapter->vcp_info[i].enable = 1; + index = i; + break; + } + } + + break; + } + case 1: + adapter->vcp_info[index].enable = 0; + adapter->vcp_info[index].pid = 0; + break; + case 2: + gf_copy_to_user(info->buf, &adapter->vcp_info[index], sizeof(gf_vcp_info)); + break; + case 4: + { + int i; + for(i=0; ivcp_info[i].enable = 0; + adapter->vcp_info[i].pid = 0; + } + break; + } + case 3: + default: + gf_copy_from_user(&adapter->vcp_info[index], info->buf, sizeof(gf_vcp_info) - 2*sizeof(int));//don't overwrite last two parameter + break; + } + + info->argu = index; + } + break; + + case GF_QUERY_DIAGS: + { + status = vidmm_query_info(adapter, info); + info->diags.device_id = adapter->bus_config.device_id; + info->diags.vendor_id = adapter->bus_config.vendor_id; + info->diags.pci_link_speed = adapter->bus_config.link_status & 0xf; + info->diags.pci_link_width = (adapter->bus_config.link_status & 0x3f0) >> 4; + } + break; + default: + gf_assert(0, "unknown query type"); + status = -1; + break; + } + + return status; +} + +static int krnl_set_callback_func(void *data, int type, void *func, void *argu) +{ + adapter_t *adapter = data; + int status = S_OK; + + switch (type) + { + case OS_CALLBACK_POST_EVENT: + adapter->post_event_argu = argu; + adapter->post_event = func; + break; + case OS_CALLBACK_POST_SYNCOBJ_EVENT: + adapter->post_sync_event_argu = argu; + adapter->post_sync_event = func; + break; + case OS_CALLBACK_DRM_CB: + adapter->drm_cb = func; + adapter->drm_cb_argu = argu; + break; + default: + gf_error("unknown callback func type: %d.\n", type); + status = E_INVALIDARG; + break; + } + + return status; +} + +static int krnl_begin_perf_event(void *data, gf_begin_perf_event_t *begin_perf_event) +{ + adapter_t *adapter = data; + int result = 0; + + result = perf_event_begin(adapter, begin_perf_event); + + return result; +} + +static int krnl_begin_miu_dump_perf_event(void *data, gf_begin_miu_dump_perf_event_t *begin_miu_perf_event) +{ + adapter_t *adapter = data; + int result = 0; + + result = perf_event_begin_miu_dump(adapter, begin_miu_perf_event); + + return result; +} + +static int krnl_end_perf_event(void *data, gf_end_perf_event_t *end_perf_event) +{ + adapter_t *adapter = data; + int result = 0; + + result = perf_event_end(adapter, end_perf_event); + + return result; +} + +static int krnl_end_miu_dump_perf_event(void *data, gf_end_miu_dump_perf_event_t *end_miu_perf_event) +{ + adapter_t *adapter = data; + int result = 0; + + result = perf_event_end_miu_dump(adapter, end_miu_perf_event); + + return result; +} + +static int krnl_get_miu_dump_perf_event(void *data, gf_get_miu_dump_perf_event_t *get_miu_dump) +{ + adapter_t *adapter = data; + int result = 0; + + result = perf_event_get_miu_event(adapter, get_miu_dump); + + return result; +} + +static int krnl_direct_get_miu_dump_perf_event(void *data, gf_direct_get_miu_dump_perf_event_t *direct_get_dump) +{ + adapter_t *adapter = data; + int result = 0; + + result = perf_event_direct_get_miu_dump_event(adapter, direct_get_dump); + + return result; +} + +static int krnl_get_perf_event(void *data, gf_get_perf_event_t *get_event) +{ + adapter_t *adapter = data; + int result = 0; + + result = perf_event_get_event(adapter, get_event); + + return result; +} + +static int krnl_set_miu_reg_list_perf_event(void *data, gf_miu_reg_list_perf_event_t *miu_reg_list) +{ + adapter_t *adapter = data; + int result = 0; + + result = perf_event_set_miu_reg_list(adapter, miu_reg_list); + + return result; +} + +static int krnl_send_perf_event(void *data, gf_perf_event_t *perf_event) +{ + adapter_t *adapter = data; + int result = 0; + + result = perf_event_add_event(adapter, perf_event); + + return result; +} + +static int krnl_get_perf_status(void *data, gf_perf_status_t *perf_status) +{ + adapter_t *adapter = data; + int result = 0; + + result = perf_event_get_status(adapter, perf_status); + + return result; +} + +static int krnl_create_context(void *data, gf_create_context_t *create_context, enum gf_mem_space mem_space) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, create_context->device); + gpu_context_t *context = NULL; + create_context_t create = {0}; + int is_kernel = (mem_space == GF_MEM_KERNEL) ? 1 : 0; + + /** + * TODO: remove this later. + */ + if (!(create_context->device & 0xFF000000)) + { + gf_info("type not correct, refuse to create context\n"); + return E_FAIL; + } + + if (!device || !device->adapter) + { + gf_info("invalid device, refuse to create context\n"); + return E_FAIL; + } + //multi-engine + create.node_ordinal = create_context->engine_index; + create.flags = create_context->flags; + + context = cm_create_context(device, &create, is_kernel); + + if(context) + { + create_context->context = context->handle; + return S_OK; + } + + return E_FAIL; +} + +static int krnl_destroy_context(void *data, gf_destroy_context_t *destroy_context) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, destroy_context->device); + gpu_context_t *context = get_from_handle(&adapter->hdl_mgr, destroy_context->context); + + cm_destroy_context(device, context); + + return S_OK; +} + +static int krnl_create_di_context(void *data, gf_create_di_context_t *create) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, create->device); + di_context_t *context; + + int status = E_FAIL; + + if(device == NULL) + { + gf_error("bad argument device: %x, %p.\n", create->device, device); + + return E_FAIL; + } + + context = cm_create_di_context(device, create); + + if(context != NULL) + { + create->context = context->handle; + create->hw_idx = context->hw_idx; + + status = S_OK; + } + + return status; +} + +static int krnl_destroy_di_context(void *data, gf_destroy_di_context_t *destroy_context) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, destroy_context->device); + di_context_t *context = get_from_handle(&adapter->hdl_mgr, destroy_context->context); + + if((device == NULL) || (context == NULL)) + { + gf_error("bad argument: device: %x, %p. context: %x, %p.\n", + destroy_context->device, device, destroy_context->context, context); + + return E_FAIL; + } + + cm_destroy_di_context(device, context); + + return S_OK; +} + +static int krnl_render(void *data, gf_render_t *render) +{ + int ret; + adapter_t *adapter = data; + gpu_context_t *gpu_context = get_from_handle(&adapter->hdl_mgr, render->context); + vidsch_render_t render_data = {0}; + + render_data.command_length = render->command_length; + render_data.flags = render->flags; + render_data.allocation_list_size = render->allocation_count; + render_data.patch_location_list_size = render->patch_location_count; + render_data.sync_object_list_size = render->sync_object_count; + render_data.allocation_list = (void*)(unsigned long)render->allocation_list; + render_data.patch_location_list = (void*)(unsigned long)render->patch_location_list; + render_data.sync_object_list = (void*)(unsigned long)render->sync_object_list; + render_data.cmdbuf_count = render->cmdbuf_count; + render_data.render_counter = gpu_context->render_counter++; + render_data.cmdbuf_array = (void*)(unsigned long)render->cmdbuf_array; + + ret = vidsch_render(gpu_context, &render_data); + + return ret; +} + +static int krnl_create_fence_sync_object(void *data, gf_create_fence_sync_object_t *create, int binding) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, create->device); + unsigned int status = E_FAIL; + + status = vidsch_create_sync_object(device, create, binding); + + return status; +} + +static int krnl_destroy_fence_sync_object(void *data, gf_destroy_fence_sync_object_t *destroy) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, destroy->device); + unsigned int status = S_OK; + + status = vidsch_destroy_sync_object(adapter, device, destroy->fence_sync_object); + + return status; +} + +static int krnl_wait_fence_sync_object(void *data, gf_wait_fence_sync_object_t *wait) +{ + adapter_t *adapter = data; + gpu_context_t *context = get_from_handle(&adapter->hdl_mgr, wait->context); + unsigned int status = S_OK; + + status = vidsch_wait_sync_object(context, wait); + + return status; +} + +static int krnl_is_fence_object_signaled(void *data, unsigned int fence_sync_object, unsigned long long wait_value) +{ + adapter_t *adapter = data; + return vidsch_is_fence_signaled(adapter,fence_sync_object,wait_value); +} + +static int krnl_is_fence_back(void *data, unsigned char engine_index, unsigned long long fence_id) +{ + adapter_t *adapter = data; + + return vidsch_is_fence_back(adapter, engine_index, fence_id); +} + +static int krnl_fence_value(void *data, gf_fence_value_t *value) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, value->device); + unsigned int status = E_FAIL; + + status = vidsch_fence_value(device, value); + + return status; +} + +static int krnl_get_allocation_state(void *data, gf_get_allocation_state_t *state) +{ + adapter_t *adapter = data; + vidmm_allocation_t *allocation = get_from_handle(&adapter->hdl_mgr, state->hAllocation); + unsigned int engine_mask = state->engine_mask; + + if (!allocation) + return E_INVALIDARG; + + if (!vidsch_is_allocation_idle(adapter, engine_mask, allocation)) + { + state->state = 1; + } + else + { + state->state = 0; + } + + return 0; +} + + +static int krnl_add_hw_ctx_buf(void *data, gf_add_hw_ctx_buf_t *add) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, add->device); + gpu_context_t *context = get_from_handle(&adapter->hdl_mgr, add->context); + int ret = 0; + + ret = cm_add_hwctx_buffer(device, context, add->hw_ctx_buf_index); + + return ret; +} + +static int krnl_rm_hw_ctx_buf(void *data, gf_rm_hw_ctx_buf_t *rm) +{ + adapter_t *adapter = data; + gpu_device_t *device = get_from_handle(&adapter->hdl_mgr, rm->device); + gpu_context_t *context = get_from_handle(&adapter->hdl_mgr, rm->context); + int ret = 0; + + ret = cm_remove_hwctx_buffer(device, context, rm->hw_ctx_buf_index); + + return ret; +} + +static struct os_pages_memory* krnl_get_allocation_pages(void *data, int handle) +{ + adapter_t *adapter = data; + + vidmm_allocation_t *allocation = get_from_handle(&adapter->hdl_mgr, handle); + + return allocation->pages_mem; +} + +static int krnl_notify_interrupt(void *data, unsigned int interrupt_event) +{ + adapter_t *adapter = data; + + return vidsch_notify_interrupt(adapter, interrupt_event); +} + +static void krnl_prepare_and_mark_unpagable(void *data, unsigned int handle, gf_open_allocation_t *info) +{ + adapter_t *adapter = data; + vidmm_allocation_t *allocation = get_from_handle(&adapter->hdl_mgr, handle); + + vidmm_prepare_and_mark_unpagable(adapter, allocation, info); +} + +static void krnl_mark_pagable(void *data, unsigned int handle) +{ + adapter_t *adapter = data; + vidmm_allocation_t *allocation = get_from_handle(&adapter->hdl_mgr, handle); + + vidmm_mark_pagable(adapter, allocation); +} + +static void krnl_perf_event_add_isr_event(void *data, gf_perf_event_t *perf_event) +{ + adapter_t *adapter = data; + if (adapter->ctl_flags.perf_event_enable && adapter->perf_event_mgr) + { + perf_event_add_isr_event(adapter, perf_event); + } +} + +static void krnl_perf_event_add_event(void *data, gf_perf_event_t *perf_event) +{ + adapter_t *adapter = data; + if (adapter->ctl_flags.perf_event_enable && adapter->perf_event_mgr) + { + perf_event_add_event(adapter, perf_event); + } +} + +static int krnl_hwq_process_vsync_event(void *data,unsigned long long time) +{ + adapter_t *adapter = data; + int ret =0; + if (adapter->ctl_flags.hwq_event_enable && adapter->hwq_event_mgr) + { + ret=hwq_process_vsync_event(adapter,time); + } + return ret; +} + +static void krnl_update_device_name(void *data, unsigned int device) +{ + adapter_t *adapter = data; + gpu_device_t *gpu_device = get_from_handle(&adapter->hdl_mgr, device); + + if (gpu_device) + { + gpu_device->pid = gf_get_current_pid(); + gpu_device->tid = gf_get_current_tid(); + gf_get_current_pname(gpu_device->pname, GF_MAX_PNAME_LEN); + } +} + +static void krnl_dump_hang_info_flag(void *data, int flag) +{ + adapter_t *adapter = data; + + adapter->display_debugbus_flag = flag; + gf_info("adapter->display_debugbus_flag = %d\n", flag); +} + +static void krnl_ctl_flags_set(void *data,unsigned int num,unsigned int mask,unsigned int value) +{ + adapter_t *adapter = data; + unsigned int *ctl_flags = (unsigned int *)&adapter->ctl_flags; + if( num > (sizeof(adapter->ctl_flags)/sizeof(unsigned int)) || num <=0 ) return; + + ctl_flags += (num-1); + *ctl_flags &= ~mask; + *ctl_flags |= value; +} + +static void krnl_task_timeout_update(void* data, unsigned long long *value, int update) +{ + adapter_t *adapter = data; + + if (update) + adapter->hw_hang_fast_timeout_ns = *value * 1000000; + else + *value = adapter->hw_hang_fast_timeout_ns / 1000000; +} + +static void krnl_reset_dvfs_power_flag(void* data) +{ + adapter_t *adapter = data; + + vidsch_dvfs_power_flag_reset(adapter); +} + +static core_interface_t gfe3k_gpu_core = { +#define INTERFACE(item) .item = krnl_##item + INTERFACE(pre_init_adapter), + INTERFACE(init_adapter), + INTERFACE(deinit_adapter), + INTERFACE(get_adapter_info), + INTERFACE(update_adapter_info), + INTERFACE(dump_resource), + INTERFACE(debugfs_dump), + INTERFACE(final_cleanup), + INTERFACE(wait_chip_idle), + INTERFACE(wait_allocation_idle), + INTERFACE(get_allocation_state), + INTERFACE(save_state), + INTERFACE(restore_state), + INTERFACE(query_info), + INTERFACE(create_device), + INTERFACE(destroy_device), + INTERFACE(create_allocation), + INTERFACE(create_allocation_list), + INTERFACE(create_allocation_from_pages), + INTERFACE(destroy_allocation), + INTERFACE(set_callback_func), + INTERFACE(begin_perf_event), + INTERFACE(end_perf_event), + INTERFACE(get_perf_event), + INTERFACE(send_perf_event), + INTERFACE(get_perf_status), + INTERFACE(begin_miu_dump_perf_event), + INTERFACE(end_miu_dump_perf_event), + INTERFACE(set_miu_reg_list_perf_event), + INTERFACE(get_miu_dump_perf_event), + INTERFACE(direct_get_miu_dump_perf_event), + INTERFACE(create_context), + INTERFACE(destroy_context), + INTERFACE(render), + INTERFACE(create_di_context), + INTERFACE(destroy_di_context), + INTERFACE(create_fence_sync_object), + INTERFACE(destroy_fence_sync_object), + INTERFACE(wait_fence_sync_object), + INTERFACE(fence_value), + INTERFACE(is_fence_object_signaled), + INTERFACE(is_fence_back), + INTERFACE(add_hw_ctx_buf), + INTERFACE(rm_hw_ctx_buf), + INTERFACE(cil2_misc), + INTERFACE(get_allocation_pages), + INTERFACE(notify_interrupt), + INTERFACE(get_map_allocation_info), + INTERFACE(prepare_and_mark_unpagable), + INTERFACE(mark_pagable), + INTERFACE(perf_event_add_isr_event), + INTERFACE(perf_event_add_event), + INTERFACE(update_device_name), + INTERFACE(dump_hang_info_flag), + INTERFACE(ctl_flags_set), + INTERFACE(hwq_process_vsync_event), + INTERFACE(task_timeout_update), + INTERFACE(reset_dvfs_power_flag), +#undef INTERFACE +}; + +core_interface_t *gf_core_interface = &gfe3k_gpu_core; diff --git a/drivers/gpu/drm/arise/core/perfevent/perfevent.c b/drivers/gpu/drm/arise/core/perfevent/perfevent.c new file mode 100755 index 0000000000000..8cf232f050eb9 --- /dev/null +++ b/drivers/gpu/drm/arise/core/perfevent/perfevent.c @@ -0,0 +1,1115 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "gf_def.h" +#include "perfeventi.h" +#include "perfevent.h" + +#define PERF_EVENT_TRACE_ENABLE 0 + +#if PERF_EVENT_TRACE_ENABLE +#define perf_event_trace gf_info +#else +#define perf_event_trace(args...) +#endif + +#define PERF_EVENT_MAX_ISR_EVENT_BUFFER_SIZE (512*1024) + + + +int perf_event_init(adapter_t *adapter) +{ + perf_event_mgr_t *perf_event_mgr; + int ret = 0; + + perf_event_mgr = gf_calloc(sizeof(perf_event_mgr_t)); + + perf_event_mgr->event_list_lock = gf_create_spinlock(0); + gf_assert(perf_event_mgr->event_list_lock != NULL, "perf_event_mgr->event_list_lock != NULL"); + + perf_event_mgr->miu_event_list_lock = gf_create_spinlock(0); + gf_assert(perf_event_mgr->miu_event_list_lock != NULL, "perf_event_mgr->miu_event_list_lock != NULL"); + + list_init_head(&perf_event_mgr->event_list); + list_init_head(&perf_event_mgr->miu_event_list); + + perf_event_mgr->isr_event_buffer = gf_calloc(PERF_EVENT_MAX_ISR_EVENT_BUFFER_SIZE); + gf_assert(perf_event_mgr->isr_event_buffer != NULL, "perf_event_mgr->isr_event_buffer != NULL"); + perf_event_mgr->isr_event_tail = 0; + perf_event_mgr->isr_event_head = 0; + perf_event_mgr->isr_event_lock = gf_create_spinlock(0); + + perf_event_mgr->miu_table_lock = gf_create_spinlock(0); + gf_assert(perf_event_mgr->miu_table_lock != NULL, "perf_event_mgr->miu_table_lock != NULL"); + + perf_event_mgr->chip_func = &perf_chip_func; + + adapter->perf_event_mgr = perf_event_mgr; + + return ret; +} + +int perf_event_deinit(adapter_t *adapter) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + perf_event_node *event_node = NULL; + perf_event_node *event_node_next; + + list_for_each_entry_safe(event_node, event_node_next, &perf_event_mgr->event_list, list_node) + { + list_del(&event_node->list_node); + gf_free(event_node); + } + + // clean miu list. + list_for_each_entry_safe(event_node, event_node_next, &perf_event_mgr->miu_event_list, list_node) + { + list_del(&event_node->list_node); + gf_free(event_node); + } + + gf_destroy_spinlock(perf_event_mgr->event_list_lock); + perf_event_mgr->event_list_lock = NULL; + + gf_free(perf_event_mgr->isr_event_buffer); + perf_event_mgr->isr_event_buffer = NULL; + + gf_destroy_spinlock(perf_event_mgr->isr_event_lock); + perf_event_mgr->isr_event_lock = NULL; + + gf_destroy_spinlock(perf_event_mgr->miu_table_lock); + perf_event_mgr->miu_table_lock = NULL; + + gf_destroy_spinlock(perf_event_mgr->miu_event_list_lock); + perf_event_mgr->miu_event_list_lock = NULL; + + gf_free(perf_event_mgr); + adapter->perf_event_mgr = NULL; + + return 0; +} + +int perf_event_begin(adapter_t *adapter, gf_begin_perf_event_t *begin) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + perf_event_node *event_node = NULL; + perf_event_node *event_node_next; + + gf_assert(adapter->ctl_flags.perf_event_enable, "adapter->ctl_flags.perf_event_enable"); + gf_assert(perf_event_mgr->perf_started == FALSE, "perf_event_mgr->perf_started == FALSE"); + + //resetting buffer + perf_event_mgr->isr_event_head = 0; + perf_event_mgr->isr_event_tail = 0; + perf_event_mgr->isr_event_buffer_size = 0; + + perf_event_mgr->lost_event_number = 0; + perf_event_mgr->event_number = 0; + + list_for_each_entry_safe(event_node, event_node_next, &perf_event_mgr->event_list, list_node) + { + list_del(&event_node->list_node); + gf_free(event_node); + } + + perf_event_mgr->perf_started = TRUE; + perf_event_mgr->max_event_number = begin->max_event_num; + + perf_event_trace("perf_event_begin, max_event_number:%x\n", begin->max_event_num); + + return 0; +} + +int perf_event_begin_miu_dump(adapter_t *adapter, gf_begin_miu_dump_perf_event_t *miu_begin) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + + perf_event_trace("perf_event_begin_miu_dump enter\n"); + + gf_assert(adapter->ctl_flags.perf_event_enable == TRUE, "adapter->ctl_flags.perf_event_enable == TRUE"); + + if(adapter->ctl_flags.miu_counter_enable == TRUE) + { + gf_info("krnl miu dump already begin, call miu begin twice?\n"); + } + + adapter->ctl_flags.miu_counter_enable = TRUE; + + perf_event_mgr->miu_max_event_number = miu_begin->max_event_num; + perf_event_mgr->miu_event_number = 0; + perf_event_mgr->miu_lost_event_number = 0; + + perf_event_trace("perf_event_begin_miu_dump exit\n"); + + return 0; +} + +int perf_event_end(adapter_t *adapter, gf_end_perf_event_t *end) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + + gf_assert(perf_event_mgr->perf_started == TRUE, "perf_event_mgr->perf_started == TRUE"); + perf_event_mgr->perf_started = FALSE; + + perf_event_trace("perf_event_end\n"); + + return 0; +} + +int perf_event_end_miu_dump(adapter_t *adapter, gf_end_miu_dump_perf_event_t *miu_end) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + perf_event_node *event_node = NULL; + perf_event_node *event_node_next = NULL; + + perf_event_trace("perf_event_end_miu_dump enter\n"); + + if(adapter->ctl_flags.miu_counter_enable == FALSE) + { + gf_info("krnl miu dump already end, call miu end twice?\n"); + } + + adapter->ctl_flags.miu_counter_enable = FALSE; + + // free miu event list. + gf_spin_lock(perf_event_mgr->miu_event_list_lock); + + list_for_each_entry_safe(event_node, event_node_next, &perf_event_mgr->miu_event_list, list_node) + { + list_del(&event_node->list_node); + gf_free(event_node); + } + + perf_event_mgr->miu_event_number = 0; + perf_event_mgr->miu_lost_event_number = 0; + perf_event_mgr->miu_lost_event_time = 0; + + gf_spin_unlock(perf_event_mgr->miu_event_list_lock); + + perf_event_trace("perf_event_end_miu_dump exit\n"); + + return 0; +} + + +int perf_event_add_miu_event(adapter_t *adapter, unsigned int gpu_context, unsigned long long task_id, unsigned long long fence_id, int task_end) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + gf_perf_event_t *miu_perf_event = NULL; + perf_event_node *event_node = NULL; + gf_miu_list_item_t *miu_table = NULL; + unsigned long long timestamp = 0; + + unsigned int miu_table_size = 0, perf_event_size = 0; + int ret = 0, list_full = 0; + + miu_table_size = perf_event_mgr->miu_table_length*sizeof(gf_miu_list_item_t); + perf_event_size = sizeof(gf_perf_event_miu_counter_dump_t) + miu_table_size; + + perf_event_trace("perf_event_add_miu_event enter\n"); + + if (adapter->ctl_flags.miu_counter_enable == FALSE) + { + ret = -1; + goto exit; + } + + if (perf_event_mgr->miu_lost_event_number > 0) + { + perf_event_mgr->miu_lost_event_number ++; + ret = -1; + goto exit; + } + + event_node = gf_calloc(perf_event_size + sizeof(struct list_head)); + if (event_node == NULL) + { + gf_info("perf_event_mgr: alloc memroy fail for miu node.\n"); + ret = -1; + goto exit; + } + + miu_perf_event = (gf_perf_event_t*)(&event_node->perf_event); + + // fill miu perf event, then copy event info to event node. + miu_perf_event->header.size = perf_event_size; + miu_perf_event->header.type = GF_PERF_EVENT_MIU_COUNTER; + miu_perf_event->miu_counter.counter_buffer_offset = sizeof(gf_perf_event_miu_counter_dump_t); + miu_perf_event->miu_counter.buffer_length = perf_event_mgr->miu_table_length; + + miu_perf_event->miu_counter.gpu_context = gpu_context; + miu_perf_event->miu_counter.task_id_high = task_id >> 32; + miu_perf_event->miu_counter.task_id_low = (task_id) & 0xffffffff; + miu_perf_event->miu_counter.fence_id_high = fence_id >> 32; + miu_perf_event->miu_counter.fence_id_low = (fence_id) & 0xffffffff; + + gf_get_nsecs(×tamp); + miu_perf_event->header.timestamp_high = timestamp >> 32; + miu_perf_event->header.timestamp_low = (timestamp) & 0xffffffff; + + // miu list item array start address. + miu_table = (gf_miu_list_item_t*)((char*)&event_node->perf_event + sizeof(gf_perf_event_miu_counter_dump_t)); + + gf_spin_lock(perf_event_mgr->miu_table_lock); + gf_memcpy(miu_table, perf_event_mgr->miu_table, miu_table_size); + gf_spin_unlock(perf_event_mgr->miu_table_lock); + + if(miu_table == NULL) + { + ret = -1; + goto exit; + } + + // run miu command from user space. + perf_event_mgr->chip_func->direct_get_miu_counter(adapter, miu_table, perf_event_mgr->miu_table_length, task_end); + + perf_event_trace("add event type: %x, pid %x, tid %x\n", perf_event->header.type, perf_event->header.pid, perf_event->header.tid); + + gf_spin_lock(perf_event_mgr->miu_event_list_lock); + + if (perf_event_mgr->miu_event_number < perf_event_mgr->miu_max_event_number) + { + list_add_tail(&event_node->list_node, &perf_event_mgr->miu_event_list); + perf_event_mgr->miu_event_number++; + } + else + { + list_full = 1; + perf_event_mgr->miu_lost_event_number++; + if(perf_event_mgr->miu_lost_event_number == 1) + { + gf_get_nsecs(&perf_event_mgr->miu_lost_event_time); + } + + gf_info("perf_event_mgr: miu perf event lost.\n"); + } + + gf_spin_unlock(perf_event_mgr->miu_event_list_lock); + + if(list_full == 1) + { + gf_free(event_node); + ret = -1; + goto exit; + } + + perf_event_trace("add miu perf event num:%x\n", perf_event_mgr->miu_event_number); + + perf_event_trace("perf_event_add_miu_event exit.\n"); + +exit: + return ret; + +} + +int perf_event_add_event(adapter_t *adapter, gf_perf_event_t *perf_event) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + perf_event_node *event_node; + int ret = 0; + + if (perf_event_mgr->perf_started == FALSE) + { + ret = -1; + goto exit; + } + + if (perf_event_mgr->lost_event_number > 0) + { + perf_event_mgr->lost_event_number++; + ret = -1; + goto exit; + } + + event_node = gf_calloc(perf_event->header.size + sizeof(struct list_head)); + if (event_node == NULL) + { + gf_info("perf_event_mgr: alloc memory fail.\n"); + ret = -1; + goto exit; + } + + gf_memcpy(&event_node->perf_event, perf_event, perf_event->header.size); + + perf_event_trace("add event type: %x, pid %x, tid %x\n", perf_event->header.type, perf_event->header.pid, perf_event->header.tid); + + gf_spin_lock(perf_event_mgr->event_list_lock); + + if (perf_event_mgr->event_number < perf_event_mgr->max_event_number) + { + list_add_tail(&event_node->list_node, &perf_event_mgr->event_list); + perf_event_mgr->event_number++; + } + else + { + perf_event_mgr->lost_event_number++; + + if (perf_event_mgr->lost_event_number == 1) + { + gf_get_nsecs(&perf_event_mgr->lost_event_time); + } + + gf_info("perf_event_mgr: event lost\n"); + } + + gf_spin_unlock(perf_event_mgr->event_list_lock); + + if (perf_event_mgr->lost_event_number > 0) + { + if (event_node->list_node.next != &perf_event_mgr->event_list) + { + gf_free(event_node); + ret = -1; + goto exit; + } + } + + perf_event_trace("add perf event num:%x\n", perf_event_mgr->event_number); + + if (perf_event->header.type == GF_PERF_EVENT_DMA_BUFFER_QUEUED) + { + perf_event_trace("add event dma queue dma idx low: %x, high: %x\n", perf_event->dma_buffer_queued.dma_idx_low, perf_event->dma_buffer_queued.dma_idx_high); + perf_event_trace("add event dma queue time low: %x, high: %x\n", perf_event->header.timestamp_low, perf_event->header.timestamp_high); + } + +exit: + return ret; +} + +int perf_event_get_miu_event(adapter_t *adapter, gf_get_miu_dump_perf_event_t *get_perf_event) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + perf_event_node *event_node = NULL; + perf_event_node *event_node_next = NULL; + gf_perf_event_header_t *perf_event = NULL; + int event_fill_num = 0; + char *dst_buf = get_perf_event->event_buffer; + + int i = 0, ret = 0; + + perf_event_trace("miu perf_event_get_event enter\n"); + + if (perf_event_mgr->perf_started == FALSE) + { + ret = -1; + goto exit; + } + + gf_spin_lock(perf_event_mgr->miu_event_list_lock); + event_fill_num = perf_event_mgr->miu_event_number; + gf_spin_unlock(perf_event_mgr->miu_event_list_lock); + + if (event_fill_num == 0) + { + get_perf_event->event_filled_num = 0; + get_perf_event->event_buffer_filled_size = 0; + get_perf_event->event_lost_num = 0; + + goto exit; + } + + list_for_each_entry_safe(event_node, event_node_next, &perf_event_mgr->miu_event_list, list_node) + { + if(get_perf_event->max_event_buffer_size < event_node->perf_event.size) + { + gf_info("insufficient buffer to contain miu counter data!\n"); + ret = -1; + break; + } + + gf_copy_to_user(dst_buf, &event_node->perf_event, event_node->perf_event.size); + dst_buf += event_node->perf_event.size; + + perf_event = &event_node->perf_event; + + list_del(&event_node->list_node); + + gf_free(event_node); + i++; + + if (i >= get_perf_event->max_event_num || + i >= event_fill_num) + { + break; + } + } + + get_perf_event->event_filled_num = i; + get_perf_event->event_buffer_filled_size = util_get_ptr_span(dst_buf, get_perf_event->event_buffer); + + gf_spin_lock(perf_event_mgr->miu_event_list_lock); + + get_perf_event->event_lost_num = perf_event_mgr->miu_lost_event_number; + get_perf_event->event_lost_timestamp = perf_event_mgr->miu_lost_event_time; + + perf_event_mgr->miu_event_number -= i; + perf_event_mgr->miu_lost_event_number = 0; + perf_event_mgr->miu_lost_event_time = 0; + + gf_spin_unlock(perf_event_mgr->miu_event_list_lock); + +exit: + return ret; + +} + +int perf_event_get_event(adapter_t *adapter, gf_get_perf_event_t *get_perf_event) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + perf_event_node *event_node = NULL; + perf_event_node *event_node_next; + int event_fill_num = 0; + int i = 0; + int ret = 0; + char *dst_buf = get_perf_event->event_buffer; + gf_perf_event_header_t *perf_event; + + perf_event_trace("perf_event_get_event enter\n"); + + if (perf_event_mgr->perf_started == FALSE) + { + ret = -1; + goto exit; + } + + gf_spin_lock(perf_event_mgr->event_list_lock); + event_fill_num = perf_event_mgr->event_number; + gf_spin_unlock(perf_event_mgr->event_list_lock); + + if (event_fill_num == 0) + { + get_perf_event->event_filled_num = 0; + get_perf_event->event_buffer_filled_size = 0; + get_perf_event->event_lost_num = 0; + + if(perf_event_mgr->isr_event_num == 0) + { + goto exit; + } + else + { + goto isr_event; + } + } + + list_for_each_entry_safe(event_node, event_node_next, &perf_event_mgr->event_list, list_node) + { + gf_copy_to_user(dst_buf, &event_node->perf_event, event_node->perf_event.size); + dst_buf += event_node->perf_event.size; + + perf_event = &event_node->perf_event; + + list_del(&event_node->list_node); + + gf_free(event_node); + i++; + + if (i >= get_perf_event->max_event_num || + i >= event_fill_num) + { + break; + } + } + + get_perf_event->event_filled_num = i; + get_perf_event->event_buffer_filled_size = dst_buf - (char *)get_perf_event->event_buffer; + + gf_spin_lock(perf_event_mgr->event_list_lock); + + get_perf_event->event_lost_num = perf_event_mgr->lost_event_number; + get_perf_event->event_lost_timestamp = perf_event_mgr->lost_event_time; + + perf_event_mgr->event_number -= i; + perf_event_mgr->lost_event_number = 0; + perf_event_mgr->lost_event_time = 0; + + gf_spin_unlock(perf_event_mgr->event_list_lock); + +isr_event: + ret = perf_event_get_isr_event(adapter, get_perf_event); + + perf_event_trace("perf_event_get exit, event_filled_num: %x, isr_event_num: %x\n", + get_perf_event->event_filled_num, get_perf_event->isr_filled_num); + +exit: + return ret; +} + +int perf_event_add_isr_event(adapter_t *adapter, gf_perf_event_t *perf_event) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + unsigned long flags = 0; + char *buf = NULL; + int ret = 0; + int partial_copy_size; + + if (perf_event_mgr->perf_started == FALSE) + { + ret = -1; + goto exit; + } + + flags = gf_spin_lock_irqsave(perf_event_mgr->isr_event_lock); + + if (perf_event_mgr->isr_event_buffer_size + perf_event->header.size < PERF_EVENT_MAX_ISR_EVENT_BUFFER_SIZE) + { + buf = perf_event_mgr->isr_event_buffer + perf_event_mgr->isr_event_tail; + if(buf + perf_event->header.size < perf_event_mgr->isr_event_buffer + PERF_EVENT_MAX_ISR_EVENT_BUFFER_SIZE) + { + gf_memcpy(buf, perf_event, perf_event->header.size); + } + else + { + partial_copy_size = perf_event_mgr->isr_event_buffer + PERF_EVENT_MAX_ISR_EVENT_BUFFER_SIZE - buf; + gf_memcpy(buf, perf_event, partial_copy_size); + + buf = perf_event_mgr->isr_event_buffer; + gf_memcpy(buf, (char*)perf_event + partial_copy_size, perf_event->header.size - partial_copy_size); + } + + perf_event_mgr->isr_event_tail = + (perf_event_mgr->isr_event_tail + perf_event->header.size) % PERF_EVENT_MAX_ISR_EVENT_BUFFER_SIZE; + perf_event_mgr->isr_event_buffer_size += perf_event->header.size; + perf_event_mgr->isr_event_num++; + + perf_event_trace("add isr event, added size:%x, tail:%x, number:%x\n", perf_event_mgr->isr_event_buffer_size, + perf_event_mgr->isr_event_tail, perf_event_mgr->isr_event_num); + } + else + { + //gf_info("perf_event_mgr: dma completed event lost, should not happen.\n"); + } + + gf_spin_unlock_irqrestore(perf_event_mgr->isr_event_lock, flags); + + perf_event_trace("add isr event time low:%x, time high:%x, event type :%x\n", + perf_event->header.timestamp_low, perf_event->header.timestamp_high, perf_event->header.type); + +exit: + return ret; +} + +int perf_event_get_isr_event(adapter_t *adapter, gf_get_perf_event_t *get_perf_event) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + unsigned long flags = 0; + char *buf = NULL; + char *buf_dst = get_perf_event->isr_event_buffer; + int event_fill_number = 0; + int event_fill_size = 0; + int fill_size_partial = 0; + int ret = 0; + + perf_event_trace("start get_isr_event, event number:%x, size: %x\n", perf_event_mgr->isr_event_num, perf_event_mgr->isr_event_buffer_size); + + if (perf_event_mgr->perf_started == FALSE) + { + ret = -1; + goto exit; + } + + flags = gf_spin_lock_irqsave(perf_event_mgr->isr_event_lock); + + if (perf_event_mgr->isr_event_num) + { + event_fill_number = perf_event_mgr->isr_event_num; + event_fill_size = perf_event_mgr->isr_event_buffer_size; + } + else + { + perf_event_mgr->isr_event_num = 0; + perf_event_mgr->isr_event_buffer_size = 0; + ret = 0; + + gf_spin_unlock_irqrestore(perf_event_mgr->isr_event_lock, flags); + + goto exit; + } + + gf_spin_unlock_irqrestore(perf_event_mgr->isr_event_lock, flags); + + if (event_fill_number) + { + if (perf_event_mgr->isr_event_head + event_fill_size <= PERF_EVENT_MAX_ISR_EVENT_BUFFER_SIZE) + { + buf = perf_event_mgr->isr_event_buffer + perf_event_mgr->isr_event_head; + gf_copy_to_user(buf_dst, buf, perf_event_mgr->isr_event_buffer_size); + } + else + { + fill_size_partial = PERF_EVENT_MAX_ISR_EVENT_BUFFER_SIZE - perf_event_mgr->isr_event_head; + + buf = perf_event_mgr->isr_event_buffer + perf_event_mgr->isr_event_head; + gf_copy_to_user(buf_dst, buf, fill_size_partial); + + buf = perf_event_mgr->isr_event_buffer; + buf_dst += fill_size_partial; + gf_copy_to_user(buf_dst, buf, event_fill_size); + } + } + + perf_event_mgr->isr_event_head = + (perf_event_mgr->isr_event_head + event_fill_size) % PERF_EVENT_MAX_ISR_EVENT_BUFFER_SIZE; + + flags = gf_spin_lock_irqsave(perf_event_mgr->isr_event_lock); + + perf_event_mgr->isr_event_num -= event_fill_number; + perf_event_mgr->isr_event_buffer_size -= event_fill_size; + + gf_spin_unlock_irqrestore(perf_event_mgr->isr_event_lock, flags); + + get_perf_event->isr_filled_num = event_fill_number; + get_perf_event->isr_filled_size = event_fill_size; + +exit: + perf_event_trace("perf event get isr num:%x, head:%x\n", event_fill_number, perf_event_mgr->isr_event_head); + + return ret; +} + +int perf_event_get_status(adapter_t *adapter, gf_perf_status_t *get_status) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + int ret = 0; + + get_status->started = perf_event_mgr->perf_started; + get_status->miu_started = adapter->ctl_flags.miu_counter_enable; + + return ret; +} + +int perf_event_set_miu_reg_list(adapter_t *adapter, gf_miu_reg_list_perf_event_t *miu_reg_list) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + gf_miu_list_item_t *miu_table = NULL; + unsigned int miu_table_size = sizeof(gf_miu_list_item_t)*miu_reg_list->miu_table_length; + int ret = 0; + + perf_event_trace("perf_event_set_miu_reg_list enter\n"); + + miu_table = gf_calloc(miu_table_size); + gf_assert(miu_table != NULL, "miu_table != NULL"); + + // get miu table from user space, which will contains write/read command to/from miu regsiter. + gf_copy_from_user(miu_table, miu_reg_list->miu_table, miu_table_size); + + gf_spin_lock(perf_event_mgr->miu_table_lock); + if(perf_event_mgr->miu_table != NULL) + { + gf_free(perf_event_mgr->miu_table); + } + perf_event_mgr->miu_table = miu_table; + perf_event_mgr->miu_table_length = miu_reg_list->miu_table_length; + gf_spin_unlock(perf_event_mgr->miu_table_lock); + + perf_event_trace("perf_event_set_miu_reg_list exit\n"); + + return ret; +} + +int perf_event_direct_get_miu_dump_event(adapter_t *adapter, gf_direct_get_miu_dump_perf_event_t *get_perf_event) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + gf_miu_list_item_t *local_miu_table = NULL; + unsigned long long timestamp = 0; + unsigned int miu_table_size = 0; + + perf_event_trace("perf_event_direct_get_miu_dump_event enter\n"); + + miu_table_size = sizeof(gf_miu_list_item_t)*(get_perf_event->miu_table_length); + + local_miu_table = gf_calloc(miu_table_size); + gf_assert(local_miu_table != NULL, "local_miu_table != NULL"); + + gf_copy_from_user(local_miu_table, get_perf_event->miu_table, miu_table_size); + + gf_get_nsecs(×tamp); + get_perf_event->timestamp_high = timestamp >> 32; + get_perf_event->timestamp_low = (timestamp) & 0xffffffff; + + perf_event_mgr->chip_func->direct_get_miu_counter(adapter, local_miu_table, get_perf_event->miu_table_length, 0); + + gf_copy_to_user(get_perf_event->miu_table, local_miu_table, miu_table_size); + + gf_free(local_miu_table); + + perf_event_trace("perf_event_direct_get_miu_dump_event exit\n"); + + return 0; +} + +int perf_event_util_miu_counter_dump(adapter_t *adapter, gf_miu_list_item_t *miu_list, unsigned int list_length, int force_read) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + + return perf_event_mgr->chip_func->direct_get_miu_counter(adapter, miu_list, list_length, force_read); +} + + +int gf_hwq_event_init(adapter_t *adapter) +{ + int ret = 0; + hwq_event_mgr_t *hwq_event_mgr = NULL; + adapter->usage_3d=0; + adapter->usage_vcp=0; + adapter->usage_vpp=0; + + hwq_event_mgr = gf_calloc(sizeof(hwq_event_mgr_t)); + hwq_event_mgr->sample_time=1000000000; + hwq_event_mgr->hwq_event = (hwq_event_info *)gf_calloc(adapter->active_engine_count * sizeof(hwq_event_info)); + + adapter->hwq_event_mgr=hwq_event_mgr; + + return ret; +} + + + +int gf_hwq_event_deinit(adapter_t *adapter) +{ + hwq_event_mgr_t *hwq_event_mgr; + + hwq_event_mgr=adapter->hwq_event_mgr; + if(hwq_event_mgr) + { + gf_free(hwq_event_mgr->hwq_event); + hwq_event_mgr->hwq_event = NULL; + gf_free(hwq_event_mgr); + adapter->hwq_event_mgr = NULL; + + } + + return 0; +} + + +int hwq_process_complete_event(adapter_t *adapter, unsigned long long time, unsigned int fence_id,unsigned int engine) +{ + hwq_event_mgr_t *hwq_event_mgr =adapter->hwq_event_mgr; + hwq_event_info *p_hwq_event; + + int ret = 0; + + if (hwq_event_mgr->hwq_started == 0) + { + return 0; + } + + p_hwq_event = (hwq_event_info*)(hwq_event_mgr->hwq_event)+engine; + + if(p_hwq_event->submit_fence_id==fence_id) + { + p_hwq_event->engine_status.status=ENGINE_IDLE; + p_hwq_event->last_busy2idletime=time; + } + else + { + p_hwq_event->engine_status.status=ENGINE_BUSY; + } + + p_hwq_event->complete_fence_id=fence_id; + p_hwq_event->engine_status.active =1; + + return ret; +} + +int hwq_process_submit_event(adapter_t *adapter, unsigned long long time, unsigned int fence_id,unsigned int engine) +{ + hwq_event_mgr_t *hwq_event_mgr =adapter->hwq_event_mgr; + hwq_event_info *p_hwq_event; + unsigned long long s_idle_time; + unsigned long long e_idle_time; + int ret = 0; + + if (hwq_event_mgr->hwq_started == 0) + { + return 0; + } + p_hwq_event = (hwq_event_info*)(hwq_event_mgr->hwq_event)+engine; + + if(p_hwq_event->engine_status.status==ENGINE_IDLE) + { + s_idle_time=p_hwq_event->last_busy2idletime; + + if(hwq_event_mgr->start_time > s_idle_time) + { + s_idle_time = hwq_event_mgr->start_time ; + } + e_idle_time = time; + p_hwq_event->idle_time+=(e_idle_time - s_idle_time); + + } + p_hwq_event->submit_fence_id=fence_id; + p_hwq_event->engine_status.active =1; + p_hwq_event->engine_status.status =ENGINE_BUSY; + + return ret; +} + + +int hwq_process_vsync_event(adapter_t *adapter, unsigned long long time) +{ + gf_hwq_info hwq_info; + hwq_event_mgr_t *hwq_event_mgr = adapter->hwq_event_mgr; + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + unsigned long long sample_time; + + unsigned int engine = 0; + hwq_event_info *p_hwq_event; + unsigned long long s_idle_time; + unsigned long long e_idle_time; + int ret=0; + + if(!(adapter->ctl_flags.hwq_event_enable)) + { + return 0; + } + + hwq_get_hwq_info(adapter,&hwq_info); + + if(hwq_event_mgr==NULL) + { + return -1; + } + if(hwq_event_mgr->hwq_started==0) + { + return 0; + } + sample_time=1000000000; + if(time-hwq_event_mgr->start_timeactive_engine_count; engine++) + { + p_hwq_event = (hwq_event_info*)(hwq_event_mgr->hwq_event)+engine; + if(p_hwq_event->engine_status.active==0) + { + if(p_hwq_event->engine_status.status==ENGINE_IDLE || p_hwq_event->engine_status.status==ENGINE_NONE) + { + p_hwq_event->engine_usage=0; + } + else if(p_hwq_event->engine_status.status==ENGINE_BUSY) + { + p_hwq_event->engine_usage=100; + } + p_hwq_event->idle_time=0; + continue; + } + + if(p_hwq_event->engine_status.status==ENGINE_IDLE) + { + s_idle_time = p_hwq_event->last_busy2idletime; + + if(hwq_event_mgr->start_time > s_idle_time) + { + s_idle_time = hwq_event_mgr->start_time ; + } + p_hwq_event->idle_time+=(e_idle_time - s_idle_time); + } + p_hwq_event->engine_usage=100-((p_hwq_event->idle_time)*100/((time-hwq_event_mgr->start_time))); + //gf_info("\n EngineNum=%d engine_usage ALL=%llu%%\n",engine,p_hwq_event->engine_usage); + + p_hwq_event->idle_time=0; + p_hwq_event->engine_status.active=0; + } + + gf_memset(&hwq_info,0,sizeof(gf_hwq_info)); + + ret = perf_event_mgr->chip_func->calculate_engine_usage(adapter, &hwq_info); + + adapter->usage_3d = hwq_info.Usage_3D; + adapter->usage_vcp = hwq_info.Usage_VCP; + adapter->usage_vpp = hwq_info.Usage_VPP; + //gf_info(" hwq_process_vsync_event adapter->usage_3d=%d adapter->usage_vcp = %d \n", adapter->usage_3d, adapter->usage_vcp ); + hwq_event_mgr->start_time=time; + return ret; +} + +int hwq_get_hwq_info(void *adp,gf_hwq_info *hwq_info) +{ + adapter_t *adapter = adp; + hwq_event_mgr_t *hwq_event_mgr = adapter->hwq_event_mgr; + int ret=0; + unsigned long long time=0; + unsigned int sample_time=0; + + if( !(adapter->ctl_flags.hwq_event_enable) || !(adapter->hwq_event_mgr) ) + { + return -1; + } + + if(hwq_event_mgr->hwq_started==0) + { + gf_get_nsecs(&time); + hwq_event_mgr->start_time=time; + hwq_event_mgr->hwq_started=1; + } + + if(sample_time<50) + { + sample_time=50; + } + + if(hwq_event_mgr->sample_time!=sample_time*1000ull*1000) + { + hwq_event_mgr->sample_time=sample_time*1000ull*1000; + } + + //gf_util tool will get gpu usage through this inteface. + hwq_info->Usage_3D = adapter->usage_3d; + hwq_info->Usage_VCP = adapter->usage_vcp; + hwq_info->Usage_VPP = adapter->usage_vpp; + + return ret; +} + +int hwq_get_hwq_info_ext(adapter_t *adapter,gfx_hwq_info_ext *phwq_info_ext) +{ + perf_event_mgr_t *perf_event_mgr = adapter->perf_event_mgr; + return perf_event_mgr->chip_func->calculate_engine_usage_ext(adapter, phwq_info_ext); +} + +int hwq_get_video_info(void *adp, gf_video_info *video_info) +{ + int ret = 0, i; + adapter_t *adapter = (adapter_t *)adp; + + unsigned long long interval_ms = 0; + unsigned long long time = 0; + static unsigned long long last_time[VCP_INFO_COUNT] = {0},last_decodetime[VCP_INFO_COUNT] = {0}; + static unsigned int frame_num[VCP_INFO_COUNT] = {0},decode_framenum[VCP_INFO_COUNT] = {0},bit_size[VCP_INFO_COUNT] = {0}; + + if( !(adapter->ctl_flags.hwq_event_enable) || !(adapter->hwq_event_mgr) ) + { + return -1; + } + + i = video_info->index; + if (!adapter->vcp_info[i].enable) { //inital again + last_time[i] = 0; + frame_num[i] = 0; + bit_size[i] = 0; + return 0; + } + video_info->pid[i] = adapter->vcp_info[i].pid; + video_info->width[i] = adapter->vcp_info[i].DecodeWidth; + video_info->height[i] = adapter->vcp_info[i].DecodeHeight; + video_info->TotalDecodeFrameNum[i] = adapter->vcp_info[i].TotalDecodeFrameNum; + video_info->TotalRenderFrameNum[i] = adapter->vcp_info[i].TotalRenderFrameNum; + switch(adapter->vcp_info[i].DecodeApi) + { + case 0: + gf_strncpy(video_info->decodeapi[i], "VAAPI", gf_strlen("VAAPI")); + break; + case 1: + gf_strncpy(video_info->decodeapi[i], "VDPAU", gf_strlen("VDPAU")); + break; + } + + switch(adapter->vcp_info[i].PresentApi) + { + case 1: + gf_strncpy(video_info->presentapi[i], "VAAPI", gf_strlen("VAAPI")); + break; + case 2: + gf_strncpy(video_info->presentapi[i], "VDPAU", gf_strlen("VDPAU")); + break; + case 3: + gf_strncpy(video_info->presentapi[i], "GPU", gf_strlen("GPU")); + break; + default: + gf_strncpy(video_info->presentapi[i], "UNKNOW", gf_strlen("UNKNOW")); + break; + } + + switch(adapter->vcp_info[i].dwDecodeType) + { + case 128: + gf_strncpy(video_info->codec[i], "H264ENC", gf_strlen("H264ENC")); + break; + case 134: + gf_strncpy(video_info->codec[i], "HEVCENC", gf_strlen("HEVCENC")); + break; + case 132: + gf_strncpy(video_info->codec[i], "JPEGENC", gf_strlen("JPEGENC")); + break; + case 0: + gf_strncpy(video_info->codec[i], "MPEG2", gf_strlen("MPEG2")); + break; + case 1: + gf_strncpy(video_info->codec[i], "MPEG4", gf_strlen("MPEG4")); + break; + case 2: + gf_strncpy(video_info->codec[i], "VC1/WMV9", gf_strlen("VC1/WMV9")); + break; + case 3: + gf_strncpy(video_info->codec[i], "H264CAVLC", gf_strlen("H264CAVLC")); + break; + case 4: + gf_strncpy(video_info->codec[i], "H264CABAC", gf_strlen("H264CABAC")); + break; + case 5: + gf_strncpy(video_info->codec[i], "AVS", gf_strlen("AVS")); + break; + case 7: + gf_strncpy(video_info->codec[i], "VP8", gf_strlen("VP8")); + break; + case 9: + gf_strncpy(video_info->codec[i], "JPEG", gf_strlen("JPEG")); + break; + case 10: + gf_strncpy(video_info->codec[i], "HEVC", gf_strlen("HEVC")); + break; + case 11: + gf_strncpy(video_info->codec[i], "H263", gf_strlen("H263")); + break; + case 13: + gf_strncpy(video_info->codec[i], "AVS2", gf_strlen("AVS2")); + break; + default: + gf_strncpy(video_info->codec[i], "UNKNOWN", gf_strlen("UNKNOWN")); + break; + } + + gf_get_nsecs(&time); + if (last_time[i] == 0) //first time + { + last_time[i] = time; + frame_num[i] = adapter->vcp_info[i].TotalRenderFrameNum; + bit_size[i] = adapter->vcp_info[i].TotalBitstreamSize; + video_info->bitrate[i] = 0; + video_info->presentspeed[i] = 0; + last_decodetime[i] = adapter->vcp_info[i].TotalDecodetime; + decode_framenum[i] = adapter->vcp_info[i].TotalDecodeFrameNum; + return ret; + } + interval_ms = (time - last_time[i]) / 1000000; + if (interval_ms < 1 || adapter->vcp_info[i].TotalDecodetime == last_decodetime[i]) return 0; // + video_info->presentspeed[i] = (adapter->vcp_info[i].TotalRenderFrameNum - frame_num[i]) * 1000 / interval_ms; + video_info->decodespeed[i] = (adapter->vcp_info[i].TotalDecodeFrameNum - decode_framenum[i]) * 1000 /(adapter->vcp_info[i].TotalDecodetime -last_decodetime[i]); + video_info->bitrate[i] = (adapter->vcp_info[i].TotalBitstreamSize - bit_size[i]) * 8 * 1000/ interval_ms / 1024; + last_time[i] = time; + frame_num[i] = adapter->vcp_info[i].TotalRenderFrameNum; + bit_size[i] = adapter->vcp_info[i].TotalBitstreamSize; + last_decodetime[i] = adapter->vcp_info[i].TotalDecodetime; + decode_framenum[i] = adapter->vcp_info[i].TotalDecodeFrameNum; + + //gf_info("---presentspeed = %d, bitrate %d kbit/s, pid %d\n", video_info->presentspeed[i], video_info->bitrate[i], video_info->pid[i]); + return ret; +} diff --git a/drivers/gpu/drm/arise/core/perfevent/perfevent.h b/drivers/gpu/drm/arise/core/perfevent/perfevent.h new file mode 100755 index 0000000000000..807b429b180d2 --- /dev/null +++ b/drivers/gpu/drm/arise/core/perfevent/perfevent.h @@ -0,0 +1,50 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __PERF_EVENT_H__ +#define __PERF_EVENT_H__ + +#include "gf_def.h" + +extern int perf_event_init(adapter_t *adapter); +extern int perf_event_deinit(adapter_t *adapter); +extern int perf_event_begin(adapter_t *adapter, gf_begin_perf_event_t *begin); +extern int perf_event_end(adapter_t *adapter, gf_end_perf_event_t *end); +extern int perf_event_add_event(adapter_t *adapter, gf_perf_event_t *perf_event); +extern int perf_event_get_event(adapter_t *adapter, gf_get_perf_event_t *get_perf_event); +extern int perf_event_get_status(adapter_t *adapter, gf_perf_status_t *get_status); +extern int perf_event_add_isr_event(adapter_t *adapter, gf_perf_event_t *perf_event); +extern int perf_event_get_isr_event(adapter_t *adapter, gf_get_perf_event_t *get_perf_event); + +extern int perf_event_begin_miu_dump(adapter_t *adapter, gf_begin_miu_dump_perf_event_t *miu_begin); +extern int perf_event_end_miu_dump(adapter_t *adapter, gf_end_miu_dump_perf_event_t *miu_end); +extern int perf_event_set_miu_reg_list(adapter_t *adapter, gf_miu_reg_list_perf_event_t *miu_reg_list); +extern int perf_event_add_miu_event(adapter_t *adapter, unsigned int gpu_context, unsigned long long task_id, unsigned long long fence_id, int task_end); +extern int perf_event_get_miu_event(adapter_t *adapter, gf_get_miu_dump_perf_event_t *get_miu_perf_event); +extern int perf_event_util_miu_counter_dump(adapter_t *adapter, gf_miu_list_item_t *miu_list, unsigned int list_length, int fore_read); +extern int perf_event_direct_get_miu_dump_event(adapter_t *adapter, gf_direct_get_miu_dump_perf_event_t *current_miu); + +extern int gf_hwq_event_init(adapter_t *adapter); +extern int gf_hwq_event_deinit(adapter_t *adapter); +extern int hwq_process_complete_event(adapter_t *adapter, unsigned long long time, unsigned int fence_id,unsigned int engine); +extern int hwq_process_submit_event(adapter_t *adapter, unsigned long long time, unsigned int fence_id,unsigned int engine); +extern int hwq_process_vsync_event(adapter_t *adapter, unsigned long long time); + + +extern int hwq_get_hwq_info(void *adp,gf_hwq_info *hwq_info); +extern int hwq_get_video_info(void *adp, gf_video_info *video_info); +extern int hwq_get_hwq_info_ext(adapter_t *adapter,gfx_hwq_info_ext *phwq_info_ext); + +#endif + diff --git a/drivers/gpu/drm/arise/core/perfevent/perfeventi.h b/drivers/gpu/drm/arise/core/perfevent/perfeventi.h new file mode 100644 index 0000000000000..2d6783f4c81e9 --- /dev/null +++ b/drivers/gpu/drm/arise/core/perfevent/perfeventi.h @@ -0,0 +1,108 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __PERF_EVENTI_H__ +#define __PERF_EVENTI_H__ + +#include "gf_adapter.h" +#include "gf_def.h" +#include "list.h" + + +typedef struct _perf_chip_func +{ + int (*direct_get_miu_counter)(adapter_t *adapter, gf_miu_list_item_t *miu_table, unsigned int miu_table_length,int force_read); + int (*calculate_engine_usage)(adapter_t *, gf_hwq_info *); + int (*calculate_engine_usage_ext)(adapter_t *, gfx_hwq_info_ext *); +}perf_chip_func_t; + +extern perf_chip_func_t perf_chip_func; + +typedef struct _perf_event_node +{ + struct list_head list_node; + gf_perf_event_header_t perf_event; +}perf_event_node; + +typedef struct _perf_event_mgr +{ + int perf_started; + + struct list_head event_list; + int event_number; + int max_event_number; + int lost_event_number; + unsigned long long lost_event_time; + struct os_spinlock *event_list_lock; + + char *isr_event_buffer; + int isr_event_tail; //offset in bytes + int isr_event_head; //offset in bytes + int isr_event_buffer_size; //size in bytes + int isr_event_num; + struct os_spinlock *isr_event_lock; + + gf_miu_list_item_t *miu_table; + unsigned int miu_table_length; + struct os_spinlock *miu_table_lock; + + struct list_head miu_event_list; + unsigned int miu_event_number; + unsigned int miu_max_event_number; + unsigned int miu_lost_event_number; + unsigned long long miu_lost_event_time; + struct os_spinlock *miu_event_list_lock; + + perf_chip_func_t *chip_func; + +}perf_event_mgr_t; + +#define ENGINE_NONE 0x0 +#define ENGINE_IDLE 0x1 +#define ENGINE_BUSY 0x2 + typedef struct engine_status +{ + unsigned int active :1; + unsigned int status :2; + unsigned int reserved :29; +}engine_status_t; + + +typedef struct _hwq_event_info +{ + + unsigned int submit_fence_id; + unsigned int complete_fence_id; + unsigned long long last_busy2idletime; + + engine_status_t engine_status; + + unsigned long long idle_time; + unsigned long long engine_usage; + + +}hwq_event_info; + + +typedef struct _hwq_event_mgr +{ + int hwq_started; + unsigned long long start_time; + unsigned long long sample_time; + + hwq_event_info *hwq_event; +}hwq_event_mgr_t; + +#endif + diff --git a/drivers/gpu/drm/arise/core/powermgr/powermgr.c b/drivers/gpu/drm/arise/core/powermgr/powermgr.c new file mode 100644 index 0000000000000..d69239908b4f2 --- /dev/null +++ b/drivers/gpu/drm/arise/core/powermgr/powermgr.c @@ -0,0 +1,84 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidmm.h" +#include "context.h" +#include "global.h" +#include "powermgr.h" + +int pm_save_state(adapter_t *adapter, int need_save_memory) +{ + int ret = S_OK; + + adapter->in_suspend_resume = TRUE; + + ret = cm_save(adapter, need_save_memory); + + if (ret != S_OK) + { + return ret; + } + + ret = vidsch_save(adapter); + + if (ret != S_OK) + { + return ret; + } + + ret = vidmm_save(adapter); + + adapter->in_suspend_resume = FALSE; + + return ret; + /* system will suspend, set our card mode as uninitialize */ +} + + +//temp use only, will remove after resume stable. +static inline void util_print_time(char *info) +{ + long time_sec = 0, time_usec = 0; + + gf_getsecs(&time_sec, &time_usec); + gf_info("%s %ld(ms)\n",info,(time_sec * 1000 + gf_do_div(time_usec, 1000))); +} + +int pm_restore_state(adapter_t *adapter) +{ + int ret = S_OK; + + adapter->in_suspend_resume = TRUE; + + //temp use only, will remove all this function called after resume stable. + util_print_time("pm_restore_state enter, cur time"); + + glb_init_chip_interface(adapter); + util_print_time("glb_init_chip_interface finish, cur time"); + + vidmm_restore(adapter); + util_print_time("vidmm_restore finish, cur time"); + + vidsch_restore(adapter); + util_print_time("vidsch_restore finish, cur time"); + + cm_restore(adapter); + util_print_time("cm_restore finish, cur time"); + + adapter->in_suspend_resume = FALSE; + + return ret; +} diff --git a/drivers/gpu/drm/arise/core/powermgr/powermgr.h b/drivers/gpu/drm/arise/core/powermgr/powermgr.h new file mode 100644 index 0000000000000..cc0a36fa453f3 --- /dev/null +++ b/drivers/gpu/drm/arise/core/powermgr/powermgr.h @@ -0,0 +1,21 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __POWER_MGR_H__ +#define __POWER_MGR_H__ + +int pm_save_state(adapter_t *adapter, int need_save_memory); +int pm_restore_state(adapter_t *adapter); + +#endif diff --git a/drivers/gpu/drm/arise/core/util/bit_op.h b/drivers/gpu/drm/arise/core/util/bit_op.h new file mode 100644 index 0000000000000..61a7231b98222 --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/bit_op.h @@ -0,0 +1,306 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +#ifndef _BIT_OPERATROR_H_ +#define _BIT_OPERATROR_H_ + + +#ifndef __GNUC__ +#error "This is only for GCC" +#endif + +#define VERIFY_BIT_OP 0 + + +static __inline__ unsigned char _BitScanForward(volatile unsigned int *Index, unsigned int Mask) +{ + +#if VERIFY_BIT_OP + unsigned int mask_range = Mask; +#endif + if(Mask==0) + { + return 0; + } +#if defined(__i386__) || defined(__x86_64__) + __asm__ __volatile__( + "bsfl %1, %0" + :"=r"(Mask) + :"r" (Mask) + ); +#else + Mask = __builtin_ffs(Mask)-1; +#endif + *Index = Mask; + + + +#if VERIFY_BIT_OP + { + unsigned int i = 32; + //find the set bit from lsb +#if __BIG_ENDIAN__ + for(i=31; i>=0; i--) + { + if(mask_range & (1<=0; i--) + { + if(mask_range & (1<> b) & 1); + + __asm__ __volatile__( + "btrl %1,%0" + :"=m"(*(a)) + :"r"(b) + ); + + return ret; +#else + int c = *a; + (*a) &= ~(1< +static __inline__ int constant_test_bit(int nr, const volatile unsigned int *addr) +{ + return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0; +} + +static __inline__ int variable_test_bit(int nr, const volatile unsigned int * addr) +{ + int oldbit; +#if defined(__i386__) || defined(__x86_64__) + __asm__ __volatile__( + "btl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit) + :"m" (*(addr)),"Ir" (nr)); +#else + if((*addr) & ( 1 << (nr&31))) + { + oldbit = 1; + } + else + { + oldbit = 0; + } + +#endif + return oldbit; +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + constant_test_bit((nr),(addr)) : \ + variable_test_bit((nr),(addr))) + + +static __inline__ int __test_and_set_bit(int nr, volatile unsigned int * addr) +{ + int oldbit; +#if defined(__i386__) || defined(__x86_64__) + __asm__ __volatile__( + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"+m" (*(addr)) + :"Ir" (nr)); +#else + if( (*addr) & (1 <<(nr&31))) + { + oldbit = 1; + } + else + { + (*addr) |= (1 <<(nr&31)); + oldbit = 0; + } + +#endif + return oldbit; +} + +static __inline__ unsigned char _bittest(int *a, int b) +{ + + return (unsigned char)test_bit(b, (volatile unsigned int *)a); +} + +static __inline__ unsigned char _bittestandset(int *a, int b) +{ + + return (unsigned char)__test_and_set_bit(b, (volatile unsigned int *)a); +} + +#endif + +#endif diff --git a/drivers/gpu/drm/arise/core/util/handle_manager.c b/drivers/gpu/drm/arise/core/util/handle_manager.c new file mode 100644 index 0000000000000..ec1c72bb2ceac --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/handle_manager.c @@ -0,0 +1,129 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "handle_manager.h" + +#define MAX_HANDLE (65536 * 4) + +int handle_mgr_create(handle_mgr_t *handle_mgr) +{ + long *table = NULL; + + table = gf_calloc(MAX_HANDLE * sizeof(long)); + + if(table == NULL) + { + return E_OUTOFMEMORY; + } + + handle_mgr->max_handle = MAX_HANDLE; + handle_mgr->table = table; + handle_mgr->left_num = handle_mgr->max_handle - 1; + handle_mgr->free_start = 1; + + handle_mgr->bitmap_lock = gf_create_spinlock(0); + handle_mgr->bitmap_size = handle_mgr->max_handle >> 3; + handle_mgr->bitmap = gf_calloc(handle_mgr->bitmap_size); + + gf_set_bit(0, handle_mgr->bitmap); // 0 will not used + + return S_OK; +} + +void handle_mgr_destroy(handle_mgr_t *handle_mgr) +{ + if(handle_mgr->table) + { + gf_free(handle_mgr->table); + + handle_mgr->max_handle = 0; + handle_mgr->table = NULL; + } + + gf_free(handle_mgr->bitmap); + + gf_destroy_spinlock(handle_mgr->bitmap_lock); +} + +unsigned int add_handle(handle_mgr_t *handle_mgr, unsigned int type, void *data) +{ + int index = 0; + unsigned int new_handle = 0; + long *table; + unsigned long flags; + + flags = gf_spin_lock_irqsave(handle_mgr->bitmap_lock); + + table = handle_mgr->table; + + index = gf_find_next_zero_bit(handle_mgr->bitmap, handle_mgr->max_handle, handle_mgr->free_start); + + if(index < handle_mgr->max_handle) + { + gf_set_bit(index, handle_mgr->bitmap); + + handle_mgr->left_num--; + handle_mgr->free_start = (index + 1) % handle_mgr->max_handle; + table[index] = (long)data; + new_handle = index | (type << 24); + } + else + { + gf_info("no enough handle, left_num %d max_handle:%d.\n", handle_mgr->left_num, handle_mgr->max_handle); + gf_assert(0, "no enough handle"); + } + + gf_spin_unlock_irqrestore(handle_mgr->bitmap_lock, flags); + + return new_handle; +} + +void *get_from_handle_and_validate(handle_mgr_t *handle_mgr, unsigned int handle, unsigned int type) +{ + void *ptr = NULL; + + if((handle & 0xFF000000) == (type << 24)) + { + ptr = get_from_handle(handle_mgr, handle); + } + + return ptr; +} + +void remove_handle(handle_mgr_t *handle_mgr, unsigned int handle) +{ + long *table = NULL; + unsigned int index = handle & 0x00FFFFFF; + unsigned long flags; + + flags = gf_spin_lock_irqsave(handle_mgr->bitmap_lock); + + table = handle_mgr->table; + + if(index < handle_mgr->max_handle) + { + handle_mgr->left_num++; + + gf_clear_bit(index, handle_mgr->bitmap); + table[index] = 0; + } + else + { + gf_info("unknow handle: handle: %x, max_handle:%d.\n", handle, handle_mgr->max_handle); + gf_assert(0, "unknow handle"); + } + + gf_spin_unlock_irqrestore(handle_mgr->bitmap_lock, flags); +} + diff --git a/drivers/gpu/drm/arise/core/util/handle_manager.h b/drivers/gpu/drm/arise/core/util/handle_manager.h new file mode 100644 index 0000000000000..9ae5857615206 --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/handle_manager.h @@ -0,0 +1,73 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __HANDLE_MANAGER_H__ +#define __HANDLE_MANAGER_H__ + +#include "core_errno.h" +#include "core_import.h" + +#define HDL_TYPE_ADAPTER 0x01 +#define HDL_TYPE_DEVICE 0x02 +#define HDL_TYPE_CONTEXT 0x03 +#define HDL_TYPE_RESOURCE 0x04 +#define HDL_TYPE_ALLOCATION 0x05 +#define HDL_TYPE_SYNC_OBJ 0x06 +#define HDL_TYPE_OVERLAY 0x07 +#define HDL_TYPE_CAPTURE 0x08 +#define HDL_TYPE_STREAM 0x09 +#define HDL_TYPE_DI_CONTEXT 0x0a + +typedef struct handle_mgr +{ + unsigned int max_handle; + long *table; + + unsigned int left_num; + int free_start; + + struct os_spinlock *bitmap_lock; + unsigned long *bitmap; + unsigned int bitmap_size; +} handle_mgr_t; + + +static inline void *get_from_handle(handle_mgr_t *handle_mgr, unsigned int handle) +{ + void *data = NULL; + unsigned int index = handle & 0x00FFFFFF; + + /* NOTE: currenly handle mgr impl by bitmap, and the table/bitmap preallocated, + * so the only need lock is search zero bit in bitmap, no need lock here + */ + + //flags = gf_spin_lock_irqsave(handle_mgr->bitmap_lock); + + if(index > 0 && index < handle_mgr->max_handle) + { + data = (void *)handle_mgr->table[index]; + } + + //gf_spin_unlock_irqrestore(handle_mgr->bitmap_lock, flags); + + return data; +} + +extern int handle_mgr_create(handle_mgr_t *handle_mgr); +extern void handle_mgr_destroy(handle_mgr_t *handle_mgr); +extern unsigned int add_handle(handle_mgr_t *handle_mgr, unsigned int, void *data); +extern void *get_from_handle_and_validate(handle_mgr_t *handle_mgr, unsigned int handle, unsigned int type); +extern void remove_handle(handle_mgr_t *handle_mgr, unsigned int handle); + +#endif diff --git a/drivers/gpu/drm/arise/core/util/heap_manager.c b/drivers/gpu/drm/arise/core/util/heap_manager.c new file mode 100644 index 0000000000000..cd522fd6a808b --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/heap_manager.c @@ -0,0 +1,344 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "heap_manager.h" +#include "core_import.h" +#include "util.h" + + +static void heap_internal_dump(heap_t *heap, list_node_t *list_node, list_node_t *prev_node, list_node_t *next_node); + + +static void heap_remove_node_from_list(heap_t *heap, list_head_t *list, list_node_t *list_node) +{ + list_del(&list_node->list_item); + + list->size -= list_node->size; + list->num--; + + list_node->list_item.prev = NULL; + list_node->list_item.next = NULL; +} + +static void heap_add_node_to_list(heap_t *heap, list_head_t *list, list_node_t *list_node) +{ + if(list->order) + { + list_node_t *next = NULL; + + list_for_each_entry(next, &list->list, list_item) + { + if(next->size > list_node->size) + { + break; + } + } + + list_add(&list_node->list_item, next->list_item.prev); + } + else + { + list_add_tail(&list_node->list_item, &list->list); + } + + list->size += list_node->size; + list->num++; +} + +int heap_init(heap_t *heap, int id, unsigned long long start, unsigned long long size, unsigned int alignment) +{ + list_node_t *new_node = NULL; + int result = S_OK; + + gf_memset(heap, 0, sizeof(heap_t)); + + heap->id = id; + heap->size = size; + heap->start = start; + heap->alignment = alignment; + heap->lock = gf_create_mutex(); + + list_init_head(&heap->free.list); + + heap->free.order = TRUE; //order by size increase + + list_init_head(&heap->inuse.list); + + heap->inuse.order = FALSE; + + new_node = gf_calloc(sizeof(list_node_t)); + + if(NULL != new_node) + { + new_node->size = size; + new_node->offset = start; + + heap_add_node_to_list(heap, &heap->free, new_node); + } + else + { + gf_destroy_mutex(heap->lock); + + gf_memset(heap, 0, sizeof(heap_t)); + + result = E_FAIL; + } + + gf_debug("heap[%X]:%p, range [0x%llx -> 0x%llx), size: %dk, alignment: %08x.\n", + heap->id, heap, start, start + size, size >> 10, alignment); + + return result; +} + +void heap_destroy(heap_t *heap) +{ + if(heap->free.num == 1) + { + list_node_t *node = list_entry(heap->free.list.next, list_node_t, list_item); + + list_del(&node->list_item); + + gf_free(node); + } + else + { + gf_info("heap[%x], not merged. something wrong.\n", heap->id); + } + + gf_destroy_mutex(heap->lock); + + gf_memset(heap, 0, sizeof(heap_t)); +} + +//heap allocate will not large than 4G +list_node_t *heap_allocate(heap_t *heap, unsigned int size, unsigned int alignment, unsigned int direction) +{ + list_node_t *new_node = NULL; + list_node_t *free_node = NULL; + + unsigned long long start_alignment = util_max(alignment, heap->alignment); + unsigned long long aligned_mask = ~(start_alignment - 1); //set to long long int to avoid offset aligh cut of 64bits to 32bits + unsigned int aligned_size = util_align(size, heap->alignment); + unsigned long long aligned_offset; + unsigned int alloc_size = 0; // the size of the node, actually allocated size. + unsigned long long alloc_offset; // the offset of the node, actually offset. + + int found = FALSE; + + if(aligned_size == 0) + { + gf_warning("%s, invalidate allocate size: %d.\n", __func__, size); + +#ifdef _DEBUG_ + gf_dump_stack(); +#endif + + return NULL; + } + + gf_mutex_lock(heap->lock); + + if(aligned_size > heap->free.size) + { + goto __quit; + } + + list_for_each_entry(free_node, &heap->free.list, list_item) + { + if(aligned_size > free_node->size) + { + continue; + } + + if(direction) + { + aligned_offset = (free_node->offset + free_node->size - aligned_size) & aligned_mask; + + if(aligned_offset >= free_node->offset) + { + alloc_offset = aligned_offset; + alloc_size = (free_node->offset + free_node->size) - alloc_offset; + + found = TRUE; + break; + } + } + else + { + aligned_offset = util_align(free_node->offset, start_alignment); + + if((aligned_offset + aligned_size) <= (free_node->size + free_node->offset)) + { + alloc_offset = free_node->offset; + alloc_size = aligned_size + aligned_offset - free_node->offset; + + found = TRUE; + break; + } + } + } + + if(found) + { + heap_remove_node_from_list(heap, &heap->free, free_node); + + if(free_node->size == alloc_size) + { + new_node = free_node; + } + else + { + if(!direction) + { + free_node->offset += alloc_size; + } + + free_node->size -= alloc_size; + + heap_add_node_to_list(heap, &heap->free, free_node); + + new_node = gf_calloc(sizeof(list_node_t)); + } + + if(new_node) + { + new_node->aligned_offset = aligned_offset; + new_node->aligned_size = aligned_size; + new_node->offset = alloc_offset; + new_node->size = alloc_size; + + heap_add_node_to_list(heap, &heap->inuse, new_node); + + gf_assert(new_node->size >= size, "new_node->size >= size"); + } + else + { + gf_error("calloc failed for new_node.\n"); + } + } + +__quit: + gf_mutex_unlock(heap->lock); + + return new_node; +} + +void heap_release(heap_t *heap, list_node_t *list_node) +{ + list_node_t *prev = NULL; + list_node_t *next = NULL; + list_node_t *temp_node = NULL; + + unsigned long long upper; + unsigned long long lower; + + gf_mutex_lock(heap->lock); + + heap_remove_node_from_list(heap, &heap->inuse, list_node); + + upper = list_node->offset + list_node->size; + lower = list_node->offset; + + list_for_each_entry(temp_node, &heap->free.list, list_item) + { + if(!prev && ((temp_node->offset + temp_node->size) == lower)) + { + prev = temp_node; + } + + if(!next && (temp_node->offset == upper)) + { + next = temp_node; + } + + if(prev && next) + { + break; + } + } + + if(prev != NULL) + { + list_node->size += prev->size; + list_node->offset = prev->offset; + + heap_remove_node_from_list(heap, &heap->free, prev); + + gf_free(prev); + } + + if(next != NULL) + { + list_node->size += next->size; + + heap_remove_node_from_list(heap, &heap->free, next); + + gf_free(next); + } + + heap_add_node_to_list(heap, &heap->free, list_node); + + gf_mutex_unlock(heap->lock); +} + +static void heap_list_dump(heap_t *heap, list_head_t *list, const char *desc) +{ + list_node_t *node = NULL; + + int i = 0; + + gf_info("%s, node_num: %d, node_size: 0x%llx.\n", desc, list->num, list->size); + + list_for_each_entry(node, &list->list, list_item) + { + gf_info("node[%04x]: %p, prev: %p, next: %p, offset: %llX-%llX, size: %llX-%llX\n", + i++, node, node->list_item.prev, node->list_item.next, node->offset, node->aligned_offset, node->size, node->aligned_size); + } +} + +static void heap_internal_dump(heap_t *heap, list_node_t *list_node, list_node_t *prev_node, list_node_t *next_node) +{ + gf_info("******* node: %p, prev: %p, next: %p.\n", list_node, prev_node, next_node); + + if(list_node != NULL) + { + gf_info("list_node: %p, size: %llx, offset: %llx.\n", list_node, list_node->size, list_node->offset); + } + + if(prev_node != NULL) + { + gf_info("prev_node: %p, size: %llx, offset: %llx.\n", prev_node, prev_node->size, prev_node->offset); + } + + if(next_node != NULL) + { + gf_info("next_node: %p, size: %llx, offset: %llx.\n", next_node, next_node->size, next_node->offset); + } + + gf_info("###Heap[%2x]: %p: Size: %llX.\n", heap->id, heap, heap->size); + + heap_list_dump(heap, &heap->inuse, "**inused list"); + + heap_list_dump(heap, &heap->free, "**free list"); +} + +void heap_dump(heap_t *heap) +{ + gf_mutex_lock(heap->lock); + + heap_internal_dump(heap, NULL, NULL, NULL); + + gf_mutex_unlock(heap->lock); +} + diff --git a/drivers/gpu/drm/arise/core/util/heap_manager.h b/drivers/gpu/drm/arise/core/util/heap_manager.h new file mode 100644 index 0000000000000..925b20b656789 --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/heap_manager.h @@ -0,0 +1,58 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __HEAP_MANAGER_H__ +#define __HEAP_MANAGER_H__ + +#include "core_errno.h" +#include "list.h" + +typedef struct _list_node +{ + struct list_head list_item; + unsigned long long size; // Available Size, this node occupied space + unsigned long long offset; // Actual offset from start of heap + unsigned long long aligned_offset; // Aligned offset, offset that will be used + unsigned long long aligned_size; // Aligned size, the size that will be used +} list_node_t; + +typedef struct _list_head +{ + struct list_head list; + unsigned long long size; + int num; + int order; +} list_head_t; + +typedef struct _heap +{ + int id; + unsigned long long size; + unsigned long long start; + unsigned int alignment; + list_head_t free; + list_head_t inuse; + + struct os_mutex *lock; +} heap_t; + + +int heap_init(heap_t *heap, int id, unsigned long long start, unsigned long long size, unsigned int alignment); +void heap_destroy(heap_t *heap); +list_node_t * heap_allocate(heap_t *heap, unsigned int size, unsigned int alignment, unsigned int direction); +void heap_release(heap_t *heap, list_node_t *list_node); +void heap_dump(heap_t *heap); + +#endif + diff --git a/drivers/gpu/drm/arise/core/util/list.h b/drivers/gpu/drm/arise/core/util/list.h new file mode 100644 index 0000000000000..88362844ebcb9 --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/list.h @@ -0,0 +1,231 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __LIST_H +#define __LIST_H + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((long) &((TYPE *)0)->MEMBER) +#endif + +#define container_of(ptr, sample, member) \ + (void *)((char *)(ptr) - ((char *)&(sample)->member - (char *)(sample))) + + +struct list_head +{ + struct list_head *prev; + struct list_head *next; +}; + +static inline void list_init_head(struct list_head *item) +{ + item->prev = item; + item->next = item; +} + +#define INIT_LIST_HEAD list_init_head + +static inline void list_add(struct list_head *item, struct list_head *list) +{ + item->prev = list; + item->next = list->next; + list->next->prev = item; + list->next = item; +} + +static inline void list_add_tail(struct list_head *item, struct list_head *list) +{ + item->next = list; + item->prev = list->prev; + list->prev->next = item; + list->prev = item; +} + +static inline void list_replace(struct list_head *from, struct list_head *to) +{ + to->prev = from->prev; + to->next = from->next; + from->next->prev = to; + from->prev->next = to; +} + +static inline void list_del(struct list_head *item) +{ + item->prev->next = item->next; + item->next->prev = item->prev; + item->next = item->prev = NULL; +} + +static inline void list_del_init(struct list_head *item) +{ + item->prev->next = item->next; + item->next->prev = item->prev; + item->next = item; + item->prev = item; +} + +static inline int list_empty(struct list_head *item) +{ + return (item->next == item); +} + +/** + * list_is_last - tests whether @list is the last entry in list @head + * @list: the entry to test + * @head: the head of the list + */ +static inline int list_is_last(struct list_head *list, + struct list_head *head) +{ + return list->next == head; +} + + +static inline void __list_splice(struct list_head *list, + struct list_head *prev, + struct list_head *next) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + +/** + * list_splice - join two lists, this is designed for stacks + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head, head->next); +} + +/** + * list_splice_tail - join two lists, each list being a queue + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice_tail(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head->prev, head); +} + +/** + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head, head->next); + INIT_LIST_HEAD(list); + } +} + +/** + * list_splice_tail_init - join two lists and reinitialise the emptied list + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * Each of the lists is a queue. + * The list at @list is reinitialised + */ +static inline void list_splice_tail_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head->prev, head); + INIT_LIST_HEAD(list); + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + ((type *)((char *)(ptr) - offsetof(type, member))) + +/** + * list_first_entry - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +/** + * list_first_entry_or_null - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note that if the list is empty, it returns NULL. + */ +#define list_first_entry_or_null(ptr, type, member) \ + (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL) + + +#define list_for_each_entry(pos, head, member) \ + for (pos = container_of((head)->next, pos, member); \ + &pos->member != (head); \ + pos = container_of(pos->member.next, pos, member)) + +#define list_for_each_entry_safe(pos, storage, head, member) \ + for (pos = container_of((head)->next, pos, member), \ + storage = container_of(pos->member.next, pos, member); \ + &pos->member != (head); \ + pos = storage, storage = container_of(storage->member.next, storage, member)) + +#define list_for_each_entry_safe_rev(pos, storage, head, member)\ + for (pos = container_of((head)->prev, pos, member), \ + storage = container_of(pos->member.prev, pos, member); \ + &pos->member != (head); \ + pos = storage, storage = container_of(storage->member.prev, storage, member)) + +#define list_for_each_entry_from(pos, start, head, member) \ + for (pos = container_of((start), pos, member); \ + &pos->member != (head); \ + pos = container_of(pos->member.next, pos, member)) + +#define list_for_each_entry_from_rev(pos, start, head, member) \ + for (pos = container_of((start), pos, member); \ + &pos->member != (head); \ + pos = container_of(pos->member.prev, pos, member)) + +#endif + diff --git a/drivers/gpu/drm/arise/core/util/queue.c b/drivers/gpu/drm/arise/core/util/queue.c new file mode 100644 index 0000000000000..07621bf9e323c --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/queue.c @@ -0,0 +1,197 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "queue.h" +#include "core_import.h" + +#define calc_cyc_num(num) (num) % queue->entry_num + +int queue_init(queue_t *queue, int entry_num, int data_size) +{ + int size = (data_size + 7) & ~7; + void *entrys = gf_calloc(entry_num * size); + int status = QUEUE_SUCCESS; + + if(entrys == NULL) + { + return QUEUE_FAIL; + } + + queue->entrys = entrys; + queue->entry_size = size; + queue->data_size = data_size; + queue->entry_num = entry_num; + queue->lock = gf_create_spinlock(0); + + return status; +} + +void queue_fini(queue_t *queue) +{ + if(queue->lock) + { + gf_destroy_spinlock(queue->lock); + } + + if(queue->entrys) + { + gf_free(queue->entrys); + } +} + +void queue_query_info(queue_t *queue, int *start, int *inuse_num) +{ + unsigned long flags; + + flags = gf_spin_lock_irqsave(queue->lock); + + if(start) + { + *start = queue->start; + } + + if(inuse_num) + { + *inuse_num = queue->entry_inuse; + } + + gf_spin_unlock_irqrestore(queue->lock, flags); +} + +int queue_add_entry(queue_t *queue, void *data) +{ + void *entry = NULL; + int status = QUEUE_FULL; + unsigned long flags; + + flags = gf_spin_lock_irqsave(queue->lock); + + if(queue->entry_inuse < queue->entry_num) + { + entry = queue->entrys + calc_cyc_num(queue->start + queue->entry_inuse) * queue->entry_size; + + gf_memcpy(entry, data, queue->data_size); + + queue->entry_inuse++; + + status = QUEUE_SUCCESS; + } + else + { + gf_error("add entry to a full queue. \n"); + } + + gf_spin_unlock_irqrestore(queue->lock, flags); + + return status; +} + +int queue_get_first_entry(queue_t *queue, void *data) +{ + int status = QUEUE_EMPTY; + void *entry = NULL; + unsigned long flags; + + flags = gf_spin_lock_irqsave(queue->lock); + + if(queue->entry_inuse > 0) + { + entry = queue->entrys + queue->start * queue->entry_size; + + gf_memcpy(data, entry, queue->data_size); + + status = QUEUE_SUCCESS; + } + + gf_spin_unlock_irqrestore(queue->lock, flags); + + return status; +} + +int queue_get_first_entry_and_free(queue_t *queue, void *data) +{ + int status = QUEUE_EMPTY; + void *entry = NULL; + unsigned long flags; + + flags = gf_spin_lock_irqsave(queue->lock); + + if(queue->entry_inuse > 0) + { + entry = queue->entrys + queue->start * queue->entry_size; + + queue->start = calc_cyc_num(queue->start + 1); + + queue->entry_inuse--; + + gf_memcpy(data, entry, queue->data_size); + + status = QUEUE_SUCCESS; + } + + gf_spin_unlock_irqrestore(queue->lock, flags); + + return status; +} + +int queue_get_entry(queue_t *queue, int num, void *data) +{ + int status = QUEUE_SUCCESS; + int index = 0; + void *entry = NULL; + unsigned long flags; + + flags = gf_spin_lock_irqsave(queue->lock); + + index = calc_cyc_num(num); + entry = queue->entrys + queue->entry_size * index; + + gf_memcpy(data, entry, queue->data_size); + + gf_spin_unlock_irqrestore(queue->lock, flags); + + return status; +} + +int queue_free_entry(queue_t *queue, int num) +{ + int i, privous_cnt = 0; + void *src, *dst; + unsigned long flags; + + flags = gf_spin_lock_irqsave(queue->lock); + + privous_cnt = calc_cyc_num(num - queue->start); + + for(i = privous_cnt; i > 0; i--) + { + src = queue->entrys + calc_cyc_num(queue->start + i - 1 ) * queue->entry_size; + dst = queue->entrys + calc_cyc_num(queue->start + i ) * queue->entry_size; + + gf_memcpy(dst, src, queue->data_size); + } + + queue->start = calc_cyc_num(queue->start + 1); + + queue->entry_inuse--; + + gf_spin_unlock_irqrestore(queue->lock, flags); + + return QUEUE_SUCCESS; +} + + + + + diff --git a/drivers/gpu/drm/arise/core/util/queue.h b/drivers/gpu/drm/arise/core/util/queue.h new file mode 100644 index 0000000000000..5f203f55ebac4 --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/queue.h @@ -0,0 +1,49 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __QUEUE_H_ +#define __QUEUE_H_ + + +#define QUEUE_SUCCESS 0 +#define QUEUE_FAIL 1 +#define QUEUE_FULL 2 +#define QUEUE_EMPTY 3 + + + +typedef struct +{ + int entry_num; + int entry_size; + int data_size; + int entry_inuse; + int start; +// int end; + + struct os_spinlock *lock; + char *entrys; +}queue_t; + +extern int queue_init(queue_t *queue, int entry_num, int entry_size); +extern void queue_fini(queue_t *queue); +extern int queue_add_entry(queue_t *queue, void *data); +extern int queue_get_first_entry_and_free(queue_t *queue, void *data); +extern int queue_get_entry(queue_t *queue, int num, void *data); +extern int queue_get_first_entry(queue_t *queue, void *data); +extern int queue_free_entry(queue_t *queue, int num); +extern void queue_query_info(queue_t *queue, int *start, int *inuse_num); + +#endif /* __QUEUE_H_*/ + diff --git a/drivers/gpu/drm/arise/core/util/ring_buffer.c b/drivers/gpu/drm/arise/core/util/ring_buffer.c new file mode 100644 index 0000000000000..456a21d87f81a --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/ring_buffer.c @@ -0,0 +1,101 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "ring_buffer.h" +#include "core_errno.h" +#include "core_import.h" + +#define DEBUG_RING_BUFFER 0 + +#if DEBUG_RING_BUFFER +#define ring_debug gf_info +#else +#define ring_debug(args...) +#endif + +int ring_buffer_init(ring_buffer_t *ring, int size, int reserved_size, ring_func_t wrap, void *private_data) +{ + ring->size = size; + ring->head = + ring->tail = reserved_size; + ring->wrap = wrap; + ring->left_size = size - reserved_size; + ring->private_data = private_data; + ring->reserved_size = reserved_size; + + return S_OK; +} + +#if DEBUG_RING_BUFFER +static int wrap_print = 0; +#endif + +int ring_buffer_get_space(ring_buffer_t *ring, int requested_size) +{ + int space_offset = -1; + + /* ring wrapped, we will skip tail space and reset tail to header and only update head when this time */ + if(ring->tail + requested_size >= ring->size) + { + int skip_cnt = ring->size - ring->tail; + + ring_debug("^^ wrap :requ :%08x, tail:%08x, head:%08x, left:%08x.\n", requested_size, ring->tail, ring->head, ring->left_size); + ring->head = ring->wrap(ring, skip_cnt, ring->private_data); + + ring->tail = ring->reserved_size; + ring->left_size = ring->head - ring->tail; + + ring_debug("-- wrap :skip :%08x, tail:%08x, head:%08x, left:%08x.\n", skip_cnt, ring->tail, ring->head, ring->left_size); + } + + /* if left size not enough, update left size */ + if(ring->left_size < requested_size) + { + ring_debug("update ^^ :requ :%08x, tail:%08x, head:%08x, left:%08x.\n", requested_size, ring->tail, ring->head, ring->left_size); + ring->head = ring->wrap(ring, 0, ring->private_data); + ring->left_size = ring->size + ring->head - ring->tail - ring->reserved_size; + + ring_debug("update --:skip :%08x, tail:%08x, head:%08x, left:%08x.\n", 0, ring->tail, ring->head, ring->left_size); + } + +#if DEBUG_RING_BUFFER + if(ring->tail > ring->size - (requested_size * 3)) + { + wrap_print = 5; + } +#endif + + if(ring->left_size >= requested_size) + { + ring->left_size -= requested_size; + + space_offset = ring->tail; + ring->tail += requested_size; + } + else + { + ring_debug("fail **:requ :%08x, tail:%08x, head:%08x, left:%08x.\n", requested_size, ring->tail, ring->head, ring->left_size); + } + +#if DEBUG_RING_BUFFER + if(wrap_print > 0) + { + wrap_print--; + + ring_debug(" @@ offset:%x, tail:%x.\n", space_offset, ring->tail); + } +#endif + + return space_offset; +} diff --git a/drivers/gpu/drm/arise/core/util/ring_buffer.h b/drivers/gpu/drm/arise/core/util/ring_buffer.h new file mode 100644 index 0000000000000..ae88da385c3be --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/ring_buffer.h @@ -0,0 +1,42 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __RING_BUFFER_H +#define __RING_BUFFER_H + + +typedef struct ring_buffer ring_buffer_t; + +typedef int (*ring_func_t)(ring_buffer_t *ring, int skip_cnt, void *private_data); + + +struct ring_buffer +{ + unsigned int head; // buffer begin used offset + unsigned int tail; // buffer used end offset + unsigned int size; + unsigned int left_size; + unsigned int reserved_size; // reserved space from buffer begin. + + ring_func_t wrap; + void *private_data; +}; + + +extern int ring_buffer_init(ring_buffer_t *ring, int size, int reserved_size, ring_func_t wrap, void *private_data); +extern int ring_buffer_get_space(ring_buffer_t *ring, int requested_size); + +#endif + + diff --git a/drivers/gpu/drm/arise/core/util/util.c b/drivers/gpu/drm/arise/core/util/util.c new file mode 100644 index 0000000000000..543fdddc761de --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/util.c @@ -0,0 +1,397 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "util.h" +char func_name[255] = {'\0'}; + +unsigned int util_crc32(unsigned char *pBuf, unsigned int nSize) +{ + static unsigned int s_u32CrcTables[256]; + static unsigned int s_bInited = 0; + unsigned int crc; + const unsigned char *p; + + if (!s_bInited) + { + unsigned int poly = 0x04C11DB7; + unsigned int i; + unsigned int j; + + for (i = 0; i < 256; i++) + { + crc = i << 24; + for (j = 0; j < 8; j++) + { + crc = (crc << 1) ^ ((crc & 0x80000000) ? (poly) : 0); + } + s_u32CrcTables[i] = crc; + } + + s_bInited =1; + } + + crc = 0xFFFFFFFF; + for (p = pBuf; p < pBuf + nSize; ++p) + { + crc = (crc << 8) ^ s_u32CrcTables[((crc >> 24) ^ *p) & 0xFF]; + } + + return crc; +} + +unsigned int util_log2(unsigned int s) +{ + unsigned int iter = (unsigned int)-1; + switch (s) + { + case 1: + iter = 0; + break; + case 2: + iter = 1; + break; + case 4: + iter = 2; + break; + case 8: + iter = 3; + break; + case 16: + iter = 4; + break; + case 32: + iter = 5; + break; + case 64: + iter = 6; + break; + case 128: + iter = 7; + break; + case 256: + iter = 8; + break; + case 512: + iter = 9; + break; + case 1024: + iter = 10; + break; + default: + { + unsigned int d = 1; + do { + d *= 2; + iter++; + } while (d < s); + iter += ((s << 1) != d); + } + } + return iter; +} + + +/* +** buffer: memory to dump +** size : dumped size in DWORD +*/ + +void util_dump_memory(struct os_printer *p, void *buffer, unsigned int size, char *msg) +{ + unsigned int dword = size >> 2; + unsigned int row = dword >> 2; + unsigned int left = dword%4; + unsigned int *data = buffer; + unsigned int i; + unsigned int offset = 0; + + if((size == 0) || (buffer == NULL)) return; + + gf_printf(p, "<< ------ Start dump %s - Size: 0x%08x, dword:0x%x ------>>\n", msg, size, dword); + + for(i = 0; i < row; i++) + { + gf_printf(p,"#0x%08x %08x, %08x, %08x, %08x\n", offset, data[0], data[1], data[2], data[3]); + data = data + 4; + offset += 0x10; + } + + if(left == 3) + { + gf_printf(p,"#0x%08x %08x, %08x, %08x\n", offset, data[0], data[1], data[2]); + } + else if(left == 2) + { + gf_printf(p,"#0x%08x %08x, %08x\n", offset, data[0], data[1]); + } + else if(left == 1) + { + gf_printf(p,"#0x%08x %08x\n", offset, data[0]); + } + + gf_printf(p,"<< ----------- End dump %s ---------------->>\n", msg); +} + +/* + * buffer: memory to dump + * size : dumped size in byte + */ +void util_dump_raw_memory_to_file(void *buffer, unsigned int size, char *filename) +{ + struct os_file *file = gf_file_open(filename, OS_WRONLY | OS_CREAT, 0644); + + if(file == NULL) + { + return; + } + + if(buffer != NULL && size != 0) + { + gf_file_write(file, buffer, size); + } + + gf_file_close(file); +} + +void util_dump_memory_to_file(void *buffer, unsigned int size, char *private_msg, char *filename) +{ + struct os_file *file = gf_file_open(filename, OS_WRONLY | OS_CREAT | OS_APPEND, 0644); + int len = gf_strlen(private_msg); + char *msg = gf_calloc(256); + + if(file == NULL) + { + gf_free(msg); + return; + } + + if(len > 0) + { + gf_file_write(file, private_msg, len); + } + + if(buffer != NULL && size != 0) + { + unsigned int dword = size >> 2; + unsigned int row = dword >> 2; + unsigned int left = dword%4; + unsigned int *data = buffer; + unsigned int i; + + gf_vsnprintf(msg, 256, "-------------------->\nmemory_dump: 0x%p -> 0x%p, size:0x%x.\n", buffer, (char*)buffer+size, size); + gf_file_write(file, msg, gf_strlen(msg)); + + gf_vsnprintf(msg, 256, "dword: 0x%x, row:0x%x, left:0x%x.\n", dword, row, left); + gf_file_write(file, msg, gf_strlen(msg)); + for(i = 0; i < row; i++) + { + gf_vsnprintf(msg, 256, "#%p %08x, %08x, %08x, %08x\n", data, data[0], data[1], data[2], data[3]); + gf_file_write(file, msg, gf_strlen(msg)); + data += 4; + } + + if(left == 3) + { + gf_vsnprintf(msg, 256, "#%p %08x, %08x, %08x\n", data, data[0], data[1], data[2]); + gf_file_write(file, msg, gf_strlen(msg)); + } + else if(left == 2) + { + gf_vsnprintf(msg, 256, "#%p %08x, %08x\n", data, data[0], data[1], data[2]); + gf_file_write(file, msg, gf_strlen(msg)); + } + else if(left == 1) + { + gf_vsnprintf(msg, 256, "#%p %08x\n", data, data[0], data[1], data[2]); + gf_file_write(file, msg, gf_strlen(msg)); + } + gf_vsnprintf(msg, 256, "-------------------->"); + gf_file_write(file, msg, gf_strlen(msg)); + } + + gf_free(msg); + gf_file_close(file); + +} + +void util_write_to_file(char *buffer, unsigned int size, char *private_msg, char *filename) +{ + struct os_file *file = gf_file_open(filename, OS_WRONLY | OS_CREAT | OS_APPEND, 0644); + int len = gf_strlen(private_msg); + + if(file == NULL) + { + return; + } + + if(len > 0) + { + gf_file_write(file, private_msg, len); + } + + if(buffer != NULL && size != 0) + { + gf_file_write(file, buffer, size); + } + + gf_file_close(file); +} + +long util_get_ptr_span_trace(void *start, void *end, const char *func, int line) +{ + long span = (char*)start - (char*)end; + +#ifdef _DEBUG_ + if(span < 0) + { + gf_error("span calc failed: start:%p, end:%p, func:%s, line:%d.\n", + start, end, func, line); + } +#endif + return span; +} + +static int util_event_thread(void *data) +{ + util_event_thread_t *thread = data; + gf_event_status_t ret; + + gf_set_freezable(); + + do + { + ret = gf_thread_wait(thread->event, thread->timeout_msec); + + thread->event_handler(thread->private_data, ret); + + if(thread->can_freeze) + { + gf_try_to_freeze(); + } + + } while(!gf_thread_should_stop()); + + return 0; +} + + +struct general_wait_event* util_create_event(int need_queue) +{ + struct general_wait_event *event = gf_calloc(sizeof(struct general_wait_event)); + + if(event) + { + event->need_queue = need_queue; + event->event = 0; + event->event_lock = gf_create_spinlock(0); + + return event; + } + + return NULL; +} + +util_event_thread_t *util_create_event_thread(util_event_handler_t handler, void *private_data, const char *thread_name, int msec) +{ + util_event_thread_t *thread = gf_calloc(sizeof(util_event_thread_t)); + + thread->timeout_msec = msec; + thread->can_freeze = TRUE; //default freeze value, if want freeze control by thread, adjust this value in thread handler + thread->event_handler = handler; + thread->private_data = private_data; + + thread->event = gf_create_event(0); + thread->os_thread = gf_create_thread(util_event_thread, thread, thread_name); + + return thread; +} + +void util_destroy_event_thread(util_event_thread_t *thread) +{ + gf_destroy_thread(thread->os_thread); + gf_destroy_event(thread->event); + + gf_free(thread); +} + +void util_wakeup_event_thread(util_event_thread_t *thread) +{ + gf_thread_wake_up(thread->event); +} + + +#if ENABLE_UTIL_LOG + +#include + +#define MAX_LINE_NUM 512 +#define MAX_STR_LINGTH 256 + +static struct os_mutex *util_log_lock = NULL; +static char util_log_str[MAX_LINE_NUM][MAX_STR_LINGTH]; +static int util_log_id = 0; + +void util_init_log(void) +{ + int i; + util_log_lock = gf_create_mutex(); + + for(i = 0; i < MAX_LINE_NUM; i++) + { + gf_memset(util_log_str[i], 0, MAX_STR_LINGTH); + } +} + +#include + +void util_log(const char *fmt, ...) +{ + char buffer[MAX_STR_LINGTH]; + int index = 0; + va_list args; + + va_start(args, fmt); + + vsnprintf(buffer, sizeof(buffer), fmt, args); + + va_end(args); + + gf_mutex_lock(util_log_lock); + + index = (util_log_id % MAX_LINE_NUM); + + gf_vsnprintf(util_log_str[index], MAX_STR_LINGTH-1, "%8x: %s", util_log_id, buffer); + + util_log_id++; + + gf_mutex_unlock(util_log_lock); +} + +void util_print_log(void) +{ + int i = 0; + + gf_mutex_lock(util_log_lock); + + gf_info("CURR_LOG_ID: %x.\n", util_log_id); + + for(i = 0; i < MAX_LINE_NUM; i++) + { + gf_info("%s", util_log_str[i]); + } + + gf_mutex_unlock(util_log_lock); +} + +#endif diff --git a/drivers/gpu/drm/arise/core/util/util.h b/drivers/gpu/drm/arise/core/util/util.h new file mode 100644 index 0000000000000..6a46b535c75ab --- /dev/null +++ b/drivers/gpu/drm/arise/core/util/util.h @@ -0,0 +1,208 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __UTIL_H_ +#define __UTIL_H_ + +#include "core_errno.h" +#include "core_import.h" + +#define bit_0 (1 << 0) +#define bit_1 (1 << 1) +#define bit_2 (1 << 2) +#define bit_3 (1 << 3) +#define bit_4 (1 << 4) +#define bit_5 (1 << 5) +#define bit_6 (1 << 6) +#define bit_7 (1 << 7) +#define bit_8 (1 << 8) +#define bit_9 (1 << 9) + +#define bit_10 (1 << 10) +#define bit_11 (1 << 11) +#define bit_12 (1 << 12) +#define bit_13 (1 << 13) +#define bit_14 (1 << 14) +#define bit_15 (1 << 15) +#define bit_16 (1 << 16) +#define bit_17 (1 << 17) +#define bit_18 (1 << 18) +#define bit_19 (1 << 19) + +#define bit_20 (1 << 20) +#define bit_21 (1 << 21) +#define bit_22 (1 << 22) +#define bit_23 (1 << 23) +#define bit_24 (1 << 24) +#define bit_25 (1 << 25) +#define bit_26 (1 << 26) +#define bit_27 (1 << 27) +#define bit_28 (1 << 28) +#define bit_29 (1 << 29) + +#define bit_30 (1 << 30) +#define bit_31 (1 << 31) + + +#define util_get_offset(type, element) (long)(&(((type *)0)->element)) +#define util_4k_align(size) ((size + 4095) & ~4095) +#define util_256byte_align(size) ((size + 255) & ~255) +#define util_2kbits_align(size) util_256byte_align(size) +#define util_align(size, align) ((size + align - 1) & (~(align - 1))) + +#define util_fabs(v) ((v) > 0.0 ? (v) : -(v)) +#define util_ffabs(v) v&0x7fffffff +#define util_max(a, b) ( a > b ? a : b) +#define util_min(a, b) ( a > b ? b : a) + +extern char func_name[255]; + +typedef int (*util_event_handler_t)(void *data, gf_event_status_t ret); + +typedef struct +{ + void *os_thread; + struct os_wait_event *event; + void *private_data; + util_event_handler_t event_handler; + int timeout_msec; + int can_freeze; + int priority; + int stack_size; +}util_event_thread_t; + +static inline int util_IsPow2(unsigned int value) +{ + return (!(value & (value-1))); +} + +/*---------------------------------------------------------------------------*/ +/* NearestLog2() */ +/* */ +/* Finds the closest integer base-2 log of a value. */ +/* (0 will return 0xFFFFFFFF) */ +/*---------------------------------------------------------------------------*/ +static inline unsigned int util_NearestLog2(unsigned int val) +{ + unsigned int result = 0xFFFFFFFF; + unsigned int input = val; + + while (val & 0xFFFFFFF0) + { + val >>= 4; + result += 4; + } + + while (val) + { + val >>= 1; + result++; + } + + // + // if val is not a pow2, increment by one, since + // this function floors + // + + if (util_IsPow2(input) == 0) + { + result++; + } + + return(result); +} + +static inline int util_get_msb_position(unsigned int num) +{ + unsigned int msbpos = 0; + + if(num == 0) + { + gf_assert(0, "num == 0"); + } + + while (num > 1) + { + num >>= 1; + msbpos++; + } + return msbpos; +} + +static inline int util_get_lsb_position(unsigned int data) +{ + int i; + + if(data == 0) + { + gf_assert(0, "data == 0"); + } + + for(i = 0; i < sizeof(unsigned int)*8; i++) + { + if(data & (1u << i)) + break; + } + + return i; +} + +static inline char* util_remove_name_suffix(const char* func) +{ + int len = gf_strlen((char*)func); + if (len > 3 && len < 255) + { + if (func[len - 3] == 'e' && func[len - 2] == '3' && func[len - 1] == 'k') + { + gf_memcpy(func_name, func, len - 3); + func_name[len - 3] = '\0'; + if (len > 4 && func[len - 4] == '_') + func_name[len - 4] = '\0'; + return func_name; + } + } + return (char*)func; +} + +extern unsigned int util_crc32(unsigned char *buffer, unsigned int size); +extern void util_dump_memory(struct os_printer *p, void *buffer, unsigned int size, char *msg); +extern void util_dump_raw_memory_to_file(void *buffer, unsigned int size, char *filename); +extern void util_dump_memory_to_file(void *buffer, unsigned int size, char *private_msg, char *filename); +extern void util_write_to_file(char *buffer, unsigned int size, char *private_msg, char *filename); +extern long util_get_ptr_span_trace(void *start, void *end, const char *func, int line); + +#define util_get_ptr_span(start, end) util_get_ptr_span_trace(start, end, __func__, __LINE__) + +extern unsigned int util_log2(unsigned int s); + +extern util_event_thread_t *util_create_event_thread(util_event_handler_t handler, void *private_data, const char *thread_name, int msec); +extern struct general_wait_event* util_create_event(int need_queue); +extern void util_destroy_event_thread(util_event_thread_t *thread); +extern void util_wakeup_event_thread(util_event_thread_t *thread); + +#define ENABLE_UTIL_LOG 0 + +#if ENABLE_UTIL_LOG +extern void util_init_log(void); +extern void util_log(const char *fmt, ...); +extern void util_print_log(void); +#else +#define util_init_log() +#define util_log(args...) +#define util_print_log() +#endif + + +#endif + diff --git a/drivers/gpu/drm/arise/core/vidmm/vidmm.c b/drivers/gpu/drm/arise/core/vidmm/vidmm.c new file mode 100644 index 0000000000000..aa9088b1c44b9 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidmm/vidmm.c @@ -0,0 +1,1325 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "vidmm.h" +#include "vidmmi.h" +#include "heap_manager.h" +#include "vidsch.h" +#include "vidschi.h" + +static int vidmmi_get_dummy_page_addr(void *arg, int pg_start, int pg_cnt, unsigned long long dma_addr) +{ + *(unsigned long long*)arg = dma_addr; + + return 1; +} + +static int vidmmi_init_gart_table(adapter_t *adapter) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_gart_table_info_t *gart_table_L3 = NULL; + vidmm_gart_table_info_t *gart_table_L2 = NULL; + vidmm_segment_memory_t *segment_memory = NULL; + vidmm_map_flags_t map_flags = {0}; + + int result = S_OK; + + if (adapter->dummy_page_addr) + { + return S_OK; + } + + gf_pages_memory_for_each_continues(mm_mgr->dummy_page, &adapter->dummy_page_addr, vidmmi_get_dummy_page_addr); + gf_info("dummy page phys addr %llx\n", adapter->dummy_page_addr); + + { + if(adapter->hw_caps.page_4k_enable) + { + gart_table_L3 = gf_calloc(sizeof(vidmm_gart_table_info_t)); + gart_table_L2 = gf_calloc(sizeof(vidmm_gart_table_info_t)); + + gf_assert(gart_table_L3 != NULL && gart_table_L2 != NULL, "gart_table_L3 != NULL && gart_table_L2 != NULL"); + + adapter->gart_table_L3 = gart_table_L3; + adapter->gart_table_L2 = gart_table_L2; + + mm_mgr->chip_func->query_gart_table_info(adapter); + } + + if(gart_table_L3 && gart_table_L3->size) + { + segment_memory = vidmm_allocate_segment_memory(adapter, gart_table_L3->segment_id, gart_table_L3->size, 1); + + gart_table_L3->phys_addr = segment_memory->gpu_virt_addr; //pagetable address need aligned to cache line [E3K_CACHE_LINE 0xFF], heap mgr will aligned to 4k automaticlly. + + map_flags.mem_space = GF_MEM_KERNEL; + map_flags.cache_type = GF_MEM_WRITE_COMBINED; + + vidmm_map_segment_memory(adapter, NULL, segment_memory, &map_flags); + + gart_table_L3->virt_addr = segment_memory->vma->virt_addr; + gart_table_L3->page_count = gart_table_L3->size / sizeof(int);//one entery point to one page + gart_table_L3->segment_memory = segment_memory; + gart_table_L3->dirty = TRUE; + } + + if(gart_table_L2 && gart_table_L2->size) + { + segment_memory = vidmm_allocate_segment_memory(adapter, gart_table_L2->segment_id, gart_table_L2->size, 1); + + gart_table_L2->phys_addr = segment_memory->gpu_virt_addr; + + map_flags.mem_space = GF_MEM_KERNEL; + map_flags.cache_type = GF_MEM_UNCACHED; + + vidmm_map_segment_memory(adapter, NULL, segment_memory, &map_flags); + + gart_table_L2->virt_addr = segment_memory->vma->virt_addr; + gart_table_L2->page_count = gart_table_L2->size / sizeof(int);//one entery point to one page + gart_table_L2->segment_memory = segment_memory; + gart_table_L2->dirty = TRUE; + } + + mm_mgr->chip_func->init_gart_table(adapter); + + return result; + } +} + +static void vidmmi_destroy_gart_table(adapter_t *adapter) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_gart_table_info_t *gart_table = NULL; + + if (adapter->dummy_page_addr) + { + adapter->dummy_page_addr = 0LL; + } + + if(adapter->gart_table_L3) + { + gart_table = adapter->gart_table_L3; + + vidmm_unmap_segment_memory(adapter, gart_table->segment_memory, GF_MEM_KERNEL); + + vidmm_release_segment_memory(adapter, gart_table->segment_memory); + + gart_table->segment_memory = NULL; + + if(gart_table->chip_private) + { + mm_mgr->chip_func->deinit_gart_table(adapter); + + gart_table->chip_private = NULL; + } + + gf_free(gart_table); + + adapter->gart_table_L3= NULL; + } + + if(adapter->gart_table_L2) + { + gart_table = adapter->gart_table_L2; + + vidmm_unmap_segment_memory(adapter, gart_table->segment_memory, GF_MEM_KERNEL); + + vidmm_release_segment_memory(adapter, gart_table->segment_memory); + + gart_table->segment_memory = NULL; + + if(gart_table->chip_private) + { + mm_mgr->chip_func->deinit_gart_table(adapter); + + gart_table->chip_private = NULL; + } + + gf_free(gart_table); + + adapter->gart_table_L2 = NULL; + } +} + +#if DEBUG_TEST +void vidmmi_test_video_memory(adapter_t *adapter) +{ + unsigned int offset; + volatile unsigned int *frame_buffer; + unsigned long dummy_data = 0; + unsigned int result = S_OK; + unsigned int scan_scope = 0x400000;//adapter->physical_bus_base_length[1];//cpu visiable + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + unsigned int scan_line = 0x400000;//remapio will assert in vmalloc if size is larger than vmalloc total size. add to avoid this. or can add vmalloc='scan_scope' in boot manu + unsigned int scan_loop = 0; + unsigned int map_size = scan_line; + gf_map_argu_t map = {0}; + gf_vm_area_t *vma = NULL; + unsigned int count = 0; + + gf_info("==================test local memory begin==========================\n"); + gf_info("total size = %x, vidmm_bus_addr=%x \n", scan_scope, adapter->vidmm_bus_addr); + + //test local video memory + for(scan_loop=0; scan_loopvidmm_bus_addr+scan_loop; + map.size = map_size; + + vma = gf_map_io_memory(NULL, &map); + + gf_assert(vma!=NULL, "vidmm_test vma!=NULL"); + + frame_buffer = vma->virt_addr; + } + + for(offset=0; offsetvidmm_bus_addr + scan_scope+ offset*4),dummy_data,offset); + if(count++ >500) break; + } + } + + { + gf_unmap_io_memory(vma); + vma = NULL; + } + gf_info("passed %xth 4M ~~~ %xth 4M.\n", scan_loop/scan_line, scan_loop/scan_line+1); + } + + gf_info("==================test local memory end==========================\n"); +} +#endif + +static void vidmmi_map_flag_buffer(adapter_t *adapter) +{ + vidmm_segment_t *segment = NULL; + int segment_id = 1;//hardcode for local segment id + int map_size = 1024*1024;//1M + gf_map_argu_t map = {0}; + gf_vm_area_t *vm_area = NULL; + + segment = vidmm_get_segment_by_id(adapter, segment_id); + + map.flags.mem_space = GF_MEM_KERNEL; + map.size = map_size; + map.memory = segment->reserved_pages; + map.offset = 0; + map.flags.mem_type = GF_SYSTEM_RAM; + map.flags.read_only = 0; + map.flags.write_only = 0; + + if(segment->reserved_pages == NULL) + { + gf_info("memory reserved is NULL \n"); + return; + } + + vm_area = gf_map_pages_memory(NULL, &map); + if(vm_area == NULL) + { + gf_error("map addr is NULL\n"); + gf_assert(0, "vidmm map flag buffer"); + } + else + { + adapter->flag_buffer_virt_addr = vm_area->virt_addr; + gf_info("%s: flag buffer virt_addr: %p\n", __func__, vm_area->virt_addr); + + gf_memset(vm_area->virt_addr, 0, map_size); + } +} + + +#define VMEM_START_ALIGN (64*1024) +#define SYSTEM_RESERVED_PAGES_SIZE (256 * 1024 * 1024) +#define EMERENCY_PAGES_SIZE ( 64 * 1024 * 1024) + +int vidmm_init(adapter_t *adapter, int reserved_vmem) +{ + vidmm_mgr_t *mm_mgr = NULL; + vidmm_segment_t *segment = NULL; + vidmm_chip_segment_info_t *chip_segment_info = gf_calloc(sizeof(vidmm_chip_segment_info_t)); + int result = S_OK; + int id = 0; + int priority = 0; + unsigned long long max_size = 0; + mem_info_t mem = {0}; + unsigned long long heap_size, heap_start; + + mm_mgr = gf_calloc(sizeof(vidmm_mgr_t)); + + if(NULL == mm_mgr) + { + gf_error("vidmm_init failed.\n"); + result = E_OUTOFMEMORY; + goto exit; + } + + adapter->mm_mgr = mm_mgr; + mm_mgr->adapter = adapter; + mm_mgr->reserved_vmem = (reserved_vmem + VMEM_START_ALIGN - 1) & (~(VMEM_START_ALIGN -1)); + mm_mgr->hw_lock = gf_create_mutex(); + mm_mgr->list_lock = gf_create_mutex(); + + list_init_head(&mm_mgr->defer_destroy_list); + list_init_head(&mm_mgr->paging_task_list); + + /* calc max use pages size by real system memory info to avoid use much system memory */ + + gf_get_mem_info(&mem); + + if(mem.totalram > 2 * SYSTEM_RESERVED_PAGES_SIZE/adapter->os_page_size) + { + mm_mgr->max_pages_num = mem.totalram - ((SYSTEM_RESERVED_PAGES_SIZE - EMERENCY_PAGES_SIZE)/adapter->os_page_size); + mm_mgr->emergency_pages = EMERENCY_PAGES_SIZE/adapter->os_page_size; + } + else + { + mm_mgr->max_pages_num = mem.totalram >> 1; + mm_mgr->emergency_pages = mem.totalram >> 2; + } + +#ifdef ANDROID + { + mm_mgr->max_pages_num = mem.totalram; + mm_mgr->emergency_pages = mem.totalram; + } +#endif + + gf_info("GPU can used system memory size: %dk. set GPU max used size as: %dk.\n", + mem.totalram * adapter->os_page_size >> 10, mm_mgr->max_pages_num * adapter->os_page_size>> 10); + + mm_mgr->chip_func = &vidmm_chip_func; + + /* + * init segment desc & heap + */ + mm_mgr->chip_func->query_segment_info(adapter, chip_segment_info); + + mm_mgr->cpu_visible_vidmm_size = chip_segment_info->cpu_visible_vidmm_size; + mm_mgr->cpu_unvisible_vidmm_size = chip_segment_info->cpu_unvisible_vidmm_size; + mm_mgr->segment_cnt = chip_segment_info->segment_cnt; + mm_mgr->segment = gf_calloc(sizeof(vidmm_segment_t)*mm_mgr->segment_cnt); + + /* invalid segment id 0, not describe none video memory but just system cache, we name it as cache segment */ + segment = &mm_mgr->segment[SEGMENT_ID_INVALID]; + + segment->segment_id = SEGMENT_ID_INVALID; + segment->segment_name = "Segment Invalid"; + segment->flags.cpu_visible = TRUE; + segment->lock = gf_create_mutex(); + + list_init_head(&segment->unpagable_resident_list); + + for(priority = PDISCARD; priority < PALL; priority++) + { + list_init_head(&segment->pagable_resident_list[priority]); + } + + /* describe valid video segment */ + for(id = 1; id < mm_mgr->segment_cnt; id++) + { + vidmm_segment_desc_t *segment_desc = &chip_segment_info->segment_desc[id]; + + segment = &mm_mgr->segment[id]; + + segment->segment_id = segment_desc->segment_id; + segment->segment_name = segment_desc->segment_name; + segment->flags.value = segment_desc->flags.value; + segment->segment_alignment = segment_desc->segment_alignment; + segment->gpu_vm_start = segment_desc->gpu_vm_start; + segment->reserved_vm_end = segment_desc->gpu_vm_start + segment_desc->reserved_vm_size; + segment->gpu_vm_size = segment_desc->gpu_vm_size; + segment->small_heap_size = segment_desc->small_heap_size; + segment->reserved_vm_size = segment_desc->reserved_vm_size; + segment->phys_addr_start = segment_desc->phys_addr_start; + segment->lock = gf_create_mutex(); + segment->small_heap_max_allocate_size = segment_desc->small_heap_max_allocate_size; + + list_init_head(&segment->unpagable_resident_list); + + for(priority = PDISCARD; priority < PALL; priority++) + { + list_init_head(&segment->pagable_resident_list[priority]); + } + + /* only select the max pcie segment as swap segment for easy the logic. on swap func we first try swap cache segment, + * if cache not enough, we paging out swap segment to cache, and try swap it. + */ + if(segment->flags.require_system_pages && (segment->gpu_vm_size > max_size)) + { + max_size = segment->gpu_vm_size; + } + + if(segment->flags.secure_range &&(mm_mgr->secure_segment_id == SEGMENT_ID_INVALID) ) + { + mm_mgr->secure_segment_id = segment->segment_id; + segment->secure_lock = gf_create_mutex(); + } + + heap_start = segment->reserved_vm_end; + heap_size = segment->gpu_vm_size - segment->reserved_vm_size; + + if(segment->flags.small_heap_available) + { + heap_size -= segment->small_heap_size; + } + + heap_init(&segment->heap, id, heap_start, heap_size, (segment->flags.page_64kb_enable ? GF_PAGE_64KB_SIZE : segment->segment_alignment)); + + if(segment->flags.small_heap_available) + { + heap_start = segment->heap.start + segment->heap.size; + heap_size = segment->small_heap_size; + + heap_init(&segment->small_heap, id, heap_start, heap_size, segment->segment_alignment); + } + + if(segment->gpu_vm_size > 0) + { + gf_info("segment[%d]: range: [%lldM -> %lldM], size: %lldM, start reserved: %dk\n", + id, segment->gpu_vm_start >> 20, (segment->gpu_vm_start + segment->gpu_vm_size) >> 20, + segment->gpu_vm_size >> 20, segment->reserved_vm_size >> 10); + } + + segment->mtrr_reg = -1; + + if(segment->flags.mtrr) + { + /* On DST, driver will reserver some mem to video, so the size not power of 2, which lead mtrr_add fail + * Juat add 1M align here to bypass it. + */ + + unsigned long size = (segment->gpu_vm_size + 0xFFFFF)& (~0xFFFFF); //1M align + + segment->mtrr_reg = gf_mtrr_add(segment->gpu_vm_start + adapter->vidmm_bus_addr, size); + } + } + + if(adapter->hw_caps.fb_hdaudio_enable) + { + vidmm_segment_memory_t *reserved_16m_memory = NULL; + + reserved_16m_memory = vidmm_allocate_segment_memory(adapter, 1, 16*1024*1024, 1); // reserve 16M + + adapter->reserve_16m_buffer = reserved_16m_memory; + gf_info("reserved 16M for gf_hda, address=0x%llx\n", reserved_16m_memory->gpu_virt_addr); + } + + if (adapter->ctl_flags.vesa_tempbuffer_enable) + { + adapter->vesafb_tempbuffer = vidmm_allocate_segment_memory(adapter, 1, 1920*1080*4, 0); + gf_info("vesa_tempbuffer_enable: temp allocation 1920*1080*4\n"); + } + + if(adapter->UnAval_vram_size) + { + adapter->mem_unavailable_for_3miu = vidmm_allocate_segment_memory(adapter, 5, adapter->UnAval_vram_size, 1); + } + + /* + * for paging segment is common for all chip, so we initial it in share layer. + */ + if(adapter->ctl_flags.paging_enable) + { + vidmm_segment_t *paging_segment = NULL; + list_node_t *paging_segment_node = NULL; + + /* init paging semgent description */ + paging_segment = gf_calloc(sizeof(vidmm_segment_t)); + mm_mgr->paging_segment = paging_segment; + paging_segment->segment_id = chip_segment_info->paging_segment_id; + paging_segment->gpu_vm_size = chip_segment_info->paging_segment_size; + paging_segment->reserved_vm_size = 0; + paging_segment->segment_alignment= adapter->os_page_size; + + segment = &mm_mgr->segment[paging_segment->segment_id]; + + paging_segment_node = heap_allocate(&segment->heap, paging_segment->gpu_vm_size - paging_segment->reserved_vm_size, adapter->os_page_size, 1); + paging_segment->gpu_vm_start = paging_segment_node->aligned_offset; + paging_segment->reserved_vm_end = paging_segment->gpu_vm_start + paging_segment->reserved_vm_size; + paging_segment->flags.support_snoop = segment->flags.support_snoop; + mm_mgr->paging_segment_node = paging_segment_node; + + /* init paging heap */ + heap_init(&paging_segment->heap, -1, paging_segment->gpu_vm_start, paging_segment->gpu_vm_size - paging_segment->reserved_vm_size, adapter->os_page_size); + } + + /* + * create dummy page for gart table + */ + { + alloc_pages_flags_t alloc_flags = {0}; + alloc_flags.dma32 = TRUE; + alloc_flags.need_zero = TRUE; + alloc_flags.fixed_page = TRUE; + alloc_flags.need_dma_map = adapter->sys_caps.iommu_enabled; + mm_mgr->dummy_page = gf_allocate_pages_memory(adapter->os_device.pdev, adapter->os_page_size, adapter->os_page_size, alloc_flags); + +#ifdef VMI_MODE + gf_set_pages_addr(mm_mgr->dummy_page, 0); +#endif + + if (mm_mgr->dummy_page == NULL) + { + gf_error("vidmm_init: allocate dummy page failed.\n"); + goto exit; + } + } + /* + * init gart table + */ + //if(!adapter->hw_caps.local_only) + { + result = vidmmi_init_gart_table(adapter); + if(S_OK != result) + { + gf_error("vidmm_init: init gart table fail.\n"); + goto exit; + } + } + + if(mm_mgr->chip_func && mm_mgr->chip_func->mem_setting) + { + mm_mgr->chip_func->mem_setting(adapter); + } + +#if DEBUG_TEST + vidmmi_test_video_memory(adapter); +#endif + + //This is used to check if hw access 4G~8G mem will overwrite to 0~4G. +#if DEBUG_HIGH_4G_MEM + { + vidmm_map_flags_t flags = {0}; + vidmm_segment_memory_t *reserved_memory = NULL; + + reserved_memory = vidmm_allocate_segment_memory(adapter, 1, HIGH_4G_MEM_RESERVE_SIZE, 0); + + gf_memset(&flags, 0, sizeof(flags)); + + flags.write_only = 1; + flags.mem_space = GF_MEM_KERNEL; + + vidmm_map_segment_memory(adapter, NULL, reserved_memory, &flags); + gf_memset(reserved_memory->vma->virt_addr, 0, HIGH_4G_MEM_RESERVE_SIZE); + + adapter->Reserve_Buffer = reserved_memory; + gf_info("Mem Reserve for high 4g test pa is:%x\n", reserved_memory->gpu_virt_addr); + } +#endif + if(adapter->ctl_flags.flag_buffer_verify) + { + vidmmi_map_flag_buffer(adapter); + } + + //vidmmi_dump_segments(adapter); + +exit: + gf_free(chip_segment_info); + + return result; +} + +void vidmm_destroy(adapter_t *adapter) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = NULL; + int id = 0; + + if (adapter->vesafb_tempbuffer) + { + vidmm_release_segment_memory(adapter, adapter->vesafb_tempbuffer); + adapter->vesafb_tempbuffer = NULL; + + gf_info("free vesa_tempbuffer_enable\n"); + } + if(adapter->mem_unavailable_for_3miu) + { + vidmm_release_segment_memory(adapter, adapter->mem_unavailable_for_3miu); + adapter->mem_unavailable_for_3miu = NULL; + + gf_info("free mem_unavailable_for_3miu\n"); + } + +#if DEBUG_HIGH_4G_MEM + if (adapter->Reserve_Buffer) + { + vidmm_release_segment_memory(adapter, adapter->Reserve_Buffer); + adapter->Reserve_Buffer = NULL; + } +#endif + + if (adapter->hw_caps.fb_hdaudio_enable && adapter->reserve_16m_buffer) + { + vidmm_release_segment_memory(adapter, adapter->reserve_16m_buffer); + adapter->reserve_16m_buffer = NULL; + } + + if (mm_mgr->dummy_page) + { + gf_free_pages_memory(adapter->os_device.pdev, mm_mgr->dummy_page); + mm_mgr->dummy_page = NULL; + } + + vidmmi_destroy_gart_table(adapter); + + if(mm_mgr->paging_segment) + { + list_node_t *paging_segment_node = mm_mgr->paging_segment_node; + int paging_segment_id = mm_mgr->paging_segment->segment_id; + + segment = mm_mgr->paging_segment; + + mm_mgr->paging_segment = NULL; + + heap_destroy(&segment->heap); + + gf_free(segment); + + heap_release(&mm_mgr->segment[paging_segment_id].heap, paging_segment_node); + } + + if(mm_mgr->segment) + { + segment = &mm_mgr->segment[0]; + + gf_destroy_mutex(segment->lock); + + for(id = 1; id < mm_mgr->segment_cnt; id++) + { + segment = &mm_mgr->segment[id]; + + if(segment->mtrr_reg >= 0) + { + unsigned long size = (segment->gpu_vm_size + 0xFFFFF)& (~0xFFFFF); //1M align + + gf_mtrr_del(segment->mtrr_reg, segment->gpu_vm_start + adapter->vidmm_bus_addr, size); + + segment->mtrr_reg = -1; + } + + if(segment->reserved_pages) + { + gf_free_pages_memory(adapter->os_device.pdev, segment->reserved_pages); + segment->reserved_pages = NULL; + } + + if(segment->flags.small_heap_available) + { + heap_destroy(&segment->small_heap); + } + + heap_destroy(&segment->heap); + + gf_destroy_mutex(segment->lock); + + if(segment->secure_lock) + { + gf_destroy_mutex(segment->secure_lock); + } + } + + gf_free(mm_mgr->segment); + + mm_mgr->segment = NULL; + } + +#if defined(GF_HW_NULL) + if(adapter->mmio_mem) + { + gf_unmap_pages_memory(adapter->mmio_vma); + adapter->mmio_vma = NULL; + + gf_free_pages_memory(adapter->os_device.pdev, adapter->mmio_mem); + adapter->mmio_mem = NULL; + } +#endif + + gf_destroy_mutex(mm_mgr->list_lock); + gf_destroy_mutex(mm_mgr->hw_lock); + + if(adapter->mm_mgr) + { + gf_free(adapter->mm_mgr); + adapter->mm_mgr = NULL; + } +} + +vidmm_segment_t *vidmm_get_segment_by_id(adapter_t *adapter, unsigned int segment_id) +{ + vidmm_mgr_t *vidmm = adapter->mm_mgr; + vidmm_segment_t *segment = NULL; + + if((SEGMENT_ID_INVALID == segment_id) || (segment_id >= vidmm->segment_cnt)) + { + gf_info("%s(): invalid segment_id-%d\n", __func__, segment_id); + gf_assert(0, "vidmm_get_segment_by_id invalid segment_id"); + return segment; + } + + segment = &vidmm->segment[segment_id]; + return segment; +} + +heap_t * vidmm_get_burst_length_heap(adapter_t *adapter) +{ + return &adapter->mm_mgr->blheap; +} +int vidmm_get_segment_count(adapter_t *adapter) +{ + return adapter->mm_mgr->segment_cnt; +} + +#define GART_BLT_SUSPEND 1 + +int vidmm_save(adapter_t *adapter) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_memory_t *segment = NULL; + vidmm_gart_table_info_t *gart_table_L3 = adapter->gart_table_L3; + vidmm_gart_table_info_t *gart_table_L2 = adapter->gart_table_L2; + int result = E_OUTOFMEMORY; + + gart_table_L2->backup = gf_malloc(gart_table_L2->size); + if (gart_table_L2->backup) + { + gf_memcpy(gart_table_L2->backup, gart_table_L2->virt_addr, gart_table_L2->size); + } + +#if GART_BLT_SUSPEND + // In arm64, memcpy 8MB from IO memory to Physical memory will cost about 4s. + // So we use vidmm_segment_memory_transfer_e3k() to submit a page task + // Help us copy gart_table_L3->segment_memory to a new segment_memory. + result = mm_mgr->chip_func->segment_memory_transfer(adapter, &segment, gart_table_L3->segment_memory, 0); + gart_table_L3->backup = (void *)segment; +#else + + gart_table_L3->backup = gf_malloc(gart_table_L3->size); + if (gart_table_L3->backup) + { + gf_memcpy(gart_table_L3->backup, gart_table_L3->virt_addr, gart_table_L3->size); + result = S_OK; + } +#endif + + adapter->fence_buf_local->backup = gf_malloc(68 * 1024); + if (adapter->fence_buf_local->backup) + gf_memcpy(adapter->fence_buf_local->backup, adapter->fence_buf_local->reserved_memory->vma->virt_addr, 68 * 1024); + + + return result; +} + +void vidmm_restore(adapter_t *adapter) +{ + vidmm_gart_table_info_t *gart_table_L3 = adapter->gart_table_L3; + vidmm_gart_table_info_t *gart_table_L2 = adapter->gart_table_L2; + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + + if (mm_mgr->chip_func->restore != NULL) + { + mm_mgr->chip_func->restore(adapter); + } + + if (gart_table_L2->backup) + { + gf_memcpy(gart_table_L2->virt_addr, gart_table_L2->backup, gart_table_L2->size); + gf_free(gart_table_L2->backup); + } + +#if GART_BLT_SUSPEND + if (gart_table_L3->backup) + { + struct _vidmm_segment_memory *segment = (struct _vidmm_segment_memory *)gart_table_L3->backup; + vidmm_map_flags_t flags = {0}; + flags.write_only = 1; + flags.mem_space = GF_MEM_KERNEL; + vidmm_map_segment_memory(adapter, NULL, segment, &flags); + gf_memcpy(gart_table_L3->virt_addr, segment->vma->virt_addr, gart_table_L3->size); + vidmm_unmap_segment_memory(adapter, segment, GF_MEM_KERNEL); + vidmm_release_segment_memory(adapter, segment); + } +#else + if (gart_table_L3->backup) + { + gf_memcpy(gart_table_L3->virt_addr, gart_table_L3->backup, gart_table_L3->size); + gf_free(gart_table_L3->backup); + } +#endif + + if (adapter->fence_buf_local->backup) + { + gf_memcpy(adapter->fence_buf_local->reserved_memory->vma->virt_addr, adapter->fence_buf_local->backup, 68 * 1024); + gf_free(adapter->fence_buf_local->backup); + } + + adapter->fence_buf_local->backup = NULL; + gart_table_L3->backup = NULL; + gart_table_L2->backup = NULL; + + return; +} + +void vidmm_fill_allocation_info(adapter_t *adapter, vidmm_allocation_t *allocation, gf_open_allocation_t *info) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = &mm_mgr->segment[allocation->segment_id]; + vidmm_get_allocation_info_t alloc_info = {0}; + + info->device = allocation->device ? allocation->device->handle : 0; + info->allocation = allocation->handle; + info->size = allocation->size; + info->alignment = allocation->alignment; + info->width = allocation->width; + info->height = allocation->height; + info->aligned_width = allocation->aligned_width; + info->aligned_height= allocation->aligned_height; + info->tiled_width = allocation->tiled_width; + info->tiled_height = allocation->tiled_height; + info->bit_cnt = allocation->bit_count; + info->pitch = allocation->pitch; + info->unpagable = allocation->flag.unpagable; + info->tiled = allocation->flag.swizzled; + info->secured = allocation->flag.secured; + info->local = allocation->flag.secured;//now force into secure + info->compress_format = allocation->compress_format; + info->hw_format = allocation->hw_format; + info->segment_id = allocation->segment_id; + info->gpu_virt_addr = allocation->phys_addr; + info->bl_slot_index = allocation->slot_index; + info->cpu_visible = segment->flags.cpu_visible; + info->force_clear = allocation->flag.force_clear; +#ifndef VMI_MODE + if (!allocation->pages_mem) +#endif + { + info->cpu_phy_addr = allocation->phys_addr + adapter->vidmm_bus_addr; + } + info->sync_obj = allocation->sync_obj; + info->fence_addr = allocation->fence_addr; + + /* get additional information */ + alloc_info.allocation = allocation; + vidmm_get_allocation_info(adapter, &alloc_info); + + info->ForceLocal = alloc_info.ForceLocal; + info->has_pages = segment->flags.require_system_pages; + info->snoop = alloc_info.snoop; +} + +int vidmm_query_info(adapter_t *adapter, gf_query_info_t *query) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + int ret = 0; + + switch (query->type) + { + case GF_QUERY_TOTAL_VRAM_SIZE: + query->value = adapter->Real_vram_size; + break; + + case GF_QUERY_RESERV_VRAM_SIZE: + query->value = mm_mgr->reserved_vmem; + break; + + case GF_QUERY_CPU_VISIBLE_VRAM_SIZE: + query->value = mm_mgr->cpu_visible_vidmm_size; + break; + + case GF_QUERY_LOCAL_VRAM_TYPE: + query->value = GF_SYSTEM_IO; + break; + + case GF_QUERY_HEIGHT_ALIGN: + query->value = 64; + break; + + case GF_QUERY_SEGMENT_FREE_SIZE: + case GF_QUERY_SEGMENT_MEM_INFO: + if (mm_mgr->chip_func->query_info != NULL) + ret = mm_mgr->chip_func->query_info(mm_mgr, query); + break; + + case GF_QUERY_ALLOCATION_INFO: + case GF_QUERY_ALLOCATION_INFO_KMD: + { + vidmm_allocation_t *allocation = get_from_handle_and_validate(&adapter->hdl_mgr, query->argu, HDL_TYPE_ALLOCATION); + gf_open_allocation_t _data = {0}; + gf_open_allocation_t *info = (query->type == GF_QUERY_ALLOCATION_INFO) ? &_data : query->buf; + + vidmm_fill_allocation_info(adapter, allocation, info); + if (query->type == GF_QUERY_ALLOCATION_INFO) + { + gf_copy_to_user(query->buf, info, sizeof(gf_open_allocation_t)); + } + break; + } + + case GF_QUERY_LOCAL_ALLOCATION_MAX_SIZE: + { + query->value = vidmmi_query_max_size_of_local_allocation(adapter); + break; + } + + case GF_QUERY_DIAGS: + { + query->diags.total_vram_size = adapter->Real_vram_size; + query->diags.cpu_visible_size = adapter->mm_mgr->cpu_visible_vidmm_size; + break; + } + + case GF_SET_PERF_SWAP_HINT: + case GF_GET_PERF_SWAP_HINT: + { + vidmm_allocation_t *allocation = get_from_handle_and_validate(&adapter->hdl_mgr, query->argu, HDL_TYPE_ALLOCATION); + if (query->type == GF_SET_PERF_SWAP_HINT) { + allocation->perf_swap_hint = query->value; + } else if (query->type == GF_GET_PERF_SWAP_HINT) { + query->value = allocation->perf_swap_hint; + } + break; + } + + default: + ret = -1; + break; + } + + return ret; +} + +void vidmm_dump_flagbuffer_to_file(char *file_name, vidmm_allocation_t *allocation) +{ + gpu_device_t *device = allocation->device; + adapter_t * adapter = device->adapter; + unsigned int offset = 0; + unsigned int size = 0; + + { + heap_t *blheap = &adapter->mm_mgr->blheap; + gf_vm_area_t *vm_area = NULL; + gf_map_argu_t map = {0}; + + map.flags.cache_type= GF_MEM_UNCACHED; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = blheap->start + adapter->vidmm_bus_addr; + map.size = blheap->size; + + vm_area = gf_map_io_memory(NULL, &map); + + offset = allocation->bl_node->aligned_offset - blheap->start; + size = allocation->size/512; //1:512 cpmpress rate + + if(file_name) + { + util_dump_raw_memory_to_file(vm_area->virt_addr + offset, size, file_name); + } + else + { + util_dump_memory(NULL, vm_area->virt_addr + offset, size, "allocation bl:"); + } + + gf_unmap_io_memory(vm_area); + vm_area = NULL; + } + + return; +} + +void vidmm_dump_allocation_to_file(char *file_name, unsigned int name_offset, unsigned int hAllocation, adapter_t *adapter) +{ + vidmm_allocation_t *allocation = NULL; + char alloc_file_name[256]; + + if(file_name == NULL) + { + return; + } + + allocation = get_from_handle(&adapter->hdl_mgr, hAllocation); + + if(allocation == NULL) + { + gf_error("get allocaton failed, allocation %d\n", hAllocation); + return; + } + + gf_vsprintf(alloc_file_name, "%s_%d_%d_fmt%d.bin", file_name, allocation->aligned_width, allocation->aligned_height, allocation->hw_format); + + if(allocation->pages_mem) + { + gf_map_argu_t map = {0}; + gf_vm_area_t *pcie_addr = NULL; + + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.cache_type = GF_MEM_WRITE_COMBINED; + map.flags.mem_type = GF_SYSTEM_RAM; + map.size = allocation->orig_size; + map.memory = allocation->pages_mem; + + pcie_addr = gf_map_pages_memory(NULL, &map); + + util_dump_raw_memory_to_file(pcie_addr->virt_addr, allocation->orig_size, alloc_file_name); + + gf_unmap_pages_memory(pcie_addr); + } + else + { + gf_vm_area_t *vm_area = NULL; + gf_map_argu_t map = {0}; + + map.flags.cache_type = GF_MEM_UNCACHED; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = allocation->phys_addr + adapter->vidmm_bus_addr; + map.size = allocation->orig_size; + + vm_area = gf_map_io_memory(NULL, &map); + + util_dump_raw_memory_to_file(vm_area->virt_addr, allocation->orig_size, alloc_file_name); + + gf_unmap_io_memory(vm_area); + vm_area = NULL; + } + + if(allocation->compress_format) + { + vidmm_dump_flagbuffer_to_file(file_name + name_offset, allocation); + } +} + +void vidmm_dump_allocation_content(vidmm_allocation_t *allocation) +{ + gpu_device_t *device = allocation->device; + adapter_t * adapter = device->adapter; + + if(allocation->pages_mem) + { + gf_map_argu_t map = {0}; + gf_vm_area_t *pcie_addr = NULL; + + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.cache_type = GF_MEM_WRITE_COMBINED; + map.flags.mem_type = GF_SYSTEM_RAM; + map.size = allocation->orig_size; + map.memory = allocation->pages_mem; + + pcie_addr = gf_map_pages_memory(NULL, &map); + + util_dump_memory(NULL, pcie_addr->virt_addr, allocation->orig_size, "allocation mem content"); + + gf_unmap_pages_memory(pcie_addr); + } + else + { + gf_vm_area_t *vm_area = NULL; + gf_map_argu_t map = {0}; + + if (allocation->phys_addr >= adapter->Visible_vram_size) + { + gf_error("at_type %d, trying to dump cpu invisible mem!!!\n", allocation->at_type); + return; + } + + map.flags.cache_type = GF_MEM_UNCACHED; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = allocation->phys_addr + adapter->vidmm_bus_addr; + map.size = allocation->orig_size; + + vm_area = gf_map_io_memory(NULL, &map); + + util_dump_memory(NULL, vm_area->virt_addr, allocation->orig_size, "allocation mem content"); + + gf_unmap_io_memory(vm_area); + vm_area = NULL; + } + + return; +} + + +static void vidmmi_dump_allocations(vidmm_mgr_t *mm_mgr, struct list_head *allocation_list) +{ + vidmm_allocation_t *allocation = NULL, *allocation_next; + + list_for_each_entry_safe(allocation, allocation_next, allocation_list, list_item) + { + gf_info("allo:%x, refcount:%d, dev:%x, fmt:%d-%d-%d-%d, slotbuffer_index:%d, flag: 0x%x, W-H-P:%d-%d-%d, size:%6dk, gvm:%llx, AT:0x%x, status:%8x, pid:%d, tid: %d, proc:%s.\n", + allocation->handle, allocation->ref_count, allocation->device->handle, + allocation->hw_format, allocation->compress_format, allocation->flag.swizzled, allocation->bit_count, + allocation->slot_index, allocation->flag, + allocation->width, allocation->height, allocation->pitch, + util_align(allocation->orig_size, util_max(allocation->alignment, mm_mgr->adapter->os_page_size)) >> 10, + allocation->phys_addr, allocation->at_type, allocation->status.temp_unpagable, + allocation->device->pid, allocation->device->tid, allocation->device->pname); + } +} + +void vidmm_dump_resource(adapter_t *adapter) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = NULL; + + unsigned int idx, priority; + + for(idx = 0; idx < mm_mgr->segment_cnt; idx++) + { + //if(idx > 2) break; + + segment = &mm_mgr->segment[idx]; + + gf_info("\n\n"); + + gf_mutex_lock(segment->lock); + + gf_info("**** segment[%d] size: %dK, used:%lldk, allocation_num:%d\n", idx, + segment->gpu_vm_size >> 10, (segment->pagable_size + segment->unpagable_size + segment->reserved_size) >> 10, + (segment->pagable_num + segment->unpagable_num)); + gf_info("@@ Heap start: 0x%08x, size: %4dM, free size: %10dk.\n", + segment->heap.start, segment->heap.size >> 20, segment->heap.free.size >> 10); + gf_info("@@ Small Heap start: 0x%08x, size: %4dM, free size: %10dk.\n\n", + segment->small_heap.start, segment->small_heap.size >> 20, segment->small_heap.free.size >> 10); + + gf_info("## unpagable reserved size: %dk.\n", segment->reserved_size >> 10); + gf_info("## unpagable allocation num: %3d. size: %lldk\n", segment->unpagable_num, segment->unpagable_size >> 10); + + vidmmi_dump_allocations(mm_mgr, &segment->unpagable_resident_list); + + gf_msleep(10); + + gf_info("##pagable allocation num: %3d. size: %lldk\n", segment->pagable_num, segment->pagable_size >> 10); + + for(priority = PDISCARD; priority < PALL; priority++) + { + gf_info("----priority: %d.\n", priority); + + vidmmi_dump_allocations(mm_mgr, &segment->pagable_resident_list[priority]); + } + + gf_mutex_unlock(segment->lock); + + gf_msleep(10); + } +} + +void vidmm_dump_memtrack(struct os_seq_file *seq_file, adapter_t *adapter, int pid) +{ + gpu_device_t *device = NULL; + gpu_device_t *device_next = NULL; + + cm_allocation_open_instance_t *instance = NULL, *instance_next; + + unsigned long long total = 0; + + UNUSED(pid); + + gf_seq_printf(seq_file, "Name PID Usage(kB)\n"); + gf_seq_printf(seq_file, "================================================================\n"); + + gf_mutex_lock(adapter->device_list_lock); + + list_for_each_entry_safe(device, device_next, &adapter->device_list, list_node) + { + unsigned long long mem_size = 0; + + cm_device_lock(device); + + list_for_each_entry_safe(instance, instance_next, &device->allocation_open_instance_list, list_node) + { + vidmm_allocation_t *allocation = instance->allocation; + + if(device == allocation->device) + { + mem_size += (util_align(allocation->orig_size, util_max(allocation->alignment, adapter->os_page_size)) >> 10); + } + } + + total += mem_size; + + cm_device_unlock(device); + + gf_seq_printf(seq_file, " %-32s %-16d %-d\n", device->pname, device->pid, mem_size); + } + + gf_mutex_unlock(adapter->device_list_lock); + + gf_seq_printf(seq_file, "================================================================\n"); + gf_seq_printf(seq_file, "Total %d(kB)\n", total); + +} + +void vidmm_dump_bl_heap(adapter_t *adapter) +{ + vidmm_mgr_t* mm_mgr = adapter->mm_mgr; + heap_t * pblHeap = &mm_mgr->blheap; + + gf_info("********BL heap start: 0x%llx, size 0x%llx \n********************\n", pblHeap->start, pblHeap->size); + + heap_dump(pblHeap); +} + + +void vidmm_dump_heap(struct os_seq_file *seq_file, adapter_t *adapter, int id) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + gpu_device_t *device = NULL; + gpu_device_t *device_next = NULL; + vidmm_segment_t *segment = NULL; + unsigned int priority; + + int cnt = vidmm_get_segment_count(adapter); + + if(id > cnt - 1) + { + gf_seq_printf(seq_file, "vidmm_dump_heap_allocation invalid id %x\n", id); + return; + } + + segment = &mm_mgr->segment[id]; + + gf_seq_printf(seq_file, "\n\n"); + + gf_mutex_lock(segment->lock); + + gf_seq_printf(seq_file, "**** segment[%d] size: %dK, used:%lldk, allocation_num:%d\n", id, + segment->gpu_vm_size >> 10, (segment->pagable_size + segment->unpagable_size + segment->reserved_size) >> 10, + (segment->pagable_num + segment->unpagable_num)); + gf_seq_printf(seq_file, "@@ Heap start: 0x%08llx, size: %4dM, free size: %10dk.\n", + segment->heap.start, segment->heap.size >> 20, segment->heap.free.size >> 10); + gf_seq_printf(seq_file, "@@ Small Heap start: 0x%08llx, size: %4dM, free size: %10dk.\n\n", + segment->small_heap.start, segment->small_heap.size >> 20, segment->small_heap.free.size >> 10); + + gf_seq_printf(seq_file, "## unpagable reserved size: %dk.\n", segment->reserved_size >> 10); + + gf_mutex_lock(adapter->device_list_lock); + + list_for_each_entry_safe(device, device_next, &adapter->device_list, list_node) + { + vidmm_allocation_t *allocation = NULL, *allocation_next = NULL; + + int num=0; + unsigned long long size=0; + + cm_device_lock(device); + + gf_seq_printf(seq_file, "----------------------------------------------------------------------\n"); + gf_seq_printf(seq_file, " pid dev client\n"); + gf_seq_printf(seq_file, " %10d %8x %s \n", device->pid, device->handle, device->pname); + + list_for_each_entry_safe(allocation, allocation_next, &segment->unpagable_resident_list, list_item) + { + if(allocation->device->handle == device->handle) + { + gf_seq_printf(seq_file, "allo: %x, dev: %x, fmt: %3d-%2d-%d-%2d, W-H-P: %8d-%4d-%8d, size: %6dk, gvm: %llx, AT:0x%02x, page:%8x, prefer:%3d-%3d-%3d.\n", + allocation->handle, allocation->device->handle, + allocation->hw_format, allocation->compress_format, allocation->flag.swizzled, allocation->bit_count, + allocation->width, allocation->height, allocation->pitch, + util_align(allocation->orig_size, util_max(allocation->alignment, mm_mgr->adapter->os_page_size)) >> 10, + allocation->phys_addr, allocation->at_type, + allocation->status.temp_unpagable, + allocation->preferred_segment.segment_id_0,allocation->preferred_segment.segment_id_1,allocation->preferred_segment.segment_id_2); + + num++; + size += util_align(allocation->orig_size, util_max(allocation->alignment, mm_mgr->adapter->os_page_size)); + } + } + + allocation = NULL; + allocation_next = NULL; + + for(priority = PDISCARD; priority < PALL; priority++) + { + gf_seq_printf(seq_file, "----priority: %d.\n", priority); + + list_for_each_entry_safe(allocation, allocation_next, &segment->pagable_resident_list[priority], list_item) + { + if(allocation->device->handle == device->handle) + { + gf_seq_printf(seq_file, "allo: %x, dev: %x, fmt: %3d-%2d-%d-%2d, W-H-P: %8d-%4d-%8d, size: %6dk, gvm: %llx, AT:0x%02x, page:%8x, prefer:%3d-%3d-%3d.\n", + allocation->handle, allocation->device->handle, + allocation->hw_format, allocation->compress_format, allocation->flag.swizzled, allocation->bit_count, + allocation->width, allocation->height, allocation->pitch, + util_align(allocation->orig_size, util_max(allocation->alignment, mm_mgr->adapter->os_page_size)) >> 10, + allocation->phys_addr, allocation->at_type, + allocation->status.temp_unpagable, + allocation->preferred_segment.segment_id_0,allocation->preferred_segment.segment_id_1,allocation->preferred_segment.segment_id_2); + + num++; + size += util_align(allocation->orig_size, util_max(allocation->alignment, mm_mgr->adapter->os_page_size)); + } + } + + } + + cm_device_unlock(device); + + gf_seq_printf(seq_file, " allocation num %d, size %dk \n\n", num, size >> 10); + } + + gf_seq_printf(seq_file, "----------------------------------------------------------------------\n"); + + gf_mutex_unlock(adapter->device_list_lock); + + gf_mutex_unlock(segment->lock); +#if DEBUG_HIGH_4G_MEM + if((id == 1) && (adapter->Reserve_Buffer != NULL)) + { + vidmm_segment_memory_t *reserved_memory = adapter->Reserve_Buffer; + + util_dump_memory(reserved_memory->vma->virt_addr, HIGH_4G_MEM_RESERVE_SIZE, "mem reserved for high 4g test"); + } +#endif + + vidmm_dump_bl_heap(adapter); +} + +void* vidmm_get_from_gem_handle(adapter_t *adapter, gpu_device_t *device, unsigned int gem_handle) +{ + unsigned int handle; + void *ret = NULL; + +#ifdef VMI_MODE + handle = gem_handle; + ret = get_from_handle(&adapter->hdl_mgr, handle); +#else + if (adapter->drm_cb) + { + handle = adapter->drm_cb->gem.get_from_handle(device->filp, gem_handle); + if (handle) + { + ret = get_from_handle(&adapter->hdl_mgr, handle); + } + } +#endif + + return ret; +} diff --git a/drivers/gpu/drm/arise/core/vidmm/vidmm.h b/drivers/gpu/drm/arise/core/vidmm/vidmm.h new file mode 100644 index 0000000000000..468326bec5b48 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidmm/vidmm.h @@ -0,0 +1,391 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_VIDMM_H__ +#define __GF_VIDMM_H__ + +#include "heap_manager.h" +#include "list.h" +#include "context.h" +#include "gf_def.h" + +#define SEGMENT_ID_INVALID 0x0 +#define SEGMENT_ID_LOCAL 0x1 + +#define MAX_SEGMENT_ID 0xF +#define MAX_APERTURES 0x10 + +#define FLAG_BUFFER_RANGE_NUM 1 + +typedef union _vidmm_segment_desc_flags_t +{ + struct + { + unsigned int require_system_pages :1; // if need allocate pages after vm range allocate, since some chip have phys memory on gpu chip, + // these phys_addr same with vm_addr, no need allocate phys memory on this, + // this flags also implicit gpu need gart to access these phys page. + unsigned int system_phys_mem_reserved :1; //reserved system physical mem + unsigned int chip_phys_mem_reserved :1; //reserved on chip physical mem + unsigned int system_pages_reserved :1; //system allocated pages mem, will allocated these pages when init + unsigned int system_pages_un_reserved :1; //normal system mem + + unsigned int cpu_visible :1; // set if this gpu vm range described phys addr can be mapped to cpu vm range and accessed by CPU + unsigned int support_aperture :1; // do this segment support aperture + unsigned int support_snoop :1; + unsigned int support_manual_flush :1; + + unsigned int mtrr :1; //cpu side feature, if this flag set, we can set this GPU memory range as wc by add_mtrr. + unsigned int small_heap_available :1; + unsigned int page_64kb_enable :1; + unsigned int secure_range :1; + }; + unsigned int value; +}vidmm_segment_desc_flags_t; + + +/* +* segment: +* +* |<--------------------- gpu_vm_size ------------------->| +* |<--reserved_vm_size-->| +* +----------------------+--------------------------------+ +* | reserved_vmem | heap | +* +----------------------+--------------------------------+ +* ^ ^ +* gpu_vm_start reserved_vm_end +* +*/ +typedef struct _vidmm_segment +{ + unsigned int segment_id; //segment id + const char *segment_name; + vidmm_segment_desc_flags_t flags; + unsigned int segment_alignment; //elite dynamic: 4M, dst/exc/elite pcie/ahb: 4k + unsigned char *cpu_vm_start; + unsigned long long gpu_vm_start; + unsigned long long reserved_vm_end; + unsigned int reserved_vm_size; + unsigned long long gpu_vm_size; + unsigned long long small_heap_size; + unsigned long long small_heap_max_allocate_size; + + unsigned long long phys_addr_start; //used for reserved system memory for elite + + int mtrr_reg; //used in x86 when mtrr bit in flag. + heap_t heap; + heap_t small_heap; //heap used allocate small and unpagable allocation. + + struct list_head pagable_resident_list[PALL]; + struct list_head unpagable_resident_list; + + long long pagable_size; /* pagable memory size */ + long long unpagable_size; /* unpable memory size */ + + long long reserved_size; /* unpagable reserved from this segment */ + + int pagable_num; /* pagable alloacation num*/ + int unpagable_num; /* unpagable allocation num*/ + + struct os_mutex *lock; + struct os_mutex *secure_lock; + + struct os_pages_memory *reserved_pages; +} vidmm_segment_t; + +typedef struct _vidmm_segment_memory +{ + unsigned int segment_id; + unsigned long long gpu_virt_addr; + unsigned int snooping_enabled; // usr this flag to support per page snoop + list_node_t *list_node; + struct os_pages_memory *pages_mem; + gf_vm_area_t *vma; +} vidmm_segment_memory_t; + +typedef struct vidmm_map_flags +{ + unsigned char mem_space; + unsigned char cache_type; + unsigned char read_only :1; + unsigned char write_only :1; +}vidmm_map_flags_t; + +typedef struct _vidmm_segment_preference +{ + union + { + struct + { + unsigned int segment_id_0 : 5; // 0x0000001F + unsigned int direction_0 : 1; // 0x00000020 + unsigned int segment_id_1 : 5; // 0x000007C0 + unsigned int direction_1 : 1; // 0x00000800 + unsigned int segment_id_2 : 5; // 0x0001F000 + unsigned int direction_2 : 1; // 0x00020000 + unsigned int segment_id_3 : 5; // 0x007C0000 + unsigned int direction_3 : 1; // 0x00800000 + unsigned int segment_id_4 : 5; // 0x1F000000 + unsigned int direction_4 : 1; // 0x20000000 + unsigned int reserved : 2; // 0xC0000000 + }; + unsigned int value; + }; +} vidmm_segment_preference_t; + +typedef struct _vidmm_allocation_flag +{ + union + { + struct + { + unsigned int cpu_visible : 1; + unsigned int primary : 1;//primary means must force local + unsigned int swizzled : 1; + unsigned int none_snooping : 1; + unsigned int unpagable : 1; + unsigned int fence_sync : 1; /* binding sync object to this allocation */ + unsigned int secured : 1; + unsigned int compressed : 1; + unsigned int try_secure : 1; + unsigned int video : 1; + unsigned int camera : 1; + unsigned int cacheable : 1; + unsigned int force_clear : 1;//force clear when create + unsigned int overlay : 1;// overlay means can't put to snoopable segment + unsigned int bVideoInternal : 1;//e3k video ALWAYS set this flag for resource assignment indication. + unsigned int bHwctxBuffer : 1;//used in aarch64 platform to put 2d hwctx buffer in local heap to improve the performance + }; + unsigned int value; + }; +} vidmm_allocation_flag_t; + +typedef struct _vidmm_allocation_status +{ + union + { + struct + { + unsigned int submit_ref_cnt : 16; + unsigned int force_unpagable : 5; + unsigned int wait_for_destroy : 1; + unsigned int reserved0 : 10; + }; + + unsigned int temp_unpagable; + }; + union + { + struct + { + unsigned int need_restore : 1; /* means local video memory saved to pages_mem, used restore when resume */ + unsigned int reserved1 :31; + }; + unsigned int value2; + }; +} vidmm_allocation_status_t; + +/* since we support paging, so allocation segment memory things unstable. but how to access it. there are two method. + * 1. hold paging lock and access. like paging process. + * 2. first set allocation is temp_unpagable, and then wait paging idle, then the segment members are stable, lock allocation go this way + */ + +typedef struct _vidmm_allocation +{ + struct list_head list_item; // item may in segment pagable list, unpagable list, accord allocation status + struct list_head destroy_list_item; // use for defer destroy list + struct list_head device_ref_list; // list for which device referenced this allocation; + + unsigned int handle; + gpu_device_t *device; + unsigned int alignment; + unsigned int orig_size; // require size from user mode + unsigned int size; // allocation aligned size + vidmm_segment_preference_t preferred_segment_raw; // raw use store preferred_segment client requested. + vidmm_segment_preference_t preferred_segment; // for some hw limitation, use requested segment we can not use. + // we need validate the raw, here is the real one used to allocate. + unsigned int priority; + vidmm_allocation_flag_t flag; //unchangeable allocation flags. + int ref_count; + unsigned int segment_id; + unsigned int backup_segment_id; + unsigned long long phys_addr; // deprecated, we will rename it to gpu_virt_addr. phys_addr is physical address of memory + unsigned long long cpu_phys_addr; // only take effect when allocation is allocated from IO local + unsigned int snooping_enabled; // default snoop disabled, only enable it when use, like when lock. + struct os_pages_memory *pages_mem; + void *file_storage; // shmem file cache + list_node_t *list_node; + unsigned long long fence_id[MAX_ENGINE_COUNT]; + unsigned long long write_fence_id[MAX_ENGINE_COUNT]; + unsigned long long last_paging; // last paging fence id + vidmm_allocation_status_t status; //dynamic changed status during allocation's life + int render_count[MAX_ENGINE_COUNT]; + int write_render_count[MAX_ENGINE_COUNT]; + struct os_spinlock *lock; + + /* chip related attributes */ + unsigned char compress_format; + unsigned int bit_count; + unsigned int width; + unsigned int height; + unsigned int aligned_width; + unsigned int aligned_height; + unsigned int tiled_width; + unsigned int tiled_height; + unsigned int pitch; + unsigned int hw_format; + unsigned int at_type; + + void *bo; + unsigned int sync_obj; // binding fence sync object to this allocation, this sync obj create/destroy just follow allocation's + unsigned long long fence_addr; + list_node_t *bl_node; + unsigned int slot_index; + int perf_swap_hint; +}vidmm_allocation_t; + +typedef struct _vidmm_paging_allocation +{ + list_node_t *list_node; + int segment_id; + unsigned int size; + unsigned long long gpu_virt_addr; + + vidmm_allocation_t *allocation; + vidmm_allocation_t *temp_allocation; +}vidmm_paging_allocation_t; + +typedef struct _vidmm_rename_create_arg +{ + vidmm_allocation_t *reference; // input + unsigned int hAllocation; // output + unsigned long long Size; // output +} vidmm_rename_create_t; + +typedef struct _vidmm_gf_create_arg +{ + gf_create_allocation_t *create_data; + struct os_pages_memory *import_pages_mem; +} vidmm_gf_create_t; + +typedef gf_create_alloc_info_t vidmm_escape_create_t; + +#define VIDMM_CREATE_TYPE_ESCAPE (1) +#define VIDMM_CREATE_TYPE_GF (2) +#define VIDMM_CREATE_TYPE_RENAME (3) + +typedef struct _vidmm_create_allocation_arg +{ + unsigned int create_type; + unsigned int allocation_count; + + union { + vidmm_gf_create_t *create_list; // for gf_create + vidmm_escape_create_t *info_list; // for escape_create + vidmm_rename_create_t *rename_list; // for rename_create + }; + + void **bos; // input, used to pass gem_obj to core +} vidmm_create_allocation_arg_t; + +typedef struct _vidmm_gart_table_info +{ + list_node_t *list_node; + unsigned int segment_id; + vidmm_segment_memory_t *segment_memory; + void *virt_addr; + void *pcie_addr; + unsigned long long phys_addr; + unsigned long long gart_start_addr; //the start address to be gart + unsigned int size; /* in bytes */ + unsigned int page_count; + unsigned int pcie_count; + int dirty; + unsigned long long gart_table_dirty_addr; + unsigned long long gart_table_dirty_mask; + unsigned int page_key_ram[512]; + void *backup; + void *chip_private; +} vidmm_gart_table_info_t; + +typedef struct _vidmm_destroy_allocatin_arg +{ + int allocation_count; + vidmm_allocation_t **allocation_list; +} vidmm_destroy_allocatin_arg_t; + +typedef struct vidmm_get_allocation_info +{ + vidmm_allocation_t *allocation; + unsigned long long gpu_vm_addr; + unsigned int tiled; + unsigned int pitch; + unsigned int snoop; + unsigned int segment_id; + unsigned int hw_format; + unsigned int ForceLocal; +}vidmm_get_allocation_info_t; + + +extern int vidmm_init(adapter_t *adapter, int reserved_vmem); +extern void vidmm_destroy(adapter_t *adapter); +extern int vidmm_save(adapter_t *adapter); +extern void vidmm_restore(adapter_t *adapter); +extern int vidmm_save_allocation(gpu_device_t *device, vidmm_allocation_t *allocation); +extern void vidmm_restore_allocation(gpu_device_t *device, vidmm_allocation_t *allocation); +extern int vidmm_create_allocation(gpu_device_t *device, vidmm_create_allocation_arg_t *data); +extern void vidmm_destroy_allocation(gpu_device_t *device, vidmm_destroy_allocatin_arg_t *data); +extern int vidmm_segment_unresident_allocations(adapter_t *adapter, unsigned int segment_id); +extern int vidmm_resident_one_allocation(gpu_device_t *device, void *ptask, vidmm_paging_allocation_t *paging_allocation, unsigned int); +extern void vidmm_map_gart_table(adapter_t *adapter, vidmm_allocation_t *allocation, int snooping); +extern void vidmm_destroy_defer_allocation(adapter_t *adapter); +extern void vidmm_try_decrease_heap_size(adapter_t *adapter); +extern void vidmm_validate_allocation_memory(adapter_t*, vidmm_allocation_t *allocation); +extern int vidmm_allocate_super_page(adapter_t *adapter, unsigned int preferred_segment_id, unsigned int size); +extern int vidmm_get_allocation_info(adapter_t *adapter, vidmm_get_allocation_info_t *info); +extern int vidmm_query_info(adapter_t *adapter, gf_query_info_t *info); +extern vidmm_segment_t* vidmm_get_segment_by_id(adapter_t *adapter, unsigned int segment_id); +extern heap_t * vidmm_get_burst_length_heap(adapter_t *adapter); +extern int vidmm_get_segment_count(adapter_t *adapter); +extern vidmm_segment_memory_t *vidmm_allocate_segment_memory(adapter_t *adapter, unsigned int segment_id, unsigned int size, int direction); +extern void vidmm_release_segment_memory(adapter_t *adapter, vidmm_segment_memory_t *segment_memory); +extern void* vidmm_map_segment_memory(adapter_t *adapter, void *filp, vidmm_segment_memory_t *segment_memory, vidmm_map_flags_t *map); +extern void vidmm_unmap_segment_memory(adapter_t *adapter, vidmm_segment_memory_t *segment_memory, enum gf_mem_space mem_space); +extern void vidmm_release_temp_paging_memory(adapter_t *adapter, void *ptask); +extern void vidmm_dump_allocation(adapter_t *adapter); +extern int vidmm_allocate_mirror_super_page_elt(adapter_t *adapter, unsigned int count, unsigned int segment_id); +extern void vidmm_destroy_mirror_super_page_elt(adapter_t *adapter, unsigned int count, unsigned int segment_id); +extern void vidmm_add_allocation_to_resident_list(adapter_t *adapter, vidmm_allocation_t *allocation); +extern void vidmm_remove_allocation_from_resident_list(adapter_t *adapter, vidmm_allocation_t *allocation); +extern void vidmm_add_allocation_to_cache_list(adapter_t *adapter, vidmm_allocation_t *allocation); +extern void vidmm_remove_allocation_from_cache_list(adapter_t *adapter, vidmm_allocation_t *allocation); +extern void vidmm_dump_resource(adapter_t *adapter); +extern void vidmm_dump_heap(struct os_seq_file *seq_file, adapter_t *adapter, int id); +extern void vidmm_dump_memtrack(struct os_seq_file *seq_file, adapter_t *adapter, int pid); +extern void vidmm_dump_allocation_to_file(char *file, unsigned int offset, unsigned int hAllocation, adapter_t *adapter); +extern void vidmm_dump_allocation_content(vidmm_allocation_t *allocation); +extern void vidmm_get_map_allocation_info(adapter_t *adapter, vidmm_allocation_t *allocation, gf_map_argu_t *map); + + +extern void vidmm_unreference_allocation(adapter_t *adapter, gpu_device_t *device, vidmm_allocation_t *allocation); + +extern void vidmm_reference_allocation(adapter_t *adapter, gpu_device_t *device, vidmm_allocation_t *allocation); + +extern void* vidmm_get_from_gem_handle(adapter_t *adapter, gpu_device_t *device, unsigned int gem_handle); +extern void vidmm_mark_pagable(adapter_t *adapter, vidmm_allocation_t *allocation); +extern void vidmm_prepare_and_mark_unpagable(adapter_t *adapter, vidmm_allocation_t *allocation, gf_open_allocation_t *info); +extern void vidmm_fill_allocation_info(adapter_t *adapter, vidmm_allocation_t *allocation, gf_open_allocation_t *info); +extern void vidmm_dump_flagbuffer_to_file(char *file_name, vidmm_allocation_t *allocation); +extern void vidmm_dump_bl_heap(adapter_t *adapter); +#endif + diff --git a/drivers/gpu/drm/arise/core/vidmm/vidmm_allocate.c b/drivers/gpu/drm/arise/core/vidmm/vidmm_allocate.c new file mode 100644 index 0000000000000..a81684c03ffd8 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidmm/vidmm_allocate.c @@ -0,0 +1,1316 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "vidmm.h" +#include "vidmmi.h" +#include "vidsch.h" + +static unsigned int vidmmi_allocate_bl_slot(vidmm_mgr_t *mm_mgr, vidmm_allocation_t *allocation) +{ + unsigned int bl_size = allocation->size >> 9;// 1:512 compress rate + heap_t * pblHeap = &mm_mgr->blheap; + + allocation->bl_node = heap_allocate(pblHeap, bl_size, pblHeap->alignment , 0); + + if(!allocation->bl_node) + { + gf_error("bl allocate failed, allo handle0x:%x, bl size:0x%x\n", allocation->handle, bl_size); + vidmm_dump_bl_heap(mm_mgr->adapter); + gf_assert(0, "bl allocate failed"); + return 0; + } + else + { + return gf_do_div(allocation->bl_node->aligned_offset - pblHeap->start ,pblHeap->alignment); //slice index + } +} + +static void vidmmi_free_bl_slot(vidmm_mgr_t *mm_mgr, vidmm_allocation_t *allocation) +{ + heap_release(&mm_mgr->blheap, allocation->bl_node); +} + +unsigned int vidmmi_query_max_size_of_local_allocation(adapter_t *adapter) +{ + unsigned int max_size = 0; + + //gf_info("%s() fb segment size-0x%x, Real_vram_size-0x%x\n", __func__, adapter->Visible_vram_size, adapter->Real_vram_size); + if(adapter->Visible_vram_size == 512*1024 *1024) + { + max_size = (8*1024) * (2*1024); //8k*2k + } + else + { + max_size = (4*1024) * (2*1024); //4k*2k + } + + return max_size; +} + +static list_node_t* vidmmi_allocate_segment_memory(vidmm_mgr_t *mm_mgr, int segment_id, unsigned int size, unsigned int alignment, int direction, int secured) +{ + list_node_t *list_node = NULL; + vidmm_segment_t *segment = NULL; + + gf_assert(SEGMENT_ID_INVALID != segment_id, "SEGMENT_ID_INVALID != segment_id"); + + segment = &mm_mgr->segment[segment_id]; + + if(secured && !segment->flags.secure_range) + { + return NULL; + } + + if(segment->flags.small_heap_available && (segment->small_heap_max_allocate_size >= size)) + { + list_node = heap_allocate(&segment->small_heap, size, alignment, direction); + } + + if(NULL == list_node) + { + list_node = heap_allocate(&segment->heap, size, alignment, direction); + } + + return list_node; +} + +void vidmmi_release_segment_memory(vidmm_mgr_t *mm_mgr, int segment_id, list_node_t *list_node) +{ + vidmm_segment_t *segment = NULL; + + segment = &mm_mgr->segment[segment_id]; + + if(list_node) + { + if(list_node->aligned_offset < (segment->heap.start + segment->heap.size)) + { + heap_release(&segment->heap, list_node); + } + else + { + gf_assert(segment->flags.small_heap_available, "segment->flags.small_heap_available"); + + heap_release(&segment->small_heap, list_node); + } + } +} + +/* NOTE: fill allocation is thread unsafe, this func can only used in vidmm_create_allocation + * before add allocation to resident list + */ + +static void vidmmi_fill_allocation(vidmm_mgr_t *mm_mgr, vidmm_allocation_t *allocation, unsigned int fill_pattern) +{ + adapter_t *adapter = mm_mgr->adapter; + vidmm_private_build_paging_buffer_arg_t build_paging_buffer = {0}; + + task_paging_t *paging_task = vidsch_allocate_paging_task(adapter, 16*4*1024, 1); + + int result = S_OK; + + gf_begin_section_trace_event("fill_allocation"); + gf_counter_trace_event("arg_allocation", allocation->handle); + gf_counter_trace_event("arg_size", allocation->size); + + paging_task->paging_allocation_list[0].allocation = allocation; + paging_task->paging_allocation_num = 1; + + allocation->render_count[adapter->paging_engine_index]++; + allocation->write_render_count[adapter->paging_engine_index]++; + + build_paging_buffer.allocation = allocation; + build_paging_buffer.operation = BUILDING_PAGING_OPERATION_FILL; + build_paging_buffer.dma_buffer = paging_task->dma->virt_base_addr; + build_paging_buffer.dma_size = paging_task->dma->size; + build_paging_buffer.multi_pass_offset = 0; + build_paging_buffer.fill.fill_size = allocation->size; + build_paging_buffer.fill.fill_pattern = fill_pattern; + build_paging_buffer.fill.phy_addr = allocation->phys_addr; + build_paging_buffer.fill.segment_id = allocation->segment_id; + + result = mm_mgr->chip_func->build_paging_buffer(adapter, &build_paging_buffer); + + gf_assert(result == S_OK, "vidmmi_fill_allocation not sucess"); + + paging_task->command_length = util_get_ptr_span(build_paging_buffer.dma_buffer, paging_task->dma->virt_base_addr); + + vidsch_submit_paging_task(adapter, paging_task); + + gf_end_section_trace_event(result); +} + +/* + * vidmmi_allocate_video_memroy_try will try muti segment_id specified on prefreered_segment. + */ +int vidmmi_allocate_video_memory_try(vidmm_mgr_t *mm_mgr, vidmm_allocation_t *allocation, vidmm_segment_preference_t *preferred_segment) +{ + list_node_t *list_node = NULL; + int segment_id = 0; + int direction = 0; + vidmm_segment_t *segment = NULL; + heap_t *heap = NULL; + int result = E_FAIL; + + /* + * try to allocate list node by preferred segment list order + */ + + if(allocation->flag.try_secure) + { + segment_id = mm_mgr->secure_segment_id; + segment = &mm_mgr->segment[segment_id]; + + if((segment!= NULL) && segment->flags.secure_range) + { + list_node = vidmmi_allocate_segment_memory(mm_mgr, segment_id, allocation->orig_size, allocation->alignment, \ + direction, allocation->flag.secured); + } + } + + if(list_node == NULL) + { + segment_id = preferred_segment->segment_id_0; + direction = preferred_segment->direction_0; + + if(SEGMENT_ID_INVALID != segment_id) + { + list_node = vidmmi_allocate_segment_memory(mm_mgr, segment_id, allocation->orig_size, allocation->alignment, \ + direction, allocation->flag.secured); + } + } + + if(list_node == NULL) + { + segment_id = preferred_segment->segment_id_1; + direction = preferred_segment->direction_1; + + if(SEGMENT_ID_INVALID != segment_id) + { + list_node = vidmmi_allocate_segment_memory(mm_mgr, segment_id, allocation->orig_size, allocation->alignment, \ + direction, allocation->flag.secured); + } + } + + if(list_node == NULL) + { + segment_id = preferred_segment->segment_id_2; + direction = preferred_segment->direction_2; + + if(SEGMENT_ID_INVALID != segment_id) + { + list_node = vidmmi_allocate_segment_memory(mm_mgr, segment_id, allocation->orig_size, allocation->alignment, \ + direction, allocation->flag.secured); + } + } + + if(list_node == NULL) + { + segment_id = preferred_segment->segment_id_3; + direction = preferred_segment->direction_3; + segment = &mm_mgr->segment[segment_id]; + + if(SEGMENT_ID_INVALID != segment_id) + { + list_node = vidmmi_allocate_segment_memory(mm_mgr, segment_id, allocation->orig_size, allocation->alignment, \ + direction, allocation->flag.secured); + } + } + + if(list_node == NULL) + { + segment_id = preferred_segment->segment_id_4; + direction = preferred_segment->direction_4; + + if(SEGMENT_ID_INVALID != segment_id) + { + list_node = vidmmi_allocate_segment_memory(mm_mgr, segment_id, allocation->orig_size, allocation->alignment, \ + direction, allocation->flag.secured); + } + } + + /* + * if list_node is NULL, then memory space is not enough. + */ + if(list_node != NULL) + { + segment = &mm_mgr->segment[segment_id]; + + allocation->segment_id = segment_id; + allocation->size = util_align(allocation->orig_size, segment->segment_alignment); + allocation->phys_addr = list_node->aligned_offset; + allocation->list_node = list_node; + allocation->cpu_phys_addr= allocation->phys_addr - segment->gpu_vm_start + segment->phys_addr_start; + + if(list_node->aligned_offset >= (segment->heap.start + segment->heap.size)) + { + gf_assert(segment->flags.small_heap_available, "segment->flags.small_heap_available"); + + allocation->flag.unpagable = TRUE; + } + + result = S_OK; + } + else + { + int id = 0; + + vidmm_trace("%s(): allocate video memory failed.\n", __func__); + vidmm_trace("requested_size: 0x%x, requeseted_segment:0x%08x.\n", allocation->orig_size, preferred_segment->value); + for(id=1; idsegment_cnt; id++) + { + segment = &mm_mgr->segment[id]; + heap = &segment->heap; + vidmm_trace("heap: ID:%d, size available: 0x%08x, flag: 0x%x\n", id, heap->size, segment->flags); + } + result = E_FAIL; + } + + vidmm_trace("create_video_memroy: allocation:0x%p, handle:0x%x. phys:0x%llx, size:0x%08x compress_format 0x%x segment_id %x at type %x direction %x secure flag %x\n", + allocation, allocation->handle, allocation->phys_addr, allocation->size, allocation->compress_format, allocation->segment_id, allocation->at_type, allocation->preferred_segment.direction_0, allocation->flag.secured); + + return result; +} + +void vidmmi_release_video_memory(vidmm_mgr_t *mm_mgr, vidmm_allocation_t *allocation) +{ +// vidmm_segment_t *segment = &mm_mgr->segment[allocation->segment_id]; + + allocation->snooping_enabled = FALSE; + + /* unmap acctually not needed, just for debug purpose or patch HW bug like HW access out allocation boundary, + * so when unmap need internally map a dummp page to Gart + */ + + /* if page mem not NULL and have valid segment id, mean Gart memory */ + if((allocation->pages_mem != NULL) && (allocation->segment_id != SEGMENT_ID_INVALID)) + { + mm_mgr->chip_func->unmap_gart_table(mm_mgr->adapter, allocation); + } + + if(allocation->list_node) + { + vidmmi_release_segment_memory(mm_mgr, allocation->segment_id, allocation->list_node); + + allocation->list_node = NULL; + allocation->phys_addr = 0; + allocation->size = 0; + allocation->segment_id = SEGMENT_ID_INVALID; + } +} + +#define SWAP_OUT_PAGES_SIZE 32*1024*1024 + +int vidmmi_allocate_system_memory(adapter_t *adapter, vidmm_allocation_t *allocation, int must_success, int paging_locked) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = NULL; + + int result = S_OK, try_times = 5; + + if(NULL == allocation->pages_mem) + { + unsigned int page_num = (allocation->orig_size + adapter->os_page_size - 1) / adapter->os_page_size; + unsigned int max_pages = must_success ? + mm_mgr->max_pages_num + mm_mgr->emergency_pages : + mm_mgr->max_pages_num; + int can_alloc = FALSE; + + gf_mutex_lock(mm_mgr->hw_lock); + + if((mm_mgr->own_pages_num + page_num) < max_pages) + { + mm_mgr->own_pages_num += page_num; + mm_mgr->used_pages_num += page_num; + can_alloc = TRUE; + } + + gf_mutex_unlock(mm_mgr->hw_lock); + + if(can_alloc) + { + alloc_pages_flags_t alloc_flags = {0}; + + int page_size = 0; + + segment = allocation->segment_id ? &mm_mgr->segment[allocation->segment_id] : mm_mgr->paging_segment; + + alloc_flags.dma32 = !adapter->hw_caps.address_mode_64bit; + alloc_flags.need_flush = !segment->flags.support_snoop; + alloc_flags.fixed_page = TRUE; + alloc_flags.need_dma_map = adapter->sys_caps.iommu_enabled; + page_size = segment->flags.page_64kb_enable ? GF_PAGE_64KB_SIZE : adapter->os_page_size; + + allocation->pages_mem = gf_allocate_pages_memory(adapter->os_device.pdev, allocation->orig_size, page_size, alloc_flags); + + if(allocation->pages_mem == NULL) + { + gf_mutex_lock(mm_mgr->hw_lock); + + mm_mgr->used_pages_num -= page_num; + mm_mgr->own_pages_num -= page_num; + gf_mutex_unlock(mm_mgr->hw_lock); + } + } + + if(allocation->pages_mem == NULL) + { + gf_info("allocate %x system pages failed. already used size: %dK, request size: %dk.\n", + allocation->handle, mm_mgr->used_pages_num << 2, page_num << 2); + } + + result = allocation->pages_mem ? S_OK : E_FAIL; + } + + return result; +} + +void vidmmi_release_system_memory(adapter_t *adapter, vidmm_allocation_t *allocation) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + + if(allocation->pages_mem) + { + int own_page = gf_is_own_pages(allocation->pages_mem); + unsigned int page_num = (allocation->orig_size + adapter->os_page_size - 1) / adapter->os_page_size; + + gf_free_pages_memory(adapter->os_device.pdev, allocation->pages_mem); + + gf_mutex_lock(mm_mgr->hw_lock); + + mm_mgr->used_pages_num -= page_num; + if(own_page) mm_mgr->own_pages_num -= page_num; + gf_mutex_unlock(mm_mgr->hw_lock); + + allocation->pages_mem = NULL; + } +} + +void vidmm_map_gart_table(adapter_t *adapter, vidmm_allocation_t *allocation, int snooping) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + +#ifndef GF_HW_NULL + mm_mgr->chip_func->map_gart_table(adapter, allocation, snooping); + + allocation->snooping_enabled = snooping; +#endif +} + +void vidmmi_destroy_allocation(adapter_t *adapter, vidmm_allocation_t *allocation) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + + vidmmi_release_video_memory(mm_mgr, allocation); + + vidmmi_release_system_memory(adapter, allocation); + + if(allocation->file_storage) + { + gf_release_file_storage(allocation->file_storage); + + allocation->file_storage = NULL; + mm_mgr->swap_page_num -= (allocation->orig_size + mm_mgr->adapter->os_page_size - 1) / mm_mgr->adapter->os_page_size; + } + + if(allocation->sync_obj != 0) + { + sync_trace("destroy allocation binding fence sync: %x, sync_obj:%x.\n", allocation->handle, allocation->sync_obj); + + vidsch_destroy_sync_object(adapter, allocation->device, allocation->sync_obj); + } + + if(allocation->compress_format != 0 && allocation->slot_index ) + { + vidmmi_free_bl_slot(mm_mgr, allocation); + allocation->slot_index = 0; + } + remove_handle(&adapter->hdl_mgr, allocation->handle); + + cm_device_create_num_dec(allocation->device); + + if(allocation->lock) + { + gf_destroy_spinlock(allocation->lock); + } + + gf_free(allocation); +} + +void vidmm_destroy_defer_allocation(adapter_t *adapter) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_allocation_t *allocation = NULL; + vidmm_allocation_t *allocation_next; + struct list_head destroy_list; + + INIT_LIST_HEAD(&destroy_list); + gf_mutex_lock(mm_mgr->list_lock); + list_splice(&mm_mgr->defer_destroy_list, &destroy_list); + list_init_head(&mm_mgr->defer_destroy_list); + gf_mutex_unlock(mm_mgr->list_lock); + + list_for_each_entry_safe(allocation, allocation_next, &destroy_list, destroy_list_item) + { + int idle; + /*lock allocation because prevent free allocation before unlock in other thread*/ + if(gf_spin_try_lock(allocation->lock) == GF_LOCK_FAILED) continue; + idle = vidsch_is_allocation_idle(adapter, ALL_ENGINE_MASK, allocation); + gf_spin_unlock(allocation->lock); + + if(idle) + { + list_del(&allocation->destroy_list_item); + if(allocation->segment_id != SEGMENT_ID_INVALID) + { + vidmm_remove_allocation_from_resident_list(adapter, allocation); + } + else if(allocation->pages_mem != NULL) + { + vidmm_remove_allocation_from_cache_list(adapter, allocation); + } + vidmmi_destroy_allocation(adapter, allocation); + } + } + + gf_mutex_lock(mm_mgr->list_lock); + list_splice(&destroy_list,&mm_mgr->defer_destroy_list); + gf_mutex_unlock(mm_mgr->list_lock); +} + +int vidmm_create_allocation(gpu_device_t *device, vidmm_create_allocation_arg_t *create) +{ + adapter_t *adapter = device->adapter; + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + int index = 0, result = S_OK; + + if(create->allocation_count <= 0) + { + result = E_INVALIDARG; + gf_error("%s: create->allocation_count <= 0.\n", __func__); + return result; + } + + vidmm_destroy_defer_allocation(adapter); + + + /* Three steps when create an allocation + * 1. describe allocation to get create info from chip layer. + * 2. create gpu virtual address range. + * 3. create system memory and map it for gart memory. (local already have vram bind to, no need) + */ + + for(index = 0; index < create->allocation_count; index++) + { + vidmm_describe_allocation_t desc_info = {0}; + vidmm_allocation_t *allocation = gf_calloc(sizeof(vidmm_allocation_t)); + vidmm_segment_t *segment = NULL; + + int create_system_cache = FALSE; + + if(allocation == NULL) + { + gf_error("%s: allocate allocation struct memory failed.\n", __func__); + result = E_OUTOFMEMORY; + goto exit; + } + + allocation->handle = add_handle(&adapter->hdl_mgr, HDL_TYPE_ALLOCATION, allocation); + allocation->ref_count = 1; + allocation->device = device; + + list_init_head(&allocation->device_ref_list); + list_init_head(&allocation->list_item); + list_init_head(&allocation->device_ref_list); + + + allocation->lock = gf_create_spinlock(0); + + cm_device_create_num_inc(device); + + /* Step 1: describe allocation */ + if(create->create_type == VIDMM_CREATE_TYPE_ESCAPE) + { + gf_create_alloc_info_t *desc = create->info_list + index; + + allocation->orig_size = desc->Size; + allocation->hw_format = desc->HwFormat; + allocation->at_type = desc->AtType; + allocation->priority = desc->Priority; + allocation->alignment = desc->Alignment; + allocation->preferred_segment_raw.value = desc->PreferredSegment; + + allocation->bit_count = desc->BitCount; + allocation->width = desc->Width; + allocation->height = desc->Height; + allocation->pitch = desc->Pitch; + + allocation->flag.cpu_visible = desc->CpuVisible; + allocation->flag.primary = desc->Primary; + allocation->flag.swizzled = desc->Swizzled; + allocation->flag.video = desc->Video; + allocation->flag.overlay = desc->Overlay; + allocation->flag.camera = desc->Camera; + allocation->flag.none_snooping = desc->bNonSnoop; + allocation->flag.unpagable = desc->Unpagable | !adapter->ctl_flags.paging_enable; + allocation->flag.fence_sync = desc->FenceSync; + + desc_info.create_info = desc; + } + else if(create->create_type == VIDMM_CREATE_TYPE_GF) + { + gf_create_allocation_t *create_hint = create->create_list[index].create_data; + + allocation->flag.fence_sync = create_hint->fence_sync; + + allocation->flag.primary = create_hint->primary; + + desc_info.create_gf = create->create_list + index; + } + else if(create->create_type == VIDMM_CREATE_TYPE_RENAME) + { + vidmm_allocation_t *src_allocation = create->rename_list[index].reference; + + allocation->alignment = src_allocation->alignment; + allocation->orig_size = src_allocation->orig_size; + allocation->hw_format = src_allocation->hw_format; + allocation->bit_count = src_allocation->bit_count; + allocation->priority = src_allocation->priority; + allocation->pitch = src_allocation->pitch; + allocation->at_type = src_allocation->at_type; + allocation->width = src_allocation->width; + allocation->height = src_allocation->height; + allocation->flag = src_allocation->flag; + + allocation->aligned_width = src_allocation->aligned_width; + allocation->aligned_height = src_allocation->aligned_height; + allocation->tiled_width = src_allocation->tiled_width; + allocation->tiled_height = src_allocation->tiled_height; + allocation->compress_format= src_allocation->compress_format; + + allocation->preferred_segment_raw.value = src_allocation->preferred_segment_raw.value; + allocation->preferred_segment.value = src_allocation->preferred_segment.value; + } + else + { + gf_error("create_type = %d", create->create_type); + } + + if(create->create_type != VIDMM_CREATE_TYPE_RENAME) + { + desc_info.allocation = allocation; + + result = mm_mgr->chip_func->describe_allocation(adapter, &desc_info); + + if(result != S_OK) + { + gf_error("%s: describe_allocation failed.\n", __func__); + goto exit; + } + } + + /* Step 2: create video memory for allocation */ + + if(allocation->flag.primary) + { + /* direction = 1 have problem when vt switch do not know why? */ + allocation->preferred_segment.direction_0 = 0; + } + +#ifdef GF_HW_NULL + if(adapter->hw_caps.local_only == FALSE) + { + allocation->preferred_segment.segment_id_0 = 2; + } +#endif + result = vidmmi_allocate_video_memory_try(mm_mgr, allocation, &allocation->preferred_segment); + + if(result != S_OK) + { + int force_create = FALSE; + + /* rename not do paging, just return fail */ + if(!adapter->ctl_flags.paging_enable || (create->create_type == VIDMM_CREATE_TYPE_RENAME)) + { + gf_error("%s: allocate video memory failed while paging disabled, need size:%lld, AT:%d,prefer:%d:%d:%d, prefered raw:%d:%d:%d\n", + __func__,allocation->size, allocation->at_type, + allocation->preferred_segment.segment_id_0,allocation->preferred_segment.segment_id_1,allocation->preferred_segment.segment_id_2, + allocation->preferred_segment_raw.segment_id_0,allocation->preferred_segment_raw.segment_id_1,allocation->preferred_segment_raw.segment_id_2); + goto exit; + } + + if(allocation->flag.primary || allocation->flag.unpagable || allocation->compress_format != 0) + { + force_create = TRUE; + } + else + { + create_system_cache = TRUE; + } + + if(force_create) + { + int paging_result, try_times = 0; + + segment = &mm_mgr->segment[allocation->preferred_segment.segment_id_0]; + + try_again: + + gf_mutex_lock(adapter->paging_lock); + + paging_result = vidmmi_segment_unresident_allocations(mm_mgr, segment, FALSE); + + gf_mutex_unlock(adapter->paging_lock); + + result = vidmmi_allocate_video_memory_try(mm_mgr, allocation, &allocation->preferred_segment); + + if(result != S_OK) + { + if(paging_result == S_OK) + { + goto try_again; + } + else if(try_times < 100) + { + gf_msleep(10); + try_times++; + if(try_times == 100) + { + if((allocation->backup_segment_id != 0)&&(allocation->preferred_segment.segment_id_1 == 0)) + { + allocation->preferred_segment.segment_id_1 = allocation->backup_segment_id; + gf_info("force create allocation[0x%d-%dK] failed by not enough local memory, add segment %d to preferred and try again.\n", allocation->handle, allocation->orig_size/1024, allocation->backup_segment_id); + } + } + goto try_again; + } + else + { + gf_info("force create failed. size: %dk. preferred_segment: %x,\n", allocation->orig_size >> 10, allocation->preferred_segment.value); + goto exit; + } + } + } + } + + + /*[E3K]: allcoate burst length for compressformat allocation*/ + if(allocation->compress_format != 0) + { + allocation->slot_index = vidmmi_allocate_bl_slot(mm_mgr, allocation); + } + + + /* Step 3: create system memory and map it to gart table */ + segment = &mm_mgr->segment[allocation->segment_id]; + + if(create_system_cache || segment->flags.require_system_pages) + { + if (create->create_type == VIDMM_CREATE_TYPE_GF && create->create_list[index].import_pages_mem) + { + gf_mutex_lock(mm_mgr->hw_lock); + mm_mgr->used_pages_num += (allocation->size + adapter->os_page_size - 1) / adapter->os_page_size; + gf_mutex_unlock(mm_mgr->hw_lock); + + allocation->pages_mem = create->create_list[index].import_pages_mem; + result = S_OK; + } + else + { + result = vidmmi_allocate_system_memory(adapter, allocation, FALSE, FALSE); + } + + if(result == S_OK) + { + if(!create_system_cache) + { + vidmm_map_gart_table(adapter, allocation, segment->flags.support_snoop); + } + } + else + { + gf_error("%s: allocate system memory failed.\n", __func__); + goto exit; + } + } + + /* create finished, zero video memory */ + if(allocation->segment_id != SEGMENT_ID_INVALID) + { + /* Patch: + * zero video memory for 2d and video to fix garbage issue + * zero the follow video memory.. + * (1) on chip memory + * (2) dynamic memory for elite + */ + int is_fill_alloc = FALSE; + + segment = &mm_mgr->segment[allocation->segment_id]; + + if(allocation->compress_format != 0 || allocation->flag.force_clear) + { + is_fill_alloc = TRUE; + } + else if(segment->flags.system_phys_mem_reserved || segment->flags.system_pages_reserved || segment->flags.chip_phys_mem_reserved) + { + is_fill_alloc = TRUE; + + if(create->create_type == VIDMM_CREATE_TYPE_GF) + { + gf_create_allocation_t *create_hint = create->create_list[index].create_data; + if(create_hint->usage_mask & GF_USAGE_CREATE_PIXMAP) + { + is_fill_alloc = FALSE; + } + } + } + + if(is_fill_alloc) + { + allocation->flag.force_clear = TRUE; + vidmmi_fill_allocation(mm_mgr, allocation, 0); + } + } + + /* step4: create sync object and binding it to this allocation */ + if(allocation->flag.fence_sync) + { + gf_create_fence_sync_object_t create_sync = {0}; + int status; + + create_sync.type = GF_SYNC_OBJ_TYPE_FENCE; + create_sync.fence.init_value = 0; /* initialized value set to 0 */ + + status = vidsch_create_sync_object(device, &create_sync, TRUE); + + if(status == S_OK) + { + allocation->sync_obj = create_sync.fence_sync_object; + allocation->fence_addr = create_sync.fence.fence_addr; + } + else + { + gf_error("create allocation binding FenceSyncOject failed. device: %x, allocation: %x.\n", device->handle, allocation->handle); + } + + sync_trace("device: %x, allocation:%x, %dx%d@%d, sync_obj: %x, fence_addr:%llx.\n", + device->handle, allocation->handle, allocation->width, allocation->height, allocation->bit_count, + allocation->sync_obj, allocation->fence_addr); + } + + if(create->create_type == VIDMM_CREATE_TYPE_ESCAPE) + { + gf_create_alloc_info_t *desc = create->info_list + index; + if(allocation->flag.unpagable) + { + desc->Address = allocation->phys_addr; + desc->PhysAddr= allocation->cpu_phys_addr; + } + else + { + desc->Address = 0x0ll; + desc->PhysAddr= 0x0ll; + } + + desc->FenceSyncObject = allocation->sync_obj; + desc->FenceAddress = allocation->fence_addr; + + desc->hAllocation = allocation->handle; + desc->Size = allocation->size; + } + else if(create->create_type == VIDMM_CREATE_TYPE_GF) + { + gf_create_allocation_t *create_hint = create->create_list[index].create_data; + + create_hint->width = allocation->width; + create_hint->height = allocation->height; + + create_hint->width_aligned = allocation->aligned_width; + create_hint->height_aligned = allocation->aligned_height; + + create_hint->tiled_width = allocation->tiled_width; + create_hint->tiled_height = allocation->tiled_height; + + create_hint->size = allocation->size; + create_hint->bit_cnt = allocation->bit_count; + create_hint->pitch = allocation->pitch; + create_hint->tiled = allocation->flag.swizzled; + create_hint->unpagable = allocation->flag.unpagable; + create_hint->compressed = (allocation->compress_format != 0) ? 1:0; + create_hint->allocation = allocation->handle; + create_hint->gpu_virt_addr = allocation->phys_addr; + create_hint->tiled_width = allocation->tiled_width; + create_hint->sync_obj = allocation->sync_obj; + create_hint->fence_addr = allocation->fence_addr; + create_hint->hw_format = allocation->hw_format; + create_hint->compressed = allocation->compress_format != 0 ? 1 : 0; + create_hint->compress_format = allocation->compress_format; + create_hint->segment_id = allocation->segment_id; + create_hint->force_clear = allocation->flag.force_clear; + create_hint->has_pages = segment->flags.require_system_pages; + } + else if (create->create_type == VIDMM_CREATE_TYPE_RENAME) + { + create->rename_list[index].Size = allocation->size; + create->rename_list[index].hAllocation = allocation->handle; + } + } + +#define VIDMM_GET_ALLOCATION(create, index) \ + (((create)->create_type == VIDMM_CREATE_TYPE_GF) ? (create)->create_list[(index)].create_data->allocation : \ + ((create)->create_type == VIDMM_CREATE_TYPE_ESCAPE ? (create)->info_list[(index)].hAllocation : \ + (create)->rename_list[(index)].hAllocation)) + +exit: + if(result == S_OK) + { + vidmm_allocation_t *allocation = NULL; + + for(index = 0; index < create->allocation_count; index++) + { + allocation = get_from_handle(&adapter->hdl_mgr, VIDMM_GET_ALLOCATION(create, index)); + + allocation->bo = create->bos ? create->bos[index] : NULL; + + if(allocation->segment_id != SEGMENT_ID_INVALID) + { + cm_device_add_reference(device,allocation); + vidmm_add_allocation_to_resident_list(adapter, allocation); + } + else + { + vidmm_add_allocation_to_cache_list(adapter, allocation); + } + } + } + else + { + for(index = 0; index < create->allocation_count; index++) + { + vidmm_allocation_t *allocation = get_from_handle(&adapter->hdl_mgr, VIDMM_GET_ALLOCATION(create, index)); + + if(allocation) + { + cm_device_del_reference(device, allocation); + + vidmmi_destroy_allocation(adapter, allocation); + } + } + } + + return result; +} + +void vidmm_reference_allocation(adapter_t *adapter, gpu_device_t *device, vidmm_allocation_t *allocation) +{ + if (device) + { + cm_device_lock_allocation(device, allocation); + } + else + { + gf_spin_lock(allocation->lock); + } + + ++allocation->ref_count; + + if (device) + { + cm_device_unlock_allocation(device, allocation); + } + else + { + gf_spin_unlock(allocation->lock); + } +} + + +void vidmm_unreference_allocation(adapter_t *adapter, gpu_device_t *device, vidmm_allocation_t *allocation) +{ + int can_destroy = FALSE, idle = FALSE; + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + + if (device) + { + cm_device_lock_allocation(device, allocation); + } + else + { + gf_spin_lock(allocation->lock); + } + + if(--allocation->ref_count == 0) + { + can_destroy = TRUE; + + allocation->status.wait_for_destroy = TRUE; + + idle = vidsch_is_allocation_idle(adapter, ALL_ENGINE_MASK, allocation); + } + else + { + can_destroy = FALSE; + } + + if (device) + { + cm_device_unlock_allocation(device, allocation); + } + else + { + gf_spin_unlock(allocation->lock); + } + + if(can_destroy) + { + if(idle) + { + if(allocation->segment_id != SEGMENT_ID_INVALID) + { + vidmm_remove_allocation_from_resident_list(adapter, allocation); + } + else if(allocation->pages_mem != NULL) + { + vidmm_remove_allocation_from_cache_list(adapter, allocation); + } + vidmmi_destroy_allocation(adapter, allocation); + } + else + { + gf_mutex_lock(mm_mgr->list_lock); + + list_add_tail(&allocation->destroy_list_item, &mm_mgr->defer_destroy_list); + + gf_mutex_unlock(mm_mgr->list_lock); + } + } +} + +void vidmmi_try_destroy_one_allocation(gpu_device_t *device, vidmm_allocation_t *allocation) +{ + adapter_t *adapter = device->adapter; + + cm_device_del_reference(device, allocation); + + vidmm_unreference_allocation(adapter, device, allocation); +} + + +void vidmm_destroy_allocation(gpu_device_t *device, vidmm_destroy_allocatin_arg_t *data) +{ +// adapter_t *adapter = device->adapter; +// vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_allocation_t *allocation = NULL; + + int allocation_count = 0; + int i = 0; + + /* NOTE: here not protect resource list when destroy resource, since general when destroy resource called, + * this resource is invalid, if on destroy, resource used by create, this should be a user mode driver bug. + */ + + allocation_count = data->allocation_count; + + for(i = 0; i < allocation_count; i++) + { + allocation = data->allocation_list[i]; + + //gf_assert(NULL != allocation); + + if (allocation) + { + allocation->bo = NULL; + + vidmmi_try_destroy_one_allocation(device, allocation); + } + else + { + gf_info("try destroy NULL allocation\n"); + } + } +} + + +int vidmm_get_allocation_info(adapter_t *adapter, vidmm_get_allocation_info_t *info) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_allocation_t *allocation = info->allocation; + + info->gpu_vm_addr = allocation->phys_addr; + info->pitch = allocation->pitch; + info->tiled = allocation->flag.swizzled; + info->segment_id = allocation->segment_id; + info->hw_format = allocation->hw_format; + + mm_mgr->chip_func->get_allocation_info(adapter, info); + + return S_OK; +} + +void vidmmi_dump_video_memory(vidmm_mgr_t *mm_mgr, unsigned int segment_id) +{ + vidmm_segment_t *segment = &mm_mgr->segment[segment_id]; + + if(NULL != segment) + { + heap_dump(&segment->heap); + } +} + +vidmm_segment_memory_t *vidmm_allocate_segment_memory(adapter_t *adapter, unsigned int segment_id, unsigned int size, int direction) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = &mm_mgr->segment[segment_id]; + vidmm_segment_memory_t *segment_memory = NULL; + list_node_t *list_node = NULL; + struct os_pages_memory *pages_mem = NULL; + + segment_memory = gf_calloc(sizeof(vidmm_segment_memory_t)); + if(segment_memory == NULL) + { + gf_error("%s(): allocate system memory failed\n", __func__); + goto exit; + } + + segment_memory->segment_id = segment_id; + list_node = vidmmi_allocate_segment_memory(mm_mgr, segment_id, size, adapter->os_page_size, direction, 0); + if(list_node == NULL) + { + gf_error("%s(): allocate memory from segment failed\n", __func__); + gf_free(segment_memory); + segment_memory = NULL; + goto exit; + } + + segment_memory->gpu_virt_addr = list_node->aligned_offset; + + /* allocate system pages */ + if(segment->flags.require_system_pages) + { + alloc_pages_flags_t alloc_flags = {0}; + vidmm_allocation_t *allocation = NULL; + int page_size; + + alloc_flags.dma32 = !adapter->hw_caps.address_mode_64bit; + alloc_flags.need_flush = !segment->flags.support_snoop; + alloc_flags.fixed_page = TRUE; + alloc_flags.need_dma_map = adapter->sys_caps.iommu_enabled; + page_size = segment->flags.page_64kb_enable ? GF_PAGE_64KB_SIZE : adapter->os_page_size; + + allocation = gf_calloc(sizeof(vidmm_allocation_t)); + if (allocation == NULL) + { + goto exit; + } + pages_mem = gf_allocate_pages_memory(adapter->os_device.pdev, list_node->aligned_size, page_size, alloc_flags); + if(pages_mem == NULL) + { + gf_error("%s(): allocate pages failed\n", __func__); + vidmmi_release_segment_memory(mm_mgr, segment_id, list_node); + gf_free(segment_memory); + segment_memory = NULL; + goto exit; + } + + /* map gart table */ + allocation->phys_addr = segment_memory->gpu_virt_addr; + allocation->size = list_node->aligned_size; + allocation->pages_mem = pages_mem; + + vidmm_map_gart_table(adapter, allocation, segment->flags.support_snoop); + gf_free(allocation); + } + + segment_memory->list_node = list_node; + segment_memory->pages_mem = pages_mem; + + segment->reserved_size += list_node->aligned_size; + +exit: + return segment_memory; +} + +void vidmm_release_segment_memory(adapter_t *adapter, vidmm_segment_memory_t *segment_memory) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = &mm_mgr->segment[segment_memory->segment_id]; + + if(segment_memory->pages_mem) + { + gf_free_pages_memory(adapter->os_device.pdev, segment_memory->pages_mem); + + segment_memory->pages_mem = NULL; + } + + segment->reserved_size -= segment_memory->list_node->aligned_size; + + vidmmi_release_segment_memory(mm_mgr, segment_memory->segment_id, segment_memory->list_node); + + gf_free(segment_memory); +} + +/* + * For map segment memory, you can set your own cache flags, but this cache flag may conflict with segment caps. + * like you may set wb type to a none snoop segment, on this case, user should explictly do flush cache. + * So after map segment, user should check flags vma->need_flush_cache, if set TRUE, user must flush cache manually + * before GPU use to avoid coherence issue. + */ + +void* vidmm_map_segment_memory(adapter_t *adapter, void *filp, vidmm_segment_memory_t *segment_memory, vidmm_map_flags_t *flags) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + unsigned int segment_id = segment_memory->segment_id; + vidmm_segment_t *segment = &mm_mgr->segment[segment_id]; + gf_map_argu_t map = {0}; + gf_vm_area_t *vma = NULL; + + if(flags->mem_space == GF_MEM_KERNEL) + { + vma = segment_memory->vma; + } + else + { + gf_assert(0, "vidmm_map_segment_memory only used for kernel map"); + } + + if(vma) + { + return vma->virt_addr; + } + + map.size = segment_memory->list_node->aligned_size; + map.flags.mem_space = flags->mem_space; + map.flags.read_only = flags->read_only; + map.flags.write_only = flags->write_only; + + if(segment_memory->pages_mem) + { +#ifdef VMI_MODE + gf_set_pages_addr(segment_memory->pages_mem, adapter->vidmm_bus_addr + segment_memory->gpu_virt_addr); +#endif + map.flags.mem_type = GF_SYSTEM_RAM; + map.memory = segment_memory->pages_mem; + map.offset = 0; + + if(flags->cache_type) + { + map.flags.cache_type = flags->cache_type; + } + else if(segment->flags.support_snoop || segment->flags.support_manual_flush) + { + map.flags.cache_type = GF_MEM_WRITE_BACK; + } + else + { + map.flags.cache_type = GF_MEM_WRITE_COMBINED; + } + + vma = gf_map_pages_memory(filp, &map); + + if(segment->flags.support_snoop && (vma->flags.cache_type == GF_MEM_WRITE_BACK)) + { + if(!segment_memory->snooping_enabled) + { + vidmm_allocation_t *allocation = NULL; + + allocation = gf_calloc(sizeof(vidmm_allocation_t)); + + allocation->phys_addr = segment_memory->gpu_virt_addr; + allocation->size = segment_memory->list_node->aligned_size; + allocation->pages_mem = segment_memory->pages_mem; + + mm_mgr->chip_func->set_snooping(adapter, allocation, TRUE); + + segment_memory->snooping_enabled = TRUE; + gf_free(allocation); + } + } + } + else if(segment->flags.system_phys_mem_reserved) + { + if(segment->flags.support_snoop || segment->flags.support_manual_flush) + { + map.flags.cache_type = GF_MEM_WRITE_BACK; + } + else + { + map.flags.cache_type = GF_MEM_WRITE_COMBINED; + } + + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = segment_memory->gpu_virt_addr - segment->gpu_vm_start + segment->phys_addr_start; + + vma = gf_map_io_memory(filp, &map); + } + else + { + if(flags->cache_type) + { + map.flags.cache_type = flags->cache_type; + } + else + { + map.flags.cache_type = GF_MEM_WRITE_COMBINED; + } + + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = adapter->vidmm_bus_addr + segment_memory->gpu_virt_addr - segment->gpu_vm_start + segment->phys_addr_start; + + vma = gf_map_io_memory(filp, &map); + } + + /* put need flush check in the last, maybe future we also map io as wb */ + if((!segment_memory->snooping_enabled) && (vma->flags.cache_type == GF_MEM_WRITE_BACK)) + { + vma->need_flush_cache = TRUE; + } + + segment_memory->vma = vma; + + return vma->virt_addr; +} + +void vidmm_unmap_segment_memory(adapter_t *adapter, vidmm_segment_memory_t *segment_memory, enum gf_mem_space mem_space) +{ + gf_vm_area_t *vma = NULL; + + if(mem_space == GF_MEM_KERNEL) + { + vma = segment_memory->vma; + + segment_memory->vma = NULL; + } + else if(mem_space == GF_MEM_USER) + { + gf_assert(0, "only for kernel unmap"); + } + + if(vma == NULL) + { + return; + } + + switch(vma->flags.mem_type) + { + case GF_SYSTEM_IO: + gf_unmap_io_memory(vma); + break; + case GF_SYSTEM_RAM: + gf_unmap_pages_memory(vma); + break; + default: + gf_assert(0, "unmap with vma->flags.mem_type"); + } +} diff --git a/drivers/gpu/drm/arise/core/vidmm/vidmm_lock.c b/drivers/gpu/drm/arise/core/vidmm/vidmm_lock.c new file mode 100644 index 0000000000000..ac8cf6daf6f06 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidmm/vidmm_lock.c @@ -0,0 +1,89 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "vidmm.h" +#include "vidmmi.h" +#include "vidsch.h" +#include "perfevent.h" + +void vidmm_get_map_allocation_info(adapter_t *adapter, vidmm_allocation_t *allocation, gf_map_argu_t *argu) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = &mm_mgr->segment[allocation->segment_id]; + + argu->size = allocation->size; + + if (allocation->pages_mem) + { + argu->memory = allocation->pages_mem; + argu->flags.mem_type = GF_SYSTEM_RAM; + argu->offset = 0; + + if (segment->flags.support_snoop) + { + argu->flags.cache_type = GF_MEM_WRITE_BACK; + } + else if (allocation->flag.cacheable) + { + argu->flags.cache_type = GF_MEM_WRITE_BACK; + } + else if (segment->flags.support_manual_flush && (allocation->segment_id != 0)) + { + argu->flags.cache_type = GF_MEM_WRITE_BACK; + } + else + { + argu->flags.cache_type = GF_MEM_WRITE_COMBINED; + } + } + else if (segment->flags.system_phys_mem_reserved) + { + if(segment->flags.support_snoop || segment->flags.support_manual_flush) + { + argu->flags.cache_type = GF_MEM_WRITE_BACK; + } + else + { + argu->flags.cache_type = GF_MEM_WRITE_COMBINED; + } + + argu->flags.mem_type = GF_SYSTEM_IO; + argu->phys_addr = allocation->phys_addr - segment->gpu_vm_start + segment->phys_addr_start; + } + else + { + if(segment->flags.support_snoop) + { + argu->flags.cache_type = GF_MEM_WRITE_BACK; + } + else if(segment->flags.support_manual_flush && (allocation->segment_id != 0)) + { + argu->flags.cache_type = GF_MEM_WRITE_BACK; + } + else + { + argu->flags.cache_type = GF_MEM_WRITE_COMBINED; + } + + argu->flags.mem_type = GF_SYSTEM_IO; + argu->phys_addr = allocation->phys_addr + adapter->vidmm_bus_addr; + + if(argu->phys_addr >= (adapter->vidmm_bus_addr + adapter->Visible_vram_size)) + { + gf_warning("vidmm_get_map_allocation_info map invisable allocation!!!"); + } + } +} diff --git a/drivers/gpu/drm/arise/core/vidmm/vidmm_paging.c b/drivers/gpu/drm/arise/core/vidmm/vidmm_paging.c new file mode 100644 index 0000000000000..8f862f6d263f3 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidmm/vidmm_paging.c @@ -0,0 +1,1023 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "vidmm.h" +#include "vidsch.h" +#include "vidmmi.h" + +extern int vidmmi_copy_data(struct _vidmm_mgr *mm_mgr, task_paging_t *paging_task,vidmm_allocation_t *dst_allocation, + unsigned long long src_addr, unsigned long long dst_addr, + unsigned int src_compress, unsigned int dst_compress, unsigned int size); + +static inline void vidmmi_add_allocation_to_resident_list(vidmm_segment_t *segment, vidmm_allocation_t *allocation) +{ + if(allocation->flag.unpagable) + { + list_add_tail(&allocation->list_item, &segment->unpagable_resident_list); + + segment->unpagable_size += allocation->size; + segment->unpagable_num++; + } + else + { + list_add_tail(&allocation->list_item, &segment->pagable_resident_list[allocation->priority]); + + segment->pagable_size += allocation->size; + segment->pagable_num++; + } + + gf_counter_trace_event(segment->segment_name, + (segment->pagable_size + segment->unpagable_size + segment->reserved_size) >> 10); +} + +static inline void vidmmi_remove_allocation_from_resident_list(vidmm_segment_t *segment, vidmm_allocation_t *allocation) +{ + list_del(&allocation->list_item); + + if(allocation->flag.unpagable) + { + segment->unpagable_size -= allocation->size; + segment->unpagable_num--; + } + else + { + segment->pagable_size -= allocation->size; + segment->pagable_num--; + } + + gf_counter_trace_event(segment->segment_name, + (segment->pagable_size + segment->unpagable_size + segment->reserved_size) >> 10); +} + +void vidmm_add_allocation_to_resident_list(adapter_t *adapter, vidmm_allocation_t *allocation) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = &mm_mgr->segment[allocation->segment_id]; + + gf_assert(allocation->segment_id != SEGMENT_ID_INVALID, "allocation->segment_id != SEGMENT_ID_INVALID"); + + gf_mutex_lock(segment->lock); + + vidmmi_add_allocation_to_resident_list(segment, allocation); + + gf_mutex_unlock(segment->lock); +} + +void vidmm_remove_allocation_from_resident_list(adapter_t *adapter, vidmm_allocation_t *allocation) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = &mm_mgr->segment[allocation->segment_id]; + + gf_mutex_lock(segment->lock); + + vidmmi_remove_allocation_from_resident_list(segment, allocation); + + gf_mutex_unlock(segment->lock); +} + +#define vidmmi_add_allocation_to_cache_list(segment, allocation) vidmmi_add_allocation_to_resident_list(segment, allocation) +#define vidmmi_remove_allocation_from_cache_list(segment, allocation) vidmmi_remove_allocation_from_resident_list(segment, allocation) + +void vidmm_add_allocation_to_cache_list(adapter_t *adapter, vidmm_allocation_t *allocation) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *cache_segment = &mm_mgr->segment[0]; + + gf_assert(allocation->segment_id == 0, "add allocation->segment_id == 0"); + + gf_mutex_lock(cache_segment->lock); + + vidmmi_add_allocation_to_cache_list(cache_segment, allocation); + + gf_mutex_unlock(cache_segment->lock); +} + +void vidmm_remove_allocation_from_cache_list(adapter_t *adapter, vidmm_allocation_t *allocation) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *cache_segment = &mm_mgr->segment[0]; + + gf_assert(allocation->segment_id == 0, "remove allocation->segment_id == 0"); + + gf_mutex_lock(cache_segment->lock); + + vidmmi_remove_allocation_from_cache_list(cache_segment, allocation); + + gf_mutex_unlock(cache_segment->lock); +} + +int vidmmi_copy_data(vidmm_mgr_t *mm_mgr, task_paging_t *paging_task,vidmm_allocation_t *dst_allocation, + unsigned long long src_addr, unsigned long long dst_addr, unsigned int src_compress, unsigned int dst_compress, unsigned int size) +{ + vidmm_private_build_paging_buffer_arg_t build_paging_buffer = {0}; + + int status = S_OK; + + build_paging_buffer.operation = BUILDING_PAGING_OPERATION_TRANSFER; + build_paging_buffer.dma_buffer = paging_task->dma->virt_base_addr + paging_task->command_length; + build_paging_buffer.dma_size = paging_task->dma->size - paging_task->command_length; + build_paging_buffer.multi_pass_offset = 0; + build_paging_buffer.transfer.transfer_size = size; + build_paging_buffer.transfer.src.phy_addr = src_addr; + build_paging_buffer.transfer.dst.phy_addr = dst_addr; + build_paging_buffer.allocation = dst_allocation; + + build_paging_buffer.transfer.src.compress_format = src_compress; + build_paging_buffer.transfer.dst.compress_format = dst_compress; + + status = mm_mgr->chip_func->build_paging_buffer(mm_mgr->adapter, &build_paging_buffer); + + if(status == S_OK) + { + /* update cmd_length */ + paging_task->command_length = util_get_ptr_span(build_paging_buffer.dma_buffer, paging_task->dma->virt_base_addr); + } + else + { + gf_info("Paging DMA size not enough: size: %d, current_size: %d.\n", + paging_task->dma->size, util_get_ptr_span(build_paging_buffer.dma_buffer, paging_task->dma->virt_base_addr)); + } + + return status; +} + +/* allocate temp paging video memory */ +static int vidmmi_allocate_temp_paging_memory(vidmm_mgr_t *mm_mgr, vidmm_allocation_t *allocation) +{ + adapter_t *adapter = mm_mgr->adapter; + vidmm_segment_t *paging_segment = mm_mgr->paging_segment; + + int status = S_OK; + + //allocation->list_node = heap_allocate(&paging_segment->heap, allocation->orig_size, allocation->alignment, 0); + + while(allocation->list_node == NULL) + { + unsigned long long uncomplete_paging = 0ll; + + vidsch_release_completed_tasks(adapter, adapter->paging_engine_index, &uncomplete_paging); + + allocation->list_node = heap_allocate(&paging_segment->heap, allocation->orig_size, allocation->alignment, 0); + + if(allocation->list_node == NULL) + { + if(uncomplete_paging == 0ll) + { + gf_info("allocate temp paging memory failed. want size: %dk, paging heap size: %dk.\n", + util_align(allocation->orig_size, adapter->os_page_size) >> 10, paging_segment->gpu_vm_size >> 10); + + gf_info("paging heap status: \n"); + + heap_dump(&paging_segment->heap); + + status = E_FAIL; + break; + } + + vidsch_wait_fence_back(adapter, adapter->paging_engine_index, uncomplete_paging); + } + } + + if(allocation->list_node != NULL) + { + allocation->segment_id = 0; + allocation->size = util_align(allocation->orig_size, adapter->os_page_size); + allocation->phys_addr = allocation->list_node->aligned_offset; + } + + return status; +} + +static void vidmmi_release_temp_paging_memory(vidmm_mgr_t *mm_mgr, vidmm_allocation_t *temp_allocation) +{ + vidmm_segment_t *paging_segment = mm_mgr->paging_segment; + + if(temp_allocation->list_node != NULL) + { + heap_release(&paging_segment->heap, temp_allocation->list_node); + + temp_allocation->list_node = NULL; + } + + if(temp_allocation->pages_mem != NULL) + { + vidmmi_release_system_memory(mm_mgr->adapter, temp_allocation); + + temp_allocation->pages_mem = NULL; + } + + gf_free(temp_allocation); +} + +/* release complete temp paging allocation in paging task */ +void vidmm_release_temp_paging_memory(adapter_t *adapter, void *ptask) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_allocation_t *temp_allocation = NULL; + task_paging_t *paging_task = ptask; + + int i; + + for(i = 0; i < paging_task->paging_allocation_num; i++) + { + temp_allocation = paging_task->paging_allocation_list[i].temp_allocation; + + if(temp_allocation != NULL) + { + vidmmi_release_temp_paging_memory(mm_mgr, temp_allocation); + } + } +} + +/* paging out: move allocation data to system pages. 2 conditions here. + * 1. gart segment acctually is system pages, no need move data. + * 2. local segment, need allocate system pages, and copy data to it. + * NOTE: paging_out do not release video memory, video memory only can released after copy finished. + */ + +static int vidmmi_paging_out(vidmm_mgr_t *mm_mgr, task_paging_t *paging_task, vidmm_paging_allocation_t *paging_allocation) +{ + vidmm_segment_t *segment = &mm_mgr->segment[paging_allocation->segment_id]; + vidmm_allocation_t *temp_allocation = NULL; + + int result = S_OK; + + if(segment->flags.require_system_pages) + { + vidmm_allocation_t *allocation = paging_allocation->allocation; + + if(allocation->compress_format != 0) + { + gf_warning("Paging OUT compressed PCIE allocation. handle: %x process: %s.\n", allocation->handle, allocation->device->pname); + } + /* gart segment alreay in system pages, no need paging out */ + return S_OK; + } + + gf_assert(paging_allocation->allocation->pages_mem == NULL, "paging_allocation->allocation->pages_mem == NULL"); + + /* local to paging memory then to system cache */ + temp_allocation = gf_calloc(sizeof(vidmm_allocation_t)); + + if(temp_allocation == NULL) + { + return E_OUTOFMEMORY; + } + + result = vidmmi_allocate_system_memory(mm_mgr->adapter, paging_allocation->allocation, paging_task->must_success, TRUE); + + if(S_OK != result) + { + gf_free(temp_allocation); + + return E_OUTOFMEMORY; + } + + temp_allocation->orig_size = paging_allocation->size; + temp_allocation->alignment = paging_allocation->allocation->alignment; + temp_allocation->pages_mem = paging_allocation->allocation->pages_mem; + + result = vidmmi_allocate_temp_paging_memory(mm_mgr, temp_allocation); + + if(S_OK != result) + { + goto exit; + } + + vidmm_map_gart_table(mm_mgr->adapter, temp_allocation, mm_mgr->paging_segment->flags.support_snoop); + + paging_task->paging_type = 2; + + result = vidmmi_copy_data(mm_mgr, + paging_task, + temp_allocation, + paging_allocation->gpu_virt_addr, + temp_allocation->phys_addr, + paging_allocation->allocation->compress_format, + temp_allocation->compress_format, + paging_allocation->size); +exit: + if(result == S_OK) + { + temp_allocation->pages_mem = NULL; + + paging_allocation->temp_allocation = temp_allocation; + } + else + { + paging_allocation->allocation->pages_mem = NULL; + + vidmmi_release_temp_paging_memory(mm_mgr, temp_allocation); + } + + return result; +} + +/* paging in: move allocation data from system pages to video. 2 conditions here. + * 1. gart segment acctually is system pages, no need move data. + * 2. local segment, need allocate local video memory, and copy data to it. + * NOTE: paging_out do not release system pages, system pages only can released after copy finished. + */ + +static int vidmmi_paging_in(vidmm_mgr_t *mm_mgr, task_paging_t *paging_task, vidmm_paging_allocation_t *paging_allocation) +{ + vidmm_segment_t *segment = &mm_mgr->segment[paging_allocation->segment_id]; + vidmm_allocation_t *allocation = paging_allocation->allocation; + vidmm_allocation_t *temp_allocation = NULL; + + int result = S_OK; + + if(paging_allocation->allocation->pages_mem == NULL) + { + gf_assert(allocation->file_storage != NULL, "allocation->file_storage != NULL"); + + result = vidmmi_allocate_system_memory(mm_mgr->adapter, allocation, TRUE, TRUE); + + if(result == S_OK) + { +// gf_info("shrink swapin: allocation:%x, size: %dk.\n", allocation->handle, allocation->size >> 10); + /* swap file_storage to pages */ + if(gf_pages_memory_swapin(allocation->pages_mem, allocation->file_storage)) + { + vidmmi_release_system_memory(mm_mgr->adapter, allocation); + + return E_OUTOFMEMORY; + } + else + { + allocation->file_storage = NULL; + } + } + else + { + return E_OUTOFMEMORY; + } + } + else + { + if (!paging_task->save_restore) + { + vidmm_remove_allocation_from_cache_list(mm_mgr->adapter, allocation); + } + } + + gf_assert(paging_allocation->allocation->pages_mem != NULL, "paging_allocation->allocation->pages_mem != NULL"); + + if(segment->flags.require_system_pages) + { + /* gart segment acctually is system pages, no need copy */ + vidmm_allocation_t *allocation = paging_allocation->allocation; + + allocation->phys_addr = paging_allocation->gpu_virt_addr; + allocation->size = paging_allocation->size; + + vidmm_map_gart_table(mm_mgr->adapter, allocation, segment->flags.support_snoop); + + return S_OK; + } + + /* local to paging memory then to system cache */ + temp_allocation = gf_calloc(sizeof(vidmm_allocation_t)); + + if(temp_allocation == NULL) + { + if(!paging_task->save_restore) + { + vidmm_add_allocation_to_cache_list(mm_mgr->adapter, allocation); + } + + return E_OUTOFMEMORY; + } + + temp_allocation->orig_size = paging_allocation->size; + temp_allocation->alignment = paging_allocation->allocation->alignment; + temp_allocation->pages_mem = paging_allocation->allocation->pages_mem; + + result = vidmmi_allocate_temp_paging_memory(mm_mgr, temp_allocation); + + if(S_OK != result) + { + result = E_FAIL; + goto exit; + } + + vidmm_map_gart_table(mm_mgr->adapter, temp_allocation, mm_mgr->paging_segment->flags.support_snoop); + + paging_task->paging_type = 1; + + result = vidmmi_copy_data(mm_mgr, + paging_task, + allocation, + temp_allocation->phys_addr, + paging_allocation->gpu_virt_addr, + temp_allocation->compress_format, + allocation->compress_format, + paging_allocation->size); +exit: + if(result == S_OK) + { + paging_allocation->allocation->pages_mem = NULL; + paging_allocation->temp_allocation = temp_allocation; + } + else + { + temp_allocation->pages_mem = NULL; + + vidmmi_release_temp_paging_memory(mm_mgr, temp_allocation); + + if (!paging_task->save_restore) + { + vidmm_add_allocation_to_cache_list(mm_mgr->adapter, allocation); + } + } + + return result; +} + +#define VIDMM_MAX_PAGING_OUT_MEMORY_SIZE 4*1024*1024 //4M +#define VIDMM_MAX_PAGING_OUT_ALLOCATION_NUM 32 +#define VIDMM_MAX_PAGING_OUT_DMA_SIZE 32*1024 + +int vidmmi_segment_unresident_allocations(vidmm_mgr_t *mm_mgr, vidmm_segment_t *segment, int must_success) +{ + adapter_t *adapter = mm_mgr->adapter; + vidmm_allocation_t *candidate = NULL; + vidmm_allocation_t *candidate_next = NULL; + vidmm_paging_allocation_t *paging_allocation = NULL; + + int index, priority, vram_size = 0, result = E_FAIL; + + task_paging_t *paging_task = vidsch_allocate_paging_task( + adapter, + VIDMM_MAX_PAGING_OUT_DMA_SIZE, + VIDMM_MAX_PAGING_OUT_ALLOCATION_NUM); + + paging_task->must_success = must_success; + + /* Step 1. select paging out allocations */ + + gf_mutex_lock(segment->lock); + + for(priority = PDISCARD; priority < PALL; priority++) + { + /* loop for pagable list to select candidate list to paging out */ + list_for_each_entry_safe(candidate, candidate_next, &segment->pagable_resident_list[priority], list_item) + { + cm_device_lock_allocation(candidate->device, candidate); + + if(!candidate->status.temp_unpagable && + !vidsch_allocation_in_hw_queue(adapter, ALL_ENGINE_MASK, candidate)) + { + gf_assert(candidate->segment_id != 0, "candidate->segment_id != 0"); + + /* remove selected allocation from resident list */ + vidmmi_remove_allocation_from_resident_list(segment, candidate); + + /* mark it referenced by paging, then this allocation can not released + * because the paging out allocation maybe destroyed after submit paging task + * and when waiting fence back, so reference count need be increased twice, + * one for submit paging task, one for sync lock + */ + + candidate->render_count[adapter->paging_engine_index] += 2; + candidate->write_render_count[adapter->paging_engine_index]++; + + paging_allocation = &paging_task->paging_allocation_list[paging_task->paging_allocation_num++]; + + paging_allocation->allocation = candidate; + paging_allocation->segment_id = candidate->segment_id; + paging_allocation->list_node = candidate->list_node; + paging_allocation->gpu_virt_addr = candidate->phys_addr; + paging_allocation->size = candidate->size; + + /* NOTE: here clear segment id, to tell user allocation is not resident, + segment id = 0 mean allocation is unstable, must wait allocation idle + if want access member like pages_mem, list node, size, must first set + unpagable flag and then wait it idle or just access it in paging lock + */ + candidate->segment_id = SEGMENT_ID_INVALID; + candidate->list_node = NULL; + candidate->phys_addr = 0; + candidate->size = 0; + + cm_device_unlock_allocation(candidate->device, candidate); + + /* use list_node size but not allocation size here, since the listnode size is real size */ + vram_size += paging_allocation->list_node->size; + + if((vram_size >= VIDMM_MAX_PAGING_OUT_MEMORY_SIZE) || + (paging_task->paging_allocation_num == paging_task->paging_allocation_list_size)) + { + goto do_paging_out; + } + } + else + { + cm_device_unlock_allocation(candidate->device, candidate); + } + } + } + +do_paging_out: + + gf_mutex_unlock(segment->lock); + + /* Step 2. build paging out cmd buffer */ + + if(paging_task->paging_allocation_num > 0) + { + for(index = 0; index < paging_task->paging_allocation_num; index++) + { + paging_allocation = &paging_task->paging_allocation_list[index]; + gf_begin_section_trace_event("unresident_allocation"); + gf_counter_trace_event("arg_allocation", paging_allocation->allocation->handle); + gf_counter_trace_event("arg_segment", paging_allocation->segment_id); + gf_counter_trace_event("arg_size", paging_allocation->size); + result = vidmmi_paging_out(mm_mgr, paging_task, paging_allocation); + gf_end_section_trace_event(result); + + if(result == E_FAIL) + { + gf_info("paging out failed. paging heap is not enough for temp paging buffer\n"); + break; + } + else if(result == E_OUTOFMEMORY) + { + /* out of memory mean system pages not enough, can not do page out anymore, return error */ + gf_info("paging out failed. outof memory: %d, %dk\n", segment->segment_id, paging_allocation->size >> 10); + break; + } + else if(result == E_INSUFFICIENT_DMA_BUFFER) + { + /* just reminder here, but can not be here, since the dma buffer allocate 8K for 8M video memory, enough */ + gf_info("paging out one allocation failed. dma buffer not enough, segment_id: %d, size: %dk\n", + segment->segment_id, paging_allocation->size >> 10); + + gf_info("Unresident %d allocations failed. dma buffer not enough, success_num: %d.\n", + paging_task->paging_allocation_num, index); + break; + } + } + + /* if system pages not enough, we need restore failed candidate allocations, + * but still paging out the success allocations + */ + if(result != S_OK) + { + int i = index; + + gf_mutex_lock(segment->lock); + + /* restore paging failed allocations */ + for(i = index; i < paging_task->paging_allocation_num; i++) + { + paging_allocation = &paging_task->paging_allocation_list[i]; + candidate = paging_allocation->allocation; + + cm_device_lock_allocation(candidate->device, candidate); + + candidate->segment_id = paging_allocation->segment_id; + candidate->list_node = paging_allocation->list_node; + candidate->phys_addr = paging_allocation->gpu_virt_addr; + candidate->size = paging_allocation->size; + + /* NOTE: here also add failed paging out allocation to the list head */ + list_add(&candidate->list_item, &segment->pagable_resident_list[candidate->priority]); + + /* the render count increased twice befor */ + candidate->render_count[adapter->paging_engine_index] -= 2; + candidate->write_render_count[adapter->paging_engine_index]--; + + cm_device_unlock_allocation(candidate->device, candidate); + + paging_allocation->allocation = NULL; + paging_allocation->segment_id = SEGMENT_ID_INVALID; + + segment->pagable_size += candidate->size; + segment->pagable_num++; + gf_counter_trace_event(segment->segment_name, + (segment->pagable_size + segment->unpagable_size + segment->reserved_size) >> 10); + } + + gf_mutex_unlock(segment->lock); + + /* notify a FENCE event to wakeup thread which wait for render_count dec, since here no real fence interrupt */ + vidsch_notify_interrupt(adapter, 0); + + /* udpate allocation num to real num */ + paging_task->paging_allocation_num = index; + + /* if any allocation paging out success we still treat segment paging out success */ + if(paging_task->paging_allocation_num > 0) + { + result = S_OK; + } + } + } + else + { + /* not found suitable allocation to paging out, return FAIL, failed allowed caller wait a while and try again */ + result = E_FAIL; + } + + /* Step 3: submit paging out task and wait it back */ + vidsch_task_inc_reference(adapter, adapter->paging_engine_index, &paging_task->desc); + + vidsch_submit_paging_task(adapter, paging_task); + + vidsch_wait_fence_back(adapter, adapter->paging_engine_index, paging_task->desc.fence_id); + + /* Step 4: release video memory */ + for(index = 0; index < paging_task->paging_allocation_num; index++) + { + paging_allocation = &paging_task->paging_allocation_list[index]; + candidate = paging_allocation->allocation; + + + if(paging_allocation->list_node) + { + if(paging_allocation->list_node->aligned_offset < (segment->heap.start + segment->heap.size)) + { + heap_release(&segment->heap, paging_allocation->list_node); + } + else + { + gf_assert(segment->flags.small_heap_available, "segment->flags.small_heap_available"); + + heap_release(&segment->small_heap, paging_allocation->list_node); + } + } + + + /* mark allocation resident in system cache */ + vidmm_add_allocation_to_cache_list(adapter, paging_allocation->allocation); + + cm_device_lock_allocation(candidate->device, candidate); + + candidate->render_count[adapter->paging_engine_index]--; + + cm_device_unlock_allocation(candidate->device, candidate); + } + + vidsch_task_dec_reference(adapter, adapter->paging_engine_index, &paging_task->desc); + + return result; +} + +int vidmm_segment_unresident_allocations(adapter_t *adapter, unsigned int segment_id) +{ + int ret = S_OK; + vidmm_segment_t *segment = &adapter->mm_mgr->segment[segment_id]; + gf_mutex_lock(adapter->paging_lock); + + ret = vidmmi_segment_unresident_allocations(adapter->mm_mgr, segment, 1); + + gf_mutex_unlock(adapter->paging_lock); + return ret; +} + +int vidmm_resident_one_allocation(gpu_device_t *device, void *ptask, vidmm_paging_allocation_t *paging_allocation, unsigned int segment_id) +{ + adapter_t *adapter = device->adapter; + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_allocation_t *temp_allocation = NULL; + vidmm_allocation_t *allocation = paging_allocation->allocation; + vidmm_segment_t *segment = NULL; + task_paging_t *paging_task = ptask; + + unsigned int segment_id_list[MAX_SEGMENT_ID]; + unsigned int segment_id_count = 0, index; + + int try_again, result = E_FAIL; + + if(segment_id != SEGMENT_ID_INVALID) + { + segment_id_list[0] = segment_id; + segment_id_count = 1; + } + else + { + if(allocation->preferred_segment.segment_id_0) + { + segment_id_list[segment_id_count++] = allocation->preferred_segment.segment_id_0; + } + if(allocation->preferred_segment.segment_id_1) + { + segment_id_list[segment_id_count++] = allocation->preferred_segment.segment_id_1; + } + if(allocation->preferred_segment.segment_id_2) + { + segment_id_list[segment_id_count++] = allocation->preferred_segment.segment_id_2; + } + if(allocation->preferred_segment.segment_id_3) + { + segment_id_list[segment_id_count++] = allocation->preferred_segment.segment_id_3; + } + if(allocation->preferred_segment.segment_id_4) + { + segment_id_list[segment_id_count++] = allocation->preferred_segment.segment_id_4; + } + } + + temp_allocation = (vidmm_allocation_t *)gf_calloc(sizeof(vidmm_allocation_t)); + + temp_allocation->orig_size = allocation->orig_size; + temp_allocation->alignment = allocation->alignment; + temp_allocation->preferred_segment.value = allocation->preferred_segment.value; + + for(index = 0; index < segment_id_count; index++) + { + segment = &mm_mgr->segment[segment_id_list[index]]; + + try_again = TRUE; + + while(try_again) + { + /* Step 1. try to allocate video memory */ + result = vidmmi_allocate_video_memory_try(mm_mgr, temp_allocation, &temp_allocation->preferred_segment); + + if(result == S_OK) + { + paging_allocation->segment_id = temp_allocation->segment_id; + paging_allocation->gpu_virt_addr = temp_allocation->phys_addr; + paging_allocation->size = temp_allocation->size; + paging_allocation->list_node = temp_allocation->list_node; + + /* Step 3. paging in allocation to list_node */ + gf_begin_section_trace_event("resident_allocation"); + gf_counter_trace_event("arg_allocation", paging_allocation->allocation->handle); + gf_counter_trace_event("arg_segment_id", paging_allocation->segment_id); + gf_counter_trace_event("arg_size", paging_allocation->size); + result = vidmmi_paging_in(mm_mgr, paging_task, paging_allocation); + gf_end_section_trace_event(result); + + if(result == S_OK) + { + /* paging in success mark it referenced by render cmd */ + cm_device_lock_allocation(allocation->device, allocation); + + allocation->render_count[adapter->paging_engine_index]++; + + allocation->write_render_count[adapter->paging_engine_index]++; + + cm_device_unlock_allocation(allocation->device, allocation); + + gf_free(temp_allocation); + + return result; + } + else + { + /* system memory exhausted or dma buffer not enough, return fail */ + vidmmi_release_segment_memory(mm_mgr, temp_allocation->segment_id, temp_allocation->list_node); + + temp_allocation->list_node = NULL; + temp_allocation->segment_id = SEGMENT_ID_INVALID; + + gf_free(temp_allocation); + + return result; + } + } + else + { + /* Step 2. paging out some video memory */ + + /* paging out allocation to system cache to release some segment memory */ + + result = vidmmi_segment_unresident_allocations(mm_mgr, segment, paging_task->must_success); + + if(result == S_OK) + { + /* some segment memory released, try_again */ + continue; + } + else if(result == E_FAIL) + { + /* can not paging out segment memory, try another segment */ + break; + } + else + { + /* system memory exhausted, can not do paging anymore, return. */ + gf_free(temp_allocation); + return result; + } + } + } + } + gf_free(temp_allocation); + return result; +} + +/* prepare alloation used for lock allocation */ +int vidmmi_prepare_one_allocation(gpu_device_t *device, vidmm_allocation_t *allocation) +{ + adapter_t *adapter = device->adapter; + vidmm_paging_allocation_t *paging_allocation = NULL; + task_paging_t *paging_task = NULL; + + int result =S_OK; + + gf_mutex_lock(adapter->paging_lock); + + //hold the paging_lock for double check, in case of multi-thread issue. + if(allocation->segment_id == SEGMENT_ID_INVALID) + { + paging_task = vidsch_allocate_paging_task(adapter, 8*1024, 1); + + paging_task->paging_allocation_num = 1; + paging_task->must_success = TRUE; + + vidsch_task_inc_reference(adapter, adapter->paging_engine_index, &paging_task->desc); + + paging_allocation = &paging_task->paging_allocation_list[0]; + + paging_allocation->allocation = allocation; + + result = vidmm_resident_one_allocation(device, paging_task, paging_allocation, 0); + + vidsch_submit_paging_task(adapter, paging_task); + + vidsch_wait_fence_back(adapter, adapter->paging_engine_index, paging_task->desc.fence_id); + + if(result == S_OK) + { + allocation->list_node = paging_allocation->list_node; + allocation->phys_addr = paging_allocation->gpu_virt_addr; + allocation->segment_id = paging_allocation->segment_id; + allocation->size = paging_allocation->size; + + vidmm_add_allocation_to_resident_list(adapter, allocation); + } + + vidsch_task_dec_reference(adapter, adapter->paging_engine_index, &paging_task->desc); + } + gf_mutex_unlock(adapter->paging_lock); + + return result; +} + +/* NOTE: save/restore do not use lock since save/restore used by pm func, + * when here all app-thread/gf-thread all freezing + */ + +int vidmm_save_allocation(gpu_device_t *device, vidmm_allocation_t *allocation) +{ + adapter_t *adapter = device->adapter; + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + vidmm_segment_t *segment = &mm_mgr->segment[allocation->segment_id]; + task_paging_t *paging_task = NULL; + + vidmm_paging_allocation_t *paging_allocation = NULL; + + int result = S_OK; + + /* only need save allocation which locate in local(VRAM on chip) + * 1. if pages_mem != NULL means allocation currently locate in system, gart or system cache + * 2. elite dynamic acctually is system memory, so no need save + * 3. elite1000 reserved system memory. + */ + if((allocation->pages_mem != NULL) || segment->flags.system_phys_mem_reserved || segment->flags.system_pages_un_reserved) + { + return result; + } + + paging_task = vidsch_allocate_paging_task(adapter, 8*1024, 1); + + paging_task->paging_allocation_num = 1; + paging_task->save_restore = 1; + + paging_allocation = &paging_task->paging_allocation_list[0]; + + paging_allocation->allocation = allocation; + paging_allocation->segment_id = allocation->segment_id; + paging_allocation->list_node = allocation->list_node; + paging_allocation->gpu_virt_addr = allocation->phys_addr; + paging_allocation->size = allocation->size; + + gf_begin_section_trace_event("save_allocation"); + gf_counter_trace_event("arg_allocation", allocation->handle); + gf_counter_trace_event("arg_segment_id", allocation->segment_id); + gf_counter_trace_event("arg_size", allocation->size); + result = vidmmi_paging_out(mm_mgr, paging_task, paging_allocation); + gf_end_section_trace_event(result); + + if(result == S_OK) + { + allocation->render_count[adapter->paging_engine_index]++; + + allocation->write_render_count[adapter->paging_engine_index]++; + } + else + { + gf_info("save allocation %x failed. size:%dk, errno:%d.\n", allocation->handle, allocation->size >> 10, result); + } + + allocation->status.need_restore = TRUE; + + vidsch_task_inc_reference(adapter, adapter->paging_engine_index, &paging_task->desc); + + vidsch_submit_paging_task(adapter, paging_task); + + vidsch_wait_fence_back(adapter, adapter->paging_engine_index, paging_task->desc.fence_id); + + vidsch_task_dec_reference(adapter, adapter->paging_engine_index, &paging_task->desc); + + return result; +} + +void vidmm_restore_allocation(gpu_device_t *device, vidmm_allocation_t *allocation) +{ + adapter_t *adapter = device->adapter; + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + task_paging_t *paging_task = NULL; + + vidmm_paging_allocation_t *paging_allocation = NULL; + + int result; + + if(!allocation->status.need_restore) + { + return; + } + + paging_task = vidsch_allocate_paging_task(adapter, 8*1024, 1); + + paging_task->paging_allocation_num = 1; + paging_task->save_restore = 1; + + paging_allocation = &paging_task->paging_allocation_list[0]; + + paging_allocation->allocation = allocation; + paging_allocation->segment_id = allocation->segment_id; + paging_allocation->list_node = allocation->list_node; + paging_allocation->gpu_virt_addr = allocation->phys_addr; + paging_allocation->size = allocation->size; + + gf_begin_section_trace_event("restore_allocation"); + gf_counter_trace_event("arg_allocation", allocation->handle); + gf_counter_trace_event("arg_segment_id", allocation->segment_id); + gf_counter_trace_event("arg_size", allocation->size); + result = vidmmi_paging_in(mm_mgr, paging_task, paging_allocation); + gf_end_section_trace_event(result); + + if(result == S_OK) + { + allocation->render_count[adapter->paging_engine_index]++; + + allocation->write_render_count[adapter->paging_engine_index]++; + } + else + { + gf_info("restore allocation %x failed. size:%dk, errno:%d.\n", allocation->handle, allocation->size >> 10, result); + } + + allocation->status.need_restore = FALSE; + + vidsch_task_inc_reference(adapter, adapter->paging_engine_index, &paging_task->desc); + + vidsch_submit_paging_task(adapter, paging_task); + + vidsch_wait_fence_back(adapter, adapter->paging_engine_index, paging_task->desc.fence_id); + + vidsch_task_dec_reference(adapter, adapter->paging_engine_index, &paging_task->desc); +} + + +void vidmm_prepare_and_mark_unpagable(adapter_t *adapter, vidmm_allocation_t *allocation, gf_open_allocation_t *info) +{ + gf_spin_lock(allocation->lock); + ++allocation->status.force_unpagable; + gf_spin_unlock(allocation->lock); + + if (allocation->segment_id == SEGMENT_ID_INVALID) + { + vidmmi_prepare_one_allocation(allocation->device, allocation); + } + + if (info) + { + vidmm_fill_allocation_info(adapter, allocation, info); + } +} + +void vidmm_mark_pagable(adapter_t *adapter, vidmm_allocation_t *allocation) +{ + gf_spin_lock(allocation->lock); + --allocation->status.force_unpagable; + gf_spin_unlock(allocation->lock); +} diff --git a/drivers/gpu/drm/arise/core/vidmm/vidmmi.h b/drivers/gpu/drm/arise/core/vidmm/vidmmi.h new file mode 100644 index 0000000000000..5d26020b9247a --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidmm/vidmmi.h @@ -0,0 +1,182 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_VIDMMI_H__ +#define __GF_VIDMMI_H__ + +#include "list.h" + + +typedef struct _vidmm_describe_allocation +{ + vidmm_allocation_t *allocation; + + vidmm_gf_create_t *create_gf; // for gf_create + vidmm_escape_create_t *create_info; // for escape_create +} vidmm_describe_allocation_t; + +typedef enum _build_paging_buffer_operation +{ + BUILDING_PAGING_OPERATION_TRANSFER = 1, + BUILDING_PAGING_OPERATION_FILL = 2, +} build_paging_buffer_operation_t; + +typedef struct _vidmm_private_build_paging_buffer_arg +{ + vidmm_allocation_t *allocation; + void *dma_buffer; + unsigned int dma_size; + build_paging_buffer_operation_t operation; + unsigned int multi_pass_offset; + + union + { + struct + { + unsigned int transfer_offset; + unsigned int transfer_size; + struct + { + unsigned int segment_id; + unsigned long long phy_addr; + unsigned int compress_format; + } src; + struct + { + unsigned int segment_id; + unsigned long long phy_addr; + unsigned int compress_format; + } dst; + } transfer; + struct + { + unsigned int fill_size; + unsigned int fill_pattern; + struct + { + unsigned int segment_id; + unsigned long long phy_addr; + }; + } fill; + }; +} vidmm_private_build_paging_buffer_arg_t; + +typedef struct _vidmm_segment_desc_t +{ + unsigned int segment_id; //segment id + const char *segment_name; + vidmm_segment_desc_flags_t flags; + unsigned int segment_alignment; //elite dynamic: 4M, dst/exc/elite pcie/ahb: 4k + unsigned long long gpu_vm_start; + unsigned long long gpu_vm_size; + unsigned int reserved_vm_size; + unsigned long long small_heap_size; + unsigned long long small_heap_max_allocate_size; + unsigned long long phys_addr_start; //used for local video memory or reserved system memory + struct list_head pagable_allocation_list[PALL]; + struct os_mutex *lock; +} vidmm_segment_desc_t; + +typedef struct _vidmm_chip_segment_info_t +{ + unsigned int segment_cnt; + vidmm_segment_desc_t segment_desc[MAX_SEGMENT_ID]; + unsigned long long cpu_visible_vidmm_size; + unsigned long long cpu_unvisible_vidmm_size; + unsigned int paging_segment_id; + unsigned int paging_segment_size; +} vidmm_chip_segment_info_t; + +typedef struct _vidmm_chip_func +{ + void (*query_segment_info)(adapter_t*, vidmm_chip_segment_info_t*); + void (*mem_setting)(adapter_t *); + void (*init_gart_table)(adapter_t*); + void (*deinit_gart_table)(adapter_t*); + int (*query_gart_table_info)(adapter_t*); + int (*describe_allocation)(adapter_t *, vidmm_describe_allocation_t *); + int (*build_paging_buffer)(adapter_t*, vidmm_private_build_paging_buffer_arg_t*); + void (*map_gart_table)(adapter_t*, vidmm_allocation_t*, int); + void (*unmap_gart_table)(adapter_t*, vidmm_allocation_t*); + void (*set_snooping)(adapter_t *, vidmm_allocation_t*, int); + int (*get_allocation_info)(adapter_t *, vidmm_get_allocation_info_t *); + void (*restore)(adapter_t *); + int (*query_info)(struct _vidmm_mgr *, gf_query_info_t *); + int (*segment_memory_transfer)(adapter_t *, vidmm_segment_memory_t **, vidmm_segment_memory_t *, int); +} vidmm_chip_func_t; + +typedef struct _vidmm_mgr +{ + adapter_t *adapter; + + unsigned int segment_cnt; + vidmm_segment_t *segment; + + vidmm_segment_t *paging_segment; + list_node_t *paging_segment_node; + + unsigned int secure_segment_id; + + unsigned long max_pages_num; // max system pages can used for vidmm + unsigned long emergency_pages; // must success can allocate from this + unsigned long used_pages_num; // already used pages in our vidmm + unsigned long own_pages_num; // allocate page by this driver + unsigned long swap_page_num; + int swap_gmem ; + + unsigned long long cpu_visible_vidmm_size; + unsigned long long cpu_unvisible_vidmm_size; + unsigned int pcie_segment_size; + unsigned int reserved_vmem; + unsigned char aperture_used[MAX_APERTURES]; + + struct os_mutex *hw_lock; /* lock for aperture, pages */ + + struct list_head paging_task_list; + struct list_head defer_destroy_list; + + struct os_mutex *list_lock; /* list lock for paging_task, defer_list*/ + + struct os_pages_memory* dummy_page; + + //chip private funcs + vidmm_chip_func_t *chip_func; + + void *flag_buffer; + heap_t blheap; +} vidmm_mgr_t; + +extern vidmm_chip_func_t vidmm_chip_func; + + +extern int vidmmi_allocate_video_memory_try(vidmm_mgr_t *mm_mgr, vidmm_allocation_t *allocation, vidmm_segment_preference_t *preferred_segment); +extern void vidmmi_release_video_memory(vidmm_mgr_t *mm_mgr, vidmm_allocation_t *allocation); +extern void vidmmi_release_segment_memory(vidmm_mgr_t *mm_mgr, int segment_id, list_node_t *list_node); + +extern int vidmmi_allocate_system_memory(adapter_t *adapter, vidmm_allocation_t *allocation, int must_success, int paging_locked); +extern void vidmmi_release_system_memory(adapter_t *adapter, vidmm_allocation_t *allocation); + +extern void vidmmi_try_destroy_one_allocation(gpu_device_t *device, vidmm_allocation_t *allocation); + +extern int vidmmi_segment_unresident_allocations(vidmm_mgr_t *mm_mgr, vidmm_segment_t *segment, int must_success); +extern int vidmmi_prepare_one_allocation(gpu_device_t *device, vidmm_allocation_t *allocation); + +extern void vidmmi_dump_video_memory(vidmm_mgr_t *mm_mgr, unsigned int segment_id); +extern void vidmmi_destroy_allocation(adapter_t *adapter, vidmm_allocation_t *allocation); + +extern void vidmmi_dump_segments(adapter_t *adapter); + +extern unsigned int vidmmi_query_max_size_of_local_allocation(adapter_t *adapter); +#endif + diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch.c b/drivers/gpu/drm/arise/core/vidsch/vidsch.c new file mode 100755 index 0000000000000..8372a647eec56 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch.c @@ -0,0 +1,1322 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "global.h" +#include "vidmm.h" +#include "vidmmi.h" +#include "vidsch.h" +#include "vidsch_sync.h" +#include "vidschi.h" +#include "vidsch_submit.h" +#include "vidsch_workerthread.h" +#include "perfevent.h" + +static vidsch_fence_buffer_t *vidschi_create_fence_buffer(adapter_t *adapter, unsigned int segment_id, int buffer_size); +static void vidschi_destroy_fence_buffer(adapter_t *adapter, vidsch_fence_buffer_t *fence_buf); + +extern vidschedule_chip_func_t vidschedule_chip_func; + +void vidsch_force_wakup(adapter_t *adapter) +{ + vidsch_mgr_t *vidsch = NULL; + int i = 0; + + for(i = 0; i < adapter->active_engine_count; i++) + { + vidsch = adapter->sch_mgr[i]; + + if (!vidsch) continue; + + if (vidsch->worker_thread) + { + util_wakeup_event_thread(vidsch->worker_thread); + } + } +} + +int vidsch_create(adapter_t *adapter) +{ + vidschedule_t *schedule = NULL; + vidsch_mgr_t *sch_mgr = NULL; + vidmm_segment_memory_t *dma_reserved_memory = NULL; + vidmm_segment_memory_t *local_reserved_memory = NULL; + vidmm_segment_memory_t *pcie_reserved_memory = NULL; + vidsch_query_private_t query_data = {0}; + vidmm_map_flags_t flags = {0}; + int i = 0; + int ret = S_OK; + + /* initialize GPU schedule */ + schedule = gf_calloc(sizeof(vidschedule_t)); + + schedule->adapter = adapter; + adapter->schedule = schedule; + + schedule->chip_func = &vidschedule_chip_func; + + schedule->rw_lock = gf_create_rwsema(); + + schedule->dvfs_status_lock = gf_create_spinlock(0); + schedule->power_status_lock = gf_create_spinlock(0); + + ret = vidsch_query_chip(adapter, &query_data); + + adapter->active_engine_count = query_data.engine_count; + + adapter->fence_buf = vidschi_create_fence_buffer(adapter, query_data.fence_buffer_segment_id, 68*1024); + adapter->fence_buf_local = vidschi_create_fence_buffer(adapter, 0x1, 68*1024); + adapter->fence_buf_snoop = vidschi_create_fence_buffer(adapter, 0x3, 68*1024); + + adapter->current_slice_mask = adapter->hw_caps.chip_slice_mask; + adapter->min_slice_mask = 0; + for (i = 0; i < 3; i++) + { + if(adapter->hw_caps.chip_slice_mask & (0xf << i * 4)) + { + adapter->min_slice_mask |= 1 << i * 4; + } + } + + /* initilize GPU engine */ + for (i = 0; i < query_data.engine_count; i++) + { + if(query_data.engine_ctrl[i] & ENGINE_CTRL_DISABLE) + { + continue; + } + + if(query_data.engine_caps[i] & ENGINE_CAPS_PAGING) + { + adapter->paging_engine_index = i; + } + + sch_mgr = gf_calloc(sizeof(vidsch_mgr_t)); + + adapter->sch_mgr[i] = sch_mgr; + + sch_mgr->adapter = adapter; + sch_mgr->engine_caps = query_data.engine_caps[i]; + sch_mgr->engine_ctrl = query_data.engine_ctrl[i]; + sch_mgr->engine_index = i; + sch_mgr->chip_func = query_data.engine_func[i]; + sch_mgr->init_submit = 1; + sch_mgr->hw_queue_size = query_data.engine_hw_queue_size[i]; + + list_init_head(&sch_mgr->allocated_task_list); + list_init_head(&sch_mgr->submitted_task_list); + + sch_mgr->last_send_fence_id = 0; + sch_mgr->returned_fence_id = 0; + sch_mgr->fence_event = gf_create_event(0); + sch_mgr->fence_lock = gf_create_spinlock(0); + sch_mgr->power_status_lock = gf_create_spinlock(0); + + sch_mgr->engine_lock = gf_create_mutex(); + + //gf_info("schedule_serialize[%d] = %d\n", i, query_data.schedule_serialize[i]); + + if (query_data.schedule_serialize[i]) + { + sch_mgr->task_id_lock = gf_create_mutex(); + } + else + { + sch_mgr->task_id_lock = NULL; + } + + sch_mgr->dma_buffer_segment_id = query_data.dma_segment[i]; + + /* allocate dma buffer */ + dma_reserved_memory = vidmm_allocate_segment_memory(adapter, sch_mgr->dma_buffer_segment_id, query_data.dma_buffer_size[i], 1); + + /* map dma buffer */ + gf_memset(&flags, 0, sizeof(flags)); + + flags.write_only = 1; + flags.mem_space = GF_MEM_KERNEL; + + vidmm_map_segment_memory(adapter, NULL, dma_reserved_memory, &flags); + + sch_mgr->dma_reserved_memory = dma_reserved_memory; + /* initial dma heap */ + sch_mgr->dma_heap = gf_calloc(sizeof(heap_t)); + + heap_init(sch_mgr->dma_heap, i, dma_reserved_memory->gpu_virt_addr, query_data.dma_buffer_size[i], adapter->os_page_size); + + sch_mgr->task_list_lock = gf_create_mutex(); + + /* reserved memory for chip private initialization use */ + if(query_data.local_memory_size[i]) + { + /* allocate local reserved memory */ + local_reserved_memory = vidmm_allocate_segment_memory(adapter, query_data.local_segment_id, query_data.local_memory_size[i], 1); + + /* map local reserved memory */ + gf_memset(&flags, 0, sizeof(flags)); + + flags.mem_space = GF_MEM_KERNEL; + + vidmm_map_segment_memory(adapter, NULL, local_reserved_memory, &flags); + + sch_mgr->local_reserved_memory = local_reserved_memory; + + gf_debug("engine %d local reserved_memory segment_id:%d gpu_virt_addr:%x\n", i, query_data.local_segment_id, local_reserved_memory->gpu_virt_addr); + + } + + if(query_data.pcie_memory_size[i]) + { + /* allocate pcie reserved memory */ + pcie_reserved_memory = vidmm_allocate_segment_memory(adapter, query_data.pcie_segment_id, query_data.pcie_memory_size[i], 1); + + /* map pcie reserved memory */ + gf_memset(&flags, 0, sizeof(flags)); + flags.write_only = 1; + flags.mem_space = GF_MEM_KERNEL; + + vidmm_map_segment_memory(adapter, NULL, pcie_reserved_memory, &flags); + + gf_memset(pcie_reserved_memory->vma->virt_addr, 0, query_data.pcie_memory_size[i]); + + sch_mgr->pcie_reserved_memory = pcie_reserved_memory; + + gf_debug("engine %d pcie reserved_memory segment_id:%d gpu_virt_addr:%x\n", i, query_data.pcie_segment_id, pcie_reserved_memory->gpu_virt_addr); + } + + ret = sch_mgr->chip_func->initialize(adapter, sch_mgr); + + if (ret != S_OK) + { + goto exit; + } + + vidschi_init_task_pool(&sch_mgr->normal_task_pool, TRUE); + sch_mgr->total_task_num = gf_create_atomic(0); + + if (adapter->ctl_flags.worker_thread_enable && (sch_mgr->engine_ctrl & ENGINE_CTRL_THREAD_ENABLE)) + { + char thread_name[256]; + sch_mgr->normal_pool_sema = gf_create_sema(PENDING_TASK_QUEUE_LENGTH); + gf_vsprintf(thread_name, "kthread-%d", i); + sch_mgr->worker_thread = util_create_event_thread(vidsch_worker_thread_event_handler, sch_mgr, thread_name, 0); + } + + sch_mgr->engine_dvfs_power_on = TRUE; //default is on + sch_mgr->hang_index = -1; //default is invalid value + sch_mgr->hang_fence_id = 0; //default is invalid value + sch_mgr->hang_hw_copy_mem = 0; //default is 0 + } + + adapter->hw_reset_lock = gf_create_mutex(); + + if(adapter->ctl_flags.run_on_qt) + { + adapter->hw_hang_max_timeout_ns = HW_HANG_MAX_TIMEOUT_NS_ON_QT; + adapter->hw_hang_fast_timeout_ns = HW_HANG_FAST_RECOVERY_TIMEOUT_NS; + adapter->sync_max_server_wait_time_ns = SYNC_OBJECT_MAX_SERVER_WAIT_TIME_NS_ON_QT; + adapter->context_destroy_timeout = CM_DESTROY_TIMEOUT_ON_QT; + } + else + { + adapter->hw_hang_max_timeout_ns = HW_HANG_MAX_TIMEOUT_NS; + adapter->hw_hang_fast_timeout_ns = HW_HANG_FAST_RECOVERY_TIMEOUT_NS; + adapter->sync_max_server_wait_time_ns = SYNC_OBJECT_MAX_SERVER_WAIT_TIME_NS; + adapter->context_destroy_timeout = CM_DESTROY_TIMEOUT; + + if(adapter->ctl_flags.run_on_qemu_device) + { + adapter->hw_hang_max_timeout_ns *= 100; + adapter->hw_hang_fast_timeout_ns = adapter->hw_hang_max_timeout_ns; + adapter->sync_max_server_wait_time_ns *= 100; + adapter->context_destroy_timeout *= 100; + } + } + + vidschi_init_daemon_thread(adapter); + + //vidschi_dump_buffer(adapter); +exit: + return ret; +} + +/* check if fence is back in target engine */ +int vidsch_is_fence_back(adapter_t *adapter, unsigned char engine_index, unsigned long long fence_id) +{ + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[engine_index]; + int ret = FALSE; + + if (sch_mgr->returned_fence_id >= fence_id) + { + ret = TRUE; + } + + return ret; +} + + +void vidsch_update_engine_idle_status(adapter_t *adapter, unsigned int engine_mask) +{ + vidsch_mgr_t *sch_mgr = NULL; + vidschedule_t *schedule = adapter->schedule; + unsigned long long timestamp = 0ll; + + unsigned int i = 0; + unsigned int work_thread_idel; + unsigned int fence_back; + unsigned long flags; + + schedule->busy_engine_mask = 0; + + for(i = 0; i < adapter->active_engine_count; i++) + { + + if((engine_mask & (1<sch_mgr[i]; + if(sch_mgr == NULL) continue; + + //IRQ cann't handle MUTEX + //task_list_empty = list_empty(&sch_mgr->allocated_task_list) && list_empty(&sch_mgr->submitted_task_list); + work_thread_idel = (sch_mgr->normal_task_pool.task_num == 0); + + + flags = gf_spin_lock_irqsave(sch_mgr->fence_lock); + fence_back = sch_mgr->returned_fence_id >= sch_mgr->last_send_fence_id ? 1:0; + gf_spin_unlock_irqrestore(sch_mgr->fence_lock,flags); + + gf_get_nsecs(×tamp); + timestamp = gf_do_div(timestamp, 1000000); + + //task_list_empty && + if(work_thread_idel && fence_back && !sch_mgr->hang_hw_copy_mem) + { + sch_mgr->last_idle = timestamp; + sch_mgr->completely_idle = 1; + sch_mgr->idle_elapse = sch_mgr->last_idle - sch_mgr->last_busy; + schedule->busy_engine_mask &= ~(1 << i); + } + else + { + sch_mgr->last_busy = timestamp; + sch_mgr->completely_idle = 0; + sch_mgr->idle_elapse = 0; + schedule->busy_engine_mask |= 1 << i; + } + } +} + +static int vidsch_is_fence_back_condition(void *argu) +{ + vidsch_wait_fence_t *wait_fence = argu; + + return vidsch_is_fence_back(wait_fence->adapter, wait_fence->engine, wait_fence->fence_id); +} + +inline int vidschi_allocation_in_cmd_queue(unsigned char engine_index, vidmm_allocation_t *allocation) +{ + return allocation->render_count[engine_index] == 0 ? FALSE : TRUE; +} + +inline int vidschi_allocation_in_write_cmd_queue(unsigned char engine_index, vidmm_allocation_t *allocation) +{ + return allocation->write_render_count[engine_index] == 0 ? FALSE : TRUE; +} + +static int vidsch_is_allocation_idle_condition(void *argu) +{ + int ret; + vidsch_wait_fence_t *wait_fence = argu; + int engine_index = wait_fence->engine; + vidmm_allocation_t *allocation = (vidmm_allocation_t*)wait_fence->allocation; + + gf_spin_lock(allocation->lock); + + if (wait_fence->read_only) + { + ret = !vidschi_allocation_in_write_cmd_queue(engine_index, allocation) && + vidsch_is_fence_back(wait_fence->adapter, engine_index, allocation->write_fence_id[engine_index]); + } + else + { + ret = !vidschi_allocation_in_cmd_queue(engine_index, allocation) && + vidsch_is_fence_back(wait_fence->adapter, engine_index, allocation->fence_id[engine_index]); + } + + gf_spin_unlock(allocation->lock); + + return ret; +} + +/** vidsch_wait_fence_interrupt implemented by vidsch_wait_fence_back. + * So if use vidsch_wait_fence_interrupt, before wait check, we need + * log current fence id, if check failed, we can directly wait + * fence_id + 1 back. + **/ +extern void vidschi_notify_fence_interrupt(adapter_t *adapter, unsigned int engine_mask); + +void vidsch_wait_fence_back(adapter_t *adapter, unsigned char engine_index, unsigned long long fence_id) +{ + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[engine_index]; + vidsch_wait_fence_t wait_fence = {0}; + condition_func_t condition = vidsch_is_fence_back_condition; + gf_event_status_t e_status = GF_EVENT_UNKNOWN; + int timeout = adapter->hw_caps.fence_interrupt_enable ? 2000*10:2; + int timeout_cnt = 0, max_timeout = 8000 *100 /timeout; + + if(adapter->in_suspend_resume) + { + unsigned int csp_intr_bits = gf_read32(adapter->mmio + 0x854c); //ADV_INTR_EN_REG + + if (!(csp_intr_bits & 0x8000000))//ENGINE_FENCE_INT + { + gf_info("%s() : FENCE_INT is not enabled, csp_intr_bits-0x%x\n", __func__, csp_intr_bits); + } + timeout = 100; + + //gf_info("%s() timeout-%d, fence intr-0x%x\n", __func__, timeout, csp_intr_bits & 0x8000000); + } + else + { + timeout = adapter->hw_caps.fence_interrupt_enable ? 2000*10:2; + } + + + wait_fence.adapter = adapter; + wait_fence.engine = engine_index; + wait_fence.fence_id = fence_id; + + while(e_status != GF_EVENT_BACK) + { + e_status = gf_wait_event_thread_safe(sch_mgr->fence_event, condition, &wait_fence, timeout); + + /* general timeout should not happen, but only HW hang, or interrupt disabled(we only update fence id on ISR) + * So if interrutp disabled, we need a place to update fence too, we add here. + */ + + /* + * Notice: pls do not add any printk to here, consider this: when system reboot, interrupt already disabled, + * we need use timeout to update the fence, if fb enabled and printk add here, it will lead a dead loop like + * this, we loop to wait hw idle, but we add some draw on this loop, this lead this loop never end. + */ + if(e_status == GF_EVENT_TIMEOUT) + { + timeout_cnt++; + //gf_info("%s() timeout: %d time for %dms\n", __func__, timeout_cnt, timeout); + + if (timeout_cnt > max_timeout) + { + gf_info("FENCE not back. engine index %x, wait fence id %lld, last send: %lld, last_return: %lld\n", + engine_index, fence_id, sch_mgr->last_send_fence_id, sch_mgr->returned_fence_id); + +#ifdef _DEBUG_ + gf_dump_stack(); +#endif + + max_timeout = 0; + break; + } + + /* timeout happen, force notify a interrupt to update fence id */ + vidsch_notify_interrupt(adapter, 0); + } + } +} + +static void vidschi_wait_allocation_idle(adapter_t *adapter, unsigned char engine_index, vidmm_allocation_t *allocation, int read_only) +{ + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[engine_index]; + vidsch_wait_fence_t wait_fence = {0}; + condition_func_t condition = &vidsch_is_allocation_idle_condition; + gf_event_status_t e_status = GF_EVENT_UNKNOWN; + int timeout = adapter->hw_caps.fence_interrupt_enable ? 2000*10:2; + int timeout_cnt = 0, max_timeout = 8000 *100 /timeout; + + wait_fence.adapter = adapter; + wait_fence.engine = engine_index; + wait_fence.allocation = allocation; + wait_fence.read_only = read_only; + + while(e_status != GF_EVENT_BACK) + { + e_status = gf_wait_event_thread_safe(sch_mgr->fence_event, condition, &wait_fence, timeout); + + /* general timeout should not happen, but only HW hang, or interrupt disabled(we only update fence id on ISR) + * So if interrutp disabled, we need a place to update fence too, we add here. + */ + + /* + * Notice: pls do not add any printk to here, consider this: when system reboot, interrupt already disabled, + * we need use timeout to update the fence, if fb enabled and printk add here, it will lead a dead loop like + * this, we loop to wait hw idle, but we add some draw on this loop, this lead this loop never end. + */ + if(e_status == GF_EVENT_TIMEOUT) + { + timeout_cnt++; + + if (timeout_cnt > max_timeout) + { + gf_info("Wait idle timeout. engine index %x, allocation %x\n", + engine_index, allocation->handle); + +#ifdef _DEBUG_ + gf_dump_stack(); +#endif + + max_timeout = 0; + } + + /* timeout happen, force notify a interrupt to update fence id */ + vidsch_notify_interrupt(adapter, 0); + } + } +} + +void vidsch_wait_engine_idle(adapter_t *adapter, int idx) +{ + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[idx]; + + if (!sch_mgr) + return; + + if(sch_mgr->worker_thread) + { + vidschi_wait_worker_thread_idle(sch_mgr); + } + + vidsch_wait_fence_back(sch_mgr->adapter, sch_mgr->engine_index, sch_mgr->last_send_fence_id); + +} + +void vidsch_wait_chip_idle(adapter_t *adapter, unsigned int engine_mask) +{ + int i = 0; + + if (adapter->hw_caps.video_only) + { + engine_mask &= ((1 << 7) | (1 << 8) | (1 << 9)); + } + + for(i = 0; i < adapter->active_engine_count; i++) + { + if((engine_mask & ( 1 << i)) && (adapter->sch_mgr[i] != NULL)) + { + vidsch_wait_engine_idle(adapter, i); + } + } +} + +int vidsch_destroy(adapter_t *adapter) +{ + vidschedule_t *schedule = adapter->schedule; + vidsch_mgr_t *sch_mgr = NULL; + vidmm_segment_memory_t *reserved_memory = NULL; + int i = 0; + + vidschi_deinit_daemon_thread(adapter); + + gf_destroy_mutex(adapter->hw_reset_lock); + + for (i = 0; i < MAX_ENGINE_COUNT; i++) + { + sch_mgr = adapter->sch_mgr[i]; + + if (sch_mgr == NULL) + { + continue; + } + + /* wait worker thread idle and kill it */ + vidschi_wait_worker_thread_idle(sch_mgr); + + vidsch_release_completed_tasks(adapter, sch_mgr->engine_index, NULL); + + vidschi_release_allocated_tasks(sch_mgr); + + gf_destroy_event(sch_mgr->fence_event); + gf_destroy_spinlock(sch_mgr->fence_lock); + gf_destroy_spinlock(sch_mgr->power_status_lock); + + util_destroy_event_thread(sch_mgr->worker_thread); + + gf_destroy_sema(sch_mgr->normal_pool_sema); + + vidschi_fini_task_pool(&sch_mgr->normal_task_pool); + + gf_destroy_atomic(sch_mgr->total_task_num); + + gf_destroy_mutex(sch_mgr->task_list_lock); + + /* free reserved video and pcie memory */ + if(sch_mgr->pcie_reserved_memory) + { + reserved_memory = sch_mgr->pcie_reserved_memory; + + vidmm_unmap_segment_memory(adapter, reserved_memory, GF_MEM_KERNEL); + + vidmm_release_segment_memory(adapter, reserved_memory); + + sch_mgr->pcie_reserved_memory = NULL; + } + + if(sch_mgr->local_reserved_memory) + { + reserved_memory = sch_mgr->local_reserved_memory; + + vidmm_unmap_segment_memory(adapter, reserved_memory, GF_MEM_KERNEL); + + vidmm_release_segment_memory(adapter,reserved_memory); + + sch_mgr->local_reserved_memory = NULL; + } + + if(sch_mgr->dma_reserved_memory) + { + reserved_memory = sch_mgr->dma_reserved_memory; + + vidmm_unmap_segment_memory(adapter, reserved_memory, GF_MEM_KERNEL); + + vidmm_release_segment_memory(adapter, reserved_memory); + + sch_mgr->dma_reserved_memory = NULL; + } + + if(sch_mgr->dma_heap) + { + heap_destroy(sch_mgr->dma_heap); + gf_free(sch_mgr->dma_heap); + sch_mgr->dma_heap = NULL; + } + + if(sch_mgr->private_data) + { + sch_mgr->chip_func->destroy(sch_mgr); + } + + gf_destroy_mutex(sch_mgr->engine_lock); + + if (sch_mgr->task_id_lock) + { + gf_destroy_mutex(sch_mgr->task_id_lock); + } + + gf_free(sch_mgr); + adapter->sch_mgr[i] = NULL; + } + + vidschi_destroy_fence_buffer(adapter, adapter->fence_buf); + vidschi_destroy_fence_buffer(adapter, adapter->fence_buf_local); + vidschi_destroy_fence_buffer(adapter, adapter->fence_buf_snoop); + + gf_destroy_rwsema(schedule->rw_lock); + + gf_destroy_spinlock(schedule->dvfs_status_lock); + gf_destroy_spinlock(schedule->power_status_lock); + + gf_free(schedule); + + adapter->schedule = NULL; + + return S_OK; +} + +unsigned long long vidsch_get_current_returned_fence(adapter_t *adapter, int engine) +{ + vidsch_mgr_t *vidsch = adapter->sch_mgr[engine]; + + return vidsch->returned_fence_id; +} + +int vidsch_save(adapter_t *adapter) +{ + vidsch_mgr_t *vidsch = NULL; + int i = 0; + int result = 0; + vidsch_wait_chip_idle(adapter, ALL_ENGINE_MASK); + + for(i = 0; i < adapter->active_engine_count; i++) + { + vidsch = adapter->sch_mgr[i]; + + if(vidsch == NULL) continue; + + result = vidsch->chip_func->save(vidsch); + if (result) + { + return result; + } + } + return result; +} + +void vidsch_restore(adapter_t *adapter) +{ + vidsch_mgr_t *vidsch = NULL; + int i = 0; + + for(i = 0; i < adapter->active_engine_count; i++) + { + vidsch = adapter->sch_mgr[i]; + + if(vidsch == NULL) continue; + + vidsch->chip_func->restore(vidsch, TRUE); + + vidsch->engine_dvfs_power_on = TRUE; + vidsch->init_submit = TRUE; + + } +} + +void vidsch_dvfs_power_flag_reset(adapter_t *adapter) +{ + vidsch_mgr_t *vidsch = NULL; + int i; + + for (i = 0; i < adapter->active_engine_count; i++) + { + vidsch = adapter->sch_mgr[i]; + if (vidsch == NULL) + continue; + + vidsch->engine_dvfs_power_on = FALSE; + } +} + +static vidsch_fence_buffer_t *vidschi_create_fence_buffer(adapter_t *adapter, unsigned int segment_id, int buffer_size) +{ + vidsch_fence_buffer_t *fence_buf = gf_calloc(sizeof(vidsch_fence_buffer_t)); + vidmm_segment_memory_t *reserved_memory = NULL; + vidmm_map_flags_t map_flags = {0}; + unsigned short total_num = 0; + + reserved_memory = vidmm_allocate_segment_memory(adapter, segment_id, buffer_size, 0); + + // issue 14961 exists if fence buf is put into 3G ~ 3G+32M + if (0xc0000000 <= reserved_memory->gpu_virt_addr && reserved_memory->gpu_virt_addr < 0xc2000000) + { + vidmm_release_segment_memory(adapter, reserved_memory); + reserved_memory = vidmm_allocate_segment_memory(adapter, segment_id, buffer_size, 1); + if (0xc0000000 <= reserved_memory->gpu_virt_addr && reserved_memory->gpu_virt_addr < 0xc2000000) + gf_error("issue 14961 exists if fence buf is put into 3G ~ 3G+32M!\n"); + } + + /* map fence buffer */ + map_flags.read_only = 1; + map_flags.cache_type = GF_MEM_UNCACHED; + map_flags.mem_space = GF_MEM_KERNEL; + + vidmm_map_segment_memory(adapter, NULL, reserved_memory, &map_flags); + + /* per fence use a 64-bit slot */ + total_num = reserved_memory->list_node->aligned_size / sizeof(unsigned long long); + + //gf_info("create fence buffer total num %d \n", total_num); + //gf_info("fence buffer segment_id:%d, gpu_virt_addr:%llx\n", segment_id, reserved_memory->gpu_virt_addr); + + fence_buf->reserved_memory = reserved_memory; + + fence_buf->bitmap_lock = gf_create_spinlock(0); + fence_buf->bitmap_size = total_num >> 3; + fence_buf->bitmap = gf_calloc(fence_buf->bitmap_size); + fence_buf->total_num = + fence_buf->left_num = total_num; + fence_buf->free_start = 0; + + return fence_buf; +} + +static void vidschi_destroy_fence_buffer(adapter_t *adapter, vidsch_fence_buffer_t *fence_buf) +{ + vidmm_segment_memory_t *reserved_memory = fence_buf->reserved_memory; + + vidmm_unmap_segment_memory(adapter, reserved_memory, GF_MEM_KERNEL); + + vidmm_release_segment_memory(adapter, reserved_memory); + + gf_destroy_spinlock(fence_buf->bitmap_lock); + + gf_free(fence_buf->bitmap); + + gf_free(fence_buf); +} + +int vidsch_request_fence_space(adapter_t *adapter, void *buf, unsigned long long **virt_addr, unsigned long long *gpu_addr) +{ + vidsch_fence_buffer_t *fence_buf = (vidsch_fence_buffer_t *)buf; + vidmm_segment_memory_t *reserved_memory = fence_buf->reserved_memory; + int num = 0; + int status = E_FAIL; + + if(fence_buf->left_num == 0) + { + gf_error("fence_buf no enough space.\n"); + } + + gf_spin_lock(fence_buf->bitmap_lock); + + num = gf_find_next_zero_bit(fence_buf->bitmap, fence_buf->total_num, fence_buf->free_start); + + if(num < fence_buf->total_num) + { + gf_set_bit(num, fence_buf->bitmap); + + fence_buf->left_num--; + fence_buf->free_start = (num + 1) % fence_buf->total_num; + + *gpu_addr = reserved_memory->gpu_virt_addr + (num << 3); + *virt_addr = (unsigned long long*)reserved_memory->vma->virt_addr + num; + **virt_addr = 0ll; + + status = S_OK; + } + + gf_spin_unlock(fence_buf->bitmap_lock); + + return status; +} + +int vidsch_release_fence_space(adapter_t *adapter, void *buf, unsigned long long gpu_addr) +{ + vidsch_fence_buffer_t *fence_buf = (vidsch_fence_buffer_t *)buf; + vidmm_segment_memory_t *reserved_memory = fence_buf->reserved_memory; + + int num = (gpu_addr - reserved_memory->gpu_virt_addr) >> 3; + + gf_spin_lock(fence_buf->bitmap_lock); + + fence_buf->left_num++; + + gf_clear_bit(num, fence_buf->bitmap); + + gf_spin_unlock(fence_buf->bitmap_lock); + + return S_OK; +} + +int vidschi_can_prepare_task_dma(vidsch_mgr_t *sch_mgr, task_dma_t *task) +{ + unsigned long flags; + + flags = gf_spin_lock_irqsave(sch_mgr->fence_lock); + + if((sch_mgr->uncomplete_task_num + sch_mgr->prepare_task_num) < sch_mgr->hw_queue_size) + { + sch_mgr->prepare_task_num++; + task->prepare_submit = TRUE; + } + else + { + task->prepare_submit = FALSE; + } + + gf_spin_unlock_irqrestore(sch_mgr->fence_lock, flags); + + return task->prepare_submit; +} + +unsigned long long vidschi_inc_send_fence_id(vidsch_mgr_t *sch_mgr, int dec_prepare_num) +{ + unsigned long long fence_id; + unsigned long flags; + + flags = gf_spin_lock_irqsave(sch_mgr->fence_lock); + + sch_mgr->last_send_fence_id++; + + sch_mgr->uncomplete_task_num = sch_mgr->last_send_fence_id - sch_mgr->returned_fence_id; + + //Arise HW Limitation on VPP Engine: + //when fence/blc/qdump followed word hit blc/qdump/fence command type, wrong FSM might be triggered. + //the value of fence should be limitated are (include high & low part): + //0xcxxx,xxxx + if(sch_mgr->engine_index == 9/*RB_INDEX_VPP*/) + { + if((sch_mgr->last_send_fence_id & 0xF0000000) == 0xc0000000) + { + sch_mgr->last_send_fence_id += 0x10000000; + } + + if((sch_mgr->last_send_fence_id & 0xF000000000000000) == 0xc000000000000000) + { + sch_mgr->last_send_fence_id += 0x1000000000000000; + } + } + + fence_id = sch_mgr->last_send_fence_id; + + if(dec_prepare_num) + { + sch_mgr->prepare_task_num--; + } + + gf_spin_unlock_irqrestore(sch_mgr->fence_lock, flags); + + return fence_id; +} + +/* update fence id will returned latest returned fence id */ + +static int vidschi_update_fence_id(vidsch_mgr_t *sch_mgr, unsigned long long *curr_returned) +{ + unsigned long long new_fence, old_fence; + unsigned long flags; + + int update_new = FALSE; + + flags = gf_spin_lock_irqsave(sch_mgr->fence_lock); + new_fence = sch_mgr->chip_func->update_fence_id(sch_mgr); + + old_fence = sch_mgr->returned_fence_id; + /* check if new_returned valid, if not skipped it */ + if(((new_fence > sch_mgr->returned_fence_id) && + (new_fence <= sch_mgr->last_send_fence_id)) && + (old_fence <= sch_mgr->last_send_fence_id)) + { + sch_mgr->returned_fence_id = new_fence; + sch_mgr->uncomplete_task_num = sch_mgr->last_send_fence_id - sch_mgr->returned_fence_id; + update_new = TRUE; + } + else + { + new_fence = sch_mgr->returned_fence_id; + } + + gf_spin_unlock_irqrestore(sch_mgr->fence_lock, flags); + + if(new_fence > old_fence) + { + gf_get_nsecs(&sch_mgr->returned_timestamp); + } + + *curr_returned = new_fence; + + return update_new; +} + +void vidschi_notify_fence_interrupt(adapter_t *adapter, unsigned int engine_mask) +{ + vidsch_mgr_t *sch_mgr = NULL; + unsigned int engine = 0; + gf_perf_event_t perf_event = {0}; + unsigned long long returned_fence_id = 0ll; + unsigned long long timestamp = 0ll; + + int new_fence = FALSE; + + if (adapter->ctl_flags.perf_event_enable) + { + gf_get_nsecs(×tamp); + perf_event.header.timestamp_high = timestamp >> 32; + perf_event.header.timestamp_low = (timestamp) & 0xffffffff; + + perf_event.header.size = sizeof(gf_perf_event_dma_buffer_completed_t); + perf_event.header.type = GF_PERF_EVENT_DMA_BUFFER_COMPLETED; + } + + for(engine = 0; engine < adapter->active_engine_count; engine++) + { + if((1 << engine) & engine_mask) + { + sch_mgr = adapter->sch_mgr[engine]; + + if(sch_mgr == NULL) continue; + new_fence = vidschi_update_fence_id(sch_mgr, &returned_fence_id); + + if(new_fence) + { + static int fence_counter = 0; + gf_fence_back_trace_event(adapter->index << 16 | sch_mgr->engine_index, returned_fence_id); + gf_counter_trace_event("fence interrupt", fence_counter = !fence_counter); + } + + if (adapter->ctl_flags.perf_event_enable && new_fence) + { + perf_event.dma_buffer_completed.engine_idx = engine; + perf_event.dma_buffer_completed.fence_id_low = returned_fence_id & 0xffffffff; + perf_event.dma_buffer_completed.fence_id_high = (returned_fence_id >> 32) & 0xffffffff; + perf_event_add_isr_event(adapter, &perf_event); + } + if(adapter->ctl_flags.hwq_event_enable && new_fence) + { + if(timestamp==0) + { + gf_get_nsecs(×tamp); + } + hwq_process_complete_event(adapter, timestamp,returned_fence_id & 0xffffffff,engine); + } + gf_wake_up_event(sch_mgr->fence_event); + if (gf_atomic_read(sch_mgr->total_task_num) > 0) + { + util_wakeup_event_thread(sch_mgr->worker_thread); + } + } + } + + + if (adapter->post_sync_event) + { + gf_get_nsecs(×tamp); + adapter->post_sync_event(adapter->post_sync_event_argu,0,timestamp); + } + + vidschi_notify_dma_fence(adapter); +} + +int vidsch_notify_interrupt(adapter_t *adapter, unsigned int interrupt_event) +{ + vidschedule_t *schedule = adapter->schedule; + + if(schedule->disable_schedule) + { + return S_OK; + } + + vidschi_notify_fence_interrupt(adapter, ALL_ENGINE_MASK); + + //do cg and dfs when fence back. + if(!adapter->hw_caps.video_only && + !adapter->hw_caps.gfx_only ) + { + vidschi_try_power_tuning(adapter, TRUE); + } + + return S_OK; +} + +int vidsch_allocation_in_hw_queue(adapter_t *adapter, unsigned int engine_mask, vidmm_allocation_t *allocation) +{ + int result = FALSE; + unsigned char i = 0; + + for(i = 0; i < adapter->active_engine_count; i++) + { + if((engine_mask & (0x1 <sch_mgr[i] != NULL)) + { + if(!vidsch_is_fence_back(adapter, i, allocation->fence_id[i])) + { + result = TRUE; + break; + } + } + } + + return result; +} + + +int vidsch_is_allocation_idle(adapter_t *adapter, unsigned int engine_mask, vidmm_allocation_t *allocation) +{ + int result = TRUE; + int i = 0; + + if (adapter->hw_caps.video_only) + { + engine_mask &= ((1 << 7) | (1 << 8) | (1 << 9)); + } + + for(i = 0; i < adapter->active_engine_count; i++) + { + if((engine_mask & (0x1 <sch_mgr[i] != NULL)) + { + if( vidschi_allocation_in_cmd_queue(i, allocation) || + (!vidschi_allocation_in_cmd_queue(i, allocation) && !vidsch_is_fence_back(adapter, i, allocation->fence_id[i]))) + { + result = FALSE; + break; + } + } + } + + return result; +} + +/* + * why add wait_allocation idle in vidsch module, because only vidsch can know the allocation idle status. + */ + +void vidsch_wait_allocation_idle(adapter_t *adapter, unsigned int engine_mask, int read_only, vidmm_allocation_t *allocation) +{ + unsigned char engine_index = 0; + + if (adapter->hw_caps.video_only) + { + engine_mask &= ((1 << 7)|(1 << 8)|(1 << 9)); + } + + for(engine_index = 0; engine_index < adapter->active_engine_count; engine_index++) + { + if(!(engine_mask & (1 << engine_index)) || (adapter->sch_mgr[engine_index] == NULL)) + { + continue; + } + + vidschi_wait_allocation_idle(adapter, engine_index, allocation, read_only); + } +} +void vidsch_get_set_reg(adapter_t *adapter, gf_query_info_t *info) +{ + vidschedule_t *schedule = adapter->schedule; + + if(schedule->chip_func->get_set_reg) + { + return schedule->chip_func->get_set_reg(adapter, info); + } +} + +void vidsch_set_miu_reg(adapter_t *adapter,gf_query_info_t *info) +{ + vidsch_mgr_t *sch_mgr= adapter->sch_mgr[0]; + if(sch_mgr!=NULL) + { + sch_mgr->chip_func->set_miu_reg(adapter, info); + } +} + +void vidsch_read_miu_reg(adapter_t *adapter,gf_query_info_t *info) +{ + vidsch_mgr_t *sch_mgr= adapter->sch_mgr[0]; + if(sch_mgr!=NULL) + { + sch_mgr->chip_func->read_miu_reg(adapter, info); + } +} + +void vidsch_dump(struct os_printer *p, adapter_t *adapter) +{ + vidsch_mgr_t *sch_mgr = NULL; + int i; + + for(i = 0; i < MAX_ENGINE_COUNT; i++) + { + sch_mgr = adapter->sch_mgr[i]; + + if(sch_mgr == NULL) continue; + + if(sch_mgr->worker_thread == NULL) continue; + + gf_printf(p, "\n"); + gf_printf(p, "Engine: %x, last send: %lld, returned: %lld. global_task_id: %lld, last_submit_task_id: %lld\n", + sch_mgr->engine_index, sch_mgr->last_send_fence_id, sch_mgr->returned_fence_id, sch_mgr->task_id, sch_mgr->last_submit_task_id); + + vidschi_dump_task_pool(p, adapter, &sch_mgr->normal_task_pool, "Normal"); + } +} + +static int vidsch_query_hw_hang(adapter_t *adapter, gf_query_info_t *info) +{ + + vidschedule_t *schedule = adapter->schedule; + + info->value = schedule->hw_hang; + + schedule->hw_hang = 0; + + //gf_info("%s() hw_hang-0x%x\n", __func__, info->value); + + return 0; +} + +static int vidsch_query_process_info(adapter_t *adapter, gf_query_info_t *info) +{ + vidmm_mgr_t *mm_mgr = adapter->mm_mgr; + gpu_device_t *device = NULL; + gpu_device_t *device_next = NULL; + gpu_context_t *context = NULL; + gpu_context_t *context_next = NULL; + vidmm_segment_t *segment = NULL; + unsigned int priority; + + gf_process_base_t *base_info = gf_calloc(sizeof(gf_process_base_t)); + gf_process_base_t *process_base_info = (gf_process_base_t *)info->buf; + unsigned int cnt = vidmm_get_segment_count(adapter); + int id = 0, process_count = 0; + + list_for_each_entry_safe(device, device_next, &adapter->device_list, list_node) + { + cm_device_lock(device); + base_info->pid = device->pid; + gf_memcpy(base_info->name, device->pname, KERNAL_STRING_ARRAY_MAX); + list_for_each_entry_safe(context, context_next, &device->context_list, list_node) + { + base_info->context_handle[base_info->context_count++] = context->handle; + } + + for (id = 0; id < cnt; id++) + { + vidmm_allocation_t *allocation = NULL, *allocation_next = NULL; + segment = &mm_mgr->segment[id]; + list_for_each_entry_safe(allocation, allocation_next, &segment->unpagable_resident_list, list_item) + { + gf_process_allocation_t alloc_info = {}; + if (allocation->device->handle == device->handle) + { + + alloc_info.handle = allocation->handle; + alloc_info.format = allocation->hw_format; + alloc_info.compress_format = allocation->compress_format; + alloc_info.segment_id = allocation->segment_id; + alloc_info.width = allocation->width; + alloc_info.height = allocation->height; + alloc_info.pitch = allocation->pitch; + alloc_info.bit_count = allocation->bit_count; + alloc_info.alignment = util_max(allocation->alignment, mm_mgr->adapter->os_page_size) >> 10; + alloc_info.size = util_align(allocation->orig_size, alloc_info.alignment); + alloc_info.physical_addr = allocation->phys_addr; + alloc_info.priority = allocation->priority; + alloc_info.at_type = allocation->at_type; + alloc_info.flag = allocation->flag.value; + alloc_info.status = allocation->status.value2; + alloc_info.perference = allocation->preferred_segment.value; + if (base_info->alloc_num >= KERNAL_NORMAT_ARRAY_MAX) + goto ALLOC_FULL; + gf_memcpy(&base_info->alloc_info[base_info->alloc_num], &alloc_info, sizeof(gf_process_allocation_t)); + base_info->alloc_num++; + } + } + + allocation = NULL; + allocation_next = NULL; + + for (priority = PDISCARD; priority < PALL; priority++) + { + list_for_each_entry_safe(allocation, allocation_next, &segment->pagable_resident_list[priority], list_item) + { + gf_process_allocation_t alloc_info = {}; + if (allocation->device->handle == device->handle) + { + + alloc_info.handle = allocation->handle; + alloc_info.format = allocation->hw_format; + alloc_info.compress_format = allocation->compress_format; + alloc_info.segment_id = allocation->segment_id; + alloc_info.width = allocation->width; + alloc_info.height = allocation->height; + alloc_info.pitch = allocation->pitch; + alloc_info.bit_count = allocation->bit_count; + alloc_info.alignment = util_max(allocation->alignment, mm_mgr->adapter->os_page_size) >> 10; + alloc_info.size = util_align(allocation->orig_size, alloc_info.alignment); + alloc_info.physical_addr = allocation->phys_addr; + alloc_info.priority = allocation->priority; + alloc_info.at_type = allocation->at_type; + alloc_info.flag = allocation->flag.value; + alloc_info.status = allocation->status.value2; + alloc_info.perference = allocation->preferred_segment.value; + if (base_info->alloc_num >= KERNAL_NORMAT_ARRAY_MAX) + goto ALLOC_FULL; + gf_memcpy(&base_info->alloc_info[base_info->alloc_num], &alloc_info, sizeof(gf_process_allocation_t)); + base_info->alloc_num++; + } + } + } + } + ALLOC_FULL: + base_info->device_handle = device->handle; + gf_copy_to_user(&process_base_info[process_count], base_info, sizeof(gf_process_base_t)); + cm_device_unlock(device); + if (process_count < KERNAL_NORMAT_ARRAY_MAX - 1) + process_count++; + else + break; + } + gf_free(base_info); + info->buf_len = process_count; + return 0; +} + +int vidsch_query_info(adapter_t *adapter, gf_query_info_t *info) +{ + int ret = 0; + gpu_device_t *device = NULL; + switch(info->type) + { + case GF_QUERY_HW_HANG: + ret = vidsch_query_hw_hang(adapter, info); + break; + case GF_QUERY_GET_VIDEO_BRIDGE_BUFFER: + info->value64 = adapter->sch_mgr[info->argu + RB_INDEX_VIDEO_START]->local_reserved_memory->gpu_virt_addr; + break; + case GF_QUERY_GPU_TIME_STAMP: + case GF_QUERY_REGISTER_U32: + case GF_SET_REGISTER_U32: + vidsch_get_set_reg(adapter, info); + break; + case GF_SET_MIU_REGISTER_U32: + vidsch_set_miu_reg(adapter,info); + break; + case GF_QUERY_MIU_REGISTER_U32: + vidsch_read_miu_reg(adapter,info); + break; + case GF_QUERY_VCP_INDEX: + if(adapter->chip_id >= CHIP_ARISE1020) + info->value = VCP0_INDEX; + else + { + if(info->value < VCP0_INDEX || info->value > VCP1_INDEX) + info->value = adapter->vcp_index_cnt[VCP0_INDEX] > adapter->vcp_index_cnt[VCP1_INDEX] ? VCP1_INDEX : VCP0_INDEX; + } + + device = get_from_handle(&adapter->hdl_mgr, info->argu); + if(device) + device->video_core_index_cnt[info->value]++; + + adapter->vcp_index_cnt[info->value]++; + break; + case GF_QUERY_PROCESS_INFO: + vidsch_query_process_info(adapter,info); + break; + default: + gf_assert(0, "vidsch_query_info"); + } + + return ret; +} + +int vidsch_cil2_misc(gpu_device_t *device, krnl_cil2_misc_t *misc) +{ + adapter_t *adapter = device->adapter; + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[0]; + + if (misc->context) + { + sch_mgr = adapter->sch_mgr[misc->context->engine_index]; + } + + return sch_mgr->chip_func->cil2_misc(sch_mgr, misc); +} + +int vidsch_dump_info(struct os_seq_file *seq_file, adapter_t *adapter) +{ + vidschedule_t *schedule = adapter->schedule; + + gf_seq_printf(seq_file, "dvfs_auto =%d, dvfs_force=%d\n", adapter->pm_caps.dvfs_auto, adapter->pm_caps.dvfs_force); + if (schedule->chip_func->dump_info) + { + schedule->chip_func->dump_info(seq_file, adapter); + } + + return 0; +} + +int vidsch_dump_debugbus(struct os_printer *p, adapter_t *adapter) +{ + vidschedule_t *schedule = adapter->schedule; + + if (schedule->chip_func->dump_debugbus) + { + schedule->chip_func->dump_debugbus(p, adapter); + } + return 0; +} + diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch.h b/drivers/gpu/drm/arise/core/vidsch/vidsch.h new file mode 100644 index 0000000000000..32efc28e2ef52 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch.h @@ -0,0 +1,262 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __VIDSCH_H__ +#define __VIDSCH_H__ + +#include "vidmm.h" +#include "context.h" +#include "gf_def.h" +#include "list.h" +#include "kernel_interface.h" + +/* scheduler allocation, record allocation infomation for one dma */ +typedef struct _vidsch_allocation +{ + vidmm_allocation_t *mm_allocation; /* vidmm allocation pointer */ + unsigned long long phy_addr; + struct + { + unsigned int write_operation : 1; /* if current dma write to allocation */ + unsigned int segment_id : 5; + unsigned int reserved : 26; + }; +}vidsch_allocation_t; + +typedef struct _vidsch_sync_object_reference +{ + struct vidsch_sync_object *sync_object; /* vidmm allocation pointer */ + unsigned int patch_offset; + unsigned long long fence_value; +}vidsch_sync_object_reference_t; + +/* arguments of vidsch manager interface render */ +typedef struct _vidsch_render +{ + unsigned int command_length; /* in: command length, in bytes */ + + unsigned int allocation_list_size; /* in: allocation list size */ + unsigned int patch_location_list_size; /* in: patch location list size */ + unsigned int sync_object_list_size; + + gf_render_flags_t flags; /* in: render flags */ + + unsigned int queued_buffer_count; /* out: task queue count when render, for debug */ + + unsigned long long render_counter; /* in: for trace events */ + + gf_allocation_list_t *allocation_list; + gf_syncobj_list_t *sync_object_list; + gf_patchlocation_list_t *patch_location_list; + + unsigned int cmdbuf_count; /* in */ + gf_cmdbuf_t *cmdbuf_array; /* in */ +}vidsch_render_t; + +typedef struct dma_node +{ + list_node_t *list_node; + unsigned char *virt_base_addr; + unsigned long long gpu_phy_base_addr; + unsigned int size; + unsigned int cmd_size; +}dma_node_t; + +typedef enum +{ + DRAW_2D_DMA = 1, + DRAW_3D_DMA = 2, + DRAW_3D_BLT = 3, + PAGING_DMA = 4, +}DMA_TYPE; + +/* task type */ +typedef enum _task_type +{ + task_type_render = 1, /* task dma */ + task_type_sync_wait = 2, /* task sync */ + task_type_sync_signal = 3, + task_type_paging = 4, + task_type_reserve = 5, +}task_type_t; + +/* self task desciption struct*/ +typedef struct _task_desc +{ + struct list_head list_item; + struct list_head schedule_node; + task_type_t type; + union + { + struct task_dma *task_render; + struct task_paging *task_paging; + struct task_signal *task_signal; + struct task_wait *task_wait; + }; + gpu_context_t *context; /* gpu_context */ + void *dma_fence; + unsigned int submitted : 1; + unsigned int fake_submitted : 1; + unsigned int reset_dropped : 1; + unsigned int need_dma_fence : 1; + unsigned int large_dma : 1; + int ref_cnt; + int cmd_size; + unsigned long long global_task_id; + unsigned long long context_task_id; + unsigned long long timestamp; + unsigned long long fence_id; + gf_render_flags_t Flags; + int hang_index; + unsigned long long hang_context; +}task_desc_t; + +/* dma information, used in render, patch, submit */ +typedef struct task_dma +{ + task_desc_t desc; + DMA_TYPE dma_type; + hw_ctxbuf_t *hw_ctx_info; + unsigned int engine_index; /* the engine the dma will be submitted to */ + dma_node_t *dma_buffer_node; + unsigned int command_length; + unsigned int submit_start_offset; /* submit start offset */ + unsigned int submit_end_offset; /* submit end offset */ + + gf_allocation_list_t *allocation_list_raw; + vidsch_allocation_t *sch_allocation_list; /* vidsch allocation list */ + unsigned int allocation_list_size; /* mm, sch allocation list size */ + + gf_patchlocation_list_t *patch_location_list; /* patch location list */ + unsigned int patch_location_list_size; /* patch location list size */ + unsigned int patch_start_offset; /* patch start offset */ + unsigned int patch_end_offset; /* patch end offset */ + + gf_syncobj_list_t *sync_object_list_raw; + vidsch_sync_object_reference_t *sync_object_list; + unsigned int sync_object_list_size; + + struct + { + unsigned int need_hwctx_switch : 1; + unsigned int need_paging : 1; /* need paging */ + unsigned int need_split : 1; /* need split */ + unsigned int paging : 1; /* paging dma buffer */ + unsigned int null_rendering : 1; /* update fence only */ + unsigned int dump_miu : 1; /* indicate miu counter dump*/ + unsigned int submit_failed : 1; /* submit fail */ + unsigned int prepare_submit : 1; + unsigned int prepare_succeeded : 1; + unsigned int reserved : 23; + }; + + unsigned long long render_counter; /* for trace events */ + unsigned long long timestamp_ms; +}task_dma_t; + +typedef struct task_paging +{ + //struct list_head list_item; + task_desc_t desc; + dma_node_t *dma; + unsigned int command_length; + + struct + { + unsigned int paging_type : 2; /* 0 means fill, 1 means paging in, 2 means paging out*/ + unsigned int reserved : 30; + }; + + int must_success; + int save_restore; + int paging_allocation_num; + int paging_allocation_list_size; + vidmm_paging_allocation_t *paging_allocation_list; +}task_paging_t; + +typedef struct +{ + DMA_TYPE dma_type; + gpu_context_t *context; + unsigned int command_length; + unsigned int allocation_count; + unsigned int patch_location_count; + unsigned int sync_object_count; + gf_render_flags_t Flags; +}vidsch_allocate_task_dma_t; + +/* export interface for other modules */ + +extern int vidsch_create(adapter_t *adapter); +extern int vidsch_destroy(adapter_t *adapter); + +extern int vidsch_render(gpu_context_t *gpu_context, vidsch_render_t *vidsch_render); +extern int vidsch_create_sync_object(gpu_device_t *gpu_device, gf_create_fence_sync_object_t *create, int binding); +extern int vidsch_destroy_sync_object(adapter_t *adapter, gpu_device_t *gpu_device, unsigned int hSync); +extern void vidsch_sync_obj_inc_reference(adapter_t *adapter, unsigned int hSync); +extern void vidsch_sync_obj_dec_reference(adapter_t *adapter, unsigned int hSync); +extern void vidsch_force_signal_fence_sync_object(adapter_t *adapter, unsigned int hSync, unsigned long long fence_value); +extern int vidsch_signal_sync_object(gpu_context_t *gpu_context, unsigned int hSync); +extern int vidsch_wait_sync_object(gpu_context_t *gpu_context, gf_wait_fence_sync_object_t *wait); +extern int vidsch_destroy_remained_sync_obj(gpu_device_t *device); +extern int vidsch_fence_value(gpu_device_t *device, gf_fence_value_t *value); +extern int vidsch_is_fence_signaled(adapter_t *adapter, unsigned int hSync, unsigned long long wait_value); + +extern void vidsch_update_engine_idle_status(adapter_t *adapter, unsigned int engine_mask); + + +extern int vidsch_is_fence_back(adapter_t *adapter, unsigned char engine_index, unsigned long long fence_id); +extern void vidsch_wait_fence_back(adapter_t *adapter, unsigned char engine_index, unsigned long long fence_id); +#define vidsch_wait_fence_interrupt vidsch_wait_fence_back +extern unsigned long long vidsch_get_current_returned_fence(adapter_t *adapter, int engine); + +extern void vidsch_wait_chip_idle(adapter_t *adapter, unsigned int engine_mask); +extern void vidsch_wait_engine_idle(adapter_t *adapter, int idx); + +extern int vidsch_save(adapter_t *adapter); +extern void vidsch_restore(adapter_t *adapter); +extern void vidsch_dvfs_power_flag_reset(adapter_t *adapter); +extern task_dma_t *vidsch_allocate_task_dma(adapter_t *adapter, unsigned int engine_index, vidsch_allocate_task_dma_t *dma_arg); + +extern task_paging_t *vidsch_allocate_paging_task(adapter_t *adapter, int dma_size, int allocation_num); +extern void vidsch_submit_paging_task(adapter_t *adapter, task_paging_t *paging_task); + +extern void vidsch_release_completed_tasks(adapter_t *adapter, int engine_index, unsigned long long *uncompleted_dma); + +extern void vidsch_task_inc_reference(adapter_t *adapter, int engine_index, task_desc_t *desc); +extern void vidsch_task_dec_reference(adapter_t *adapter, int engine_index, task_desc_t *desc); + +extern int vidsch_request_fence_space(adapter_t *adapter, void *fence_buf, unsigned long long **virt_addr, unsigned long long *gpu_addr); +extern int vidsch_release_fence_space(adapter_t *adapter, void *fence_buf, unsigned long long gpu_addr); + +extern int vidsch_notify_interrupt(adapter_t *adapter, unsigned int interrupt_events); + +extern int vidsch_cil2_misc(gpu_device_t *device, krnl_cil2_misc_t *misc); + +extern void vidsch_dump(struct os_printer *p, adapter_t *adapter); +extern int vidsch_dump_info(struct os_seq_file *seq_file, adapter_t *adapter); +extern int vidsch_dump_debugbus(struct os_printer *p, adapter_t *adapter); + +extern int vidsch_allocation_in_hw_queue(adapter_t *adapter, unsigned int engine_mask, vidmm_allocation_t *allocation); +extern int vidsch_is_allocation_idle(adapter_t *adapter, unsigned int engine_mask, vidmm_allocation_t *allocation); +extern void vidsch_wait_allocation_idle(adapter_t *adapter, unsigned int engine_mask, int read_only, vidmm_allocation_t *allocation); + + +extern void vidsch_get_set_reg(adapter_t *adapter, gf_query_info_t *info); +extern void vidsch_set_miu_reg(adapter_t *adapter,gf_query_info_t *info); +extern void vidsch_read_miu_reg(adapter_t *adapter,gf_query_info_t *info); +extern int vidsch_query_info(adapter_t *adapter, gf_query_info_t *info); +extern void vidsch_force_wakup(adapter_t *adapter); + +#endif diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_daemon_thread.c b/drivers/gpu/drm/arise/core/vidsch/vidsch_daemon_thread.c new file mode 100644 index 0000000000000..11d8c9486dd18 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch_daemon_thread.c @@ -0,0 +1,233 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_workerthread.h" +#include "vidsch_submit.h" + +static int vidschi_reset_hw(adapter_t *adapter, unsigned int hang_engines) +{ + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[util_get_lsb_position(hang_engines)]; + unsigned int i; + unsigned int ret = S_OK; + + gf_disable_interrupt(adapter->os_device.pdev); + + ret = sch_mgr->chip_func->reset_hw(sch_mgr); + + if (ret == S_OK) + { + for (i = 0; i < MAX_ENGINE_COUNT; i++) + { + sch_mgr = adapter->sch_mgr[i]; + + if(sch_mgr == NULL) continue; + + vidschi_set_uncompleted_task_dropped(sch_mgr, -1ll); + + vidsch_release_completed_tasks(adapter, i, NULL); + } + } + + //gf_info("reset finished.\n"); + + if(sch_mgr != NULL) + { + sch_mgr->init_submit = TRUE; + } + + gf_enable_interrupt(adapter->os_device.pdev); + + return S_OK; +} + +void vidschi_dump_hang_info(adapter_t *adapter, unsigned int hang_engines) +{ + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[util_get_lsb_position(hang_engines)]; + + if(sch_mgr != NULL && sch_mgr->chip_func->dump_hang_info != NULL) + { + sch_mgr->chip_func->dump_hang_info(sch_mgr); + } +} + +static void vidschi_dump_hang(adapter_t *adapter, unsigned int hang_engines) +{ + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[util_get_lsb_position(hang_engines)]; + + if(sch_mgr != NULL && sch_mgr->chip_func->dump_hang != NULL) + { + sch_mgr->chip_func->dump_hang(adapter); + } +} + +static int vidschi_check_hang_and_recovery(adapter_t *adapter) +{ + vidsch_mgr_t *sch_mgr = NULL; + vidschedule_t *schedule = adapter->schedule; + task_desc_t *hang_tasks[MAX_ENGINE_COUNT]; + + unsigned int i, hang_engines = 0; + + for (i = 0; i < MAX_ENGINE_COUNT; i++) + { + sch_mgr = adapter->sch_mgr[i]; + hang_tasks[i] = NULL; + + if(sch_mgr == NULL) continue; + + hang_tasks[i] = vidschi_uncompleted_task_exceed_wait_time(sch_mgr, adapter->hw_hang_max_timeout_ns); + + if(hang_tasks[i] != NULL) + { + gf_info("checked timeout type:%d, fence_id:%d", hang_tasks[i]->type, hang_tasks[i]->fence_id); + vidschi_dump_task(NULL,adapter, hang_tasks[i], 0, FALSE); + if(adapter->ctl_flags.hang_dump == 2 && hang_tasks[i]->type == task_type_paging) + { + gf_error("vidschi_check_hang_and_recovery not support paging task dump\n"); + } + + vidsch_task_dec_reference(adapter, sch_mgr->engine_index, hang_tasks[i]); + sch_mgr->hang_index = hang_tasks[i]->hang_index; + sch_mgr->hang_fence_id = hang_tasks[i]->fence_id; + + hang_tasks[i] = NULL; + hang_engines |= 1 << i; + } + } + + vidschi_try_power_tuning(adapter, FALSE); + + + schedule->hw_hang |= hang_engines; + + if (hang_engines != 0) + { + for (i=0; isch_mgr[i]; + break; + } + } + schedule->disable_schedule = TRUE; + + //vidmm_dump_resource(sch_mgr->adapter); + + //gf_info("vidsch_reset_engines, need reset hw, hang_engines:0x%x \n", hang_engines); + gf_info("timeout engine index %x, returned fence id %lld, send fence id %lld\n", + i, sch_mgr->returned_fence_id, sch_mgr->last_send_fence_id); + vidschi_dump_hang_info(adapter, hang_engines); +#if 1 + if(adapter->ctl_flags.recovery_enable == TRUE) + { + int status = 0; + //gf_info("before hw rest\n"); + gf_console_lock(1); + status = vidschi_reset_hw(adapter, hang_engines); + gf_console_lock(0); + + if(status == S_OK) + { + schedule->hw_hang = 0; + if(adapter->ctl_flags.hang_dump == 2) + { + vidschi_dump_hang(adapter, hang_engines); + } + } + + gf_msleep(10); + + schedule->disable_schedule = FALSE; + + vidsch_notify_interrupt(adapter, 0); + } + else +#endif + { + gf_msleep(100000);//ensure write to file done + gf_info("trigger assert, hang detected but recovery not enabled, stop kernel here to avoid endless hang.\n"); + gf_assert(0, "trigger assert, hang detected"); + + } + } + return 0; +} + +static int vidsch_daemon_delay_allocation(void *data, gf_event_status_t ret) +{ + vidschedule_t *schedule = data; + adapter_t *adapter = schedule->adapter; + + vidmm_destroy_defer_allocation(adapter); + return 0; +} + +static int vidsch_daemon_check_hang(void *data, gf_event_status_t ret) +{ + vidschedule_t *schedule = data; + adapter_t *adapter = schedule->adapter; + unsigned long long timestamp; + + // vidmm_destroy_defer_allocation(adapter); +#if 0 + //vidschi_try_power_tuning(adapter); + + if(!adapter->hw_caps.video_only && + !adapter->hw_caps.gfx_only && + adapter->hw_caps.dfs_enable) + { + vidsch_try_dvfs_tuning(adapter); + } +#endif + gf_get_nsecs(×tamp); + gf_core_interface->hwq_process_vsync_event(adapter, timestamp); + + vidschi_check_hang_and_recovery(adapter); + + return 0; +} + +/* init schedule daemon thread, mainly contains power gating. + * hw reset function also be called in this daemon thread */ +int vidschi_init_daemon_thread(adapter_t *adapter) +{ + vidschedule_t *schedule = adapter->schedule; + schedule->daemon_thread_check_hang = + util_create_event_thread(vidsch_daemon_check_hang, schedule, "daemon_check_hang", DAEMON_THREAD_INTERVAL); + schedule->daemon_thread_destory_allocation = + util_create_event_thread(vidsch_daemon_delay_allocation, schedule, "daemon_delay_allocation", DAEMON_THREAD_INTERVAL); + + return 0; +} + +int vidschi_deinit_daemon_thread(adapter_t *adapter) +{ + vidschedule_t *schedule = adapter->schedule; + + if (schedule->daemon_thread_check_hang) + { + util_destroy_event_thread(schedule->daemon_thread_check_hang); + } + if (schedule->daemon_thread_destory_allocation) + { + util_destroy_event_thread(schedule->daemon_thread_destory_allocation); + } + + return 0; +} + diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_gating.c b/drivers/gpu/drm/arise/core/vidsch/vidsch_gating.c new file mode 100644 index 0000000000000..5309368aa20c5 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch_gating.c @@ -0,0 +1,61 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" + +/* must called sch_mgr->engine_lock locked */ +void vidschi_engine_dvfs_power_on(vidsch_mgr_t *sch_mgr) +{ + adapter_t *adapter = sch_mgr->adapter; + + if (!adapter->pwm_level.EnableClockGating) + { + return; + } + + if(!sch_mgr->engine_dvfs_power_on) + { + if(!list_empty(&sch_mgr->submitted_task_list) || sch_mgr->last_send_fence_id != sch_mgr->returned_fence_id) + { + if(sch_mgr->chip_func->power_clock) + { + sch_mgr->chip_func->power_clock(sch_mgr, FALSE); + + sch_mgr->engine_dvfs_power_on = TRUE; + } + } + } + + return; +} + +void vidschi_try_power_tuning(adapter_t *adapter, unsigned int gfx_only) +{ + vidschedule_t *schedule = adapter->schedule; + + if (!adapter->pwm_level.EnableClockGating) + { + return; + } + + if(schedule->chip_func->power_tuning) + { + schedule->chip_func->power_tuning(adapter, gfx_only); + } + return; +} + + diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_render.c b/drivers/gpu/drm/arise/core/vidsch/vidsch_render.c new file mode 100644 index 0000000000000..030ef1b67f9a6 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch_render.c @@ -0,0 +1,481 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_render.h" +#include "vidsch_submit.h" +#include "vidsch_workerthread.h" +#include "vidsch_sync.h" +#include "vidmm.h" +#include "context.h" +#include "global.h" +#include "perfevent.h" + +/* +** vidschi_can_submit_in_main_thread() +** check task queue empty +** check if touch flip queue +** check if worker thread is disabled +*/ +/* this function must not re-entry, guranteed by kernel interface lock */ +static int vidschi_can_submit_in_main_thread(adapter_t *adapter, vidsch_mgr_t *sch_mgr, task_dma_t *task_dma) +{ + return CAN_SUBMIT_IN_MAIN_THREAD; +} + +void vidschi_emit_dma_fence(vidsch_mgr_t *sch_mgr, task_desc_t *task) +{ + adapter_t *adapter = sch_mgr->adapter; + + gf_assert(!task->dma_fence, "already emit fence"); + if (adapter->drm_cb) + { + task->dma_fence = adapter->drm_cb->fence.create( + adapter->drm_cb_argu, sch_mgr->engine_index, 0xffffffffffffffffULL); + + if (task->type == task_type_render) + { + int i; + task_dma_t *render = task->task_render; + vidsch_allocation_t *sch_allocation_list = render->sch_allocation_list; + vidmm_allocation_t *allocation = NULL; + + for (i = 0; i < render->allocation_list_size; i++) + { + if (sch_allocation_list[i].mm_allocation == NULL) continue; + + allocation = sch_allocation_list[i].mm_allocation; + + if (allocation->bo) + { + adapter->drm_cb->fence.attach_buffer( + adapter->drm_cb_argu, allocation->bo, + task->dma_fence, sch_allocation_list[i].write_operation ? 0 : 1); + } + } + } + } +} + +void vidschi_update_and_release_dma_fence(adapter_t *adapter, task_desc_t *task) +{ + if (adapter->drm_cb && task->dma_fence) + { + adapter->drm_cb->fence.update_value( + adapter->drm_cb_argu, task->dma_fence, task->fence_id); + + adapter->drm_cb->fence.release( + adapter->drm_cb_argu, task->dma_fence); + + task->dma_fence = NULL; + } +} + +void vidschi_notify_dma_fence(adapter_t *adapter) +{ + if (adapter->drm_cb) + { + adapter->drm_cb->fence.notify_event(adapter->drm_cb_argu); + } +} + +int vidschi_send_to_submit_queue(vidsch_mgr_t *sch_mgr, task_dma_t *task_dma) +{ + adapter_t *adapter = sch_mgr->adapter; + int status = S_OK; + + /* if task have hwctx, need check if hwctx invalid, since previous task may submit by worker thread, + * and thread may encounter problem, like paging failed, which lead task dropped. since hwctx switch + * task may depend on previous task, so we set hwctx invalid if drop task. and skip all follow task based on this hwctx + */ + if((task_dma->hw_ctx_info != NULL) && task_dma->hw_ctx_info->is_invalid) + { + status = E_FAIL; + } + + if(vidschi_can_submit_task(&task_dma->desc) && + vidschi_can_submit_in_main_thread(adapter, sch_mgr, task_dma)) + { + task_dma->desc.context->last_submit_to_sw = task_dma->desc.context_task_id; + + status = vidschi_prepare_and_submit_dma(sch_mgr, task_dma); + } + else + { + vidschi_add_task_to_pending_queue(sch_mgr, &task_dma->desc); + } + + return status; +} + +static void vidsch_dma_sync_object_trigger(void *arg) +{ + vidsch_mgr_t *sch_mgr = arg; + + util_wakeup_event_thread(sch_mgr->worker_thread); +} + + +static task_wait_t *vidsch_prepare_render_allocation_list(vidsch_mgr_t *sch_mgr, task_dma_t *render) +{ + adapter_t *adapter = sch_mgr->adapter; + gpu_context_t *context = render->desc.context; + gpu_device_t *device = context->device; + vidsch_allocation_t *sch_allocation_list = render->sch_allocation_list; + vidmm_allocation_t *allocation = NULL; + int i, engine_index = context->engine_index; + task_wait_t *wait_task = NULL; + vidsch_wait_instance_t *instance = NULL; + vidsch_sync_object_t *sync_obj = NULL; + + vidschi_destroy_defer_sync_obj(adapter); + + for (i = 0; i < render->allocation_list_size; i++) + { + allocation = sch_allocation_list[i].mm_allocation; + if (allocation && allocation->bo) + { + void *dma_sync_obj = NULL; + + if (adapter->drm_cb) + { + dma_sync_obj = adapter->drm_cb->fence.dma_sync_object_create(adapter->drm_cb_argu, + allocation->bo, sch_allocation_list[i].write_operation, engine_index, vidsch_dma_sync_object_trigger, sch_mgr); + } + + if (dma_sync_obj) + { + if (!wait_task) + { + wait_task = gf_calloc(sizeof(task_wait_t)); + + gf_get_nsecs(&wait_task->desc.timestamp); + gf_atomic_inc(context->ref_cnt); + wait_task->desc.context = context; + wait_task->desc.type = task_type_sync_wait; + wait_task->desc.task_wait = wait_task; + wait_task->instance_cnt = 0; + wait_task->only_check_status = FALSE; + wait_task->desc.context_task_id = ++context->task_id; + if (render->allocation_list_size <= sizeof(wait_task->instances_builtin)/sizeof(wait_task->instances_builtin[0])) + { + wait_task->instances = wait_task->instances_builtin; + } + else + { + wait_task->instances = gf_malloc(render->allocation_list_size * sizeof(*instance)); + } + gf_task_create_trace_event(adapter->index << 16 | engine_index, context->handle, wait_task->desc.context_task_id, wait_task->desc.type); + } + sync_obj = gf_calloc(sizeof(vidsch_sync_object_t)); + list_init_head(&sync_obj->instance_list); + sync_obj->type = GF_SYNC_OBJ_TYPE_DMAFENCE; + sync_obj->dma.dma_sync_obj = dma_sync_obj; + sync_obj->ref_cnt = gf_create_atomic(0); + sync_obj->lock = gf_create_spinlock(0); + sync_obj->binding = TRUE; + sync_obj->device = device; + + instance = &wait_task->instances[wait_task->instance_cnt++]; + instance->sync_obj = sync_obj; + vidschi_sync_obj_add_reference(sync_obj, instance); + vidschi_add_sync_to_defer_destroy(adapter, sync_obj); + } + } + } + + return wait_task; +} + +static void vidschi_init_render_allocation_list(vidsch_mgr_t *sch_mgr, task_dma_t *render) +{ + adapter_t *adapter = sch_mgr->adapter; + gpu_context_t *context = render->desc.context; + gpu_device_t *device = context->device; + vidsch_allocation_t *sch_allocation_list = render->sch_allocation_list; + vidmm_allocation_t *allocation = NULL; + gf_allocation_list_t *allocation_list = render->allocation_list_raw; + int i, engine_index = context->engine_index; + + cm_device_lock(device); + + for (i = 0; i < render->allocation_list_size; i++) + { + if (!allocation_list[i].hAllocation) continue; + + allocation = vidmm_get_from_gem_handle(adapter, device, allocation_list[i].hAllocation); + + if (allocation == NULL) continue; + + gf_spin_lock(allocation->lock); + + allocation->render_count[engine_index]++; + + if(allocation_list[i].WriteOperation) + { + gf_counter_trace_event("var_write_allocation", allocation->handle); + allocation->write_render_count[engine_index]++; + sch_allocation_list[i].write_operation = 1; + } + else + { + gf_counter_trace_event("var_read_allocation", allocation->handle); + } + + gf_spin_unlock(allocation->lock); + + sch_allocation_list[i].mm_allocation = allocation; + } + + cm_device_unlock(device); +} + +static void vidschi_init_render_sync_object_list(vidsch_mgr_t *sch_mgr, task_dma_t *render) +{ + adapter_t *adapter = sch_mgr->adapter; + vidsch_sync_object_reference_t *sch_sync_list = render->sync_object_list; + vidsch_sync_object_t *sync_obj = NULL; + gf_syncobj_list_t *sync_list = render->sync_object_list_raw; + + int i; + + for(i = 0; i < render->sync_object_list_size; i++) + { + sync_obj = get_from_handle(&adapter->hdl_mgr, sync_list[i].hSyncObject); + + if(sync_obj == NULL) continue; + + vidschi_sync_obj_inc_reference(sync_obj); + + sch_sync_list[i].sync_object = sync_obj; + sch_sync_list[i].patch_offset = sync_list[i].PatchOffset; + sch_sync_list[i].fence_value = sync_list[i].FenceValue; + + if (adapter->ctl_flags.perf_event_enable) + { + gf_perf_event_t perf_event = {0}; + unsigned long long timestamp = 0; + gf_memset(&perf_event, 0, sizeof(gf_perf_event_t)); + + gf_get_nsecs(×tamp); + perf_event.header.timestamp_high = timestamp >> 32; + perf_event.header.timestamp_low = (timestamp) & 0xffffffff; + + perf_event.header.size = sizeof(gf_perf_event_sync_event_t); + perf_event.header.type = GF_PERF_EVENT_SYNC_EVENT; + + perf_event.sync_event.engine_idx = render->engine_index; + perf_event.sync_event.type = sync_obj->type; + perf_event.sync_event.handle = sync_obj->handle; + perf_event.sync_event.fence_value_high = sch_sync_list[i].fence_value >> 32; + perf_event.sync_event.fence_value_low = sch_sync_list[i].fence_value & 0xffffffff; + perf_event.sync_event.gpu_context = render->desc.context->handle; + perf_event.sync_event.ctx_task_id_high = render->desc.context_task_id >> 32; + perf_event.sync_event.ctx_task_id_low = render->desc.context_task_id & 0xffffffff; + + perf_event_add_event(adapter, &perf_event); + } + } +} + +void vidschi_deinit_render_sync_object_list(vidsch_mgr_t *sch_mgr, task_dma_t *render) +{ + vidsch_sync_object_reference_t *sch_sync_list = render->sync_object_list; + vidsch_sync_object_t *sync_obj = NULL; + + int i, force_signal; + + force_signal = render->desc.reset_dropped|render->desc.fake_submitted; + + for(i = 0; i < render->sync_object_list_size; i++) + { + sync_obj = sch_sync_list[i].sync_object; + + if(sync_obj == NULL) continue; + + if(force_signal) + { + gf_info("render task: %p, force signal object[%2d]: %x.\n", render, i, sync_obj->handle); + + vidschi_force_signal_fence_sync_object(sync_obj, sch_sync_list[i].fence_value); + } + + vidschi_sync_obj_dec_reference(sync_obj); + } +} + +int vidsch_render(gpu_context_t *context, vidsch_render_t *render_data) +{ + adapter_t *adapter = context->device->adapter; + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[context->engine_index]; + task_dma_t *task_dma = 0; + task_wait_t *task_wait = NULL; + vidsch_allocate_task_dma_t task_arg = {0}; + int status = 0; + gf_cmdbuf_t *cmdbuf_array = NULL; + + if (render_data->command_length == 0) + { + return S_OK; + } + + gf_begin_section_trace_event("vidsch_render"); + + if (adapter->ctl_flags.perf_event_enable) + { + gf_perf_event_t perf_event = {0}; + unsigned long long timestamp = 0; + + perf_event.header.size = sizeof(gf_perf_event_dma_buffer_queued_t); + perf_event.header.type = GF_PERF_EVENT_DMA_BUFFER_QUEUED; + perf_event.header.pid = gf_get_current_pid(); + perf_event.header.tid = gf_get_current_tid(); + + gf_get_nsecs(×tamp); + perf_event.header.timestamp_high = timestamp >> 32; + perf_event.header.timestamp_low = timestamp & 0xffffffff; + + perf_event.dma_buffer_queued.gpu_context = context->handle; + perf_event.dma_buffer_queued.engine_idx = context->engine_index; + perf_event.dma_buffer_queued.dma_idx_low = render_data->render_counter & 0xffffffff; + perf_event.dma_buffer_queued.dma_idx_high = (render_data->render_counter >> 32) & 0xffffffff; + + perf_event_add_event(adapter, &perf_event); + } + + task_arg.context = context; + task_arg.command_length = render_data->command_length; + task_arg.allocation_count = render_data->allocation_list_size; + task_arg.patch_location_count = render_data->patch_location_list_size; + task_arg.sync_object_count = render_data->sync_object_list_size; + + cmdbuf_array = render_data->cmdbuf_array; + task_arg.Flags = render_data->flags; + + //check the cmd is normal Xserver 2D command or CompositeBlt command + // if compositblt, the dmatpye set to DRAW_3D_BLT + // first check Flag3dbltCmd, since hwc maybe set Flag3dbltCmd & Flag2dCmd both. + if (render_data->flags.Flag3dbltCmd) + { + task_arg.dma_type = DRAW_3D_BLT; + } + else if (render_data->flags.Flag2dCmd) + { + task_arg.dma_type = DRAW_2D_DMA; + } + else + { + task_arg.dma_type = DRAW_3D_DMA; + } + + task_dma = vidsch_allocate_task_dma(adapter, context->engine_index, &task_arg); + + if (context->is_kernel) + { + if (render_data->allocation_list_size > 0) + gf_memcpy(task_dma->allocation_list_raw, render_data->allocation_list, + render_data->allocation_list_size * sizeof(gf_allocation_list_t)); + + if (render_data->patch_location_list_size > 0) + gf_memcpy(task_dma->patch_location_list, render_data->patch_location_list, + render_data->patch_location_list_size * sizeof(gf_patchlocation_list_t)); + + if (render_data->sync_object_list_size > 0) + gf_memcpy(task_dma->sync_object_list_raw, render_data->sync_object_list, + render_data->sync_object_list_size * sizeof(gf_syncobj_list_t)); + } + else + { + if (render_data->allocation_list_size > 0) + gf_copy_from_user(task_dma->allocation_list_raw, render_data->allocation_list, + render_data->allocation_list_size * sizeof(gf_allocation_list_t)); + + if (render_data->patch_location_list_size > 0) + gf_copy_from_user(task_dma->patch_location_list, render_data->patch_location_list, + render_data->patch_location_list_size * sizeof(gf_patchlocation_list_t)); + + if (render_data->sync_object_list_size > 0) + gf_copy_from_user(task_dma->sync_object_list_raw, render_data->sync_object_list, + render_data->sync_object_list_size * sizeof(gf_syncobj_list_t)); + } + + vidschi_init_render_allocation_list(sch_mgr, task_dma); + + vidschi_init_render_sync_object_list(sch_mgr, task_dma); + + task_wait = vidsch_prepare_render_allocation_list(sch_mgr, task_dma); + + if (task_wait) + { + /* swap task_dma & task_wait's task_id */ + unsigned long long temp = task_wait->desc.context_task_id; + task_wait->desc.context_task_id = task_dma->desc.context_task_id; + task_dma->desc.context_task_id = temp; + + /* always add to pending queue, even if client_wait, otherwise last_submit_to_sw will incorrect */ + if (adapter->ctl_flags.worker_thread_enable) + { + vidschi_add_task_to_pending_queue(sch_mgr, &task_wait->desc); + } + else + { + vidschi_client_wait(task_wait); + context->last_submit_to_sw = task_wait->desc.context_task_id; + vidschi_release_wait_task(task_wait); + } + } + + if(task_dma->need_hwctx_switch) + { + task_dma->hw_ctx_info = cm_get_hwctx_buffer(context->device, context, render_data->flags.HWCtxBufIndex); + } + + do + { + int i; + char *dst = task_dma->dma_buffer_node->virt_base_addr; + + for (i = 0; i < render_data->cmdbuf_count; i++) + { + if (context->is_kernel) + { + gf_memcpy(dst, (void*)(unsigned long)cmdbuf_array[i].ptr, cmdbuf_array[i].size); + } + else + { + gf_copy_from_user(dst, (void*)(unsigned long)cmdbuf_array[i].ptr, cmdbuf_array[i].size); + } + dst += cmdbuf_array[i].size; + } + gf_assert(dst - (char*)task_dma->dma_buffer_node->virt_base_addr == render_data->command_length, "incorrect command_length"); + } + while(0); + + task_dma->render_counter = render_data->render_counter; + + sch_mgr->chip_func->render(context, task_dma); + + task_dma->desc.need_dma_fence = 1; + + gf_wmb(); + + status = vidschi_send_to_submit_queue(sch_mgr, task_dma); + + gf_end_section_trace_event(status); + + return status; +} + diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_render.h b/drivers/gpu/drm/arise/core/vidsch/vidsch_render.h new file mode 100644 index 0000000000000..3693e5d6721c1 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch_render.h @@ -0,0 +1,23 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __VIDSCH_RENDER_H__ +#define __VIDSCH_RENDER_H__ + + +#define TEST_HW_RESET 0 +#define TEST_HW_RESET_TIME_STEP 120*1000*1000 + + +#endif diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_submit.c b/drivers/gpu/drm/arise/core/vidsch/vidsch_submit.c new file mode 100644 index 0000000000000..273f0ce94b9df --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch_submit.c @@ -0,0 +1,954 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_render.h" +#include "vidmm.h" +#include "context.h" +#include "vidsch_submit.h" +#include "perfevent.h" + +static int vidschi_submit_dma(vidsch_mgr_t *sch_mgr, task_dma_t *task_dma) +{ + adapter_t *adapter = sch_mgr->adapter; + vidschedule_t *schedule = adapter->schedule; + gpu_context_t *context = task_dma->desc.context; + vidmm_allocation_t *mm_allocation = NULL; + vidsch_allocation_t *sch_allocation = NULL; + unsigned long long fence_id, last_send_fence_id; + int i, ret = S_OK; + + gf_down_read(schedule->rw_lock); + + gf_mutex_lock(sch_mgr->engine_lock); + + //gf_mutex_lock(adapter->hw_reset_lock); + + last_send_fence_id = sch_mgr->last_send_fence_id; + fence_id = vidschi_inc_send_fence_id(sch_mgr, task_dma->prepare_submit); + + task_dma->prepare_submit = FALSE; + + cm_device_lock(context->device); + + for (i = 0; i < task_dma->allocation_list_size; i++) + { + sch_allocation = &task_dma->sch_allocation_list[i]; + mm_allocation = sch_allocation->mm_allocation; + + if (mm_allocation) + { + gf_spin_lock(mm_allocation->lock); + + mm_allocation->fence_id[sch_mgr->engine_index] = fence_id; + + if(sch_allocation->write_operation) + { + mm_allocation->write_fence_id[sch_mgr->engine_index] = fence_id; + + mm_allocation->write_render_count[sch_mgr->engine_index]--; + } + + mm_allocation->render_count[sch_mgr->engine_index]--; + + mm_allocation->status.submit_ref_cnt--; + + gf_spin_unlock(mm_allocation->lock); + + sch_allocation->segment_id = mm_allocation->segment_id; + sch_allocation->phy_addr = mm_allocation->phys_addr; + + } + } + + cm_device_unlock(context->device); + + if (task_dma->patch_location_list_size > 0) + { + sch_mgr->chip_func->patch(adapter, task_dma); + } + + task_dma->desc.cmd_size = task_dma->submit_end_offset - task_dma->submit_start_offset; + task_dma->desc.fence_id = fence_id; + + if(sch_mgr->dma_reserved_memory->vma->need_flush_cache) + { + gf_flush_cache(adapter->os_device.pdev, sch_mgr->dma_reserved_memory->vma, sch_mgr->dma_reserved_memory->pages_mem, 0, task_dma->dma_buffer_node->size); + } + + /* call chip ddi submit dma buffer */ + /* after dma kick off, allocations ptr referenced in current dma + * may invalid, maybe freed by other thread. So do no access it. reason as follow: + * + * app-thread submit_thread + * create_allocation_A + * render to allocation_A + * --> submit this taskA to thread + * destroy allocation A submit_taskA + * --> add to defer destroy allocation -->update fence id, + * --> wait_allocation_idle to destroy -->update render_count--; + * on this point, allocation may idle when fence id back. + * -->killoff task. + * (after kick off fence will back anytime, + * if so allocation can be destroy by other thread, + * so after kickoff, allocatin ptr in task are invalid) + * + */ + + vidschi_update_and_release_dma_fence(adapter, &task_dma->desc); + + ret = sch_mgr->chip_func->submit(adapter, sch_mgr, task_dma); + + gf_task_submit_trace_event(adapter->index << 16 | sch_mgr->engine_index, context->handle, task_dma->desc.context_task_id, task_dma->desc.type, fence_id, task_dma->dma_type); + + //gf_mutex_unlock(adapter->hw_reset_lock); + gf_mutex_unlock(sch_mgr->engine_lock); + + gf_up_read(schedule->rw_lock); + + /* set dma node submitted*/ + vidschi_set_dma_task_submitted(sch_mgr, &task_dma->desc); + + return ret; +} + +void vidsch_submit_paging_task(adapter_t *adapter, task_paging_t *paging_task) +{ + vidschedule_t *schedule = adapter->schedule; + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[adapter->paging_engine_index]; + vidmm_allocation_t *allocation = NULL; + + int i; + + if(paging_task->command_length > 0) + { + task_dma_t task_dma = {0}; + unsigned long long fence_id; + + task_dma.dma_type = PAGING_DMA; + task_dma.need_hwctx_switch = FALSE; + task_dma.command_length = paging_task->command_length; + task_dma.dma_buffer_node = paging_task->dma; + task_dma.submit_start_offset = 0; + task_dma.submit_end_offset = paging_task->command_length; + + if(sch_mgr->dma_reserved_memory->vma->need_flush_cache) + { + gf_flush_cache(adapter->os_device.pdev, sch_mgr->dma_reserved_memory->vma, sch_mgr->dma_reserved_memory->pages_mem, 0, task_dma.dma_buffer_node->size); + } + + gf_down_read(schedule->rw_lock); + + /* lock engine */ + gf_mutex_lock(sch_mgr->engine_lock); + + fence_id = vidschi_inc_send_fence_id(sch_mgr, FALSE); + + paging_task->desc.fence_id = fence_id; + paging_task->desc.cmd_size = paging_task->command_length; + + task_dma.desc.fence_id = fence_id; + + /* udpate fence id must locked by engine_lock to make sure the fence id is increased */ + for(i = 0; i < paging_task->paging_allocation_num; i++) + { + allocation = paging_task->paging_allocation_list[i].allocation; + + cm_device_lock_allocation(allocation->device, allocation); + + allocation->fence_id[sch_mgr->engine_index] = fence_id; + + allocation->write_fence_id[sch_mgr->engine_index] = fence_id; + + allocation->last_paging = fence_id; + + allocation->render_count[sch_mgr->engine_index]--; + + allocation->write_render_count[sch_mgr->engine_index]--; + + cm_device_unlock_allocation(allocation->device, allocation); + } + + /* call chip submit dma buffer */ + sch_mgr->chip_func->submit(adapter, sch_mgr, &task_dma); + + gf_task_submit_trace_event(adapter->index << 16 | sch_mgr->engine_index, 0, ptr_to_ptr64(&paging_task->desc), task_type_paging, fence_id, PAGING_DMA); + + /* unlock engine */ + gf_mutex_unlock(sch_mgr->engine_lock); + + gf_up_read(schedule->rw_lock); + + /* set dma node submitted*/ + vidschi_set_dma_task_submitted(sch_mgr, &paging_task->desc); + } + else + { + /* cmd size == 0, mean paging task is for paging gart memory to system pages, + * since gart segment memory data already in system pages, so only update allocation info + */ + + for(i = 0; i < paging_task->paging_allocation_num; i++) + { + allocation = paging_task->paging_allocation_list[i].allocation; + + cm_device_lock_allocation(allocation->device, allocation); + + allocation->render_count[sch_mgr->engine_index]--; + + allocation->write_render_count[sch_mgr->engine_index]--; + + cm_device_unlock_allocation(allocation->device, allocation); + } + + gf_task_submit_trace_event(adapter->index << 16 | sch_mgr->engine_index, 0, ptr_to_ptr64(&paging_task->desc), task_type_paging, 0, PAGING_DMA); + + vidsch_notify_interrupt(adapter, 0); //render_count update, wait up waiter + + vidschi_set_dma_task_fake_submitted(sch_mgr, &paging_task->desc); + } + +} + +#define VIDSCH_MAX_PAGING_IN_DMA_SIZE 16*1024 + +static int vidschi_resident_task_allocations(vidsch_mgr_t *sch_mgr, task_dma_t *task_dma) +{ + adapter_t *adapter = sch_mgr->adapter; + gpu_context_t *context = task_dma->desc.context; + vidmm_allocation_t *allocation = NULL; + unsigned long long last_paging = 0x0ll; + + int i, unresident_num = 0, result = S_OK; + + cm_device_lock(context->device); + + /* first loop to check if task need do paging and estimate the paging allocation num, + * NOTE: the num is not real num, since this loop not use paging lock, the real num may lower than this value. + * WHY not lock this loop? for none-paging task need not wait pervious paging finish, better for performance + */ + for(i = 0; i < task_dma->allocation_list_size; i++) + { + allocation = task_dma->sch_allocation_list[i].mm_allocation; + + if(allocation != NULL) + { + gf_spin_lock(allocation->lock); + + /* mark allocation temp unpagable since allocation referenced by submit */ + allocation->status.submit_ref_cnt++; + + /* if allocation not resident need do paging in */ + if(allocation->segment_id == SEGMENT_ID_INVALID) + { + unresident_num++; + } + + if(allocation->last_paging > last_paging) + { + last_paging = allocation->last_paging; + } + + gf_spin_unlock(allocation->lock); + } + } + + cm_device_unlock(context->device); + + /* if need paging, then enter paging path, paging will re-loop the allocation list, to calc the real paging allocation num */ + if(unresident_num > 0) + { + task_paging_t *paging_task = vidsch_allocate_paging_task(adapter, VIDSCH_MAX_PAGING_IN_DMA_SIZE, unresident_num); + vidmm_paging_allocation_t *paging_allocation = NULL; + int real_unresident_num = 0; + + paging_task->must_success = TRUE; + + gf_mutex_lock(adapter->paging_lock); + + for(i = 0; i < task_dma->allocation_list_size; i++) + { + allocation = task_dma->sch_allocation_list[i].mm_allocation; + + /* since allocation segment memory only can be changed by paging, we already in paging, + * this value never changed, no need lock + */ + + /* TODO: we can make resident lru list here if needed */ + if((allocation != NULL) && + (allocation->segment_id == SEGMENT_ID_INVALID) ) + { + /* + WHY: do not redundancy add same allocation into the paging_allocation_list, + since after allocation paging in success and before this paging_task submit, allocation's segment id is alway SEGMENT_ID_INVALID, + if re-call vidmm_resident_one_allocation for same allocation will cause paging assert(no pags_mem ,file_store and segment id is SEGMENT_ID_INVALID). + */ + int j=0, found=0; + + for(j = 0; j < real_unresident_num; j++) + { + if(paging_task->paging_allocation_list[j].allocation == allocation) + { + found = 1; + break; + } + } + + if(!found) + paging_task->paging_allocation_list[real_unresident_num++].allocation = allocation; + } + } + + for(i = 0; i < real_unresident_num; i++) + { + paging_allocation = &paging_task->paging_allocation_list[i]; + try_again: + result = vidmm_resident_one_allocation(context->device, paging_task, paging_allocation, 0); + + if(result == S_OK) + { + /* successfully resident one allocation, try next */ + continue; + } + else if(result == E_FAIL) + { + /* for force local allocation, the resident fail will probably make the dma submit failed, + * patch the backup segment id to this allocation's preferred segment, make the resident success. + */ + allocation = paging_allocation->allocation; + if((allocation->backup_segment_id != 0)&&(allocation->preferred_segment.segment_id_1 == 0)) + { + allocation->preferred_segment.segment_id_1 = allocation->backup_segment_id; + gf_info("resident allocation[0x%d-%dK] failed by not enough local memory, add segment %d to preferred and try again.\n", + allocation->handle, allocation->orig_size/1024, allocation->backup_segment_id); + goto try_again; + } + + /* no enought video memory, resident failed. return fail to caller, + * caller can go split or wait a while and try again + */ + break; + } + else if(result == E_OUTOFMEMORY) + { + /* system pages exhausted when paging out, can not do anything return error */ + break; + } + else if(result == E_INSUFFICIENT_DMA_BUFFER) + { + /* dma_buffer not enough, will submit success resident allocations, and also return fail + * to caller to notify not all unresident allocations resident, caller can try resident again + */ + gf_info("Resident task: %lld[context: %x] failed, since dma buffer not enough.\n", + task_dma->desc.context_task_id, context->handle); + + gf_info(" Task Total allocations: %d, need resident: %d, success resident: %d\n", + task_dma->allocation_list_size, real_unresident_num, i); + break; + } + } + + gf_info("resident %d/%d allocation, cmd_length:%d/%d...\n", + i, real_unresident_num, paging_task->command_length, paging_task->dma->size); + + paging_task->paging_allocation_num = i; /* udpate num to real success num */ + + vidsch_task_inc_reference(adapter, adapter->paging_engine_index, &paging_task->desc); + + /* no matter submit success or fail submit paging task, since submit also release paging dma resource */ + vidsch_submit_paging_task(adapter, paging_task); + + /* mark success allocation resident and add it to resident list */ + for(i = 0; i < paging_task->paging_allocation_num; i++) + { + paging_allocation = &paging_task->paging_allocation_list[i]; + allocation = paging_allocation->allocation; + + cm_device_lock_allocation(context->device, allocation); + + allocation->segment_id = paging_allocation->segment_id; + allocation->list_node = paging_allocation->list_node; + allocation->size = paging_allocation->size; + allocation->phys_addr = paging_allocation->gpu_virt_addr; + + cm_device_unlock_allocation(context->device, allocation); + + vidmm_add_allocation_to_resident_list(adapter, allocation); + } + + if(result != S_OK) + { + cm_device_lock(context->device); + + for(i = 0; i < task_dma->allocation_list_size; i++) + { + allocation = task_dma->sch_allocation_list[i].mm_allocation; + + if(allocation != NULL) + { + /* resident failed, dma can not submit, so clear the reference */ + gf_spin_lock(allocation->lock); + + allocation->status.submit_ref_cnt--; + + gf_spin_unlock(allocation->lock); + } + } + + cm_device_unlock(context->device); + } + + if(paging_task->command_length > 0) + { + last_paging = paging_task->desc.fence_id; + } + + vidsch_task_dec_reference(adapter, adapter->paging_engine_index, &paging_task->desc); + + gf_mutex_unlock(adapter->paging_lock); + } + + task_dma->prepare_succeeded = (result == S_OK); + + /* multi-engine sync: wait paging back, if task referenced allocation paging before by other engine need wait it back*/ + if(context->engine_index != adapter->paging_engine_index) + { + vidsch_wait_fence_back(adapter, adapter->paging_engine_index, last_paging); + } + + return result; + +} + +/* prepare dma, paging in task_dma allocations and patch the cmd buffer + * return: S_OK + * E_FAIL mean video memory not enough, caller can go split or wait a while and try again. + * E_OUTOFMEMORY mean fatal error, system pages not enough. this lead render fail + */ + +#define VISCH_MAX_PREPARE_TRY_TIMES 1000 + +static int vidschi_prepare_task_dma(vidsch_mgr_t *sch_mgr, task_dma_t *task_dma, int must_success) +{ + int try_times = VISCH_MAX_PREPARE_TRY_TIMES, result; + +try_again: + + result = vidschi_resident_task_allocations(sch_mgr, task_dma); + + if(result == S_OK) + { + return result; + } + else if(result == E_FAIL) + { + if(must_success && (try_times > 0)) + { + gf_msleep(5); + + try_times--; + + goto try_again; + } + else + { + return result; + } + } + else if(result == E_INSUFFICIENT_DMA_BUFFER) + { + if(try_times > 0) + { + try_times--; + + gf_info("Engine[%d] Resident task: %lld %4dth try failed, since dma buffer not enough. try again\n", + sch_mgr->engine_index, task_dma->desc.context_task_id, VISCH_MAX_PREPARE_TRY_TIMES - try_times); + + goto try_again; + } + else + { + gf_info("resident task failed, since dma buffer not enough. \n"); + + return E_FAIL; //notify fail mean GPU resource not enough, like video memory. + } + } + else if(result == E_OUTOFMEMORY) + { + return result; + } + + return result; +} + +/* fake submit: use to update allocation/device info when submit failed or split */ +void vidschi_fake_submit_dma(vidsch_mgr_t *sch_mgr, task_dma_t *task_dma, int discard) +{ + adapter_t *adapter = sch_mgr->adapter; + gpu_context_t *context = task_dma->desc.context; + vidmm_allocation_t *allocation = NULL; + + int i; + + cm_device_lock(context->device); + + for (i = 0; i < task_dma->allocation_list_size; i++) + { + allocation = task_dma->sch_allocation_list[i].mm_allocation; + + if (allocation != NULL) + { + gf_spin_lock(allocation->lock); + + allocation->render_count[sch_mgr->engine_index]--; + + if(task_dma->sch_allocation_list[i].write_operation) + { + allocation->write_render_count[sch_mgr->engine_index]--; + } + + if(task_dma->prepare_succeeded) + { + allocation->status.submit_ref_cnt--; + } + + gf_spin_unlock(allocation->lock); + } + } + + cm_device_unlock(context->device); + + if(task_dma->prepare_submit) + { + unsigned long flags; + + flags = gf_spin_lock_irqsave(sch_mgr->fence_lock); + + sch_mgr->prepare_task_num--; + + gf_spin_unlock_irqrestore(sch_mgr->fence_lock, flags); + + task_dma->prepare_submit = FALSE; + } + + task_dma->desc.fence_id = 0; + + gf_task_submit_trace_event(adapter->index << 16 | sch_mgr->engine_index, context->handle, task_dma->desc.context_task_id, task_dma->desc.type, 0, task_dma->dma_type); + + vidschi_update_and_release_dma_fence(adapter, &task_dma->desc); + + vidschi_set_dma_task_fake_submitted(sch_mgr, &task_dma->desc); + + vidsch_notify_interrupt(adapter, 0); +} + +#ifdef GF_HW_NULL +static void vidschi_fake_submit_dma_with_fence(vidsch_mgr_t *sch_mgr, task_dma_t *dma_task) +{ + unsigned long long completed_fence_id = dma_task->desc.fence_id; + + gf_debug("fake submit dma task with fence_id: %lld\n", completed_fence_id); + if(sch_mgr->chip_func->set_fence_id) + { + sch_mgr->chip_func->set_fence_id(sch_mgr, completed_fence_id); + } + vidschi_fake_submit_dma(sch_mgr, dma_task, FALSE); +} +#endif + +static task_dma_t *vidsch_allocate_split_dma(adapter_t *adapter, unsigned int engine_index, task_dma_t *task_dma) +{ + task_dma_t *split_dma = NULL; + char* memory = NULL; + unsigned int offset = 0; + unsigned int allocations_size = 0;//task_dma->allocation_list_size * sizeof(vidsch_allocation_t); + unsigned int patchs_size = 0;//task_dma->patch_location_list_size * sizeof(gf_patchlocation_list_t); + unsigned int syncs_size = 0;//task_dma->sync_object_list_size * sizeof(vidsch_sync_object_reference_t); + vidsch_mgr_t *vidsch = adapter->sch_mgr[engine_index]; + gpu_context_t *context = task_dma->desc.context; + + unsigned int total_size = util_align(sizeof(task_dma_t), 16) + + util_align(allocations_size, 16) + + util_align(patchs_size, 16) + + util_align(syncs_size, 16); + + memory = gf_calloc(total_size); + if(memory == NULL) + { + gf_error("func vidsch_allocate_split_dma allocated memory failed, size:%x.\n", total_size); + } + + split_dma = (task_dma_t *)(memory + offset); + offset += util_align(sizeof(task_dma_t), 16); + + gf_memcpy(split_dma,task_dma,sizeof(task_dma_t)); + + //dma fence can not release multiple times, and task_dma will submit after all split dma submited(whatever success or not) + //just keep task_dma own dma fence can handle all the case + split_dma->desc.dma_fence = NULL; + + gf_atomic_inc(context->ref_cnt); //to avoid del context, although it would not happened. + + split_dma->desc.list_item.prev = &(split_dma->desc.list_item);//not disturb task_dma's order + split_dma->desc.list_item.next = &(split_dma->desc.list_item); +// split_dma->dump = 1; + + if(0 && task_dma->allocation_list_size) + { + split_dma->sch_allocation_list = (vidsch_allocation_t *)(memory + offset); + split_dma->allocation_list_size = task_dma->allocation_list_size; + offset += util_align(allocations_size, 16); + } + + if(0 && task_dma->patch_location_list_size) + { + split_dma->patch_location_list = (gf_patchlocation_list_t *)(memory + offset); + split_dma->patch_location_list_size = task_dma->patch_location_list_size; + split_dma->patch_start_offset = 0; + split_dma->patch_end_offset = task_dma->patch_end_offset; + offset += util_align(patchs_size, 16); + } + + if(0 && task_dma->sync_object_list_size) + { + split_dma->sync_object_list = (vidsch_sync_object_reference_t *)(memory + offset); + split_dma->sync_object_list_size = task_dma->sync_object_list_size; + + offset += util_align(syncs_size, 16); + } + + gf_assert(offset == total_size, "offset == total_size"); + + split_dma->dma_buffer_node = vidschi_allocate_dma_node(vidsch, task_dma->command_length); + gf_memcpy(split_dma->dma_buffer_node->virt_base_addr,task_dma->dma_buffer_node->virt_base_addr,task_dma->command_length); +// gf_memcpy(split_dma->patch_location_list,task_dma->patch_location_list,patchs_size); + + return split_dma; + +} + +static int vidschi_split_dma(vidsch_mgr_t *sch_mgr, task_dma_t *task_dma) +{ + adapter_t *adapter = sch_mgr->adapter; + gpu_context_t *context = task_dma->desc.context; + unsigned int dma_start = task_dma->submit_start_offset; + unsigned int dma_end = task_dma->submit_end_offset; + unsigned int patch_start = task_dma->patch_start_offset; + unsigned int patch_end = task_dma->patch_end_offset; + gf_patchlocation_list_t *patch_location_list = NULL, *temp_patch = NULL; + vidsch_allocation_t *sch_allocation_list = NULL; + vidmm_allocation_t *allocation = NULL; + task_dma_t *split_dma; + int can_split = FALSE; + unsigned int i = 0, j = 0, k = 0, ret = S_OK; + unsigned int *patch_per_slot = NULL, *cur_patch_per_slot = NULL; + int engine_index = sch_mgr->engine_index; + int end = dma_start; + + vidsch_trace("vidsch: enter vidschi_split_dma. \n"); + /* check split point, if no, return fail */ + for (i = patch_start; i < patch_end; i++) + { + patch_location_list = task_dma->patch_location_list + i; + if (patch_location_list->SplitOffset > dma_start && + patch_location_list->SplitOffset < dma_end) + { + can_split = TRUE; + break; + } + } + + if (!can_split || !adapter->ctl_flags.split_enable) + { + return E_INVALIDARG; + } + + patch_per_slot = gf_calloc((sch_mgr->slot_count+1) * sizeof(unsigned int) * 2); + + gf_memset(patch_per_slot, -1, (sch_mgr->slot_count+1) * sizeof(unsigned int) * 2); + + cur_patch_per_slot = patch_per_slot + sch_mgr->slot_count + 1; + + sch_allocation_list = gf_calloc(task_dma->allocation_list_size * sizeof(vidsch_allocation_t)); + + // split_dma.sch_allocation_list = sch_allocation_list; + + do{ + vidmm_trace("vidsch: vidschi_split: split dma from %d. \n", patch_start); + + split_dma = vidsch_allocate_split_dma(adapter, engine_index, task_dma); + split_dma->desc.task_render = split_dma; + split_dma->sch_allocation_list = sch_allocation_list; + + vidsch_task_inc_reference(adapter, engine_index,&(split_dma->desc)); + + gf_memset(sch_allocation_list, 0, sizeof(vidsch_allocation_t) * task_dma->allocation_list_size); + gf_memset(cur_patch_per_slot, -1, (sch_mgr->slot_count+1) * sizeof(unsigned int)); + + /* loop find split point from start, split dma buffer */ + for (i = patch_start; i < patch_end+1; i++) + { + patch_location_list = task_dma->patch_location_list + i; + + if ((i == patch_end) || patch_location_list->SplitOffset > dma_start) + { + for(j = 1; j <= sch_mgr->slot_count; j++) + { + if((-1 != patch_per_slot[j]) || (-1 != cur_patch_per_slot[j])) + { + k = (patch_per_slot[j] != -1) ? patch_per_slot[j] : cur_patch_per_slot[j]; + temp_patch = task_dma->patch_location_list + k; + sch_allocation_list[temp_patch->AllocationIndex].mm_allocation = + task_dma->sch_allocation_list[temp_patch->AllocationIndex].mm_allocation; + sch_allocation_list[temp_patch->AllocationIndex].write_operation = + task_dma->sch_allocation_list[temp_patch->AllocationIndex].write_operation; + } + } + + split_dma->submit_start_offset = dma_start; + split_dma->patch_start_offset = patch_start; + split_dma->patch_end_offset = i; + if(i < patch_end) + { + split_dma->submit_end_offset = + end = patch_location_list->SplitOffset; + patch_start = i; + dma_start = patch_location_list->SplitOffset; + } + else + { + /* last split dma */ + split_dma->submit_end_offset = + end = dma_end; + } + + break; + } + else + { + gf_assert(patch_location_list->SplitOffset == dma_start, "patch_location_list->SplitOffset == dma_start"); + gf_assert(patch_location_list->SlotId > 0, "patch_location_list->SlotId > 0"); + gf_assert(patch_location_list->SlotId <= sch_mgr->slot_count, "patch_location_list->SlotId <= sch_mgr->slot_count"); + + if(patch_location_list->AllocationIndex) + { + patch_per_slot[patch_location_list->SlotId] = i; + cur_patch_per_slot[patch_location_list->SlotId] = i; + } + else + { + /* Free Slot case */ + patch_per_slot[patch_location_list->SlotId] = -1; + } + } + } + + /* new task generated, mark render_cnt++*/ + cm_device_lock(context->device); + + for(i = 0; i allocation_list_size; i++) + { + allocation = split_dma->sch_allocation_list[i].mm_allocation; + + if(allocation != NULL) + { + gf_spin_lock(allocation->lock); + + allocation->render_count[sch_mgr->engine_index]++; + + if(split_dma->sch_allocation_list[i].write_operation) + { + allocation->write_render_count[sch_mgr->engine_index]++; + } + + gf_spin_unlock(allocation->lock); + } + } + + cm_device_unlock(context->device); + + { + int can_prepare = FALSE; + + + for(i = 0; i < 2000; i++) + { + can_prepare = vidschi_can_prepare_task_dma(sch_mgr, split_dma); + + if(can_prepare) break; + + gf_msleep(1); + } + + if(can_prepare) + { + ret = vidschi_prepare_task_dma(sch_mgr, split_dma, TRUE); + + if(ret == S_OK) + { + vidschi_submit_dma(sch_mgr, split_dma); + } + else + { + int i; + /* since split dma is part of task_dma, not discard */ + vidschi_fake_submit_dma(sch_mgr, split_dma, FALSE); + gf_error("vidschi_split_dma: prepare_task_dma failed. %d \n", ret); + + gf_info("vidschi_split_dma: split_dma info: device: %s, type: %d, size: %d.\n", split_dma->desc.context->device->pname, split_dma->dma_type, split_dma->desc.cmd_size); + gf_info("vidschi_split_dma: split dma allocation info:\n"); + for(i = 0; i < split_dma->allocation_list_size; i++) + { + allocation = split_dma->sch_allocation_list[i].mm_allocation; + if (allocation) + { + gf_info("allo: %x, refcount:%d, dev: %x, fmt: %3d-%2d-%d-%2d, W-H-P: %8d-%4d-%8d, size: %6dk, gvm: %08x, AT:0x%02x, status: %8x.\n", + allocation->handle, allocation->ref_count, allocation->device->handle, + allocation->hw_format, allocation->compress_format, allocation->flag.swizzled, allocation->bit_count, + allocation->width, allocation->height, allocation->pitch, + util_align(allocation->orig_size, util_max(allocation->alignment, adapter->os_page_size)) >> 10, + allocation->phys_addr, allocation->at_type, allocation->status.temp_unpagable); + } + } + + vidmm_dump_resource(adapter); + cm_dump_resource(adapter); + break; + } + } + else + { + /* can not prepare since hw queue issue */ + vidschi_fake_submit_dma(sch_mgr, split_dma, FALSE); + + gf_error("vidschi_split_dma: can_prepare_task_dma failed. can not be here.\n"); + + break; + } + } + + vidsch_wait_fence_back(adapter, engine_index, split_dma->desc.fence_id); + vidsch_task_dec_reference(adapter, engine_index,&(split_dma->desc)); + + } while (end != task_dma->submit_end_offset); + + if(patch_per_slot) + { + gf_free(patch_per_slot); + } + + if(sch_allocation_list) + { + gf_free(sch_allocation_list); + } + + vidsch_trace("vidsch: leave vidschi_split_dma. \n"); + + return ret; +} + + +int vidschi_prepare_and_submit_dma(vidsch_mgr_t *sch_mgr, task_dma_t *task_dma) +{ + hw_ctxbuf_t *hw_ctx = task_dma->hw_ctx_info; + int result = S_OK; + int discard = FALSE; + + gf_begin_section_trace_event("vidschi_prepare_and_submit_dma"); + + if(hw_ctx && hw_ctx->is_invalid) + { + vidschi_fake_submit_dma(sch_mgr, task_dma, TRUE); + + gf_end_section_trace_event(E_FAIL); + return E_FAIL; + } + + result = vidschi_prepare_task_dma(sch_mgr, task_dma, sch_mgr->adapter->ctl_flags.split_enable); + + if(result == S_OK) + { + vidschi_submit_dma(sch_mgr, task_dma); + } + else if(result == E_FAIL) + { + /* if prepare failed by video memory not enough, do split */ + result = vidschi_split_dma(sch_mgr, task_dma); + + /* if task can not do split, go general way */ + if(result == E_INVALIDARG) + { + result = vidschi_prepare_task_dma(sch_mgr, task_dma, TRUE); + + if(result == S_OK) + { + vidschi_submit_dma(sch_mgr, task_dma); + } + else + { + /* prepare failed discard this task */ + discard = TRUE; + } + } + else if(result == S_OK) + { + /* if split happen and success, since split task dma to multi new task and submitted, + * So here only fake submit to update the allocation info + */ + vidschi_fake_submit_dma(sch_mgr, task_dma, FALSE); + } + else + { + /* split may failed partially, so here wait subimtted part back. seems no need wait, + * but still add here to make sure there is no issue + */ + vidsch_wait_fence_back(sch_mgr->adapter, sch_mgr->engine_index, task_dma->desc.fence_id); + + discard = TRUE; + } + } + else + { + /* if prepare task failed by pages not enough, discard the task */ + discard = TRUE; + } + + if(discard) + { + /* submit fail, mark hw_ctx invalid and discard this task_dma */ + gpu_context_t *context = task_dma->desc.context; + + gf_info("submit failed, set hwctx invalid.\n"); + + context->device->task_dropped = TRUE; + + if(hw_ctx) + { + hw_ctx->is_invalid = TRUE; + } + + vidschi_fake_submit_dma(sch_mgr, task_dma, TRUE); + } + +#ifdef GF_HW_NULL + vidschi_fake_submit_dma_with_fence(sch_mgr, task_dma); +#endif + + gf_end_section_trace_event(result); + return result; +} + + diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_submit.h b/drivers/gpu/drm/arise/core/vidsch/vidsch_submit.h new file mode 100644 index 0000000000000..d5327aaf70d2c --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch_submit.h @@ -0,0 +1,29 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __VIDSCH_SUBMIT_H__ +#define __VIDSCH_SUBMIT_H__ + +extern int vidschi_prepare_and_submit_dma(vidsch_mgr_t *sch_mgr, task_dma_t *task_dma); +extern void vidschi_fake_submit_dma(vidsch_mgr_t *sch_mgr, task_dma_t *task_dma, int discard); + +extern void vidschi_release_allocated_tasks(vidsch_mgr_t *sch_mgr); +extern task_desc_t *vidschi_uncompleted_task_exceed_wait_time(vidsch_mgr_t *sch_mgr, unsigned long long max_wait_time); + +extern void vidschi_set_dma_task_submitted(vidsch_mgr_t *sch_mgr, task_desc_t *task); +extern void vidschi_set_dma_task_fake_submitted(vidsch_mgr_t *sch_mgr, task_desc_t *task); +extern void vidschi_set_uncompleted_task_dropped(vidsch_mgr_t *sch_mgr, unsigned long long dropped_task); + +#endif + diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_sync.c b/drivers/gpu/drm/arise/core/vidsch/vidsch_sync.c new file mode 100644 index 0000000000000..490fa5aa6690c --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch_sync.c @@ -0,0 +1,1118 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_sync.h" +#include "vidsch_workerthread.h" +#include "handle_manager.h" +#include "perfevent.h" + + +//NOTE: this function can't be sleep as be called in spinlocked +static int vidschi_do_destroy_sync_object(adapter_t *adapter, vidsch_sync_object_t *sync_obj) +{ + switch (sync_obj->type) + { + case GF_SYNC_OBJ_TYPE_MUTEX: + + gf_destroy_mutex(sync_obj->mutex.mlock); + + break; + + case GF_SYNC_OBJ_TYPE_SEMPAPHORE: + + gf_destroy_sema(sync_obj->sema.slock); + + break; + + case GF_SYNC_OBJ_TYPE_FENCE: + + vidsch_release_fence_space(adapter, adapter->fence_buf, sync_obj->fence.gpu_addr); + + break; + + case GF_SYNC_OBJ_TYPE_DMAFENCE: + + adapter->drm_cb->fence.dma_sync_object_release(sync_obj->dma.dma_sync_obj); + + break; + + case GF_SYNC_OBJ_TYPE_CPU_NOTIFICATION: + + break; + + default: + + break; + } + + if(sync_obj->lock) + { + gf_destroy_spinlock(sync_obj->lock); + } + + if(sync_obj->ref_cnt) + { + gf_destroy_atomic(sync_obj->ref_cnt); + } + + if(sync_obj->handle != 0) + { + remove_handle(&adapter->hdl_mgr, sync_obj->handle); + } + + gf_free(sync_obj); + + return S_OK; +} + +void vidschi_add_sync_to_defer_destroy(adapter_t *adapter, vidsch_sync_object_t *sync_obj) +{ + gf_spin_lock(adapter->lock); + + list_add_tail(&sync_obj->list_node, &adapter->sync_obj_list); + + gf_spin_unlock(adapter->lock); +} + +void vidschi_destroy_defer_sync_obj(adapter_t *adapter) +{ + vidsch_sync_object_t *sync_obj = NULL; + vidsch_sync_object_t *sync_obj_next = NULL; + + gf_spin_lock(adapter->lock); + + list_for_each_entry_safe(sync_obj, sync_obj_next, &adapter->sync_obj_list, list_node) + { + if(!vidschi_sync_obj_referenced(sync_obj)) + { + list_del(&sync_obj->list_node); + + vidschi_do_destroy_sync_object(adapter, sync_obj); + } + } + + gf_spin_unlock(adapter->lock); +} + + +int vidsch_create_sync_object(gpu_device_t *gpu_device, gf_create_fence_sync_object_t *create, int binding) +{ + vidsch_sync_object_t *sync_obj = NULL; + int status = S_OK; + + vidschi_destroy_defer_sync_obj(gpu_device->adapter); + + if(!binding) + { + //add sync object size limit per device + if(gf_atomic_read(gpu_device->sync_obj_count) > MAX_SYNC_OBJECT_SIZE_PER_DEVICE) + { + gf_error("allocate sync obj failed for exceeding the limit\n"); + return E_FAIL; + } + else + { + gf_atomic_inc(gpu_device->sync_obj_count); + } + } + + sync_obj = gf_calloc(sizeof(vidsch_sync_object_t)); + + if(sync_obj == NULL) + { + gf_error("allocate sync obj failed. pls check if leak happen.\n"); + return E_FAIL; + } + + list_init_head(&sync_obj->instance_list); + + switch (create->type) + { + case GF_SYNC_OBJ_TYPE_MUTEX: + + sync_obj->mutex.mlock = gf_create_mutex(); + sync_obj->mutex.initial_state = create->mutex.init_state; + + if(create->mutex.init_state) + { + gf_mutex_lock(sync_obj->mutex.mlock); + } + + break; + + case GF_SYNC_OBJ_TYPE_SEMPAPHORE: + + sync_obj->sema.slock = gf_create_sema(create->semaphore.max_count); + sync_obj->sema.initial_cnt = create->semaphore.init_count; + + break; + + case GF_SYNC_OBJ_TYPE_FENCE: + + status = vidsch_request_fence_space(gpu_device->adapter, gpu_device->adapter->fence_buf, &sync_obj->fence.virt_addr, &sync_obj->fence.gpu_addr); + + if(status == S_OK) + { + create->fence.fence_addr = sync_obj->fence.gpu_addr; + + *sync_obj->fence.virt_addr = create->fence.init_value; + } + else + { + gf_error("allocate fence space failed. pls check if leak happen.\n"); + goto exit; + } + + break; + + case GF_SYNC_OBJ_TYPE_CPU_NOTIFICATION: + gf_error("currently not support cpu notification SyncObject.\n"); + status = E_FAIL; + goto exit; + + default: + gf_error("vidsch_create_sync_object: invalid type.\n "); + status = E_FAIL; + goto exit; + } + + create->fence_sync_object = + sync_obj->handle = add_handle(&gpu_device->adapter->hdl_mgr, HDL_TYPE_SYNC_OBJ, sync_obj); + sync_obj->device = gpu_device; + sync_obj->type = create->type; + sync_obj->binding = binding; + sync_obj->lock = gf_create_spinlock(0); + sync_obj->ref_cnt = gf_create_atomic(0); + + if(!sync_obj->binding) + { + cm_device_lock(gpu_device); + + list_add(&sync_obj->list_node, &gpu_device->sync_obj_list); + + cm_device_unlock(gpu_device); + } + +exit: + + if(status != S_OK) + { + vidschi_do_destroy_sync_object(gpu_device->adapter, sync_obj); + } + + return status; +} + +int vidsch_destroy_sync_object(adapter_t *adapter, gpu_device_t *gpu_device, unsigned int hSync) +{ + vidsch_sync_object_t *sync_obj = get_from_handle(&adapter->hdl_mgr, hSync); + + if(sync_obj == NULL) + { + gf_error("destroy invalid sync obj: %d.\n", hSync); + return S_OK; + } + + if(!sync_obj->binding) + { + gf_assert(gpu_device != NULL, "gpu_device != NULL"); + + cm_device_lock(gpu_device); + + list_del(&sync_obj->list_node); + + gf_atomic_dec(gpu_device->sync_obj_count); + + cm_device_unlock(gpu_device); + } + + sync_trace("destroy sync obj: %x.\n", hSync); + + if(vidschi_sync_obj_referenced(sync_obj)) + { + vidschi_add_sync_to_defer_destroy(adapter, sync_obj); + } + else + { + vidschi_do_destroy_sync_object(adapter, sync_obj); + } + + return S_OK; +} + +int vidsch_destroy_remained_sync_obj(gpu_device_t *gpu_device) +{ + vidsch_sync_object_t *sync_obj = NULL, *sync_obj_next; + + list_for_each_entry_safe(sync_obj, sync_obj_next, &gpu_device->sync_obj_list, list_node) + { + vidsch_destroy_sync_object(gpu_device->adapter, gpu_device, sync_obj->handle); + } + + vidschi_destroy_defer_sync_obj(gpu_device->adapter); + + return S_OK; +} + +static int vidschi_is_fence_sync_object_signaled(vidsch_wait_fence_signaled_arg_t *argu) +{ + task_wait_t *task = argu->task; + vidsch_wait_instance_t *wait = argu->wait; + vidsch_fence_sync_object_t *fence_sync = &wait->sync_obj->fence; + + /* if device have dropped task before, since fence signal cmd also put in gerneal dma task, + * so dropped task may lead this wait never back, so force set it back if device dropped task. + */ + if(wait->sync_obj->device->task_dropped) + { + *(volatile unsigned long long *)fence_sync->virt_addr = wait->fence_id; + } + + /* only consider fence back and all previous task submit to sw queue as signaled */ + /* and fence sync have no explicit signal func called by user like mutex, semaphore + * so consider fence object signaled when first fence back meet. + */ + + if((!wait->signaled) && + (*(volatile unsigned long long *)fence_sync->virt_addr >= wait->fence_id) && + (task->only_check_status || vidschi_can_submit_task(&task->desc))) + { + wait->signaled = TRUE; + } + + return wait->signaled; +} + +/* Server wait must timeout one by one, since when server wait pending queue may pending many wait_instanced based on sync_obj_X. + * like wait_X_A, wait_X_B, wait_X_C. which in multi-engine pending queue like engine_A, engine_B, engine_C, since A,B,C in seperated thread. + * we better timeout it by app wait order. + */ +static int vidschi_is_server_wait_instance_timeout(task_wait_t *task, vidsch_wait_instance_t *wait, unsigned long long curr_time) +{ + vidsch_sync_object_t *sync_obj = wait->sync_obj; + gpu_context_t *context = task->desc.context; + adapter_t *adapter = context->device->adapter; + + unsigned long long task_id = task->desc.context_task_id; + long long used_time = 0; + int timeout = FALSE; + unsigned long long waittime = adapter->sync_max_server_wait_time_ns; + + gf_spin_lock(sync_obj->lock); + + /* check if instance is first place in instance list. we check timeout in instance list in order. only first can timeout */ + if(wait == list_entry(sync_obj->instance_list.next, vidsch_wait_instance_t, list_node)) + { + unsigned long long delta_time = 0; + + if((task_id <= context->wait_delta_check_end) && + (task_id > context->wait_delta_check_start)) + { + { + /* for general just increase 0.5s, previous is a timeout, which may stop a signal cmd to submit, + * So here if previous have timeout, the followed wait more time. + * NOTE: this value is Optional + * NOTE: big value here may lead timeout use more time. another word screen may stop more time. + */ + delta_time = 500000000; //0.5s + } + + //gf_info("increase delta time: context: %x. engine: %d. sync_obj: %x, delta: %d.\n", + // context->handle, context->engine_index, sync_obj->handle, (int)(task_id - context->wait_delta_check_start)); + } + + delta_time += wait->delta_time; + used_time = curr_time - task->desc.timestamp; + + if(used_time >= (waittime + delta_time)) + { + timeout = TRUE; + } + } + + /* if timeout happen, increase the follow instance delta_time, to let it wait more times, + * only timeout the real timeout instance + */ + if(timeout) + { + vidsch_wait_instance_t *instance = NULL; + vidsch_wait_instance_t *instance_next; + + list_for_each_entry_safe(instance, instance_next, &sync_obj->instance_list, list_node) + { + instance->delta_time += gf_do_div(waittime, 2); + } + + /* if one wait timeout, we need care follow wait. only set follow 100 here, this will enough */ + context->wait_delta_check_start = task_id; + context->wait_delta_check_end = context->task_id + 100; + } + + gf_spin_unlock(sync_obj->lock); + + return timeout; +} + +int vidschi_is_server_wait_timeout(task_wait_t *task, unsigned long long curr_time) +{ + vidsch_wait_instance_t *instance = NULL; + gpu_context_t *context = task->desc.context; + adapter_t *adapter = context->device->adapter; + + int i = 0, task_timeout = FALSE, instance_timeout = FALSE; + long long used_time = curr_time - task->desc.timestamp; + + /* first precheck if task exist exceed timeout */ + if(used_time < adapter->sync_max_server_wait_time_ns) + { + return FALSE; + } + + /* if task exceed timeout value, rechck if instance real timeout + * if any instance timeout then treat task is timeout. because we only timeout first instance in sync_obj, + * and we support multi-instance in one task, if all instance timeout may lead never timeout. + */ + for(i = 0; i < task->instance_cnt; i++) + { + instance = &task->instances[i]; + + if(instance->sync_obj == NULL) continue; + + instance_timeout = vidschi_is_server_wait_instance_timeout(task, &task->instances[i], curr_time); + + if(instance_timeout) + { + gf_info("Instance: %p task_id: %lld context: %x, engine:%d, timeout. start time: %lld, curr_time:%lld. instance_delta: %lld\n", + instance, task->desc.context_task_id, task->desc.context->handle, task->desc.context->engine_index, + task->desc.timestamp, curr_time, instance->delta_time); + + task_timeout = TRUE; + break; + } + } + + /* if task is timeout, del the instance reference the sync_obj + */ + if(task_timeout) + { + gf_info("Server Wait Timeout.\n"); + + vidschi_dump_wait_task(NULL, task, 0, FALSE); + + for(i = 0; i < task->instance_cnt; i++) + { + instance = &task->instances[i]; + + if(instance->sync_obj != NULL) + { + vidschi_sync_obj_del_reference(instance->sync_obj, instance); + + instance->sync_obj = NULL; + } + } + } + + return task_timeout; +} + + +/* check if sync objected signaled */ +/* client_wait means if this function called from client side, this for client/server mixed wait case, and mult-context. + * above case only client side can not insure the task submit order. So if this wait_task if client wait, + * we must wait utill ref_cnt == 0, all previous wait on this sync_obj all finished, if server wait we submit wait_task + * to pending queue to let worker thread do it. + * + * for fence obj: there is no multi-context issue, but we must insurance multi-wait in one context submit in order, no matter + * it signaled or not, So for this add a per context task id, if still some task pending before wait task, we consider wait as + * unsignaled. + */ + +static int vidschi_is_sync_object_signaled(task_wait_t *task, vidsch_wait_instance_t *wait, int client_wait) +{ + adapter_t *adapter = task->desc.context->device->adapter; + vidsch_sync_object_t *sync_obj = wait->sync_obj; + int signaled = FALSE; + + switch (sync_obj->type) + { + case GF_SYNC_OBJ_TYPE_MUTEX: + + if(client_wait && gf_atomic_read(wait->sync_obj->ref_cnt) >= 1) + { + break; + } + + if(gf_mutex_trylock(wait->sync_obj->mutex.mlock) == GF_LOCKED) + { + signaled = TRUE; + } + + break; + + case GF_SYNC_OBJ_TYPE_SEMPAPHORE: + + if(client_wait && (gf_atomic_read(wait->sync_obj->ref_cnt) >= wait->sync_obj->sema.initial_cnt)) + { + break; + } + + if(gf_down_trylock(wait->sync_obj->sema.slock) == GF_LOCKED) + { + signaled = TRUE; + } + + break; + + case GF_SYNC_OBJ_TYPE_DMAFENCE: + if (adapter->drm_cb->fence.dma_sync_object_is_signaled(sync_obj->dma.dma_sync_obj)) + { + signaled = TRUE; + } + break; + case GF_SYNC_OBJ_TYPE_FENCE: + { + vidsch_wait_fence_signaled_arg_t argu = {0}; + + argu.task = task; + argu.wait = wait; + + if(vidschi_is_fence_sync_object_signaled(&argu)) + { + signaled = TRUE; + } + + break; + } + + case GF_SYNC_OBJ_TYPE_CPU_NOTIFICATION: + + break; + + default: + + break; + } + + return signaled; +} + +/* client wait will wait untill fence conditon meet or timeout expired */ +#define DEFAULT_CLIENT_WAIT_TIMEOUT 10000 + +static int vidschi_wait_fence_sync_object_signaled(task_wait_t *task, vidsch_wait_instance_t *instance) +{ + gpu_context_t *context = task->desc.context; + adapter_t *adapter = context->device->adapter; + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[context->engine_index]; + condition_func_t condition = (condition_func_t)&vidschi_is_fence_sync_object_signaled; + unsigned int msec = gf_do_div(instance->timeout, 1000); + unsigned int e_status = 0, status = 0; + + vidsch_wait_fence_signaled_arg_t argu = {0}; + + argu.task = task; + argu.wait = instance; + + /* if timeout <= 5ms, warning it, since 5ms, maybe always timeout */ + if(msec <= 5) + { + gf_info("Warning: context: %x, TID: %d, client wait timeout: %dms, %lldns reset it to %ds.\n", + context->handle, context->tid, msec, instance->timeout, DEFAULT_CLIENT_WAIT_TIMEOUT); + msec = DEFAULT_CLIENT_WAIT_TIMEOUT; + } + +try_again: + + e_status = gf_wait_event_thread_safe(sch_mgr->fence_event, condition, &argu, msec); + + if(e_status == GF_EVENT_BACK) + { + status = GF_SYNC_OBJ_CONDITION_SATISFIED; + } + else if(e_status == GF_EVENT_TIMEOUT) + { + if(vidschi_can_submit_task(&task->desc)) + { + status = GF_SYNC_OBJ_TIMEOUT_EXPIRED; + } + else + { + goto try_again; + } + } + else if(e_status == GF_EVENT_SIGNAL) + { + goto try_again; + } + + return status; +} + + +static int vidschi_client_wait_instance_signaled(task_wait_t *task, vidsch_wait_instance_t *instance) +{ + adapter_t *adapter = task->desc.context->device->adapter; + vidsch_sync_object_t *sync_obj = instance->sync_obj; + + int status = GF_SYNC_OBJ_CONDITION_SATISFIED; + + switch (sync_obj->type) + { + case GF_SYNC_OBJ_TYPE_MUTEX: + + gf_mutex_lock(sync_obj->mutex.mlock); + + break; + + case GF_SYNC_OBJ_TYPE_SEMPAPHORE: + + gf_down(sync_obj->sema.slock); + + break; + + case GF_SYNC_OBJ_TYPE_FENCE: + + status = vidschi_wait_fence_sync_object_signaled(task, instance); + + break; + + case GF_SYNC_OBJ_TYPE_DMAFENCE: + + status = adapter->drm_cb->fence.dma_sync_object_wait(adapter->drm_cb_argu, sync_obj->dma.dma_sync_obj, 1000); + + break; + + case GF_SYNC_OBJ_TYPE_CPU_NOTIFICATION: + + break; + + default: + + break; + } + + return status; +} + +int vidschi_client_wait(task_wait_t *task) +{ + vidsch_wait_instance_t *instance = NULL; + int i = 0, status = GF_SYNC_OBJ_ALREAD_SIGNALED; + + for(i = 0; i < task->instance_cnt; i++) + { + instance = &task->instances[i]; + + if(instance->sync_obj == NULL) continue; + + status = vidschi_client_wait_instance_signaled(task, &task->instances[i]); + + if((status == GF_SYNC_OBJ_ALREAD_SIGNALED) || + (status == GF_SYNC_OBJ_CONDITION_SATISFIED)) + { + vidschi_sync_obj_del_reference(instance->sync_obj, instance); + + instance->sync_obj = NULL; + } + + } + + return status; +} + +int vidschi_try_wait(task_wait_t *wait_task, int client_wait) +{ + vidsch_wait_instance_t *instance = NULL; + + int i, lock_failed = FALSE; + + /* when lock failed, do we readly need unlock previous locked sync_obj. + * I don't think so, consider this wait_t1 (mutex_A, mutex_B), wait_t2(mutex_A) + * when t1, Mutex_B lock failed, if we unlock mutex_A, next t2 can get the mutex_A + * this not right, So I think, when try lock we should loop all wait instance, and lock + * all can locked. and get these lock to wait unlocked object. + */ + + for(i = 0; i < wait_task->instance_cnt; i++) + { + instance = &wait_task->instances[i]; + + if(instance->sync_obj == NULL) continue; + + if(vidschi_is_sync_object_signaled(wait_task, instance, client_wait)) + { + vidschi_sync_obj_del_reference(instance->sync_obj, instance); + + instance->sync_obj = NULL; + } + else + { + lock_failed |= TRUE; + } + } + + return lock_failed ? E_FAIL : S_OK; +} + +static task_wait_t *vidschi_allocate_wait_task(gpu_context_t *context, gf_wait_fence_sync_object_t *wait) +{ + adapter_t *adapter = context->device->adapter; + task_wait_t *wait_task= NULL; + vidsch_wait_instance_t *instance = NULL; + vidsch_sync_object_t *sync_obj = NULL; + unsigned int hSync = 0; + + /* only_check_status: + * in fence sync, spec said if timeout == 0, means no wait just return current fence status, + * impl by this no matter lient/server wait, if all obj is fence sync and all timeout == 0, + * consider it as client wait, and return its status ASAP. but still a problem we only can return + * one status + */ + + wait_task = gf_calloc(sizeof(task_wait_t)); + + wait_task->desc.context = context; + wait_task->desc.type = task_type_sync_wait; + wait_task->desc.task_wait = wait_task; + wait_task->instance_cnt = 1; + wait_task->only_check_status = TRUE; + wait_task->instances = wait_task->instances_builtin; + + gf_atomic_inc(context->ref_cnt); + + gf_get_nsecs(&wait_task->desc.timestamp); + + { + hSync = wait->fence_sync_object; + instance = &wait_task->instances[0]; + + if(hSync == 0) goto done; + + instance->sync_obj = + sync_obj = get_from_handle(&adapter->hdl_mgr, hSync); + + if(sync_obj == NULL) + { + gf_error("sync task: invalid sync handle 0x%x.\n", hSync); + goto done; + } + vidschi_sync_obj_add_reference(sync_obj, instance); + + if(instance->sync_obj->type == GF_SYNC_OBJ_TYPE_FENCE) + { + instance->fence_id = wait->fence_value; + instance->timeout = wait->timeout; + + if(instance->timeout == 0) + { + wait_task->only_check_status &= TRUE; + } + else + { + wait_task->only_check_status = FALSE; + } + } + } +done: + return wait_task; +} + +void vidschi_release_wait_task(task_wait_t *task) +{ + vidsch_wait_instance_t *instance = NULL; + int i = 0; + + for(i = 0; i < task->instance_cnt; i++) + { + instance = &task->instances[i]; + + if(instance->sync_obj == NULL) continue; + + vidschi_sync_obj_del_reference(instance->sync_obj, instance); + + instance->sync_obj = NULL; + } + + gf_atomic_dec(task->desc.context->ref_cnt); + + if (task->instances != task->instances_builtin) + { + gf_free(task->instances); + } + gf_free(task); +} + +/* current wait sync support wait multi-obj in one task, and one sync_obj can both support + * client/server wait, for easy implementation. we consider this multi-obj as a unity, + * we abstract these multi-obj as wait_task, and use this task to do client/server wait. + */ +int vidsch_wait_sync_object(gpu_context_t *context, gf_wait_fence_sync_object_t *wait) +{ + adapter_t *adapter = context->device->adapter; + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[context->engine_index]; + task_wait_t *wait_task= NULL; + + int status = S_OK; + + wait_task = vidschi_allocate_wait_task(context, wait); + + status = vidschi_try_wait(wait_task, TRUE); + + if(wait_task->only_check_status) + { + //gf_info("sync wait, only check status 0x%x last_submit_to_sw %lld task id %lld.\n", status, context->last_submit_to_sw, context->task_id); + + wait->status = (status == S_OK) ? GF_SYNC_OBJ_ALREAD_SIGNALED : GF_SYNC_OBJ_TIMEOUT_EXPIRED; + + vidschi_release_wait_task(wait_task); + + return TRUE; + } + + /* GO real wait path */ + wait_task->desc.context_task_id = ++context->task_id; + + if (adapter->ctl_flags.perf_event_enable) + { + vidsch_wait_instance_t *instance = NULL; + gf_perf_event_t perf_event = {0}; + unsigned long long timestamp = 0; + unsigned int i; + + gf_memset(&perf_event, 0, sizeof(gf_perf_event_t)); + + gf_get_nsecs(×tamp); + perf_event.header.timestamp_high = timestamp >> 32; + perf_event.header.timestamp_low = (timestamp) & 0xffffffff; + + perf_event.header.size = sizeof(gf_perf_event_wait_start_t); + perf_event.header.type = GF_PERF_EVENT_WAIT_START; + + perf_event.wait_start.engine_idx = context->engine_index; + perf_event.wait_start.gpu_context = context->handle; + perf_event.wait_start.task_id_high = wait_task->desc.context_task_id >> 32; + perf_event.wait_start.task_id_low = wait_task->desc.context_task_id & 0xffffffff; + + for (i = 0; i < wait_task->instance_cnt; i++) + { + instance = &wait_task->instances[i]; + + if(instance->sync_obj == NULL) continue; + + perf_event.wait_start.instance[i].handle = instance->sync_obj->handle; + perf_event.wait_start.instance[i].fence_value_high = instance->fence_id >> 32; + perf_event.wait_start.instance[i].fence_value_low = instance->fence_id & 0xffffffff; + perf_event.wait_start.instance[i].timeout = instance->timeout; + } + + perf_event_add_event(adapter, &perf_event); + } + + gf_task_create_trace_event(adapter->index << 16 | context->engine_index, context->handle, wait_task->desc.context_task_id, wait_task->desc.type); + + if((status == S_OK) && vidschi_can_submit_task(&wait_task->desc)) + { + wait->status = GF_SYNC_OBJ_ALREAD_SIGNALED; + + context->last_submit_to_sw = wait_task->desc.context_task_id; + + gf_task_submit_trace_event(adapter->index << 16 | context->engine_index, context->handle, wait_task->desc.context_task_id, wait_task->desc.type, 0, wait->status); + + vidschi_release_wait_task(wait_task); + } + else if(wait->server_wait && adapter->ctl_flags.worker_thread_enable) + { + vidschi_add_task_to_pending_queue(sch_mgr, &wait_task->desc); + + wait->status = GF_SYNC_OBJ_WAIT_ON_SERVER; + } + else + { + wait->status = vidschi_client_wait(wait_task); + + context->last_submit_to_sw = wait_task->desc.context_task_id; + + gf_task_submit_trace_event(adapter->index << 16 | context->engine_index, context->handle, wait_task->desc.context_task_id, wait_task->desc.type, 0, wait->status); + + vidschi_release_wait_task(wait_task); + } + + if ((adapter->ctl_flags.perf_event_enable)&&(wait->status != GF_SYNC_OBJ_WAIT_ON_SERVER)) + { + gf_perf_event_t perf_event = {0}; + unsigned long long timestamp = 0; + unsigned long long task_id = context->last_submit_to_sw; + + gf_memset(&perf_event, 0, sizeof(gf_perf_event_t)); + gf_get_nsecs(×tamp); + + perf_event.header.timestamp_high = timestamp >> 32; + perf_event.header.timestamp_low = (timestamp) & 0xffffffff; + + perf_event.header.size = sizeof(gf_perf_event_wait_finish_t); + perf_event.header.type = GF_PERF_EVENT_WAIT_FINISH; + perf_event.wait_finish.engine_idx = context->engine_index; + perf_event.wait_finish.gpu_context = context->handle; + perf_event.wait_finish.status = wait->status; + perf_event.wait_finish.task_id_high = task_id >> 32; + perf_event.wait_finish.task_id_low = task_id & 0xffffffff; + + perf_event_add_event(adapter, &perf_event); + } + + sync_trace("wait hSync: %x, context:%x, thread: %d, status:%d, waitValue:%lld.\n", + wait->fence_sync_object, context->handle, context->tid, wait->status, wait->fence_value); + + return S_OK; +} + + +void vidschi_force_signal_fence_sync_object(vidsch_sync_object_t *sync_obj, unsigned long long fence_value) +{ + gpu_device_t *device = sync_obj->device; + adapter_t *adapter = device->adapter; + vidsch_mgr_t *sch_mgr = NULL; + unsigned int engine; + + if(sync_obj->type == GF_SYNC_OBJ_TYPE_FENCE) + { + vidsch_fence_sync_object_t *fence = &sync_obj->fence; + +// gf_info("force signal fence sync object: %x, curr_value: %lld, signal_value: %lld.\n", +// sync_obj->handle, *fence->virt_addr, fence_value); + + if(fence->virt_addr == NULL) + { + gf_error(" fence->virt_addr = NULL, hSync = %x.\n", sync_obj->handle); + } + else if(*fence->virt_addr < fence_value) + { + *fence->virt_addr = fence_value; + } + + for(engine = 0; engine < adapter->active_engine_count; engine++) + { + sch_mgr = adapter->sch_mgr[engine]; + if (sch_mgr == NULL) continue; + gf_wake_up_event(sch_mgr->fence_event); + } + } +} + +int vidschi_try_signal(task_signal_t *signal) +{ + vidsch_sync_object_t *sync_obj = signal->sync_obj; + + int status = S_OK; + + if(!vidschi_can_submit_task(&signal->desc)) + { + return E_FAIL; + } + + switch (sync_obj->type) + { + case GF_SYNC_OBJ_TYPE_MUTEX: + + gf_mutex_unlock(sync_obj->mutex.mlock); + + break; + + case GF_SYNC_OBJ_TYPE_SEMPAPHORE: + + gf_up(sync_obj->sema.slock); + + break; + + case GF_SYNC_OBJ_TYPE_FENCE: + + gf_assert(0, "GF_SYNC_OBJ_TYPE_FENCE"); + + break; + + case GF_SYNC_OBJ_TYPE_CPU_NOTIFICATION: + + break; + + default: + + break; + } + + return status; +} + +int vidsch_signal_sync_object(gpu_context_t *context, unsigned int hSync) +{ + adapter_t *adapter = context->device->adapter; + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[context->engine_index]; + vidsch_sync_object_t *sync_obj = get_from_handle(&adapter->hdl_mgr, hSync); + task_signal_t *signal = gf_calloc(sizeof(task_signal_t)); + + signal->desc.type = task_type_sync_signal; + signal->desc.context = context; + signal->desc.context_task_id = ++context->task_id; + signal->desc.task_signal = signal; + signal->sync_obj = sync_obj; + + gf_task_create_trace_event(adapter->index << 16 | context->engine_index, context->handle, signal->desc.context_task_id, signal->desc.type); + + if(vidschi_try_signal(signal) != S_OK) + { + vidschi_add_task_to_pending_queue(sch_mgr, &signal->desc); + } + else + { + context->last_submit_to_sw = signal->desc.context_task_id; + gf_task_submit_trace_event(adapter->index << 16 | context->engine_index, context->handle, signal->desc.context_task_id, signal->desc.type, 0, 0); + gf_free(signal); + } + + /* wakeup all engines worker thread to check pending task queue */ + vidsch_notify_interrupt(adapter, 0); + + return S_OK; +} + +int vidsch_fence_value(gpu_device_t *device, gf_fence_value_t *value) +{ + adapter_t *adapter = device->adapter; + vidsch_sync_object_t *sync_obj = get_from_handle(&adapter->hdl_mgr, value->fence_sync_object); + + if(sync_obj == NULL) + { + gf_info("%s, send a invalidate hSyncObject: %x.\n", __func__, value->fence_sync_object); + + return E_INVALIDARG; + } + + if(value->opcode == GF_GET_FENCE_VALUE) + { + value->fence_value = sync_obj->fence.shared_value; + value->appid = sync_obj->fence.appid; + value->flip_limit = sync_obj->fence.flip_limit; + value->discard_sync =sync_obj->fence.discard; + if(value->flip_limit > 0) + { + sync_trace("get flipcounter pid %d appid %d flip_limit %d \n", gf_get_current_pid(),value->appid, value->flip_limit); + } + } + else if(value->opcode == GF_SET_FENCE_VALUE) + { + if(value->fence_value != 0 && (value->fence_value < sync_obj->fence.shared_value)) + { + gf_info("pid %d : decrease fence value (%lld -> %lld), maybe a bug...?\n", gf_get_current_pid(), sync_obj->fence.shared_value, value->fence_value); + } + + sync_obj->fence.discard = value->discard_sync; + if (value->fence_value > 0) + { + sync_obj->fence.shared_value = value->fence_value; + } + + if(value->appid > 0) + { + sync_obj->fence.appid = value->appid; + sync_obj->fence.flip_limit = value->flip_limit; + } + + if(value->flip_limit > 0) + { + sync_trace("set flipcounter pid %d appid %d flip_limit %d \n", gf_get_current_pid(),value->appid, value->flip_limit); + } + } + else + { + gf_error("unkonwn Op: %s.\n", __func__); + } + + return S_OK; +} + +int vidsch_is_fence_signaled(adapter_t *adapter, unsigned int hSync, unsigned long long wait_value) +{ + int ret = FALSE; + vidsch_sync_object_t *sync_obj = get_from_handle(&adapter->hdl_mgr, hSync); + if (sync_obj->type == GF_SYNC_OBJ_TYPE_FENCE) + { + if (*(volatile unsigned long long *)sync_obj->fence.virt_addr >= wait_value) + { + ret = TRUE; + } + } + return ret; +} + +void vidsch_sync_obj_inc_reference(adapter_t *adapter, unsigned int hSync) +{ + vidsch_sync_object_t *sync_obj = get_from_handle(&adapter->hdl_mgr, hSync); + + vidschi_sync_obj_inc_reference(sync_obj); +} + +void vidsch_sync_obj_dec_reference(adapter_t *adapter, unsigned int hSync) +{ + vidsch_sync_object_t *sync_obj = get_from_handle(&adapter->hdl_mgr, hSync); + + vidschi_sync_obj_dec_reference(sync_obj); +} + +void vidsch_force_signal_fence_sync_object(adapter_t *adapter, unsigned int hSync, unsigned long long fence_value) +{ + vidsch_sync_object_t *sync_obj = get_from_handle(&adapter->hdl_mgr, hSync); + + if(sync_obj) + { + vidschi_force_signal_fence_sync_object(sync_obj, fence_value); + } + else + { + gf_error("sync_obj is NULL, hSync = %x.\n", hSync); + } +} + +void vidschi_dump_wait_task(struct os_printer *p, task_wait_t *wait, int idx, int dump_detail) +{ + adapter_t *adapter = wait->desc.context->device->adapter; + vidsch_sync_object_t *sync_obj = NULL; + vidsch_wait_instance_t *instance = NULL; + int index; + + gf_printf(p,"[^^^^ %4d, Dump Wait Task]\n", idx); + + vidschi_dump_general_task_info(p, &wait->desc); + + for(index = 0; index < wait->instance_cnt; index++) + { + instance = &wait->instances[index]; + sync_obj = instance->sync_obj; + + if (sync_obj == NULL) continue; + + if(sync_obj->type == GF_SYNC_OBJ_TYPE_FENCE) + { + gf_printf(p, "instance[%d], sync obj: %x, instance deltatime: %d, WaitV: %lld, CurrV: %lld.\n", + index, sync_obj->handle, instance->delta_time, instance->fence_id, *instance->sync_obj->fence.virt_addr); + } + else if(sync_obj->type == GF_SYNC_OBJ_TYPE_DMAFENCE) + { + adapter->drm_cb->fence.dma_sync_object_dump(sync_obj->dma.dma_sync_obj); + } + } +} + + diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_sync.h b/drivers/gpu/drm/arise/core/vidsch/vidsch_sync.h new file mode 100644 index 0000000000000..40a2149f157f3 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch_sync.h @@ -0,0 +1,165 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __VIDSCH_SYNC_H__ +#define __VIDSCH_SYNC_H__ + +#include "list.h" + +typedef struct vidsch_fence_sync_object +{ + unsigned long long gpu_addr; + unsigned long long *virt_addr; + unsigned long long shared_value; /* a value shared by multi process, general use this value a send fence value */ + int appid; + int flip_limit; + int discard; /* user mode info*/ +}vidsch_fence_sync_object_t; + +typedef struct vidsch_dma_sync_object +{ + void *dma_sync_obj; +}vidsch_dma_sync_object_t; + +typedef struct vidsch_sema_sync_object +{ +// int max_count; + int initial_cnt; + struct os_sema *slock; //sema used for client wait +}vidsch_sema_sync_object_t; + +typedef struct vidsch_mutex_sync_object +{ + int initial_state; + struct os_mutex *mlock; +}vidsch_mutex_sync_object_t; + +typedef struct vidsch_sync_object +{ + struct list_head list_node; + + gpu_device_t *device; //creater + unsigned int binding : 1; //if binding set mean this sync object create by other resource like context, allocation, and binding to it, + //not directly create by device, on this device, sync object lifetime maintenanced by create resource. + // no need add it to device sync object list. + unsigned int type; + unsigned int handle; + + + + struct os_spinlock *lock; + + struct list_head instance_list; //wait instance reference list. + struct os_atomic *ref_cnt; +// int ref_cnt; //wait instance reference cnt, use for easy debug + + union + { + vidsch_sema_sync_object_t sema; + vidsch_mutex_sync_object_t mutex; + vidsch_fence_sync_object_t fence; + vidsch_dma_sync_object_t dma; + }; +}vidsch_sync_object_t; + +typedef struct vidsch_wait_instance +{ + struct list_head list_node; /* link to sync_obj instance list */ + unsigned long long fence_id; //only for fence sync + unsigned long long timeout; + unsigned long long delta_time; // server wait timeout adjust. + unsigned int signaled; //for fence synce + vidsch_sync_object_t *sync_obj; +}vidsch_wait_instance_t; + +typedef struct task_wait +{ + task_desc_t desc; + int only_check_status; + int instance_cnt; + vidsch_wait_instance_t *instances; + vidsch_wait_instance_t instances_builtin[4]; +}task_wait_t; + +typedef struct task_signal +{ + task_desc_t desc; + vidsch_sync_object_t *sync_obj; +}task_signal_t; + +typedef struct vidch_wait_fence_signaled_arg +{ + task_wait_t *task; + vidsch_wait_instance_t *wait; +}vidsch_wait_fence_signaled_arg_t; + +extern int vidschi_try_wait(task_wait_t *wait_task, int clent_wait); +extern int vidschi_try_signal(task_signal_t *signal); +extern int vidschi_is_server_wait_timeout(task_wait_t *task, unsigned long long curr_time); + +extern void vidschi_dump_wait_task(struct os_printer *p, task_wait_t *wait, int idx, int dump_detail); +extern int vidschi_client_wait(task_wait_t *task); + +extern void vidschi_release_wait_task(task_wait_t *task_wait); +extern void vidschi_force_signal_fence_sync_object(vidsch_sync_object_t *sync_obj, unsigned long long fence_value); +extern void vidschi_destroy_defer_sync_obj(adapter_t *adapter); +extern void vidschi_add_sync_to_defer_destroy(adapter_t *adapter, vidsch_sync_object_t *sync_obj); + +static inline void vidschi_sync_obj_add_reference(vidsch_sync_object_t *sync_obj, vidsch_wait_instance_t *instance) +{ + gf_spin_lock(sync_obj->lock); + + list_add_tail(&instance->list_node, &sync_obj->instance_list); + + gf_atomic_inc(sync_obj->ref_cnt); + + gf_spin_unlock(sync_obj->lock); +} + +static inline void vidschi_sync_obj_del_reference(vidsch_sync_object_t *sync_obj, vidsch_wait_instance_t *instance) +{ + gf_spin_lock(sync_obj->lock); + + list_del(&instance->list_node); + + gf_atomic_dec(sync_obj->ref_cnt); + + gf_spin_unlock(sync_obj->lock); +} + +static inline void vidschi_sync_obj_inc_reference(vidsch_sync_object_t *sync_obj) +{ + gf_atomic_inc(sync_obj->ref_cnt); +} + +static inline void vidschi_sync_obj_dec_reference(vidsch_sync_object_t *sync_obj) +{ + gf_atomic_dec(sync_obj->ref_cnt); +} + +static inline int vidschi_sync_obj_referenced(vidsch_sync_object_t *sync_obj) +{ + int referenced; + + gf_spin_lock(sync_obj->lock); + + referenced = (gf_atomic_read(sync_obj->ref_cnt) == 0) ? FALSE : TRUE; + + gf_spin_unlock(sync_obj->lock); + + return referenced; +} + +#endif + diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_task.c b/drivers/gpu/drm/arise/core/vidsch/vidsch_task.c new file mode 100755 index 0000000000000..79932dd97b070 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch_task.c @@ -0,0 +1,823 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "context.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_sync.h" +#include "vidsch_submit.h" + +#if 0 +static int vidschi_update_fence_id_temp(vidsch_mgr_t *sch_mgr, unsigned long long *curr_returned) +{ + unsigned long long new_fence, old_fence; + unsigned long flags; + + int update_new = FALSE; + + flags = gf_spin_lock_irqsave(sch_mgr->fence_lock); + + new_fence = sch_mgr->chip_func->update_fence_id(sch_mgr); + + old_fence = sch_mgr->returned_fence_id; + + /* check if new_returned valid, if not skipped it */ + if(((new_fence > sch_mgr->returned_fence_id) && + (new_fence <= sch_mgr->last_send_fence_id)) && + (old_fence <= sch_mgr->last_send_fence_id)) + { + sch_mgr->returned_fence_id = new_fence; + sch_mgr->uncomplete_task_num = sch_mgr->last_send_fence_id - sch_mgr->returned_fence_id; + + update_new = TRUE; + } + else + { + new_fence = sch_mgr->returned_fence_id; + } + + gf_spin_unlock_irqrestore(sch_mgr->fence_lock, flags); + + if(new_fence > old_fence) + { + gf_get_nsecs(&sch_mgr->returned_timestamp); + } + + *curr_returned = new_fence; + + return update_new; +} + +static void vidschi_dump_task_list(vidsch_mgr_t *sch_mgr, struct list_head *task_list) +{ + task_desc_t *task = NULL; + + int i = 0; + + gf_mutex_lock(sch_mgr->task_list_lock); + + list_for_each_entry(task, task_list, list_item) + { + gf_info("task[%02d]: %p, type: %d, cmd_size: %8d, fence_id: %lld. submitted: %d, fake_submit: %d.\n", + i++, task, task->type, task->cmd_size, task->fence_id, task->submitted, task->fake_submitted); + gf_info("--------------- context: %p, time: %d, task_id: %lld.\n", + task->context, (unsigned int)gf_do_div(task->timestamp, 1000000), task->context_task_id); + } + + gf_mutex_unlock(sch_mgr->task_list_lock); +} + +static void vidschi_dump_dma_info(vidsch_mgr_t *sch_mgr) +{ + heap_t *dma_heap = sch_mgr->dma_heap; + + gf_info("********engine: %d, DMA info\n********************\n", sch_mgr->engine_index); + + heap_dump(dma_heap); + + gf_info("--------dump submitted task list: \n"); + + vidschi_dump_task_list(sch_mgr, &sch_mgr->submitted_task_list); + + gf_info("--------dump allocated task list: \n"); + + vidschi_dump_task_list(sch_mgr, &sch_mgr->allocated_task_list); + + gf_info("----------------------------------------------------\n"); +} +#endif + +static void vidschi_dump_allocation_member(struct os_printer *p , int index, vidmm_allocation_t *allocation) +{ + gpu_device_t *device = allocation->device; + adapter_t * adapter = device->adapter; + + gf_printf(p, "allo[%03d]: %x, dev: %x, fmt: %8d-%8d-%d-%2d, W-H-P: %8d-%8d-%8d, size: %8dk, gvm: %llx, AT:0x%02x, status %8x, pid:%d, tid: %d, proc:%s.\n", + index, allocation->handle, allocation->device->handle, + allocation->hw_format, allocation->compress_format, allocation->flag.swizzled, allocation->bit_count, + allocation->width, allocation->height, allocation->pitch, + util_align(allocation->orig_size, util_max(allocation->alignment, adapter->os_page_size)) >> 10, + allocation->phys_addr, allocation->at_type, allocation->status.temp_unpagable, + allocation->device->pid, allocation->device->tid, allocation->device->pname); +} + +void vidschi_dump_general_task_info(struct os_printer *p, task_desc_t *task) +{ + gpu_context_t *context = task->context; + gpu_device_t *device = context->device; + + gf_printf(p,"TaskId: %lld, GlobalTaskId:%lld, ContextLastSubmitted: %lld. Device: %x, Context: %x, Engine: %d.\n", + task->context_task_id, task->global_task_id, context->last_submit_to_sw, device->handle, context->handle, context->engine_index); + gf_printf(p,"Submitted By Process: PID: %d, TID: %d, %s.\n", + context->pid, context->tid, context->pname); +} + +static void vidschi_dump_render_task(struct os_printer *p, adapter_t * adapter, task_dma_t *render, int idx, int dump_detail) +{ + vidmm_allocation_t *allocation = NULL; + + unsigned long long hwctx_addr = (render->hw_ctx_info != NULL) ? + render->hw_ctx_info->context_buffer_address : 0; + + int i = 0; + + gf_printf(p,"[^^^^ %4d, Dump Render Task]\n", idx); + + vidschi_dump_general_task_info(p,&render->desc); + + gf_printf(p,"RenderType: %d, FenceID: %lld, hwctx addr: 0x%x. allocations: %d, patchs: %d.\n", + render->dma_type, render->desc.fence_id, hwctx_addr, + render->allocation_list_size, render->patch_location_list_size); + + if(!adapter->display_debugbus_flag) return; + gf_msleep(10); + + for(i = 0; i < render->allocation_list_size; i++) + { + allocation = render->sch_allocation_list[i].mm_allocation; + + if(allocation == NULL) continue; + + vidschi_dump_allocation_member(p, i, allocation); + + if(dump_detail && (allocation->at_type == 18 || //MM_AT_EUPFSHADER_E3K + allocation->at_type == 19 || //MM_AT_EUPBSHADER_E3K + allocation->at_type == 22)) //MM_AT_CONTEXT_E3K + { + vidmm_dump_allocation_content(allocation); + } + + if(dump_detail && allocation->compress_format) + { + vidmm_dump_flagbuffer_to_file(NULL, allocation); + } + } + + if(!dump_detail) return; + + gf_msleep(20); + + if(render->dma_buffer_node != NULL) + { + util_dump_memory(p, render->dma_buffer_node->virt_base_addr, render->command_length, "Dma"); + + gf_msleep(10); + } +} + +static void vidschi_dump_paging_task(struct os_printer *p, adapter_t *adapter, task_paging_t *paging, int idx, int dump_detail) +{ + vidmm_allocation_t *allocation = NULL; + vidmm_paging_allocation_t *paging_allocation = NULL; + + int i = 0; + + gf_printf(p, "[^^^^ %4d, Dump Paging Task]: Type: %d, AllocationNum: %d, FenceId: %d.\n", + idx, paging->paging_type, paging->paging_allocation_list_size, paging->desc.fence_id); + + for(i = 0; i < paging->paging_allocation_list_size; i++) + { + paging_allocation = &paging->paging_allocation_list[i]; + allocation = paging_allocation->allocation; + + if(allocation == NULL) continue; + + gf_printf(p, "addr:%x, segment_id:%d, temp_addr:%x\n", paging_allocation->gpu_virt_addr, paging_allocation->segment_id, + paging_allocation->temp_allocation != NULL ? paging_allocation->temp_allocation->phys_addr : 0); + + vidschi_dump_allocation_member(p, i, allocation); + + if(dump_detail && (allocation->at_type == 18 || //MM_AT_EUPFSHADER_E3K + allocation->at_type == 19 || //MM_AT_EUPBSHADER_E3K + allocation->at_type == 22)) //MM_AT_CONTEXT_E3K + { + vidmm_dump_allocation_content(allocation); + } + + if(dump_detail && allocation->compress_format) + { + vidmm_dump_flagbuffer_to_file(NULL, allocation); + } + } + + if(!dump_detail) return; + + gf_msleep(20); + + if(paging->dma != NULL) + { + util_dump_memory(p, paging->dma->virt_base_addr, paging->command_length, "Dma"); + + gf_msleep(10); + } +} + +void vidschi_dump_task(struct os_printer *p, adapter_t *adapter, task_desc_t *task, int idx, int dump_detail) +{ + switch (task->type) + { + case task_type_render: + vidschi_dump_render_task(p, adapter, task->task_render, idx, dump_detail); + break; + + case task_type_sync_wait: + vidschi_dump_wait_task(p, task->task_wait, idx, dump_detail); + break; + + case task_type_sync_signal: + gf_printf(p, "signal task.\n"); + break; + + case task_type_paging: + vidschi_dump_paging_task(p, adapter, task->task_paging, idx, dump_detail); + break; + + default: + gf_error("Unknown Task type: %d.\n", task->type); + break; + } +} + + dma_node_t *vidschi_allocate_dma_node(vidsch_mgr_t *sch_mgr, unsigned int dma_size) +{ + vidmm_segment_memory_t *dma_reserved_memory = sch_mgr->dma_reserved_memory; + heap_t *dma_heap = sch_mgr->dma_heap; + dma_node_t *dma = gf_calloc(sizeof(dma_node_t)); + int sleep_cnt = 0; + + while(dma->list_node == NULL) + { + unsigned long long uncomplete_task = 0ll; + + vidsch_release_completed_tasks(sch_mgr->adapter, sch_mgr->engine_index, &uncomplete_task); + + dma->list_node = heap_allocate(dma_heap, dma_size, 0, 0); + + if (dma->list_node == NULL) + { + if(uncomplete_task == 0ll) + { + if(sleep_cnt > 500) + { + gf_info("use 500 * 20ms try allocate dma (size: %d) failed.\n", dma_size); + + //vidschi_dump_dma_info(sch_mgr); + + gf_info("try another 500 * 20ms to allocate dma.\n"); + + sleep_cnt = 0; + } + + gf_msleep(20); + + sleep_cnt++; + } + else + { + sleep_cnt = 0; + + vidsch_wait_fence_back(sch_mgr->adapter, sch_mgr->engine_index, uncomplete_task); + } + } + } + + dma->gpu_phy_base_addr = dma->list_node->aligned_offset; + dma->virt_base_addr = (unsigned char *)dma_reserved_memory->vma->virt_addr + dma->list_node->aligned_offset - dma_reserved_memory->gpu_virt_addr; + dma->size = dma->list_node->aligned_size; + dma->cmd_size = dma_size; + + //gf_info("allocate dma:%p gvirt_addr: %x, size: %d, request_size: %d.\n", + // dma, dma->gpu_phy_base_addr, dma->size, dma->cmd_size); + + return dma; +} + +static inline void vidschi_release_dma_node(vidsch_mgr_t *sch_mgr, dma_node_t *dma) +{ + //gf_info("release dma:%p gvirt_addr: %x, size: %d, request_size: %d.\n", + // dma, dma->gpu_phy_base_addr, dma->size, dma->cmd_size); + + heap_release(sch_mgr->dma_heap, dma->list_node); + + gf_free(dma); +} + +static inline void vidschi_init_task_desc(vidsch_mgr_t *sch_mgr, task_desc_t *task, gpu_context_t *context, int task_type, int cmd_size) +{ + task->context = context; + task->type = task_type; + task->cmd_size = cmd_size; + + if(context != NULL) + { + task->context_task_id = ++context->task_id; + + gf_atomic_inc(context->ref_cnt); + } + + gf_mutex_lock(sch_mgr->task_list_lock); + + list_add_tail(&task->list_item, &sch_mgr->allocated_task_list); + + gf_mutex_unlock(sch_mgr->task_list_lock); + + gf_get_nsecs(&task->timestamp); +} + +static inline void vidschi_deinit_task_desc(vidsch_mgr_t *sch_mgr, task_desc_t *task, int list_locked) +{ + gpu_context_t *context = task->context; + + if(context != NULL) + { + gf_atomic_dec(context->ref_cnt); + task->context = NULL; + } + + if(!list_locked) gf_mutex_lock(sch_mgr->task_list_lock); + + list_del(&task->list_item); + + if(!list_locked) gf_mutex_unlock(sch_mgr->task_list_lock); +} + +task_dma_t *vidsch_allocate_task_dma(adapter_t *adapter, unsigned int engine_index, vidsch_allocate_task_dma_t *dma_arg) +{ + unsigned int offset = 0; + char *memory = NULL; + task_dma_t *task_dma = NULL; + unsigned int allocations_raw_size = dma_arg->allocation_count * sizeof(gf_allocation_list_t); + unsigned int allocations_size = dma_arg->allocation_count * sizeof(vidsch_allocation_t); + unsigned int patchs_size = dma_arg->patch_location_count * sizeof(gf_patchlocation_list_t); + unsigned int syncs_raw_size = dma_arg->sync_object_count * sizeof(gf_syncobj_list_t); + unsigned int syncs_size = dma_arg->sync_object_count * sizeof(vidsch_sync_object_reference_t); + vidsch_mgr_t *vidsch = adapter->sch_mgr[engine_index]; + + unsigned int total_size = util_align(sizeof(task_dma_t), 16) + + util_align(allocations_raw_size, 16) + + util_align(syncs_raw_size, 16) + + util_align(allocations_size, 16) + + util_align(patchs_size, 16) + + util_align(syncs_size, 16); + + memory = gf_calloc(total_size); + if(memory == NULL) + { + gf_error("func vidsch_allocate_task_dma allocated memory failed, size:%x.\n", total_size); + } + + task_dma = (task_dma_t *)(memory + offset); + offset += util_align(sizeof(task_dma_t), 16); + + if(dma_arg->allocation_count) + { + task_dma->allocation_list_raw = (gf_allocation_list_t*)(memory + offset); + offset += util_align(allocations_raw_size, 16); + + task_dma->sch_allocation_list = (vidsch_allocation_t *)(memory + offset); + task_dma->allocation_list_size = dma_arg->allocation_count; + offset += util_align(allocations_size, 16); + } + + if(dma_arg->patch_location_count) + { + task_dma->patch_location_list = (gf_patchlocation_list_t*)(memory + offset); + task_dma->patch_location_list_size = dma_arg->patch_location_count; + task_dma->patch_start_offset = 0; + task_dma->patch_end_offset = dma_arg->patch_location_count; + offset += util_align(patchs_size, 16); + } + + if(dma_arg->sync_object_count) + { + task_dma->sync_object_list_raw = (gf_syncobj_list_t*)(memory + offset); + offset += util_align(syncs_raw_size, 16); + + task_dma->sync_object_list = (vidsch_sync_object_reference_t *)(memory + offset); + task_dma->sync_object_list_size = dma_arg->sync_object_count; + + offset += util_align(syncs_size, 16); + } + + gf_assert(offset == total_size, "offset == total_size"); + + task_dma->dma_buffer_node = vidschi_allocate_dma_node(vidsch, dma_arg->command_length); + + task_dma->command_length = dma_arg->command_length; + task_dma->submit_start_offset = 0; + task_dma->submit_end_offset = dma_arg->command_length; + task_dma->dma_type = dma_arg->dma_type; + task_dma->hw_ctx_info = NULL; + task_dma->need_hwctx_switch = (dma_arg->dma_type == DRAW_3D_DMA) ? TRUE:FALSE; + task_dma->desc.task_render = task_dma; + + /* if hw engine no hw ctx, then no need hwctx swicth */ + if(vidsch->engine_caps & ENGINE_CAPS_NO_HWCTX) + { + task_dma->need_hwctx_switch = FALSE; + } + + vidschi_init_task_desc(vidsch, &task_dma->desc, dma_arg->context, task_type_render, dma_arg->command_length); + task_dma->desc.Flags = dma_arg->Flags; + + gf_task_create_trace_event(adapter->index << 16 | dma_arg->context->engine_index, dma_arg->context->handle, task_dma->desc.context_task_id, task_dma->desc.type); + + return task_dma; +} + +static void vidschi_release_task_dma(vidsch_mgr_t *sch_mgr, task_dma_t *render) +{ + vidschi_deinit_render_sync_object_list(sch_mgr, render); + + vidschi_release_dma_node(sch_mgr, render->dma_buffer_node); + + render->dma_buffer_node = NULL; + + gf_free(render); +} + +task_paging_t *vidsch_allocate_paging_task(adapter_t *adapter, int dma_size, int allocation_num) +{ + vidsch_mgr_t *paging_engine = adapter->sch_mgr[adapter->paging_engine_index]; + task_paging_t *paging_task = NULL; + + unsigned int total_size = util_align(sizeof(task_paging_t), 16) + + util_align(sizeof(vidmm_paging_allocation_t) * allocation_num, 16); + + paging_task = gf_calloc(total_size); + + paging_task->paging_allocation_list = (vidmm_paging_allocation_t *)((char *)paging_task + util_align(sizeof(task_paging_t), 16)); + paging_task->paging_allocation_list_size = allocation_num; + paging_task->dma = vidschi_allocate_dma_node(paging_engine, dma_size); + paging_task->desc.hang_index = -1; + paging_task->desc.task_paging = paging_task; + + vidschi_init_task_desc(paging_engine, &paging_task->desc, NULL, task_type_paging, dma_size); + + gf_task_create_trace_event(adapter->index << 16 | paging_engine->engine_index, 0, ptr_to_ptr64(&paging_task->desc), paging_task->desc.type); + + return paging_task; +} + +static void vidschi_release_paging_task(vidsch_mgr_t *paging_engine, task_paging_t *paging_task) +{ + adapter_t *adapter = paging_engine->adapter; + + vidschi_release_dma_node(paging_engine, paging_task->dma); + + vidmm_release_temp_paging_memory(adapter, paging_task); + + gf_free(paging_task); +} + + +static inline void vidschi_do_release_task(vidsch_mgr_t *sch_mgr, task_desc_t *task) +{ + switch (task->type) + { + case task_type_render: + + vidschi_release_task_dma(sch_mgr, task->task_render); + break; + + case task_type_paging: + + vidschi_release_paging_task(sch_mgr, task->task_paging); + break; + + default: + gf_error("SOMETHING WRONG task: %d, can not put in dma submit list.\n", task->type); + break; + } +} + +void vidschi_set_dma_task_fake_submitted(vidsch_mgr_t *sch_mgr, task_desc_t *task) +{ +#if 0 + dma_node_t *dma = NULL; + switch (task->type) + { + case task_type_render: + + dma = task->task_render->dma_buffer_node; + break; + + case task_type_paging: + + dma = task->task_paging->dma; + break; + + default: + break; + } + + if(dma != NULL) + { + gf_info("fake sub dma:%p gvirt_addr: %x, size: %d, request_size: %d. task: %d\n", + dma, dma->gpu_phy_base_addr, dma->size, dma->cmd_size, task->type); + } +#endif + + task->fake_submitted = TRUE; + + if(task->ref_cnt == 0) + { + vidschi_deinit_task_desc(sch_mgr, task, FALSE); + + vidschi_do_release_task(sch_mgr, task); + } +} + +void vidschi_set_dma_task_submitted(vidsch_mgr_t *sch_mgr, task_desc_t *task) +{ +#if 0 + dma_node_t *dma = NULL; + + switch (task->type) + { + case task_type_render: + + dma = task->task_render->dma_buffer_node; + break; + + case task_type_paging: + + dma = task->task_paging->dma; + break; + + default: + break; + } + + if(dma != NULL) + { + gf_info("submitted dma:%p gvirt_addr: %x, size: %d, request_size: %d. task: %d\n", + dma, dma->gpu_phy_base_addr, dma->size, dma->cmd_size, task->type); + } +#endif + + /* update submit timestamp */ + gf_get_nsecs(&task->timestamp); + + task->submitted = TRUE; + + gf_mutex_lock(sch_mgr->task_list_lock); + + list_del(&task->list_item); + + list_add_tail(&task->list_item, &sch_mgr->submitted_task_list); + + gf_mutex_unlock(sch_mgr->task_list_lock); +} + +void vidsch_task_inc_reference(adapter_t *adapter, int engine_index, task_desc_t *desc) +{ + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[engine_index]; + + gf_mutex_lock(sch_mgr->task_list_lock); + + desc->ref_cnt++; + + gf_mutex_unlock(sch_mgr->task_list_lock); +} + +void vidsch_task_dec_reference(adapter_t *adapter, int engine_index, task_desc_t *task) +{ + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[engine_index]; + + int do_release_task = FALSE; + + gf_mutex_lock(sch_mgr->task_list_lock); + + task->ref_cnt--; + + if((task->type == task_type_paging) && task->fake_submitted && (task->ref_cnt == 0)) + { + do_release_task = TRUE; + } + + gf_mutex_unlock(sch_mgr->task_list_lock); + + if(do_release_task) + { + vidschi_deinit_task_desc(sch_mgr, task, FALSE); + + vidschi_do_release_task(sch_mgr, task); + } + else + { + vidsch_release_completed_tasks(adapter, engine_index, NULL); + } +} + +void vidsch_release_completed_tasks(adapter_t *adapter, int engine_index, unsigned long long *uncompleted_dma) +{ + vidsch_mgr_t *sch_mgr = adapter->sch_mgr[engine_index]; + task_desc_t *task; + +try_next: + + task = NULL; + + gf_mutex_lock(sch_mgr->task_list_lock); + + if(!list_empty(&sch_mgr->submitted_task_list)) + { + task = list_entry(sch_mgr->submitted_task_list.next, task_desc_t, list_item); + + if((task->ref_cnt == 0) && vidsch_is_fence_back(sch_mgr->adapter, sch_mgr->engine_index, task->fence_id)) + { + vidschi_deinit_task_desc(sch_mgr, task, TRUE); + } + else + { + if(task->timestamp < sch_mgr->returned_timestamp) + { + task->timestamp = sch_mgr->returned_timestamp; + } + + if(uncompleted_dma != NULL) + { + *uncompleted_dma = task->fence_id; + } + + task = NULL; + } + } + + gf_mutex_unlock(sch_mgr->task_list_lock); + + if(task != NULL) + { + vidschi_do_release_task(sch_mgr, task); + + goto try_next; + } +} + +void vidschi_release_allocated_tasks(vidsch_mgr_t *sch_mgr) +{ + task_desc_t *task; + +try_next: + + task = NULL; + + gf_mutex_lock(sch_mgr->task_list_lock); + + if(!list_empty(&sch_mgr->allocated_task_list)) + { + task = list_entry(sch_mgr->allocated_task_list.next, task_desc_t, list_item); + + vidschi_deinit_task_desc(sch_mgr, task, TRUE); + } + + gf_mutex_unlock(sch_mgr->task_list_lock); + + if(task != NULL) + { + vidschi_do_release_task(sch_mgr, task); + + goto try_next; + } +} + +task_desc_t *vidschi_uncompleted_task_exceed_wait_time(vidsch_mgr_t *sch_mgr, unsigned long long max_wait_time) +{ + adapter_t *adapter = sch_mgr->adapter; + task_desc_t *task = NULL; + int exceed = FALSE; + static unsigned long long fence_timeout_cnt = 0; + unsigned long long wait_time = 0; +#if 0 + unsigned long long returned_fence_id; + unsigned int new_fence = 0; + new_fence = vidschi_update_fence_id_temp(sch_mgr, &returned_fence_id); + + if(new_fence) + { + + gf_wake_up_event(sch_mgr->fence_event); + + if((sch_mgr->emergency_task_pool.task_num > 0) || + (sch_mgr->normal_task_pool.task_num > 0)) + { + util_wakeup_event_thread(sch_mgr->worker_thread); + } + } +#endif + /* first release completed task in queue */ + vidsch_release_completed_tasks(adapter, sch_mgr->engine_index, NULL); + + gf_mutex_lock(sch_mgr->task_list_lock); + + if(!list_empty(&sch_mgr->submitted_task_list)) + { + unsigned long long curr_time = 0ll; + + task = list_entry(sch_mgr->submitted_task_list.next, task_desc_t, list_item); + wait_time = task->Flags.normal_recovery ? max_wait_time : adapter->hw_hang_fast_timeout_ns; + + gf_get_nsecs(&curr_time); + + /* NOTE: all timestamp is unsigned value, so if x - y < 0, since the type it minus value still a + * unsigned which will be big vale, So not use if(x - y > delta) but if(x + delta > y) to avoid overflow issue + */ + + if((task->timestamp + wait_time) < curr_time && sch_mgr->returned_fence_id < task->fence_id) + { + + unsigned long long new_fence_id = sch_mgr->chip_func->update_fence_id(sch_mgr); + + if(new_fence_id >= task->fence_id){ + + fence_timeout_cnt++; + + if ((fence_timeout_cnt <= 10) ||(adapter->debugfs_mask & GF_DEBUGFS_FAKE_HANG)) + { + gf_info("fence timeout: engine[%d], fence_id:%lld, dma_size: %d. used_time: %dms, submit_time: %dms, curr_time: %dms, returned_fence_id-%lld, new_fence_id-%lld\n", + sch_mgr->engine_index, + task->fence_id, + task->cmd_size, + (unsigned int)gf_do_div(curr_time - task->timestamp, 1000000), + (unsigned int)gf_do_div(task->timestamp, 1000000), + (unsigned int)gf_do_div(curr_time, 1000000), + sch_mgr->returned_fence_id, + new_fence_id); + } + vidsch_notify_interrupt(adapter, 0); + /*patch lost interrupt*/ + gf_disable_interrupt(adapter->os_device.pdev); + gf_enable_interrupt(adapter->os_device.pdev); + }else { + gf_info("timeout detect: engine[%d], fence_id:%lld, dma_size: %d. used_time: %dms, submit_time: %dms, curr_time: %dms, returned_fence_id-%lld, new_fence_id-%lld\n", + sch_mgr->engine_index, + task->fence_id, + task->cmd_size, + (unsigned int)gf_do_div(curr_time - task->timestamp, 1000000), + (unsigned int)gf_do_div(task->timestamp, 1000000), + (unsigned int)gf_do_div(curr_time, 1000000), + sch_mgr->returned_fence_id, + new_fence_id); + + exceed = TRUE; + task->ref_cnt++; + } + } + } + + gf_mutex_unlock(sch_mgr->task_list_lock); + + return exceed ? task : NULL; +} + +void vidschi_set_uncompleted_task_dropped(vidsch_mgr_t *sch_mgr, unsigned long long dropped_task) +{ + adapter_t *adapter = sch_mgr->adapter; + task_desc_t *task = NULL; + + gf_mutex_lock(sch_mgr->task_list_lock); + + list_for_each_entry(task, &sch_mgr->submitted_task_list, list_item) + { + if(task->fence_id <= dropped_task) + { + task->reset_dropped = TRUE; + + if(adapter->display_debugbus_flag) + { + gf_info("task: %p, cmd_size: %d, fence_id: %lld, type: %d, dropped.\n", + task, task->cmd_size, task->fence_id, task->type); + } + + if(task->type == task_type_render) + { + task_dma_t *render = task->task_render; + gpu_context_t *context = task->context; + + if(adapter->display_debugbus_flag) + { + gf_info("task: %p, context: %x, tid: %d, allocations: %d, patch locations: %d, sync objects: %d.\n", + render, context->handle, context->tid, + render->allocation_list_size, render->patch_location_list_size, render->sync_object_list_size); + } + } + } + } + + gf_mutex_unlock(sch_mgr->task_list_lock); +} + + diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_workerthread.c b/drivers/gpu/drm/arise/core/vidsch/vidsch_workerthread.c new file mode 100755 index 0000000000000..40c9c0b3ef3a1 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch_workerthread.c @@ -0,0 +1,287 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_adapter.h" +#include "vidsch.h" +#include "vidschi.h" +#include "vidsch_workerthread.h" +#include "vidsch_sync.h" +#include "vidsch_submit.h" +#include "context.h" +#include "perfevent.h" + +void vidschi_dump_task_pool(struct os_printer *p, adapter_t *adapter, pending_task_pool_t *pool, const char *log_str) +{ + task_desc_t *task = NULL; + + pending_task_pool_t dump_pool; + + int idx = 0; + + vidschi_init_task_pool(&dump_pool, FALSE); + + vidschi_splice_task_pool(&dump_pool, pool); + + if(dump_pool.task_num <= 0) return; + + gf_printf(p, "********* Begin Dump %s, task_num: %d.\n", log_str, dump_pool.task_num); + + list_for_each_entry(task, &dump_pool.task_list, schedule_node) + { + vidschi_dump_task(p, adapter, task, idx++, FALSE); + } + + vidschi_splice_task_pool(pool, &dump_pool); + + vidschi_fini_task_pool(&dump_pool); +} + +static int vidschi_try_submit_pending_task(vidsch_mgr_t *sch_mgr, pending_task_pool_t *pool) +{ + adapter_t *adapter = sch_mgr->adapter; + task_desc_t *task = NULL; + gpu_context_t *context = NULL; + + pending_task_pool_t schedule_pool; + pending_task_pool_t unready_pool; + + unsigned long long task_id = 0ll; + unsigned long long timestamp = 0ll; + unsigned long long global_task_id = 0ll; + int submited_count = 0; + + int submitted = FALSE, signaled = FALSE; + + vidschi_init_task_pool(&schedule_pool, TRUE); + vidschi_init_task_pool(&unready_pool, FALSE); + + vidschi_splice_task_pool(&schedule_pool, pool); + submited_count = schedule_pool.task_num; + + while(!list_empty(&schedule_pool.task_list)) + { + task = vidschi_fetch_first_task_from_pool(&schedule_pool); + + if(!vidschi_can_submit_task(task) || + (sch_mgr->task_id_lock && task->global_task_id != sch_mgr->last_submit_task_id + 1)) + { + vidschi_add_task_to_pool(&unready_pool, task); + continue; + } + + context = task->context; + task_id = task->context_task_id; + global_task_id = task->global_task_id; + submitted = FALSE; + + switch (task->type) + { + case task_type_sync_wait: + + gf_get_nsecs(×tamp); + + if(vidschi_try_wait(task->task_wait, FALSE) == S_OK) + { + submitted = TRUE; + } + else if(vidschi_is_server_wait_timeout(task->task_wait, timestamp)) + { + /* if timeout, treat it as signaled.*/ + submitted = TRUE; + } + + if(submitted) + { + context->last_submit_to_sw = task_id; + if(sch_mgr->task_id_lock) + { + gf_assert(sch_mgr->last_submit_task_id == global_task_id - 1, "wait sch_mgr->last_submit_task_id == global_task_id - 1"); + sch_mgr->last_submit_task_id = global_task_id; + } + gf_task_submit_trace_event(adapter->index << 16 | context->engine_index, context->handle, task_id, task->type, 0, GF_SYNC_OBJ_WAIT_ON_SERVER); + vidschi_release_wait_task(task->task_wait); + } + + if ((adapter->ctl_flags.perf_event_enable)&&(submitted == TRUE)) + { + gf_perf_event_t perf_event; + + gf_memset(&perf_event, 0, sizeof(gf_perf_event_t)); + gf_get_nsecs(×tamp); + + perf_event.header.timestamp_high = timestamp >> 32; + perf_event.header.timestamp_low = (timestamp) & 0xffffffff; + + perf_event.header.size = sizeof(gf_perf_event_wait_on_server_finish_t); + perf_event.header.type = GF_PERF_EVENT_WAIT_ON_SERVER_FINISH; + perf_event.wait_on_server_finish.engine_idx = context->engine_index; + perf_event.wait_on_server_finish.gpu_context = context->handle; + perf_event.wait_on_server_finish.task_id_high= task_id >> 32; + perf_event.wait_on_server_finish.task_id_low = task_id & 0xffffffff;; + + perf_event_add_event(adapter, &perf_event); + } + + break; + + case task_type_sync_signal: + + if(vidschi_try_signal(task->task_signal) == S_OK) + { + signaled = TRUE; + submitted = TRUE; + + context->last_submit_to_sw = task_id; + if(sch_mgr->task_id_lock) + { + gf_assert(sch_mgr->last_submit_task_id == global_task_id - 1, "signal sch_mgr->last_submit_task_id == global_task_id - 1"); + sch_mgr->last_submit_task_id = global_task_id; + } + + gf_task_submit_trace_event(adapter->index << 16 | context->engine_index, context->handle, task_id, task->type, 0, 0); + + gf_free(task); + } + break; + + case task_type_render: + + if (vidschi_can_prepare_in_worker_thread(sch_mgr, task->task_render)) + { + vidschi_prepare_and_submit_dma(sch_mgr, task->task_render); + + context->last_submit_to_sw = task_id; + + if (sch_mgr->task_id_lock) + { + gf_assert(sch_mgr->last_submit_task_id == global_task_id - 1, "render sch_mgr->last_submit_task_id == global_task_id - 1"); + sch_mgr->last_submit_task_id = global_task_id; + } + + submitted = TRUE; + } + + break; + + default: + submitted = TRUE; + gf_error("unkonw task type: %d.\n", task->type); + break; + } + + if(submitted) + { + if(pool == &sch_mgr->normal_task_pool) + { + gf_up(sch_mgr->normal_pool_sema); + if(context->context_ctrl) + { + gf_up(context->context_sema); + } + + } + } + else + { + vidschi_add_task_to_pool(&unready_pool, task); + } + } + + /* check if still have task unready, merge it to sch_mgr pending_queue */ + if(unready_pool.task_num > 0) + { + submited_count -= unready_pool.task_num; + vidschi_splice_task_pool(pool, &unready_pool); + } + +#if 0 + if(signaled) + { + /* try wakeup all thread for none fence syncobj*/ + } +#endif + + vidschi_fini_task_pool(&schedule_pool); + vidschi_fini_task_pool(&unready_pool); + + gf_atomic_sub(sch_mgr->total_task_num, submited_count); + return S_OK; +} + + +/* +** worker thread will be wakeup in three place: +** 1 main thread when add task to task queue +** 2 fence interrupt handler, trigger flip queue +** 3 v-sync interrupt handler, trigger task queue and flip queue +*/ +int vidsch_worker_thread_event_handler(void *data, gf_event_status_t ret) +{ + vidsch_mgr_t *sch_mgr = data; + adapter_t *adapter = sch_mgr->adapter; + pending_task_pool_t *normal = &sch_mgr->normal_task_pool; + + int try_freeze_num = 0; + +try_again: + + if(normal->task_num > 0) + { + vidschi_try_submit_pending_task(sch_mgr, normal); + } + + sch_mgr->worker_thread->can_freeze = FALSE; + + if(gf_freezing()) + { + /* if need freezing, we should cleanup task in thread firstly */ + if(!vidschi_worker_thread_idle(sch_mgr)) + { + gf_info("*** ENGINE[%d] wait render finished: normal: %dm try_freeze_num: %d\n", + sch_mgr->engine_index, normal->task_num, try_freeze_num); + + gf_msleep(10); //relase CPU wait 10ms, and try_again + + try_freeze_num++; + + if(try_freeze_num > 100) + { + gf_info("*** render thread [%d] try cleanup queue: %d.\n", sch_mgr->engine_index, try_freeze_num); + + vidschi_dump_hang_info(adapter, 1<engine_index); + } + + goto try_again; + } + else + { + sch_mgr->worker_thread->can_freeze = TRUE; + + gf_debug("sleep render thread %d.\n", sch_mgr->engine_index); + } + } + + return 0; +} + + +/* when call this function, main thread will block itself to add task to queue */ +/* deprecated func, need delete later */ +void vidschi_wait_worker_thread_idle(vidsch_mgr_t *sch_mgr) +{ + while (!vidschi_worker_thread_idle(sch_mgr)) + { + gf_msleep(1); + } +} diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_workerthread.h b/drivers/gpu/drm/arise/core/vidsch/vidsch_workerthread.h new file mode 100644 index 0000000000000..3f0472946030e --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidsch_workerthread.h @@ -0,0 +1,187 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __VIDSCH_WORKER_THREAD_H__ +#define __VIDSCH_WORKER_THREAD_H__ + +static inline int vidschi_can_prepare_in_worker_thread(vidsch_mgr_t *sch_mgr, task_dma_t *task_dma) +{ + return vidschi_can_prepare_task_dma(sch_mgr, task_dma); +} + +static inline int vidschi_can_submit_task(task_desc_t *task) +{ + int can = FALSE; + + if(task->context_task_id - task->context->last_submit_to_sw == 1) + { + can = TRUE; + } + + return can; +} + +static inline void vidschi_init_task_pool(pending_task_pool_t *pool, int need_lock) +{ + list_init_head(&pool->task_list); + + pool->task_num = 0; + pool->lock = need_lock ? gf_create_spinlock(0) : NULL; +} + +static inline void vidschi_fini_task_pool(pending_task_pool_t *pool) +{ + if(pool->lock) + { + gf_destroy_spinlock(pool->lock); + + pool->lock = NULL; + } +} + +static inline void vidschi_add_task_to_pool(pending_task_pool_t *pool, task_desc_t *task) +{ + if(pool->lock) gf_spin_lock(pool->lock); + + list_add_tail(&task->schedule_node, &pool->task_list); + + pool->task_num++; + + if(pool->lock) gf_spin_unlock(pool->lock); +} + +static inline void vidschi_add_task_to_pool_head(pending_task_pool_t *pool, task_desc_t *task) +{ + if(pool->lock) gf_spin_lock(pool->lock); + + list_add(&task->schedule_node, &pool->task_list); + + pool->task_num++; + + if(pool->lock) gf_spin_unlock(pool->lock); +} + +/* fetch mean get and del */ +static inline task_desc_t *vidschi_fetch_first_task_from_pool(pending_task_pool_t *pool) +{ + task_desc_t *task = NULL; + + if(pool->lock) gf_spin_lock(pool->lock); + + if(!list_empty(&pool->task_list)) + { + task = list_first_entry(&pool->task_list, task_desc_t, schedule_node); + + list_del(&task->schedule_node); + + pool->task_num--; + } + + if(pool->lock) gf_spin_unlock(pool->lock); + + return task; +} + +/* get and return */ +static inline task_desc_t *vidschi_get_first_task_from_pool(pending_task_pool_t *pool) +{ + task_desc_t *task = NULL; + + if(pool->lock) gf_spin_lock(pool->lock); + + if(!list_empty(&pool->task_list)) + { + task = list_first_entry(&pool->task_list, task_desc_t, schedule_node); + } + + if(pool->lock) gf_spin_unlock(pool->lock); + + return task; +} + +static inline void vidschi_del_task_from_pool(pending_task_pool_t *pool, task_desc_t *task) +{ + if(pool->lock) gf_spin_lock(pool->lock); + + list_del(&task->schedule_node); + + pool->task_num--; + + if(pool->lock) gf_spin_unlock(pool->lock); +} + +static inline void vidschi_splice_task_pool(pending_task_pool_t *dst, pending_task_pool_t *src) +{ + if(src->lock != NULL) gf_spin_lock(src->lock); + if(dst->lock != NULL) gf_spin_lock(dst->lock); + + list_splice_init(&src->task_list, &dst->task_list); + + dst->task_num += src->task_num; + src->task_num = 0; + + if(dst->lock != NULL) gf_spin_unlock(dst->lock); + if(src->lock != NULL) gf_spin_unlock(src->lock); + +} + +extern void vidschi_emit_dma_fence(vidsch_mgr_t *sch_mgr, task_desc_t *task); +static inline int vidschi_add_task_to_pending_queue(vidsch_mgr_t *sch_mgr, task_desc_t *task) +{ + gpu_context_t *context = task->context; + pending_task_pool_t *pool = &sch_mgr->normal_task_pool; + + + gf_down(sch_mgr->normal_pool_sema); + if(context->context_ctrl) + { + gf_down(context->context_sema); + } + + + if (sch_mgr->task_id_lock) + { + gf_mutex_lock(sch_mgr->task_id_lock); + task->global_task_id = ++sch_mgr->task_id; + gf_mutex_unlock(sch_mgr->task_id_lock); + } + + if (task->need_dma_fence) + { + vidschi_emit_dma_fence(sch_mgr, task); + } + + gf_atomic_inc(sch_mgr->total_task_num); + vidschi_add_task_to_pool(pool, task); + + util_wakeup_event_thread(sch_mgr->worker_thread); + + return S_OK; +} + +static inline int vidschi_worker_thread_idle(vidsch_mgr_t *sch_mgr) +{ + pending_task_pool_t *normal = &sch_mgr->normal_task_pool; + + int idle = (normal->task_num == 0); + + return idle; +} + +extern int vidsch_worker_thread_event_handler(void *data, gf_event_status_t ret); +extern void vidschi_wait_worker_thread_idle(vidsch_mgr_t *sch_mgr); +extern void vidschi_dump_task_queue(adapter_t *adapter, queue_t *queue, const char *log_str); + +#endif + diff --git a/drivers/gpu/drm/arise/core/vidsch/vidschi.h b/drivers/gpu/drm/arise/core/vidsch/vidschi.h new file mode 100644 index 0000000000000..d1116b4beebb1 --- /dev/null +++ b/drivers/gpu/drm/arise/core/vidsch/vidschi.h @@ -0,0 +1,341 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __VIDSCHI_H__ +#define __VIDSCHI_H__ + +#include "queue.h" +#include "util.h" +#include "kernel_interface.h" + +#define MAX_OBJECT_WAITED 8 +#define MAX_OBJECT_SIGNALED 8 + +#if defined(ANDROID) +#define HW_HANG_LOG_FILE "/data/gf_hw_hang.log" +#else +#define HW_HANG_LOG_FILE "/var/log/gf_hw_hang.log" +#endif + +#define DAEMON_THREAD_INTERVAL 500 //0.5s + +#if defined(GFX_ONLY_FPGA) || defined(VMI_MODE) +#define HW_HANG_MAX_TIMEOUT_NS (200000 * 1000000ll) //200s +#define HW_HANG_FAST_RECOVERY_TIMEOUT_NS HW_HANG_MAX_TIMEOUT_NS //200s +#define SYNC_OBJECT_MAX_SERVER_WAIT_TIME_NS (2000000 * 1000000ll) //2000s +#define ENGINE_IDLE_TIMEOUT_IN_MS (300 * 1000000ll) //300sec +#else +#define HW_HANG_MAX_TIMEOUT_NS (60000 * 1000000ll) //60s +#define HW_HANG_FAST_RECOVERY_TIMEOUT_NS (6000 * 1000000ll) //6s +#define SYNC_OBJECT_MAX_SERVER_WAIT_TIME_NS (90000 * 1000000ll) //90s +#define ENGINE_IDLE_TIMEOUT_IN_MS (20 * 1000000ll) //20sec +#endif + +#ifdef VMI_MODE +#define CAN_SUBMIT_IN_MAIN_THREAD TRUE +#else +#define CAN_SUBMIT_IN_MAIN_THREAD FALSE +#endif + +#define HW_HANG_MAX_TIMEOUT_NS_ON_QT (200000 * 1000000ll) // 200s +#define SYNC_OBJECT_MAX_SERVER_WAIT_TIME_NS_ON_QT (200000 * 1000000ll) // 200s + +#define PRESENT_SRC_ALLOCATION_INDEX 1 +#define PRESENT_DST_ALLOCATION_INDEX 2 + +#define PENDING_TASK_QUEUE_LENGTH 32 +#define FLIP_QUEUE_LENGTH 16 + +#define PRESENT_BUFFER_SIZE 0x00004000 +#define PRESENT_PATCH_COUNT 0x00000100 +#define PRESENT_ALLOCATION_COUNT 0x00000004 +#define PRESENT_COUNT_CMD_SIZE 0x00000020 + + +/* engine support task type */ +#define ENGINE_CAPS_PAGING bit_0 +#define ENGINE_CAPS_PRESENT_2DBLT bit_1 +#define ENGINE_CAPS_PRESENT_3DBLT bit_2 +#define ENGINE_CAPS_PRESENT_DMAFLIP bit_3 +#define ENGINE_CAPS_PRESENT_MMIOFLIP bit_4 +#define ENGINE_CAPS_PRESENT_OVERLAYFLIP bit_5 +#define ENGINE_CAPS_2D_GRAPHICS bit_6 +#define ENGINE_CAPS_3D_GRAPHICS bit_7 +#define ENGINE_CAPS_VIDEO_DECODE bit_8 +#define ENGINE_CAPS_VIDEO_ENCODE bit_9 +#define ENGINE_CAPS_VIDEO_VPP bit_10 +#define ENGINE_CAPS_VIDEO_CAPTURE bit_11 +#define ENGINE_CAPS_CS bit_12 + + +/* misc hw engine caps*/ + +#define ENGINE_CAPS_NO_HWCTX bit_30 + + +#define ENGINE_CAPS_PRESENT_ALL (ENGINE_CAPS_PRESENT_2DBLT | ENGINE_CAPS_PRESENT_3DBLT | \ + ENGINE_CAPS_PRESENT_DMAFLIP | ENGINE_CAPS_PRESENT_MMIOFLIP | \ + ENGINE_CAPS_PRESENT_OVERLAYFLIP) + + +#define ENGINE_CAPS_SUPPORT_ALL (ENGINE_CAPS_PAGING | ENGINE_CAPS_PRESENT_ALL | \ + ENGINE_CAPS_2D_GRAPHICS | ENGINE_CAPS_3D_GRAPHICS | \ + ENGINE_CAPS_VIDEO_DECODE | ENGINE_CAPS_VIDEO_ENCODE | \ + ENGINE_CAPS_VIDEO_VPP) + + +#define ENGINE_CAPS_VIDEO (ENGINE_CAPS_VIDEO_DECODE | ENGINE_CAPS_VIDEO_ENCODE | \ + ENGINE_CAPS_VIDEO_VPP) + + +#define ENGINE_CAPS_GFX (ENGINE_CAPS_2D_GRAPHICS | ENGINE_CAPS_3D_GRAPHICS) + +#define ENGINE_CAPS_MANUAL_POWER_CLOCK (ENGINE_CAPS_VIDEO_DECODE | ENGINE_CAPS_VIDEO_ENCODE | \ + ENGINE_CAPS_VIDEO_VPP) + +#define ENGINE_CTRL_DISABLE bit_0 +#define ENGINE_CTRL_THREAD_ENABLE bit_1 + + +/* include heap and list node header files */ +/* include wdk header files */ + +typedef struct _vidsch_query_private +{ + unsigned char engine_count; /* out: total engine count */ + unsigned int pcie_segment_id; + unsigned int local_segment_id; + unsigned int fence_buffer_segment_id; + unsigned int engine_caps[MAX_ENGINE_COUNT]; + unsigned int engine_ctrl[MAX_ENGINE_COUNT]; + unsigned int engine_hw_queue_size[MAX_ENGINE_COUNT]; + unsigned int dma_segment[MAX_ENGINE_COUNT]; /* out: dma heap segment */ + unsigned int dma_buffer_size[MAX_ENGINE_COUNT]; /* out: dma heap size */ + unsigned int pcie_memory_size[MAX_ENGINE_COUNT]; /* out: pcie memory size need be reserved */ + unsigned int local_memory_size[MAX_ENGINE_COUNT]; /* out: local memory size need be reserved */ + unsigned int schedule_serialize[MAX_ENGINE_COUNT]; /* out: if this engine schedule serial or percontext */ + struct vidsch_chip_func *engine_func[MAX_ENGINE_COUNT]; +}vidsch_query_private_t; + +typedef struct _vidsch_private_send_count +{ + unsigned char *dma_buffer0; + unsigned char *dma_buffer; + unsigned int dma_size; + unsigned long long present_id; +}vidsch_private_send_count_t; + +typedef struct vidsch_chip_func vidsch_chip_func_t; +typedef struct vidschedule_chip_func vidschedule_chip_func_t; + +typedef struct vidsch_wait_fence +{ + adapter_t *adapter; + int engine; + + union { + struct { + unsigned long long fence_id; + }; + + struct { + vidmm_allocation_t *allocation; + int read_only; + }; + }; +}vidsch_wait_fence_t; + +typedef struct vidsch_fence_buffer +{ + vidmm_segment_memory_t *reserved_memory; + + unsigned int bitmap_size; + unsigned int total_num; + unsigned int left_num; + int free_start; + + struct os_spinlock *bitmap_lock; + unsigned long *bitmap; + void *backup; +}vidsch_fence_buffer_t; + + +typedef struct __pending_task_pool +{ + struct os_spinlock *lock; + struct list_head task_list; + unsigned int task_num; +}pending_task_pool_t; + +/* scheduler manager is corresponding to hardware engine */ +typedef struct _vidsch_mgr +{ + adapter_t *adapter; /* pointer to adapter */ + + unsigned int engine_caps; /* hw caps for this engine */ + unsigned int engine_ctrl; /* how to use this engine */ + unsigned int engine_index; /* engine index */ + + struct os_spinlock *fence_lock; + + unsigned int hw_queue_size; + int uncomplete_task_num; + int prepare_task_num; + + struct os_mutex *task_id_lock; // if NULL means percontext schedule + unsigned long long task_id; + unsigned long long last_submit_task_id; + + unsigned long long last_send_fence_id; /* last fence id sent to hardware engine */ + unsigned long long returned_fence_id; /* current fence id returned from hw, update in ISR */ + unsigned long long last_returned_fence_id; + + unsigned long long returned_timestamp; /* THE time returned fence id */ + + struct os_wait_event *fence_event; + struct os_mutex *engine_lock; + struct os_spinlock *power_status_lock; + + struct os_mutex *task_list_lock; + struct list_head submitted_task_list; /* submitted dma list */ + struct list_head allocated_task_list; /* allocated but not submit to HW */ + + vidmm_segment_memory_t *dma_reserved_memory; + heap_t *dma_heap; + + unsigned int dma_buffer_segment_id; /* segment id of dma buffer heap */ + + util_event_thread_t *worker_thread; + + //queue_t pending_queue; + struct os_sema *normal_pool_sema; + pending_task_pool_t normal_task_pool; + struct os_atomic *total_task_num; + + vidmm_segment_memory_t *local_reserved_memory; + + vidmm_segment_memory_t *pcie_reserved_memory; + + void *local_reserved_backup; + + int init_submit; /* need init submit ?*/ + + void *private_data; /* chip private data */ + unsigned int slot_count; + + unsigned int engine_dvfs_power_on; + + vidsch_chip_func_t *chip_func; + + int hang_index; + unsigned long long hang_fence_id; + unsigned int hang_hw_copy_mem; + + + unsigned long long last_idle; + unsigned long long last_busy; + unsigned int completely_idle; + unsigned long long idle_elapse; +}vidsch_mgr_t; + +/* for histroy issue, vidsch_mgr_t acctuall mean HW engine, and vidsch_global is engine manager */ +typedef struct vidschedule +{ + adapter_t *adapter; + + int disable_schedule; + + util_event_thread_t *daemon_thread_destory_allocation; + util_event_thread_t *daemon_thread_check_hang; + + unsigned int hw_hang; /* one bit for one engine, added for video module checking hw hang by looping */ + + unsigned int dvfs_init; + struct os_spinlock *dvfs_status_lock; + struct os_spinlock *power_status_lock; + unsigned int clock_patch_done; + + struct os_rwsema *rw_lock; + + void *private_data; + + unsigned int busy_engine_mask; + + vidschedule_chip_func_t *chip_func; +}vidschedule_t; + +struct vidsch_chip_func +{ + int (*initialize)(adapter_t *adapter, vidsch_mgr_t *sch_mgr); + int (*destroy)(vidsch_mgr_t *sch_mgr); + + int (*save)(vidsch_mgr_t *sch_mgr); + void (*restore)(vidsch_mgr_t *sch_mgr, unsigned int pm); + + int (*render)(gpu_context_t *gpu_context, task_dma_t *task_dma); + + int (*patch)(adapter_t *adapter, task_dma_t *task_dma); + int (*submit)(adapter_t *adapter, vidsch_mgr_t *sch_mgr, task_dma_t *task_dma); + + unsigned long long (*update_fence_id)(vidsch_mgr_t *vidsch); + void (*set_fence_id)(vidsch_mgr_t *sch_mgr, unsigned long long fence_id);//for hw null use only. set the fence id with cpu. + int (*reset_hw)(vidsch_mgr_t *vidsch); + + void (*dump_hang_info)(vidsch_mgr_t *sch_mgr); + void (*dump_hang)(adapter_t *adapter); + + int (*cil2_misc)(vidsch_mgr_t *sch_mgr, krnl_cil2_misc_t *cil2); + void (*set_miu_reg)(adapter_t *adapter,gf_query_info_t *info); + void (*read_miu_reg)(adapter_t *adapter,gf_query_info_t *info); + int (*power_clock)(vidsch_mgr_t *sch_mgr, unsigned int off); +}; + +struct vidschedule_chip_func +{ + void (*dvfs_tuning)(adapter_t* adapter); + void (*power_tuning)(adapter_t* adapter, unsigned int gfx_only); + + void (*dump_info)(struct os_seq_file *seq_file, adapter_t *adapter); + void (*dump_debugbus)(struct os_printer *p, adapter_t *adapter); + void (*get_set_reg)(adapter_t *adapter, gf_query_info_t *info); +}; + +extern int vidschi_can_prepare_task_dma(vidsch_mgr_t *sch_mgr, task_dma_t *dma); +extern int vidschi_send_to_submit_queue(vidsch_mgr_t *sch_mgr, task_dma_t *task_dma); +extern void vidschi_deinit_render_sync_object_list(vidsch_mgr_t *sch_mgr, task_dma_t *render); + +extern void vidschi_engine_dvfs_power_on(vidsch_mgr_t *sch_mgr); +extern void vidschi_try_power_tuning(adapter_t *adapter, unsigned int gfx_only); + +extern unsigned long long vidschi_inc_send_fence_id(vidsch_mgr_t *sch_mgr, int dec_prepare_num); + +extern void vidschi_dump_hang_info(adapter_t *adapter, unsigned int hang_engines); + +extern void vidschi_dump_general_task_info(struct os_printer *p, task_desc_t *task); +extern void vidschi_dump_task(struct os_printer *p, adapter_t *adapter, task_desc_t *task, int idx, int dump_detail); +extern void vidschi_dump_task_pool(struct os_printer *p, adapter_t *adapter, pending_task_pool_t *pool, const char *log_str); + +extern int vidsch_query_chip(adapter_t *adapter, vidsch_query_private_t *info); + +extern int vidschi_init_daemon_thread(adapter_t *adapter); +extern int vidschi_deinit_daemon_thread(adapter_t *adapter); + +extern dma_node_t * vidschi_allocate_dma_node(vidsch_mgr_t *vidsch_mgr, unsigned int dma_size); + +extern void vidschi_update_and_release_dma_fence(adapter_t *adapter, task_desc_t *task); +extern void vidschi_notify_dma_fence(adapter_t *adapter); + +#endif + + diff --git a/drivers/gpu/drm/arise/gf_version.h b/drivers/gpu/drm/arise/gf_version.h new file mode 100644 index 0000000000000..dc267e41573dd --- /dev/null +++ b/drivers/gpu/drm/arise/gf_version.h @@ -0,0 +1,14 @@ +#define DRIVER_DATE "07/15/2024" +#define DRIVER_MAJOR 0x25 +#define DRIVER_MINOR 0x00 +#define DRIVER_PATCHLEVEL 0x33 +#define DRIVER_CLASS "" +#define DRIVER_NAME arise +#define DRIVER_VENDOR "Glenfly Tech Co., Ltd." +#define DRIVER_LICENSE "Glenfly" +#define DRIVER_VERSION ((DRIVER_MAJOR<<24)|(DRIVER_MINOR<<16)|DRIVER_PATCHLEVEL) +#define DRIVER_VERSION_CHAR "25.00.33" +#define OS_VERSION "" +#define CC_VERSION "" +#define LD_VERSION "" + diff --git a/drivers/gpu/drm/arise/linux/Makefile b/drivers/gpu/drm/arise/linux/Makefile new file mode 100644 index 0000000000000..0b1243c386bf6 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/Makefile @@ -0,0 +1,58 @@ + +ifeq ($(CONFIG_ARM64), y) + ccflags-y += -mstrict-align +ifeq ($(CONFIG_KYLINOS_DESKTOP), y) + ccflags-y += -DKYLIN +else ifeq ($(CONFIG_KYLINOS_SERVER), y) + ccflags-y += -DKYLIN +endif +else ifeq ($(CONFIG_MIPS), y) + ccflags-y += -mips64r2 -D__mips64__ -mlong-calls +endif + +ccflags-y += -fms-extensions + +ccflags-y += \ + -I$(GFGPU_FULL_PATH)/shared \ + -I$(GFGPU_FULL_PATH)/core/include \ + -I$(GFGPU_FULL_PATH)/cbios \ + -I$(GFGPU_FULL_PATH)/linux + + +linux-objs:= \ + os_interface.o \ + gf.o \ + gf_driver.o \ + ../shared/os_shared.o \ + gf_debugfs.o \ + gf_sysfs.o \ + gf_ioctl.o \ + gf_gem.o \ + gf_fence.o \ + gf_trace_events.o \ + gf_atomic.o \ + gf_connector.o \ + gf_crtc.o \ + gf_disp.o \ + gf_drmfb.o \ + gf_encoder.o \ + gf_irq.o \ + gf_plane.o \ + gf_fbdev.o \ + gf_cbios.o \ + gf_params.o \ + gf_capture_drv.o \ + gf_vip.o \ + gf_wb.o \ + gf_i2c.o \ + gf_sink.o \ + gf_splice.o \ + e3k/gf_irq_e3k.o + +ifeq ($(HW_NULL), 1) + linux-objs += gf_hw_null.o +else + linux-objs += gf_pcie.o +endif + +$(PRO_DRIVER_NAME)-objs += $(addprefix linux/, $(linux-objs)) diff --git a/drivers/gpu/drm/arise/linux/e3k/gf_irq_e3k.c b/drivers/gpu/drm/arise/linux/e3k/gf_irq_e3k.c new file mode 100755 index 0000000000000..a4ff24290ac1c --- /dev/null +++ b/drivers/gpu/drm/arise/linux/e3k/gf_irq_e3k.c @@ -0,0 +1,237 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_irq_e3k.h" + +static void gf_translate_interrupt_bits(disp_info_t* disp_info, int sw2hw, intr_info_t* info, int* masks) +{ + adapter_info_t* adapter = disp_info->adp_info; + + if(!info || !masks) + { + return; + } + + if(sw2hw) + { + info->biu_intr_bits = 0; + info->csp_intr_bits = 0; + + info->biu_intr_bits |= (*masks & INT_VSYNC1)? VSYNC1_INT : 0; + info->biu_intr_bits |= (*masks & INT_VSYNC2)? VSYNC2_INT : 0; + info->biu_intr_bits |= (*masks & INT_VSYNC3)? VSYNC3_INT : 0; + info->biu_intr_bits |= (*masks & INT_VSYNC4)? VSYNC4_INT : 0; + info->biu_intr_bits |= (*masks & INT_DP1)? DP1_INT : 0; + info->biu_intr_bits |= (*masks & INT_DP2)? DP2_INT : 0; + info->biu_intr_bits |= (*masks & INT_DP3)? DP3_INT : 0; + info->biu_intr_bits |= (*masks & INT_DP4)? DP4_INT : 0; + info->biu_intr_bits |= (*masks & INT_VIP1)? VIP1_INT : 0; + info->biu_intr_bits |= (*masks & INT_VIP2)? VIP2_INT : 0; + info->biu_intr_bits |= (*masks & INT_VIP3)? VIP3_INT : 0; + info->biu_intr_bits |= (*masks & INT_VIP4)? VIP4_INT : 0; + if((adapter->chip_id == CHIP_ARISE1020) && adapter->non_simul_chip) + { + info->biu_intr_bits |= (*masks & INT_HDCODEC)? HDCODEC_INT_1020 : 0; + } + else + { + info->biu_intr_bits |= (*masks & INT_HDCODEC)? HDCODEC_INT : 0; + } + info->biu_intr_bits |= (*masks & INT_HDCP)? HDCP_INT : 0; + + info->csp_intr_bits |= (*masks & INT_FENCE)? ENGINE_FENCE_INT : 0; + info->csp_intr_bits |= (*masks & INT_FE_HANG_VD0)? FE_HANG_VD0_INT : 0; + info->csp_intr_bits |= (*masks & INT_BE_HANG_VD0)? BE_HANG_VD0_INT : 0; + info->csp_intr_bits |= (*masks & INT_FE_ERROR_VD0)? FE_ERROR_VD0_INT : 0; + info->csp_intr_bits |= (*masks & INT_BE_ERROR_VD0)? BE_ERROR_VD0_INT : 0; + info->csp_intr_bits |= (*masks & INT_FE_HANG_VD1)? FE_HANG_VD1_INT : 0; + info->csp_intr_bits |= (*masks & INT_BE_HANG_VD1)? BE_HANG_VD1_INT : 0; + info->csp_intr_bits |= (*masks & INT_FE_ERROR_VD1)? FE_ERROR_VD1_INT : 0; + info->csp_intr_bits |= (*masks & INT_BE_ERROR_VD1)? BE_ERROR_VD1_INT : 0; + } + else + { + *masks = 0; + *masks |= (info->biu_intr_bits & VSYNC1_INT)? INT_VSYNC1 : 0; + *masks |= (info->biu_intr_bits & VSYNC2_INT)? INT_VSYNC2 : 0; + *masks |= (info->biu_intr_bits & VSYNC3_INT)? INT_VSYNC3 : 0; + *masks |= (info->biu_intr_bits & VSYNC4_INT)? INT_VSYNC4 : 0; + *masks |= (info->biu_intr_bits & DP1_INT)? INT_DP1 : 0; + *masks |= (info->biu_intr_bits & DP2_INT)? INT_DP2 : 0; + *masks |= (info->biu_intr_bits & DP3_INT)? INT_DP3 : 0; + *masks |= (info->biu_intr_bits & DP4_INT)? INT_DP4 : 0; + *masks |= (info->biu_intr_bits & VIP1_INT)? INT_VIP1 : 0; + *masks |= (info->biu_intr_bits & VIP2_INT)? INT_VIP2 : 0; + *masks |= (info->biu_intr_bits & VIP3_INT)? INT_VIP3 : 0; + *masks |= (info->biu_intr_bits & VIP4_INT)? INT_VIP4 : 0; + if((adapter->chip_id == CHIP_ARISE1020) && adapter->non_simul_chip) + { + *masks |= (info->biu_intr_bits & HDCODEC_INT_1020)? INT_HDCODEC : 0; + } + else + { + *masks |= (info->biu_intr_bits & HDCODEC_INT)? INT_HDCODEC : 0; + } + *masks |= (info->biu_intr_bits & HDCP_INT)? INT_HDCP: 0; + + *masks |= (info->csp_intr_bits & ENGINE_FENCE_INT)? INT_FENCE : 0; + *masks |= (info->csp_intr_bits & FE_HANG_VD0_INT)? INT_FE_HANG_VD0 : 0; + *masks |= (info->csp_intr_bits & BE_HANG_VD0_INT)? INT_BE_HANG_VD0 : 0; + *masks |= (info->csp_intr_bits & FE_ERROR_VD0_INT)? INT_FE_ERROR_VD0 : 0; + *masks |= (info->csp_intr_bits & BE_ERROR_VD0_INT)? INT_BE_ERROR_VD0 : 0; + *masks |= (info->csp_intr_bits & FE_HANG_VD1_INT)? INT_FE_HANG_VD1 : 0; + *masks |= (info->csp_intr_bits & BE_HANG_VD1_INT)? INT_BE_HANG_VD1 : 0; + *masks |= (info->csp_intr_bits & FE_ERROR_VD1_INT)? INT_FE_ERROR_VD1 : 0; + *masks |= (info->csp_intr_bits & BE_ERROR_VD1_INT)? INT_BE_ERROR_VD1 : 0; + } +} + +static int gf_get_intr_enable_mask_e3k(disp_info_t* disp_info) +{ + adapter_info_t* adapter = disp_info->adp_info; + intr_info_t intr_info = {0}; + int masks = 0; + + intr_info.biu_intr_bits = gf_read32(adapter->mmio + INTR_EN_REG); + intr_info.csp_intr_bits = gf_read32(adapter->mmio + ADV_INTR_EN_REG); + + gf_translate_interrupt_bits(disp_info, 0, &intr_info, &masks); + + return masks; +} + +static void gf_set_intr_enable_mask_e3k(disp_info_t* disp_info, int masks) +{ + adapter_info_t* adapter = disp_info->adp_info; + intr_info_t intr_info = {0}; + + gf_translate_interrupt_bits(disp_info, 1, &intr_info, &masks); + + if((masks & INT_FENCE) == 0) + { + gf_error("Found INT_FENCE disable by user! mask = 0x%08x when set mask\n", masks); +#ifdef _DEBUG_ + gf_dump_stack(); +#endif + } + + gf_write32(adapter->mmio + INTR_EN_REG, intr_info.biu_intr_bits); + gf_write32(adapter->mmio + ADV_INTR_EN_REG, intr_info.csp_intr_bits); +} + +static void gf_enable_msi_e3k(disp_info_t* disp_info) +{ + unsigned int tmp; + adapter_info_t* adapter = disp_info->adp_info; + + //when MSI is turned on from registry,the MSI address should have be written here by OS + tmp = gf_read32(adapter->mmio + 0x804C); + + if (tmp != 0) + { + tmp = gf_read32(adapter->mmio + 0x8048); + if ((tmp & 0x10000) == 0) + { + // Before turn on MSI we need clear all pending interrupts, clear all BIU interrupts + gf_write32(adapter->mmio + INTR_SHADOW_REG, 0); + + gf_write32(adapter->mmio + 0x8048, tmp | 0x10000); + } + } +} + +static void gf_disable_msi_e3k(disp_info_t* disp_info) +{ + unsigned int temp; + adapter_info_t* adapter = disp_info->adp_info; + + temp = gf_read32(adapter->mmio + 0x8048); + temp &= ~0x10000; + + gf_write32(adapter->mmio + 0x8048, temp); +} + +static int gf_disable_interrupt_e3k(disp_info_t* disp_info) +{ + adapter_info_t* adapter = disp_info->adp_info; + int intr_masks; + unsigned char mm8aa0; + + intr_masks = gf_get_intr_enable_mask_e3k(disp_info); //save enabled interrupts, later will restore it in enable_interrupt + + gf_write32(adapter->mmio + INTR_EN_REG, 0); //Disable all BIU interrupts + + gf_wmb(); + + //Disable all Advanced interrupts + gf_write32(adapter->mmio + ADV_INTR_EN_REG, 0x00); + gf_wmb(); + + //Disable adapter interrupts + mm8aa0 = gf_read8(adapter->mmio + 0x8AA0); + gf_write8(adapter->mmio + 0x8AA0, mm8aa0 & 0xFE); + gf_wmb(); + + gf_write32(adapter->mmio + INTR_SHADOW_REG, 0x00); //Clear all interrupts with any write to MM8574 + + return intr_masks; +} + +static void gf_enable_interrupt_e3k(disp_info_t* disp_info, int intr_masks) +{ + adapter_info_t* adapter = disp_info->adp_info; + intr_info_t intr_info = {0}; + unsigned char mm8aa0; + + gf_translate_interrupt_bits(disp_info, 1, &intr_info, &intr_masks); + + gf_write32(adapter->mmio + INTR_EN_REG, intr_info.biu_intr_bits); //Enable BIU specified interrupts + gf_write32(adapter->mmio + ADV_INTR_EN_REG, intr_info.csp_intr_bits); //Enable advanced interrupts + gf_wmb(); + + //enable adapter interrupt; + mm8aa0 = gf_read8(adapter->mmio + 0x8AA0); + gf_write8(adapter->mmio + 0x8AA0, mm8aa0 | 0x01); + + gf_wmb(); + gf_write32(adapter->mmio + INTR_SHADOW_REG, 0x00); //Clear all interrupts with any write to MM8574 +} + +static int gf_get_interrupt_mask_e3k(disp_info_t* disp_info) +{ + adapter_info_t* adapter = disp_info->adp_info; + intr_info_t intr_info = {0}; + int intr_masks = 0; + + gf_write32(adapter->mmio + INTR_SHADOW_REG, 0); + gf_mb(); + + intr_info.biu_intr_bits = gf_read32(adapter->mmio + INTR_SHADOW_REG); + intr_info.csp_intr_bits = gf_read32(adapter->mmio + ADV_SHADOW_REG); + + gf_translate_interrupt_bits(disp_info, 0, &intr_info, &intr_masks); + + return intr_masks; +} + +irq_chip_funcs_t irq_chip_funcs = +{ + .get_intr_enable_mask = gf_get_intr_enable_mask_e3k, + .set_intr_enable_mask = gf_set_intr_enable_mask_e3k, + .enable_msi = gf_enable_msi_e3k, + .disable_msi = gf_disable_msi_e3k, + .disable_interrupt = gf_disable_interrupt_e3k, + .enable_interrupt = gf_enable_interrupt_e3k, + .get_interrupt_mask = gf_get_interrupt_mask_e3k, +}; diff --git a/drivers/gpu/drm/arise/linux/e3k/gf_irq_e3k.h b/drivers/gpu/drm/arise/linux/e3k/gf_irq_e3k.h new file mode 100644 index 0000000000000..2f91ce04baca3 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/e3k/gf_irq_e3k.h @@ -0,0 +1,64 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _GF_IRQ_E3K_ +#define _GF_IRQ_E3K_ + +#include "../gf_irq.h" + + +#define INTR_EN_REG 0x8508 +#define ADV_INTR_EN_REG 0x854c +#define INTR_SHADOW_REG 0x8574 +#define ADV_SHADOW_REG 0x8578 + +typedef enum _BIU_INTR_BIT +{ + VSYNC1_INT = 0x1, + VSYNC2_INT = 0x4, + VSYNC3_INT = 0x8, + VSYNC4_INT = 0x10, + DP1_INT = 0x80, + DP2_INT = 0x100, + DP3_INT = 0x10000, + DP4_INT = 0x20000, + HDCODEC_INT_1020 = 0x200000, + HDCP_INT = 0x400000, + VIP1_INT = 0x1000000, + HDCODEC_INT = 0x4000000, + VIP2_INT = 0x8000000, + VIP3_INT = 0x10000000, + VIP4_INT = 0x40000000, +}BIU_INTR_BIT; + +typedef enum _CSP_INTR_BIT +{ + FE_HANG_VD0_INT = 0x1, + BE_HANG_VD0_INT = 0x2, + FE_ERROR_VD0_INT = 0x4, + BE_ERROR_VD0_INT = 0x8, + FE_HANG_VD1_INT = 0x10, + BE_HANG_VD1_INT = 0x20, + FE_ERROR_VD1_INT = 0x40, + BE_ERROR_VD1_INT = 0x80, + ENGINE_FENCE_INT = 0x8000000, +}CSP_INTR_BIT; + +typedef struct _intr_info +{ + unsigned int biu_intr_bits; + unsigned int csp_intr_bits; +}intr_info_t; + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf.c b/drivers/gpu/drm/arise/linux/gf.c new file mode 100644 index 0000000000000..d243216c9eb83 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf.c @@ -0,0 +1,76 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf.h" +#include "os_interface.h" +#include "gf_driver.h" +#include "gf_ioctl.h" +#include "gf_version.h" +#include "gf_debugfs.h" + +char *gf_fb_mode = NULL; //"800x600-32@60"; +#ifdef GF_HW_NULL +int gf_fb = 0; +#else +int gf_fb = 1; +#endif + +static int __init gf_init(void) +{ + int ret = -ENOMEM; + + gf_info("%s\n", DRIVER_VENDOR); + //gf_info("Version: %0d.%02d.%02d%s Build on: %s\n", DRIVER_MAJOR, DRIVER_MINOR, DRIVER_PATCHLEVEL, DRIVER_BRANCH, DRIVER_DATE); + gf_info("Version: %02x.%02x.%02x%s Build on: %s\n", DRIVER_MAJOR, DRIVER_MINOR, DRIVER_PATCHLEVEL, DRIVER_CLASS, DRIVER_DATE); + +#if GF_MALLOC_TRACK | GF_ALLOC_PAGE_TRACK | GF_MAP_PAGES_TRACK | GF_MAP_IO_TRACK + gf_mem_track_init(); +#endif + ret = gf_register_driver(); + + if(ret) + { + gf_error("register_driver() failed in init. ret:%x.\n", ret); + } + + return 0; +} + +static void __exit gf_exit(void) +{ + gf_unregister_driver(); + +#if GF_MALLOC_TRACK | GF_ALLOC_PAGE_TRACK | GF_MAP_PAGES_TRACK | GF_MAP_IO_TRACK + gf_mem_track_list_result(); +#endif + + gf_info("exit driver.\n"); +} + +module_init(gf_init); +module_exit(gf_exit); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRIVER_VERSION_CHAR); + +#ifndef KERNEL_2_4 +module_param(gf_fb, int, 0); +module_param(gf_fb_mode, charp, 0); +#else +MODULE_PARM(gf_fb_mode, "s"); +#endif + +MODULE_PARM_DESC(gf_fb, "enable gf fb driver"); +MODULE_PARM_DESC(gf_fb_mode, "Initial video mode:x-@"); +MODULE_PARM_DESC(gf_flip, "enable frame buffer flip support"); + diff --git a/drivers/gpu/drm/arise/linux/gf.h b/drivers/gpu/drm/arise/linux/gf.h new file mode 100644 index 0000000000000..52f1f4241fe32 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf.h @@ -0,0 +1,392 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_H__ +#define __GF_H__ + +#ifdef __KERNEL__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef DRM_VERSION_CODE +#define DRM_VERSION_CODE LINUX_VERSION_CODE +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,5,0) +#include +#include +#include +#include +#include +#include +#else +#include +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) +#include +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,4,0) +#include +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0) +#include +#endif + +#define __GF_MUTEX_DEBUG__ + +#ifdef CONFIG_PCI +#include +#endif + +#ifdef CONFIG_ARM_AMBA +#include +#endif + +#if defined(CONFIG_GENERIC_GPIO) +#include +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0) +#include +#include +#endif + +#ifdef CONFIG_SYNC +#ifndef __aarch64__ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) +#include +#elif defined(YHQILIN) && LINUX_VERSION_CODE == KERNEL_VERSION(4,4,131) +#else +#include <../drivers/staging/android/sync.h> +#endif +#endif +#endif + +#if defined(__alpha__) || defined(__powerpc__) +#include /* For pte_wrprotect */ +#endif + +#ifdef __alpha__ +#include +#endif + +#include +#include +#include +#include +#include +#ifdef CONFIG_MTRR +#include +#endif + +//#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) +#if defined(CONFIG_VGA_ARB) +#include +#endif +//#endif +#endif + +#ifdef CONFIG_FB +#include +#endif + +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) +#include /* For (un)lock_kernel */ +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#include +#endif + +#if defined(__i386__) || defined(__x86_64__) +//#include +#endif +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41) +#include +#else +#include +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) +#define HAS_SET_PAGES_ARRAY_WC +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) +#define HAS_VM_MMAP +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) +#define cap_t(x) (x).cap[0] +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) +#define NO_PROC_CREATE_FUNC +#endif + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) +#define SEQ_PRINTF +#endif + +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif + +#ifndef PM_EVENT_SLEEP +#define PM_EVENT_SLEEP PM_EVENT_SUSPEND +#endif + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) +#define acquire_console_sem console_lock +#define release_console_sem console_unlock +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) +#define HAS_SHRINKER +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) +#define HAS_SHRINK_CONTROL +#endif +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) +#define os_shmem_read_mapping_page(mapping, index, data) shmem_read_mapping_page(mapping, index) +#else +#define os_shmem_read_mapping_page(mapping, index, data) read_mapping_page(mapping, index, data) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,6) + +#define OS_KM_USER0 0 +#define OS_KM_USER1 0 + +#define os_kmap_atomic(a, b) kmap_atomic(a) +#define os_kunmap_atomic(a, b) kunmap_atomic(a) + +#else + +#define OS_KM_USER0 KM_USER0 +#define OS_KM_USER1 KM_USER1 + +#define os_kmap_atomic(a, b) kmap_atomic(a, b) +#define os_kunmap_atomic(a, b) kunmap_atomic(a, b) + +#endif + +#define GF_FUNC_NAME(name) (((name)[0] == 'z') && ((name[1] == 'x')))?((name) + 3):(name) + +struct gf_dma_addr_t +{ + dma_addr_t dma_addr; +}; + +struct os_atomic +{ + atomic_t counter; +}; + +struct os_spinlock +{ + spinlock_t lock; +}; + +struct os_sema +{ + struct semaphore lock; +}; + +struct os_rwsema +{ + struct rw_semaphore lock; +}; + +#ifndef mutex_init +struct os_mutex +{ + struct semaphore lock; +}; +#define mutex_init(lock) sema_init(lock, 1) +#define mutex_destroy(lock) sema_init(lock, -99) +#define mutex_lock(lock) down(lock) +#define mutex_trylock(lock) (down_trylock(lock) ? 0 : 1) +#define mutex_unlock(lock) up(lock) +#define mutex_lock_killable(lock) down_killable(lock) +#else +struct os_mutex +{ + struct mutex lock; +}; +#endif + +struct os_file +{ + struct file *filp; +}; + +struct os_seq_file +{ + struct seq_file *seq_file; +}; + +#ifndef _ALIGN_DOWN +#define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1))) +#endif + +struct os_pages_memory +{ + unsigned int size; + unsigned int page_size; + unsigned int need_flush:1; + unsigned int need_zero:1; + unsigned int fixed_page:1; + unsigned int page_4K_64K:1; + unsigned int noswap:1; + unsigned int dma32:1; //alloc in low 4G phys addr + unsigned int shared:1; + unsigned int userptr:1; + unsigned int has_dma_map:1; + unsigned int ref_cnt; + struct sg_table *st; + unsigned char *cache_type_per_page; + struct page **pages; // it's flatten of st + struct page **pages_temp; // it's temp workspace, avoid many gf_alloc(page_array) +}; + +struct os_wait_event +{ + atomic_t state; + wait_queue_head_t wait_queue; +}; + +struct os_wait_queue +{ + wait_queue_head_t wait_queue; +}; + +struct os_printer +{ + void (*printfn)(struct os_printer *p, struct va_format *vaf); + void *arg; +}; + +#ifdef CONFIG_X86_PAT +static inline int os_set_page_uc(struct page *pg) +{ + int retval; +#ifdef HAS_SET_PAGES_ARRAY_WC + retval = set_pages_array_uc(&pg, 1); +#else + retval = set_memory_uc((unsigned long)page_address(pg), 1); +#endif + + if(retval) + { + printk(KERN_ERR "gf" "set page to uc failed.\n"); + } + + return retval; +} + +static inline int os_set_page_wc(struct page *pg) +{ + int retval; +#ifdef HAS_SET_PAGES_ARRAY_WC + retval = set_pages_array_wc(&pg, 1); +#else + retval = set_memory_wc((unsigned long)page_address(pg), 1); +#endif + + if(retval) + { + printk(KERN_ERR "gf" "set page to wc failed.\n"); + } + + return retval; +} + +static inline int os_set_page_wb(struct page *pg) +{ + int retval; +#ifdef HAS_SET_PAGES_ARRAY_WC + retval = set_pages_array_wb(&pg, 1); +#else + retval = set_memory_wb((unsigned long)page_address(pg), 1); +#endif + + if(retval) + { + printk(KERN_ERR "gf" "set page to wb failed.\n"); + } + + return retval; +} +#endif + +extern pgprot_t os_get_pgprot_val(unsigned int *cache_type, pgprot_t old_prot, int io_map); +extern struct file *os_shmem_file_setup(const char *name, loff_t size, unsigned long flags); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +static inline struct proc_dir_entry* create_proc_read_entry(const char *name, ...) +{ + return NULL; +} +#endif + +#endif + diff --git a/drivers/gpu/drm/arise/linux/gf_atomic.c b/drivers/gpu/drm/arise/linux/gf_atomic.c new file mode 100644 index 0000000000000..c11a460c40baa --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_atomic.c @@ -0,0 +1,282 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_atomic.h" +#include "gf_kms.h" +#include "gf_sink.h" +#include "gf_splice.h" + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + +struct drm_atomic_state* gf_atomic_state_alloc(struct drm_device *dev) +{ + gf_ato_state_t *state = gf_calloc(sizeof(gf_ato_state_t)); + + if (!state || drm_atomic_state_init(dev, &state->base_ato_state) < 0) + { + gf_free(state); + return NULL; + } + + return &state->base_ato_state; +} + +void gf_atomic_state_clear(struct drm_atomic_state *s) +{ + drm_atomic_state_default_clear(s); +} + +void gf_atomic_state_free(struct drm_atomic_state *s) +{ + gf_ato_state_t *state = to_gf_atomic_state(s); + drm_atomic_state_default_release(s); + gf_free(state); +} + +struct drm_crtc_state* gf_crtc_duplicate_state(struct drm_crtc *crtc) +{ + gf_crtc_state_t* crtc_state, *cur_crtc_state; + + cur_crtc_state = to_gf_crtc_state(crtc->state); + + crtc_state = gf_calloc(sizeof(gf_crtc_state_t)); + if (!crtc_state) + { + return NULL; + } + + if(cur_crtc_state->sink) + { + crtc_state->sink = cur_crtc_state->sink; + gf_sink_get(crtc_state->sink); + } + + __drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base_cstate); + + return &crtc_state->base_cstate; +} + +void gf_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *s) +{ + gf_crtc_state_t* state = to_gf_crtc_state(s); + + if(state->sink) + { + gf_sink_put(state->sink); + } + + __drm_atomic_helper_crtc_destroy_state(s); + gf_free(state); +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +int gf_crtc_helper_check(struct drm_crtc *crtc, struct drm_atomic_state *atomic_state) +#else +int gf_crtc_helper_check(struct drm_crtc *crtc, struct drm_crtc_state *state) +#endif +{ + //a patch for HDMI & CRT on IGA1, when switch from IGA1->HDMI1 to IGA1->CRT with same timing, + //framework will not call crtc/encoder_set_mode, so we will meet active device/path error +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) + struct drm_crtc_state *state = drm_atomic_get_new_crtc_state(atomic_state, crtc); +#endif + + if (!state || !state->active) + { + return 0; + } + + if (state->enable && + !(state->plane_mask & 1 << drm_plane_index(crtc->primary))) { + DRM_DEBUG_ATOMIC("can't enable crtc-%d without enabling primary plane.\n", crtc->index); + return -EINVAL; + } + + if (!state->mode_changed && !drm_mode_equal(&state->adjusted_mode, &crtc->state->adjusted_mode)) + { + DRM_DEBUG_ATOMIC("Adj mode changed on crtc-%d, need do full modeset.\n", crtc->index); + state->mode_changed = 1; + } + else if (!state->mode_changed && state->connectors_changed) + { + DRM_DEBUG_ATOMIC("Connectors changed on crtc-%d, need do full modeset.\n", crtc->index); + state->mode_changed = 1; + } + + return 0; +} + +int gf_connector_atomic_set_property(struct drm_connector *connector, + struct drm_connector_state *state, + struct drm_property *property, + uint64_t val) +{ + int ret = 0; + gf_connector_t* gf_conn = to_gf_connector(connector); + gf_connector_state_t* gf_conn_state = to_gf_conn_state(state); + + ret = gf_splice_set_connector_property(state, property, val); + if (ret) + { + + DRM_ERROR("Invalid driver-private property '%s'\n", property->name); + } + + return ret; +} + +int gf_connector_atomic_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) +{ + int ret = 0; + gf_connector_t* gf_conn = to_gf_connector(connector); + gf_connector_state_t* gf_conn_state = to_gf_conn_state(state); + + ret = gf_splice_get_connector_property(state, property, val); + if (ret) + { + DRM_ERROR("Invalid driver-private property '%s'\n", property->name); + } + + return ret; +} + +struct drm_connector_state* gf_connector_duplicate_state(struct drm_connector *connector) +{ + gf_connector_state_t* gf_conn_state; + + gf_conn_state = gf_calloc(sizeof(gf_connector_state_t)); + if (!gf_conn_state) + { + return NULL; + } + + __drm_atomic_helper_connector_duplicate_state(connector, &gf_conn_state->base_conn_state); + + gf_splice_duplicate_connector_state(&gf_conn_state->base_conn_state, connector->state); + + return &gf_conn_state->base_conn_state; +} + +void gf_connector_destroy_state(struct drm_connector *connector, struct drm_connector_state *state) +{ + gf_connector_state_t *gf_conn_state = to_gf_conn_state(state); + __drm_atomic_helper_connector_destroy_state(state); + gf_free(gf_conn_state); +} + + + +static void gf_update_crtc_sink(struct drm_atomic_state *old_state) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_state, *new_crtc_state; + gf_crtc_state_t *new_gf_crtc_state; + struct drm_connector_state *new_conn_state; + struct drm_connector *connector; + gf_connector_t *gf_connector = NULL; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 12, 0) + struct drm_connector_state *old_conn_state; +#endif + int i, j; + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 12, 0) + for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) + { + new_crtc_state = crtc->state; +#else + for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) + { +#endif + new_gf_crtc_state = to_gf_crtc_state(new_crtc_state); + gf_connector = NULL; + + if (new_crtc_state->active && drm_atomic_crtc_needs_modeset(new_crtc_state)) + { + //find the first crtc matching connector + #if DRM_VERSION_CODE < KERNEL_VERSION(4, 12, 0) + for_each_connector_in_state(old_state, connector, old_conn_state, j) + { + new_conn_state = connector->state; + #else + for_each_new_connector_in_state(old_state, connector, new_conn_state, j) + { + #endif + if (new_conn_state->crtc == crtc) + { + gf_connector = to_gf_connector(connector); + break; + } + } + + if (gf_connector && new_gf_crtc_state->sink != gf_connector->sink) + { + gf_sink_put(new_gf_crtc_state->sink); + new_gf_crtc_state->sink = gf_connector->sink; + gf_sink_get(new_gf_crtc_state->sink); + } + } + + if (old_crtc_state->active && + drm_atomic_crtc_needs_modeset(new_crtc_state)) + { + if (!new_crtc_state->active) + { + gf_sink_put(new_gf_crtc_state->sink); + new_gf_crtc_state->sink = NULL; + } + } + } +} + +void gf_atomic_helper_commit_tail(struct drm_atomic_state *old_state) +{ + struct drm_device *dev = old_state->dev; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + uint32_t flags = DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET; +#else + bool flags = false; +#endif + + drm_atomic_helper_commit_modeset_disables(dev, old_state); + + drm_atomic_helper_commit_modeset_enables(dev, old_state); + + gf_update_crtc_sink(old_state); + + drm_atomic_helper_commit_planes(dev, old_state, flags); + + gf_atomic_commit_connector_prop(dev, old_state); + + drm_atomic_helper_commit_hw_done(old_state); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) + drm_atomic_helper_fake_vblank(old_state); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + drm_atomic_helper_wait_for_flip_done(dev, old_state); +#else + drm_atomic_helper_wait_for_vblanks(dev, old_state); +#endif + + drm_atomic_helper_cleanup_planes(dev, old_state); +} + + +#endif + diff --git a/drivers/gpu/drm/arise/linux/gf_atomic.h b/drivers/gpu/drm/arise/linux/gf_atomic.h new file mode 100644 index 0000000000000..bba7c0d5fc00a --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_atomic.h @@ -0,0 +1,56 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _GF_ATOMIC_H_ +#define _GF_ATOMIC_H_ + +#include "gf_disp.h" +#include "gf_cbios.h" + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + +struct drm_atomic_state* gf_atomic_state_alloc(struct drm_device *dev); + +void gf_atomic_state_clear(struct drm_atomic_state *s); + +void gf_atomic_state_free(struct drm_atomic_state *s); + +struct drm_crtc_state* gf_crtc_duplicate_state(struct drm_crtc *crtc); + +void gf_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *s); +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) + int gf_crtc_helper_check(struct drm_crtc *crtc, struct drm_atomic_state *state); +#else + int gf_crtc_helper_check(struct drm_crtc *crtc, struct drm_crtc_state *state); +#endif + +struct drm_connector_state* gf_connector_duplicate_state(struct drm_connector *connector); + +int gf_connector_atomic_set_property(struct drm_connector *connector, + struct drm_connector_state *state, + struct drm_property *property, + uint64_t val); + +int gf_connector_atomic_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val); + +void gf_connector_destroy_state(struct drm_connector *connector, struct drm_connector_state *state); + +void gf_atomic_helper_commit_tail(struct drm_atomic_state *old_state); + +#endif + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_capture_drv.c b/drivers/gpu/drm/arise/linux/gf_capture_drv.c new file mode 100644 index 0000000000000..5575e8e937b2a --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_capture_drv.c @@ -0,0 +1,162 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_disp.h" +#include "gf_vip.h" +#include "gf_wb.h" +#include "gf_capture_drv.h" +#include "gf_version.h" + +static disp_info_t *g_disp_info = NULL; + +void disp_register_capture(disp_info_t *disp_info, gf_capture_t *capture) +{ + capture->cf_next = disp_info->captures; + disp_info->captures = capture; +} + +void disp_unregister_capture(disp_info_t *disp_info, gf_capture_t *capture) +{ + gf_capture_t **actcf; + + for (actcf = &disp_info->captures; *actcf && *actcf != capture; actcf = &((*actcf)->cf_next)) + ; + + if (*actcf) + *actcf = (*actcf)->cf_next; +} + + +gf_capture_t *disp_find_capture(disp_info_t *disp_info, int id) +{ + + gf_capture_t *actcf; + + for (actcf = disp_info->captures; actcf && actcf->cf_fmt_id != id; actcf = actcf->cf_next) + ; + + return actcf; +} + + +int disp_capture_ctl(void *pdata, gf_capture_id_t id, void *params) +{ + disp_info_t *disp_info = (disp_info_t *)pdata; + + gf_capture_t *capture = disp_find_capture(disp_info, id); + + + if (!capture) + { + gf_error("wrong capture fmt id !!!\n"); + + return -1; + } + + return capture->cf_ctl(disp_info, capture, params); +} + + +void disp_capture_init(disp_info_t *disp_info) +{ + gf_info("disp cature init enter \n"); + disp_register_vip_capture(disp_info); + disp_register_wb_capture(disp_info); + + //TODO: refine the card index function + g_disp_info = disp_info; + + gf_info("disp cature init out \n"); +} + +void disp_capture_deinit(disp_info_t *disp_info) +{ + gf_info("disp cature deinit enter \n"); + disp_unregister_vip_capture(disp_info); + disp_unregister_wb_capture(disp_info); + + //TODO: refine the card index function + g_disp_info = NULL; + + gf_info("disp cature deinit out \n"); +} + + +#define GF_CF_INT_TBL_ENTRY(_cf_id, _irq_mask) \ + { \ + .cf_id = _cf_id, \ + .irq_mask = _irq_mask, \ + } + +static gf_cf_irq_tbl_t cf_irq_tbl[] = +{ + GF_CF_INT_TBL_ENTRY(GF_CAPTURE_VIP1, INT_VIP1), + GF_CF_INT_TBL_ENTRY(GF_CAPTURE_VIP2, INT_VIP2), + GF_CF_INT_TBL_ENTRY(GF_CAPTURE_VIP3, INT_VIP3), + GF_CF_INT_TBL_ENTRY(GF_CAPTURE_VIP4, INT_VIP4), + GF_CF_INT_TBL_ENTRY(GF_CAPTURE_WB1, INT_VSYNC1), + GF_CF_INT_TBL_ENTRY(GF_CAPTURE_WB2, INT_VSYNC2), + GF_CF_INT_TBL_ENTRY(GF_CAPTURE_WB3, INT_VSYNC3), + GF_CF_INT_TBL_ENTRY(GF_CAPTURE_WB4, INT_VSYNC4), +}; + +void gf_capture_interrupt_handle(disp_info_t *disp_info, unsigned int itrr) +{ + gf_capture_t *capture = NULL; + int i = 0; + + for (; i < sizeof(cf_irq_tbl) / sizeof(gf_cf_irq_tbl_t); i++) + { + if (itrr & cf_irq_tbl[i].irq_mask) + { + capture = disp_find_capture(disp_info, cf_irq_tbl[i].cf_id); + if (capture != NULL && (capture->flags & CAPTURE_ENABLE_B)) + { + capture->notify_interrupt(disp_info, capture); + } + } + + } + +} + +void gf_capture_handle_event(disp_info_t *disp_info, gf_capture_id_t cf_id, gf_capture_event_t event) +{ + gf_capture_t *capture = NULL; + + gf_info("capture %d, event: %d \n", cf_id, event); + + capture = disp_find_capture(disp_info, cf_id); + if (capture != NULL) + { + capture->event_handler(disp_info, capture, event); + } + +} + +#undef __CONCAT +#undef CONCAT +#define __CONCAT(x,y) x##y +#define CONCAT(x,y) __CONCAT(x,y) + +void CONCAT(gf_krnl_get_capture_interface_, DRIVER_NAME)(unsigned int id, void **pdata, PFN_GF_CAPTURE_OPS_T *interface) +{ + *pdata = (void *)(g_disp_info); + *interface = disp_capture_ctl; +} + +EXPORT_SYMBOL(CONCAT(gf_krnl_get_capture_interface_, DRIVER_NAME)); + +#undef __CONCAT +#undef CONCAT diff --git a/drivers/gpu/drm/arise/linux/gf_capture_drv.h b/drivers/gpu/drm/arise/linux/gf_capture_drv.h new file mode 100644 index 0000000000000..c946bb5d05832 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_capture_drv.h @@ -0,0 +1,69 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_CAPTURE_DRV_H_ +#define __GF_CAPTURE_DRV_H_ + +#include "gf_capture.h" + +#define CAPTURE_INIT_B (0x1 << 1) +#define CAPTURE_ENABLE_B (0x1 << 2) +#define CAPTURE_NEED_SKIP_B (0x1 << 3) + +typedef enum _gf_capture_event_t +{ + GF_CAPTURE_EVENT_NONE = 0, + GF_CAPTURE_EVENT_PLUG_OUT = 1, + GF_CAPTURE_EVENT_PLUG_IN = 2, + GF_CAPTURE_EVENT_SIGNAL_OFF = 3, + GF_CAPTURE_EVENT_SIGNAL_ON = 4, +}gf_capture_event_t; + +typedef struct _gf_capture_desc +{ + gf_capture_id_t cf_fmt_id; + char* cf_name; +}gf_capture_desc; + +struct gf_capture_type +{ + gf_capture_id_t cf_fmt_id; + char *cf_name; + int (*cf_ctl)(disp_info_t *disp_info, struct gf_capture_type *capture, void *params); + void (*notify_interrupt)(disp_info_t *disp_info, struct gf_capture_type *capture); + void (*event_handler)(disp_info_t *disp_info, struct gf_capture_type *capture, gf_capture_event_t event); + unsigned int flags; + void *priv_info; + struct gf_capture_type *cf_next; +}; + +typedef struct gf_capture_type gf_capture_t; + +typedef struct _gf_cf_irq_tbl_t +{ + unsigned int irq_mask; + gf_capture_id_t cf_id; +}gf_cf_irq_tbl_t; + + +void gf_capture_interrupt_handle(disp_info_t *disp_info, unsigned int itrr); +void gf_capture_handle_event(disp_info_t *disp_info, gf_capture_id_t cf_id, gf_capture_event_t event); +void disp_register_capture(disp_info_t *disp_info, gf_capture_t *capture); +void disp_unregister_capture(disp_info_t *disp_info, gf_capture_t *capture); +gf_capture_t *disp_find_capture(disp_info_t *disp_info, int id); +void disp_capture_init(disp_info_t *disp_info); +void disp_capture_deinit(disp_info_t *disp_info); + + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_cbios.c b/drivers/gpu/drm/arise/linux/gf_cbios.c new file mode 100644 index 0000000000000..02f096e1cc94f --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_cbios.c @@ -0,0 +1,2738 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_disp.h" +#include "gf_vip.h" +#include "gf_wb.h" +#include "gf_cbios.h" +#include "gf_drmfb.h" +#include "gf_modifies.h" +#include "gf_trace.h" + +/* cbios call back functions */ +void disp_dbg_print(unsigned int debug_level, char *debug_message) +{ + gf_cb_printk(debug_message); +} + +void disp_delay_micro_seconds(unsigned int usecs) +{ + if(usecs <= 20) + { + gf_udelay(usecs); + } + else if(usecs < 20000) + { + gf_usleep_range(usecs, usecs + (usecs >> 3)); + } + else + { + gf_msleep(usecs/1000 + 1); + } +} + +unsigned char disp_read_uchar(void *data, unsigned int port) +{ + disp_info_t *disp_info = data; + adapter_info_t* adapter = disp_info->adp_info; + + return gf_read8(adapter->mmio + port); +} + +unsigned short disp_read_ushort(void *data, unsigned int port) +{ + disp_info_t *disp_info = data; + adapter_info_t *adapter = disp_info->adp_info; + + return gf_read16(adapter->mmio + port); +} + +unsigned int disp_read_ulong(void *data, unsigned int port) +{ + disp_info_t *disp_info = data; + adapter_info_t *adapter = disp_info->adp_info; + + return gf_read32(adapter->mmio + port); +} + +void disp_write_uchar(void *data, unsigned int port, unsigned char value) +{ + disp_info_t *disp_info = data; + adapter_info_t *adapter = disp_info->adp_info; + + gf_write8(adapter->mmio + port, value); +} + +void disp_write_ushort(void *data, unsigned int port, unsigned short value) +{ + disp_info_t *disp_info = data; + adapter_info_t *adapter = disp_info->adp_info; + + gf_write16(adapter->mmio + port, value); +} + +void disp_write_ulong(void *data, unsigned int port, unsigned int value) +{ + disp_info_t *disp_info = data; + adapter_info_t *adapter = disp_info->adp_info; + + gf_write32(adapter->mmio + port, value); +} + +void* disp_alloc_memory(unsigned int size) +{ + return gf_calloc(size); +} + +void disp_free_pool(void *pool) +{ + gf_free(pool); +} + +unsigned long long disp_acquire_spin_lock(void *spin_lock) +{ + struct os_spinlock *spin = (struct os_spinlock *)spin_lock; + + if (spin_lock == NULL) + { + gf_error("In func %s :first param spin_lock is NULL.\n", GF_FUNC_NAME(__func__)); + + return 0; + } + + return (unsigned long long)gf_spin_lock_irqsave(spin); +} + +void disp_release_spin_lock(void *spin_lock, unsigned long long irq_status) +{ + struct os_spinlock *spin = (struct os_spinlock *)spin_lock; + + if (spin_lock == NULL) + { + gf_error("In func %s :first param spin_lock is NULL.\n", GF_FUNC_NAME(__func__)); + + return; + } + + gf_spin_unlock_irqrestore(spin, (unsigned long)irq_status); +} + +void disp_acquire_mutex(void *mutex) +{ + struct os_mutex *m = (struct os_mutex *)mutex; + + if (m == NULL) + { + gf_error("In func %s :first param mutex is NULL.\n", GF_FUNC_NAME(__func__)); + + return; + } + + gf_mutex_lock(m); +} + +void disp_release_mutex(void *mutex) +{ + struct os_mutex *m = (struct os_mutex *)mutex; + + if (m == NULL) + { + gf_error("In func %s :first param mutex is NULL.\n", GF_FUNC_NAME(__func__)); + + return; + } + + gf_mutex_unlock(m); +} + +unsigned char disp_read_port_uchar(unsigned char *port) +{ + return gf_inb((unsigned short)(long)port); +} + +void disp_write_port_uchar(unsigned char *port, unsigned char value) +{ + return gf_outb((unsigned short)(long)port, value); +} + +void disp_write_log_file(unsigned int dbgleverl, unsigned char * dbgmsg, void * buffer, unsigned int size) +{ + //util_dump_memory_to_file(buffer, size, dbgmsg, CBIOS_LOG_FILE); +} + +unsigned int disp_get_platform_config(void *data, const char* config_name, int *buffer, int length) +{ + disp_info_t *disp_info = data; + gf_card_t* gf_card = disp_info->gf_card; + unsigned int ret = FALSE; + + if (!gf_get_platform_config(gf_card->pdev, config_name, buffer, length)) + { + ret = TRUE; + } + else + { + ret = FALSE; + } + + return ret; +} + +void disp_query_sys_time(unsigned long long *u64_time) +{ + unsigned long sec = 0, usec = 0; + + if(u64_time == NULL) + { + return ; + } + + gf_getsecs(&sec, &usec); + + *u64_time = (unsigned long long)sec * 1000000 + usec; +} + +int disp_get_output_num(int outputs) +{ + int num = 0; + while(outputs) + { + if(outputs & 1) + { + num++; + } + outputs >>= 1; + } + return num; +} + +int disp_biosmonitor_to_output(int bios_monitor) +{ + int output = 0; + if(bios_monitor & CBIOS_MONITOR_TYPE_CRT) + { + output |= UT_OUTPUT_TYPE_CRT; + } + if(bios_monitor & CBIOS_MONITOR_TYPE_TV) + { + output |= UT_OUTPUT_TYPE_TV; + } + if(bios_monitor & CBIOS_MONITOR_TYPE_HDTV) + { + output |= UT_OUTPUT_TYPE_HDTV; + } + if(bios_monitor & CBIOS_MONITOR_TYPE_PANEL) + { + output |= UT_OUTPUT_TYPE_PANEL; + } + if(bios_monitor & CBIOS_MONITOR_TYPE_DVI) + { + output |= UT_OUTPUT_TYPE_DVI; + } + if(bios_monitor & CBIOS_MONITOR_TYPE_HDMI) + { + output |= UT_OUTPUT_TYPE_HDMI; + } + if(bios_monitor & CBIOS_MONITOR_TYPE_DP) + { + output |= UT_OUTPUT_TYPE_DP; + } + if(bios_monitor & CBIOS_MONITOR_TYPE_MHL) + { + output |= UT_OUTPUT_TYPE_MHL; + } + + return output; +} + +int disp_output_to_biosmonitor(int output) +{ + int bios_monitor = 0; + if(output & UT_OUTPUT_TYPE_CRT) + { + bios_monitor |= CBIOS_MONITOR_TYPE_CRT; + } + if(output & UT_OUTPUT_TYPE_TV) + { + bios_monitor |= CBIOS_MONITOR_TYPE_TV; + } + if(output & UT_OUTPUT_TYPE_HDTV) + { + bios_monitor |= CBIOS_MONITOR_TYPE_HDTV; + } + if(output & UT_OUTPUT_TYPE_PANEL) + { + bios_monitor |= CBIOS_MONITOR_TYPE_PANEL; + } + if(output & UT_OUTPUT_TYPE_DVI) + { + bios_monitor |= CBIOS_MONITOR_TYPE_DVI; + } + if(output & UT_OUTPUT_TYPE_HDMI) + { + bios_monitor |= CBIOS_MONITOR_TYPE_HDMI; + } + if(output & UT_OUTPUT_TYPE_DP) + { + bios_monitor |= CBIOS_MONITOR_TYPE_DP; + } + if(output & UT_OUTPUT_TYPE_MHL) + { + bios_monitor |= CBIOS_MONITOR_TYPE_MHL; + } + + return bios_monitor; +} + +CHIPID_HW disp_chipid_to_cbios_chipid(unsigned int chip_id) +{ + CHIPID_HW cb_chip_id = 0; + + switch(chip_id) + { + case CHIP_ARISE: + cb_chip_id = CHIPID_E3K; + break; + case CHIP_ARISE1020: + cb_chip_id = CHIPID_ARISE1020; + break; + case CHIP_ARISE1040: + cb_chip_id = CHIPID_ARISE1040; + break; + case CHIP_ARISE1010: + cb_chip_id = CHIPID_ARISE1010; + break; + case CHIP_ARISE10C0T: + cb_chip_id = CHIPID_ARISE10C0T; + break; + case CHIP_ARISE2030: + cb_chip_id = CHIPID_ARISE2030; + break; + case CHIP_ARISE2020: + cb_chip_id = CHIPID_ARISE2020; + break; + default: + gf_assert(0, "Invalid chip id."); + break; + } + + return cb_chip_id; +} + +int disp_get_shadow_rom_image(disp_info_t *disp_info) +{ + void *shadow_rom_image = NULL; + void *src_image = NULL; + unsigned char cr_a0_c, sr_1f; + unsigned int mm850c = 0, vid_boundary = 0, bound_reg = 0; + adapter_info_t* adapter_info = disp_info->adp_info; + gf_map_argu_t map = {0}; + gf_vm_area_t *vma = NULL; + + if((adapter_info->run_on_qt)) + { + return 0; + } + + vid_boundary = ((adapter_info->fb_total_size >> 24) -1 ) & 0xFF; + bound_reg = gf_read32(adapter_info->mmio + 0x490a0); + gf_write32(adapter_info->mmio + 0x490a0, (bound_reg & 0xFFFFFF00) | vid_boundary); + + shadow_rom_image = gf_calloc(GF_SHADOW_VBIOS_SIZE); + if(!shadow_rom_image) + { + gf_error("malloc shadow rom memory failed\n"); + goto fail; + } + + map.flags.cache_type = GF_MEM_UNCACHED; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.mem_type = GF_SYSTEM_IO; + map.phys_addr = adapter_info->fb_bus_addr + adapter_info->fb_total_size - GF_SHADOW_VBIOS_SIZE; + map.size = GF_SHADOW_VBIOS_SIZE; + + vma = gf_map_io_memory(NULL, &map); + + src_image = vma->virt_addr; + if(!src_image) + { + gf_error("map shadow vbios failed\n"); + goto fail; + } + + /* enable eclk */ + sr_1f = gf_read8(adapter_info->mmio + 0x861F); + gf_write8(adapter_info->mmio + 0x861F, sr_1f & 0xfe); + + /* enable linear address */ + cr_a0_c = gf_read8(adapter_info->mmio + 0x8AA0); + gf_write8(adapter_info->mmio + 0x8AA0, cr_a0_c | 0x10); + + mm850c = gf_read32(adapter_info->mmio + 0x850c); + if(!(mm850c & 0x2)) + { + gf_write8(adapter_info->mmio + 0x850c, mm850c | 0x2); + } + + gf_memcpy(shadow_rom_image, src_image, GF_SHADOW_VBIOS_SIZE); + + gf_unmap_io_memory(vma); + + /* restore cr_a0_c */ + gf_write8(adapter_info->mmio + 0x8AA0, cr_a0_c); + gf_write32(adapter_info->mmio + 0x850c, mm850c); + + if(*(unsigned short*)shadow_rom_image != 0xAA55) + { + gf_error("Invalid shadow rom_image \n"); + goto fail; + } + + disp_info->rom_image = shadow_rom_image; + + return GF_SHADOW_VBIOS_SIZE; + +fail: + if(shadow_rom_image) + { + gf_free(shadow_rom_image); + shadow_rom_image = NULL; + } + + return 0; +} + +unsigned int disp_get_rom_bar_size(disp_info_t *disp_info) +{ + gf_card_t *gf_card = disp_info->gf_card; + unsigned int rom_save = 0, temp = 0; + + gf_get_rom_save_addr(gf_card->pdev, &rom_save); + + temp = 0xFFFFFFFF; + gf_write_rom_save_addr(gf_card->pdev, temp); + + gf_get_rom_save_addr(gf_card->pdev, &temp); + temp &= 0xFFFFFFFE; + temp = ~temp; + temp = temp + 1; + + gf_write_rom_save_addr(gf_card->pdev, rom_save); + + return temp; +} + +unsigned int disp_get_rom_bar_image(disp_info_t *disp_info) +{ + gf_card_t *gf_card = disp_info->gf_card; + adapter_info_t *adapter_info = disp_info->adp_info; + void *rom_bar_image = NULL; + unsigned int rom_len = 0, i; + unsigned char *pbyte = NULL; + int ret = -1; + + rom_bar_image = gf_calloc(GF_VBIOS_ROM_SIZE); + if (!rom_bar_image) + { + gf_error("malloc rom image memory failed!\n"); + disp_info->rom_image = NULL; + return 0; + } + + ret = gf_pci_get_rom(gf_card->pdev, rom_bar_image, GF_VBIOS_ROM_SIZE); + + if (ret == 0) + { + rom_len = GF_VBIOS_ROM_SIZE; + } + else + { + gf_info("invalid rom head(0x%x)=0x%x.\n", rom_bar_image, *(unsigned short*)rom_bar_image); + } + + if (!rom_len) + { + // if can't get rom bar image, try to get image from pmp + if (0xaa55 == gf_read16(adapter_info->mmio + GF_PMP_SHADOW_IMG_OFFSET)) + { + gf_info("get shadow rom image from pmp. \n"); + pbyte = rom_bar_image; + for (i = 0; i < GF_PMP_SHADOW_IMG_SIZE; i++) + { + *pbyte++ = gf_read8(adapter_info->mmio + GF_PMP_SHADOW_IMG_OFFSET + i); + } + + rom_len = GF_PMP_SHADOW_IMG_SIZE; + } + else + { + gf_info("get rom image failed! \n"); + rom_len = disp_get_rom_bar_size(disp_info); + } + } + + disp_info->rom_image = rom_bar_image; + return rom_len; +} + +int disp_wait_for_vblank(disp_info_t* disp_info, int pipe, int timeout) +{ + unsigned long timeout_j = jiffies + msecs_to_jiffies(timeout) + 1; + unsigned int ori_vblcnt = 0, curr_vblcnt = 0; + int ret = 0; + gf_get_counter_t get_cnt = {0}; + + get_cnt.crtc_index = pipe; + get_cnt.vblk = &ori_vblcnt; + + disp_cbios_get_counter(disp_info, &get_cnt); + + curr_vblcnt = ori_vblcnt; + get_cnt.vblk = &curr_vblcnt; + + while(curr_vblcnt == ori_vblcnt) + { + if(time_after(jiffies, timeout_j)) + { + ret = -ETIMEDOUT; + break; + } + if(drm_can_sleep()) + { + gf_msleep(1); + } + else + { + gf_udelay(1000); + } + disp_cbios_get_counter(disp_info, &get_cnt); + } + + return ret; +} + +/*CBIOS Initialization sequence: + * 1) set Call back function + * 2) Set Mmio Endian Mode + * 3) CbiosInit + * 4) CbiosInitHW + * Before 2, we can't let CBIOS access MMIO as we don't set MMIO mode as we required + * */ +int disp_init_cbios(disp_info_t *disp_info) +{ + CBIOS_PARAM_INIT CBParamInit = {0}; + CBIOS_CALLBACK_FUNCTIONS fnCallBack = {0}; + CBIOS_CHIP_ID CBChipId; + adapter_info_t* adapter_info = disp_info->adp_info; + void *pcbe = NULL; + unsigned int rom_lenth = 0; + unsigned int CBiosStatus; + unsigned int CBiosExtensionSize; + unsigned int i = 0; + + fnCallBack.Size = sizeof(CBIOS_CALLBACK_FUNCTIONS); + + fnCallBack.pFnDbgPrint = disp_dbg_print; + fnCallBack.pFnDelayMicroSeconds = disp_delay_micro_seconds; + fnCallBack.pFnReadUchar = disp_read_uchar; + fnCallBack.pFnReadUshort = disp_read_ushort; + fnCallBack.pFnReadUlong = disp_read_ulong; + fnCallBack.pFnWriteUchar = disp_write_uchar; + fnCallBack.pFnWriteUshort = disp_write_ushort; + fnCallBack.pFnWriteUlong = disp_write_ulong; + fnCallBack.pFnQuerySystemTime = disp_query_sys_time; + fnCallBack.pFnAllocateNonpagedMemory = disp_alloc_memory; + fnCallBack.pFnAllocatePagedMemory= disp_alloc_memory; + fnCallBack.pFnFreePool = disp_free_pool; + fnCallBack.pFnAcquireSpinLock = disp_acquire_spin_lock; + fnCallBack.pFnReleaseSpinLock = disp_release_spin_lock; + fnCallBack.pFnAcquireMutex = disp_acquire_mutex; + fnCallBack.pFnReleaseMutex = disp_release_mutex; + fnCallBack.pFnReadPortUchar = disp_read_port_uchar; + fnCallBack.pFnWritePortUchar = disp_write_port_uchar; + fnCallBack.pFnDbgPrintToFile = disp_write_log_file; + fnCallBack.pFnGetPlatformConfigU32 = disp_get_platform_config; + + fnCallBack.pFnStrcmp = gf_strcmp; + fnCallBack.pFnStrcpy = gf_strcpy; + fnCallBack.pFnStrncmp = gf_strncmp; + fnCallBack.pFnMemset = gf_memset; + fnCallBack.pFnMemcpy = gf_memcpy; + fnCallBack.pFnMemcmp = gf_memcmp; + fnCallBack.pFnDodiv = gf_do_div; + fnCallBack.pFnVsprintf = gf_vsprintf; + fnCallBack.pFnVsnprintf = gf_vsnprintf; + + if(CBiosSetCallBackFunctions(&fnCallBack) != CBIOS_OK) + { + gf_info("CBios set call back func failed.\n"); + } + + rom_lenth = disp_get_rom_bar_image(disp_info); + + gf_memset(&CBChipId, 0, sizeof(CBIOS_CHIP_ID)); + CBChipId.Size = sizeof(CBIOS_CHIP_ID); + CBChipId.GenericChipID = adapter_info->generic_id; + CBChipId.ChipID = disp_chipid_to_cbios_chipid(adapter_info->chip_id); + + CBiosStatus = CBiosGetExtensionSize(&CBChipId, &CBiosExtensionSize); + + if(CBiosExtensionSize == 0 || CBiosStatus != CBIOS_OK) + { + gf_error("Get cbios extension size failed\n"); + } + + pcbe = gf_calloc(CBiosExtensionSize); + + if(pcbe == NULL) + { + gf_error("Alloc memory for cbios pcbe failed\n"); + } + + CBParamInit.pAdapterContext = disp_info; + CBParamInit.MAMMPrimaryAdapter = adapter_info->primary; + CBParamInit.GeneralChipID = adapter_info->generic_id; + CBParamInit.ChipID = disp_chipid_to_cbios_chipid(adapter_info->chip_id); + + CBParamInit.RomImage = disp_info->rom_image; + CBParamInit.RomImageLength = rom_lenth; + CBParamInit.pSpinLock = disp_info->cbios_inner_spin_lock; + CBParamInit.pAuxMutex = disp_info->cbios_aux_mutex; + + for(i = 0;i < CBIOS_MAX_I2CBUS;i++) + { + CBParamInit.pI2CMutex[i] = disp_info->cbios_i2c_mutex[i]; + } + + CBParamInit.Size = sizeof(CBIOS_PARAM_INIT); + +#ifdef GFX_ONLY_FPGA + CBParamInit.bRunOnQT = 0x1; +#endif + + if (adapter_info->run_on_qt) + { + CBParamInit.bRunOnQT = 0x1; + } + + CBiosInit(pcbe, &CBParamInit); + + disp_info->cbios_ext = pcbe; + + return DISP_OK; +} + +int disp_cbios_init_hw(disp_info_t *disp_info) +{ + int ret = DISP_OK; + int cb_status = CBIOS_OK; + + cb_status = CBiosInitHW(disp_info->cbios_ext); + + if(cb_status != CBIOS_OK) + { + gf_error("CBiosInitHW failed. cbios status is %x\n",cb_status); + ret = DISP_FAIL; + } + + gf_info("disp cbios_init_hw finished.\n"); + + return ret; +} + +void disp_cbios_get_crtc_resource(disp_info_t *disp_info) +{ + CBIOS_GET_DISP_RESOURCE cb_disp_res = {0}; + int i = 0; + + if(CBIOS_OK == CBiosGetDispResource(disp_info->cbios_ext, &cb_disp_res)) + { + gf_assert(MAX_CORE_CRTCS >= cb_disp_res.CrtcNum, "crtc num > MAX_CORE_CRTCS"); + + disp_info->num_crtc = cb_disp_res.CrtcNum; + + for(i = 0; i < cb_disp_res.CrtcNum; i++) + { + disp_info->num_plane[i]= cb_disp_res.PlaneNum[i]; + } + + gf_info("CRTC num: %d.\n", disp_info->num_crtc); + } +} + +void disp_cbios_get_crtc_caps(disp_info_t *disp_info) +{ + CBIOS_DISPLAY_CAPS cb_disp_caps = {0}; + CBIOS_U32 up_plane[MAX_CORE_CRTCS] = {0}; + CBIOS_U32 down_plane[MAX_CORE_CRTCS] = {0}; + int i = 0; + + cb_disp_caps.pUpScalePlaneMask = up_plane; + cb_disp_caps.pDownScalePlaneMask = down_plane; + + if(CBIOS_OK == CBiosGetDisplayCaps(disp_info->cbios_ext, &cb_disp_caps)) + { + disp_info->scale_support = cb_disp_caps.SuppCrtcUpScale; //only use crtc upscaler + + for(i = 0; i < disp_info->num_crtc; i++) + { + disp_info->up_scale_plane_mask[i] = up_plane[i]; + } + for(i = 0; i < disp_info->num_crtc; i++) + { + disp_info->down_scale_plane_mask[i] = down_plane[i]; + } + } +} + +int disp_cbios_cleanup(disp_info_t *disp_info) +{ + CBiosUnload(disp_info->cbios_ext); + +#if 0 + if(disp_info->cbios_ext) + { + gf_free(disp_info->cbios_ext); + + disp_info->cbios_ext = NULL; + } +#endif + + if(disp_info->rom_image) + { + gf_free(disp_info->rom_image); + + disp_info->rom_image = NULL; + } + + return DISP_OK; +} + +void disp_cbios_query_vbeinfo(disp_info_t *disp_info) +{ + adapter_info_t* adapter_info = disp_info->adp_info; + void* pcbe = disp_info->cbios_ext; + CBIOS_VBINFO_PARAM vbeinfo = {0}; + int status = CBIOS_OK; + + vbeinfo.Size = sizeof(vbeinfo); + vbeinfo.BiosVersion = CBIOSVERSION; + + status = CBiosGetVBiosInfo(pcbe, &vbeinfo); + if(status != CBIOS_OK) + { + gf_error("Get cbios vbeinfo failed\n"); + } + else + { + adapter_info->chan_num = vbeinfo.MemChNum; + adapter_info->avai_mem_size_mb = vbeinfo.AvalMemSize; + adapter_info->total_mem_size_mb = vbeinfo.TotalMemSize; + adapter_info->hdaudio_to_local = vbeinfo.HdaudioToLocal; + adapter_info->non_simul_chip = vbeinfo.NonSimulChip; + gf_memcpy(disp_info->pmp_version,vbeinfo.PMPVer,sizeof(vbeinfo.PMPVer)); + + disp_info->support_output = vbeinfo.SupportDev; + disp_info->num_output = disp_get_output_num(vbeinfo.SupportDev); + + disp_info->supp_hpd_outputs = disp_info->support_output & vbeinfo.HPDDevicesMask; + disp_info->supp_polling_outputs = disp_info->support_output & vbeinfo.PollingDevMask; + + disp_info->vbios_version = vbeinfo.BiosVersion; + disp_info->firmware_version = vbeinfo.FwVersion; + gf_memcpy(disp_info->firmware_name, vbeinfo.FwName, sizeof(vbeinfo.FwName)); + + gf_info("bios supported device: 0x%x\n", disp_info->support_output); + gf_info("low_top_address : 0x%x\n", adapter_info->low_top_addr); + } +} + +int disp_cbios_get_modes_size(disp_info_t *disp_info, int output) +{ + void *pcbe = disp_info->cbios_ext; + int mode_size = 0; + + if(CBIOS_OK == CBiosGetDeviceModeListBufferSize(pcbe, output, &mode_size)) + { + if(mode_size > 0) + { + mode_size += 10 * sizeof(CBiosModeInfoExt); //add some space to avoid overflow in get mode list later + } + else + { + mode_size = 0; + } + } + + return mode_size; +} + +int disp_cbios_get_modes(disp_info_t *disp_info, int output, void* buffer, int buf_size) +{ + void *pcbe = disp_info->cbios_ext; + int real_size = buf_size; + int real_num = 0; + + if(!buffer || !buf_size) + { + return 0; + } + + CBiosGetDeviceModeList(pcbe, output, (PCBiosModeInfoExt)buffer, &real_size); + + if(real_size > buf_size) + { + gf_error("OVERFLOW detected: malloc_size: %d, used size: %x.\n", buf_size, real_size); + } + + real_num = real_size / sizeof(CBiosModeInfoExt); + + return real_num; +} + +int disp_cbios_get_adapter_modes_size(disp_info_t *disp_info) +{ + void *pcbe = disp_info->cbios_ext; + int mode_size = 0; + + if(CBIOS_OK == CBiosGetAdapterModeListBufferSize(pcbe, &mode_size)) + { + if(mode_size > 0) + { + mode_size += 10 * sizeof(CBiosModeInfoExt); //add some space to avoid overflow in get mode list later + } + else + { + mode_size = 0; + } + } + + return mode_size; +} + +int disp_cbios_get_adapter_modes(disp_info_t *disp_info, void* buffer, int buf_size) +{ + void *pcbe = disp_info->cbios_ext; + int real_size = buf_size; + int real_num = 0; + + if(!buffer || !buf_size) + { + return 0; + } + + CBiosGetAdapterModeList(pcbe, (PCBiosModeInfoExt)buffer, &real_size); + + if(real_size > buf_size) + { + gf_error("OVERFLOW detected: malloc_size: %d, used size: %x.\n", buf_size, real_size); + } + + real_num = real_size / sizeof(CBiosModeInfoExt); + + return real_num; +} + +int disp_cbios_merge_modes(CBiosModeInfoExt* merge_mode_list, CBiosModeInfoExt * adapter_mode_list, unsigned int const adapter_mode_num, + CBiosModeInfoExt const * dev_mode_list, unsigned int const dev_mode_num) +{ + CBiosModeInfoExt tmpBuf; + unsigned int i = 0; + unsigned int adapter_index = 0; + unsigned int dev_index = 0; + unsigned int mode_index = 0; + unsigned int num_mode = 0; + unsigned int *valid_adapter_mode_flag = NULL; + + + valid_adapter_mode_flag = gf_calloc(adapter_mode_num * sizeof(unsigned int )); + + // reverse adapter modelist + for (i = 0; i < adapter_mode_num/2; i++) + { + gf_memcpy(&tmpBuf, &adapter_mode_list[i], sizeof(CBiosModeInfoExt)); + gf_memcpy(&adapter_mode_list[i], &adapter_mode_list[adapter_mode_num - i -1], sizeof(CBiosModeInfoExt)); + gf_memcpy(&adapter_mode_list[adapter_mode_num - i -1], &tmpBuf, sizeof(CBiosModeInfoExt)); + } + + //make sure all the adapter modes is smaller than the largest device mode. + //adapter mode is not strict sorted from small to large . + //adatper modes : 640x480 800x600 1024x768 1280x720 1280x1024 1680x1050 1920x1080 + //1024x768 is not smaller than 1280x720 strictly. + + // mark adapter mode whether it's bigger than the largest device mode or not + for (i = 0; i < adapter_mode_num; i++) + { + if ((adapter_mode_list[i].XRes <= dev_mode_list[0].XRes) && + (adapter_mode_list[i].YRes <= dev_mode_list[0].YRes) && + (adapter_mode_list[i].RefreshRate <= dev_mode_list[0].RefreshRate)) + { + valid_adapter_mode_flag[i] = 1; + } + else + { + valid_adapter_mode_flag[i] = 0; + } + } + + // merge + dev_index = 0; + mode_index = 0; + num_mode = 0; + adapter_index = 0; + while ((dev_index < dev_mode_num) && (adapter_index < adapter_mode_num)) + { + if(valid_adapter_mode_flag[adapter_index] == 0) + { + adapter_index++; + continue; + } + if ((dev_mode_list[dev_index].XRes > adapter_mode_list[adapter_index].XRes) || + ((dev_mode_list[dev_index].XRes == adapter_mode_list[adapter_index].XRes) && + (dev_mode_list[dev_index].YRes > adapter_mode_list[adapter_index].YRes)) || + ((dev_mode_list[dev_index].XRes == adapter_mode_list[adapter_index].XRes) && + (dev_mode_list[dev_index].YRes == adapter_mode_list[adapter_index].YRes) && + (dev_mode_list[dev_index].RefreshRate > adapter_mode_list[adapter_index].RefreshRate))) + { + gf_memcpy(&merge_mode_list[mode_index], &dev_mode_list[dev_index], sizeof(CBiosModeInfoExt)); + mode_index++; + dev_index++; + num_mode++; + } + else if ((dev_mode_list[dev_index].XRes == adapter_mode_list[adapter_index].XRes) && + (dev_mode_list[dev_index].YRes == adapter_mode_list[adapter_index].YRes) && + (dev_mode_list[dev_index].RefreshRate == adapter_mode_list[adapter_index].RefreshRate)) + { + gf_memcpy(&merge_mode_list[mode_index], &dev_mode_list[dev_index], sizeof(CBiosModeInfoExt)); + merge_mode_list[mode_index].InterlaceProgressiveCaps |= adapter_mode_list[adapter_index].InterlaceProgressiveCaps; + merge_mode_list[mode_index].DeviceFlags |= adapter_mode_list[adapter_index].DeviceFlags; + merge_mode_list[mode_index].ColorDepthCaps |= adapter_mode_list[adapter_index].ColorDepthCaps; + merge_mode_list[mode_index].AspectRatioCaps |= adapter_mode_list[adapter_index].AspectRatioCaps; + mode_index++; + dev_index++; + adapter_index++; + num_mode++; + } + else + { + gf_memcpy(&merge_mode_list[mode_index], &adapter_mode_list[adapter_index], sizeof(CBiosModeInfoExt)); + mode_index++; + adapter_index++; + num_mode++; + } + } + + if ((dev_index == dev_mode_num) && (adapter_index < adapter_mode_num)) + { + while(adapter_index < adapter_mode_num) + { + if(valid_adapter_mode_flag[adapter_index] == 1) + { + gf_memcpy(&merge_mode_list[mode_index], &adapter_mode_list[adapter_index], sizeof(CBiosModeInfoExt)); + num_mode++; + mode_index++; + } + adapter_index++; + } + } + + if ((dev_index < dev_mode_num) && (adapter_index == adapter_mode_num)) + { + gf_memcpy(&merge_mode_list[mode_index], &dev_mode_list[dev_index], + sizeof(CBiosModeInfoExt)*(dev_mode_num - dev_index)); + num_mode += (dev_mode_num - dev_index); + } + + if(valid_adapter_mode_flag) + { + gf_free(valid_adapter_mode_flag); + valid_adapter_mode_flag = NULL; + } + + return num_mode; +} + +int disp_cbios_cbmode_to_drmmode(disp_info_t *disp_info, int output, void* cbmode, int i, struct drm_display_mode *drm_mode) +{ + void *pcbe = disp_info->cbios_ext; + CBIOS_GET_MODE_TIMING_PARAM get_timing = {0}; + CBIOS_TIMING_ATTRIB timing_attrib = {0}; + PCBiosModeInfoExt cbios_mode = (PCBiosModeInfoExt)cbmode + i; + + if(!cbios_mode || !drm_mode) + { + return DISP_FAIL; + } + + get_timing.DeviceId = output; + get_timing.pMode = cbios_mode; + get_timing.pTiming = &timing_attrib; + if(CBIOS_OK != CBiosGetModeTiming(pcbe, &get_timing)) + { + return DISP_FAIL; + } + + drm_mode->clock = timing_attrib.PixelClock / 10; + drm_mode->hdisplay = timing_attrib.XRes; + drm_mode->hsync_start = timing_attrib.HorSyncStart; + drm_mode->hsync_end = timing_attrib.HorSyncEnd; + drm_mode->htotal = timing_attrib.HorTotal; + drm_mode->hskew = 0; + + drm_mode->vdisplay = timing_attrib.YRes; + drm_mode->vsync_start = timing_attrib.VerSyncStart; + drm_mode->vsync_end = timing_attrib.VerSyncEnd; + drm_mode->vtotal = timing_attrib.VerTotal; + drm_mode->vscan = 0; + +#if DRM_VERSION_CODE < KERNEL_VERSION(5,9,0) + drm_mode->vrefresh = timing_attrib.RefreshRate / 100; +#endif + drm_mode->type |= DRM_MODE_TYPE_DRIVER; + if (cbios_mode->isPreferredMode) + { + drm_mode->type |= DRM_MODE_TYPE_PREFERRED; + } + + if (cbios_mode->InterlaceProgressiveCaps & 0x02) + { + drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; + } + + drm_mode->flags |= (timing_attrib.HVPolarity & HOR_NEGATIVE) ? + DRM_MODE_FLAG_NHSYNC : DRM_MODE_FLAG_PHSYNC; + drm_mode->flags |= (timing_attrib.HVPolarity & VER_NEGATIVE) ? + DRM_MODE_FLAG_NVSYNC : DRM_MODE_FLAG_PVSYNC; + drm_mode->flags |= DRM_MODE_FLAG_3D_NONE; + + return DISP_OK; +} + +int disp_cbios_3dmode_to_drmmode(disp_info_t *disp_info, int output, void* mode, int i, struct drm_display_mode *drm_mode) +{ + void *pcbe = disp_info->cbios_ext; + CBIOS_GET_MODE_TIMING_PARAM get_timing = {0}; + CBIOS_TIMING_ATTRIB timing_attrib = {0}; + CBiosModeInfoExt cbios_mode = {0}; + PCBIOS_3D_VIDEO_MODE_LIST cb_3d_mode = (PCBIOS_3D_VIDEO_MODE_LIST)mode + i; + + if(!cb_3d_mode || !drm_mode) + { + return DISP_FAIL; + } + + cbios_mode.XRes = cb_3d_mode->XRes; + cbios_mode.YRes = cb_3d_mode->YRes; + cbios_mode.RefreshRate = cb_3d_mode->RefreshRate; + cbios_mode.InterlaceProgressiveCaps = (cb_3d_mode->bIsInterlace)? 2 : 1; + + get_timing.DeviceId = output; + get_timing.pMode = &cbios_mode; + get_timing.pTiming = &timing_attrib; + + if(CBIOS_OK != CBiosGetModeTiming(pcbe, &get_timing)) + { + return DISP_FAIL; + } + + drm_mode->clock = timing_attrib.PixelClock / 10; + drm_mode->hdisplay = timing_attrib.XRes; + drm_mode->hsync_start = timing_attrib.HorSyncStart; + drm_mode->hsync_end = timing_attrib.HorSyncEnd; + drm_mode->htotal = timing_attrib.HorTotal; + drm_mode->hskew = 0; + + drm_mode->vdisplay = timing_attrib.YRes; + drm_mode->vsync_start = timing_attrib.VerSyncStart; + drm_mode->vsync_end = timing_attrib.VerSyncEnd; + drm_mode->vtotal = timing_attrib.VerTotal; + drm_mode->vscan = 0; + +#if DRM_VERSION_CODE < KERNEL_VERSION(5,9,0) + drm_mode->vrefresh = timing_attrib.RefreshRate / 100; +#endif + + drm_mode->type |= DRM_MODE_TYPE_DRIVER; + + if (cb_3d_mode->bIsInterlace) + { + drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; + } + drm_mode->flags |= (timing_attrib.HVPolarity & HOR_NEGATIVE) ? + DRM_MODE_FLAG_NHSYNC : DRM_MODE_FLAG_PHSYNC; + drm_mode->flags |= (timing_attrib.HVPolarity & VER_NEGATIVE) ? + DRM_MODE_FLAG_NVSYNC : DRM_MODE_FLAG_PVSYNC; + + if (cb_3d_mode->SupportStructures.FramePacking) + { + drm_mode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING; + } + if (cb_3d_mode->SupportStructures.FieldAlternative) + { + drm_mode->flags |= DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE; + } + if (cb_3d_mode->SupportStructures.LineAlternative) + { + drm_mode->flags |= DRM_MODE_FLAG_3D_LINE_ALTERNATIVE; + } + if (cb_3d_mode->SupportStructures.SideBySideFull) + { + drm_mode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL; + } + if (cb_3d_mode->SupportStructures.LDepth) + { + drm_mode->flags |= DRM_MODE_FLAG_3D_L_DEPTH; + } + if (cb_3d_mode->SupportStructures.LDepthGraphics) + { + drm_mode->flags |= DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH; + } + if (cb_3d_mode->SupportStructures.TopAndBottom) + { + drm_mode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM; + } + if (cb_3d_mode->SupportStructures.SideBySideHalf) + { + drm_mode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF; + } + + return DISP_OK; +} + +int disp_cbios_get_3dmode_size(disp_info_t* disp_info, int output) +{ + void *pcbe = disp_info->cbios_ext; + CBIOS_MONITOR_3D_CAPABILITY_PARA CbiosMonitor3DCapablitityPara = {0}; + int buf_size = 0, support = 0; + + CbiosMonitor3DCapablitityPara.DeviceId = output; + CbiosMonitor3DCapablitityPara.pMonitor3DModeList = NULL; + + if(CBIOS_OK == CBiosQueryMonitor3DCapability(pcbe, &CbiosMonitor3DCapablitityPara)) + { + support = CbiosMonitor3DCapablitityPara.bIsSupport3DVideo; + } + + if(support) + { + buf_size = CbiosMonitor3DCapablitityPara.Monitor3DModeNum; + buf_size *= sizeof(CBIOS_3D_VIDEO_MODE_LIST); + } + + return buf_size; +} + +int disp_cbios_get_3dmodes(disp_info_t *disp_info, int output, void* buffer, int buf_size) +{ + void *pcbe = disp_info->cbios_ext; + CBIOS_MONITOR_3D_CAPABILITY_PARA CbiosMonitor3DCapablitityPara = {0}; + int real_size = 0, real_num = 0; + + if(!buffer || !buf_size) + { + return real_num; + } + + CbiosMonitor3DCapablitityPara.DeviceId = output; + CbiosMonitor3DCapablitityPara.pMonitor3DModeList = (PCBIOS_3D_VIDEO_MODE_LIST)buffer; + + CBiosQueryMonitor3DCapability(pcbe, &CbiosMonitor3DCapablitityPara); + + if(CbiosMonitor3DCapablitityPara.bIsSupport3DVideo) + { + real_size = CbiosMonitor3DCapablitityPara.Monitor3DModeNum * sizeof(CBIOS_3D_VIDEO_MODE_LIST); + if(real_size > buf_size) + { + gf_error("OVERFLOW detected: malloc_size: %d, used size: %x.\n", buf_size, real_size); + } + real_num = CbiosMonitor3DCapablitityPara.Monitor3DModeNum; + } + + return real_num; +} + +void* disp_cbios_get_device_modelist(disp_info_t *disp_info, int output_type, int* mode_num) +{ + void *pmode_list = NULL, *mode_buf = NULL, *adapter_buf = NULL, *merge_buf = NULL; + int dev_mode_size = 0, adapter_mode_size = 0, dev_num = 0, adapter_num = 0, real_num = 0; + + if(!disp_info || !output_type) + { + goto END; + } + + dev_mode_size = disp_cbios_get_modes_size(disp_info, output_type); + + if(!dev_mode_size) + { + goto END; + } + + mode_buf = gf_calloc(dev_mode_size); + + if(!mode_buf) + { + goto END; + } + + dev_num = disp_cbios_get_modes(disp_info, output_type, mode_buf, dev_mode_size); + + pmode_list = mode_buf; + real_num = dev_num; + + if(disp_info->scale_support) + { + adapter_mode_size = disp_cbios_get_adapter_modes_size(disp_info); + + if(adapter_mode_size != 0) + { + adapter_buf = gf_calloc(adapter_mode_size); + + if(!adapter_buf) + { + goto END; + } + adapter_num = disp_cbios_get_adapter_modes(disp_info, adapter_buf, adapter_mode_size); + + merge_buf = gf_calloc((dev_num + adapter_num) * sizeof(CBiosModeInfoExt)); + + if(!merge_buf) + { + gf_free(adapter_buf); + goto END; + } + + real_num = disp_cbios_merge_modes(merge_buf, adapter_buf, adapter_num, mode_buf, dev_num); + pmode_list = merge_buf; + + gf_free(mode_buf); + gf_free(adapter_buf); + } + } + +END: + if(mode_num) + { + *mode_num = real_num; + } + + return pmode_list; +} + +int disp_cbios_get_mode_timing(disp_info_t *disp_info, int output, struct drm_display_mode *drm_mode) +{ + void *pcbe = disp_info->cbios_ext; + CBIOS_GET_MODE_TIMING_PARAM get_timing = {0}; + CBIOS_TIMING_ATTRIB timing_attrib = {0}; + CBiosModeInfoExt cbios_mode = {0}; + int temp = 0; + + if(!drm_mode) + { + return DISP_FAIL; + } + + cbios_mode.XRes = drm_mode->hdisplay; + cbios_mode.YRes = drm_mode->vdisplay; + temp = drm_mode->clock * 1000/drm_mode->htotal; + cbios_mode.RefreshRate = temp * 100/drm_mode->vtotal; + cbios_mode.InterlaceProgressiveCaps = (drm_mode->flags & DRM_MODE_FLAG_INTERLACE) ? 0x02 : 0x01; + + get_timing.DeviceId = output; + get_timing.pMode = &cbios_mode; + get_timing.pTiming = &timing_attrib; + if(CBIOS_OK != CBiosGetModeTiming(pcbe, &get_timing)) + { + return DISP_FAIL; + } + + drm_mode->crtc_clock = timing_attrib.PixelClock / 10; + drm_mode->crtc_hdisplay = timing_attrib.XRes; + drm_mode->crtc_hblank_start = timing_attrib.HorBStart; + drm_mode->crtc_hblank_end = timing_attrib.HorBEnd; + drm_mode->crtc_hsync_start = timing_attrib.HorSyncStart; + drm_mode->crtc_hsync_end = timing_attrib.HorSyncEnd; + drm_mode->crtc_htotal = timing_attrib.HorTotal; + drm_mode->crtc_hskew = 0; + + drm_mode->crtc_vdisplay = timing_attrib.YRes; + drm_mode->crtc_vblank_start = timing_attrib.VerBStart; + drm_mode->crtc_vblank_end = timing_attrib.VerBEnd; + drm_mode->crtc_vsync_start = timing_attrib.VerSyncStart; + drm_mode->crtc_vsync_end = timing_attrib.VerSyncEnd; + drm_mode->crtc_vtotal = timing_attrib.VerTotal; + + return DISP_OK; +} + +void* disp_cbios_read_edid(disp_info_t *disp_info, int drv_dev) +{ + void *pcbe = disp_info->cbios_ext; + + CBIOS_PARAM_GET_EDID cbParamGetEdid = {0}; + unsigned char *pEdid = NULL; + + pEdid = gf_calloc(EDID_BUF_SIZE); + + if(!pEdid) + { + return NULL; + } + + cbParamGetEdid.EdidBuffer = pEdid; + cbParamGetEdid.EdidBufferLen = EDID_BUF_SIZE; + cbParamGetEdid.Size = sizeof(CBIOS_PARAM_GET_EDID); + cbParamGetEdid.DeviceId = drv_dev; + + if(CBiosGetEdid(pcbe, &cbParamGetEdid) != CBIOS_OK) + { + gf_debug("device id: 0x%x has no valid EDID.\n", drv_dev); + gf_free(pEdid); + pEdid = NULL; + } + + return pEdid; +} + +int disp_cbios_update_output_active(disp_info_t *disp_info, int* outputs) +{ + void *pcbe = disp_info->cbios_ext; + CIP_ACTIVE_DEVICES activeDevices = {0}; + + gf_memcpy(activeDevices.DeviceId, outputs, sizeof(activeDevices.DeviceId)); + + return (CBiosSetActiveDevice(pcbe, &activeDevices) == CBIOS_OK)? 0 : -1; +} + +int disp_cbios_sync_vbios(disp_info_t *disp_info) +{ + int status = DISP_OK; + CBIOS_VBIOS_DATA_PARAM DataParam = {0}; + + if(CBIOS_OK != CBiosSyncDataWithVbios(disp_info->cbios_ext, &DataParam)) + { + status = DISP_FAIL; + } + return status; +} + +int disp_cbios_get_active_devices(disp_info_t *disp_info, int* devices) +{ + int status = DISP_OK; + CIP_ACTIVE_DEVICES activeDevices = {0}; + + if(CBIOS_OK != CBiosGetActiveDevice(disp_info->cbios_ext, &activeDevices)) + { + status = DISP_FAIL; + } + else + { + gf_memcpy(devices, activeDevices.DeviceId, sizeof(activeDevices.DeviceId)); + } + return status; +} + +int disp_cbios_detect_connected_output(disp_info_t *disp_info, int to_detect, int full_detect) +{ + void *pcbe = disp_info->cbios_ext; + CIP_DEVICES_DETECT_PARAM devicesDetectParam = {0}; + int status; + int curr_dev = 0; + + devicesDetectParam.DevicesToDetect = disp_info->support_output & to_detect; + devicesDetectParam.FullDetect = full_detect; + + status = CBiosDetectAttachedDisplayDevices(pcbe, &devicesDetectParam); + + if(status == CBIOS_OK) + { + curr_dev = devicesDetectParam.DetectedDevices; + } + + return curr_dev; +} + +//get monitor type per device id, connected = 0, supported monitor type, =1, current connected monitor type +int disp_cbios_get_monitor_type(disp_info_t *disp_info, int device_id, int connected) +{ + int status = CBIOS_OK; + int monitor_type = 0; + void* pcbe = disp_info->cbios_ext; + CBIOS_QUERY_MONITOR_TYPE_PER_PORT query_monitor = {0}; + + if(device_id) + { + query_monitor.ActiveDevId = GET_LAST_BIT(device_id); + query_monitor.bConnected = (connected)? CBIOS_TRUE : CBIOS_FALSE; + + status = CBiosGetMonitorTypePerPort(pcbe, &query_monitor); + + if(status == CBIOS_OK) + { + monitor_type = (int)query_monitor.MonitorType; + } + } + monitor_type = disp_biosmonitor_to_output(monitor_type); + + return monitor_type; +} + +int disp_cbios_set_hdac_connect_status(disp_info_t *disp_info, int device , int bPresent, int bEldValid) +{ + void *pcbe = disp_info->cbios_ext; + CBIOS_HDAC_PARA CbiosHDACPara = {0}; + int monitor_type = 0; + + monitor_type = disp_cbios_get_monitor_type(disp_info, device, FALSE); + if (monitor_type & (UT_OUTPUT_TYPE_HDMI | UT_OUTPUT_TYPE_DP | UT_OUTPUT_TYPE_MHL)) + { + CbiosHDACPara.Size = sizeof(CBIOS_HDAC_PARA); + CbiosHDACPara.DeviceId = device; + CbiosHDACPara.bPresent = bPresent; + CbiosHDACPara.bEldValid = bEldValid; + + CBiosSetHDACConnectStatus(pcbe, &CbiosHDACPara); + } + return DISP_OK; +} + +int disp_cbios_set_mode(disp_info_t *disp_info, int crtc, struct drm_display_mode* mode, struct drm_display_mode* adjusted_mode, int flag) +{ + void* pcbe = disp_info->cbios_ext; + CBIOS_STATUS cb_status; + int temp = 0; + + CBiosSettingModeParams mode_param = {0}; + + temp = adjusted_mode->clock * 1000/adjusted_mode->htotal; + mode_param.DestModeParams.RefreshRate = temp * 100/adjusted_mode->vtotal; + + mode_param.SourcModeParams.XRes = mode->hdisplay; + mode_param.SourcModeParams.YRes = mode->vdisplay; + + mode_param.DestModeParams.XRes = adjusted_mode->hdisplay; + mode_param.DestModeParams.YRes = adjusted_mode->vdisplay; + + mode_param.DestModeParams.InterlaceFlag = (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)? 1 : 0;; + mode_param.DestModeParams.AspectRatioFlag = 0; + mode_param.DestModeParams.OutputSignal = CBIOS_RGBOUTPUT; + + mode_param.ScalerSizeParams.XRes = adjusted_mode->hdisplay; + mode_param.ScalerSizeParams.YRes = adjusted_mode->vdisplay; + + mode_param.IGAIndex = crtc; + mode_param.BitPerComponent = 8; + mode_param.SkipIgaMode = (flag & UPDATE_CRTC_MODE_FLAG)? 0 : 1; + mode_param.SkipDeviceMode = (flag & UPDATE_ENCODER_MODE_FLAG)? 0 : 1; + + if(mode_param.SkipIgaMode == 0) + { + gf_info("KMS set mode to path(iga_index-->active_device): %d-->0x%x.\n", crtc, disp_info->active_output[crtc]); + } + + if(adjusted_mode->flags & DRM_MODE_FLAG_3D_MASK) + { + mode_param.Is3DVideoMode = 1; + mode_param.IsSingleBuffer= 0; + if(mode->flags & DRM_MODE_FLAG_3D_FRAME_PACKING) + { + mode_param.Video3DStruct = FRAME_PACKING; + } + else if(mode->flags & DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE) + { + mode_param.Video3DStruct = FIELD_ALTERNATIVE; + } + else if(mode->flags & DRM_MODE_FLAG_3D_LINE_ALTERNATIVE) + { + mode_param.Video3DStruct = LINE_ALTERNATIVE; + } + else if(mode->flags & DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL) + { + mode_param.Video3DStruct = SIDE_BY_SIDE_FULL; + } + else if(mode->flags & DRM_MODE_FLAG_3D_L_DEPTH) + { + mode_param.Video3DStruct = L_DEPTH; + } + else if(mode->flags & DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH) + { + mode_param.Video3DStruct = L_DEPTH_GRAPHICS; + } + else if(mode->flags & DRM_MODE_FLAG_3D_TOP_AND_BOTTOM) + { + mode_param.Video3DStruct = TOP_AND_BOTTOM; + } + else if(mode->flags & DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF) + { + mode_param.Video3DStruct = SIDE_BY_SIDE_HALF; + } + } + + cb_status = CBiosSetModeToIGA(pcbe, &mode_param); + + return (cb_status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + +int disp_cbios_turn_onoff_screen(disp_info_t *disp_info, int iga, int bOn) +{ + void *pcbe = disp_info->cbios_ext; + int cb_status; + + cb_status = CBiosSetIgaScreenOnOffState(pcbe, bOn, iga); + + return (cb_status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + +int disp_cbios_set_dpms(disp_info_t *disp_info, int device, int dpms_mode) +{ + int status = DISP_OK; + + if(CBIOS_OK != CBiosSetDisplayDevicePowerState(disp_info->cbios_ext, device, dpms_mode)) + { + status = DISP_FAIL; + } + + return status; +} + +int disp_cbios_set_gamma(disp_info_t *disp_info, int pipe, void* data) +{ + int status; + void *pcbe = disp_info->cbios_ext; + CBIOS_GAMMA_PARA gamma_para = {0}; + + if(pipe >= disp_info->num_crtc) + { + return DISP_FAIL; + } + + gamma_para.pGammaTable = data; + + gamma_para.IGAIndex = pipe; + gamma_para.FisrtEntryIndex = 0; + gamma_para.EntryNum = 256; + gamma_para.Flags.bConfigGamma = 1; + gamma_para.Flags.bSetLUT = 1; + + status = CBiosSetGamma(pcbe, &gamma_para); + + return (status == CBIOS_OK)? DISP_OK : DISP_FAIL; +} + +/* +int disp_mode_fixup(disp_info_t *disp_info, gf_mode_info_t *mode) +{ + output_t *output = dispmgri_get_output_by_type(disp_info, mode->output); + gf_mode_t *modes = NULL; + + unsigned int caps = 0; + int delta_x = 0; + int delta_y = 0; + unsigned int delta_xy= -1; + + int i, status = DISP_FAIL; + + if(output == NULL) + { + return status; + } + + modes = output->modes; + + if(mode->bpp == 8) + { + caps = 0x02; + } + else if(mode->bpp == 16) + { + caps = 0x04; + } + else if(mode->bpp == 32) + { + caps = 0x01; + } + + for(i = 0; i < output->num_modes; i++) + { + if((modes[i].xres == mode->width) && + (modes[i].yres == mode->height) && + (modes[i].color_depth_caps & caps)) + { + mode->dst_width = modes[i].xres; + mode->dst_height = modes[i].yres; + mode->dst_refresh = modes[i].refresh_rate; + break; + } + + delta_x = modes[i].xres - mode->width; + delta_y = modes[i].yres - mode->height; + + if((delta_x >= 0) && + (delta_y >= 0) && + (delta_xy > delta_x + delta_y) && + (modes[i].color_depth_caps & caps)) + { + mode->dst_width = modes[i].xres; + mode->dst_height = modes[i].yres; + mode->dst_refresh = modes[i].refresh_rate; + delta_xy = delta_x + delta_y; + } + } + + status = mode->dst_refresh ? DISP_OK:DISP_FAIL; + + return status; + +} + +int disp_pwm_func_ctrl(disp_info_t *disp_info, gf_pwm_func_ctrl_t *pwm) +{ + output_t *output = NULL; + void *pvcbe = disp_info->cbios_ext; + + CBIOS_PWM_FUNCTION_CTRL_PARAMS pwm_param = {0}; + + int status = DISP_FAIL; + + switch(pwm->type) + { + case GF_SET_FAN: + pwm_param.PWMFunction = PWM_SET_FAN_CTRL_STATUS; + pwm_param.PWMFuncSetting.FanCtrlArg.byFanSpeedLevel = pwm->value; + + break; + + case GF_SET_BACKLIGHT: + pwm_param.PWMFunction = PWM_SET_BACKLIGHT_STATUS; + pwm_param.PWMFuncSetting.BLctrlArg.byBLLevel = pwm->value; + + output = disp_get_output_by_type(disp_info, pwm->output); + + output->curr_back_light_level = pwm->value; + + break; + + case GF_GET_FAN: + pwm_param.PWMFunction = PWM_GET_FAN_CTRL_STATUS; + + break; + + case GF_GET_BACKLIGHT: + + pwm_param.PWMFunction = PWM_GET_BACKLIGHT_STATUS; + break; + + default: + return DISP_FAIL; + } + + gf_mutex_lock(disp_mgr->cbios_lock); + status = CBiosPWMFunctionCtrl(pvcbe, &pwm_param); + gf_mutex_unlock(disp_mgr->cbios_lock); + + if(status != 0) + { + gf_error("pwm setting fail\n"); + status = DISP_FAIL; + } + + return status; +} + +int disp_cbios_dbg_level_get(disp_info_t *disp_info) +{ + CBIOS_DBG_LEVEL_CTRL dbg_level_ctl = {0}; + + dbg_level_ctl.Size = sizeof(CBIOS_DBG_LEVEL_CTRL); + dbg_level_ctl.bGetValue = 1; + + CBiosDbgLevelCtl(&dbg_level_ctl); + + return dbg_level_ctl.DbgLevel; +} + +void disp_cbios_dbg_level_set(disp_info_t *disp_info, int dbg_level) +{ + CBIOS_DBG_LEVEL_CTRL dbg_level_ctl = {0}; + dbg_level_ctl.Size = sizeof(CBIOS_DBG_LEVEL_CTRL); + dbg_level_ctl.DbgLevel = dbg_level; + + CBiosDbgLevelCtl(&dbg_level_ctl); +}*/ + +int disp_cbios_get_connector_attrib(disp_info_t *disp_info, gf_connector_t *gf_connector) +{ + void* pcbe = disp_info->cbios_ext; + CBIOS_STATUS status = CBIOS_OK; + CBiosMonitorAttribute attrib = {0}; + + attrib.Size = sizeof(CBiosMonitorAttribute); + attrib.ActiveDevId = gf_connector->output_type; + + status = CBiosQueryMonitorAttribute(pcbe, &attrib); + + if (status == CBIOS_OK) + { + gf_connector->base_connector.display_info.width_mm = attrib.MonitorHorSize; + gf_connector->base_connector.display_info.height_mm = attrib.MonitorVerSize; + gf_connector->monitor_type = disp_biosmonitor_to_output(attrib.MonitorType); + gf_connector->support_audio = attrib.bSupportHDAudio ? 1 : 0; + } + + return (status == CBIOS_OK)? DISP_OK : DISP_FAIL; +} + +int disp_cbios_get_crtc_mask(disp_info_t *disp_info, int device) +{ + void* pcbe = disp_info->cbios_ext; + CBIOS_STATUS status = CBIOS_OK; + CBIOS_GET_IGA_MASK GetIgaMask = {0}; + + GetIgaMask.Size = sizeof(CBIOS_GET_IGA_MASK); + GetIgaMask.DeviceId = device; + + status = CBiosGetIgaMask(pcbe, &GetIgaMask); + + return (status == CBIOS_OK)? GetIgaMask.IgaMask : 0; +} + +int disp_cbios_get_clock(disp_info_t *disp_info, unsigned int type, unsigned int *output) +{ + adapter_info_t* adapter_info = disp_info->adp_info; + CBios_GetClock_Params GetClock = {0}; + + int status = CBIOS_OK; + + GetClock.Size = sizeof(CBios_GetClock_Params); + GetClock.ClockFreq = output; + + if(type == GF_QUERY_ENGINE_CLOCK || type == GF_QUERY_CORE_CLOCK) + { + GetClock.ClockType = CBIOS_ECLKTYPE; + } + else if(type == GF_QUERY_I_CLOCK) + { + GetClock.ClockType = CBIOS_ICLKTYPE; + } + else if (type == GF_QUERY_CPU_FREQUENCE) + { + GetClock.ClockType = CBIOS_CPUFRQTYPE; + } + else if(type == GF_QUERY_VCLK) + { + GetClock.ClockType = CBIOS_VCLKTYPE; + } + else if(type == GF_QUERY_MCLK) + { + GetClock.ClockType = CBIOS_MCLKTYPE; + } + else + { + gf_error("unknown get clock type: %d.\n", type); + + gf_assert(0, "Invalid clock type."); + } + + status = CBiosGetClock(disp_info->cbios_ext, &GetClock); + + if(status != CBIOS_OK) + { + gf_error("disp_cbios_get_clock failed: %d.\n", status); + } + + if (type == GF_QUERY_ENGINE_CLOCK || type == GF_QUERY_CORE_CLOCK) + { + *output = (gf_do_div(*output, 10000) + 1) * 10000; + + if((adapter_info->chip_id >= CHIP_ARISE1020) && (adapter_info->chip_id < CHIP_ARISE2030) && (type == GF_QUERY_CORE_CLOCK)) + { + *output *= 2; + } + } + + if ((adapter_info->chip_id >= CHIP_ARISE2030) && (type == GF_QUERY_VCLK)) + { + *output = (gf_do_div(*output, 10000) + 1) * 10000 * 2; + } + + return (status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + +int disp_cbios_set_clock(disp_info_t *disp_info, unsigned int type, unsigned int para) +{ + CBios_SetClock_Params SetClock = {0}; + + int status = CBIOS_OK; + + SetClock.Size = sizeof(CBios_SetClock_Params); + + if (type == GF_SET_I_CLOCK) + { + SetClock.ClockType = CBIOS_ICLKTYPE; + SetClock.ClockFreq = para; + } + else if (type == GF_SET_CPU_FREQUENCE) + { + SetClock.ClockType = CBIOS_CPUFRQTYPE; + SetClock.ClockFreq = para; + } + else + { + gf_error("unknown set clock type: %d.\n", type); + + gf_assert(0, "Invalid clock type."); + } + + status = CBiosSetClock(disp_info->cbios_ext, &SetClock); + + if(status != CBIOS_OK) + { + gf_error("disp_cbios_set_clock failed: %d.\n", status); + } + + return (status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + +int disp_cbios_enable_hdcp(disp_info_t *disp_info, unsigned int enable, unsigned int devices) +{ + CBiosContentProtectionOnOffParams hdcp_para = {0}; + + int status = CBIOS_OK; + + hdcp_para.Size = sizeof(CBiosContentProtectionOnOffParams); + hdcp_para.DevicesId = devices; + hdcp_para.bHdcpStatus = enable ? CBIOS_TRUE : CBIOS_FALSE; + + status = CBiosContentProtectionOnOff(disp_info->cbios_ext, &hdcp_para); + + if (status != CBIOS_OK) + { + gf_info("disp_cbios_enable_hdcp failed\n"); + } + + return (status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + +int disp_cbios_get_hdcp_status(disp_info_t *disp_info, gf_hdcp_op_t *dhcp_op, unsigned int devices) +{ + CBIOS_HDCP_STATUS_PARA hdcp_status = {0}; + + int status = CBIOS_OK; + + hdcp_status.Size = sizeof(CBIOS_HDCP_STATUS_PARA); + hdcp_status.DevicesId = devices; + + status = CBiosGetHDCPStatus(disp_info->cbios_ext, &hdcp_status); + + if (status == CBIOS_OK) + { + dhcp_op->result = hdcp_status.HdcpStatus == CBIOS_TRUE ? GF_HDCP_ENABLED : GF_HDCP_FAILED; + } + else + { + gf_error("disp_cbios_get_hdcp_status failed\n"); + } + + return (status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + +static unsigned int DrmFormat2CBiosFormat(unsigned int drm_format, unsigned long long modifier) +{ + CBIOS_FORMAT cbios_format = CBIOS_FMT_INVALID; + switch (drm_format) + { + case DRM_FORMAT_RGB565: + cbios_format = CBIOS_FMT_R5G6B5; + break; + case DRM_FORMAT_ARGB8888: + if (modifier == DRM_FORMAT_MOD_GF_RB_ALT) + cbios_format = CBIOS_FMT_A8B8G8R8; + else + cbios_format = CBIOS_FMT_A8R8G8B8; + break; + case DRM_FORMAT_ABGR8888: + cbios_format = CBIOS_FMT_A8B8G8R8; + break; + case DRM_FORMAT_XBGR8888: + cbios_format = CBIOS_FMT_X8B8G8R8; + break; + case DRM_FORMAT_XRGB8888: + if (modifier == DRM_FORMAT_MOD_GF_RB_ALT) + cbios_format = CBIOS_FMT_X8B8G8R8; + else + cbios_format = CBIOS_FMT_X8R8G8B8; + break; + case DRM_FORMAT_ARGB2101010: + cbios_format = CBIOS_FMT_A2R10G10B10; + break; + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + cbios_format = CBIOS_FMT_CRYCBY422_16BIT; + break; + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + cbios_format = CBIOS_FMT_YCRYCB422_16BIT; + break; + case DRM_FORMAT_AYUV: + cbios_format = CBIOS_FMT_YCBCR8888_32BIT; + break; + default: + gf_assert(0, "invalid drm format"); + cbios_format = CBIOS_FMT_A8R8G8B8; + break; + } + + return cbios_format; +} + +int disp_cbios_crtc_flip(disp_info_t *disp_info, gf_crtc_flip_t *arg) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_framebuffer *fb = arg->fb; + struct drm_gf_framebuffer *gfb = fb? to_gfb(arg->fb) : NULL; + CBIOS_OVERLAY_INFO overlay = {0}; + CBIOS_STREAM_PARA input_stream = {0}; + CBIOS_PLANE_PARA disp_plane = {0}; + CBIOS_UPDATE_FRAME_PARA update_frame = {0}; + + update_frame.Size = sizeof(update_frame); + update_frame.IGAIndex = arg->crtc; + update_frame.pPlanePara[0] = &disp_plane; + + disp_plane.PlaneIndex = arg->stream_type; + disp_plane.StreamType = arg->stream_type; + disp_plane.pInputStream = &input_stream; + + trace_gfx_crtc_flip(gf_card->index << 16 | arg->crtc, arg, gfb ? gfb->obj : NULL); + + if(fb) + { + disp_plane.FlipMode.FlipType = CBIOS_PLANE_FLIP_WITH_ENABLE; + } + else + { + disp_plane.FlipMode.FlipType = CBIOS_PLANE_FLIP_WITH_DISABLE; + } + + if(fb) + { + input_stream.SurfaceAttrib.StartAddr = gfb->obj->info.gpu_virt_addr; + input_stream.SurfaceAttrib.SurfaceSize = (fb->width) | (fb->height << 16); +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 10, 0) + input_stream.SurfaceAttrib.SurfaceFmt = DrmFormat2CBiosFormat(fb->pixel_format, fb->modifier[0]); +#elif DRM_VERSION_CODE < KERNEL_VERSION(4, 11, 0) + input_stream.SurfaceAttrib.SurfaceFmt = DrmFormat2CBiosFormat(fb->pixel_format, fb->modifier); +#else + input_stream.SurfaceAttrib.SurfaceFmt = DrmFormat2CBiosFormat(fb->format->format, fb->modifier); +#endif + input_stream.SurfaceAttrib.Pitch = fb->pitches[0]; + input_stream.SurfaceAttrib.bCompress = (gfb->obj->info.compress_format != 0); + if(input_stream.SurfaceAttrib.bCompress) + { + input_stream.SurfaceAttrib.BLIndex = gfb->obj->info.bl_slot_index; + input_stream.SurfaceAttrib.Range_Type = gfb->obj->info.compress_format; + } + + input_stream.SrcWindow.Position = arg->src_x | (arg->src_y << 16); + input_stream.SrcWindow.WinSize = arg->src_w | (arg->src_h << 16); + + input_stream.DispWindow.Position = arg->crtc_x | (arg->crtc_y << 16); + input_stream.DispWindow.WinSize = arg->crtc_w | (arg->crtc_h << 16); + + if(disp_plane.PlaneIndex == CBIOS_STREAM_PS) + { + disp_plane.pOverlayInfo = &overlay; + overlay.KeyMode = CBIOS_WINDOW_KEY; + overlay.WindowKey.Ka = 0; + overlay.WindowKey.Kb = 8; + } +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + else + { + disp_plane.pOverlayInfo = &overlay; + if(arg->blend_mode == DRM_MODE_BLEND_PIXEL_NONE) + { + overlay.KeyMode = CBIOS_CONSTANT_ALPHA; + overlay.ConstantAlphaBlending.ConstantAlpha = (CBIOS_U8)(arg->const_alpha >> 8); + } + else if(arg->blend_mode == DRM_MODE_BLEND_COVERAGE) //coverage with plane alpha + { + overlay.KeyMode = CBIOS_ALPHA_BLENDING; + overlay.AlphaBlending.bUseAAlpha = (arg->blend_alpha_source)? 1 : 0; + overlay.AlphaBlending.bPremulBlend = 0; + overlay.AlphaBlending.bUsePlaneAlpha = 1; + overlay.AlphaBlending.PlaneValue = (CBIOS_U8)(arg->plane_alpha >> 8); + } + else //premultied with plane alpha + { + overlay.KeyMode = CBIOS_ALPHA_BLENDING; + overlay.AlphaBlending.bUseAAlpha = (arg->blend_alpha_source)? 1 : 0; + overlay.AlphaBlending.bPremulBlend = 1; + overlay.AlphaBlending.bUsePlaneAlpha = 1; + overlay.AlphaBlending.PlaneValue = (CBIOS_U8)(arg->plane_alpha >> 8); + } + } +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + if(arg->async_flip) + { + disp_plane.FlipMode.FlipImme = 1; + } +#endif + } + + return (CBiosUpdateFrame(disp_info->cbios_ext, &update_frame) == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + + +int disp_cbios_update_cursor(disp_info_t *disp_info, gf_cursor_update_t *arg) +{ + CBIOS_CURSOR_PARA update_cursor = {0}; + + //update_cursor.bVsyncOn = arg->vsync_on; + if (arg->bo) + { + update_cursor.bDisable = 0; + if (arg->width == 64 && arg->height == 64) + { + update_cursor.Position.CursorSize = CBIOS_CURSOR_SIZE_64x64; + } + else if (arg->width == 128 && arg->height == 128) + { + update_cursor.Position.CursorSize = CBIOS_CURSOR_SIZE_128x128; + } + update_cursor.CursorAttrib.Type = CBIOS_PREMULT_CURSOR; + update_cursor.CursorAttrib.CurAddr = arg->bo->info.gpu_virt_addr; + update_cursor.Position.PositionX = arg->pos_x; + update_cursor.Position.PositionY = arg->pos_y; + } + else + { + update_cursor.bDisable = 1; + } + + update_cursor.Size = sizeof(update_cursor); + update_cursor.IGAIndex = arg->crtc; + + return (CBiosSetCursor(disp_info->cbios_ext, &update_cursor) == CBIOS_OK)? DISP_OK : DISP_FAIL; +} + +int disp_cbios_get_interrupt_info(disp_info_t *disp_info, unsigned int *interrupt_mask) +{ + int status = CBIOS_OK; + CBIOS_INTERRUPT_INFO interrupt_info = {0}; + + status = CBiosGetInterruptInfo(disp_info->cbios_ext, &interrupt_info); +/* + if(interrupt_info.InterruptType & CBIOS_VSYNC_1_INT) + { + *interrupt_mask |= VSYNC_1_INT; + } + + if(interrupt_info.InterruptType & CBIOS_VSYNC_2_INT) + { + *interrupt_mask |= VSYNC_2_INT; + } + + if(interrupt_info.InterruptType & CBIOS_VSYNC_3_INT) + { + *interrupt_mask |= VSYNC_3_INT; + } + + if(interrupt_info.InterruptType & CBIOS_VSYNC_4_INT) + { + *interrupt_mask |= VSYNC_4_INT; + } + + if(interrupt_info.InterruptType & CBIOS_DP_1_INT) + { + *interrupt_mask |= DP_1_INT; + } + + if(interrupt_info.InterruptType & CBIOS_DP_2_INT) + { + *interrupt_mask |= DP_2_INT; + } + + if(interrupt_info.InterruptType & CBIOS_DP_3_INT) + { + *interrupt_mask |= DP_3_INT; + } + + if(interrupt_info.InterruptType & CBIOS_DP_4_INT) + { + *interrupt_mask |= DP_4_INT; + } + + if(interrupt_info.InterruptType & CBIOS_HDCP_INT) + { + *interrupt_mask |= INT_HDMI_CP; + } + + if(interrupt_info.InterruptType & CBIOS_CEC_INT) + { + *interrupt_mask |= INT_CEC_CONTROL; + } + + if(interrupt_info.InterruptType & CBIOS_HDA_CODEC_INT) + { + *interrupt_mask |= INT_HDCODEC; + }*/ + + if((interrupt_info.AdvancedIntType & CBIOS_FENCE_INT)) /* || + (interrupt_info.AdvancedIntType & CBIOS_PAGE_FAULT_INT) || + (interrupt_info.AdvancedIntType & CBIOS_MXU_INVALID_ADDR_FAULT_INT))*/ //need refine + { + *interrupt_mask |= INT_FENCE; + } + + return (status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + +int disp_cbios_get_dpint_type(disp_info_t *disp_info,unsigned int device) +{ + CBIOS_DP_INT_PARA DpIntPara = {0}; + int hpd = DP_HPD_NONE; + + DpIntPara.Size = sizeof(CBIOS_DP_INT_PARA); + DpIntPara.DeviceId = device; + if(CBIOS_OK == CBiosGetDPIntType(disp_info->cbios_ext, &DpIntPara)) + { + hpd = DpIntPara.IntType; + } + + return hpd; +} + +int disp_cbios_handle_dp_irq(disp_info_t *disp_info, unsigned int device, int int_type, int* need_detect, int* need_comp_edid) +{ + CBIOS_DP_HANDLE_IRQ_PARA handle_irq = {0}; + int status = DISP_FAIL; + + handle_irq.Size = sizeof(CBIOS_DP_HANDLE_IRQ_PARA); + handle_irq.DeviceId = device; + handle_irq.IntType = int_type; + if(CBIOS_OK == CBiosHandleDPIrq(disp_info->cbios_ext, &handle_irq)) + { + status = DISP_OK; + if(need_detect) + { + *need_detect = handle_irq.bNeedDetect; + } + + if(need_comp_edid) + { + *need_comp_edid = handle_irq.bNeedCompEdid; + } + } + + return status; +} + + +void disp_cbios_dump_registers(disp_info_t *disp_info, int type) +{ + CBIOS_DUMP_PARA para = {0}; + + para.Size = sizeof(CBIOS_DUMP_PARA); + + para.DumpType = CBIOS_DUMP_VCP_INFO | + CBIOS_DUMP_MODE_INFO | + CBIOS_DUMP_CLOCK_INFO; + + if(type & DUMP_REGISTER_STREAM) + { + para.DumpType |= CBIOS_DUMP_PS1_REG | + CBIOS_DUMP_PS2_REG | + CBIOS_DUMP_SS1_REG | + CBIOS_DUMP_SS2_REG | + CBIOS_DUMP_TS1_REG | + CBIOS_DUMP_TS2_REG; + } + + CBiosDumpInfo(disp_info->cbios_ext, ¶); +} + +int disp_cbios_set_hda_codec(disp_info_t *disp_info, gf_connector_t* gf_connector) +{ + void *pcbe = disp_info->cbios_ext; + CBIOS_HDAC_PARA CbiosHDACPara = {0}; + int cb_status = CBIOS_OK; + + if((gf_connector->monitor_type == UT_OUTPUT_TYPE_HDMI) || + (gf_connector->monitor_type == UT_OUTPUT_TYPE_MHL) || + (gf_connector->monitor_type == UT_OUTPUT_TYPE_DP)) + { + CbiosHDACPara.Size = sizeof(CBIOS_HDAC_PARA); + CbiosHDACPara.DeviceId = gf_connector->output_type; + + cb_status = CBiosSetHDACodecPara(pcbe, &CbiosHDACPara); + } + return (cb_status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + +int disp_cbios_hdcp_isr(disp_info_t *disp_info, gf_connector_t* gf_connector) +{ + void *pcbe = disp_info->cbios_ext; + CBIOS_HDCP_ISR_PARA CbiosHdcpIsrPara = {0}; + int cb_status = CBIOS_OK; + + if(gf_connector->monitor_type == UT_OUTPUT_TYPE_HDMI || gf_connector->monitor_type == UT_OUTPUT_TYPE_DVI) + { + CbiosHdcpIsrPara.Size = sizeof(CBIOS_HDCP_ISR_PARA); + CbiosHdcpIsrPara.DevicesId = gf_connector->output_type; + + cb_status = CBiosHDCPIsr(pcbe, &CbiosHdcpIsrPara); + } + return (cb_status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + + +int disp_cbios_get_hdmi_audio_format(disp_info_t *disp_info, unsigned int device_id, gf_hdmi_audio_formats *audio_formats) +{ + void *pcbe = disp_info->cbios_ext; + + unsigned int buffer_size = 0; + unsigned int real_buffer_size = 0; + unsigned int num_formats = 0; + unsigned int i = 0; + CBiosHDMIAudioFormat *cb_audio_formats = NULL; + CBIOS_STATUS cb_status = CBIOS_OK; + + cb_status = CBiosGetHDMIAudioFomatListBufferSize(pcbe, device_id, &buffer_size); + if ((cb_status != CBIOS_OK) || (buffer_size == 0)) + { + gf_error("can not get the audio format buffer size\n"); + return DISP_FAIL; + } + + cb_audio_formats = gf_calloc(buffer_size); + if (cb_audio_formats == NULL) + { + return DISP_FAIL; + } + + num_formats = buffer_size / sizeof(CBiosHDMIAudioFormat); + for(i = 0; i < num_formats; i++) + { + cb_audio_formats[i].Size = sizeof(CBiosHDMIAudioFormat); + } + + cb_status = CBiosGetHDMIAudioFomatList(pcbe, device_id, cb_audio_formats, &real_buffer_size); + + if ((cb_status != CBIOS_OK) || (real_buffer_size == 0)) + { + gf_error("can not get the audio format\n"); + gf_free(cb_audio_formats); + return DISP_FAIL; + } + + if (num_formats > sizeof(audio_formats->audio_formats)/sizeof(gf_hdmi_audio_format_t)) + { + gf_error("the num of audio formats exceeds the buffer size, so cut it."); + num_formats = sizeof(audio_formats->audio_formats)/sizeof(gf_hdmi_audio_format_t); + } + + audio_formats->num_formats = num_formats; + for (i = 0; i < num_formats; i++) + { + audio_formats->audio_formats[i].format = (GF_HDMI_AUDIO_FORMAT_TYPE)cb_audio_formats[i].Format; + audio_formats->audio_formats[i].max_channel_num= cb_audio_formats[i].MaxChannelNum; + audio_formats->audio_formats[i].sample_rate_unit = cb_audio_formats[i].SampleRateUnit; + audio_formats->audio_formats[i].unit = cb_audio_formats[i].Unit; + } + + if (cb_audio_formats) + { + gf_free(cb_audio_formats); + cb_audio_formats = NULL; + } + return DISP_OK; +} + +void disp_cbios_reset_hw_block(disp_info_t *disp_info, gf_hw_block hw_block) +{ + CBIOS_HW_BLOCK cbios_hw_block = {0}; + + if(hw_block == GF_HW_IGA) + { + cbios_hw_block = CBIOS_HW_IGA; + } + else + { + cbios_hw_block = CBIOS_HW_NONE; + } + + CBiosResetHWBlock(disp_info->cbios_ext, cbios_hw_block); +} + +int disp_cbios_get_counter(disp_info_t* disp_info, gf_get_counter_t* get_counter) +{ + CBIOS_GET_HW_COUNTER CbiosGetHwCnt = {0}; + int status = DISP_FAIL; + + if(!get_counter || get_counter->crtc_index >= disp_info->num_crtc) + { + return status; + } + + CbiosGetHwCnt.IgaIndex = get_counter->crtc_index; + + if(get_counter->hpos) + { + CbiosGetHwCnt.bGetPixelCnt = 1; + } + + if(get_counter->vpos) + { + CbiosGetHwCnt.bGetLineCnt = 1; + } + + if(get_counter->vblk) + { + CbiosGetHwCnt.bGetFrameCnt = 1; + } + + if(CBIOS_OK == CBiosGetHwCounter(disp_info->cbios_ext, &CbiosGetHwCnt)) + { + status = DISP_OK; + } + if(get_counter->hpos) + { + *get_counter->hpos = (status == DISP_OK)? CbiosGetHwCnt.Value[CBIOS_COUNTER_PIXEL] : 0; + } + if(get_counter->vpos) + { + *get_counter->vpos = (status == DISP_OK)? CbiosGetHwCnt.Value[CBIOS_COUNTER_LINE] : 0; + } + if(get_counter->vblk) + { + *get_counter->vblk = (status == DISP_OK)? CbiosGetHwCnt.Value[CBIOS_COUNTER_FRAME] : 0; + } + if(get_counter->in_vblk) + { + *get_counter->in_vblk = (status == DISP_OK && CbiosGetHwCnt.bInVblank)? 1 : 0; + } + + return status; +} + +int disp_get_vip_capture_fmt(unsigned int fmt) +{ + unsigned int capture_fmt = GF_VIP_FMT_RGB444_24BIT_SDR; + + switch (fmt) + { + case CBIOS_VIP_FMT_RGB444_24BIT_SDR: + { + capture_fmt = GF_VIP_FMT_RGB444_24BIT_SDR; + } + break; + + case CBIOS_VIP_FMT_YCBCR444_24BIT_SDR: + { + capture_fmt = GF_VIP_FMT_YCBCR444_24BIT_SDR; + } + break; + + case CBIOS_VIP_FMT_YCBCR422_8BIT_SDR_ES: + { + capture_fmt = GF_VIP_FMT_YCBCR422_8BIT_SDR_ES; + } + break; + + case CBIOS_VIP_FMT_YCBCR422_8BIT_DDR_ES: + { + capture_fmt = GF_VIP_FMT_YCBCR422_8BIT_DDR_ES; + } + break; + + + default: + { + gf_error("not supported yet, default to RGB444\n"); + } + break; + + } + + return capture_fmt; + +} + +int disp_get_wb_capture_fmt(unsigned int fmt) +{ + unsigned int capture_fmt = GF_WB_FMT_RGB888; + + switch (fmt) + { + case CBIOS_RGBOUTPUT: + { + capture_fmt = GF_WB_FMT_RGB888; + } + break; + + default: + { + capture_fmt = GF_WB_FMT_RGB888; + gf_error("not supported fmt %d, default to RGB\n", fmt); + } + break; + + } + + return capture_fmt; + +} + +int disp_cbios_vip_ctl(disp_info_t *disp_info, gf_vip_set_t *v_set) +{ + void *pcbe = disp_info->cbios_ext; + CBIOS_VIP_CTRL_DATA cbios_vip_params = {0}; + int cb_status = CBIOS_OK; + int i = 0; + + cbios_vip_params.vip = v_set->vip; + cbios_vip_params.cmd = CBIOS_VIP_NOP; + + switch (v_set->op) + { + case GF_VIP_ENABLE: + case GF_VIP_DISABLE: + { + cbios_vip_params.cmd = CBIOS_VIP_ENABLE; + cbios_vip_params.enable = v_set->op == GF_VIP_ENABLE ? 1 : 0; + } + break; + + case GF_VIP_QUERY_CAPS: + { + cbios_vip_params.cmd = CBIOS_VIP_QUERY_CAPS; + } + break; + + case GF_VIP_SET_MODE: + { + cbios_vip_params.cmd = CBIOS_VIP_SET_MODE; + cbios_vip_params.modeSet.fmt = CBIOS_VIP_FMT_RGB444_24BIT_SDR; + cbios_vip_params.modeSet.vCard = v_set->mode.chip; + cbios_vip_params.modeSet.xRes = v_set->mode.x_res; + cbios_vip_params.modeSet.yRes = v_set->mode.y_res; + cbios_vip_params.modeSet.refs = v_set->mode.refs; + } + break; + + case GF_VIP_SET_BUFFER: + { + cbios_vip_params.cmd = CBIOS_VIP_SET_BUFFER; + cbios_vip_params.fbSet.num = v_set->fb.fb_num; + cbios_vip_params.fbSet.idx = v_set->fb.fb_idx; + cbios_vip_params.fbSet.addr = v_set->fb.fb_addr; + } + break; + + default: + { + gf_error("unspported vip set cmd: %d", v_set->op); + } + break; + + } + + if (cbios_vip_params.cmd != CBIOS_VIP_NOP) + { + cb_status = CBiosVIPCtl(pcbe, &cbios_vip_params); + } + + if (cbios_vip_params.cmd == CBIOS_VIP_QUERY_CAPS && cb_status == CBIOS_OK) + { + v_set->caps.mode_num = cbios_vip_params.caps.supportModeNum; + if (v_set->caps.mode != NULL) + { + for (; i < v_set->caps.mode_num; i++) + { + v_set->caps.mode[i].xRes = cbios_vip_params.caps.mode[i].xRes; + v_set->caps.mode[i].yRes = cbios_vip_params.caps.mode[i].yRes; + v_set->caps.mode[i].refreshrate = cbios_vip_params.caps.mode[i].refs; + v_set->caps.mode[i].fmt = disp_get_vip_capture_fmt(cbios_vip_params.caps.mode[i].fmt); + } + } + } + + return (cb_status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + +int disp_cbios_wb_ctl(disp_info_t *disp_info, gf_wb_set_t *wb_set) +{ + void *pcbe = disp_info->cbios_ext; + CBIOS_WB_PARA cbios_wb_params = {0}; + CBiosSettingModeParams cbios_mode = {0}; + int cb_status = CBIOS_OK; + + if (wb_set->op_flags & GF_WB_QUERY_CAPS) + { + cbios_mode.IGAIndex = wb_set->iga_idx; + CBiosGetModeFromIGA(pcbe, &cbios_mode); + + wb_set->input_mode.src_x = cbios_mode.DestModeParams.XRes; + wb_set->input_mode.src_y = cbios_mode.DestModeParams.YRes; + wb_set->input_mode.refreshrate = cbios_mode.DestModeParams.RefreshRate; + wb_set->input_mode.capture_fmt = disp_get_wb_capture_fmt(cbios_mode.DestModeParams.OutputSignal); + + return cb_status; + } + + cbios_wb_params.IGAIndex = wb_set->iga_idx; + + if (wb_set->op_flags & GF_WB_SET_BYPASS_MODE) + { + cbios_wb_params.bByPass = 1; + } + + if (wb_set->op_flags & GF_WB_SET_VSYNC_OFF) + { + cbios_wb_params.bUpdateImme = 1; + } + + if ((wb_set->op_flags & GF_WB_ENABLE) || (wb_set->op_flags & GF_WB_DISABLE)) + { + cbios_wb_params.bEnableOP = 1; + cbios_wb_params.bEnable = (wb_set->op_flags & GF_WB_ENABLE) ? 1 : 0; + } + + if (wb_set->op_flags & GF_WB_SET_MODE) + { + cbios_wb_params.bSetModeOP = 1; + cbios_wb_params.SrcSize = (wb_set->mode.src_x & 0xFFFF) | ((wb_set->mode.src_y & 0xFFFF) << 16); + //FIXME: to refine the fmt. + cbios_wb_params.SrcFmt = CSC_FMT_RGB; + cbios_wb_params.CscOutFmt = CSC_FMT_RGB; + + if (wb_set->op_flags & GF_WB_SET_DOWNSCALER_MODE) + { + cbios_wb_params.DSCL.Mode = CBIOS_WB_P2P; + cbios_wb_params.DSCL.DstSize = (wb_set->mode.dst_x & 0xFFFF) | ((wb_set->mode.dst_x & 0xFFFF) << 16); + cbios_wb_params.DSCL.bDoubleBuffer = wb_set->mode.double_buf; + } + } + + if (wb_set->op_flags & GF_WB_SET_BUFFER) + { + cbios_wb_params.bSetAddrOP = 1; + cbios_wb_params.DstBaseAddr = wb_set->fb.fb_addr; + } + + cb_status = CBiosSetWriteback(pcbe, &cbios_wb_params); + + return (cb_status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + +int disp_wait_idle(void *_disp_info) +{ + disp_info_t *disp_info = _disp_info; + + unsigned long timeout_j = jiffies + msecs_to_jiffies(50) + 1; + unsigned int in_vblank; + int ret = DISP_OK; + gf_get_counter_t get_cnt = {0}; + unsigned int i = 0; + + if(!disp_info) + { + gf_info("why disp_info is null, 0x%x 0x%x\n",disp_info,_disp_info); + return -1; + } + + i = 0; + while(i < disp_info->num_crtc) + { + if(disp_info->active_output[i]) + { + break; + } + i++; + } + + //case1): has one active crtc, wait the crtc's vblank + //case2): no active crtc, no need to wait. + if(i != disp_info->num_crtc) //has active crtc + { + get_cnt.crtc_index = i; + get_cnt.in_vblk = &in_vblank; + + disp_cbios_get_counter(disp_info, &get_cnt); + + while(in_vblank == 1) + { + if(time_after(jiffies, timeout_j)) + { + gf_error("wait in vblank tiemout \n"); + ret = -ETIMEDOUT; + break; + } + disp_cbios_get_counter(disp_info, &get_cnt); + } + + timeout_j = jiffies + msecs_to_jiffies(50) + 1; + + while(in_vblank == 0) + { + if(time_after(jiffies, timeout_j)) + { + gf_error("wait in active timeout\n"); + ret = -ETIMEDOUT; + break; + } + disp_cbios_get_counter(disp_info, &get_cnt); + } + } + + return ret; +} + +static unsigned int cal_bits(unsigned int v) +{ + unsigned int n = 0; + + while(v) + { + if(v & 0x1) + n++; + v >>= 1; + } + return n; +} + +static unsigned int validate_chip_slice_mask(unsigned int org) +{ + int aval_efuse_slice = org & 0xFFF; + unsigned int per_gpc_slice = 0; + unsigned int gpc_idx = 0; + unsigned int new_slice = 0; + + while(aval_efuse_slice > 0) + { + per_gpc_slice = aval_efuse_slice & 0xF; + + new_slice += per_gpc_slice << (gpc_idx * 4); + gpc_idx++; + aval_efuse_slice >>= 4; + } + + if(new_slice == 0) new_slice = 1; + + return new_slice; +} + +int disp_cbios_get_slice_num(disp_info_t *disp_info) +{ + adapter_info_t* adapter_info = disp_info->adp_info; + void *pcbe = disp_info->cbios_ext; + signed char slice_num = 0; + unsigned int efuse_slice_disable_mask = 0, efuse_slice_enable_mask = 0; + unsigned int total_usable_slice_num = 0; + unsigned int final_slice_mask = 0; + unsigned int gpc_slice_bits = 0, gpc_slice_mask = 0, gpc_idx = 0; + + int status = DISP_OK; + + if(CBIOS_OK != CBiosGetSliceNum(pcbe, &slice_num, &efuse_slice_disable_mask)) + { + status = DISP_FAIL; + } + + //efuse use bit1~bit12, bit0 not use. + efuse_slice_disable_mask &= 0x1FFF; + efuse_slice_disable_mask >>=1; + + if(efuse_slice_disable_mask >= 0xFFF){ + efuse_slice_disable_mask = 0; + gf_info("efuse disable all slice, ignore efuse disable bits\n"); + } + + efuse_slice_enable_mask = validate_chip_slice_mask((~efuse_slice_disable_mask) & 0xFFF); + + gf_info("disp_cbios_get_slice_num: get slice_num: %d, efuse enable slice: %x\n", slice_num, efuse_slice_enable_mask); + + total_usable_slice_num = cal_bits(efuse_slice_enable_mask & 0xFFF); + + if(slice_num <= 0 ||slice_num > total_usable_slice_num){ + gf_info("cbios get invalidate slice enable num, force to efuse's slice num: %d\n", total_usable_slice_num); + slice_num = total_usable_slice_num; + } + + while(slice_num > 0 && gpc_idx < 3) + { + gpc_slice_mask = efuse_slice_enable_mask & 0xF; + gpc_slice_bits = cal_bits(gpc_slice_mask); + + if(slice_num < gpc_slice_bits) + { + //if(slice_num == 4), not likely, since nax value for gpc_slice_bits is 4 + if(slice_num == 2 ||slice_num == 3){ + gpc_slice_mask = 0x3; + gpc_slice_bits = 2; + }else if(slice_num == 1){ + gpc_slice_mask = 0x1; + gpc_slice_bits = 1; + } + } + + final_slice_mask += (gpc_slice_mask << (gpc_idx*4)); + + efuse_slice_enable_mask >>= 4; + + slice_num -=gpc_slice_bits; + + gpc_idx++; + } + + adapter_info->chip_slice_mask = validate_chip_slice_mask(final_slice_mask); + gf_info("final slice mask:%x\n", adapter_info->chip_slice_mask); + + return status; +} + +int disp_cbios_i2c_ctrl(disp_info_t *disp_info, gf_i2c_param_t *i2c_param) +{ + CBIOS_PARAM_I2C_DATA i2c_data = {0}; + int cb_status = CBIOS_OK; + i2c_data.bUseDevType = i2c_param->use_dev_type; + i2c_data.DeviceId = i2c_param->device_id; + i2c_data.PortNumber = i2c_param->port; + i2c_data.SlaveAddress = i2c_param->slave_addr; + i2c_data.OffSet = i2c_param->offset; + i2c_data.Buffer = i2c_param->buf; + i2c_data.BufferLen = i2c_param->buf_len; + i2c_data.bHDCPEnable = i2c_param->use_hdcp; + switch (i2c_param->request_type) + { + case GF_I2C_DDCCI: + i2c_data.RequestType = CBIOS_I2CDDCCI; + break; + case GF_I2C_HDCP: + i2c_data.RequestType = CBIOS_I2CHDCP; + break; + default: + i2c_data.RequestType = CBIOS_I2CNORMAL; + break; + } + if (i2c_param->op == GF_I2C_WRITE) + cb_status = CBiosI2CDataWrite(disp_info->cbios_ext, &i2c_data); + else + cb_status = CBiosI2CDataRead(disp_info->cbios_ext, &i2c_data); + return (cb_status == CBIOS_OK) ? DISP_OK : DISP_FAIL; +} + diff --git a/drivers/gpu/drm/arise/linux/gf_cbios.h b/drivers/gpu/drm/arise/linux/gf_cbios.h new file mode 100644 index 0000000000000..97609533fb881 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_cbios.h @@ -0,0 +1,168 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_CBIOS_H__ +#define __GF_CBIOS_H__ +#include "CBios.h" + +#define MAX_CRTC_NUM CBIOS_MAX_CRTCS + +enum +{ + FAMILY_CMODEL, + FAMILY_CLB, + FAMILY_DST, + FAMILY_CSR, + FAMILY_INV, + FAMILY_EXC, + FAMILY_ELT, + FAMILY_LAST, +}; + +enum +{ + CHIP_CMODEL, + CHIP_CLB, + CHIP_DST, + CHIP_CSR, + CHIP_INV, + CHIP_H5, + CHIP_H5S1, + CHIP_H6S2, + CHIP_CMS, + CHIP_METRO, + CHIP_MANHATTAN, + CHIP_MATRIX, + CHIP_DST2, + CHIP_DST3, + CHIP_DUMA, + CHIP_H6S1, + CHIP_DST4, + CHIP_EXC1, //Excalibur-1 + CHIP_E2UMA, //E2UMA + CHIP_ELT, //Elite + CHIP_ELT1K, //Elite1k + CHIP_ELT2K, //Elite2k + CHIP_ELT2K5, //Elite2500 + CHIP_ZX2000, //ZX2000 + CHIP_ELT3K, //ELITE3K + CHIP_ARISE=CHIP_ELT3K, //ARISE + CHIP_ARISE10C0T, //ARISE10C0T + CHIP_ARISE1040, //ARISE1040 + CHIP_ARISE1020, //ARISE1020 + CHIP_ARISE1010, //ARISE1010 + CHIP_ARISE2030, //ARISE2030 + CHIP_ARISE2020, //ARISE2020 + CHIP_CHX001, //CHX001 + CHIP_CHX002, //CHX002 + CHIP_ZX2100, //ZX2100 + CHIP_LAST, //Maximum number of chips supported. +}; + + +typedef struct +{ + int crtc_index; + int *hpos; + int *vpos; + int *vblk; + int *in_vblk; +}gf_get_counter_t; + + + +#define GF_SELECT_MCLK 0x00 +#define GF_SELECT_DCLK1 0x01 +#define GF_SELECT_DCLK2 0x02 +#define GF_SELECT_TVCLK 0x03 +#define GF_SELECT_ECLK 0x04 +#define GF_SELECT_ICLK 0x05 + +#define GF_VBIOS_ROM_SIZE 0x10000 +#define GF_SHADOW_VBIOS_SIZE 0x20000 +#define GF_PMP_SHADOW_IMG_SIZE 0x200 +#define GF_PMP_SHADOW_IMG_OFFSET 0x7CE00 // 52K - 512 byte + +#define GF_RUN_HDCP_CTS 0 + +#define EDID_BUF_SIZE 512 + +#define DUMP_REGISTER_STREAM 0x1 + +#define UPDATE_CRTC_MODE_FLAG 0x1 +#define UPDATE_ENCODER_MODE_FLAG 0x2 + +int disp_get_output_num(int outputs); +int disp_init_cbios(disp_info_t *disp_info); +int disp_cbios_init_hw(disp_info_t *disp_info); +int disp_cbios_cleanup(disp_info_t *disp_info); +void disp_cbios_get_crtc_resource(disp_info_t *disp_info); +void disp_cbios_get_crtc_caps(disp_info_t *disp_info); +void disp_cbios_query_vbeinfo(disp_info_t *disp_info); +int disp_cbios_get_modes_size(disp_info_t *disp_info, int output); +int disp_cbios_get_modes(disp_info_t *disp_info, int output, void* buffer, int buf_size); +int disp_cbios_get_adapter_modes_size(disp_info_t *disp_info); +int disp_cbios_get_adapter_modes(disp_info_t *disp_info, void* buffer, int buf_size); +int disp_cbios_merge_modes(CBiosModeInfoExt* merge_mode_list, CBiosModeInfoExt * adapter_mode_list, unsigned int const adapter_mode_num, + CBiosModeInfoExt const * dev_mode_list, unsigned int const dev_mode_num); +int disp_cbios_cbmode_to_drmmode(disp_info_t *disp_info, int output, void* cbmode, int i, struct drm_display_mode *drm_mode); +int disp_cbios_3dmode_to_drmmode(disp_info_t *disp_info, int output, void* mode, int i, struct drm_display_mode *drm_mode); +int disp_cbios_get_3dmode_size(disp_info_t* disp_info, int output); +int disp_cbios_get_3dmodes(disp_info_t *disp_info, int output, void* buffer, int buf_size); +void* disp_cbios_get_device_modelist(disp_info_t *disp_info, int output_type, int* mode_num); +int disp_cbios_get_mode_timing(disp_info_t *disp_info, int output, struct drm_display_mode *drm_mode); +int disp_cbios_get_monitor_type(disp_info_t *disp_info, int device, int connected); +void* disp_cbios_read_edid(disp_info_t *disp_info, int output); +int disp_cbios_update_output_active(disp_info_t *disp_info, int* outputs); +int disp_cbios_set_mode(disp_info_t *disp_info, int crtc, struct drm_display_mode* mode, struct drm_display_mode* adjusted_mode, int update_flag); +int disp_cbios_set_hdac_connect_status(disp_info_t *disp_info, int device , int bPresent, int bEldValid); +int disp_cbios_turn_onoff_screen(disp_info_t *disp_info, int iga, int on); +int disp_cbios_detect_connected_output(disp_info_t *disp_info, int to_detect, int full_detect); +int disp_cbios_set_dpms(disp_info_t *disp_info, int device, int dpms_mode); +int disp_cbios_sync_vbios(disp_info_t *disp_info); +int disp_cbios_get_active_devices(disp_info_t *disp_info, int* devices); +int disp_cbios_set_gamma(disp_info_t *disp_info, int pipe, void* data); +void disp_write_port_uchar(unsigned char *port, unsigned char value); +void disp_delay_micro_seconds(unsigned int usecs); +int disp_cbios_dbg_level_get(disp_info_t *disp_info); +void disp_cbios_dbg_level_set(disp_info_t *disp_info, int dbg_level); +int disp_cbios_get_connector_attrib(disp_info_t *disp_info, gf_connector_t *gf_connector); +int disp_cbios_get_crtc_mask(disp_info_t *disp_info, int device); +int disp_cbios_get_clock(disp_info_t *disp_info, unsigned int type, unsigned int *clock); +int disp_cbios_set_clock(disp_info_t *disp_info, unsigned int type, unsigned int para); +int disp_cbios_enable_hdcp(disp_info_t *disp_info, unsigned int enable, unsigned int devices); +int disp_cbios_get_hdcp_status(disp_info_t *disp_info, gf_hdcp_op_t *dhcp_op, unsigned int devices); +int disp_cbios_get_interrupt_info(disp_info_t *disp_info, unsigned int *interrupt_mask); +int disp_cbios_get_dpint_type(disp_info_t *disp_info,unsigned int device); +int disp_cbios_handle_dp_irq(disp_info_t *disp_info, unsigned int device, int int_type, int* need_detect, int* need_comp_edid); +void disp_cbios_dump_registers(disp_info_t *disp_info, int type); +int disp_cbios_set_hda_codec(disp_info_t *disp_info, gf_connector_t* gf_connector); +int disp_cbios_hdcp_isr(disp_info_t *disp_info, gf_connector_t* gf_connector); +int disp_cbios_get_hdmi_audio_format(disp_info_t *disp_info, unsigned int device_id, gf_hdmi_audio_formats *audio_formats); +void disp_cbios_reset_hw_block(disp_info_t *disp_info, gf_hw_block hw_block); +int disp_cbios_get_counter(disp_info_t* disp_info, gf_get_counter_t* get_counter); +int disp_cbios_crtc_flip(disp_info_t *disp_info, gf_crtc_flip_t *arg); +int disp_cbios_update_cursor(disp_info_t *disp_info, gf_cursor_update_t *arg); +int disp_wait_for_vblank(disp_info_t* disp_info, int pipe, int timeout); +int disp_cbios_get_slice_num(disp_info_t * disp_info); +#ifdef GF_CAPTURE_VIP_INTERFACE +int disp_cbios_vip_ctl(disp_info_t *disp_info, gf_vip_set_t *v_set); +#endif + +#ifdef GF_CAPTURE_WB_INTERFACE +int disp_cbios_wb_ctl(disp_info_t *disp_info, gf_wb_set_t *wb_set); +#endif +int disp_cbios_i2c_ctrl(disp_info_t *disp_info, gf_i2c_param_t *i2c_param); + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_connector.c b/drivers/gpu/drm/arise/linux/gf_connector.c new file mode 100644 index 0000000000000..dbbb8b87f35db --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_connector.c @@ -0,0 +1,789 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_disp.h" +#include "gf_cbios.h" +#include "gf_atomic.h" +#include "gf_i2c.h" +#include "gf_kms.h" +#include "gf_sink.h" +#include "gf_splice.h" + +gf_connector_t* gf_get_connector_by_device_id(disp_info_t* disp_info, int device_id) +{ + gf_card_t *gf_card = (gf_card_t *)disp_info->gf_card; + struct drm_device *drm = gf_card->drm_dev; + gf_connector_t *gf_conn = NULL; + struct drm_connector *connector = NULL; + + if(!drm || !device_id) + { + return gf_conn; + } + + list_for_each_entry(connector, &drm->mode_config.connector_list, head) + { + if((to_gf_connector(connector))->output_type == device_id) + { + gf_conn = to_gf_connector(connector); + break; + } + } + + return gf_conn; +} + +enum drm_connector_status +gf_connector_detect_internal(struct drm_connector *connector, bool force, int full_detect) +{ + struct drm_device *dev = connector->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_connector_t *gf_connector = to_gf_connector(connector); + disp_output_type output = gf_connector->output_type; + int detected_output = 0; + unsigned char* edid = NULL; + enum drm_connector_status conn_status; + struct gf_sink_create_data sink_create_data = {0}; + bool sink_edid_valid = FALSE; + +#ifdef ENABLE_HDMI4_VGA_ON_IGA4 + struct drm_connector* tmp_conn = NULL; +#endif + + if (gf_connector->output_type == DISP_OUTPUT_SPLICE) + { + return connector->funcs->detect(connector, force); + } + +#if GF_RUN_HDCP_CTS + if((!full_detect) && (output & DISP_OUTPUT_DP_TYPES) && gf_connector->detected) + { + conn_status = connector->status; + } + else + { + if(gf_connector->hpd_out &&(output & DISP_OUTPUT_DP_TYPES)) + { + gf_connector->hpd_out = 0; + conn_status = connector_status_disconnected; + } + else + { + detected_output = disp_cbios_detect_connected_output(disp_info, output, full_detect); + conn_status = (detected_output & output)? connector_status_connected : connector_status_disconnected; + gf_connector->edid_changed = 0; + gf_connector->detected = 1; + } + } +#else + gf_mutex_lock(gf_connector->conn_mutex); + detected_output = disp_cbios_detect_connected_output(disp_info, output, full_detect); + gf_mutex_unlock(gf_connector->conn_mutex); + + conn_status = (detected_output & output)? connector_status_connected : connector_status_disconnected; + + gf_connector->edid_changed = 0; +#endif + +#ifdef ENABLE_HDMI4_VGA_ON_IGA4 + if(gf_connector->output_type == disp_info->conflict_low && disp_info->conflict_high && conn_status == connector_status_connected) + { + list_for_each_entry(tmp_conn, &dev->mode_config.connector_list, head) + { + if(to_gf_connector(tmp_conn)->output_type == disp_info->conflict_high && + tmp_conn->status == connector_status_connected) + { + conn_status = connector_status_disconnected; + break; + } + } + } +#endif + + if(conn_status == connector_status_connected) + { + if(connector->status != connector_status_connected) + { + edid = disp_cbios_read_edid(disp_info, output); + // fix kos brightness disbale. if crt detect by DAC and not edid, so restore previous edid in sink. + if (!edid && gf_connector->output_type == DISP_OUTPUT_CRT) + { + gf_connector->edid_changed = 0; + } + else + { + gf_connector->edid_changed = 1; + } + } + else if(gf_connector->compare_edid) + { + edid = disp_cbios_read_edid(disp_info, output); + sink_edid_valid = gf_sink_is_edid_valid(gf_connector->sink); + if ((edid && !sink_edid_valid) || + (!edid && sink_edid_valid) || + (edid && sink_edid_valid && gf_memcmp(gf_connector->sink->edid_data, edid, EDID_BUF_SIZE))) + { + gf_connector->edid_changed = 1; + } + } + + if(gf_connector->edid_changed) + { + if(gf_connector->sink) + { + gf_sink_put(gf_connector->sink); + gf_connector->sink = NULL; + } + + sink_create_data.output_type = gf_connector->output_type; + gf_connector->sink = gf_sink_create(&sink_create_data); + + if (edid) + { + gf_memcpy(gf_connector->sink->edid_data, edid, EDID_BUF_SIZE); + } + + disp_cbios_get_connector_attrib(disp_info, gf_connector); + } + + if (edid) + { + gf_free(edid); + edid = NULL; + } + } + else + { + if(gf_connector->sink && gf_connector->output_type != DISP_OUTPUT_CRT) + { + gf_sink_put(gf_connector->sink); + gf_connector->sink = NULL; + } + } + + if (is_connector_work_in_splice_mode(connector)) + { + gf_connector->source_status = conn_status; + return connector_status_disconnected; + } + + return conn_status; +} + +static enum drm_connector_status +gf_connector_detect(struct drm_connector *connector, bool force) +{ + return gf_connector_detect_internal(connector, force, 0); +} + +static int gf_connector_get_modes(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_connector_t *gf_connector = to_gf_connector(connector); + int real_num = 0, added_num = 0; + int i = 0, skip_create = 0; + void* cb_mode_list = NULL; + int output = gf_connector->output_type; + struct drm_display_mode *drm_mode = NULL; + struct edid *drm_edid = NULL; + + if (is_connector_work_in_splice_mode(connector)) + { +#if DRM_VERSION_CODE >= KERNEL_VERSION(4,19,0) + drm_connector_update_edid_property(connector, NULL); +#else + drm_mode_connector_update_edid_property(connector, NULL); +#endif + + goto END; + } + + if (gf_sink_is_edid_valid(gf_connector->sink)) + { + drm_edid = (struct edid*)gf_connector->sink->edid_data; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4,19,0) + drm_connector_update_edid_property(connector, drm_edid); +#else + drm_mode_connector_update_edid_property(connector, drm_edid); +#endif + + cb_mode_list = disp_cbios_get_device_modelist(disp_info, output, &real_num); + + for (i = 0; i < real_num; i++) + { + if(!skip_create) + { + drm_mode = drm_mode_create(dev); + } + if(!drm_mode) + { + skip_create = 0; + break; + } + if(DISP_OK != disp_cbios_cbmode_to_drmmode(disp_info, output, cb_mode_list, i, drm_mode)) + { + skip_create = 1; + continue; + } + + skip_create = 0; + drm_mode_set_name(drm_mode); + drm_mode_probed_add(connector, drm_mode); + added_num++; + } +/* + dev_mode_size = disp_cbios_get_3dmode_size(disp_info, output); + mode_buf = gf_calloc(dev_mode_size); + if(!mode_buf) + { + goto END; + } + + real_num = disp_cbios_get_3dmodes(disp_info, output, mode_buf, dev_mode_size); + + for(i = 0; i < real_num; i++) + { + if(!skip_create) + { + drm_mode = drm_mode_create(dev); + } + if(!drm_mode) + { + skip_create = 0; + break; + } + if(DISP_OK != disp_cbios_3dmode_to_drmmode(disp_info, output, mode_buf, i, drm_mode)) + { + skip_create = 1; + continue; + } + + skip_create = 0; + drm_mode_set_name(drm_mode); + drm_mode_probed_add(connector, drm_mode); + added_num++; + } +*/ +END: + + if(skip_create && drm_mode) + { + drm_mode_destroy(dev, drm_mode); + } + + if(cb_mode_list) + { + gf_free(cb_mode_list); + cb_mode_list = NULL; + } + + return added_num; +} + +static enum drm_mode_status +gf_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) +{ + gf_connector_t *gf_connector = to_gf_connector(connector); + int max_clock; + + if (gf_connector->output_type == DISP_OUTPUT_CRT) + { + max_clock = 400000; // 400 MHz + } + else + { + max_clock = 600000; // 600 MHz + } + + if (mode->clock > max_clock) + { + return MODE_CLOCK_HIGH; + } + + return MODE_OK; +} + +static void gf_connector_destroy(struct drm_connector *connector) +{ + gf_connector_t *gf_connector = to_gf_connector(connector); + + drm_connector_unregister(connector); + drm_connector_cleanup(connector); + + if(gf_connector->sink) + { + gf_sink_put(gf_connector->sink); + gf_connector->sink = NULL; + } + + gf_i2c_adapter_destroy(gf_connector->i2c_adapter); + gf_connector->i2c_adapter= NULL; + + gf_destroy_mutex(gf_connector->conn_mutex); + gf_connector->conn_mutex = NULL; + + gf_free(gf_connector); +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 3, 0) +static int gf_connector_dpms(struct drm_connector *connector, int mode) +#else +static void gf_connector_dpms(struct drm_connector *connector, int mode) +#endif +{ + if(connector->encoder) + { + if(mode == DRM_MODE_DPMS_ON) + { + gf_encoder_enable(connector->encoder); + } + else + { + gf_encoder_disable(connector->encoder); + } + + connector->dpms = mode; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 3, 0) + return 0; +#endif +} + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) +//in gf chip, connector is fixed to encoder, so we just pick up the 1st encoder from table +static struct drm_encoder *gf_best_encoder(struct drm_connector *connector) +{ + struct drm_mode_object* obj = NULL; + int encoder_id = connector->encoder_ids[0]; + + obj = drm_mode_object_find(connector->dev, encoder_id, DRM_MODE_OBJECT_ENCODER); + gf_assert(obj != NULL, "obj = NULL"); + + return obj_to_encoder(obj); +} +#endif + +static const struct drm_connector_funcs gf_connector_funcs = +{ + .detect = gf_connector_detect, + .dpms = gf_connector_dpms, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = gf_connector_destroy, +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + .atomic_destroy_state = gf_connector_destroy_state, + .atomic_duplicate_state = gf_connector_duplicate_state, + .atomic_set_property = gf_connector_atomic_set_property, + .atomic_get_property = gf_connector_atomic_get_property, +#endif +}; + +static const struct drm_connector_helper_funcs gf_connector_helper_funcs = +{ + .get_modes = gf_connector_get_modes, + .mode_valid = gf_connector_mode_valid, +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + .best_encoder = gf_best_encoder, +#endif +}; + +void disp_probe_connector_after_resume(struct drm_device *dev) +{ + struct drm_connector* connector = NULL; + gf_connector_t* gf_connector = NULL; + enum drm_connector_status old_status; + bool connector_changed = false; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + struct drm_connector_list_iter conn_iter; +#endif + + mutex_lock(&dev->mode_config.mutex); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_begin(dev, &conn_iter); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + drm_for_each_connector_iter(connector, &conn_iter) +#else + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + drm_for_each_connector(connector, dev) +#else + list_for_each_entry(connector, &dev->mode_config.connector_list, head) +#endif + +#endif + { + gf_connector = to_gf_connector(connector); + + if (gf_connector->monitor_type != UT_OUTPUT_TYPE_PANEL) + { + old_status = connector->status; + + gf_connector->compare_edid = 1; + connector->status = gf_connector_detect_internal(connector, 0, 0); + + if (gf_connector->edid_changed || old_status != connector->status) + { + connector_changed = true; + } + + gf_connector->compare_edid = 0; + } + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_end(&conn_iter); +#endif + + mutex_unlock(&dev->mode_config.mutex); + + if (connector_changed) + { + drm_kms_helper_hotplug_event(dev); + } +} + + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) +static void disp_create_connector_property(disp_info_t* disp_info, gf_connector_t* gf_connector) +{ + struct drm_property *primary_card_prop, *global_id_proph, *global_id_propl; + gf_card_t* gf_card = NULL; + adapter_info_t* adapter_info = NULL; + unsigned int primary = 0, pci_id = 0, internal_id = 0; //pci_id = (vend << 16) | device, internal_id = (bdf << 16) + internal_output_id + + if (!disp_info || !gf_connector) + { + return; + } + + gf_card = disp_info->gf_card; + adapter_info = disp_info->adp_info; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) + if(vga_default_device() == gf_card->pdev) +#endif + { + primary = 1; + } + + pci_id = adapter_info->ven_dev; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) + internal_id = (unsigned int)pci_dev_id(gf_card->pdev); +#else + internal_id = (unsigned int)PCI_DEVID(gf_card->pdev->bus->number, gf_card->pdev->devfn); +#endif + + internal_id <<= 16; + internal_id |= gf_connector->output_id; + + gf_info("Create property for dev 0x%x, primary = %d, pci_id = 0x%x, internal_id = 0x%x.\n", gf_connector->output_type, primary, pci_id, internal_id); + + if(!disp_info->primary_card_prop) + { + primary_card_prop = drm_property_create_bool(gf_card->drm_dev, DRM_MODE_PROP_IMMUTABLE, "primarycard"); + if(primary_card_prop) + { + disp_info->primary_card_prop = primary_card_prop; + } + } + + if(disp_info->primary_card_prop) + { + drm_object_attach_property(&gf_connector->base_connector.base, disp_info->primary_card_prop, primary); + } + + if(!disp_info->global_id_proph) + { + global_id_proph = drm_property_create_range(gf_card->drm_dev, DRM_MODE_PROP_IMMUTABLE, "global_id_h", 0, UINT_MAX); + if(global_id_proph) + { + disp_info->global_id_proph = global_id_proph; + } + } + + if(!disp_info->global_id_propl) + { + global_id_propl = drm_property_create_range(gf_card->drm_dev, DRM_MODE_PROP_IMMUTABLE, "global_id_l", 0, UINT_MAX); + if(global_id_propl) + { + disp_info->global_id_propl = global_id_propl; + } + } + + if(disp_info->global_id_proph) + { + drm_object_attach_property(&gf_connector->base_connector.base, disp_info->global_id_proph, pci_id); + } + + if(disp_info->global_id_propl) + { + drm_object_attach_property(&gf_connector->base_connector.base, disp_info->global_id_propl, internal_id); + } + + gf_splice_attach_connector_property(&gf_connector->base_connector); +} +#endif + +struct drm_connector* disp_connector_init(disp_info_t* disp_info, disp_output_type output) +{ + gf_card_t *gf_card = disp_info->gf_card; + struct drm_device *drm = gf_card->drm_dev; + struct drm_connector *connector = NULL; + gf_connector_t *gf_connector = NULL; + int conn_type = 0; + struct gf_i2c_adapter *gf_adapter = NULL; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + gf_connector_state_t *gf_conn_state = NULL; +#endif + + gf_connector = gf_calloc(sizeof(gf_connector_t)); + if (!gf_connector) + { + DRM_ERROR("failed to alloc gf connector\n"); + goto failed; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + gf_conn_state = gf_calloc(sizeof(gf_connector_state_t)); + if (!gf_conn_state) + { + DRM_ERROR("failed to alloc gf connector state\n"); + goto failed; + } + + gf_connector->base_connector.state = &gf_conn_state->base_conn_state; + gf_conn_state->base_conn_state.connector = &gf_connector->base_connector; +#endif + + gf_connector->output_type = output; + if(gf_connector->output_type >= 0x100) + { + gf_connector->output_id = gf_connector->output_type >> 8; + } + else + { + gf_connector->output_id = gf_connector->output_type; + } + + disp_info->output_id_masks |= gf_connector->output_id; + + connector = &gf_connector->base_connector; + + if (output == DISP_OUTPUT_CRT) + { + conn_type = DRM_MODE_CONNECTOR_VGA; + connector->stereo_allowed = FALSE; + connector->interlace_allowed = FALSE; + } + else if (output == DISP_OUTPUT_DP2) + { + conn_type = DRM_MODE_CONNECTOR_DisplayPort; + connector->stereo_allowed = TRUE; + connector->interlace_allowed = TRUE; + } + else if (output & (DISP_OUTPUT_DP_TYPES & (~DISP_OUTPUT_DP2))) + { + conn_type = DRM_MODE_CONNECTOR_HDMIA; + connector->stereo_allowed = TRUE; + connector->interlace_allowed = TRUE; + } + else + { + DRM_ERROR("Unknown output\n"); + goto failed; + } + + gf_connector->conn_mutex = gf_create_mutex(); + + gf_adapter = gf_i2c_adapter_create(drm, connector); + if (IS_ERR(gf_adapter)) + { + DRM_ERROR("failed to create zx i2c adapter\n"); + goto failed; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) + drm_connector_init_with_ddc(drm, connector, &gf_connector_funcs, conn_type, &gf_adapter->adapter); +#else + drm_connector_init(drm, connector, &gf_connector_funcs, conn_type); +#endif + + drm_connector_helper_add(connector, &gf_connector_helper_funcs); + + connector->doublescan_allowed = FALSE; + + if(output & disp_info->supp_polling_outputs) + { + connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; + } + else if(output & disp_info->supp_hpd_outputs) + { + connector->polled = DRM_CONNECTOR_POLL_HPD; + if(output == DISP_OUTPUT_DP1) + { + gf_connector->hpd_int_bit = INT_DP1; + gf_connector->hda_codec_index = (1 << 0); + gf_connector->hdcp_index = (1 << 0); + } + else if(output == DISP_OUTPUT_DP2) + { + gf_connector->hpd_int_bit = INT_DP2; + gf_connector->hda_codec_index = (1 << 1); + gf_connector->hdcp_index = (1 << 1); + } + else if(output == DISP_OUTPUT_DP3) + { + gf_connector->hpd_int_bit = INT_DP3; + gf_connector->hdcp_index = (1 << 2); + } + else if(output == DISP_OUTPUT_DP4) + { + gf_connector->hpd_int_bit = INT_DP4; + gf_connector->hdcp_index = (1 << 3); + } + gf_connector->hdcp_enable = 0; + gf_connector->detected = 0; + gf_connector->hpd_out = 0; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + disp_create_connector_property(disp_info, gf_connector); +#endif + + return connector; + +failed: +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + if (gf_conn_state) + { + gf_free(gf_conn_state); + gf_conn_state = NULL; + } +#endif + + if (gf_connector) + { + if (gf_connector->conn_mutex) + { + gf_destroy_mutex(gf_connector->conn_mutex); + gf_connector->conn_mutex = NULL; + } + + gf_free(gf_connector); + gf_connector = NULL; + } + + return NULL; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + +static void __gf_restore_drm_connector_state(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx) +{ + + int ret = 0; + struct drm_device *dev = connector->dev; + struct drm_atomic_state *state = drm_atomic_state_alloc(dev); + struct drm_crtc *crtc = connector->encoder->crtc; + struct drm_plane *plane = crtc->primary; + struct drm_connector_state *conn_state; + struct drm_crtc_state *crtc_state; + struct drm_plane_state *plane_state; + + if (!state) + { + return; + } + + state->acquire_ctx = ctx; + + conn_state = drm_atomic_get_connector_state(state, connector); + if (IS_ERR(conn_state)) + { + ret = PTR_ERR(conn_state); + goto out; + } + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) + { + ret = PTR_ERR(crtc_state); + goto out; + } + + crtc_state->mode_changed = TRUE; + + plane_state = drm_atomic_get_plane_state(state, plane); + if (IS_ERR(plane_state)) + { + ret = PTR_ERR(plane_state); + goto out; + } + + ret = drm_atomic_commit(state); + +out: + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + drm_atomic_state_put(state); +#else + drm_atomic_state_free(state); +#endif + + if (ret) + { + DRM_DEBUG("Restoring old connector state failed with %d\n", ret); + } +} + +void gf_restore_drm_connector_state(struct drm_device *dev, struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx) +{ + gf_connector_t *gf_connector = to_gf_connector(connector); + struct drm_crtc *crtc = NULL; + gf_crtc_state_t *gf_crtc_state = NULL; + + if (!gf_connector->sink || !connector->encoder) + { + return; + } + + crtc = connector->encoder->crtc; + if (!crtc) + { + return; + } + + gf_crtc_state = to_gf_crtc_state(crtc->state); + + if (gf_crtc_state->sink != gf_connector->sink) + { + gf_info("To restore connector mode after plug in.\n"); + __gf_restore_drm_connector_state(connector, ctx); + } +} + +#endif + diff --git a/drivers/gpu/drm/arise/linux/gf_crtc.c b/drivers/gpu/drm/arise/linux/gf_crtc.c new file mode 100644 index 0000000000000..6621cf9c01119 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_crtc.c @@ -0,0 +1,1138 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_crtc.h" +#include "gf_fence.h" +#include "gf_drmfb.h" +#include "gf_splice.h" + +void gf_crtc_destroy(struct drm_crtc *crtc) +{ + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + + drm_crtc_cleanup(crtc); + + gf_free(gf_crtc); +} + +void gf_crtc_dpms_onoff_helper(struct drm_crtc *crtc, int dpms_on) +{ + struct drm_device *drm_dev = crtc->dev; + gf_card_t *gf_card = drm_dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + int status = dpms_on? 1 : 0; + + if (gf_crtc->crtc_dpms != status) + { + if (!(is_crtc_work_in_splice_mode(crtc) && + is_splice_target_active_in_drm(drm_dev))) + { + disp_cbios_turn_onoff_screen(disp_info, gf_crtc->pipe, status); + } + + gf_crtc->crtc_dpms = status; + } +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + +static void gf_update_active_connector(struct drm_crtc *crtc) +{ + struct drm_device * drm_dev = crtc->dev; + gf_card_t* gf_card = drm_dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + struct drm_connector* connector = NULL; + gf_connector_t* gf_connector = NULL; + int i = 0; + unsigned int active[MAX_CORE_CRTCS] = {0}; + + if(!crtc->state->connector_mask || !crtc->state->active) + { + return; + } + + gf_memcpy(active, disp_info->active_output, sizeof(disp_info->active_output)); + + active[crtc->index] = 0; + + list_for_each_entry(connector, &drm_dev->mode_config.connector_list, head) + { + if((crtc->state->connector_mask & (1 << drm_connector_index(connector))) && (connector->state->crtc == crtc)) + { + gf_connector = to_gf_connector(connector); + + for(i = 0; i < disp_info->num_crtc; i++) + { + active[i] &= ~gf_connector->output_type; + } + + active[crtc->index] |= gf_connector->output_type; + } + } + + if(!disp_cbios_update_output_active(disp_info, active)) + { + gf_memcpy(disp_info->active_output, active, sizeof(disp_info->active_output)); + } +} + +void gf_crtc_helper_set_mode(struct drm_crtc *crtc) +{ + struct drm_device * drm_dev = crtc->dev; + gf_card_t* gf_card = drm_dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + struct drm_crtc_state * crtc_state = crtc->state; + struct drm_display_mode* mode = &crtc->state->mode; + struct drm_display_mode* adj_mode = &crtc_state->adjusted_mode; + int flag = 0; + + //in atomic set phase, atomic state is updated to state of crtc/encoder/connector, + //so we can't roll back mode setting, that means all parameter check should be placed in + //atomic check function, and now all para is correct, we only need flush them to HW register + //but we still add para check code here tempararily, it will be removed after code stable. + + DRM_DEBUG_KMS("crtc=%d\n", crtc->index); + + gf_update_active_connector(crtc); + + flag |= UPDATE_CRTC_MODE_FLAG; + + disp_cbios_set_mode(disp_info, drm_crtc_index(crtc), mode, adj_mode, flag); +} + +void gf_crtc_helper_disable(struct drm_crtc *crtc) +{ + gf_info("CRTC disable: to turn off screen of crtc: %d\n", crtc->index); + + gf_crtc_dpms_onoff_helper(crtc, 0); + + drm_crtc_vblank_off(crtc); +} + +void gf_crtc_helper_enable(struct drm_crtc *crtc) +{ + gf_info("CRTC enable: to turn on screen of crtc: %d\n", crtc->index); + + drm_crtc_vblank_on(crtc); + + gf_crtc_dpms_onoff_helper(crtc, 1); + + +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +void gf_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state) +#else +void gf_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +#endif +{ + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + + gf_info("CRTC atomic enable: to turn on vblank and screen of crtc: %d\n", crtc->index); + + drm_crtc_vblank_on(crtc); + + gf_crtc_dpms_onoff_helper(crtc, 1); + + gf_crtc->enabled = 1; +} + +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +void gf_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state) +#else +void gf_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +#endif +{ + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + u64 old_cnt; +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); +#endif + + gf_info("CRTC atomic disable: to turn off vblank and screen of crtc: %d\n", crtc->index); + + //disable all planes on this crtc without flush event +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); +#else + drm_atomic_helper_disable_planes_on_crtc(crtc, false); +#endif + + if (0 == drm_crtc_vblank_get(crtc)) + { + old_cnt = drm_crtc_vblank_count(crtc); + + if(0 == wait_event_timeout(crtc->dev->vblank[crtc->index].queue, + old_cnt != drm_crtc_vblank_count(crtc), + msecs_to_jiffies(40))) + { + gf_info("Wait vblank queue timeout after disable planes of crtc %d\n", crtc->index); + } + + drm_crtc_vblank_put(crtc); + } + + gf_crtc_dpms_onoff_helper(crtc, 0); + + drm_crtc_vblank_off(crtc); + + gf_crtc->enabled = 0; +} + +void gf_crtc_update_lut(struct drm_crtc_state *crtc_state) +{ + struct drm_crtc *crtc = crtc_state->crtc; + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + struct drm_device *dev = crtc->dev; + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + struct drm_color_lut *lut = NULL; + int *gamma = NULL; + unsigned int r, g, b; + unsigned int i = 0, lut_len = 0; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) + lut_len = drm_color_lut_size(crtc_state->gamma_lut); +#else + lut_len = crtc_state->gamma_lut->length / sizeof(*lut); +#endif + + if (lut_len != COLOR_LEGACY_LUT_LENGTH) + { + DRM_DEBUG_KMS("gamma size not supported\n"); + return; + } + + lut = (struct drm_color_lut *)crtc_state->gamma_lut->data; + + gamma = gf_calloc(sizeof(int) * COLOR_LEGACY_LUT_LENGTH); + + if (!gamma) + { + DRM_ERROR("alloc gamma table failed\n"); + return; + } + + for (i = 0; i < COLOR_LEGACY_LUT_LENGTH; i++) + { + r = drm_color_lut_extract(lut[i].red, 16); + g = drm_color_lut_extract(lut[i].green, 16); + b = drm_color_lut_extract(lut[i].blue, 16); + gamma[i] = ((b >> 6) & 0x3FF) + ((g << 4) & 0xFFC00) + ((r << 14) & 0x3FF00000); + } + + disp_cbios_set_gamma(disp_info, gf_crtc->pipe, gamma); + + gf_free(gamma); +} + + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +void gf_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state) +#else +void gf_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +#endif +{ + struct drm_crtc_state *crtc_state = NULL; +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); +#else + crtc_state = crtc->state; +#endif + //do some prepare on specified crtc before update planes + //for intel chip, it will wait until scan line is not in (vblank-100us) ~ vblank + //will implement it later + if(crtc_state->color_mgmt_changed || + drm_atomic_crtc_needs_modeset(crtc_state)) + { + if(crtc_state->gamma_lut) + { + gf_crtc_update_lut(crtc_state); + } + } +} + +static bool gf_need_wait_vblank(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +{ + struct drm_plane *plane; + struct drm_plane_state *old_plane_state; + int i; + bool need_wait = false; + + if ((is_crtc_work_in_splice_mode(crtc) && + is_splice_target_active_in_drm(crtc->dev))) + { + need_wait = false; + goto End; + } + + if(crtc->state && drm_atomic_crtc_needs_modeset(crtc->state)) + { + need_wait = true; + goto End; + } + + if(!old_crtc_state || !old_crtc_state->state) + { + need_wait = true; + goto End; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) + if(crtc->state && crtc->state->async_flip) +#else + if(crtc->state && (crtc->state->pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC)) +#endif + { + gf_crtc_state_t* gf_cstate = to_gf_crtc_state(crtc->state); + if(!gf_cstate->keep_vsync) + { + need_wait = false; + goto End; + } + } +#endif + + for(i = 0; i < crtc->dev->mode_config.num_total_plane; i++) + { + if(old_crtc_state->state->planes[i].ptr) + { + plane = old_crtc_state->state->planes[i].ptr; + old_plane_state = old_crtc_state->state->planes[i].state; + if(plane->state->crtc == crtc && crtc->state && (crtc->state->plane_mask & (1 << plane->index))) + { + if(plane->state->fb != old_plane_state->fb) + { + need_wait = true; + break; + } + } + } + } + +End: + if(need_wait) + { + if(drm_crtc_vblank_get(crtc) != 0) + { + need_wait = false; + } + } + + return need_wait; +} +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +void gf_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) +#else +void gf_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +#endif +{ + struct drm_pending_vblank_event *event = crtc->state->event; +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,crtc); +#endif + DRM_DEBUG_KMS("crtc=%d\n", crtc->index); + //do some flush work on spcified crtc after planes update finished. + //install vblank event(flip complete) to queue, then it will be signaled at vblank interrupt + if (event) + { + crtc->state->event = NULL; + + spin_lock_irq(&crtc->dev->event_lock); + if (gf_need_wait_vblank(crtc, old_crtc_state)) + { + // should hold a reference for arm_vblank + drm_crtc_arm_vblank_event(crtc, event); + } + else + { + drm_crtc_send_vblank_event(crtc, event); + } + spin_unlock_irq(&crtc->dev->event_lock); + } +} + +#else + +int gf_crtc_cursor_set(struct drm_crtc *crtc, + struct drm_file *file, + uint32_t handle, + uint32_t width, uint32_t height) +{ + struct drm_device *dev = crtc->dev; + struct drm_gem_object* obj = NULL; + struct drm_gf_gem_object* cursor_bo = NULL; + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + gf_cursor_update_t arg = {0, }; + gf_map_argu_t map = {0}; + int ret; + + arg.crtc = to_gf_crtc(crtc)->pipe; + +/* if we want to turn off the cursor ignore width and height */ + if (!handle) + { + DRM_DEBUG_KMS("cursor off\n"); + + if (gf_crtc->cursor_bo) + { + gf_gem_object_put(gf_crtc->cursor_bo); + gf_crtc->cursor_bo = NULL; + } + + goto Finish; + } + +#if DRM_VERSION_CODE < KERNEL_VERSION(4,7,0) && !defined PHYTIUM_2000 + obj = drm_gem_object_lookup(dev, file, handle); +#else + obj = drm_gem_object_lookup(file, handle); +#endif + + if (obj == NULL) + { + return -ENOENT; + } + cursor_bo = to_gf_bo(obj); + + if ((width != 64 || height != 64) && + (width != 128 || height != 128)) + { + gf_gem_object_put(cursor_bo); + DRM_ERROR("wrong cursor size, width=%d height=%d!\n", width, height); + return -EINVAL; + } + + if (obj->size < width * height * 4) + { + gf_gem_object_put(cursor_bo); + DRM_ERROR("buffer is to small\n"); + return -ENOMEM; + } + + if (gf_crtc->cursor_bo) + { + gf_gem_object_put(gf_crtc->cursor_bo); + } + + gf_crtc->cursor_bo= cursor_bo; + gf_crtc->cursor_w = width; + gf_crtc->cursor_h = height; + + arg.vsync_on = 0; + arg.pos_x = gf_crtc->cursor_x; + arg.pos_y = gf_crtc->cursor_y; + arg.width = gf_crtc->cursor_w; + arg.height = gf_crtc->cursor_h; + arg.bo = cursor_bo; + +Finish: + return disp_cbios_update_cursor(disp_info, &arg); +} + +int gf_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) +{ + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + struct drm_device *dev = crtc->dev; + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_cursor_update_t arg = {0, }; + + gf_crtc->cursor_x = x; + gf_crtc->cursor_y = y; + + arg.crtc = to_gf_crtc(crtc)->pipe; + arg.vsync_on = 0; + arg.pos_x = gf_crtc->cursor_x; + arg.pos_y = gf_crtc->cursor_y; + arg.width = gf_crtc->cursor_w; + arg.height = gf_crtc->cursor_h; + arg.bo = gf_crtc->cursor_bo; + + return disp_cbios_update_cursor(disp_info, &arg); +} +#ifdef PHYTIUM_2000 +int gf_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, + u16 *blue, uint32_t size) +#else +void gf_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, + u16 *blue, uint32_t start, uint32_t size) +#endif +{ + int i = 0; +#ifdef PHYTIUM_2000 + uint32_t start = 0; +#endif + int end = (start + size > 256) ? 256 : start + size; + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + struct drm_device *dev = crtc->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + + for (i = start; i < end; i++) { + gf_crtc->lut_entry[i] = (blue[i] >> 6) | ((green[i] << 4) & 0xFFC00) | ((red[i] << 14) & 0x3FF00000); + } + + disp_cbios_set_gamma(disp_info, gf_crtc->pipe, gf_crtc->lut_entry); +#ifdef PHYTIUM_2000 + return 0; +#endif +} + +static void gf_swap_changed_encoder_crtc(struct drm_device *dev, bool update_old, bool clear_new) +{ + struct drm_crtc* crtc = NULL; + struct drm_connector *connector = NULL; + struct drm_encoder *encoder = NULL, *temp_enc = NULL; + gf_connector_t* gf_connector= NULL; + gf_encoder_t* gf_encoder = NULL; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + gf_connector = to_gf_connector(connector); + temp_enc = connector->encoder; + + if(update_old) + { + if(gf_connector->new_encoder) + { + connector->encoder = &gf_connector->new_encoder->base_encoder; + } + else + { + connector->encoder = NULL; + } + } + + if(temp_enc && !clear_new) + { + gf_connector->new_encoder = to_gf_encoder(temp_enc); + } + else + { + gf_connector->new_encoder = NULL; + } + } + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) + { + gf_encoder = to_gf_encoder(encoder); + crtc = encoder->crtc; + + if(update_old) + { + if(gf_encoder->new_crtc) + { + encoder->crtc = &gf_encoder->new_crtc->base_crtc; + } + else + { + encoder->crtc = NULL; + } + } + + if(crtc && !clear_new) + { + gf_encoder->new_crtc = to_gf_crtc(crtc); + } + else + { + gf_encoder->new_crtc = NULL; + } + } +} + +static void gf_init_new_encoder_crtc(struct drm_device *dev) +{ + struct drm_connector *connector = NULL; + struct drm_encoder *encoder = NULL; + gf_connector_t* gf_connector= NULL; + gf_encoder_t* gf_encoder = NULL; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + gf_connector = to_gf_connector(connector); + + gf_connector->new_encoder = NULL; + } + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) + { + gf_encoder = to_gf_encoder(encoder); + + gf_encoder->new_crtc = NULL; + } +} + +static void gf_drm_disable_unused_functions(struct drm_device *dev) +{ + struct drm_encoder *encoder; + struct drm_crtc *crtc; + struct drm_connector* connector; + const struct drm_encoder_helper_funcs *encoder_funcs; + const struct drm_crtc_helper_funcs *crtc_funcs; + struct drm_framebuffer *old_fb; + + drm_warn_on_modeset_not_all_locked(dev); + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + if (connector->encoder && (connector->status == connector_status_disconnected)) + { + connector->encoder = NULL; + } + } + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) + { + encoder_funcs = encoder->helper_private; + if (!drm_helper_encoder_in_use(encoder)) + { + if (encoder_funcs->disable) + { + (*encoder_funcs->disable)(encoder); + } + else + { + (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); + } + + if (encoder->bridge) + { + encoder->bridge->funcs->disable(encoder->bridge); + } + } + } + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + { + crtc_funcs = crtc->helper_private; + + crtc->enabled = drm_helper_crtc_in_use(crtc); + if (!crtc->enabled) + { + if (crtc_funcs->disable) + { + (*crtc_funcs->disable)(crtc); + } + else + { + (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF); + } + + old_fb = drm_get_crtc_primary_fb(crtc); + + drm_set_crtc_primary_fb(crtc, NULL); + + if(crtc_funcs->mode_set_base && old_fb != NULL) + { + (*crtc_funcs->mode_set_base)(crtc, 0, 0, old_fb); + } + } + } +} + +static void gf_drm_crtc_disable_helper(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_connector *connector; + struct drm_encoder *encoder; + + /* Decouple all encoders and their attached connectors from this crtc */ + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) + { + if (encoder->crtc != crtc) + { + continue; + } + + encoder->crtc = NULL; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + if (connector->encoder != encoder) + { + continue; + } + connector->encoder = NULL; + } + } + gf_drm_disable_unused_functions(dev); +} + +int gf_crtc_helper_set_config(struct drm_mode_set *set) +{ + struct drm_device *dev; + struct drm_crtc *crtc = NULL; + struct drm_framebuffer *old_fb = NULL; + struct drm_connector *connector = NULL; + struct drm_encoder* encoder = NULL; + gf_connector_t* gf_connector= NULL; + bool mode_changed = FALSE, fb_changed = FALSE; + bool pre_swap = TRUE; + const struct drm_crtc_helper_funcs *crtc_funcs; + struct drm_mode_set save_set; + int ret = 0, ro = 0, conn_masks = 0; + + if(!set || !set->crtc) + { + return -EINVAL; + } + + if(!set->crtc->helper_private) + { + return -EINVAL; + } + + crtc_funcs = set->crtc->helper_private; + + if(!set->mode) + { + set->fb = NULL; + } + + if(!set->fb) + { + gf_drm_crtc_disable_helper(set->crtc); + return 0; + } + + dev = set->crtc->dev; + + save_set.crtc = set->crtc; + save_set.mode = &set->crtc->mode; + save_set.x = set->crtc->x; + save_set.y = set->crtc->y; + save_set.fb = drm_get_crtc_primary_fb(set->crtc); + + gf_init_new_encoder_crtc(dev); + + /* We should be able to check here if the fb has the same properties + * and then just flip_or_move it */ + if(drm_get_crtc_primary_fb(set->crtc) != set->fb) + { + /* If we have no fb then treat it as a full mode set */ + if(drm_get_crtc_primary_fb(set->crtc) == NULL) + { + DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); + mode_changed = TRUE; + } + else if(set->fb == NULL) + { + mode_changed = TRUE; + } + else + { + fb_changed = TRUE; + } + } + + if(set->x != set->crtc->x || set->y != set->crtc->y) + { + fb_changed = TRUE; + } + + if(set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) + { + drm_mode_debug_printmodeline(set->mode); + mode_changed = TRUE; + } + + for(ro = 0; ro < set->num_connectors; ro++) + { + if(set->connectors[ro]) + { + conn_masks |= to_gf_connector(set->connectors[ro])->output_type; + } + } + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; + gf_connector = to_gf_connector(connector); + + if(gf_connector->output_type & conn_masks) + { + encoder = connector_funcs->best_encoder(connector); + gf_connector->new_encoder = to_gf_encoder(encoder); + } + else + { + if(connector->encoder && connector->encoder->crtc != set->crtc) + { + gf_connector->new_encoder = to_gf_encoder(connector->encoder); + } + else + { + gf_connector->new_encoder = NULL; + } + } + + if (gf_connector->new_encoder && (&gf_connector->new_encoder->base_encoder != connector->encoder)) + { + mode_changed = TRUE; + } + } + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + gf_connector = to_gf_connector(connector); + if(gf_connector->new_encoder) + { + crtc = gf_connector->new_encoder->base_encoder.crtc; + + if(gf_connector->output_type & conn_masks) + { + crtc = set->crtc; + } + + /* Make sure the new CRTC will work with the encoder */ + if(crtc && !drm_encoder_crtc_ok(&gf_connector->new_encoder->base_encoder, crtc)) + { + ret = -EINVAL; + goto Fail; + } + + if(crtc != gf_connector->new_encoder->base_encoder.crtc) + { + mode_changed = TRUE; + } + + gf_connector->new_encoder->new_crtc = (crtc)? to_gf_crtc(crtc) : NULL; + + if(&gf_connector->new_encoder->base_encoder != connector->encoder) + { + if(connector->encoder) + { + to_gf_encoder(connector->encoder)->new_crtc = NULL; + } + } + } + else if(connector->encoder) + { + to_gf_encoder(connector->encoder)->new_crtc = NULL; + mode_changed = TRUE; + } + } + + //swap old state and new state + gf_swap_changed_encoder_crtc(dev, TRUE, FALSE); + + pre_swap = FALSE; + + if (mode_changed) + { + if(drm_helper_crtc_in_use(set->crtc)) + { + drm_mode_debug_printmodeline(set->mode); + + old_fb = drm_get_crtc_primary_fb(set->crtc); + drm_set_crtc_primary_fb(set->crtc, set->fb); + + if(!drm_crtc_helper_set_mode(set->crtc, set->mode, set->x, set->y, old_fb)) + { + DRM_ERROR("failed to set mode on [CRTC:%d]\n", set->crtc->base.id); + drm_set_crtc_primary_fb(set->crtc, old_fb); + ret = -EINVAL; + goto Fail; + } + } + + gf_drm_disable_unused_functions(dev); + } + else if(fb_changed) + { + old_fb = drm_get_crtc_primary_fb(set->crtc); + drm_set_crtc_primary_fb(set->crtc, set->fb); + + ret = crtc_funcs->mode_set_base(set->crtc, set->x, set->y, old_fb); + if (ret != 0) + { + drm_set_crtc_primary_fb(set->crtc, old_fb); + ret = -EINVAL; + goto Fail; + } + } + + gf_swap_changed_encoder_crtc(dev, FALSE, TRUE); + + return 0; + +Fail: + if(pre_swap) + { + gf_swap_changed_encoder_crtc(dev, FALSE, TRUE); + } + else + { + gf_swap_changed_encoder_crtc(dev, TRUE, TRUE); + /* Try to restore the config */ + if (mode_changed) + { + drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x, save_set.y, save_set.fb); + } + else if(fb_changed) + { + crtc_funcs->mode_set_base(save_set.crtc, save_set.x, save_set.y, save_set.fb); + } + } + + return ret; +} + +void gf_crtc_prepare(struct drm_crtc *crtc) +{ + struct drm_device* dev = crtc->dev; + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_crtc_t* gf_crtc = to_gf_crtc(crtc); + struct drm_encoder* encoder = NULL; + gf_encoder_t* gf_encoder = NULL; + unsigned int active[MAX_CORE_CRTCS]; + + gf_crtc_dpms_onoff_helper(crtc, 0); + + gf_memcpy(active, disp_info->active_output, sizeof(active)); + + active[gf_crtc->pipe] = 0; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) + { + gf_encoder = to_gf_encoder(encoder); + if(encoder->crtc == crtc) + { + active[gf_crtc->pipe] |= gf_encoder->output_type; + } + } + + if(!disp_cbios_update_output_active(disp_info, active)) + { + gf_memcpy(disp_info->active_output, active, sizeof(active)); + } +} + +void gf_crtc_disable(struct drm_crtc *crtc) +{ + gf_crtc_dpms_onoff_helper(crtc, 0); +} + +void gf_crtc_commit(struct drm_crtc *crtc) +{ + gf_crtc_dpms_onoff_helper(crtc, 1); +} + +bool gf_crtc_mode_fixup(struct drm_crtc *crtc, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return TRUE; +} + +int gf_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, int x, int y, + struct drm_framebuffer *old_fb) +{ + struct drm_device* dev = crtc->dev; + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_crtc_t* gf_crtc = to_gf_crtc(crtc); + gf_crtc_flip_t arg = {0}; + int flag = UPDATE_CRTC_MODE_FLAG; + + disp_cbios_set_mode(disp_info, gf_crtc->pipe, mode, adjusted_mode, flag); + + arg.crtc = to_gf_crtc(crtc)->pipe; + arg.stream_type = GF_PLANE_PS; + arg.fb = drm_get_crtc_primary_fb(crtc); + arg.crtc_x = 0; + arg.crtc_y = 0; + arg.crtc_w = mode->hdisplay; + arg.crtc_h = mode->vdisplay; + arg.src_x = x; + arg.src_y = y; + arg.src_w = mode->hdisplay; + arg.src_h = mode->vdisplay; + + return disp_cbios_crtc_flip(disp_info, &arg); +} + +int gf_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb) +{ + struct drm_device* dev = crtc->dev; + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_crtc_t* gf_crtc = to_gf_crtc(crtc); + gf_crtc_flip_t arg = {0}; + int ret = 0; + + arg.crtc = to_gf_crtc(crtc)->pipe; + arg.stream_type = GF_PLANE_PS; + arg.fb = drm_get_crtc_primary_fb(crtc); + arg.crtc_x = 0; + arg.crtc_y = 0; + arg.crtc_w = crtc->mode.hdisplay; + arg.crtc_h = crtc->mode.vdisplay; + arg.src_x = x; + arg.src_y = y; + arg.src_w = crtc->mode.hdisplay; + arg.src_h = crtc->mode.vdisplay; + + ret = disp_cbios_crtc_flip(disp_info, &arg); + if(!ret) + { + crtc->x = x; + crtc->y = y; + } + + return ret; +} + +struct gf_flip_work +{ + struct work_struct work; + struct drm_pending_vblank_event *event; + struct drm_crtc *crtc; + struct drm_framebuffer *old_fb; + int stream_type; + dma_fence_t *fence; +}; + +static void gf_crtc_flip_work_func(struct work_struct *w) +{ + struct gf_flip_work *work = container_of(w, struct gf_flip_work, work); + struct drm_crtc *crtc = work->crtc; + struct drm_gf_framebuffer *fb = to_gfb(drm_get_crtc_primary_fb(crtc)); + gf_card_t *gf = crtc->dev->dev_private; + u32 vblank_count; + gf_crtc_flip_t arg = {0}; + int ret; + + // paging + gf_core_interface->prepare_and_mark_unpagable(gf->adapter, fb->obj->core_handle, &fb->obj->info); + + // wait fence + if (work->fence) + { + dma_fence_wait(work->fence, FALSE); + dma_fence_put(work->fence); + work->fence = NULL; + } + + arg.crtc = to_gf_crtc(crtc)->pipe; + arg.stream_type = work->stream_type; + arg.fb = &fb->base; + arg.crtc_x = 0; + arg.crtc_y = 0; + arg.crtc_w = crtc->mode.hdisplay; + arg.crtc_h = crtc->mode.vdisplay; + arg.src_x = crtc->x; + arg.src_y = crtc->y; + arg.src_w = crtc->mode.hdisplay; + arg.src_h = crtc->mode.vdisplay; + + disp_cbios_crtc_flip(gf->disp_info, &arg); + + // wait vblank + vblank_count = drm_crtc_vblank_count(crtc); + ret = wait_event_timeout(crtc->dev->vblank[drm_get_crtc_index(crtc)].queue, + vblank_count != drm_crtc_vblank_count(crtc), + msecs_to_jiffies(50)); + drm_crtc_vblank_put(crtc); + + // complete + gf_core_interface->mark_pagable(gf->adapter, to_gfb(work->old_fb)->obj->core_handle); + drm_framebuffer_unreference(work->old_fb); + work->old_fb = NULL; + + spin_lock_irq(&crtc->dev->event_lock); + to_gf_crtc(crtc)->flip_work = NULL; + if (work->event) + { + drm_crtc_send_vblank_event(crtc, work->event); + } + spin_unlock_irq(&crtc->dev->event_lock); + + // mark pageable + gf_free(work); +} + +int gf_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t flags) +{ + int ret; + struct drm_plane *plane = crtc->primary; + struct drm_framebuffer *old_fb = drm_get_crtc_primary_fb(crtc); + struct drm_device* dev = crtc->dev; + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + struct gf_flip_work *work; + + if (!old_fb || !to_gfb(old_fb)->obj) + return -EBUSY; + + if (fb->pixel_format != crtc->primary->fb->pixel_format) + return -EINVAL; + + work = gf_calloc(sizeof(*work)); + if (!work) + return -ENOMEM; + + work->event = event; + work->crtc = crtc; + work->old_fb = old_fb; + work->stream_type = GF_STREAM_PS; + ret = drm_crtc_vblank_get(crtc); + if (ret) + goto free_work; + + spin_lock_irq(&crtc->dev->event_lock); + if (gf_crtc->flip_work) + { + DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); + spin_unlock_irq(&crtc->dev->event_lock); + + drm_crtc_vblank_put(crtc); + gf_free(work); + return -EBUSY; + } + gf_crtc->flip_work = work; + spin_unlock_irq(&crtc->dev->event_lock); + + work->fence = gf_reservation_object_get_excl_rcu(to_gfb(fb)->obj->resv); + drm_framebuffer_reference(work->old_fb); + drm_set_crtc_primary_fb(crtc, fb); + + INIT_WORK(&work->work, gf_crtc_flip_work_func); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35) + queue_work(system_unbound_wq, &work->work); +#else + queue_work(disp_info->wq, &work->work); +#endif + + return 0; +free_work: + gf_free(work); + return ret; +} +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_crtc.h b/drivers/gpu/drm/arise/linux/gf_crtc.h new file mode 100644 index 0000000000000..9fd53103ea6f3 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_crtc.h @@ -0,0 +1,122 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _GF_CRTC_H_ +#define _GF_CRTC_H_ + +#include "gf_disp.h" +#include "gf_cbios.h" + +void gf_crtc_destroy(struct drm_crtc *crtc); +void gf_crtc_dpms_onoff_helper(struct drm_crtc *crtc, int dpms_on); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + +void gf_crtc_helper_set_mode(struct drm_crtc *crtc); + +void gf_crtc_helper_enable(struct drm_crtc *crtc); + +void gf_crtc_helper_disable(struct drm_crtc *crtc); +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +void gf_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state); + +void gf_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state); + +void gf_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state); + +void gf_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state); +#else +void gf_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state); + +void gf_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state); + +void gf_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state); + +void gf_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state); +#endif + +static inline u32 drm_get_crtc_index(struct drm_crtc *crtc) +{ + return crtc->index; +} + +static inline struct drm_framebuffer *drm_get_crtc_primary_fb(struct drm_crtc *crtc) +{ + return crtc->primary->fb; +} + +static inline void drm_set_crtc_primary_fb(struct drm_crtc *crtc, struct drm_framebuffer *fb) +{ + crtc->primary->fb = fb; +} + +#else + +int gf_crtc_cursor_set(struct drm_crtc *crtc, + struct drm_file *file, + uint32_t handle, + uint32_t width, uint32_t height); + +int gf_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); +#ifdef PHYTIUM_2000 +int gf_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, + u16 *blue, uint32_t size); +#else +void gf_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, + u16 *blue, uint32_t start, uint32_t size); +#endif + +int gf_crtc_helper_set_config(struct drm_mode_set *set); + +void gf_crtc_prepare(struct drm_crtc *crtc); + +void gf_crtc_commit(struct drm_crtc *crtc); + +bool gf_crtc_mode_fixup(struct drm_crtc *crtc, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + +int gf_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, int x, int y, + struct drm_framebuffer *old_fb); + +int gf_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb); + +void gf_crtc_disable(struct drm_crtc *crtc); + +int gf_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t flags); + +static inline u32 drm_get_crtc_index(struct drm_crtc *crtc) +{ + return to_gf_crtc(crtc)->pipe; +} +static inline struct drm_framebuffer *drm_get_crtc_primary_fb(struct drm_crtc *crtc) +{ + return crtc->primary->fb; +} + +static inline void drm_set_crtc_primary_fb(struct drm_crtc *crtc, struct drm_framebuffer *fb) +{ + crtc->primary->fb = fb; +} +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) +typedef unsigned int pipe_t; +#else +typedef int pipe_t; +#endif + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_debugfs.c b/drivers/gpu/drm/arise/linux/gf_debugfs.c new file mode 100644 index 0000000000000..1d2e58414268c --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_debugfs.c @@ -0,0 +1,1046 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_debugfs.h" + +typedef struct gf_mmio_segment +{ + const char *name; + unsigned int start; + unsigned int end; + unsigned int alignment; +}gf_mmio_segment_t; + +gf_mmio_segment_t mmio_seg_e3k[] = { + {"MMIO1", 0x8000, 0x80E4, 4}, + {"MMIO2", 0x8180, 0x83B0, 4}, + {"MMIO3", 0x8400, 0x8600, 4}, + {"MMIO4", 0x8600, 0x8B00, 1}, + {"MMIO5", 0x9000, 0x9200, 1}, + {"MMIO6", 0x9400, 0x9600, 1}, + {"MMIO7", 0x30000, 0x30380,4}, /* CSP */ + {"MMIO8", 0x33000, 0x35000, 4}, + {"MMIO9", 0x48C000, 0x48CD0, 4}, + {"MMIO10", 0x49000, 0x49080, 4}, +}; + +static int gf_debugfs_node_show(struct seq_file *s, void *unused) +{ + gf_debugfs_node_t *node = (gf_debugfs_node_t *)(s->private); + struct os_seq_file seq_file={0}; + struct os_printer seq_p = gf_seq_file_printer(&seq_file); + struct drm_device* dev = node->dev->gf->drm_dev; + + seq_file.seq_file = s; + + gf_mutex_lock(node->dev->lock); + + switch(node->type) + { + case DEBUGFS_NODE_DEVICE: + gf_core_interface->debugfs_dump(&seq_file, node->adapter, node->type, &node->hDevice); + break; + + case DEBUGFS_NODE_HEAP: + gf_core_interface->debugfs_dump(&seq_file, node->adapter, node->type, &node->id); + break; + + case DEBUGFS_NODE_INFO: + gf_core_interface->debugfs_dump(&seq_file, node->adapter, node->type, NULL); + gf_debugfs_clock_dump(s, dev); + break; + + case DEBUGFS_NODE_MEMTRACK: + gf_core_interface->debugfs_dump(&seq_file, node->adapter, node->type, &node->id); + break; + case DEBUGFS_NODE_DVFS: + gf_core_interface->debugfs_dump(&seq_file, node->adapter, node->type, NULL); + break; + case DEBUGFS_NODE_CG: + gf_core_interface->debugfs_dump(&seq_file, node->adapter, node->type, NULL); + break; + case DEBUGFS_NODE_VIDSCH: + gf_core_interface->debugfs_dump(&seq_file, node->adapter, node->type, &seq_p); + break; + case DEBUGFS_NODE_DEBUGBUS: + gf_core_interface->debugfs_dump(&seq_file, node->adapter, node->type, &seq_p); + break; + default: + gf_info("dump unknow node :%d\n", node->type); + break; + } + + gf_mutex_unlock(node->dev->lock); + + return 0; +} + +static int gf_debugfs_node_open(struct inode *inode, struct file *file) +{ + return single_open(file, gf_debugfs_node_show, inode->i_private); +} + +static ssize_t gf_debugfs_node_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos) +{ + struct os_seq_file seq_file = {0}; + gf_debugfs_node_t *node = NULL; + char info[32] = {'\0'}; + int ret = 0; + + seq_file.seq_file = file->private_data; + node = (gf_debugfs_node_t *)((seq_file.seq_file)->private); + + if(size > 1 && size < 32) + { + ret = gf_copy_from_user(info, buf, size); + if(!ret) + { + info[size-1] = '\0'; + } + else + return -1; + } + + gf_mutex_lock(node->dev->lock); + + if (!gf_strcmp(info, "1")) + { + gf_core_interface->dump_hang_info_flag(node->adapter, 1); + } + else + { + gf_core_interface->dump_hang_info_flag(node->adapter, 0); + } + + + gf_mutex_unlock(node->dev->lock); + + return (ret == 0) ? size : ret; +} + +static const struct file_operations debugfs_node_fops = { + .open = gf_debugfs_node_open, + .read = seq_read, + .write = gf_debugfs_node_write, + .llseek = seq_lseek, + .release = single_release, +}; + +// displayinfo node +static int gf_debugfs_node_displayinfo_show(struct seq_file *s, void *unused) +{ + gf_debugfs_node_t *node = (gf_debugfs_node_t *)(s->private); + struct drm_device* dev = node->dev->gf->drm_dev; + + gf_debugfs_displayinfo_dump(s, dev); + + return 0; +} + +static int gf_debugfs_node_displayinfo_open(struct inode *inode, struct file *file) +{ + return single_open(file, gf_debugfs_node_displayinfo_show, inode->i_private); +} + + +static const struct file_operations debugfs_node_displayinfo_fops = { + .open = gf_debugfs_node_displayinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int gf_debugfs_node_umd_trace_show(struct seq_file *s, void *unused) +{ + gf_debugfs_node_t *node = (gf_debugfs_node_t *)(s->private); + + seq_printf(s, "0x%lx\n", node->dev->gf->umd_trace_tags); + + return 0; +} + +static int gf_debugfs_node_umd_trace_open(struct inode *inode, struct file *file) +{ + return single_open(file, gf_debugfs_node_umd_trace_show, inode->i_private); +} + +static ssize_t gf_debugfs_node_umd_trace_write(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + gf_debugfs_node_t* node = file_inode(f)->i_private; + gf_card_t *gf_card = node->dev->gf; + unsigned long val; + int ret; + char event_string[32]; + char *envp[] = { event_string, NULL }; + + ret = kstrtoul_from_user(buf, size, 0, &val); + if (ret) + return ret; + + gf_card->umd_trace_tags = val; + + // trace_buffer is the new way to control trace + if (gf_card->trace_buffer_vma && gf_card->trace_buffer_vma->virt_addr) + { + *((uint64_t *)gf_card->trace_buffer_vma->virt_addr) = val; + } + + gf_vsprintf(event_string, "GF_TRACE_TAGS=0x%lx", val); + // send uevent to usermode to enable/disable trace + kobject_uevent_env(&gf_card->pdev->dev.kobj, KOBJ_CHANGE, envp); + + *pos += size; + + return size; +} + +static const struct file_operations debugfs_node_umd_trace_fops = { + .open = gf_debugfs_node_umd_trace_open, + .read = seq_read, + .write = gf_debugfs_node_umd_trace_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static int gf_debugfs_node_allocation_trace_show(struct seq_file *s, void *unused) +{ + gf_debugfs_node_t *node = (gf_debugfs_node_t *)(s->private); + + seq_printf(s, "0x%lx\n", node->dev->gf->allocation_trace_tags); + + return 0; +} + +static int gf_debugfs_node_allocation_trace_open(struct inode *inode, struct file *file) +{ + return single_open(file, gf_debugfs_node_allocation_trace_show, inode->i_private); +} + +static ssize_t gf_debugfs_node_allocation_trace_write(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + gf_debugfs_node_t* node = file_inode(f)->i_private; + unsigned long val; + int ret; + + ret = kstrtoul_from_user(buf, size, 0, &val); + if (ret) + return ret; + + node->dev->gf->allocation_trace_tags = val; + + *pos += size; + + return size; +} + +static const struct file_operations debugfs_node_allocation_trace_fops = { + .open = gf_debugfs_node_allocation_trace_open, + .read = seq_read, + .write = gf_debugfs_node_allocation_trace_write, + .llseek = seq_lseek, + .release = single_release, +}; + + +static int gf_debugfs_node_video_ctr_debug_show(struct seq_file *s, void *unused) +{ + gf_debugfs_node_t *node = (gf_debugfs_node_t *)(s->private); + seq_printf(s, "0x%x\n", node->dev->gf->video_irq_info_all); + gf_info("show node->dev->gf->video_irq_info_all = %d \n", node->dev->gf->video_irq_info_all); + + return 0; +} + +static int gf_debugfs_node_video_ctr_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, gf_debugfs_node_video_ctr_debug_show, inode->i_private); +} + +static ssize_t gf_debugfs_node_video_ctr_debug_write(struct file *file, const char __user *buf, + size_t size, loff_t *pos) +{ + struct os_seq_file seq_file = {0}; + gf_debugfs_node_t *node = NULL; + char info[32] = {'\0'}; + int ret = 0; + + seq_file.seq_file = file->private_data; + node = (gf_debugfs_node_t *)((seq_file.seq_file)->private); + + if(size > 1 && size < 32) + { + ret = gf_copy_from_user(info, buf, size); + if(!ret) + { + info[size-1] = '\0'; + } + else + return -1; + } + + gf_mutex_lock(node->dev->lock); + if (!gf_strcmp(info, "1")) + { + node->dev->gf->video_irq_info_all = 1; + } + else + { + node->dev->gf->video_irq_info_all = 0; + } + gf_mutex_unlock(node->dev->lock); + gf_info("write node->dev->gf->video_irq_info_all = %d \n", node->dev->gf->video_irq_info_all); + + return (ret == 0) ? size : ret; +} + + +static const struct file_operations debugfs_node_video_ctr_debug_fops = { + .open = gf_debugfs_node_video_ctr_debug_open, + .read = seq_read, + .write = gf_debugfs_node_video_ctr_debug_write, + .llseek = seq_lseek, + .release = single_release, +}; + + +static int gf_mmio_find_segment(gf_mmio_segment_t* seg, int seg_num, int mmio_size, int pos, int* seg_index, int* empty) +{ + int i = 0; + + if(!seg || !seg_num || !mmio_size || (pos >= mmio_size)) + { + return -EINVAL; + } + + for(i = 0; i < seg_num; i++) + { + if(pos >= 0 && pos < seg[0].start) + { + *empty = 1; + *seg_index = 0; + break; + } + else if(pos >= seg[seg_num-1].end) + { + *empty = 1; + *seg_index = seg_num; + break; + } + else if(pos >= seg[i].start && pos < seg[i].end) + { + *empty = 0; + *seg_index = i; + break; + } + else if(pos >= seg[i].end && pos < seg[i+1].start) + { + *empty = 1; + *seg_index = i+1; + break; + } + } + + return 0; +} + +static ssize_t gf_mmio_write(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + gf_debugfs_node_t* node = file_inode(f)->i_private; + adapter_info_t *ainfo = &node->dev->gf->adapter_info; + unsigned int mmio_size = ainfo->mmio_size + 1; + unsigned char *mmio_base = ainfo->mmio; + gf_mmio_segment_t* mmio_seg = mmio_seg_e3k; + unsigned int seg_num = sizeof(mmio_seg_e3k)/sizeof(mmio_seg_e3k[0]); + unsigned int length = 0, seg_end = 0, empty_hole = 0, seg_align = 0, index = 0; + ssize_t result = 0; + uint32_t value = 0; + + if(!size || gf_mmio_find_segment(mmio_seg, seg_num, mmio_size, *pos, &index, &empty_hole)) + { + return 0; + } + + seg_align = (empty_hole)? 4 : mmio_seg[index].alignment; + if(*pos & (seg_align - 1)) + { + return -EINVAL; + } + + if(*pos + size > mmio_size) + { + size = mmio_size - *pos; + } + + gf_mmio_find_segment(mmio_seg, seg_num, mmio_size, *pos+size-1, &index, &empty_hole); + seg_align = (empty_hole)? 4 : mmio_seg[index].alignment; + if((*pos + size) & (seg_align - 1)) + { + return -EINVAL; + } + + while(size) + { + gf_mmio_find_segment(mmio_seg, seg_num, mmio_size, *pos, &index, &empty_hole); + if(empty_hole) + { + seg_end = (index == seg_num)? mmio_size : mmio_seg[index].start; + } + else + { + seg_end = mmio_seg[index].end; + } + seg_align = (empty_hole)? 4 : mmio_seg[index].alignment; + + if(*pos + size > seg_end) + { + length = seg_end - *pos; + } + else + { + length = size; + } + + if(empty_hole) + { + *pos += length; + buf += length; + result += length; + size -= length; + } + else + { + size -= length; + while(length) + { + if(seg_align == 4) + { + get_user(value, (uint32_t __user *)buf); + gf_write32(mmio_base + *pos, value); + } + else if(seg_align == 2) + { + get_user(value, (uint16_t __user *)buf); + gf_write16(mmio_base + *pos, (uint16_t)value); + } + else if(seg_align == 1) + { + get_user(value, (uint8_t __user *)buf); + gf_write8(mmio_base + *pos, (uint8_t)value); + } + else + { + gf_assert(0, GF_FUNC_NAME(__func__)); + } + *pos += seg_align; + buf += seg_align; + result += seg_align; + length -= seg_align; + } + } + } + + return result; +} + +static ssize_t gf_mmio_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) +{ + gf_debugfs_node_t* node = file_inode(f)->i_private; + adapter_info_t *ainfo = &node->dev->gf->adapter_info; + unsigned int mmio_size = ainfo->mmio_size + 1; + unsigned char *mmio_base = ainfo->mmio; + gf_mmio_segment_t* mmio_seg = mmio_seg_e3k; + unsigned int seg_num = sizeof(mmio_seg_e3k)/sizeof(mmio_seg_e3k[0]); + unsigned int length = 0, seg_end = 0, empty_hole = 0, seg_align = 0, index = 0; + ssize_t result = 0; + uint32_t value = 0; + + if(!size || gf_mmio_find_segment(mmio_seg, seg_num, mmio_size, *pos, &index, &empty_hole)) + { + return 0; + } + + seg_align = (empty_hole)? 4 : mmio_seg[index].alignment; + if(*pos & (seg_align - 1)) + { + return -EINVAL; + } + + if(*pos + size > mmio_size) + { + size = mmio_size - *pos; + } + + gf_mmio_find_segment(mmio_seg, seg_num, mmio_size, *pos+size-1, &index, &empty_hole); + seg_align = (empty_hole)? 4 : mmio_seg[index].alignment; + if((*pos + size) & (seg_align - 1)) + { + return -EINVAL; + } + + while(size) + { + gf_mmio_find_segment(mmio_seg, seg_num, mmio_size, *pos, &index, &empty_hole); + if(empty_hole) + { + seg_end = (index == seg_num)? mmio_size : mmio_seg[index].start; + } + else + { + seg_end = mmio_seg[index].end; + } + seg_align = (empty_hole)? 4 : mmio_seg[index].alignment; + + if(*pos + size > seg_end) + { + length = seg_end - *pos; + } + else + { + length = size; + } + + if(empty_hole) + { + value = 0; + size -= length; + while(length) + { + put_user(value, (uint32_t __user *)buf); + *pos += seg_align; + buf += seg_align; + result += seg_align; + length -= seg_align; + } + } + else + { + size -= length; + while(length) + { + if(seg_align == 4) + { + value = gf_read32(mmio_base + *pos); + put_user(value, (uint32_t __user *)buf); + } + else if(seg_align == 2) + { + value = gf_read16(mmio_base + *pos); + put_user((uint16_t)value, (uint16_t __user *)buf); + } + else if(seg_align == 1) + { + value = gf_read8(mmio_base + *pos); + put_user((uint8_t)value, (uint8_t __user *)buf); + } + else + { + gf_assert(0, GF_FUNC_NAME(__func__)); + } + *pos += seg_align; + buf += seg_align; + result += seg_align; + length -= seg_align; + } + } + } + + return result; +} + +static const struct file_operations debugfs_mmio_reg_fops = { + .owner = THIS_MODULE, + .read = gf_mmio_read, + .write = gf_mmio_write, + .llseek = default_llseek, +}; + +static int gf_debugfs_mmio_info_show(struct seq_file *s, void *unused) +{ + gf_debugfs_node_t *node = (gf_debugfs_node_t *)(s->private); + adapter_info_t *ainfo = &node->dev->gf->adapter_info; + int i; + + seq_printf(s, "mmio virtual base=0x%p\n", ainfo->mmio); + seq_printf(s, "mmio size=0x%x\n", ainfo->mmio_size); + for (i = 0; i < sizeof(mmio_seg_e3k)/sizeof(mmio_seg_e3k[0]); i++) + { + seq_printf(s, "mmio seg %s: start=0x%0x, end=0x%0x, alignment=%d\n", + mmio_seg_e3k[i].name, mmio_seg_e3k[i].start, mmio_seg_e3k[i].end, mmio_seg_e3k[i].alignment); + } + return 0; +} + +static int gf_debugfs_mmio_info_open(struct inode *inode, struct file *file) +{ + return single_open(file, gf_debugfs_mmio_info_show, inode->i_private); +} + +static const struct file_operations debugfs_mmio_info_fops = { + .open = gf_debugfs_mmio_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void gf_debugfs_init_mmio_nodes(gf_debugfs_device_t *debug_dev) +{ + gf_debugfs_mmio_t *debug_mmio = &debug_dev->mmio; + debug_mmio->mmio_root = debugfs_create_dir("mmio", debug_dev->debug_root); + if (debug_mmio->mmio_root) { + + debug_mmio->regs.type = 0; + debug_mmio->regs.id = 0; + debug_mmio->regs.adapter = debug_dev->gf->adapter; + debug_mmio->regs.dev = debug_dev; + + gf_vsprintf(debug_mmio->regs.name, "regs"); + + debug_mmio->regs.node_dentry = debugfs_create_file(debug_mmio->regs.name, 0664, debug_mmio->mmio_root, &(debug_mmio->regs), &debugfs_mmio_reg_fops); + + if (debug_mmio->regs.node_dentry == NULL) + { + gf_error("Failed to create debugfs node %s\n", debug_mmio->regs.name); + return ; + } + + debug_mmio->info.type = 0; + debug_mmio->info.id = 0; + debug_mmio->info.adapter = debug_dev->gf->adapter; + debug_mmio->info.dev = debug_dev; + + gf_vsprintf(debug_mmio->info.name, "info"); + + debug_mmio->regs.node_dentry = debugfs_create_file(debug_mmio->info.name, 0444, debug_mmio->mmio_root, &(debug_mmio->info), &debugfs_mmio_info_fops); + + if (debug_mmio->regs.node_dentry == NULL) + { + gf_error("Failed to create debugfs node %s\n", debug_mmio->info.name); + return ; + } + } + else { + gf_error("debugfs: failed to create debugfs root directory.\n"); + } +} + + +static int gf_debugfs_crtc_show(struct seq_file *s, void *unused) +{ + gf_debugfs_node_t *node = (gf_debugfs_node_t *)(s->private); + struct drm_device* dev = node->dev->gf->drm_dev; + + return gf_debugfs_crtc_dump(s, dev, node->id); +} + +static int gf_debugfs_crtc_open(struct inode *inode, struct file *file) +{ + return single_open(file, gf_debugfs_crtc_show, inode->i_private); +} + +static const struct file_operations debugfs_crtcs_fops = { + .open = gf_debugfs_crtc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void gf_debugfs_init_crtcs_nodes(gf_debugfs_device_t *debug_dev) +{ + gf_debugfs_crtcs_t* crtcs = &debug_dev->crtcs; + int i = 0; + + crtcs->crtcs_root = debugfs_create_dir("crtcs", debug_dev->debug_root); + if(!crtcs->crtcs_root) + { + gf_error("Failed to create dir for debugfs crtcs root.\n"); + goto FAIL; + } + + crtcs->debug_dev = debug_dev; + crtcs->node_num = debug_dev->gf->drm_dev->mode_config.num_crtc; + if(crtcs->node_num) + { + crtcs->crtcs_nodes = gf_calloc(sizeof(struct gf_debugfs_node)*crtcs->node_num); + } + if(!crtcs->crtcs_nodes) + { + gf_error("Failed to alloc mem for debugfs crtcs nodes.\n"); + goto FAIL; + } + + for(i = 0; i < crtcs->node_num; i++) + { + crtcs->crtcs_nodes[i].type = 0; + crtcs->crtcs_nodes[i].id = i; + + crtcs->crtcs_nodes[i].dev = debug_dev; + gf_vsprintf(crtcs->crtcs_nodes[i].name, "IGA%d", (i + 1)); + + crtcs->crtcs_nodes[i].node_dentry = debugfs_create_file(crtcs->crtcs_nodes[i].name, 0444, crtcs->crtcs_root, &crtcs->crtcs_nodes[i], &debugfs_crtcs_fops); + if(!crtcs->crtcs_nodes[i].node_dentry) + { + gf_error("Failed to create debugfs file for crtc node.\n"); + goto FAIL; + } + } + + return; + +FAIL: + + if(crtcs->crtcs_root) + { + debugfs_remove_recursive(crtcs->crtcs_root); + } + + if(crtcs->crtcs_nodes) + { + gf_free(crtcs->crtcs_nodes); + crtcs->crtcs_nodes = NULL; + } +} + +gf_debugfs_device_t* gf_debugfs_create(gf_card_t *gf, struct dentry *minor_root) +{ + gf_debugfs_device_t *dev; + int i=0; + gf_heap_info_t *heap; + dev = gf_calloc(sizeof(struct gf_debugfs_device)); + if (!dev) + { + return NULL; + } + + dev->gf = gf; + dev->lock = gf_create_mutex(); + INIT_LIST_HEAD(&(dev->node_list)); + INIT_LIST_HEAD(&(dev->device_node_list)); + + dev->debug_root = debugfs_create_dir("gf", minor_root); + if (!dev->debug_root) + { + gf_error("debugfs: failed to create debugfs root directory.\n"); + return NULL; + } + + dev->device_root = debugfs_create_dir("devices", dev->debug_root); + + dev->allocation_root = debugfs_create_dir("allocations", dev->debug_root); + +/*HEAP info*/ + heap = &dev->heap_info; + heap->heap_dir = debugfs_create_dir("heaps", dev->debug_root); + if (!heap->heap_dir) + { + gf_error("debugfs: failed to create debugfs root directory.\n"); + return NULL; + } + + for(i = 0; iheap[i].type = DEBUGFS_NODE_HEAP; + heap->heap[i].id = i; + heap->heap[i].adapter = dev->gf->adapter; + heap->heap[i].dev = dev; + + gf_vsprintf(heap->heap[i].name, "heap%d", i); + + heap->heap[i].node_dentry = debugfs_create_file(heap->heap[i].name, 0664, heap->heap_dir, &(heap->heap[i]), &debugfs_node_fops); + + if (heap->heap[i].node_dentry == NULL) + { + gf_error("Failed to create debugfs node %s\n", heap->heap[i].name); + return NULL; + } + } + + dev->info.type = DEBUGFS_NODE_INFO; + dev->info.adapter = dev->gf->adapter; + dev->info.dev = dev; + + gf_vsprintf(dev->info.name, "info"); + + dev->info.node_dentry = debugfs_create_file(dev->info.name, 0664, dev->debug_root, &(dev->info), &debugfs_node_fops); + + if (dev->info.node_dentry == NULL) + { + gf_error("Failed to create debugfs node %s\n", dev->info.name); + return NULL; + } + + dev->memtrack.type = DEBUGFS_NODE_MEMTRACK; + dev->memtrack.adapter = dev->gf->adapter; + dev->memtrack.dev = dev; + dev->memtrack.id = -1; + + gf_vsprintf(dev->memtrack.name, "memtrack"); + + dev->memtrack.node_dentry = debugfs_create_file(dev->memtrack.name, 0664, dev->debug_root, &(dev->memtrack), &debugfs_node_fops); + + if (dev->memtrack.node_dentry == NULL) + { + gf_error("Failed to create debugfs node %s\n", dev->memtrack.name); + return NULL; + } + + dev->vidsch.type = DEBUGFS_NODE_VIDSCH; + dev->vidsch.adapter = dev->gf->adapter; + dev->vidsch.dev = dev; + + gf_vsprintf(dev->vidsch.name, "vidsch"); + + dev->vidsch.node_dentry = debugfs_create_file(dev->vidsch.name, 0664, dev->debug_root, &(dev->vidsch), &debugfs_node_fops); + + if (dev->vidsch.node_dentry == NULL) + { + gf_error("Failed to create debugfs node %s\n", dev->vidsch.name); + return NULL; + } + + // here to create displayinfo node to get info + dev->displayinfo.type = 0; + dev->displayinfo.adapter = dev->gf->adapter; + dev->displayinfo.dev = dev; + + gf_vsprintf(dev->displayinfo.name, "displayinfo"); + + dev->displayinfo.node_dentry = debugfs_create_file(dev->displayinfo.name, 0664, dev->debug_root, &(dev->displayinfo), &debugfs_node_displayinfo_fops); + + if (dev->displayinfo.node_dentry == NULL) + { + gf_error("Failed to create debugfs node %s\n", dev->displayinfo.name); + return NULL; + } + + dev->debugbus.type = DEBUGFS_NODE_DEBUGBUS; + dev->debugbus.adapter = dev->gf->adapter; + dev->debugbus.dev = dev; + + gf_vsprintf(dev->debugbus.name, "debugbus"); + + dev->debugbus.node_dentry = debugfs_create_file(dev->debugbus.name, 0664, dev->debug_root, &(dev->debugbus), &debugfs_node_fops); + + if (dev->debugbus.node_dentry == NULL) + { + gf_error("Failed to create debugfs node %s\n", dev->debugbus.name); + } + + // create file to enable/disable usermode trace. + // NOTE: kmd trace is controlled by /sys/kernel/debug/tracing/events/gfx/enable + dev->umd_trace.type = 0; + dev->umd_trace.adapter = dev->gf->adapter; + dev->umd_trace.dev = dev; + + gf_vsprintf(dev->umd_trace.name, "umd_trace"); + + dev->umd_trace.node_dentry = debugfs_create_file(dev->umd_trace.name, 0664, dev->debug_root, &(dev->umd_trace), &debugfs_node_umd_trace_fops); + + if (dev->umd_trace.node_dentry == NULL) + { + gf_error("Failed to create debugfs node %s\n", dev->umd_trace.name); + return NULL; + } + + // create file to enable/disable allocation trace + dev->allocation_trace.type = 0; + dev->allocation_trace.adapter = dev->gf->adapter; + dev->allocation_trace.dev = dev; + + gf_vsprintf(dev->allocation_trace.name, "allocation_trace"); + + dev->allocation_trace.node_dentry = debugfs_create_file(dev->allocation_trace.name, 0664, dev->debug_root, &(dev->allocation_trace), &debugfs_node_allocation_trace_fops); + + if (dev->allocation_trace.node_dentry == NULL) + { + gf_error("Failed to create debugfs node %s\n", dev->allocation_trace.name); + return NULL; + } + + // create file to control video interrupt output info + dev->video_interrupt_info.type = 0; + dev->video_interrupt_info.adapter = dev->gf->adapter; + dev->video_interrupt_info.dev = dev; + + gf_vsprintf(dev->video_interrupt_info.name, "video_interrupt_info"); + + dev->video_interrupt_info.node_dentry = debugfs_create_file(dev->video_interrupt_info.name, 0664, dev->debug_root, &(dev->video_interrupt_info), &debugfs_node_video_ctr_debug_fops); + + if (dev->video_interrupt_info.node_dentry == NULL) + { + gf_error("Failed to create debugfs node %s\n", dev->video_interrupt_info.name); + return NULL; + } + + gf_debugfs_init_mmio_nodes(dev); + + gf_debugfs_init_crtcs_nodes(dev); + + return dev; +} + +int gf_debugfs_destroy(gf_debugfs_device_t* dev) +{ + gf_debugfs_node_t *node1 = NULL; + gf_debugfs_node_t *node2 = NULL; + + if(dev == NULL) + { + gf_error("destroy a null dubugfs dev\n"); + return -1; + } + + if(dev->lock) + { + gf_destroy_mutex(dev->lock); + } + + if(dev->debug_root) + { + debugfs_remove_recursive(dev->debug_root); + } + + list_for_each_entry_safe(node1, node2, &(dev->node_list), list_item) + { + gf_free(node1); + } + + if(dev->crtcs.crtcs_nodes) + { + gf_free(dev->crtcs.crtcs_nodes); + } + + gf_free(dev); + + return 0; +} + +static int gf_debugfs_device_show(struct seq_file *s, void *unused) +{ + gf_device_debug_info_t *node = (gf_device_debug_info_t *)(s->private); + seq_printf(s, "pid = %lu\n", node->user_pid); + seq_printf(s, "handle = 0x%x\n", node->hDevice); + + return 0; +} + +static int gf_debugfs_device_open(struct inode *inode, struct file *file) +{ + return single_open(file, gf_debugfs_device_show, inode->i_private); +} + +static const struct file_operations debugfs_device_fops = { + .open = gf_debugfs_device_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +gf_device_debug_info_t* gf_debugfs_add_device_node(gf_debugfs_device_t* dev, int id, unsigned int handle) +{ + gf_device_debug_info_t *node = gf_calloc(sizeof(gf_device_debug_info_t)); + + gf_device_debug_info_t *node1 = NULL; + gf_device_debug_info_t *node2 = NULL; + struct dentry *parent = dev->device_root; + + node->id = id; + node->adapter = dev->gf->adapter; + node->debugfs_dev = dev; + node->hDevice = handle; + + gf_mutex_lock(dev->lock); + + list_for_each_entry_safe(node1, node2, &(dev->device_node_list), list_item) + { + if(node1->id == node->id) + { + node->min_id++; + } + } + gf_mutex_unlock(dev->lock); + + gf_vsprintf(node->name, "%08x", handle); + node->dentry = debugfs_create_dir(node->name, parent); + if (node->dentry) { + node->info = debugfs_create_file(node->name, 0664, node->dentry, node, &debugfs_device_fops); + if (!node->info) + { + gf_error("Failed to create debugfs node %s\n", node->name); + gf_free(node); + + return NULL; + } + node->d_alloc = debugfs_create_dir("allocations", node->dentry); + if (!node->d_alloc) { + gf_error("Failed to create debugfs node %s allocations dir%s\n", node->name); + gf_free(node); + + return NULL; + } + } else { + gf_error("Failed to create debugfs dir %s\n", node->name); + gf_free(node); + return NULL; + } + + gf_mutex_lock(dev->lock); + list_add_tail(&(node->list_item), &(dev->device_node_list)); + gf_mutex_unlock(dev->lock); + + return node; +} + +int gf_debugfs_remove_device_node(gf_debugfs_device_t* dev, gf_device_debug_info_t *dnode) +{ + gf_device_debug_info_t *node1 = NULL; + gf_device_debug_info_t *node2 = NULL; + + if (dnode == NULL) + { + return 0; + } + + gf_mutex_lock(dev->lock); + + list_for_each_entry_safe(node1, node2, &(dev->device_node_list), list_item) + { + if(node1 && (node1->hDevice == dnode->hDevice)) + { + debugfs_remove_recursive(node1->dentry); + list_del(&(node1->list_item)); + + gf_free(node1); + break; + } + } + + gf_mutex_unlock(dev->lock); + + return 0; +} + +int gf_debugfs_init(gf_card_t *gf) +{ + gf->debugfs_dev = gf_debugfs_create(gf, gf->drm_dev->primary->debugfs_root); + if (!gf->debugfs_dev) + { + return -1; + } + + return 0; +} diff --git a/drivers/gpu/drm/arise/linux/gf_debugfs.h b/drivers/gpu/drm/arise/linux/gf_debugfs.h new file mode 100644 index 0000000000000..ccbd8ba0af318 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_debugfs.h @@ -0,0 +1,109 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_DEUBGFS_H__ +#define __GF_DEUBGFS_H__ + +#include "gf.h" +#include "gf_driver.h" +#include "gf_device_debug.h" + +#define DEBUGFS_ESCAPE_CREATE 1 +#define DEBUGFS_GF_CREATE 2 + +#define DEBUGFS_HEAP_NUM 8 +#define DEBUGFS_MEMTRACK (DEBUGFS_HEAP_NUM + 1) + +struct gf_debugfs_device; + +typedef struct gf_debugfs_node +{ + int type; + void *adapter; + struct gf_debugfs_device *dev; + int id; + char name[20]; + struct dentry *node_dentry; + int create_hint; + int min_id; + struct list_head list_item; + unsigned int hDevice; + +}gf_debugfs_node_t; + +struct gf_debugfs_device; +typedef struct gf_debugfs_mmio +{ + struct dentry *mmio_root; + struct gf_debugfs_node regs; + struct gf_debugfs_node info; + struct gf_debugfs_device *debug_dev; +}gf_debugfs_mmio_t; + +typedef struct gf_heap_info +{ + struct gf_debugfs_node heap[DEBUGFS_HEAP_NUM]; + struct dentry *heap_dir; +}gf_heap_info_t; + +typedef struct gf_debugfs_crtcs +{ + struct gf_debugfs_device* debug_dev; + struct dentry* crtcs_root; + struct gf_debugfs_node* crtcs_nodes; + int node_num; +}gf_debugfs_crtcs_t; + +typedef struct gf_debugfs_device +{ + gf_card_t *gf; + struct list_head node_list; + + struct dentry *device_root; + struct list_head device_node_list; + + struct dentry *allocation_root; + + gf_heap_info_t heap_info; + + struct gf_debugfs_node info; + struct gf_debugfs_node memtrack; + struct gf_debugfs_node vidsch; + struct gf_debugfs_node displayinfo; + struct gf_debugfs_node debugbus; + struct gf_debugfs_node umd_trace; + struct gf_debugfs_node allocation_trace; + struct gf_debugfs_node video_interrupt_info; + struct dentry *debug_root; + struct os_mutex *lock; + gf_debugfs_mmio_t mmio; + gf_debugfs_crtcs_t crtcs; +}gf_debugfs_device_t; + + + +gf_debugfs_device_t* gf_debugfs_create(gf_card_t *gf, struct dentry *minor_root); +int gf_debugfs_destroy(gf_debugfs_device_t* dev); +gf_device_debug_info_t* gf_debugfs_add_device_node(gf_debugfs_device_t* dev, int id, unsigned int handle); +int gf_debugfs_remove_device_node(gf_debugfs_device_t* dev, gf_device_debug_info_t *dnode); +int gf_debugfs_init(gf_card_t *gf); + +static __inline__ struct dentry *gf_debugfs_get_allocation_root(void *debugfs_dev) +{ + gf_debugfs_device_t *dev = (gf_debugfs_device_t *)debugfs_dev; + return dev->allocation_root; +} +#endif + + diff --git a/drivers/gpu/drm/arise/linux/gf_device_debug.h b/drivers/gpu/drm/arise/linux/gf_device_debug.h new file mode 100644 index 0000000000000..46a92568f26e3 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_device_debug.h @@ -0,0 +1,33 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_DEVICE_DEUBG_H__ +#define __GF_DEVICE_DEUBG_H__ +typedef struct gf_device_debug_info { + struct dentry *dentry; //the device root directly + struct dentry *info; + void *adapter; + void *debugfs_dev; //the gf root device + int id; + char name[20]; + int min_id; + struct list_head list_item; + unsigned int hDevice; + + struct dentry *d_alloc; + unsigned long user_pid; +}gf_device_debug_info_t; + +#endif + diff --git a/drivers/gpu/drm/arise/linux/gf_disp.c b/drivers/gpu/drm/arise/linux/gf_disp.c new file mode 100644 index 0000000000000..f3c649aad9928 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_disp.c @@ -0,0 +1,1896 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_disp.h" +#include "gf_cbios.h" +#include "gf_atomic.h" +#include "gf_crtc.h" +#include "gf_plane.h" +#include "gf_drmfb.h" +#include "gf_irq.h" +#include "gf_fbdev.h" +#include "gf_capture_drv.h" +#include "gf_splice.h" +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) +#include +#endif + +static const struct drm_mode_config_funcs gf_kms_mode_funcs = { + .fb_create = gf_fb_create, +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .output_poll_changed = gf_fbdev_poll_changed, +#else + .output_poll_changed = drm_fb_helper_output_poll_changed, +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, + .atomic_state_alloc = gf_atomic_state_alloc, + .atomic_state_clear = gf_atomic_state_clear, + .atomic_state_free = gf_atomic_state_free, +#endif +}; + +static const int chx_plane_formats[] = { + DRM_FORMAT_C8, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_XRGB2101010, + DRM_FORMAT_XBGR2101010, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_ABGR2101010, + DRM_FORMAT_YUYV, + DRM_FORMAT_YVYU, + DRM_FORMAT_UYVY, + DRM_FORMAT_VYUY, + DRM_FORMAT_AYUV, +}; + +static const int chx_cursor_formats[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, +}; + +static char* plane_name[] = { + "PS", + "SS", + "TS", + "FS", +}; + +static char* cursor_name = "cursor"; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) +static const struct drm_mode_config_helper_funcs gf_kms_mode_helper_funcs = { +#else +static struct drm_mode_config_helper_funcs gf_kms_mode_helper_funcs = { +#endif + .atomic_commit_tail = gf_atomic_helper_commit_tail, +}; + +static const struct drm_plane_funcs gf_plane_funcs = { + .update_plane = gf_atomic_helper_update_plane, + .disable_plane = gf_atomic_helper_disable_plane, + .destroy = gf_plane_destroy, +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + .set_property = drm_atomic_helper_plane_set_property, +#endif + .atomic_duplicate_state = gf_plane_duplicate_state, + .atomic_destroy_state = gf_plane_destroy_state, + .atomic_set_property = gf_plane_atomic_set_property, + .atomic_get_property = gf_plane_atomic_get_property, +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) + .format_mod_supported = gf_plane_format_mod_supported, +#endif +}; + +static const struct drm_plane_helper_funcs gf_plane_helper_funcs = { + .prepare_fb = gf_prepare_plane_fb, + .cleanup_fb = gf_cleanup_plane_fb, + .atomic_check = gf_plane_atomic_check, + .atomic_update = gf_plane_atomic_update, + .atomic_disable = gf_plane_atomic_disable, +}; + +static const struct drm_crtc_funcs gf_crtc_funcs = { +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + .gamma_set = drm_atomic_helper_legacy_gamma_set, +#endif + .destroy = gf_crtc_destroy, + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + .set_property = drm_atomic_helper_crtc_set_property, +#endif + .atomic_duplicate_state = gf_crtc_duplicate_state, + .atomic_destroy_state = gf_crtc_destroy_state, +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) + .get_vblank_counter = gf_get_vblank_counter, + .enable_vblank = gf_enable_vblank, + .disable_vblank = gf_disable_vblank, + .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, +#endif +}; + +static const struct drm_crtc_helper_funcs gf_helper_funcs = { + .mode_set_nofb = gf_crtc_helper_set_mode, +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + .enable = gf_crtc_helper_enable, +#endif + .disable = gf_crtc_helper_disable, + .atomic_check = gf_crtc_helper_check, + .atomic_begin = gf_crtc_atomic_begin, + .atomic_flush = gf_crtc_atomic_flush, +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + .atomic_enable = gf_crtc_atomic_enable, +#endif +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + .atomic_disable = gf_crtc_atomic_disable, +#endif +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) + .get_scanout_position = gf_crtc_get_scanout_position, +#endif +}; + +#else + +static const struct drm_plane_funcs gf_plane_funcs = { + .update_plane = gf_update_plane, + .disable_plane = gf_disable_plane, + .destroy = gf_legacy_plane_destroy, +}; + +static const struct drm_crtc_funcs gf_crtc_funcs = { + .cursor_set = gf_crtc_cursor_set, + .cursor_move = gf_crtc_cursor_move, + .gamma_set = gf_crtc_gamma_set, + .set_config = gf_crtc_helper_set_config, + .destroy = gf_crtc_destroy, + .page_flip = gf_crtc_page_flip, +}; + +static const struct drm_crtc_helper_funcs gf_helper_funcs = { + .prepare = gf_crtc_prepare, + .commit = gf_crtc_commit, + .mode_fixup = gf_crtc_mode_fixup, + .mode_set = gf_crtc_mode_set, + .mode_set_base = gf_crtc_mode_set_base, + .disable = gf_crtc_disable, +}; + +#endif + +static void disp_info_pre_init(disp_info_t* disp_info) +{ + unsigned int i = 0; + + disp_info->cbios_lock = gf_create_mutex(); + + disp_info->intr_lock = gf_create_spinlock(0); + disp_info->hpd_lock = gf_create_spinlock(0); + disp_info->hda_lock = gf_create_spinlock(0); + disp_info->hdcp_lock = gf_create_spinlock(0); + + disp_info->cbios_inner_spin_lock = gf_create_spinlock(0); + disp_info->cbios_aux_mutex = gf_create_mutex(); + + for(i = 0;i < MAX_I2CBUS;i++) + { + disp_info->cbios_i2c_mutex[i] = gf_create_mutex(); + } + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35) + disp_info->wq = create_workqueue("arise"); +#endif +} + +static void disp_info_deinit(disp_info_t* disp_info) +{ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35) + destroy_workqueue(disp_info->wq); + disp_info->wq = NULL; +#endif + + gf_destroy_mutex(disp_info->cbios_lock); + disp_info->cbios_lock = NULL; + + gf_destroy_spinlock(disp_info->intr_lock); + disp_info->intr_lock = NULL; + + gf_destroy_spinlock(disp_info->hpd_lock); + disp_info->hpd_lock = NULL; + + gf_destroy_spinlock(disp_info->hda_lock); + disp_info->hda_lock = NULL; + + gf_destroy_spinlock(disp_info->hdcp_lock); + disp_info->hdcp_lock = NULL; + +#if 0 + int i = 0; + gf_destroy_spinlock(disp_info->cbios_inner_spin_lock); + disp_info->cbios_inner_spin_lock = NULL; + + gf_destroy_mutex(disp_info->cbios_aux_mutex); + disp_info->cbios_aux_mutex = NULL; + + for(i = 0;i < MAX_I2CBUS;i++) + { + gf_destroy_mutex(disp_info->cbios_i2c_mutex[i]) ; + disp_info->cbios_i2c_mutex[i] = NULL; + } +#endif + +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 20, 0) +int disp_create_blend_mode_property(struct drm_plane *plane, unsigned int supported_modes) +{ + struct drm_device *dev = plane->dev; + struct drm_property *prop; + gf_plane_t* gf_plane = to_gf_plane(plane); + static const struct drm_prop_enum_list props[] = { + { DRM_MODE_BLEND_PIXEL_NONE, "None" }, + { DRM_MODE_BLEND_PREMULTI, "Pre-multiplied" }, + { DRM_MODE_BLEND_COVERAGE, "Coverage" }, + }; + unsigned int valid_mode_mask = BIT(DRM_MODE_BLEND_PIXEL_NONE) | + BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE); + int i = 0, j = 0; + + if ((supported_modes & ~valid_mode_mask) ||((supported_modes & BIT(DRM_MODE_BLEND_PREMULTI)) == 0)) + { + return -EINVAL; + } + + prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, "pixel blend mode", hweight32(supported_modes)); + if (!prop) + { + return -ENOMEM; + } + + for (i = 0; i < ARRAY_SIZE(props); i++) + { + int ret; + + if (!(BIT(props[i].type) & supported_modes)) + { + continue; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + ret = drm_property_add_enum(prop, props[i].type, props[i].name); +#else + ret = drm_property_add_enum(prop, j++, props[i].type, props[i].name); +#endif + + if (ret) + { + drm_property_destroy(dev, prop); + return ret; + } + } + + drm_object_attach_property(&plane->base, prop, DRM_MODE_BLEND_PREMULTI); + gf_plane->blend_mode_property = prop; + + if(plane->state) + { + to_gf_plane_state(plane->state)->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; + } + + return 0; +} +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 18, 0) +int disp_create_alpha_property(struct drm_plane *plane) +{ + struct drm_property *prop; + gf_plane_t* gf_plane = to_gf_plane(plane); + + prop = drm_property_create_range(plane->dev, 0, "alpha", 0, DRM_BLEND_ALPHA_OPAQUE); + if (!prop) + { + return -ENOMEM; + } + + drm_object_attach_property(&plane->base, prop, DRM_BLEND_ALPHA_OPAQUE); + gf_plane->alpha_property = prop; + + if (plane->state) + { + to_gf_plane_state(plane->state)->alpha = DRM_BLEND_ALPHA_OPAQUE; + } + + return 0; +} +#endif + +int disp_create_alpha_source_property(struct drm_plane* plane) +{ + struct drm_device *dev = plane->dev; + gf_plane_t* gf_plane = to_gf_plane(plane); + struct drm_property *prop; + int i = 0; + + static const struct drm_prop_enum_list props[] = { + { DRM_MODE_BLEND_CURR_LAYER_ALPHA, "Use alpha of current layer" }, + { DRM_MODE_BLEND_LOWER_LAYER_ALPHA, "Use alpha of lower layer" }, + }; + + prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, "blend alpha source", ARRAY_SIZE(props)); + if (!prop) + { + return -ENOMEM; + } + + for (i = 0; i < ARRAY_SIZE(props); i++) + { + int ret; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + ret = drm_property_add_enum(prop, props[i].type, props[i].name); +#else + ret = drm_property_add_enum(prop, i, props[i].type, props[i].name); +#endif + + if (ret) + { + drm_property_destroy(dev, prop); + return ret; + } + } + + drm_object_attach_property(&plane->base, prop, DRM_MODE_BLEND_CURR_LAYER_ALPHA); + gf_plane->alpha_source_prop = prop; + + if(plane->state) + { + to_gf_plane_state(plane->state)->alpha_source = DRM_MODE_BLEND_CURR_LAYER_ALPHA; + } + + return 0; +} + +void disp_create_plane_property(struct drm_device* dev, gf_plane_t* gf_plane) +{ + int zpos = 0; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 13, 0) + drm_plane_create_rotation_property(&gf_plane->base_plane, DRM_ROTATE_0, DRM_ROTATE_0); +#else + drm_plane_create_rotation_property(&gf_plane->base_plane, DRM_MODE_ROTATE_0, DRM_MODE_ROTATE_0); +#endif +#else + if (GF_PLANE_PS == gf_plane->plane_type) + { + if (!dev->mode_config.rotation_property) + { + dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev, DRM_ROTATE_0); + } + + if(dev->mode_config.rotation_property) + { + drm_object_attach_property(&gf_plane->base_plane.base, dev->mode_config.rotation_property, DRM_ROTATE_0); + } + } + + if(gf_plane->base_plane.state) + { + gf_plane->base_plane.state->rotation = DRM_ROTATE_0; + } +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + drm_plane_create_alpha_property(&gf_plane->base_plane); +#else + disp_create_alpha_property(&gf_plane->base_plane); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) + drm_plane_create_blend_mode_property(&gf_plane->base_plane, + BIT(DRM_MODE_BLEND_PIXEL_NONE) | + BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE)); +#else + disp_create_blend_mode_property(&gf_plane->base_plane, + BIT(DRM_MODE_BLEND_PIXEL_NONE) | + BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE)); +#endif + + disp_create_alpha_source_property(&gf_plane->base_plane); + + zpos = (gf_plane->is_cursor)? 32 : gf_plane->plane_type; + drm_plane_create_zpos_immutable_property(&gf_plane->base_plane, zpos); //we do not support dynamic plane order +} + +static gf_plane_t* disp_gene_plane_create(disp_info_t* disp_info, int index, GF_PLANE_TYPE type, int is_cursor) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + gf_plane_t* gf_plane = NULL; + gf_plane_state_t* gf_pstate = NULL; + int ret = 0; + const int* formats = 0; + int fmt_count = 0; + int drm_ptype; + char* name; + + gf_plane = gf_calloc(sizeof(gf_plane_t)); + if (!gf_plane) + { + goto fail; + } + + gf_plane->crtc_index = index; + if(is_cursor) + { + gf_plane->plane_type = GF_MAX_PLANE; + gf_plane->is_cursor = 1; + gf_plane->can_window = 1; + } + else + { + gf_plane->plane_type = type; + gf_plane->can_window = (type != GF_PLANE_PS)? 1 : 0; + gf_plane->can_up_scale = (disp_info->up_scale_plane_mask[index] & (1 << type))? 1 : 0; + gf_plane->can_down_scale = (disp_info->down_scale_plane_mask[index] & (1 << type))? 1 : 0; + } + + gf_pstate = gf_calloc(sizeof(gf_plane_state_t)); + if (!gf_pstate) + { + goto fail; + } + + gf_pstate->base_pstate.plane = &gf_plane->base_plane; + gf_plane->base_plane.state = &gf_pstate->base_pstate; + + if(is_cursor) + { + formats = chx_cursor_formats; + fmt_count = sizeof(chx_cursor_formats)/sizeof(chx_cursor_formats[0]); + name = cursor_name; + drm_ptype = DRM_PLANE_TYPE_CURSOR; + } + else + { + formats = chx_plane_formats; + fmt_count = sizeof(chx_plane_formats)/sizeof(chx_plane_formats[0]); + name = plane_name[type]; + drm_ptype = (type == GF_PLANE_PS)? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; + } + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + ret = drm_universal_plane_init(drm, &gf_plane->base_plane, + (1 << index), &gf_plane_funcs, + formats, fmt_count, + drm_ptype, + "IGA%d-%s", (index+1), name); +#else + ret = drm_universal_plane_init(drm, &gf_plane->base_plane, + (1 << index), &gf_plane_funcs, + formats, fmt_count, NULL, + drm_ptype, + "IGA%d-%s", (index+1), name); +#endif + + if(ret) + { + goto fail; + } + + drm_plane_helper_add(&gf_plane->base_plane, &gf_plane_helper_funcs); + + disp_create_plane_property(drm, gf_plane); + + DRM_DEBUG_KMS("plane=%d,name=%s\n", gf_plane->base_plane.index, gf_plane->base_plane.name); + return gf_plane; + +fail: + if(gf_plane) + { + gf_free(gf_plane); + gf_plane = NULL; + } + if(gf_pstate) + { + gf_free(gf_pstate); + gf_pstate = NULL; + } + return NULL; +} + +#else + +static gf_plane_t* disp_gene_plane_create(disp_info_t* disp_info, int index, GF_PLANE_TYPE type, int is_cursor) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + gf_plane_t* gf_plane = NULL; + int ret = 0; + const int* formats = 0; + int fmt_count = 0; + + gf_plane = gf_calloc(sizeof(gf_plane_t)); + if (!gf_plane) + { + gf_error("Alloc plane failed. plane type = %d, crtc index = %d.\n", type, index); + return NULL; + } + + gf_plane->crtc_index = index; + gf_plane->plane_type = type; + gf_plane->can_window = (type != GF_PLANE_PS)? 1 : 0; + gf_plane->can_up_scale = (disp_info->up_scale_plane_mask[index] & (1 << type))? 1 : 0; + gf_plane->can_down_scale = (disp_info->down_scale_plane_mask[index] & (1 << type))? 1 : 0; + + formats = chx_plane_formats; + fmt_count = sizeof(chx_plane_formats)/sizeof(chx_plane_formats[0]); + + ret = drm_plane_init(drm, &gf_plane->base_plane, (1 << index), &gf_plane_funcs, formats, fmt_count, FALSE); + + if(ret) + { + gf_error("Init plane failed. plane type = %d, crtc index = %d.\n", type, index); + gf_free(gf_plane); + gf_plane = NULL; + } + return gf_plane; +} +#endif + +void disp_irq_init(disp_info_t* disp_info) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + + INIT_WORK(&disp_info->hotplug_work, gf_hotplug_work_func); + INIT_WORK(&disp_info->dp_irq_work, gf_dp_irq_work_func); + INIT_WORK(&disp_info->hda_work, gf_hda_work_func); + INIT_WORK(&disp_info->hdcp_work, gf_hdcp_work_func); + disp_info->irq_chip_func = &irq_chip_funcs; + + drm->vblank_disable_immediate = true; + + drm->max_vblank_count = 0xFFFF; + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) + drm->driver->get_vblank_counter = gf_get_vblank_counter; + drm->driver->enable_vblank = gf_enable_vblank; + drm->driver->disable_vblank = gf_disable_vblank; + drm->driver->get_vblank_timestamp = gf_get_vblank_timestamp; +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 13, 0) +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 4, 0) + drm->driver->get_scanout_position = gf_legacy_get_crtc_scanoutpos; +#else + drm->driver->get_scanout_position = gf_get_crtc_scanoutpos; +#endif +#elif DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) + drm->driver->get_scanout_position = gf_get_crtc_scanoutpos_kernel_4_10; +#endif + + if(gf_card->support_msi && !gf_card->pdev->msi_enabled) + { + pci_enable_msi(gf_card->pdev); + } +} + +void disp_irq_deinit(disp_info_t* disp_info) +{ + gf_card_t* gf_card = disp_info->gf_card; + + cancel_work_sync(&disp_info->dp_irq_work); + cancel_work_sync(&disp_info->hotplug_work); + cancel_work_sync(&disp_info->hda_work); + cancel_work_sync(&disp_info->hdcp_work); + + if(gf_card->pdev->msi_enabled) + { + pci_disable_msi(gf_card->pdev); + } +} + +void disp_irq_install(disp_info_t* disp_info) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 14, 0) + drm_irq_install(drm, drm->pdev->irq); +#else + gf_irq_install(drm); +#endif + + disp_info->irq_enabled = 1; +} + +void disp_irq_uninstall(disp_info_t* disp_info) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + + disp_info->irq_enabled = 0; + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 14, 0) + drm_irq_uninstall(drm); +#else + gf_irq_uninstall(drm); +#endif +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) +static int disp_crtc_init(disp_info_t* disp_info, unsigned int index) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + gf_crtc_t* gf_crtc = NULL; + gf_crtc_state_t* crtc_state = NULL; + gf_plane_t* gf_plane[GF_MAX_PLANE] = {NULL}; + gf_plane_t* gf_cursor = NULL; + int ret = 0, type = 0; + + gf_crtc = gf_calloc(sizeof(gf_crtc_t)); + if (!gf_crtc) + { + return -ENOMEM; + } + + crtc_state = gf_calloc(sizeof(gf_crtc_state_t)); + if (!crtc_state) + { + ret = -ENOMEM; + goto fail; + } + + gf_crtc->pipe = index; + gf_crtc->base_crtc.state = &crtc_state->base_cstate; + crtc_state->base_cstate.crtc = &gf_crtc->base_crtc; + gf_crtc->crtc_dpms = 0; + + gf_crtc->support_scale = disp_info->scale_support; + + gf_crtc->plane_cnt = disp_info->num_plane[index]; + + for(type = 0; type < gf_crtc->plane_cnt; type++) + { + gf_plane[type] = disp_gene_plane_create(disp_info, index, type, 0); + } + + gf_cursor = disp_gene_plane_create(disp_info, index, 0, 1); + + ret = drm_crtc_init_with_planes(drm, &gf_crtc->base_crtc, + &gf_plane[GF_PLANE_PS]->base_plane, + &gf_cursor->base_plane, + &gf_crtc_funcs, + "IGA%d", (index + 1)); + + if(ret) + { + goto fail; + } + + drm_crtc_helper_add(&gf_crtc->base_crtc, &gf_helper_funcs); + + drm_mode_crtc_set_gamma_size(&gf_crtc->base_crtc, 256); + + drm_crtc_enable_color_mgmt(&gf_crtc->base_crtc, 0, 1, 256); + + DRM_DEBUG_KMS("crtc=%d,name=%s\n", gf_crtc->base_crtc.index, gf_crtc->base_crtc.name); + return 0; + + fail: + if(gf_crtc) + { + gf_free(gf_crtc); + gf_crtc = NULL; + } + if(crtc_state) + { + gf_free(crtc_state); + crtc_state = NULL; + } + + return ret; +} + +#else + +static int disp_crtc_init(disp_info_t* disp_info, unsigned int index) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + gf_crtc_t* gf_crtc = NULL; + gf_plane_t* gf_plane[GF_MAX_PLANE] = {NULL}; + int ret = 0, type = 0, i = 0; + + gf_crtc = gf_calloc(sizeof(gf_crtc_t)); + if (!gf_crtc) + { + return -ENOMEM; + } + + gf_crtc->pipe = index; + + gf_crtc->support_scale = disp_info->scale_support; + + gf_crtc->plane_cnt = disp_info->num_plane[index]; + + gf_crtc->crtc_dpms = 0; + + ret = drm_crtc_init(drm, &gf_crtc->base_crtc, &gf_crtc_funcs); + + if(ret) + { + goto fail; + } + + drm_mode_crtc_set_gamma_size(&gf_crtc->base_crtc, 256); + for (i = 0; i < 256; i ++) + { + gf_crtc->lut_entry[i] = (i << 2) + (i << 12) + (i << 22); + } + + drm_crtc_helper_add(&gf_crtc->base_crtc, &gf_helper_funcs); + + //in legacy kms, plane is stand for overlay exclude primary stream and cursor + for(type = GF_PLANE_SS; type < gf_crtc->plane_cnt; type++) + { + gf_plane[type] = disp_gene_plane_create(disp_info, index, type, 0); + } + + return 0; + +fail: + for(type = 0; type < gf_crtc->plane_cnt; type++) + { + if(gf_plane[type]) + { + gf_free(gf_plane[type]); + gf_plane[type] = NULL; + } + } + + if(gf_crtc) + { + gf_free(gf_crtc); + gf_crtc = NULL; + } + + return ret; +} + +#endif + +static int disp_output_init(disp_info_t* disp_info) +{ + unsigned int support_output = disp_info->support_output; + struct drm_connector* connector = NULL; + struct drm_encoder* encoder = NULL; + int output; + int ret = 0; + + while (support_output) + { + output = GET_LAST_BIT(support_output); + + connector = disp_connector_init(disp_info, output); + encoder = disp_encoder_init(disp_info, output); + if (connector && encoder) + { + #if DRM_VERSION_CODE >= KERNEL_VERSION(4,19,0) + drm_connector_attach_encoder(connector, encoder); + #else + drm_mode_connector_attach_encoder(connector, encoder); + #endif +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + drm_connector_register(connector); +#endif + } + else + { + ret = -ENOMEM; + } + + support_output &= (~output); + } + +#ifdef ENABLE_HDMI4_VGA_ON_IGA4 + disp_info->conflict_high = DISP_OUTPUT_DP4 & disp_info->support_output; + disp_info->conflict_low = DISP_OUTPUT_CRT & disp_info->support_output; +#endif + + return ret; +} + +static void disp_hotplug_init(disp_info_t* disp_info) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + + //at boot/resume stage, no hpd event for all output, we need poll the hpd outputs once + drm_helper_hpd_irq_event(drm); + + //enable hot plug interrupt + gf_hot_plug_intr_onoff(disp_info, 1); +} + +static void disp_polling_init(disp_info_t* disp_info) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + + INIT_DELAYED_WORK(&drm->mode_config.output_poll_work, gf_output_poll_work_func); + drm->mode_config.poll_enabled = 1; + + gf_poll_enable(disp_info); +} + +int disp_get_pipe_from_crtc(gf_file_t *priv, gf_kms_get_pipe_from_crtc_t *get) +{ + gf_card_t *gf = priv->card; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 15, 0) + struct drm_crtc *drmmode_crtc = drm_crtc_find(gf->drm_dev, get->crtc_id); +#else + struct drm_crtc *drmmode_crtc = drm_crtc_find(gf->drm_dev, (struct drm_file*)priv->parent_file, get->crtc_id); +#endif + + if (!drmmode_crtc) + return -ENOENT; + + get->pipe = to_gf_crtc(drmmode_crtc)->pipe; + + return 0; +} + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + +void gf_disp_suspend_helper(struct drm_device *dev) +{ + struct drm_crtc *crtc = NULL; + struct drm_encoder *encoder = NULL; + struct drm_connector* connector = NULL; + const struct drm_connector_funcs *conn_funcs; + const struct drm_encoder_helper_funcs *encoder_funcs; + const struct drm_crtc_helper_funcs *crtc_funcs; + bool enc_in_use, has_valid_encoder; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + { + has_valid_encoder = false; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) + { + enc_in_use = false; + + if(encoder->crtc != crtc) + { + continue; + } + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + if(connector->encoder != encoder) + { + continue; + } + + enc_in_use = true; + has_valid_encoder = true; + + conn_funcs = connector->funcs; + if(conn_funcs->dpms) + { + (*conn_funcs->dpms)(connector, DRM_MODE_DPMS_OFF); + } + } + + if(enc_in_use) + { + encoder_funcs = encoder->helper_private; + if(encoder_funcs->disable) + { + (*encoder_funcs->disable)(encoder); + } + else if(encoder_funcs->dpms) + { + (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); + } + } + } + + if(has_valid_encoder) + { + crtc_funcs = crtc->helper_private; + if(crtc_funcs->disable) + { + (*crtc_funcs->disable)(crtc); + } + else if(crtc_funcs->dpms) + { + (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF); + } + } + } +} + +#endif + +int disp_suspend(struct drm_device *dev) +{ + gf_card_t *gf = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf->disp_info; + int ret = 0; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + struct drm_atomic_state *state; +#endif + + gf_hot_plug_intr_onoff(disp_info, 0); + + gf_poll_disable(disp_info); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + state = drm_atomic_helper_suspend(dev); + ret = PTR_ERR_OR_ZERO(state); + + if (ret) + { + DRM_ERROR("Suspending crtc's failed with %i\n", ret); + } + else + { + disp_info->modeset_restore_state = state; + } +#else + gf_disp_suspend_helper(dev); +#endif + + cancel_work_sync(&disp_info->dp_irq_work); + cancel_work_sync(&disp_info->hotplug_work); + cancel_work_sync(&disp_info->hda_work); + cancel_work_sync(&disp_info->hdcp_work); + + return ret; +} + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + +void disp_vblank_save(struct drm_device* dev) +{ + struct drm_crtc* crtc; + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + { + drm_crtc_vblank_off(crtc); + } +} + +void disp_vblank_restore(struct drm_device* dev) +{ + struct drm_crtc* crtc; + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + { + drm_crtc_vblank_on(crtc); + } +} + +#endif + +void disp_pre_resume(struct drm_device *dev) +{ + gf_card_t *gf = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf->disp_info; + + disp_cbios_init_hw(disp_info); +} + +void disp_post_resume(struct drm_device *dev) +{ + gf_card_t *gf = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf->disp_info; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + struct drm_atomic_state *state = disp_info->modeset_restore_state; + struct drm_crtc_state *crtc_state; + struct drm_plane_state *plane_state; + struct drm_modeset_acquire_ctx ctx; +#endif + struct drm_crtc *crtc; + struct drm_plane *plane; + gf_plane_t *gf_plane; + int i, ret; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + disp_info->modeset_restore_state = NULL; + if (state) + { + state->acquire_ctx = &ctx; + } +#endif + + drm_mode_config_reset(dev); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + mutex_lock(&dev->mode_config.mutex); + drm_modeset_acquire_init(&ctx, 0); + + while (1) + { + ret = drm_modeset_lock_all_ctx(dev, &ctx); + if (ret != -EDEADLK) + break; + drm_modeset_backoff(&ctx); + } + + if (!ret && state) + { +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 15, 0) + for_each_crtc_in_state(state, crtc, crtc_state, i) +#else + for_each_new_crtc_in_state(state, crtc, crtc_state, i) +#endif + { + crtc_state->mode_changed = true; + } + + if (gf->flags & GF_S4_RESUME) + { +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 15, 0) + for_each_plane_in_state(state, plane, plane_state, i) +#else + for_each_new_plane_in_state(state, plane, plane_state, i) +#endif + { + if (plane_state->crtc != NULL && plane_state->fb != NULL) + { + gf_plane = to_gf_plane(plane); + gf_plane->resume_from_s4 = 1; + } + } + + gf->flags &= ~GF_S4_RESUME; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) + ret = drm_atomic_helper_commit_duplicated_state(state, &ctx); +#else + ret = drm_atomic_commit(state); +#endif + } + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + mutex_unlock(&dev->mode_config.mutex); + + if (ret){ + DRM_ERROR("Restoring old state failed with %i\n", ret); +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 10, 0) + drm_atomic_state_free(state); +#endif + } +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) + if (state) + drm_atomic_state_put(state); +#endif +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + drm_helper_resume_force_mode(dev); +#endif + + gf_poll_enable(disp_info); + + disp_probe_connector_after_resume(dev); + + gf_hot_plug_intr_onoff(disp_info, 1); +} + +static int disp_mode_config_init(disp_info_t* disp_info) +{ + gf_card_t* gf_card = disp_info->gf_card; + adapter_info_t* adapter_info = &gf_card->adapter_info; + struct drm_device* drm = gf_card->drm_dev; + + drm_mode_config_init(drm); + + drm->mode_config.min_width = 0; + drm->mode_config.min_height = 0; + + drm->mode_config.max_width = 3840*4; // 4*4k + drm->mode_config.max_height = 2160*4; + drm->mode_config.cursor_width = 64; + drm->mode_config.cursor_height = 64; + + drm->mode_config.preferred_depth = 24; + drm->mode_config.prefer_shadow = 1; + + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) + drm->mode_config.fb_modifiers_not_supported = TRUE; +#elif DRM_VERSION_CODE < KERNEL_VERSION(5, 14, 0) + drm->mode_config.allow_fb_modifiers = TRUE; +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(6, 2, 0) + drm->mode_config.fb_base = adapter_info->fb_bus_addr; +#endif + + drm->mode_config.funcs = &gf_kms_mode_funcs; + + drm->mode_config.async_page_flip = TRUE; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + drm->mode_config.helper_private = &gf_kms_mode_helper_funcs; +#endif + + return 0; +} + +static void disp_turn_off_crtc_output(disp_info_t* disp_info) +{ + unsigned int devices[MAX_CORE_CRTCS] = {0}; + unsigned int index, detect_devices = 0; + + gf_info("To turn off igas and devices.\n"); + + disp_cbios_sync_vbios(disp_info); + disp_cbios_get_active_devices(disp_info, devices); + for(index = 0; index < disp_info->num_crtc; index++) + { + detect_devices |= devices[index]; + } + disp_cbios_detect_connected_output(disp_info, detect_devices, 0); + disp_cbios_set_dpms(disp_info, detect_devices, GF_DPMS_OFF); + + for(index = 0; index < disp_info->num_crtc; index++) + { + disp_cbios_turn_onoff_screen(disp_info, index, 0); + } +} + +static void disp_info_print(disp_info_t* disp_info) +{ + adapter_info_t* adapter_info = disp_info->adp_info; + unsigned char* pmpversion = disp_info->pmp_version; + unsigned int value = 0; + int vbiosVer = 0; + int pmpdatelen = 0; + int pmptimelen = 0; + + vbiosVer = disp_info->vbios_version; + if(vbiosVer && (vbiosVer != 0xffffffff)) + { + gf_info("displayinfo Vbios Version:%02x.%02x.%02x.%02x\n", (vbiosVer>>24)&0xff,(vbiosVer>>16)&0xff,(vbiosVer>>8)&0xff,vbiosVer&0xff); + } + + if(*pmpversion) + { + // pmpVersion:str1 -> pmp version,str2 -> pmp build date,str3 -> pmp build time + pmpdatelen = gf_strlen(pmpversion) + 1; + pmptimelen = gf_strlen(pmpversion + pmpdatelen) + 1; + gf_info("displayinfo PMP Version:%s Build Time:%s %s\n",pmpversion,(pmpversion + pmpdatelen),(pmpversion + pmpdatelen + pmptimelen) ); + } + + gf_info("displayinfo Driver Version:%02x.%02x.%02x%s\n",DRIVER_MAJOR,DRIVER_MINOR,DRIVER_PATCHLEVEL,DRIVER_CLASS); + gf_info("displayinfo Driver Release Date:%s\n",DRIVER_DATE); + gf_info("displayinfo FB Size:%d M\n",adapter_info->total_mem_size_mb); + gf_info("displayinfo Chip Slice Mask:0x%x\n",adapter_info->chip_slice_mask); + gf_info("displayinfo MIU channel num:%d\n",adapter_info->chan_num); + + //becuse the Unit from cbios is KHZ,so divide 1000 to MHZ + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_CORE_CLOCK, &value)) + { + gf_info("displayinfo Coreclk:%dMHz\n",value / 1000); + } + if (DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_ENGINE_CLOCK, &value)) + { + gf_info("displayinfo Eclk:%dMHz\n", value / 1000); + } + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_VCLK, &value)) + { + gf_info("displayinfo Vclk:%dMHz\n", (value + 500)/1000); + } + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_MCLK, &value)) + { + value = gf_calc_double_standard_mclk(value); + gf_info("displayinfo Mclk:%dMHz\n", value / 2); + } +} + +static int disp_modeset_create_properties(disp_info_t *disp_info) +{ + gf_card_t *gf_card = disp_info->gf_card; + struct drm_device *drm = gf_card->drm_dev; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) + disp_info->splice_active_prop = + drm_property_create_range(drm, 0, "splice active", 0, 1); + if (!disp_info->splice_active_prop) + { + return -ENOMEM; + } + + disp_info->mode_x_prop = + drm_property_create_range(drm, 0, "splice mode x", 0, 16384); + if (!disp_info->mode_x_prop) + { + return -ENOMEM; + } + + disp_info->mode_y_prop = + drm_property_create_range(drm, 0, "splice mode y", 0, 8640); + if (!disp_info->mode_y_prop) + { + return -ENOMEM; + } + + disp_info->mode_rate_prop = + drm_property_create_range(drm, 0, "splice mode rate", 0, 12000); + if (!disp_info->mode_rate_prop) + { + return -ENOMEM; + } + + disp_info->crtc_x_prop = + drm_property_create_range(drm, 0, "splice crtc x", 0, 16384); + if (!disp_info->crtc_x_prop) + { + return -ENOMEM; + } + + disp_info->crtc_y_prop = + drm_property_create_range(drm, 0, "splice crtc y", 0, 8640); + if (!disp_info->crtc_y_prop) + { + return -ENOMEM; + } + + disp_info->crtc_w_prop = + drm_property_create_range(drm, 0, "splice crtc w", 0, 8192); + if (!disp_info->crtc_w_prop) + { + return -ENOMEM; + } + + disp_info->crtc_h_prop = + drm_property_create_range(drm, 0, "splice crtc h", 0, 4320); + if (!disp_info->crtc_h_prop) + { + return -ENOMEM; + } + + disp_info->splice_trigger_prop = + drm_property_create_range(drm, 0, "splice trigger", 0, 0xFFFF); + if (!disp_info->splice_trigger_prop) + { + return -ENOMEM; + } + +#endif + + return 0; +} + +int gf_init_modeset(struct drm_device *dev) +{ + gf_card_t* gf_card = dev->dev_private; + adapter_info_t* adapter_info = &gf_card->adapter_info; + krnl_adapter_init_info_t* a_info = &gf_card->a_info; + disp_info_t* disp_info = NULL; + unsigned int index = 0, ret = -1; + + //drm_debug = 0xffffffff; + + disp_info = gf_calloc(sizeof(disp_info_t)); + + if(!disp_info) + { + return ret; + } + + gf_card->disp_info = disp_info; + disp_info->gf_card = gf_card; + disp_info->adp_info = adapter_info; + adapter_info->init_render = 1; + + gf_core_interface->get_adapter_info(gf_card->adapter, adapter_info); + + disp_info_pre_init(disp_info); + + disp_init_cbios(disp_info); + + disp_cbios_init_hw(disp_info); + + disp_cbios_query_vbeinfo(disp_info); + + disp_cbios_get_slice_num(disp_info); + + gf_core_interface->update_adapter_info(gf_card->adapter, adapter_info, a_info); + + disp_cbios_get_crtc_resource(disp_info); + + disp_cbios_get_crtc_caps(disp_info); + + disp_turn_off_crtc_output(disp_info); + + disp_irq_init(disp_info); + + if (disp_info->num_crtc) + { + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) + //NOTE: support splice from 4.19.0 + ret = drm_vblank_init(dev, disp_info->num_crtc + 1); +#else + ret = drm_vblank_init(dev, disp_info->num_crtc); +#endif + if (ret) + { + goto err_vblk; + } + } + + disp_mode_config_init(disp_info); + + ret = disp_modeset_create_properties(disp_info); + if (ret) + { + goto err_props; + } + + for(index = 0; index < disp_info->num_crtc; index++) + { + ret = disp_crtc_init(disp_info, index); + if (ret) + { + goto err_crtc; + } + } + + disp_output_init(disp_info); + + gf_splice_manager_init(disp_info, disp_info->num_crtc); + + disp_polling_init(disp_info); + + disp_hotplug_init(disp_info); + + disp_capture_init(disp_info); + + disp_info_print(disp_info); + + return ret; + +err_props: +err_crtc: + + //drm_vblank_cleanup(dev); + + drm_mode_config_cleanup(dev); + +err_vblk: + disp_capture_deinit(disp_info); + + disp_irq_deinit(disp_info); + + disp_cbios_cleanup(disp_info); + + disp_info_deinit(disp_info); + + gf_free(disp_info); + + gf_card->disp_info = NULL; + + return ret; +} + +void gf_deinit_modeset(struct drm_device *dev) +{ + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + + if(!disp_info) + { + return; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_atomic_helper_shutdown(dev); +#endif + + disp_capture_deinit(disp_info); + + disp_irq_deinit(disp_info); + + drm_kms_helper_poll_fini(dev); + + gf_splice_manager_deinit(disp_info); + + drm_mode_config_cleanup(dev); + + disp_cbios_cleanup(disp_info); + + disp_info_deinit(disp_info); + + gf_free(disp_info); + + gf_card->disp_info = NULL; +} + +int gf_debugfs_crtc_dump(struct seq_file* file, struct drm_device* dev, int index) +{ + struct drm_crtc* crtc = NULL; + gf_crtc_t* gf_crtc = NULL; + struct drm_display_mode *mode, *hwmode; + struct drm_plane* plane = NULL; + gf_plane_t* gf_plane= NULL; + struct drm_gf_gem_object *obj = NULL; + int enabled, h, v; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + { + if(to_gf_crtc(crtc)->pipe == index) + { + gf_crtc = to_gf_crtc(crtc); + break; + } + } + + if(!gf_crtc) + { + return 0; + } + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + mutex_lock(&dev->mode_config.mutex); + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + enabled = drm_helper_crtc_in_use(crtc); + drm_modeset_unlock(&dev->mode_config.connection_mutex); + mutex_unlock(&dev->mode_config.mutex); +#else + enabled = (crtc->state->enable && crtc->state->mode_blob); +#endif + + if(!enabled) + { + seq_printf(file, "IGA status: disabled.\n"); + return 0; + } + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + mode = &crtc->mode; + hwmode = &crtc->hwmode; +#else + mode = &crtc->state->mode; + hwmode = &crtc->state->adjusted_mode; +#endif + + h = mode->hdisplay; + v = mode->vdisplay; + + seq_printf(file, "IGA status: enabled.\n"); + seq_printf(file, "SW timing: active: %d x %d. total: %d x %d. clock: %dk\n", + h, v, mode->htotal, mode->vtotal, mode->clock); + seq_printf(file, "HW timing: active: %d x %d. total: %d x %d. clock: %dk\n", + hwmode->hdisplay, hwmode->vdisplay, hwmode->htotal, hwmode->vtotal, hwmode->clock); + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + //primary +#if DRM_VERSION_CODE >= KERNEL_VERSION(3, 15, 0) + obj = (crtc->primary->fb)? to_gfb(crtc->primary->fb)->obj : NULL; +#else + obj = (crtc->fb)? to_gfb(crtc->fb)->obj : NULL; +#endif + seq_printf(file, "IGA%d-PS: src window: [%d, %d, %d, %d], dst window: [0, 0, %d, %d], handle: 0x%x, gpu vt addr: 0x%llx.\n", + (gf_crtc->pipe+1), crtc->x, crtc->y, crtc->x+h, crtc->y + v, h, v, obj->info.allocation, obj->info.gpu_virt_addr); + //overlay +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 3, 0) + drm_for_each_legacy_plane(plane, dev) +#elif DRM_VERSION_CODE >= KERNEL_VERSION(3, 15, 0) + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) +#else + list_for_each_entry(plane, &dev->mode_config.plane_list, head) +#endif + { + gf_plane = to_gf_plane(plane); + if(gf_plane->crtc_index != gf_crtc->pipe) + { + continue; + } + + if(!plane->crtc || !plane->fb) + { + seq_printf(file, "IGA%d-%s: disabled.\n", (gf_crtc->pipe+1), plane_name[gf_plane->plane_type]); + } + else + { + int src_x = gf_plane->src_pos & 0xFFFF; + int src_y = (gf_plane->src_pos >> 16) & 0xFFFF; + int src_w = gf_plane->src_size & 0xFFFF; + int src_h = (gf_plane->src_size >> 16) & 0xFFFF; + int dst_x = gf_plane->dst_pos & 0xFFFF; + int dst_y = (gf_plane->dst_pos >> 16) & 0xFFFF; + int dst_w = gf_plane->dst_size & 0xFFFF; + int dst_h = (gf_plane->dst_size >> 16) & 0xFFFF; + obj = to_gfb(plane->fb)->obj; + seq_printf(file, "IGA%d-%s: src window: [%d, %d, %d, %d], dst window: [%d, %d, %d, %d], handle: 0x%x, gpu vt addr: 0x%llx.\n", + (gf_crtc->pipe+1), plane_name[gf_plane->plane_type], src_x, src_y, src_x + src_w, src_y + src_h, + dst_x, dst_y, dst_x + dst_w, dst_y + dst_h, obj->info.allocation, obj->info.gpu_virt_addr); + } + } + //cursor + if(!gf_crtc->cursor_bo) + { + seq_printf(file, "IGA%d-cursor: disabled.\n", (gf_crtc->pipe+1)); + } + else + { + obj = gf_crtc->cursor_bo; + seq_printf(file, "IGA%d-cursor: src window: [%d, %d, %d, %d], dst window: [%d, %d, %d, %d], handle: 0x%x, gpu vt addr: 0x%llx.\n", + (gf_crtc->pipe+1), 0, 0, gf_crtc->cursor_w, gf_crtc->cursor_h, gf_crtc->cursor_x, gf_crtc->cursor_y, + gf_crtc->cursor_x + gf_crtc->cursor_w, gf_crtc->cursor_y + gf_crtc->cursor_h, obj->info.allocation, obj->info.gpu_virt_addr); + } +#else + list_for_each_entry(plane, &dev->mode_config.plane_list, head) + { + gf_plane = to_gf_plane(plane); + if(gf_plane->crtc_index != gf_crtc->pipe) + { + continue; + } + + if(!gf_plane->base_plane.state->crtc || ! gf_plane->base_plane.state->fb) + { + seq_printf(file, "%s: disabled.\n", gf_plane->base_plane.name); + } + else + { + int src_x = gf_plane->base_plane.state->src_x >> 16; + int src_y = gf_plane->base_plane.state->src_y >> 16; + int src_w = gf_plane->base_plane.state->src_w >> 16; + int src_h = gf_plane->base_plane.state->src_h >> 16; + int dst_x = gf_plane->base_plane.state->crtc_x; + int dst_y = gf_plane->base_plane.state->crtc_y; + int dst_w = gf_plane->base_plane.state->crtc_w; + int dst_h = gf_plane->base_plane.state->crtc_h; + obj = to_gfb(gf_plane->base_plane.state->fb)->obj; + seq_printf(file, "%s: src window: [%d, %d, %d, %d], dst window: [%d, %d, %d, %d], handle: 0x%x, gpu vt addr: 0x%llx.\n", + gf_plane->base_plane.name, src_x, src_y, src_x + src_w, src_y + src_h, + dst_x, dst_y, dst_x + dst_w, dst_y + dst_h, obj->info.allocation, obj->info.gpu_virt_addr); + } + } +#endif + + return 0; +} + +int gf_debugfs_clock_dump(struct seq_file* file, struct drm_device* dev) +{ + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + unsigned int value = 0; + + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_ENGINE_CLOCK, &value)) + { + seq_printf(file, "Engine clock = %dMHz.\n", value/1000); + } + + return 0; +} + +void gf_chip_fan_init_legacy(void* dispi, int index) +{ + disp_info_t* disp_info = (disp_info_t*)dispi; + adapter_info_t* adp_info = disp_info->adp_info; + int ctrl_reg_8x000, ctrl_reg_8x00c, ctrl_reg_8x014; + unsigned int *pRegAddr_8x000,*pRegAddr_8x00c,*pRegAddr_8x014; + int fanbase; + + if(adp_info->mmio_size < 0x8F024) + { + gf_info("Can't access temper sense register range from 0x8F000 to 0x8F024!\n"); + return; + } + + if(index == 1) + { + fanbase = 0x8c000; + } + else if(index == 0) + { + fanbase = 0x8d000; + } + else + { + return; + } + + pRegAddr_8x000 = (unsigned int*)(adp_info->mmio + fanbase + 0x000); + pRegAddr_8x00c = (unsigned int*)(adp_info->mmio + fanbase + 0x00c); + pRegAddr_8x014 = (unsigned int*)(adp_info->mmio + fanbase + 0x014); + + ctrl_reg_8x00c = gf_read32(pRegAddr_8x00c); + ctrl_reg_8x00c |= 0x3; + gf_write32(pRegAddr_8x00c, ctrl_reg_8x00c); + + ctrl_reg_8x014 = 0x7D00; + gf_write32(pRegAddr_8x014, ctrl_reg_8x014); + + ctrl_reg_8x000 = gf_read32(pRegAddr_8x000); + ctrl_reg_8x000 |= 0x3; + gf_write32(pRegAddr_8x000, ctrl_reg_8x000); + + return; +} + +int gf_get_chip_fanspeed(void* dispi, int index) +{ + disp_info_t* disp_info = (disp_info_t*)dispi; + adapter_info_t* adp_info = disp_info->adp_info; + unsigned int fan_duty = 0; + int val; + + val = gf_read32(adp_info->mmio + 0xd001c) - 0x10; + if (val < 0) + fan_duty = 0; + else + fan_duty = ((val & 0x0f) / 2 * 10 + 84 + (val >> 4) * 8 * 10) / 10; + + return fan_duty; +} + +int gf_get_chip_fanspeed_legacy(void* dispi, int index) +{ + static int fanspeed = 0,pwm = 0; + disp_info_t* disp_info = (disp_info_t*)dispi; + adapter_info_t* adp_info = disp_info->adp_info; + int ctrl_reg_8x000, ctrl_reg_8x008, ctrl_reg_8x014, out_8x01c; + unsigned int *pRegAddr_8x000, *pRegAddr_8x004, *pRegAddr_8x008, *pRegAddr_8x00c, *pRegAddr_8x014, *pRegAddr_8x01c, *pRegAddr_d00xc; + int temp = 0, fanbase = 0, pwmoffset = 0; + + if(adp_info->mmio_size < 0x8F024) + { + gf_info("Can't access temper sense register range from 0x8F000 to 0x8F024!\n"); + return -1; + } + + if(index == 1) + { + fanspeed = gf_read32(adp_info->mmio + 0xd3dc); + if (fanspeed) + return fanspeed; + + fanbase = 0x8c000; + pwmoffset = 0x10; + } + else if(index == 0) + { + fanbase = 0x8d000; + pwmoffset = 0x0; + } + else + { + return -1; + } + + pRegAddr_8x000 = (unsigned int*)(adp_info->mmio + fanbase + 0x000); + pRegAddr_8x004 = (unsigned int*)(adp_info->mmio + fanbase + 0x004); + pRegAddr_8x008 = (unsigned int*)(adp_info->mmio + fanbase + 0x008); + pRegAddr_8x00c = (unsigned int*)(adp_info->mmio + fanbase + 0x00c); + pRegAddr_8x014 = (unsigned int*)(adp_info->mmio + fanbase + 0x014); + pRegAddr_8x01c = (unsigned int*)(adp_info->mmio + fanbase + 0x01c); + pRegAddr_d00xc = (unsigned int*)(adp_info->mmio + pwmoffset + 0xd0000 + 0x0c); + + if((gf_read32(pRegAddr_8x004) & 0x2) != 0) + { + out_8x01c = gf_read32(pRegAddr_8x01c); + if(out_8x01c != 0) + { + temp = 16000 * 60; + temp = (unsigned int)(temp / out_8x01c); + fanspeed = temp; + } + else + { + fanspeed = -1; + } + } + else + { + ctrl_reg_8x014 = 0x0; + gf_write32(pRegAddr_8x014, ctrl_reg_8x014); + + fanspeed = -1; + } + + pwm = gf_read32(pRegAddr_d00xc) & 0xfff; + + ctrl_reg_8x014 = 0x7D00; + gf_write32(pRegAddr_8x014, ctrl_reg_8x014); + + ctrl_reg_8x008 = gf_read32(pRegAddr_8x008); + ctrl_reg_8x008 |= 0x3; + gf_write32(pRegAddr_8x008, ctrl_reg_8x008); + + ctrl_reg_8x000 = gf_read32(pRegAddr_8x000); + ctrl_reg_8x000 |= 0x3; + gf_write32(pRegAddr_8x000, ctrl_reg_8x000); + return fanspeed; +} + +int gf_get_chip_temp(void *dispi) +{ + disp_info_t* disp_info = (disp_info_t*)dispi; + adapter_info_t* adp_info = disp_info->adp_info; + int val, temper, temper_1, temper_2; + + val = gf_read32(adp_info->mmio + 0xD3F4); + if (!val) + return val; + + temper_1 = -9 * val * val / 100; + temper_2 = 2754 * val / 10; + + temper = temper_1 + temper_2 - 44596; + temper /= 1000; + + return temper; +} + +int gf_get_chip_temp_legacy(void *dispi) +{ + disp_info_t* disp_info = (disp_info_t*)dispi; + adapter_info_t* adp_info = disp_info->adp_info; + int ctrl_reg_8f018, irq_en_8f008, irq_status_8f004, irq_clr_8f00c, out_8f020; + int temper; + + temper = gf_read32(adp_info->mmio + 0xD3D4); + if (temper) + return temper; + + if(adp_info->mmio_size < 0x8F024) + { + gf_info("Can't access temper sense register range from 0x8F000 to 0x8F024!\n"); + return 0; + } + + ctrl_reg_8f018 = gf_read32(adp_info->mmio + 0x8F018); + ctrl_reg_8f018 &= 0xFFFFF3FF; + gf_write32(adp_info->mmio + 0x8F018, ctrl_reg_8f018); + ctrl_reg_8f018 = gf_read32(adp_info->mmio + 0x8F018); + ctrl_reg_8f018 |= 0x400; + gf_write32(adp_info->mmio + 0x8F018, ctrl_reg_8f018); + + irq_en_8f008 = gf_read32(adp_info->mmio + 0x8F008); + irq_en_8f008 |= 0x80; + gf_write32(adp_info->mmio + 0x8F008, irq_en_8f008); + + irq_status_8f004 = gf_read32(adp_info->mmio + 0x8F004); + irq_status_8f004 |= 0x80; + gf_write32(adp_info->mmio + 0x8F004, irq_status_8f004); + + while((gf_read32(adp_info->mmio + 0x8F004) & 0x80) == 0); + + irq_clr_8f00c = gf_read32(adp_info->mmio + 0x8F00C); + irq_clr_8f00c |= 0x80; + gf_write32(adp_info->mmio + 0x8F00C, irq_clr_8f00c); + + out_8f020 = gf_read32(adp_info->mmio + 0x8F020); + out_8f020 &= 0x3FF; + + temper = (27540 - 9 * out_8f020) * out_8f020; + temper = (int)gf_do_div(temper, 100); + temper -= 44596; + temper = (int)gf_do_div(temper, 1000); + + return temper; +} + +unsigned int gf_calc_double_standard_mclk(unsigned int mclk) +{ + unsigned int mclk_standard_freq[] = {2133, 2400, 2666, 2933, 3200}; + unsigned int n, min, freq; + + mclk = 2 * ((mclk + 500) / 1000); + min = 0xffffffff; + + for (n = 0; n < sizeof(mclk_standard_freq) / sizeof(mclk_standard_freq[0]); n++) + { + if (mclk > mclk_standard_freq[n]) + freq = mclk - mclk_standard_freq[n]; + else + freq = mclk_standard_freq[n] - mclk; + + if (min >= freq) + min = freq; + else + break; + } + + return mclk_standard_freq[n - 1]; +} + +int gf_debugfs_displayinfo_dump(struct seq_file* file, struct drm_device* dev) +{ + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + adapter_info_t* adapter_info = &gf_card->adapter_info; + unsigned char* pmpversion = disp_info->pmp_version; + unsigned char* fwname = disp_info->firmware_name; + unsigned int value = 0; + int vbiosVer = 0; + int pmpdatelen = 0; + int pmptimelen = 0; + int fwVer = disp_info->firmware_version; + + vbiosVer = disp_info->vbios_version; + if(vbiosVer && (vbiosVer != 0xffffffff)) + { + seq_printf(file, "Vbios Version:%02x.%02x.%02x.%02x\n", (vbiosVer>>24)&0xff,(vbiosVer>>16)&0xff,(vbiosVer>>8)&0xff,vbiosVer&0xff); + } + + if(*pmpversion) + { + // pmpVersion:str1 -> pmp version,str2 -> pmp build date,str3 -> pmp build time + pmpdatelen = gf_strlen(pmpversion) + 1; + pmptimelen = gf_strlen(pmpversion + pmpdatelen) + 1; + seq_printf(file, "PMP Version:%s Build Time:%s %s\n",pmpversion,(pmpversion + pmpdatelen),(pmpversion + pmpdatelen + pmptimelen) ); + } + + if(*fwname) + { + seq_printf(file, "Firmware Version:%02x.%02x.%02x.%02x\n", (fwVer>>24)&0xff,(fwVer>>16)&0xff,(fwVer>>8)&0xff,fwVer&0xff); + seq_printf(file, "Firmware Name:%s\n", fwname); + } + + seq_printf(file,"Driver Version:%02x.%02x.%02x%s\n",DRIVER_MAJOR,DRIVER_MINOR,DRIVER_PATCHLEVEL,DRIVER_CLASS); + seq_printf(file,"Driver Release Date:%s\n",DRIVER_DATE); + seq_printf(file,"FB Size:%d M\n",adapter_info->total_mem_size_mb); + seq_printf(file,"Chip Slice Mask:0x%x\n",adapter_info->chip_slice_mask); + seq_printf(file,"MIU channel num:%d\n",adapter_info->chan_num); + + //becuse the Unit from cbios is KHZ,so divide 1000 to MHZ + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_CORE_CLOCK, &value)) + { + seq_printf(file, "Coreclk:%dMHz\n",value / 1000); + } + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_ENGINE_CLOCK, &value)) + { + seq_printf(file, "Eclk:%dMHz\n", value / 1000); + } + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_VCLK, &value)) + { + seq_printf(file, "Vclk:%dMHz\n", (value + 500)/1000); + } + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_MCLK, &value)) + { + value = gf_calc_double_standard_mclk(value); + seq_printf(file, "Mclk:%dMHz\n", value / 2); + } + + seq_printf(file, "Temper: %d degree\n", gf_get_chip_temp(gf_card->disp_info)); + + return 0; +} + diff --git a/drivers/gpu/drm/arise/linux/gf_disp.h b/drivers/gpu/drm/arise/linux/gf_disp.h new file mode 100644 index 0000000000000..80999f75fbc97 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_disp.h @@ -0,0 +1,400 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _GF_DISP_H +#define _GF_DISP_H + +#include "gf_kms.h" +#include "gf_driver.h" +#if DRM_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#include +#endif + +/* same to CBIOS_REGISTER_TYPE */ +enum +{ + /* CR_SET = 0, //CR registers to be set, used in s3postreg */ + /* SR_SET, //SR registers to be set */ + /* GR_SET, //GR registers to be set */ + CR=0, /*CR registers */ + SR, /*SR registers */ + AR, + GR, + MISC, + CR_X, + SR_X, + CR_B, /* B-set of CR */ + CR_C, /* C-set of CR */ + CR_D, /* D-set of CR */ + CR_T, /* CR on IGA3 */ + SR_T, /* SR on IGA3 */ + SR_B, + CR_D_0, + CR_D_1, + CR_D_2, + CR_D_3, + RESERVED=0xFF +}; + +enum +{ + DP_HPD_NONE = 0, + DP_HPD_IN, + DP_HPD_HDMI_OUT, + DP_HPD_DP_OUT, + DP_HPD_IRQ, +}; + +#define GET_LAST_BIT(N) ((~((N)-1))&(N)) + +//interrupt bit used by SW, it's irrelevant to HW register define, DO NOT set them to register directly +#define INT_VSYNC1 (1 << 0) +#define INT_VSYNC2 (1 << 1) +#define INT_VSYNC3 (1 << 2) +#define INT_VSYNC4 (1 << 3) +#define INT_VSYNCS (INT_VSYNC1 | INT_VSYNC2 | INT_VSYNC3 | INT_VSYNC4) + +#define INT_DP1 (1 << 4) +#define INT_DP2 (1 << 5) +#define INT_DP3 (1 << 6) +#define INT_DP4 (1 << 7) +#define INT_HOTPLUG (INT_DP1 | INT_DP2 | INT_DP3 | INT_DP4) + +#define INT_VIP1 (1 << 8) +#define INT_VIP2 (1 << 9) +#define INT_VIP3 (1 << 10) +#define INT_VIP4 (1 << 11) +#define INT_VIPS (INT_VIP1 | INT_VIP2 | INT_VIP3 | INT_VIP4) + +#define INT_HDCODEC (1 << 12) + +#define INT_FENCE (1 << 13) +#define INT_FE_HANG_VD0 (1 << 14) +#define INT_BE_HANG_VD0 (1 << 15) +#define INT_FE_ERROR_VD0 (1 << 16) +#define INT_BE_ERROR_VD0 (1 << 17) +#define INT_FE_HANG_VD1 (1 << 18) +#define INT_BE_HANG_VD1 (1 << 19) +#define INT_FE_ERROR_VD1 (1 << 20) +#define INT_BE_ERROR_VD1 (1 << 21) +#define INT_VIDEO_EVENTS (INT_FE_HANG_VD0 | INT_BE_HANG_VD0 | INT_FE_ERROR_VD0 | INT_BE_ERROR_VD0 | INT_FE_HANG_VD1 | INT_BE_HANG_VD1 | INT_FE_ERROR_VD1 | INT_BE_ERROR_VD1) + +#define INT_HDCP (1 << 22) + +//default interrupt to be enabled at irq install, vsync and hotplug intr is controlled by independent module +#define DEF_INTR (INT_VIDEO_EVENTS | INT_FENCE | INT_HDCODEC | INT_VIPS | INT_HDCP) + +#define AR_INIT_REG 0x83DA +#define AR_INDEX 0x83C0 +#define AR_DATA 0x83C1 +#define CR_INDEX 0x83D4 +#define CR_DATA 0x83D5 +#define SR_INDEX 0x83C4 +#define SR_DATA 0x83C5 + +//mmioOffset of registers +#define MMIO_OFFSET_SR_GROUP_A_EXC 0x8600 +#define MMIO_OFFSET_SR_GROUP_B_EXC 0x8700 +#define MMIO_OFFSET_CR_GROUP_A_EXC 0x8800 +#define MMIO_OFFSET_CR_GROUP_B_EXC 0x8900 +#define MMIO_OFFSET_CR_GROUP_C_EXC 0x8A00 +#define MMIO_OFFSET_CR_GROUP_D_EXC 0x8B00 // for 4-channel MIU CR_D registers +#define MMIO_OFFSET_CR_GROUP_D0_EXC 0x8C00 // MIU channel 0 CR_D registers +#define MMIO_OFFSET_CR_GROUP_D1_EXC 0x8D00 // MIU channel 1 CR_D registers +#define MMIO_OFFSET_CR_GROUP_D2_EXC 0x8E00 // MIU channel 2 CR_D registers +#define MMIO_OFFSET_CR_GROUP_D3_EXC 0x8F00 // MIU channel 3 CR_D registers +#define MMIO_OFFSET_SR_GROUP_T_EXC 0x9400 +#define MMIO_OFFSET_CR_GROUP_T_EXC 0x9500 + +// H/V sync Polarity +#define HOR_NEGATIVE 0x40 +#define HOR_POSITIVE 0x00 +#define VER_NEGATIVE 0x80 +#define VER_POSITIVE 0x00 + +#define DISP_OK 0 +#define DISP_FAIL (-1) + +#ifndef gf_mb +#if defined(__i386__) || defined(__x86_64__) +#define gf_mb() asm volatile("mfence":::"memory") +#define gf_rmb() asm volatile("lfence":::"memory") +#define gf_wmb() asm volatile("sfence":::"memory") +#define gf_flush_wc() gf_wmb() +#else +#define gf_mb() +#define gf_rmb() +#define gf_wmb() +#define gf_flush_wc() +#endif +#endif + +#define GF_DPMS_OFF 4 +#define GF_DPMS_ON 0 + +#define ENABLE_HDMI4_VGA_ON_IGA4 1 + +typedef enum +{ + DISP_OUTPUT_NONE = 0x00, + DISP_OUTPUT_CRT = 0x01, + DISP_OUTPUT_DP1 = 0x8000, + DISP_OUTPUT_DP2 = 0x10000, + DISP_OUTPUT_DP3 = 0x20000, + DISP_OUTPUT_DP4 = 0x40000, + DISP_OUTPUT_SPLICE = 0x80000, +}disp_output_type; + + +#define DISP_OUTPUT_DP_TYPES (DISP_OUTPUT_DP1| DISP_OUTPUT_DP2|DISP_OUTPUT_DP3|DISP_OUTPUT_DP4) + + +typedef struct +{ + int device; + int int_type; +}DP_EVENT, *PDP_EVENT; + +#define MAX_DP_EVENT_NUM 64 +#define MAX_I2CBUS 5 + +typedef enum +{ + GF_I2C_DDCCI, + GF_I2C_HDCP, + GF_I2C_ERR_TYPE, +}gf_i2c_type_t; +typedef enum +{ + GF_I2C_READ, + GF_I2C_WRITE, +}gf_i2c_op_t; +typedef struct +{ + bool use_dev_type; + unsigned int device_id; + unsigned char port; + unsigned char slave_addr; + unsigned char offset; + unsigned char *buf; + unsigned int buf_len; + unsigned int request_type; + int use_hdcp; + gf_i2c_op_t op; +}gf_i2c_param_t; + +typedef struct +{ + void *rom_image; + void *cbios_ext; + struct os_spinlock *cbios_inner_spin_lock; + struct os_mutex *cbios_aux_mutex; + struct os_mutex *cbios_i2c_mutex[MAX_I2CBUS]; + struct os_mutex *cbios_lock; //protect cbios reentry. + void* gf_card; + adapter_info_t* adp_info; + + unsigned int num_crtc; + unsigned int num_output; + unsigned int num_plane[MAX_CORE_CRTCS]; + unsigned int scale_support; //support panel up scale + unsigned int up_scale_plane_mask[MAX_CORE_CRTCS]; //stream mask for each crtc + unsigned int down_scale_plane_mask[MAX_CORE_CRTCS]; + + unsigned int support_output; + unsigned int output_id_masks; + unsigned int active_output[MAX_CORE_CRTCS]; + + void* irq_chip_func; + unsigned int intr_en_bits; + unsigned int force_output; //outputs that have no hpd intr and can't be detected, like hdtv, tv + unsigned int supp_polling_outputs; //outputs that have no hpd intr, but still can be detected, such as CRT + unsigned int supp_hpd_outputs; + unsigned int hpd_outputs; + unsigned int compare_edid_outputs; + unsigned int hda_intr_outputs; + unsigned int hdcp_intr_outputs; +#ifdef ENABLE_HDMI4_VGA_ON_IGA4 + disp_output_type conflict_high; + disp_output_type conflict_low; +#endif + struct os_spinlock *intr_lock; + struct os_spinlock *hpd_lock; + struct os_spinlock *hda_lock; + struct os_spinlock *hdcp_lock; + int irq_enabled; + int poll_running; + atomic_t atomic_irq_lock; + struct work_struct hotplug_work; + struct work_struct dp_irq_work; + struct work_struct hda_work; + struct work_struct hdcp_work; + struct + { + unsigned int head; + unsigned int tail; + DP_EVENT event[MAX_DP_EVENT_NUM]; + }; + + void *modeset_restore_state; + + int vbios_version; + int vbios_revision; + unsigned char pmp_version[64]; // PMP info,include version and build time + int firmware_version; + unsigned char firmware_name[10]; + + struct gf_capture_type *captures; + struct gf_splice_manager *splice_manager; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + struct drm_property *primary_card_prop; + struct drm_property *global_id_proph; + struct drm_property *global_id_propl; +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) + struct drm_property *splice_trigger_prop; + struct drm_property *splice_active_prop; + struct drm_property *mode_x_prop; + struct drm_property *mode_y_prop; + struct drm_property *mode_rate_prop; + struct drm_property *crtc_x_prop; + struct drm_property *crtc_y_prop; + struct drm_property *crtc_w_prop; + struct drm_property *crtc_h_prop; +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35) + struct workqueue_struct *wq; +#endif + +}disp_info_t; + +static __inline__ unsigned char read_reg_exc(unsigned char *mmio, int type, unsigned char index) +{ + unsigned int offset = 0; + unsigned char temp = 0; + + switch(type) + { + case CR: + offset = MMIO_OFFSET_CR_GROUP_A_EXC + index; + break; + case CR_B: + offset = MMIO_OFFSET_CR_GROUP_B_EXC + index; + break; + case CR_C: + offset = MMIO_OFFSET_CR_GROUP_C_EXC + index; + break; + case SR: + offset = MMIO_OFFSET_SR_GROUP_A_EXC + index; + break; + case SR_B: + offset = MMIO_OFFSET_SR_GROUP_B_EXC + index; + break; + case AR: + gf_read8(mmio + AR_INIT_REG); + gf_write8(mmio + AR_INDEX, index); + temp = gf_read8(mmio + AR_DATA); + return temp; + default: + gf_assert(0, GF_FUNC_NAME(__func__)); + break; + } + + temp = gf_read8(mmio + offset); + + return temp; +} + +static __inline__ void write_reg_exc(unsigned char *mmio, int type, unsigned char index, unsigned char value, unsigned char mask) +{ + unsigned int offset = 0; + unsigned char temp = 0; + + switch(type) + { + case CR: + offset = MMIO_OFFSET_CR_GROUP_A_EXC + index; + break; + case CR_B: + offset = MMIO_OFFSET_CR_GROUP_B_EXC + index; + break; + case CR_C: + offset = MMIO_OFFSET_CR_GROUP_C_EXC + index; + break; + case SR: + offset = MMIO_OFFSET_SR_GROUP_A_EXC + index; + break; + case SR_B: + offset = MMIO_OFFSET_SR_GROUP_B_EXC + index; + break; + case SR_T: + offset = MMIO_OFFSET_SR_GROUP_T_EXC + index; + break; + case CR_T: + offset = MMIO_OFFSET_CR_GROUP_T_EXC + index; + break; + default: + gf_assert(0, GF_FUNC_NAME(__func__)); + break; + } + + temp = gf_read8(mmio + offset); + temp = (temp & mask) | (value & ~mask); + + gf_write8(mmio + offset, temp); +} + +void disp_irq_init(disp_info_t* disp_info); +void disp_irq_deinit(disp_info_t* disp_info); +void disp_irq_install(disp_info_t* disp_info); +void disp_irq_uninstall(disp_info_t* disp_info); +struct drm_connector* disp_connector_init(disp_info_t* disp_info, disp_output_type output); +struct drm_encoder* disp_encoder_init(disp_info_t* disp_info, disp_output_type output); +int disp_get_pipe_from_crtc(gf_file_t *priv, gf_kms_get_pipe_from_crtc_t *get); +int disp_suspend(struct drm_device *dev); + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) +void disp_vblank_save(struct drm_device* dev); +void disp_vblank_restore(struct drm_device* dev); +void gf_disp_suspend_helper(struct drm_device *dev); +#endif + +void disp_pre_resume(struct drm_device *dev); +void disp_post_resume(struct drm_device *dev); +void gf_encoder_disable(struct drm_encoder *encoder); +void gf_encoder_enable(struct drm_encoder *encoder); + +bool gf_encoder_mode_fixup_internal(disp_info_t* disp_info, int output_type, + const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); + +int disp_cbios_get_clock(disp_info_t *disp_info, unsigned int type, unsigned int *output); + +enum drm_connector_status +gf_connector_detect_internal(struct drm_connector *connector, bool force, int full_detect); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) +void gf_restore_drm_connector_state(struct drm_device *dev, struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx); +#endif + +void disp_probe_connector_after_resume(struct drm_device *dev); + +void disp_create_plane_property(struct drm_device* dev, gf_plane_t* gf_plane); + +gf_connector_t* gf_get_connector_by_device_id(disp_info_t *disp_info, int device_id); + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_driver.c b/drivers/gpu/drm/arise/linux/gf_driver.c new file mode 100644 index 0000000000000..fe9d0c1fca736 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_driver.c @@ -0,0 +1,1117 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "os_interface.h" +#include "gf_driver.h" +#include "gf_ioctl.h" +#include "gf_debugfs.h" +#include "gf_fence.h" +#include "gf_irq.h" +#include "gf_fbdev.h" +#include "gf_params.h" + + +extern int gf_run_on_qt; +extern const struct attribute *gf_os_gpu_info; +extern const struct attribute_group gf_sysfs_group; +extern struct bin_attribute gf_sysfs_trace_attr; + +static int gf_init_procfs_entry(gf_card_t *gf); +static int gf_deinit_procfs_entry(gf_card_t *gf); + +pgprot_t os_get_pgprot_val(unsigned int *cache_type, pgprot_t old_prot, int io_map) +{ + pgprot_t prot = old_prot; + + if(*cache_type == GF_MEM_UNCACHED) + { + prot = pgprot_noncached(old_prot); + } + else if(*cache_type == GF_MEM_WRITE_COMBINED) + { +#ifdef CONFIG_X86 +#ifdef CONFIG_X86_PAT +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0) + prot = __pgprot((pgprot_val(old_prot) & ~ _PAGE_CACHE_MASK) | cachemode2protval(_PAGE_CACHE_MODE_WC)); +#else + prot = __pgprot((pgprot_val(old_prot) & ~ _PAGE_CACHE_MASK) | _PAGE_CACHE_WC); +#endif +#else + prot = pgprot_noncached(old_prot); + + *cache_type = GF_MEM_UNCACHED; +#endif +#else + prot = pgprot_writecombine(old_prot); +#endif + + } +#ifdef GF_AHB_BUS + else if(*cache_type == GF_MEM_WRITE_BACK) + { + // for snoop path, current linux kennel defalut is not WA+WB + prot = __pgprot((pgprot_val(old_prot)&(~(L_PTE_MT_MASK))) | (L_PTE_MT_WRITEBACK | L_PTE_MT_WRITEALLOC)); + } +#endif + return prot; +} + +#ifndef __frv__ +int gf_map_system_io(struct vm_area_struct* vma, gf_map_argu_t *map) +{ + unsigned int cache_type = map->flags.cache_type; +#if LINUX_VERSION_CODE >= 0x020612 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); +#endif + vma->vm_page_prot = os_get_pgprot_val(&cache_type, vma->vm_page_prot, 1); + + map->flags.cache_type = cache_type; + + if (remap_pfn_range(vma, vma->vm_start, + vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) + { + return -EAGAIN; + } + + return 0; +} +#if 1 +int gf_map_system_ram(struct vm_area_struct* vma, gf_map_argu_t *map) +{ + struct os_pages_memory *memory = map->memory; + unsigned long start = vma->vm_start; + unsigned long pfn; + unsigned int cache_type; + + int i; + int start_page = _ALIGN_DOWN(map->offset, PAGE_SIZE) / PAGE_SIZE; + int end_page = start_page + PAGE_ALIGN(map->size) / PAGE_SIZE; + +#if LINUX_VERSION_CODE <= 0x02040e + vma->vm_flags |= VM_LOCKED; +#elif LINUX_VERSION_CODE < 0x030700 + vma->vm_flags |= VM_RESERVED; +#else +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,3,0) + vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; +#else + vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP); +#endif +#endif + + cache_type = map->flags.cache_type; + +#if LINUX_VERSION_CODE >= 0x020612 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); +#endif + vma->vm_page_prot = os_get_pgprot_val(&cache_type, vma->vm_page_prot, 0); + for (i = start_page; i < end_page; i++) + { + struct page *pg = memory->pages[i]; + pfn = page_to_pfn(pg); + if(remap_pfn_range(vma, start, pfn, PAGE_SIZE, vma->vm_page_prot)) + { + return -EAGAIN; + } + start += PAGE_SIZE; + } + + return 0; +} +#endif +#endif + +static int gf_notify_fence_interrupt(gf_card_t *gf) +{ + return gf_core_interface->notify_interrupt(gf->adapter, INT_FENCE); +} + +void gf_interrupt_init(gf_card_t *gf) +{ + tasklet_init(&gf->fence_notify, (void*)gf_notify_fence_interrupt, (unsigned long)gf); + tasklet_disable(&gf->fence_notify); + tasklet_enable(&gf->fence_notify); +} + +void gf_interrupt_reinit(gf_card_t *gf) +{ + tasklet_enable(&gf->fence_notify); +} + +void gf_interrupt_deinit(gf_card_t *gf) +{ + tasklet_disable(&gf->fence_notify); + synchronize_irq(to_pci_dev(gf->drm_dev->dev)->irq); + tasklet_kill(&gf->fence_notify); +} + +void gf_enable_interrupt(void *pdev_) +{ + struct pci_dev *pdev = pdev_; + struct drm_device *dev = pci_get_drvdata(pdev); + gf_card_t *gf = dev->dev_private; + + gf_disp_enable_interrupt(gf->disp_info, 0); +} + +void gf_disable_interrupt(void *pdev_) +{ + struct pci_dev *pdev = pdev_; + struct drm_device *dev = pci_get_drvdata(pdev); + gf_card_t *gf = dev->dev_private; + + gf_disp_disable_interrupt(gf->disp_info, 0); +} + +static void gf_disable_async_suspend(gf_card_t *gf) +{ + struct pci_dev *pdev = gf->pdev; + struct pci_dev *pdev_audio = NULL; + unsigned int devfn_audio; + + pdev->dev.power.async_suspend = 0; + + devfn_audio = PCI_DEVFN(PCI_SLOT(pdev->devfn), 1); + pdev_audio = pci_get_slot(pdev->bus, devfn_audio); + + if(pdev_audio) + { + gf_info("found audio device, devfn = 0x%x \n", pdev_audio->devfn); + pdev_audio->dev.power.async_suspend = 0; + } + else + { + gf_error("Can't find audio device.\n"); + } + +} + +static void gf_allocate_trace_buffer(gf_card_t *gf) +{ + alloc_pages_flags_t alloc_flags = {0}; + gf_map_argu_t map_argu = {0}; + int i; + unsigned int page_cnt; + + alloc_flags.fixed_page = 1; + alloc_flags.need_dma_map = 0; + alloc_flags.need_zero = 1; + alloc_flags.need_flush = 1; + gf->trace_buffer = gf_allocate_pages_memory_priv(gf->pdev, PAGE_SIZE, PAGE_SIZE, alloc_flags); + if (!gf->trace_buffer) + { + gf->trace_buffer_vma = NULL; + return; + } + + map_argu.memory = gf->trace_buffer; + map_argu.flags.mem_space = GF_MEM_KERNEL; + map_argu.flags.read_only = false; + map_argu.flags.mem_type = GF_SYSTEM_RAM; + map_argu.size = gf->trace_buffer->size; + map_argu.offset = 0; + map_argu.flags.cache_type = GF_MEM_WRITE_BACK; + gf->trace_buffer_vma = gf_map_pages_memory_priv(NULL, &map_argu); + + // gf_info("gf_allocate_trace_buffer: trace_buffer_vma->virt_addr=%px, pfn=0x%x\n", + // gf->trace_buffer_vma->virt_addr, page_to_pfn(gf->trace_buffer->pages[0])); +} + +static void gf_free_trace_buffer(gf_card_t *gf) +{ + if (gf->trace_buffer_vma) + { + gf_unmap_pages_memory_priv(gf->trace_buffer_vma); + gf->trace_buffer_vma = NULL; + } + if (gf->trace_buffer) + { + gf_free_pages_memory_priv(gf->pdev, gf->trace_buffer); + gf->trace_buffer = NULL; + } +} + +static krnl_import_func_list_t gf_export = +{ + .udelay = gf_udelay, + .do_div = gf_do_div, + .msleep = gf_msleep, + .getsecs = gf_getsecs, + .get_nsecs = gf_get_nsecs, + .assert = gf_assert, + .dump_stack = gf_dump_stack, + .copy_from_user = gf_copy_from_user, + .copy_to_user = gf_copy_to_user, + .memset = gf_memset, + .memcpy = gf_memcpy, + .memcmp_priv = gf_memcmp, + .byte_copy = gf_byte_copy, + .strcmp = gf_strcmp, + .strcpy = gf_strcpy, + .strncmp = gf_strncmp, + .strncpy = gf_strncpy, + .strlen = gf_strlen, + .read64 = gf_read64, + .read32 = gf_read32, + .read16 = gf_read16, + .read8 = gf_read8, + .write32 = gf_write32, + .write16 = gf_write16, + .write8 = gf_write8, + .file_open = gf_file_open, + .file_close = gf_file_close, + .file_read = gf_file_read, + .file_write = gf_file_write, + .vsprintf = gf_vsprintf, + .vsnprintf = gf_vsnprintf, + .sscanf = gf_sscanf, + .printk = gf_printk, + .cb_printk = gf_cb_printk, + .seq_printf = gf_seq_printf, + .find_first_zero_bit = gf_find_first_zero_bit, + .find_next_zero_bit = gf_find_next_zero_bit, + .set_bit = gf_set_bit, + .clear_bit = gf_clear_bit, + .create_thread = gf_create_thread, + .destroy_thread = gf_destroy_thread, + .thread_should_stop = gf_thread_should_stop, + .create_atomic = gf_create_atomic, + .destroy_atomic = gf_destroy_atomic, + .atomic_read = gf_atomic_read, + .atomic_inc = gf_atomic_inc, + .atomic_dec = gf_atomic_dec, + .atomic_add = gf_atomic_add, + .atomic_sub = gf_atomic_sub, + .create_mutex = gf_create_mutex, + .destroy_mutex = gf_destroy_mutex, + .mutex_lock = gf_mutex_lock, + .mutex_lock_killable = gf_mutex_lock_killable, + .mutex_trylock = gf_mutex_trylock, + .mutex_unlock = gf_mutex_unlock, + .create_sema = gf_create_sema, + .destroy_sema = gf_destroy_sema, + .down = gf_down, + .down_trylock = gf_down_trylock, + .up = gf_up, + .create_rwsema = gf_create_rwsema, + .destroy_rwsema = gf_destroy_rwsema, + .down_read = gf_down_read, + .down_write = gf_down_write, + .up_read = gf_up_read, + .up_write = gf_up_write, + .create_spinlock = gf_create_spinlock, + .destroy_spinlock = gf_destroy_spinlock, + .spin_lock = gf_spin_lock, + .spin_try_lock = gf_spin_try_lock, + .spin_unlock = gf_spin_unlock, + .spin_lock_irqsave = gf_spin_lock_irqsave, + .spin_unlock_irqrestore = gf_spin_unlock_irqrestore, + .create_event = gf_create_event, + .destroy_event = gf_destroy_event, + .wait_event_thread_safe = gf_wait_event_thread_safe, + .wait_event = gf_wait_event, + .wake_up_event = gf_wake_up_event, + .thread_wait = gf_thread_wait, + .create_wait_queue = gf_create_wait_queue, + .thread_wake_up = gf_thread_wake_up, + .try_to_freeze = gf_try_to_freeze, + .freezable = gf_freezable, + .clear_freezable = gf_clear_freezable, + .set_freezable = gf_set_freezable, + .freezing = gf_freezing, + .get_current_pid = gf_get_current_pid, + .get_current_tid = gf_get_current_tid, + .get_current_pname = gf_get_current_pname, + .flush_cache = gf_flush_cache, + .inv_cache = gf_inv_cache, + .pages_memory_for_each_continues = gf_pages_memory_for_each_continues, + .ioremap = gf_ioremap, + .iounmap_priv = gf_iounmap, + .mtrr_add = gf_mtrr_add, + .mtrr_del = gf_mtrr_del, + .get_mem_info = gf_get_mem_info, + .is_own_pages = gf_is_own_pages, + .pages_memory_swapout = gf_pages_memory_swapout, + .pages_memory_swapin = gf_pages_memory_swapin, + .release_file_storage = gf_release_file_storage, + .get_bus_config = gf_get_bus_config, + .get_platform_config = gf_get_platform_config, + + .malloc_track = gf_malloc_track, + .calloc_track = gf_calloc_track, + .free_track = gf_free_track, + .malloc_priv = gf_malloc_priv, + .calloc_priv = gf_calloc_priv, + .free_priv = gf_free_priv, + .allocate_pages_memory_track = gf_allocate_pages_memory_track, + .free_pages_memory_track = gf_free_pages_memory_track, + .allocate_pages_memory_priv = gf_allocate_pages_memory_priv, + .free_pages_memory_priv = gf_free_pages_memory_priv, + + .map_pages_memory_track = gf_map_pages_memory_track, + .unmap_pages_memory_track = gf_unmap_pages_memory_track, + .map_pages_memory_priv = gf_map_pages_memory_priv, + .unmap_pages_memory_priv = gf_unmap_pages_memory_priv, + .map_io_memory_track = gf_map_io_memory_track, + .unmap_io_memory_track = gf_unmap_io_memory_track, + .map_io_memory_priv = gf_map_io_memory_priv, + .unmap_io_memory_priv = gf_unmap_io_memory_priv, + .register_trace_events = gf_register_trace_events, + .unregister_trace_events = gf_unregister_trace_events, + .task_create_trace_event = gf_task_create_trace_event, + .task_submit_trace_event = gf_task_submit_trace_event, + .fence_back_trace_event = gf_fence_back_trace_event, + .begin_section_trace_event = gf_begin_section_trace_event, + .end_section_trace_event = gf_end_section_trace_event, + .counter_trace_event = gf_counter_trace_event, + + .query_platform_caps = gf_query_platform_caps, + + .console_lock = gf_console_lock, + .enable_interrupt = gf_enable_interrupt, + .disable_interrupt = gf_disable_interrupt, + .os_printf = gf_printf, + .disp_wait_idle = gf_disp_wait_idle, + .mb = gf_mb, + .rmb = gf_rmb, + .wmb = gf_wmb, + .flush_wc = gf_flush_wc, + .dsb = gf_dsb, +}; + +/***/ +#include + +#ifdef NO_PROC_CREATE_FUNC +static int gf_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + + gf_card_t *gf = data; + struct os_printer p = gf_info_printer(gf); + gf_core_interface->dump_resource(&p, gf->adapter, 5, 0); + + return 0; +} + +static int gf_gpuinfo_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + return 0; +} + +#else +static ssize_t gf_proc_read(struct file *filp, char *buf, size_t count, loff_t *offp) +{ +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 17, 0) + gf_card_t *gf = PDE_DATA(file_inode(filp)); +#else + gf_card_t *gf = pde_data(file_inode(filp)); +#endif + struct os_printer p = gf_info_printer(gf); + gf_core_interface->dump_resource(&p, gf->adapter, 1, 0); + + return 0; +} + +extern int hwq_get_hwq_info(void *adp, gf_hwq_info *hwq_info); +static ssize_t gf_gpuinfo_proc_read(struct file *filp, char *buf, size_t count, loff_t *offp) +{ +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 17, 0) + gf_card_t *gf = PDE_DATA(file_inode(filp)); +#else + gf_card_t *gf = pde_data(file_inode(filp)); +#endif + + gf_hwq_info hwq_info; + gf_query_info_t query_info; + bus_config_t bus_config; + struct pci_dev *pdev = gf->pdev; + adapter_info_t *adapter_info = &gf->adapter_info; + disp_info_t *disp_info = (disp_info_t *)gf->disp_info; + + int ret = 0; + size_t len = 0; + static int print_flag = 1; + char *buffer = NULL, *memory_type = "DDR4", *pmp_version = NULL, *product_name = NULL, *type_dp = "\0"; + char *output_type_vga_hdmi = "VGA, HDMI", *output_type_full = "VGA, HDMI, DP", *hdmi_resolution = "3840 x 2160", *vga_resolution = "1920 x 1080", *output_type = output_type_vga_hdmi; + unsigned int mclk, coreclk, eclk, free_mem, mem_usage, usage_3d, usage_vcp, usage_vpp; + unsigned int subsystemid, technology, pixel_fillrate, texture_fillrate; + unsigned int pci_gen, pci_width; + unsigned int memory_width = 64, output_cnt = 2, hdmi_fps; + int temp, vbios_version = 0, pmp_datelen = 0, pmp_timelen = 0; + unsigned char *fwname = NULL; + int fw_version = 0; + + if (!print_flag) + goto exit; + + buffer = gf_calloc(1024); + if (!buffer) + goto exit_nomem; + + gf_core_interface->ctl_flags_set(gf->adapter, 1, (1UL << 16), (1 << 16)); + gf_core_interface->ctl_flags_set(gf->adapter, 1, (1UL << 9), (1 << 9)); + + gf_get_bus_config(pdev, &bus_config); + pci_width = (bus_config.link_status >> 4) & 0x1F; + pci_gen = bus_config.link_status & 0xF; + + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_MCLK, &mclk)) + mclk = gf_calc_double_standard_mclk(mclk); + else + mclk = 0; + + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_CORE_CLOCK, &coreclk)) + coreclk /= 1000; + else + coreclk = 0; + + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_ENGINE_CLOCK, &eclk)) + eclk /= 1000; + else + eclk = 0; + + query_info.type = GF_QUERY_SEGMENT_FREE_SIZE; + query_info.argu = 1;//low + gf_core_interface->query_info(gf->adapter, &query_info); + free_mem = query_info.signed_value; + + query_info.type = GF_QUERY_SEGMENT_FREE_SIZE; + query_info.argu = 4;//high 4G- + gf_core_interface->query_info(gf->adapter, &query_info); + free_mem += query_info.signed_value; + + query_info.type = GF_QUERY_SEGMENT_FREE_SIZE; + query_info.argu = 5;//high 4G+ + gf_core_interface->query_info(gf->adapter, &query_info); + free_mem += query_info.signed_value; + + free_mem /= 1024; + + mem_usage = ((adapter_info->total_mem_size_mb - free_mem) * 100) / adapter_info->total_mem_size_mb; + + memory_width = adapter_info->chan_num * memory_width; + + temp = gf_get_chip_temp(gf->disp_info); + + ret = hwq_get_hwq_info(gf->adapter, &hwq_info); + if (!ret) + { + usage_3d = hwq_info.Usage_3D; + usage_vcp = hwq_info.Usage_VCP; + usage_vpp = hwq_info.Usage_VPP; + } + else + { + usage_3d = usage_vcp = usage_vpp = 0; + } + + switch (pdev->device) + { + case 0x3d00: + hdmi_fps = 60; + subsystemid = 0x10C0; + technology = 28; + pixel_fillrate = 96 * eclk; + texture_fillrate = pixel_fillrate *2; + product_name = "Arise-GT10C0"; + break; + + case 0x3d02: + hdmi_fps = 30; + subsystemid = 0x1020; + technology = 28; + pixel_fillrate = 16 * eclk; + texture_fillrate = pixel_fillrate *2; + product_name = "Arise1020"; + break; + + case 0x3d03: + hdmi_fps = 60; + subsystemid = 0x1040; + technology = 28; + pixel_fillrate = 32 * eclk; + texture_fillrate = pixel_fillrate *2; + product_name = "Arise-GT1040"; + break; + + case 0x3d04: + hdmi_fps = 30; + subsystemid = 0x1010; + technology = 28; + pixel_fillrate = 8 * eclk; + texture_fillrate = pixel_fillrate *2; + product_name = "Arise1010"; + break; + + case 0x3d06: + hdmi_fps = 60; + subsystemid = 0x10C0; + technology = 28; + pixel_fillrate = 96 * eclk; + texture_fillrate = pixel_fillrate *2; + product_name = "Arise-GT10C0t"; + if (adapter_info->chan_num == 3) + { + output_cnt = 4; + output_type = output_type_full; + } + break; + + case 0x3d07: + hdmi_fps = 60; + subsystemid = 0x2030; + technology = 28; + pixel_fillrate = 32 * eclk; + texture_fillrate = pixel_fillrate *2; + product_name = "Arise2030"; + output_cnt = 3; + output_type = output_type_full; + type_dp = "/DP"; + break; + + case 0x3d08: + hdmi_fps = 60; + subsystemid = 0x2020; + technology = 28; + pixel_fillrate = 32 * eclk; + texture_fillrate = pixel_fillrate *2; + product_name = "Arise2020"; + output_cnt = 3; + output_type = output_type_full; + type_dp = "/DP"; + break; + + default: + hdmi_fps = 60; + subsystemid = 0; + technology = 0; + pixel_fillrate = 0; + texture_fillrate = 0; + product_name = "Arise N/A"; + break; + } + + pmp_version = disp_info->pmp_version; + vbios_version = disp_info->vbios_version; + fwname = disp_info->firmware_name; + fw_version = disp_info->firmware_version; + + if (pmp_version) + { + pmp_datelen = gf_strlen(pmp_version) + 1; + pmp_timelen = gf_strlen(pmp_version + pmp_datelen) + 1; + } + + len += sprintf(buffer + len, "Vendor : %s\n", DRIVER_VENDOR); + len += sprintf(buffer + len, "Product Name : %s\n", product_name); + len += sprintf(buffer + len, "Vendor ID : %X\n", pdev->vendor); + len += sprintf(buffer + len, "Device ID : %X\n", pdev->device); + //len += sprintf(buffer + len, "Subsystemid : %X\n", subsystemid); + len += sprintf(buffer + len, "Technology : %u nm\n", technology); + len += sprintf(buffer + len, "Bus Type : PCIE%d.0 x%u\n", pci_gen, pci_width); + len += sprintf(buffer + len, "Driver Version : %02x.%02x.%02x%s\n", DRIVER_MAJOR, DRIVER_MINOR, DRIVER_PATCHLEVEL, DRIVER_CLASS); + if (*fwname) + { + len += sprintf(buffer + len, "Firmware Version : %02x.%02x.%02x.%02x\n", (fw_version>>24)&0xff, (fw_version>>16)&0xff, (fw_version>>8)&0xff, fw_version&0xff); + len += sprintf(buffer + len, "Firmware Name : %s\n", fwname); + } + + len += sprintf(buffer + len, "Pixel Fillrate : %d MPixel/s\n", pixel_fillrate); + len += sprintf(buffer + len, "Texture Fillrate : %d MTexel/s\n", texture_fillrate); + len += sprintf(buffer + len, "Memory Type : %s\n", memory_type); + len += sprintf(buffer + len, "Memory Width : %d bits\n", memory_width); + len += sprintf(buffer + len, "Memory Size : %d MB\n", adapter_info->total_mem_size_mb); + len += sprintf(buffer + len, "Memory ddr Remain Size : %d MB\n", free_mem); + len += sprintf(buffer + len, "Memory Clock Freq : %d MHz\n", mclk / 2); + len += sprintf(buffer + len, "Memory Transfer Rates : %d MT/s\n", mclk); + len += sprintf(buffer + len, "GPU Work Frequency : Core %d MHz / Aux %d MHz\n", coreclk, eclk); + len += sprintf(buffer + len, "Realtime Temperature : %d Degree\n", temp); + len += sprintf(buffer + len, "Max Display Port : %d\n", output_cnt); + len += sprintf(buffer + len, "Support Display Type : %s\n", output_type); + len += sprintf(buffer + len, "HDMI%s Max Display Resolution : %s@%dHz\n", type_dp, hdmi_resolution, hdmi_fps); + len += sprintf(buffer + len, "VGA Max Display Resolution : %s@60Hz\n", vga_resolution); + + len += sprintf(buffer + len, "GPU Memory Usage : %d%%\n", mem_usage); + len += sprintf(buffer + len, "GPU Use Rate(3d) : %d%%\n", usage_3d); + len += sprintf(buffer + len, "GPU Use Rate(video) : %d%%\n", usage_vcp); + len += sprintf(buffer + len, "GPU Use Rate(vpp) : %d%%\n", usage_vpp); + + ret = copy_to_user(buf, buffer, len); + gf_free(buffer); + + if (ret) + goto exit_err; + + print_flag = 0; + return len; + +exit_err: + return -EFAULT; + +exit_nomem: + return -ENOMEM; + +exit: + print_flag = 1; + return 0; +} + +#define GF_DUMP_FENCE_INDEX 0x5000 +#define GF_CLEAR_FENCE_INDEX 0x6000 +#define GF_FORCE_WAKEUP 0x7000 + +static ssize_t gf_proc_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp) +{ +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 17, 0) + gf_card_t *gf = PDE_DATA(file_inode(filp)); +#else + gf_card_t *gf = pde_data(file_inode(filp)); +#endif + + char mode = '0'; + int dump_index = 0; + unsigned int ret = 0; + char temp[20] = {0}; + unsigned int crtc = 0; + unsigned long value = 0; + + //maybe later we can change it to using gf_seq_file_printer + struct os_printer p = gf_info_printer(gf); + + if(count > 1 && count < 20) + { + ret = copy_from_user(&temp[0], buf, count); + temp[count-1] = '\0'; + + if(count == 2) + { + mode = temp[0]; + + if(mode >= '0' && mode <= '9') + { + dump_index = (mode - '0'); + } + else if((mode >= 'a' && mode < 'e')) + { + dump_index = mode - 'a' + 0xa; + } + else if (mode == 'f') + { + dump_index = GF_DUMP_FENCE_INDEX; + } + else if (mode == 'g') + { + dump_index = GF_CLEAR_FENCE_INDEX; + } + else if (mode == 'w') + { + dump_index = GF_FORCE_WAKEUP; + } + else + { + gf_error("echo error proc mode, should between 0 and d \n"); + return -EFAULT; + } + } + else + { + value = simple_strtoul(&temp[1], NULL, 16); + + gf_info("value %d \n", value); + } + } + else + { + gf_error("proc write pass too long param, should less than 20\n"); + } + + if (dump_index == GF_DUMP_FENCE_INDEX) + { + gf_dma_track_fences_dump(gf); + } + else if (dump_index == GF_CLEAR_FENCE_INDEX) + { + gf_dma_track_fences_clear(gf); + } + else if((dump_index >=0 && dump_index <=7)) + { + gf_core_interface->dump_resource(&p, gf->adapter, dump_index, 0); + } + else if (dump_index == GF_FORCE_WAKEUP) + { + gf_core_interface->notify_interrupt(gf->adapter, INT_FENCE); + gf_core_interface->dump_resource(&p, gf->adapter, dump_index, 0); + } + + return count; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +static const struct proc_ops gf_proc_fops = +{ + .proc_read = gf_proc_read, + .proc_write = gf_proc_write, +}; + +static const struct proc_ops gf_gpuinfo_proc_fops = +{ + .proc_read = gf_gpuinfo_proc_read, +}; + +#else +static const struct file_operations gf_proc_fops = +{ + .owner = THIS_MODULE, + .read = gf_proc_read, + .write = gf_proc_write, +}; + +static const struct file_operations gf_gpuinfo_proc_fops = +{ + .owner = THIS_MODULE, + .read = gf_gpuinfo_proc_read, +}; + +#endif +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0) + +static int temperature_mode = 0; +static ssize_t gf_show_temperature(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + gf_card_t *gf_card = dev_get_drvdata(dev); + int temp = 0; + + if (!temperature_mode) + temp = gf_get_chip_temp(gf_card->disp_info); + else + temp = gf_get_chip_temp_legacy(gf_card->disp_info); + + return snprintf(buf, PAGE_SIZE, "%d *C\n", temp); +} + +static ssize_t gf_temperature_mode_set(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + unsigned int enable = 0; + int ret; + + ret = sscanf(buf, "%u", &enable); + if (ret <= 0) + return -EINVAL; + + if (enable == 1) + { + temperature_mode = 1; + gf_info("set temperature mode to legacy\n"); + } + else + { + temperature_mode = 0; + gf_info("set temperature mode to normal\n"); + } + + return count; +} + +static int fan_mode = 0; +static ssize_t gf_show_fan0_input(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + gf_card_t *gf_card = dev_get_drvdata(dev); + static int fanspeed = 0, initflag = 1; + static ktime_t stime, etime; + + if (!fan_mode) + { + fanspeed = gf_get_chip_fanspeed(gf_card->disp_info, 0); + } + else + { + etime = ktime_get(); + if (ktime_to_ns(stime) == 0) + stime = etime; + + initflag = 0; + + gf_chip_fan_init_legacy(gf_card->disp_info, 0); + + //Read Fan speed interval + if (ktime_ms_delta(etime, stime) > 100) + { + fanspeed = gf_get_chip_fanspeed_legacy(gf_card->disp_info, 0); + stime = etime; + } + } + + return snprintf(buf, PAGE_SIZE, "%d %%\n", fanspeed); +} + +static ssize_t gf_show_fan1_input(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + gf_card_t *gf_card = dev_get_drvdata(dev); + static int fanspeed = 0, initflag = 1; + static ktime_t stime, etime; + + if (!fan_mode) + { + fanspeed = gf_get_chip_fanspeed(gf_card->disp_info, 1); + } + else + { + etime = ktime_get(); + if (ktime_to_ns(stime) == 0) + stime = etime; + + initflag = 0; + + gf_chip_fan_init_legacy(gf_card->disp_info, 1); + + //Read Fan speed interval + if (ktime_ms_delta(etime, stime) > 100) + { + fanspeed = gf_get_chip_fanspeed_legacy(gf_card->disp_info, 1); + stime = etime; + } + } + + return snprintf(buf, PAGE_SIZE, "%d %%\n", fanspeed); +} + +static ssize_t gf_fan_mode_set(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + unsigned int enable = 0; + int ret; + + ret = sscanf(buf, "%u", &enable); + if (ret <= 0) + return -EINVAL; + + if (enable == 1) + { + fan_mode = 1; + gf_info("set fan mode to legacy\n"); + } + else + { + fan_mode = 0; + gf_info("set fan mode to normal\n"); + } + + return count; +} + +static SENSOR_DEVICE_ATTR(temps1_input, S_IRUGO | S_IWUSR, gf_show_temperature, gf_temperature_mode_set, 0); +static SENSOR_DEVICE_ATTR(fans0_input, S_IRUGO | S_IWUSR, gf_show_fan0_input, gf_fan_mode_set, 0); +static SENSOR_DEVICE_ATTR(fans1_input, S_IRUGO | S_IWUSR, gf_show_fan1_input, gf_fan_mode_set, 0); + +static struct attribute *gf_hwmon_attrs[] = { + &sensor_dev_attr_temps1_input.dev_attr.attr, + &sensor_dev_attr_fans0_input.dev_attr.attr, + &sensor_dev_attr_fans1_input.dev_attr.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(gf_hwmon); + +#endif + +int gf_card_init(gf_card_t *gf, void *pdev) +{ + int ret = 0; + + gf_init_procfs_entry(gf); + + gf_init_bus_id(gf); + +#ifdef GF_PCIE_BUS + gf->support_msi = 1; +#else + gf->support_msi = 0; +#endif + + gf->adapter = gf_core_interface->pre_init_adapter(pdev, &gf->a_info, &gf_export); + + if(gf->adapter == NULL) + { + ret = -1; + + gf_error("init adapter failed\n"); + } + + gf_init_modeset(gf->drm_dev); + + gf_disable_async_suspend(gf); + + gf_core_interface->init_adapter(gf->adapter, gf->reserved_vmem, gf->disp_info); + +#ifndef GF_HW_NULL + gf_interrupt_init(gf); +#endif + + gf->lock = gf_create_mutex(); + + ret = sysfs_create_files(&gf->pdev->dev.kobj, &gf_os_gpu_info); + if(ret) + { + gf_warning("Could not create device attr\n"); + } + + ret = sysfs_create_group(&gf->pdev->dev.kobj, &gf_sysfs_group); + if(ret) + { + gf_warning("Could not create attr group\n"); + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0) + gf->hwmon_dev = hwmon_device_register_with_groups(&gf->pdev->dev, STR(DRIVER_NAME), gf, gf_hwmon_groups); + if(!gf->hwmon_dev) + { + gf_info("Register hwmon sense failed!\n"); + } +#endif + + gf_allocate_trace_buffer(gf); + ret = sysfs_create_bin_file(&gf->pdev->dev.kobj, &gf_sysfs_trace_attr); + if(ret) + { + gf_warning("Could not create sysfs trace attr\n"); + } + + gf->fps_count = 0; + gf->rxa_blt_scn_cnt = 0; + gf->misc_control_flag = gf_modparams.misc_control_flag; + gf->allocation_trace_tags = 0; + gf->video_irq_info_all = 0; + + return ret; +} + +int gf_card_deinit(gf_card_t *gf) +{ + char *name; + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + gf_fbdev_deinit(gf); +#endif + + gf_core_interface->wait_chip_idle(gf->adapter); + + gf_deinit_modeset(gf->drm_dev); + +#ifndef GF_HW_NULL + gf_interrupt_deinit(gf); +#endif + + gf_core_interface->deinit_adapter(gf->adapter); + + gf->len = 0; + + if(gf->lock) + { + gf_destroy_mutex(gf->lock); + gf->lock = NULL; + } + + if(gf->debugfs_dev) + { + gf_debugfs_destroy((gf_debugfs_device_t*)(gf->debugfs_dev)); + gf->debugfs_dev = NULL; + } + + sysfs_remove_files(&gf->pdev->dev.kobj, &gf_os_gpu_info); + + sysfs_remove_group(&gf->pdev->dev.kobj, &gf_sysfs_group); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0) + if(gf->hwmon_dev) + { + hwmon_device_unregister(gf->hwmon_dev); + gf->hwmon_dev = NULL; + } +#endif + + if(gf->procfs_entry) + { + gf_deinit_procfs_entry(gf); + gf->procfs_entry = NULL; + } + + sysfs_remove_bin_file(&gf->pdev->dev.kobj, &gf_sysfs_trace_attr); + gf_free_trace_buffer(gf); + + gf->fps_count = 0; + return 0; +} + +static int gf_init_procfs_entry(gf_card_t *gf) +{ + char name[64] = ""; + + gf_vsnprintf(name, 64, "driver/dri%d", gf->index); + +#ifdef NO_PROC_CREATE_FUNC + //create_proce_read_entry is not used any more in Linux 3.10 and above. use proc_create_data instead. + gf->procfs_entry = create_proc_read_entry(name, 0, NULL, gf_read_proc, gf); + + gf_vsnprintf(name, 64, "gpuinfo_%d", gf->index); + gf->procfs_gpuinfo_entry = create_proc_read_entry(name, 0, NULL, gf_gpuinfo_read_proc, gf); +#else + gf->procfs_entry = proc_create_data(name, 0, NULL, &gf_proc_fops, gf); + + gf_vsnprintf(name, 64, "gpuinfo_%d", gf->index); + gf->procfs_gpuinfo_entry = proc_create_data(name, 0, NULL, &gf_gpuinfo_proc_fops, gf); + gf_vsnprintf(name, 64, "driver/dri%d", gf->index); +#endif + + gf_info("%s() name-%s, procfs_entry-0x%x\n", GF_FUNC_NAME(__func__), name, gf->procfs_entry); + + return 0; +} + +static int gf_deinit_procfs_entry(gf_card_t *gf) +{ + char name[64] = ""; + + gf_vsnprintf(name, 64, "driver/dri%d", gf->index); +#ifdef NO_PROC_CREATE_FUNC + //this path is not verified yet + remove_proc_entry(name, gf->procfs_entry); + + gf_vsnprintf(name, 64, "gpuinfo_%d", gf->index); + remove_proc_entry(name, gf->procfs_gpuinfo_entry); +#else + proc_remove(gf->procfs_entry); + proc_remove(gf->procfs_gpuinfo_entry); +#endif + + return 0; +} + + diff --git a/drivers/gpu/drm/arise/linux/gf_driver.h b/drivers/gpu/drm/arise/linux/gf_driver.h new file mode 100644 index 0000000000000..daa56ae499dad --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_driver.h @@ -0,0 +1,178 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_DRIVER_H +#define __GF_DRIVER_H + +#include "gf.h" +#include "gf_def.h" +#include "gf_types.h" +#include "os_interface.h" +#include "kernel_interface.h" +#include "gf_device_debug.h" + +#define __STR(x) #x +#define STR(x) __STR(x) + +typedef struct gf_file gf_file_t; + +typedef int (*gf_ioctl_t)(struct drm_device *dev, void *data,struct drm_file *filp); + +typedef int (*irq_func_t)(void*); + +typedef struct +{ + void *adapter; +#ifdef GF_PCIE_BUS + struct pci_dev *pdev; +#else + struct platform_device *pdev; +#endif + struct drm_device *drm_dev; + adapter_info_t adapter_info; + void* disp_info; + char busId[64]; + int len; + int index; + + struct os_mutex *lock; + + int support_msi; + + struct tasklet_struct fence_notify; + + int reserved_vmem; + + void *debugfs_dev; + struct device *hwmon_dev; + struct device *pci_device; + struct gf_dma_fence_driver *fence_drv; + void *fbdev; + struct krnl_adapter_init_info_s a_info; + struct proc_dir_entry *procfs_entry; + struct proc_dir_entry *procfs_gpuinfo_entry; + unsigned long umd_trace_tags; // usermode trace tags, 0 to disable. + struct os_pages_memory *trace_buffer; + gf_vm_area_t *trace_buffer_vma; + +#define GF_S4_RESUME 0x01 + unsigned int flags; + unsigned int fps_count; + unsigned int rxa_blt_scn_cnt; + unsigned int misc_control_flag; + unsigned long allocation_trace_tags; // allocation trace tags, 0 to disable. + unsigned int video_irq_info_all; +}gf_card_t; + +struct gf_file +{ + struct drm_file *parent_file; + gf_card_t *card; + + void *map; + unsigned int gpu_device; + + gf_device_debug_info_t *debug; + + unsigned int server_index; + + int hold_lock; + int freezable; + struct os_mutex *lock; +}; + +extern char *gf_fb_mode; +extern int gf_fb; + +extern struct class *gf_class; +extern struct drm_ioctl_desc gf_ioctls[]; +extern struct drm_ioctl_desc gf_ioctls_compat[]; + +extern int gf_card_init(gf_card_t *gf, void *pdev); +extern int gf_card_deinit(gf_card_t *gf); +extern int gf_init_modeset(struct drm_device *dev); +extern void gf_deinit_modeset(struct drm_device *dev); +extern int gf_debugfs_crtc_dump(struct seq_file* file, struct drm_device* dev, int index); +extern int gf_debugfs_clock_dump(struct seq_file* file, struct drm_device* dev); +extern int gf_debugfs_displayinfo_dump(struct seq_file* file, struct drm_device* dev); +extern int gf_get_chip_temp(void* dispi); +extern unsigned int gf_calc_double_standard_mclk(unsigned int mclk); +extern void gf_chip_fan_init_legacy(void* dispi,int index); +extern int gf_get_chip_fanspeed(void* dispi, int index); +extern int gf_get_chip_temp_legacy(void* dispi); +extern int gf_get_chip_fanspeed_legacy(void* dispi, int index); + +extern void gf_splice_manager_handle_hpd(struct work_struct* work); + +extern void gf_interrupt_init(gf_card_t *gf); +extern void gf_interrupt_reinit(gf_card_t *gf); +extern void gf_interrupt_deinit(gf_card_t *gf); + +extern int gf_map_system_io(struct vm_area_struct *vma, gf_map_argu_t *map); +extern int gf_map_system_ram(struct vm_area_struct *vma, gf_map_argu_t *map); + +extern void gf_enable_interrupt(void *pdev); +extern void gf_disable_interrupt(void *pdev); + +extern void gf_init_bus_id(gf_card_t *gf); +extern int gf_register_driver(void); +extern void gf_unregister_driver(void); +extern int gf_register_interrupt(gf_card_t *gf, void *isr); +extern void gf_unregister_interrupt(gf_card_t *gf); + +extern int gf_mmap(struct file *filp, struct vm_area_struct *vma); + +extern int gf_ioctl_wait_chip_idle(struct drm_device *dev, void *data,struct drm_file *filp); + +extern int gf_ioctl_wait_allocation_idle(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_query_info(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_create_device(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_destroy_device(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_begin_perf_event(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_begin_miu_dump_perf_event(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_end_perf_event(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_end_miu_dump_perf_event(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_get_perf_event(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_send_perf_event(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_get_perf_status(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_create_context(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_destroy_context(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_create_di_context(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_destroy_di_context(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_query_chip_id(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_create_fence_sync_object(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_destroy_fence_sync_object(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_wait_fence_sync_object(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_fence_value(struct drm_device *dev, void *data,struct drm_file *filp); + +extern int gf_ioctl_wait_context_idle(struct drm_device *dev, void *data,struct drm_file *filp); + +extern int gf_ioctl_get_allocation_state(struct drm_device *dev, void *data,struct drm_file *filp); + +extern int gf_ioctl_cil2_misc(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_gem_create_allocation(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_gem_create_context(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_gem_map_gtt(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_gem_begin_cpu_access(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_gem_end_cpu_access(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_render(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_gem_create_resource(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_add_hw_ctx_buf(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_rm_hw_ctx_buf(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_set_miu_reg_list_perf_event(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_get_miu_dump_perf_event(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_direct_get_miu_dump_perf_event(struct drm_device *dev, void *data,struct drm_file *filp); +extern int gf_ioctl_kms_get_pipe_from_crtc(struct drm_device *dev, void *data,struct drm_file *filp); +#endif + diff --git a/drivers/gpu/drm/arise/linux/gf_drmfb.c b/drivers/gpu/drm/arise/linux/gf_drmfb.c new file mode 100644 index 0000000000000..b311cbf0f5e99 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_drmfb.c @@ -0,0 +1,104 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_drmfb.h" + +static void gf_drm_framebuffer_destroy(struct drm_framebuffer *fb) +{ + struct drm_gf_framebuffer *gfb = to_gfb(fb); + + drm_framebuffer_cleanup(fb); + gf_gem_object_put(gfb->obj); + gf_free(gfb); +} + +static int gf_drm_framebuffer_create_handle(struct drm_framebuffer *fb, + struct drm_file *file, + unsigned int *handle) +{ + struct drm_gf_framebuffer *gfb = to_gfb(fb); + + return drm_gem_handle_create(file, &gfb->obj->base, handle); +} + +static int gf_drm_framebuffer_dirty(struct drm_framebuffer *fb, + struct drm_file *file, + unsigned int flags, + unsigned color, + struct drm_clip_rect *clips, + unsigned int num_clips) +{ + return 0; +} + +static const struct drm_framebuffer_funcs gf_fb_funcs = +{ + .destroy = gf_drm_framebuffer_destroy, + .create_handle = gf_drm_framebuffer_create_handle, + .dirty = gf_drm_framebuffer_dirty, +}; + +struct drm_gf_framebuffer* +__gf_framebuffer_create(struct drm_device *dev, + struct drm_mode_fb_cmd2 *mode_cmd, + struct drm_gf_gem_object *obj) +{ + int ret; + struct drm_gf_framebuffer *gfb; + gfb = gf_calloc(sizeof(*gfb)); + if (!gfb) + return ERR_PTR(-ENOMEM); + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 11, 0) + drm_helper_mode_fill_fb_struct(&gfb->base, mode_cmd); +#else + drm_helper_mode_fill_fb_struct(dev, &gfb->base, mode_cmd); +#endif + gfb->obj = obj; + + ret = drm_framebuffer_init(dev, &gfb->base, &gf_fb_funcs); + if (ret) + goto err_free; + + return gfb; +err_free: + gf_free(gfb); + return ERR_PTR(ret); +} + +struct drm_framebuffer * +gf_fb_create(struct drm_device *dev, + struct drm_file *file, +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 5, 0) && !defined (PHYTIUM_2000) + struct drm_mode_fb_cmd2 *user_mode_cmd +#else + const struct drm_mode_fb_cmd2 *user_mode_cmd +#endif + ) +{ + struct drm_gf_framebuffer *fb; + struct drm_gf_gem_object *obj; + struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd; + + obj = gf_drm_gem_object_lookup(dev, file, mode_cmd.handles[0]); + if (!obj) + return ERR_PTR(-ENOENT); + + fb = __gf_framebuffer_create(dev, &mode_cmd, obj); + if (IS_ERR(fb)) + gf_gem_object_put(obj); + + return &fb->base; +} + diff --git a/drivers/gpu/drm/arise/linux/gf_drmfb.h b/drivers/gpu/drm/arise/linux/gf_drmfb.h new file mode 100644 index 0000000000000..257b227417537 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_drmfb.h @@ -0,0 +1,48 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _GF_DRMFB_H_ +#define _GF_DRMFB_H_ + +#include "gf_disp.h" +#include "gf_gem.h" +#include "gf_gem_priv.h" +#if DRM_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#include +#endif + +struct drm_gf_framebuffer +{ + struct drm_framebuffer base; + struct drm_gf_gem_object *obj; +}; +#define to_gfb(fb) container_of((fb), struct drm_gf_framebuffer, base) + +struct drm_framebuffer * +gf_fb_create(struct drm_device *dev, + struct drm_file *file_priv, + #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) || defined (PHYTIUM_2000) + const struct drm_mode_fb_cmd2 *mode_cmd + #else + struct drm_mode_fb_cmd2 *mode_cmd + #endif + ); + +void gf_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state); + +struct drm_gf_framebuffer* +__gf_framebuffer_create(struct drm_device *dev, + struct drm_mode_fb_cmd2 *mode_cmd, + struct drm_gf_gem_object *obj); +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_encoder.c b/drivers/gpu/drm/arise/linux/gf_encoder.c new file mode 100644 index 0000000000000..0cf24eea7004c --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_encoder.c @@ -0,0 +1,389 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_disp.h" +#include "gf_cbios.h" +#include "gf_atomic.h" +#include "gf_capture_drv.h" +#include "gf_splice.h" + +static void gf_encoder_destroy(struct drm_encoder *encoder) +{ + gf_encoder_t *gf_encoder = to_gf_encoder(encoder); + + drm_encoder_cleanup(encoder); + gf_free(gf_encoder); +} + +static gf_connector_t* gf_encoder_get_connector(gf_encoder_t* gf_encoder) +{ + struct drm_encoder *encoder = &gf_encoder->base_encoder; + struct drm_device *dev = encoder->dev; + struct drm_connector *connector; + gf_connector_t *gf_connector = NULL; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + if (connector->encoder == encoder) + { + gf_connector = to_gf_connector(connector); + break; + } + } + + return gf_connector; +} + +void gf_encoder_disable(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_encoder_t *gf_encoder = to_gf_encoder(encoder); + gf_connector_t *gf_connector = gf_encoder_get_connector(gf_encoder); + gf_capture_id_t cf_id = GF_CAPTURE_INVALID; + + if (!gf_connector) + { + return; + } + + if (DISP_OUTPUT_DP1 == gf_encoder->output_type) + { + cf_id = GF_CAPTURE_WB1; + } + else if (DISP_OUTPUT_DP2 == gf_encoder->output_type) + { + cf_id = GF_CAPTURE_WB2; + } + else if (DISP_OUTPUT_DP3 == gf_encoder->output_type) + { + cf_id = GF_CAPTURE_WB3; + } + else if (DISP_OUTPUT_DP4 == gf_encoder->output_type) + { + cf_id = GF_CAPTURE_WB4; + } + + if(gf_encoder->enc_dpms != GF_DPMS_OFF) + { + if (!(is_crtc_work_in_splice_mode(encoder->crtc) && + is_splice_target_active_in_drm(dev))) + { + + disp_cbios_set_hdac_connect_status(disp_info, gf_encoder->output_type, FALSE, FALSE); + + gf_usleep_range(1000, 1100); //delay 1 ms + + #if GF_RUN_HDCP_CTS + if (gf_connector->hdcp_enable) + { + disp_cbios_enable_hdcp(disp_info,FALSE, gf_encoder->output_type); + gf_connector->hdcp_enable = 0; + } + #endif + + gf_info("To turn off power of device: 0x%x.\n", gf_encoder->output_type); + + gf_capture_handle_event(disp_info, cf_id, GF_CAPTURE_EVENT_SIGNAL_OFF); + + gf_mutex_lock(gf_connector->conn_mutex); + disp_cbios_set_dpms(disp_info, gf_encoder->output_type, GF_DPMS_OFF); + gf_mutex_unlock(gf_connector->conn_mutex); + } + + gf_encoder->enc_dpms = GF_DPMS_OFF; + } +} + +void gf_encoder_enable(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_encoder_t *gf_encoder = to_gf_encoder(encoder); + gf_connector_t *gf_connector = gf_encoder_get_connector(gf_encoder); + gf_capture_id_t cf_id = GF_CAPTURE_INVALID; + + if (!gf_connector) + { + return; + } + + if (DISP_OUTPUT_DP1 == gf_encoder->output_type) + { + cf_id = GF_CAPTURE_WB1; + } + else if (DISP_OUTPUT_DP2 == gf_encoder->output_type) + { + cf_id = GF_CAPTURE_WB2; + } + else if (DISP_OUTPUT_DP3 == gf_encoder->output_type) + { + cf_id = GF_CAPTURE_WB3; + } + else if (DISP_OUTPUT_DP4 == gf_encoder->output_type) + { + cf_id = GF_CAPTURE_WB4; + } + + if(gf_encoder->enc_dpms != GF_DPMS_ON) + { + gf_info("To turn on power of device: 0x%x.\n", gf_encoder->output_type); + + gf_mutex_lock(gf_connector->conn_mutex); + disp_cbios_set_dpms(disp_info, gf_encoder->output_type, GF_DPMS_ON); + gf_mutex_unlock(gf_connector->conn_mutex); + gf_encoder->enc_dpms = GF_DPMS_ON; + + if (gf_connector->support_audio) + { + disp_cbios_set_hdac_connect_status(disp_info, gf_encoder->output_type, TRUE, TRUE); + } + +#if GF_RUN_HDCP_CTS + if ((!(gf_connector->hdcp_enable)) + &&(gf_connector->monitor_type == UT_OUTPUT_TYPE_HDMI || gf_connector->monitor_type == UT_OUTPUT_TYPE_DVI)) + { + disp_cbios_enable_hdcp(disp_info, TRUE, gf_encoder->output_type); + gf_connector->hdcp_enable = 1; + } +#endif + + gf_capture_handle_event(disp_info, cf_id, GF_CAPTURE_EVENT_SIGNAL_ON); + } +} + +bool gf_encoder_mode_fixup_internal(disp_info_t* disp_info, + int output_type, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + unsigned int dev_mode_size = 0, dev_real_num = 0, i = 0, matched = 0; + void * dev_mode_buf = NULL; + PCBiosModeInfoExt pcbios_mode = NULL, matched_mode = NULL; + + dev_mode_size = disp_cbios_get_modes_size(disp_info, output_type); + if(dev_mode_size) + { + dev_mode_buf = gf_calloc(dev_mode_size); + if(dev_mode_buf) + { + dev_real_num = disp_cbios_get_modes(disp_info, output_type, dev_mode_buf, dev_mode_size); + for(i = 0; i < dev_real_num; i++) + { + pcbios_mode = (PCBiosModeInfoExt)dev_mode_buf + i; + if((pcbios_mode->XRes == mode->hdisplay) && + (pcbios_mode->YRes == mode->vdisplay) && + (pcbios_mode->RefreshRate/100 == drm_mode_vrefresh(mode)) && + ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? (pcbios_mode->InterlaceProgressiveCaps == 0x02) : (pcbios_mode->InterlaceProgressiveCaps == 0x01))) + { + matched = 1; + break; + } + } + } + } + + if(!matched && disp_info->scale_support) + { + for(i = 0; i < dev_real_num; i++) + { + pcbios_mode = (PCBiosModeInfoExt)dev_mode_buf + i; + if(pcbios_mode->XRes >= mode->hdisplay && pcbios_mode->YRes >= mode->vdisplay && + pcbios_mode->RefreshRate/100 >= drm_mode_vrefresh(mode)) + { + if(pcbios_mode->isPreferredMode) + { + matched_mode = pcbios_mode; + break; + } + else if(!matched_mode) + { + matched_mode = pcbios_mode; + } + } + } + + if(matched_mode) + { + if(adjusted_mode) + { + disp_cbios_cbmode_to_drmmode(disp_info, output_type, matched_mode, 0, adjusted_mode); + } + matched = 1; + } + } + + if (adjusted_mode && matched) + { +#if DRM_VERSION_CODE < KERNEL_VERSION(5,9,0) + adjusted_mode->vrefresh = drm_mode_vrefresh(adjusted_mode); +#endif + disp_cbios_get_mode_timing(disp_info, output_type, adjusted_mode); + } + + if (dev_mode_buf) + { + gf_free(dev_mode_buf); + dev_mode_buf = NULL; + } + + return (matched)? TRUE : FALSE; +} + +static bool gf_encoder_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device* dev = encoder->dev; + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_encoder_t *gf_encoder = to_gf_encoder(encoder); + + return gf_encoder_mode_fixup_internal(disp_info, gf_encoder->output_type, mode, adjusted_mode); +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + +void gf_encoder_atomic_mode_set(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct drm_device* dev = encoder->dev; + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + struct drm_display_mode* mode = &crtc_state->mode; + struct drm_display_mode* adj_mode = &crtc_state->adjusted_mode; + struct drm_crtc* crtc = NULL; + int flag = 0; + + //in atomic set phase, atomic state is updated to state of crtc/encoder/connector, + //so we can't roll back mode setting, that means all parameter check should be placed in + //atomic check function, and now all para is correct, we only need flush them to HW register + //but we still add para check code here tempararily, it will be removed after code stable. + + crtc = encoder->crtc; + + if (!crtc) + { + DRM_ERROR("crtc is NULL\n"); + return; + } + + DRM_DEBUG_KMS("encoder=%d,crtc=%d\n", encoder->index, crtc->index); + flag |= UPDATE_ENCODER_MODE_FLAG; + + disp_cbios_set_mode(disp_info, drm_crtc_index(crtc), mode, adj_mode, flag); +} + +#else + +void gf_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device* dev = encoder->dev; + struct drm_crtc* crtc = encoder->crtc; + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + int flag = 0; + + if(!crtc) + { + gf_assert(0, GF_FUNC_NAME(__func__)); + } + + flag = UPDATE_ENCODER_MODE_FLAG; + + disp_cbios_set_mode(disp_info, to_gf_crtc(crtc)->pipe, mode, adjusted_mode, flag); +} + +#endif + +static const struct drm_encoder_funcs gf_encoder_funcs = +{ + .destroy = gf_encoder_destroy, +}; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + +static const struct drm_encoder_helper_funcs gf_encoder_helper_funcs = +{ + .disable = gf_encoder_disable, + .enable = gf_encoder_enable, + .mode_fixup = gf_encoder_mode_fixup, +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + .atomic_mode_set = gf_encoder_atomic_mode_set, +#endif +}; + +#else + +static const struct drm_encoder_helper_funcs gf_encoder_helper_funcs = +{ + .mode_fixup = gf_encoder_mode_fixup, + .prepare = gf_encoder_disable, + .commit = gf_encoder_enable, + .mode_set = gf_encoder_mode_set, + .disable = gf_encoder_disable, +}; + +#endif + +struct drm_encoder* disp_encoder_init(disp_info_t* disp_info, disp_output_type output) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + struct drm_encoder* encoder = NULL; + gf_encoder_t* gf_encoder = NULL; + int encoder_type = 0; + + gf_encoder = gf_calloc(sizeof(gf_encoder_t)); + if (!gf_encoder) + { + return NULL; + } + + encoder = &gf_encoder->base_encoder; + encoder->possible_clones = 0; + encoder->possible_crtcs = disp_cbios_get_crtc_mask(disp_info, output); + + switch (output) + { + case DISP_OUTPUT_CRT: + encoder_type = DRM_MODE_ENCODER_DAC; + break; + case DISP_OUTPUT_DP1: + case DISP_OUTPUT_DP2: + case DISP_OUTPUT_DP3: + case DISP_OUTPUT_DP4: + encoder_type = DRM_MODE_ENCODER_TMDS; + break; + default: + encoder_type = DRM_MODE_ENCODER_NONE; + break; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) || defined PHYTIUM_2000 + drm_encoder_init(drm, encoder, &gf_encoder_funcs, encoder_type, NULL); +#else + drm_encoder_init(drm, encoder, &gf_encoder_funcs, encoder_type); +#endif + drm_encoder_helper_add(encoder, &gf_encoder_helper_funcs); + gf_encoder->output_type = output; + gf_encoder->enc_dpms = GF_DPMS_OFF; + + return encoder; +} diff --git a/drivers/gpu/drm/arise/linux/gf_fbdev.c b/drivers/gpu/drm/arise/linux/gf_fbdev.c new file mode 100644 index 0000000000000..75b82ce93ce54 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_fbdev.c @@ -0,0 +1,358 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_disp.h" +#include "gf_driver.h" +#include "gf_fbdev.h" +#include "gf_debugfs.h" +#include "gf_vip.h" +#include +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 11, 0) +#include +#endif +#include + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + +#define __STR(x) #x +#define STR(x) __STR(x) + +static int gf_drm_fb_set_par(struct fb_info *info) +{ + gf_info("To set par on drm fb.\n"); + + return drm_fb_helper_set_par(info); +} + + +static struct fb_ops gfb_ops = { + .owner = THIS_MODULE, +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + DRM_FB_HELPER_DEFAULT_OPS, +#endif + .fb_set_par = gf_drm_fb_set_par, + .fb_fillrect = drm_fb_helper_cfb_fillrect, + .fb_copyarea = drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, +#else + .fb_check_var = drm_fb_helper_check_var, + .fb_set_par = drm_fb_helper_set_par, + .fb_pan_display = drm_fb_helper_pan_display, + .fb_blank = drm_fb_helper_blank, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) + .fb_debug_enter = drm_fb_helper_debug_enter, + .fb_debug_leave = drm_fb_helper_debug_leave, +#endif + .fb_setcmap = drm_fb_helper_setcmap, + + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, +#endif +}; + +static bool gf_fb_initial_config(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_crtc **crtcs, + struct drm_display_mode **modes, + struct drm_fb_offset *offsets, + bool *enabled, int width, int height) +{ + return false; +} + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 14, 0) +static void gf_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int reqno) +{ + DRM_DEBUG_KMS("crtc=%d,red=%d,green=%d,blue=%d\n", to_gf_crtc(crtc)->pipe, red, green, blue); +} + +static void gf_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, int reqno) +{ + DRM_DEBUG_KMS("crtc=%d\n", to_gf_crtc(crtc)->pipe); +} +#endif + +static int gfb_create(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) +{ +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + int ret = 0; +#endif + struct fb_info *info; + struct gf_fbdev *fbdev = to_gf_fbdev(helper); + struct drm_gf_framebuffer *fb = fbdev->fb; + struct drm_device *dev = helper->dev; + gf_card_t *gf = dev->dev_private; + struct drm_mode_fb_cmd2 mode_cmd = {0, }; + struct drm_gf_gem_object *obj = NULL; + gf_create_allocation_t create = {0, }; + + DRM_DEBUG_KMS("fb_width=%d,fb_height=%d,surface_width=%d,surface_height=%d,surface_bpp=%d,surface_depth=%d\n", + sizes->fb_width, sizes->fb_height, sizes->surface_width, sizes->surface_height, sizes->surface_bpp, sizes->surface_depth); + + mutex_lock(&dev->struct_mutex); + + if (fb && + (sizes->fb_width > fb->base.width || + sizes->fb_height > fb->base.height)) + { +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 12, 0) + drm_framebuffer_unreference(&fb->base); +#else + drm_framebuffer_put(&fb->base); +#endif + fbdev->fb = NULL; + fb = NULL; + } + + if (!fb) + { + create.device = fbdev->gpu_device; + create.width = sizes->surface_width; + create.height = sizes->surface_height; + create.format = (sizes->surface_bpp == 32) ? GF_FORMAT_B8G8R8A8_UNORM : GF_FORMAT_B5G6R5_UNORM; + create.tiled = 0; + create.unpagable = TRUE; + create.usage_mask = GF_USAGE_FORCE_LOCAL | GF_USAGE_DISPLAY_SURFACE | GF_USAGE_FRAMEBUFFER; + create.access_hint = GF_ACCESS_CPU_ALMOST; + create.primary = 1; + + obj = gf_drm_gem_create_object(gf, &create, &fbdev->debug); + + mode_cmd.width = sizes->surface_width; + mode_cmd.height = sizes->surface_height; + mode_cmd.pitches[0] = obj->info.pitch; + mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); + fb = __gf_framebuffer_create(dev, &mode_cmd, obj); + fbdev->fb = fb; + } + else + { + sizes->fb_width = fb->base.width; + sizes->fb_height = fb->base.height; + } + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + info = framebuffer_alloc(0, &dev->pdev->dev); + gf_assert(info != NULL, GF_FUNC_NAME(__func__)); + + info->par = helper; + info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; + info->fbops = &gfb_ops; + + ret = fb_alloc_cmap(&info->cmap, 256, 0); + gf_assert(ret == 0, GF_FUNC_NAME(__func__)); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) + info->apertures = alloc_apertures(1); + gf_assert(info->apertures != NULL, GF_FUNC_NAME(__func__)); + + info->apertures->ranges[0].base = dev->mode_config.fb_base; + info->apertures->ranges[0].size = obj->info.pitch * obj->info.height; +#endif + helper->fbdev = info; +#else +#if DRM_VERSION_CODE < KERNEL_VERSION(6, 2, 0) + info = drm_fb_helper_alloc_fbi(helper); +#else + info = drm_fb_helper_alloc_info(helper); +#endif + info->par = helper; +#if DRM_VERSION_CODE < KERNEL_VERSION(6, 6, 0) + info->flags = FBINFO_DEFAULT; +#endif + info->fbops = &gfb_ops; +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 20, 0) + info->flags |= FBINFO_CAN_FORCE_OUTPUT; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) + info->skip_vt_switch = true; +#endif + + fbdev->helper.fb = &fb->base; + gf_vsprintf(info->fix.id, "drmfb"); + + if(obj) + { + info->fix.smem_start = obj->info.cpu_phy_addr; + info->fix.smem_len = obj->info.pitch * obj->info.aligned_height; + + //map fbdev fb gem object + info->screen_base = gf_gem_object_vmap(obj); + info->screen_size = obj->info.pitch * obj->info.aligned_height; + } + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 11, 0) + drm_fb_helper_fill_fix(info, fb->base.pitches[0], fb->base.depth); + drm_fb_helper_fill_var(info, &fbdev->helper, sizes->fb_width, sizes->fb_height); +#elif DRM_VERSION_CODE < KERNEL_VERSION(5, 2, 0) + drm_fb_helper_fill_fix(info, fb->base.pitches[0], fb->base.format->depth); + drm_fb_helper_fill_var(info, &fbdev->helper, sizes->fb_width, sizes->fb_height); +#else + drm_fb_helper_fill_info(info, &fbdev->helper, sizes); +#endif + + DRM_DEBUG_KMS("screen_base=0x%p,screen_size=0x%lx,smem_start=0x%lx,smem_len=0x%x,xres=%d,yres=%d\n", + info->screen_base, info->screen_size, info->fix.smem_start, info->fix.smem_len, info->var.xres, info->var.yres); + + mutex_unlock(&dev->struct_mutex); + return 0; +} + +static const struct drm_fb_helper_funcs gf_fb_helper_funcs = { +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 2, 0) + .initial_config = gf_fb_initial_config, +#endif +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + .gamma_set = gf_crtc_fb_gamma_set, + .gamma_get = gf_crtc_fb_gamma_get, +#endif + .fb_probe = gfb_create, +#if DRM_VERSION_CODE >= KERNEL_VERSION(6, 2, 0) + .fb_dirty = gfb_dirty, +#endif +}; + +int gf_fbdev_init(gf_card_t *gf) +{ + int ret; + struct gf_fbdev *fbdev; + + DRM_DEBUG_KMS("gf=%p\n", gf); + + fbdev = gf_calloc(sizeof(*fbdev)); + if (!fbdev) + { + gf_error("alloc fbdev failed\n"); + return -ENOMEM; + } + + gf_assert(fbdev != NULL, GF_FUNC_NAME(__func__)); + + ret = gf_core_interface->create_device(gf->adapter, NULL, &fbdev->gpu_device); + + fbdev->debug = gf_debugfs_add_device_node(gf->debugfs_dev, gf_get_current_pid(), fbdev->gpu_device); + drm_fb_helper_prepare(gf->drm_dev, &fbdev->helper, &gf_fb_helper_funcs); + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 11, 0) + ret = drm_fb_helper_init(gf->drm_dev, &fbdev->helper, ((disp_info_t*)(gf->disp_info))->num_crtc, 4); +#else + ret = drm_fb_helper_init(gf->drm_dev, &fbdev->helper, 4); +#endif + gf_assert(ret == 0, GF_FUNC_NAME(__func__)); + + drm_fb_helper_single_add_all_connectors(&fbdev->helper); + + drm_fb_helper_initial_config(&fbdev->helper, 32); + + gf->fbdev = fbdev; + + return 0; +} + + +int gf_fbdev_deinit(gf_card_t *gf) +{ + struct gf_fbdev *fbdev = gf->fbdev; + struct drm_gf_framebuffer *fb = NULL; + struct fb_info *info; + + if (!fbdev) + { + return 0; + } + + fb = fbdev->fb; + + info = fbdev->helper.fbdev; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + unregister_framebuffer(info); +#else + drm_fb_helper_unregister_fbi(&fbdev->helper); +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + iounmap(info->screen_base); + if (info->cmap.len) + fb_dealloc_cmap(&info->cmap); + framebuffer_release(info); +#elif DRM_VERSION_CODE < KERNEL_VERSION(4, 12, 0) + drm_fb_helper_release_fbi(&fbdev->helper); +#endif + + if (fb->obj) + { + gf_gem_object_vunmap(fb->obj); + gf_gem_object_put(fb->obj); + fb->obj = NULL; + drm_framebuffer_unregister_private(&fb->base); + drm_framebuffer_cleanup(&fb->base); + } + drm_fb_helper_fini(&fbdev->helper); + gf_free(fbdev); + + return 0; +} + +void gf_fbdev_restore_mode(gf_card_t *gf) +{ + struct gf_fbdev *fbdev = gf->fbdev; + + if (fbdev) + { + drm_fb_helper_restore_fbdev_mode_unlocked(&fbdev->helper); + } +} + +void gf_fbdev_set_suspend(gf_card_t *gf, int state) +{ + struct gf_fbdev *fbdev = gf->fbdev; + struct fb_info *info; + + if (fbdev) + { + console_lock(); + + info = fbdev->helper.fbdev; + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + if (info) + fb_set_suspend(info, state); +#else + drm_fb_helper_set_suspend(&fbdev->helper, state); +#endif + + console_unlock(); + } +} + +void gf_fbdev_poll_changed(struct drm_device *dev) +{ + gf_card_t* gf = dev->dev_private; + struct gf_fbdev *fbdev = gf->fbdev; + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + if (fbdev && fbdev->fb) +#else + if (fbdev) +#endif + { + drm_fb_helper_hotplug_event(&fbdev->helper); + } +} + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_fbdev.h b/drivers/gpu/drm/arise/linux/gf_fbdev.h new file mode 100644 index 0000000000000..baa0181c1315c --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_fbdev.h @@ -0,0 +1,39 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _H_GF_FBDEV_H +#define _H_GF_FBDEV_H +#include "gf_drmfb.h" +#include "gf_device_debug.h" + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + +struct gf_fbdev +{ + unsigned int gpu_device; + struct drm_fb_helper helper; + struct drm_gf_framebuffer *fb; + gf_device_debug_info_t *debug; +}; + +#define to_gf_fbdev(helper) container_of(helper, struct gf_fbdev, helper) + +int gf_fbdev_init(gf_card_t *gf); +int gf_fbdev_deinit(gf_card_t *gf); +void gf_fbdev_set_suspend(gf_card_t *gf, int state); +void gf_fbdev_restore_mode(gf_card_t *gf); +void gf_fbdev_poll_changed(struct drm_device *dev); +#endif + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_fence.c b/drivers/gpu/drm/arise/linux/gf_fence.c new file mode 100644 index 0000000000000..44cfc82bc3449 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_fence.c @@ -0,0 +1,604 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_fence.h" +#include "gf_gem.h" +#include "gf_gem_priv.h" +#include "gf_trace.h" + +static const char *engine_name[MAX_ENGINE_COUNT] = { + "ring0", + "ring1", + "ring2", + "ring3", + "ring4", + "ring5", + "ring6", + "ring7", + "ring8", + "ring9", +}; + +static struct gf_dma_fence_driver *fence_driver = NULL; + +static bool gf_dma_fence_signaled(dma_fence_t *base) +{ + struct gf_dma_fence *fence = to_gf_fence(base); + + return gf_core_interface->is_fence_back(fence->driver->adapter, gf_engine_by_fence(fence->driver, base), fence->value); +} + +static bool gf_dma_fence_enable_signaling(dma_fence_t *base) +{ + bool ret = true; + struct gf_dma_fence *fence = to_gf_fence(base); + struct gf_dma_fence_driver *driver = fence->driver; + struct gf_dma_fence_context *context = gf_context_by_fence(driver, base); + + trace_gfx_dma_fence_enable_signaling(base); + + assert_spin_locked(&context->lock); + if (gf_dma_fence_signaled(base)) + return false; + + spin_lock(&driver->lock); + if (gf_dma_fence_signaled(base)) + { + ret = false; + goto unlock; + } + dma_fence_get(base); + list_add_tail(&fence->link, &driver->fence_list); + gf_get_nsecs(&fence->enqueue_time); + atomic_inc(&driver->fence_count); + +unlock: + spin_unlock(&driver->lock); + return ret; +} + +signed long gf_dma_fence_wait(dma_fence_t *base, bool intr, signed long timeout) +{ + trace_gfx_dma_fence_wait(base, intr, timeout); + + return dma_fence_default_wait(base, intr, timeout); +} + +static void gf_dma_fence_free(struct rcu_head *rcu) +{ + dma_fence_t *base = container_of(rcu, dma_fence_t, rcu); + struct gf_dma_fence *fence = to_gf_fence(base); + + if (fence_driver != fence->driver) + gf_info("detect someone trying to write fence:0x%llx\n", fence->driver); + + atomic_dec(&fence_driver->fence_alloc_count); + + kmem_cache_free(fence_driver->fence_slab, fence); +} + +static void gf_dma_fence_release(dma_fence_t *base) +{ + call_rcu(&base->rcu, gf_dma_fence_free); +} + +static const char *gf_dma_fence_get_driver_name(dma_fence_t *fence) +{ + return "gf"; +} + +static const char *gf_dma_fence_get_timeline_name(dma_fence_t *fence_) +{ + struct gf_dma_fence *fence = to_gf_fence(fence_); + + if (gf_dma_fence_signaled(fence_)) + return "signaled"; + else if (fence->value == fence->initialize_value) + return "swq"; + else + return engine_name[gf_engine_by_fence(fence->driver, fence_)]; +} + +static dma_fence_ops_t gf_dma_fence_ops = { + .get_driver_name = gf_dma_fence_get_driver_name, + .enable_signaling = gf_dma_fence_enable_signaling, + .signaled = gf_dma_fence_signaled, + .wait = gf_dma_fence_wait, + .release = gf_dma_fence_release, + .get_timeline_name = gf_dma_fence_get_timeline_name, +}; + +static void *gf_dma_fence_create_cb(void *driver_, unsigned int engine_index, unsigned long long initialize_value) +{ + unsigned int seq; + struct gf_dma_fence *fence; + struct gf_dma_fence_driver *driver = driver_; + struct gf_dma_fence_context *context = gf_context_by_engine(driver, engine_index); + + fence = kmem_cache_alloc(driver->fence_slab, GFP_KERNEL); + if (fence == NULL) + return NULL; + + seq = ++context->sync_seq; + fence->initialize_value = + fence->value = initialize_value; + fence->driver = driver; + gf_get_nsecs(&fence->create_time); + INIT_LIST_HEAD(&fence->link); + dma_fence_init(&fence->base, &gf_dma_fence_ops, &context->lock, context->id, seq); + + atomic_inc(&driver->fence_alloc_count); + + return fence; +} + +static void gf_dma_fence_attach_bo_cb(void *driver_, void *bo_, void *fence_, int readonly) +{ + struct drm_gf_gem_object *bo = bo_; + struct gf_dma_fence *fence = fence_; + + reservation_object_lock(bo->resv, NULL); + if (!readonly) + { +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,19,0) + if (reservation_object_reserve_shared(bo->resv,1) == 0) +#endif + { + reservation_object_add_excl_fence(bo->resv, &fence->base); + } + } +#if DRM_VERSION_CODE < KERNEL_VERSION(5,0,0) + else if (reservation_object_reserve_shared(bo->resv) == 0) +#else + else if (reservation_object_reserve_shared(bo->resv,1) == 0) +#endif + { + reservation_object_add_shared_fence(bo->resv, &fence->base); + } + reservation_object_unlock(bo->resv); +} + +static void gf_dma_fence_release_cb(void *driver, void *fence_) +{ + struct gf_dma_fence *fence = fence_; + + dma_fence_put(&fence->base); +} + +static void gf_dma_fence_post_event_cb(void *driver_) +{ + struct gf_dma_fence_driver *driver = driver_; + + if (driver && atomic_read(&driver->fence_count) > 0) + { + gf_thread_wake_up(driver->event); + } +} + +static void gf_dma_fence_update_value_cb(void *driver_, void *fence_, unsigned long long value) +{ + struct gf_dma_fence *fence = fence_; + + fence->value = value; +} + +struct gf_dma_sync_object_fence_cb +{ + dma_fence_cb_t cb; + struct gf_dma_sync_object *sync_obj; +}; + +struct gf_dma_sync_object +{ + dma_fence_t base; + + spinlock_t lock; + unsigned num_fences; + atomic_t num_pending; + dma_fence_t **fences; + + dma_fence_cb_t cb; + void (*callback)(void *); + void *arg; + + struct gf_dma_sync_object_fence_cb *fence_cb; +}; + +static const char *gf_dma_sync_object_get_driver_name(dma_fence_t *fence) +{ + return "gf_dma_sync_object"; +} + +static const char *gf_dma_sync_object_get_timeline_name(dma_fence_t *fence) +{ + return "unbound"; +} + +static void gf_dma_sync_object_fence_cb_func(dma_fence_t *f, dma_fence_cb_t *cb) +{ + struct gf_dma_sync_object_fence_cb *fence_cb = container_of(cb, struct gf_dma_sync_object_fence_cb, cb); + struct gf_dma_sync_object *sync_obj = fence_cb->sync_obj; + + if (atomic_dec_and_test(&sync_obj->num_pending)) + { + dma_fence_signal(&sync_obj->base); + } + + dma_fence_put(&sync_obj->base); +} + +static bool gf_dma_sync_object_enable_signaling(dma_fence_t *fence) +{ + struct gf_dma_sync_object *sync_obj = container_of(fence, struct gf_dma_sync_object, base); + unsigned i; + + for (i = 0; i < sync_obj->num_fences; ++i) + { + sync_obj->fence_cb[i].sync_obj = sync_obj; + dma_fence_get(&sync_obj->base); + if (dma_fence_add_callback(sync_obj->fences[i], &sync_obj->fence_cb[i].cb, gf_dma_sync_object_fence_cb_func)) + { + dma_fence_put(&sync_obj->base); + if (atomic_dec_and_test(&sync_obj->num_pending)) + { + return false; + } + } + } + + return true; +} + +static bool gf_dma_sync_object_signaled(dma_fence_t *fence) +{ + struct gf_dma_sync_object *sync_obj = container_of(fence, struct gf_dma_sync_object, base); + + return atomic_read(&sync_obj->num_pending) <= 0; +} + +static void gf_dma_sync_object_release(dma_fence_t *fence) +{ + struct gf_dma_sync_object *sync_obj = container_of(fence, struct gf_dma_sync_object, base); + unsigned i; + + for (i = 0; i < sync_obj->num_fences; ++i) + { + dma_fence_put(sync_obj->fences[i]); + } + + gf_free(sync_obj); +} + +static dma_fence_ops_t gf_dma_sync_object_ops = +{ + .get_driver_name = gf_dma_sync_object_get_driver_name, + .get_timeline_name = gf_dma_sync_object_get_timeline_name, + .enable_signaling = gf_dma_sync_object_enable_signaling, + .signaled = gf_dma_sync_object_signaled, + .wait = dma_fence_default_wait, + .release = gf_dma_sync_object_release, +}; + +static void gf_dma_sync_object_callback(dma_fence_t *fence, dma_fence_cb_t *cb) +{ + struct gf_dma_sync_object *sync_obj = container_of(cb, struct gf_dma_sync_object, cb); + + sync_obj->callback(sync_obj->arg); +} + +static int gf_dma_sync_object_is_signaled_cb(void *sync_obj_) +{ + struct gf_dma_sync_object *sync_obj = sync_obj_; + + return dma_fence_is_signaled(&sync_obj->base); +} + +static struct gf_dma_sync_object *gf_dma_sync_object_alloc(struct gf_dma_fence_context *context, int max_fence_count, void (*callback)(void*), void* arg) +{ + int extra_size = max_fence_count * (sizeof(struct gf_dma_sync_object_fence_cb) + sizeof(dma_fence_t*)); + struct gf_dma_sync_object *sync_obj = gf_calloc(sizeof(*sync_obj) + extra_size); + + spin_lock_init(&sync_obj->lock); + dma_fence_init(&sync_obj->base, &gf_dma_sync_object_ops, &sync_obj->lock, context->id, ++context->sync_seq); + + sync_obj->fence_cb = (void*)(sync_obj + 1); + sync_obj->fences = (void*)(sync_obj->fence_cb + max_fence_count); + + sync_obj->num_fences = 0; + atomic_set(&sync_obj->num_pending, 0); + sync_obj->callback = callback; + sync_obj->arg = arg; + + return sync_obj; +} + +static void* gf_dma_sync_object_create_cb(void *driver_, void *bo_, int write, int engine, void (*callback)(void*), void* arg) +{ + struct gf_dma_fence_driver *driver = driver_; + struct gf_dma_fence_context *context = gf_context_by_engine(driver, engine); + struct drm_gf_gem_object *bo = bo_; + struct gf_dma_sync_object *sync_obj = NULL; + int ret; + int i, fence_count = 0; + dma_fence_t **fences = NULL; + + ret = reservation_get_fences(bo->resv, write, &fence_count, &fences); + gf_assert(ret == 0, GF_FUNC_NAME(__func__)); + + for (i = 0; i < fence_count; i++) + { + if (fences[i]->context != context->id) + { + if (!sync_obj) + { + sync_obj = gf_dma_sync_object_alloc(context, fence_count - i, callback, arg); + } + + sync_obj->fences[sync_obj->num_fences++] = fences[i]; + } + else + { + dma_fence_put(fences[i]); + } + } + + if (fences) + kfree(fences); + + if (sync_obj) + { + atomic_set(&sync_obj->num_pending, sync_obj->num_fences); + + if (dma_fence_add_callback(&sync_obj->base, &sync_obj->cb, gf_dma_sync_object_callback)) + { + dma_fence_put(&sync_obj->base); + sync_obj = NULL; + } + } + + return sync_obj; +} + +static void gf_dma_sync_object_release_cb(void *sync_obj_) +{ + struct gf_dma_sync_object *sync_obj = sync_obj_; + + dma_fence_put(&sync_obj->base); +} + +static void gf_fence_dump(struct gf_dma_fence *fence) +{ + gf_info(" DmaFence %p baseid:%lld context:%lld value:%lld flags:0x%x\n", fence,fence->driver->base_context_id, fence->base.context, fence->value, fence->base.flags); +} + +static long gf_dma_sync_object_wait_cb(void *driver, void *sync_obj_, unsigned long long timeout) +{ + struct gf_dma_sync_object *sync_obj = sync_obj_; + + return dma_fence_wait_timeout(&sync_obj->base, FALSE, gf_do_div(timeout * HZ, 1000)); +} + +static void gf_dma_sync_object_dump_cb(void *sync_obj_) +{ + int i; + struct gf_dma_sync_object *sync_obj = sync_obj_; + + gf_info("FenceArray %p, count:%d, flags:%x signal:%d\n", + sync_obj, sync_obj->num_fences, sync_obj->base.flags, dma_fence_is_signaled(&sync_obj->base)); + + for (i = 0; i < sync_obj->num_fences; i++) + { + dma_fence_t *fence = sync_obj->fences[i]; + + if (fence && fence->ops == &gf_dma_fence_ops) + { + gf_fence_dump(to_gf_fence(fence)); + } + } +} + +static gf_drm_callback_t gf_drm_callback = +{ + .fence = { + .create = gf_dma_fence_create_cb, + .attach_buffer= gf_dma_fence_attach_bo_cb, + .update_value = gf_dma_fence_update_value_cb, + .release = gf_dma_fence_release_cb, + .notify_event = gf_dma_fence_post_event_cb, + + .dma_sync_object_create = gf_dma_sync_object_create_cb, + .dma_sync_object_release = gf_dma_sync_object_release_cb, + .dma_sync_object_is_signaled = gf_dma_sync_object_is_signaled_cb, + .dma_sync_object_wait = gf_dma_sync_object_wait_cb, + .dma_sync_object_dump = gf_dma_sync_object_dump_cb, + }, + + .gem = { + .get_from_handle = gf_get_from_gem_handle, + }, +}; + +static int gf_dma_fence_event_thread(void *data) +{ + int ret = 0; + struct list_head process_list; + struct gf_dma_fence *fence, *tmp; + struct gf_dma_fence_driver *driver = data; + int try_freeze_num = 0; + + gf_set_freezable(); + INIT_LIST_HEAD(&process_list); + + do { + ret = gf_thread_wait(driver->event, driver->timeout_msec); + +try_again1: + spin_lock(&driver->lock); + list_splice_init(&driver->fence_list, &process_list); + spin_unlock(&driver->lock); + +try_again2: + list_for_each_entry_safe(fence, tmp, &process_list, link) + { + if (gf_dma_fence_signaled(&fence->base)) + { + list_del(&fence->link); + atomic_dec(&driver->fence_count); + dma_fence_signal(&fence->base); + dma_fence_put(&fence->base); + } + } + + if (driver->can_freeze) + { + if(gf_freezing()) + { + if (!list_empty(&process_list)) + { + gf_msleep(10); //relase CPU wait 10ms, and try_again + + if (++try_freeze_num > 100) + { + gf_info("dma fence event thread! try freezing count %d \n", try_freeze_num); + try_freeze_num = 0; + } + goto try_again2; + }else if(!list_empty(&driver->fence_list)){ + goto try_again1; + } + gf_info("sleep fence thread! freezing\n"); + } + + spin_lock(&driver->lock); + list_splice_init(&process_list, &driver->fence_list); + spin_unlock(&driver->lock); + if(gf_try_to_freeze()) + gf_info("dma fence thread resumed!\n"); + } + } while(!gf_thread_should_stop()); + + return 0; +} + +long gf_gem_fence_await_reservation(struct reservation_object *resv, int exclude_self, long timeout, int write) +{ + int ret = 0; + dma_fence_t **fences = NULL; + unsigned int fence_count = 0, i; + + if (timeout == 0) + timeout = 1; + + ret = reservation_get_fences(resv, write, &fence_count, &fences); + if (ret) + return (long)ret; + + for (i = 0; i < fence_count; i++) + { + if (exclude_self && fences[i]->ops == &gf_dma_fence_ops) + continue; + + timeout = dma_fence_wait_timeout(fences[i], 0, timeout); + if (timeout < 0) + break; + } + + for (i = 0; i < fence_count; i++) + { + dma_fence_put(fences[i]); + } + + if (fences) + kfree(fences); + + if (timeout <= 0) + gf_warning("wait fences timeout or interrupted:%d\n", timeout); + + return timeout; +} + +int gf_dma_fence_driver_init(void *adapter, struct gf_dma_fence_driver *driver) +{ + int i; + int engine_count = MAX_ENGINE_COUNT; + + driver->adapter = adapter; + driver->base_context_id = dma_fence_context_alloc(engine_count); + driver->context = gf_calloc(sizeof(struct gf_dma_fence_context) * engine_count); + spin_lock_init(&driver->lock); + driver->fence_slab = kmem_cache_create( + "gf_dma_fence", sizeof(struct gf_dma_fence), 0, SLAB_HWCACHE_ALIGN, NULL); + gf_assert(driver->fence_slab != NULL, GF_FUNC_NAME(__func__)); + for (i = 0; i < engine_count; i++) + { + driver->context[i].id = driver->base_context_id + i; + driver->context[i].sync_seq = 0; + spin_lock_init(&driver->context[i].lock); + } + gf_core_interface->set_callback_func(adapter, OS_CALLBACK_DRM_CB, &gf_drm_callback, driver); + + atomic_set(&driver->fence_count, 0); + driver->timeout_msec = -1; + driver->can_freeze = TRUE; + driver->event = gf_create_event(0); + atomic_set(&driver->fence_alloc_count, 0); + INIT_LIST_HEAD(&driver->fence_list); + driver->os_thread = gf_create_thread(gf_dma_fence_event_thread, driver, "dma_fenced"); + + /** + * TODO: remove this + */ + fence_driver = driver; + + return 0; +} + +void gf_dma_fence_driver_fini(struct gf_dma_fence_driver *driver) +{ + gf_destroy_thread(driver->os_thread); + + gf_destroy_event(driver->event); + driver->event = NULL; + + if(driver->context) + { + gf_free(driver->context); + driver->context = NULL; + } + + rcu_barrier(); + kmem_cache_destroy(driver->fence_slab); + driver->fence_slab = NULL; +} + +void gf_dma_track_fences_dump(gf_card_t *card) +{ + struct gf_dma_fence_driver *driver = card->fence_drv; + struct gf_dma_fence *fence; + unsigned long long now; + + spin_lock(&driver->lock); + gf_get_nsecs(&now); + gf_info("now:%lld, fence_alloc_count: %d, queue_count: %d\n", now, atomic_read(&driver->fence_alloc_count), atomic_read(&driver->fence_count)); + list_for_each_entry(fence, &driver->fence_list, link) + { + gf_info(" fence:%p value:%lld context:%d seqno:%d create:%lld enqueue:%lld.\n", + fence, fence->value, fence->base.context, fence->base.seqno, fence->create_time, fence->enqueue_time); + } + spin_unlock(&driver->lock); +} + +void gf_dma_track_fences_clear(gf_card_t *card) +{ +} diff --git a/drivers/gpu/drm/arise/linux/gf_fence.h b/drivers/gpu/drm/arise/linux/gf_fence.h new file mode 100644 index 0000000000000..9d5dc42ac032d --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_fence.h @@ -0,0 +1,254 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _H_GF_FENCE_H +#define _H_GF_FENCE_H + +#include "gf_driver.h" + +#if DRM_VERSION_CODE < KERNEL_VERSION(4,10,0) +#include +#else +#include +#endif + + +#if DRM_VERSION_CODE < KERNEL_VERSION(4,11,0) +#define reservation_object_lock(resv, a) ww_mutex_lock(&(resv)->lock, (a)) +#define reservation_object_unlock(resv) ww_mutex_unlock(&(resv)->lock) +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(4,10,0) +typedef struct fence dma_fence_t; +typedef struct fence_ops dma_fence_ops_t; +typedef struct fence_cb dma_fence_cb_t; +#define dma_fence_init fence_init +#define dma_fence_get fence_get +#define dma_fence_put fence_put +#define dma_fence_wait fence_wait +#define dma_fence_signal fence_signal +#define dma_fence_default_wait fence_default_wait +#define dma_fence_context_alloc fence_context_alloc +#define dma_fence_is_signaled fence_is_signaled +#define dma_fence_wait_timeout fence_wait_timeout +#define dma_fence_add_callback fence_add_callback +#else +typedef struct dma_fence dma_fence_t; +typedef struct dma_fence_ops dma_fence_ops_t; +typedef struct dma_fence_cb dma_fence_cb_t; +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,4,0) +#include +#define reservation_object dma_resv +#define reservation_object_init dma_resv_init +#define reservation_object_fini dma_resv_fini +#define reservation_object_lock dma_resv_lock +#define reservation_object_unlock dma_resv_unlock + +#if DRM_VERSION_CODE < KERNEL_VERSION(5,19,0) +#define reservation_object_reserve_shared dma_resv_reserve_shared +#define reservation_object_add_excl_fence dma_resv_add_excl_fence +#define reservation_object_add_shared_fence dma_resv_add_shared_fence +#else +#define reservation_object_reserve_shared dma_resv_reserve_fences +static inline void reservation_object_add_excl_fence(struct reservation_object *obj, dma_fence_t *fence) +{ + dma_resv_add_fence(obj, fence, DMA_RESV_USAGE_WRITE); +} +static inline void reservation_object_add_shared_fence(struct reservation_object *obj, dma_fence_t *fence) +{ + dma_resv_add_fence(obj, fence, DMA_RESV_USAGE_READ); +} +#endif + +// __reservation_object_get_fences_rcu should be a help function just in this file, shouldn't call it anywhere else. +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,14,0) +#define __reservation_object_get_fences_rcu dma_resv_get_fences +#if DRM_VERSION_CODE < KERNEL_VERSION(5,17,0) +#define gf_reservation_object_get_excl_rcu dma_resv_get_excl_unlocked +#elif DRM_VERSION_CODE >= KERNEL_VERSION(5,19,0) +static inline dma_fence_t* gf_reservation_object_get_excl_rcu(struct reservation_object *obj) +{ + dma_fence_t **fences = NULL; + dma_fence_t *fence = NULL; + int count, i, ret; + int max_index = 0; + + ret = dma_resv_get_fences(obj, DMA_RESV_USAGE_WRITE, &count, &fences); + if (ret != 0 || count < 1) + return NULL; + + for (i = 1; i < count; i++) + { + if(fences[max_index]->seqno < fences[i]->seqno) + { + dma_fence_put(fences[max_index]); + max_index = i; + } + else + dma_fence_put(fences[i]); + } + + return fences[max_index]; +} +#else // DRM_VERSION_CODE < KERNEL_VERSION(5,17,0) +static inline dma_fence_t* gf_reservation_object_get_excl_rcu(struct reservation_object *obj) +{ + dma_fence_t *fence; + rcu_read_lock(); + fence = dma_resv_excl_fence(obj); + if (fence) + dma_fence_get(fence); + rcu_read_unlock(); + + return fence; +} +#endif // DRM_VERSION_CODE < KERNEL_VERSION(5,17,0) +#else // DRM_VERSION_CODE >= KERNEL_VERSION(5,14,0) +#define __reservation_object_get_fences_rcu dma_resv_get_fences_rcu +#define gf_reservation_object_get_excl_rcu dma_resv_get_excl_rcu +#endif // DRM_VERSION_CODE >= KERNEL_VERSION(5,14,0) + +#else // DRM_VERSION_CODE >= KERNEL_VERSION(5,4,0) +#include +#define __reservation_object_get_fences_rcu reservation_object_get_fences_rcu +#if DRM_VERSION_CODE >= KERNEL_VERSION(4,10,0) +#define gf_reservation_object_get_excl_rcu reservation_object_get_excl_rcu +#else //DRM_VERSION_CODE >= KERNEL_VERSION(4,10,0) +static inline dma_fence_t *gf_reservation_object_get_excl_rcu(struct reservation_object *obj) +{ + dma_fence_t *fence; + unsigned retry = 1; + + if (!rcu_access_pointer(obj->fence_excl)) + return NULL; + + while(retry) + { + unsigned seq = read_seqcount_begin(&obj->seq); + rcu_read_lock(); + fence = rcu_dereference(obj->fence_excl); + retry = read_seqcount_retry(&obj->seq, seq); + if (retry) + goto unlock; + if (fence && !fence_get_rcu(fence)) + { + retry = 1; + } +unlock: + rcu_read_unlock(); + } + return fence; +} +#endif +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,19,0) +static inline int reservation_get_fences(struct reservation_object *obj, bool write, unsigned int *num_fences, dma_fence_t ***fences) +{ + enum dma_resv_usage usage = write ? DMA_RESV_USAGE_READ: DMA_RESV_USAGE_WRITE; + + return dma_resv_get_fences(obj, usage, num_fences, fences); +} +#elif DRM_VERSION_CODE < KERNEL_VERSION(5,18,0) +static inline int reservation_get_fences(struct reservation_object *obj, bool write, unsigned int *num_fences, dma_fence_t ***fences) +{ + int ret = 0; + dma_fence_t *excl = NULL; + + while(*num_fences) + dma_fence_put((*fences)[--(*num_fences)]); + + if (write) { + ret = __reservation_object_get_fences_rcu(obj, &excl, num_fences, fences); + if (ret) + return ret; + if (excl) { + // append excl fence to the array + *fences = krealloc(*fences, (*num_fences + 1) * sizeof(void*), GFP_KERNEL); + (*fences)[(*num_fences)++] = excl; + } + } else { + excl = gf_reservation_object_get_excl_rcu(obj); + if (excl) { + *fences = krealloc(*fences, sizeof(void*), GFP_KERNEL); + (*fences)[0] = excl; + *num_fences = 1; + } + } + return ret; +} +#else +#define reservation_get_fences dma_resv_get_fences +#endif + +struct gf_dma_fence_driver; + +struct gf_dma_fence +{ + struct gf_dma_fence_driver *driver; + dma_fence_t base; + unsigned long long initialize_value; + unsigned long long value; + + unsigned long long create_time; + unsigned long long enqueue_time; + struct list_head link; +}; + +#define to_gf_fence(fence) \ + container_of(fence, struct gf_dma_fence, base) + +struct gf_dma_fence_context +{ + unsigned long long id; + spinlock_t lock; + unsigned int sync_seq; +}; + +struct gf_dma_fence_driver +{ + void *adapter; + void *os_thread; + struct os_wait_event *event; + int timeout_msec; + int can_freeze; + spinlock_t lock; + struct list_head fence_list; + atomic_t fence_count; + unsigned long long base_context_id; + struct gf_dma_fence_context *context; + struct kmem_cache *fence_slab; + atomic_t fence_alloc_count; +}; + +#define gf_engine_by_fence(driver, fence) \ + ((fence)->context - (driver)->base_context_id) + +#define gf_context_by_fence(driver, fence) \ + ((driver)->context + (fence)->context - (driver)->base_context_id) + +#define gf_context_by_engine(driver, engine) \ + ((driver)->context + (engine)) + + +int gf_dma_fence_driver_init(void *adapter, struct gf_dma_fence_driver *driver); +void gf_dma_fence_driver_fini(struct gf_dma_fence_driver *driver); +signed long gf_dma_fence_wait(dma_fence_t *base, bool intr, signed long timeout); +signed long gf_gem_fence_await_reservation(struct reservation_object *resv, int exclude_self, long timeout, int write); + +void gf_dma_track_fences_dump(gf_card_t *card); +void gf_dma_track_fences_clear(gf_card_t *card); +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_gem.c b/drivers/gpu/drm/arise/linux/gf_gem.c new file mode 100644 index 0000000000000..33c227bd216fa --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_gem.c @@ -0,0 +1,1989 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf.h" +#include "gf_debugfs.h" +#include "gf_gem.h" +#include "gf_gem_priv.h" +#include "gf_fence.h" +#include "gf_driver.h" +#include "gf_trace.h" +#include "os_interface.h" + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) +MODULE_IMPORT_NS(DMA_BUF); +#endif + +extern struct os_pages_memory* gf_allocate_pages_memory_struct(int page_cnt, struct sg_table *st); +extern void gf_pages_memory_extract_st(struct os_pages_memory *memory); +extern unsigned char gf_validate_page_cache(struct os_pages_memory *memory, int start_page, int end_page, unsigned char request_cache_type); +int gf_gem_debugfs_add_object(struct drm_gf_gem_object *obj); +void gf_gem_debugfs_remove_object(struct drm_gf_gem_object *obj); + +#define GF_DEFAULT_PREFAULT_NUM 16 +#define NUM_PAGES(x) (((x) + PAGE_SIZE-1) / PAGE_SIZE) + +#if DRM_VERSION_CODE < KERNEL_VERSION(5,18,0) +#define DMABUF_PREFIX(x) dma_buf_##x +#else +#define DMABUF_PREFIX(x) iosys_##x +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(5,11,0) +#define DMA_BUF_MAP_CLEAR() do {} while(0) +#else +#define DMA_BUF_MAP_CLEAR() do { DMABUF_PREFIX(map_clear)(map); } while(0) +#endif + +unsigned int gf_get_from_gem_handle(void *file_, unsigned int handle) +{ + struct drm_file *file = file_; + gf_file_t *priv = file->driver_priv; + + return gf_gem_get_core_handle(priv, handle); +} + +static int gf_gem_object_pin_pages(struct drm_gf_gem_object *obj) +{ + int err = 0; + + mutex_lock(&obj->mm.lock); + if (++obj->mm.pages_pin_count == 1) + { + gf_assert(!obj->mm.pages, GF_FUNC_NAME(__func__)); + err = obj->ops->get_pages(obj); + if (err) + --obj->mm.pages_pin_count; + } + mutex_unlock(&obj->mm.lock); + return err; +} + +static void gf_gem_object_unpin_pages(struct drm_gf_gem_object *obj) +{ + struct sg_table *pages; + + mutex_lock(&obj->mm.lock); + gf_assert(obj->mm.pages_pin_count > 0, GF_FUNC_NAME(__func__)); + if (--obj->mm.pages_pin_count == 0) + { + pages = obj->mm.pages; + obj->mm.pages = NULL; + if (!IS_ERR(pages)) + obj->ops->put_pages(obj, pages); + } + mutex_unlock(&obj->mm.lock); +} + +void gf_gem_free_object(struct drm_gem_object *gem_obj) +{ + struct drm_gf_gem_object *obj = to_gf_bo(gem_obj); + gf_card_t *gf = obj->base.dev->dev_private; + + trace_gfx_drm_gem_release_object(gf->index, obj); + + drm_gem_object_release(&obj->base); + + if (obj->ops->release) + { + obj->ops->release(obj); + } + + reservation_object_fini(&obj->__builtin_resv); + + gf_assert(!obj->mm.pages_pin_count, GF_FUNC_NAME(__func__)); + gf_assert(!obj->mm.pages, GF_FUNC_NAME(__func__)); + + gf_free(obj); +} + +static struct sg_table *gf_gem_vram_map_dma_buf(struct device *dev, phys_addr_t phys, size_t size, enum dma_data_direction dir) +{ + struct sg_table *st = NULL; + struct scatterlist *sg = NULL; + dma_addr_t dma_addr; + + st = gf_malloc(sizeof(*st)); + if (!st) + return NULL; + + if (sg_alloc_table(st, 1, GFP_KERNEL)) + goto error_free; + + sg = st->sgl; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(4,8,0) + dma_addr = dma_map_resource(dev, phys, size, dir, DMA_ATTR_SKIP_CPU_SYNC); + if (dma_mapping_error(dev, dma_addr)) + goto error_free_table; + + sg_dma_address(sg) = dma_addr; +#else + sg_dma_address(sg) = phys; +#endif + + sg_set_page(sg, NULL, size, 0); + sg_dma_len(sg) = size; + + return st; + +error_free_table: + gf_error("vram gem map fail\n"); + sg_free_table(st); + +error_free: + gf_free(st); + + return NULL; +} + +static struct sg_table *gf_gem_pages_map_dma_buf(struct device *dev, struct sg_table *pages, enum dma_data_direction dir) +{ + struct sg_table *st; + struct scatterlist *src, *dst; + int i; + + st = kmalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!st) + goto err_exit; + + if (sg_alloc_table(st, pages->nents, GFP_KERNEL)) + goto err_free; + + src = pages->sgl; + dst = st->sgl; + for (i = 0; i < pages->nents; i++) + { + sg_set_page(dst, sg_page(src), src->length, 0); + dst = sg_next(dst); + src = sg_next(src); + } + + st->nents = dma_map_sg(dev, st->sgl, st->orig_nents, dir); + if (!st->nents) + goto err_free_sg; + + return st; + +err_free_sg: + sg_free_table(st); +err_free: + kfree(st); +err_exit: + return NULL; +} + +static struct sg_table *gf_gem_map_dma_buf(struct dma_buf_attachment *attachment, enum dma_data_direction dir) +{ + struct sg_table *st = NULL; + struct drm_gf_gem_object *obj = dmabuf_to_gf_bo(attachment->dmabuf); + gf_card_t *gf = obj->base.dev->dev_private; + gf_map_argu_t map_argu = {0, }; + + gf_core_interface->prepare_and_mark_unpagable(gf->adapter, obj->core_handle, &obj->info); + + if (gf_gem_object_pin_pages(obj)) + goto err_exit; + + map_argu.flags.mem_space = GF_MEM_KERNEL; + map_argu.flags.read_only = false; + gf_core_interface->get_map_allocation_info(gf->adapter, obj->core_handle, &map_argu); + + if (map_argu.flags.mem_type == GF_SYSTEM_RAM) + st = gf_gem_pages_map_dma_buf(attachment->dev, obj->mm.pages, dir); + else + st = gf_gem_vram_map_dma_buf(attachment->dev, map_argu.phys_addr, map_argu.size, dir); + + if (!st) + goto err_unpin_pages; + + return st; + +err_unpin_pages: + gf_gem_object_unpin_pages(obj); +err_exit: + gf_core_interface->mark_pagable(gf->adapter, obj->core_handle); + return NULL; +} + +static void gf_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, struct sg_table *sg, enum dma_data_direction dir) +{ + struct drm_gf_gem_object *obj = dmabuf_to_gf_bo(attachment->dmabuf); + gf_card_t *gf = obj->base.dev->dev_private; + + if (obj->mm.pages) + dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir); +#if LINUX_VERSION_CODE > KERNEL_VERSION(4,8,0) + else + dma_unmap_resource(attachment->dev, sg->sgl->dma_address, sg->sgl->length, dir, DMA_ATTR_SKIP_CPU_SYNC); +#endif + + sg_free_table(sg); + kfree(sg); + + gf_gem_object_unpin_pages(obj); + gf_core_interface->mark_pagable(gf->adapter, obj->core_handle); +} + +void *gf_gem_object_vmap(struct drm_gf_gem_object *obj) +{ + gf_card_t *gf = obj->base.dev->dev_private; + gf_vm_area_t *vma = NULL; + gf_map_argu_t map_argu = {0, }; + + gf_core_interface->prepare_and_mark_unpagable(gf->adapter, obj->core_handle, &obj->info); + + mutex_lock(&obj->mm.lock); + if (obj->krnl_vma) + { + vma = obj->krnl_vma; + obj->krnl_vma->ref_cnt++; + goto unlock; + } + + map_argu.flags.mem_space = GF_MEM_KERNEL; + map_argu.flags.read_only = false; + gf_core_interface->get_map_allocation_info(gf->adapter, obj->core_handle, &map_argu); + + gf_assert(map_argu.flags.mem_space == GF_MEM_KERNEL, GF_FUNC_NAME(__func__)); + if (map_argu.flags.mem_type == GF_SYSTEM_IO) + { + vma = gf_map_io_memory(NULL, &map_argu); + } + else if (map_argu.flags.mem_type == GF_SYSTEM_RAM) + { + vma = gf_map_pages_memory(NULL, &map_argu); + } + else + { + gf_assert(0, GF_FUNC_NAME(__func__)); + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) + obj->vmap_mem_type = map_argu.flags.mem_type; +#endif + + obj->krnl_vma = vma; +unlock: + mutex_unlock(&obj->mm.lock); + return vma ? vma->virt_addr : NULL; +} + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 11, 0) +void *gf_gem_prime_vmap(struct drm_gem_object *gem_obj) +{ + struct drm_gf_gem_object *gf_gem_obj= to_gf_bo(gem_obj); + void *virt_addr = NULL; + + virt_addr = gf_gem_object_vmap(gf_gem_obj); + + if (!virt_addr) + { + return ERR_PTR(-ENOMEM); + } + + return virt_addr; +} + +void gf_gem_prime_vunmap(struct drm_gem_object *gem_obj, void *vaddr) +{ + struct drm_gf_gem_object *gf_gem_obj= to_gf_bo(gem_obj); + + gf_gem_object_vunmap(gf_gem_obj); +} +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) +static int gf_gem_object_vmap_wrapper(struct drm_gem_object *gem, struct DMABUF_PREFIX(map) *map) +{ + struct drm_gf_gem_object *obj= to_gf_bo(gem); + void *virt_addr = NULL; + + virt_addr = gf_gem_object_vmap(obj); + + if (!virt_addr) + return -ENOMEM; + + if (obj->vmap_mem_type == GF_SYSTEM_IO) + { + DMABUF_PREFIX(map_set_vaddr_iomem)(map, (void __iomem *)virt_addr); + } + else if (obj->vmap_mem_type == GF_SYSTEM_RAM) + { + DMABUF_PREFIX(map_set_vaddr)(map, virt_addr); + } + else + { + return -ENODEV; + } + + return 0; +} +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) +static int gf_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct DMABUF_PREFIX(map) *map) +#else +static void *gf_gem_dmabuf_vmap(struct dma_buf *dma_buf) +#endif +{ +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) + struct drm_gem_object *obj = dma_buf->priv; + int ret; + + if(!obj->funcs->vmap) + return -EOPNOTSUPP; + + ret = obj->funcs->vmap(obj, map); + if(ret) + return ret; + else if(DMABUF_PREFIX(map_is_null)(map)) + return -ENOMEM; + + return 0; +#else + struct drm_gf_gem_object *obj= dmabuf_to_gf_bo(dma_buf); + + return gf_gem_object_vmap(obj); +#endif +} + +void gf_gem_object_vunmap(struct drm_gf_gem_object *obj) +{ + gf_card_t *gf = obj->base.dev->dev_private; + + mutex_lock(&obj->mm.lock); + if (obj->krnl_vma && --obj->krnl_vma->ref_cnt == 0) + { + switch(obj->krnl_vma->flags.mem_type) + { + case GF_SYSTEM_IO: + gf_unmap_io_memory(obj->krnl_vma); + break; + case GF_SYSTEM_RAM: + gf_unmap_pages_memory(obj->krnl_vma); + break; + default: + gf_assert(0, GF_FUNC_NAME(__func__)); + break; + } + obj->krnl_vma = NULL; + + gf_core_interface->mark_pagable(gf->adapter, obj->core_handle); + } + mutex_unlock(&obj->mm.lock); +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) +static void gf_gem_object_vunmap_wrapper(struct drm_gem_object *gem, struct DMABUF_PREFIX(map) *map) +{ + struct drm_gf_gem_object *obj= to_gf_bo(gem); + + gf_gem_object_vunmap(obj); + + DMA_BUF_MAP_CLEAR(); +} +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) +static void gf_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct DMABUF_PREFIX(map) *map) +#else +static void gf_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) +#endif +{ +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) + struct drm_gem_object *obj = dma_buf->priv; + + if(!obj->funcs->vunmap) + { + gf_error("drm gem object funcs vunmap not register.\n"); + DMA_BUF_MAP_CLEAR(); + return; + } + else + { + obj->funcs->vunmap(obj, map); + } +#else + struct drm_gf_gem_object *obj = dmabuf_to_gf_bo(dma_buf); + + gf_gem_object_vunmap(obj); +#endif +} + +static void *gf_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num) +{ + gf_info("kmap_atomic: not support yet.\n"); + return NULL; +} + +static void gf_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, unsigned long page_num, void *addr) +{ + gf_info("kunmap_atomic: not support yet.\n"); +} + +static void *gf_gem_dmabuf_kmap(struct dma_buf *dma_buf, unsigned long page_num) +{ + gf_info("kmap: not support yet.\n"); + return NULL; +} + +static void gf_gem_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_num, void *addr) +{ + gf_info("kunmap: not support yet.\n"); +} + +static int gf_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma) +{ + struct drm_gf_gem_object *obj = dmabuf_to_gf_bo(dma_buf); + gf_card_t *gf = obj->base.dev->dev_private; + gf_map_argu_t map_argu = {0, }; + int ret = 0; + + gf_info("gem_dmabuf_mmap(%p)\n", dma_buf); + + mutex_lock(&obj->mm.lock); + + map_argu.flags.mem_space = GF_MEM_USER; + map_argu.flags.read_only = false; + gf_core_interface->get_map_allocation_info(gf->adapter, obj->core_handle, &map_argu); + + gf_assert(map_argu.flags.mem_space == GF_MEM_USER, GF_FUNC_NAME(__func__)); + + switch(map_argu.flags.mem_type) + { + case GF_SYSTEM_IO: + vma->vm_pgoff = map_argu.phys_addr >> PAGE_SHIFT; + ret = gf_map_system_io(vma, &map_argu); + break; + case GF_SYSTEM_RAM: + { + int start_page = _ALIGN_DOWN(map_argu.offset, PAGE_SIZE)/PAGE_SIZE; + int end_page = start_page + ALIGN(map_argu.size, PAGE_SIZE) / PAGE_SIZE; + map_argu.flags.cache_type = gf_validate_page_cache(map_argu.memory, start_page, end_page, map_argu.flags.cache_type); + ret = gf_map_system_ram(vma, &map_argu); + break; + } + default: + gf_assert(0, GF_FUNC_NAME(__func__)); + break; + } + + mutex_unlock(&obj->mm.lock); + return ret; +} + + +#if DRM_VERSION_CODE < KERNEL_VERSION(4,6,0) || (defined(YHQILIN) && DRM_VERSION_CODE == KERNEL_VERSION(4,9,0)) +static int gf_gem_begin_cpu_access(struct dma_buf *dma_buf, size_t s1, size_t s2, enum dma_data_direction direction) +#else +static int gf_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction) +#endif +{ + struct drm_gf_gem_object *obj= dmabuf_to_gf_bo(dma_buf); + int write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE); + + gf_gem_object_begin_cpu_access(obj, 10 * HZ, write); + + return 0; +} + +#if defined PHYTIUM_2000 +#if DRM_VERSION_CODE < KERNEL_VERSION(4,6,0) +static int gf_gem_end_cpu_access(struct dma_buf *dma_buf, size_t s1, size_t s2, enum dma_data_direction direction) +#else +static int gf_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction) +#endif +#elif (DRM_VERSION_CODE < KERNEL_VERSION(4,6,0) || (defined(YHQILIN) && (DRM_SUBVERSION_CODE < 20200710))) +static void gf_gem_end_cpu_access(struct dma_buf *dma_buf, size_t s1, size_t s2, enum dma_data_direction direction) +#elif defined(YHQILIN) && DRM_VERSION_CODE == KERNEL_VERSION(4,9,0) +static int gf_gem_end_cpu_access(struct dma_buf *dma_buf, size_t s1, size_t s2, enum dma_data_direction direction) +#else +static int gf_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction) +#endif +{ + struct drm_gf_gem_object *obj = dmabuf_to_gf_bo(dma_buf); + int write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE); + + gf_gem_object_end_cpu_access(obj, write); +#if (DRM_VERSION_CODE >= KERNEL_VERSION(4,6,0) && !defined(YHQILIN)) || defined(PHYTIUM_2000) + return 0; +#elif defined(YHQILIN) && DRM_VERSION_CODE == KERNEL_VERSION(4,9,0) && (DRM_SUBVERSION_CODE >= 20200710) + return 0; +#endif +} + +static struct os_pages_memory* gf_allocate_pages_memory_from_sg(struct sg_table *st, int size) +{ + int page_cnt = ALIGN(size, PAGE_SIZE) / PAGE_SIZE; + struct os_pages_memory *memory = NULL; + + memory = gf_allocate_pages_memory_struct(page_cnt, st); + if (!memory) + return NULL; + + memory->shared = TRUE; + memory->size = ALIGN(size, PAGE_SIZE); + memory->need_flush = TRUE; + memory->need_zero = FALSE; + memory->fixed_page = TRUE; + memory->page_size = PAGE_SIZE; + memory->dma32 = FALSE; + memory->page_4K_64K = FALSE; + memory->st = st; + memory->has_dma_map = TRUE; + gf_pages_memory_extract_st(memory); + return memory; +} + +static int gf_gem_object_get_pages_generic(struct drm_gf_gem_object *obj) +{ + struct os_pages_memory *memory = NULL; + gf_card_t *gf = obj->base.dev->dev_private; + + memory = gf_core_interface->get_allocation_pages(gf->adapter, obj->core_handle); + if (memory && memory->st) + obj->mm.pages = memory->st; + else + obj->mm.pages = NULL; + + return 0; +} + +static void gf_gem_object_put_pages_generic(struct drm_gf_gem_object *obj, struct sg_table *pages) +{ +} + +static void gf_gem_object_release_generic(struct drm_gf_gem_object *obj) +{ + gf_destroy_allocation_t destroy = {0, }; + gf_card_t *gf = obj->base.dev->dev_private; + + destroy.device = 0; + destroy.allocation = obj->core_handle; + if (gf->a_info.debugfs_mask & GF_DEBUGFS_GEM_ENABLE) + { + gf_gem_debugfs_remove_object(obj); + } + gf_core_interface->destroy_allocation(gf->adapter, &destroy); + obj->core_handle = 0; +} + + +static const struct drm_gf_gem_object_ops gf_gem_object_generic_ops = +{ + .get_pages = gf_gem_object_get_pages_generic, + .put_pages = gf_gem_object_put_pages_generic, + .release = gf_gem_object_release_generic, +}; + +static int gf_gem_dmabuf_open(struct drm_gem_object *gem_obj, struct drm_file *file) +{ + struct dma_buf_attachment *attach = gem_obj->import_attach; + struct dma_buf *dma_buf = attach->dmabuf; + struct drm_gf_gem_object *obj = to_gf_bo(gem_obj); + struct os_pages_memory *pages = NULL; + gf_file_t *priv = file->driver_priv; + gf_card_t *gf = priv->card; + gf_create_allocation_t create = {0, }; + gf_query_info_t query = {0, }; + int ret = 0; + + if (obj->core_handle) + return 0; + + gf_assert(priv->gpu_device, GF_FUNC_NAME(__func__)); + + ret = gf_gem_object_pin_pages(obj); + if (ret) + return ret; + + pages = gf_allocate_pages_memory_from_sg(obj->mm.pages, gem_obj->size); + if (!pages) + goto fail_unpin; + + create.device = priv->gpu_device; + create.width = gem_obj->size; + create.height = 1; + create.usage_mask = GF_USAGE_TEMP_BUFFER; + create.format = GF_FORMAT_A8_UNORM; + create.access_hint = GF_ACCESS_CPU_ALMOST; + + gf_core_interface->create_allocation_from_pages(priv->card->adapter, &create, pages, obj); + gf_assert(create.allocation != 0, GF_FUNC_NAME(__func__)); + obj->core_handle = create.allocation; + + if (!obj->core_handle) + { + ret = -ENOMEM; + goto fail_unpin; + } + + query.type = GF_QUERY_ALLOCATION_INFO_KMD; + query.argu = create.allocation; + query.buf = &obj->info; + gf_core_interface->query_info(priv->card->adapter, &query); + + if (gf->a_info.debugfs_mask & GF_DEBUGFS_GEM_ENABLE) + { + obj->debug.parent_gem = obj; + obj->debug.root = gf_debugfs_get_allocation_root(gf->debugfs_dev); + obj->debug.parent_dev = &priv->debug; + obj->debug.is_dma_buf_import = true; + gf_gem_debugfs_add_object(obj); + } + + return ret; + +fail_unpin: + if (pages) + gf_free_pages_memory(gf->pdev, pages); + + gf_gem_object_unpin_pages(obj); + return ret; +} + +int gf_gem_open(struct drm_gem_object *gem_obj, struct drm_file *file) +{ + if (gem_obj->import_attach) + return gf_gem_dmabuf_open(gem_obj, file); + + return 0; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) +static const struct drm_gem_object_funcs gf_gem_object_funcs = +{ + //.close = , + .open = gf_gem_open, + .free = gf_gem_free_object, + //mmp is still in drm_driver + //.mmp + .vm_ops = &gf_gem_vm_ops, + //.pin = , + //.unpin = , + .vmap = gf_gem_object_vmap_wrapper, + .vunmap = gf_gem_object_vunmap_wrapper, + .export = gf_gem_prime_export, + //.get_set_table = , +}; +#endif + +static int gf_drm_gem_object_mmap_immediate(struct vm_area_struct* vma, gf_map_argu_t *map_argu) +{ + int ret = 0; + + switch(map_argu->flags.mem_type) + { + case GF_SYSTEM_IO: + vma->vm_pgoff = map_argu->phys_addr >> PAGE_SHIFT; + ret = gf_map_system_io(vma, map_argu); + break; + case GF_SYSTEM_RAM: + { + int start_page = _ALIGN_DOWN(map_argu->offset, PAGE_SIZE)/PAGE_SIZE; + int end_page = start_page + ALIGN(map_argu->size, PAGE_SIZE) / PAGE_SIZE; + map_argu->flags.cache_type = gf_validate_page_cache(map_argu->memory, start_page, end_page, map_argu->flags.cache_type); + ret = gf_map_system_ram(vma, map_argu); + break; + } + default: + gf_assert(0, GF_FUNC_NAME(__func__)); + break; + } + + return ret; +} + +static void gf_drm_gem_object_mmap_delay(struct vm_area_struct* vma, gf_map_argu_t *map_argu) +{ + unsigned int cache_type; + + switch(map_argu->flags.mem_type) + { + case GF_SYSTEM_IO: + cache_type = map_argu->flags.cache_type; +#if LINUX_VERSION_CODE >= 0x020612 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); +#endif + vma->vm_page_prot = os_get_pgprot_val(&cache_type, vma->vm_page_prot, 1); + map_argu->flags.cache_type = cache_type; + + break; + case GF_SYSTEM_RAM: + // actually map 0 pages here, just force update cache_type + map_argu->flags.cache_type = gf_validate_page_cache(map_argu->memory, 0, 0, map_argu->flags.cache_type); + cache_type = map_argu->flags.cache_type; + +#if LINUX_VERSION_CODE >= 0x020612 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); +#endif + vma->vm_page_prot = os_get_pgprot_val(&cache_type, vma->vm_page_prot, 0); + + break; + default: + gf_assert(0, GF_FUNC_NAME(__func__)); + break; + } +} + +static int gf_drm_gem_object_mmap(struct file *filp, struct drm_gf_gem_object *obj, struct vm_area_struct *vma) +{ + struct drm_file *file = filp->private_data; + gf_file_t *priv = file->driver_priv; + gf_map_argu_t map_argu = {0, }; + gf_wait_allocation_idle_t wait = {0, }; + int ret = 0; + + mutex_lock(&obj->mm.lock); + + map_argu.flags.mem_space = GF_MEM_USER; + map_argu.flags.read_only = false; + gf_core_interface->get_map_allocation_info(priv->card->adapter, obj->core_handle, &map_argu); + + wait.engine_mask = ALL_ENGINE_MASK; + wait.hAllocation = obj->core_handle; + gf_core_interface->wait_allocation_idle(priv->card->adapter, &wait); + +#if DRM_VERSION_CODE < KERNEL_VERSION(6,3,0) + vma->vm_flags |= (VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); +#else + vm_flags_set(vma, (VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP)); +#endif + + if ((map_argu.flags.mem_type == GF_SYSTEM_RAM) && + ((obj->info.segment_id) != 2 && (obj->info.segment_id != 3))) + { + gf_error("drm_gem_object_mmap failed: mem_type is ram but segment_id is %d.\n", obj->info.segment_id); + gf_assert(0, GF_FUNC_NAME(__func__)); + } + +#if defined (__mips64__) || defined(__loongarch__) + if (map_argu.flags.mem_type == GF_SYSTEM_IO) + { + map_argu.flags.cache_type = GF_MEM_UNCACHED; + } +#endif + + if (obj->delay_map == 0) + ret = gf_drm_gem_object_mmap_immediate(vma, &map_argu); + else + gf_drm_gem_object_mmap_delay(vma, &map_argu); + + obj->map_argu = map_argu; + + mutex_unlock(&obj->mm.lock); + + return ret; +} + + +static void gf_drm_gem_object_vm_prepare(struct drm_gf_gem_object *obj) +{ + gf_card_t *gf = obj->base.dev->dev_private; + + gf_core_interface->prepare_and_mark_unpagable(gf->adapter, obj->core_handle, &(obj->info)); +} + +static void gf_drm_gem_object_vm_release(struct drm_gf_gem_object *obj) +{ + gf_card_t *gf = obj->base.dev->dev_private; + + gf_core_interface->mark_pagable(gf->adapter, obj->core_handle); +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) +static void gf_gem_object_init(struct drm_gf_gem_object *obj, const struct drm_gf_gem_object_ops *ops, const struct drm_gem_object_funcs *funcs) +#else +static void gf_gem_object_init(struct drm_gf_gem_object *obj, const struct drm_gf_gem_object_ops *ops) +#endif +{ + mutex_init(&obj->mm.lock); + obj->ops = ops; + + reservation_object_init(&obj->__builtin_resv); + obj->resv = &obj->__builtin_resv; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) + obj->base.funcs = funcs; +#endif +} + +static int gf_get_pages_from_userptr(struct device *dev, unsigned long userptr, unsigned int size, struct os_pages_memory **mem) +{ + struct os_pages_memory *memory = NULL; + struct page **pages = NULL; + int page_num = PAGE_ALIGN(size)/PAGE_SIZE; + int index = 0; + int pinned = 0; + int result = 0; + + pages = vzalloc(page_num * sizeof(struct page*)); + +#if DRM_VERSION_CODE < KERNEL_VERSION(5,8,0) + down_read(¤t->mm->mmap_sem); +#else + down_read(¤t->mm->mmap_lock); +#endif + while (pinned < page_num) + { + +// For CentOS old kernel + new drm backport, we will include drm_backport.h globally, +// DRM_BACKPORT_H_ is defined in drm_backport.h, and get_user_pages() is also redefined +// in drm_backport.h to be used by backported new drm drivers, so use DRM_VERSION_CODE +// to check which get_user_pages() to call. +// If the DRM_BACKPORT_H_ is not defined, should always use LINUX_VERSION_CODE even if +// the drm is backported, since the get_user_pages() is defined by kernel, not by drm. +#ifdef DRM_BACKPORT_H_ +#define GET_USER_PAGES_VERSION_CODE DRM_VERSION_CODE +#else +#define GET_USER_PAGES_VERSION_CODE LINUX_VERSION_CODE +#endif + +#if GET_USER_PAGES_VERSION_CODE >= KERNEL_VERSION(6, 5, 0) + result = get_user_pages(userptr + (pinned * PAGE_SIZE), + page_num - pinned, + FOLL_WRITE, + &pages[pinned]); +#elif GET_USER_PAGES_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + result = get_user_pages(userptr + (pinned * PAGE_SIZE), + page_num - pinned, + FOLL_WRITE, + &pages[pinned], + NULL); +#elif GET_USER_PAGES_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) + result = get_user_pages(userptr + (pinned * PAGE_SIZE), + page_num - pinned, + FOLL_WRITE, + 0, + &pages[pinned], + NULL); +#elif GET_USER_PAGES_VERSION_CODE >= KERNEL_VERSION(4, 4, 168) && GET_USER_PAGES_VERSION_CODE < KERNEL_VERSION(4, 5, 0) + result = get_user_pages(current, + current->mm, + userptr + (pinned * PAGE_SIZE), + page_num - pinned, + FOLL_WRITE, + &pages[pinned], + NULL); +#else + result = get_user_pages(current, + current->mm, + userptr + (pinned * PAGE_SIZE), + page_num - pinned, + 1, + 0, + &pages[pinned], + NULL); +#endif + if (result < 0) + { + goto release_pages; + } + pinned += result; + } +#if DRM_VERSION_CODE < KERNEL_VERSION(5,8,0) + up_read(¤t->mm->mmap_sem); +#else + up_read(¤t->mm->mmap_lock); +#endif + + memory = gf_allocate_pages_memory_struct(page_num, NULL); + + memory->size = PAGE_ALIGN(size); // supose size==PAGE_ALIGN(size) + memory->page_size = PAGE_SIZE; + memory->need_flush = TRUE; + memory->fixed_page = TRUE; + memory->need_zero = FALSE; + memory->page_4K_64K = FALSE; + memory->noswap = FALSE; + memory->dma32 = FALSE; + memory->shared = FALSE; + memory->userptr = TRUE; + sg_alloc_table_from_pages(memory->st, pages, page_num, 0, PAGE_ALIGN(size), GFP_KERNEL); + gf_pages_memory_extract_st(memory); + + memory->st->nents = dma_map_sg(dev, memory->st->sgl, memory->st->orig_nents, DMA_BIDIRECTIONAL); + if (memory->st->nents) { + memory->has_dma_map = TRUE; + } else { + gf_assert(0, "dma_map_sg failed.\n"); + } + + *mem = memory; + + vfree(pages); + + return S_OK; + + +release_pages: + for(index = 0; index < pinned; index++) + { + put_page(pages[index]); + } +#if DRM_VERSION_CODE < KERNEL_VERSION(5,8,0) + up_read(¤t->mm->mmap_sem); +#else + up_read(¤t->mm->mmap_lock); +#endif + vfree(pages); + + return E_FAIL; +} + + +struct drm_gf_gem_object* gf_drm_gem_create_object(gf_card_t *gf, gf_create_allocation_t *create, gf_device_debug_info_t **ddbg) +{ + struct drm_gf_gem_object *obj = NULL; + gf_query_info_t query = {0, }; + int result = 0; + + obj = gf_calloc(sizeof(*obj)); + + if(create->user_ptr) + { + struct os_pages_memory *memory=NULL; + + result = gf_get_pages_from_userptr(&(gf->pdev->dev), (unsigned long)create->user_ptr, create->user_buf_size, &memory); + if(result < 0) + { + gf_free(obj); + return NULL; + } + + gf_core_interface->create_allocation_from_pages(gf->adapter, create, memory, obj); + } + else + { + gf_core_interface->create_allocation(gf->adapter, create, obj); + } + + if(!create->allocation) + { + gf_free(obj); + return NULL; + } + + query.type = GF_QUERY_ALLOCATION_INFO_KMD; + query.argu = create->allocation; + query.buf = &obj->info; + gf_core_interface->query_info(gf->adapter, &query); + obj->core_handle = create->allocation; + + drm_gem_private_object_init(pci_get_drvdata(gf->pdev), &obj->base, create->size); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) + gf_gem_object_init(obj, &gf_gem_object_generic_ops, &gf_gem_object_funcs); +#else + gf_gem_object_init(obj, &gf_gem_object_generic_ops); +#endif + + if (gf->a_info.debugfs_mask & GF_DEBUGFS_GEM_ENABLE) + { + obj->debug.parent_dev = ddbg; + obj->debug.parent_gem = obj; + obj->debug.root = gf_debugfs_get_allocation_root(gf->debugfs_dev); + obj->debug.is_dma_buf_import = false; + + gf_gem_debugfs_add_object(obj); + } + trace_gfx_drm_gem_create_object(gf->index, obj); + return obj; +} + +int gf_drm_gem_create_object_ioctl(struct drm_file *file, gf_create_allocation_t *create) +{ + int ret = 0; + struct drm_gf_gem_object *obj = NULL; + gf_file_t *priv = file->driver_priv; + gf_card_t *gf = priv->card; + + gf_assert(create->device == priv->gpu_device, GF_FUNC_NAME(__func__)); + + obj = gf_drm_gem_create_object(gf, create, &priv->debug); + + if (!obj) + return -ENOMEM; + + ret = drm_gem_handle_create(file, &obj->base, &create->allocation); + + gf_assert(ret == 0, GF_FUNC_NAME(__func__)); + + gf_gem_object_put(obj); + + return 0; +} + +int gf_drm_gem_create_resource_ioctl(struct drm_file *file, gf_create_resource_t *create) +{ + int ret = 0, i; + gf_file_t *priv = file->driver_priv; + gf_card_t *gf = priv->card; + int obj_count = create->NumAllocations; + gf_create_alloc_info_t stack_kinfos[8]; + gf_create_alloc_info_t *kinfo = stack_kinfos; + gf_create_alloc_info_t __user *uinfo = ptr64_to_ptr(create->pAllocationInfo); + struct drm_gf_gem_object *stack_objs[8]; + struct drm_gf_gem_object **objs = stack_objs; + gf_query_info_t query = {0, }; + + gf_assert(create->device == priv->gpu_device, GF_FUNC_NAME(__func__)); + gf_assert(uinfo != NULL, GF_FUNC_NAME(__func__)); + + if (obj_count > sizeof(stack_kinfos) / sizeof(stack_kinfos[0])) + { + kinfo = gf_malloc(obj_count * sizeof(gf_create_alloc_info_t)); + } + create->pAllocationInfo = ptr_to_ptr64(kinfo); + + if (obj_count > sizeof(stack_objs) / sizeof(stack_objs[0])) + { + objs = gf_malloc(obj_count * sizeof(*objs)); + } + + gf_copy_from_user(kinfo, uinfo, obj_count * sizeof(gf_create_alloc_info_t)); + + for (i = 0; i < obj_count; i++) + { + objs[i] = gf_calloc(sizeof(**objs)); +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) + gf_gem_object_init(objs[i], &gf_gem_object_generic_ops, &gf_gem_object_funcs); +#else + gf_gem_object_init(objs[i], &gf_gem_object_generic_ops); +#endif + } + + ret = gf_core_interface->create_allocation_list(gf->adapter, create, (void**)objs); + gf_assert(ret == 0, GF_FUNC_NAME(__func__)); + + create->pAllocationInfo = ptr_to_ptr64(uinfo); + if (ret) + goto failed_free; + + for (i = 0; i < obj_count; i++) + { + objs[i]->core_handle = kinfo[i].hAllocation; + gf_assert(kinfo[i].hAllocation, GF_FUNC_NAME(__func__)); + + query.type = GF_QUERY_ALLOCATION_INFO_KMD; + query.argu = kinfo[i].hAllocation; + query.buf = &objs[i]->info; + gf_core_interface->query_info(gf->adapter, &query); + + drm_gem_private_object_init(pci_get_drvdata(gf->pdev), &objs[i]->base, kinfo[i].Size); + ret = drm_gem_handle_create(file, &objs[i]->base, &kinfo[i].hAllocation); + gf_assert(0 == ret, GF_FUNC_NAME(__func__)); + + if (gf->a_info.debugfs_mask & GF_DEBUGFS_GEM_ENABLE) + { + objs[i]->debug.parent_dev = &priv->debug; + objs[i]->debug.parent_gem = objs[i]; + objs[i]->debug.root = gf_debugfs_get_allocation_root(gf->debugfs_dev); + objs[i]->debug.is_dma_buf_import = false; + + gf_gem_debugfs_add_object(objs[i]); + } + trace_gfx_drm_gem_create_object(gf->index, objs[i]); + gf_gem_object_put(objs[i]); + } + + gf_copy_to_user(uinfo, kinfo, obj_count * sizeof(gf_create_alloc_info_t)); + +failed_free: + if (kinfo != stack_kinfos) + { + gf_free(kinfo); + } + if (objs != stack_objs) + { + gf_free(objs); + } + + return ret; +} + + +// DMABUF +static int gf_gem_object_get_pages_dmabuf(struct drm_gf_gem_object *obj) +{ + struct sg_table *pages; + pages = dma_buf_map_attachment(obj->base.import_attach, DMA_BIDIRECTIONAL); + if (IS_ERR(pages)) + return PTR_ERR(pages); + + obj->mm.pages = pages; + return 0; +} + +static void gf_gem_object_put_pages_dmabuf(struct drm_gf_gem_object *obj, struct sg_table *pages) +{ + gf_assert(pages != NULL, GF_FUNC_NAME(__func__)); + dma_buf_unmap_attachment(obj->base.import_attach, pages, DMA_BIDIRECTIONAL); +} + +static void gf_gem_object_release_dmabuf(struct drm_gf_gem_object *obj) +{ + gf_destroy_allocation_t destroy = {0, }; + gf_card_t *gf = obj->base.dev->dev_private; + gf_wait_allocation_idle_t wait = {0, }; + struct dma_buf_attachment *attach; + struct dma_buf *dma_buf; + + if (obj->core_handle) + { + wait.engine_mask = ALL_ENGINE_MASK; + wait.hAllocation = obj->core_handle; + gf_core_interface->wait_allocation_idle(gf->adapter, &wait); + + destroy.device = 0; + destroy.allocation = obj->core_handle; + gf_core_interface->destroy_allocation(gf->adapter, &destroy); + obj->core_handle = 0; + + if (gf->a_info.debugfs_mask & GF_DEBUGFS_GEM_ENABLE) + { + gf_gem_debugfs_remove_object(obj); + } + + gf_gem_object_unpin_pages(obj); + } + + attach = obj->base.import_attach; + dma_buf = attach->dmabuf; + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); +} + +static const struct drm_gf_gem_object_ops gf_gem_object_dmabuf_ops = +{ + .get_pages = gf_gem_object_get_pages_dmabuf, + .put_pages = gf_gem_object_put_pages_dmabuf, + .release = gf_gem_object_release_dmabuf, +}; + + +#if DRM_VERSION_CODE < KERNEL_VERSION(6,6,0) +int gf_gem_prime_fd_to_handle(struct drm_device *dev, struct drm_file *file_priv, int prime_fd, uint32_t *handle) +{ + int ret; + struct drm_gf_driver *driver = to_drm_gf_driver(dev->driver); + + mutex_lock(&driver->lock); + gf_assert(!driver->file_priv, GF_FUNC_NAME(__func__)); + + driver->file_priv = file_priv; + ret = drm_gem_prime_fd_to_handle(dev, file_priv, prime_fd, handle); + driver->file_priv = NULL; + mutex_unlock(&driver->lock); + + return ret; +} +#endif + +signed long gf_gem_object_begin_cpu_access(struct drm_gf_gem_object *obj, long timeout, int write) +{ + gf_card_t *gf = obj->base.dev->dev_private; + trace_gfx_gem_object_begin_cpu_access(gf->index, obj, timeout, write); + + return gf_gem_fence_await_reservation(obj->resv, 0, timeout, write); +} + +int gf_gem_object_begin_cpu_access_ioctl(struct drm_file *file, gf_drm_gem_begin_cpu_access_t *args) +{ + int ret = 0; + struct drm_device *dev = file->minor->dev; + struct drm_gf_gem_object *obj; + + obj = gf_drm_gem_object_lookup(dev, file, args->handle); + + if (!obj) + return -ENOENT; + + ret = gf_gem_object_begin_cpu_access(obj, 10 * HZ, !args->readonly); + + gf_gem_object_put(obj); + return 0; +} + +void gf_gem_object_end_cpu_access(struct drm_gf_gem_object *obj, int write) +{ + gf_card_t *gf = obj->base.dev->dev_private; + gf_map_argu_t map_argu = {0, }; + + map_argu.flags.mem_space = GF_MEM_KERNEL; + map_argu.flags.read_only = false; + gf_core_interface->get_map_allocation_info(gf->adapter, obj->core_handle, &map_argu); + + if (map_argu.flags.mem_type == GF_SYSTEM_RAM && + map_argu.flags.cache_type == GF_MEM_WRITE_BACK && + (!obj->info.snoop) && + map_argu.memory) + { + gf_flush_cache(gf->pdev, NULL, map_argu.memory, map_argu.offset, map_argu.size); + } + + if (map_argu.flags.cache_type == GF_MEM_WRITE_COMBINED) + { + gf_wmb(); + } + + trace_gfx_gem_object_end_cpu_access(gf->index, obj); + +} + +void gf_gem_object_end_cpu_access_ioctl(struct drm_file *file, gf_drm_gem_end_cpu_access_t *args) +{ + struct drm_device *dev = file->minor->dev; + struct drm_gf_gem_object *obj; + + obj = gf_drm_gem_object_lookup(dev, file, args->handle); + + if (!obj) + return; + + gf_gem_object_end_cpu_access(obj, 1); + gf_gem_object_put(obj); +} + +const struct dma_buf_ops CONCAT(gf_dmabuf_ops,DRIVER_NAME) = +{ + .map_dma_buf = gf_gem_map_dma_buf, + .unmap_dma_buf = gf_gem_unmap_dma_buf, + .release = drm_gem_dmabuf_release, +#if DRM_VERSION_CODE < KERNEL_VERSION(5,6,0) +#if DRM_VERSION_CODE > KERNEL_VERSION(4,11,0) + .map = gf_gem_dmabuf_kmap, + .unmap = gf_gem_dmabuf_kunmap, +#if DRM_VERSION_CODE < KERNEL_VERSION(4,19,0) + .map_atomic = gf_gem_dmabuf_kmap_atomic, + .unmap_atomic = gf_gem_dmabuf_kunmap_atomic, +#endif +#else + .kmap = gf_gem_dmabuf_kmap, + .kmap_atomic = gf_gem_dmabuf_kmap_atomic, + .kunmap = gf_gem_dmabuf_kunmap, + .kunmap_atomic = gf_gem_dmabuf_kunmap_atomic, +#endif +#endif + .mmap = gf_gem_dmabuf_mmap, + .vmap = gf_gem_dmabuf_vmap, + .vunmap = gf_gem_dmabuf_vunmap, + .begin_cpu_access = gf_gem_begin_cpu_access, + .end_cpu_access = gf_gem_end_cpu_access, +}; + +EXPORT_SYMBOL(CONCAT(gf_dmabuf_ops,DRIVER_NAME)); + +struct drm_gem_object *gf_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf) +{ + struct drm_gf_driver *driver = to_drm_gf_driver(dev->driver); + gf_card_t *gf = dev->dev_private; + struct drm_gf_gem_object *obj = NULL; + struct dma_buf_attachment *attach; + + if (dma_buf->ops == &CONCAT(gf_dmabuf_ops, DRIVER_NAME)) + { + obj = dmabuf_to_gf_bo(dma_buf); + + if (obj->base.dev == dev) + { + trace_gfx_gem_prime_import(gf->index, dma_buf, obj); + return &(gf_gem_object_get(obj)->base); + } + } + + attach = dma_buf_attach(dma_buf, dev->dev); + if (IS_ERR(attach)) + return ERR_CAST(attach); + + get_dma_buf(dma_buf); + obj = gf_calloc(sizeof(*obj)); + if (obj == NULL) + goto fail_detach; + + drm_gem_private_object_init(dev, &obj->base, dma_buf->size); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,11,0) + gf_gem_object_init(obj, &gf_gem_object_dmabuf_ops, &gf_gem_object_funcs); +#else + gf_gem_object_init(obj, &gf_gem_object_dmabuf_ops); +#endif + + obj->base.import_attach = attach; + obj->resv = dma_buf->resv; + + trace_gfx_drm_gem_create_object(gf->index, obj); + trace_gfx_gem_prime_import(gf->index, dma_buf, obj); + + return &obj->base; + +fail_detach: + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); + + return NULL; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,4,0) +struct dma_buf *gf_gem_prime_export(struct drm_gem_object *gem_obj, int flags) +#else +struct dma_buf *gf_gem_prime_export(struct drm_device *dev, struct drm_gem_object *gem_obj, int flags) +#endif +{ + struct dma_buf *dma_buf; + struct drm_gf_gem_object *obj; + struct drm_device *dev1; + gf_card_t *gf; + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,4,0) + dev1 = gem_obj->dev; +#else + dev1 = dev; +#endif + gf = dev1->dev_private; + obj = to_gf_bo(gem_obj); + + exp_info.ops = &CONCAT(gf_dmabuf_ops,DRIVER_NAME); + exp_info.size = obj->base.size; + exp_info.flags = flags; + exp_info.priv = gem_obj; + exp_info.resv = obj->resv; + +#if DRM_VERSION_CODE < KERNEL_VERSION(4,9,0) && !defined(PHYTIUM_2000) + dma_buf = dma_buf_export(&exp_info); +#else + dma_buf = drm_gem_dmabuf_export(dev1, &exp_info); +#endif + + trace_gfx_gem_prime_export(gf->index, dma_buf, obj); + + return dma_buf; +} + +int gf_gem_mmap_gtt(struct drm_file *file, struct drm_device *dev, uint32_t handle, uint64_t *offset) +{ + int ret; + struct drm_gf_gem_object *obj; + + obj = gf_drm_gem_object_lookup(dev, file, handle); + if (!obj) + { + gf_error("gf_gem_mmap_gtt lookup failed \n"); + ret = -ENOENT; + goto unlock; + } + + ret = drm_gem_create_mmap_offset(&obj->base); + if (ret) + { + gf_error("gf_gem_mmap_gtt create mmap offset failed \n"); + goto out; + } + *offset = drm_vma_node_offset_addr(&obj->base.vma_node); + +out: + gf_gem_object_put(obj); +unlock: + return ret; +} + +int gf_gem_mmap_gtt_ioctl(struct drm_file *file, gf_drm_gem_map_t *args) +{ + int ret; + struct drm_gf_gem_object *obj; + + obj = gf_drm_gem_object_lookup(file->minor->dev, file, args->gem_handle); + if (!obj) + { + gf_error("gf_gem_mmap_gtt_ioctl lookup failed \n"); + ret = -ENOENT; + goto unlock; + } + + obj->delay_map = args->delay_map; + obj->prefault_num = args->prefault_num; + + ret = drm_gem_create_mmap_offset(&obj->base); + if (ret) + { + gf_error("gf_gem_mmap_gtt_ioctl create mmap offset failed \n"); + goto out; + } + args->offset = drm_vma_node_offset_addr(&obj->base.vma_node); + +out: + gf_gem_object_put(obj); +unlock: + return ret; +} + +int gf_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct drm_gf_gem_object *obj; + struct drm_file *file = filp->private_data; + gf_file_t *priv = file->driver_priv; + int ret = 0; + + if (priv->map) + { + return gf_mmap(filp, vma); + } + + ret = drm_gem_mmap(filp, vma); + if (ret < 0) + { + gf_error("failed to mmap, ret = %d.\n", ret); + return ret; + } + + obj = to_gf_bo(vma->vm_private_data); + +#if DRM_VERSION_CODE < KERNEL_VERSION(6,3,0) + vma->vm_flags &= ~(VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); +#else + vm_flags_clear(vma, (VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP)); +#endif + + vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); + + gf_drm_gem_object_vm_prepare(obj); + + return gf_drm_gem_object_mmap(filp, obj, vma); +} + +int gf_gem_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args) +{ + int ret = 0; + struct drm_gf_gem_object *obj = NULL; + gf_file_t *priv = file->driver_priv; + gf_card_t *gf = priv->card; + gf_create_allocation_t create = {0, }; + gf_format gfFormat = GF_FORMAT_R8_UNORM; + + if(args->bpp == 32) + { + gfFormat = GF_FORMAT_B8G8R8A8_UNORM; + } + else if(args->bpp == 16) + { + gfFormat = GF_FORMAT_B5G6R5_UNORM; + } + + create.device = priv->gpu_device; + create.width = args->width; + create.height = args->height; + create.format = gfFormat; + create.tiled = 0; + create.unpagable = TRUE; + create.usage_mask = GF_USAGE_DISPLAY_SURFACE | GF_USAGE_FRAMEBUFFER; + create.access_hint = GF_ACCESS_CPU_ALMOST; + create.primary = 1; + + obj = gf_drm_gem_create_object(gf, &create, &priv->debug); + if (!obj) + return -ENOMEM; + + ret = drm_gem_handle_create(file, &obj->base, &args->handle); + gf_assert(ret == 0, GF_FUNC_NAME(__func__)); + + args->pitch = create.pitch; + args->size = create.size; + gf_gem_object_put(obj); + + return ret; +} + +static vm_fault_t gf_gem_io_insert(struct vm_area_struct *vma, unsigned long address, gf_map_argu_t *map, unsigned int offset, unsigned int prefault_num) +{ + unsigned long pfn; + vm_fault_t retval = VM_FAULT_NOPAGE; + int i ; + + for(i = 0; i < prefault_num ; i++) + { + if(offset >= map->size) + break; + + pfn = (map->phys_addr + offset) >> PAGE_SHIFT; + + retval = vmf_insert_pfn(vma, address, pfn); + if (unlikely((retval == VM_FAULT_NOPAGE && i > 0))) + break; + else if (unlikely(retval & VM_FAULT_ERROR)) + { + return retval; + } + + offset += PAGE_SIZE; + address += PAGE_SIZE; + } + + return retval; +} + +static vm_fault_t gf_gem_ram_insert(struct vm_area_struct *vma, unsigned long address, gf_map_argu_t *map, unsigned int offset, unsigned int prefault_num) +{ + unsigned long pfn; + vm_fault_t retval = VM_FAULT_NOPAGE; + int i, start_page, end_page; + + start_page = _ALIGN_DOWN(offset, PAGE_SIZE) / PAGE_SIZE; + end_page = min((int)(start_page+prefault_num), (int)(map->memory->size / PAGE_SIZE)); + map->flags.cache_type = gf_validate_page_cache(map->memory, start_page, end_page, map->flags.cache_type); + + for (i = start_page; i < end_page; i++) + { + pfn = page_to_pfn(map->memory->pages[i]); + retval = vmf_insert_pfn(vma, address, pfn); + if (unlikely((retval == VM_FAULT_NOPAGE && i > start_page))) + break; + else if (unlikely(retval & VM_FAULT_ERROR)) + { + return retval; + } + address += PAGE_SIZE; + } + return retval; +} + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0) +static vm_fault_t gf_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +#else +static vm_fault_t gf_gem_fault(struct vm_fault *vmf) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0) + struct vm_area_struct *vma = vmf->vma; +#endif + struct drm_gf_gem_object *obj; + unsigned long offset; + uint64_t vma_node_offset; + vm_fault_t ret = VM_FAULT_NOPAGE; + unsigned long address; + unsigned int prefault_num = 0; + unsigned int page_num = 0; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + address = vmf->address; +#else + address = (unsigned long)vmf->virtual_address; +#endif + obj = to_gf_bo(vma->vm_private_data); + + vma_node_offset = drm_vma_node_offset_addr(&(obj->base.vma_node)); + offset = ((vma->vm_pgoff << PAGE_SHIFT) - vma_node_offset) + (address - vma->vm_start); + + gf_assert(obj->delay_map != 0, GF_FUNC_NAME(__func__)); + + page_num = NUM_PAGES(vma->vm_end - address); + + if (obj->prefault_num == 0) + prefault_num = min((unsigned int)GF_DEFAULT_PREFAULT_NUM, page_num); + else + prefault_num = min(obj->prefault_num, page_num); + + switch(obj->map_argu.flags.mem_type) + { + case GF_SYSTEM_IO: + ret = gf_gem_io_insert(vma, address, &obj->map_argu, offset, prefault_num); + break; + case GF_SYSTEM_RAM: + ret = gf_gem_ram_insert(vma, address, &obj->map_argu, offset, prefault_num); + break; + default: + gf_assert(0, GF_FUNC_NAME(__func__)); + break; + } + + return ret; +} + +static void gf_gem_vm_open(struct vm_area_struct *vma) +{ + struct drm_gf_gem_object *obj = to_gf_bo(vma->vm_private_data); + + gf_drm_gem_object_vm_prepare(obj); + drm_gem_vm_open(vma); +} + +static void gf_gem_vm_close(struct vm_area_struct *vma) +{ + struct drm_gf_gem_object *obj = to_gf_bo(vma->vm_private_data); + + gf_drm_gem_object_vm_release(obj); + drm_gem_vm_close(vma); +} + +static int gf_gem_vm_access(struct vm_area_struct *vma, unsigned long addr, void *buf, int len, int write) +{ + void *virtul_addr = NULL; + struct drm_gf_gem_object *obj; + unsigned long offset; + int rest, this_size; + char *p; + + obj = to_gf_bo(vma->vm_private_data); + offset = addr - vma->vm_start + ((vma->vm_pgoff - drm_vma_node_start(&obj->base.vma_node)) << PAGE_SHIFT); + //gf_info("gf_gem_vm_access(addr:%p, len:%d, write:%d, offset:%llx)\n", (void*)addr, len, write, offset); + + if (len < 1 || (offset + len) > obj->base.size) + { + gf_info("access overflow (size:%x, vm_start:%llx, vm_pgoff:%llx, node_offset:%llx)\n", + obj->base.size, vma->vm_start, vma->vm_pgoff, drm_vma_node_start(&obj->base.vma_node)); + return -EIO; + } + + virtul_addr = gf_gem_object_vmap(obj); + if (!virtul_addr) + { + gf_info("vmap failed.\n"); + return -EIO; + } + + rest = len; + p = (char*)buf; + +#define __MIN(a,b) ((a) > (b) ? (b) : (a)) + + this_size = __MIN(rest, obj->base.size - offset); + if (write) + gf_memcpy(virtul_addr + offset, p, this_size); + else + gf_memcpy(p, virtul_addr + offset, this_size); + rest -= this_size; + + gf_gem_object_vunmap(obj); + + return len - rest; +} + +const struct vm_operations_struct gf_gem_vm_ops = { + .fault = gf_gem_fault, + .open = gf_gem_vm_open, + .close = gf_gem_vm_close, + .access = gf_gem_vm_access, +}; + +static int gf_gem_debugfs_show_info(struct seq_file *s, void *unused) +{ + struct gf_gem_debug_info *dnode = (struct gf_gem_debug_info *)(s->private); + struct drm_gf_gem_object *obj = (struct drm_gf_gem_object *) dnode->parent_gem; + gf_open_allocation_t *info = &obj->info; +/*print the info*/ + seq_printf(s, "device=0x%x\n", info->device); + seq_printf(s, "handle=0x%x\n", info->allocation); + + seq_printf(s, "width=%d\n", info->width); + seq_printf(s, "height=%d\n", info->height); + seq_printf(s, "pitch=%d\n", info->pitch); + seq_printf(s, "bit_cnt=%d\n", info->bit_cnt); + + seq_printf(s, "secured=%d\n", info->secured); + seq_printf(s, "size=%d\n", info->size); + seq_printf(s, "tile=%d\n", info->tiled); + seq_printf(s, "segmentid=%d\n", info->segment_id); + seq_printf(s, "hw_format=%d\n", info->hw_format); + seq_printf(s, "compress_format=%d\n", info->compress_format); + seq_printf(s, "bl_slot_index=%d\n", info->bl_slot_index); + seq_printf(s, "gpu_virt_addr=%lld\n", info->gpu_virt_addr); + seq_printf(s, "imported=%d\n", dnode->is_dma_buf_import); + + return 0; +} + +static int gf_gem_debugfs_info_open(struct inode *inode, struct file *file) +{ + return single_open(file, gf_gem_debugfs_show_info, inode->i_private); +} + +static const struct file_operations debugfs_gem_info_fops = { + .open = gf_gem_debugfs_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static ssize_t gf_gem_debugfs_data_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) +{ + //map & read + gf_gem_debug_info_t *dbg = file_inode(f)->i_private; + struct drm_gf_gem_object *obj = dbg->parent_gem; + gf_card_t *gf = obj->base.dev->dev_private; + void *data = NULL; + ssize_t result = 0; + int data_off = 0; + int copy_size = 0; + int a_size = 0; + + if (!gf->allocation_trace_tags) return 0; + + data = gf_gem_object_vmap(obj); + if (data) { + gf_gem_object_begin_cpu_access(obj, 10 * HZ, 0); + a_size = obj->krnl_vma->size; + data_off = *pos; + copy_size = min(size, (size_t)(a_size - data_off)); + if (copy_to_user(buf, data + data_off, copy_size)){ + result = -EFAULT; + } else { + result += copy_size; + *pos += copy_size; + } + gf_gem_object_end_cpu_access(obj,0); + } + else { + result = -EINVAL; + } + gf_gem_object_vunmap(obj); + + return result; +} + +static const struct file_operations debugfs_gem_data_fops = { + .read = gf_gem_debugfs_data_read, + .llseek = default_llseek, +}; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) +static ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos, + const void __user *from, size_t count) +{ + loff_t pos = *ppos; + size_t res; + + if (pos < 0) + return -EINVAL; + if (pos >= available || !count) + return 0; + if (count > available - pos) + count = available - pos; + res = copy_from_user(to + pos, from, count); + if (res == count) + return -EFAULT; + count -= res; + *ppos = pos + count; + return count; +} +#endif + +static ssize_t gf_gem_debugfs_control_write(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + gf_gem_debug_info_t *dbg = file_inode(f)->i_private; + struct drm_gf_gem_object *obj = dbg->parent_gem; + gf_card_t *gf = obj->base.dev->dev_private; + char c = 0; + ssize_t ret = 0; + + ret = simple_write_to_buffer(&c, 1, pos, buf, size); + if (ret > 0) { + if (c != '0' && !dbg->mark_unpagable) { + gf_core_interface->prepare_and_mark_unpagable(gf->adapter, obj->core_handle, &obj->info); + dbg->mark_unpagable = true; + } else if (c == '0' && dbg->mark_unpagable) { + gf_core_interface->mark_pagable(gf->adapter, obj->core_handle); + dbg->mark_unpagable = false; + } + ret = size; + } + return ret; +} + +static ssize_t gf_gem_debugfs_control_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) +{ + gf_gem_debug_info_t *dbg = file_inode(f)->i_private; + struct drm_gf_gem_object *obj = dbg->parent_gem; + gf_card_t *gf = obj->base.dev->dev_private; + char c = dbg->mark_unpagable ? '1' : '0'; + + if (!gf->allocation_trace_tags) return 0; + + return simple_read_from_buffer(buf, size, pos, &c, 1); +} + +static const struct file_operations debugfs_gem_control_fops = { + .write = gf_gem_debugfs_control_write, + .read = gf_gem_debugfs_control_read, + .llseek = default_llseek, +}; + +//define from mm_e3k.h +#define BL_BUFFER_SIZE 0x2000000 //32M +#define BL_INDEX_BITS 18 +#define BL_MAPPING_RATIO 512 + +#define BL_SLOT_SIZE (BL_BUFFER_SIZE >> BL_INDEX_BITS) +#define BL_SLICE_ALIGNMENT (BL_BUFFER_SIZE >> BL_INDEX_BITS) + +static ssize_t gf_gem_debugfs_bl_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) +{ + gf_gem_debug_info_t *dbg = file_inode(f)->i_private; + struct drm_gf_gem_object *obj = dbg->parent_gem; + gf_card_t *gf = obj->base.dev->dev_private; + adapter_info_t *ainfo = &gf->adapter_info; + + void *data = NULL; + ssize_t result = 0; + int data_off = 0; + int copy_size = 0; + int a_size = 0; + + gf_vm_area_t *vma = NULL; + gf_map_argu_t map_argu = {0, }; + + if (!gf->allocation_trace_tags) return 0; + + if (!obj->info.bl_slot_index) + { + gf_info("uncompress buffer bl_slot_index is 0\n"); + return result; + } + + map_argu.flags.mem_space = GF_MEM_KERNEL; + map_argu.flags.cache_type = GF_MEM_UNCACHED; + map_argu.flags.mem_type = GF_SYSTEM_IO; + map_argu.phys_addr = obj->info.bl_slot_index * BL_SLOT_SIZE + ainfo->fb_bus_addr; + map_argu.size = ALIGN(obj->info.size/BL_MAPPING_RATIO, BL_SLICE_ALIGNMENT); // 1:512, compress ratio + + //gf_info("offset %u, addr %llu size 0x%lu \n",obj->info.bl_slot_index * BL_SLOT_SIZE, map_argu.phys_addr, map_argu.size); + + vma = gf_map_io_memory(NULL, &map_argu); + + if (vma != NULL) + { + data = vma->virt_addr; + if (data) + { + a_size = vma->size; + data_off = *pos; + copy_size = min(size, (size_t)(a_size - data_off)); + if (copy_to_user(buf, data + data_off, copy_size)) + { + result = -EFAULT; + } + else + { + result += copy_size; + *pos += copy_size; + } + } + else + { + result = -EINVAL; + } + + gf_unmap_io_memory(vma); + } + else + { + gf_error("map bl buffer fail \n"); + result = -EINVAL; + } + + return result; +} + +static const struct file_operations debugfs_gem_bl_fops = { + .read = gf_gem_debugfs_bl_read, + .llseek = default_llseek, +}; + +int gf_gem_debugfs_add_object(struct drm_gf_gem_object *obj) +{ + gf_gem_debug_info_t *dbg = &obj->debug; + int result = 0; + + dbg->is_cpu_accessable = true; //s houdle false for cpu invisable + + gf_vsprintf(dbg->name,"%08x", obj->info.allocation); + + dbg->self_dir = debugfs_create_dir(dbg->name, dbg->root); + if (dbg->self_dir) { + dbg->alloc_info = debugfs_create_file("info", 0444, dbg->self_dir, dbg, &debugfs_gem_info_fops); + dbg->data = debugfs_create_file("data", 0444, dbg->self_dir, dbg, &debugfs_gem_data_fops); + dbg->control = debugfs_create_file("control", 0444, dbg->self_dir, dbg, &debugfs_gem_control_fops); + dbg->bl = debugfs_create_file("bl", 0444, dbg->self_dir, dbg, &debugfs_gem_bl_fops); + }else { + gf_error("create allocation %s dir failed\n", dbg->name); + result = -1; + } + return result; +} + +void gf_gem_debugfs_remove_object(struct drm_gf_gem_object *obj) +{ + gf_gem_debug_info_t *dbg = &obj->debug; + if (dbg->self_dir) { + + debugfs_remove(dbg->alloc_info); + debugfs_remove(dbg->data); + debugfs_remove(dbg->control); + debugfs_remove(dbg->bl); + debugfs_remove(dbg->self_dir); + + dbg->alloc_info = NULL; + dbg->data = NULL; + dbg->self_dir = NULL; + dbg->control = NULL; + dbg->bl = NULL; + } +} + +static inline gf_card_t * get_gfcard(struct pci_dev *dev) +{ + struct drm_device *drm_dev = pci_get_drvdata(dev); + return (gf_card_t *)drm_dev->dev_private; +} +struct drm_gf_gem_object* CONCAT(gf_krnl_gem_create_object,DRIVER_NAME)(struct pci_dev *dev, + gf_create_allocation_t *create, gf_device_debug_info_t **ddev) +{ + gf_card_t *gf = get_gfcard(dev); + return gf_drm_gem_create_object(gf, create, ddev); +} +EXPORT_SYMBOL(CONCAT(gf_krnl_gem_create_object,DRIVER_NAME)); + +int CONCAT(gf_krnl_create_device, DRIVER_NAME)(struct pci_dev *dev, + struct gf_krnl_device_create *vdev_create) +{ + int err = 0; + gf_card_t *gf = get_gfcard(dev); + err = gf_core_interface->create_device(gf->adapter, NULL, &vdev_create->gpu_device); + gf_assert(err == 0, GF_FUNC_NAME(__func__)); + if(gf->debugfs_dev) + { + vdev_create->debug = gf_debugfs_add_device_node(gf->debugfs_dev, gf_get_current_pid(), vdev_create->gpu_device); + } + return err; +} + +EXPORT_SYMBOL(CONCAT(gf_krnl_create_device,DRIVER_NAME)); + +void CONCAT(gf_krnl_destroy_device,DRIVER_NAME)(struct pci_dev *dev, + struct gf_krnl_device_destroy *destroy) +{ + gf_card_t *gf = get_gfcard(dev); + gf_core_interface->destroy_device(gf->adapter, destroy->gpu_device); + if (destroy->debug && gf->debugfs_dev) { + gf_debugfs_remove_device_node(gf->debugfs_dev, destroy->debug); + } +} + +EXPORT_SYMBOL(CONCAT(gf_krnl_destroy_device,DRIVER_NAME)); + diff --git a/drivers/gpu/drm/arise/linux/gf_gem.h b/drivers/gpu/drm/arise/linux/gf_gem.h new file mode 100644 index 0000000000000..ddf63f285cbb7 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_gem.h @@ -0,0 +1,120 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _H_GF_GEM_OBJECT_H +#define _H_GF_GEM_OBJECT_H +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,5,0) +#include +#else +#include +#endif +#include +#include +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,4,0) +#include +#define reservation_object dma_resv +#else +#include +#endif +#include +#include "gf_types.h" +#include "gf_gem_debug.h" +#include "gf_version.h" + +struct drm_gf_gem_object; + +struct drm_gf_gem_object_ops +{ + int (*get_pages)(struct drm_gf_gem_object *); + void (*put_pages)(struct drm_gf_gem_object *, struct sg_table *); + void (*release)(struct drm_gf_gem_object *); +}; + +struct drm_gf_gem_object +{ + struct drm_gem_object base; + const struct drm_gf_gem_object_ops *ops; + + unsigned int core_handle; + struct + { + struct mutex lock; + int pages_pin_count; + struct sg_table *pages; + } mm; + + gf_open_allocation_t info; + gf_map_argu_t map_argu; + gf_vm_area_t *krnl_vma; + struct reservation_object *resv; + struct reservation_object __builtin_resv; + + unsigned int prefault_num; + unsigned int delay_map; + + unsigned int vmap_mem_type; +//debugfs related things + gf_gem_debug_info_t debug; +}; + + +static inline struct drm_gf_gem_object* gf_gem_object_get(struct drm_gf_gem_object* obj) +{ +#if DRM_VERSION_CODE < KERNEL_VERSION(4,12,0) + drm_gem_object_reference(&obj->base); +#else + drm_gem_object_get(&obj->base); +#endif + return obj; +} + +static inline void gf_gem_object_put(struct drm_gf_gem_object* obj) +{ +#if DRM_VERSION_CODE < KERNEL_VERSION(4,12,0) + drm_gem_object_unreference_unlocked(&obj->base); +#elif DRM_VERSION_CODE < KERNEL_VERSION(5,9,0) + drm_gem_object_put_unlocked(&obj->base); +#else + drm_gem_object_put(&obj->base); +#endif +} + +#undef __CONCAT +#undef CONCAT +#define __CONCAT(x,y) x##y +#define CONCAT(x,y) __CONCAT(x,y) + +extern struct drm_gf_gem_object* CONCAT(gf_krnl_gem_create_object, DRIVER_NAME)(struct pci_dev *dev, + gf_create_allocation_t *create, gf_device_debug_info_t **ddev); + + +struct gf_krnl_device_create { + unsigned int gpu_device; //out, virtual device handle + gf_device_debug_info_t *debug; //out, for debugfs +}; + +extern int CONCAT(gf_krnl_create_device, DRIVER_NAME)(struct pci_dev *dev, + struct gf_krnl_device_create *vdev_create); + +struct gf_krnl_device_destroy { + unsigned int gpu_device; //in, virtual device handle + gf_device_debug_info_t *debug; //in, for debugfs +}; + +extern void CONCAT(gf_krnl_destroy_device,DRIVER_NAME)(struct pci_dev *dev, + struct gf_krnl_device_destroy *destroy); + +extern const struct dma_buf_ops CONCAT(gf_dmabuf_ops,DRIVER_NAME); +#endif + diff --git a/drivers/gpu/drm/arise/linux/gf_gem_debug.h b/drivers/gpu/drm/arise/linux/gf_gem_debug.h new file mode 100644 index 0000000000000..d50f873b36c73 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_gem_debug.h @@ -0,0 +1,46 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_GEM_DEUBG_H__ +#define __GF_GEM_DEUBG_H__ +#include "gf_device_debug.h" + +typedef struct gf_gem_debug_info { + gf_device_debug_info_t **parent_dev; /*in*/ + char name[20]; /*in*/ + struct dentry *root; /*in*/ + + + void *parent_gem; + + struct dentry *self_dir; + struct dentry *alloc_info; + + + struct dentry *data; + bool is_cpu_accessable; + + struct dentry *control; + bool mark_unpagable; + + struct dentry *link; + struct dentry *bl; //burst length for compress + + bool is_dma_buf_import; +}gf_gem_debug_info_t; + + + +#endif + diff --git a/drivers/gpu/drm/arise/linux/gf_gem_priv.h b/drivers/gpu/drm/arise/linux/gf_gem_priv.h new file mode 100644 index 0000000000000..d4b95725eec4e --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_gem_priv.h @@ -0,0 +1,175 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_GEM_PRIV_H__ +#define __GF_GEM_PRIV_H__ +#include +#include +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,4,0) +#include +#define reservation_object dma_resv +#else +#include +#endif +#include +#include "gf_types.h" +#include "gf_driver.h" +#include "kernel_import.h" +#include "os_interface.h" +#include "gf_gem_debug.h" + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) || \ + DRM_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) && !defined(YHQILIN) +#include +#else +typedef struct { + u64 val; +} pfn_t; +#endif + + +#define to_gf_bo(gem) container_of(gem, struct drm_gf_gem_object, base) +#define dmabuf_to_gf_bo(dmabuf) to_gf_bo((struct drm_gem_object*)((dmabuf)->priv)) + +static inline unsigned int gf_gem_get_core_handle(gf_file_t *file, unsigned int handle) +{ + struct drm_gem_object *gem; + struct drm_file *drm_file = file->parent_file; + + spin_lock(&drm_file->table_lock); + gem = idr_find(&drm_file->object_idr, handle); + spin_unlock(&drm_file->table_lock); + + if (!gem) + return 0; + + return to_gf_bo(gem)->core_handle; +} + +static inline struct drm_gf_gem_object *gf_gem_get_object(gf_file_t *file, unsigned int handle) +{ + struct drm_gem_object *gem; + struct drm_file *drm_file = file->parent_file; + + spin_lock(&drm_file->table_lock); + gem = idr_find(&drm_file->object_idr, handle); + spin_unlock(&drm_file->table_lock); + + if (!gem) + return NULL; + + return to_gf_bo(gem); +} + +struct drm_gf_driver +{ + struct mutex lock; + struct drm_file *file_priv; + struct drm_driver base; +}; +#define to_drm_gf_driver(drm_driver) container_of((drm_driver), struct drm_gf_driver, base) + +extern struct drm_gf_gem_object* gf_drm_gem_create_object(gf_card_t *gf, gf_create_allocation_t *create, gf_device_debug_info_t **ddev); + +extern int gf_drm_gem_create_object_ioctl(struct drm_file *file, gf_create_allocation_t *create); +extern int gf_drm_gem_create_resource_ioctl(struct drm_file *file, gf_create_resource_t *create); + +extern int gf_gem_mmap_gtt(struct drm_file *file, struct drm_device *dev, uint32_t handle, uint64_t *offset); +extern int gf_gem_mmap_gtt_ioctl(struct drm_file *file, gf_drm_gem_map_t *args); +extern int gf_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); + +extern void gf_gem_free_object(struct drm_gem_object *gem_obj); +extern int gf_gem_open(struct drm_gem_object *gem_obj, struct drm_file *file); +#if DRM_VERSION_CODE < KERNEL_VERSION(6,6,0) +extern int gf_gem_prime_fd_to_handle(struct drm_device *dev, struct drm_file *file_priv, int prime_fd, uint32_t *handle); +#endif + +extern struct drm_gem_object *gf_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,4,0) +extern struct dma_buf *gf_gem_prime_export(struct drm_gem_object *gem_obj, int flags); +#else +extern struct dma_buf *gf_gem_prime_export(struct drm_device *dev, struct drm_gem_object *gem_obj, int flags); +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 11, 0) +extern void *gf_gem_prime_vmap(struct drm_gem_object *gem_obj); +extern void gf_gem_prime_vunmap(struct drm_gem_object *gem_obj, void *vaddr); +#endif + +extern int gf_gem_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); + +extern signed long gf_gem_object_begin_cpu_access(struct drm_gf_gem_object *allocation, long timeout, int write); +extern void gf_gem_object_end_cpu_access(struct drm_gf_gem_object *allocation, int write); +extern int gf_gem_object_begin_cpu_access_ioctl(struct drm_file *file, gf_drm_gem_begin_cpu_access_t *args); +extern void gf_gem_object_end_cpu_access_ioctl(struct drm_file *file, gf_drm_gem_end_cpu_access_t *args); + +extern unsigned int gf_get_from_gem_handle(void *file_, unsigned int handle); +extern void* gf_gem_object_vmap(struct drm_gf_gem_object *obj); +extern void gf_gem_object_vunmap(struct drm_gf_gem_object *obj); + +static inline struct drm_gf_gem_object * +gf_drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, + u32 handle) +{ + struct drm_gem_object *obj; +#if DRM_VERSION_CODE < KERNEL_VERSION(4,7,0) && !defined (PHYTIUM_2000) + obj = drm_gem_object_lookup(dev, filp, handle); +#else + obj = drm_gem_object_lookup(filp, handle); +#endif + + if (!obj) + return NULL; + return to_gf_bo(obj); +} + +extern const struct vm_operations_struct gf_gem_vm_ops; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) +typedef int vm_fault_t; + +static inline vm_fault_t vmf_insert_mixed(struct vm_area_struct *vma, + unsigned long addr, +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) && !(defined(YHQILIN) && DRM_VERSION_CODE == KERNEL_VERSION(4,9,0)) + pfn_t pfn) +#else + unsigned long pfn) +#endif +{ + int err = vm_insert_mixed(vma, addr, pfn); + + if (err == -ENOMEM) + return VM_FAULT_OOM; + if (err < 0 && err != -EBUSY) + return VM_FAULT_SIGBUS; + + return VM_FAULT_NOPAGE; +} + +static inline vm_fault_t vmf_insert_pfn(struct vm_area_struct *vma, + unsigned long addr, unsigned long pfn) +{ + int err = vm_insert_pfn(vma, addr, pfn); + + if (err == -ENOMEM) + return VM_FAULT_OOM; + if (err < 0 && err != -EBUSY) + return VM_FAULT_SIGBUS; + + return VM_FAULT_NOPAGE; +} + +#endif +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_hw_null.c b/drivers/gpu/drm/arise/linux/gf_hw_null.c new file mode 100644 index 0000000000000..39f0261b4dced --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_hw_null.c @@ -0,0 +1,156 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf." +#include "gf_driver.h" +#include "os_interface.h" + + +/* for elite in ahb bus, only use it to check if current card is primary(0x01) */ +int gf_get_command_status16(void *dev, unsigned short *command) +{ + *command = 0x01; + return 0; +} + +int gf_get_command_status32(void *dev, unsigned int *command) +{ + *command = 0x01; + return 0; +} + +/* useless for elite in ahb bus */ +int gf_write_command_status16(void *dev, unsigned short command) +{ + return 0; +} + +/* useless for elite in ahb bus */ +int gf_write_command_status32(void *dev, unsigned int command) +{ + return 0; +} + +/* useless for elite in ahb bus */ +int gf_get_bar1(void *dev, unsigned int *bar1) +{ + *bar1 = 0x0; + return 0; +} + +/* useless for elite in ahb bus */ +int gf_get_rom_save_addr(void *dev, unsigned int *romsave) +{ + *romsave = 0x0; + return 0; +} + +/* useless for elite in ahb bus */ +int gf_write_rom_save_addr(void *dev, unsigned int romsave) +{ + return 0; +} + +int gf_get_platform_config(void *dev, const char* config_name, int *buffer, int length) +{ + + return 0; +} +void gf_get_bus_config(void *dev, bus_config_t *bus) +{ + bus->device_id = 0x3D00;//E3K + bus->vendor_id = 0x1d17; + bus->command = 0x01; + bus->status = 0; + bus->revision_id = 0; + bus->prog_if = 0; + bus->sub_class = 0; + bus->base_class = 0; + bus->cache_line_size = 0; + bus->latency_timer = 0; + bus->header_type = 0; + bus->bist = 0; + bus->sub_sys_vendor_id = 0; + bus->sub_sys_id = 0; + bus->link_status = 0; + + bus->mem_start_addr[0] = 10*1024*1024; + bus->mem_end_addr[0] = 266*1024*1024; + + bus->reg_start_addr[0] = 0; + bus->reg_start_addr[1] = 0x700*1024*1024; + bus->reg_start_addr[2] = 0; + bus->reg_start_addr[3] = 0; + bus->reg_start_addr[4] = 0; + + bus->reg_end_addr[0] = 0; + bus->reg_end_addr[1] = 0x800*1024*1024ul;//total 256M local reserved in linux kernel + bus->reg_end_addr[2] = 0; + bus->reg_end_addr[3] = 0; + bus->reg_end_addr[4] = 0; +} + +/* useless for elite in ahb bus */ +unsigned long gf_get_rom_start_addr(void *dev) +{ + return 0; +} + +/* useless for elite in ahb bus */ +void gf_init_bus_id(gf_card_t *gf) +{ +} + +static gf_card_t *gf_dev = NULL; + +int gf_register_driver(void) +{ + gf_card_t *gf = NULL; + + int result; + + gf = gf_calloc(sizeof(gf_card_t)); + if (!gf) { + gf_error("register driver failed!\n"); + } + gf_memset(gf, 0, sizeof(gf_card_t)); + + gf_info("gf HW_NULL init driver\n"); + + gf_fb_mode = "640x480-32@60"; + + result = gf_card_init(gf, NULL); + gf_dev = gf; + return result; +} + +void gf_unregister_driver(void) +{ + gf_card_t *gf = gf_dev; + + gf_card_deinit(gf); + gf_free(gf); + gf_dev = NULL; +} + +int gf_register_interrupt(gf_card_t *gf, void *isr) +{ + gf_info("gf interrupt irq :NULL\n"); + + return 0; +} + +void gf_unregister_interrupt(gf_card_t *gf) +{ +} diff --git a/drivers/gpu/drm/arise/linux/gf_i2c.c b/drivers/gpu/drm/arise/linux/gf_i2c.c new file mode 100644 index 0000000000000..6edf4fd8f55b1 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_i2c.c @@ -0,0 +1,165 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** +#include "gf_disp.h" +#include "gf_cbios.h" +#include "os_interface.h" +#include "gf_i2c.h" +static int gf_i2c_xfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs, int num) +{ + struct gf_i2c_adapter *gf_adapter = i2c_get_adapdata(i2c_adapter); + struct drm_device *dev = gf_adapter->dev; + gf_connector_t *gf_connector = (gf_connector_t *)(gf_adapter->pgf_connector); + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_i2c_param_t i2c_param; + int i = 0, retval = 0; + for (i = 0; i < num; i++) + { + DRM_DEBUG_KMS("xfer: num: %d/%d, len:%d, flags:%#x\n\n", i + 1, + num, msgs[i].len, msgs[i].flags); + /*gf_info("xfer: num MUTEX: %d/%d, len:%d, flags:%#x\n\n", i + 1, + num, msgs[i].len, msgs[i].flags);*/ + gf_memset(&i2c_param, 0, sizeof(gf_i2c_param_t)); + i2c_param.use_dev_type = 1; + i2c_param.device_id = gf_connector->output_type; + i2c_param.slave_addr = ((msgs[i].addr)<<1); + i2c_param.offset = 0; + i2c_param.buf = msgs[i].buf; + i2c_param.buf_len = msgs[i].len; + i2c_param.request_type = GF_I2C_ERR_TYPE; + if(i2c_param.slave_addr == 0x6E) //DDC operation + { + i2c_param.request_type = GF_I2C_DDCCI; + } + if (msgs[i].flags & I2C_M_RD) + i2c_param.op = GF_I2C_READ; + else + i2c_param.op = GF_I2C_WRITE; + + //if i2c operation is write, but not used to adjust brightness, just skip it + if ((i2c_param.op == GF_I2C_WRITE) && (i2c_param.request_type != GF_I2C_DDCCI)) + { + continue; + } + + gf_mutex_lock(gf_connector->conn_mutex); + retval = disp_cbios_i2c_ctrl(disp_info, &i2c_param); + gf_mutex_unlock(gf_connector->conn_mutex); + if (retval < 0) + return retval; + } + return num; +} + +static u32 gf_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm gf_i2c_algo = +{ + .master_xfer = gf_i2c_xfer, + .functionality = gf_i2c_func, +}; + +struct gf_i2c_adapter *gf_i2c_adapter_create(struct drm_device *dev, struct drm_connector *connector) +{ + struct i2c_adapter *adapter; + struct gf_i2c_adapter *gf_adapter; + gf_connector_t *gf_connector = to_gf_connector(connector); + char *name = NULL; + int ret = 0; + + switch (gf_connector->output_type) + { + case DISP_OUTPUT_CRT: + { + name = "CRT"; + } + break; + case DISP_OUTPUT_DP1: + { + name = "DP1"; + } + break; + case DISP_OUTPUT_DP2: + { + name = "DP2"; + } + break; + case DISP_OUTPUT_DP3: + { + name = "DP3"; + } + break; + case DISP_OUTPUT_DP4: + { + name = "DP4"; + } + break; + default: + { + DRM_DEBUG_KMS("skip create i2c adapter for output 0x%x\n", gf_connector->output_type); + return NULL; + } + } + + gf_adapter = gf_calloc(sizeof(struct gf_i2c_adapter)); + if (!gf_adapter) + { + DRM_ERROR("failed to allo gf_adapter\n"); + return ERR_PTR(-ENOMEM); + } + + adapter = &gf_adapter->adapter; + adapter->owner = THIS_MODULE; +#if DRM_VERSION_CODE < KERNEL_VERSION(6,8,0) + adapter->class = I2C_CLASS_DDC; +#endif + adapter->dev.parent = dev->dev; + gf_adapter->dev = dev; + gf_adapter->pgf_connector = (void *)gf_connector; + i2c_set_adapdata(adapter, gf_adapter); + + gf_vsnprintf(adapter->name, sizeof(adapter->name), "gf_i2c_%s", name); + + adapter->algo = &gf_i2c_algo; + + ret = i2c_add_adapter(adapter); + if (ret) + { + DRM_ERROR("failed to register i2c adapter\n"); + + gf_free(gf_adapter); + gf_adapter = NULL; + + return ERR_PTR(ret); + } + + gf_connector->i2c_adapter = gf_adapter; + + return gf_adapter; +} + +void gf_i2c_adapter_destroy(struct gf_i2c_adapter *gf_adapter) +{ + if (!gf_adapter) + { + return; + } + + i2c_del_adapter(&gf_adapter->adapter); + + gf_free(gf_adapter); +} diff --git a/drivers/gpu/drm/arise/linux/gf_i2c.h b/drivers/gpu/drm/arise/linux/gf_i2c.h new file mode 100644 index 0000000000000..7cacfe30484bb --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_i2c.h @@ -0,0 +1,28 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** +#ifndef __GF_I2C_H__ +#define __GF_I2C_H__ + +struct gf_i2c_adapter +{ + struct i2c_adapter adapter; + struct drm_device *dev; + void *pgf_connector; +}; + +struct gf_i2c_adapter *gf_i2c_adapter_create(struct drm_device *dev, struct drm_connector *connector); + +void gf_i2c_adapter_destroy(struct gf_i2c_adapter *gf_adapter); + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_ioctl.c b/drivers/gpu/drm/arise/linux/gf_ioctl.c new file mode 100644 index 0000000000000..71a1f195f7d61 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_ioctl.c @@ -0,0 +1,545 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_def.h" +#include "gf_ioctl.h" +#include "os_interface.h" +#include "kernel_interface.h" +#include "gf_debugfs.h" +#include "gf_gem.h" +#include "gf_gem_priv.h" +#include "gf_disp.h" + +int gf_ioctl_wait_chip_idle(struct drm_device *dev, void *data,struct drm_file *filp) +{ + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + + gf_core_interface->wait_chip_idle(gf->adapter); + + return 0; +} + + +int gf_ioctl_wait_allocation_idle(struct drm_device *dev, void *data,struct drm_file *filp) +{ + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_wait_allocation_idle_t *wait_allocation = (gf_wait_allocation_idle_t *)data; + + wait_allocation->hAllocation = gf_gem_get_core_handle(priv, wait_allocation->hAllocation); + gf_core_interface->wait_allocation_idle(gf->adapter, wait_allocation); + + return 0; +} + +int gf_ioctl_query_info(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_query_info_t *info = (gf_query_info_t *)data; + unsigned int saved = 0; + + switch(info->type) + { + case GF_QUERY_ALLOCATION_INFO: + case GF_SET_PERF_SWAP_HINT: + case GF_GET_PERF_SWAP_HINT: + saved = info->argu; + info->argu = gf_gem_get_core_handle(priv, info->argu); + break; + case GF_QUERY_ENGINE_CLOCK: + { + if (DISP_OK == disp_cbios_get_clock(gf->disp_info, GF_QUERY_CORE_CLOCK, &info->value)) + { + info->value /= 1000;//cbios clock is KHZ, change to MHZ + goto done; + } + else + { + return -1; + } + } + case GF_QUERY_DIAGS: + { + disp_cbios_get_clock(gf->disp_info, GF_QUERY_MCLK, &info->diags.memory_clk); + disp_cbios_get_clock(gf->disp_info, GF_QUERY_ENGINE_CLOCK, &info->diags.engine_clk); + disp_cbios_get_clock(gf->disp_info, GF_QUERY_VCLK, &info->diags.video_clk); + + info->diags.memory_clk = gf_calc_double_standard_mclk(info->diags.memory_clk) / 2; + } + } + ret = gf_core_interface->query_info(gf->adapter, info); + if (saved) + { + info->argu = saved; + } +done: + return ret; +} + +int gf_ioctl_create_device(struct drm_device *dev, void *data,struct drm_file *filp) +{ + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_create_device_t *create_device = (gf_create_device_t *)data; + + gf_assert(priv->gpu_device != 0, GF_FUNC_NAME(__func__)); + create_device->device = priv->gpu_device; + gf_core_interface->update_device_name(gf->adapter, priv->gpu_device); + if (priv->debug) { + priv->debug->user_pid = gf_get_current_pid(); + } + + return 0; +} + +int gf_ioctl_destroy_device(struct drm_device *dev, void *data,struct drm_file *filp) +{ + gf_file_t *priv = filp->driver_priv; + unsigned int *device = (unsigned int *)data; + + gf_assert(*device == priv->gpu_device, GF_FUNC_NAME(__func__)); + + return 0; +} + +int gf_ioctl_send_perf_event(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_perf_event_t perf_event = {0}; + gf_perf_event_header_t *perf_event_header = (gf_perf_event_header_t *)data; + + if (perf_event_header->size > sizeof(gf_perf_event_t)) + { + return -1; + } + + if (perf_event_header->size >= sizeof(gf_perf_event_header_t)) + { + gf_memcpy((void *)&perf_event, data, perf_event_header->size); + ret = gf_core_interface->send_perf_event(gf->adapter, &perf_event); + } + else + { + return -1; + } + + + return ret; +} + + +int gf_ioctl_get_perf_status(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_perf_status_t *perf_status = (gf_perf_status_t *)data; + + ret = gf_core_interface->get_perf_status(gf->adapter, perf_status); + return ret; +} + +int gf_ioctl_create_di_context(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_create_di_context_t *create_context = (gf_create_di_context_t *)data; + + ret = gf_core_interface->create_di_context(gf->adapter, create_context); + return ret; +} + +int gf_ioctl_destroy_di_context(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_destroy_di_context_t *destroy_context = (gf_destroy_di_context_t *)data; + + ret = gf_core_interface->destroy_di_context(gf->adapter, destroy_context); + return ret; +} + +int gf_ioctl_render(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_cmdbuf_t stack_cmdbufs[8]; + gf_cmdbuf_t __user *cmdbuf; + gf_render_t *render = (gf_render_t *)data; + + cmdbuf = (gf_cmdbuf_t __user*)(unsigned long)render->cmdbuf_array; + if (render->cmdbuf_count > sizeof(stack_cmdbufs)/sizeof(stack_cmdbufs[0])) + { + render->cmdbuf_array = (gf_ptr64_t)(unsigned long)gf_malloc(render->cmdbuf_count * sizeof(gf_cmdbuf_t)); + } + else + { + render->cmdbuf_array = (gf_ptr64_t)(unsigned long)stack_cmdbufs; + } + gf_copy_from_user((void*)(unsigned long)render->cmdbuf_array, cmdbuf, sizeof(gf_cmdbuf_t) * render->cmdbuf_count); + ret = gf_core_interface->render(gf->adapter, render); + if ((unsigned long)render->cmdbuf_array != (unsigned long)stack_cmdbufs) + { + gf_free((void*)(unsigned long)render->cmdbuf_array); + } + + return ret; +} + +int gf_ioctl_create_fence_sync_object(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + + gf_create_fence_sync_object_t *create = (gf_create_fence_sync_object_t *)data; + + ret = gf_core_interface->create_fence_sync_object(gf->adapter, create, FALSE); + return ret; +} + +int gf_ioctl_destroy_fence_sync_object(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + + + gf_destroy_fence_sync_object_t *destroy = (gf_destroy_fence_sync_object_t *)data; + + ret = gf_core_interface->destroy_fence_sync_object(gf->adapter, destroy); + return ret; +} + +int gf_ioctl_wait_fence_sync_object(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + + + gf_wait_fence_sync_object_t *wait = (gf_wait_fence_sync_object_t *)data; + + ret = gf_core_interface->wait_fence_sync_object(gf->adapter, wait); + + return ret; +} + +int gf_ioctl_fence_value(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + + + gf_fence_value_t *value = (gf_fence_value_t *)data; + + ret = gf_core_interface->fence_value(gf->adapter, value); + return ret; +} + + +int gf_ioctl_get_allocation_state(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = -1; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_get_allocation_state_t *state = (gf_get_allocation_state_t *)data; + unsigned int gem = 0; + + gem = state->hAllocation; + state->hAllocation = gf_gem_get_core_handle(priv, gem); + ret = gf_core_interface->get_allocation_state(gf->adapter, state); + + if (ret == 0) + { + state->hAllocation = gem; + } + + return ret; +} + +int gf_ioctl_gem_create_allocation(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = -1; + gf_file_t *priv = filp->driver_priv; + gf_create_allocation_t *create = (gf_create_allocation_t *)data; + unsigned int gem = 0; + + if (create->reference) + { + gem = create->reference; + create->reference = gf_gem_get_core_handle(priv, gem); + } + + ret = gf_drm_gem_create_object_ioctl(priv->parent_file, create); + + if (ret == 0) + { + create->reference = gem; + } + + return ret; +} + + +int gf_ioctl_create_context(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = -1; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_create_context_t *create = (gf_create_context_t *)data; + + ret = gf_core_interface->create_context(gf->adapter, create, GF_MEM_USER); + return ret; +} + +int gf_ioctl_destroy_context(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = -1; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_destroy_context_t *destroy = (gf_destroy_context_t *)data; + + ret = gf_core_interface->destroy_context(gf->adapter, destroy); + return ret; +} + +int gf_ioctl_gem_map_gtt(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = -1; + gf_file_t *priv = filp->driver_priv; + gf_drm_gem_map_t *map = (gf_drm_gem_map_t *)data; + + ret = gf_gem_mmap_gtt_ioctl(priv->parent_file, map); + return ret; +} + + +int gf_ioctl_gem_create_resource(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = -1; + gf_file_t *priv = filp->driver_priv; + gf_create_resource_t *create = (gf_create_resource_t *)data; + + ret = gf_drm_gem_create_resource_ioctl(priv->parent_file, create); + return ret; +} + +int gf_ioctl_add_hw_ctx_buf(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = -1; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_add_hw_ctx_buf_t *add = (gf_add_hw_ctx_buf_t *)data; + + ret = gf_core_interface->add_hw_ctx_buf(gf->adapter, add); + return ret; +} + +int gf_ioctl_rm_hw_ctx_buf(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = -1; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_rm_hw_ctx_buf_t *rm = (gf_rm_hw_ctx_buf_t *)data; + + ret = gf_core_interface->rm_hw_ctx_buf(gf->adapter, rm); + return ret; +} + +int gf_ioctl_gem_begin_cpu_access(struct drm_device *dev, void *data,struct drm_file *filp) +{ + gf_file_t *priv = filp->driver_priv; + gf_drm_gem_begin_cpu_access_t *begin = (gf_drm_gem_begin_cpu_access_t *)data; + + return gf_gem_object_begin_cpu_access_ioctl(priv->parent_file, begin); +} + +int gf_ioctl_cil2_misc(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = -1; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_cil2_misc_t *misc = (gf_cil2_misc_t *)data; + + ret = gf_core_interface->cil2_misc(gf->adapter, misc); + return ret; +} + +int gf_ioctl_gem_end_cpu_access(struct drm_device *dev, void *data,struct drm_file *filp) +{ + gf_file_t *priv = filp->driver_priv; + gf_drm_gem_end_cpu_access_t *end = (gf_drm_gem_end_cpu_access_t *)data; + + gf_gem_object_end_cpu_access_ioctl(priv->parent_file, end); + + return 0; +} + +int gf_ioctl_begin_perf_event(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_begin_perf_event_t *begin_perf_event = (gf_begin_perf_event_t *)data; + + ret = gf_core_interface->begin_perf_event(gf->adapter, begin_perf_event); + return ret; +} + +int gf_ioctl_kms_get_pipe_from_crtc(struct drm_device *dev, void *data,struct drm_file *filp) +{ + gf_file_t *priv = filp->driver_priv; + gf_kms_get_pipe_from_crtc_t *get = (gf_kms_get_pipe_from_crtc_t *)data; + + if (disp_get_pipe_from_crtc(priv, get)) + { + return -1; + } + + return 0; +} + +int gf_ioctl_begin_miu_dump_perf_event(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_begin_miu_dump_perf_event_t *begin_miu_dump = (gf_begin_miu_dump_perf_event_t *)data; + + ret = gf_core_interface->begin_miu_dump_perf_event(gf->adapter, begin_miu_dump); + return ret; +} + +int gf_ioctl_end_perf_event(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_end_perf_event_t *end_perf_event = (gf_end_perf_event_t *)data; + + ret = gf_core_interface->end_perf_event(gf->adapter, end_perf_event); + return ret; +} + +int gf_ioctl_end_miu_dump_perf_event(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_end_miu_dump_perf_event_t *end_miu_dump = (gf_end_miu_dump_perf_event_t *)data; + + ret = gf_core_interface->end_miu_dump_perf_event(gf->adapter, end_miu_dump); + return ret; +} + + +int gf_ioctl_set_miu_reg_list_perf_event(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_miu_reg_list_perf_event_t *miu_reg_list = (gf_miu_reg_list_perf_event_t *)data; + + ret = gf_core_interface->set_miu_reg_list_perf_event(gf->adapter, miu_reg_list); + return ret; +} + +int gf_ioctl_get_miu_dump_perf_event(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_get_miu_dump_perf_event_t *get_miu_dump = (gf_get_miu_dump_perf_event_t *)data; + + ret = gf_core_interface->get_miu_dump_perf_event(gf->adapter, get_miu_dump); + return ret; +} + +int gf_ioctl_direct_get_miu_dump_perf_event(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_direct_get_miu_dump_perf_event_t *direct_get_dump = (gf_direct_get_miu_dump_perf_event_t *)data; + + ret = gf_core_interface->direct_get_miu_dump_perf_event(gf->adapter, direct_get_dump); + return ret; +} + +int gf_ioctl_get_perf_event(struct drm_device *dev, void *data,struct drm_file *filp) +{ + int ret = 0; + gf_file_t *priv = filp->driver_priv; + gf_card_t *gf = priv->card; + gf_get_perf_event_t *get_perf_event = (gf_get_perf_event_t *)data; + + ret = gf_core_interface->get_perf_event(gf->adapter, get_perf_event); + return ret; +} + +struct drm_ioctl_desc gf_ioctls[] = +{ +#define GF_IOCTL_DEF_DRV(ioctl, _func, _flags) \ + [GF_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = { \ + .cmd = ioctl, \ + .func = _func, \ + .flags = _flags, \ + .name = #ioctl \ + } + + GF_IOCTL_DEF_DRV(GF_IOCTL_WAIT_CHIP_IDLE,gf_ioctl_wait_chip_idle,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_WAIT_ALLOCATION_IDLE,gf_ioctl_wait_allocation_idle,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_QUERY_INFO,gf_ioctl_query_info,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_CREATE_DEVICE,gf_ioctl_create_device,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_DESTROY_DEVICE,gf_ioctl_destroy_device,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_BEGIN_PERF_EVENT,gf_ioctl_begin_perf_event,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_END_PERF_EVENT,gf_ioctl_end_perf_event,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_GET_PERF_EVENT,gf_ioctl_get_perf_event,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_SEND_PERF_EVENT,gf_ioctl_send_perf_event,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_GET_PERF_STATUS,gf_ioctl_get_perf_status,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_BEGIN_MIU_DUMP_PERF_EVENT,gf_ioctl_begin_miu_dump_perf_event,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_END_MIU_DUMP_PERF_EVENT,gf_ioctl_end_miu_dump_perf_event,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_SET_MIU_REG_LIST_PERF_EVENT,gf_ioctl_set_miu_reg_list_perf_event,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_GET_MIU_DUMP_PERF_EVENT,gf_ioctl_get_miu_dump_perf_event,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_DIRECT_GET_MIU_DUMP_PERF_EVENT,gf_ioctl_direct_get_miu_dump_perf_event,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_CREATE_CONTEXT,gf_ioctl_create_context,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_DESTROY_CONTEXT,gf_ioctl_destroy_context,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_RENDER,gf_ioctl_render,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_CREATE_FENCE_SYNC_OBJECT,gf_ioctl_create_fence_sync_object,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_DESTROY_FENCE_SYNC_OBJECT,gf_ioctl_destroy_fence_sync_object,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_WAIT_FENCE_SYNC_OBJECT,gf_ioctl_wait_fence_sync_object,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_FENCE_VALUE,gf_ioctl_fence_value,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_CREATE_DI_CONTEXT,gf_ioctl_create_di_context,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_DESTROY_DI_CONTEXT,gf_ioctl_destroy_di_context,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_GET_ALLOCATION_STATE,gf_ioctl_get_allocation_state,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_ADD_HW_CTX_BUF,gf_ioctl_add_hw_ctx_buf,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_RM_HW_CTX_BUF,gf_ioctl_rm_hw_ctx_buf,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_CIL2_MISC,gf_ioctl_cil2_misc,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_DRM_GEM_CREATE_ALLOCATION,gf_ioctl_gem_create_allocation,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_DRM_GEM_CREATE_RESOURCE,gf_ioctl_gem_create_resource,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_DRM_GEM_MAP_GTT,gf_ioctl_gem_map_gtt,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_DRM_BEGIN_CPU_ACCESS,gf_ioctl_gem_begin_cpu_access,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_DRM_END_CPU_ACCESS,gf_ioctl_gem_end_cpu_access,DRM_AUTH|DRM_RENDER_ALLOW), + GF_IOCTL_DEF_DRV(GF_IOCTL_KMS_GET_PIPE_FROM_CRTC,gf_ioctl_kms_get_pipe_from_crtc,DRM_AUTH|DRM_RENDER_ALLOW), +}; diff --git a/drivers/gpu/drm/arise/linux/gf_ioctl.h b/drivers/gpu/drm/arise/linux/gf_ioctl.h new file mode 100644 index 0000000000000..41298cb7600f1 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_ioctl.h @@ -0,0 +1,145 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_IOCTL_H__ +#define __GF_IOCTL_H__ + +#if defined(__linux__) +#include +#include +#define GF_IOCTL_NR(n) _IOC_NR(n) +#define GF_IOCTL_TYPE(n) _IOC_TYPE(n) +#define GF_IOC_VOID _IOC_NONE +#define GF_IOC_READ _IOC_READ +#define GF_IOC_WRITE _IOC_WRITE +#define GF_IOC_READWRITE _IOC_READ | _IOC_WRITE +#define GF_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#if defined(__FreeBSD__) && defined(IN_MODULE) +#undef ioctl +#include +#define ioctl(a,b,c) xf86ioctl(a,b,c) +#else +#include +#endif +#define GF_IOCTL_NR(n) ((n) & 0xff) +#define GF_IOCTL_TYPE(n) (((n) >> 8) & 0xff) +#define GF_IOC_VOID IOC_VOID +#define GF_IOC_READ IOC_OUT +#define GF_IOC_WRITE IOC_IN +#define GF_IOC_READWRITE IOC_INOUT +#define GF_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#endif + +#ifndef __user +#define __user +#endif + +enum gf_ioctl_nr +{ + ioctl_nr_begin_perf_event = 0, + ioctl_nr_end_perf_event = 1, + ioctl_nr_get_perf_event = 2, + ioctl_nr_send_perf_event = 3, + ioctl_nr_get_perf_status = 4, + ioctl_nr_begin_miu_dump_perf_event = 5, + ioctl_nr_end_miu_dump_perf_event = 6, + ioctl_nr_set_miu_reg_list_perf_event = 7, + ioctl_nr_get_miu_dump_perf_event = 8, + ioctl_nr_direct_get_miu_dump_perf_event = 9, + ioctl_nr_perf_reserved = 10, + + ioctl_nr_wait_chip_idle = 11, + ioctl_nr_wait_allocation_idle = 12, + ioctl_nr_query_info = 13, + ioctl_nr_create_device = 14, + ioctl_nr_destroy_device = 15, + ioctl_nr_create_context = 16, + ioctl_nr_destroy_context = 17, + ioctl_nr_render = 18, + ioctl_nr_create_fence_sync_object = 19, + ioctl_nr_destroy_fence_sync_object = 20, + ioctl_nr_wait_fence_sync_object = 21, + ioctl_nr_fence_value = 22, + ioctl_nr_get_allocation_state = 23, + + ioctl_nr_drm_gem_create_allocation = 24, + ioctl_nr_drm_gem_create_resource = 25, + ioctl_nr_drm_gem_map = 26, + ioctl_nr_drm_begin_cpu_access = 27, + ioctl_nr_drm_end_cpu_access = 28, + ioctl_nr_kms_get_pipe_from_crtc = 29, + + ioctl_nr_get_hw_context = 30, + ioctl_nr_add_hw_context = 31, + ioctl_nr_rm_hw_context = 32, + + ioctl_nr_cil2_misc = 33, + + ioctl_nr_video = 36, + ioctl_nr_create_di_context = 37, + ioctl_nr_destroy_di_context = 38, + ioctl_nr_set_interactive = 39, + + /* new ioctl MUST add before 'ioctl_nr_total_num' which used to count total ioctl nums */ + ioctl_nr_total_num +}; + +#define GF_IOCTL_BASE 'd' +#define GF_IO(nr) _IO(GF_IOCTL_BASE, nr) +#define GF_IOR(nr, type) _IOR(GF_IOCTL_BASE, nr, type) +#define GF_IOW(nr, type) _IOW(GF_IOCTL_BASE, nr, type) +#define GF_IOWR(nr, type) _IOWR(GF_IOCTL_BASE, nr, type) + +#define GF_IOCTL_WAIT_CHIP_IDLE GF_IO(DRM_COMMAND_BASE + ioctl_nr_wait_chip_idle) +#define GF_IOCTL_ESCAPE_CALL GF_IOW(DRM_COMMAND_BASE + ioctl_nr_escape_call, long) +#define GF_IOCTL_WAIT_ALLOCATION_IDLE GF_IOW(DRM_COMMAND_BASE + ioctl_nr_wait_allocation_idle, gf_wait_allocation_idle_t) +#define GF_IOCTL_QUERY_INFO GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_query_info, gf_query_info_t) +#define GF_IOCTL_CREATE_DEVICE GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_create_device, gf_create_device_t) +#define GF_IOCTL_DESTROY_DEVICE GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_destroy_device, unsigned int) +#define GF_IOCTL_BEGIN_PERF_EVENT GF_IOW(DRM_COMMAND_BASE + ioctl_nr_begin_perf_event, gf_begin_perf_event_t) +#define GF_IOCTL_END_PERF_EVENT GF_IOW(DRM_COMMAND_BASE + ioctl_nr_end_perf_event, gf_end_perf_event_t) +#define GF_IOCTL_GET_PERF_EVENT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_get_perf_event, gf_get_perf_event_t) +#define GF_IOCTL_SEND_PERF_EVENT GF_IOW(DRM_COMMAND_BASE + ioctl_nr_send_perf_event, gf_perf_event_t) +#define GF_IOCTL_GET_PERF_STATUS GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_get_perf_status, gf_perf_status_t) +#define GF_IOCTL_BEGIN_MIU_DUMP_PERF_EVENT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_begin_miu_dump_perf_event, gf_begin_miu_dump_perf_event_t) +#define GF_IOCTL_END_MIU_DUMP_PERF_EVENT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_end_miu_dump_perf_event, gf_end_miu_dump_perf_event_t) +#define GF_IOCTL_SET_MIU_REG_LIST_PERF_EVENT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_set_miu_reg_list_perf_event, gf_miu_reg_list_perf_event_t) +#define GF_IOCTL_GET_MIU_DUMP_PERF_EVENT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_get_miu_dump_perf_event, gf_get_miu_dump_perf_event_t) +#define GF_IOCTL_DIRECT_GET_MIU_DUMP_PERF_EVENT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_direct_get_miu_dump_perf_event, gf_direct_get_miu_dump_perf_event_t) +#define GF_IOCTL_CREATE_CONTEXT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_create_context, gf_create_context_t) +#define GF_IOCTL_DESTROY_CONTEXT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_destroy_context, gf_destroy_context_t) +#define GF_IOCTL_RENDER GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_render, gf_render_t) +#define GF_IOCTL_CREATE_FENCE_SYNC_OBJECT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_create_fence_sync_object, gf_create_fence_sync_object_t) +#define GF_IOCTL_DESTROY_FENCE_SYNC_OBJECT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_destroy_fence_sync_object, gf_destroy_fence_sync_object_t) +#define GF_IOCTL_WAIT_FENCE_SYNC_OBJECT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_wait_fence_sync_object, gf_wait_fence_sync_object_t) +#define GF_IOCTL_FENCE_VALUE GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_fence_value, gf_fence_value_t) +#define GF_IOCTL_CREATE_DI_CONTEXT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_create_di_context, gf_create_di_context_t) +#define GF_IOCTL_DESTROY_DI_CONTEXT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_destroy_di_context, gf_destroy_di_context_t) +#define GF_IOCTL_RENDER GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_render, gf_render_t) +#define GF_IOCTL_GET_ALLOCATION_STATE GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_get_allocation_state, gf_get_allocation_state_t) + + +#define GF_IOCTL_DRM_GEM_CREATE_ALLOCATION GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_drm_gem_create_allocation, gf_create_allocation_t) +#define GF_IOCTL_DRM_GEM_CREATE_RESOURCE GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_drm_gem_create_resource, gf_create_resource_t) +#define GF_IOCTL_DRM_GEM_MAP_GTT GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_drm_gem_map, gf_drm_gem_map_t) +#define GF_IOCTL_ADD_HW_CTX_BUF GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_add_hw_context, gf_add_hw_ctx_buf_t) +#define GF_IOCTL_RM_HW_CTX_BUF GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_rm_hw_context, gf_rm_hw_ctx_buf_t) +#define GF_IOCTL_DRM_BEGIN_CPU_ACCESS GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_drm_begin_cpu_access, gf_drm_gem_begin_cpu_access_t) +#define GF_IOCTL_DRM_END_CPU_ACCESS GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_drm_end_cpu_access, gf_drm_gem_end_cpu_access_t) +#define GF_IOCTL_KMS_GET_PIPE_FROM_CRTC GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_kms_get_pipe_from_crtc, gf_kms_get_pipe_from_crtc_t) + +#define GF_IOCTL_CIL2_MISC GF_IOWR(DRM_COMMAND_BASE + ioctl_nr_cil2_misc, gf_cil2_misc_t) + +#endif //__GF_IOCTL_H__ diff --git a/drivers/gpu/drm/arise/linux/gf_irq.c b/drivers/gpu/drm/arise/linux/gf_irq.c new file mode 100755 index 0000000000000..9152f3dd61de4 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_irq.c @@ -0,0 +1,1683 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_irq.h" +#include "gf_crtc.h" +#include "gf_capture_drv.h" +#include "gf_disp.h" +#include "gf_kms.h" +#include "gf_splice.h" +#include "gf_trace.h" + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) +/* get_scanout_position() return flags */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) +#endif + +#define DEFAULT_PRINT_COUNT 3 +#define VIDEO_ERROR_INFO_NUM 8 + +#define RESET_TIME_MINUTE_interval 10 + + +static int video_irq_info_count[VIDEO_ERROR_INFO_NUM] = {0}; +static ktime_t video_irq_info_time[VIDEO_ERROR_INFO_NUM] = {0}; +static int video_irq_mask[VIDEO_ERROR_INFO_NUM] = {INT_FE_HANG_VD0, INT_BE_HANG_VD0, INT_FE_HANG_VD1, INT_BE_HANG_VD1, + INT_FE_ERROR_VD0, INT_BE_ERROR_VD0, INT_FE_ERROR_VD1, INT_BE_ERROR_VD1}; +static char* video_irq_name[VIDEO_ERROR_INFO_NUM] = {"CORE0_FE_HANG", "CORE0_BE_HANG", "CORE1_FE_HANG", "CORE1_BE_HANG", + "CORE0_FE_ERROR", "CORE0_BE_ERROR", "CORE1_FE_ERROR", "CORE1_BE_ERROR"}; +static int video_reg_offset[VIDEO_ERROR_INFO_NUM] = {0x4C81C, 0x4C81C, 0x4A81C, 0x4A81C, 0x4C81C, 0x4C81C, 0x4A81C, 0x4A81C}; + + + + +static struct drm_crtc* gf_get_crtc_by_pipe(struct drm_device *dev, pipe_t pipe) +{ + struct drm_crtc *crtc = NULL; + + list_for_each_entry(crtc, &(dev->mode_config.crtc_list), head) + { + if (drm_get_crtc_index(crtc) == pipe) + { + return crtc; + } + } + + return NULL; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) +u32 gf_get_vblank_counter(struct drm_crtc *crtc) +#else +u32 gf_get_vblank_counter(struct drm_device *dev, pipe_t pipe) +#endif +{ +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; +#endif + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_get_counter_t gf_counter; + int vblank_cnt = 0; + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) + if (is_splice_target_crtc(dev, pipe)) + { + return gf_splice_get_vblank_counter(dev, pipe); + } +#endif + + gf_memset(&gf_counter, 0, sizeof(gf_get_counter_t)); + gf_counter.crtc_index = pipe; + gf_counter.vblk = &vblank_cnt; + disp_cbios_get_counter(disp_info, &gf_counter); + + return (u32)vblank_cnt; +} + + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 13, 0) +int gf_get_vblank_timestamp(struct drm_device *dev, pipe_t pipe, + int *max_error, struct timeval *time, unsigned flags) +#else +bool gf_get_vblank_timestamp(struct drm_device *dev, + unsigned int pipe, + int *max_error, + #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) + ktime_t *vblank_time, + #else + struct timeval *vblank_time, + #endif + bool in_vblank_irq) +#endif +{ + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 13, 0) + struct drm_crtc *crtc = gf_get_crtc_by_pipe(dev, pipe); + struct drm_display_mode *mode; + + if (!crtc) + return -EINVAL; + + if (is_splice_target_crtc(dev, pipe)) + { + return gf_splice_get_vblank_timestamp(dev, pipe, max_error, time, flags); + } + + mode = &crtc->hwmode; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) + if (dev->mode_config.funcs->atomic_commit) + { + mode = &crtc->state->adjusted_mode; + } + + return drm_calc_vbltimestamp_from_scanoutpos(dev, + pipe, max_error, time, flags, mode); +#else + return drm_calc_vbltimestamp_from_scanoutpos(dev, + pipe, max_error, time, flags, crtc, mode); +#endif + +#else + + if (is_splice_target_crtc(dev, pipe)) + { + return gf_splice_get_vblank_timestamp(dev, pipe, max_error, vblank_time, in_vblank_irq); + } + + return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, + vblank_time, in_vblank_irq); +#endif +} +#endif + +int gf_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + unsigned int flags, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_get_counter_t gf_counter; + int in_vblank = 0, ret = 0, status = 0; + + gf_memset(&gf_counter, 0, sizeof(gf_get_counter_t)); + gf_counter.crtc_index = pipe; + gf_counter.hpos = hpos; + gf_counter.vpos = vpos; + gf_counter.in_vblk = &in_vblank; + + if (stime) + { + *stime = ktime_get(); + } + + status = disp_cbios_get_counter(disp_info, &gf_counter); + + if (etime) + { + *etime = ktime_get(); + } + + if(status == DISP_OK) + { + ret = DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; + if(in_vblank) + { + *vpos -= mode->crtc_vblank_end; + if(*hpos) + { + *hpos -= mode->crtc_htotal; + *vpos += 1; + } + ret |= DRM_SCANOUTPOS_IN_VBLANK; + } + } + + return ret; +} + +int gf_legacy_get_crtc_scanoutpos(struct drm_device *dev, int pipe, unsigned int flags, + int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) +{ + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_get_counter_t gf_counter; + struct drm_crtc* crtc = NULL; + struct drm_display_mode* mode = NULL; + int in_vblank = 0, ret = 0, status = 0; + + gf_memset(&gf_counter, 0, sizeof(gf_get_counter_t)); + gf_counter.crtc_index = pipe; + gf_counter.hpos = hpos; + gf_counter.vpos = vpos; + gf_counter.in_vblk = &in_vblank; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + { + if(crtc && to_gf_crtc(crtc)->pipe == pipe) + { + mode = &crtc->hwmode; + break; + } + } + if (stime) + { + *stime = ktime_get(); + } + status = disp_cbios_get_counter(disp_info, &gf_counter); + + if (etime) + { + *etime = ktime_get(); + } + if(status == DISP_OK) + { + ret = DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; + if(in_vblank) + { + if(mode) + { + *vpos -= mode->crtc_vblank_end; + if(*hpos) + { + *hpos -= mode->crtc_htotal; + *vpos += 1; + } + } + ret |= DRM_SCANOUTPOS_IN_VBLANK; + } + } + + return ret; +} + +bool gf_get_crtc_scanoutpos_kernel_4_10(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + return gf_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, stime, etime, mode); +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) +bool gf_crtc_get_scanout_position(struct drm_crtc *crtc, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; + + return gf_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, stime, etime, mode); +} +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) +int gf_enable_vblank(struct drm_crtc *crtc) +#else +int gf_enable_vblank(struct drm_device *dev, pipe_t pipe) +#endif +{ +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; +#endif + + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + irq_chip_funcs_t* chip_func = (irq_chip_funcs_t*)disp_info->irq_chip_func; + int intrrpt = 0, intr_en = 0; + unsigned long flags = 0; + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) + if (is_splice_target_crtc(dev, pipe)) + { + return gf_splice_enable_vblank(dev, pipe); + } +#endif + + if(!chip_func || !chip_func->get_intr_enable_mask || !chip_func->set_intr_enable_mask) + { + return 0; + } + + if(pipe == IGA1) + { + intrrpt = INT_VSYNC1; + } + else if(pipe == IGA2) + { + intrrpt = INT_VSYNC2; + } + else if(pipe == IGA3) + { + intrrpt = INT_VSYNC3; + } + else if(pipe == IGA4) + { + intrrpt = INT_VSYNC4; + } + + flags = gf_spin_lock_irqsave(disp_info->intr_lock); + + if(disp_info->irq_enabled) + { + intr_en = chip_func->get_intr_enable_mask(disp_info); + intr_en |= intrrpt; + chip_func->set_intr_enable_mask(disp_info, intr_en); + } + else + { + disp_info->intr_en_bits |= intrrpt; + } + + gf_spin_unlock_irqrestore(disp_info->intr_lock, flags); + + trace_gfx_vblank_onoff(gf_card->index << 16 | pipe, 1); + + return 0; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) +void gf_disable_vblank(struct drm_crtc *crtc) +#else +void gf_disable_vblank(struct drm_device *dev, pipe_t pipe) +#endif +{ +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; +#else + struct drm_crtc *crtc = gf_get_crtc_by_pipe(dev, pipe); +#endif + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + irq_chip_funcs_t* chip_func = (irq_chip_funcs_t*)disp_info->irq_chip_func; + int intrrpt = 0, intr_en = 0; + unsigned long flags = 0; + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) + if (is_splice_target_crtc(dev, pipe)) + { + return gf_splice_disable_vblank(dev, pipe); + } +#endif + + if (!(is_crtc_work_in_splice_mode(crtc) && + is_splice_target_active_in_drm(dev))) + { + + if(!chip_func || !chip_func->get_intr_enable_mask || !chip_func->set_intr_enable_mask) + { + return; + } + + if(pipe == IGA1) + { + intrrpt = INT_VSYNC1; + } + else if(pipe == IGA2) + { + intrrpt = INT_VSYNC2; + } + else if(pipe == IGA3) + { + intrrpt = INT_VSYNC3; + } + else if(pipe == IGA4) + { + intrrpt = INT_VSYNC4; + } + + flags = gf_spin_lock_irqsave(disp_info->intr_lock); + + if(disp_info->irq_enabled) + { + intr_en = chip_func->get_intr_enable_mask(disp_info); + intr_en &= ~intrrpt; + chip_func->set_intr_enable_mask(disp_info, intr_en); + } + else + { + disp_info->intr_en_bits &= ~intrrpt; + } + + gf_spin_unlock_irqrestore(disp_info->intr_lock, flags); + } + + trace_gfx_vblank_onoff(gf_card->index << 16 | pipe, 0); +} + + +void gf_disp_enable_interrupt(disp_info_t* disp_info, int irq_inst_uninst) +{ + gf_card_t* gf_card = disp_info->gf_card; + irq_chip_funcs_t* chip_func = (irq_chip_funcs_t*)disp_info->irq_chip_func; + int intr_en, fence_int_lost = 0, new_int = 0; + unsigned long flags = 0; +#ifdef _DEBUG_ + adapter_info_t* adapter = disp_info->adp_info; + unsigned char mm8aa0 = 0; +#endif + + if(!chip_func || !chip_func->enable_interrupt) + { + return; + } + + if(!irq_inst_uninst && disp_info->irq_enabled) + { + return; + } + +#ifdef _DEBUG_ + gf_info("To enable GFX interrupt.\n"); +#endif + + flags = gf_spin_lock_irqsave(disp_info->intr_lock); + + if(irq_inst_uninst) + { + intr_en = DEF_INTR | disp_info->intr_en_bits; + } + else + { + intr_en = disp_info->intr_en_bits; //intr_en_bits is saved by disable_interrupt func + } + + if((intr_en & INT_FENCE) == 0) + { + intr_en |= INT_FENCE; + fence_int_lost = 1; + } + + chip_func->enable_interrupt(disp_info, intr_en); + + if(gf_card->pdev->msi_enabled && chip_func->enable_msi) + { + chip_func->enable_msi(disp_info); + } + + new_int = chip_func->get_intr_enable_mask(disp_info); + + if(!irq_inst_uninst) + { + disp_info->irq_enabled = 1; + } + + gf_spin_unlock_irqrestore(disp_info->intr_lock, flags); + +#ifdef _DEBUG_ + mm8aa0 = gf_read8(adapter->mmio + 0x8AA0); + gf_info("After enable interrupt, mm8AA0=0x%x.\n", mm8aa0); +#endif + + if(intr_en == new_int && new_int) + { +#ifdef _DEBUG_ + gf_info("Enabled int is 0x%x.\n", new_int); +#endif + } + else + { + gf_error("#### Something error, old int:0x%x, new int:0x%x. ####\n", intr_en, new_int); + } + + if(fence_int_lost) + { + gf_error("#### Fence INT cleared by sw! inter_en %x ####\n", (intr_en & ~INT_FENCE)); +#ifdef _DEBUG_ + gf_dump_stack(); +#endif + } +} + +void gf_disp_disable_interrupt(disp_info_t* disp_info, int irq_inst_uninst) +{ + gf_card_t* gf_card = disp_info->gf_card; + irq_chip_funcs_t* chip_func = (irq_chip_funcs_t*)disp_info->irq_chip_func; + int intr_en; + unsigned long flags = 0; + + if(!chip_func || !chip_func->disable_interrupt) + { + return; + } + + if(!irq_inst_uninst && !disp_info->irq_enabled) + { + return; + } + +#ifdef _DEBUG_ + gf_info("To disable GFX interrupt.\n"); +#endif + + flags = gf_spin_lock_irqsave(disp_info->intr_lock); + + intr_en = chip_func->disable_interrupt(disp_info); + + if(gf_card->pdev->msi_enabled && chip_func->disable_msi) + { + chip_func->disable_msi(disp_info); + } + + if(!irq_inst_uninst) + { + disp_info->irq_enabled = 0; + disp_info->intr_en_bits = intr_en; + if((intr_en & INT_FENCE) == 0) + { + //patch for fence INT lost issue + disp_info->intr_en_bits |= INT_FENCE; + } + } + + gf_spin_unlock_irqrestore(disp_info->intr_lock, flags); + + if(((intr_en & INT_FENCE) == 0) && (!irq_inst_uninst)) + { + gf_error("#### Found hw reg value exception! inter_en %x ####\n", intr_en); +#ifdef _DEBUG_ + gf_dump_stack(); +#endif + } +} + +void gf_irq_preinstall(struct drm_device *dev) +{ + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + + //disable all interrupt + gf_disp_disable_interrupt(disp_info, 1); +} + +int gf_irq_postinstall(struct drm_device *dev) +{ + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + + gf_disp_enable_interrupt(disp_info, 1); + + return 0; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) + +int gf_irq_install(struct drm_device *drm_dev) +{ + int irq = to_pci_dev(drm_dev->dev)->irq; + int ret = 0; + + gf_irq_preinstall(drm_dev); + + ret = request_irq(irq, gf_irq_handle, IRQF_SHARED, STR(DRIVER_NAME), drm_dev); + + if (ret < 0) + { + gf_error("request irq failed\n"); + return ret; + } + + gf_irq_postinstall(drm_dev); + + return ret; +} + +#endif + +static void gf_vblank_intrr_handle(struct drm_device* dev, unsigned int intrr) +{ + unsigned int index = 0; + unsigned int vsync[MAX_CRTC_NUM] = {INT_VSYNC1, INT_VSYNC2, INT_VSYNC3, INT_VSYNC4}; + struct drm_crtc* crtc = NULL; + gf_card_t *gf = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + gf_splice_target_t *target = NULL; + gf_splice_source_t *source = NULL; + struct drm_crtc *splice_source_crtc = NULL, *splice_target_crtc = NULL; + + if (splice_manager != NULL) + { + target = &splice_manager->target; + splice_target_crtc = target->crtc; + if (to_gf_crtc(splice_target_crtc)->enabled) + { + source = &(splice_manager->sources[target->config.vblank_source]); + + splice_source_crtc = gf_splice_get_crtc_by_source(dev, source); + } + } + + if(intrr & INT_VSYNCS) + { + for (index = 0; index < MAX_CRTC_NUM; index++) + { + if (intrr & vsync[index]) + { + gf_perf_event_t perf_event = {0, }; + gf_get_counter_t get_cnt = {0, }; + unsigned int vblcnt = 0; + unsigned long long timestamp; + + crtc = gf_get_crtc_by_pipe(dev, index); + + //TODO: support splice combination with stand along connector + if (splice_source_crtc == crtc) + { + drm_crtc_handle_vblank(splice_target_crtc); + } + + if (to_gf_crtc(crtc)->enabled) + { + drm_crtc_handle_vblank(crtc); + } + + get_cnt.crtc_index = index; + get_cnt.vblk = &vblcnt; + disp_cbios_get_counter(disp_info, &get_cnt); + + trace_gfx_vblank_intrr(gf->index << 16 | index, vblcnt); + + gf_get_nsecs(×tamp); + perf_event.header.timestamp_high = timestamp >> 32; + perf_event.header.timestamp_low = timestamp & 0xffffffff; + perf_event.header.size = sizeof(gf_perf_event_vsync_t); + perf_event.header.type = GF_PERF_EVENT_VSYNC; + perf_event.vsync_event.iga_idx = index + 1; + perf_event.vsync_event.vsync_cnt_low = vblcnt; + perf_event.vsync_event.vsync_cnt_high = 0; + + gf_core_interface->perf_event_add_isr_event(gf->adapter, &perf_event); + //gf_core_interface->hwq_process_vsync_event(gf->adapter, timestamp); + } + } + } +} + +#define MAX_DP_QUEUE_DEPTH (MAX_DP_EVENT_NUM -1) +#define DP_QUEUE_DEPTH(head, tail) ((head <= tail)? (tail-head) : (MAX_DP_EVENT_NUM -head + tail)) +#define DP_QUEUE_FULL(head, tail) (DP_QUEUE_DEPTH(head, tail) >= MAX_DP_QUEUE_DEPTH) +#define DP_QUEUE_EMPTY(head, tail) (DP_QUEUE_DEPTH(head, tail) == 0) +#define DP_ADVANCE_QUEUE_POS(pos) {pos = (pos < MAX_DP_QUEUE_DEPTH)? (pos + 1) : 0; } + + +static void gf_hpd_handle(struct drm_device* dev, unsigned int hpd) +{ + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + struct drm_connector* connector = NULL; + gf_connector_t* gf_connector = NULL; + int hpd_happen = 0, dp_int = 0, queue_irq_work = 0; + unsigned long flags; + + if(!hpd) + { + return; + } + + flags = gf_spin_lock_irqsave(disp_info->hpd_lock); + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + gf_connector = to_gf_connector(connector); + + if((connector->polled == DRM_CONNECTOR_POLL_HPD) && + (gf_connector->hpd_int_bit & hpd) && (gf_connector->hpd_enable)) + { + if(connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort || + connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) + { + dp_int = disp_cbios_get_dpint_type(disp_info, gf_connector->output_type); + if(dp_int == DP_HPD_HDMI_OUT || dp_int == DP_HPD_DP_OUT) + { + hpd_happen = 1; + disp_info->hpd_outputs |= gf_connector->output_type; +#if GF_RUN_HDCP_CTS + disp_cbios_enable_hdcp(disp_info, FALSE, gf_connector->output_type); + gf_connector->hdcp_enable = 0; + gf_connector->hpd_out = 1; +#endif + } + else if(dp_int == DP_HPD_IRQ || dp_int == DP_HPD_IN) + { + if(DP_QUEUE_EMPTY(disp_info->head, disp_info->tail)) + { + queue_irq_work = 1; + } + + if(!DP_QUEUE_FULL(disp_info->head, disp_info->tail)) + { + disp_info->event[disp_info->tail].device = gf_connector->output_type; + disp_info->event[disp_info->tail].int_type = dp_int; + DP_ADVANCE_QUEUE_POS(disp_info->tail); + } + } + } + else + { + hpd_happen = 1; + disp_info->hpd_outputs |= gf_connector->output_type; + } + } + } + + gf_spin_unlock_irqrestore(disp_info->hpd_lock, flags); + + if(queue_irq_work) + { + schedule_work(&disp_info->dp_irq_work); + } + + if(hpd_happen) + { + schedule_work(&disp_info->hotplug_work); + } +} + +#define HDAC_INT_REG1 0x8288 +#define HDAC_INT_REG2 0x33D9C +#define HDAC_INT_BITS (1 << 25) + +static void gf_hdaudio_handle(struct drm_device* dev) +{ + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + adapter_info_t* adapter = disp_info->adp_info; + struct drm_connector* connector = NULL; + gf_connector_t* gf_connector = NULL; + unsigned long flags; + unsigned int hdac_int_value = 0; + unsigned int hda_codec_index = 0; + + hdac_int_value = gf_read32(adapter->mmio + HDAC_INT_REG1); + gf_write32(adapter->mmio + HDAC_INT_REG1, (hdac_int_value & ~HDAC_INT_BITS)); + if(hdac_int_value & HDAC_INT_BITS) + { + hda_codec_index |= (1 << 0); + } + + hdac_int_value = gf_read32(adapter->mmio + HDAC_INT_REG2); + gf_write32(adapter->mmio + HDAC_INT_REG2, (hdac_int_value & ~HDAC_INT_BITS)); + if(hdac_int_value & HDAC_INT_BITS) + { + hda_codec_index |= (1 << 1); + } + + if(!hda_codec_index) + { + return; + } + + flags = gf_spin_lock_irqsave(disp_info->hda_lock); + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + gf_connector = to_gf_connector(connector); + + if(gf_connector->hda_codec_index & hda_codec_index) + { + disp_info->hda_intr_outputs |= gf_connector->output_type; + } + } + + gf_spin_unlock_irqrestore(disp_info->hda_lock, flags); + + if(disp_info->hda_intr_outputs) + { + schedule_work(&disp_info->hda_work); + } +} + + +#define HDCP_INT_REG1 0x82C8 +#define HDCP_INT_REG2 0x33C70 +#define HDCP_INT_REG3 0x34370 +#define HDCP_INT_REG4 0x34A70 +#define HDCP_INT_BITS (1 << 16) + +#define HDCP_ISR_REG1 0x3368C +#define HDCP_ISR_REG2 0x33C88 +#define HDCP_ISR_REG3 0x34388 +#define HDCP_ISR_REG4 0x34A88 + +static void gf_hdcp_handle(struct drm_device* dev) +{ + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + adapter_info_t* adapter = disp_info->adp_info; + struct drm_connector* connector = NULL; + gf_connector_t* gf_connector = NULL; + unsigned long flags; + unsigned int hdcp_int_value = 0; + unsigned int hdcp_index = 0; + unsigned int hdcp_isr_value = 0; + + hdcp_int_value = gf_read32(adapter->mmio + HDCP_INT_REG1); + gf_write32(adapter->mmio + HDCP_INT_REG1, (hdcp_int_value & ~HDCP_INT_BITS)); + if(hdcp_int_value & HDCP_INT_BITS) + { + hdcp_index |= (1 << 0); + } + + hdcp_int_value = gf_read32(adapter->mmio + HDCP_INT_REG2); + gf_write32(adapter->mmio + HDCP_INT_REG2, (hdcp_int_value & ~HDCP_INT_BITS)); + if(hdcp_int_value & HDCP_INT_BITS) + { + hdcp_index |= (1 << 1); + } + + hdcp_int_value = gf_read32(adapter->mmio + HDCP_INT_REG3); + gf_write32(adapter->mmio + HDCP_INT_REG3, (hdcp_int_value & ~HDCP_INT_BITS)); + if(hdcp_int_value & HDCP_INT_BITS) + { + hdcp_index |= (1 << 2); + } + + hdcp_int_value = gf_read32(adapter->mmio + HDCP_INT_REG4); + gf_write32(adapter->mmio + HDCP_INT_REG4, (hdcp_int_value & ~HDCP_INT_BITS)); + if(hdcp_int_value & HDCP_INT_BITS) + { + hdcp_index |= (1 << 3); + } + + hdcp_isr_value = gf_read32(adapter->mmio + HDCP_ISR_REG1); + if(hdcp_isr_value != 0) + { + hdcp_index |= (1 << 0); + } + + hdcp_isr_value = gf_read32(adapter->mmio + HDCP_ISR_REG2); + if(hdcp_isr_value != 0) + { + hdcp_index |= (1 << 1); + } + + hdcp_isr_value = gf_read32(adapter->mmio + HDCP_ISR_REG3); + if(hdcp_isr_value != 0) + { + hdcp_index |= (1 << 2); + } + + hdcp_isr_value = gf_read32(adapter->mmio + HDCP_ISR_REG4); + if(hdcp_isr_value != 0) + { + hdcp_index |= (1 << 3); + } + + if(!hdcp_index) + { + return; + } + + flags = gf_spin_lock_irqsave(disp_info->hdcp_lock); + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + gf_connector = to_gf_connector(connector); + if(gf_connector->hdcp_index & hdcp_index) + { + disp_info->hdcp_intr_outputs |= gf_connector->output_type; + } + } + + gf_spin_unlock_irqrestore(disp_info->hdcp_lock, flags); + + if(disp_info->hdcp_intr_outputs) + { + schedule_work(&disp_info->hdcp_work); + } +} + +irqreturn_t gf_irq_handle(int irq, void *arg) +{ + struct drm_device* dev = arg; + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + irq_chip_funcs_t* chip_func = (irq_chip_funcs_t*)disp_info->irq_chip_func; + unsigned short command; + unsigned int intrr = 0; + + if(!disp_info->irq_enabled) + { + return IRQ_NONE; + } + + if(atomic_xchg(&disp_info->atomic_irq_lock, 1) == 1) + { + return IRQ_NONE; + } + + if(!chip_func || !chip_func->get_interrupt_mask) + { + return IRQ_NONE; + } + +#if 0 + gf_get_command_status16(gf_card->pdev, &command); + + if(!(command & PCI_EN_MEM_SPACE)) + { + gf_write_command_status16(gf_card->pdev, (command | PCI_EN_MEM_SPACE)); + } +#endif + + intrr = chip_func->get_interrupt_mask(disp_info); + + if(intrr & INT_VSYNCS) + { + gf_vblank_intrr_handle(dev, intrr & INT_VSYNCS); + + gf_capture_interrupt_handle(disp_info, intrr & INT_VSYNCS); + } + + if(intrr & INT_HDCODEC) + { + gf_hdaudio_handle(dev); + } + + if (intrr & INT_HOTPLUG) + { + gf_hpd_handle(dev, intrr & INT_HOTPLUG); + } + + if(intrr & INT_HDCP) + { + gf_hdcp_handle(dev); + } + + if(intrr & INT_VIPS) + { + gf_capture_interrupt_handle(disp_info, intrr & INT_VIPS); + } + + if(intrr & INT_VIDEO_EVENTS) + { + gf_video_interrupt_handle(disp_info, intrr & INT_VIDEO_EVENTS, gf_card->video_irq_info_all); + } + + if (!gf_card->adapter_info.init_render && + gf_card->adapter_info.patch_fence_intr_lost) + { + intrr |= INT_FENCE; + } + if(intrr & INT_FENCE) + { + tasklet_schedule(&gf_card->fence_notify); + + gf_card->adapter_info.init_render = 0; + } + + atomic_set(&disp_info->atomic_irq_lock, 0); + + return IRQ_HANDLED; +} + +static void gf_hot_plug_intr_ctrl(disp_info_t* disp_info, unsigned int intr, int enable) +{ + irq_chip_funcs_t* chip_func = (irq_chip_funcs_t*)disp_info->irq_chip_func; + unsigned long flags = 0; + unsigned int intr_en = 0; + + if (!chip_func || !chip_func->get_intr_enable_mask || !chip_func->set_intr_enable_mask) + { + return; + } + + intr &= INT_HOTPLUG; + + flags = gf_spin_lock_irqsave(disp_info->intr_lock); + + if(disp_info->irq_enabled) + { + intr_en = chip_func->get_intr_enable_mask(disp_info); + } + else + { + intr_en = disp_info->intr_en_bits; + } + + if(enable) + { + intr_en |= intr; + } + else + { + intr_en &= ~intr; + } + + if(disp_info->irq_enabled) + { + chip_func->set_intr_enable_mask(disp_info, intr_en); + } + else + { + disp_info->intr_en_bits = intr_en; + } + + + gf_spin_unlock_irqrestore(disp_info->intr_lock, flags); +} + +void gf_hot_plug_intr_onoff(disp_info_t* disp_info, int on) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + struct drm_connector* connector = NULL; + gf_connector_t* gf_connector = NULL; + unsigned int hpd_int_bits = 0; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + struct drm_connector_list_iter conn_iter; +#endif + + mutex_lock(&drm->mode_config.mutex); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_begin(drm, &conn_iter); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + drm_for_each_connector_iter(connector, &conn_iter) +#else + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + drm_for_each_connector(connector, drm) +#else + list_for_each_entry(connector, &drm->mode_config.connector_list, head) +#endif + +#endif + { + //mark status to enable for all outputs that support hot plug + gf_connector = to_gf_connector(connector); + + if ((connector->polled == DRM_CONNECTOR_POLL_HPD) && gf_connector->hpd_int_bit) + { + gf_connector->hpd_enable = on; + hpd_int_bits |= gf_connector->hpd_int_bit; + } + } +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_end(&conn_iter); +#endif + + mutex_unlock(&drm->mode_config.mutex); + + if (hpd_int_bits) + { + gf_hot_plug_intr_ctrl(disp_info, hpd_int_bits, on); + } +} + +void gf_dp_irq_work_func(struct work_struct *work) +{ + disp_info_t *disp_info = container_of(work, disp_info_t, dp_irq_work); + gf_connector_t *gf_connector = NULL; + unsigned long irq = 0; + int device = 0, int_type = 0, detect_devices = 0, comp_edid_devs = 0; + int empty = 0, need_detect = 0, need_comp_edid = 0; + + while(1) + { + irq = gf_spin_lock_irqsave(disp_info->hpd_lock); + + if(DP_QUEUE_EMPTY(disp_info->head, disp_info->tail)) + { + empty = 1; + } + else + { + device = disp_info->event[disp_info->head].device; + int_type = disp_info->event[disp_info->head].int_type; + DP_ADVANCE_QUEUE_POS(disp_info->head); + } + + gf_spin_unlock_irqrestore(disp_info->hpd_lock, irq); + + if(empty) + { + break; + } + + gf_connector = gf_get_connector_by_device_id(disp_info, device); + if(!gf_connector) + { + continue; + } + need_detect = need_comp_edid = 0; + + gf_mutex_lock(gf_connector->conn_mutex); + disp_cbios_handle_dp_irq(disp_info, device, int_type, &need_detect, &need_comp_edid); + gf_mutex_unlock(gf_connector->conn_mutex); + + if(need_detect) + { + detect_devices |= device; + + if(need_comp_edid) + { + comp_edid_devs |= device; + } + } + } + + if(detect_devices) + { + irq = gf_spin_lock_irqsave(disp_info->hpd_lock); + + disp_info->hpd_outputs |= detect_devices; + disp_info->compare_edid_outputs |= comp_edid_devs; + + gf_spin_unlock_irqrestore(disp_info->hpd_lock, irq); + +#if GF_RUN_HDCP_CTS + //here we add some delay to make sure plug out is report to OS + gf_msleep(2000); +#endif + schedule_work(&disp_info->hotplug_work); + } +} + +static void gf_poll_enable_locked(struct drm_device *dev) +{ + int poll = 0; + struct drm_connector *connector = NULL; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + struct drm_connector_list_iter conn_iter; +#endif + + WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); + + if (!dev->mode_config.poll_enabled) + { + return; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_begin(dev, &conn_iter); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + drm_for_each_connector_iter(connector, &conn_iter) +#else + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + drm_for_each_connector(connector, dev) +#else + list_for_each_entry(connector, &dev->mode_config.connector_list, head) +#endif + +#endif + { + if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT)) + { + poll = true; + break; + } + } +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_end(&conn_iter); +#endif + + if (poll) + { + schedule_delayed_work(&dev->mode_config.output_poll_work, OUTPUT_POLL_PERIOD); + } +} + +#define INIT_POLLING_TIME 10 + +void gf_hotplug_work_func(struct work_struct *work) +{ + disp_info_t* disp_info = container_of(work, disp_info_t, hotplug_work); + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + struct drm_mode_config *mode_config = &drm->mode_config; + struct drm_connector* connector = NULL; + gf_connector_t* gf_connector = NULL; + unsigned long irq = 0; + unsigned int hpd_outputs = 0, changed = 0, comp_edid_outputs = 0, need_poll = 0; + unsigned int plug_out = 0, plug_in = 0, cur_output = 0; + enum drm_connector_status old_status; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + struct drm_connector_list_iter conn_iter; +#endif +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + struct drm_modeset_acquire_ctx ctx; + int ret = 0; +#endif + gf_capture_id_t cf_id = GF_CAPTURE_INVALID; + gf_capture_event_t cf_event = GF_CAPTURE_EVENT_NONE; + + irq = gf_spin_lock_irqsave(disp_info->hpd_lock); + + hpd_outputs = disp_info->hpd_outputs; + disp_info->hpd_outputs = 0; + + comp_edid_outputs = disp_info->compare_edid_outputs; + disp_info->compare_edid_outputs = 0; + + gf_spin_unlock_irqrestore(disp_info->hpd_lock, irq); + + if(!hpd_outputs) + { + return; + } + + mutex_lock(&mode_config->mutex); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_begin(drm, &conn_iter); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + drm_for_each_connector_iter(connector, &conn_iter) +#else + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + drm_for_each_connector(connector, drm) +#else + list_for_each_entry(connector, &mode_config->connector_list, head) +#endif + +#endif + { + gf_connector = to_gf_connector(connector); + if ((gf_connector->output_type & hpd_outputs) && (gf_connector->monitor_type != UT_OUTPUT_TYPE_PANEL)) + { + if (is_connector_work_in_splice_mode(connector)) + { + changed = gf_splice_handle_source_status(connector); + continue; + } + + old_status = connector->status; + gf_connector->compare_edid = (comp_edid_outputs & gf_connector->output_type)? 1 : 0; + connector->status = gf_connector_detect_internal(connector, 0, 1); + + if(connector_status_connected == old_status && connector_status_disconnected == connector->status) + { + plug_out |= gf_connector->output_type; + } + else if(connector_status_disconnected == old_status && connector_status_connected == connector->status) + { + plug_in |= gf_connector->output_type; + } + + if(old_status != connector->status) + { + changed = 1; + gf_connector->polling_time = 0; + } + else if(gf_connector->compare_edid && gf_connector->edid_changed) + { + changed = 1; + gf_connector->polling_time = 0; + } + else if(old_status == connector_status_connected && UT_OUTPUT_TYPE_HDMI == gf_connector->monitor_type) + { + //HDMI plug out INT happen, but no change can be detected, use polling + gf_info("Polling work will detect connector 0x%x for %d times.\n", gf_connector->output_type, INIT_POLLING_TIME); + gf_connector->polling_time = INIT_POLLING_TIME; + if(!disp_info->poll_running) + { + need_poll = 1; + } + } + gf_connector->compare_edid = 0; + } + + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + if (plug_in & gf_connector->output_type) + { + drm_modeset_acquire_init(&ctx, 0); + while (1) + { + ret = drm_modeset_lock_all_ctx(drm, &ctx); + if (ret != -EDEADLK) + break; + + drm_modeset_backoff(&ctx); + } + + if (!ret) + { + gf_restore_drm_connector_state(drm, connector, &ctx); + } + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + } +#endif + } +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_end(&conn_iter); +#endif + + if(need_poll) + { + gf_poll_enable_locked(drm); + } + + mutex_unlock(&mode_config->mutex); + + if(changed) + { + drm_kms_helper_hotplug_event(drm); + if(plug_out || plug_in) + { + gf_info("**** Hot plug detected: plug_out : 0x%x, plug_in : 0x%x.****\n", plug_out, plug_in); + } + + cur_output = plug_out; + cf_event = GF_CAPTURE_EVENT_PLUG_OUT; + if (plug_in) + { + cur_output = plug_in; + cf_event = GF_CAPTURE_EVENT_PLUG_IN; + } + + if (DISP_OUTPUT_DP1 == cur_output) + { + cf_id = GF_CAPTURE_WB1; + } + else if (DISP_OUTPUT_DP2 == cur_output) + { + cf_id = GF_CAPTURE_WB2; + } + else if (DISP_OUTPUT_DP3 == cur_output) + { + cf_id = GF_CAPTURE_WB3; + } + else if (DISP_OUTPUT_DP4 == cur_output) + { + cf_id = GF_CAPTURE_WB4; + } + + gf_capture_handle_event(disp_info, cf_id, cf_event); + } +} + +void gf_hda_work_func(struct work_struct* work) +{ + disp_info_t* disp_info = container_of(work, disp_info_t, hda_work); + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + struct drm_mode_config *mode_config = &drm->mode_config; + struct drm_connector* connector = NULL; + gf_connector_t* gf_connector = NULL; + unsigned long irq = 0; + unsigned int hda_outputs = 0; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + struct drm_connector_list_iter conn_iter; +#endif + + irq = gf_spin_lock_irqsave(disp_info->hda_lock); + + hda_outputs = disp_info->hda_intr_outputs; + disp_info->hda_intr_outputs = 0; + + gf_spin_unlock_irqrestore(disp_info->hda_lock, irq); + + if(!hda_outputs) + { + return; + } + + mutex_lock(&mode_config->mutex); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_begin(drm, &conn_iter); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + drm_for_each_connector_iter(connector, &conn_iter) +#else + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + drm_for_each_connector(connector, drm) +#else + list_for_each_entry(connector, &mode_config->connector_list, head) +#endif + +#endif + { + gf_connector = to_gf_connector(connector); + if(gf_connector->output_type & hda_outputs && gf_connector->support_audio) + { + disp_cbios_set_hda_codec(disp_info, gf_connector); + } + } +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_end(&conn_iter); +#endif + + mutex_unlock(&mode_config->mutex); +} + +void gf_hdcp_work_func(struct work_struct* work) +{ + disp_info_t* disp_info = container_of(work, disp_info_t, hdcp_work); + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + struct drm_mode_config *mode_config = &drm->mode_config; + struct drm_connector* connector = NULL; + gf_connector_t* gf_connector = NULL; + unsigned long irq = 0; + unsigned int hdcp_outputs = 0; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + struct drm_connector_list_iter conn_iter; +#endif + + irq = gf_spin_lock_irqsave(disp_info->hdcp_lock); + + hdcp_outputs = disp_info->hdcp_intr_outputs; + disp_info->hdcp_intr_outputs = 0; + + gf_spin_unlock_irqrestore(disp_info->hdcp_lock, irq); + + if(!hdcp_outputs) + { + return; + } + + mutex_lock(&mode_config->mutex); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_begin(drm, &conn_iter); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + drm_for_each_connector_iter(connector, &conn_iter) +#else + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + drm_for_each_connector(connector, drm) +#else + list_for_each_entry(connector, &mode_config->connector_list, head) +#endif + +#endif + { + gf_connector = to_gf_connector(connector); + if(gf_connector->output_type & hdcp_outputs) + { + disp_cbios_hdcp_isr(disp_info, gf_connector); + } + } +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_end(&conn_iter); +#endif + + mutex_unlock(&mode_config->mutex); +} + +void gf_irq_uninstall (struct drm_device *dev) +{ + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) + int irq = to_pci_dev(dev->dev)->irq; + free_irq(irq, dev); +#endif + + //disable all interrupt + gf_disp_disable_interrupt(disp_info, 1); +} + +void gf_poll_enable(disp_info_t* disp_info) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + + mutex_lock(&drm->mode_config.mutex); + gf_poll_enable_locked(drm); + mutex_unlock(&drm->mode_config.mutex); +} + +void gf_poll_disable(disp_info_t *disp_info) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + + if (!drm->mode_config.poll_enabled) + return; + cancel_delayed_work_sync(&drm->mode_config.output_poll_work); +} + +void gf_output_poll_work_func(struct work_struct *work) +{ + struct delayed_work *delayed_work = to_delayed_work(work); + struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work); + struct drm_connector *connector = NULL; + enum drm_connector_status old_status; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_connector_t *gf_connector; + int repoll = 0, changed = 0; + unsigned char *p_edid = NULL; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + struct drm_connector_list_iter conn_iter; +#endif + + if (!mutex_trylock(&dev->mode_config.mutex)) + { + repoll = true; + goto out; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_begin(dev, &conn_iter); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + drm_for_each_connector_iter(connector, &conn_iter) +#else + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + drm_for_each_connector(connector, dev) +#else + list_for_each_entry(connector, &dev->mode_config.connector_list, head) +#endif + +#endif + { + gf_connector = to_gf_connector(connector); + + /* Ignore forced connectors. */ + if ((connector->force) || gf_connector->output_type == DISP_OUTPUT_SPLICE || + (!connector->polled || (connector->polled == DRM_CONNECTOR_POLL_HPD && !gf_connector->polling_time))) + { + continue; + } + + old_status = connector->status; + /* if we are connected and don't want to poll for disconnect skip it */ + if (old_status == connector_status_connected && + connector->polled != DRM_CONNECTOR_POLL_HPD && + !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT)) + { + continue; + } + + repoll = 1; + + if (is_connector_work_in_splice_mode(connector)) + { + changed = gf_splice_handle_source_status(connector); + continue; + } + + if (connector->funcs->detect) + { + p_edid = disp_cbios_read_edid(disp_info, gf_connector->output_type); + if (!p_edid) + { + gf_connector->compare_edid = 1; + } + connector->status = gf_connector_detect_internal(connector, 0, 0); + gf_connector->compare_edid = 0; + + if (p_edid) + { + gf_free(p_edid); + } + } + else + { + connector->status = connector_status_connected; + } + + if (old_status != connector->status) + { + if (connector->status == connector_status_unknown) + { + connector->status = old_status; + continue; + } + + changed = 1; + gf_connector->polling_time = 0; + } + else if(gf_connector->polling_time > 0) + { + if (gf_connector->edid_changed) + { + changed = 1; + gf_connector->polling_time = 0; + } + else + { + gf_connector->polling_time--; + } + } + } +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + drm_connector_list_iter_end(&conn_iter); +#endif + + disp_info->poll_running = 0; + if(repoll) + { + disp_info->poll_running = 1; + } + mutex_unlock(&dev->mode_config.mutex); + +out: + if (changed) + { + drm_kms_helper_hotplug_event(dev); + } + + if (repoll) + { + schedule_delayed_work(delayed_work, OUTPUT_POLL_PERIOD); + } +} + +void gf_video_interrupt_handle(disp_info_t* disp_info, unsigned int video_int_mask, int output_all) +{ + adapter_info_t* adapter = disp_info->adp_info; + unsigned int video0_info0 = 0, video0_info1 = 0, video0_info2 = 0; + unsigned int video1_info0 = 0, video1_info1 = 0, video1_info2 = 0; + int i = 0; + + for (i = 0; i < VIDEO_ERROR_INFO_NUM; i++) + { + if (video_int_mask & video_irq_mask[i]) + { + ktime_t ctime = ktime_get(); + if (output_all || video_irq_info_count[i] < DEFAULT_PRINT_COUNT) + { + gf_info("*******************%s!*******************\n", video_irq_name[i]); + if (i < 4) + { + video0_info0 = gf_read32(adapter->mmio + video_reg_offset[i]); + gf_info("info0: 0x%x\n", video0_info0); + } + else + { + video0_info0 = gf_read32(adapter->mmio + video_reg_offset[i]); + video0_info1 = gf_read32(adapter->mmio + video_reg_offset[i] + 4); + video0_info2 = gf_read32(adapter->mmio + video_reg_offset[i] + 8); + if (5 == i || 7 == i) + { + if(!((video0_info2 << 4) & 0x32)) + gf_info("info0: 0x%x info1: 0x%x info2: 0x%x\n", video0_info0, video0_info1, video0_info2); + } + else + { + gf_info("info0: 0x%x info1: 0x%x info2: 0x%x\n", video0_info0, video0_info1, video0_info2); + } + } + video_irq_info_time[i] = ctime; + video_irq_info_count[i]++; + } + + if (ktime_ms_delta(ctime, video_irq_info_time[i]) > (RESET_TIME_MINUTE_interval * 60 * 1000L)) + video_irq_info_count[i] = 0; + } + } +} + diff --git a/drivers/gpu/drm/arise/linux/gf_irq.h b/drivers/gpu/drm/arise/linux/gf_irq.h new file mode 100644 index 0000000000000..d7445c37492c5 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_irq.h @@ -0,0 +1,123 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _GF_IRQ_ +#define _GF_IRQ_ + +#include "gf_disp.h" +#include "gf_cbios.h" +#include "gf_crtc.h" + +#define PCI_EN_MEM_SPACE 0x02 + +#define OUTPUT_POLL_PERIOD (HZ) + +typedef struct _irq_chip_funcs +{ + int (*get_intr_enable_mask)(disp_info_t* disp_info); + void (*set_intr_enable_mask)(disp_info_t* disp_info, int intr_mask); + void (*enable_msi)(disp_info_t* disp_info); + void (*disable_msi)(disp_info_t* disp_info); + int (*disable_interrupt)(disp_info_t* disp_info); + void (*enable_interrupt)(disp_info_t* disp_info, int intr_mask); + int (*get_interrupt_mask)(disp_info_t* disp_info); +}irq_chip_funcs_t; + +extern irq_chip_funcs_t irq_chip_funcs; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) +u32 gf_get_vblank_counter(struct drm_crtc *crtc); +int gf_enable_vblank(struct drm_crtc *crtc); +void gf_disable_vblank(struct drm_crtc *crtc); +#else +u32 gf_get_vblank_counter(struct drm_device *dev, pipe_t pipe); +int gf_enable_vblank(struct drm_device *dev, pipe_t pipe); +void gf_disable_vblank(struct drm_device *dev, pipe_t pipe); +#endif + + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 13, 0) +int gf_get_vblank_timestamp(struct drm_device *dev, pipe_t pipe, + int *max_error, struct timeval *time, unsigned flags); +#elif DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) +bool gf_get_vblank_timestamp(struct drm_device *dev, + unsigned int pipe, + int *max_error, + #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) + ktime_t *vblank_time, + #else + struct timeval *vblank_time, + #endif + bool in_vblank_irq); +#endif + +int gf_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + unsigned int flags, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); + +int gf_get_crtc_scanoutpos_kernel_4_8(struct drm_device *dev, unsigned int pipe, + unsigned int flags, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime); + +int gf_legacy_get_crtc_scanoutpos(struct drm_device *dev, int pipe, unsigned int flags, + int *vpos, int *hpos, ktime_t *stime, ktime_t *etime); + +bool gf_get_crtc_scanoutpos_kernel_4_10(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) +bool gf_crtc_get_scanout_position(struct drm_crtc *crtc, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) +int gf_irq_install(struct drm_device *drm_dev); +#endif + +void gf_irq_preinstall(struct drm_device *dev); + +int gf_irq_postinstall(struct drm_device *dev); + +irqreturn_t gf_irq_handle(int irq, void *arg); + +void gf_irq_uninstall (struct drm_device *dev); + +void gf_hot_plug_intr_onoff(disp_info_t* disp_info, int on); + +void gf_hotplug_work_func(struct work_struct *work); + +void gf_dp_irq_work_func(struct work_struct *work); + +void gf_hda_work_func(struct work_struct* work); + +void gf_hdcp_work_func(struct work_struct* work); + +void gf_output_poll_work_func(struct work_struct *work); + +void gf_poll_enable(disp_info_t* disp_info); + +void gf_poll_disable(disp_info_t *disp_info); + +void gf_disp_enable_interrupt(disp_info_t* disp_info, int irq_inst_uninst); + +void gf_disp_disable_interrupt(disp_info_t* disp_info, int irq_inst_uninst); + +void gf_video_interrupt_handle(disp_info_t* disp_info, unsigned int video_int_mask, int output_all); + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_kms.h b/drivers/gpu/drm/arise/linux/gf_kms.h new file mode 100644 index 0000000000000..7e78031f25abd --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_kms.h @@ -0,0 +1,275 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _GF_KMS_ +#define _GF_KMS_ + +#include + +#ifndef DRM_VERSION_CODE +#define DRM_VERSION_CODE LINUX_VERSION_CODE +#endif + + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) +#include +#include +#include +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) +#include +#endif + +#include + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) +#include +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) +#include +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 5, 0) +#include +#include +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 14, 0) +#include +#endif +#endif +#include + +#ifndef container_of +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#define container_of(ptr, type, member) (type *)((char *)(ptr) - offsetof(type, member)) +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) +#define to_gf_atomic_state(x) container_of(x, gf_ato_state_t, base_ato_state) +#define to_gf_crtc_state(x) container_of(x, gf_crtc_state_t, base_cstate) +#define to_gf_plane_state(x) container_of(x, gf_plane_state_t, base_pstate) +#define to_gf_conn_state(x) container_of(x, gf_connector_state_t, base_conn_state) +#endif + +#define to_gf_crtc(x) container_of(x, gf_crtc_t, base_crtc) +#define to_gf_connector(x) container_of(x, gf_connector_t, base_connector) +#define to_gf_plane(x) container_of(x, gf_plane_t, base_plane) +#define to_gf_encoder(x) container_of(x, gf_encoder_t, base_encoder) + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 20, 0) +#define DRM_MODE_BLEND_PREMULTI 0 +#define DRM_MODE_BLEND_COVERAGE 1 +#define DRM_MODE_BLEND_PIXEL_NONE 2 +#endif + +#define DRM_MODE_BLEND_CURR_LAYER_ALPHA 0 +#define DRM_MODE_BLEND_LOWER_LAYER_ALPHA 1 + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 18, 0) +#define DRM_BLEND_ALPHA_OPAQUE 0xffff +#endif + +#define COLOR_LEGACY_LUT_LENGTH 256 + +typedef struct +{ + struct drm_crtc base_crtc; + unsigned int pipe; + int crtc_dpms; + int support_scale; + unsigned int scaler_width; + unsigned int scaler_height; + unsigned int dst_width; + unsigned int dst_height; + unsigned int plane_cnt; + struct gf_flip_work *flip_work; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + struct drm_gf_gem_object *cursor_bo; + unsigned short cursor_x, cursor_y; + unsigned short cursor_w, cursor_h; + unsigned int lut_entry[256]; //(b | g << 8 | r << 16) for 8bit lut or (b | g << 10 | r << 20) for 10bit lut +#endif + unsigned int enabled; +}gf_crtc_t; + +typedef struct +{ + struct drm_encoder base_encoder; + int output_type; + int enc_dpms; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + gf_crtc_t* new_crtc; +#endif +}gf_encoder_t; + +typedef struct +{ + struct drm_connector base_connector; + int output_type; + int output_id; + int monitor_type; + int hda_codec_index; + int hpd_int_bit; + int hpd_enable; + int polling_time; + struct os_mutex* conn_mutex; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + gf_encoder_t* new_encoder; +#endif + + struct gf_sink *sink; + struct gf_i2c_adapter *i2c_adapter; + struct + { + unsigned int support_audio : 1; + unsigned int compare_edid : 1; + unsigned int edid_changed : 1; + unsigned int reserved : 29; + }; + int hdcp_index; + int hdcp_enable; + int detected; //fot hdcp cts + int hpd_out; //for hdcp cts + int source_status; +}gf_connector_t; + +typedef struct +{ + struct drm_plane base_plane; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + unsigned int src_pos; + unsigned int src_size; + unsigned int dst_pos; + unsigned int dst_size; +#else +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 20, 0) + struct drm_property *blend_mode_property; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 18, 0) + struct drm_property *alpha_property; +#endif +#endif + struct drm_property *alpha_source_prop; +#endif + int crtc_index; + int plane_type; + unsigned int can_window : 1; //except PS + unsigned int can_up_scale : 1; + unsigned int can_down_scale : 1; + unsigned int is_cursor : 1; + unsigned int resume_from_s4: 1; +}gf_plane_t; + +typedef struct +{ + struct drm_framebuffer *fb; + int crtc; + int stream_type; + int crtc_x; + int crtc_y; + int crtc_w; + int crtc_h; + int src_x; + int src_y; + int src_w; + int src_h; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + struct + { + int blend_mode; + int blend_alpha_source; + union + { + unsigned int const_alpha; + unsigned int plane_alpha; + unsigned int color_key; + }; + }; +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + int async_flip; +#endif +}gf_crtc_flip_t; +//int disp_cbios_crtc_flip(disp_info_t *disp_info, struct drm_crtc *crtc, struct drm_framebuffer *fb, +// int stream_type, int visible, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h); + +typedef struct +{ + int crtc; + int vsync_on; + int pos_x; + int pos_y; + int width; + int height; + struct drm_gf_gem_object *bo; +}gf_cursor_update_t; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + +typedef struct +{ + struct drm_connector_state base_conn_state; + unsigned int splice_active; + unsigned int splice_trigger; + unsigned int splice_mode_x; + unsigned int splice_mode_y; + unsigned int splice_mode_rate; + unsigned int splice_crtc_x; + unsigned int splice_crtc_y; + unsigned int splice_crtc_w; + unsigned int splice_crtc_h; +}gf_connector_state_t; + +typedef struct +{ + struct drm_crtc_state base_cstate; + struct gf_sink *sink; + struct + { + unsigned int scale_change : 1; + unsigned int dst_change : 1; + unsigned int keep_vsync : 1; + unsigned int reserved : 29; + }; +}gf_crtc_state_t; + +typedef struct +{ + struct drm_plane_state base_pstate; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 20, 0) + unsigned int pixel_blend_mode; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 18, 0) + unsigned int alpha; +#endif +#endif + unsigned int alpha_source; + unsigned int color_key; + struct + { + unsigned int disable : 1; + unsigned int legacy_cursor : 1; + unsigned int reserved : 30; + }; +}gf_plane_state_t; + +typedef struct +{ + struct drm_atomic_state base_ato_state; +}gf_ato_state_t; + +#endif + +#endif + diff --git a/drivers/gpu/drm/arise/linux/gf_params.c b/drivers/gpu/drm/arise/linux/gf_params.c new file mode 100644 index 0000000000000..f32beb40227b6 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_params.c @@ -0,0 +1,73 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_params.h" +#include "gf_driver.h" + +struct gf_params gf_modparams __read_mostly = { + .gf_fb_mode = NULL, +#ifdef GF_HW_NULL + .gf_fb = 0, +#else + .gf_fb = 1, +#endif + .gf_pwm_mode = 0x1, + .gf_dfs_mode = 0, + .gf_worker_thread_enable = 1, + .gf_recovery_enable = 1, + .gf_hang_dump = 0, /*0-disable, 1-pre hang, 2-post hang, 3-duplicate hang */ + .gf_run_on_qt = 0, + .gf_flag_buffer_verify = 1, /*0 - disable, 1 - enable */ + + .gf_vesa_tempbuffer_enable = 0, /* control wether reserve memory during boot */ + + .miu_channel_size = 0, /* 0/1/2 for 256B/512B/1kb Swizzle */ + .gf_backdoor_enable = 1, + + //gpc/slice setting + .chip_slice_mask = 0, /* 0x001 ~ 0xfff or 0, if none zero set, driver will use this setting, otherwise use value from bios*/ + .gf_local_size_g = 0,//adjust local memory size, 0 use real local memory + .gf_local_size_m = 0, + .gf_pcie_size_g = 0,//adjust pcie memory size, 0 use real pcie memory + .gf_pcie_size_m = 0, + .debugfs_mask = 0x1, + .misc_control_flag = 0x111, +}; + +#define gf_param_named(name, T, perm, desc) \ + module_param_named(name, gf_modparams.name, T, perm); \ + MODULE_PARM_DESC(name, desc) + +gf_param_named(gf_fb, int, 0600, "enable gf drm fb 0=disable, 1=enable"); +gf_param_named(gf_fb_mode, charp, 0600, "The fb mode, like string 1920x1080@60"); +gf_param_named(gf_vesa_tempbuffer_enable, int, 0444, "control wether reserve memory during boot"); +gf_param_named(gf_pwm_mode, int, 0444,"control power mode"); +gf_param_named(gf_dfs_mode, int, 0444, "control of dfs"); +gf_param_named(gf_worker_thread_enable, int, 0444, "enable work thread to submit"); +gf_param_named(gf_recovery_enable, int, 0444, "enable recovery"); +gf_param_named(gf_hang_dump, int, 0444, "0-disable, 1-pre hang, 2-post hang, 3-duplicate hang"); +gf_param_named(gf_flag_buffer_verify, int, 0444, ""); +gf_param_named(gf_run_on_qt, int, 0444, ""); +gf_param_named(miu_channel_size, int, 0444, "0/1/2 for 256B/512B/1kb Swizzle"); +gf_param_named(gf_backdoor_enable, int, 0444, "enable backdoor"); +gf_param_named(chip_slice_mask, int, 0444, "0x001 ~ 0xfff or 0, if none zero set, driver will use this setting, otherwise use value from bios"); +gf_param_named(gf_local_size_g, int, 0444, "manual set the local vram size, uint in GB, the size should not larger than real vram size"); +gf_param_named(gf_local_size_m, int, 0444, "manual set the local vram size, uint in MB, the size should not larger than real vram size"); +gf_param_named(gf_pcie_size_g, int, 0444, "manual set the pcie vram size, uint in GB, the size should not larger than real vram size"); +gf_param_named(gf_pcie_size_m, int, 0444, "manual set the pcie vram size, uint in MB, the size should not larger than real vram size"); +gf_param_named(debugfs_mask, int, 0444, "debugfs control bits"); +gf_param_named(misc_control_flag, int, 0444, "misc control flag"); + + + diff --git a/drivers/gpu/drm/arise/linux/gf_params.h b/drivers/gpu/drm/arise/linux/gf_params.h new file mode 100644 index 0000000000000..991dc4990b5fc --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_params.h @@ -0,0 +1,49 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_PARAMS_H__ +#define __GF_PARAMS_H__ +#include /* for __read_mostly */ + +struct gf_params { + char *gf_fb_mode; + int gf_fb; + + int gf_pwm_mode ; /*0-disable CG, 1-enable CG, 0x10-enable 3D auto mode, 0x20-enable VCP auto mode, 0x40-enable VPP auto mode*/ + int gf_dfs_mode ;/* control dvfs of gf, 0-disable , 1-enable kmd auto tuning */ + int gf_worker_thread_enable;/* control worker thread on/off */ + int gf_recovery_enable ; /* enable recovery when hw hang */ + int gf_hang_dump;/*0-disable, 1-pre hang, 2-post hang, 3-duplicate hang */ + int gf_run_on_qt; /* control wether run on QT */ + int gf_flag_buffer_verify ;/*0 - disable, 1 - enable */ + int gf_vesa_tempbuffer_enable ; /* control wether reserve memory during boot */ + + int miu_channel_num; // 0/1/2 for 1/2/3 Miu channel, Elite 3000 support up to 3 MIU channel + int miu_channel_size; //0/1/2 for 256B/512B/1kb Swizzle + int gf_backdoor_enable; + + //gpc/slice setting + unsigned int chip_slice_mask;//// CHIP_SLICE_MASK own 12 bits(should be set 0x001 ~ 0xfff), driver use this to set the Slice_Mask which HW used. + int mem_size; // 1/2/3/4 for 4G/8G/12G/16G + + int gf_local_size_g; + int gf_local_size_m; + int gf_pcie_size_g; + int gf_pcie_size_m; + int debugfs_mask; //debugfs mask, bit0: gem_enable + int misc_control_flag; +}; + +extern struct gf_params gf_modparams; +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_pcie.c b/drivers/gpu/drm/arise/linux/gf_pcie.c new file mode 100644 index 0000000000000..3b8898a5d88b9 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_pcie.c @@ -0,0 +1,1131 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf.h" +#include "gf_driver.h" +#include "os_interface.h" +#include "gf_ioctl.h" +#include "gf_debugfs.h" +#include "gf_version.h" +#include "gf_gem.h" +#include "gf_gem_priv.h" +#include "gf_fence.h" +#include "gf_irq.h" +#include "gf_fbdev.h" +#include "gf_params.h" + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5,5,0) +#if DRM_VERSION_CODE < KERNEL_VERSION(5,8,0) +#include +#else +#if DRM_VERSION_CODE < KERNEL_VERSION(6,8,0) +#include +#endif +#endif +#endif +#include + +#if DRM_VERSION_CODE >= KERNEL_VERSION(6, 2, 0) +#include +#endif + +#define DRIVER_DESC "Glenfly DRM Pro" + +#define ROM_IMAGE_HEADER 0xaa55 + +struct gf_device_info { + u32 display_mmio_offset; + u32 intrupte_enable_regs; +}; + +static struct drm_gf_driver gf_drm_driver; + +/* + * A pci_device_id struct { + * __u32 vendor, device; + * __u32 subvendor, subdevice; + * __u32 class, class_mask; + * kernel_ulong_t driver_data; + * }; + * Don't use C99 here because "class" is reserved and we want to + * give userspace flexibility. + */ +static const struct gf_device_info gf_e3k_info = { + 0, + 0, +}; + + +static struct pci_device_id pciidlist[] = +{ + {0x1d17, 0x3D00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&gf_e3k_info}, //e3k + {0x6766, 0x3D00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&gf_e3k_info}, //arise10c0 + {0x6766, 0x3D02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&gf_e3k_info}, //arise1020 + {0x6766, 0x3D03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&gf_e3k_info}, //arise1040 + {0x6766, 0x3D04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&gf_e3k_info}, //arise1010 + {0x6766, 0x3D06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&gf_e3k_info}, //arise10c0t + {0x6766, 0x3D07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&gf_e3k_info}, + {0x6766, 0x3D08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)&gf_e3k_info}, + {0, 0, 0} +}; + +MODULE_DEVICE_TABLE(pci, pciidlist); + +static struct pci_driver gf_driver; + +#if 0 +static int gf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + gf_card_t *gf = &gf_cards[num_probed_card++]; + int ret = 0; + + gf_memset(gf, 0, sizeof(gf_card_t)); + + pci_set_drvdata(pdev, gf); + + gf_card_pre_init(gf, pdev); + + ret = pci_request_regions(pdev, gf_driver.name); + if(ret) + { + gf_error("pci_request_regions() failed. ret:%x.\n", ret); + } + + ret = pci_enable_device(pdev); + if(ret) + { + gf_error("pci_enable_device() failed. ret:%x.\n", ret); + } + + pci_set_master(pdev); + + /*don't use the vga arbiter*/ +#if defined(CONFIG_VGA_ARB) + vga_set_legacy_decoding(pdev, VGA_RSRC_NONE); +#endif + + ret = gf_card_init(gf, pdev); + + return ret; +} + +static void gf_pcie_shutdown(struct pci_dev *pdev) +{ + gf_card_t *gf = pci_get_drvdata(pdev); + + if(gf->gfb_enable) + { +#ifdef CONFIG_FB + gf_fb_shutdown(gf); +#endif + } + +} +#endif + +static int gf_drm_suspend(struct drm_device *dev, pm_message_t state) +{ + gf_card_t* gf = dev->dev_private; + int ret; + + gf_info("gfx driver suspending, pm event = %d.\n", state.event); + disp_suspend(dev); + gf_info("drm suspend: save display status finished.\n"); + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + gf_fbdev_set_suspend(gf, 1); +#else + drm_fb_helper_set_suspend_unlocked(dev->fb_helper, true); +#endif + gf_info("drm suspend: save drmfb status finished.\n"); + + ret = gf_core_interface->save_state(gf->adapter, state.event == PM_EVENT_FREEZE); + + if (ret) + { + gf_error("drm suspend: save state failed.\n"); + return ret; + } + + /* disable IRQ */ +#ifdef _DEBUG_ + gf_info("Start Disable irq.\n"); +#endif + gf_disable_interrupt(gf->pdev); + +#ifdef _DEBUG_ + gf_info("Start Disable tasklet.\n"); +#endif + tasklet_disable(&gf->fence_notify); + + synchronize_irq(to_pci_dev(dev->dev)->irq); + gf_info("drm suspend: disable irq finished.\n"); + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + disp_vblank_save(dev); +#endif + + pci_save_state(to_pci_dev(dev->dev)); + + if (state.event == PM_EVENT_SUSPEND) + { + /*patch for CHX001 A0 and B0, pci_disable_device will clear master bit PCI04[2], and this bit can't be cleared for chx001 hw, so don't call pci_disable_device here*/ + pci_disable_device(to_pci_dev(dev->dev)); + pci_set_power_state(to_pci_dev(dev->dev), PCI_D3hot); + } + + return 0; +} + +static int gf_drm_resume(struct drm_device *dev) +{ + gf_card_t* gf = dev->dev_private; + int ret = 0; + + gf_info("gfx driver resume back.\n"); + + pci_set_power_state(to_pci_dev(dev->dev), PCI_D0); + + pci_restore_state(to_pci_dev(dev->dev)); + + if (pci_enable_device(to_pci_dev(dev->dev))) + { + return -1; + } + pci_set_master(to_pci_dev(dev->dev)); + + disp_pre_resume(dev); + gf_info("drm resume: enable and post chip finished.\n"); + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + disp_vblank_restore(dev); +#endif + + gf_core_interface->reset_dvfs_power_flag(gf->adapter); + + tasklet_enable(&gf->fence_notify); + gf_enable_interrupt(gf->pdev); + gf_info("drm resume: re-enable irq finished.\n"); + + ret = gf_core_interface->restore_state(gf->adapter); + + if(ret != 0) + { + return -1; + } + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + gf_fbdev_set_suspend(gf, 0); +#else + drm_fb_helper_set_suspend_unlocked(dev->fb_helper, false); +#endif + gf_info("drm resume: restore drmfb status finished.\n"); + + disp_post_resume(dev); + gf_info("drm resume: restore display status finished.\n"); + + return 0; +} + +static __inline__ int gf_backdoor_available(void) +{ +#if defined(__i386__) || defined(__x86_64__) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0) + return (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR || boot_cpu_data.x86_vendor == X86_VENDOR_ZHAOXIN) && + boot_cpu_data.x86_model == 59; +#else + // old kernel may be patched with zhaoxin cpu driver (such as UOS 4.19 and kylin V10 4.4) + return (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR || boot_cpu_data.x86_vendor == 10) && + boot_cpu_data.x86_model == 59; +#endif +#else + return TRUE; +#endif +} + +static __inline__ void gf_init_adapter_info_by_params(struct krnl_adapter_init_info_s *info, struct gf_params *p) +{ + info->gf_pwm_mode = p->gf_pwm_mode; + info->gf_dfs_mode = p->gf_dfs_mode; + info->gf_worker_thread_enable = p->gf_worker_thread_enable; + info->gf_recovery_enable = p->gf_recovery_enable; + info->gf_hang_dump = p->gf_hang_dump; + info->gf_run_on_qt = p->gf_run_on_qt; + info->gf_flag_buffer_verify = p->gf_flag_buffer_verify; + info->gf_vesa_tempbuffer_enable = p->gf_vesa_tempbuffer_enable; + + info->miu_channel_size = p->miu_channel_size; + info->gf_backdoor_enable = p->gf_backdoor_enable && gf_backdoor_available(); + + info->chip_slice_mask = p->chip_slice_mask; + info->gf_local_size_g = p->gf_local_size_g; + info->gf_local_size_m = p->gf_local_size_m; + info->gf_pcie_size_g = p->gf_pcie_size_g; + info->gf_pcie_size_m = p->gf_pcie_size_m; + info->debugfs_mask = p->debugfs_mask; +} + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 14, 0) +static int gf_kick_out_firmware_fb(struct pci_dev *pdev) +{ + struct apertures_struct *ap; + bool primary = false; + + ap = alloc_apertures(1); + if (!ap) + return -ENOMEM; + + ap->ranges[0].base = pci_resource_start(pdev, 1); + ap->ranges[0].size = pci_resource_len(pdev, 1); + +#ifdef CONFIG_X86 + primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + drm_fb_helper_remove_conflicting_framebuffers(ap, "arisedrmfb", primary); +#else + remove_conflicting_framebuffers(ap, "arisedrmfb", primary); +#endif + gf_free(ap); + + return 0; +} +#endif + +#define PCI_EN_IO_SPACE 1 +static int gf_drm_load_kms(struct drm_device *dev, unsigned long flags) +{ + struct pci_dev *pdev = to_pci_dev(dev->dev); + struct device* device = &pdev->dev; + gf_card_t *gf = NULL; + int ret = 0; + + gf = (gf_card_t *)gf_calloc(sizeof(gf_card_t)); + if (!gf) { + gf_error("allocate failed for gfx card!\n"); + return -ENOMEM; + } + + dev->dev_private = (void*)gf; + + gf->drm_dev = dev; + //TODO..FIXME. need remove gf->index. + gf->index = dev->primary->index; + + pci_set_drvdata(pdev, dev); + + dma_set_mask_and_coherent(device, DMA_BIT_MASK(40)); + + gf->pdev = pdev; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, (const struct drm_driver *)&gf_drm_driver.base); +#elif DRM_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) + ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "arisedrmfb"); +#else + ret = gf_kick_out_firmware_fb(pdev); +#endif + + if (ret) + { + gf_error("remove conflicting framebuffer failed. ret:%x.\n", ret); + } + + + ret = pci_request_regions(pdev, gf_driver.name); + if(ret) + { + gf_error("pci_request_regions() failed. ret:%x.\n", ret); + } + + pci_set_master(pdev); + + //fpga only +#if 0 + unsigned short command = 0; + gf_get_command_status16(pdev,&command); + gf_info("command:%x\n",command); + if(!(command & PCI_EN_IO_SPACE)) + { + gf_write_command_status16(pdev,(command|PCI_EN_IO_SPACE)); + gf_info("set primary command:%x\n",gf_get_command_status16(pdev,&command)); + } +#endif + + /*don't use the vga arbiter*/ +#if defined(CONFIG_VGA_ARB) + vga_set_legacy_decoding(pdev, VGA_RSRC_NONE); +#endif + + gf_init_adapter_info_by_params(&gf->a_info, &gf_modparams); + gf->a_info.minor_index = gf->index; + ret = gf_card_init(gf, pdev); + if(ret) + { + gf_error("%s_card_init() failed. ret:0x%x\n", STR(DRIVER_NAME), ret); + } + + gf->fence_drv = gf_calloc(sizeof(struct gf_dma_fence_driver)); + + gf_dma_fence_driver_init(gf->adapter, gf->fence_drv); + + gf_info("%s = %p, %s->pdev = %p, dev = %p, dev->primary = %p\n", STR(DRIVER_NAME), gf, STR(DRIVER_NAME), gf->pdev, dev, dev ? dev->primary : NULL); + + disp_irq_install(gf->disp_info); + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + gf_debugfs_init(gf); + gf_fbdev_init(gf); +#endif + + return ret; +} + +static int gf_drm_open(struct drm_device *dev, struct drm_file *file) +{ + gf_card_t *gf = dev->dev_private; + gf_file_t *priv; + int err = -ENODEV; + + if (!gf->adapter) + { + return err; + } + + priv = gf_calloc(sizeof(gf_file_t)); + if (!priv) + return -ENOMEM; + + file->driver_priv = priv; + priv->parent_file = file; + priv->card = gf; + + priv->lock = gf_create_mutex(); + + err = gf_core_interface->create_device(gf->adapter, file, &priv->gpu_device); + gf_assert(err == 0, GF_FUNC_NAME(__func__)); + if(gf->debugfs_dev) + { + priv->debug = gf_debugfs_add_device_node(gf->debugfs_dev, gf_get_current_pid(), priv->gpu_device); + } + + return 0; +} + +static void gf_drm_postclose(struct drm_device *dev, struct drm_file *file) +{ + gf_file_t *priv = file->driver_priv; + gf_card_t *gf = priv->card; + + if(priv->hold_lock) + { + gf_mutex_unlock(gf->lock); + } + + if(priv->gpu_device) + { + if(gf->debugfs_dev) + { + gf_debugfs_remove_device_node(gf->debugfs_dev, priv->debug); + priv->debug = NULL; + } + + gf_core_interface->final_cleanup(gf->adapter, priv->gpu_device); + priv->gpu_device = 0; + } + + gf_destroy_mutex(priv->lock); + gf_free(priv); + + file->driver_priv = NULL; +} + +static void gf_drm_last_close(struct drm_device* dev) +{ +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + gf_card_t *gf = dev->dev_private; + gf_fbdev_restore_mode(gf); +#else + drm_fb_helper_lastclose(dev); +#endif +} + +#if DRM_VERSION_CODE < KERNEL_VERSION(4,11,0) +static int gf_drm_device_is_agp(struct drm_device * dev) +{ + return 0; +} +#endif + +int gf_mmap(struct file *filp, struct vm_area_struct *vma) +{ + int ret = 0; +#ifndef __frv__ + struct drm_file *file = filp->private_data; + gf_file_t *priv = file->driver_priv; + gf_card_t *card = priv->card; + gf_map_argu_t *map = priv->map; + gf_map_argu_t map_argu; + + if(map == NULL) + { + bus_config_t bus_config = {0}; + + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + + gf_get_bus_config(card->pdev, &bus_config); + + map_argu.flags.mem_type = GF_SYSTEM_IO; + + if((offset >= bus_config.mem_start_addr[0]) && + (offset < bus_config.mem_end_addr[0])) + { + /* map fb as wc */ + map_argu.flags.cache_type = GF_MEM_WRITE_COMBINED; + } + else + { + /* map mmio reg as uc*/ + map_argu.flags.cache_type = GF_MEM_UNCACHED; + } + + map = &map_argu; + } + + switch(map->flags.mem_type) + { + case GF_SYSTEM_IO: + ret = gf_map_system_io(vma, map); + break; + + case GF_SYSTEM_RAM: + //case GF_SYSTEM_RAM_DYNAMIC: + ret = gf_map_system_ram(vma, map); + break; + + default: + gf_error("%s, unknown memory map type", GF_FUNC_NAME(__func__)); + ret = -1; + break; + } +#endif + + return ret; +} + +#if defined(CONFIG_COMPAT) +static long gf_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + unsigned int nr = GF_IOCTL_NR(cmd); + + if (nr < DRM_COMMAND_BASE) + { + ret = drm_compat_ioctl(filp, cmd, arg); + } + else + { + ret = drm_ioctl(filp, cmd, arg); + } + + return ret; +} +#endif + + +static void gf_drm_unload_kms(struct drm_device *dev) +{ + gf_card_t *gf = dev->dev_private; + gf_info("drm unload.\n"); + + if(gf == NULL) return; + + disp_irq_uninstall(gf->disp_info); + + if (gf->fence_drv) { + gf_dma_fence_driver_fini(gf->fence_drv); + gf_free(gf->fence_drv); + gf->fence_drv = NULL; + } + gf_card_deinit(gf); + gf_free(gf); + dev->dev_private = NULL; +} +static struct file_operations gf_drm_fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .unlocked_ioctl = drm_ioctl, +#if defined(__x86_64__) && defined(CONFIG_COMPAT) + .compat_ioctl = gf_compat_ioctl, +#endif + .mmap = gf_drm_gem_mmap, + .read = drm_read, + .poll = drm_poll, + .llseek = noop_llseek, +}; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) +#define GF_DRM_FEATURE \ + ( DRIVER_MODESET | DRIVER_RENDER | DRIVER_GEM) +#elif DRM_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) +#define GF_DRM_FEATURE \ + ( DRIVER_MODESET | DRIVER_RENDER | DRIVER_PRIME | DRIVER_GEM) +#else +#define GF_DRM_FEATURE \ + (DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_MODESET | DRIVER_RENDER | DRIVER_PRIME | DRIVER_GEM) +#endif + +static struct drm_gf_driver gf_drm_driver = { + .file_priv = NULL, +// .lock = __MUTEX_INITIALIZER(gf_drm_driver_lock), + .base = { + .driver_features = GF_DRM_FEATURE, + #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + .driver_features = GF_DRM_FEATURE | DRIVER_ATOMIC, + #endif + + #if DRM_VERSION_CODE < KERNEL_VERSION(4, 19, 0) + .load = gf_drm_load_kms, + #endif + .open = gf_drm_open, + + #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + .unload = gf_drm_unload_kms, + #endif + + .postclose = gf_drm_postclose, + .lastclose = gf_drm_last_close, + .ioctls = gf_ioctls, + .num_ioctls = ioctl_nr_total_num, + #if DRM_VERSION_CODE < KERNEL_VERSION(4,14,0) && DRM_VERSION_CODE >= KERNEL_VERSION(3,18,0) + .set_busid = drm_pci_set_busid, + #endif + + #if DRM_VERSION_CODE < KERNEL_VERSION(4,0,0) + #ifndef __ARM_ARCH + .suspend = gf_drm_suspend, + .resume = gf_drm_resume, + #endif + #endif + #if DRM_VERSION_CODE < KERNEL_VERSION(4,11,0) + .device_is_agp = gf_drm_device_is_agp, + #endif + .fops = &gf_drm_fops, + + #if DRM_VERSION_CODE < KERNEL_VERSION(5,11,0) + .gem_vm_ops = &gf_gem_vm_ops, + #endif + + #if DRM_VERSION_CODE < KERNEL_VERSION(5, 11, 0) + .gem_prime_vmap = gf_gem_prime_vmap, + .gem_prime_vunmap = gf_gem_prime_vunmap, + #endif + + + #if DRM_VERSION_CODE < KERNEL_VERSION(5,9,0) + .gem_free_object = gf_gem_free_object, + #elif DRM_VERSION_CODE < KERNEL_VERSION(5,11,0) + .gem_free_object_unlocked = gf_gem_free_object, + #else + #endif + #if DRM_VERSION_CODE < KERNEL_VERSION(6,6,0) + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .prime_fd_to_handle = gf_gem_prime_fd_to_handle, + #endif + + #if DRM_VERSION_CODE < KERNEL_VERSION(5,11,0) + .gem_open_object = gf_gem_open, + .gem_prime_export = gf_gem_prime_export, + #endif + .gem_prime_import = gf_gem_prime_import, + + .dumb_create = gf_gem_dumb_create, + .dumb_map_offset = gf_gem_mmap_gtt, + + #if DRM_VERSION_CODE < KERNEL_VERSION(5,14,0) + .irq_preinstall = gf_irq_preinstall, + .irq_postinstall = gf_irq_postinstall, + .irq_handler = gf_irq_handle, + .irq_uninstall = gf_irq_uninstall, + #endif + + #if DRM_VERSION_CODE < KERNEL_VERSION(5,12,0) + .dumb_destroy = drm_gem_dumb_destroy, + #endif + .name = STR(DRIVER_NAME), + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, + } +}; + +static int gf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 19 ,0) + struct drm_device *dev; + unsigned long flags = ent->driver_data; + gf_card_t *gf = NULL; + int ret; + + dev = drm_dev_alloc(&gf_drm_driver.base, &pdev->dev); + if (IS_ERR(dev)) + { + return PTR_ERR(dev); + } + + ret = pci_enable_device(pdev); + if (ret) + { + goto err_free; + } + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 14, 0) + dev->pdev = pdev; +#endif + + pci_set_drvdata(pdev, dev); + + ret = gf_drm_load_kms(dev, flags); + if (ret) + { + goto err_pci; + } + + ret = drm_dev_register(dev, flags); + if (ret) + { + goto err_pci; + } + + gf = (gf_card_t *)dev->dev_private; + + gf_debugfs_init(gf); + + drm_fbdev_generic_setup(dev, 32); + + return 0; + +err_pci: + pci_disable_device(pdev); +err_free: + drm_dev_put(dev); + return ret; + +#elif DRM_VERSION_CODE > KERNEL_VERSION(3,10,52) + return drm_get_pci_dev(pdev, ent, &gf_drm_driver.base); +#else + return 0; +#endif +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(3,10,52) +static void __exit gf_pcie_cleanup(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + gf_info("pcie_cleanup.\n"); +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + drm_dev_unplug(dev); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) + drm_dev_put(dev); +#endif + +#else + gf_drm_unload_kms(dev); + + drm_put_dev(dev); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 19 ,0) + pci_disable_device(pdev); +#endif + + pci_set_drvdata(pdev, NULL); + + pci_release_regions(pdev); +} +#endif + +static int gf_pmops_suspend(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + + gf_info("pci device(vendor:0x%X, device:0x%X) pm suspend\n", pdev->vendor, pdev->device); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4,0,0) + gf_drm_suspend(pci_get_drvdata(pdev), PMSG_SUSPEND); +#endif + + return 0; +} +static int gf_pmops_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + + gf_info("pci device(vendor:0x%X, device:0x%X) pm resume\n", pdev->vendor, pdev->device); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4,0,0) + gf_drm_resume(pci_get_drvdata(pdev)); +#endif + + return 0; +} + +static int gf_pmops_freeze(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + + gf_info("pci device(vendor:0x%X, device:0x%X) pm freeze\n", pdev->vendor, pdev->device); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4,0,0) + gf_drm_suspend(pci_get_drvdata(pdev), PMSG_FREEZE); +#endif + + return 0; +} + +static int gf_pmops_thaw(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = NULL; + gf_card_t *gf_card = NULL; + + gf_info("pci device(vendor:0x%X, device:0x%X) pm thaw\n", pdev->vendor, pdev->device); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4,0,0) + drm_dev = (struct drm_device *)pci_get_drvdata(pdev); + gf_card = (gf_card_t *)drm_dev->dev_private; + gf_card->flags |= GF_S4_RESUME; + + gf_drm_resume(pci_get_drvdata(pdev)); +#endif + + return 0; +} + +static int gf_pmops_poweroff(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + + gf_info("pci device(vendor:0x%X, device:0x%X) pm poweroff\n", pdev->vendor, pdev->device); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4,0,0) + gf_drm_suspend(pci_get_drvdata(pdev), PMSG_SUSPEND); +#endif + + return 0; +} + +static int gf_pmops_restore(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + + gf_info("pci device(vendor:0x%X, device:0x%X) pm restore\n", pdev->vendor, pdev->device); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4,0,0) + gf_drm_resume(pci_get_drvdata(pdev)); +#endif + + return 0; +} + +static int gf_pmops_runtime_suspend(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + + gf_info("pci device(vendor:0x%X, device:0x%X) pm runtime_suspend\n", pdev->vendor, pdev->device); + + return 0; +} + +static int gf_pmops_runtime_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + + gf_info("pci device(vendor:0x%X, device:0x%X) pm runtime_resume\n", pdev->vendor, pdev->device); + + return 0; +} +static int gf_pmops_runtime_idle(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + + gf_info("pci device(vendor:0x%X, device:0x%X) pm runtime_idle\n", pdev->vendor, pdev->device); + + return 0; +} + +static void gf_shutdown(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + gf_card_t *gf = dev->dev_private; + + gf_info("pci device(vendor:0x%X, device:0x%X) shutting down.\n", pdev->vendor, pdev->device); + + gf_core_interface->wait_chip_idle(gf->adapter); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + drm_atomic_helper_suspend(dev); +#else + gf_disp_suspend_helper(dev); +#endif + gf_info("pci device(vendor:0x%X, device:0x%X) already shut down.\n", pdev->vendor, pdev->device); +} + +static const struct dev_pm_ops gf_pm_ops = { + .suspend = gf_pmops_suspend, + .resume = gf_pmops_resume, + .freeze = gf_pmops_freeze, + .thaw = gf_pmops_thaw, + .poweroff = gf_pmops_poweroff, + .restore = gf_pmops_restore, + .runtime_suspend = gf_pmops_runtime_suspend, + .runtime_resume = gf_pmops_runtime_resume, + .runtime_idle = gf_pmops_runtime_idle, +}; + +static struct pci_driver gf_driver = +{ + .name = STR(DRIVER_NAME), + .id_table = pciidlist, + .probe = gf_pcie_probe, +#if DRM_VERSION_CODE < KERNEL_VERSION(3,10,52) + //.remove = __devexit_p(gf_pcie_cleanup), + .remove = NULL, +#else + .remove = __exit_p(gf_pcie_cleanup), +#endif + .driver.pm = &gf_pm_ops, + .shutdown = gf_shutdown, +}; + + +/*************************************** PCI functions ********************************************/ + +int gf_get_command_status16(void *dev, unsigned short *command) +{ + return pci_read_config_word((struct pci_dev*)dev, 0x4, command); +} + +int gf_get_command_status32(void *dev, unsigned int *command) +{ + return pci_read_config_dword((struct pci_dev*)dev, 0x4, command); +} + +int gf_write_command_status16(void *dev, unsigned short command) +{ + return pci_write_config_word((struct pci_dev*)dev, 0x4, command); +} + +int gf_write_command_status32(void *dev, unsigned int command) +{ + return pci_write_config_dword((struct pci_dev*)dev, 0x4, command); +} + + +int gf_get_bar1(void *dev, unsigned int *bar1) +{ + return pci_read_config_dword((struct pci_dev*)dev, 0x14, bar1); +} + +int gf_get_rom_save_addr(void *dev, unsigned int *romsave) +{ + return pci_read_config_dword((struct pci_dev*)dev, 0x30, romsave); +} + +int gf_write_rom_save_addr(void *dev, unsigned int romsave) +{ + return pci_write_config_dword((struct pci_dev*)dev, 0x30, romsave); +} + +int gf_pci_get_rom(void *dev, void *buf, unsigned int buf_size) +{ + size_t size; + int ret = -1; + struct pci_dev *pdev = (struct pci_dev*)dev; +#ifdef __aarch64__ + struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; + void *virt_addr = NULL; + + if ((res == NULL) || (res->start == 0) || (res->start == ~0)) + { + gf_info("invalid pci resource!\n"); + return -1; + } + + if (pci_enable_rom(pdev)) + { + gf_info("enable pci rom failed!\n"); + return -1; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) + virt_addr = ioremap((phys_addr_t)res->start, 0x10000); +#else + virt_addr = ioremap_nocache((phys_addr_t)res->start, 0x10000); +#endif + + if (virt_addr) + { + if (*(unsigned short*)virt_addr == ROM_IMAGE_HEADER) + { + gf_memcpy(buf, virt_addr, buf_size); + ret = 0; + } + + iounmap(virt_addr); + + if (!(res->flags & IORESOURCE_ROM_ENABLE)) + { + pci_disable_rom(pdev); + } + } +#else + unsigned int rom_base = 0; + gf_map_argu_t map = {0}; + gf_vm_area_t *vma = NULL; + void *src_image = NULL; + + gf_get_rom_save_addr(pdev, &rom_base); + rom_base |= 0x01; // enable expansion rom + gf_write_rom_save_addr(pdev, rom_base); + rom_base &= 0xFFFFFFFE; + map.flags.cache_type = GF_MEM_UNCACHED; + map.flags.mem_space = GF_MEM_KERNEL; + map.flags.mem_type = GF_SYSTEM_IO; + map.size = 0x10000; + map.phys_addr = rom_base; + + vma = gf_map_io_memory(NULL, &map); + src_image = vma->virt_addr; + + if ((src_image) && (*(unsigned short*)src_image == ROM_IMAGE_HEADER)) + { + gf_memcpy(buf, src_image, buf_size); + gf_unmap_io_memory(vma); + ret = 0; + } + else + { + if (src_image) + { + gf_unmap_io_memory(vma); + gf_write_rom_save_addr(pdev, rom_base); + } + + src_image = pci_map_rom(pdev, &size); + if (src_image) + { + if (*(unsigned short*)src_image == ROM_IMAGE_HEADER) + { + gf_memcpy(buf, src_image, buf_size); + ret = 0; + } + + pci_unmap_rom(pdev, src_image); + } + } +#endif + + return ret; +} + +unsigned long gf_get_rom_start_addr(void *dev) +{ + return pci_resource_start((struct pci_dev*)dev, 6); +} + +int gf_get_platform_config(void *dev, const char* config_name, int *buffer, int length) +{ + return 0; +} + +void gf_get_bus_config(void *dev, bus_config_t *bus) +{ + struct pci_dev *pdev = dev; + + pci_read_config_word(pdev, 0x2, &bus->device_id); + pci_read_config_word(pdev, 0x0, &bus->vendor_id); + pci_read_config_word(pdev, 0x4, &bus->command); + pci_read_config_word(pdev, 0x6, &bus->status); + pci_read_config_byte(pdev, 0x8, &bus->revision_id); + pci_read_config_byte(pdev, 0x9, &bus->prog_if); + + pci_read_config_byte(pdev, 0xa, &bus->sub_class); + pci_read_config_byte(pdev, 0xb, &bus->base_class); + pci_read_config_byte(pdev, 0xc, &bus->cache_line_size); + pci_read_config_byte(pdev, 0xd, &bus->latency_timer); + pci_read_config_byte(pdev, 0xe, &bus->header_type); + pci_read_config_byte(pdev, 0xf, &bus->bist); + pci_read_config_word(pdev, 0x2c, &bus->sub_sys_vendor_id); + pci_read_config_word(pdev, 0x2e, &bus->sub_sys_id); + //pci_read_config_word(pdev, 0x52, &bus->link_status); + pcie_capability_read_word(pdev,0x12, &bus->link_status); //PCI_EXP_LNKST + + //pci_write_config_word(pdev, 0x4, 7); + + bus->reg_start_addr[0] = pci_resource_start(pdev, 0); + + bus->mem_start_addr[0] = pci_resource_start(pdev, 1); + + bus->reg_start_addr[2] = 0; + bus->reg_start_addr[3] = 0; + bus->reg_start_addr[4] = 0; + + bus->reg_end_addr[0] = pci_resource_end(pdev, 0); + bus->mem_end_addr[0] = pci_resource_end(pdev, 1); + + bus->reg_end_addr[2] = 0; + bus->reg_end_addr[3] = 0; + bus->reg_end_addr[4] = 0; +} + +void gf_init_bus_id(gf_card_t *gf) +{ + struct pci_dev *pdev = gf->pdev; + + int pci_domain = 0; + int pci_bus = pdev->bus->number; + int pci_slot = PCI_SLOT(pdev->devfn); + int pci_func = PCI_FUNC(pdev->devfn); + + gf->len = snprintf(gf->busId, 40, "pci:%04x:%02x:%02x.%d", pci_domain, pci_bus, pci_slot, pci_func); +} + +int gf_register_driver(void) +{ + int ret = 0; + + mutex_init(&gf_drm_driver.lock); + + ret = pci_register_driver(&gf_driver);//register driver first, register drm device during pci probe +#if DRM_VERSION_CODE <= KERNEL_VERSION(3,10,52) + ret = drm_pci_init(&gf_drm_driver.base, &gf_driver); +#endif + + return ret; +} + +void gf_unregister_driver(void) +{ +#if DRM_VERSION_CODE <= KERNEL_VERSION(3,10,52) + drm_pci_exit(&gf_drm_driver.base, &gf_driver); +#endif + + pci_unregister_driver(&gf_driver); +} diff --git a/drivers/gpu/drm/arise/linux/gf_plane.c b/drivers/gpu/drm/arise/linux/gf_plane.c new file mode 100644 index 0000000000000..c64fdb579dda8 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_plane.c @@ -0,0 +1,784 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_plane.h" +#include "gf_drmfb.h" +#include "gf_fence.h" +#include "gf_modifies.h" +#include "gf_splice.h" + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) +int gf_atomic_helper_update_plane(struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h, + struct drm_modeset_acquire_ctx *ctx) +#else +int gf_atomic_helper_update_plane(struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) +#endif +{ + struct drm_plane_state* plane_state = plane->state; + const struct drm_plane_helper_funcs *funcs; + + gf_assert(!!crtc == !!fb, GF_FUNC_NAME(__func__)); + + if (to_gf_plane(plane)->is_cursor == 0) + { +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + return drm_atomic_helper_update_plane(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h, ctx); +#else + return drm_atomic_helper_update_plane(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h); +#endif + } + + plane_state->crtc = crtc; + if(crtc->state) + { + crtc->state->plane_mask |= (1 << drm_plane_index(plane)); + } + + drm_atomic_set_fb_for_plane(plane_state, fb); + plane_state->crtc_x = crtc_x; + plane_state->crtc_y = crtc_y; + plane_state->crtc_w = crtc_w; + plane_state->crtc_h = crtc_h; + plane_state->src_x = src_x; + plane_state->src_y = src_y; + plane_state->src_w = src_w; + plane_state->src_h = src_h; + to_gf_plane_state(plane_state)->legacy_cursor = 1; + + funcs = plane->helper_private; + if(funcs && funcs->atomic_check) + { + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + gf_assert(funcs->atomic_check(plane, NULL) == 0, GF_FUNC_NAME(__func__)); +#else + gf_assert(funcs->atomic_check(plane, plane_state) == 0, GF_FUNC_NAME(__func__)); +#endif + } + + if(funcs && funcs->atomic_update) + { + funcs->atomic_update(plane, NULL); + } + + plane->old_fb = plane->fb; + + return 0; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) +int gf_atomic_helper_disable_plane(struct drm_plane *plane, struct drm_modeset_acquire_ctx *ctx) +#else +int gf_atomic_helper_disable_plane(struct drm_plane *plane) +#endif +{ + struct drm_plane_state* plane_state = plane->state; + const struct drm_plane_helper_funcs *funcs; + + if(to_gf_plane(plane)->is_cursor == 0) + { +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + return drm_atomic_helper_disable_plane(plane, ctx); +#else + return drm_atomic_helper_disable_plane(plane); +#endif + } + if((plane_state->crtc)&&(plane_state->crtc->state)) + { + plane_state->crtc->state->plane_mask &= ~(1 << drm_plane_index(plane)); + } + plane_state->crtc = NULL; + drm_atomic_set_fb_for_plane(plane_state, NULL); + plane_state->crtc_x = 0; + plane_state->crtc_y = 0; + plane_state->crtc_w = 0; + plane_state->crtc_h = 0; + plane_state->src_x = 0; + plane_state->src_y = 0; + plane_state->src_w = 0; + plane_state->src_h = 0; + to_gf_plane_state(plane_state)->legacy_cursor = 1; + + funcs = plane->helper_private; + if(funcs && funcs->atomic_check) + { +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + gf_assert(funcs->atomic_check(plane, NULL) == 0, GF_FUNC_NAME(__func__)); +#else + gf_assert(funcs->atomic_check(plane, plane_state) == 0, GF_FUNC_NAME(__func__)); +#endif + } + + if(funcs && funcs->atomic_disable) + { + funcs->atomic_disable(plane, NULL); + } + + plane->old_fb = plane->fb; + + return 0; +} + +void gf_plane_destroy(struct drm_plane *plane) +{ + drm_plane_cleanup(plane); + gf_free(to_gf_plane(plane)); +} + +void gf_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) +{ + gf_plane_state_t* gf_pstate = to_gf_plane_state(state); + + __drm_atomic_helper_plane_destroy_state(state); + + gf_free(gf_pstate); +} + +struct drm_plane_state* gf_plane_duplicate_state(struct drm_plane *plane) +{ + struct drm_plane_state *state; + gf_plane_state_t *gf_pstate; + + gf_pstate = gf_calloc(sizeof(gf_plane_state_t)); + + if (!gf_pstate) + { + return NULL; + } + + state = &gf_pstate->base_pstate; + + __drm_atomic_helper_plane_duplicate_state(plane, state); + + if(plane->state) + { +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 20, 0) + gf_pstate->pixel_blend_mode = to_gf_plane_state(plane->state)->pixel_blend_mode; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 18, 0) + gf_pstate->alpha = to_gf_plane_state(plane->state)->alpha; +#endif +#endif + gf_pstate->alpha_source = to_gf_plane_state(plane->state)->alpha_source; + } + + return state; +} + +//get/set driver private property, we can add this later +int gf_plane_atomic_get_property(struct drm_plane *plane, + const struct drm_plane_state *state, + struct drm_property *property, + uint64_t *val) +{ + int ret = -EINVAL; + gf_plane_t* gf_plane = to_gf_plane(plane); + gf_plane_state_t* gf_plane_state = to_gf_plane_state(state); + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 20, 0) + if(property == gf_plane->blend_mode_property) + { + *val = gf_plane_state->pixel_blend_mode; + ret = 0; + } +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 18, 0) + if(property == gf_plane->alpha_property) + { + *val = gf_plane_state->alpha; + ret = 0; + } +#endif + + if(property == gf_plane->alpha_source_prop) + { + *val = gf_plane_state->alpha_source; + ret = 0; + } + + if(ret) + { +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + DRM_WARN("Invalid driver-private property '%s'\n", property->name); +#endif + } + return ret; +} + +int gf_plane_atomic_set_property(struct drm_plane *plane, + struct drm_plane_state *state, + struct drm_property *property, + uint64_t val) +{ + int ret = -EINVAL; + gf_plane_t* gf_plane = to_gf_plane(plane); + gf_plane_state_t* gf_plane_state = to_gf_plane_state(state); + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 20, 0) + if(property == gf_plane->blend_mode_property) + { + gf_plane_state->pixel_blend_mode = val; + ret = 0; + } +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 18, 0) + if(property == gf_plane->alpha_property) + { + gf_plane_state->alpha = val; + ret = 0; + } +#endif + + if(property == gf_plane->alpha_source_prop) + { + gf_plane_state->alpha_source = val; + ret = 0; + } + + if(ret) + { +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + DRM_WARN("Invalid driver-private property '%s'\n", property->name); +#endif + } + return ret; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) +int gf_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) +#else +int gf_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *new_state) +#endif +{ +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_plane_state *new_state = NULL; +#endif + gf_plane_t* gf_plane = to_gf_plane(plane); + unsigned int src_w, src_h, dst_w, dst_h; + int status = 0; + + DRM_DEBUG_KMS("plane=%d\n", plane->index); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + if (gf_plane->is_cursor) + { + new_state = plane->state; + } + else + { + new_state = drm_atomic_get_new_plane_state(state, plane); + } +#endif + + src_w = (new_state->src_w >> 16) & 0xFFFF; + src_h = (new_state->src_h >> 16) & 0xFFFF; + + dst_w = new_state->crtc_w; + dst_h = new_state->crtc_h; + + if(!gf_plane->can_window && (new_state->crtc_x != 0 || new_state->crtc_y != 0)) + { + status = -EINVAL; + goto END; + } + + if(!gf_plane->can_up_scale) + { + if((src_w < dst_w) || (src_h < dst_h)) + { + status = -EINVAL; + goto END; + } + } + + if(!gf_plane->can_down_scale) + { + if((src_w > dst_w) || (src_h > dst_h)) + { + status = -EINVAL; + goto END; + } + } + //max cursor size if 128x128 + if (gf_plane->is_cursor) + { + if((dst_w > 128) || (dst_h > 128)) + { + status = -EINVAL; + goto END; + } + } + +END: + return status; +} + +//add this interface to make kernel 4.9 and above version compatible +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) +void drm_atomic_set_fence_for_plane_gf(struct drm_plane_state *plane_state, dma_fence_t *fence) +#else +void drm_atomic_set_fence_for_plane_gf(const struct drm_plane_state *plane_state, dma_fence_t *fence) +#endif +{ + if (plane_state->fence) { + dma_fence_put(fence); + + return; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + plane_state->fence = fence; +#endif +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) +int gf_prepare_plane_fb(struct drm_plane *plane, struct drm_plane_state *new_state) +#else +int gf_prepare_plane_fb(struct drm_plane *plane, const struct drm_plane_state *new_state) +#endif +{ + struct drm_framebuffer *fb = new_state->fb; + struct drm_gf_framebuffer *gfb = to_gfb(fb); + gf_card_t *gf = plane->dev->dev_private; + + if (!fb || !gfb->obj) + { + return 0; + } + + /* resident */ + gf_core_interface->prepare_and_mark_unpagable(gf->adapter, gfb->obj->core_handle, &gfb->obj->info); + + if (plane->state->fb != fb) + { + dma_fence_t *fence = gf_reservation_object_get_excl_rcu(gfb->obj->resv); + if (fence) + { + drm_atomic_set_fence_for_plane_gf(new_state, fence); + } + } + + return 0; +} + +static bool gf_plane_can_async_flip(struct drm_plane_state *new_state, struct drm_plane_state *old_state) +{ + struct drm_gf_framebuffer *new_gfb = new_state->fb? to_gfb(new_state->fb) : NULL; + struct drm_gf_framebuffer *old_gfb = old_state->fb? to_gfb(old_state->fb) : NULL; + + if (!old_gfb || !new_gfb) + { + return true; + } + + if (!!new_gfb->obj->info.compress_format != !!old_gfb->obj->info.compress_format) + { + return false; + } + + if (new_state->fb->pitches[0] != old_state->fb->pitches[0]) + { + return false; + } + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 11, 0) + if (new_state->fb->pixel_format != old_state->fb->pixel_format) +#else + if (new_state->fb->format->format != old_state->fb->format->format) +#endif + { + return false; + } + + return true; +} + +void gf_plane_atomic_update_internal(struct drm_plane *plane, struct drm_plane_state *new_state, struct drm_plane_state *old_state) +{ + gf_card_t *card = plane->dev->dev_private; + gf_plane_state_t* gf_plane_state = to_gf_plane_state(plane->state); + + DRM_DEBUG_KMS("plane=%d, crtc=%d\n", plane->index, (to_gf_plane(plane))->crtc_index); + + if ((is_plane_work_in_splice_mode(plane) && + is_splice_target_active_in_drm(plane->dev))) + { + return; + } + + if (to_gf_plane(plane)->is_cursor) + { + gf_cursor_update_t arg = {0, }; + + arg.crtc = to_gf_plane(plane)->crtc_index; + + if (gf_plane_state->legacy_cursor) + { + arg.vsync_on = 0; + } + else + { + arg.vsync_on = 1; + } + + if (plane->state->crtc && !gf_plane_state->disable) + { + arg.bo = new_state->fb ? to_gfb(new_state->fb)->obj : NULL; + arg.pos_x = new_state->crtc_x; + arg.pos_y = new_state->crtc_y; + arg.width = new_state->crtc_w; + arg.height = new_state->crtc_h; + } + + disp_cbios_update_cursor(card->disp_info, &arg); + } + else + { + gf_crtc_flip_t arg = {0}; + + arg.crtc = to_gf_plane(plane)->crtc_index; + arg.stream_type = to_gf_plane(plane)->plane_type; + + if (new_state->crtc && !gf_plane_state->disable) + { + arg.fb = new_state->fb; + arg.crtc_x = new_state->crtc_x; + arg.crtc_y = new_state->crtc_y; + arg.crtc_w = new_state->crtc_w; + arg.crtc_h = new_state->crtc_h; + arg.src_x = new_state->src_x >> 16; + arg.src_y = new_state->src_y >> 16; + arg.src_w = new_state->src_w >> 16; + arg.src_h = new_state->src_h >> 16; + if(plane->type == DRM_PLANE_TYPE_OVERLAY) + { +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 20, 0) + arg.blend_mode = gf_plane_state->pixel_blend_mode; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 18, 0) + arg.const_alpha = gf_plane_state->alpha; +#else + arg.const_alpha = new_state->alpha; +#endif +#else + arg.const_alpha = new_state->alpha; + arg.blend_mode = new_state->pixel_blend_mode; +#endif + arg.blend_alpha_source = gf_plane_state->alpha_source; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) + if(plane->state->crtc->state->async_flip) +#else + if(plane->state->crtc->state->pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) +#endif + { + if (gf_plane_can_async_flip(new_state, old_state)) + { + arg.async_flip = 1; + } + else + { + gf_crtc_state_t* gf_cstate = to_gf_crtc_state(plane->state->crtc->state); + arg.async_flip = 0; + gf_cstate->keep_vsync = 1; + } + + } +#endif + } + + disp_cbios_crtc_flip(card->disp_info, &arg); + + { + gf_perf_event_t perf_event = {0, }; + unsigned long long timestamp; + + gf_get_nsecs(×tamp); + perf_event.header.timestamp_high = timestamp >> 32; + perf_event.header.timestamp_low = timestamp & 0xffffffff; + + perf_event.header.size = sizeof(gf_perf_event_ps_flip_t); + perf_event.header.type = GF_PERF_EVENT_PS_FLIP; + perf_event.ps_flip_event.iga_idx = to_gf_plane(plane)->crtc_index + 1; + + gf_core_interface->perf_event_add_event(card->adapter, &perf_event); + card->fps_count++; + } + } +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) +void gf_plane_atomic_update(struct drm_plane* plane, struct drm_atomic_state* state) +#else +void gf_plane_atomic_update(struct drm_plane* plane, struct drm_plane_state* old_state) +#endif +{ + struct drm_plane_state *new_state = NULL; + gf_plane_t* gf_plane = to_gf_plane(plane); + gf_plane_state_t* gf_pstate = to_gf_plane_state(plane->state); +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_plane_state* old_state = NULL; +#endif + + DRM_DEBUG_KMS("Update plane=%d\n", plane->index); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + if (gf_plane->is_cursor || state == NULL) + { + new_state = plane->state; + } + else + { + new_state = drm_atomic_get_new_plane_state(state, plane); + old_state = drm_atomic_get_old_plane_state(state, plane); + } +#else + new_state = plane->state; +#endif + + if (gf_plane->resume_from_s4) + { + gf_pstate->disable = 1; + gf_plane->resume_from_s4 = 0; + } + else + { + gf_pstate->disable = 0; + } + + gf_plane_atomic_update_internal(plane, new_state, old_state); +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) +void gf_plane_atomic_disable(struct drm_plane *plane, struct drm_atomic_state *state) +#else +void gf_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) +#endif +{ +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_plane_state *old_state = NULL; +#endif + struct drm_plane_state *new_state = NULL; + gf_plane_state_t* gf_pstate = to_gf_plane_state(plane->state); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + gf_plane_t* gf_plane = to_gf_plane(plane); + + if (gf_plane->is_cursor || state == NULL) + { + new_state = plane->state; + } + else + { + new_state = drm_atomic_get_new_plane_state(state, plane); + old_state = drm_atomic_get_old_plane_state(state, plane); + } +#else + new_state = plane->state; +#endif + + DRM_DEBUG_KMS("Disable plane=%d\n", plane->index); + + gf_pstate->disable = 1; + + gf_plane_atomic_update_internal(plane, new_state, old_state); +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) +void gf_cleanup_plane_fb(struct drm_plane *plane, struct drm_plane_state *old_state) +#else +void gf_cleanup_plane_fb(struct drm_plane *plane, const struct drm_plane_state *old_state) +#endif +{ + gf_card_t *gf = plane->dev->dev_private; + struct drm_framebuffer *fb = old_state->fb; + + if (fb && to_gfb(fb)->obj) + { + gf_core_interface->mark_pagable(gf->adapter, to_gfb(fb)->obj->core_handle); + } +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) +bool gf_plane_format_mod_supported(struct drm_plane *plane, uint32_t format, + uint64_t modifier) +{ + int i; + bool ret = false; + + switch(modifier) + { + case DRM_FORMAT_MOD_GF_DISPLAY: + case DRM_FORMAT_MOD_GF_LINEAR: + case DRM_FORMAT_MOD_GF_TILED: + case DRM_FORMAT_MOD_GF_COMPRESS: + case DRM_FORMAT_MOD_GF_TILED_COMPRESS: + case DRM_FORMAT_MOD_GF_LOCAL: + case DRM_FORMAT_MOD_GF_PCIE: + case DRM_FORMAT_MOD_GF_INVALID: + /* TODO: should do something? */ + ret = true; + goto check_done; + default: + break; + } + + /* check that modifier is on the list of the plane's supported modifiers. */ + for (i = 0; i < plane->modifier_count; i++) + { + if (modifier == plane->modifiers[i]) + break; + } + if (i == plane->modifier_count) + { + ret = false; + goto check_done; + } + + /* + TODO: check the format and modifier whether being supported + */ + +check_done: + if (!ret) + { + gf_info("^^^ not support modifier %lld\n", modifier); + } + return ret; +} + +#endif + +#else + +int gf_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + struct drm_framebuffer *fb, int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) +{ + struct drm_device *dev = plane->dev; + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + gf_plane_t *gf_plane = to_gf_plane(plane); + gf_card_t *card = dev->dev_private; + int pipe = gf_plane->crtc_index; + int ret = 0; + int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay; + gf_crtc_flip_t arg = {0}; + + src_x = src_x >> 16; + src_y = src_y >> 16; + src_w = src_w >> 16; + src_h = src_h >> 16; + + if (crtc_x >= primary_w || crtc_y >= primary_h) + { + return -EINVAL; + } + + /* Don't modify another pipe's plane */ + if (pipe != gf_crtc->pipe) + { + return -EINVAL; + } + + if ((crtc_x + crtc_w) > primary_w) + { + crtc_w = primary_w - crtc_x; + } + + if (crtc_y + crtc_h > primary_h) + { + crtc_h = primary_h - crtc_y; + } + + if (!crtc_w || !crtc_h) /* Again, nothing to display */ + { + goto out; + } + + if(!gf_plane->can_window && (crtc_w != primary_w || crtc_h != primary_h)) + { + return -EINVAL; + } + + if(!gf_plane->can_up_scale && (src_w < crtc_w || src_h < crtc_h)) + { + return -EINVAL; + } + + if(!gf_plane->can_down_scale && (src_w > crtc_w || src_h > crtc_h)) + { + return -EINVAL; + } + + arg.fb = fb; + arg.crtc = to_gf_crtc(crtc)->pipe; + arg.stream_type = gf_plane->plane_type; + arg.crtc_x = crtc_x; + arg.crtc_y = crtc_y; + arg.crtc_w = crtc_w; + arg.crtc_h = crtc_h; + arg.src_x = src_x; + arg.src_y = src_y; + arg.src_w = src_w; + arg.src_h = src_h; + + mutex_lock(&dev->struct_mutex); + + //need add wait fence back? intel is to pin fence + disp_cbios_crtc_flip(card->disp_info, &arg); + + //need add wait_vblank if fb changed + disp_wait_for_vblank(card->disp_info, pipe, 50); + + gf_plane->src_pos = src_x | (src_y << 16); + gf_plane->src_size = src_w | (src_h << 16); + gf_plane->dst_pos = crtc_x | (crtc_y << 16); + gf_plane->dst_size = crtc_w | (crtc_h << 16); + + mutex_unlock(&dev->struct_mutex); +out: + return ret; +} + +int gf_disable_plane(struct drm_plane *plane) +{ + return 0; +} + +void gf_legacy_plane_destroy(struct drm_plane* plane) +{ + gf_disable_plane(plane); + drm_plane_cleanup(plane); + gf_free(to_gf_plane(plane)); +} + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_plane.h b/drivers/gpu/drm/arise/linux/gf_plane.h new file mode 100644 index 0000000000000..073d96a50d33b --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_plane.h @@ -0,0 +1,110 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _GF_PLANE_H_ +#define _GF_PLANE_H_ + +#include "gf_disp.h" +#include "gf_cbios.h" +#include "gf_fence.h" + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + +int gf_atomic_helper_update_plane(struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h, + struct drm_modeset_acquire_ctx *ctx); + +int gf_atomic_helper_disable_plane(struct drm_plane *plane, struct drm_modeset_acquire_ctx *ctx); + +#else + +int gf_atomic_helper_update_plane(struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h); + +int gf_atomic_helper_disable_plane(struct drm_plane *plane); + +#endif + +void gf_plane_destroy(struct drm_plane *plane); + +void gf_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state); + +struct drm_plane_state* gf_plane_duplicate_state(struct drm_plane *plane); + +int gf_plane_atomic_get_property(struct drm_plane *plane, + const struct drm_plane_state *state, + struct drm_property *property, + uint64_t *val); + +int gf_plane_atomic_set_property(struct drm_plane *plane, + struct drm_plane_state *state, + struct drm_property *property, + uint64_t val); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) +int gf_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state); + +void gf_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state); + +void gf_plane_atomic_disable(struct drm_plane *plane, struct drm_atomic_state *state); +#else +int gf_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *new_state); + +void gf_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state); + +void gf_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) +int gf_prepare_plane_fb(struct drm_plane *plane, struct drm_plane_state *new_state); +void gf_cleanup_plane_fb(struct drm_plane *plane, struct drm_plane_state *old_state); +void drm_atomic_set_fence_for_plane_gf(struct drm_plane_state *plane_state, dma_fence_t *fence); +#else +int gf_prepare_plane_fb(struct drm_plane *plane, const struct drm_plane_state *new_state); +void gf_cleanup_plane_fb(struct drm_plane *plane, const struct drm_plane_state *old_state); +void drm_atomic_set_fence_for_plane_gf(const struct drm_plane_state *plane_state, dma_fence_t *fence); +#endif + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) +bool gf_plane_format_mod_supported(struct drm_plane *plane, uint32_t format, + uint64_t modifier); +#endif + +#else + +int gf_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + struct drm_framebuffer *fb, int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h); + +int gf_disable_plane(struct drm_plane *plane); + +void gf_legacy_plane_destroy(struct drm_plane* plane); + +#endif + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_sink.c b/drivers/gpu/drm/arise/linux/gf_sink.c new file mode 100644 index 0000000000000..9b701cdfa54e4 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_sink.c @@ -0,0 +1,90 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + + +#include "gf_disp.h" +#include "gf_cbios.h" +#include "gf_sink.h" + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 11, 0) +static inline unsigned int kref_read(const struct kref *kref) +{ + return atomic_read(&kref->refcount); +} +#endif + +static void gf_sink_release(struct kref *ref) +{ + struct gf_sink *sink = container_of(ref, struct gf_sink, refcount); + + DRM_DEBUG_DRIVER("sink released: %p\n", sink); + + gf_free(sink); +} + +void gf_sink_get(struct gf_sink *sink) +{ + if (sink) + { + DRM_DEBUG_DRIVER("get sink: %p, ref: %d \n", sink, kref_read(&sink->refcount)); + kref_get(&sink->refcount); + } +} + +void gf_sink_put(struct gf_sink *sink) +{ + if (sink) + { + DRM_DEBUG_DRIVER("put sink: %p, ref: %d \n", sink, kref_read(&sink->refcount)); + kref_put(&sink->refcount, gf_sink_release); + } +} + +bool gf_sink_is_edid_valid(struct gf_sink *sink) +{ + unsigned char edid_header[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}; + + if (!sink) + { + return FALSE; + } + + if (gf_memcmp(sink->edid_data, edid_header, sizeof(edid_header))) + { + return FALSE; + } + + return TRUE; +} + +struct gf_sink* gf_sink_create(struct gf_sink_create_data *create_data) +{ + struct gf_sink *sink = gf_calloc(sizeof(*sink)); + + if (!sink) + { + goto alloc_fail; + } + + sink->output_type = create_data->output_type; + + kref_init(&sink->refcount); + + DRM_DEBUG_DRIVER("new sink created: %p\n", sink); + + return sink; + +alloc_fail: + return NULL; +} diff --git a/drivers/gpu/drm/arise/linux/gf_sink.h b/drivers/gpu/drm/arise/linux/gf_sink.h new file mode 100644 index 0000000000000..900f5007ea474 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_sink.h @@ -0,0 +1,38 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef _GF_SINK_H_ +#define _GF_SINK_H_ + +struct gf_sink_create_data +{ + int output_type; +}; + +struct gf_sink +{ + unsigned char edid_data[EDID_BUF_SIZE]; + int output_type; + struct kref refcount; +}; + +struct gf_sink* gf_sink_create(struct gf_sink_create_data *create_data); + +void gf_sink_get(struct gf_sink *sink); + +void gf_sink_put(struct gf_sink *sink); + +bool gf_sink_is_edid_valid(struct gf_sink *sink); + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_splice.c b/drivers/gpu/drm/arise/linux/gf_splice.c new file mode 100644 index 0000000000000..c75ab4594856e --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_splice.c @@ -0,0 +1,2540 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** +#include "gf.h" +#include "gf_disp.h" +#include "gf_cbios.h" +#include "gf_crtc.h" +#include "gf_kms.h" +#include "gf_drmfb.h" +#include "gf_fence.h" +#include "gf_irq.h" +#include "gf_trace.h" +#include "gf_splice.h" + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) +/* get_scanout_position() return flags */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) +#endif + +static void gf_splice_encoder_enable(struct drm_encoder *encoder); +static void gf_splice_encoder_disable(struct drm_encoder *encoder); + +static const int splice_plane_formats[] = { + DRM_FORMAT_C8, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_XRGB2101010, + DRM_FORMAT_XBGR2101010, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_ABGR2101010, + DRM_FORMAT_YUYV, + DRM_FORMAT_YVYU, + DRM_FORMAT_UYVY, + DRM_FORMAT_VYUY, + DRM_FORMAT_AYUV, +}; + +static const int splice_cursor_formats[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, +}; + +struct drm_crtc* gf_splice_get_crtc_by_source(struct drm_device *dev, gf_splice_source_t *source) +{ + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + pipe_t pipe = 0xFFFFFFFF; + disp_output_type output = source->output_type; + int crtc_mask = disp_cbios_get_crtc_mask(disp_info, output); + struct drm_crtc *crtc = NULL; + + list_for_each_entry(crtc, &(dev->mode_config.crtc_list), head) + { + pipe = drm_get_crtc_index(crtc); + if ((1 << pipe) & crtc_mask) + { + return crtc; + } + } + + return NULL; +} + + +gf_splice_source_t* gf_splice_get_source_by_connector(gf_splice_manager_t *splice_manager, struct drm_connector *connector) +{ + int i = 0; + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_t *source = &(splice_manager->sources[i]); + if (source->connector == connector) + { + return source; + } + } + + return NULL; +} + +bool is_connector_work_in_splice_mode(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + gf_splice_source_t *splice_source = gf_splice_get_source_by_connector(splice_manager, connector); + gf_splice_source_cfg_t *src_config = NULL; + + if (splice_source == NULL) + { + DRM_ERROR("can not find source of connector 0x%x", to_gf_connector(connector)->output_type); + + return FALSE; + } + + src_config = &(splice_source->config); + + if (splice_manager->splice_enable && src_config->enable) + { + return TRUE; + } + else + { + return FALSE; + } +} + +static enum drm_connector_status gf_splice_connector_detect(struct drm_connector *connector, bool force) +{ + //TOOD: iter the source connector list + struct drm_device *dev = connector->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + + if (splice_manager->splice_enable) + { + return connector_status_connected; + } + else + { + return connector_status_disconnected; + } +} + +bool is_splice_source_active_in_drm(struct drm_device *dev, gf_splice_source_t *source) +{ + struct drm_crtc *source_crtc = gf_splice_get_crtc_by_source(dev, source); + + if (to_gf_crtc(source_crtc)->enabled) + { + return TRUE; + } + + return FALSE; +} + +bool is_crtc_work_in_splice_mode(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + int i = 0; + bool ret = FALSE; + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_t *source = &(splice_manager->sources[i]); + gf_splice_source_cfg_t *src_config = &(source->config); + struct drm_crtc *source_crtc = NULL; + + if (!src_config->enable) + { + continue; + } + + source_crtc = gf_splice_get_crtc_by_source(dev, source); + if (source_crtc == crtc && splice_manager->splice_enable == 1) + { + ret = TRUE; + break; + } + } + + return ret; +} + +bool is_plane_work_in_splice_mode(struct drm_plane *plane) +{ + struct drm_device *dev = plane->dev; + struct drm_crtc *crtc = plane->state->crtc; + + if (!crtc) + { + return FALSE; + } + + return is_crtc_work_in_splice_mode(crtc); +} + +bool is_splice_target_active_in_drm(struct drm_device *dev) +{ + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + struct drm_crtc *target_crtc = splice_manager->target.crtc; + + if (to_gf_crtc(target_crtc)->enabled) + { + return TRUE; + } + + return FALSE; +} + +static int gf_splice_connector_dpms(struct drm_connector *connector, int mode) +{ + //TOOD: iter the source connector and do dpms + if (connector->encoder) + { + if (mode == DRM_MODE_DPMS_ON) + { + gf_splice_encoder_enable(connector->encoder); + } + else + { + gf_splice_encoder_disable(connector->encoder); + } + + connector->dpms = mode; + } + + return 0; +} + +static int gf_splice_connector_fill_modes(struct drm_connector *connector, + uint32_t maxX, uint32_t maxY) +{ + return 0; +} + +static void gf_splice_connector_destroy(struct drm_connector *connector) +{ + gf_connector_t *gf_connector = to_gf_connector(connector); + + drm_connector_unregister(connector); + drm_connector_cleanup(connector); + + gf_destroy_mutex(gf_connector->conn_mutex); + gf_free(gf_connector); +} + +struct drm_connector_state* gf_splice_connector_duplicate_state(struct drm_connector *connector) +{ + gf_connector_state_t* gf_conn_state; + + gf_conn_state = gf_calloc(sizeof(gf_connector_state_t)); + if (!gf_conn_state) + { + return NULL; + } + + __drm_atomic_helper_connector_duplicate_state(connector, &gf_conn_state->base_conn_state); + + gf_splice_duplicate_connector_state(&gf_conn_state->base_conn_state, connector->state); + + return &gf_conn_state->base_conn_state; +} + +static int gf_splice_connector_atomic_set_property(struct drm_connector *connector, + struct drm_connector_state *state, + struct drm_property *property, + uint64_t val) +{ + int ret = 0; + gf_connector_t* gf_conn = to_gf_connector(connector); + gf_connector_state_t* gf_conn_state = to_gf_conn_state(state); + + ret = gf_splice_set_connector_property(state, property, val); + if (ret) + { + DRM_WARN("Invalid driver-private property '%s'\n", property->name); + } + + return ret; +} + +static int gf_splice_connector_atomic_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) +{ + int ret = 0; + gf_connector_t* gf_conn = to_gf_connector(connector); + gf_connector_state_t* gf_conn_state = to_gf_conn_state(state); + + ret = gf_splice_get_connector_property(state, property, val); + if (ret) + { + DRM_WARN("Invalid driver-private property '%s'\n", property->name); + } + + return ret; +} + +void gf_splice_connector_destroy_state(struct drm_connector *connector, struct drm_connector_state *state) +{ + gf_connector_state_t *gf_conn_state = to_gf_conn_state(state); + __drm_atomic_helper_connector_destroy_state(state); + gf_free(gf_conn_state); +} + +static int gf_splice_connector_get_modes(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t* manager = disp_info->splice_manager; + gf_splice_target_cfg_t* target_config = &(manager->target.config); + + struct drm_display_mode *mode; + + //to get splice conector modes. + if (!manager->splice_enable) + { + return 0; + } + + mode = drm_cvt_mode(dev, target_config->mode_x, target_config->mode_y, target_config->mode_rate/100, false, false, false); + if (!mode) { + DRM_ERROR("Failed to create a new display mode\n"); + return 0; + } + + drm_mode_set_name(mode); + drm_mode_probed_add(connector, mode); + + return 1; +} + +static const struct drm_connector_funcs gf_splice_connector_funcs = { + .detect = gf_splice_connector_detect, + .dpms = gf_splice_connector_dpms, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = gf_splice_connector_destroy, + .atomic_destroy_state = gf_splice_connector_destroy_state, + .atomic_duplicate_state = gf_splice_connector_duplicate_state, + .atomic_set_property = gf_splice_connector_atomic_set_property, + .atomic_get_property = gf_splice_connector_atomic_get_property, +}; + +static const struct drm_connector_helper_funcs gf_splice_connector_helper_funcs = { + .get_modes = gf_splice_connector_get_modes, +}; + +struct drm_connector* gf_splice_connector_init(gf_splice_manager_t* splice_manager) +{ + disp_info_t *disp_info = (disp_info_t*) splice_manager->private; + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + struct drm_connector* connector = NULL; + gf_connector_t* gf_connector = NULL; + gf_connector_state_t* gf_conn_state = NULL; + + gf_connector = gf_calloc(sizeof(gf_connector_t)); + + gf_conn_state = gf_calloc(sizeof(gf_connector_state_t)); + if (!gf_conn_state) + { + if (gf_connector) + { + gf_free(gf_connector); + } + return NULL; + } + + gf_connector->base_connector.state = &gf_conn_state->base_conn_state; + gf_conn_state->base_conn_state.connector = &gf_connector->base_connector; + + connector = &gf_connector->base_connector; + + connector->stereo_allowed = FALSE; + connector->interlace_allowed = FALSE; + + gf_connector->conn_mutex = gf_create_mutex(); + gf_connector->output_type = DISP_OUTPUT_SPLICE; + + drm_connector_init(drm, connector, &gf_splice_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); + drm_connector_helper_add(connector, &gf_splice_connector_helper_funcs); + + connector->polled = DRM_CONNECTOR_POLL_HPD; + + gf_splice_attach_connector_property(connector); + + return connector; +} + +static void gf_splice_encoder_destroy(struct drm_encoder *encoder) +{ + gf_encoder_t *gf_encoder = to_gf_encoder(encoder); + + drm_encoder_cleanup(encoder); + + gf_free(gf_encoder); +} + +static void gf_splice_encoder_disable(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + gf_encoder_t *gf_encoder = to_gf_encoder(encoder); + int i = 0; + + if (gf_encoder->enc_dpms == GF_DPMS_OFF) + { + return; + } + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_t *source = &(splice_manager->sources[i]); + gf_splice_source_cfg_t *src_config = &(source->config); + gf_connector_t *gf_connector = NULL; + + if (!src_config->enable) + { + continue; + } + + gf_connector = to_gf_connector(source->connector); + if (is_splice_source_active_in_drm(dev, source) && splice_manager->splice_enable == 0) + { + continue; + } + disp_cbios_set_hdac_connect_status(disp_info, gf_connector->output_type, FALSE, FALSE); + + gf_usleep_range(1000, 1100); //delay 1 ms + + disp_cbios_set_dpms(disp_info, gf_connector->output_type, GF_DPMS_OFF); + } + + gf_encoder->enc_dpms = GF_DPMS_OFF; +} + +static void gf_splice_encoder_enable(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + gf_encoder_t *gf_encoder = to_gf_encoder(encoder); + int i = 0; + + if (gf_encoder->enc_dpms == GF_DPMS_ON) + { + return; + } + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_t *source = &(splice_manager->sources[i]); + gf_splice_source_cfg_t *src_config = &(source->config); + gf_connector_t *gf_connector = NULL; + + if (!src_config->enable) + { + continue; + } + + gf_connector = to_gf_connector(source->connector); + disp_cbios_set_dpms(disp_info, gf_connector->output_type, GF_DPMS_ON); + + if (gf_connector->support_audio) + { + disp_cbios_set_hdac_connect_status(disp_info, gf_connector->output_type, TRUE, TRUE); + } + } + + gf_encoder->enc_dpms = GF_DPMS_ON; +} + +static bool gf_splice_encoder_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + + //TODO: + + return TRUE; +} + +static void gf_splice_encoder_atomic_mode_set(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct drm_device *dev = encoder->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *manager = disp_info->splice_manager; + int flag = 0; + int i = 0; + + flag |= UPDATE_ENCODER_MODE_FLAG; + + for (i = 0; i < manager->source_num; i++) + { + gf_splice_source_t *source = &(manager->sources[i]); + gf_splice_source_cfg_t *src_config = &(source->config); + struct drm_crtc *splice_crtc = NULL; + + if (!src_config->enable) + { + continue; + } + + splice_crtc = gf_splice_get_crtc_by_source(dev, source); + + disp_cbios_set_mode(disp_info, drm_get_crtc_index(splice_crtc), &(source->config.drm_mode), &(source->config.hw_mode), flag); + } +} + + +static const struct drm_encoder_funcs gf_splice_encoder_funcs = +{ + .destroy = gf_splice_encoder_destroy, +}; + +static const struct drm_encoder_helper_funcs gf_splice_encoder_helper_funcs = +{ + .disable = gf_splice_encoder_disable, + .enable = gf_splice_encoder_enable, + .mode_fixup = gf_splice_encoder_mode_fixup, + .atomic_mode_set = gf_splice_encoder_atomic_mode_set, +}; + +struct drm_encoder* gf_splice_encoder_init(gf_splice_manager_t *splice_manager) +{ + disp_info_t *disp_info = (disp_info_t*) splice_manager->private; + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + struct drm_encoder* encoder = NULL; + gf_encoder_t* gf_encoder = NULL; + unsigned int target_crtc_index = splice_manager->target.crtc_index; + + gf_encoder = gf_calloc(sizeof(gf_encoder_t)); + + if (!gf_encoder) + { + return NULL; + } + + encoder = &gf_encoder->base_encoder; + encoder->possible_clones = 0; + encoder->possible_crtcs = 1 << target_crtc_index; + + drm_encoder_init(drm, encoder, &gf_splice_encoder_funcs, DRM_MODE_ENCODER_DAC, NULL); + drm_encoder_helper_add(encoder, &gf_splice_encoder_helper_funcs); + + gf_encoder->output_type = DISP_OUTPUT_SPLICE; + gf_encoder->enc_dpms = GF_DPMS_OFF; + + return encoder; +} + +static int gf_splice_update_plane(struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h, + struct drm_modeset_acquire_ctx *ctx) +{ + + struct drm_plane_state* plane_state = plane->state; + const struct drm_plane_helper_funcs *funcs; + + if (to_gf_plane(plane)->is_cursor == 0) + { + //TODO: iter the plane + return drm_atomic_helper_update_plane(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h, ctx); + } + + plane_state->crtc = crtc; + if(crtc->state) + { + crtc->state->plane_mask |= (1 << drm_plane_index(plane)); + } + drm_atomic_set_fb_for_plane(plane_state, fb); + plane_state->crtc_x = crtc_x; + plane_state->crtc_y = crtc_y; + plane_state->crtc_w = crtc_w; + plane_state->crtc_h = crtc_h; + plane_state->src_x = src_x; + plane_state->src_y = src_y; + plane_state->src_w = src_w; + plane_state->src_h = src_h; + to_gf_plane_state(plane_state)->legacy_cursor = 1; + + funcs = plane->helper_private; + if(funcs && funcs->atomic_check) + { + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + gf_assert(funcs->atomic_check(plane, NULL) == 0, GF_FUNC_NAME(__func__)); +#else + gf_assert(funcs->atomic_check(plane, plane_state) == 0, GF_FUNC_NAME(__func__)); +#endif + } + + if(funcs && funcs->atomic_update) + { + funcs->atomic_update(plane, NULL); + } + + plane->old_fb = plane->fb; + + return 0; + +} + +static int gf_splice_disable_plane(struct drm_plane *plane, struct drm_modeset_acquire_ctx *ctx) +{ + struct drm_plane_state* plane_state = plane->state; + const struct drm_plane_helper_funcs *funcs; + + if(to_gf_plane(plane)->is_cursor == 0) + { + return drm_atomic_helper_disable_plane(plane, ctx); + } + + if ((plane_state->crtc)&&(plane_state->crtc->state)) + { + plane_state->crtc->state->plane_mask &= ~(1 << drm_plane_index(plane)); + } + plane_state->crtc = NULL; + drm_atomic_set_fb_for_plane(plane_state, NULL); + plane_state->crtc_x = 0; + plane_state->crtc_y = 0; + plane_state->crtc_w = 0; + plane_state->crtc_h = 0; + plane_state->src_x = 0; + plane_state->src_y = 0; + plane_state->src_w = 0; + plane_state->src_h = 0; + to_gf_plane_state(plane_state)->legacy_cursor = 1; + + funcs = plane->helper_private; + if(funcs && funcs->atomic_check) + { +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + gf_assert(funcs->atomic_check(plane, NULL) == 0, GF_FUNC_NAME(__func__)); +#else + gf_assert(funcs->atomic_check(plane, plane_state) == 0, GF_FUNC_NAME(__func__)); +#endif + } + + if(funcs && funcs->atomic_disable) + { + funcs->atomic_disable(plane, NULL); + } + + plane->old_fb = plane->fb; + + return 0; +} + +static void gf_splice_plane_destroy(struct drm_plane *plane) +{ + drm_plane_cleanup(plane); + gf_free(to_gf_plane(plane)); +} + +static struct drm_plane_state* gf_splice_plane_duplicate_state(struct drm_plane *plane) +{ + struct drm_plane_state *state; + gf_plane_state_t *gf_pstate; + + gf_pstate = gf_calloc(sizeof(gf_plane_state_t)); + + if (!gf_pstate) + { + return NULL; + } + + state = &gf_pstate->base_pstate; + + __drm_atomic_helper_plane_duplicate_state(plane, state); + + if(plane->state) + { +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 20, 0) + gf_pstate->pixel_blend_mode = to_gf_plane_state(plane->state)->pixel_blend_mode; +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 18, 0) + gf_pstate->alpha = to_gf_plane_state(plane->state)->alpha; +#endif +#endif + gf_pstate->alpha_source = to_gf_plane_state(plane->state)->alpha_source; + } + + return state; +} + + +static void gf_splice_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) +{ + gf_plane_state_t* gf_pstate = to_gf_plane_state(state); + + __drm_atomic_helper_plane_destroy_state(state); + + gf_free(gf_pstate); +} + +static int gf_splice_plane_atomic_set_property(struct drm_plane *plane, + struct drm_plane_state *state, + struct drm_property *property, + uint64_t val) +{ + //TODO: set property + + return 0; +} + + +static int gf_splice_plane_atomic_get_property(struct drm_plane *plane, + const struct drm_plane_state *state, + struct drm_property *property, + uint64_t *val) +{ + + //TODO: get property + return 0; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) +static bool gf_splice_plane_format_mod_supported(struct drm_plane *plane, uint32_t format, + uint64_t modifier) +{ + + return TRUE; + +} +#endif + +static void drm_atomic_set_fence_for_plane_gf(struct drm_plane_state *plane_state, dma_fence_t *fence) +{ + if (plane_state->fence) { + dma_fence_put(fence); + + return; + } + + plane_state->fence = fence; +} + +static int gf_splice_prepare_plane_fb(struct drm_plane *plane, struct drm_plane_state *new_state) +{ + struct drm_framebuffer *fb = new_state->fb; + struct drm_gf_framebuffer *gfb = to_gfb(fb); + gf_card_t *gf = plane->dev->dev_private; + + if (!fb || !gfb->obj) + { + return 0; + } + + /* resident */ + gf_core_interface->prepare_and_mark_unpagable(gf->adapter, gfb->obj->core_handle, &gfb->obj->info); + + if (plane->state->fb != fb) + { + dma_fence_t *fence = gf_reservation_object_get_excl_rcu(gfb->obj->resv); + if (fence) + { + drm_atomic_set_fence_for_plane_gf(new_state, fence); + } + } + + return 0; +} + + +static void gf_splice_cleanup_plane_fb(struct drm_plane *plane, struct drm_plane_state *old_state) +{ + gf_card_t *gf = plane->dev->dev_private; + struct drm_framebuffer *fb = old_state->fb; + + if (fb && to_gfb(fb)->obj) + { + gf_core_interface->mark_pagable(gf->adapter, to_gfb(fb)->obj->core_handle); + } +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) +int gf_splice_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) +#else +int gf_splice_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *new_state) +#endif +{ + + return 0; +} + + +static void gf_splice_plane_atomic_update_internal(struct drm_plane *plane, struct drm_plane_state *new_state, struct drm_plane_state *old_state) +{ + //TODO + gf_card_t *gf_card = plane->dev->dev_private; + struct drm_device *drm_dev = gf_card->drm_dev; + gf_plane_state_t *gf_plane_state = to_gf_plane_state(plane->state); + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + int i = 0; + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_t *source = &(splice_manager->sources[i]); + gf_connector_state_t *gf_conn_state = NULL; + struct drm_crtc *splice_crtc = NULL; + gf_splice_source_cfg_t *src_config = &(source->config); + + if (!src_config->enable) + { + continue; + } + + if (is_splice_source_active_in_drm(drm_dev, source) && splice_manager->splice_enable == 0) + { + continue; + } + + splice_crtc = gf_splice_get_crtc_by_source(drm_dev, source); + + if (to_gf_plane(plane)->is_cursor) + { + gf_cursor_update_t arg = {0, }; + arg.crtc = drm_get_crtc_index(splice_crtc); + arg.vsync_on = gf_plane_state->legacy_cursor ? 0 : 1; + + if (new_state->crtc_x >= src_config->crtc_x && new_state->crtc_x <= (src_config->crtc_x + src_config->crtc_w) && + new_state->crtc_y >= src_config->crtc_y && new_state->crtc_y <= (src_config->crtc_y + src_config->crtc_h)) + { + if (plane->state->crtc && !gf_plane_state->disable) + { + arg.bo = new_state->fb ? to_gfb(new_state->fb)->obj : NULL; + arg.pos_x = new_state->crtc_x - src_config->crtc_x; + arg.pos_y = new_state->crtc_y - src_config->crtc_y; + arg.width = new_state->crtc_w; + arg.height = new_state->crtc_h; + } + + source->cursor_status |= GF_SPLICE_CURSOR_ACTIVE; + + disp_cbios_update_cursor(disp_info, &arg); + } + else if (source->cursor_status & GF_SPLICE_CURSOR_ACTIVE) + { + source->cursor_status &= ~GF_SPLICE_CURSOR_ACTIVE; + + disp_cbios_update_cursor(disp_info, &arg); + } + + } + else + { + gf_crtc_flip_t arg = {0}; + + arg.crtc = drm_get_crtc_index(splice_crtc); + arg.stream_type = to_gf_plane(plane)->plane_type; + + if (new_state->crtc && !gf_plane_state->disable) + { + arg.fb = new_state->fb; + arg.crtc_x = 0; + arg.crtc_y = 0; + arg.crtc_w = src_config->crtc_w; + arg.crtc_h = src_config->crtc_h; + arg.src_x = src_config->crtc_x; + arg.src_y = src_config->crtc_y; + arg.src_w = src_config->crtc_w; + arg.src_h = src_config->crtc_h; + + #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + #if DRM_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) + if(plane->state->crtc->state->async_flip) + #else + if(plane->state->crtc->state->pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) + #endif + { + /* + if (gf_plane_can_async_flip(new_state, old_state)) + { + arg.async_flip = 1; + } + else + { + gf_crtc_state_t* gf_cstate = to_gf_crtc_state(plane->state->crtc->state); + arg.async_flip = 0; + gf_cstate->keep_vsync = 1; + } + */ + + gf_crtc_state_t* gf_cstate = to_gf_crtc_state(plane->state->crtc->state); + + arg.async_flip = 0; + gf_cstate->keep_vsync = 1; + + } + #endif + + } + + disp_cbios_crtc_flip(disp_info, &arg); + } + } + +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) +void gf_splice_plane_atomic_update(struct drm_plane* plane, struct drm_atomic_state* state) +#else +void gf_splice_plane_atomic_update(struct drm_plane* plane, struct drm_plane_state* old_state) +#endif +{ + struct drm_plane_state *new_state = NULL; + gf_plane_t* gf_plane = to_gf_plane(plane); + gf_plane_state_t* gf_pstate = to_gf_plane_state(plane->state); +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_plane_state* old_state = NULL; +#endif + + DRM_DEBUG_KMS("Update plane=%d\n", plane->index); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + if (gf_plane->is_cursor || state == NULL) + { + new_state = plane->state; + } + else + { + new_state = drm_atomic_get_new_plane_state(state, plane); + old_state = drm_atomic_get_old_plane_state(state, plane); + } +#else + new_state = plane->state; +#endif + + gf_pstate->disable = 0; + + gf_splice_plane_atomic_update_internal(plane, new_state, old_state); +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) +static void gf_splice_plane_atomic_disable(struct drm_plane *plane, struct drm_atomic_state *state) +#else +static void gf_splice_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) +#endif +{ +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_plane_state *old_state = NULL; +#endif + struct drm_plane_state *new_state = NULL; + gf_plane_state_t* gf_pstate = to_gf_plane_state(plane->state); + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + gf_plane_t* gf_plane = to_gf_plane(plane); + + if (gf_plane->is_cursor || state == NULL) + { + new_state = plane->state; + } + else + { + new_state = drm_atomic_get_new_plane_state(state, plane); + old_state = drm_atomic_get_old_plane_state(state, plane); + } +#else + new_state = plane->state; +#endif + + DRM_DEBUG_KMS("Disable plane=%d\n", plane->index); + + gf_pstate->disable = 1; + + gf_splice_plane_atomic_update_internal(plane, new_state, old_state); +} + +static const struct drm_plane_funcs gf_splice_plane_funcs = { + .update_plane = gf_splice_update_plane, + .disable_plane = gf_splice_disable_plane, + .destroy = gf_splice_plane_destroy, + .atomic_duplicate_state = gf_splice_plane_duplicate_state, + .atomic_destroy_state = gf_splice_plane_destroy_state, + .atomic_set_property = gf_splice_plane_atomic_set_property, + .atomic_get_property = gf_splice_plane_atomic_get_property, +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 14, 0) + .format_mod_supported = gf_splice_plane_format_mod_supported, +#endif +}; + +static const struct drm_plane_helper_funcs gf_splice_plane_helper_funcs = { + .prepare_fb = gf_splice_prepare_plane_fb, + .cleanup_fb = gf_splice_cleanup_plane_fb, + .atomic_check = gf_splice_plane_atomic_check, + .atomic_update = gf_splice_plane_atomic_update, + .atomic_disable = gf_splice_plane_atomic_disable, +}; + +static gf_plane_t* gf_splice_plane_create(gf_splice_manager_t* splice_manager, int is_cursor) +{ + disp_info_t *disp_info = (disp_info_t*) splice_manager->private; + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + gf_plane_t *gf_plane = NULL; + gf_plane_state_t* gf_pstate = NULL; + const int* formats = 0; + char* name; + int fmt_count = 0; + int drm_ptype, ret = 0; + unsigned int target_crtc_index = splice_manager->target.crtc_index; + + gf_plane = gf_calloc(sizeof(gf_plane_t)); + if (!gf_plane) + { + DRM_ERROR("failed to alloc gf plane\n"); + goto fail; + } + + gf_plane->crtc_index = target_crtc_index; + + if (is_cursor) + { + gf_plane->plane_type = GF_SPLICE_CURSOR_PLANE; + gf_plane->is_cursor = 1; + gf_plane->can_window = 1; + } + else + { + gf_plane->plane_type = GF_SPLICE_PRIMARY_PLANE; + gf_plane->can_window = 0; + gf_plane->can_up_scale = 0; + gf_plane->can_down_scale = 0; + } + + gf_pstate = gf_calloc(sizeof(gf_plane_state_t)); + if (!gf_pstate) + { + DRM_ERROR("failed to alloc gf plane state\n"); + goto fail; + } + + gf_pstate->base_pstate.plane = &gf_plane->base_plane; + gf_plane->base_plane.state = &gf_pstate->base_pstate; + + if(is_cursor) + { + formats = splice_cursor_formats; + fmt_count = sizeof(splice_cursor_formats)/sizeof(splice_cursor_formats[0]); + name = "cursor"; + drm_ptype = DRM_PLANE_TYPE_CURSOR; + } + else + { + formats = splice_plane_formats; + fmt_count = sizeof(splice_plane_formats)/sizeof(splice_plane_formats[0]); + name = "PS"; + drm_ptype = DRM_PLANE_TYPE_PRIMARY; + } + + ret = drm_universal_plane_init(drm, &gf_plane->base_plane, + (1 << target_crtc_index), &gf_splice_plane_funcs, + formats, fmt_count, NULL, + drm_ptype, + "IGA%d-%s", (target_crtc_index + 1), name); + if (ret) + { + DRM_ERROR("failed to init drm plane\n"); + goto fail; + } + + drm_plane_helper_add(&gf_plane->base_plane, &gf_splice_plane_helper_funcs); + + disp_create_plane_property(drm, gf_plane); + + DRM_DEBUG_KMS("plane=%d,name=%s\n", gf_plane->base_plane.index, gf_plane->base_plane.name); + + return gf_plane; + +fail: + if (gf_plane) + { + gf_free(gf_plane); + gf_plane = NULL; + } + if (gf_pstate) + { + gf_free(gf_pstate); + gf_pstate = NULL; + } + + return NULL; +} + + +static int gf_splice_crtc_legacy_gamma_set(struct drm_crtc *crtc, + u16 *red, u16 *green, u16 *blue, + uint32_t size, + struct drm_modeset_acquire_ctx *ctx) + +{ + //TODO: handle gamma set + return 0; +} + +static void gf_splice_crtc_destroy(struct drm_crtc *crtc) +{ + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + + drm_crtc_cleanup(crtc); + + gf_free(gf_crtc); +} + + +static int gf_splice_crtc_set_config(struct drm_mode_set *set, struct drm_modeset_acquire_ctx *ctx) +{ + + //NOTE: set config + + return drm_atomic_helper_set_config(set, ctx); +} + +static int gf_splice_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t flags, + struct drm_modeset_acquire_ctx *ctx) +{ + //NOTE: page_flip + + return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx); +} + +static struct drm_crtc_state* gf_splice_crtc_duplicate_state(struct drm_crtc *crtc) +{ + gf_crtc_state_t* crtc_state, *cur_crtc_state; + + cur_crtc_state = to_gf_crtc_state(crtc->state); + + crtc_state = gf_calloc(sizeof(gf_crtc_state_t)); + if (!crtc_state) + { + return NULL; + } + + __drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base_cstate); + + return &crtc_state->base_cstate; +} + +static void gf_splice_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *s) +{ + gf_crtc_state_t* state = to_gf_crtc_state(s); + + __drm_atomic_helper_crtc_destroy_state(s); + gf_free(state); +} + + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) +u32 gf_splice_get_vblank_counter(struct drm_crtc *crtc) +#else +u32 gf_splice_get_vblank_counter(struct drm_device *dev, pipe_t pipe) +#endif +{ +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; +#endif + + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *manager = disp_info->splice_manager; + gf_splice_target_t *target = &manager->target; + gf_splice_source_t *source = &(manager->sources[target->config.vblank_source]); + struct drm_crtc *vbl_src_crtc = gf_splice_get_crtc_by_source(dev, source); + gf_get_counter_t gf_counter; + int vblank_cnt = 0; + int i = 0; + + pipe = drm_get_crtc_index(vbl_src_crtc); + + gf_memset(&gf_counter, 0, sizeof(gf_get_counter_t)); + gf_counter.crtc_index = pipe; + gf_counter.vblk = &vblank_cnt; + disp_cbios_get_counter(disp_info, &gf_counter); + + //return (u32)(vblank_cnt - source->last_vblank); + return (u32)vblank_cnt; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) +int gf_splice_enable_vblank(struct drm_crtc *crtc) +#else +int gf_splice_enable_vblank(struct drm_device *dev, pipe_t pipe) +#endif +{ + //TODO: splice +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; +#endif + + gf_card_t* gf_card = dev->dev_private; + disp_info_t* disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *manager = disp_info->splice_manager; + irq_chip_funcs_t* chip_func = (irq_chip_funcs_t*)disp_info->irq_chip_func; + int intrrpt = 0, intr_en = 0; + unsigned long flags = 0; + int i = 0; + + if(!chip_func || !chip_func->get_intr_enable_mask || !chip_func->set_intr_enable_mask) + { + return 0; + } + + for (i = 0; i < manager->source_num; i++) + { + gf_splice_source_t *source = &(manager->sources[i]); + gf_splice_source_cfg_t *src_config = &(source->config); + struct drm_crtc *splice_crtc = NULL; + + if (!src_config->enable) + { + continue; + } + + splice_crtc = gf_splice_get_crtc_by_source(dev, source); + pipe = drm_get_crtc_index(splice_crtc); + + if(pipe == IGA1) + { + intrrpt = INT_VSYNC1; + } + else if(pipe == IGA2) + { + intrrpt = INT_VSYNC2; + } + else if(pipe == IGA3) + { + intrrpt = INT_VSYNC3; + } + else if(pipe == IGA4) + { + intrrpt = INT_VSYNC4; + } + + flags = gf_spin_lock_irqsave(disp_info->intr_lock); + + if(disp_info->irq_enabled) + { + intr_en = chip_func->get_intr_enable_mask(disp_info); + intr_en |= intrrpt; + chip_func->set_intr_enable_mask(disp_info, intr_en); + } + else + { + disp_info->intr_en_bits |= intrrpt; + } + + gf_spin_unlock_irqrestore(disp_info->intr_lock, flags); + + trace_gfx_vblank_onoff(gf_card->index << 16 | pipe, 1); + + } + + return 0; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) +void gf_splice_disable_vblank(struct drm_crtc *crtc) +#else +void gf_splice_disable_vblank(struct drm_device *dev, pipe_t pipe) +#endif +{ + //TODO: splice +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; +#endif + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + irq_chip_funcs_t *chip_func = (irq_chip_funcs_t*)disp_info->irq_chip_func; + int intrrpt = 0, intr_en = 0; + unsigned long flags = 0; + int i = 0; + + if (!chip_func || !chip_func->get_intr_enable_mask || !chip_func->set_intr_enable_mask) + { + return; + } + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_t *source = &(splice_manager->sources[i]); + gf_splice_source_cfg_t *src_config = &(source->config); + struct drm_crtc *splice_crtc = NULL; + + if (!src_config->enable) + { + continue; + } + + if (is_splice_source_active_in_drm(dev, source) && splice_manager->splice_enable == 0) + { + continue; + } + + splice_crtc = gf_splice_get_crtc_by_source(dev, source); + pipe = drm_get_crtc_index(splice_crtc); + + if(pipe == IGA1) + { + intrrpt = INT_VSYNC1; + } + else if(pipe == IGA2) + { + intrrpt = INT_VSYNC2; + } + else if(pipe == IGA3) + { + intrrpt = INT_VSYNC3; + } + else if(pipe == IGA4) + { + intrrpt = INT_VSYNC4; + } + + flags = gf_spin_lock_irqsave(disp_info->intr_lock); + + if (disp_info->irq_enabled) + { + intr_en = chip_func->get_intr_enable_mask(disp_info); + intr_en &= ~intrrpt; + chip_func->set_intr_enable_mask(disp_info, intr_en); + } + else + { + disp_info->intr_en_bits &= ~intrrpt; + } + + gf_spin_unlock_irqrestore(disp_info->intr_lock, flags); + + trace_gfx_vblank_onoff(gf_card->index << 16 | pipe, 0); + } +} + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +int gf_splice_crtc_get_scanout_position(struct drm_device *dev, + int pipe, unsigned int flags, + int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime) +{ + //NOTE: not support 4.4 kernel + return 0; +} +#elif DRM_VERSION_CODE < KERNEL_VERSION(4, 13, 0) +int gf_splice_crtc_get_scanout_position(struct drm_device *dev, + int pipe, unsigned int flags, + int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime) +{ + //TODO: support 4.13 kernel + return 0; +} +#else +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) +bool gf_splice_crtc_get_scanout_position(struct drm_device *dev, + unsigned int pipe, bool in_vblank_irq, + int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +#else +bool gf_splice_crtc_get_scanout_position(struct drm_crtc *crtc, + bool in_vblank_irq, + int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +#endif +{ + //TODO: use vlank source as the vblank source right now +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; +#endif + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + gf_get_counter_t gf_counter; + gf_splice_target_t *target = &splice_manager->target; + gf_splice_source_t *source = &(splice_manager->sources[target->config.vblank_source]); + struct drm_crtc *splice_crtc = gf_splice_get_crtc_by_source(dev, source); + int in_vblank = 0, ret = 0, status = 0; + + pipe = drm_get_crtc_index(splice_crtc); + mode = &(source->config.hw_mode); + + gf_memset(&gf_counter, 0, sizeof(gf_get_counter_t)); + gf_counter.crtc_index = pipe; + gf_counter.hpos = hpos; + gf_counter.vpos = vpos; + gf_counter.in_vblk = &in_vblank; + + if (stime) + { + *stime = ktime_get(); + } + + status = disp_cbios_get_counter(disp_info, &gf_counter); + + if (etime) + { + *etime = ktime_get(); + } + + if (status == S_OK) + { + ret = DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; + if (in_vblank) + { + *vpos -= mode->crtc_vblank_end; + if(*hpos) + { + *hpos -= mode->crtc_htotal; + *vpos += 1; + } + ret |= DRM_SCANOUTPOS_IN_VBLANK; + } + } + + return ret; +} +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 13, 0) +int gf_splice_get_vblank_timestamp(struct drm_device *dev, + pipe_t pipe, + int *max_error, + struct timeval *time, + unsigned flags) +{ + //TODO: support 4.13 kernel + + + return 0; +} + +#else + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) +bool gf_splice_get_vblank_timestamp(struct drm_device *dev, + pipe_t pipe, + int *max_error, + #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) + ktime_t *vblank_time, + #else + struct timeval *vblank_time, + #endif + bool in_vblank_irq) +{ + +#else +bool gf_splice_get_vblank_timestamp(struct drm_crtc *crtc, + int *max_error, + ktime_t *vblank_time, + bool in_vblank_irq) +{ + struct drm_device *dev = crtc->dev; + unsigned int pipe = crtc->index; +#endif + + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *manager = disp_info->splice_manager; + gf_splice_target_t *target = &manager->target; + gf_splice_source_t *source = &(manager->sources[target->config.vblank_source]); + const struct drm_display_mode *mode; + int vpos, hpos, i; + ktime_t stime, etime; + int delta_ns, duration_ns; + bool vbl_status; + + mode = &(source->config.hw_mode); + + for (i = 0; i < GF_DRM_TIMESTAMP_MAXRETRIES; i++) { + /* + * Get vertical and horizontal scanout position vpos, hpos, + * and bounding timestamps stime, etime, pre/post query. + */ + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) + vbl_status = gf_splice_crtc_get_scanout_position(dev, pipe, in_vblank_irq, + &vpos, &hpos, + &stime, &etime, + mode); +#else + vbl_status = gf_splice_crtc_get_scanout_position(crtc, in_vblank_irq, + &vpos, &hpos, + &stime, &etime, + mode); +#endif + /* Return as no-op if scanout query unsupported or failed. */ + if (!vbl_status) { + DRM_DEBUG("crtc %u : scanoutpos query failed.\n", pipe); + return false; + } + + /* Compute uncertainty in timestamp of scanout position query. */ + duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime); + + /* Accept result with < max_error nsecs timing uncertainty. */ + if (duration_ns <= *max_error) + break; + } + + /* Noisy system timing? */ + if (i == GF_DRM_TIMESTAMP_MAXRETRIES) { + DRM_DEBUG("crtc %u: Noisy timestamp %d us > %d us [%d reps].\n", + pipe, duration_ns/1000, *max_error/1000, i); + } + + /* Return upper bound of timestamp precision error. */ + *max_error = duration_ns; + + + /* Convert scanout position into elapsed time at raw_time query + * since start of scanout at first display scanline. delta_ns + * can be negative if start of scanout hasn't happened yet. + */ + delta_ns = div_s64(1000000LL * (vpos * mode->crtc_htotal + hpos), + mode->crtc_clock); + + /* Subtract time delta from raw timestamp to get final + * vblank_time timestamp for end of vblank. + */ + *vblank_time = ktime_sub_ns(etime, delta_ns); + + return true; + +} +#endif + +static void gf_splice_crtc_helper_set_mode(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *manager = disp_info->splice_manager; + gf_splice_target_t *target = &manager->target; + gf_splice_source_t *vblank_source = &(manager->sources[target->config.vblank_source]); + struct drm_crtc *vblank_crtc = gf_splice_get_crtc_by_source(dev, vblank_source); + gf_get_counter_t gf_counter; + int vblank_cnt = 0; + int flag = 0; + int i = 0, j = 0; + + flag |= UPDATE_CRTC_MODE_FLAG; + + for (i = 0; i < manager->source_num; i++) + { + gf_splice_source_t *source = &(manager->sources[i]); + gf_splice_source_cfg_t *src_config = &(source->config); + unsigned int active[MAX_CORE_CRTCS] = {0}; + struct drm_crtc *splice_crtc = NULL; + unsigned int crtc_index = 0; + + if (!src_config->enable) + { + continue; + } + + splice_crtc = gf_splice_get_crtc_by_source(dev, source); + crtc_index = drm_get_crtc_index(splice_crtc); + + gf_memcpy(active, disp_info->active_output, sizeof(disp_info->active_output)); + active[crtc_index] = 0; + + for(j = 0; j < disp_info->num_crtc; j++) + { + active[j] &= ~source->output_type; + } + + active[crtc_index] |= source->output_type; + if (!disp_cbios_update_output_active(disp_info, active)) + { + gf_memcpy(disp_info->active_output, active, sizeof(disp_info->active_output)); + } + + disp_cbios_set_mode(disp_info, crtc_index, &(source->config.drm_mode), &(source->config.hw_mode), flag); + } + + gf_memset(&gf_counter, 0, sizeof(gf_get_counter_t)); + gf_counter.crtc_index = drm_get_crtc_index(vblank_crtc); + gf_counter.vblk = &vblank_cnt; + disp_cbios_get_counter(disp_info, &gf_counter); + + vblank_source->last_vblank = vblank_cnt; +} + +static void gf_splice_crtc_dpms_onoff_helper(struct drm_crtc *crtc, int dpms_on) +{ + struct drm_device *drm_dev = crtc->dev; + gf_card_t *gf_card = drm_dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + int status = dpms_on? 1 : 0; + int i = 0; + + if (gf_crtc->crtc_dpms == status) + { + return; + } + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_t *source = &(splice_manager->sources[i]); + gf_splice_source_cfg_t *src_config = &(source->config); + struct drm_crtc *source_crtc = NULL; + gf_crtc_t *gf_source_crtc = NULL; + + if (!src_config->enable) + { + continue; + } + + source_crtc = gf_splice_get_crtc_by_source(drm_dev, source); + gf_source_crtc = to_gf_crtc(source_crtc); + + if (is_splice_source_active_in_drm(drm_dev, source) && splice_manager->splice_enable == 0) + { + continue; + } + + disp_cbios_turn_onoff_screen(disp_info, gf_source_crtc->pipe, status); + } + + gf_crtc->crtc_dpms = status; +} + + +static void gf_splice_crtc_helper_disable(struct drm_crtc *crtc) +{ + + gf_splice_crtc_dpms_onoff_helper(crtc, 0); + drm_crtc_vblank_off(crtc); +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +static int gf_splice_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *atomic_state) +#else +static int gf_splice_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) +#endif +{ + //NOTE: splice crtc helper atomic_check + return 0; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +void gf_splice_crtc_helper_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state) +#else +void gf_splice_crtc_helper_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +#endif +{ + //NOTE: splice crtc helper atomic_begin + + return; +} + +static bool gf_splice_need_wait_vblank(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +{ + struct drm_plane *plane; + struct drm_plane_state *old_plane_state; + int i; + bool need_wait = false; + + if(crtc->state && drm_atomic_crtc_needs_modeset(crtc->state)) + { + need_wait = true; + goto End; + } + + if(!old_crtc_state || !old_crtc_state->state) + { + need_wait = true; + goto End; + } + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) + if(crtc->state && crtc->state->async_flip) +#else + if(crtc->state && (crtc->state->pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC)) +#endif + { + gf_crtc_state_t* gf_cstate = to_gf_crtc_state(crtc->state); + if(!gf_cstate->keep_vsync) + { + need_wait = false; + goto End; + } + } +#endif + + for(i = 0; i < crtc->dev->mode_config.num_total_plane; i++) + { + if(old_crtc_state->state->planes[i].ptr) + { + plane = old_crtc_state->state->planes[i].ptr; + old_plane_state = old_crtc_state->state->planes[i].state; + if(plane->state->crtc == crtc && crtc->state && (crtc->state->plane_mask & (1 << plane->index))) + { + if(plane->state->fb != old_plane_state->fb) + { + need_wait = true; + break; + } + } + } + } + +End: + if(need_wait) + { + if(drm_crtc_vblank_get(crtc) != 0) + { + need_wait = false; + } + } + + return need_wait; +} + + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +void gf_splice_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) +#else +void gf_splice_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +#endif +{ + //TODO: splice crtc helper atomic_flush + struct drm_pending_vblank_event *event = crtc->state->event; +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,crtc); +#endif + DRM_DEBUG_KMS("crtc=%d\n", crtc->index); + //do some flush work on spcified crtc after planes update finished. + //install vblank event(flip complete) to queue, then it will be signaled at vblank interrupt + if (event) + { + crtc->state->event = NULL; + + spin_lock_irq(&crtc->dev->event_lock); + if (gf_splice_need_wait_vblank(crtc, old_crtc_state)) + { + // should hold a reference for arm_vblank + drm_crtc_arm_vblank_event(crtc, event); + } + else + { + drm_crtc_send_vblank_event(crtc, event); + } + spin_unlock_irq(&crtc->dev->event_lock); + } +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +void gf_splice_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state) +#else +void gf_splice_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +#endif +{ + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + + //NOTE: splice crtc helper atomic_enable + gf_info("CRTC atomic enable: to turn on vblank and screen of crtc: %d\n", crtc->index); + + drm_crtc_vblank_on(crtc); + + gf_splice_crtc_dpms_onoff_helper(crtc, 1); + + gf_crtc->enabled = 1; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +void gf_splice_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state) +#else +void gf_splice_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +#endif +{ + //NOTE: splice crtc helper atomic_disable + gf_crtc_t *gf_crtc = to_gf_crtc(crtc); + u64 old_cnt; +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); +#endif + + gf_info("CRTC atomic disable: to turn off vblank and screen of crtc: %d\n", crtc->index); + + //disable all planes on this crtc without flush event +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); +#else + drm_atomic_helper_disable_planes_on_crtc(crtc, false); +#endif + + if(0 == drm_crtc_vblank_get(crtc)) + { + old_cnt = drm_crtc_vblank_count(crtc); + + if(0 == wait_event_timeout(crtc->dev->vblank[crtc->index].queue, + old_cnt != drm_crtc_vblank_count(crtc), + msecs_to_jiffies(40))) + { + gf_info("Wait vblank queue timeout after disable planes of crtc %d\n", crtc->index); + } + + drm_crtc_vblank_put(crtc); + } + + gf_splice_crtc_dpms_onoff_helper(crtc, 0); + + drm_crtc_vblank_off(crtc); + + gf_crtc->enabled = 0; +} + +static const struct drm_crtc_funcs gf_splice_crtc_funcs = { +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 12, 0) + .gamma_set = gf_splice_crtc_legacy_gamma_set, +#endif + .destroy = gf_splice_crtc_destroy, + .set_config = gf_splice_crtc_set_config, + .page_flip = gf_splice_crtc_page_flip, + .atomic_duplicate_state = gf_splice_crtc_duplicate_state, + .atomic_destroy_state = gf_splice_crtc_destroy_state, +#if DRM_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) + .get_vblank_counter = gf_splice_get_vblank_counter, + .enable_vblank = gf_splice_enable_vblank, + .disable_vblank = gf_splice_disable_vblank, + .get_vblank_timestamp = gf_splice_get_vblank_timestamp, +#endif +}; + +static const struct drm_crtc_helper_funcs gf_splice_crtc_helper_funcs = { + .mode_set_nofb = gf_splice_crtc_helper_set_mode, + .disable = gf_splice_crtc_helper_disable, + .atomic_check = gf_splice_crtc_helper_atomic_check, + .atomic_begin = gf_splice_crtc_helper_atomic_begin, + .atomic_flush = gf_splice_crtc_helper_atomic_flush, + .atomic_enable = gf_splice_crtc_helper_atomic_enable, + .atomic_disable = gf_splice_crtc_helper_atomic_disable, +#if DRM_VERISON_CODE >= KERNEL_VERSION(5, 7, 0) + .get_scanout_position = gf_splice_crtc_get_scanout_position, +#endif +}; + +static void gf_splice_attach_state_info_property(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + gf_connector_t* gf_conn = to_gf_connector(connector); + gf_connector_state_t* gf_state = to_gf_conn_state(connector->state); + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + + if (gf_conn->output_type == DISP_OUTPUT_SPLICE) + { + return; + } + + drm_object_attach_property(&connector->base, disp_info->splice_active_prop, 0); + gf_state->splice_active = 0; +} + +static void gf_splice_attach_mode_info_property(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + gf_connector_state_t* gf_state = to_gf_conn_state(connector->state); + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + + drm_object_attach_property(&connector->base, disp_info->mode_x_prop, 0); + gf_state->splice_mode_x = 0; + + drm_object_attach_property(&connector->base, disp_info->mode_y_prop, 0); + gf_state->splice_mode_y = 0; + + drm_object_attach_property(&connector->base, disp_info->mode_rate_prop, 0); + gf_state->splice_mode_rate = 0; +} + +static void gf_splice_attach_size_info_property(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + gf_connector_t* gf_conn = to_gf_connector(connector); + gf_connector_state_t* gf_state = to_gf_conn_state(connector->state); + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + + if (gf_conn->output_type == DISP_OUTPUT_SPLICE) + { + return; + } + + drm_object_attach_property(&connector->base, disp_info->crtc_x_prop, 0); + gf_state->splice_crtc_x = 0; + + drm_object_attach_property(&connector->base, disp_info->crtc_y_prop, 0); + gf_state->splice_crtc_y = 0; + + drm_object_attach_property(&connector->base, disp_info->crtc_w_prop, 0); + gf_state->splice_crtc_w = 0; + + drm_object_attach_property(&connector->base, disp_info->crtc_h_prop, 0); + gf_state->splice_crtc_h = 0; +} + +static void gf_splice_attach_trigger_property(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + gf_connector_t* gf_conn = to_gf_connector(connector); + gf_connector_state_t* gf_state = to_gf_conn_state(connector->state); + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + + if(gf_conn->output_type != DISP_OUTPUT_SPLICE) + { + return; + } + + drm_object_attach_property(&connector->base, disp_info->splice_trigger_prop, 0); + gf_state->splice_trigger = 0; +} + +void gf_splice_attach_connector_property(struct drm_connector *connector) +{ + gf_splice_attach_state_info_property(connector); + gf_splice_attach_mode_info_property(connector); + gf_splice_attach_size_info_property(connector); + + gf_splice_attach_trigger_property(connector); +} + +static int gf_splice_init_sources(gf_splice_manager_t *splice_manager) +{ + disp_info_t *disp_info = (disp_info_t*) splice_manager->private; + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm_dev = gf_card->drm_dev; + struct drm_connector* connector = NULL; + gf_splice_source_t *sources = NULL; + int i = 0; + + sources = gf_calloc(sizeof(gf_splice_source_t) * disp_info->num_output); + if (!sources) + { + DRM_ERROR("allocate splice sources failed\n"); + return -ENOMEM; + } + + list_for_each_entry(connector, &drm_dev->mode_config.connector_list, head) + { + gf_connector_t* gf_connector = to_gf_connector(connector) ; + + sources[i].connector = connector; + sources[i].output_type = gf_connector->output_type; + i++; + } + + splice_manager->sources = sources; + splice_manager->source_num = disp_info->num_output; + + return 0; +} + +static void gf_splice_init_encoders_and_connectors(gf_splice_manager_t *splice_manager) +{ + struct drm_connector *connector = NULL; + struct drm_encoder* encoder = NULL; + + connector = gf_splice_connector_init(splice_manager); + + encoder = gf_splice_encoder_init(splice_manager); + + drm_connector_attach_encoder(connector, encoder); + + splice_manager->target.connector = connector; +} + +static void gf_splice_init_crtc_and_planes(gf_splice_manager_t *splice_manager) +{ + disp_info_t *disp_info = (disp_info_t*) splice_manager->private; + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* drm = gf_card->drm_dev; + gf_plane_t* gf_plane = NULL; + gf_plane_t* gf_cursor = NULL; + gf_crtc_t* gf_crtc = NULL; + gf_crtc_state_t* crtc_state = NULL; + gf_splice_target_t *target = &(splice_manager->target); + int ret = 0; + + gf_plane = gf_splice_plane_create(splice_manager, 0); + + gf_cursor = gf_splice_plane_create(splice_manager, 1); + + gf_crtc = gf_calloc(sizeof(gf_crtc_t)); + if (!gf_crtc) + { + gf_error("failed to alloc gf crtc\n"); + goto failed; + } + + crtc_state = gf_calloc(sizeof(gf_crtc_state_t)); + if (!crtc_state) + { + gf_error("failed to alloc gf crtc state\n"); + goto failed; + } + + gf_crtc->base_crtc.state = &crtc_state->base_cstate; + crtc_state->base_cstate.crtc = &gf_crtc->base_crtc; + + gf_crtc->pipe = target->crtc_index; + gf_crtc->crtc_dpms = 0; + gf_crtc->support_scale = disp_info->scale_support; + gf_crtc->plane_cnt = GF_SPLICE_PLANE_NUM; + + ret = drm_crtc_init_with_planes(drm, &gf_crtc->base_crtc, + &gf_plane->base_plane, + &gf_cursor->base_plane, + &gf_splice_crtc_funcs, "IGA%d", (gf_crtc->pipe + 1)); + if (ret) + { + DRM_ERROR("failed to init crtc\n"); + goto failed; + } + + drm_crtc_helper_add(&gf_crtc->base_crtc, &gf_splice_crtc_helper_funcs); + + drm_mode_crtc_set_gamma_size(&gf_crtc->base_crtc, 256); + + drm_crtc_enable_color_mgmt(&gf_crtc->base_crtc, 0, 1, 256); + + splice_manager->target.crtc = &gf_crtc->base_crtc; + + return; +failed: + if (crtc_state) + { + gf_free(crtc_state); + crtc_state = NULL; + } + + if (gf_crtc) + { + gf_free(gf_crtc); + gf_crtc = NULL; + } +} + +int gf_splice_find_source_hw_mode(gf_splice_manager_t *splice_manager, + gf_splice_source_t *source) +{ + disp_info_t *disp_info = (disp_info_t*)splice_manager->private; + struct drm_display_mode *hw_mode = &(source->config.hw_mode); + struct drm_display_mode *mode = &(source->config.drm_mode); + int output = source->output_type; + int ret = -1; + + drm_mode_copy(hw_mode, mode); + if(gf_encoder_mode_fixup_internal(disp_info, output, (const struct drm_display_mode*)mode, hw_mode)) + { + ret = 0; + } + + return ret; +} + +int gf_splice_validate_source_params(gf_splice_manager_t *splice_manager) +{ + disp_info_t *disp_info = (disp_info_t*)splice_manager->private; + gf_splice_source_t *sources = splice_manager->sources; + CBiosModeInfoExt *pcbios_mode = NULL; + void* pmode_list = NULL; + struct drm_connector *connector = NULL; + gf_connector_t *gf_conn = NULL; + gf_connector_state_t *gf_conn_state = NULL; + gf_splice_source_cfg_t *src_config = NULL; + int i = 0, j = 0, ret = 0, mode_num = 0; + int active_src_num = 0; + int trigger_ids = splice_manager->trigger_value; + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_cfg_t *src_config = NULL; + connector = sources[i].connector; + gf_conn = to_gf_connector(connector); + + src_config = &(sources[i].config); + + gf_memcpy(&(sources[i].restored_config), &(sources[i].config), sizeof(gf_splice_source_cfg_t)); + sources[i].has_restored = TRUE; + + if ((trigger_ids & gf_conn->output_id) == 0) + { + src_config->enable = FALSE; + continue; + } + trigger_ids &= ~gf_conn->output_id; + + gf_conn_state = to_gf_conn_state(connector->state); + + src_config->enable = TRUE; + + active_src_num++; + + if (connector->status != connector_status_connected) + { + DRM_ERROR("source: 0x%x splice connector is not connected!\n", gf_conn->output_type); + ret = -2; + goto END; + } + + if (!gf_conn_state->splice_mode_x || !gf_conn_state->splice_mode_y || !gf_conn_state->splice_mode_rate) + { + DRM_ERROR("source: 0x%x Invalid splice mode para!\n", gf_conn->output_type); + ret = -3; + goto END; + } + + src_config->crtc_x = gf_conn_state->splice_crtc_x; + src_config->crtc_y = gf_conn_state->splice_crtc_y; + src_config->crtc_w = gf_conn_state->splice_crtc_w; + src_config->crtc_h = gf_conn_state->splice_crtc_h; + + gf_info("## User set splice mode for device 0x%x, mode %dx%d@%d.\n", gf_conn->output_type, + gf_conn_state->splice_mode_x, gf_conn_state->splice_mode_y, gf_conn_state->splice_mode_rate); + + pmode_list = disp_cbios_get_device_modelist(disp_info, gf_conn->output_type, &mode_num); + if (!pmode_list || !mode_num) + { + DRM_ERROR("source: 0x%x get modelist failed\n", gf_conn->output_type); + ret = -4; + goto END; + } + + for (j = 0; j < mode_num; j++) + { + pcbios_mode = (CBiosModeInfoExt*)pmode_list + j; + if (pcbios_mode->XRes == gf_conn_state->splice_mode_x + && pcbios_mode->YRes == gf_conn_state->splice_mode_y) + { + ret = disp_cbios_cbmode_to_drmmode(disp_info, gf_conn->output_type, pcbios_mode, 0, &(src_config->drm_mode)); + if (!ret) + { + int temp = src_config->drm_mode.clock * 1000/src_config->drm_mode.htotal; + if (gf_conn_state->splice_mode_rate == temp * 100/src_config->drm_mode.vtotal) + { + break; + } + } + } + } + + if(j == mode_num) + { + DRM_ERROR("source: 0x%x find user set splice mode:%dx%d@%d failed\n", gf_conn->output_type, + gf_conn_state->splice_mode_x, gf_conn_state->splice_mode_y, gf_conn_state->splice_mode_rate); + ret = -5; + goto END; + } + + ret = gf_splice_find_source_hw_mode(splice_manager, &sources[i]); + if (ret) + { + DRM_ERROR("source: 0x%x find hw splice mode error\n", sources[i].output_type); + ret = -6; + goto END; + } + + if(pmode_list) + { + gf_free(pmode_list); + pmode_list = NULL; + } + } + + if (!active_src_num) + { + DRM_ERROR("Non active splice source exists\n"); + ret = -7; + goto END; + } + + if(trigger_ids) + { + DRM_ERROR("Invalid trigger value 0x%x\n", splice_manager->trigger_value); + ret = -8; + goto END; + } + +END: + if (pmode_list) + { + gf_free(pmode_list); + pmode_list = NULL; + } + + return ret; +} + +int gf_splice_validate_target_params(gf_splice_manager_t *splice_manager) +{ + gf_splice_source_t *sources = splice_manager->sources; + gf_splice_target_t *target = &splice_manager->target; + struct drm_connector *connector = NULL; + gf_connector_state_t *gf_conn_state = NULL; + gf_splice_source_cfg_t *src_config = NULL; + int min_refresh = 0xFFFF, vbl_source_index = 0; + unsigned int tmp_target_x = 0, tmp_target_y = 0, tmp_target_refresh = 0; + int i = 0; + + connector = target->connector; + gf_conn_state = to_gf_conn_state(connector->state); + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_cfg_t *src_config = &(sources[i].config); + + if (!src_config->enable) + { + continue; + } + + if ((gf_conn_state->splice_mode_x % src_config->drm_mode.hdisplay) != 0 || + (gf_conn_state->splice_mode_y % src_config->drm_mode.vdisplay) != 0) + { + DRM_ERROR("splice target mode error\n"); + return -1; + } + break; + } + + tmp_target_x = gf_conn_state->splice_mode_x; + tmp_target_y = gf_conn_state->splice_mode_y; + tmp_target_refresh = gf_conn_state->splice_mode_rate; + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_cfg_t *src_config = &(sources[i].config); + + if (!src_config->enable) + { + continue; + } + + connector = sources[i].connector; + gf_conn_state = to_gf_conn_state(connector->state); + + if ((src_config->crtc_x + src_config->crtc_w) > tmp_target_x || + (src_config->crtc_y + src_config->crtc_h) > tmp_target_y) + { + DRM_ERROR("splice source size exceeds target mode\n"); + return -2; + } + + if (min_refresh > gf_conn_state->splice_mode_rate) + { + min_refresh = gf_conn_state->splice_mode_rate; + vbl_source_index = i; + } + } + + target->config.vblank_source = vbl_source_index; + + target->config.mode_x = tmp_target_x; + target->config.mode_y = tmp_target_y; + target->config.mode_rate = tmp_target_refresh; + + return 0; +} + +void gf_splice_reset_state(gf_splice_manager_t *splice_manager, bool need_restore) +{ + gf_connector_t *gf_connector= NULL; + struct drm_connector *connector = NULL; + gf_connector_state_t *gf_conn_state = NULL; + int i = 0; + + if (!splice_manager) + { + return; + } + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_t *source = &(splice_manager->sources[i]); + + if (source->has_restored && need_restore) + { + gf_memcpy(&(source->config), &(source->restored_config), sizeof(gf_splice_source_cfg_t)); + + source->has_restored = FALSE; + } + + connector = source->connector; + gf_conn_state = to_gf_conn_state(connector->state); + //connector->status = connector_status_connected; + + gf_conn_state->splice_active = 0; + gf_conn_state->splice_mode_x = 0; + gf_conn_state->splice_mode_y = 0; + gf_conn_state->splice_mode_rate= 0; + gf_conn_state->splice_crtc_x = 0; + gf_conn_state->splice_crtc_y= 0; + gf_conn_state->splice_crtc_w = 0; + gf_conn_state->splice_crtc_h = 0; + } + + connector = splice_manager->target.connector; + gf_conn_state = to_gf_conn_state(connector->state); + connector->status = connector_status_disconnected; + gf_conn_state->splice_mode_x = 0; + gf_conn_state->splice_mode_y = 0; + gf_conn_state->splice_mode_rate = 0; + gf_conn_state->splice_trigger = 0; +} + +int gf_splice_handle_source_status(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_connector_t *gf_connector = to_gf_connector(connector); + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + int changed = 0; + + if (connector->polled == DRM_CONNECTOR_POLL_HPD) + { + gf_connector_detect_internal(connector, 0, 1); + } + else + { + gf_connector_detect_internal(connector, 0, 0); + } + + if (gf_connector->source_status == connector_status_disconnected) + { + gf_info("source 0x%x plug out, exit splice mode\n", gf_connector->output_type); + splice_manager->splice_enable = 0; + gf_splice_reset_state(splice_manager, FALSE); + changed = 1; + } + + return changed; +} + +void gf_splice_manager_handle_hpd(struct work_struct* work) +{ + gf_splice_manager_t *splice_manager = container_of(work, gf_splice_manager_t, splice_trigger_work); + disp_info_t *disp_info = (disp_info_t *)splice_manager->private; + gf_card_t *gf_card = (gf_card_t *)disp_info->gf_card; + struct drm_device *dev = gf_card->drm_dev; + struct drm_mode_config *mode_config = &dev->mode_config; + gf_connector_t *gf_connector= NULL; + struct drm_connector *connector = NULL; + struct drm_crtc *target_crtc = splice_manager->target.crtc; + int i = 0, ret = 0; + + if (splice_manager->trigger_value == 0 && splice_manager->splice_enable == 1) + { + mutex_lock(&mode_config->mutex); + + splice_manager->splice_enable = 0; + + gf_splice_reset_state(splice_manager, FALSE); + + mutex_unlock(&mode_config->mutex); + + drm_kms_helper_hotplug_event(dev); + + gf_info("splice mode exit\n"); + } + else if (splice_manager->trigger_value && splice_manager->splice_enable == 0) + { + mutex_lock(&mode_config->mutex); + + ret = gf_splice_validate_source_params(splice_manager); + if (ret) + { + gf_splice_reset_state(splice_manager, TRUE); + mutex_unlock(&mode_config->mutex); + return; + } + + ret = gf_splice_validate_target_params(splice_manager); + if (ret) + { + gf_splice_reset_state(splice_manager, TRUE); + mutex_unlock(&mode_config->mutex); + return; + } + + for (i = 0; i < splice_manager->source_num; i++) + { + gf_splice_source_t *source = &(splice_manager->sources[i]); + gf_splice_source_cfg_t *src_config = &(source->config); + connector = source->connector; + if (src_config->enable) + { + connector->status = connector_status_disconnected; + } + } + + splice_manager->target.connector->status = connector_status_connected; + splice_manager->splice_enable = 1; + + mutex_unlock(&mode_config->mutex); + + drm_kms_helper_hotplug_event(dev); + + gf_info("splice mode enter\n"); + } +} + + +int gf_splice_manager_init(disp_info_t *disp_info, unsigned int crtc_index) +{ + gf_splice_manager_t *splice_manager = NULL; + int ret = 0; + + splice_manager = gf_calloc(sizeof(gf_splice_manager_t)); + if (!splice_manager) + { + DRM_ERROR("splice manager allocate fail\n"); + return -ENOMEM; + } + + splice_manager->splice_enable = 0; + + disp_info->splice_manager = splice_manager; + splice_manager->private = disp_info; + + splice_manager->trigger_value = 0; + INIT_WORK(&splice_manager->splice_trigger_work, gf_splice_manager_handle_hpd); + + ret = gf_splice_init_sources(splice_manager); + if (ret) + { + goto alloc_fail; + } + + splice_manager->target.crtc_index = crtc_index; + gf_splice_init_crtc_and_planes(splice_manager); + + gf_splice_init_encoders_and_connectors(splice_manager); + + return 0; + +alloc_fail: + gf_free(splice_manager->sources); + splice_manager->sources = NULL; + + gf_free(splice_manager); + disp_info->splice_manager = NULL; + + return ret; +} + +void gf_splice_manager_deinit(disp_info_t *disp_info) +{ + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + + if (!splice_manager) + { + return; + } + + if (splice_manager->sources) + { + gf_free(splice_manager->sources); + } + splice_manager->sources = NULL; + + gf_free(splice_manager); + disp_info->splice_manager = NULL; +} + +void gf_atomic_commit_connector_prop(struct drm_device *dev, struct drm_atomic_state *old_state) +{ + struct drm_connector *connector = NULL; + struct drm_connector_state *old_conn_state, *new_conn_state; + unsigned int old_trg, new_trg; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + int i = 0; + + for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) + { + old_trg = to_gf_conn_state(old_conn_state)->splice_trigger; + new_trg = to_gf_conn_state(new_conn_state)->splice_trigger; + + if(to_gf_connector(connector)->output_type == DISP_OUTPUT_SPLICE + && old_trg != new_trg && disp_info->splice_manager) + { + if(new_trg == 0) + { + gf_info("To trigger splice disable\n"); + disp_info->splice_manager->trigger_value = 0; + schedule_work(&disp_info->splice_manager->splice_trigger_work); + } + else if((new_trg & disp_info->output_id_masks) == new_trg && (new_trg & (new_trg-1)) != 0) + { + gf_info("To trigger splice enable, value = 0x%x\n", new_trg); + disp_info->splice_manager->trigger_value = new_trg; + schedule_work(&disp_info->splice_manager->splice_trigger_work); + } + else + { + //not store invalid value + to_gf_conn_state(new_conn_state)->splice_trigger = old_trg; + } + } + } +} + +#endif + + diff --git a/drivers/gpu/drm/arise/linux/gf_splice.h b/drivers/gpu/drm/arise/linux/gf_splice.h new file mode 100644 index 0000000000000..d9a7d678f2b0e --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_splice.h @@ -0,0 +1,396 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** +#ifndef __GF_SPLICE_H__ +#define __GF_SPLICE_H__ + +#include "gf_disp.h" +#include "gf_cbios.h" +#include "gf_crtc.h" + +#define GF_SPLICE_CURSOR_PLANE 4 + +#define GF_SPLICE_PRIMARY_PLANE 0 + +#define GF_SPLICE_PLANE_NUM 1 + +#define GF_DRM_TIMESTAMP_MAXRETRIES 3 + +#define GF_SPLICE_CURSOR_ACTIVE 1 + +typedef struct gf_splice_source_cfg +{ + bool enable; + unsigned int crtc_x; + unsigned int crtc_y; + unsigned int crtc_w; + unsigned int crtc_h; + struct drm_display_mode drm_mode; + struct drm_display_mode hw_mode; +}gf_splice_source_cfg_t; + +typedef struct gf_splice_source +{ + unsigned int output_type; + unsigned int cursor_status; + struct drm_connector *connector; + gf_splice_source_cfg_t config; + gf_splice_source_cfg_t restored_config; + bool has_restored; + unsigned int last_vblank; +}gf_splice_source_t; + +typedef struct gf_splice_target_cfg +{ + unsigned int mode_x; + unsigned int mode_y; + unsigned int mode_rate; + unsigned int vblank_source; +}gf_splice_target_cfg_t; + +typedef struct gf_splice_target +{ + struct drm_connector *connector; + struct drm_crtc *crtc; + unsigned int crtc_index; + gf_splice_target_cfg_t config; +}gf_splice_target_t; + +typedef struct gf_splice_manager +{ + gf_splice_source_t *sources; + unsigned int source_num; + + gf_splice_target_t target; + + int splice_enable; + void *private; + + int trigger_value; + struct work_struct splice_trigger_work; +}gf_splice_manager_t; + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) + +static inline void gf_splice_duplicate_connector_state(struct drm_connector_state *new_state, struct drm_connector_state *old_state) +{ + gf_connector_state_t *gf_new_state = to_gf_conn_state(new_state); + gf_connector_state_t *gf_old_state = to_gf_conn_state(old_state); + + gf_new_state->splice_active = gf_old_state->splice_active; + gf_new_state->splice_mode_x = gf_old_state->splice_mode_x; + gf_new_state->splice_mode_y = gf_old_state->splice_mode_y; + gf_new_state->splice_mode_rate = gf_old_state->splice_mode_rate; + gf_new_state->splice_crtc_x = gf_old_state->splice_crtc_x; + gf_new_state->splice_crtc_y = gf_old_state->splice_crtc_y; + gf_new_state->splice_crtc_w = gf_old_state->splice_crtc_w; + gf_new_state->splice_crtc_h = gf_old_state->splice_crtc_h; + gf_new_state->splice_trigger = gf_old_state->splice_trigger; +} + +static inline int gf_splice_set_connector_property(struct drm_connector_state *state, + struct drm_property *property, + uint64_t val) +{ + gf_connector_state_t* gf_state = to_gf_conn_state(state); + struct drm_device *dev = state->connector->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + int ret = 0; + + if (property == disp_info->splice_active_prop && to_gf_connector(state->connector)->output_type != DISP_OUTPUT_SPLICE) + { + gf_state->splice_active = val; + } + else if (property == disp_info->mode_x_prop) + { + gf_state->splice_mode_x = val; + } + else if (property == disp_info->mode_y_prop) + { + gf_state->splice_mode_y = val; + } + else if (property == disp_info->mode_rate_prop) + { + gf_state->splice_mode_rate = val; + } + else if (property == disp_info->crtc_x_prop) + { + gf_state->splice_crtc_x = val; + } + else if (property == disp_info->crtc_y_prop) + { + gf_state->splice_crtc_y = val; + } + else if (property == disp_info->crtc_h_prop) + { + gf_state->splice_crtc_h = val; + } + else if (property == disp_info->crtc_w_prop) + { + gf_state->splice_crtc_w = val; + } + else if(property == disp_info->splice_trigger_prop && to_gf_connector(state->connector)->output_type == DISP_OUTPUT_SPLICE) + { + gf_state->splice_trigger = val; + } + else + { + ret = -EINVAL; + } + + return ret; +} + +static inline int gf_splice_get_connector_property(const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) +{ + gf_connector_state_t* gf_state = to_gf_conn_state(state); + struct drm_device *dev = state->connector->dev; + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + int ret = 0; + + if (property == disp_info->splice_active_prop) + { + *val = gf_state->splice_active; + } + else if (property == disp_info->mode_x_prop) + { + *val = gf_state->splice_mode_x; + } + else if (property == disp_info->mode_y_prop) + { + *val = gf_state->splice_mode_y; + } + else if (property == disp_info->mode_rate_prop) + { + *val = gf_state->splice_mode_rate; + } + else if (property == disp_info->crtc_x_prop) + { + *val = gf_state->splice_crtc_x; + } + else if (property == disp_info->crtc_y_prop) + { + *val = gf_state->splice_crtc_y; + } + else if (property == disp_info->crtc_w_prop) + { + *val = gf_state->splice_crtc_w; + } + else if (property == disp_info->crtc_h_prop) + { + *val = gf_state->splice_crtc_h; + } + else if(property == disp_info->splice_trigger_prop) + { + *val = gf_state->splice_trigger; + } + else + { + ret = -EINVAL; + } + + return ret; +} + +static inline bool is_splice_target_crtc(struct drm_device *dev, pipe_t pipe) +{ + gf_card_t *gf_card = dev->dev_private; + disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; + gf_splice_manager_t *splice_manager = disp_info->splice_manager; + unsigned int target_crtc_index = splice_manager->target.crtc_index; + + return !!(pipe == target_crtc_index); +} + +int gf_splice_manager_init(disp_info_t *disp_info, unsigned int crtc_index); +void gf_splice_manager_deinit(disp_info_t *disp_info); + +void gf_atomic_commit_connector_prop(struct drm_device *dev, struct drm_atomic_state *old_state); + +struct drm_crtc* gf_splice_get_crtc_by_source(struct drm_device *dev, gf_splice_source_t *source); + +bool is_connector_work_in_splice_mode(struct drm_connector *connector); +bool is_crtc_work_in_splice_mode(struct drm_crtc *crtc); +bool is_plane_work_in_splice_mode(struct drm_plane *plane); +bool is_splice_target_active_in_drm(struct drm_device *dev); + +void gf_splice_attach_connector_property(struct drm_connector *connector); + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) +u32 gf_splice_get_vblank_counter(struct drm_device *dev, pipe_t pipe); +int gf_splice_enable_vblank(struct drm_device *dev, pipe_t pipe); +void gf_splice_disable_vblank(struct drm_device *dev, pipe_t pipe); +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 13, 0) +int gf_splice_get_vblank_timestamp(struct drm_device *dev, + pipe_t pipe, + int *max_error, + struct timeval *time, + unsigned flags); +#elif DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) +bool gf_splice_get_vblank_timestamp(struct drm_device *dev, + pipe_t pipe, + int *max_error, + #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) + ktime_t *vblank_time, + #else + struct timeval *vblank_time, + #endif + bool in_vblank_irq); +#else +bool gf_splice_get_vblank_timestamp(struct drm_crtc *crtc, + int *max_error, + ktime_t *vblank_time, + bool in_vblank_irq); +#endif + +int gf_splice_handle_source_status(struct drm_connector *connector); + +#else + +static inline int gf_splice_manager_init(disp_info_t *disp_info, unsigned int crtc_index) +{ + return 0; +} + +static inline void gf_splice_manager_deinit(disp_info_t *disp_info) +{ +} + +static inline void gf_atomic_commit_connector_prop(struct drm_device *dev, struct drm_atomic_state *old_state) +{ +} + +static inline struct drm_crtc* gf_splice_get_crtc_by_source(struct drm_device *dev, gf_splice_source_t *source) +{ + return NULL; +} + +static inline void gf_splice_attach_connector_property(struct drm_connector *connector) +{ + return; +} + +static inline u32 gf_splice_get_vblank_counter(struct drm_device *dev, pipe_t pipe) +{ + return 0; +} + +static inline int gf_splice_enable_vblank(struct drm_device *dev, pipe_t pipe) +{ + return 0; +} + +static inline void gf_splice_disable_vblank(struct drm_device *dev, pipe_t pipe) +{ + return; +} + +#if DRM_VERSION_CODE < KERNEL_VERSION(4, 13, 0) +static inline int gf_splice_get_vblank_timestamp(struct drm_device *dev, + pipe_t pipe, + int *max_error, + struct timeval *time, + unsigned flags) +{ + return 0; +} +#else +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 7, 0) +static inline bool gf_splice_get_vblank_timestamp(struct drm_device *dev, + pipe_t pipe, + int *max_error, + #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) + ktime_t *vblank_time, + #else + struct timeval *vblank_time, + #endif + bool in_vblank_irq) +{ + return true; +} +#else +static inline bool gf_splice_get_vblank_timestamp(struct drm_crtc *crtc, + int *max_error, + ktime_t *vblank_time, + bool in_vblank_irq) +{ + + return true; +} +#endif + +#endif + +static inline bool is_connector_work_in_splice_mode(struct drm_connector *connector) +{ + return false; +} + +static inline bool is_crtc_work_in_splice_mode(struct drm_crtc *crtc) +{ + return false; +} + +static inline bool is_plane_work_in_splice_mode(struct drm_plane *plane) +{ + return false; +} + +static inline bool is_splice_target_active_in_drm(struct drm_device *dev) +{ + return false; +} + +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) +static inline void gf_splice_duplicate_connector_state(struct drm_connector_state *new_state, struct drm_connector_state *old_state) +{ + return; +} + +static inline int gf_splice_set_connector_property(struct drm_connector_state *state, + struct drm_property *property, + uint64_t val) +{ + return 0; +} + +static inline int gf_splice_get_connector_property(const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) +{ + + return 0; +} +#endif + +static inline int gf_splice_handle_source_status(struct drm_connector *connector) +{ + return 0; +} + + +static inline bool is_splice_target_crtc(struct drm_device *dev, pipe_t pipe) +{ + return false; +} + +#endif + + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_sysfs.c b/drivers/gpu/drm/arise/linux/gf_sysfs.c new file mode 100755 index 0000000000000..f41b786588f41 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_sysfs.c @@ -0,0 +1,820 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** +#include "gf.h" +#include "gf_disp.h" +#include "gf_cbios.h" +#include "gf_driver.h" +#include "gf_version.h" + +/* + DEVICE_ATTR() will do PERMISSIONS Check + Kernel Code VERIFY_OCTAL_PERMISSIONS() not allowed to Give "Other User" Write permissions +*/ + +#define GF_DEVICE_ATTR_RO(name) \ + static DEVICE_ATTR(name,0444,gf_##name##_show,NULL) + +#define GF_DEVICE_ATTR_RW(name) \ + static DEVICE_ATTR(name,0664,gf_##name##_show,gf_##name##_store) + +#define GF_DEVICE_ATTR_WO(name) \ + static DEVICE_ATTR(name,0220,NULL,gf_##name##_store) + +/* + "gf_string_show" and "gf_string_store" is demo shows + how to add sys read write file with GF_DEVICE_ATTR_RW() +*/ + +static char string_buffer [64] = {0}; + +static ssize_t gf_string_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + return sprintf(buf, "Store String:%s\n",string_buffer); +} + +static ssize_t gf_string_store(struct device *dev,struct device_attribute *attr, const char *buf,size_t len) +{ + if(len>=64) + { + len = 63; + } + memcpy(string_buffer,buf,len); + string_buffer[len] = '\0'; + return len; +} + +extern int hwq_get_hwq_info(void *adp,gf_hwq_info *hwq_info); +extern int hwq_get_video_info(void *adp, gf_video_info *video_info); +static ssize_t gf_enable_usage_store(struct device *dev,struct device_attribute *attr, const char *buf,size_t len) +{ + int ret = 0; + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + + unsigned long value = 0; + ret = kstrtoul(buf, 0, &value); + if(ret < 0) + { + return ret; + } + + value = (value==0)? 0:1; + gf_core_interface->ctl_flags_set(gf_card->adapter,1,(1UL<<16),(value<<16)); //First Int Bit16 hwq_event_enable + if(value) + { + gf_core_interface->ctl_flags_set(gf_card->adapter,1,(1UL<<9),(value<<9)); //First Int Bit11, perf_event_enable + } + return len; +} + +static ssize_t gf_enable_perf_store(struct device *dev,struct device_attribute *attr, const char *buf,size_t len) +{ + int ret = 0; + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + + unsigned long value = 0; + ret = kstrtoul(buf, 0, &value); + if(ret < 0) + { + return ret; + } + + value = (value==0)? 0:1; + gf_core_interface->ctl_flags_set(gf_card->adapter,1,(1UL<<9),(value<<9)); //First Int Bit11 perf_event_enable + if(value==0) + { + gf_core_interface->ctl_flags_set(gf_card->adapter,1,(1UL<<16),(value<<16)); //First Int Bit16 hwq_event_enable + } + return len; +} + +static ssize_t gf_voltage_core_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + int voltage = 0; + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + adapter_info_t* adapter_info = &gf_card->adapter_info; + + voltage = gf_read32(adapter_info->mmio + 0xd3d8); + if (voltage) + return sprintf(buf, "Voltage: %d mV\n", voltage); + + return sprintf(buf, "Voltage: read fail\n"); +} + +static ssize_t gf_engine_3d_usage_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + int ret = 0; + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + + gf_hwq_info hwq_info; + ret = hwq_get_hwq_info(gf_card->adapter,&hwq_info); + + if(ret == 0) + { + return sprintf(buf, "%d\n",hwq_info.Usage_3D); + } + return sprintf(buf, "Not Enable!\n"); +} + +static ssize_t gf_engine_vcp_usage_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + int ret = 0; + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + + gf_hwq_info hwq_info; + ret = hwq_get_hwq_info(gf_card->adapter,&hwq_info); + + if(ret == 0) + { + return sprintf(buf, "%d\n",hwq_info.Usage_VCP); + } + return sprintf(buf, "Not Enable!\n"); + +} + +static ssize_t gf_engine_vcp_info_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + int ret = 0, i; + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + int buf_size = 0, size_offset = 0; + int pid = 0; + + gf_sscanf(string_buffer, "%d", &pid); + + for (i = 0; i < VIDEO_INFO_NUM; i++) + { + gf_video_info* video_info = gf_calloc(sizeof(gf_video_info)); + gf_memset(video_info, 0, sizeof(gf_video_info)); + video_info->index = i; + + ret = hwq_get_video_info(gf_card->adapter, video_info); + if (ret) + { + gf_free(video_info); + return sprintf(buf, "Not Enable!\n"); + } + + if (pid == 0) { //get all info + if (video_info->pid[video_info->index]) { + //PID + size_offset = sprintf(buf + buf_size, "pid:%d\n", video_info->pid[video_info->index]); + buf_size += size_offset; + //clip width + size_offset = sprintf(buf + buf_size, "width:%d\n", video_info->width[video_info->index]); + buf_size += size_offset; + //clip height + size_offset = sprintf(buf + buf_size, "height:%d\n", video_info->height[video_info->index]); + buf_size += size_offset; + //clip codec + size_offset = sprintf(buf + buf_size, "codec:%s\n", video_info->codec[video_info->index]); + buf_size += size_offset; + //decodeapi + size_offset = sprintf(buf + buf_size, "decode_api:%s\n", video_info->decodeapi[video_info->index]); + buf_size += size_offset; + //renderapi + size_offset = sprintf(buf + buf_size, "render_api:%s\n", video_info->presentapi[video_info->index]); + buf_size += size_offset; + //total decode frame + size_offset = sprintf(buf + buf_size, "total_decodeframe:%d\n", video_info->TotalDecodeFrameNum[video_info->index]); + buf_size += size_offset; + //total render frame + size_offset = sprintf(buf + buf_size, "total_renderframe:%d\n", video_info->TotalRenderFrameNum[video_info->index]); + buf_size += size_offset; + //presentspeed + size_offset = sprintf(buf + buf_size, "average_presentspeed:%dFPS\n", video_info->presentspeed[video_info->index]); + buf_size += size_offset; + //bit rate + size_offset = sprintf(buf + buf_size, "average_bitrate:%dKbPS\n", video_info->bitrate[video_info->index]); + buf_size += size_offset; + //gpu deocdespeed + size_offset = sprintf(buf + buf_size, "average_decodespeed:%dFPS\n", video_info->decodespeed[video_info->index]); + buf_size += size_offset; + //others + } + } else { //get pid info + if (video_info->pid[video_info->index] == pid) { + //PID + size_offset = sprintf(buf + buf_size, "pid:%d\n", video_info->pid[video_info->index]); + buf_size += size_offset; + //clip width + size_offset = sprintf(buf + buf_size, "width:%d\n", video_info->width[video_info->index]); + buf_size += size_offset; + //clip height + size_offset = sprintf(buf + buf_size, "height:%d\n", video_info->height[video_info->index]); + buf_size += size_offset; + //clip codec + size_offset = sprintf(buf + buf_size, "codec:%s\n", video_info->codec[video_info->index]); + buf_size += size_offset; + //decodeapi + size_offset = sprintf(buf + buf_size, "decode_api:%s\n", video_info->decodeapi[video_info->index]); + buf_size += size_offset; + //renderapi + size_offset = sprintf(buf + buf_size, "render_api:%s\n", video_info->presentapi[video_info->index]); + buf_size += size_offset; + //total decode frame + size_offset = sprintf(buf + buf_size, "total_decodeframe:%d\n", video_info->TotalDecodeFrameNum[video_info->index]); + buf_size += size_offset; + //total render frame + size_offset = sprintf(buf + buf_size, "total_renderframe:%d\n", video_info->TotalRenderFrameNum[video_info->index]); + buf_size += size_offset; + //presentspeed + size_offset = sprintf(buf + buf_size, "average_presentspeed:%dFPS\n", video_info->presentspeed[video_info->index]); + buf_size += size_offset; + //bit rate + size_offset = sprintf(buf + buf_size, "average_bitrate:%dKbPS\n", video_info->bitrate[video_info->index]); + buf_size += size_offset; + //gpu deocdespeed + size_offset = sprintf(buf + buf_size, "average_decodespeed:%dFPS\n", video_info->decodespeed[video_info->index]); + buf_size += size_offset; + //others + } + } + gf_free(video_info); + } + + //gf_info("buffer size %d, pid %d\n", buf_size, pid); + return buf_size; +} + +static ssize_t gf_engine_vpp_usage_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + int ret = 0; + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + + gf_hwq_info hwq_info; + ret = hwq_get_hwq_info(gf_card->adapter,&hwq_info); + + if(ret == 0) + { + return sprintf(buf, "%d\n",hwq_info.Usage_VPP); + } + return sprintf(buf, "Not Enable!\n"); +} + +static ssize_t gf_mclk_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + + unsigned int value = 0; + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_MCLK, &value)) + { + value = gf_calc_double_standard_mclk(value); + return sprintf(buf,"%dMHz\n", value / 2); + } + return sprintf(buf, "Mclk Read Error\n"); +} + +static ssize_t gf_fps_count_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + unsigned long long flip_timestamp; + gf_get_nsecs(&flip_timestamp); + if(gf_card->fps_count) + { + return sprintf(buf,"%u %lld\n", gf_card->fps_count,flip_timestamp); + } + return sprintf(buf, "fps Read Error\n"); +} + +static ssize_t gf_rxa_blt_scn_cnt_store(struct device *dev,struct device_attribute *attr, const char *buf,size_t len) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + if(len>=16) + { + len = 16; + } + + sscanf(buf, "%d", &gf_card->rxa_blt_scn_cnt); + //gf_info("gf_rxa_blt_scn_cnt_store set data %d", gf_card->rxa_blt_scn_cnt); + + return len; +} + + +static ssize_t gf_rxa_blt_scn_cnt_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + + //gf_info("gf_rxa_blt_scn_cnt_show get data %d", gf_card->rxa_blt_scn_cnt); + + if(gf_card->rxa_blt_scn_cnt > 0) + { + return sprintf(buf,"%d\n", gf_card->rxa_blt_scn_cnt); + } + return sprintf(buf, "rxa_blt_scn_cnt Read Error\n"); +} + + + +static ssize_t gf_misc_ctl_flag_store(struct device *dev,struct device_attribute *attr, const char *buf,size_t len) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + if(len>=16) + { + len = 16; + } + + sscanf(buf, "%d", &gf_card->misc_control_flag); + //gf_info("gf_misc_ctl_flag_store set data %d, len %d", gf_card->misc_control_flag, len); + + return len; +} + + +static ssize_t gf_misc_ctl_flag_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + + //gf_info("gf_misc_ctl_flag_show get data %d", gf_card->rxa_blt_scn_cnt); + return sprintf(buf,"%d\n", gf_card->misc_control_flag); +} + + + + +static ssize_t gf_vclk_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + + unsigned int value = 0; + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_VCLK, &value)) + { + return sprintf(buf,"%dMHz\n", (value + 500)/1000); + } + + return sprintf(buf, "Vclk Read Error\n"); +} + +static ssize_t gf_coreclk_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct pci_dev * pdev = container_of(dev, struct pci_dev, dev); + struct drm_device *drm_dev = pci_get_drvdata(pdev); + gf_card_t * gf_card = drm_dev->dev_private; + disp_info_t * disp_info = (disp_info_t *)gf_card->disp_info; + + unsigned int value = 0; + if (DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_CORE_CLOCK, &value)) + { + return sprintf(buf, "%dMHz\n", value / 1000); + } + + return sprintf(buf, "Coreclk Read Error\n"); +} + +static ssize_t gf_eclk_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + + unsigned int value = 0; + if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_ENGINE_CLOCK, &value)) + { + return sprintf(buf, "%dMHz\n", value / 1000); + } + + return sprintf(buf, "Eclk Read Error\n"); + +} + +static ssize_t gf_free_fb_mem_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + + gf_query_info_t query_info; + int mem_total = 0; + query_info.type = GF_QUERY_SEGMENT_FREE_SIZE; + query_info.argu = 1; + gf_core_interface->query_info(gf_card->adapter,&query_info); + mem_total += query_info.signed_value; + + query_info.type = GF_QUERY_SEGMENT_FREE_SIZE; + query_info.argu = 4; + gf_core_interface->query_info(gf_card->adapter,&query_info); + mem_total += query_info.signed_value; + + query_info.type = GF_QUERY_SEGMENT_FREE_SIZE; + query_info.argu = 5; + gf_core_interface->query_info(gf_card->adapter,&query_info); + mem_total += query_info.signed_value; + + return sprintf(buf,"%d\n",mem_total); +} + +static ssize_t gf_fb_size_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + adapter_info_t* adapter_info = &gf_card->adapter_info; + + return sprintf(buf,"%d M\n",adapter_info->total_mem_size_mb); +} + +static ssize_t gf_mem_usage_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + adapter_info_t* adapter_info = &gf_card->adapter_info; + + gf_query_info_t query_info; + int mem_free_total = 0, mem_usage; + query_info.type = GF_QUERY_SEGMENT_FREE_SIZE; + query_info.argu = 1; + gf_core_interface->query_info(gf_card->adapter, &query_info); + mem_free_total += query_info.signed_value; + + query_info.type = GF_QUERY_SEGMENT_FREE_SIZE; + query_info.argu = 4; + gf_core_interface->query_info(gf_card->adapter, &query_info); + mem_free_total += query_info.signed_value; + + query_info.type = GF_QUERY_SEGMENT_FREE_SIZE; + query_info.argu = 5; + gf_core_interface->query_info(gf_card->adapter, &query_info); + mem_free_total += query_info.signed_value; + + mem_free_total /= 1024; + + mem_usage = ((adapter_info->total_mem_size_mb - mem_free_total) * 100) / adapter_info->total_mem_size_mb; + + return sprintf(buf,"%d%%\n", mem_usage); +} + +static ssize_t gf_segment_info_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + gf_segment_mem_t seg_mem_data; + gf_query_info_t query_info; + int segmenti = 0; + int ret = 0; + int print_offset = 0; + + for(segmenti = 0; segmenti < 6; segmenti ++) + { + gf_memset(&seg_mem_data, 0, sizeof(gf_segment_mem_t)); + query_info.type = GF_QUERY_SEGMENT_MEM_INFO; + query_info.argu = (segmenti | 0x80000000); + query_info.buf = &seg_mem_data; + + ret = gf_core_interface->query_info(gf_card->adapter,&query_info); + if(ret < 0) + { + break; + } + else + { + print_offset += sprintf(buf + print_offset,"segment_id:%d,total_size:%d,used_size:%d \n", + seg_mem_data.segment_id, + seg_mem_data.segment_total_size, + seg_mem_data.segment_used_size); + } + } + + return print_offset; +} + +static ssize_t gf_slice_mask_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + adapter_info_t* adapter_info = &gf_card->adapter_info; + + return sprintf(buf,"0x%x\n",adapter_info->chip_slice_mask); +} + +static ssize_t gf_miu_channel_num_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + adapter_info_t* adapter_info = &gf_card->adapter_info; + + return sprintf(buf,"%d\n",adapter_info->chan_num); + +} + +static ssize_t gf_driver_version_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + return sprintf(buf,"%02x.%02x.%02x%s\n",DRIVER_MAJOR,DRIVER_MINOR,DRIVER_PATCHLEVEL,DRIVER_CLASS); +} + +static ssize_t gf_release_date_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + return sprintf(buf,"%s\n",DRIVER_DATE); +} + +static ssize_t gf_pmp_version_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + + unsigned char* pmpversion = disp_info->pmp_version; + int pmpdatelen = 0; + int pmptimelen = 0; + + if(*pmpversion) + { + // pmpVersion:str1 -> pmp version,str2 -> pmp build date,str3 -> pmp build time + pmpdatelen = gf_strlen(pmpversion) + 1; + pmptimelen = gf_strlen(pmpversion + pmpdatelen) + 1; + return sprintf(buf, "%s %s %s\n",pmpversion,(pmpversion + pmpdatelen),(pmpversion + pmpdatelen + pmptimelen) ); + } + return sprintf(buf,"get error\n"); + +} + +static ssize_t gf_vbios_version_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + int vbiosVer = disp_info->vbios_version; + return sprintf(buf, "%02x.%02x.%02x.%02x\n", (vbiosVer>>24)&0xff,(vbiosVer>>16)&0xff,(vbiosVer>>8)&0xff,vbiosVer&0xff); +} + +static ssize_t gf_task_timeout_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + unsigned long long timeout; + int ret; + + gf_core_interface->task_timeout_update(gf_card->adapter, &timeout, 0); + + return sprintf(buf, "%llums\n", timeout); +} + +static ssize_t gf_task_timeout_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + unsigned long long timeout; + int ret; + + ret = sscanf(buf, "%llu", &timeout); + if (ret <= 0) + return -EINVAL; + + gf_core_interface->task_timeout_update(gf_card->adapter, &timeout, 1); + + return len; +} + +static ssize_t gf_firmware_version_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + disp_info_t* disp_info = (disp_info_t*)gf_card->disp_info; + int fw_version = disp_info->firmware_version; + + return sprintf(buf, "%02x.%02x.%02x.%02x\n", (fw_version >> 24) & 0xff, (fw_version >> 16) & 0xff, (fw_version >> 8) & 0xff, fw_version & 0xff); +} + +GF_DEVICE_ATTR_RW(string); +GF_DEVICE_ATTR_WO(enable_usage); +GF_DEVICE_ATTR_WO(enable_perf); + +GF_DEVICE_ATTR_RO(voltage_core); +GF_DEVICE_ATTR_RO(engine_3d_usage); +GF_DEVICE_ATTR_RO(engine_vcp_usage); +GF_DEVICE_ATTR_RO(engine_vcp_info); +GF_DEVICE_ATTR_RO(engine_vpp_usage); +GF_DEVICE_ATTR_RO(vbios_version); +GF_DEVICE_ATTR_RO(pmp_version); +GF_DEVICE_ATTR_RO(release_date); +GF_DEVICE_ATTR_RO(driver_version); +GF_DEVICE_ATTR_RO(miu_channel_num); +GF_DEVICE_ATTR_RO(slice_mask); +GF_DEVICE_ATTR_RO(fb_size); +GF_DEVICE_ATTR_RO(free_fb_mem); +GF_DEVICE_ATTR_RO(mem_usage); +GF_DEVICE_ATTR_RO(coreclk); +GF_DEVICE_ATTR_RO(eclk); +GF_DEVICE_ATTR_RO(vclk); +GF_DEVICE_ATTR_RO(mclk); +GF_DEVICE_ATTR_RO(fps_count); +GF_DEVICE_ATTR_RW(rxa_blt_scn_cnt); +GF_DEVICE_ATTR_RW(misc_ctl_flag); +GF_DEVICE_ATTR_RO(segment_info); +GF_DEVICE_ATTR_RW(task_timeout); +GF_DEVICE_ATTR_RO(firmware_version); + +static struct attribute *gf_info_attributes[] = { + &dev_attr_string.attr, + &dev_attr_enable_usage.attr, + &dev_attr_enable_perf.attr, + + &dev_attr_voltage_core.attr, + &dev_attr_engine_3d_usage.attr, + &dev_attr_engine_vpp_usage.attr, + &dev_attr_engine_vcp_usage.attr, + &dev_attr_engine_vcp_info.attr, + &dev_attr_vbios_version.attr, + &dev_attr_pmp_version.attr, + &dev_attr_release_date.attr, + &dev_attr_driver_version.attr, + &dev_attr_miu_channel_num.attr, + &dev_attr_slice_mask.attr, + &dev_attr_fb_size.attr, + &dev_attr_free_fb_mem.attr, + &dev_attr_mem_usage.attr, + &dev_attr_coreclk.attr, + &dev_attr_eclk.attr, + &dev_attr_vclk.attr, + &dev_attr_mclk.attr, + &dev_attr_fps_count.attr, + &dev_attr_rxa_blt_scn_cnt.attr, + &dev_attr_misc_ctl_flag.attr, + &dev_attr_segment_info.attr, + &dev_attr_task_timeout.attr, + &dev_attr_firmware_version.attr, + NULL +}; + +const struct attribute_group gf_sysfs_group = { + .attrs = gf_info_attributes, + .name = "gf_info" +}; + + +/** + * Format such as: + * VRAM total size:0x80000000 +*/ +static ssize_t gf_gpu_info_show(struct device *dev, struct device_attribute *attr,char *buf) +{ + struct pci_dev* pdev = container_of(dev,struct pci_dev,dev); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + adapter_info_t* adapter_info = &gf_card->adapter_info; + unsigned long long total_mem_size = adapter_info->total_mem_size_mb; + total_mem_size = total_mem_size *1024*1024; + + return sprintf(buf,"VRAM total size:0x%llx\n",total_mem_size); +} + +static struct device_attribute dev_attr_gpu_info = __ATTR(gpu-info,0444,gf_gpu_info_show,NULL); + +const struct attribute *gf_os_gpu_info[] = { + &dev_attr_gpu_info.attr, + NULL +}; + +static ssize_t gf_sysfs_trace_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) +{ + struct pci_dev* pdev = to_pci_dev(container_of(kobj,struct device,kobj)); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + ssize_t ret = 0; + + if (gf_card->trace_buffer_vma && gf_card->trace_buffer_vma->virt_addr) + { + char val_buf[32]; + unsigned int len; + + len = sprintf(val_buf, "%llu\n", *((uint64_t *)gf_card->trace_buffer_vma->virt_addr)); + ret = memory_read_from_buffer(buf, size, &pos, val_buf, len); + } + + return ret; +} + +static ssize_t gf_sysfs_trace_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) +{ + struct pci_dev* pdev = to_pci_dev(container_of(kobj,struct device,kobj)); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + unsigned long val; + int ret; + + if (!gf_card->trace_buffer_vma || !gf_card->trace_buffer_vma->virt_addr) + return 0; + + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; + + *((uint64_t *)gf_card->trace_buffer_vma->virt_addr) = val; + + return size; +} + +// for gdb (ptrace) to access this memory by access_process_vm +static int gf_sysfs_trace_access(struct vm_area_struct *vma, unsigned long addr, void *buf, int len, int write) +{ + gf_card_t* gf_card = vma->vm_private_data; + unsigned long offset = addr - vma->vm_start; + + // gf_info("gf_sysfs_trace_access: vma=%p, addr=%lx, vma->vm_start=%llx\n", vma, addr, vma->vm_start); + + if (offset + len > gf_card->trace_buffer->size) + return -EINVAL; + + if (!gf_card->trace_buffer_vma || !gf_card->trace_buffer_vma->virt_addr) + return 0; + + if (write) + gf_memcpy(gf_card->trace_buffer_vma->virt_addr + offset, buf, len); + else + gf_memcpy(buf, gf_card->trace_buffer_vma->virt_addr + offset, len); + + return len; +} + +static const struct vm_operations_struct gf_sysfs_trace_vmops = { + .access = gf_sysfs_trace_access, +}; + +extern unsigned char gf_validate_page_cache(struct os_pages_memory *memory, int start_page, int end_page, unsigned char request_cache_type); + +static int gf_sysfs_trace_mmap(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + struct vm_area_struct *vma) +{ + struct pci_dev* pdev = to_pci_dev(container_of(kobj,struct device,kobj)); + struct drm_device* drm_dev = pci_get_drvdata(pdev); + gf_card_t* gf_card = drm_dev->dev_private; + unsigned int cache_type; + + gf_map_argu_t map_argu = {0}; + int start_page, end_page; + + // gf_info("gf_sysfs_trace_mmap: vma=%p, vma->vm_start=%llx\n", vma, vma->vm_start); + + vma->vm_ops = &gf_sysfs_trace_vmops; + vma->vm_private_data = gf_card; + + map_argu.memory = gf_card->trace_buffer; + map_argu.flags.mem_space = GF_MEM_USER; + map_argu.flags.read_only = true; + map_argu.flags.mem_type = GF_SYSTEM_RAM; + map_argu.size = gf_card->trace_buffer->size; + map_argu.offset = 0; + start_page = _ALIGN_DOWN(map_argu.offset, PAGE_SIZE)/PAGE_SIZE; + end_page = start_page + ALIGN(map_argu.size, PAGE_SIZE) / PAGE_SIZE; + map_argu.flags.cache_type = gf_validate_page_cache(map_argu.memory, start_page, end_page, GF_MEM_WRITE_BACK); + + return gf_map_system_ram(vma, &map_argu); +} + +struct bin_attribute gf_sysfs_trace_attr = { + .attr = {.name = "trace", .mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH}, // 0644 + .size = PAGE_SIZE, + .read = gf_sysfs_trace_read, + .write = gf_sysfs_trace_write, + .mmap = gf_sysfs_trace_mmap, +}; diff --git a/drivers/gpu/drm/arise/linux/gf_trace.h b/drivers/gpu/drm/arise/linux/gf_trace.h new file mode 100644 index 0000000000000..c926562016b8a --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_trace.h @@ -0,0 +1,434 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_version.h" + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM DRIVER_NAME + +#if !defined(_GFX_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _GFX_TRACE_H + +#if GF_TRACE_EVENT +#include +#include "gf_fence.h" +#include "gf_gem.h" +#include "gf_kms.h" + + +TRACE_EVENT(gfx_task_create, + + TP_PROTO(int engine_index, unsigned int context, unsigned long long task_id, unsigned int task_type), + + TP_ARGS(engine_index, context, task_id, task_type), + + TP_STRUCT__entry( + __field(int, engine_index) + __field(unsigned int, context) + __field(unsigned long long, task_id) + __field(unsigned int, task_type) + ), + + TP_fast_assign( + __entry->engine_index = engine_index; + __entry->context = context; + __entry->task_id = task_id; + __entry->task_type = task_type; + ), + + TP_printk("engine_index=%d, context=0x%x, task_id=%llu, task_type=%u", + __entry->engine_index, __entry->context, __entry->task_id, __entry->task_type) +); + +TRACE_EVENT(gfx_task_submit, + + TP_PROTO(int engine_index, unsigned int context, unsigned long long task_id, unsigned int task_type, unsigned long long fence_id, unsigned int args), + + TP_ARGS(engine_index, context, task_id, task_type, fence_id, args), + + TP_STRUCT__entry( + __field(int, engine_index) + __field(unsigned int, context) + __field(unsigned long long, task_id) + __field(unsigned int, task_type) + __field(unsigned long long, fence_id) + __field(unsigned int, args) + ), + + TP_fast_assign( + __entry->engine_index = engine_index; + __entry->context = context; + __entry->task_id = task_id; + __entry->task_type = task_type; + __entry->fence_id = fence_id; + __entry->args = args; + ), + + TP_printk("engine_index=%d, context=0x%x, task_id=%llu, task_type=%u, fence_id=%llu, args=%u", + __entry->engine_index, __entry->context, __entry->task_id, __entry->task_type, __entry->fence_id, __entry->args) +); + +TRACE_EVENT(gfx_fence_back, + + TP_PROTO(unsigned long engine_index, unsigned long long fence_id), + + TP_ARGS(engine_index, fence_id), + + TP_STRUCT__entry( + __field(unsigned long, engine_index) + __field(unsigned long long, fence_id) + ), + + TP_fast_assign( + __entry->engine_index = engine_index; + __entry->fence_id = fence_id; + ), + + TP_printk("engine_index=%lu, fence_id=%llu", __entry->engine_index, __entry->fence_id) +); + +TRACE_EVENT(gfx_vblank_intrr, + TP_PROTO(unsigned int index, unsigned int cnt), + + TP_ARGS(index, cnt), + + TP_STRUCT__entry( + __field(unsigned int, index) + __field(unsigned int, cnt) + ), + + TP_fast_assign( + __entry->index = index; + __entry->cnt = cnt; + ), + + TP_printk("crtc_index=%d, vbl_count=%d", __entry->index, __entry->cnt) +); + +TRACE_EVENT(gfx_vblank_onoff, + TP_PROTO(int index, int on), + + TP_ARGS(index, on), + + TP_STRUCT__entry( + __field(int, index) + __field(int, on) + ), + + TP_fast_assign( + __entry->index = index; + __entry->on = on; + ), + + TP_printk("crtc_index=%d, vblank on=%d", __entry->index, __entry->on) +); + +TRACE_EVENT(gfx_drm_gem_create_object, + TP_PROTO(long long card_index, struct drm_gf_gem_object *obj), + TP_ARGS(card_index, obj), + + TP_STRUCT__entry( + __field(unsigned long long, allocation) + __field(unsigned int, size) + __field(unsigned int, width) + __field(unsigned int, height) + __field(unsigned int, bit_cnt) + __field(unsigned int, pitch) + __field(unsigned int, segment_id) + __field(unsigned int, hw_format) + __field(unsigned int, compress_format) + __field(unsigned int, tiled) + ), + + TP_fast_assign( + __entry->allocation = card_index << 32 | obj->core_handle; + __entry->size = obj->info.size; + __entry->width = obj->info.width; + __entry->height = obj->info.height; + __entry->bit_cnt = obj->info.bit_cnt; + __entry->pitch = obj->info.pitch; + __entry->segment_id = obj->info.segment_id; + __entry->hw_format = obj->info.hw_format; + __entry->compress_format = obj->info.compress_format; + __entry->tiled = obj->info.tiled; + ), + + TP_printk("allocation=%llx, size=%d, width=%d, height=%d, bit_cnt=%d, pitch=%d, segment_id=%d, hw_format=%d, compress_format=%d, tiled=%d", + __entry->allocation, __entry->size, __entry->width, __entry->height, __entry->bit_cnt, __entry->pitch, + __entry->segment_id, __entry->hw_format, __entry->compress_format, __entry->tiled) +); + +TRACE_EVENT(gfx_drm_gem_release_object, + TP_PROTO(long long card_index, struct drm_gf_gem_object *obj), + TP_ARGS(card_index, obj), + + TP_STRUCT__entry( + __field(unsigned long long, allocation) + ), + + TP_fast_assign( + __entry->allocation = card_index << 32 | obj->core_handle; + ), + + TP_printk("allocation=%llx", __entry->allocation) +); + +TRACE_EVENT(gfx_gem_prime_import, + TP_PROTO(long long card_index, struct dma_buf *dma_buf, struct drm_gf_gem_object* obj), + TP_ARGS(card_index, dma_buf, obj), + + TP_STRUCT__entry( + __field(struct dma_buf *, dma_buf) + __field(unsigned long long, allocation) + __field(unsigned int, size) + __field(unsigned int, width) + __field(unsigned int, height) + __field(unsigned int, bit_cnt) + __field(unsigned int, pitch) + __field(unsigned int, segment_id) + __field(unsigned int, hw_format) + __field(unsigned int, compress_format) + __field(unsigned int, tiled) + ), + + TP_fast_assign( + __entry->dma_buf = dma_buf; + __entry->allocation = card_index << 32 | obj->core_handle; + __entry->size = obj->info.size; + __entry->width = obj->info.width; + __entry->height = obj->info.height; + __entry->bit_cnt = obj->info.bit_cnt; + __entry->pitch = obj->info.pitch; + __entry->segment_id = obj->info.segment_id; + __entry->hw_format = obj->info.hw_format; + __entry->compress_format = obj->info.compress_format; + __entry->tiled = obj->info.tiled; + ), + + TP_printk("dma_buf=%p, allocation=%llx, size=%d, width=%d, height=%d, bit_cnt=%d, pitch=%d, segment_id=%d, hw_format=%d, compress_format=%d, tiled=%d", + __entry->dma_buf, __entry->allocation, __entry->size, __entry->width, __entry->height, __entry->bit_cnt, __entry->pitch, + __entry->segment_id, __entry->hw_format, __entry->compress_format, __entry->tiled) +); + +TRACE_EVENT(gfx_gem_prime_export, + TP_PROTO(long long card_index, struct dma_buf *dma_buf, struct drm_gf_gem_object* obj), + TP_ARGS(card_index, dma_buf, obj), + + TP_STRUCT__entry( + __field(struct dma_buf *, dma_buf) + __field(unsigned long long, allocation) + ), + + TP_fast_assign( + __entry->dma_buf = dma_buf; + __entry->allocation = card_index << 32 | obj->core_handle; + ), + + TP_printk("dma_buf=%p, allocation=%llx", __entry->dma_buf, __entry->allocation) +); + +TRACE_EVENT(gfx_dma_fence_wait, + TP_PROTO(dma_fence_t *fence, bool intr, signed long timeout), + TP_ARGS(fence, intr, timeout), + + TP_STRUCT__entry( + __field(dma_fence_t *, fence) + __field(bool , intr) + __field(signed long , timeout) + ), + + TP_fast_assign( + __entry->fence = fence; + __entry->intr = intr; + __entry->timeout = timeout; + ), + + TP_printk("fence=%p, intr=%d, timeout=%ld", __entry->fence, __entry->intr, __entry->timeout) +); + +TRACE_EVENT(gfx_dma_fence_enable_signaling, + TP_PROTO(dma_fence_t *fence), + TP_ARGS(fence), + + TP_STRUCT__entry( + __field(dma_fence_t *, fence) + ), + + TP_fast_assign( + __entry->fence = fence; + ), + + TP_printk("fence=%p", __entry->fence) +); + +TRACE_EVENT(gfx_gem_object_begin_cpu_access, + TP_PROTO(long long card_index, struct drm_gf_gem_object *obj, long timeout, int write), + TP_ARGS(card_index, obj, timeout, write), + + TP_STRUCT__entry( + __field(unsigned long long, allocation) + __field(long, timeout) + __field(int, write) + ), + + TP_fast_assign( + __entry->allocation = card_index << 32 | obj->core_handle; + __entry->timeout = timeout; + __entry->write = write; + ), + + TP_printk("allocation=%llx, timeout=%ld, write=%d", __entry->allocation, __entry->timeout, __entry->write) +); + +TRACE_EVENT(gfx_gem_object_end_cpu_access, + TP_PROTO(long long card_index, struct drm_gf_gem_object *obj), + TP_ARGS(card_index, obj), + + TP_STRUCT__entry( + __field(unsigned long long, allocation) + ), + + TP_fast_assign( + __entry->allocation = card_index << 32 | obj->core_handle; + ), + + TP_printk("allocation=%llx", __entry->allocation) +); + +TRACE_EVENT(gfx_atomic_flush, + TP_PROTO(long pipe, void *e), + TP_ARGS(pipe, e), + + TP_STRUCT__entry( + __field(long, pipe) + __field(void *, e) + ), + + TP_fast_assign( + __entry->pipe = pipe; + __entry->e = e + ), + + TP_printk("flush pipe=%ld,e=%p ", __entry->pipe, __entry->e) +); + +TRACE_EVENT(gfx_crtc_flip, + TP_PROTO(int crtc, const gf_crtc_flip_t *flip_arg, const struct drm_gf_gem_object *obj), + TP_ARGS(crtc, flip_arg, obj), + + TP_STRUCT__entry( + __field(int, crtc) + __field(int, stream_type) + __field(int, async_flip) + __field(unsigned int, allocation) + ), + + TP_fast_assign( + __entry->crtc = crtc; + __entry->stream_type = flip_arg->stream_type; +#if DRM_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + __entry->async_flip = flip_arg->async_flip; +#else + __entry->async_flip = 0; +#endif + __entry->allocation = obj ? obj->core_handle : 0; + ), + + TP_printk("crtc=%d, stream_type=%d, allocation=%x, async_flip=%d", __entry->crtc, __entry->stream_type, + __entry->allocation, __entry->async_flip) +); + +TRACE_EVENT(gfx_begin_section, + TP_PROTO(const char *desc), + TP_ARGS(desc), + + TP_STRUCT__entry( + __array(char, desc, 32) + ), + + TP_fast_assign( + strncpy(__entry->desc, desc, 32); + ), + + TP_printk("begin=%s", __entry->desc) +); + +TRACE_EVENT(gfx_end_section, + TP_PROTO(int result), + TP_ARGS(result), + + TP_STRUCT__entry( + __field(int, result) + ), + + TP_fast_assign( + __entry->result = result; + ), + + TP_printk("end=%d", __entry->result) +); + +TRACE_EVENT(gfx_counter, + TP_PROTO(const char *desc, unsigned long long value), + TP_ARGS(desc, value), + + TP_STRUCT__entry( + __array(char, desc, 32) + __field(unsigned long long, value) + ), + + TP_fast_assign( + strncpy(__entry->desc, desc, 32); + __entry->value = value; + ), + + TP_printk("desc=%s, val=0x%llx", __entry->desc, __entry->value) +); + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE gf_trace +#include + +#else + +#define trace_gfx_task_create(args...) do {} while(0) +#define trace_gfx_task_submit(args...) do {} while(0) +#define trace_gfx_fence_back(args...) do {} while(0) +#define trace_gfx_vblank_intrr(args...) do {} while(0) +#define trace_gfx_vblank_onoff(args...) do {} while(0) + +#define trace_gfx_drm_gem_create_object(args...) do {} while(0) +#define trace_gfx_drm_gem_release_object(args...) do {} while(0) +#define trace_gfx_gem_object_begin_cpu_access(args...) do {} while(0) +#define trace_gfx_gem_object_end_cpu_access(args...) do {} while(0) +#define trace_gfx_gem_prime_import(args...) do {} while(0) +#define trace_gfx_gem_prime_export(args...) do {} while(0) +#define trace_gfx_dma_fence_wait(args...) do {} while(0) +#define trace_gfx_dma_fence_enable_signaling(args...) do {} while(0) +#define trace_gfx_atomic_flush(args...) do {} while(0) +#define trace_gfx_crtc_flip(args...) do {} while(0) + +#define trace_gfx_begin_section(args...) do {} while(0) +#define trace_gfx_end_section(args...) do {} while(0) +#define trace_gfx_counter(args...) do {} while(0) + +#endif + +#endif + +/*_GFX_TRACE_H */ + + diff --git a/drivers/gpu/drm/arise/linux/gf_trace_events.c b/drivers/gpu/drm/arise/linux/gf_trace_events.c new file mode 100644 index 0000000000000..85bb8c6ead769 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_trace_events.c @@ -0,0 +1,66 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "os_interface.h" +#include "gf.h" + +#define CREATE_TRACE_POINTS +#include "gf_trace.h" + + +/* os interface for trace points */ +void gf_fence_back_trace_event(int engine_index, unsigned long long fence_id) +{ + trace_gfx_fence_back(engine_index, fence_id); +} + +void gf_task_create_trace_event(int engine_index, unsigned int context, + unsigned long long task_id, unsigned int task_type) +{ + trace_gfx_task_create(engine_index, context, task_id, task_type); +} + +void gf_task_submit_trace_event(int engine_index, unsigned int context, + unsigned long long task_id, unsigned int task_type, + unsigned long long fence_id, unsigned int args) +{ + trace_gfx_task_submit(engine_index, context, task_id, task_type, fence_id, args); +} + +void gf_begin_section_trace_event(const char* desc) +{ + trace_gfx_begin_section(desc); +} + +void gf_end_section_trace_event(int result) +{ + trace_gfx_end_section(result); +} + +void gf_counter_trace_event(const char* desc, unsigned long long value) +{ + trace_gfx_counter(desc, value); +} + +/* register/unregister probe functions */ +void gf_register_trace_events(void) +{ + +} + +void gf_unregister_trace_events(void) +{ + +} + diff --git a/drivers/gpu/drm/arise/linux/gf_vip.c b/drivers/gpu/drm/arise/linux/gf_vip.c new file mode 100644 index 0000000000000..24694111ae7e8 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_vip.c @@ -0,0 +1,385 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_disp.h" +#include "gf_vip.h" +#include "gf_cbios.h" + +int disp_vip_ops(disp_info_t *disp_info, gf_capture_t *capture, void *params); +void disp_vip_notify_interrupt(disp_info_t *disp_info, gf_capture_t *capture); +void disp_vip_event_handler(disp_info_t *disp_info, gf_capture_t *capture, gf_capture_event_t event); +void disp_vip_work_func(struct work_struct *work); + +static gf_capture_desc gf_vip_descs[] = +{ + { + .cf_fmt_id = GF_CAPTURE_VIP1, + .cf_name = "VIP1" + }, + { + .cf_fmt_id = GF_CAPTURE_VIP2, + .cf_name = "VIP2" + }, + { + .cf_fmt_id = GF_CAPTURE_VIP3, + .cf_name = "VIP3" + }, + { + .cf_fmt_id = GF_CAPTURE_VIP4, + .cf_name = "VIP4" + } +}; + +static unsigned char cf_id2vip(gf_capture_id_t cf_fmt_id) +{ + if (cf_fmt_id == GF_CAPTURE_VIP1) + { + return 0; + } + + if (cf_fmt_id == GF_CAPTURE_VIP2) + { + return 1; + } + + if (cf_fmt_id == GF_CAPTURE_VIP3) + { + return 2; + } + + if (cf_fmt_id == GF_CAPTURE_VIP4) + { + return 3; + } + + return -1; +} + + +void disp_register_vip_capture(disp_info_t *disp_info) +{ + gf_capture_t *capture = NULL; + int i = 0; + + for (i = 0; i < sizeof(gf_vip_descs) / sizeof(gf_capture_desc); i++) + { + capture = (gf_capture_t *)gf_calloc(sizeof(gf_capture_t)); + capture->cf_fmt_id = gf_vip_descs[i].cf_fmt_id; + capture->cf_name = gf_vip_descs[i].cf_name; + capture->cf_ctl = disp_vip_ops; + capture->notify_interrupt = disp_vip_notify_interrupt; + capture->event_handler = disp_vip_event_handler; + disp_register_capture(disp_info, capture); + } + +} + +void disp_unregister_vip_capture(disp_info_t *disp_info) +{ + gf_capture_t *capture = NULL; + int i = 0; + + for (i = 0; i < sizeof(gf_vip_descs) / sizeof(gf_capture_desc); i++) + { + capture = disp_find_capture(disp_info, gf_vip_descs[i].cf_fmt_id); + if (capture) + { + disp_unregister_capture(disp_info, capture); + gf_free(capture); + } + } +} + +int disp_vip_capture_init(gf_capture_t *capture, vip_op_params_t *mparams) +{ + vip_spec_info_t *info = NULL; + + capture->priv_info = gf_calloc(sizeof(vip_spec_info_t)); + + info = (vip_spec_info_t *)capture->priv_info; + info->mcapture = capture; + info->vip = cf_id2vip(capture->cf_fmt_id); + info->fb_num = mparams->init_param.fbNum; + + INIT_WORK(&info->vip_work, disp_vip_work_func); + + capture->flags |= CAPTURE_INIT_B; + + gf_info("capture %s init\n", capture->cf_name); + + return 0; +} + +int disp_vip_capture_deinit(gf_capture_t *capture, vip_op_params_t *mparams) +{ + vip_spec_info_t* info = (vip_spec_info_t *)capture->priv_info; + + capture->flags &= ~CAPTURE_INIT_B; + + info->mcapture = capture; + + cancel_work_sync(&info->vip_work); + + gf_free(capture->priv_info); + capture->priv_info = NULL; + + gf_info("capture %s deinit\n", capture->cf_name); + + return 0; +} + +int disp_vip_query_caps(disp_info_t *disp_info, gf_capture_t *capture, vip_op_params_t *mparams) +{ + vip_spec_info_t* info = (vip_spec_info_t *)capture->priv_info; + gf_vip_set_t v_set = {0}; + int status = 0; + + v_set.vip = info->vip; + v_set.op = GF_VIP_QUERY_CAPS; + v_set.caps.mode = mparams->query_caps_param.mode; + disp_cbios_vip_ctl(disp_info, &v_set); + + if (status) + { + gf_error("capture %s query caps failed!! \n", capture->cf_name); + } + else + { + mparams->query_caps_param.modeNum = v_set.caps.mode_num; + gf_info("capture %s query caps\n", capture->cf_name); + } + + return status; +} + +int disp_vip_set_mode(disp_info_t *disp_info, gf_capture_t *capture, vip_op_params_t *mparams) +{ + vip_spec_info_t* info = (vip_spec_info_t *)capture->priv_info; + gf_vip_set_t v_set = {0}; + int status = 0; + + v_set.vip = info->vip; + v_set.op = GF_VIP_SET_MODE; + v_set.mode.fmt = mparams->set_mode_param.fmt; + v_set.mode.chip = mparams->set_mode_param.chip; + v_set.mode.x_res = mparams->set_mode_param.xres; + v_set.mode.y_res = mparams->set_mode_param.yres; + v_set.mode.refs = mparams->set_mode_param.refreshrate; + disp_cbios_vip_ctl(disp_info, &v_set); + + if (status) + { + gf_error("capture %s set mode failed!! \n", capture->cf_name); + } + else + { + gf_info("capture %s set mode\n", capture->cf_name); + } + + return status; +} + +int disp_vip_set_buffer(disp_info_t *disp_info, gf_capture_t *capture, vip_op_params_t *mparams) +{ + vip_spec_info_t* info = (vip_spec_info_t *)capture->priv_info; + gf_vip_set_t v_set = {0}; + int status = 0; + + //TODO: get buffer phys address interface + v_set.vip = info->vip; + v_set.op = GF_VIP_SET_BUFFER; + v_set.fb.fb_num = info->fb_num; + v_set.fb.fb_idx = mparams->set_buffer_param.fbIdx; + v_set.fb.fb_addr = mparams->set_buffer_param.fbAddr; + + status = disp_cbios_vip_ctl(disp_info, &v_set); + + if (status) + { + gf_error("capture %s set buffer failed!! \n", capture->cf_name); + } + else + { + //gf_info("capture %s set buffer, idx %d, buf %x\n", capture->cf_name, mparams->set_buffer_param.fbIdx, mparams->set_buffer_param.fbAddr); + } + + return status; +} + +int disp_vip_capture_enable(disp_info_t *disp_info, gf_capture_t *capture, vip_op_params_t *mparams) +{ + vip_spec_info_t* info = (vip_spec_info_t *)capture->priv_info; + gf_vip_set_t v_set = {0}; + int status = 0; + + v_set.vip = info->vip; + v_set.op = GF_VIP_ENABLE; + + status = disp_cbios_vip_ctl(disp_info, &v_set); + + if (status) + { + gf_error("capture %s enable failed!! \n", capture->cf_name); + } + else + { + capture->flags |= CAPTURE_ENABLE_B; + gf_info("capture %s enable\n", capture->cf_name); + } + + return status; +} + +int disp_vip_capture_disable(disp_info_t *disp_info, gf_capture_t *capture, vip_op_params_t *mparams) +{ + vip_spec_info_t* info = (vip_spec_info_t *)capture->priv_info; + gf_vip_set_t v_set = {0}; + int status = 0; + + v_set.vip = info->vip; + v_set.op = GF_VIP_DISABLE; + + status = disp_cbios_vip_ctl(disp_info, &v_set); + + if (status) + { + gf_error("capture %s disable failed!! \n", capture->cf_name); + } + else + { + capture->flags &= ~CAPTURE_ENABLE_B; + gf_info("capture %s disable\n", capture->cf_name); + } + + return status; +} + +void disp_vip_notify_interrupt(disp_info_t *disp_info, gf_capture_t *capture) +{ + vip_spec_info_t* info = (vip_spec_info_t *)capture->priv_info; + + schedule_work(&info->vip_work); +} + +void disp_vip_event_handler(disp_info_t *disp_info, gf_capture_t *capture, gf_capture_event_t event) +{ + gf_info("capture %s, event: %d \n", capture->cf_name, event); +} + +void disp_vip_work_func(struct work_struct *work) +{ + vip_spec_info_t* info = container_of(work, vip_spec_info_t, vip_work); + gf_capture_t* capture = info->mcapture; + unsigned int flags = 0; + + if (!(capture->flags & CAPTURE_ENABLE_B)) + { + return; + } + + flags |= GF_CAPTURE_SET_BUFFER; + + info->cb(capture->cf_fmt_id, info->cb_data, flags); +} + +int disp_vip_ops(disp_info_t *disp_info, gf_capture_t *capture, void *params) +{ + vip_op_params_t *mparams = (vip_op_params_t *)params; + + int status = 0; + + switch(mparams->op) + { + case GF_CAPTURE_OP_INIT: + { + status = disp_vip_capture_init(capture, mparams); + } + break; + + case GF_CAPTURE_OP_DEINIT: + { + status = disp_vip_capture_deinit(capture, mparams); + } + break; + + case GF_CAPTURE_OP_ENABLE: + { + status = disp_vip_capture_enable(disp_info, capture, mparams); + } + break; + + case GF_CAPTURE_OP_DISABLE: + { + status = disp_vip_capture_disable(disp_info, capture, mparams); + } + break; + + case GF_CAPTURE_OP_QUERY_CAPS: + { + status = disp_vip_query_caps(disp_info, capture, mparams); + } + break; + + case GF_CAPTURE_OP_SET_MODE: + { + status = disp_vip_set_mode(disp_info, capture, mparams); + } + break; + + case GF_CAPTURE_OP_SET_BUFF: + { + status = disp_vip_set_buffer(disp_info, capture, mparams); + } + break; + + case GF_CAPTURE_OP_SET_CALLBACK: + { + vip_spec_info_t *info = (vip_spec_info_t *)capture->priv_info; + info->cb = mparams->set_callback_param.cb; + info->cb_data = mparams->set_callback_param.cb_data; + } + break; + + case GF_CAPTURE_OP_QUERY_CHIPINFO: + { + mparams->query_chipinfo_param.vipCard = GF_VIP_CARD_AVD7611; + } + break; + + case GF_CAPTURE_OP_GET_FRONT_MODE: + { + //FIXME: get mode info from the vip card later + mparams->get_front_mode_param.hasInput = 1; + mparams->get_front_mode_param.mode.xRes = 1920; + mparams->get_front_mode_param.mode.yRes = 1080; + mparams->get_front_mode_param.mode.refreshrate = 6000; + mparams->get_front_mode_param.mode.fmt = GF_VIP_FMT_RGB444_24BIT_SDR; + } + break; + + case GF_CAPTURE_OP_SET_PREFER_MODE: + { + //TODO + } + break; + + default: + { + gf_error("op not support on vip\n"); + } + break; + } + + return status; +} diff --git a/drivers/gpu/drm/arise/linux/gf_vip.h b/drivers/gpu/drm/arise/linux/gf_vip.h new file mode 100644 index 0000000000000..abaef18a45d19 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_vip.h @@ -0,0 +1,70 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_VIP_H_ +#define __GF_VIP_H_ + +#include "gf_capture_drv.h" + +#define GF_VIP_ENABLE 0 +#define GF_VIP_DISABLE 1 +#define GF_VIP_SET_MODE 2 +#define GF_VIP_SET_BUFFER 3 +#define GF_VIP_QUERY_CAPS 4 + +#define GF_CAPTURE_VIP_INTERFACE + +typedef struct +{ + gf_capture_t *mcapture; + unsigned char fb_num; + unsigned char vip; + void (*cb)(gf_capture_id_t id, void *data, unsigned int flags); + void *cb_data; + struct work_struct vip_work; +}vip_spec_info_t; + +typedef struct +{ + unsigned char vip; + unsigned int op; + union{ + struct + { + unsigned int fmt; + unsigned int chip; + unsigned int x_res; + unsigned int y_res; + unsigned int refs; + }mode; + + struct + { + unsigned char fb_num; + unsigned char fb_idx; + unsigned long long fb_addr; + }fb; + + struct + { + unsigned int mode_num; + gf_vip_mode_t *mode; + }caps; + }; +}gf_vip_set_t; + +void disp_register_vip_capture(disp_info_t *disp_info); +void disp_unregister_vip_capture(disp_info_t *disp_info); + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_wb.c b/drivers/gpu/drm/arise/linux/gf_wb.c new file mode 100644 index 0000000000000..91c4365d68f39 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_wb.c @@ -0,0 +1,465 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "gf_disp.h" +#include "gf_wb.h" +#include "gf_cbios.h" + +int disp_wb_ops(disp_info_t *disp_info, gf_capture_t *capture, void *params); +void disp_wb_notify_interrupt(disp_info_t *disp_info, gf_capture_t *capture); +void disp_wb_event_handler(disp_info_t *disp_info, gf_capture_t *capture, gf_capture_event_t event); +void disp_wb_work_func(struct work_struct *work); + +static gf_capture_desc gf_wb_descs[] = +{ + { + .cf_fmt_id = GF_CAPTURE_WB1, + .cf_name = "WB1" + }, + { + .cf_fmt_id = GF_CAPTURE_WB2, + .cf_name = "WB2" + }, + { + .cf_fmt_id = GF_CAPTURE_WB3, + .cf_name = "WB3" + }, + { + .cf_fmt_id = GF_CAPTURE_WB4, + .cf_name = "WB4" + } +}; + +static unsigned char cf_id2iga(gf_capture_id_t cf_fmt_id) +{ + if (cf_fmt_id == GF_CAPTURE_WB1) + { + return IGA1; + } + + if (cf_fmt_id == GF_CAPTURE_WB2) + { + return IGA2; + } + + if (cf_fmt_id == GF_CAPTURE_WB3) + { + return IGA3; + } + + if (cf_fmt_id == GF_CAPTURE_WB4) + { + return IGA4; + } + + return -1; +} + +void disp_register_wb_capture(disp_info_t *disp_info) +{ + gf_capture_t *capture = NULL; + int i = 0; + + for (i = 0; i < sizeof(gf_wb_descs) / sizeof(gf_capture_desc); i++) + { + capture = (gf_capture_t *)gf_calloc(sizeof(gf_capture_t)); + capture->cf_fmt_id = gf_wb_descs[i].cf_fmt_id; + capture->cf_name = gf_wb_descs[i].cf_name; + capture->cf_ctl = disp_wb_ops; + capture->notify_interrupt = disp_wb_notify_interrupt; + capture->event_handler = disp_wb_event_handler; + disp_register_capture(disp_info, capture); + } +} + +void disp_unregister_wb_capture(disp_info_t *disp_info) +{ + gf_capture_t *capture = NULL; + int i = 0; + + for (i = 0; i < sizeof(gf_wb_descs) / sizeof(gf_capture_desc); i++) + { + capture = disp_find_capture(disp_info, gf_wb_descs[i].cf_fmt_id); + if (capture) + { + disp_unregister_capture(disp_info, capture); + gf_free(capture); + } + } +} + +int disp_wb_capture_init(gf_capture_t *capture, wb_op_params_t *mparams) +{ + wb_spec_info_t *info; + + capture->priv_info = gf_calloc(sizeof(wb_spec_info_t)); + + info = (wb_spec_info_t *)capture->priv_info; + + info->mcapture = capture; + info->iga = cf_id2iga(capture->cf_fmt_id); + + INIT_WORK(&info->wb_work, disp_wb_work_func); + + capture->flags |= CAPTURE_INIT_B; + + capture->flags |= CAPTURE_NEED_SKIP_B; + + gf_info("capture %s init\n", capture->cf_name); + + return 0; +} + +int disp_wb_capture_deinit(gf_capture_t *capture, wb_op_params_t *mparams) +{ + wb_spec_info_t *info = (wb_spec_info_t *)capture->priv_info; + + capture->flags &= ~CAPTURE_INIT_B; + + cancel_work_sync(&info->wb_work); + + gf_free(capture->priv_info); + capture->priv_info = NULL; + + gf_info("capture %s deinit \n", capture->cf_name); + + return 0; +} + +int disp_wb_query_caps(disp_info_t *disp_info, gf_capture_t *capture, wb_op_params_t *mparams) +{ + wb_spec_info_t *info = (wb_spec_info_t *)capture->priv_info; + gf_wb_set_t wb_set = {0}; + int status = 0; + + wb_set.iga_idx = info->iga; + wb_set.op_flags = GF_WB_QUERY_CAPS; + + status = disp_cbios_wb_ctl(disp_info, &wb_set); + + mparams->query_caps_param.width = wb_set.input_mode.src_x; + mparams->query_caps_param.height = wb_set.input_mode.src_y; + mparams->query_caps_param.refrate = wb_set.input_mode.refreshrate; + mparams->query_caps_param.capture_fmt = wb_set.input_mode.capture_fmt; + + if (status) + { + gf_error("capture %s query caps failed!! \n", capture->cf_name); + } + else + { + gf_info("capture %s query mode\n", capture->cf_name); + } + + + return status; +} + + +int disp_wb_set_buffer(disp_info_t *disp_info, gf_capture_t *capture, wb_op_params_t *mparams) +{ + wb_spec_info_t *info = (wb_spec_info_t *)capture->priv_info; + gf_wb_set_t wb_set = {0}; + + int status = 0; + + if (info->wb_status & GF_WB_MODE_BYPASS_S) + { + wb_set.op_flags |= GF_WB_SET_BYPASS_MODE; + } + + if (info->wb_status & GF_WB_VSYNC_OFF_S) + { + wb_set.op_flags |= GF_WB_SET_VSYNC_OFF; + } + + wb_set.iga_idx = info->iga; + wb_set.op_flags |= GF_WB_SET_BUFFER; + wb_set.fb.fb_addr = mparams->set_buffer_param.fbAddr; + + status = disp_cbios_wb_ctl(disp_info, &wb_set); + + if (status) + { + gf_error("capture %s set buffer failed!! \n", capture->cf_name); + } + else + { + //gf_info("capture %s set buffer, buf %x \n", capture->cf_name, mparams->set_buffer_param.fbAddr); + } + + return status; +} + + +int disp_wb_set_mode(disp_info_t *disp_info, gf_capture_t *capture, wb_op_params_t *mparams) +{ + wb_spec_info_t *info = (wb_spec_info_t *)capture->priv_info; + int status = 0; + + info->wb_status |= GF_WB_MODE_SETTING_S; + + if (mparams->set_mode_param.bByPass) + { + info->wb_status |= GF_WB_MODE_BYPASS_S; + } + + if (mparams->set_mode_param.bUpdateImme) + { + info->wb_status |= GF_WB_VSYNC_OFF_S; + } + + info->mode_set.src_x = mparams->set_mode_param.srcX; + info->mode_set.src_y = mparams->set_mode_param.srcY; + info->mode_set.out_fmt = mparams->set_mode_param.outFmt; + info->mode_set.work_mode = mparams->set_mode_param.mode; + info->mode_set.dst_x = mparams->set_mode_param.dstX; + info->mode_set.dst_y = mparams->set_mode_param.dstY; + info->mode_set.double_buf = mparams->set_mode_param.bDoubleBuffer; + + if (status) + { + gf_error("capture %s set mode failed!! \n", capture->cf_name); + } + else + { + gf_info("capture %s set mode\n", capture->cf_name); + } + + + return status; +} + + +int disp_wb_capture_enable(disp_info_t *disp_info, gf_capture_t *capture, wb_op_params_t *mparams) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* dev = gf_card->drm_dev; + struct drm_crtc* crtc = NULL; + wb_spec_info_t *info = (wb_spec_info_t *)capture->priv_info; + gf_wb_set_t wb_set = {0}; + int status = 0; + + wb_set.iga_idx = info->iga; + wb_set.op_flags = GF_WB_ENABLE; + + if (info->wb_status & GF_WB_MODE_SETTING_S) + { + wb_set.op_flags |= GF_WB_SET_MODE; + info->wb_status &= ~GF_WB_MODE_SETTING_S; + gf_memcpy(&wb_set.mode, &info->mode_set, sizeof(gf_wb_mode_set_t)); + } + + if (info->wb_status & GF_WB_MODE_BYPASS_S) + { + wb_set.op_flags |= GF_WB_SET_BYPASS_MODE; + } + + if (info->wb_status & GF_WB_VSYNC_OFF_S) + { + wb_set.op_flags |= GF_WB_SET_VSYNC_OFF; + } + + status = disp_cbios_wb_ctl(disp_info, &wb_set); + + if (status) + { + gf_error("capture %s enable failed!! \n", capture->cf_name); + } + else + { + capture->flags |= CAPTURE_ENABLE_B; + gf_info("capture %s enable\n", capture->cf_name); + + //vblank off should be disabled after wb enable, because wb rely on vsync interrupt + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + { + if(to_gf_crtc(crtc)->pipe == info->iga) + { + drm_crtc_vblank_get(crtc); + break; + } + } + } + + return status; +} + +int disp_wb_capture_disable(disp_info_t *disp_info, gf_capture_t *capture, wb_op_params_t *mparams) +{ + gf_card_t* gf_card = disp_info->gf_card; + struct drm_device* dev = gf_card->drm_dev; + struct drm_crtc* crtc = NULL; + wb_spec_info_t *info = (wb_spec_info_t *)capture->priv_info; + gf_wb_set_t wb_set = {0}; + int status = 0; + + wb_set.iga_idx = info->iga; + wb_set.op_flags = GF_WB_DISABLE; + + status = disp_cbios_wb_ctl(disp_info, &wb_set); + + if (status) + { + gf_error("capture %s disable failed!! \n", capture->cf_name); + } + else + { + capture->flags &= ~CAPTURE_ENABLE_B; + gf_info("capture %s disable\n", capture->cf_name); + + //After wb disable, should enable vblank off + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + { + if(to_gf_crtc(crtc)->pipe == info->iga) + { + drm_crtc_vblank_put(crtc); + break; + } + } + } + + return status; +} + +void disp_wb_notify_interrupt(disp_info_t *disp_info, gf_capture_t *capture) +{ + wb_spec_info_t* info = (wb_spec_info_t *)capture->priv_info; + + schedule_work(&info->wb_work); +} + +void disp_wb_event_handler(disp_info_t *disp_info, gf_capture_t *capture, gf_capture_event_t event) +{ + wb_spec_info_t* info = (wb_spec_info_t *)capture->priv_info; + unsigned int flags = 0; + + + gf_info("capture %s, event: %d \n", capture->cf_name, event); + + if (info == NULL || info->cb == NULL) + { + return; + } + + if (GF_CAPTURE_EVENT_PLUG_OUT == event) + { + flags |= GF_CAPTURE_PLUG_OUT; + } + else if (GF_CAPTURE_EVENT_PLUG_IN == event) + { + flags |= GF_CAPTURE_PLUG_IN; + } + else if (GF_CAPTURE_EVENT_SIGNAL_OFF == event) + { + flags |= GF_CAPTURE_SIGNAL_OFF; + } + else if (GF_CAPTURE_EVENT_SIGNAL_ON == event) + { + flags |= GF_CAPTURE_SIGNAL_ON; + } + + info->cb(capture->cf_fmt_id, info->cb_data, flags); +} + +void disp_wb_work_func(struct work_struct *work) +{ + wb_spec_info_t* info = container_of(work, wb_spec_info_t, wb_work); + gf_capture_t* capture = info->mcapture; + unsigned int flags = 0; + + if (!(capture->flags & CAPTURE_ENABLE_B)) + { + return; + } + + flags |= GF_CAPTURE_SET_BUFFER; + + //the first capture should skip as it just triggered + if (capture->flags & CAPTURE_NEED_SKIP_B) + { + flags |= GF_CAPTURE_SKIP_FRAME; + capture->flags &= ~CAPTURE_NEED_SKIP_B; + } + + info->cb(capture->cf_fmt_id, info->cb_data, flags); +} + +int disp_wb_ops(disp_info_t *disp_info, gf_capture_t *capture, void *params) +{ + wb_op_params_t *mparams = (wb_op_params_t *)params; + + int status = 0; + + switch(mparams->op) + { + case GF_CAPTURE_OP_INIT: + { + status = disp_wb_capture_init(capture, mparams); + } + break; + + case GF_CAPTURE_OP_DEINIT: + { + status = disp_wb_capture_deinit(capture, mparams); + } + break; + + case GF_CAPTURE_OP_ENABLE: + { + status = disp_wb_capture_enable(disp_info, capture, mparams); + } + break; + + case GF_CAPTURE_OP_DISABLE: + { + status = disp_wb_capture_disable(disp_info, capture, mparams); + } + break; + + case GF_CAPTURE_OP_QUERY_CAPS: + { + status = disp_wb_query_caps(disp_info, capture, mparams); + } + break; + + case GF_CAPTURE_OP_SET_MODE: + { + status = disp_wb_set_mode(disp_info, capture, mparams); + } + break; + + case GF_CAPTURE_OP_SET_BUFF: + { + status = disp_wb_set_buffer(disp_info, capture, mparams); + } + break; + + case GF_CAPTURE_OP_SET_CALLBACK: + { + wb_spec_info_t *info = (wb_spec_info_t *)capture->priv_info; + info->cb = mparams->set_callback_param.cb; + info->cb_data = mparams->set_callback_param.cb_data; + } + break; + + default: + { + gf_error("op not support on write back\n"); + } + break; + } + + return status; +} diff --git a/drivers/gpu/drm/arise/linux/gf_wb.h b/drivers/gpu/drm/arise/linux/gf_wb.h new file mode 100644 index 0000000000000..4c79bd334456d --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_wb.h @@ -0,0 +1,84 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_WB_H_ +#define __GF_WB_H_ + +#include "gf_capture_drv.h" + +#define GF_WB_ENABLE (0x1 << 0) +#define GF_WB_DISABLE (0x1 << 1) +#define GF_WB_SET_MODE (0x1 << 2) +#define GF_WB_SET_BUFFER (0x1 << 3) +#define GF_WB_QUERY_CAPS (0x1 << 4) +#define GF_WB_SET_BYPASS_MODE (0x1 << 5) +#define GF_WB_SET_DOWNSCALER_MODE (0x1 << 6) +#define GF_WB_SET_VSYNC_OFF (0x1 << 7) + +#define GF_WB_MODE_SETTING_S (0x1 << 0) +#define GF_WB_MODE_BYPASS_S (0x1 << 1) +#define GF_WB_VSYNC_OFF_S (0x1 << 2) + + +#define GF_CAPTURE_WB_INTERFACE + +typedef struct +{ + unsigned int src_x; + unsigned int src_y; + unsigned int out_fmt; + unsigned int work_mode; + unsigned int dst_x; + unsigned int dst_y; + unsigned int double_buf; +}gf_wb_mode_set_t; + +typedef struct +{ + gf_capture_t *mcapture; + unsigned char iga; + void (*cb)(gf_capture_id_t id, void *data, unsigned int flags); + void *cb_data; + gf_wb_mode_set_t mode_set; + unsigned int wb_status; + struct work_struct wb_work; +}wb_spec_info_t; + + +typedef struct +{ + unsigned int op_flags; + unsigned char iga_idx; + union{ + gf_wb_mode_set_t mode; + + struct + { + unsigned int src_x; + unsigned int src_y; + unsigned int refreshrate; + unsigned int capture_fmt; + }input_mode; + + struct + { + unsigned long long fb_addr; + }fb; + }; +}gf_wb_set_t; + +void disp_register_wb_capture(disp_info_t *disp_info); +void disp_unregister_wb_capture(disp_info_t *disp_info); + +#endif diff --git a/drivers/gpu/drm/arise/linux/os_interface.c b/drivers/gpu/drm/arise/linux/os_interface.c new file mode 100644 index 0000000000000..48045b9766aa7 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/os_interface.c @@ -0,0 +1,2366 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "os_interface.h" +#include "gf.h" +#include "gf_driver.h" +#include "gf_params.h" +#include "gf_version.h" + + + +#define __STR(x) #x +#define STR(x) __STR(x) + +/* globals constants */ +const unsigned int GF_PAGE_SHIFT = PAGE_SHIFT; +#ifndef __frv__ +const unsigned int GF_PAGE_SIZE = PAGE_SIZE; +#else +const unsigned int GF_PAGE_SIZE = 0x1000; +#endif +const unsigned long GF_PAGE_MASK = PAGE_MASK; +const unsigned long GF_LINUX_VERSION_CODE = LINUX_VERSION_CODE; + + +char *gf_mem_track_result_path = "/var/log/gf-mem-track.txt"; + +void gf_udelay(unsigned long long usecs_num) +{ + unsigned long long msecs = usecs_num; + unsigned long usecs = do_div(msecs, 1000); + + if(msecs != 0)mdelay(msecs); + if(usecs != 0)udelay(usecs); +} + +unsigned long long gf_do_div(unsigned long long x, unsigned long long y) +{ + do_div(x, y); + return x; +} + +void gf_msleep(int num) +{ + msleep(num); +} + +void gf_getsecs(long *secs, long *usecs) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) + struct timespec64 tv = {0}; + ktime_get_ts64(&tv); +#else + struct timespec tv = {0}; + + //do_posix_clock_monotonic_gettime(&tv); + ktime_get_ts(&tv); +#endif + + if (secs) + { + *secs = tv.tv_sec; + } + + if (usecs) + { + *usecs= tv.tv_nsec/1000; + } + return; +} + +void gf_get_nsecs(unsigned long long *nsec) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) + struct timespec64 tv = {0}; + ktime_get_ts64(&tv); +#else + struct timespec tv = {0}; + + //do_posix_clock_monotonic_gettime(&tv); + ktime_get_ts(&tv); +#endif + + *nsec = (unsigned long long)(tv.tv_sec) * 1000000000 + tv.tv_nsec; + + return; +} + + +void gf_usleep_range(long min, long max) +{ + usleep_range(min, max); +} + +void gf_assert(int match, const char *msg) +{ + if(!match) + { + if(msg) + { + gf_info("%s\n", msg); + } + BUG(); + } +} + +void gf_dump_stack(void) +{ + dump_stack(); +} + +int GF_API_CALL gf_copy_from_user(void* to, const void* from, unsigned long size) +{ + return copy_from_user(to, from, size); +} + +int GF_API_CALL gf_copy_to_user(void* to, const void* from, unsigned long size) +{ + return copy_to_user(to, from, size); +} + +void* GF_API_CALL gf_memset(void* s, int c, unsigned long count) +{ +#if defined(__aarch64__) + //aarch net support device memory memset, need more study. + + int i; + char* set; + + set = (char*)s; + + for(i=0;ifilp = filp_open(path, o_flags, mode); + + if(IS_ERR(file->filp)) + { + gf_error("open file %s failed %ld.\n", path, PTR_ERR(file->filp)); + + gf_free(file); + + file = NULL; + } + + return file; +} + +void gf_file_close(struct os_file *file) +{ + filp_close(file->filp, current->files); + + gf_free(file); +} + +int gf_file_read(struct os_file *file, void *buf, unsigned long size, unsigned long long *read_pos) +{ + struct file *filp = file->filp; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + mm_segment_t oldfs = get_fs(); +#endif + loff_t pos = 0; + int len = 0; + + if(read_pos) + { + pos = *read_pos; + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + set_fs(KERNEL_DS); + len = vfs_read(filp, buf, size, &pos); + set_fs(oldfs); +#else + len = kernel_read(filp, buf, size, &pos); +#endif + + if(read_pos) + { + *read_pos = pos; + } + + return len; +} + +int gf_file_write(struct os_file *file, void *buf, unsigned long size) +{ + struct file *filp = file->filp; + int len = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + mm_segment_t oldfs = get_fs(); + set_fs(KERNEL_DS); + len = vfs_write(filp, buf, size, &filp->f_pos); + set_fs(oldfs); +#else + len = kernel_write(filp, buf, size, &filp->f_pos); +#endif + return len; +} + +/*****************************************************************************/ +int GF_API_CALL gf_vsprintf(char *buf, const char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + + ret = vsprintf(buf, fmt, args); + + va_end(args); + + return ret; +} + +int GF_API_CALL gf_vsnprintf(char *buf, unsigned long size, const char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + + ret = vsnprintf(buf, size, fmt, args); + + va_end(args); + + return ret; +} + +int GF_API_CALL gf_sscanf(char *buf, char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + + ret = vsscanf(buf, fmt, args); + + va_end(args); + + return ret; +} + + +void GF_API_CALL gf_cb_printk(const char* msg) +{ + if(msg) + { + printk("%s", msg); + } +} + +void GF_API_CALL gf_printk(unsigned int msglevel, const char* fmt, ...) +{ + char buffer[256]; + va_list marker; + + if(msglevel >= GF_MSG_LEVEL) + { + va_start(marker, fmt); + vsnprintf(buffer, 256, fmt, marker); + va_end(marker); + + switch ( msglevel ) + { + case GF_DRV_DEBUG: + printk(KERN_DEBUG"%s debug: %s", STR(DRIVER_NAME), buffer); + break; + case GF_DRV_WARNING: + printk(KERN_WARNING"%s warning: %s", STR(DRIVER_NAME), buffer); + break; + case GF_DRV_INFO: + printk(KERN_INFO"%s info: %s", STR(DRIVER_NAME), buffer); + break; + case GF_DRV_ERROR: + printk(KERN_ERR"%s warning: %s", STR(DRIVER_NAME), buffer); + break; + case GF_DRV_EMERG: + printk(KERN_EMERG"%s warning: %s", STR(DRIVER_NAME), buffer); + break; + default: + /* invalidate message level */ + gf_assert(0, NULL); + break; + } + } +} + +#define GF_MAX_KMALLOC_SIZE 32 * 1024 + +void* gf_malloc_priv(unsigned long size) +{ + void* addr = NULL; + + if(size <= GF_MAX_KMALLOC_SIZE) + { + addr = kmalloc(size, GFP_KERNEL); + } + + if(addr == NULL) + { + addr = vmalloc(size); + } + + return addr; +} + +void* gf_calloc_priv(unsigned long size) +{ + void* addr = gf_malloc_priv(size); + if(addr != NULL) + { + memset(addr, 0, size); + } + return addr; +} + +void gf_free_priv(void* addr) +{ + unsigned long addr_l = (unsigned long)addr; + if(addr == NULL) return; + +#ifndef __frv__ + if(addr_l >= VMALLOC_START && addr_l < VMALLOC_END) + { + vfree(addr); + } + else + { + kfree(addr); + } +#else + kfree(addr); +#endif + +} + +/* bit ops */ +int gf_find_first_zero_bit(void *buf, unsigned int size) +{ + return find_first_zero_bit(buf, size); +} + +int gf_find_next_zero_bit(void *buf, unsigned int size, int offset) +{ + int pos = find_next_zero_bit(buf, size, offset); + + if(pos >= size) + { + pos = find_next_zero_bit(buf, size, 0); + } + + return pos; +} + +void gf_set_bit(unsigned int nr, void *buf) +{ + set_bit(nr, buf); +} + +void gf_clear_bit(unsigned int nr, void *buf) +{ + clear_bit(nr, buf); +} + +static void *gf_do_mmap(struct file *filp, gf_map_argu_t *map) +{ + struct drm_file *drm_file = filp->private_data; + gf_file_t *priv = drm_file->driver_priv; + void *virtual = NULL; + phys_addr_t phys_addr = 0; + + if(map->flags.mem_type == GF_SYSTEM_IO) + { + /*Since the PA to be mapped in kernel always cpu visiable, whcih means the PA is in kernel range, + * loss accuracy caused by [u32 <-- unsigned long long] will not happen. + */ + phys_addr = map->phys_addr; + } + + gf_mutex_lock(priv->lock); + +#ifdef HAS_VM_MMAP + priv->map = map; + + virtual = (void *)vm_mmap(filp, 0, map->size, PROT_READ | PROT_WRITE, MAP_SHARED, phys_addr); + + priv->map = NULL; +#else + down_write(¤t->mm->mmap_sem); + + priv->map = map; + + virtual = (void *)do_mmap(filp, 0, map->size, PROT_READ | PROT_WRITE, MAP_SHARED, phys_addr); + + priv->map = NULL; + + up_write(¤t->mm->mmap_sem); +#endif + + gf_mutex_unlock(priv->lock); + + return virtual; +} + +static int gf_do_munmap(gf_vm_area_t *vma) +{ + int ret = 0; + + if(current->mm) + { +#ifdef HAS_VM_MMAP + ret = vm_munmap((unsigned long)vma->virt_addr, vma->size); +#else + down_write(¤t->mm->mmap_sem); + + ret = do_munmap(current->mm, (unsigned long)vma->virt_addr, vma->size); + + up_write(¤t->mm->mmap_sem); +#endif + } + + return ret; +} + +struct os_atomic *gf_create_atomic(int val) +{ + struct os_atomic *atomic = gf_calloc(sizeof(struct os_atomic)); + + if(atomic) + { + atomic_set(&atomic->counter, val); + } + + return atomic; +} + +void gf_destroy_atomic(struct os_atomic *atomic) +{ + gf_free(atomic); +} + +int gf_atomic_read(struct os_atomic *atomic) +{ + return atomic_read(&atomic->counter); +} + +void gf_atomic_inc(struct os_atomic *atomic) +{ + return atomic_inc(&atomic->counter); +} + +void gf_atomic_dec(struct os_atomic *atomic) +{ + return atomic_dec(&atomic->counter); +} + +int gf_atomic_add(struct os_atomic *atomic, int v) +{ + return atomic_add_return(v, &atomic->counter); +} + +int gf_atomic_sub(struct os_atomic *atomic, int v) +{ + return atomic_sub_return(v, &atomic->counter); +} + +struct os_mutex *gf_create_mutex(void) +{ + struct os_mutex *mutex = gf_calloc(sizeof(struct os_mutex)); + + if(mutex) + { + mutex_init(&mutex->lock); + } + return mutex; +} + +void gf_destroy_mutex(struct os_mutex *mutex) +{ + if(mutex) + { + gf_free(mutex); + } +} + +void gf_mutex_lock(struct os_mutex *mutex) +{ + mutex_lock(&mutex->lock); +} + +int gf_mutex_lock_killable(struct os_mutex *mutex) +{ + return mutex_lock_killable(&mutex->lock); +} + +int gf_mutex_trylock(struct os_mutex *mutex) +{ + int status = GF_LOCKED; + + if(!mutex_trylock(&mutex->lock)) + { + status = GF_LOCK_FAILED; + } + + return status; +} + +void gf_mutex_unlock(struct os_mutex *mutex) +{ + mutex_unlock(&mutex->lock); +} + +struct os_sema *gf_create_sema(int val) +{ + struct os_sema *sem = gf_calloc(sizeof(struct os_sema)); + + if(sem != NULL) + { + sema_init(&sem->lock, val); + } + + return sem; +} + +void gf_destroy_sema(struct os_sema *sem) +{ + gf_free(sem); +} + +void gf_down(struct os_sema *sem) +{ + down(&sem->lock); +} + +int gf_down_trylock(struct os_sema *sem) +{ + int status = GF_LOCKED; + + if(down_trylock(&sem->lock)) + { + status = GF_LOCK_FAILED; + } + + return status; +} + +void gf_up(struct os_sema *sem) +{ + up(&sem->lock); +} + +struct os_rwsema *gf_create_rwsema(void) +{ + struct os_rwsema *sem = gf_calloc(sizeof(struct os_rwsema)); + + if(sem != NULL) + { + init_rwsem(&sem->lock); + } + + return sem; +} + +void gf_destroy_rwsema(struct os_rwsema *sem) +{ + gf_free(sem); +} + +void gf_down_read(struct os_rwsema *sem) +{ + down_read(&sem->lock); +} + +void gf_down_write(struct os_rwsema *sem) +{ + down_write(&sem->lock); +} + +void gf_up_read(struct os_rwsema *sem) +{ + up_read(&sem->lock); +} + +void gf_up_write(struct os_rwsema *sem) +{ + up_write(&sem->lock); +} + +struct os_spinlock *gf_create_spinlock(int type) +{ + struct os_spinlock *spin = gf_calloc(sizeof(struct os_spinlock)); + + if(spin != NULL) + { + spin_lock_init(&spin->lock); + } + + return spin; +} + +void gf_destroy_spinlock(struct os_spinlock *spin) +{ + if(spin_is_locked(&spin->lock)) + { + spin_unlock(&spin->lock); + } + + gf_free(spin); +} + +int gf_spin_try_lock(struct os_spinlock *spin) +{ + + int status = GF_LOCK_FAILED; + + if(spin_trylock(&spin->lock)) + { + status = GF_LOCKED; + } + + return status; + +} +void gf_spin_lock(struct os_spinlock *spin) +{ + spin_lock(&spin->lock); +} + +void gf_spin_unlock(struct os_spinlock *spin) +{ + spin_unlock(&spin->lock); +} + +unsigned long gf_spin_lock_irqsave(struct os_spinlock *spin) +{ + unsigned long flags; + + spin_lock_irqsave(&spin->lock, flags); + + return flags; +} + +void gf_spin_unlock_irqrestore(struct os_spinlock *spin, unsigned long flags) +{ + spin_unlock_irqrestore(&spin->lock, flags); +} + +struct os_wait_queue* gf_create_wait_queue(void) +{ + struct os_wait_queue *queue = gf_calloc(sizeof(struct os_wait_queue)); + if(queue) + { + init_waitqueue_head(&queue->wait_queue); + } + + return queue; + +} + +struct os_wait_event* gf_create_event(int task_id) +{ + struct os_wait_event *event = gf_calloc(sizeof(struct os_wait_event)); + + if(event) + { + atomic_set(&event->state, 0); + init_waitqueue_head(&event->wait_queue); + } + + return event; +} + +void gf_destroy_event(void *event) +{ + if(event) + { + gf_free(event); + } +} + +gf_event_status_t gf_wait_event_thread_safe(struct os_wait_event *event, condition_func_t condition, void *argu, int msec) +{ + gf_event_status_t status = GF_EVENT_UNKNOWN; + + if(msec) + { + long timeout = msecs_to_jiffies(msec); + + timeout = wait_event_timeout(event->wait_queue, (*condition)(argu), timeout); + + if(timeout > 0) + { + status = GF_EVENT_BACK; + } + else if(timeout == 0) + { + status = GF_EVENT_TIMEOUT; + } + else if(timeout == -ERESTARTSYS) + { + status = GF_EVENT_SIGNAL; + } + } + else + { + wait_event(event->wait_queue, (*condition)(argu)); + status = GF_EVENT_BACK; + } + + return status; +} + +static int gf_generic_condition_func(void *argu) +{ + struct os_wait_event *event = argu; + + return atomic_xchg(&event->state, 0); +} + +static int event_condition(void** events, int cnt, wakeup_event *wakeup) +{ + struct general_wait_event ** p_events = (struct general_wait_event **)events; + int wake = FALSE; + int i = 0; + + if(cnt > WAIT_EVENT_MAX) + cnt = WAIT_EVENT_MAX; + + for(i = 0; i < cnt; i++) + { + if(p_events[i]->event) + { + wake = TRUE; + break; + } + } + + if(wake) + { + (*wakeup) = WAIT_EVENT0 + i; + } + else + { + (*wakeup) = WAIT_EVENT_MAX; + } + return wake; +} + +gf_event_status_t gf_wait_event(struct os_wait_event *event, int msec) +{ + return gf_wait_event_thread_safe(event, &gf_generic_condition_func, event, msec); +} + +void gf_wake_up_event(struct os_wait_event *event) +{ + atomic_set(&event->state, 1); + wake_up(&event->wait_queue); +} + +void* gf_create_thread(gf_thread_func_t func, void *data, const char *thread_name) +{ + struct task_struct* thread; + struct sched_param param = {.sched_priority = 99}; + + thread = (struct task_struct*)kthread_run(func, data, thread_name); +#if DRM_VERSION_CODE < KERNEL_VERSION(5,9,0) + sched_setscheduler(thread, SCHED_RR, ¶m); +#else + sched_set_fifo(thread); +#endif + + return thread; +} + +void gf_destroy_thread(void* thread) +{ + if(thread) + { + kthread_stop(thread); + } +} + +int gf_thread_should_stop(void) +{ + return kthread_should_stop(); +} + +gf_event_status_t gf_thread_wait(struct os_wait_event *event, int msec) +{ + gf_event_status_t status = GF_EVENT_UNKNOWN; + + if(msec) + { + long timeout = msecs_to_jiffies(msec); + + timeout = wait_event_interruptible_timeout(event->wait_queue, + gf_generic_condition_func(event) || freezing(current) || kthread_should_stop(), + timeout); + + if(timeout > 0) + { + status = GF_EVENT_BACK; + } + else if(timeout == 0) + { + status = GF_EVENT_TIMEOUT; + } + else if(timeout == -ERESTARTSYS) + { + status = GF_EVENT_SIGNAL; + } + } + else + { + int ret = wait_event_interruptible(event->wait_queue, + gf_generic_condition_func(event) || freezing(current) || kthread_should_stop()); + + if(ret == 0) + { + status = GF_EVENT_BACK; + } + else if(ret == -ERESTARTSYS) + { + status = GF_EVENT_SIGNAL; + } + } + + return status; +} + +void gf_thread_wake_up(struct os_wait_event *event) +{ + atomic_set(&event->state, 1); + wake_up_interruptible(&event->wait_queue); +} + +int gf_try_to_freeze(void) +{ +#ifdef CONFIG_PM_SLEEP + return try_to_freeze(); +#else + return 0; +#endif +} + +int gf_freezable(void) +{ + return !(current->flags & PF_NOFREEZE); +} + +void gf_clear_freezable(void) +{ + current->flags |= PF_NOFREEZE; +} + +void gf_old_set_freezable(void) +{ + current->flags &= ~PF_NOFREEZE; +} + +void gf_set_freezable(void) +{ +#ifdef CONFIG_PM_SLEEP + set_freezable(); +#else + current->flags &= ~PF_NOFREEZE; +#endif +} + +int gf_freezing(void) +{ + return freezing(current); +} + +unsigned long gf_get_current_pid(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + return (unsigned long)current->tgid; +#else + return (unsigned long)current; +#endif +} + +unsigned long gf_get_current_tid(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + return current->pid; +#else + return (unsigned long)current; +#endif +} + +void gf_get_current_pname(char *pname, int size) +{ + char buf[TASK_COMM_LEN]; + + get_task_comm(buf, current); + + gf_strncpy(pname, buf, size); +} + +void gf_dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) +{ + unsigned long long len; + unsigned long addr = (unsigned long)vaddr; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + dma_cache_sync(dev, vaddr, size, direction); +#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) +#if defined(__mips64__) || defined(__loongarch__) + for (len = 0; len < size; len += PAGE_SIZE) + { + flush_data_cache_page(addr); + addr += PAGE_SIZE; + } +#endif +#endif +} + +static void gf_flush_page_cache(struct device *dev, struct page *pages, unsigned int flush_size) +{ +#if defined(__mips64__) || defined(__loongarch__) + int page_count = flush_size/PAGE_SIZE; + void *ptr; + + while(page_count--) + { + ptr = kmap(pages); + //dma_cache_wback_inv + gf_dma_cache_sync(dev, ptr, PAGE_SIZE, DMA_BIDIRECTIONAL); + kunmap(pages); + pages++; + } +#elif !defined(CONFIG_X86) + int page_count = flush_size/PAGE_SIZE; + void *ptr; + + while(page_count--) + { + ptr = kmap(pages); +#if __ARM_ARCH >= 8 + flush_icache_range((unsigned long)ptr, (unsigned long)(ptr+PAGE_SIZE)); +#else + dmac_flush_range(ptr, ptr + PAGE_SIZE); + outer_flush_range(page_to_phys(pages), page_to_phys(pages) + PAGE_SIZE); +#endif + kunmap(pages); + pages++; + } +#else + int page_count = flush_size/PAGE_SIZE; + unsigned long ptr; + pte_t *pte; + unsigned int level; + while(page_count--) + { + if(PageHighMem(pages)) + ptr = (unsigned long)kmap(pages); + else + ptr = (unsigned long)page_address(pages); + + pte = lookup_address(ptr,&level); + + if(pte&& (pte_val(*pte)& _PAGE_PRESENT)) + { + clflush_cache_range((void*)ptr,PAGE_SIZE); + } + + if(PageHighMem(pages)) + kunmap(pages); + + pages++; + } + +#endif +} + +static void gf_free_st_internal(struct device *dev, struct sg_table *st, bool userptr, bool need_dma_unmap) +{ + struct scatterlist *sg; + struct sg_page_iter sg_iter; + + if (need_dma_unmap) + { + dma_unmap_sg(dev, st->sgl, st->nents, DMA_BIDIRECTIONAL); + } + if (userptr) + { + for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) + { + struct page *page = sg_page_iter_page(&sg_iter); + put_page(page); + } + } + else + { + for (sg = st->sgl; sg; sg = sg_next(sg)) + { + __free_pages(sg_page(sg), get_order(sg->length)); + } + } + + sg_free_table(st); + gf_free(st); +} + +void gf_free_pages_memory_priv(void *pdev, struct os_pages_memory *memory) +{ + int i; + int page_cnt; + int pg_arr_index = 0; + struct pci_dev *pci_dev = pdev; + + if(memory == NULL) + { + return; + } + page_cnt = memory->size / PAGE_SIZE; + +#ifdef CONFIG_X86_PAT +#ifdef HAS_SET_PAGES_ARRAY_WC + for (i = 0; i < page_cnt; i++) { + if (memory->cache_type_per_page[i] != GF_MEM_WRITE_BACK) { + memory->pages_temp[pg_arr_index++] = memory->pages[i]; + } + } + set_pages_array_wb(memory->pages_temp, pg_arr_index); +#else + for (i = 0; i < page_cnt; i++) { + if (memory->cache_type_per_page[i] != GF_MEM_WRITE_BACK) { + struct page *pg = memory->pages[i]; + set_memory_wb((unsigned long)page_address(pg), 1); + } + } +#endif +#endif + + /* shared means this pages was import from other, shouldn't free!! */ + if (!memory->shared) { + gf_free_st_internal(&pci_dev->dev, memory->st, memory->userptr, memory->has_dma_map); + } + gf_free(memory); +} + +struct os_pages_memory* gf_allocate_pages_memory_struct(int page_cnt, struct sg_table *st) +{ + int ret, i; + int extra_size = sizeof(struct page*) * page_cnt * 2 + sizeof(char) * page_cnt; + struct os_pages_memory *memory = gf_calloc(sizeof(struct os_pages_memory) + extra_size); + + if (memory) + { + memory->pages = (void*)(memory + 1); + memory->pages_temp = memory->pages + page_cnt; + memory->cache_type_per_page = (char*)(memory->pages_temp + page_cnt); + if (st) + { + memory->st = st; + } + else + { + memory->st = gf_calloc(sizeof(*memory->st)); + ret = sg_alloc_table(memory->st, page_cnt, GFP_KERNEL); + if (ret < 0) + goto sg_alloc_failed; + } + #ifdef CONFIG_X86_PAT + if (GF_MEM_WRITE_BACK != 0) { + for(i = 0; i < page_cnt; i++) + memory->cache_type_per_page[i] = GF_MEM_WRITE_BACK; + } + #endif + } + return memory; +sg_alloc_failed: + gf_free(memory); + return NULL; +} + +void gf_pages_memory_extract_st(struct os_pages_memory *memory) +{ + int i = 0; + struct sg_page_iter sg_iter; + + for_each_sg_page(memory->st->sgl, &sg_iter, memory->st->nents, 0) + { + struct page *page = sg_page_iter_page(&sg_iter); + memory->pages[i] = page; + i++; + } +} + +//mips PAGE_SIZE is 16k, others is 4k, suppose max page is 2M. +#define MAX_ALLOC_ORDER ilog2((2*1024*1024/PAGE_SIZE)) + +// 2^order <= size +static int gf_get_alloc_order(int size) +{ + int order = get_order(size); + + if ((((1 << (order)) << PAGE_SHIFT) > size) && order) + order--; + + return order > MAX_ALLOC_ORDER ? MAX_ALLOC_ORDER : order; +} + +struct os_pages_memory *gf_allocate_pages_memory_priv(void *pdev, int size, int page_size, alloc_pages_flags_t alloc_flags) +{ + int rest_size; + int order; + int page_cnt = PAGE_ALIGN(size) / PAGE_SIZE; + struct page *page; + struct os_pages_memory *memory = NULL; + struct scatterlist *sg = NULL, *end_sg = NULL; + gfp_t gfp_mask = GFP_KERNEL; + struct pci_dev *pci_dev = pdev; + struct page **pages = NULL; + int *orders = NULL; + struct sg_table *st = NULL; + int n_pages = 0; + int i; + + if(size <= 0) + { + return NULL; + } + + pages = gf_calloc(page_cnt * sizeof(struct page *)); + orders = gf_calloc(page_cnt * sizeof(int)); + st = gf_calloc(sizeof(struct sg_table)); + + if(!pages || !orders || !st) + { + goto alloc_pages_failed; + } + + if (alloc_flags.need_zero) + { + gfp_mask |= __GFP_ZERO; + } + if (alloc_flags.dma32 && sizeof(dma_addr_t) == 8) + { + gfp_mask |= pci_dev->dev.coherent_dma_mask < DMA_BIT_MASK(32) ? GFP_DMA : GFP_DMA32; + } + else + { +#ifdef HAS_SET_PAGES_ARRAY_WC + gfp_mask |= __GFP_HIGHMEM; +#endif + } + + rest_size = PAGE_ALIGN(size); + order = gf_get_alloc_order(rest_size); + + while(rest_size > 0) + { + page = alloc_pages(gfp_mask | (order ? (__GFP_NORETRY | __GFP_NOWARN) : 0), order); + if (page == NULL) + { + if (order == 0) + goto alloc_pages_failed; + else + order--; + } + else + { + orders[n_pages] = order; + pages[n_pages++] = page; + + if (alloc_flags.need_flush) + gf_flush_page_cache(&pci_dev->dev, page, PAGE_SIZE << order); + rest_size -= (PAGE_SIZE << order); + if (rest_size > 0) + { + order = min(gf_get_alloc_order(rest_size), order); + } + } + } + + if(sg_alloc_table(st, n_pages, GFP_KERNEL)) + { + goto alloc_pages_failed; + } + + for_each_sg(st->sgl, sg, st->orig_nents, i) + { + sg_set_page(sg, pages[i], PAGE_SIZE << orders[i], 0); + end_sg = sg; + } + + sg_mark_end(end_sg); + + memory = gf_allocate_pages_memory_struct(page_cnt, st); + gf_assert(alloc_flags.fixed_page == TRUE, GF_FUNC_NAME(__func__)); + gf_assert(alloc_flags.page_4K_64K == FALSE, "only support 4K page yet"); + gf_assert(page_size == PAGE_SIZE, "only support 4K page yet"); + + memory->shared = FALSE; + memory->size = PAGE_ALIGN(size); + memory->fixed_page = alloc_flags.fixed_page; + memory->page_4K_64K = alloc_flags.page_4K_64K; + memory->page_size = memory->fixed_page ? PAGE_ALIGN(page_size) : 0; + memory->dma32 = alloc_flags.dma32; + memory->need_zero = alloc_flags.need_zero; + + sg = memory->st->sgl; + + gf_pages_memory_extract_st(memory); + + if (alloc_flags.need_dma_map) + { + memory->st->nents = dma_map_sg(&pci_dev->dev, memory->st->sgl, memory->st->orig_nents, DMA_BIDIRECTIONAL); + if (!memory->st->nents) + { + goto alloc_pages_failed; + } + memory->has_dma_map = 1; + if (0) + { + gf_info("alloc[%p] st:%p pages:%d size:0x%x nents:%d orig_nents:%d\n", + memory, memory->st, page_cnt, memory->size, memory->st->nents, memory->st->orig_nents); + for_each_sg(memory->st->sgl, sg, memory->st->nents, i) { + gf_info(" [%p] sg:%p i:%d pgcnt:%d off:%x length:%x dmalen:%x dma:[%llx ~ %llx] phys:%llx\n", + memory, sg, i, PAGE_ALIGN(sg->offset + sg_dma_len(sg)) >> PAGE_SHIFT, sg->offset, + sg->length, sg_dma_len(sg), sg_dma_address(sg), sg_dma_address(sg) + sg_dma_len(sg), sg_phys(sg)); + } + } + } + + gf_free(pages); + gf_free(orders); + return memory; +alloc_pages_failed: + gf_error("%s: alloc page failed, size:0x%x\n", __func__, size); + + if(pages) + { + gf_free(pages); + } + + if(orders) + { + gf_free(orders); + } + + if(st) + { + gf_free_st_internal(&pci_dev->dev, st, FALSE, memory ? memory->has_dma_map : FALSE); + } + + gf_free(memory); + return NULL; +} + +void gf_pages_memory_for_each_continues(struct os_pages_memory *memory, void *arg, + int (*cb)(void* arg, int page_start, int page_cnt, unsigned long long dma_addr)) +{ + int i; + int page_start = 0; + struct scatterlist *sg; + + for_each_sg(memory->st->sgl, sg, memory->st->nents, i) + { + unsigned int length = memory->has_dma_map ? sg_dma_len(sg) : sg->length; + int page_cnt = PAGE_ALIGN(sg->offset + length) >> PAGE_SHIFT; + + if (0 != cb(arg, page_start, page_cnt, memory->has_dma_map ? sg_dma_address(sg) : sg_phys(sg))) { + break; + } + page_start += page_cnt; + } +} + +static struct page** gf_acquire_os_pages(struct os_pages_memory *memory, unsigned int size, int m_offset, int *pg_cnt) +{ + unsigned int mapped_size = PAGE_ALIGN(size); + int pages_cnt = mapped_size / PAGE_SIZE; + int offset = _ALIGN_DOWN(m_offset, PAGE_SIZE); + + if (pg_cnt) + *pg_cnt = pages_cnt; + + return memory->pages + (offset / PAGE_SIZE); +} + +static void gf_release_os_pages(struct page **pages) +{ +} + +unsigned char gf_validate_page_cache(struct os_pages_memory *memory, int start_page, int end_page, unsigned char request_cache_type) +{ + int i; + int pg_arr_index = 0; +#ifdef CONFIG_X86_PAT +#ifdef HAS_SET_PAGES_ARRAY_WC + for (i = start_page; i < end_page; i++) + { + if (memory->cache_type_per_page[i] == GF_MEM_WRITE_BACK && request_cache_type != GF_MEM_WRITE_BACK) + { + memory->pages_temp[pg_arr_index++] = memory->pages[i]; + memory->cache_type_per_page[i] = request_cache_type; + } + } + if (pg_arr_index > 0) + { + if(request_cache_type == GF_MEM_WRITE_COMBINED) + { + set_pages_array_wc(memory->pages_temp, pg_arr_index); + } + else if(request_cache_type == GF_MEM_UNCACHED) + { + set_pages_array_uc(memory->pages_temp, pg_arr_index); + } + } +#else + for (i = start_page; i < end_page; i++) + { + if (memory->cache_type_per_page[i] == GF_MEM_WRITE_BACK && request_cache_type != GF_MEM_WRITE_BACK) + { + struct page* pg = memory->pages[i]; + if(request_cache_type == GF_MEM_WRITE_COMBINED) + { + set_memory_wc((unsigned long)page_address(pg), 1); + } + else if(request_cache_type == GF_MEM_UNCACHED) + { + set_memory_uc((unsigned long)page_address(pg), 1); + } + memory->cache_type_per_page[i] = request_cache_type; + } + } +#endif +#endif + +#if defined(__aarch64__) + //only map arm64 to write back because cache flush code is not ready. wb is safe for snoop path. + //now only enable snoop path in arm64. + return GF_MEM_WRITE_BACK; +// map_argu->flags.cache_type = GF_MEM_WRITE_COMBINED; +#endif + +#if defined(__mips64__) || defined(__loongarch__) + //force to GF_MEM_WRITE_BACK, but acqually prot will still be PAGE_KERNEL + //can not be other type, which will change prot to uncached and mips will random hang or blackscreen + return GF_MEM_WRITE_BACK; +#endif + + return request_cache_type; +} + +gf_vm_area_t *gf_map_pages_memory_priv(void *filp, gf_map_argu_t *map_argu) +{ + struct os_pages_memory *memory = map_argu->memory; + gf_vm_area_t *vm_area = gf_calloc(sizeof(gf_vm_area_t)); + struct drm_file *drm_file = filp; + int start = _ALIGN_DOWN(map_argu->offset, PAGE_SIZE) / PAGE_SIZE; + int end = start + PAGE_ALIGN(map_argu->size) / PAGE_SIZE; + + map_argu->flags.cache_type = gf_validate_page_cache(memory, start, end, map_argu->flags.cache_type); + + if(map_argu->flags.mem_space == GF_MEM_KERNEL) + { + pgprot_t prot = PAGE_KERNEL; + unsigned int cache_type = map_argu->flags.cache_type; + int page_cnt = 0; + struct page **pages; + + prot = os_get_pgprot_val(&cache_type, prot, 0); + + pages = gf_acquire_os_pages(memory, map_argu->size, map_argu->offset, &page_cnt); + + vm_area->flags.value = map_argu->flags.value; + vm_area->size = map_argu->size; + + vm_area->virt_addr = vmap(pages, page_cnt, VM_MAP, prot); + + gf_release_os_pages(pages); + } + else if(map_argu->flags.mem_space == GF_MEM_USER) + { + vm_area->size = map_argu->size; + vm_area->owner = gf_get_current_pid(); + vm_area->virt_addr = gf_do_mmap(drm_file->filp, map_argu); + vm_area->flags.value = map_argu->flags.value; + } + + return vm_area; +} + +void gf_unmap_pages_memory_priv(gf_vm_area_t *vm_area) +{ + if(vm_area->flags.mem_space == GF_MEM_KERNEL) + { + vunmap(vm_area->virt_addr); + } + else if(vm_area->flags.mem_space == GF_MEM_USER) + { + gf_do_munmap(vm_area); + } + + gf_free(vm_area); +} + + +void gf_flush_cache(void *pdev, gf_vm_area_t *vma, struct os_pages_memory* memory, unsigned int offset, unsigned int size) +{ +#ifdef CONFIG_X86 + struct page **acquired_pages; + struct page *pages; + unsigned long ptr; + pte_t *pte; + int page_start = offset/PAGE_SIZE; + int page_end = (offset + size -1)/PAGE_SIZE; + int page_start_offset = offset%PAGE_SIZE; + int page_end_offset = (offset + size -1)%PAGE_SIZE; + int i; + int page_count; + int level; + + if((offset % 32 != 0) || (size % 32 != 0) ) + { + gf_error("offset does not align to data cache line boundary(32B)"); + } + + gf_assert(size>0, "size>0" ); + gf_assert(offset+size <= memory->size, "offset+size <= memory->size"); + gf_assert(page_start <= page_end, "page_start <= page_end"); + + acquired_pages = gf_acquire_os_pages(memory, PAGE_SIZE*(page_end-page_start+1), 0, &page_count); + if(page_count != (page_end-page_start+1)) + { + gf_error("page count unequal, need to check!"); + } + + if(page_start == page_end) + { + pages = acquired_pages[0]; + ptr = (unsigned long)page_address(pages); + pte = lookup_address(ptr,&level); + if(pte&& (pte_val(*pte)& _PAGE_PRESENT)) + { + clflush_cache_range((void*)ptr+page_start_offset,page_end_offset-page_start_offset); + } + } + else + { + pages = acquired_pages[0]; + + ptr = (unsigned long)page_address(pages); + pte = lookup_address(ptr,&level); + if(pte&& (pte_val(*pte)& _PAGE_PRESENT)) + { + clflush_cache_range((void*)ptr+page_start_offset,PAGE_SIZE); + } + + pages = acquired_pages[page_end-page_start]; + + ptr = (unsigned long)page_address(pages); + pte = lookup_address(ptr,&level); + if(pte&& (pte_val(*pte)& _PAGE_PRESENT)) + { + clflush_cache_range((void*)ptr,page_end_offset); + } + } + + for(i = page_start+1 ; i <= page_end-1; i++) + { + pages = acquired_pages[i-page_start]; + + ptr = (unsigned long)page_address(pages); + pte = lookup_address(ptr,&level); + if(pte&& (pte_val(*pte)& _PAGE_PRESENT)) + { + clflush_cache_range((void*)ptr,PAGE_SIZE); + } + } + gf_release_os_pages(acquired_pages); + +#else + struct page **acquired_pages; + struct page *pages; + void *ptr; + int page_start = offset/PAGE_SIZE; + int page_end = (offset + size -1)/PAGE_SIZE; + int page_start_offset = offset%PAGE_SIZE; + int page_end_offset = (offset + size -1)%PAGE_SIZE; + int i; + int page_count; + struct device *dev = &((struct pci_dev *)pdev)->dev; + + if((offset % 32 != 0) || (size % 32 != 0) ) + { + gf_error("offset does not align to data cache line boundary(32B)"); + } + + gf_assert(size>0, "size>0"); + gf_assert(offset+size <= memory->size, "offset+size <= memory->size"); + gf_assert(page_start <= page_end, "page_start <= page_end"); + + acquired_pages = gf_acquire_os_pages(memory, PAGE_SIZE*(page_end-page_start+1), 0, &page_count); + if(page_count != (page_end-page_start+1)) + { + gf_error("page count unequal, need to check!"); + } + + if(page_start == page_end) + { + pages = acquired_pages[0]; + ptr = kmap(pages); +#if defined(__mips64__) || defined(__loongarch__) + gf_dma_cache_sync(dev, ptr + page_start_offset, page_end_offset - page_start_offset, DMA_BIDIRECTIONAL); +#elif __ARM_ARCH >= 8 + flush_icache_range((unsigned long)(ptr + page_start_offset), (unsigned long)(ptr + page_end_offset)); +#else + dmac_flush_range(ptr + page_start_offset, ptr + page_end_offset); + outer_flush_range(page_to_phys(pages) + page_start_offset, page_to_phys(pages) + page_end_offset); +#endif + kunmap(pages); + } + else + { + pages = acquired_pages[0]; + ptr = kmap(pages); +#if defined(__mips64__) || defined(__loongarch__) + gf_dma_cache_sync(dev, ptr + page_start_offset, PAGE_SIZE - page_start_offset, DMA_BIDIRECTIONAL); +#elif __ARM_ARCH >= 8 + flush_icache_range((unsigned long)(ptr + page_start_offset), (unsigned long)(ptr + PAGE_SIZE)); +#else + dmac_flush_range(ptr + page_start_offset, ptr + PAGE_SIZE); + outer_flush_range(page_to_phys(pages) + page_start_offset, page_to_phys(pages) + PAGE_SIZE); +#endif + kunmap(pages); + + pages = acquired_pages[page_end-page_start]; + ptr = kmap(pages); +#if defined(__mips64__) || defined(__loongarch__) + gf_dma_cache_sync(dev, ptr, page_end_offset, DMA_BIDIRECTIONAL); +#elif __ARM_ARCH >= 8 + flush_icache_range((unsigned long)ptr, (unsigned long)(ptr + page_end_offset)); +#else + dmac_flush_range(ptr, ptr + PAGE_SIZE); + outer_flush_range(page_to_phys(pages), page_to_phys(pages) + page_end_offset); +#endif + kunmap(pages); + } + + for(i = page_start+1 ; i <= page_end-1; i++) + { + pages = acquired_pages[i-page_start]; + ptr = kmap(pages); +#if defined(__mips64__) || defined(__loongarch__) + gf_dma_cache_sync(dev, ptr, PAGE_SIZE, DMA_BIDIRECTIONAL); +#elif __ARM_ARCH >= 8 + flush_icache_range((unsigned long)ptr, (unsigned long)(ptr + PAGE_SIZE)); +#else + dmac_flush_range(ptr, ptr + PAGE_SIZE); + outer_flush_range(page_to_phys(pages), page_to_phys(pages) + PAGE_SIZE); +#endif + kunmap(pages); + } + gf_release_os_pages(acquired_pages); +#endif +} + +void gf_inv_cache(void *pdev, gf_vm_area_t *vma, struct os_pages_memory* memory, unsigned int offset, unsigned int size) +{ +#ifdef CONFIG_X86 + //clflush_cache_range(start, size); + wbinvd(); +#else + struct page **acquired_pages; + struct page *pages; + void *ptr; + int page_start = offset/PAGE_SIZE; + int page_end = (offset + size -1)/PAGE_SIZE; + int page_start_offset = offset%PAGE_SIZE; + int page_end_offset = (offset + size - 1)%PAGE_SIZE; + int i; + struct device *dev = &((struct pci_dev *)pdev)->dev; + + if((offset % 32 != 0) || (size % 32 != 0) ) + { + gf_error("offset does not align to data cache line boundary(32B)"); + } + + gf_assert(offset>0, "offset>0"); + gf_assert(size>0, "size>0"); + gf_assert(offset+size <= memory->size, "offset+size <= memory->size"); + gf_assert(page_start <= page_end, "page_start <= page_end"); + + acquired_pages = gf_acquire_os_pages(memory, PAGE_SIZE*(page_end-page_start+1), 0, NULL); + if(page_start == page_end) + { + pages = acquired_pages[0]; + ptr = kmap(pages); +#if defined(__mips64__) || defined(__loongarch__) + gf_dma_cache_sync(dev, ptr + page_start_offset, page_end_offset - page_start_offset, DMA_BIDIRECTIONAL); +#elif __ARM_ARCH >= 8 + flush_icache_range((unsigned long)(ptr + page_start_offset), (unsigned long)(ptr + page_end_offset)); +#else + dmac_flush_range(ptr + page_start_offset, ptr + page_end_offset); + outer_inv_range(page_to_phys(pages) + page_start_offset, page_to_phys(pages) + page_end_offset); +#endif + kunmap(pages); + } + else + { + pages = acquired_pages[0]; + ptr = kmap(pages); +#if defined(__mips64__) || defined(__loongarch__) + gf_dma_cache_sync(dev, ptr + page_start_offset, PAGE_SIZE - page_start_offset, DMA_BIDIRECTIONAL); +#elif __ARM_ARCH >= 8 + flush_icache_range((unsigned long)(ptr + page_start_offset), (unsigned long)(ptr + PAGE_SIZE)); +#else + dmac_flush_range(ptr + page_start_offset, ptr + PAGE_SIZE); + outer_inv_range(page_to_phys(pages) + page_start_offset, page_to_phys(pages) + PAGE_SIZE); +#endif + kunmap(pages); + + pages = acquired_pages[page_end-page_start]; + ptr = kmap(pages); +#if defined(__mips64__) || defined(__loongarch__) + gf_dma_cache_sync(dev, ptr, page_end_offset, DMA_BIDIRECTIONAL); +#elif __ARM_ARCH >= 8 + flush_icache_range((unsigned long)ptr, (unsigned long)(ptr + PAGE_SIZE)); +#else + dmac_flush_range(ptr, ptr + PAGE_SIZE); + outer_inv_range(page_to_phys(pages), page_to_phys(pages) + page_end_offset); +#endif + kunmap(pages); + } + + for(i = page_start+1 ; i <= page_end-1; i++) + { + pages = acquired_pages[i-page_start]; + ptr = kmap(pages); +#if defined(__mips64__) || defined(__loongarch__) + gf_dma_cache_sync(dev, ptr, PAGE_SIZE, DMA_BIDIRECTIONAL); +#elif __ARM_ARCH >= 8 + flush_icache_range((unsigned long)ptr, (unsigned long)(ptr + PAGE_SIZE)); +#else + dmac_flush_range(ptr, ptr + PAGE_SIZE); + outer_inv_range(page_to_phys(pages), page_to_phys(pages) + PAGE_SIZE); +#endif + kunmap(pages); + } + gf_release_os_pages(acquired_pages); +#endif +} +gf_vm_area_t *gf_map_io_memory_priv(void *filp, gf_map_argu_t *map_argu) +{ + gf_vm_area_t *vm_area = gf_calloc(sizeof(gf_vm_area_t)); + void *virt_addr = NULL; + phys_addr_t phy_addr = map_argu->phys_addr; +#if defined(__mips64__) || defined(__loongarch__) + //current on pass uc in phyton platform.need to be think over. + // mips loogson 3A4000/3A3000 seems seems like wc buffer can not auto flush for io mem + // need confirm with loogson + map_argu->flags.cache_type = GF_MEM_UNCACHED; +#endif + if(map_argu->flags.mem_space == GF_MEM_KERNEL) + { + if(map_argu->flags.cache_type == GF_MEM_UNCACHED) + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) + virt_addr = ioremap(map_argu->phys_addr, map_argu->size); +#else + virt_addr = ioremap_nocache(phy_addr, map_argu->size); +#endif + } + else if(map_argu->flags.cache_type == GF_MEM_WRITE_COMBINED) + { +#if defined(CONFIG_X86) && !defined(CONFIG_X86_PAT) + virt_addr = ioremap_nocache(phy_addr, map_argu->size); + + map_argu->flags.cache_type = GF_MEM_UNCACHED; +#else + if(gf_modparams.gf_hang_dump) + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) + virt_addr = ioremap(map_argu->phys_addr, map_argu->size); +#else + virt_addr = ioremap_nocache(phy_addr, map_argu->size); +#endif + } + else + { + virt_addr = ioremap_wc(phy_addr, map_argu->size); + } +#endif + } + } + else if(map_argu->flags.mem_space == GF_MEM_USER) + { + virt_addr = gf_do_mmap(filp, map_argu); + } + + vm_area->flags.value = map_argu->flags.value; + vm_area->size = map_argu->size; + vm_area->virt_addr = virt_addr; + vm_area->owner = gf_get_current_pid(); + + return vm_area; +} + +void gf_unmap_io_memory_priv(gf_vm_area_t *vm_area) +{ + if(vm_area->flags.mem_space == GF_MEM_KERNEL) + { + iounmap(vm_area->virt_addr); + } + else if(vm_area->flags.mem_space == GF_MEM_USER) + { + gf_do_munmap(vm_area); + } + + gf_free(vm_area); +} + +void *gf_ioremap(unsigned int io_base, unsigned int size) +{ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) + return ioremap(io_base, size); +#else + return ioremap_nocache(io_base, size); +#endif +} + +void gf_iounmap(void *map_address) +{ + iounmap(map_address); +} + +int gf_mtrr_add(unsigned long start, unsigned long size) +{ + int reg = -1; + +#ifdef CONFIG_MTRR +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0) + reg = mtrr_add(start, size, MTRR_TYPE_WRCOMB, 1); +#else + reg = arch_phys_wc_add(start, size); +#endif + + if(reg < 0) + { + gf_info("set mtrr range %x -> %x failed. \n", start, start + size); + } +#endif + + return reg; +} + +int gf_mtrr_del(int reg, unsigned long base, unsigned long size) +{ + int err = -1; + +#ifdef CONFIG_MTRR +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0) + err = mtrr_del(reg, base, size); +#else + /* avoid build warning */ + base = base; + size = size; + arch_phys_wc_del(reg); + err = 0; +#endif + +#endif + + return err; +} + +int gf_get_mem_info(mem_info_t *mem) +{ + struct sysinfo si; + + si_meminfo(&si); + + /* we need set pages cache type accord usage, before set_pages_array_wc defined + * kernel only support set cache type to normal zone pages, add check if can use hight + */ + +#ifdef HAS_SET_PAGES_ARRAY_WC + mem->totalram = si.totalram; + mem->freeram = si.freeram; +#else + mem->totalram = si.totalram - si.totalhigh; + mem->freeram = si.freeram - si.freehigh; +#endif + + return 0; +} + +int gf_query_platform_caps(void *pdev, platform_caps_t *caps) +{ + struct sysinfo si; + struct device* device = &((struct pci_dev *)pdev)->dev; + + si_meminfo(&si); + +#if defined(__i386__) || defined(__x86_64__) + caps->dcache_type = GF_CPU_CACHE_PIPT; +#elif defined(CONFIG_CPU_CACHE_VIPT) + caps->dcache_type = cache_is_vipt_nonaliasing() ? + GF_CPU_CACHE_VIPT_NONALIASING : + GF_CPU_CACHE_VIPT_ALIASING; +#elif defined(CONFIG_CPU_CACHE_VIVT) + caps->dcache_type = GF_CPU_CACHE_VIVT; +#else + caps->dcache_type = GF_CPU_CACHE_UNKNOWN; +#endif + +#if defined(CONFIG_IOMMU_SUPPORT) + caps->iommu_support = iommu_present(&platform_bus_type) || +#ifdef CONFIG_ARM_AMBA + iommu_present(&amba_bustype) || +#endif + iommu_present(&pci_bus_type); +#if defined(CONFIG_ARM_GIC_PHYTIUM_2500) + caps->iommu_support = FALSE; +#endif +#else + caps->iommu_support = FALSE; +#endif + + caps->page_size = PAGE_SIZE; + caps->page_shift = PAGE_SHIFT; + + /*for (mem_res = iomem_resource.child; mem_res; mem_res = mem_res->sibling) + { + if (mem_res->name && (!gf_strcmp(mem_res->name, "System RAM")) && (mem_res->end > max_physical_addr)) + max_physical_addr = mem_res->end; + } + + + if (BITS_PER_LONG == 64 && !caps->iommu_support && max_physical_addr >= (1ULL << 36)) + { + caps->system_need_dma32 = TRUE; + }*/ + + caps->system_need_dma32 = caps->iommu_support ? FALSE : dma_get_required_mask(device) > DMA_BIT_MASK(40); + +#if defined(__i386__) || defined(__x86_64__) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) + caps->suspend_blt_mode = (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) ? 2 : 1; +#else + caps->suspend_blt_mode = (boot_cpu_data.x86_vendor == 9) ? 2 : 1; +#endif +#else + caps->suspend_blt_mode = 1; +#endif + + return 0; +} + +int gf_is_own_pages(struct os_pages_memory *pages_memory) +{ + // prevent import page and user page + return pages_memory && !pages_memory->shared && !pages_memory->userptr; +} +void *gf_pages_memory_swapout(struct os_pages_memory *pages_memory) +{ + struct file *file_storage = shmem_file_setup("gf gmem", pages_memory->size, 0); + struct address_space *file_addr_space; + struct page **pages; + struct page *src_page, *dst_page; + void *src_addr, *dst_addr; + int i = 0, j = 0, page_count = 0; + + if(file_storage == NULL) + { + gf_info("create shmem file failed. size: %dk.\n", pages_memory->size << 10); + + return NULL; + } + + file_addr_space = file_storage->f_path.dentry->d_inode->i_mapping; + + pages = gf_acquire_os_pages(pages_memory, pages_memory->size, 0, &page_count); + if(pages == NULL) return NULL; + + for(i = 0; i < page_count; i++) + { + src_page = pages[i]; + + for(j = 0; j < 100; j++) + { + dst_page = os_shmem_read_mapping_page(file_addr_space, i, NULL); + + if(unlikely(IS_ERR(dst_page))) + { + msleep(5); + } + else + { + break; + } + } + + if(unlikely(IS_ERR(dst_page))) + { + fput(file_storage); + file_storage = NULL; + gf_info("when swapout read mapping failed. %d, %d, size: %dk\n", i, j, pages_memory->size >> 10); + + goto __failed; + } + + preempt_disable(); + + src_addr = os_kmap_atomic(src_page, OS_KM_USER0); + dst_addr = os_kmap_atomic(dst_page, OS_KM_USER1); + + memcpy(dst_addr, src_addr, PAGE_SIZE); + + os_kunmap_atomic(dst_addr, OS_KM_USER1); + os_kunmap_atomic(src_addr, OS_KM_USER0); + + preempt_enable(); + + set_page_dirty(dst_page); + mark_page_accessed(dst_page); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + page_cache_release(dst_page); +#else + put_page(dst_page); +#endif + balance_dirty_pages_ratelimited(file_addr_space); + cond_resched(); + } + +__failed: + + gf_release_os_pages(pages); + return file_storage; +} + +int gf_pages_memory_swapin(struct os_pages_memory *pages_memory, void *file) +{ + struct file *file_storage = file; + struct address_space *file_addr_space; + struct page **pages; + struct page *src_page, *dst_page; + void *src_addr, *dst_addr; + int i, page_count = 0; + + file_addr_space = file_storage->f_path.dentry->d_inode->i_mapping; + + pages = gf_acquire_os_pages(pages_memory, pages_memory->size, 0, &page_count); + + if(pages == NULL) return -1; + + for(i = 0; i < page_count; i++) + { + src_page = os_shmem_read_mapping_page(file_addr_space, i, NULL); + dst_page = pages[i]; + + if(unlikely(IS_ERR(src_page))) + { + gf_info("when swapin read mapping failed. %d\n", i); + + gf_release_os_pages(pages); + + pages = NULL; + + return -1; + } + + preempt_disable(); + + src_addr = os_kmap_atomic(src_page, OS_KM_USER0); + dst_addr = os_kmap_atomic(dst_page, OS_KM_USER1); + + memcpy(dst_addr, src_addr, PAGE_SIZE); + + os_kunmap_atomic(dst_addr, OS_KM_USER1); + os_kunmap_atomic(src_addr, OS_KM_USER0); + + preempt_enable(); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + page_cache_release(src_page); +#else + put_page(src_page); +#endif + } + + fput(file_storage); + + gf_release_os_pages(pages); + + return 0; +} + +void gf_release_file_storage(void *file) +{ + fput(file); +} + +int gf_seq_printf(struct os_seq_file *seq_file, const char *f, ...) +{ + int ret; + +#ifdef SEQ_PRINTF + ret = seq_printf(seq_file->seq_file, f); +#else + va_list args; + + va_start(args, f); + seq_vprintf(seq_file->seq_file, f, args); + va_end(args); + + ret = 0; +#endif + return ret; +} + +void GF_API_CALL gf_outb(unsigned short port, unsigned char value) +{ +#if defined(__i386__) || defined(__x86_64__) + outb(value, port); +#else + /* No IO operation on non-x86 platform. */ + gf_assert(0, NULL); +#endif +} + +char GF_API_CALL gf_inb(unsigned short port) +{ +#if defined(__i386__) || defined(__x86_64__) + return inb(port); +#else + /* No IO operation on non-x86 platform. */ + gf_assert(0, NULL); + + return 0; +#endif +} + +static void __gf_printfn_seq_file(struct os_printer *p, struct va_format *vaf) +{ + gf_seq_printf(p->arg, "%pV", vaf); +} + +struct os_printer gf_seq_file_printer(struct os_seq_file *f) +{ + struct os_printer p = { + .printfn = __gf_printfn_seq_file, + .arg = f, + }; + return p; +} + +static void __gf_printfn_info(struct os_printer *p, struct va_format *vaf) +{ + gf_info("%pV", vaf); +} + +struct os_printer gf_info_printer(void *dev) +{ + struct os_printer p = { + .printfn = __gf_printfn_info, + .arg = dev, + }; + return p; +} + +void gf_printf(struct os_printer *p, const char *f, ...) +{ + struct va_format vaf; + va_list args; + struct os_printer info = gf_info_printer(NULL); + va_start(args, f); + vaf.fmt = f; + vaf.va = &args; + if (p == NULL) { + p = &info; + } + p->printfn(p, &vaf); + va_end(args); +} + +int gf_disp_wait_idle(void *disp_info) +{ + return disp_wait_idle(disp_info); +} + +#if defined(__i386__) || defined(__x86_64__) +#define gf_mb_asm() asm volatile("mfence":::"memory") +#define gf_rmb_asm() asm volatile("lfence":::"memory") +#define gf_wmb_asm() asm volatile("sfence":::"memory") +#define gf_flush_wc_asm() gf_wmb_asm() +#define gf_dsb_asm() +#elif defined(__mips64__) || defined(__loongarch__) +#include +#define gf_mb_asm() mb() +#define gf_rmb_asm() rmb() +#define gf_wmb_asm() wmb() +#define gf_flush_wc_asm() mb() +#define gf_dsb_asm() +#else +#if __ARM_ARCH >= 7 +#define dmb(opt) asm volatile("dmb " #opt : : : "memory") +#define dsb(opt) asm volatile("dsb " #opt : : : "memory") + +#define gf_mb_asm() dsb(sy) +#define gf_rmb_asm() dsb(ld) +#define gf_wmb_asm() dsb(st) +#define gf_flush_wc_asm() dsb(sy) +#define gf_dsb_asm() dsb(sy) +#endif +#endif + +void gf_mb(void) +{ + gf_mb_asm(); +} + +void gf_rmb(void) +{ + gf_rmb_asm(); +} + +void gf_wmb(void) +{ + gf_wmb_asm(); +} + +void gf_flush_wc(void) +{ + gf_flush_wc_asm(); +} + +void gf_dsb(void) +{ + gf_dsb_asm(); +} diff --git a/drivers/gpu/drm/arise/shared/gf_capture.h b/drivers/gpu/drm/arise/shared/gf_capture.h new file mode 100644 index 0000000000000..fc908cbe05b52 --- /dev/null +++ b/drivers/gpu/drm/arise/shared/gf_capture.h @@ -0,0 +1,191 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_CAPTURE_H__ +#define __GF_CAPTURE_H__ + + +#define GF_CAPTURE_SKIP_FRAME (0x1 << 0) +#define GF_CAPTURE_SET_BUFFER (0x1 << 1) +#define GF_CAPTURE_PLUG_OUT (0x1 << 2) +#define GF_CAPTURE_PLUG_IN (0x1 << 3) +#define GF_CAPTURE_SIGNAL_OFF (0x1 << 4) +#define GF_CAPTURE_SIGNAL_ON (0x1 << 5) + +typedef enum _gf_capture_id_t +{ + GF_CAPTURE_VIP1 = 0, + GF_CAPTURE_VIP2 = 1, + GF_CAPTURE_VIP3 = 2, + GF_CAPTURE_VIP4 = 3, + GF_CAPTURE_WB1 = 4, + GF_CAPTURE_WB2 = 5, + GF_CAPTURE_WB3 = 6, + GF_CAPTURE_WB4 = 7, + GF_CAPTURE_INVALID = 8, +}gf_capture_id_t; + +typedef enum _gf_capture_op_t +{ + GF_CAPTURE_OP_INIT = 0, + GF_CAPTURE_OP_DEINIT = 1, + GF_CAPTURE_OP_ENABLE = 2, + GF_CAPTURE_OP_DISABLE = 3, + GF_CAPTURE_OP_QUERY_CAPS = 4, + GF_CAPTURE_OP_SET_MODE = 5, + GF_CAPTURE_OP_SET_BUFF = 6, + GF_CAPTURE_OP_SET_CALLBACK = 7, + GF_CAPTURE_OP_QUERY_CHIPINFO = 8, + GF_CAPTURE_OP_GET_FRONT_MODE = 9, + GF_CAPTURE_OP_SET_PREFER_MODE = 10, +}gf_capture_op_t; + +enum +{ + GF_VIP_CARD_AVD7611 = 0, +}; + +enum +{ + GF_WB_MODE_P2P = 0, +}; + +enum +{ + GF_WB_FMT_RGB888 = 0, + GF_VIP_FMT_RGB444_24BIT_SDR = 1, + GF_VIP_FMT_YCBCR444_24BIT_SDR = 2, + GF_VIP_FMT_YCBCR422_8BIT_SDR_ES = 3, + GF_VIP_FMT_YCBCR422_8BIT_DDR_ES = 4, +}; + +typedef struct +{ + unsigned int xRes; + unsigned int yRes; + unsigned int refreshrate; + unsigned int fmt; +}gf_vip_mode_t; + +typedef struct +{ + gf_capture_op_t op; + + union + { + struct + { + unsigned long long fbAddr; + }set_buffer_param; + + struct + { + unsigned int bByPass; + unsigned int srcX; + unsigned int srcY; + unsigned int dstX; + unsigned int dstY; + unsigned int bDoubleBuffer; + unsigned int bUpdateImme; + unsigned int mode; + unsigned int outFmt; + }set_mode_param; + + struct + { + unsigned int width; + unsigned int height; + unsigned int refrate; + unsigned int capture_fmt; + }query_caps_param; + + struct + { + void (*cb)(gf_capture_id_t id, void *data, unsigned int flags); + void *cb_data; + }set_callback_param; + + }; + +}wb_op_params_t; + +typedef struct +{ + gf_capture_op_t op; + + union + { + struct + { + unsigned int fbNum; + }init_param; + + struct + { + unsigned int fbIdx; + unsigned long long fbAddr; + }set_buffer_param; + + struct + { + unsigned int fmt; + unsigned int chip; + unsigned int xres; + unsigned int yres; + unsigned int refreshrate; + }set_mode_param; + + struct + { + unsigned int modeNum; + gf_vip_mode_t *mode; + }query_caps_param; + + struct + { + unsigned int vipCard; + }query_chipinfo_param; + + struct + { + unsigned int hasInput; + gf_vip_mode_t mode; + }get_front_mode_param; + + struct + { + gf_vip_mode_t mode; + }set_prefer_mode_param; + + struct + { + void (*cb)(gf_capture_id_t id, void *data, unsigned int flags); + void *cb_data; + }set_callback_param; + }; + +}vip_op_params_t; + +#undef __CONCAT +#undef CONCAT +#define __CONCAT(x,y) x##y +#define CONCAT(x,y) __CONCAT(x,y) + +typedef int (*PFN_GF_CAPTURE_OPS_T)(void *pdata, gf_capture_id_t id, void *params); +void CONCAT(gf_krnl_get_capture_interface_, DRIVER_NAME)(unsigned int id, void **pdata, PFN_GF_CAPTURE_OPS_T *interface); + +#undef __CONCAT +#undef CONCAT + +#endif diff --git a/drivers/gpu/drm/arise/shared/gf_def.h b/drivers/gpu/drm/arise/shared/gf_def.h new file mode 100644 index 0000000000000..13750d16e133b --- /dev/null +++ b/drivers/gpu/drm/arise/shared/gf_def.h @@ -0,0 +1,480 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __gf_def_h__ +#define __gf_def_h__ + +#include "gf_perf.h" + +#define MAX_SCREENS 4 + +//Fix-me: +// need set MAX_CORE_CRTCS as 3 in CHX001, just keep it as 2 in e2uma validation. +// currently cannot set 3, because there is no vsync interrupt for the 3rd IGA, this may lead KMD pending in some cases +// +#define MAX_CORE_CRTCS 4 + +#define OUTPUT_NAME_LEN 16 + +#define MAX_ENGINE_COUNT 10 +#define ALL_ENGINE_MASK ((1 << MAX_ENGINE_COUNT) - 1) + +typedef union +{ +#ifndef __BIG_ENDIAN__ + struct + { + unsigned int low32; + unsigned int high32; + }; + #else + struct + { + unsigned int high32; + unsigned int low32; + }; + #endif + unsigned long long quad64; +}large_inter; + +#define ALIGN8 __attribute__ ((aligned(8))) + +#ifndef UNUSED +#define UNUSED(x) (void)(x) +#endif + +typedef unsigned long long gf_ptr64_t; + +typedef struct gf_clip_rect +{ + short x1; + short y1; + short x2; + short y2; +}gf_clip_rect_t; + +typedef enum gf_miu_reg_type +{ + GF_MIU_MMIO = 1, + GF_MIU_PMC = 2, + GF_MIU_PMU = 3, +}gf_miu_reg_type_t; + + +typedef enum +{ + GF_STREAM_PS = 0, + GF_STREAM_SS, + GF_STREAM_TS, + GF_STREAM_4S, + GF_STREAM_5S, + GF_STREAM_6S, + GF_STREAM_MAX, +}GF_STREAM_TYPE; + +typedef enum +{ + GF_PLANE_PS = 0, + GF_PLANE_SS, + GF_PLANE_TS, + GF_PLANE_FS, + GF_MAX_PLANE, +}GF_PLANE_TYPE; + + +typedef enum +{ + GF_AUDIO_FORMAT_REFER_TO_STREAM_HEADER, + GF_AUDIO_FORMAT_LPCM, + GF_AUDIO_FORMAT_AC_3, + GF_AUDIO_FORMAT_MPEG_1, + GF_AUDIO_FORMAT_MP3, + GF_AUDIO_FORMAT_MPEG_2, + GF_AUDIO_FORMAT_AAC_LC, + GF_AUDIO_FORMAT_DTS, + GF_AUDIO_FORMAT_ATRAC, + GF_AUDIO_FORMAT_DSD, + GF_AUDIO_FORMAT_E_AC_3, + GF_AUDIO_FORMAT_DTS_HD, + GF_AUDIO_FORMAT_MLP, + GF_AUDIO_FORMAT_DST, + GF_AUDIO_FORMAT_WMA_PRO, + GF_AUDIO_FORMAT_HE_AAC, + GF_AUDIO_FORMAT_HE_AAC_V2, + GF_AUDIO_FORMAT_MPEG_SURROUND +}GF_HDMI_AUDIO_FORMAT_TYPE; + +typedef struct +{ + GF_HDMI_AUDIO_FORMAT_TYPE format; + unsigned int max_channel_num; + union + { + struct + { + unsigned int SR_32kHz :1; /* Bit0 = 1, support sample rate of 32kHz */ + unsigned int SR_44_1kHz :1; /* Bit1 = 1, support sample rate of 44.1kHz */ + unsigned int SR_48kHz :1; /* Bit2 = 1, support sample rate of 48kHz */ + unsigned int SR_88_2kHz :1; /* Bit3 = 1, support sample rate of 88.2kHz */ + unsigned int SR_96kHz :1; /* Bit4 = 1, support sample rate of 96kHz */ + unsigned int SR_176_4kHz :1; /* Bit5 = 1, support sample rate of 176.4kHz */ + unsigned int SR_192kHz :1; /* Bit6 = 1, support sample rate of 192kHz */ + unsigned int reserved :25; + }sample_rate; + + unsigned int sample_rate_unit; + }; + + union + { + unsigned int unit; + + // for audio format: LPCM + struct + { + unsigned int BD_16bit :1; /* Bit0 = 1, support bit depth of 16 bits */ + unsigned int BD_20bit :1; /* Bit1 = 1, support bit depth of 20 bits */ + unsigned int BD_24bit :1; /* Bit2 = 1, support bit depth of 24 bits */ + unsigned int reserved :29; + }bit_depth; + + // for audio format: AC-3, MPEG-1, MP3, MPED-2, AAC LC, DTS, ATRAC + unsigned int max_bit_Rate; // unit: kHz + + // for audio format: DSD, E-AC-3, DTS-HD, MLP, DST + unsigned int audio_format_depend_value; /* for these audio formats, this value is defined in + it's corresponding format-specific documents*/ + + // for audio format: WMA Pro + struct + { + unsigned int value :3; + unsigned int reserved :29; + }profile; + }; +}gf_hdmi_audio_format_t; + +typedef struct +{ + unsigned int num_formats; + gf_hdmi_audio_format_t audio_formats[16]; +}gf_hdmi_audio_formats; + +typedef struct +{ + unsigned int engine_mask; /* in */ + unsigned int hAllocation; /* in */ +}gf_wait_allocation_idle_t; + +typedef struct +{ + int input_size; /* in */ + int output_size; /* in */ + + gf_ptr64_t input ALIGN8;/* in */ + gf_ptr64_t output ALIGN8;/* output */ +}gf_escape_call_t; + +typedef enum +{ + GF_QUERY_VBIOS_VERSION, + GF_QUERY_TOTAL_VRAM_SIZE, + GF_QUERY_CPU_VISIBLE_VRAM_SIZE, + GF_QUERY_RESERV_VRAM_SIZE, + GF_QUERY_CHIP_ID, + GF_QUERY_CRTC_OUTPUT, + GF_QUERY_VSYNC_CNT, + GF_QUERY_HEIGHT_ALIGN, + GF_QUERY_LOCAL_VRAM_TYPE, + GF_QUERY_ENGINE_CLOCK, + GF_QUERY_VCLK, + GF_QUERY_MCLK, + GF_QUERY_VMEM_CLOCK, + GF_QUERY_VRAM_USED, + GF_QUERY_GART_USED, + GF_QUERY_REGISTER_U32, + GF_QUERY_REGISTER_U64, + GF_QUERY_INFO_MAX, + GF_QUERY_I_CLOCK, + GF_QUERY_CPU_FREQUENCE, + GF_SET_I_CLOCK, + GF_QUERY_PMU_REGISTER_U32, + GF_SET_CPU_FREQUENCE, + GF_QUERY_VENDOR_ID, + GF_QUERY_DEVICE_ID, + GF_QUERY_REVISION_ID, + GF_QUERY_SEGMENT_FREE_SIZE, + GF_QUERY_HW_HANG, + GF_QUERY_SECURED_ON, + GF_QUERY_PAGE_SWIZZLE_SUPPORT, + GF_QUERY_PENDING_FRAME_NUM, + GF_QUERY_PMC_REGISTER_U32, + GF_QUERY_ALLOCATION_INFO, + GF_QUERY_GPU_TEMPERATURE, + GF_QUERY_GPU_TIME_STAMP, + GF_QUERY_LOCAL_ALLOCATION_MAX_SIZE, + GF_SET_PERF_SWAP_HINT, + GF_GET_PERF_SWAP_HINT, + GF_QUERY_VCP_INDEX, + GF_QUERY_RET_VCP_INDEX, + GF_QUERY_VCP_INFO, + GF_QUERY_VIDEO_SEQ_INDEX, + GF_QUERY_RET_VIDEO_SEQ_INDEX, + GF_QUERY_ADAPTER_INFO, + + GF_QUERY_PCIE_LINK_WIDTH, + GF_QUERY_ACTIVE_ENGINE_COUNT, + + GF_QUERY_GET_VIDEO_BRIDGE_BUFFER, + GF_QUERY_CHIP_SLICE_MASK, + GF_SET_MIU_REGISTER_U32, + GF_QUERY_MIU_REGISTER_U32, + GF_QUERY_DIAGS, + GF_SET_REGISTER_U32, + + GF_QUERY_ALLOCATION_INFO_KMD, + GF_QUERY_SEGMENT_MEM_INFO, + GF_QUERY_ENGINE_USAGE_STATUS, + GF_QUERY_PROCESS_INFO, + GF_QUERY_ENGINE_USAGE_STATUS_EXT, + GF_QUERY_CORE_CLOCK, +}GF_QUERY_INFO_TYPE; + +typedef struct +{ + unsigned int type; /* in */ + unsigned int argu; /* in */ + unsigned int buf_len; /*in */ + unsigned int pad; + union + { + int signed_value; /* out */ + unsigned int value; /* out */ + unsigned long long value64; /* out */ + void *buf; /* out */ + }; + struct{ + unsigned int device_id; + unsigned int vendor_id; + unsigned int pci_link_width; + unsigned int pci_link_speed; + unsigned int engine_clk; + unsigned int memory_clk; + unsigned int video_clk; + unsigned int pad; + unsigned long long total_vram_size; + unsigned long long cpu_visible_size; + }diags; +}gf_query_info_t; + +typedef gf_query_info_t gf_config_info_t; + +/* +if umd need poll events, the definition need consistent between interrupt.h and gf_def.h +*/ + + +typedef struct +{ + unsigned short Vendor_ID; + unsigned char Device_ID; + unsigned char Revision_ID; +}gf_chip_id_t; + +#define GF_HDCP_ENABLED 0x0 +#define GF_HDCP_FAILED 0x1 +#define GF_HDCP_NO_SUPPORT_DEVICE 0x2 + +typedef struct +{ + unsigned int enable; /* in, 1 enable, 0 disable */ + unsigned int output_type; /* in, if 0, all HDMIs will be enable/disable */ + unsigned int result; /* out, see GF_HDCP_XXX */ +}gf_hdcp_op_t; + +typedef struct +{ + unsigned int hAllocation; + unsigned int engine_mask; + unsigned int state; +}gf_get_allocation_state_t; + +typedef enum +{ + GF_HW_NONE = 0x00, + GF_HW_IGA = 0x01, +}gf_hw_block; + +#define STREAM_MASK_UPDATE 0x01 +#define STREAM_MASK_FLIP 0x02 + +#define GF_NAME "gf" + +#define UT_OUTPUT_TYPE_NONE 0x00 +#define UT_OUTPUT_TYPE_CRT 0x01 +#define UT_OUTPUT_TYPE_TV 0x02 +#define UT_OUTPUT_TYPE_HDTV 0x04 +#define UT_OUTPUT_TYPE_PANEL 0x08 +#define UT_OUTPUT_TYPE_DVI 0x10 +#define UT_OUTPUT_TYPE_HDMI 0x20 +#define UT_OUTPUT_TYPE_DP 0x40 +#define UT_OUTPUT_TYPE_MHL 0x80 + +static inline gf_ptr64_t ptr_to_ptr64(void *ptr) +{ + return (gf_ptr64_t)(unsigned long)ptr; +} + +static inline void *ptr64_to_ptr(gf_ptr64_t ptr64) +{ + return (void*)(unsigned long)ptr64; +} + +typedef struct { + unsigned int pid; + unsigned int enable; + unsigned int dwDecodeLevel; + unsigned int dwDecodeType; + unsigned int dwFrameType; + int DecodeWidth; + int DecodeHeight; + unsigned int DecodeRTNum; + unsigned int SliceNum; + unsigned int TotalRenderFrameNum; + unsigned int TotalFrameNum; + unsigned int TotalIFrameNum; + unsigned int TotalPFrameNum; + unsigned int TotalBFrameNum; + unsigned int TotalBltFrameNum; + unsigned int TotalBitstreamSize; + unsigned int DecodeApi; + unsigned int PresentApi; + unsigned int TotalDecodetime; //ms + unsigned int TotalDecodeFrameNum; +}gf_vcp_info; + +typedef struct +{ + unsigned short VendorID; // (ro) + unsigned short DeviceID; // (ro) + unsigned short Command; // Device control + unsigned short Status; + unsigned char RevisionID; // (ro) + unsigned char ProgIf; // (ro) + unsigned char SubClass; // (ro) + unsigned char BaseClass; // (ro) + unsigned char CacheLineSize; // (ro+) + unsigned char LatencyTimer; // (ro+) + unsigned char HeaderType; // (ro) + unsigned char BIST; // Built in self test + unsigned int ulBaseAddresses[6]; // 6 == PCI_TYPE0_ADDRESSES + unsigned int CardBus; + unsigned short SubsystemVendorID; + unsigned short SubSystemID; + unsigned int PCIConfig_Unused[4]; + unsigned int AGPCapability; + unsigned int AGPStatus; + unsigned int AGPCommand; + unsigned int BusNum; + unsigned int SlotNum; + + // for PCI Express support + unsigned int LinkCaps; + unsigned short LinkStatus; + + int bSwizzled; + unsigned int memoryType; // 0: 128bits bus; 1: 64bits bus + unsigned char pageSelect; // For memory (2K, 4K, 8K page sizes) + unsigned char bankSelect; // Which address bits to use for bank select + unsigned char bankSelectShift; // Which address bits to use for bank select + unsigned char bankSelectMask; // BitMask for bank select bits + unsigned long long memorySize; +} gf_pci_config_t; + +typedef struct { + unsigned int VidmemSize; + unsigned int cjGARTTable; + unsigned int GARTTableSize; + unsigned int cjVidmemPageTable; + unsigned int VidmemPageTableSize; + unsigned int cjPageKeyBuffer; + unsigned int PageKeyBufferSize; + unsigned int cjFBRingBuffer; + unsigned int FBRingBufferSize; + int bNullHW; + int bNullBridge; + int pad; // for 32bit alignment compatible + unsigned long long UserCModelVidMemBase; + unsigned long long pfnCModelFlushEngine; + unsigned long long pfnGetCModelInfo; + unsigned long long pfnGetRegistryFromCModelIni; +} gf_model2_cil_info_t; + +typedef struct +{ + gf_pci_config_t bus_config; + unsigned int chipslicemask; + unsigned int gpucount; + unsigned int osversion; + int bVideoOnly; + int bCTEDumpEnable; + int segmentMapTable[5]; + gf_model2_cil_info_t model2cilinfo; + int non_simul_chip; + int pad; +} gf_adapter_info_t; + +//query segment usage for UMA +typedef struct +{ + //segment mem size in kbytes + unsigned int segment_total_size; + unsigned int segment_used_size; + unsigned int segment_alloc_num; + unsigned int segment_id; +} gf_segment_mem_t; +//query process info for UMA +#define KERNAL_BASE_ARRAY_MAX 16 +#define KERNAL_NORMAT_ARRAY_MAX 32 +#define KERNAL_STRING_ARRAY_MAX 64 +typedef struct +{ + unsigned int handle; + unsigned int segment_id; + unsigned int format; + unsigned int compress_format; + unsigned int width; + unsigned int height; + unsigned int pitch; + unsigned int alignment; + unsigned int size; + unsigned int bit_count; + unsigned int physical_addr; + unsigned int at_type; + unsigned int priority; + unsigned int flag; + unsigned int status; + unsigned int perference; +} gf_process_allocation_t; +typedef struct +{ + unsigned int device_handle; + unsigned int context_handle[KERNAL_NORMAT_ARRAY_MAX]; + unsigned int context_count; + unsigned int pid; + unsigned char name[KERNAL_STRING_ARRAY_MAX]; + gf_process_allocation_t alloc_info[KERNAL_NORMAT_ARRAY_MAX]; + unsigned int alloc_num; +} gf_process_base_t; +#endif \ No newline at end of file diff --git a/drivers/gpu/drm/arise/shared/gf_modifies.h b/drivers/gpu/drm/arise/shared/gf_modifies.h new file mode 100644 index 0000000000000..19b188a23e8aa --- /dev/null +++ b/drivers/gpu/drm/arise/shared/gf_modifies.h @@ -0,0 +1,75 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_MODIFIES_H_ +#define __GF_MODIFIES_H_ + +/*this piece code should be place in drm/drm-fourcc.h in kernel/mesa*/ + +#ifdef KERNEL_BUILD +#include +#else +// for usermode code, libdrm will provide the include path through its cflags +#include +#endif + +/*here just for compatiable for drm linear mod*/ +/* GF Linear mode define as same as system define, can be shared with other app/vendors */ + +#ifndef DRM_FORMAT_MOD_VENDOR_NONE +#define DRM_FORMAT_MOD_VENDOR_NONE 0 +#endif + +#ifndef DRM_FORMAT_MOD_NONE +#define DRM_FORMAT_MOD_NONE 0 +#endif + +#ifndef DRM_FORMAT_RESERVED +#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1) +#endif + +#ifndef DRM_FORMAT_MOD_INVALID +#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED) +#endif + +/* + * Linear Layout + * + * Just plain linear layout. Note that this is different from no specifying any + * modifier (e.g. not setting DRM_MODE_FB_MODIFIERS in the DRM_ADDFB2 ioctl), + * which tells the driver to also take driver-internal information into account + * and so might actually result in a tiled framebuffer. + */ +#ifndef DRM_FORMAT_MOD_LINEAR +#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0) +#endif + + +#define DRM_FORMAT_MOD_VENDOR_GF 0x19 +/*usage for display specially requirement*/ +#define DRM_FORMAT_MOD_GF_DISPLAY fourcc_mod_code(GF, 1) +#define DRM_FORMAT_MOD_GF_LINEAR DRM_FORMAT_MOD_LINEAR +#define DRM_FORMAT_MOD_GF_TILED fourcc_mod_code(GF, 3) +#define DRM_FORMAT_MOD_GF_COMPRESS fourcc_mod_code(GF, 4) +#define DRM_FORMAT_MOD_GF_TILED_COMPRESS fourcc_mod_code(GF, 5) + + +#define DRM_FORMAT_MOD_GF_LOCAL fourcc_mod_code(GF, 6) +#define DRM_FORMAT_MOD_GF_PCIE fourcc_mod_code(GF, 7) + +#define DRM_FORMAT_MOD_GF_RB_ALT fourcc_mod_code(GF, 8) + +#define DRM_FORMAT_MOD_GF_INVALID DRM_FORMAT_MOD_INVALID +#endif + diff --git a/drivers/gpu/drm/arise/shared/gf_perf.h b/drivers/gpu/drm/arise/shared/gf_perf.h new file mode 100755 index 0000000000000..958f87e3f0f45 --- /dev/null +++ b/drivers/gpu/drm/arise/shared/gf_perf.h @@ -0,0 +1,619 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __gf_perf_h__ +#define __gf_peff_h__ + +typedef struct gf_begin_perf_event_tag +{ + unsigned int max_event_num; /* in */ + unsigned int attrib_list[64]; /* in */ +} gf_begin_perf_event_t; + +typedef struct gf_end_perf_event_tag +{ + unsigned int placeholder; /* in */ +} gf_end_perf_event_t; + +typedef struct gf_get_perf_event_tag +{ + unsigned int max_event_num; /* in */ + unsigned int max_event_buffer_size; /* in */ + void *event_buffer; /* in/out */ + unsigned int event_filled_num; /* out */ + unsigned int event_buffer_filled_size; /* out */ + unsigned int event_lost_num; /* out */ + unsigned long long event_lost_timestamp;/* out */ + + void *isr_event_buffer; /* in/out */ + unsigned int isr_filled_num; /* out */ + unsigned int isr_filled_size; /* out */ +} gf_get_perf_event_t; + +typedef struct _gf_miu_list_item +{ + unsigned int write : 1; + unsigned int value_valid : 1; + unsigned int miu_type : 6; + unsigned int miu_offset : 24; + unsigned int miu_value; +}gf_miu_list_item_t; + +typedef struct gf_begin_miu_dump_tag +{ + unsigned int max_event_num; +}gf_begin_miu_dump_perf_event_t; + +typedef struct gf_end_miu_dump_tag +{ + unsigned int place_hoder; +}gf_end_miu_dump_perf_event_t; + +typedef struct gf_get_miu_dump_tag +{ + unsigned int max_event_num; + unsigned int max_event_buffer_size; + void *event_buffer; + unsigned int event_filled_num; + unsigned int event_buffer_filled_size; + unsigned int event_lost_num; + unsigned long long event_lost_timestamp; +}gf_get_miu_dump_perf_event_t; + +typedef struct gf_direct_get_miu_dump_tag +{ + gf_miu_list_item_t *miu_table; + unsigned int miu_table_length; + unsigned int timestamp_high; + unsigned int timestamp_low; +}gf_direct_get_miu_dump_perf_event_t; + +typedef struct gf_miu_reg_list_tag +{ + unsigned int miu_table_length; + gf_miu_list_item_t *miu_table; +}gf_miu_reg_list_perf_event_t; + +typedef struct gf_hwq_info_t +{ + unsigned int Usage_3D; + unsigned int Usage_VCP; + unsigned int Usage_VPP; + unsigned int sample_time; +}gf_hwq_info; + +typedef struct gfx_hwq_info_ext_t +{ + unsigned int ext_version; + unsigned int sample_time; + unsigned int Usage_3D; + unsigned int Usage_VPP; + unsigned int Usage_VCP0; + unsigned int Usage_VCP1; + unsigned int Usage_3D_High; + unsigned int reserved1; + unsigned int reserved2; + unsigned int reserved3; + unsigned int reserved4; + unsigned int reserved5; + unsigned int reserved6; + unsigned int reserved7; +}gfx_hwq_info_ext; + +//MUST be equal VCP_INFO_COUNT +#define VIDEO_INFO_NUM 17 +typedef struct gf_video_info_t +{ + unsigned short index; + unsigned int pid[VIDEO_INFO_NUM]; + unsigned short presentspeed[VIDEO_INFO_NUM]; + unsigned int bitrate[VIDEO_INFO_NUM]; + unsigned short width[VIDEO_INFO_NUM]; + unsigned short height[VIDEO_INFO_NUM]; + char codec[VIDEO_INFO_NUM][10]; + unsigned int TotalDecodeFrameNum[VIDEO_INFO_NUM]; + unsigned int TotalRenderFrameNum[VIDEO_INFO_NUM]; + char decodeapi[VIDEO_INFO_NUM][10]; + char presentapi[VIDEO_INFO_NUM][10]; + unsigned short decodespeed[VIDEO_INFO_NUM]; +}gf_video_info; + +typedef struct gf_perf_event_header_tag gf_perf_event_header_t; + +typedef struct gf_perf_event_gl_draw_enter_tag gf_perf_event_gl_draw_enter_t; +typedef struct gf_perf_event_gl_draw_exit_tag gf_perf_event_gl_draw_exit_t; +typedef struct gf_perf_event_cm_flush_enter_tag gf_perf_event_cm_flush_enter_t; +typedef struct gf_perf_event_cm_flush_exit_tag gf_perf_event_cm_flush_exit_t; +typedef struct gf_perf_event_swap_buffer_enter_tag gf_perf_event_swap_buffer_enter_t; +typedef struct gf_perf_event_swap_buffer_exit_tag gf_perf_event_swap_buffer_exit_t; +typedef struct gf_perf_event_present_enter_tag gf_perf_event_present_enter_t; +typedef struct gf_perf_event_present_exit_tag gf_perf_event_present_exit_t; +typedef struct gf_perf_event_dma_buffer_queued_tag gf_perf_event_dma_buffer_queued_t; +typedef struct gf_perf_event_dma_buffer_submitted_tag gf_perf_event_dma_buffer_submitted_t; +typedef struct gf_perf_event_dma_buffer_completed_tag gf_perf_event_dma_buffer_completed_t; +typedef struct gf_perf_event_lost_event_tag gf_perf_event_lost_event_t; +typedef struct gf_perf_event_vsync_tag gf_perf_event_vsync_t; +typedef struct gf_perf_event_ps_flip_tag gf_perf_event_ps_flip_t; +typedef struct gf_perf_event_overlay_flip_tag gf_perf_event_overlay_flip_t; + +typedef struct gf_perf_event_lock_enter_tag gf_perf_event_lock_enter_t; +typedef struct gf_perf_event_lock_exit_tag gf_perf_event_lock_exit_t; +typedef struct gf_perf_event_unlock_enter_tag gf_perf_event_unlock_enter_t; +typedef struct gf_perf_event_unlock_exit_tag gf_perf_event_unlock_exit_t; + +typedef struct gf_perf_event_enqueue_native_kernel_enter_tag gf_perf_event_enqueue_native_kernel_enter_t; +typedef struct gf_perf_event_enqueue_native_kernel_exit_tag gf_perf_event_enqueue_native_kernel_exit_t; +typedef struct gf_perf_event_enqueue_task_enter_tag gf_perf_event_enqueue_task_enter_t; +typedef struct gf_perf_event_enqueue_task_exit_tag gf_perf_event_enqueue_task_exit_t; +typedef struct gf_perf_event_enqueue_ndr_kernel_enter_tag gf_perf_event_enqueue_ndr_kernel_enter_t; +typedef struct gf_perf_event_enqueue_ndr_kernel_exit_tag gf_perf_event_enqueue_ndr_kernel_exit_t; + +typedef struct gf_perf_event_sync_event_tag gf_perf_event_sync_event_t; +typedef struct gf_perf_event_wait_start_tag gf_perf_event_wait_start_t; +typedef struct gf_perf_event_wait_finish_tag gf_perf_event_wait_finish_t; +typedef struct gf_perf_event_wait_on_server_finish_tag gf_perf_event_wait_on_server_finish_t; + +typedef struct gf_perf_event_miu_counter_dump_tag gf_perf_event_miu_counter_dump_t; + +typedef struct gf_perf_event_mm_lock_enter_tag gf_perf_event_mm_lock_enter_t; +typedef struct gf_perf_event_mm_lock_exit_tag gf_perf_event_mm_lock_exit_t; +typedef struct gf_perf_event_mm_unlock_enter_tag gf_perf_event_mm_unlock_enter_t; +typedef struct gf_perf_event_mm_unlock_exit_tag gf_perf_event_mm_unlock_exit_t; +typedef struct gf_perf_event_mm_alloc_enter_tag gf_perf_event_mm_alloc_enter_t; +typedef struct gf_perf_event_mm_alloc_exit_tag gf_perf_event_mm_alloc_exit_t; +typedef struct gf_perf_event_mm_free_enter_tag gf_perf_event_mm_free_enter_t; +typedef struct gf_perf_event_mm_free_exit_tag gf_perf_event_mm_free_exit_t; + +typedef struct gf_perf_event_bandwidth_tag gf_perf_event_bandwidth_t; + + + + +typedef union gf_perf_event_tag gf_perf_event_t; + +// perf event type +#define GF_PERF_EVENT_GL_DRAW_ENTER 0x1000 +#define GF_PERF_EVENT_GL_DRAW_EXIT 0x1001 +#define GF_PERF_EVENT_CM_FLUSH_ENTER 0x1002 +#define GF_PERF_EVENT_CM_FLUSH_EXIT 0x1003 +#define GF_PERF_EVENT_SWAP_BUFFER_ENTER 0x1004 +#define GF_PERF_EVENT_SWAP_BUFFER_EXIT 0x1005 +#define GF_PERF_EVENT_PRESENT_ENTER 0x1006 +#define GF_PERF_EVENT_PRESENT_EXIT 0x1007 +#define GF_PERF_EVENT_DMA_BUFFER_QUEUED 0x1008 +#define GF_PERF_EVENT_DMA_BUFFER_SUBMITTED 0x1009 +#define GF_PERF_EVENT_DMA_BUFFER_COMPLETED 0x100A +#define GF_PERF_EVENT_LOST_EVENT 0x100B +#define GF_PERF_EVENT_VSYNC 0x100C +#define GF_PERF_EVENT_PS_FLIP 0x100D +#define GF_PERF_EVENT_OVERLAY_FLIP 0x100E + +#define GF_PERF_EVENT_CL_ENQUEUE_NATIVE_KERNEL_ENTER 0x100F +#define GF_PERF_EVENT_CL_ENQUEUE_NATIVE_KERNEL_EXIT 0x1010 +#define GF_PERF_EVENT_CL_ENQUEUE_TASK_ENTER 0x1011 +#define GF_PERF_EVENT_CL_ENQUEUE_TASK_EXIT 0x1012 +#define GF_PERF_EVENT_CL_ENQUEUE_NDR_KERNEL_ENTER 0x1013 +#define GF_PERF_EVENT_CL_ENQUEUE_NDR_KERNEL_EXIT 0x1014 + +#define GF_PERF_EVENT_LOCK_ENTER 0x1015 +#define GF_PERF_EVENT_LOCK_EXIT 0x1016 +#define GF_PERF_EVENT_UNLOCK_ENTER 0x1017 +#define GF_PERF_EVENT_UNLOCK_EXIT 0x1018 +#define GF_PERF_EVENT_SYNC_EVENT 0x1019 +#define GF_PERF_EVENT_WAIT_START 0x101A +#define GF_PERF_EVENT_WAIT_FINISH 0x101B +#define GF_PERF_EVENT_WAIT_ON_SERVER_FINISH 0x101C + +#define GF_PERF_EVENT_HWC_FLUSH_ENTER 0x101E +#define GF_PERF_EVENT_HWC_FLUSH_EXIT 0x101F + +#define GF_PERF_EVENT_MIU_COUNTER 0x1020 + +#define GF_PERF_EVENT_MM_LOCK_ENTER 0x1050 +#define GF_PERF_EVENT_MM_LOCK_EXIT 0x1051 +#define GF_PERF_EVENT_MM_UNLOCK_ENTER 0x1052 +#define GF_PERF_EVENT_MM_UNLOCK_EXIT 0x1053 +#define GF_PERF_EVENT_MM_ALLOC_ENTER 0x1054 +#define GF_PERF_EVENT_MM_ALLOC_EXIT 0x1055 +#define GF_PERF_EVENT_MM_FREE_ENTER 0x1056 +#define GF_PERF_EVENT_MM_FREE_EXIT 0x1057 + + + +#define GF_PERF_EVENT_BANDWIDTH 0x1060 + + +#define GF_PERF_EVENT_INVALID_PID 0 +#define GF_PERF_EVENT_INVALID_TID 0 + +#define GF_PERF_EVENT_DMA_TYPE_2D 0x1 +#define GF_PERF_EVENT_DMA_TYPE_3D 0x2 +#define GF_PERF_EVENT_DMA_TYPE_3DBLT 0x3 +#define GF_PERF_EVENT_DMA_TYPE_PRESENT 0x4 +#define GF_PERF_EVENT_DMA_TYPE_PAGING 0x5 +#define GF_PERF_EVENT_DMA_TYPE_OVERLAY 0x6 + +struct gf_perf_event_header_tag +{ + unsigned int size; /* total event size */ + unsigned int type; /* event type */ + unsigned int pid; /* process id that generates the event */ + unsigned int tid; /* thead id that generates the event */ + unsigned int timestamp_low; /* ticks (or nanoseconds?) when generating the event */ + unsigned int timestamp_high; +}; + +struct gf_perf_event_gl_draw_enter_tag +{ + gf_perf_event_header_t header; + unsigned int frame_num; + unsigned int draw_num; +}; + +struct gf_perf_event_gl_draw_exit_tag +{ + gf_perf_event_header_t header; + unsigned int frame_num; + unsigned int draw_num; +}; + +struct gf_perf_event_cm_flush_enter_tag +{ + gf_perf_event_header_t header; +}; + +struct gf_perf_event_cm_flush_exit_tag +{ + gf_perf_event_header_t header; +}; + +struct gf_perf_event_swap_buffer_enter_tag +{ + gf_perf_event_header_t header; +}; + +struct gf_perf_event_swap_buffer_exit_tag +{ + gf_perf_event_header_t header; +}; + +struct gf_perf_event_present_enter_tag +{ + gf_perf_event_header_t header; +}; + +struct gf_perf_event_present_exit_tag +{ + gf_perf_event_header_t header; +}; + +struct gf_perf_event_dma_buffer_queued_tag +{ + gf_perf_event_header_t header; + unsigned int gpu_context; + unsigned int dma_idx_low; + unsigned int dma_idx_high; + unsigned int engine_idx; +}; + +struct gf_perf_event_dma_buffer_submitted_tag +{ + gf_perf_event_header_t header; + unsigned int dma_type; + unsigned int gpu_context; /* through gpu_context, dma_idx_low, dma_idx_high we can make connection */ + unsigned int dma_idx_low; /* between dma_buffer_queued and dma_buffer_submitted */ + unsigned int dma_idx_high; + unsigned int engine_idx; /* through engine_idx, fence_id_low, fence_id_high we can make connection */ + unsigned int fence_id_low; /* between dma_buffer_submitted and dma_buffer_completed */ + unsigned int fence_id_high; +}; + +struct gf_perf_event_dma_buffer_completed_tag +{ + gf_perf_event_header_t header; + unsigned int engine_idx; + unsigned int fence_id_low; + unsigned int fence_id_high; +}; + +struct gf_perf_event_lost_event_tag +{ + gf_perf_event_header_t header; + unsigned int lost_event_num; + unsigned int lost_timestamp_low; + unsigned int lost_timestamp_high; +}; + +struct gf_perf_event_vsync_tag +{ + gf_perf_event_header_t header; + unsigned int iga_idx; + unsigned int vsync_cnt_low; + unsigned int vsync_cnt_high; +}; + +struct gf_perf_event_ps_flip_tag +{ + gf_perf_event_header_t header; + unsigned int iga_idx; + unsigned int allocation; +}; + +struct gf_perf_event_overlay_flip_tag +{ + gf_perf_event_header_t header; + unsigned int iga_idx; + unsigned int overlay_idx; + unsigned int allocation; +}; + +struct gf_perf_event_lock_enter_tag +{ + gf_perf_event_header_t header; + unsigned int device; + unsigned int handle; // locked allocation handle + unsigned int flag; // lock flags +}; + +struct gf_perf_event_lock_exit_tag +{ + gf_perf_event_header_t header; + unsigned int device; + unsigned int handle; // locked allocation handle + unsigned int flag; // lock flags +}; + +struct gf_perf_event_unlock_enter_tag +{ + gf_perf_event_header_t header; + unsigned int device; + unsigned int handle; // locked allocation handle + +}; + +struct gf_perf_event_unlock_exit_tag +{ + gf_perf_event_header_t header; + unsigned int device; + unsigned int handle; // locked allocation handle +}; + +struct gf_perf_event_enqueue_native_kernel_enter_tag +{ + gf_perf_event_header_t header; + int cl_event;// is cl event, always be 1 +}; + +struct gf_perf_event_enqueue_native_kernel_exit_tag +{ + gf_perf_event_header_t header; + int cl_event; +}; + +struct gf_perf_event_enqueue_task_enter_tag +{ + gf_perf_event_header_t header; + int cl_event; +}; + +struct gf_perf_event_enqueue_task_exit_tag +{ + gf_perf_event_header_t header; + int cl_event; +}; + +struct gf_perf_event_enqueue_ndr_kernel_enter_tag +{ + gf_perf_event_header_t header; + int cl_event; +}; + +struct gf_perf_event_enqueue_ndr_kernel_exit_tag +{ + gf_perf_event_header_t header; + int cl_event; +}; + +struct gf_perf_event_sync_event_tag +{ + gf_perf_event_header_t header; + unsigned int engine_idx; + unsigned int type; // the sync type + unsigned int handle; + unsigned int fence_value_high; + unsigned int fence_value_low; + unsigned int gpu_context; + unsigned int ctx_task_id_high; + unsigned int ctx_task_id_low; +}; + +typedef struct gf_perf_event_wait_instance_tag +{ + unsigned int handle; + unsigned int fence_value_high; + unsigned int fence_value_low; + unsigned int timeout; +}gf_perf_event_wait_instance_t; + +struct gf_perf_event_wait_start_tag +{ + gf_perf_event_header_t header; + unsigned int engine_idx; + unsigned int gpu_context; + unsigned int task_id_high; + unsigned int task_id_low; + gf_perf_event_wait_instance_t instance[32]; +}; + +struct gf_perf_event_wait_finish_tag +{ + gf_perf_event_header_t header; + unsigned int engine_idx; + unsigned int gpu_context; + unsigned int status; + unsigned int task_id_high; + unsigned int task_id_low; +}; + +struct gf_perf_event_wait_on_server_finish_tag +{ + gf_perf_event_header_t header; + unsigned int engine_idx; + unsigned int gpu_context; + unsigned int task_id_high; + unsigned int task_id_low; +}; + +struct gf_perf_event_miu_counter_dump_tag +{ + gf_perf_event_header_t header; + unsigned int fence_id_high; + unsigned int fence_id_low; + unsigned int task_id_high; + unsigned int task_id_low; + unsigned int gpu_context; + + unsigned int counter_buffer_offset; + unsigned int buffer_length; +}; + +struct gf_perf_event_mm_lock_enter_tag +{ + gf_perf_event_header_t header; + unsigned int handle; // allocation handle +}; + +struct gf_perf_event_mm_lock_exit_tag +{ + gf_perf_event_header_t header; + unsigned int handle; // allocation handle +}; + +struct gf_perf_event_mm_unlock_enter_tag +{ + gf_perf_event_header_t header; + unsigned int handle; // allocation handle +}; + +struct gf_perf_event_mm_unlock_exit_tag +{ + gf_perf_event_header_t header; + unsigned int handle; // allocation handle +}; + +struct gf_perf_event_mm_alloc_enter_tag +{ + gf_perf_event_header_t header; +}; + +struct gf_perf_event_mm_alloc_exit_tag +{ + gf_perf_event_header_t header; + unsigned int handle; // allocation handle +}; + +struct gf_perf_event_mm_free_enter_tag +{ + gf_perf_event_header_t header; + unsigned int handle; // allocation handle +}; + +struct gf_perf_event_mm_free_exit_tag +{ + gf_perf_event_header_t header; + unsigned int handle; // allocation handle +}; + +typedef struct gf_perf_event_bandwidth_data_tag +{ + unsigned int diu_rd_db; + unsigned int diu_wr_db; + + unsigned int gfx_rd_db; + unsigned int gfx_wr_db; + + unsigned int vpp_rd_db; + unsigned int vpp_wr_db; + + unsigned int vcp_rd_db; + unsigned int vcp_wr_db; + + unsigned int local_rd_db; + unsigned int local_wr_db; + + unsigned int pcie_rd_db; + unsigned int pcie_wr_db; +} gf_perf_event_bandwidth_data_t; + +struct gf_perf_event_bandwidth_tag +{ + gf_perf_event_header_t header; + gf_perf_event_bandwidth_data_t bandwidth_data; +}; + +union gf_perf_event_tag +{ + gf_perf_event_header_t header; + gf_perf_event_gl_draw_enter_t gl_draw_enter; + gf_perf_event_gl_draw_exit_t gl_draw_exit; + gf_perf_event_cm_flush_enter_t cm_flush_enter; + gf_perf_event_cm_flush_exit_t cm_flush_exit; + gf_perf_event_swap_buffer_enter_t swap_buffer_enter; + gf_perf_event_swap_buffer_exit_t swap_buffer_exit; + gf_perf_event_present_exit_t present_enter; + gf_perf_event_present_exit_t present_exit; + gf_perf_event_dma_buffer_queued_t dma_buffer_queued; + gf_perf_event_dma_buffer_submitted_t dma_buffer_submitted; + gf_perf_event_dma_buffer_completed_t dma_buffer_completed; + gf_perf_event_lost_event_t lost_event; + gf_perf_event_vsync_t vsync_event; + gf_perf_event_ps_flip_t ps_flip_event; + gf_perf_event_overlay_flip_t overlay_flip_event; + + gf_perf_event_lock_enter_t lock_enter; + gf_perf_event_lock_exit_t lock_exit; + gf_perf_event_unlock_enter_t unlock_enter; + gf_perf_event_unlock_exit_t unlock_exit; + + gf_perf_event_enqueue_native_kernel_enter_t eq_native_kernel_enter; + gf_perf_event_enqueue_native_kernel_exit_t eq_native_kernel_exit; + gf_perf_event_enqueue_task_enter_t eq_task_enter; + gf_perf_event_enqueue_task_exit_t eq_task_exit; + gf_perf_event_enqueue_ndr_kernel_enter_t eq_ndr_kernel_enter; + gf_perf_event_enqueue_ndr_kernel_exit_t eq_ndr_kernel_exit; + + gf_perf_event_sync_event_t sync_event; + gf_perf_event_wait_start_t wait_start; + gf_perf_event_wait_finish_t wait_finish; + gf_perf_event_wait_on_server_finish_t wait_on_server_finish; + gf_perf_event_miu_counter_dump_t miu_counter; + + gf_perf_event_mm_lock_enter_t mm_lock_enter; + gf_perf_event_mm_lock_exit_t mm_lock_exit; + gf_perf_event_mm_unlock_enter_t mm_unlock_enter; + gf_perf_event_mm_unlock_exit_t mm_unlock_exit; + gf_perf_event_mm_alloc_enter_t mm_alloc_enter; + gf_perf_event_mm_alloc_exit_t mm_alloc_exit; + gf_perf_event_mm_free_enter_t mm_free_enter; + gf_perf_event_mm_free_exit_t mm_free_exit; + + gf_perf_event_bandwidth_t bandwidth; +}; + +typedef struct gf_perf_status_tag +{ + int started; /* out */ + int miu_started; /* out */ +} gf_perf_status_t; +#endif diff --git a/drivers/gpu/drm/arise/shared/gf_types.h b/drivers/gpu/drm/arise/shared/gf_types.h new file mode 100644 index 0000000000000..6a36a4d5a5148 --- /dev/null +++ b/drivers/gpu/drm/arise/shared/gf_types.h @@ -0,0 +1,561 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __GF_TYPES_H__ +#define __GF_TYPES_H__ + +#include "gf_def.h" + +typedef enum +{ + GF_USAGE_DISPLAY_SURFACE = 0x00000001, + GF_USAGE_OVERLAY_SURFACE = 0x00000002, + GF_USAGE_CURSOR_SURFACE = 0x00000004, + GF_USAGE_RENDER_TARGET = 0x00000008, + GF_USAGE_TEXTURE_BUFFER = 0x00000010, + GF_USAGE_SHADER_BUFFER = 0x00000020, + GF_USAGE_DATA_BUFFER = 0x00000040, + GF_USAGE_TEMP_BUFFER = 0x00000080, + GF_USAGE_COMPOSER_SURFACE = 0x00000100, + GF_USAGE_SHADOW_SURFACE = 0x00000200, + GF_USAGE_VIDEO = 0x00000400, + GF_USAGE_VIDEO_DECODER = 0x00000400, + GF_USAGE_CAMERA = 0x00000800, + GF_USAGE_VIDEO_ENCODER = 0x00001000, + GF_USAGE_RENDER_SCRIPT = 0x00002000, + + GF_USAGE_CREATE_PIXMAP = 0x01000000, + GF_USAGE_MIU_COUNTER = 0x02000000, + + GF_USAGE_FORCE_PCIE = 0x00004000, + GF_USAGE_FORCE_LOCAL = 0x00008000, + GF_USAGE_HWCTX_BUFFER = 0x00010000, + GF_USAGE_FRAMEBUFFER = 0x08000000, + GF_USAGE_TRY_TILED = 0x80000000, +}gf_usage_bit; + +typedef enum +{ + GF_ACCESS_UNKNOWN = 0, + GF_ACCESS_GPU_ONLY = 1, + GF_ACCESS_GPU_ALMOST, + GF_ACCESS_CPU_ALMOST, +// GF_ACCESS_CPU_ONLY, +}gf_access_hint; + +/* GF Format description: + All the format define as big endian byte order + the first named component is in the least-significant bits + This format as same as HSF_XXX + For example: + GF_FORMAT_R8G8B8A8_UNORM + char *pR8G8B8A8 = + pR8G8B8A8[0] = r; //R + pR8G8B8A8[1] = g; //G + pR8G8B8A8[2] = b; //B + pR8G8B8A8[3] = a; //A + + GF_FORMAT_B5G6R5_UNORM + unsigned short * p565Color + *p565Color = b | r << 5 | g << 11; + +*/ +typedef enum +{ + GF_FORMAT_A8_UNORM = 1, + GF_FORMAT_B5G6R5_UNORM = 2, /*rmask 0xf800; gmask 0x7e0; bmask 0x1f*/ + GF_FORMAT_B5G5R5A1_UNORM = 3, + GF_FORMAT_A1B5G5R5_UNORM = 4, + GF_FORMAT_B4G4R4A4_UNORM = 5, + GF_FORMAT_A4B4G4R4_UNORM = 6, + GF_FORMAT_B8G8R8A8_UNORM = 7, /*rmask 0x00ff0000; gmask 0x0000ff00; bmask 0x000000ff; amask 0xff000000*/ + GF_FORMAT_B8G8R8X8_UNORM = 8, + GF_FORMAT_R8G8B8A8_UNORM = 9, /*rmask 0x000000ff; gmask 0x0000ff00; bmask 0x00ff0000; amask 0xff000000*/ + GF_FORMAT_R8G8B8X8_UNORM = 10, + GF_FORMAT_A8R8G8B8_UNORM = 11, + GF_FORMAT_YUY2 = 12, + GF_FORMAT_NV12_LINEAR = 13, + GF_FORMAT_NV12_TILED = 14, + GF_FORMAT_NV21_LINEAR = 15, + GF_FORMAT_YV12 = 16, + GF_FORMAT_FLOAT32 = 17, + GF_FORMAT_UINT32 = 18, + GF_FORMAT_INT32 = 19, + GF_FORMAT_R8_UNORM = 20, + + GF_FORMAT_RAW10 = 21, + GF_FORMAT_RAW16 = 22, + GF_FORMAT_RAW_OPAQUE = 23, + GF_FORMAT_B10G10R10A2_UNORM = 24, + GF_FORMAT_R8G8_UNORM = 25, + GF_FORMAT_R16_UNORM = 26, + GF_FORMAT_R16G16_UNORM = 27, + GF_FORMAT_P010 = 28, + GF_FORMAT_L8_UNORM = 29, + GF_FORMAT_L8A8_UNORM = 30, + GF_FORMAT_R8G8B8_UNORM = 31, + GF_FORMAT_R4G4B4A4_UNORM = 32, + GF_FORMAT_R5G5B5A1_UNORM = 33, + GF_FORMAT_D16_UNORM = 34, + GF_FORMAT_S8_UINT = 35, + + GF_FORMAT_B8G8R8A8_SRGB = 36, +}gf_format; + +typedef struct +{ + unsigned int device; /* in */ + unsigned int reference; /* in, for rename create, if set this field, ignore all follow input field */ + unsigned int width; /* in */ + unsigned int height; /* in */ + unsigned int usage_mask; /* in */ + gf_format format; /* in */ + gf_ptr64_t user_ptr; /* in */ + unsigned int user_buf_size; /* in */ + gf_access_hint access_hint; /* in */ + unsigned int fence_sync : 1; /* in */ + unsigned int unpagable : 1; /* in/out */ + unsigned int tiled : 1; /* in/out */ + unsigned int secured : 1; /* in/out */ + unsigned int compressed : 1; /* in/out */ + unsigned int primary : 1; /* in/out */ + unsigned int has_pages : 1; /* out */ + unsigned int force_clear : 1; /* out */ + + unsigned int hw_format; /* out */ + unsigned int size; /* out */ + unsigned int width_aligned; /* out */ + unsigned int height_aligned; /* out */ + unsigned int bit_cnt; /* out */ + unsigned int pitch; /* out */ + unsigned int tiled_width; /* out */ + unsigned int tiled_height; /* out */ + unsigned int allocation; /* out */ + + unsigned int sync_obj; /* out */ + unsigned int compress_format; /* out */ + unsigned int buffer_fd; /* out */ + unsigned int segment_id; /* out */ + unsigned long long gpu_virt_addr; /* out */ + unsigned long long fence_addr; /* out */ +}gf_create_allocation_t; + +typedef struct +{ + unsigned int device; /* in */ + unsigned int allocation; /* in */ + + unsigned int size; /* out */ + unsigned int alignment; /* out */ + unsigned int width; /* out */ + unsigned int height; /* out */ + unsigned int aligned_width; /* out */ + unsigned int aligned_height; /* out */ + unsigned int tiled_width; /* out */ + unsigned int tiled_height; /* out */ + unsigned int bit_cnt; /* out */ + unsigned int pitch; /* out */ + unsigned int unpagable : 1; /* out */ + unsigned int tiled : 1; /* out */ + unsigned int secured : 1; /* out */ + unsigned int snoop : 1; /* out */ + unsigned int local : 1; /* out */ + unsigned int ForceLocal: 1; /* out */ + unsigned int has_pages : 1; /* out */ + unsigned int cpu_visible :1; /* out */ + unsigned int force_clear : 1; /* out */ + + unsigned int compress_format; /* out */ + unsigned int hw_format; /* out */ + unsigned int segment_id; /* out */ + unsigned int bl_slot_index; /* out */ + + unsigned int sync_obj; /* out */ + unsigned long long gpu_virt_addr; /* out */ + unsigned long long cpu_phy_addr; /* out */ + unsigned long long fence_addr; /* out */ +}gf_open_allocation_t; + +typedef struct +{ + unsigned int device; /* in */ + unsigned int allocation; /* in */ +}gf_destroy_allocation_t; + +typedef struct +{ + unsigned int device; /* out */ +}gf_create_device_t; + +typedef struct +{ + unsigned int device; /* in */ + unsigned int engine_index; /* in */ + unsigned int flags; /* in */ + unsigned int context; /* out */ +}gf_create_context_t; + +typedef struct +{ + unsigned int device; /* in */ + unsigned int context; /* in */ +}gf_destroy_context_t; + +typedef struct +{ + unsigned int device; /* in */ + unsigned int stream_id; /* in video stream id */ + unsigned int context; /* out */ + unsigned int hw_idx; /* out */ +}gf_create_di_context_t; + +typedef struct +{ + unsigned int device; /* in */ + unsigned int context; /* in */ +}gf_destroy_di_context_t; + +typedef struct +{ + gf_ptr64_t ptr; + unsigned int size; + unsigned int pad; +}gf_cmdbuf_t; + +typedef struct +{ + unsigned int ValidHead; + unsigned int HWCtxBufIndex; + unsigned int Pad; // for alignment request + unsigned int GF_Interface_Version; + + union + { + struct + { + unsigned int Contain3dCmd :1; // keep consistent with source_new, not used for elite + unsigned int ContainLpdpCmd :1; + unsigned int CLCSOnly :1; // opencl without 2D/3D blt/L2 invalidate + unsigned int Flag2dCmd :1; // Xserver 2d command + unsigned int Flag3dbltCmd :1; // Xserver composite 3d blt command + unsigned int DvfsForceLevel :3; + unsigned int InitializeContext :1; + unsigned int ContainDIP :1; + unsigned int TraceDMA :1; + + unsigned int resize_command_buffer :1; /* resize command buffer after render */ + unsigned int resize_allocation_list :1; /* resize allocation list after render */ + unsigned int resize_patch_location_list :1; /* resize patch location list after render */ + unsigned int null_rendering :1; /* null rendering, refer to WDK */ + unsigned int normal_recovery :1; /* recovery normally if engine hang */ + unsigned int ForceSlice :1; /* ForceSlice */ + unsigned int Reserved :15; + }; + unsigned int flags; + }; +} gf_render_flags_t; + +typedef struct gf_allocation_list +{ + unsigned int hAllocation; + union + { + struct + { + unsigned int WriteOperation : 1; // 0x00000001 + unsigned int DoNotRetireInstance : 1; // 0x00000002 + unsigned int Reserved :30; // 0xFFFFFFFC + }; + unsigned int Value; + }; +} gf_allocation_list_t; + +typedef struct gf_patchlocation_list +{ + unsigned int AllocationIndex; + union { + struct + { + unsigned int SlotId : 24; // 0x00FFFFFF + unsigned int Reserved : 8; // 0xFF000000 + }; + unsigned int Value; + }; + + unsigned int DriverId; + unsigned int AllocationOffset; + unsigned int PatchOffset; + unsigned int SplitOffset; +} gf_patchlocation_list_t; + +typedef struct gf_syncobj_list +{ + unsigned int hSyncObject; + unsigned int PatchOffset; + unsigned long long FenceValue; +} gf_syncobj_list_t; + +typedef struct +{ + unsigned int context; /* in */ + unsigned int command_length; /* in(number of bytes) */ + unsigned int allocation_count; /* in */ + unsigned int patch_location_count; /* in */ + unsigned int sync_object_count; /* in */ + unsigned int cmdbuf_count; /* in */ + gf_render_flags_t flags; + unsigned int pad; + gf_ptr64_t allocation_list; + gf_ptr64_t patch_location_list; + gf_ptr64_t sync_object_list; + gf_ptr64_t cmdbuf_array; +}gf_render_t; + +/**************fence sync object relate***************/ +#define GF_SYNC_OBJ_TYPE_MUTEX 1 +#define GF_SYNC_OBJ_TYPE_SEMPAPHORE 2 +#define GF_SYNC_OBJ_TYPE_FENCE 3 +#define GF_SYNC_OBJ_TYPE_CPU_NOTIFICATION 4 +#define GF_SYNC_OBJ_TYPE_DMAFENCE 15 +typedef struct +{ + unsigned int type; + unsigned int device; /* in */ + unsigned int fence_sync_object; /* out */ + unsigned int pad; + union { + struct { + unsigned long long init_value; /* in */ + unsigned long long fence_addr; /* out */ + } fence; + + struct { + unsigned int init_state; + } mutex; + + struct { + unsigned int event; + } cpu_notification; + + struct { + unsigned int max_count; + unsigned int init_count; + } semaphore; + }; +}gf_create_fence_sync_object_t; + + +typedef struct +{ + unsigned int device; /* in */ + unsigned int fence_sync_object; /* in */ +}gf_destroy_fence_sync_object_t; + +#define GF_SYNC_OBJ_ERROR -1 +#define GF_SYNC_OBJ_INVALID_ARGU -2 +#define GF_SYNC_OBJ_ALREAD_SIGNALED 1 +#define GF_SYNC_OBJ_TIMEOUT_EXPIRED 2 +#define GF_SYNC_OBJ_CONDITION_SATISFIED 3 +#define GF_SYNC_OBJ_WAIT_ON_SERVER 4 +#define GF_SYNC_OBJ_UNSIGNALED 5 + +typedef struct +{ + unsigned int context; /* in */ + unsigned int fence_sync_object; /* in */ + unsigned long long timeout; /* in nano_sec */ //timeout == 0, no wait just return current object status + unsigned long long fence_value; /* in */ + unsigned int server_wait; /* in */ + int status; /* out */ +}gf_wait_fence_sync_object_t; + +#define GF_SET_FENCE_VALUE 0x01 +#define GF_GET_FENCE_VALUE 0x02 + +typedef struct +{ + unsigned int device; /* in */ + unsigned int opcode; /* in */ + unsigned int fence_sync_object; /* in */ + int appid; /* out */ + int flip_limit; /* out */ + int discard_sync; /* in & out*/ + unsigned long long fence_value; /* out */ +}gf_fence_value_t; + +typedef struct +{ + unsigned int context; /* in */ + unsigned int server_wait; /* in */ + unsigned long long timeout; /* in nano_sec */ //timeout == 0, no wait just return current object status + int status; /* out */ + int pad; /* out */ +}gf_wait_fence_t; + +#define gf_align_down(val, align) ((val) & ~((align) - 1)) +#define gf_align_up(val, align) (((val) + ((align) - 1)) & ~((align) - 1)) + +typedef enum +{ + PDISCARD = 0, + PLOW, + PNORMAL, + PHIGH, + PMAX, + PALL, +} gf_allocation_priority_t; + +typedef struct +{ + unsigned int Size; // inout + unsigned int HwFormat; // in + unsigned int HWCompressFormat; // in + unsigned int AtType; // in + unsigned int Priority; // in + unsigned int Alignment; // in + unsigned int PreferredSegment; // in + unsigned int BitCount; // in + unsigned int Width; // in + unsigned int Height; // in + unsigned int Pitch; // in + + unsigned int MaximumRenamingListLength; // in + + unsigned int bSecurity :1; // in + unsigned int CpuVisible :1; // in + unsigned int Primary :1; // in + unsigned int Swizzled :1; // in + unsigned int Video :1; // in + unsigned int Overlay :1; // in + unsigned int Camera :1; // in + unsigned int bNonSnoop :1; // in + unsigned int bVideoInternal :1; // in + unsigned int Unpagable :1; // in + unsigned int FenceSync :1; // in, TODO(deleted) + + unsigned int hAllocation; // out + unsigned int FenceSyncObject; // out + unsigned int pad; + unsigned long long FenceAddress; // out + + unsigned long long PhysAddr; // out + unsigned long long Address; // out +} gf_create_alloc_info_t; + +typedef struct +{ + unsigned int device; + unsigned int NumAllocations; + gf_ptr64_t pAllocationInfo; +} gf_create_resource_t; + +typedef struct +{ + unsigned int handle; // in + unsigned int offset; // in + unsigned int size; // in + unsigned int readonly:1;// in +} gf_drm_gem_begin_cpu_access_t; + +typedef struct +{ + unsigned int handle; +} gf_drm_gem_end_cpu_access_t; + +typedef struct +{ + unsigned int gem_handle; + unsigned int pad; + unsigned long long offset; + unsigned int prefault_num; + unsigned int delay_map; +} gf_drm_gem_map_t; + +typedef struct +{ + unsigned int crtc_id; /* in */ + unsigned int pipe; /* out */ +} gf_kms_get_pipe_from_crtc_t; + +typedef struct +{ + unsigned int device; /* in */ + unsigned int context; /* in */ + unsigned int hw_ctx_buf_index; /* in */ +} gf_add_hw_ctx_buf_t; + +typedef struct +{ + unsigned int device; /* in */ + unsigned int context; /* in */ + unsigned int hw_ctx_buf_index; /* in */ +} gf_rm_hw_ctx_buf_t; + +#define GF_MISC_GET_3DBLT_CODE (1) +typedef struct +{ + unsigned int size; // output + unsigned int capacity; // output + unsigned long long base; // output +} gf_misc_get_3dblt_code_t; + +#define GF_MISC_SET_3DBLT_CODE (2) +typedef struct +{ + unsigned int size; // input + unsigned int pad; // for alignment + gf_ptr64_t data; // input +} gf_misc_set_3dblt_code_t; + +#define GF_MISC_MAP_GPUVA (3) +typedef struct +{ + unsigned int allocation; // input + unsigned int pad; // for alignment + unsigned long long gpu_va; // input +} gf_misc_map_gpuva_t; + +#define GF_MISC_VIDEO_FENCE_GET (4) +typedef struct +{ + unsigned int index; // input + unsigned int fence; // output +} gf_misc_video_fence_get_t; + +#define GF_MISC_VIDEO_FENCE_CLEAR (5) +typedef struct +{ + unsigned int index; // input +} gf_misc_video_fence_clear_t; + +typedef struct +{ + unsigned int op_code; + unsigned int device; + unsigned int context; + unsigned int pad; // for alignment + union { + gf_misc_get_3dblt_code_t get_3dblt_code; + gf_misc_set_3dblt_code_t set_3dblt_code; + gf_misc_map_gpuva_t map_gpuva; + gf_misc_video_fence_get_t video_fence_get; + gf_misc_video_fence_clear_t video_fence_clear; + }; +} gf_cil2_misc_t; + +#define GF_DEBUGFS_GEM_ENABLE 0x1 +#define GF_DEBUGFS_FAKE_HANG 0x2 + +#endif /* __GF_TYPES_H__*/ + diff --git a/drivers/gpu/drm/arise/shared/os_interface.h b/drivers/gpu/drm/arise/shared/os_interface.h new file mode 100644 index 0000000000000..594bc4f0b3922 --- /dev/null +++ b/drivers/gpu/drm/arise/shared/os_interface.h @@ -0,0 +1,311 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#ifndef __OS_INTERFACE_H__ +#define __OS_INTERFACE_H__ + +#include "kernel_import.h" + +#if !defined(GF_API_CALL) +#define GF_API_CALL +#endif + +extern void gf_udelay(unsigned long long usecs_num); +extern unsigned long long gf_do_div(unsigned long long x, unsigned long long y); +extern void gf_msleep(int); +extern void gf_getsecs(long *secs, long *usecs); +extern void gf_get_nsecs(unsigned long long *nsecs); +extern void GF_API_CALL gf_assert(int a, const char *msg); +extern void gf_dump_stack(void); + +extern int gf_find_first_zero_bit(void *buf, unsigned int size); +extern int gf_find_next_zero_bit(void *buf, unsigned int size, int offset); +extern void gf_set_bit(unsigned int nr, void *buf); +extern void gf_clear_bit(unsigned int nr, void *buf); + +extern struct os_atomic *gf_create_atomic(int val); +extern void gf_destroy_atomic(struct os_atomic *atomic); +extern int gf_atomic_read(struct os_atomic *atomic); +extern void gf_atomic_inc(struct os_atomic *atomic); +extern void gf_atomic_dec(struct os_atomic *atomic); +extern int gf_atomic_add(struct os_atomic *atomic, int v); +extern int gf_atomic_sub(struct os_atomic *atomic, int v); + +extern struct os_mutex *gf_create_mutex(void); +extern void gf_destroy_mutex(struct os_mutex *mutex); +extern void gf_mutex_lock(struct os_mutex *mutex); +extern int gf_mutex_lock_killable(struct os_mutex *mutex); +extern int gf_mutex_trylock(struct os_mutex *mutex); +extern void gf_mutex_unlock(struct os_mutex *mutex); + +extern struct os_sema *gf_create_sema(int value); +extern void gf_destroy_sema(struct os_sema *sema); +extern void gf_down(struct os_sema *sema); +extern int gf_down_trylock(struct os_sema *sema); +extern void gf_up(struct os_sema *sema); + +extern struct os_rwsema *gf_create_rwsema(void); +extern void gf_destroy_rwsema(struct os_rwsema *sema); +extern void gf_down_read(struct os_rwsema *sema); +extern void gf_down_write(struct os_rwsema *sema); +extern void gf_up_read(struct os_rwsema *sema); +extern void gf_up_write(struct os_rwsema *sema); + +extern struct os_spinlock *gf_create_spinlock(int type); +extern void gf_destroy_spinlock(struct os_spinlock *spin); +extern void gf_spin_lock(struct os_spinlock *spin); +extern int gf_spin_try_lock(struct os_spinlock *spin); +extern void gf_spin_unlock(struct os_spinlock *spin); +extern unsigned long gf_spin_lock_irqsave(struct os_spinlock *spin); +extern void gf_spin_unlock_irqrestore(struct os_spinlock *spin, unsigned long flags); + +extern int GF_API_CALL gf_copy_from_user(void *to, const void *from, unsigned long size); +extern int GF_API_CALL gf_copy_to_user(void *to, const void *from, unsigned long size); + +extern void* GF_API_CALL gf_memset(void *s, int c, unsigned long count); +extern void* GF_API_CALL gf_memcpy(void *d, const void *s, unsigned long count); +extern int GF_API_CALL gf_memcmp(const void *, const void *, unsigned long); +extern void GF_API_CALL gf_byte_copy(char* dst, char* src, int len); + +extern int gf_strcmp(const char *, const char *); +extern char* gf_strcpy(char *, const char *); +extern int gf_strncmp(const char *, const char *, unsigned long); +extern char* gf_strncpy(char *, const char *, unsigned long); +extern unsigned long gf_strlen(char *s); + +extern void gf_usleep_range(long min, long max); +extern int gf_get_platform_config(void *dev, const char* config_name, int *buffer, int length); +extern void gf_printf(struct os_printer *p, const char *f, ...); +extern struct os_printer gf_info_printer(void *dev); +extern struct os_printer gf_seq_file_printer(struct os_seq_file *f); +extern unsigned long gf_get_current_pid(void); +extern unsigned long gf_get_current_tid(void); +extern void gf_get_current_pname(char *pname, int size); + + + + +/****************************** IO access functions*********************************/ +extern unsigned long long GF_API_CALL gf_read64(void *addr); +extern unsigned int GF_API_CALL gf_read32(void *addr); +extern unsigned short GF_API_CALL gf_read16(void *addr); +extern unsigned char GF_API_CALL gf_read8(void *addr); +extern void GF_API_CALL gf_write32(void *addr, unsigned int val); +extern void GF_API_CALL gf_write16(void *addr, unsigned short val); +extern void GF_API_CALL gf_write8(void *addr, unsigned char val); + +extern int GF_API_CALL gf_vsprintf(char *buf, const char *fmt, ...); +extern int GF_API_CALL gf_vsnprintf(char *buf, unsigned long size, const char *fmt, ...); + +extern int GF_API_CALL gf_sscanf(char *buf, char *fmt, ...); + +extern void GF_API_CALL gf_printk(unsigned int msglevel, const char* fmt, ...); +extern void GF_API_CALL gf_cb_printk(const char* msg); + +#ifdef _DEBUG_ +#define GF_MSG_LEVEL GF_DRV_DEBUG +#define gf_debug(args...) gf_printk(GF_DRV_DEBUG, ##args) +#else +#define GF_MSG_LEVEL GF_DRV_INFO +#define gf_debug(args...) +#endif + +#define gf_emerg(args...) gf_printk(GF_DRV_EMERG, ##args) +#define gf_error(args...) gf_printk(GF_DRV_ERROR, ##args) +#define gf_info(args...) gf_printk(GF_DRV_INFO, ##args) +#define gf_warning(args...) gf_printk(GF_DRV_WARNING, ##args) + +extern struct os_wait_queue* gf_create_wait_queue(void); +extern struct os_wait_event* gf_create_event(int); +extern void gf_destroy_event(void *event); +extern gf_event_status_t gf_wait_event_thread_safe(struct os_wait_event *event, condition_func_t condition, void *argu, int msec); +extern void gf_wake_up_event(struct os_wait_event *event); +extern gf_event_status_t gf_wait_event(struct os_wait_event *event, int msec); + +extern void* gf_create_thread(gf_thread_func_t func, void *data, const char *thread_name); +extern void gf_destroy_thread(void *thread); +extern int gf_thread_should_stop(void); +extern void gf_thread_wake_up(struct os_wait_event *event); +extern gf_event_status_t gf_thread_wait(struct os_wait_event *event, int msec); + +extern struct os_file *gf_file_open(const char *path, int flags, unsigned short mode); +extern void gf_file_close(struct os_file *file); +extern int gf_file_read(struct os_file *file, void *buf, unsigned long size, unsigned long long *read_pos); +extern int gf_file_write(struct os_file *file, void *buf, unsigned long size); + +extern int gf_try_to_freeze(void); +extern void gf_set_freezable(void); +extern void gf_old_set_freezable(void); +extern void gf_clear_freezable(void); +extern int gf_freezing(void); +extern int gf_freezable(void); + +/* os private alloc pages func*/ +extern struct os_pages_memory* gf_allocate_pages_memory_priv(void *pdev, int size, int page_size, alloc_pages_flags_t alloc_flags); +extern void gf_free_pages_memory_priv(void *pdev, struct os_pages_memory *memory); +extern gf_vm_area_t *gf_map_pages_memory_priv(void *process_context, gf_map_argu_t *map); +extern void gf_unmap_pages_memory_priv(gf_vm_area_t *vm_area); +extern gf_vm_area_t *gf_map_io_memory_priv(void *process_context, gf_map_argu_t *map); +extern void gf_unmap_io_memory_priv(gf_vm_area_t *map); +extern void gf_pages_memory_for_each_continues(struct os_pages_memory *memory, void *arg, + int (*cb)(void *arg, int page_start, int page_cnt, unsigned long long dma_addr)); + +extern void gf_flush_cache(void *pdev, gf_vm_area_t *vma, struct os_pages_memory* memory, unsigned int offset, unsigned int size); +extern void gf_inv_cache(void *pdev, gf_vm_area_t *vma, struct os_pages_memory* memory, unsigned int offset, unsigned int size); +extern int gf_mtrr_add(unsigned long base, unsigned long size); +extern int gf_mtrr_del(int reg, unsigned long base, unsigned long size); + +/* os private malloc func */ +extern void* gf_malloc_priv(unsigned long size); +extern void* gf_calloc_priv(unsigned long size); +extern void gf_free_priv(void *addr); + +extern int gf_get_command_status16(void *dev, unsigned short *command); +extern int gf_get_command_status32(void *dev, unsigned int *command); +extern int gf_write_command_status16(void *dev, unsigned short command); +extern int gf_write_command_status32(void *dev, unsigned int command); +extern int gf_get_rom_save_addr(void *dev, unsigned int *romsave); +extern int gf_write_rom_save_addr(void *dev, unsigned int romsave); +extern int gf_get_bar1(void *dev, unsigned int *bar1); +extern int gf_pci_get_rom(void *dev, void *buf, unsigned int buf_size); + +extern void gf_get_bus_config(void *pdev, bus_config_t *bus); +extern unsigned long gf_get_rom_start_addr(void *dev); +extern void *gf_ioremap( unsigned int io_base, unsigned int size); +extern void gf_iounmap(void *map_address); + +/* mem track func*/ +extern void gf_mem_track_init(void); +extern void gf_mem_track_list_result(void); +extern void gf_mem_leak_list(void); + +/* malloc track func*/ +extern void* gf_malloc_track(unsigned long size, const char *file, unsigned int line); +extern void* gf_calloc_track(unsigned long size, const char *file, unsigned int line); +extern void gf_free_track(void *addr, const char *file, unsigned int line); +extern void gf_mem_leak_list(void); + +#if GF_MALLOC_TRACK +#define gf_malloc(size) gf_malloc_track(size, __FILE__, __LINE__) +#define gf_calloc(size) gf_calloc_track(size, __FILE__, __LINE__) +#define gf_free(addr) gf_free_track(addr, __FILE__, __LINE__) +#else +#define gf_malloc(size) gf_malloc_priv(size) +#define gf_calloc(size) gf_calloc_priv(size) +#define gf_free(addr) gf_free_priv(addr) +#endif + +/* alloc pages track func*/ +extern struct os_pages_memory *gf_allocate_pages_memory_track(void *pdev, int size, int page_size, + alloc_pages_flags_t alloc_flags, + const char *file, unsigned int line); +extern void gf_free_pages_memory_track(void *pdev, struct os_pages_memory *memory, + const char *file, unsigned int line); + +#if GF_ALLOC_PAGE_TRACK +#define gf_allocate_pages_memory(pdev, size, flag) \ + gf_allocate_pages_memory_track(pdev, size, flag, __FILE__, __LINE__) +#define gf_free_pages_memory(pdev, memory) \ + gf_free_pages_memory_track(pdev, memory, __FILE__, __LINE__) +#else +#define gf_allocate_pages_memory(pdev, size, flag) \ + gf_allocate_pages_memory_priv(pdev, size, flag) +#define gf_free_pages_memory(pdev, memory) \ + gf_free_pages_memory_priv(pdev, memory) +#endif + +extern gf_vm_area_t *gf_map_pages_memory_track(void *process_context, + gf_map_argu_t *map, + const char *file, unsigned int line); +extern void gf_unmap_pages_memory_track(gf_vm_area_t *vm_area, + const char *file, unsigned int line); + +#if GF_MAP_PAGES_TRACK +#define gf_map_pages_memory(priv, argu) \ + gf_map_pages_memory_track(priv, argu, __FILE__, __LINE__) +#define gf_unmap_pages_memory(map) \ + gf_unmap_pages_memory_track(map, __FILE__, __LINE__) +#else +#define gf_map_pages_memory(priv, argu) \ + gf_map_pages_memory_priv(priv, argu) +#define gf_unmap_pages_memory(vma) \ + gf_unmap_pages_memory_priv(vma) +#endif + +extern gf_vm_area_t *gf_map_io_memory_track(void *process_context, + gf_map_argu_t *map, + const char *file, unsigned int line); +extern void gf_unmap_io_memory_track(gf_vm_area_t *vm_area, + const char *file, unsigned int line); + +#if GF_MAP_IO_TRACK +#define gf_map_io_memory(priv, argu) \ + gf_map_io_memory_track(priv, argu, __FILE__, __LINE__) +#define gf_unmap_io_memory(argu) \ + gf_unmap_io_memory_track(argu, __FILE__, __LINE__) +#else +#define gf_map_io_memory(priv, argu) \ + gf_map_io_memory_priv(priv, argu) +#define gf_unmap_io_memory(argu) \ + gf_unmap_io_memory_priv(argu) +#endif + +extern int gf_get_mem_info(mem_info_t *mem); +extern int gf_query_platform_caps(void *pdev, platform_caps_t *caps); + +extern void gf_pages_memory_extract_st(struct os_pages_memory *memory); +extern unsigned char gf_validate_page_cache(struct os_pages_memory *memory, int start_page, int end_page, unsigned char request_cache_type); + +extern int gf_pages_memory_swapin(struct os_pages_memory *pages_memory, void *file); +extern void *gf_pages_memory_swapout(struct os_pages_memory *pages_memory); +extern int gf_is_own_pages(struct os_pages_memory *pages_memory); + +void gf_release_file_storage(void *file); + +extern char *gf_mem_track_result_path; + +#ifdef GF_TRACE_EVENT +extern void gf_register_trace_events(void); +extern void gf_unregister_trace_events(void); +extern void gf_task_create_trace_event(int engine_index, unsigned int context, + unsigned long long task_id, unsigned int task_type); +extern void gf_task_submit_trace_event(int engine_index, unsigned int context, + unsigned long long task_id, unsigned int task_type, + unsigned long long fence_id, unsigned int args); +extern void gf_fence_back_trace_event(int engine_index, unsigned long long fence_id); +extern void gf_begin_section_trace_event(const char* desc); +extern void gf_end_section_trace_event(int result); +extern void gf_counter_trace_event(const char* desc, unsigned long long value); +#endif + +extern int gf_seq_printf(struct os_seq_file *, const char *, ...); + +extern void GF_API_CALL gf_outb(unsigned short port, unsigned char value); +extern char GF_API_CALL gf_inb(unsigned short port); +extern void gf_console_lock(int lock); +extern int disp_wait_idle(void *disp_info); +extern int gf_disp_wait_idle(void *disp_info); + +extern void gf_mb(void); +extern void gf_rmb(void); +extern void gf_wmb(void); +extern void gf_flush_wc(void); +extern void gf_dsb(void); + +#ifdef VMI_MODE +extern void gf_set_pages_addr(struct os_pages_memory *mem, unsigned long long addr); +#endif + +#endif + diff --git a/drivers/gpu/drm/arise/shared/os_shared.c b/drivers/gpu/drm/arise/shared/os_shared.c new file mode 100644 index 0000000000000..a8fd8c97288c2 --- /dev/null +++ b/drivers/gpu/drm/arise/shared/os_shared.c @@ -0,0 +1,343 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and the related laws promulgated by the People's Republic of China +// and the international covenant(s) ratified by the People's Republic of China. +//***************************************************************************** + +#include "os_interface.h" + +#define GF_TRACK_OK 0 +#define GF_TRACK_FAIL 1 +#define GF_CHECK_MALLOC_OVERFLOW 0 + +typedef enum +{ + GF_TYPE_MALLOC_TRACK = 0x01, + GF_TYPE_ALLOC_PAGES_TRACK = 0x02, + GF_TYPE_MAP_PAGES_TRACK = 0x03, + GF_TYPE_MAP_IO_TRACK = 0x04, + GF_TYPE_MEM_TRACK_LAST = 0x05, + +}gf_mem_track_type; + +typedef struct __gf_mem_track* gf_mem_track_ptr; + +typedef struct __gf_mem_track +{ + gf_mem_track_ptr next; + void* addr; + const char* file; + unsigned int size; + unsigned int line; + unsigned int times; +}gf_mem_track; + +static struct os_mutex *memory_track_lock = NULL; +static gf_mem_track gf_memory_tracks[GF_TYPE_MEM_TRACK_LAST-1] = {{0},}; + +static inline void gf_mem_track_add(gf_mem_track_type type, void* addr, const char* file, int line, unsigned long size) +{ + gf_mem_track *pMemList = &gf_memory_tracks[type - 1]; + gf_mem_track *pMemTrack = NULL; + + if(addr == NULL) + { + return; + } + + pMemTrack = gf_malloc_priv(sizeof(gf_mem_track)); + + if(pMemTrack == NULL) + { + gf_error("malloc struct gf_mem_track failed.\n"); + return; + } + + if(memory_track_lock != NULL) + { + gf_mutex_lock(memory_track_lock); + } + + pMemTrack->addr = addr; + pMemTrack->file = file; + pMemTrack->line = line; + pMemTrack->size = size; + pMemTrack->next = pMemList->next; + pMemTrack->times = pMemList->times++; + + + pMemList->next = pMemTrack; + pMemList->size++; + + if(memory_track_lock != NULL) + { + gf_mutex_unlock(memory_track_lock); + } +} + +static inline int gf_mem_track_remove(gf_mem_track_type type, int check_overflow, void* addr, const char* file, int line) +{ + gf_mem_track *pMemList = &gf_memory_tracks[type - 1]; + gf_mem_track *pTemp, *pPre; + int status = GF_TRACK_OK; + + gf_mutex_lock(memory_track_lock); + + pPre = pMemList; + pTemp = pMemList->next; + + while((pTemp != NULL) && (pTemp->addr != addr)) + { + pPre = pTemp; + pTemp = pTemp->next; + } + + if(pTemp != NULL) + { + if(check_overflow) + { + char *head = (char*)pTemp->addr; + char *tail = (char*)pTemp->addr + pTemp->size - 32; + int i; + + for(i=0; i < 32; i++) + { + if(head[i] != 0x55 || tail[i] != 0x55) + { + gf_info("OVERFLOW %s: %d, size = %x, times = %d.\n", + pTemp->file, pTemp->line, pTemp->size, pTemp->times); + break; + } + } + gf_memset(pTemp->addr, 0, pTemp->size); + } + pPre->next = pTemp->next; + gf_free_priv(pTemp); + + pMemList->size--; + } + else + { + gf_info("type:%d-memory:0x%p: %s line:%d, no found in track list.\n", pMemList->line, addr, file, line); + status = GF_TRACK_FAIL; + } + gf_mutex_unlock(memory_track_lock); + + return status; +} + +static inline void gf_mem_track_list(gf_mem_track* pMemList, struct os_file *file) +{ + char msg[512]; + gf_mem_track *pList = pMemList->next; + + gf_info("memory type: %d, leaks number: %d\n", pMemList->line, pMemList->size); + + if(file != NULL) + { + gf_vsnprintf(msg, 512, "memory type: %d, leaks number: %d\n", pMemList->line, pMemList->size); + gf_file_write(file, msg, gf_strlen(msg)); + } + + while(pList) + { + gf_info("%s: %d, size = %u, times = %d.\n", pList->file, pList->line, pList->size, pList->times); + if(file != NULL) + { + gf_vsnprintf(msg, 512, "%s: %d, size = %u, times = %d.\n", pList->file, pList->line, pList->size, pList->times); + gf_file_write(file, msg, gf_strlen(msg)); + } + pList = pList->next; + } + +} + +void gf_mem_track_init(void) +{ + gf_mem_track_type type; + gf_mem_track *header = NULL; + + memory_track_lock = gf_create_mutex(); + + for(type = GF_TYPE_MALLOC_TRACK; type < GF_TYPE_MEM_TRACK_LAST; type++) + { + header = &gf_memory_tracks[type-1]; + gf_memset(header, 0, sizeof(*header)); + header->line = type; + } +} + +void gf_mem_track_list_result(void) +{ + gf_mem_track_type type; + gf_mem_track *header = NULL; + struct os_file *file = NULL; +#if GF_MEM_TRACK_RESULT_TO_FILE + file = gf_file_open(gf_mem_track_result_path, OS_WRONLY | OS_CREAT | OS_APPEND, 0644); +#endif + + gf_info("************leak************\n"); + + for(type = GF_TYPE_MALLOC_TRACK; type < GF_TYPE_MEM_TRACK_LAST; type++) + { + header = &gf_memory_tracks[type-1]; + + if(header->next) + { + gf_mem_track_list(header, file); + } + } + +#if GF_MEM_TRACK_RESULT_TO_FILE + gf_file_close(file); +#endif + + gf_destroy_mutex(memory_track_lock); + + memory_track_lock = NULL; +} + +void *gf_malloc_track(unsigned long size, const char *file, unsigned int line) +{ + unsigned long track_size = size; + void *returned_addr = NULL; + char *malloc_addr = NULL; + +#if GF_CHECK_MALLOC_OVERFLOW + track_size += 2 * 32; +#endif + + malloc_addr = gf_malloc_priv(track_size); + +#if GF_CHECK_MALLOC_OVERFLOW + gf_memset(malloc_addr, 0x55, 32); + gf_memset(malloc_addr + track_size - 32, 0x55, 32); + returned_addr = malloc_addr + 32; +#else + returned_addr = malloc_addr; +#endif + + gf_mem_track_add(GF_TYPE_MALLOC_TRACK, malloc_addr, file, line, track_size); + + return returned_addr; +} + +void *gf_calloc_track(unsigned long size, const char *file, unsigned int line) +{ + unsigned long track_size = size; + void *returned_addr = NULL; + char *malloc_addr = NULL; + +#if GF_CHECK_MALLOC_OVERFLOW + track_size += 2 * 32; +#endif + + malloc_addr = gf_calloc_priv(track_size); + +#if GF_CHECK_MALLOC_OVERFLOW + gf_memset(malloc_addr, 0x55, 32); + gf_memset(malloc_addr + track_size - 32, 0x55, 32); + returned_addr = malloc_addr + 32; +#else + returned_addr = malloc_addr; +#endif + + gf_mem_track_add(GF_TYPE_MALLOC_TRACK, malloc_addr, file, line, track_size); + + return returned_addr; +} + +void gf_free_track(void *addr, const char *file, unsigned int line) +{ + void *malloc_addr = addr; + int overflow_check = 0; +#if GF_CHECK_MALLOC_OVERFLOW + overflow_check = 1; + malloc_addr = (char*)addr - 32; +#endif + if(addr == NULL) + { + gf_error("free a NULL pointer: %s, %d.\n", file, line); + return; + } + + if(gf_mem_track_remove(GF_TYPE_MALLOC_TRACK, overflow_check, malloc_addr, file, line) == GF_TRACK_OK) + { + gf_free_priv(malloc_addr); + } +} + +struct os_pages_memory * +gf_allocate_pages_memory_track(void *pdev, int size, int page_size, alloc_pages_flags_t alloc_flags, const char *file, unsigned int line) +{ + struct os_pages_memory *memory = NULL; + + memory = gf_allocate_pages_memory_priv(pdev, size, page_size, alloc_flags); + + gf_mem_track_add(GF_TYPE_ALLOC_PAGES_TRACK, memory, file, line, size); + + return memory; +} + +void gf_free_pages_memory_track(void *pdev, struct os_pages_memory *memory, const char *file, unsigned int line) +{ + if(memory == NULL) + { + gf_error("free a NULL pages memory: %s, %d.\n", file, line); + return; + } + gf_mem_track_remove(GF_TYPE_ALLOC_PAGES_TRACK, 0, memory, file, line); + gf_free_pages_memory_priv(pdev, memory); +} + +gf_vm_area_t *gf_map_pages_memory_track(void *process_context, gf_map_argu_t *map, + const char *file, unsigned int line) +{ + gf_vm_area_t *vm_area = gf_map_pages_memory_priv(process_context, map); + + gf_mem_track_add(GF_TYPE_MAP_PAGES_TRACK, vm_area->virt_addr, file, line, vm_area->size); + + return vm_area; +} + +void gf_unmap_pages_memory_track(gf_vm_area_t *vm_area, + const char *file, unsigned int line) +{ + if(vm_area->virt_addr == NULL) + { + gf_error("unmap a NULL pages memory: %s, %d.\n", file, line); + return; + } + gf_mem_track_remove(GF_TYPE_MAP_PAGES_TRACK, 0, vm_area->virt_addr, file, line); + gf_unmap_pages_memory_priv(vm_area); +} + +gf_vm_area_t *gf_map_io_memory_track(void *process_context, gf_map_argu_t *map, + const char *file, unsigned int line) +{ + gf_vm_area_t *vm_area = gf_map_io_memory_priv(process_context, map); + + gf_mem_track_add(GF_TYPE_MAP_IO_TRACK, vm_area->virt_addr, file, line, vm_area->size); + + return vm_area; +} + +void gf_unmap_io_memory_track(gf_vm_area_t *vm_area, + const char *file, unsigned int line) +{ + if(vm_area->virt_addr == NULL) + { + gf_error("unmap a NULL io memory: %s, %d.\n", file, line); + return; + } + gf_mem_track_remove(GF_TYPE_MAP_IO_TRACK, 0, vm_area->virt_addr, file, line); + gf_unmap_io_memory_priv(vm_area); +}