#define GPU_CLK_DBG(fmt, arg...)
//disable print
-#define _dev_info(...)
+//#define _dev_info(...)
//static DEFINE_SPINLOCK(lock);
static mali_plat_info_t* pmali_plat = NULL;
ret = of_property_read_u32(gpu_dn,"def_clk",
&mpdata->def_clock);
if (ret) {
- dev_notice(&pdev->dev, "default clk set to %d\n", mpdata->dvfs_table_size/2-1);
- mpdata->def_clock = mpdata->dvfs_table_size/2 - 1;
+ mpdata->def_clock = mpdata->scale_info.maxclk;
+ dev_notice(&pdev->dev, "default clk set to %d\n", mpdata->def_clock);
}
+ if (mpdata->def_clock > mpdata->scale_info.maxclk)
+ mpdata->def_clock = mpdata->scale_info.maxclk;
+
_dev_info(&pdev->dev, "default clk is %d\n", mpdata->def_clock);
dvfs_tbl = mpdata->dvfs_table;
#else
int mali_clock_init_clk_tree(struct platform_device* pdev)
{
- //mali_dvfs_threshold_table *dvfs_tbl = &pmali_plat->dvfs_table[pmali_plat->def_clock];
+ mali_dvfs_threshold_table *dvfs_tbl = &pmali_plat->dvfs_table[pmali_plat->def_clock];
struct clk *clk_mali = pmali_plat->clk_mali;
+ if ((0 == strcmp(dvfs_tbl->clk_parent, "gp0_pll")) &&
+ !IS_ERR(dvfs_tbl->clkp_handle) &&
+ (0 != dvfs_tbl->clkp_freq)) {
+ clk_prepare_enable(dvfs_tbl->clkp_handle);
+ clk_set_rate(dvfs_tbl->clkp_handle, dvfs_tbl->clkp_freq);
+ }
clk_prepare_enable(clk_mali);
+ clk_set_rate(clk_mali, dvfs_tbl->clk_freq);
return 0;
}
if (ret) {
dev_notice(&pdev->dev, "read clk_freq failed\n");
}
-#if 0
-#ifdef MESON_CPU_VERSION_OPS
- if (is_meson_gxbbm_cpu()) {
- if (dvfs_tbl->clk_freq >= GXBBM_MAX_GPU_FREQ)
- continue;
- }
-#endif
-#endif
-#if 0
+
ret = of_property_read_string(gpu_clk_dn,"clk_parent",
- &dvfs_tbl->clk_parent);
+ &dvfs_tbl->clk_parent);
if (ret) {
dev_notice(&pdev->dev, "read clk_parent failed\n");
+ } else if (0 == strcmp(dvfs_tbl->clk_parent, "gp0_pll")) {
+ dvfs_tbl->clkp_handle = devm_clk_get(&pdev->dev, dvfs_tbl->clk_parent);
+ if (IS_ERR(dvfs_tbl->clkp_handle)) {
+ dev_notice(&pdev->dev, "failed to get %s's clock pointer\n", dvfs_tbl->clk_parent);
+ }
+ ret = of_property_read_u32(gpu_clk_dn,"clkp_freq", &dvfs_tbl->clkp_freq);
+ if (ret) {
+ dev_notice(&pdev->dev, "read clk_parent freq failed\n");
+ }
}
- dvfs_tbl->clkp_handle = devm_clk_get(&pdev->dev, dvfs_tbl->clk_parent);
- if (IS_ERR(dvfs_tbl->clkp_handle)) {
- dev_notice(&pdev->dev, "failed to get %s's clock pointer\n", dvfs_tbl->clk_parent);
- }
- ret = of_property_read_u32(gpu_clk_dn,"clkp_freq", &dvfs_tbl->clkp_freq);
- if (ret) {
- dev_notice(&pdev->dev, "read clk_parent freq failed\n");
- }
-#endif
+
ret = of_property_read_u32(gpu_clk_dn,"voltage", &dvfs_tbl->voltage);
if (ret) {
dev_notice(&pdev->dev, "read voltage failed\n");
ret = of_property_read_u32(gpu_dn,"def_clk",
&mpdata->def_clock);
if (ret) {
- dev_notice(&pdev->dev, "default clk set to %d\n", mpdata->dvfs_table_size/2-1);
- mpdata->def_clock = mpdata->dvfs_table_size/2 - 1;
+ mpdata->def_clock = mpdata->scale_info.maxclk;
+ dev_notice(&pdev->dev, "default clk set to %d\n", mpdata->def_clock);
}
+ if (mpdata->def_clock > mpdata->scale_info.maxclk)
+ mpdata->def_clock = mpdata->scale_info.maxclk;
_dev_info(&pdev->dev, "default clk is %d\n", mpdata->def_clock);
dvfs_tbl = mpdata->dvfs_table;
#include <asm/io.h>
#include <linux/clk.h>
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 29))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 29)) && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 10, 0))
#include <linux/amlogic/iomap.h>
#endif
/*
+ * mali_kbase_config_devicetree.c
*
- * (C) COPYRIGHT 2015, 2017 ARM Limited. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
- * This program is free software and is provided to you under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation, and any use by you of this program is subject to the terms
- * of such GNU licence.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, you can access it online at
- * http://www.gnu.org/licenses/gpl-2.0.html.
- *
- * SPDX-License-Identifier: GPL-2.0
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
*
*/
-
-
#ifdef CONFIG_DEVFREQ_THERMAL
#include <linux/version.h>
#include <linux/devfreq_cooling.h>
#include <mali_kbase_config.h>
+int kbase_platform_early_init(void)
+{
+ /* Nothing needed at this stage */
+ return 0;
+}
+
static struct kbase_platform_config dummy_platform_config;
struct kbase_platform_config *kbase_get_platform_config(void)
/*
+ * mali_kbase_config_platform.h
*
- * (C) COPYRIGHT 2014-2017 ARM Limited. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
- * This program is free software and is provided to you under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation, and any use by you of this program is subject to the terms
- * of such GNU licence.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, you can access it online at
- * http://www.gnu.org/licenses/gpl-2.0.html.
+ */
+
+/**
+ * Maximum frequency GPU will be clocked at. Given in kHz.
+ * This must be specified as there is no default value.
*
* SPDX-License-Identifier: GPL-2.0
*
/*
+ * mali_kbase_runtime_pm.c
*
- * (C) COPYRIGHT 2015, 2017 ARM Limited. All rights reserved.
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
- * This program is free software and is provided to you under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation, and any use by you of this program is subject to the terms
- * of such GNU licence.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, you can access it online at
- * http://www.gnu.org/licenses/gpl-2.0.html.
- *
- * SPDX-License-Identifier: GPL-2.0
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
*
*/
}
+static u32 last_utilisation, last_util_gl_share, last_util_cl_share[2];
inline int kbase_platform_dvfs_event(struct kbase_device *kbdev, u32 utilisation,
u32 util_gl_share, u32 util_cl_share[2])
{
+ last_utilisation = utilisation;
+ last_util_gl_share = util_gl_share;
+ last_util_cl_share[0] = util_cl_share[0];
+ last_util_cl_share[1] = util_cl_share[1];
mali_gpu_utilization_callback(utilisation*255/100);
return 1;
}
+u32 mpgpu_get_utilization(void)
+{
+ return last_utilisation;
+}
+u32 mpgpu_get_util_gl_share(void)
+{
+ return last_util_gl_share;
+}
+u32 mpgpu_get_util_cl_share(u32 *util)
+{
+ util[0] = last_util_cl_share[0];
+ util[1] = last_util_cl_share[1];
+ return 0;
+}
+
struct kbase_platform_funcs_conf dt_funcs_conf = {
.platform_init_func = platform_dt_init_func,
.platform_term_func = platform_dt_term_func,
void mpgpu_class_exit(void);
void mali_gpu_utilization_callback(int utilization_pp);
+u32 mpgpu_get_utilization(void);
+u32 mpgpu_get_util_gl_share(void);
+u32 mpgpu_get_util_cl_share(u32 *util);
+u32 mpgpu_get_gpu_err_count(void);
+
#endif /* MESON_MAIN_H_ */
#include "meson_main2.h"
+int meson_gpu_data_invalid_count = 0;
+int meson_gpu_fault = 0;
+
static ssize_t domain_stat_read(struct class *class,
struct class_attribute *attr, char *buf)
{
return count;
}
-#if 0
-static ssize_t max_pp_read(struct class *class,
- struct class_attribute *attr, char *buf)
-{
- mali_plat_info_t* pmali_plat = get_mali_plat_data();
- printk("maxpp:%d, maxpp_sysfs:%d, total=%d\n",
- pmali_plat->scale_info.maxpp, pmali_plat->maxpp_sysfs,
- pmali_plat->cfg_pp);
- return sprintf(buf, "%d\n", pmali_plat->cfg_pp);
-}
-
-static ssize_t max_pp_write(struct class *class,
- struct class_attribute *attr, const char *buf, size_t count)
-{
- int ret;
- unsigned int val;
- mali_plat_info_t* pmali_plat;
- mali_scale_info_t* pinfo;
-
- pmali_plat = get_mali_plat_data();
- pinfo = &pmali_plat->scale_info;
-
- ret = kstrtouint(buf, 10, &val);
- if ((0 != ret) || (val > pmali_plat->cfg_pp) || (val < pinfo->minpp))
- return -EINVAL;
-
- pmali_plat->maxpp_sysfs = val;
- pinfo->maxpp = val;
- revise_mali_rt();
-
- return count;
-}
-
-static ssize_t min_pp_read(struct class *class,
- struct class_attribute *attr, char *buf)
-{
- mali_plat_info_t* pmali_plat = get_mali_plat_data();
- return sprintf(buf, "%d\n", pmali_plat->scale_info.minpp);
-}
-
-static ssize_t min_pp_write(struct class *class,
- struct class_attribute *attr, const char *buf, size_t count)
-{
- int ret;
- unsigned int val;
- mali_plat_info_t* pmali_plat;
- mali_scale_info_t* pinfo;
-
- pmali_plat = get_mali_plat_data();
- pinfo = &pmali_plat->scale_info;
-
- ret = kstrtouint(buf, 10, &val);
- if ((0 != ret) || (val > pinfo->maxpp) || (val < 1))
- return -EINVAL;
-
- pinfo->minpp = val;
- revise_mali_rt();
-
- return count;
-}
-#endif
-
static ssize_t max_freq_read(struct class *class,
struct class_attribute *attr, char *buf)
{
return count;
}
-#if 0
-static ssize_t current_pp_read(struct class *class,
+static ssize_t utilization_read(struct class *class,
struct class_attribute *attr, char *buf)
{
- u32 clk, pp;
- get_mali_rt_clkpp(&clk, &pp);
- return sprintf(buf, "%d\n", pp);
+ return sprintf(buf, "%d\n", mpgpu_get_utilization());
+}
+
+static ssize_t util_gl_share_read(struct class *class,
+ struct class_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", mpgpu_get_util_gl_share());
}
-static ssize_t current_pp_write(struct class *class,
+static ssize_t util_cl_share_read(struct class *class,
+ struct class_attribute *attr, char *buf)
+{
+ u32 val[2];
+
+ mpgpu_get_util_cl_share(val);
+
+ return sprintf(buf, "%d %d\n", val[0], val[1]);
+}
+
+u32 mpgpu_get_gpu_err_count(void)
+{
+ return (meson_gpu_fault + meson_gpu_data_invalid_count);
+}
+
+static ssize_t meson_gpu_get_err_count(struct class *class,
+ struct class_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", mpgpu_get_gpu_err_count());
+}
+
+static ssize_t mpgpu_set_err_count(struct class *class,
struct class_attribute *attr, const char *buf, size_t count)
{
int ret;
unsigned int val;
- u32 clk, pp;
- get_mali_rt_clkpp(&clk, &pp);
ret = kstrtouint(buf, 10, &val);
if (0 != ret)
- {
return -EINVAL;
- }
- ret = kstrtouint(buf, 10, &val);
- if (0 != ret)
- return -EINVAL;
-
- set_mali_rt_clkpp(clk, val, 1);
+ meson_gpu_fault = val;
return count;
}
-#endif
static struct class_attribute mali_class_attrs[] = {
__ATTR(domain_stat, 0644, domain_stat_read, NULL),
__ATTR(scale_mode, 0644, scale_mode_read, scale_mode_write),
__ATTR(min_freq, 0644, min_freq_read, min_freq_write),
__ATTR(max_freq, 0644, max_freq_read, max_freq_write),
-#if 0
- __ATTR(min_pp, 0644, min_pp_read, min_pp_write),
- __ATTR(max_pp, 0644, max_pp_read, max_pp_write),
-#endif
__ATTR(cur_freq, 0644, freq_read, freq_write),
-#if 0
- __ATTR(cur_pp, 0644, current_pp_read, current_pp_write),
-#endif
+ __ATTR(utilization, 0644, utilization_read, NULL),
+ __ATTR(util_gl, 0644, util_gl_share_read, NULL),
+ __ATTR(util_cl, 0644, util_cl_share_read, NULL),
+ __ATTR(gpu_err, 0644, meson_gpu_get_err_count, mpgpu_set_err_count),
};
static struct class mpgpu_class = {
#include <mach/io.h>
#endif
#include <asm/io.h>
-#if defined(CONFIG_GPU_THERMAL)
-#include <linux/gpu_cooling.h>
-#include <linux/gpucore_cooling.h>
-#include <linux/amlogic/aml_thermal_hw.h>
-#endif
-#if defined(CONFIG_AMLOGIC_GPU_THERMAL)
+#ifdef CONFIG_AMLOGIC_GPU_THERMAL
#include <linux/amlogic/gpu_cooling.h>
#include <linux/amlogic/gpucore_cooling.h>
-#include <linux/amlogic/aml_thermal_hw.h>
+//#include <linux/amlogic/aml_thermal_hw.h>
+#include <linux/amlogic/meson_cooldev.h>
#endif
#include "mali_scaling.h"
return mali_plat_data.cfg_clock;
}
-#if defined(CONFIG_GPU_THERMAL) || defined(CONFIG_AMLOGIC_GPU_THERMAL)
+#ifdef CONFIG_AMLOGIC_GPU_THERMAL
static void set_limit_mali_freq(u32 idx)
{
if (mali_plat_data.limit_on == 0)
#endif
#endif
-#if defined(CONFIG_GPU_THERMAL) || defined(CONFIG_AMLOGIC_GPU_THERMAL)
+#ifdef CONFIG_AMLOGIC_GPU_THERMAL
static u32 set_limit_pp_num(u32 num)
{
u32 ret = -1;
void mali_post_init(void)
{
-#if defined(CONFIG_GPU_THERMAL) || defined(CONFIG_AMLOGIC_GPU_THERMAL)
+#ifdef CONFIG_AMLOGIC_GPU_THERMAL
int err;
struct gpufreq_cooling_device *gcdev = NULL;
struct gpucore_cooling_device *gccdev = NULL;
gcdev->get_online_pp = mali_get_online_pp;
#endif
err = gpufreq_cooling_register(gcdev);
-#if 0
-//#ifdef CONFIG_DEVFREQ_THERMAL
- aml_thermal_min_update(gcdev->cool_dev);
+#ifdef CONFIG_DEVFREQ_THERMAL
+ meson_gcooldev_min_update(gcdev->cool_dev);
#endif
if (err < 0)
printk("register GPU cooling error\n");
gccdev->max_gpu_core_num=mali_plat_data.cfg_pp;
gccdev->set_max_pp_num=set_limit_pp_num;
err = (int)gpucore_cooling_register(gccdev);
-#if 0
-//#ifdef CONFIG_DEVFREQ_THERMAL
- aml_thermal_min_update(gccdev->cool_dev);
+#ifdef CONFIG_DEVFREQ_THERMAL
+ meson_gcooldev_min_update(gccdev->cool_dev);
#endif
if (err < 0)
printk("register GPU cooling error\n");
{
mali_dvfs_threshold_table * pdvfs = pmali_plat->dvfs_table;
uint32_t execStep = currentStep;
-#if AMLOGIC_GPU_USE_GPPLL
mali_dvfs_threshold_table *dvfs_tbl = &pmali_plat->dvfs_table[currentStep];
-#endif
//if (pdvfs[currentStep].freq_index == pdvfs[lastStep].freq_index) return;
if ((pdvfs[execStep].freq_index == pdvfs[lastStep].freq_index) ||
is_gp_pll_put = 0;
gp_pll_release(gp_pll_user_gpu);
}
+#else
+ if ((0 == strcmp(dvfs_tbl->clk_parent, "gp0_pll")) &&
+ !IS_ERR(dvfs_tbl->clkp_handle) &&
+ (0 != dvfs_tbl->clkp_freq)) {
+ clk_prepare_enable(dvfs_tbl->clkp_handle);
+ clk_set_rate(dvfs_tbl->clkp_handle, dvfs_tbl->clkp_freq);
+ }
+
#endif
//mali_dev_pause();
mali_clock_set(pdvfs[execStep].freq_index);
//mali_dev_resume();
+#if AMLOGIC_GPU_USE_GPPLL==0
+ if ((0 == strcmp(pdvfs[lastStep].clk_parent,"gp0_pll")) &&
+ (0 != strcmp(pdvfs[execStep].clk_parent, "gp0_pll"))) {
+ clk_disable_unprepare(pdvfs[lastStep].clkp_handle);
+ }
+#endif
+
lastStep = execStep;
#if AMLOGIC_GPU_USE_GPPLL
if (is_gp_pll_put) {