static int pm_callback_power_on(struct kbase_device *kbdev)
{
	unsigned int current_gpu_freq_idx;

#ifndef CONFIG_MTK_CLKMGR
	int ret;
#endif

	mt_gpufreq_voltage_enable_set(1);
	mtk_set_vgpu_power_on_flag(MTK_VGPU_POWER_ON); // the power status is "power on".
#ifdef ENABLE_COMMON_DVFS
    ged_dvfs_gpu_clock_switch_notify(1);
#endif

#ifdef CONFIG_MTK_CLKMGR
		enable_clock( MT_CG_DISP0_SMI_COMMON, "GPU");
		enable_clock( MT_CG_MFG_BG3D, "GPU");
#endif

	mt_gpufreq_target(g_power_off_gpu_freq_idx);
	current_gpu_freq_idx = mt_gpufreq_get_cur_freq_index();
	if( current_gpu_freq_idx > g_power_off_gpu_freq_idx)
		pr_debug("MALI: GPU freq. can't switch to idx=%d\n", g_power_off_gpu_freq_idx );

	/* Nothing is needed on VExpress, but we may have destroyed GPU state (if the below HARD_RESET code is active) */
	return 1;
}
static void mali_dvfs_handler(struct work_struct *work)
{
    /*unsigned long flags;*/
    int           enabled;
    int           duration;
    int           boostID;
    int           perfID;
    int           gedID;
    int           halID;
    int           targetID;

    if (0 == atomic_read(&g_is_power_enabled))
    {
        MALI_DEBUG_PRINT(4, ("GPU clock is switching down\n"));
        return;
    }

    // Get related settings
    enabled  = mtk_get_input_boost_enabled();
    duration = mtk_get_input_boost_duration();
    boostID  = mtk_get_boost_frequency_id();
    perfID   = mtk_get_perf_hal_frequency_id();
    gedID    = mtk_get_ged_hal_frequency_id();
    targetID = mtk_get_current_frequency_id();

    if ((enabled != 0) && (duration > 0))
    {
        targetID = boostID;
    }
    else
    {
        if (targetID < mt_gpufreq_get_thermal_limit_index())
        {
            targetID = mt_gpufreq_get_thermal_limit_index();
        }

        /* Calculate higher boost frequency (e.g. lower index id) */
        if(perfID < gedID)
        {
            halID = perfID;
        }
        else
        {
            halID = gedID;
        }
    
        if(targetID > halID)
        {
            MALI_DEBUG_PRINT(4, ("Use GPU boost frequency %d as target!\n", halID));
            targetID = halID;
        }
    }

    if (targetID != mt_gpufreq_get_cur_freq_index())
    {
        mt_gpufreq_target(targetID);
    }
}
int mtk_set_mt_gpufreq_target(int freq_id)
{
    if (MTK_VGPU_POWER_ON == mtk_get_vgpu_power_on_flag()) {
        return  mt_gpufreq_target(freq_id);
    } else {
        ///pr_alert("MALI: VGPU power is off, ignore set freq: %d. \n",freq_id);
    }

    return 0;
}
static int pm_callback_power_on(struct kbase_device *kbdev)
{
#ifdef CONFIG_MALI_MIDGARD_DVFS
	int touch_boost_flag, touch_boost_id;
#endif /* CONFIG_MALI_MIDGARD_DVFS */

	unsigned int current_gpu_freq_idx;

#ifndef CONFIG_MTK_CLKMGR
	int ret;
#endif

	unsigned int code;
	code = mt_get_chip_hw_code();

	mt_gpufreq_voltage_enable_set(1);
#ifdef ENABLE_COMMON_DVFS
    ged_dvfs_gpu_clock_switch_notify(1);
#endif
	
#ifdef CONFIG_MTK_CLKMGR
		enable_clock( MT_CG_DISP0_SMI_COMMON, "GPU");
		enable_clock( MT_CG_MFG_BG3D, "GPU");
#endif

	g_power_status = 1; // the power status is "power on".
	mt_gpufreq_target(g_power_off_gpu_freq_idx);
	current_gpu_freq_idx = mt_gpufreq_get_cur_freq_index();
	if( current_gpu_freq_idx > g_power_off_gpu_freq_idx)
		pr_debug("MALI: GPU freq. can't switch to idx=%d\n", g_power_off_gpu_freq_idx );

    mtk_get_touch_boost_flag( &touch_boost_flag, &touch_boost_id);    
    if(touch_boost_flag > 0)
    {
        mt_gpufreq_target(touch_boost_id);        
        mtk_clear_touch_boost_flag();
    }
	
	/* Nothing is needed on VExpress, but we may have destroyed GPU state (if the below HARD_RESET code is active) */
	return 1;
}
void mtk_gpu_power_limit_callback(unsigned int limitID)
{
    unsigned int  currentID;

    MALI_DEBUG_PRINT(4, ("[MALI] mtk_gpu_power_limit_callback() set to freq id=%d\n", limitID));

    currentID = mt_gpufreq_get_cur_freq_index();

    if ((1 == atomic_read(&g_is_power_enabled)) && (currentID < limitID))
    {
        mtk_set_current_frequency_id(limitID);
        mtk_set_input_boost_duration(0);
        mtk_set_current_deferred_count(0);
        mt_gpufreq_target(limitID);
    }
}
/* MTK set boost. 0 is the lowest frequency index. The function is used for GED boost currently.*/
static void mtk_ged_hal_callback(unsigned int level)
{
    unsigned int total;
    unsigned int targetID;

    total = mt_gpufreq_get_dvfs_table_num();
    if (level >= total)
    {
        level = total - 1;
    }

    targetID = total - level - 1;

    mtk_set_ged_hal_frequency_id(targetID);

    MALI_DEBUG_PRINT(4, ("[MALI] mtk_ged_hal_callback() level=%d, boost ID=%d", level, targetID));

    if (targetID != mt_gpufreq_get_cur_freq_index())
    {
        mt_gpufreq_target(targetID);
    }
}
void mtk_gpu_input_boost_callback(unsigned int boostID)
{
    unsigned int  currentID;

    if(mtk_get_input_boost_enabled() == 0)
    {
        // Boost is disabled, so return directly.
        return;
    }

    MALI_DEBUG_PRINT(4, ("[MALI] mtk_gpu_input_boost_callback() set to freq id=%d\n", boostID));

    currentID = mt_gpufreq_get_cur_freq_index();

    if ((1 == atomic_read(&g_is_power_enabled)) && (boostID < currentID))
    {
        mtk_set_boost_frequency_id(boostID);
        mtk_set_input_boost_duration(3);
        mtk_set_current_deferred_count(0);
        mt_gpufreq_target(boostID);
    }
}
static int pm_callback_power_on(struct kbase_device *kbdev)
{
	int touch_boost_flag, touch_boost_id;
    unsigned int current_gpu_freq_idx;
#ifndef CONFIG_MTK_CLKMGR
	int ret;
#endif
	unsigned int code = mt_get_chip_hw_code();

	mt_gpufreq_voltage_enable_set(1);
    
	if (0x321 == code) {
		// do something for Denali-1(6735)
#ifdef CONFIG_MTK_CLKMGR
		enable_clock( MT_CG_DISP0_SMI_COMMON, "GPU");
		enable_clock( MT_CG_MFG_BG3D, "GPU");
#else
		ret = clk_prepare_enable(kbdev->clk_display_scp);
		if (ret)
		{
			pr_debug("MALI: clk_prepare_enable failed when enabling display MTCMOS");
		}
		
		ret = clk_prepare_enable(kbdev->clk_smi_common);
		if (ret)
		{
			pr_debug("MALI: clk_prepare_enable failed when enabling display smi_common clock");
		}
		
		ret = clk_prepare_enable(kbdev->clk_mfg_scp);
		if (ret)
		{
			pr_debug("MALI: clk_prepare_enable failed when enabling mfg MTCMOS");
		}
		
		ret = clk_prepare_enable(kbdev->clk_mfg);
		if (ret)
		{
			pr_debug("MALI: clk_prepare_enable failed when enabling mfg clock");
		}
#endif
	} else if (0x335 == code) {
		// do something for Denali-2(6735M)
#ifdef CONFIG_MTK_CLKMGR
		enable_clock( MT_CG_DISP0_SMI_COMMON, "GPU");
		enable_clock( MT_CG_MFG_BG3D, "GPU");
#endif /* CONFIG_MTK_CLKMGR */
	} else if (0x337 == code) {
		// do something for Denali-3(6753)
#ifdef CONFIG_MTK_CLKMGR
		enable_clock( MT_CG_DISP0_SMI_COMMON, "GPU");
		enable_clock( MT_CG_MFG_BG3D, "GPU");
#endif /* CONFIG_MTK_CLKMGR */
	} else {
		// unknown chip ID, error !!
#ifdef CONFIG_MTK_CLKMGR
		enable_clock( MT_CG_DISP0_SMI_COMMON, "GPU");
		enable_clock( MT_CG_MFG_BG3D, "GPU");
#endif /* CONFIG_MTK_CLKMGR */
	}

	g_power_status = 1; // the power status is "power on".
	mt_gpufreq_target(g_power_off_gpu_freq_idx);
	current_gpu_freq_idx = mt_gpufreq_get_cur_freq_index();
	if( current_gpu_freq_idx > g_power_off_gpu_freq_idx)
		pr_debug("MALI: GPU freq. can't switch to idx=%d\n", g_power_off_gpu_freq_idx );

    mtk_get_touch_boost_flag( &touch_boost_flag, &touch_boost_id);
	if(g_type_T==1)
	{
		if(touch_boost_flag > 0)
    	{
        	mt_gpufreq_target(1);
        	mtk_clear_touch_boost_flag();
    	}
	}
	else
	{
    if(touch_boost_flag > 0)
    {
        mt_gpufreq_target(touch_boost_id);
        mtk_clear_touch_boost_flag();
    }
	}

	/* Nothing is needed on VExpress, but we may have destroyed GPU state (if the below HARD_RESET code is active) */
	return 1;
}
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);

}
Esempio n. 10
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
}