static void pm_callback_power_off(struct kbase_device *kbdev) { #if HARD_RESET_AT_POWER_OFF /* Cause a GPU hard reset to test whether we have actually idled the GPU * and that we properly reconfigure the GPU on power up. * Usually this would be dangerous, but if the GPU is working correctly it should * be completely safe as the GPU should not be active at this point. * However this is disabled normally because it will most likely interfere with * bus logging etc. */ KBASE_TRACE_ADD(kbdev, CORE_GPU_HARD_RESET, NULL, NULL, 0u, 0); kbase_os_reg_write(kbdev, GPU_CONTROL_REG(GPU_COMMAND), GPU_COMMAND_HARD_RESET); #endif }
static int gpu_set_maximum_outstanding_req(int val) { volatile unsigned int reg; if (val > 0b1111) return -1; if (!pkbdev) return -2; if (!gpu_is_power_on()) return -3; reg = kbase_os_reg_read(pkbdev, GPU_CONTROL_REG(L2_MMU_CONFIG)); reg &= ~(0b1111 << 24); reg |= ((val & 0b1111) << 24); kbase_os_reg_write(pkbdev, GPU_CONTROL_REG(L2_MMU_CONFIG), reg); return 0; }
static void pm_callback_power_off(struct kbase_device *kbdev) { struct device *dev = kbdev->dev; int ret = 0, retry = 0; #if HARD_RESET_AT_POWER_OFF /* Cause a GPU hard reset to test whether we have actually idled the GPU * and that we properly reconfigure the GPU on power up. * Usually this would be dangerous, but if the GPU is working correctly it should * be completely safe as the GPU should not be active at this point. * However this is disabled normally because it will most likely interfere with * bus logging etc. */ KBASE_TRACE_ADD(kbdev, CORE_GPU_HARD_RESET, NULL, NULL, 0u, 0); kbase_os_reg_write(kbdev, GPU_CONTROL_REG(GPU_COMMAND), GPU_COMMAND_HARD_RESET); #endif if (unlikely(dev->power.disable_depth > 0)) { kbase_platform_off(kbdev); } else { do { ret = pm_schedule_suspend(dev, RUNTIME_PM_DELAY_TIME); if (ret != -EAGAIN) { if (unlikely(ret < 0)) { pr_err("[mali-midgard] pm_schedule_suspend failed (%d)\n\n", ret); WARN_ON(1); } /* correct status */ break; } /* -EAGAIN, repeated attempts for 1s totally */ msleep(50); } while (++retry < 20); } }
static void pm_callback_power_off(struct kbase_device *kbdev) { unsigned int uiCurrentFreqCount; volatile int polling_count = 100000; volatile int i = 0; unsigned int code; /// 1. Delay 0.01ms before power off for (i=0; i < DELAY_LOOP_COUNT;i++); if (DELAY_LOOP_COUNT != i) { pr_debug("[MALI] power off delay error!\n"); } /// 2. Polling the MFG_DEBUG_REG for checking GPU IDLE before MTCMOS power off (0.1ms) MFG_WRITE32(0x3, MFG_DEBUG_CTRL_REG); do { /// 0x13000184[2] /// 1'b1: bus idle /// 1'b0: bus busy if (MFG_READ32(MFG_DEBUG_STAT_REG) & MFG_BUS_IDLE_BIT) { /// pr_debug("[MALI]MFG BUS already IDLE! Ready to power off, %d\n", polling_count); break; } } while (polling_count--); if (polling_count <=0) { pr_debug("[MALI]!!!!MFG(GPU) subsys is still BUSY!!!!!, polling_count=%d\n", polling_count); } #if HARD_RESET_AT_POWER_OFF /* Cause a GPU hard reset to test whether we have actually idled the GPU * and that we properly reconfigure the GPU on power up. * Usually this would be dangerous, but if the GPU is working correctly it should * be completely safe as the GPU should not be active at this point. * However this is disabled normally because it will most likely interfere with * bus logging etc. */ //KBASE_TRACE_ADD(kbdev, CORE_GPU_HARD_RESET, NULL, NULL, 0u, 0); kbase_os_reg_write(kbdev, GPU_CONTROL_REG(GPU_COMMAND), GPU_COMMAND_HARD_RESET); #endif /// Polling the MFG_DEBUG_REG for checking GPU IDLE before MTCMOS power off (0.1ms) MFG_WRITE32(0x3, MFG_DEBUG_CTRL_REG); do { /// 0x13000184[2] /// 1'b1: bus idle /// 1'b0: bus busy if (MFG_READ32(MFG_DEBUG_STAT_REG) & MFG_BUS_IDLE_BIT) { /// pr_debug("[MALI]MFG BUS already IDLE! Ready to power off, %d\n", polling_count); break; } } while (polling_count--); if (polling_count <=0) { pr_debug("[MALI]!!!!MFG(GPU) subsys is still BUSY!!!!!, polling_count=%d\n", polling_count); } g_power_status = 0; // the power status is "power off". g_power_off_gpu_freq_idx = mt_gpufreq_get_cur_freq_index(); // record current freq. index. //pr_debug("MALI: GPU power off freq idx : %d\n",g_power_off_gpu_freq_idx ); #if 1 uiCurrentFreqCount = mt_gpufreq_get_dvfs_table_num(); // get freq. table size mt_gpufreq_target(uiCurrentFreqCount-1); // set gpu to lowest freq. #endif code = mt_get_chip_hw_code(); /* MTK clock modified */ if (0x321 == code) { // do something for Denali-1(6735) #ifdef CONFIG_MTK_CLKMGR disable_clock( MT_CG_MFG_BG3D, "GPU"); disable_clock( MT_CG_DISP0_SMI_COMMON, "GPU"); #else clk_disable_unprepare(kbdev->clk_mfg); clk_disable_unprepare(kbdev->clk_mfg_scp); clk_disable_unprepare(kbdev->clk_smi_common); clk_disable_unprepare(kbdev->clk_display_scp); #endif } else if (0x335 == code) { // do something for Denali-2(6735M) #ifdef CONFIG_MTK_CLKMGR disable_clock( MT_CG_MFG_BG3D, "GPU"); disable_clock( MT_CG_DISP0_SMI_COMMON, "GPU"); #endif /* CONFIG_MTK_CLKMGR */ } else if (0x337 == code) { // do something for Denali-3(6753) #ifdef CONFIG_MTK_CLKMGR disable_clock( MT_CG_MFG_BG3D, "GPU"); disable_clock( MT_CG_DISP0_SMI_COMMON, "GPU"); #endif /* CONFIG_MTK_CLKMGR */ } else { // unknown chip ID, error !! #ifdef CONFIG_MTK_CLKMGR disable_clock( MT_CG_MFG_BG3D, "GPU"); disable_clock( MT_CG_DISP0_SMI_COMMON, "GPU"); #endif /* CONFIG_MTK_CLKMGR */ } mt_gpufreq_voltage_enable_set(0); }
static void pm_callback_power_off(struct kbase_device *kbdev) { unsigned int uiCurrentFreqCount; volatile int polling_count = 100000; volatile int i = 0; struct mtk_config *config; if (!kbdev) { pr_alert("MALI: input parameter is NULL \n"); } config = (struct mtk_config *)kbdev->mtk_config; if (!config) { pr_alert("MALI: mtk_config is NULL \n"); } /// 1. Delay 0.01ms before power off for (i=0; i < DELAY_LOOP_COUNT;i++); if (DELAY_LOOP_COUNT != i) { pr_warn("[MALI] power off delay error!\n"); } /// 2. Polling the MFG_DEBUG_REG for checking GPU IDLE before MTCMOS power off (0.1ms) MFG_WRITE32(0x3, MFG_DEBUG_CTRL_REG); do { /// 0x13000184[2] /// 1'b1: bus idle /// 1'b0: bus busy if (MFG_READ32(MFG_DEBUG_STAT_REG) & MFG_BUS_IDLE_BIT) { /// printk("[MALI]MFG BUS already IDLE! Ready to power off, %d\n", polling_count); break; } } while (polling_count--); if (polling_count <=0) { pr_warn("[MALI]!!!!MFG(GPU) subsys is still BUSY!!!!!, polling_count=%d\n", polling_count); } #if HARD_RESET_AT_POWER_OFF /* Cause a GPU hard reset to test whether we have actually idled the GPU * and that we properly reconfigure the GPU on power up. * Usually this would be dangerous, but if the GPU is working correctly it should * be completely safe as the GPU should not be active at this point. * However this is disabled normally because it will most likely interfere with * bus logging etc. */ //KBASE_TRACE_ADD(kbdev, CORE_GPU_HARD_RESET, NULL, NULL, 0u, 0); kbase_os_reg_write(kbdev, GPU_CONTROL_REG(GPU_COMMAND), GPU_COMMAND_HARD_RESET); /// Polling the MFG_DEBUG_REG for checking GPU IDLE before MTCMOS power off (0.1ms) MFG_WRITE32(0x3, MFG_DEBUG_CTRL_REG); do { /// 0x13000184[2] /// 1'b1: bus idle /// 1'b0: bus busy if (MFG_READ32(MFG_DEBUG_STAT_REG) & MFG_BUS_IDLE_BIT) { /// printk("[MALI]MFG BUS already IDLE! Ready to power off, %d\n", polling_count); break; } } while (polling_count--); if (polling_count <=0) { printk("[MALI]!!!!MFG(GPU) subsys is still BUSY!!!!!, polling_count=%d\n", polling_count); } g_power_off_gpu_freq_idx = mt_gpufreq_get_cur_freq_index(); // record current freq. index. //printk("MALI: GPU power off freq idx : %d\n",g_power_off_gpu_freq_idx ); #if 1 uiCurrentFreqCount = mt_gpufreq_get_dvfs_table_num(); // get freq. table size mt_gpufreq_target(uiCurrentFreqCount-1); // set gpu to lowest freq. #endif /* MTK clock modified */ #ifdef CONFIG_MTK_CLKMGR disable_clock( MT_CG_MFG_BG3D, "GPU"); disable_clock( MT_CG_DISP0_SMI_COMMON, "GPU"); #endif if(mt6325_upmu_get_swcid() >= PMIC6325_E3_CID_CODE) { mt_gpufreq_voltage_enable_set(0); } #ifdef ENABLE_COMMON_DVFS ged_dvfs_gpu_clock_switch_notify(0); #endif mtk_set_vgpu_power_on_flag(MTK_VGPU_POWER_OFF); // the power status is "power off". #endif }