int gpu_set_target_clk_vol_pending(int clk) { int ret = 0, target_clk = 0, target_vol = 0; int prev_clk = 0; struct kbase_device *kbdev = pkbdev; struct exynos_context *platform = (struct exynos_context *) kbdev->platform_context; DVFS_ASSERT(platform); target_clk = gpu_check_target_clock(platform, clk); if (target_clk < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: mismatch clock error (source %d, target %d)\n", __func__, clk, target_clk); return -1; } target_vol = MAX(gpu_dvfs_get_voltage(target_clk) + platform->voltage_margin, platform->cold_min_vol); prev_clk = gpu_get_cur_clock(platform); GPU_SET_CLK_VOL(kbdev, platform->cur_clock, target_clk, target_vol); GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "pending clk[%d -> %d], vol[%d (margin : %d)]\n", prev_clk, gpu_get_cur_clock(platform), gpu_get_cur_voltage(platform), platform->voltage_margin); ret = gpu_update_cur_level(platform); return ret; }
int gpu_set_target_clk_vol(int clk, bool pending_is_allowed) { int ret = 0, target_clk = 0, target_vol = 0; int prev_clk = 0; struct kbase_device *kbdev = pkbdev; struct exynos_context *platform = (struct exynos_context *) kbdev->platform_context; DVFS_ASSERT(platform); if (!gpu_control_is_power_on(pkbdev)) { GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "%s: can't set clock and voltage in the power-off state!\n", __func__); return -1; } mutex_lock(&platform->gpu_clock_lock); #ifdef CONFIG_MALI_DVFS if (pending_is_allowed && platform->dvs_is_enabled) { if (!platform->dvfs_pending && clk < platform->cur_clock) { platform->dvfs_pending = clk; GPU_LOG(DVFS_DEBUG, DUMMY, 0u, 0u, "pending to change the clock [%d -> %d\n", platform->cur_clock, platform->dvfs_pending); } else if (clk > platform->cur_clock) { platform->dvfs_pending = 0; } mutex_unlock(&platform->gpu_clock_lock); return 0; } else { platform->dvfs_pending = 0; } #endif /* CONFIG_MALI_DVFS */ target_clk = gpu_check_target_clock(platform, clk); if (target_clk < 0) { mutex_unlock(&platform->gpu_clock_lock); GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: mismatch clock error (source %d, target %d)\n", __func__, clk, target_clk); return -1; } target_vol = MAX(gpu_dvfs_get_voltage(target_clk) + platform->voltage_margin, platform->cold_min_vol); prev_clk = gpu_get_cur_clock(platform); GPU_SET_CLK_VOL(kbdev, prev_clk, target_clk, target_vol); ret = gpu_update_cur_level(platform); mutex_unlock(&platform->gpu_clock_lock); GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "clk[%d -> %d], vol[%d (margin : %d)]\n", prev_clk, gpu_get_cur_clock(platform), gpu_get_cur_voltage(platform), platform->voltage_margin); return ret; }
int gpu_enable_dvs(struct exynos_context *platform) { #ifdef CONFIG_EXYNOS_CL_DVFS_G3D int level = 0; #endif /* CONFIG_EXYNOS_CL_DVFS_G3D */ if (!platform->dvs_status) return 0; if (!gpu_is_power_on()) { GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "%s: can't set dvs in the power-off state!\n", __func__); return -1; } #if defined(CONFIG_REGULATOR_S2MPS15) #ifdef CONFIG_EXYNOS_CL_DVFS_G3D level = gpu_dvfs_get_level(gpu_get_cur_clock(platform)); exynos7420_cl_dvfs_stop(ID_G3D, level); #endif /* CONFIG_EXYNOS_CL_DVFS_G3D */ /* Do not need to enable dvs during suspending */ if (!pkbdev->pm.suspending) { if (s2m_set_dvs_pin(true) != 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to enable dvs\n", __func__); return -1; } } #endif /* CONFIG_REGULATOR_S2MPS13 */ GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "dvs is enabled (vol: %d)\n", gpu_get_cur_voltage(platform)); return 0; }
static int pm_callback_change_dvfs_level(struct kbase_device *kbdev) { struct exynos_context *platform = (struct exynos_context *) kbdev->platform_context; mali_bool enabledebug = MALI_FALSE; if(kbdev->vendor_callbacks->get_poweron_dbg) enabledebug = kbdev->vendor_callbacks->get_poweron_dbg(); if (enabledebug) GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, #ifdef CONFIG_EXYNOS_ASV "asv table[%u] " #endif "clk[%d to %d]MHz, vol[%d (margin : %d) real: %d]mV\n", #ifdef CONFIG_EXYNOS_ASV exynos_get_table_ver(), #endif gpu_get_cur_clock(platform), platform->gpu_dvfs_start_clock, gpu_get_cur_voltage(platform), platform->voltage_margin, platform->cur_voltage); gpu_set_target_clk_vol(platform->gpu_dvfs_start_clock, false); gpu_dvfs_reset_env_data(kbdev); return 0; }
int gpu_set_target_clk_vol_pending(int clk) { int ret = 0, target_clk = 0, target_vol = 0; int prev_clk = 0; struct kbase_device *kbdev = pkbdev; struct exynos_context *platform = (struct exynos_context *) kbdev->platform_context; #ifdef CONFIG_EXYNOS_CL_DVFS_G3D int level = 0; #endif DVFS_ASSERT(platform); target_clk = gpu_check_target_clock(platform, clk); if (target_clk < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: mismatch clock error (source %d, target %d)\n", __func__, clk, target_clk); return -1; } target_vol = MAX(gpu_dvfs_get_voltage(target_clk) + platform->voltage_margin, platform->cold_min_vol); target_vol = target_vol < (int) platform->table[0].voltage ? target_vol : (int) platform->table[0].voltage; prev_clk = gpu_get_cur_clock(platform); #ifdef CONFIG_EXYNOS_CL_DVFS_G3D level = gpu_dvfs_get_level(clk); exynos7420_cl_dvfs_stop(ID_G3D, level); #endif GPU_SET_CLK_VOL(kbdev, platform->cur_clock, target_clk, target_vol); ret = gpu_update_cur_level(platform); #ifdef CONFIG_EXYNOS_CL_DVFS_G3D if (!platform->voltage_margin && platform->cl_dvfs_start_base && platform->cur_clock >= platform->cl_dvfs_start_base) exynos7420_cl_dvfs_start(ID_G3D); #endif GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "pending clk[%d -> %d], vol[%d (margin : %d)]\n", prev_clk, gpu_get_cur_clock(platform), gpu_get_cur_voltage(platform), platform->voltage_margin); return ret; }
static int gpu_set_clock_to_osc(struct exynos_context *platform) { int ret = 0; #ifdef CONFIG_MALI_RT_PM if (platform->exynos_pm_domain) mutex_lock(&platform->exynos_pm_domain->access_lock); #endif /* CONFIG_MALI_RT_PM */ if (!gpu_is_power_on()) { ret = -1; GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "%s: can't control clock in the power-off state!\n", __func__); goto err; } if (!gpu_is_clock_on()) { ret = -1; GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "%s: can't control clock in the clock-off state!\n", __func__); goto err; } /* change the mux to osc */ ret = clk_set_parent(mout_g3d_pll, fin_pll); if (ret < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_parent [mout_g3d_pll]\n", __func__); goto err; } GPU_LOG(DVFS_DEBUG, LSI_CLOCK_VALUE, platform->cur_clock, gpu_get_cur_clock(platform), "clock set to soc: %d (%d)\n", gpu_get_cur_clock(platform), platform->cur_clock); err: #ifdef CONFIG_MALI_RT_PM if (platform->exynos_pm_domain) mutex_unlock(&platform->exynos_pm_domain->access_lock); #endif /* CONFIG_MALI_RT_PM */ return ret; }
static ssize_t show_clock(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret = 0; struct exynos_context *platform = (struct exynos_context *)pkbdev->platform_context; if (!platform) return -ENODEV; ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d", gpu_is_power_on() * gpu_get_cur_clock(platform)); if (ret < PAGE_SIZE - 1) { ret += snprintf(buf+ret, PAGE_SIZE-ret, "\n"); } else { buf[PAGE_SIZE-2] = '\n'; buf[PAGE_SIZE-1] = '\0'; ret = PAGE_SIZE-1; } return ret; }
static int gpu_set_clock(struct exynos_context *platform, int clk) { long g3d_rate_prev = -1; unsigned long g3d_rate = clk * MHZ; int ret = 0; int level = 0; if (aclk_g3d == 0) return -1; #ifdef CONFIG_MALI_RT_PM if (platform->exynos_pm_domain) mutex_lock(&platform->exynos_pm_domain->access_lock); #endif /* CONFIG_MALI_RT_PM */ if (!gpu_is_power_on()) { ret = -1; GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "%s: can't set clock in the power-off state!\n", __func__); goto err; } g3d_rate_prev = clk_get_rate(aclk_g3d); /* if changed the VPLL rate, set rate for VPLL and wait for lock time */ if (g3d_rate != g3d_rate_prev) { ret = clk_set_parent(mout_g3d, fin_pll); if (ret < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_parent [fin_pll]\n", __func__); goto err; } /*change g3d pll*/ ret = clk_set_rate(fout_g3d_pll, g3d_rate); if (ret < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_rate [fout_g3d_pll]\n", __func__); goto err; } level = gpu_dvfs_get_level(g3d_rate/MHZ); if (level < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to gpu_dvfs_get_level \n", __func__); goto err; } ret = clk_set_rate(sclk_hpm_g3d, (clk_get_rate(aclk_g3d)/hpm_freq_table[level])); if(ret < 0) GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_rate [sclk_hpm_g3d]\n", __func__); ret = clk_set_parent(mout_g3d, fout_g3d_pll); if (ret < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_parent [fout_g3d_pll]\n", __func__); goto err; } g3d_rate_prev = g3d_rate; } platform->cur_clock = gpu_get_cur_clock(platform); if (platform->cur_clock != clk_get_rate(fout_g3d_pll)/MHZ) GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "clock value is wrong (aclk_g3d: %d, fout_g3d_pll: %d)\n", platform->cur_clock, (int) clk_get_rate(fout_g3d_pll)/MHZ); GPU_LOG(DVFS_DEBUG, LSI_CLOCK_VALUE, g3d_rate/MHZ, platform->cur_clock, "clock set: %ld, clock get: %d\n", g3d_rate/MHZ, platform->cur_clock); err: #ifdef CONFIG_MALI_RT_PM if (platform->exynos_pm_domain) mutex_unlock(&platform->exynos_pm_domain->access_lock); #endif /* CONFIG_MALI_RT_PM */ return ret; }
static int gpu_set_clock(struct exynos_context *platform, int clk) { long g3d_rate_prev = -1; unsigned long g3d_rate = clk * MHZ; int ret = 0; if (aclk_g3d == 0) return -1; #ifdef CONFIG_MALI_RT_PM if (platform->exynos_pm_domain) mutex_lock(&platform->exynos_pm_domain->access_lock); #endif /* CONFIG_MALI_RT_PM */ if (!gpu_is_power_on()) { ret = -1; GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "%s: can't set clock in the power-off state!\n", __func__); goto err; } if (!gpu_is_clock_on()) { ret = -1; GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "%s: can't set clock in the clock-off state! %d\n", __func__, __raw_readl(EXYNOS5430_ENABLE_ACLK_G3D)); goto err; } g3d_rate_prev = clk_get_rate(aclk_g3d); /* if changed the VPLL rate, set rate for VPLL and wait for lock time */ if (g3d_rate != g3d_rate_prev) { /*change here for future stable clock changing*/ ret = clk_set_parent(mout_g3d_pll, fin_pll); if (ret < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_parent [mout_g3d_pll]\n", __func__); goto err; } if (g3d_rate_prev != GPU_OSC_CLK) sec_debug_aux_log(SEC_DEBUG_AUXLOG_CPU_BUS_CLOCK_CHANGE, "[GPU] %7d <= %7d", g3d_rate / 1000, g3d_rate_prev / 1000); /*change g3d pll*/ ret = clk_set_rate(fout_g3d_pll, g3d_rate); if (ret < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_rate [fout_g3d_pll]\n", __func__); goto err; } /*restore parent*/ ret = clk_set_parent(mout_g3d_pll, fout_g3d_pll); if (ret < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_parent [mout_g3d_pll]\n", __func__); goto err; } } platform->cur_clock = gpu_get_cur_clock(platform); if (platform->cur_clock != clk_get_rate(fout_g3d_pll)/MHZ) GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "clock value is wrong (aclk_g3d: %d, fout_g3d_pll: %d)\n", platform->cur_clock, (int) clk_get_rate(fout_g3d_pll)/MHZ); if (g3d_rate != g3d_rate_prev) GPU_LOG(DVFS_DEBUG, LSI_CLOCK_VALUE, g3d_rate/MHZ, platform->cur_clock, "clock set: %d, clock get: %d\n", (int) g3d_rate/MHZ, platform->cur_clock); err: #ifdef CONFIG_MALI_RT_PM if (platform->exynos_pm_domain) mutex_unlock(&platform->exynos_pm_domain->access_lock); #endif /* CONFIG_MALI_RT_PM */ return ret; }
static int gpu_set_clock(struct exynos_context *platform, int clk) { long g3d_rate_prev = -1; unsigned long g3d_rate = clk * MHZ; int ret = 0; #if 0 if (aclk_g3d == 0) return -1; #endif #ifdef CONFIG_PM_RUNTIME if (platform->exynos_pm_domain) mutex_lock(&platform->exynos_pm_domain->access_lock); #endif /* CONFIG_PM_RUNTIME */ if (!gpu_is_power_on()) { ret = -1; GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "%s: can't set clock in the power-off state!\n", __func__); goto err; } if (!gpu_is_clock_on()) { ret = -1; GPU_LOG(DVFS_INFO, DUMMY, 0u, 0u, "%s: can't set clock in the clock-off state!\n", __func__); goto err; } #if 0 g3d_rate_prev = clk_get_rate(fout_g3d_pll); /* if changed the VPLL rate, set rate for VPLL and wait for lock time */ if (g3d_rate != g3d_rate_prev) { ret = gpu_set_maximum_outstanding_req(L2CONFIG_MO_1BY8); if (ret < 0) GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to set MO (%d)\n", __func__, ret); /*change here for future stable clock changing*/ ret = clk_set_parent(mout_g3d_pll, fin_pll); if (ret < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_parent [mout_g3d_pll]\n", __func__); goto err; } /*change g3d pll*/ ret = clk_set_rate(fout_g3d_pll, g3d_rate); if (ret < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_rate [fout_g3d_pll]\n", __func__); goto err; } /*restore parent*/ ret = clk_set_parent(mout_g3d_pll, fout_g3d_pll); if (ret < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_parent [mout_g3d_pll]\n", __func__); goto err; } #ifdef CONFIG_SOC_EXYNOS5433_REV_0 /*restore parent*/ ret = clk_set_parent(mout_aclk_g3d, aclk_g3d); if (ret < 0) { GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to clk_set_parent [mout_ack_g3d]\n", __func__); goto err; } #endif /* CONFIG_SOC_EXYNOS5433_REV_0 */ ret = gpu_set_maximum_outstanding_req(L2CONFIG_MO_NO_RESTRICT); if (ret < 0) GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: failed to restore MO (%d)\n", __func__, ret); g3d_rate_prev = g3d_rate; } #endif platform->cur_clock = gpu_get_cur_clock(platform); GPU_LOG(DVFS_DEBUG, LSI_CLOCK_VALUE, 0u, g3d_rate/MHZ, "clock set: %ld\n", g3d_rate/MHZ); GPU_LOG(DVFS_DEBUG, LSI_CLOCK_VALUE, 0u, platform->cur_clock, "clock get: %d\n", platform->cur_clock); err: #ifdef CONFIG_PM_RUNTIME if (platform->exynos_pm_domain) mutex_unlock(&platform->exynos_pm_domain->access_lock); #endif /* CONFIG_PM_RUNTIME */ return ret; }