diff --git a/drivers/gpu/drm/arise/Makefile b/drivers/gpu/drm/arise/Makefile index 793986b02ddae..17364abbe928e 100644 --- a/drivers/gpu/drm/arise/Makefile +++ b/drivers/gpu/drm/arise/Makefile @@ -1,12 +1,11 @@ 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 +CONFIG_DRM_ARISE?=m ifeq ("$(M)", "") CHECK_GCC_VERSION?=0 else @@ -80,4 +79,4 @@ 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 +obj-$(CONFIG_DRM_ARISE) := $(DRIVER_NAME).o diff --git a/drivers/gpu/drm/arise/cbios/Device/CBIOSVER.H b/drivers/gpu/drm/arise/cbios/Device/CBIOSVER.H old mode 100755 new mode 100644 diff --git a/drivers/gpu/drm/arise/cbios/Device/CBiosShare.h b/drivers/gpu/drm/arise/cbios/Device/CBiosShare.h index d0e5290069c8c..dbda809f6d186 100644 --- a/drivers/gpu/drm/arise/cbios/Device/CBiosShare.h +++ b/drivers/gpu/drm/arise/cbios/Device/CBiosShare.h @@ -224,7 +224,7 @@ static inline CBIOS_U32 cb_swab32(CBIOS_U32 x) #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) 0 +#define cbdo_div(a, b) 0 #define cbvsprintf(s, f, ...) 0 #else diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.c index d0452a209b185..e42d5fb4cdb33 100644 --- a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.c +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosCRTMonitor.c @@ -70,7 +70,7 @@ CBIOS_BOOL cbCRTMonitor_Detect(PCBIOS_VOID pvcbe, PCBIOS_CRT_MONITOR_CONTEXT pCr //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; diff --git a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.c b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.c index 8faef9ec22e3f..340c54fc2e099 100644 --- a/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.c +++ b/drivers/gpu/drm/arise/cbios/Device/Monitor/CBiosHDMIMonitor.c @@ -1449,7 +1449,7 @@ CBIOS_VOID cbHDMIMonitor_SetMode(PCBIOS_VOID pvcbe, PCBIOS_HDMI_MONITOR_CONTEXT if (bHDMIDevice) { // avoid HBlank being too small to not transmit any packet(32 bytes). - if (pModeParams->TargetTiming.HorBEnd - pModeParams->TargetTiming.HorBStart < + 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; diff --git a/drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.c b/drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.c index f1787bba3fe77..f5faf615e4aa6 100644 --- a/drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.c +++ b/drivers/gpu/drm/arise/cbios/Display/CBiosDisplayManager.c @@ -446,7 +446,7 @@ static CBIOS_STATUS cbDispMgrPrepareToSetMode(PCBIOS_EXTENSION_COMMON pcbe, PCBI bForceHDTV = CBIOS_TRUE; } cbPathMgrSelectDIUPath(pcbe, pDevCommon->DeviceType, pModeParams->IGAIndex, &pSettingModeParams->DestModeParams, bForceHDTV); - + cbDevUpdateDeviceModeInfo(pcbe, pDevCommon, pModeParams); return csRet; diff --git a/drivers/gpu/drm/arise/cbios/Display/CBiosMode.c b/drivers/gpu/drm/arise/cbios/Display/CBiosMode.c index d8be23b67a230..7f80e3c982556 100644 --- a/drivers/gpu/drm/arise/cbios/Display/CBiosMode.c +++ b/drivers/gpu/drm/arise/cbios/Display/CBiosMode.c @@ -5667,6 +5667,14 @@ CBIOS_VOID cbMode_GetFilterPara(PCBIOS_VOID pvcbe, CBIOS_ACTIVE_TYPE Device, PCB break; } + if((pcbe->ChipID == CHIPID_ARISE2030) || (pcbe->ChipID == CHIPID_ARISE2020)) + { + if((Device == CBIOS_TYPE_DP2) && (MonitorType == CBIOS_MONITOR_TYPE_HDMI)) + { + pFilter->MaxDclk = 3400000; + } + } + if(pFilter->MaxDclk > pcbe->ChipLimits.ulMaxIGAClock) { pFilter->MaxDclk = pcbe->ChipLimits.ulMaxIGAClock; diff --git a/drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.c b/drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.c index 8b9279ba34650..d2e730c6da658 100644 --- a/drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.c +++ b/drivers/gpu/drm/arise/cbios/Display/CBiosPathManager.c @@ -64,7 +64,7 @@ CBIOS_STATUS cbPathMgrGetDevComb(PCBIOS_VOID pvcbe, PCBIOS_GET_DEV_COMB pDevComb while(Devices) { bAssigned = CBIOS_FALSE; - + //select a high priority device if more than one device TempDev = cbDevGetPrimaryDevice(Devices); Devices &= ~TempDev; @@ -98,7 +98,7 @@ CBIOS_STATUS cbPathMgrGetDevComb(PCBIOS_VOID pvcbe, PCBIOS_GET_DEV_COMB pDevComb pDeviceComb->Iga3Dev = DevOnIga[IGA3]; pDeviceComb->Iga4Dev = DevOnIga[IGA4]; pDevComb->bSupported = CBIOS_TRUE; - + return CBIOS_OK; } else @@ -106,7 +106,7 @@ CBIOS_STATUS cbPathMgrGetDevComb(PCBIOS_VOID pvcbe, PCBIOS_GET_DEV_COMB pDevComb pDevComb->bSupported = CBIOS_FALSE; return CBIOS_ER_INVALID_PARAMETER; } - + } CBIOS_STATUS cbPathMgrGetIgaMask(PCBIOS_VOID pvcbe, PCBIOS_GET_IGA_MASK pGetIgaMask) diff --git a/drivers/gpu/drm/arise/cbios/Hw/Arise/CBios_Arise.c b/drivers/gpu/drm/arise/cbios/Hw/Arise/CBios_Arise.c index da5c7f17cc8eb..35b95fa9dd9c7 100644 --- a/drivers/gpu/drm/arise/cbios/Hw/Arise/CBios_Arise.c +++ b/drivers/gpu/drm/arise/cbios/Hw/Arise/CBios_Arise.c @@ -689,6 +689,12 @@ CBIOS_VOID cbSetSRTimingReg_Arise(PCBIOS_EXTENSION_COMMON pcbe, { cbBiosMMIOWriteReg(pcbe, CR_8F, Value, (CBIOS_U8)~0xc0, IGAIndex); } + + //Fix Arise1020/2030 VGA Hsync Timing issue + if(pcbe->DispMgr.ActiveDevices[IGAIndex] == CBIOS_TYPE_CRT) + { + cbMMIOWriteReg(pcbe, SR_18, 0x80, 0x7F); + } } diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.c index 538fedd06a7e4..6635f196ab08d 100644 --- a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.c +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosDIU_CRT.c @@ -33,7 +33,7 @@ static CBREGISTER NewCRTDetectEnv[] = { {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)~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 @@ -270,9 +270,9 @@ CBIOS_BOOL cbDIU_CRT_DACSense(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon { 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; @@ -301,11 +301,11 @@ CBIOS_BOOL cbDIU_CRT_DACSense(PCBIOS_VOID pvcbe, PCBIOS_DEVICE_COMMON pDevCommon 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; diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.c b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.c index 1243daae0c9e2..b7f7545508669 100644 --- a/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.c +++ b/drivers/gpu/drm/arise/cbios/Hw/HwBlock/CBiosPHY_DP.c @@ -1579,7 +1579,7 @@ static CBIOS_BOOL cbPHY_DP_SelectTMDSModeSource(PCBIOS_EXTENSION_COMMON pcbe, CB else if(MonitorType == CBIOS_MONITOR_TYPE_DVI) { RegSR3AValue.Value = 0; - RegSR3AValue.DP_PHY_Source_Sel = 0; + RegSR3AValue.DP_PHY_Source_Sel = 4; //PS background overlay will affect DE of DVI timing, force to HDMI mode can fix this issue } RegSR3AMask.Value = 0xFF; RegSR3AMask.DP_PHY_Source_Sel = 0; diff --git a/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.c b/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.c index 872d0a7afa51c..9f2fff71d02b8 100644 --- a/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.c +++ b/drivers/gpu/drm/arise/cbios/Hw/HwUtil/CBiosUtilHw.c @@ -1236,11 +1236,18 @@ CBIOS_U32 cbGetProgClock(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 *ClockFreq, CBI { CBIOS_CLOCK_INFO ClkInfo = {0}; CBIOS_U32 RegD130 = 0; + CBIOS_U32 D300_Value = 0; + CBIOS_BOOL bUseNewMclk = CBIOS_FALSE; if(ClockType >= CBIOS_INVALID_CLK) { return -1; } + if (pcbe->ChipID == CHIPID_ARISE1020 && ClockType == CBIOS_MCLKTYPE) + { + D300_Value = cb_ReadU32(pcbe->pAdapterContext, 0xD300); + bUseNewMclk = ((D300_Value & 0xF) == 0xA) ? CBIOS_TRUE : CBIOS_FALSE; + } switch (ClockType) { @@ -1295,17 +1302,25 @@ CBIOS_U32 cbGetProgClock(PCBIOS_EXTENSION_COMMON pcbe, CBIOS_U32 *ClockFreq, CBI } 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; + if(bUseNewMclk) + { + *ClockFreq = (D300_Value & 0xFFF00)>>8; + } + else + { + 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)) + if ((pcbe->ChipID == CHIPID_ARISE10C0T && (ClockType == CBIOS_ECLKTYPE || ClockType == CBIOS_VCLKTYPE)) || + (pcbe->ChipID == CHIPID_ARISE1020 && ClockType == CBIOS_MCLKTYPE && bUseNewMclk)) { (*ClockFreq) *= 10000; } diff --git a/drivers/gpu/drm/arise/cbios/cbios.mk b/drivers/gpu/drm/arise/cbios/cbios.mk index 26c3ab960dcff..c464f777b68c5 100644 --- a/drivers/gpu/drm/arise/cbios/cbios.mk +++ b/drivers/gpu/drm/arise/cbios/cbios.mk @@ -60,5 +60,5 @@ cbios-objs := \ Hw/Arise/CBios_Arise.o \ Hw/Arise/CBiosVCP_Arise.o -$(PRO_DRIVER_NAME)-objs += $(addprefix cbios/, $(cbios-objs)) +$(DRIVER_NAME)-objs += $(addprefix cbios/, $(cbios-objs)) diff --git a/drivers/gpu/drm/arise/core/Makefile b/drivers/gpu/drm/arise/core/Makefile index 8a17bf8c5e4f1..821a86b70c9c1 100644 --- a/drivers/gpu/drm/arise/core/Makefile +++ b/drivers/gpu/drm/arise/core/Makefile @@ -58,7 +58,7 @@ core-objs := \ $(CORE_OBJ) \ $(PERF_EVENT_OBJ) -$(PRO_DRIVER_NAME)-objs += $(addprefix core/, $(core-objs)) +$(DRIVER_NAME)-objs += $(addprefix core/, $(core-objs)) ifeq ($(CHIP), E3k) include $(GFGPU_FULL_PATH)/core/e3k/Makefile diff --git a/drivers/gpu/drm/arise/core/e3k/Makefile b/drivers/gpu/drm/arise/core/e3k/Makefile index 86b00c06997b7..442b6fddfbb53 100644 --- a/drivers/gpu/drm/arise/core/e3k/Makefile +++ b/drivers/gpu/drm/arise/core/e3k/Makefile @@ -35,4 +35,4 @@ core_e3k-objs := \ $(PERFEVENT_OBJ) \ $(GLOBAL_OBJ) -$(PRO_DRIVER_NAME)-objs += $(addprefix core/e3k/, $(core_e3k-objs)) +$(DRIVER_NAME)-objs += $(addprefix core/e3k/, $(core_e3k-objs)) 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 old mode 100755 new mode 100644 diff --git a/drivers/gpu/drm/arise/core/perfevent/perfevent.c b/drivers/gpu/drm/arise/core/perfevent/perfevent.c old mode 100755 new mode 100644 diff --git a/drivers/gpu/drm/arise/core/perfevent/perfevent.h b/drivers/gpu/drm/arise/core/perfevent/perfevent.h old mode 100755 new mode 100644 diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch.c b/drivers/gpu/drm/arise/core/vidsch/vidsch.c old mode 100755 new mode 100644 diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_task.c b/drivers/gpu/drm/arise/core/vidsch/vidsch_task.c old mode 100755 new mode 100644 diff --git a/drivers/gpu/drm/arise/core/vidsch/vidsch_workerthread.c b/drivers/gpu/drm/arise/core/vidsch/vidsch_workerthread.c old mode 100755 new mode 100644 diff --git a/drivers/gpu/drm/arise/gf_version.h b/drivers/gpu/drm/arise/gf_version.h index dc267e41573dd..3a17036542c8e 100644 --- a/drivers/gpu/drm/arise/gf_version.h +++ b/drivers/gpu/drm/arise/gf_version.h @@ -1,13 +1,13 @@ -#define DRIVER_DATE "07/15/2024" +#define DRIVER_DATE "08/27/2024" #define DRIVER_MAJOR 0x25 #define DRIVER_MINOR 0x00 -#define DRIVER_PATCHLEVEL 0x33 +#define DRIVER_PATCHLEVEL 0x35 #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 DRIVER_VERSION_CHAR "25.00.35" #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 index 0b1243c386bf6..df09d6d481616 100644 --- a/drivers/gpu/drm/arise/linux/Makefile +++ b/drivers/gpu/drm/arise/linux/Makefile @@ -55,4 +55,4 @@ else linux-objs += gf_pcie.o endif -$(PRO_DRIVER_NAME)-objs += $(addprefix linux/, $(linux-objs)) +$(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 old mode 100755 new mode 100644 diff --git a/drivers/gpu/drm/arise/linux/gf.h b/drivers/gpu/drm/arise/linux/gf.h index 52f1f4241fe32..04bf482bb6303 100644 --- a/drivers/gpu/drm/arise/linux/gf.h +++ b/drivers/gpu/drm/arise/linux/gf.h @@ -55,6 +55,8 @@ #include #include #include +#include +#include #ifndef DRM_VERSION_CODE #define DRM_VERSION_CODE LINUX_VERSION_CODE diff --git a/drivers/gpu/drm/arise/linux/gf_atomic.c b/drivers/gpu/drm/arise/linux/gf_atomic.c index c11a460c40baa..bf74af8ffaa19 100644 --- a/drivers/gpu/drm/arise/linux/gf_atomic.c +++ b/drivers/gpu/drm/arise/linux/gf_atomic.c @@ -16,6 +16,7 @@ #include "gf_kms.h" #include "gf_sink.h" #include "gf_splice.h" +#include "gf_pm.h" #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) @@ -245,6 +246,9 @@ static void gf_update_crtc_sink(struct drm_atomic_state *old_state) void gf_atomic_helper_commit_tail(struct drm_atomic_state *old_state) { struct drm_device *dev = old_state->dev; + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_state, *new_crtc_state; + int i; #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) uint32_t flags = DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET; @@ -256,7 +260,24 @@ void gf_atomic_helper_commit_tail(struct drm_atomic_state *old_state) drm_atomic_helper_commit_modeset_enables(dev, old_state); - gf_update_crtc_sink(old_state); +#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 + if (old_crtc_state->active && !new_crtc_state->active) + { + gf_rpm_put_noidle(dev->dev); + } + + if (new_crtc_state->active && !old_crtc_state->active) + { + gf_rpm_get_noresume(dev->dev); + } + } drm_atomic_helper_commit_planes(dev, old_state, flags); @@ -275,6 +296,8 @@ void gf_atomic_helper_commit_tail(struct drm_atomic_state *old_state) #endif drm_atomic_helper_cleanup_planes(dev, old_state); + + gf_rpm_mark_last_busy(dev->dev); } diff --git a/drivers/gpu/drm/arise/linux/gf_cbios.h b/drivers/gpu/drm/arise/linux/gf_cbios.h index 97609533fb881..b626271908deb 100644 --- a/drivers/gpu/drm/arise/linux/gf_cbios.h +++ b/drivers/gpu/drm/arise/linux/gf_cbios.h @@ -16,8 +16,6 @@ #define __GF_CBIOS_H__ #include "CBios.h" -#define MAX_CRTC_NUM CBIOS_MAX_CRTCS - enum { FAMILY_CMODEL, diff --git a/drivers/gpu/drm/arise/linux/gf_crtc.c b/drivers/gpu/drm/arise/linux/gf_crtc.c index 6621cf9c01119..3b1df0cc7f3d8 100644 --- a/drivers/gpu/drm/arise/linux/gf_crtc.c +++ b/drivers/gpu/drm/arise/linux/gf_crtc.c @@ -128,8 +128,6 @@ void gf_crtc_helper_enable(struct drm_crtc *crtc) drm_crtc_vblank_on(crtc); gf_crtc_dpms_onoff_helper(crtc, 1); - - } #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) diff --git a/drivers/gpu/drm/arise/linux/gf_disp.c b/drivers/gpu/drm/arise/linux/gf_disp.c index f3c649aad9928..261b7214c9988 100644 --- a/drivers/gpu/drm/arise/linux/gf_disp.c +++ b/drivers/gpu/drm/arise/linux/gf_disp.c @@ -73,6 +73,14 @@ static char* plane_name[] = { "FS", }; +static const unsigned int vsync_int_tbl[] = { + INT_VSYNC1, + INT_VSYNC2, + INT_VSYNC3, + INT_VSYNC4, +}; +#define VSYNC_INT_TABLE_LEN (sizeof(vsync_int_tbl)/sizeof(vsync_int_tbl[0])) + static char* cursor_name = "cursor"; #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) @@ -672,6 +680,13 @@ static int disp_crtc_init(disp_info_t* disp_info, unsigned int index) crtc_state->base_cstate.crtc = &gf_crtc->base_crtc; gf_crtc->crtc_dpms = 0; + if (index >= VSYNC_INT_TABLE_LEN) + { + gf_error("index excceds vsync int table length\n"); + goto fail; + } + gf_crtc->vsync_int = vsync_int_tbl[index]; + gf_crtc->support_scale = disp_info->scale_support; gf_crtc->plane_cnt = disp_info->num_plane[index]; @@ -742,6 +757,13 @@ static int disp_crtc_init(disp_info_t* disp_info, unsigned int index) gf_crtc->crtc_dpms = 0; + if (index >= VSYNC_INT_TABLE_LEN) + { + gf_error("index excceds vsync int table length\n"); + goto fail; + } + gf_crtc->vsync_int = vsync_int_tbl[index]; + ret = drm_crtc_init(drm, &gf_crtc->base_crtc, &gf_crtc_funcs); if(ret) @@ -1205,11 +1227,11 @@ static void disp_info_print(disp_info_t* disp_info) } if (DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_ENGINE_CLOCK, &value)) { - gf_info("displayinfo Eclk:%dMHz\n", value / 1000); + //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); + //gf_info("displayinfo Vclk:%dMHz\n", (value + 500)/1000); } if(DISP_OK == disp_cbios_get_clock(disp_info, GF_QUERY_MCLK, &value)) { diff --git a/drivers/gpu/drm/arise/linux/gf_driver.c b/drivers/gpu/drm/arise/linux/gf_driver.c index fe9d0c1fca736..dae02806e37b2 100644 --- a/drivers/gpu/drm/arise/linux/gf_driver.c +++ b/drivers/gpu/drm/arise/linux/gf_driver.c @@ -639,7 +639,7 @@ static ssize_t gf_gpuinfo_proc_read(struct file *filp, char *buf, size_t count, 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, "GPU Work Frequency : %d MHz\n", coreclk); 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); @@ -1009,6 +1009,7 @@ int gf_card_init(gf_card_t *gf, void *pdev) gf->misc_control_flag = gf_modparams.misc_control_flag; gf->allocation_trace_tags = 0; gf->video_irq_info_all = 0; + gf->runtime_pm = gf_modparams.gf_runtime_pm; return ret; } diff --git a/drivers/gpu/drm/arise/linux/gf_driver.h b/drivers/gpu/drm/arise/linux/gf_driver.h index daa56ae499dad..5242b8bc2e964 100644 --- a/drivers/gpu/drm/arise/linux/gf_driver.h +++ b/drivers/gpu/drm/arise/linux/gf_driver.h @@ -73,6 +73,7 @@ typedef struct unsigned int misc_control_flag; unsigned long allocation_trace_tags; // allocation trace tags, 0 to disable. unsigned int video_irq_info_all; + int runtime_pm; }gf_card_t; struct gf_file diff --git a/drivers/gpu/drm/arise/linux/gf_i2c.c b/drivers/gpu/drm/arise/linux/gf_i2c.c index 6edf4fd8f55b1..8fcaa2a3a4672 100644 --- a/drivers/gpu/drm/arise/linux/gf_i2c.c +++ b/drivers/gpu/drm/arise/linux/gf_i2c.c @@ -24,12 +24,18 @@ static int gf_i2c_xfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs, in disp_info_t *disp_info = (disp_info_t *)gf_card->disp_info; gf_i2c_param_t i2c_param; int i = 0, retval = 0; + + if (gf_connector->base_connector.status != connector_status_connected) + { + DRM_DEBUG_DRIVER("invalid i2c request as connector(0x%x) is not connected", + gf_connector->output_type); + return -EIO; + } + for (i = 0; i < num; i++) { - DRM_DEBUG_KMS("xfer: num: %d/%d, len:%d, flags:%#x\n\n", i + 1, + DRM_DEBUG_DRIVER("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; diff --git a/drivers/gpu/drm/arise/linux/gf_irq.c b/drivers/gpu/drm/arise/linux/gf_irq.c old mode 100755 new mode 100644 index 9152f3dd61de4..4ca07ced29b64 --- a/drivers/gpu/drm/arise/linux/gf_irq.c +++ b/drivers/gpu/drm/arise/linux/gf_irq.c @@ -19,6 +19,7 @@ #include "gf_kms.h" #include "gf_splice.h" #include "gf_trace.h" +#include "gf_pm.h" #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 13, 0) /* get_scanout_position() return flags */ @@ -32,7 +33,6 @@ #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, @@ -41,9 +41,6 @@ static char* video_irq_name[VIDEO_ERROR_INFO_NUM] = {"CORE0_FE_HANG", "CORE0_BE_ "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; @@ -586,15 +583,15 @@ int gf_irq_install(struct drm_device *drm_dev) 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; + 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; + struct drm_crtc *crtc = NULL; + gf_crtc_t *gf_crtc = NULL; + unsigned int crtc_idx = 0; if (splice_manager != NULL) { @@ -608,48 +605,46 @@ static void gf_vblank_intrr_handle(struct drm_device* dev, unsigned int intrr) } } - if(intrr & INT_VSYNCS) + list_for_each_entry(crtc, &(dev->mode_config.crtc_list), head) { - for (index = 0; index < MAX_CRTC_NUM; index++) + gf_crtc = to_gf_crtc(crtc); + + if (intrr & gf_crtc->vsync_int) { - 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; + 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); + if (splice_source_crtc == crtc) + { + drm_crtc_handle_vblank(splice_target_crtc); + } - //TODO: support splice combination with stand along connector - if (splice_source_crtc == crtc) - { - drm_crtc_handle_vblank(splice_target_crtc); - } + if (gf_crtc->enabled) + { + drm_crtc_handle_vblank(crtc); + } - if (to_gf_crtc(crtc)->enabled) - { - drm_crtc_handle_vblank(crtc); - } + crtc_idx = drm_get_crtc_index(crtc); - get_cnt.crtc_index = index; - get_cnt.vblk = &vblcnt; - disp_cbios_get_counter(disp_info, &get_cnt); + get_cnt.crtc_index = crtc_idx; + get_cnt.vblk = &vblcnt; + disp_cbios_get_counter(disp_info, &get_cnt); - trace_gfx_vblank_intrr(gf->index << 16 | index, vblcnt); + trace_gfx_vblank_intrr(gf->index << 16 | crtc_idx, 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_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 = crtc_idx + 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); - } + gf_core_interface->perf_event_add_isr_event(gf->adapter, &perf_event); + //gf_core_interface->hwq_process_vsync_event(gf->adapter, timestamp); } } } @@ -960,6 +955,7 @@ irqreturn_t gf_irq_handle(int irq, void *arg) { intrr |= INT_FENCE; } + if(intrr & INT_FENCE) { tasklet_schedule(&gf_card->fence_notify); @@ -969,6 +965,8 @@ irqreturn_t gf_irq_handle(int irq, void *arg) atomic_set(&disp_info->atomic_irq_lock, 0); + gf_rpm_mark_last_busy(dev->dev); + return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/arise/linux/gf_kms.h b/drivers/gpu/drm/arise/linux/gf_kms.h index 7e78031f25abd..0ab10fe55cb1c 100644 --- a/drivers/gpu/drm/arise/linux/gf_kms.h +++ b/drivers/gpu/drm/arise/linux/gf_kms.h @@ -102,6 +102,7 @@ typedef struct 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; + unsigned int vsync_int; }gf_crtc_t; typedef struct diff --git a/drivers/gpu/drm/arise/linux/gf_params.c b/drivers/gpu/drm/arise/linux/gf_params.c index f32beb40227b6..b8ce204caf51b 100644 --- a/drivers/gpu/drm/arise/linux/gf_params.c +++ b/drivers/gpu/drm/arise/linux/gf_params.c @@ -41,6 +41,7 @@ struct gf_params gf_modparams __read_mostly = { .gf_local_size_m = 0, .gf_pcie_size_g = 0,//adjust pcie memory size, 0 use real pcie memory .gf_pcie_size_m = 0, + .gf_runtime_pm = 0, .debugfs_mask = 0x1, .misc_control_flag = 0x111, }; @@ -66,6 +67,7 @@ gf_param_named(gf_local_size_g, int, 0444, "manual set the local vram size, uint 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(gf_runtime_pm, int, 0444, "0-disable, 1-enable"); 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 index 991dc4990b5fc..b1a2e80614f88 100644 --- a/drivers/gpu/drm/arise/linux/gf_params.h +++ b/drivers/gpu/drm/arise/linux/gf_params.h @@ -41,6 +41,7 @@ struct gf_params { int gf_local_size_m; int gf_pcie_size_g; int gf_pcie_size_m; + int gf_runtime_pm; int debugfs_mask; //debugfs mask, bit0: gem_enable int misc_control_flag; }; diff --git a/drivers/gpu/drm/arise/linux/gf_pcie.c b/drivers/gpu/drm/arise/linux/gf_pcie.c index 3b8898a5d88b9..9167ce336ee44 100644 --- a/drivers/gpu/drm/arise/linux/gf_pcie.c +++ b/drivers/gpu/drm/arise/linux/gf_pcie.c @@ -24,6 +24,7 @@ #include "gf_irq.h" #include "gf_fbdev.h" #include "gf_params.h" +#include "gf_pm.h" #if DRM_VERSION_CODE >= KERNEL_VERSION(5,5,0) #if DRM_VERSION_CODE < KERNEL_VERSION(5,8,0) @@ -37,7 +38,11 @@ #include #if DRM_VERSION_CODE >= KERNEL_VERSION(6, 2, 0) +#if DRM_VERSION_CODE < KERNEL_VERSION(6,11,0) #include +#else +#include +#endif #endif #define DRIVER_DESC "Glenfly DRM Pro" @@ -134,7 +139,7 @@ static void gf_pcie_shutdown(struct pci_dev *pdev) } #endif -static int gf_drm_suspend(struct drm_device *dev, pm_message_t state) +static int __gf_drm_suspend(struct drm_device *dev, pm_message_t state, bool fbcon) { gf_card_t* gf = dev->dev_private; int ret; @@ -143,12 +148,15 @@ static int gf_drm_suspend(struct drm_device *dev, pm_message_t state) 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"); + if (fbcon) + { + #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); @@ -188,7 +196,19 @@ static int gf_drm_suspend(struct drm_device *dev, pm_message_t state) return 0; } -static int gf_drm_resume(struct drm_device *dev) +static int gf_drm_suspend(struct drm_device *dev, pm_message_t state) +{ + return __gf_drm_suspend(dev, state, true); +} + +static int gf_runtime_suspend(struct drm_device *dev, pm_message_t state) +{ + //TODO + return 0; + //return __gf_drm_suspend(dev, state, false); +} + +static int __gf_drm_resume(struct drm_device *dev, bool fbcon) { gf_card_t* gf = dev->dev_private; int ret = 0; @@ -225,12 +245,15 @@ static int gf_drm_resume(struct drm_device *dev) 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"); + if (fbcon) + { + #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"); @@ -238,6 +261,18 @@ static int gf_drm_resume(struct drm_device *dev) return 0; } +static int gf_drm_resume(struct drm_device *dev) +{ + return __gf_drm_resume(dev, true); +} + +static int gf_runtime_resume(struct drm_device *dev) +{ + //TODO + return 0; + //return __gf_drm_resume(dev, false); +} + static __inline__ int gf_backdoor_available(void) { #if defined(__i386__) || defined(__x86_64__) @@ -281,6 +316,12 @@ static int gf_kick_out_firmware_fb(struct pci_dev *pdev) { struct apertures_struct *ap; bool primary = false; +#if defined(__loongarch__) + int i = 0; + struct fb_info *pfb_info = NULL; + unsigned long long fix_fb_base; + struct platform_device *pd = NULL; +#endif ap = alloc_apertures(1); if (!ap) @@ -293,11 +334,41 @@ static int gf_kick_out_firmware_fb(struct pci_dev *pdev) primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif +#if defined(__loongarch__) + if ((ap->ranges[0].base >> 32) != 0) + { + fix_fb_base = ap->ranges[0].base & 0xFFFFFFFF; + for (i = 0; i < num_registered_fb; i++) + { + pfb_info = registered_fb[i]; + if (!pfb_info) + { + continue; + } + + pd = to_platform_device(pfb_info->device); + if (!pd) + { + continue; + } + + if (gf_strcmp(pd->name, "efi-framebuffer") == 0 && + pfb_info->fix.smem_start == fix_fb_base) + { + ap->ranges[0].base = fix_fb_base; + gf_info("reassign aperture base address to remove firmware framebuffer."); + break; + } + } + } +#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; @@ -343,13 +414,6 @@ static int gf_drm_load_kms(struct drm_device *dev, unsigned long flags) 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 @@ -390,6 +454,17 @@ static int gf_drm_load_kms(struct drm_device *dev, unsigned long flags) gf_fbdev_init(gf); #endif + if (gf->runtime_pm) + { + gf_rpm_set_driver_flags(dev->dev); + gf_rpm_use_autosuspend(dev->dev); + gf_rpm_set_autosuspend_delay(dev->dev, 5000); //5s + gf_rpm_set_active(dev->dev); + gf_rpm_allow(dev->dev); //-1 + gf_rpm_mark_last_busy(dev->dev); + gf_rpm_put_autosuspend(dev->dev); + } + return ret; } @@ -404,9 +479,18 @@ static int gf_drm_open(struct drm_device *dev, struct drm_file *file) return err; } + err = gf_rpm_get_sync(dev->dev); + if (err < 0) + { + goto err_pm_put; + } + priv = gf_calloc(sizeof(gf_file_t)); if (!priv) - return -ENOMEM; + { + err = -ENOMEM; + goto err_suspend_out; + } file->driver_priv = priv; priv->parent_file = file; @@ -421,7 +505,12 @@ static int gf_drm_open(struct drm_device *dev, struct drm_file *file) priv->debug = gf_debugfs_add_device_node(gf->debugfs_dev, gf_get_current_pid(), priv->gpu_device); } - return 0; +err_suspend_out: + gf_rpm_mark_last_busy(dev->dev); +err_pm_put: + gf_rpm_put_autosuspend(dev->dev); + + return err; } static void gf_drm_postclose(struct drm_device *dev, struct drm_file *file) @@ -434,6 +523,8 @@ static void gf_drm_postclose(struct drm_device *dev, struct drm_file *file) gf_mutex_unlock(gf->lock); } + gf_rpm_get_sync(dev->dev); + if(priv->gpu_device) { if(gf->debugfs_dev) @@ -450,6 +541,9 @@ static void gf_drm_postclose(struct drm_device *dev, struct drm_file *file) gf_free(priv); file->driver_priv = NULL; + + gf_rpm_mark_last_busy(dev->dev); + gf_rpm_put_autosuspend(dev->dev); } static void gf_drm_last_close(struct drm_device* dev) @@ -525,6 +619,27 @@ int gf_mmap(struct file *filp, struct vm_area_struct *vma) return ret; } +static long gf_drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct drm_file *file_priv = filp->private_data; + struct drm_device *dev = file_priv->minor->dev ; + long ret; + + ret = gf_rpm_get_sync(dev->dev); + if (ret < 0) + { + goto out; + } + + ret = drm_ioctl(filp, cmd, arg); + + gf_rpm_mark_last_busy(dev->dev); +out: + gf_rpm_put_autosuspend(dev->dev); + return ret; +} + + #if defined(CONFIG_COMPAT) static long gf_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -537,7 +652,7 @@ static long gf_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long a } else { - ret = drm_ioctl(filp, cmd, arg); + ret = gf_drm_ioctl(filp, cmd, arg); } return ret; @@ -567,7 +682,7 @@ static struct file_operations gf_drm_fops = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .unlocked_ioctl = drm_ioctl, + .unlocked_ioctl = gf_drm_ioctl, #if defined(__x86_64__) && defined(CONFIG_COMPAT) .compat_ioctl = gf_compat_ioctl, #endif @@ -716,7 +831,20 @@ static int gf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent) gf_debugfs_init(gf); +#if DRM_VERSION_CODE < KERNEL_VERSION(6, 11, 0) drm_fbdev_generic_setup(dev, 32); +#else + drm_fbdev_ttm_setup(dev, 32); +#endif + +#if DRM_VERSION_CODE < KERNEL_VERSION(5, 2, 0) + //skip_vt_switch is not set in drm_fb_helper_alloc_fbi function under kernel version of 5.2.0, patch it here + if (dev->fb_helper && dev->fb_helper->fbdev && + dev->fb_helper->fbdev->dev) + { + pm_vt_switch_required(dev->fb_helper->fbdev->dev, false); + } +#endif return 0; @@ -734,10 +862,23 @@ static int gf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } #if DRM_VERSION_CODE >= KERNEL_VERSION(3,10,52) +#if DRM_VERSION_CODE >= KERNEL_VERSION(6,11,0) +static void gf_pcie_cleanup(struct pci_dev *pdev) +#else static void __exit gf_pcie_cleanup(struct pci_dev *pdev) +#endif { struct drm_device *dev = pci_get_drvdata(pdev); + gf_card_t *gf_card = (gf_card_t *)dev->dev_private; + gf_info("pcie_cleanup.\n"); + + if (gf_card->runtime_pm) + { + gf_rpm_get_sync(dev->dev); + gf_rpm_forbid(dev->dev); + } + #if DRM_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) drm_dev_unplug(dev); @@ -756,8 +897,6 @@ static void __exit gf_pcie_cleanup(struct pci_dev *pdev) #endif pci_set_drvdata(pdev, NULL); - - pci_release_regions(pdev); } #endif @@ -776,9 +915,18 @@ static int gf_pmops_suspend(struct device *dev) static int gf_pmops_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = pci_get_drvdata(pdev); + gf_card_t *gf_card = (gf_card_t *)drm_dev->dev_private; gf_info("pci device(vendor:0x%X, device:0x%X) pm resume\n", pdev->vendor, pdev->device); + if (gf_card->runtime_pm) + { + gf_rpm_disable(dev); + gf_rpm_set_active(dev); + gf_rpm_enable(dev); + } + #if DRM_VERSION_CODE >= KERNEL_VERSION(4,0,0) gf_drm_resume(pci_get_drvdata(pdev)); #endif @@ -847,27 +995,73 @@ static int gf_pmops_restore(struct device *dev) static int gf_pmops_runtime_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = pci_get_drvdata(pdev); + gf_card_t *gf_card = (gf_card_t *)drm_dev->dev_private; + + if (!gf_card->runtime_pm) + { + gf_rpm_forbid(dev); + return -EBUSY; + } gf_info("pci device(vendor:0x%X, device:0x%X) pm runtime_suspend\n", pdev->vendor, pdev->device); +#if DRM_VERSION_CODE >= KERNEL_VERSION(4,0,0) + gf_runtime_suspend(drm_dev, PMSG_AUTO_SUSPEND); +#endif + return 0; } static int gf_pmops_runtime_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = dev_get_drvdata(dev); + gf_card_t *gf_card = (gf_card_t *)drm_dev->dev_private; + + if (!gf_card->runtime_pm) + { + return -EINVAL; + } gf_info("pci device(vendor:0x%X, device:0x%X) pm runtime_resume\n", pdev->vendor, pdev->device); +#if DRM_VERSION_CODE >= KERNEL_VERSION(4,0,0) + gf_runtime_resume(drm_dev); +#endif + return 0; } + static int gf_pmops_runtime_idle(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = dev_get_drvdata(dev); + gf_card_t *gf_card = (gf_card_t *)drm_dev->dev_private; + struct drm_crtc *crtc; + + if (!gf_card->runtime_pm) + { + gf_rpm_forbid(dev); + return -EBUSY; + } gf_info("pci device(vendor:0x%X, device:0x%X) pm runtime_idle\n", pdev->vendor, pdev->device); - return 0; + list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) + { + if (crtc->enabled) + { + DRM_DEBUG_DRIVER("fail to power off - crtc active\n"); + return -EBUSY; + } + } + + gf_rpm_mark_last_busy(dev); + gf_rpm_autosuspend(dev); + + /* use autosuspend instead of calling rpm_suspend directly in main rpm_idle */ + return 1; } static void gf_shutdown(struct pci_dev *pdev) @@ -937,7 +1131,6 @@ 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); diff --git a/drivers/gpu/drm/arise/linux/gf_pm.h b/drivers/gpu/drm/arise/linux/gf_pm.h new file mode 100644 index 0000000000000..a01544874bcb1 --- /dev/null +++ b/drivers/gpu/drm/arise/linux/gf_pm.h @@ -0,0 +1,128 @@ +//***************************************************************************** +// Copyright (c) 2021 Glenfly Tech Co., Ltd.. +// All Rights Reserved. +// +// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Glenfly Tech Co., Ltd..; +// the contents of this file may not be disclosed to third parties, copied or +// duplicated in any form, in whole or in part, without the prior written +// permission of Glenfly Tech Co., Ltd.. +// +// The copyright of the source code is protected by the copyright laws of the People's +// Republic of China and 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_PM_H__ +#define __GF_PM_H__ + +#include + +static inline int gf_rpm_get_sync(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + return pm_runtime_get_sync(dev); +#else + return 0; +#endif +} + +static inline int gf_rpm_put_autosuspend(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + return pm_runtime_put_autosuspend(dev); +#else + return 0; +#endif +} + +static inline void gf_rpm_use_autosuspend(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + pm_runtime_use_autosuspend(dev); +#endif +} + +static inline void gf_rpm_set_autosuspend_delay(struct device *dev, int delay) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + pm_runtime_set_autosuspend_delay(dev, delay); //5s +#endif +} + +static inline int gf_rpm_set_active(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + return pm_runtime_set_active(dev); +#else + return 0; +#endif +} + +static inline void gf_rpm_allow(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + pm_runtime_allow(dev); //-1 +#endif +} + +static inline void gf_rpm_forbid(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + pm_runtime_forbid(dev); +#endif +} + +static inline void gf_rpm_mark_last_busy(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + pm_runtime_mark_last_busy(dev); +#endif +} + +static inline void gf_rpm_enable(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + pm_runtime_enable(dev); +#endif +} + +static inline void gf_rpm_disable(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + pm_runtime_disable(dev); +#endif +} + +static inline int gf_rpm_autosuspend(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + return pm_runtime_autosuspend(dev); +#else + return 0; +#endif +} + +static inline void gf_rpm_get_noresume(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + pm_runtime_get_noresume(dev); +#endif +} + +static inline void gf_rpm_put_noidle(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + pm_runtime_put_noidle(dev); +#endif +} + +static inline void gf_rpm_set_driver_flags(struct device *dev) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) + dev_pm_set_driver_flags(dev, DPM_FLAG_NO_DIRECT_COMPLETE); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) + dev_pm_set_driver_flags(dev, DPM_FLAG_NEVER_SKIP); +#endif +} + +#endif diff --git a/drivers/gpu/drm/arise/linux/gf_splice.c b/drivers/gpu/drm/arise/linux/gf_splice.c index c75ab4594856e..a64e3e2d9074f 100644 --- a/drivers/gpu/drm/arise/linux/gf_splice.c +++ b/drivers/gpu/drm/arise/linux/gf_splice.c @@ -2035,6 +2035,7 @@ static void gf_splice_init_crtc_and_planes(gf_splice_manager_t *splice_manager) gf_crtc->crtc_dpms = 0; gf_crtc->support_scale = disp_info->scale_support; gf_crtc->plane_cnt = GF_SPLICE_PLANE_NUM; + gf_crtc->vsync_int = 0; ret = drm_crtc_init_with_planes(drm, &gf_crtc->base_crtc, &gf_plane->base_plane, diff --git a/drivers/gpu/drm/arise/linux/gf_sysfs.c b/drivers/gpu/drm/arise/linux/gf_sysfs.c old mode 100755 new mode 100644 diff --git a/drivers/gpu/drm/arise/shared/gf_perf.h b/drivers/gpu/drm/arise/shared/gf_perf.h old mode 100755 new mode 100644