MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS ?= 0
MALI_UPPER_HALF_SCHEDULING ?= 1
MALI_ENABLE_CPU_CYCLES ?= 0
-MALI_PLATFORM ?= rk30
+MALI_PLATFORM ?= rk
# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases:
# The ARM proprietary product will only include the license/proprietary directory
EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1
#MALI_PLATFORM_FILES = $(wildcard platform/$(MALI_PLATFORM)/*.c)
mali-y += \
- platform/$(MALI_PLATFORM)/mali_platform.o \
- platform/$(MALI_PLATFORM)/rk3066.o \
- platform/$(MALI_PLATFORM)/mali_dvfs.o
+ platform/$(MALI_PLATFORM)/rk.o
endif
ifeq ($(MALI_PLATFORM_FILES),)
* @file mali_kernel_linux.c
* Implementation of the Linux device driver entrypoints
*/
-#include "../platform/rk30/custom_log.h"
-#include "../platform/rk30/rk_ext.h"
+#include "../platform/rk/custom_log.h"
+#include "../platform/rk/rk_ext.h"
#include <linux/module.h> /* kernel module definitions */
#include <linux/fs.h> /* file system operations */
* @file mali_osk_mali.c
* Implementation of the OS abstraction layer which is specific for the Mali kernel device driver
*/
-#include "../platform/rk30/custom_log.h"
+#include "../platform/rk/custom_log.h"
#include <linux/kernel.h>
#include <asm/uaccess.h>
return 0;
}
#else
-#include "../platform/rk30/rk_ext.h"
+#include "../platform/rk/rk_ext.h"
int get_rk_ko_version_wrapper(struct mali_session_data *session_data, _mali_rk_ko_version_s __user *uargs)
{
_mali_rk_ko_version_s kargs;
--- /dev/null
+/* ----------------------------------------------------------------------------
+ * File: custom_log.h
+ *
+ * Desc: ChenZhen 偏好的 log 输出的定制实现.
+ *
+ * --------------------------------------------------------------------
+ * < 习语 和 缩略语 > :
+ *
+ * --------------------------------------------------------------------
+ * Usage:
+ *
+ * Note:
+ *
+ * Author: ChenZhen
+ *
+ * ----------------------------------------------------------------------------
+ * Version:
+ * v1.0
+ * ----------------------------------------------------------------------------
+ * Log:
+ ----Fri Nov 19 15:20:28 2010 v1.0
+ *
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef __CUSTOM_LOG_H__
+#define __CUSTOM_LOG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Include Files
+ * -----------------------------------------------------------------------------
+ */
+#include <linux/kernel.h>
+#include <linux/printk.h>
+
+/* -----------------------------------------------------------------------------
+ * Macros Definition
+ * -----------------------------------------------------------------------------
+ */
+
+/** 若下列 macro 有被定义, 才 使能 log 输出. */
+/* #define ENABLE_DEBUG_LOG */
+
+/*----------------------------------------------------------------------------*/
+
+#ifdef ENABLE_VERBOSE_LOG
+/** Verbose log. */
+#define V(fmt, args...) \
+ pr_debug("V : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \
+ "\n", \
+ __FILE__, \
+ __LINE__, \
+ __func__, \
+ ## args)
+#else
+#define V(...) ((void)0)
+#endif
+
+#ifdef ENABLE_DEBUG_LOG
+/** Debug log. */
+#define D(fmt, args...) \
+ pr_info("D : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \
+ "\n", \
+ __FILE__, \
+ __LINE__, \
+ __func__, \
+ ## args)
+#else
+#define D(...) ((void)0)
+#endif
+
+#define I(fmt, args...) \
+ pr_info("I : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \
+ "\n", \
+ __FILE__, \
+ __LINE__, \
+ __func__, \
+ ## args)
+
+#define W(fmt, args...) \
+ pr_warn("W : [File] : %s; [Line] : %d; [Func] : %s(); " \
+ fmt "\n", \
+ __FILE__, \
+ __LINE__, \
+ __func__, \
+ ## args)
+
+#define E(fmt, args...) \
+ pr_err("E : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \
+ "\n", \
+ __FILE__, \
+ __LINE__, \
+ __func__, \
+ ## args)
+
+/*-------------------------------------------------------*/
+
+/** 使用 D(), 以十进制的形式打印变量 'var' 的 value. */
+#define D_DEC(var) D(#var " = %d.", var)
+
+#define E_DEC(var) E(#var " = %d.", var)
+
+/** 使用 D(), 以十六进制的形式打印变量 'var' 的 value. */
+#define D_HEX(var) D(#var " = 0x%x.", var)
+
+#define E_HEX(var) E(#var " = 0x%x.", var)
+
+/**
+ * 使用 D(), 以十六进制的形式,
+ * 打印指针类型变量 'ptr' 的 value.
+ */
+#define D_PTR(ptr) D(#ptr " = %p.", ptr)
+
+#define E_PTR(ptr) E(#ptr " = %p.", ptr)
+
+/** 使用 D(), 打印 char 字串. */
+#define D_STR(p_str) \
+do { \
+ if (!p_str) { \
+ D(#p_str " = NULL."); \
+ else \
+ D(#p_str " = '%s'.", p_str); \
+} while (0)
+
+#define E_STR(p_str) \
+do { \
+ if (!p_str) \
+ E(#p_str " = NULL."); \
+ else \
+ E(#p_str " = '%s'.", p_str); \
+} while (0)
+
+#ifdef ENABLE_DEBUG_LOG
+/**
+ * log 从 'p_start' 地址开始的 'len' 个字节的数据.
+ */
+#define D_MEM(p_start, len) \
+do { \
+ int i = 0; \
+ char *p = (char *)(p_start); \
+ D("dump memory from addr of '" #p_start "', from %p, length %d' : ", \
+ (p_start), \
+ (len)); \
+ pr_debug("\t\t"); \
+ for (i = 0; i < (len); i++) \
+ pr_debug("0x%02x, ", p[i]); \
+ pr_debug("\n"); \
+} while (0)
+#else
+#define D_MEM(...) ((void)0)
+#endif
+
+/*-------------------------------------------------------*/
+
+/**
+ * 在特定条件下, 判定 error 发生,
+ * 将变量 'ret_var' 设置 'err_code',
+ * log 输出对应的 Error Caution,
+ * 然后跳转 'label' 指定的代码处执行.
+ * @param msg
+ * 纯字串形式的提示信息.
+ * @param ret_var
+ * 标识函数执行状态或者结果的变量,
+ * 将被设置具体的 Error Code.
+ * 通常是 'ret' or 'result'.
+ * @param err_code
+ * 表征特定 error 的常数标识,
+ * 通常是 宏的形态.
+ * @param label
+ * 程序将要跳转到的错误处理代码的标号,
+ * 通常就是 'EXIT'.
+ * @param args...
+ * 对应 'msg_fmt' 实参中,
+ * '%s', '%d', ... 等转换说明符的具体可变长实参.
+ */
+#define SET_ERROR_AND_JUMP(msg_fmt, ret_var, err_code, label, args...) \
+do { \
+ E("To set '" #ret_var "' to %d('" #err_code "'), because : " msg_fmt, \
+ (err_code), \
+ ## args); \
+ (ret_var) = (err_code); \
+ goto label; \
+} while (0)
+
+/* -----------------------------------------------------------------------------
+ * Types and Structures Definition
+ * -----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------
+ * Global Functions' Prototype
+ * -----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------
+ * Inline Functions Implementation
+ * -----------------------------------------------------------------------------
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CUSTOM_LOG_H__ */
--- /dev/null
+/*
+ * This confidential and proprietary software may be used only as
+ * authorised by a licensing agreement from ARM Limited
+ * (C) COPYRIGHT 2009-2010, 2012 ARM Limited
+ * ALL RIGHTS RESERVED
+ * The entire notice above must be reproduced on all authorised
+ * copies and copies may only be made to the extent permitted
+ * by a licensing agreement from ARM Limited.
+ */
+
+/**
+ * @file rk.c
+ * implementation of platform_specific_code on rk platforms, such as rk3328h.
+ *
+ * mali_device_driver(MDD) includes 2 parts :
+ * .DP : platform_dependent_part :
+ * located in <mdd_src_dir>/mali/platform/<platform_name>/
+ * .DP : common_part :
+ * common part implemented by ARM.
+ */
+
+#define ENABLE_DEBUG_LOG
+#include "custom_log.h"
+
+#include <linux/platform_device.h>
+#include <linux/version.h>
+#include <linux/pm.h>
+#include <linux/of.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#ifdef CONFIG_PM
+#include <linux/pm_runtime.h>
+#endif
+#include <linux/workqueue.h>
+#include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
+#include <linux/rockchip/cpu.h>
+
+#include <linux/mali/mali_utgard.h>
+#include "mali_kernel_common.h"
+#include "../../common/mali_osk_mali.h"
+
+/*---------------------------------------------------------------------------*/
+
+u32 mali_group_error;
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * rk_platform_context_of_mali_device.
+ */
+struct rk_context {
+ /* mali device. */
+ struct device *dev;
+ /* is the GPU powered on? */
+ bool is_powered;
+};
+
+struct rk_context *s_rk_context;
+
+/*-------------------------------------------------------*/
+
+static int rk_context_create_sysfs_files(struct device *dev)
+{
+ int ret = 0;
+
+ return ret;
+}
+
+static void rk_context_remove_sysfs_files(struct device *dev)
+{
+}
+
+/*
+ * Init rk_platform_context of mali_device.
+ */
+static int rk_context_init(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct device *dev = &pdev->dev;
+ struct rk_context *platform; /* platform_context */
+
+ platform = kzalloc(sizeof(*platform), GFP_KERNEL);
+ if (!platform) {
+ E("no mem.");
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ platform->dev = dev;
+ platform->is_powered = false;
+
+ ret = rk_context_create_sysfs_files(dev);
+ if (ret) {
+ E("fail to create sysfs files, ret = %d", ret);
+ goto EXIT;
+ }
+
+ s_rk_context = platform;
+
+ pm_runtime_set_autosuspend_delay(dev, 1000);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_enable(dev);
+
+EXIT:
+ return ret;
+}
+
+static void rk_context_deinit(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct rk_context *platform = s_rk_context;
+
+ pm_runtime_disable(dev);
+
+ s_rk_context = NULL;
+
+ rk_context_remove_sysfs_files(dev);
+
+ if (platform) {
+ platform->is_powered = false;
+ platform->dev = NULL;
+ kfree(platform);
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/* for devfreq cooling. */
+
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_DEVFREQ_THERMAL)
+
+#define FALLBACK_STATIC_TEMPERATURE 55000
+
+static struct thermal_zone_device *gpu_tz;
+
+/* Calculate gpu static power example for reference */
+static unsigned long rk_model_static_power(unsigned long voltage)
+{
+ int temperature, temp;
+ int temp_squared, temp_cubed, temp_scaling_factor;
+ const unsigned long coefficient = (410UL << 20) / (729000000UL >> 10);
+ const unsigned long voltage_cubed = (voltage * voltage * voltage) >> 10;
+ unsigned long static_power;
+
+ if (gpu_tz) {
+ int ret;
+
+ ret = gpu_tz->ops->get_temp(gpu_tz, &temperature);
+ if (ret) {
+ MALI_DEBUG_PRINT(2, ("fail to read temp: %d\n", ret));
+ temperature = FALLBACK_STATIC_TEMPERATURE;
+ }
+ } else {
+ temperature = FALLBACK_STATIC_TEMPERATURE;
+ }
+
+ /* Calculate the temperature scaling factor. To be applied to the
+ * voltage scaled power.
+ */
+ temp = temperature / 1000;
+ temp_squared = temp * temp;
+ temp_cubed = temp_squared * temp;
+ temp_scaling_factor =
+ (2 * temp_cubed)
+ - (80 * temp_squared)
+ + (4700 * temp)
+ + 32000;
+
+ static_power = (((coefficient * voltage_cubed) >> 20)
+ * temp_scaling_factor)
+ / 1000000;
+
+ return static_power;
+}
+
+/* Calculate gpu dynamic power example for reference */
+static unsigned long rk_model_dynamic_power(unsigned long freq,
+ unsigned long voltage)
+{
+ /* The inputs: freq (f) is in Hz, and voltage (v) in mV.
+ * The coefficient (c) is in mW/(MHz mV mV).
+ *
+ * This function calculates the dynamic power after this formula:
+ * Pdyn (mW) = c (mW/(MHz*mV*mV)) * v (mV) * v (mV) * f (MHz)
+ */
+ const unsigned long v2 = (voltage * voltage) / 1000; /* m*(V*V) */
+ const unsigned long f_mhz = freq / 1000000; /* MHz */
+ const unsigned long coefficient = 3600; /* mW/(MHz*mV*mV) */
+ unsigned long dynamic_power;
+
+ dynamic_power = (coefficient * v2 * f_mhz) / 1000000; /* mW */
+
+ return dynamic_power;
+}
+
+struct devfreq_cooling_power rk_cooling_ops = {
+ .get_static_power = rk_model_static_power,
+ .get_dynamic_power = rk_model_dynamic_power,
+};
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+#ifdef CONFIG_PM
+
+static int rk_platform_enable_clk_gpu(struct device *dev)
+{
+ int ret = 0;
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_HAVE_CLK)
+ struct mali_device *mdev = dev_get_drvdata(dev);
+
+ if (mdev->clock)
+ ret = clk_enable(mdev->clock);
+#endif
+ return ret;
+}
+
+static void rk_platform_disable_clk_gpu(struct device *dev)
+{
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_HAVE_CLK)
+ struct mali_device *mdev = dev_get_drvdata(dev);
+
+ if (mdev->clock)
+ clk_disable(mdev->clock);
+#endif
+}
+
+static int rk_platform_enable_gpu_regulator(struct device *dev)
+{
+ int ret = 0;
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_REGULATOR)
+ struct mali_device *mdev = dev_get_drvdata(dev);
+
+ if (mdev->regulator)
+ ret = regulator_enable(mdev->regulator);
+#endif
+ return ret;
+}
+
+static void rk_platform_disable_gpu_regulator(struct device *dev)
+{
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_REGULATOR)
+ struct mali_device *mdev = dev_get_drvdata(dev);
+
+ if (mdev->regulator)
+ regulator_disable(mdev->regulator);
+#endif
+}
+
+static int rk_platform_power_on_gpu(struct device *dev)
+{
+ int ret = 0;
+
+ ret = rk_platform_enable_clk_gpu(dev);
+ if (ret) {
+ E("fail to enable clk_gpu, ret : %d.", ret);
+ goto fail_to_enable_clk;
+ }
+
+ ret = rk_platform_enable_gpu_regulator(dev);
+ if (ret) {
+ E("fail to enable vdd_gpu, ret : %d.", ret);
+ goto fail_to_enable_regulator;
+ }
+
+ return 0;
+
+fail_to_enable_regulator:
+ rk_platform_disable_clk_gpu(dev);
+
+fail_to_enable_clk:
+ return ret;
+}
+
+static void rk_platform_power_off_gpu(struct device *dev)
+{
+ rk_platform_disable_clk_gpu(dev);
+ rk_platform_disable_gpu_regulator(dev);
+}
+
+static int mali_runtime_suspend(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
+
+ if (device->driver &&
+ device->driver->pm &&
+ device->driver->pm->runtime_suspend) {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->runtime_suspend(device);
+ }
+
+ rk_platform_power_off_gpu(device);
+
+ return ret;
+}
+
+static int mali_runtime_resume(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
+
+ rk_platform_power_on_gpu(device);
+
+ if (device->driver &&
+ device->driver->pm &&
+ device->driver->pm->runtime_resume) {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->runtime_resume(device);
+ }
+
+ return ret;
+}
+
+static int mali_runtime_idle(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
+
+ if (device->driver &&
+ device->driver->pm &&
+ device->driver->pm->runtime_idle) {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->runtime_idle(device);
+ if (ret)
+ return ret;
+ }
+
+ pm_runtime_suspend(device);
+
+ return 0;
+}
+#endif
+
+static int mali_os_suspend(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
+
+ if (device->driver &&
+ device->driver->pm &&
+ device->driver->pm->suspend) {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->suspend(device);
+ }
+
+ rk_platform_power_off_gpu(device);
+
+ return ret;
+}
+
+static int mali_os_resume(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n"));
+
+ rk_platform_power_on_gpu(device);
+
+ if (device->driver &&
+ device->driver->pm &&
+ device->driver->pm->resume) {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->resume(device);
+ }
+
+ return ret;
+}
+
+static int mali_os_freeze(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_os_freeze() called\n"));
+
+ if (device->driver &&
+ device->driver->pm &&
+ device->driver->pm->freeze) {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->freeze(device);
+ }
+
+ return ret;
+}
+
+static int mali_os_thaw(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_os_thaw() called\n"));
+
+ if (device->driver &&
+ device->driver->pm &&
+ device->driver->pm->thaw) {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->thaw(device);
+ }
+
+ return ret;
+}
+
+static const struct dev_pm_ops mali_gpu_device_type_pm_ops = {
+ .suspend = mali_os_suspend,
+ .resume = mali_os_resume,
+ .freeze = mali_os_freeze,
+ .thaw = mali_os_thaw,
+#ifdef CONFIG_PM
+ .runtime_suspend = mali_runtime_suspend,
+ .runtime_resume = mali_runtime_resume,
+ .runtime_idle = mali_runtime_idle,
+#endif
+};
+
+static const struct device_type mali_gpu_device_device_type = {
+ .pm = &mali_gpu_device_type_pm_ops,
+};
+
+/*
+ * platform_specific_data of platform_device of mali_gpu.
+ */
+static const struct mali_gpu_device_data mali_gpu_data = {
+ .shared_mem_size = 1024 * 1024 * 1024, /* 1GB */
+ .max_job_runtime = 100, /* 100 ms */
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_DEVFREQ_THERMAL)
+ .gpu_cooling_ops = &rk_cooling_ops,
+#endif
+};
+
+static void mali_platform_device_add_config(struct platform_device *pdev)
+{
+ pdev->name = MALI_GPU_NAME_UTGARD,
+ pdev->id = 0;
+ pdev->dev.type = &mali_gpu_device_device_type;
+ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask,
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+}
+
+/*---------------------------------------------------------------------------*/
+/* platform_device_functions called by common_part. */
+
+int mali_platform_device_init(struct platform_device *pdev)
+{
+ int err = 0;
+
+ mali_platform_device_add_config(pdev);
+
+ D("to add platform_specific_data to platform_device_of_mali.");
+ err = platform_device_add_data(pdev,
+ &mali_gpu_data,
+ sizeof(mali_gpu_data));
+ if (err) {
+ E("fail to add platform_specific_data. err : %d.", err);
+ goto EXIT;
+ }
+
+ err = rk_context_init(pdev);
+ if (err) {
+ E("fail to init rk_context. err : %d.", err);
+ goto EXIT;
+ }
+
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_DEVFREQ_THERMAL)
+ /* Get thermal zone */
+ gpu_tz = thermal_zone_get_zone_by_name("gpu_thermal");
+ if (IS_ERR(gpu_tz)) {
+ W("Error getting gpu thermal zone (%ld), not yet ready?",
+ PTR_ERR(gpu_tz));
+ gpu_tz = NULL;
+ /* err = -EPROBE_DEFER; */
+ }
+#endif
+
+EXIT:
+ return err;
+}
+
+void mali_platform_device_deinit(struct platform_device *pdev)
+{
+ MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
+
+ rk_context_deinit(pdev);
+}
--- /dev/null
+/* ----------------------------------------------------------------------------
+ * File: rk_ext.h
+ *
+ * Desc: rk_ext_on_mali_ko 中的 通行定义等.
+ *
+ * Usage:
+ *
+ * Note:
+ *
+ * Author: ChenZhen
+ *
+ * Log:
+ *
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef __RK_EXT_H__
+#define __RK_EXT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+/** version of rk_ext on mali_ko, aka. rk_ko_ver. */
+#define RK_KO_VER (5)
+
+/*---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RK_EXT_H__ */
+
+++ /dev/null
-/* ----------------------------------------------------------------------------
- * File: custom_log.h
- *
- * Desc: ChenZhen 偏好的 log 输出的定制实现.
- *
- * --------------------------------------------------------------------
- * < 习语 和 缩略语 > :
- *
- * --------------------------------------------------------------------
- * Usage:
- *
- * Note:
- *
- * Author: ChenZhen
- *
- * ----------------------------------------------------------------------------
- * Version:
- * v1.0
- * ----------------------------------------------------------------------------
- * Log:
- ----Fri Nov 19 15:20:28 2010 v1.0
- *
- * ----------------------------------------------------------------------------
- */
-
-
-#ifndef __CUSTOM_LOG_H__
-#define __CUSTOM_LOG_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* -----------------------------------------------------------------------------
- * Include Files
- * -----------------------------------------------------------------------------
- */
-#include <linux/kernel.h>
-#include <linux/printk.h>
-
-
-/* -----------------------------------------------------------------------------
- * Macros Definition
- * -----------------------------------------------------------------------------
- */
-
-/** 若下列 macro 有被定义, 才 使能 log 输出. */
-/* #define ENABLE_DEBUG_LOG */
-
-/** .! : 若需要全局地关闭 D log, 可以使能下面的代码. */
-/*
-#undef ENABLE_DEBUG_LOG
-#warning "custom debug log is disabled globally!"
-*/
-
-/*----------------------------------------------------------------------------*/
-
-#ifdef ENABLE_VERBOSE_LOG
-/** Verbose log. */
-#define V(fmt, args...) \
- pr_info("V : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \
- "\n", \
- __FILE__, \
- __LINE__, \
- __func__, \
- ## args)
-#else
-#define V(...) ((void)0)
-#endif
-
-
-#ifdef ENABLE_DEBUG_LOG
-/** Debug log. */
-#define D(fmt, args...) \
- pr_info("D : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \
- "\n", \
- __FILE__, \
- __LINE__, \
- __func__, \
- ## args)
-#else
-#define D(...) ((void)0)
-#endif
-
-#define I(fmt, args...) \
- pr_info("I : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \
- "\n", \
- __FILE__, \
- __LINE__, \
- __func__, \
- ## args)
-
-#define W(fmt, args...) \
- pr_warn("W : [File] : %s; [Line] : %d; [Func] : %s(); " \
- fmt "\n", \
- __FILE__, \
- __LINE__, \
- __func__, \
- ## args)
-
-#define E(fmt, args...) \
- pr_err("E : [File] : %s; [Line] : %d; [Func] : %s(); " fmt \
- "\n", \
- __FILE__, \
- __LINE__, \
- __func__, \
- ## args)
-
-/*-------------------------------------------------------*/
-
-/** 使用 D(), 以十进制的形式打印变量 'var' 的 value. */
-#define D_DEC(var) D(#var " = %d.", var)
-
-#define E_DEC(var) E(#var " = %d.", var)
-
-/** 使用 D(), 以十六进制的形式打印变量 'var' 的 value. */
-#define D_HEX(var) D(#var " = 0x%x.", var)
-
-#define E_HEX(var) E(#var " = 0x%x.", var)
-
-/**
- * 使用 D(), 以十六进制的形式,
- * 打印指针类型变量 'ptr' 的 value.
- */
-#define D_PTR(ptr) D(#ptr " = %p.", ptr)
-
-#define E_PTR(ptr) E(#ptr " = %p.", ptr)
-
-/** 使用 D(), 打印 char 字串. */
-#define D_STR(p_str) \
-do { \
- if (NULL == p_str) { \
- D(#p_str" = NULL."); \
- else \
- D(#p_str" = '%s'.", p_str); \
-} while (0)
-
-#define E_STR(p_str) \
-do { \
- if (NULL == p_str) \
- E(#p_str" = NULL."); \
- else \
- E(#p_str" = '%s'.", p_str); \
-} while (0)
-
-#ifdef ENABLE_DEBUG_LOG
-/**
- * log 从 'p_start' 地址开始的 'len' 个字节的数据.
- */
-#define D_MEM(p_start, len) \
-do { \
- int i = 0; \
- char *p = (char *)(p_start); \
- D("dump memory from addr of '" #p_start "', from %p, length %d' : ", \
- (p_start), \
- (len)); \
- pr_debug("\t\t"); \
- for (i = 0; i < (len); i++) \
- pr_debug("0x%02x, ", p[i]); \
- pr_debug("\n"); \
-} while (0)
-#else
-#define D_MEM(...) ((void)0)
-#endif
-
-/*-------------------------------------------------------*/
-
-#define EXIT_FOR_DEBUG \
-do { \
- E("To exit for debug."); \
- return 1; \
-} while (0)
-
-/*-------------------------------------------------------*/
-
-/**
- * 调用函数, 并检查返回值, 根据返回值决定是否跳转到指定的错误处理代码.
- * @param func_call
- * 对特定函数的调用,
- * 该函数的返回值必须是 表征 成功 or err 的 整型数.
- * 且被 "必须" 被定义为 "返回 0 表示操作成功".
- * @param result
- * 用于记录函数返回的 error code 的 整型变量,
- * 通常是 "ret" or "result" 等.
- * @param label
- * 若函数返回错误,
- * 程序将要跳转到的 错误处理处的 标号,
- * 通常就是 "EXIT".
- */
-#define CHECK_FUNC_CALL(func_call, result, label) \
-do { \
- (result) = (func_call) \
- if (0 != (result)) { \
- E("Function call returned error : " #result " = %d.", result); \
- goto label;\
- } \
-} while (0)
-
-/**
- * 在特定条件下, 判定 error 发生, 对变量 'ret_var' 设置 'err_code',
- * Log 输出对应的 Error Caution,
- * 然后跳转 'label' 指定的代码处执行.
- * @param msg
- * 纯字串形式的提示信息.
- * @param ret_var
- * 标识函数执行状态或者结果的变量,
- * 将被设置具体的 Error Code.
- * 通常是 'ret' or 'result'.
- * @param err_code
- * 表征特定 error 的常数标识,
- * 通常是 宏的形态.
- * @param label
- * 程序将要跳转到的错误处理代码的标号,
- * 通常就是 'EXIT'.
- * @param args...
- * 对应 'msg_fmt' 实参中,
- * '%s', '%d', ... 等转换说明符的具体可变长实参.
- */
-#define SET_ERROR_AND_JUMP(msg_fmt, ret_var, err_code, label, args...) \
-do { \
- E("To set '" #ret_var "' to %d('" #err_code "'), because : " msg_fmt, \
- (err_code), \
- ## args); \
- (ret_var) = (err_code); \
- goto label; \
-} while (0)
-
-
-/* -----------------------------------------------------------------------------
- * Types and Structures Definition
- * -----------------------------------------------------------------------------
- */
-
-
-/* -----------------------------------------------------------------------------
- * Global Functions' Prototype
- * -----------------------------------------------------------------------------
- */
-
-
-/* -----------------------------------------------------------------------------
- * Inline Functions Implementation
- * -----------------------------------------------------------------------------
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CUSTOM_LOG_H__ */
+++ /dev/null
-/**
- * Rockchip SoC Mali-450 DVFS driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software FoundatIon.
- */
-
-
-/* #define ENABLE_DEBUG_LOG */
-#include "custom_log.h"
-
-#include "mali_platform.h"
-#include "mali_dvfs.h"
-
-/*---------------------------------------------------------------------------*/
-
-/**
- * 若 count_of_continuous_requests_to_jump_up_in_dvfs_level_table 达到 value,
- * 将触发一次 current_dvfs_level jump_up.
- */
-#define NUM_OF_CONTINUOUS_REQUESTS_TO_TRIGGER_REAL_JUMPING_UP (1)
-/**
- * 若 count_of_continuous_requests_to_jump_down_in_dvfs_level_table 达到 value,
- * 将触发一次 current_dvfs_level jump_down.
- */
-#define NUM_OF_CONTINUOUS_REQUESTS_TO_TRIGGER_REAL_JUMPING_DOWN (30)
-
-#define level0_min 0
-#define level0_max 70
-#define levelf_max 100
-
-#define mali_dividend 7
-#define mali_fix_float(a) \
- ((((a) * mali_dividend) % 10) \
- ? ((((a) * mali_dividend) / 10) + 1) \
- : (((a) * mali_dividend) / 10))
-
-#define work_to_dvfs(w) container_of(w, struct mali_dvfs, work)
-#define dvfs_to_drv_data(dvfs) \
- container_of(dvfs, struct mali_platform_drv_data, dvfs)
-
-/*---------------------------------------------------------------------------*/
-#if 0
-static bool mali_dvfs_should_jump_up(const struct mali_dvfs *p_dvfs)
-{
- return (p_dvfs->m_count_of_requests_to_jump_up
- >= NUM_OF_CONTINUOUS_REQUESTS_TO_TRIGGER_REAL_JUMPING_UP);
-}
-
-static bool mali_dvfs_should_jump_down(const struct mali_dvfs *p_dvfs)
-{
- return (p_dvfs->m_count_of_requests_to_jump_down
- >= NUM_OF_CONTINUOUS_REQUESTS_TO_TRIGGER_REAL_JUMPING_DOWN);
-}
-#endif
-/**
- * .KP :
- * work_to_handle_mali_utilization_event 的实现主体,
- * 将根据 current_mali_utilization_data, 改变 current_dvfs_level.
- */
- #if 0
-static void mali_dvfs_event_proc(struct work_struct *w)
-{
- struct mali_dvfs *dvfs = work_to_dvfs(w);/* mali_dvfs_context. */
- struct mali_platform_drv_data *drv_data = dvfs_to_drv_data(dvfs);
- unsigned int utilisation = dvfs->utilisation;
- int ret = 0;
- /* index_of_current_dvfs_level. */
- unsigned int level = dvfs->current_level;
- /* current_dvfs_level. */
- const struct mali_fv_info *threshold = &drv_data->fv_info[level];
- /* utilization_in_percentage. */
- utilisation = utilisation * 100 / 256;
-
- V("mali_utilization_in_percentage : %d; index_of_current_level : %d;"
- "min: %d, max : %d",
- utilisation,
- level,
- threshold->min,
- threshold->max);
- V("num_of_requests_to_jump_up : %d; num_of_requests_to_jump_down : %d",
- dvfs->m_count_of_requests_to_jump_up,
- dvfs->m_count_of_requests_to_jump_down);
-
- if (utilisation > threshold->max) {
- dvfs->m_count_of_requests_to_jump_down = 0;
-
- /* 若 current_dvfs_level 还 "有" 上跳的空间, 则... */
- if (level < (drv_data->fv_info_length - 1)) {
- V("to count one request_to_jump_up.");
- dvfs->m_count_of_requests_to_jump_up++;
-
- /* 若足够触发一次 real_jump_up, 则... */
- if (mali_dvfs_should_jump_up(dvfs)) {
- V("to preset real_jump_up.");
- level += 1;
-
- dvfs->m_count_of_requests_to_jump_up = 0;
-
- goto MAKE_DVFS_LEVEL_UPDATE_EFFECTIVE;
- }
- /* 否则, 即还 "不" 足以 real_jump_up, 则... */
- else
- return;
- }
- /* 否则, 即 "没有" 上跳的空间了, 则... */
- else
- return;
- } else if (utilisation < (threshold->min)) {
- dvfs->m_count_of_requests_to_jump_up = 0;
-
- /* 若 current_dvfs_level 还有 下跳的空间, 则... */
- if (level > 0) {
- V("to count one request_to_jump_down.");
- dvfs->m_count_of_requests_to_jump_down++;
-
- /* 若足够触发一次 real_jump_down, 则... */
- if (mali_dvfs_should_jump_down(dvfs)) {
- V("to preset real_jump_down.");
- level -= 1;
-
- dvfs->m_count_of_requests_to_jump_down = 0;
-
- goto MAKE_DVFS_LEVEL_UPDATE_EFFECTIVE;
- } else {
- return;
- }
- }
- /* 否则, 即 "没有" 下跳的空间了, 则... */
- else
- return;
- }
- /* 否则,
- * 即 mali_utilization 在 'min' 和 'max' 之间,
- * 即 current_dvfs_level 合适, 则 ... */
- else {
- dvfs->m_count_of_requests_to_jump_up = 0;
- dvfs->m_count_of_requests_to_jump_down = 0;
- return;
- }
-
- /*
- dev_dbg(drv_data->dev, "Setting dvfs level %u: freq = %lu Hz\n",
- level, drv_data->fv_info[level].freq);
- */
-
-MAKE_DVFS_LEVEL_UPDATE_EFFECTIVE:
- ret = mali_set_level(drv_data->dev, level);
- if (ret) {
- dev_err(drv_data->dev, "set freq error, %d", ret);
- return;
- }
-}
-#endif
-/**
- * 返回 mali_dvfs_facility 当前是否被使能.
- */
-bool mali_dvfs_is_enabled(struct device *dev)
-{
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- struct mali_dvfs *dvfs = &drv_data->dvfs;
-
- return dvfs->enabled;
-}
-
-/**
- * 使能 mali_dvfs_facility.
- */
-void mali_dvfs_enable(struct device *dev)
-{
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- struct mali_dvfs *dvfs = &drv_data->dvfs;
-
- dvfs->enabled = true;
-}
-
-/**
- * 禁用 mali_dvfs_facility.
- */
-void mali_dvfs_disable(struct device *dev)
-{
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- struct mali_dvfs *dvfs = &drv_data->dvfs;
-
- dvfs->enabled = false;
- cancel_work_sync(&dvfs->work);
-
- /* 使用 lowest_dvfs_level. */
- if (0 != mali_set_level(dev, 0))
- W("fail to set current_dvfs_level to index 0.");
-}
-
-/**
- * 返回当前 mali_dvfs_context 中最后记录的 mali_utilization.
- */
-unsigned int mali_dvfs_utilisation(struct device *dev)
-{
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- struct mali_dvfs *dvfs = &drv_data->dvfs;
-
- return dvfs->utilisation;
-}
-
-/**
- * 根据当前的 mali_utilization_event, 对应调整 mali_dvfs_facility.
- * 运行在 context_of_common_part_calling_back_mali_utilization_event 中.
- */
-int mali_dvfs_event(struct device *dev, u32 utilisation)
-{
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- struct mali_dvfs *dvfs = &drv_data->dvfs;
-
- dvfs->utilisation = utilisation;
- V("mali_utilization_in_percentage : %d", utilisation * 100 / 256);
-
-#if 0
- if (dvfs->enabled) {
- /* 将 work_to_handle_mali_utilization_event,
- * 放置到 kernel_global_workqueue, 待执行. */
- schedule_work(&dvfs->work);
- }
-#endif
-
- return MALI_TRUE;
-}
-#if 0
-static void mali_dvfs_threshold(u32 div,
- struct mali_platform_drv_data *drv_data)
-{
- int length = drv_data->fv_info_length;
- u32 pre_level;
- u32 tmp;
- int level;
-
- for (level = 0; level < length; level++) {
- if (level == 0) {
- drv_data->fv_info[level].min = level0_min;
- if (length == 1)
- drv_data->fv_info[level].max = levelf_max;
- else
- drv_data->fv_info[level].max = level0_max;
- } else {
- pre_level = level - 1;
- if (level == length - 1)
- drv_data->fv_info[level].max = levelf_max;
- else
- drv_data->fv_info[level].max
- = drv_data->fv_info[pre_level].max + div;
-
- drv_data->fv_info[level].min
- = drv_data->fv_info[pre_level].max
- * drv_data->fv_info[pre_level].freq
- / drv_data->fv_info[level].freq;
-
- tmp
- = drv_data->fv_info[level].max
- - drv_data->fv_info[level].min;
- drv_data->fv_info[level].min += mali_fix_float(tmp);
- }
-
- dev_info(drv_data->dev, "freq: %lu, min_threshold: %d, max_threshold: %d\n",
- drv_data->fv_info[level].freq,
- drv_data->fv_info[level].min,
- drv_data->fv_info[level].max);
- }
-}
-#endif
-/*---------------------------------------------------------------------------*/
-
-int mali_dvfs_init(struct device *dev)
-{
-#if 0
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- /*mali_dvfs_context. */
- struct mali_dvfs *dvfs = &drv_data->dvfs;
- /* gpu_clk_freq_table. */
- struct cpufreq_frequency_table *freq_table;
- int i = 0;
- int div_dvfs;
- int ret;
-
- freq_table = dvfs_get_freq_volt_table(drv_data->clk);
- if (!freq_table) {
- dev_err(dev, "Can't find dvfs table in dts\n");
- return -1;
- }
-
- /* 确定 len_of_avaialble_dvfs_level_list. */
- while (freq_table[i].frequency != CPUFREQ_TABLE_END) {
- drv_data->fv_info_length++;
- i++;
- }
-
- drv_data->fv_info = devm_kcalloc(dev, drv_data->fv_info_length,
- sizeof(*drv_data->fv_info),
- GFP_KERNEL);
- if (!drv_data->fv_info)
- return -ENOMEM;
-
- for (i = 0; i < drv_data->fv_info_length; i++)
- drv_data->fv_info[i].freq = freq_table[i].frequency * 1000;
-
- if (drv_data->fv_info_length > 1)
- div_dvfs
- = round_up(((levelf_max - level0_max)
- / (drv_data->fv_info_length - 1)),
- 1);
-
- mali_dvfs_threshold(div_dvfs, drv_data);
-
- ret = dvfs_clk_set_rate(drv_data->clk, drv_data->fv_info[0].freq);
- if (ret)
- return ret;
-
- drv_data->dvfs.current_level = 0;
-
- dev_info(dev, "initial freq = %lu\n",
- dvfs_clk_get_rate(drv_data->clk));
-
- INIT_WORK(&dvfs->work, mali_dvfs_event_proc);
- dvfs->enabled = true;
-
- dvfs->m_count_of_requests_to_jump_up = 0;
- dvfs->m_count_of_requests_to_jump_down = 0;
-
-#endif
- return 0;
-}
-
-void mali_dvfs_term(struct device *dev)
-{
-#if 0
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- struct mali_dvfs *dvfs = &drv_data->dvfs;
-
- dvfs->m_count_of_requests_to_jump_up = 0;
- dvfs->m_count_of_requests_to_jump_down = 0;
-
- dvfs->enabled = false;
- cancel_work_sync(&dvfs->work);
-#endif
-}
-
+++ /dev/null
-/*
- * Rockchip SoC Mali-450 DVFS driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software FoundatIon.
- */
-#include <linux/workqueue.h>
-#include <linux/types.h>
-#include <linux/device.h>
-
-#ifndef _MALI_DVFS_H_
-#define _MALI_DVFS_H_
-
-
-/**
- * mali_dvfs_context_t, context of mali_dvfs_facility.
- */
-struct mali_dvfs {
- /**
- * work_to_handle_mali_utilization_event.
- */
- struct work_struct work;
- /**
- * current_mali_utilization.
- */
- unsigned int utilisation;
- /**
- * index_of_current_dvfs_level.
- * current_dvfs_level 在 available_dvfs_level_list 中的 index.
- */
- unsigned int current_level;
-
- /**
- * mali_dvfs_facility 是否被使能.
- */
- bool enabled;
-
- /**
- * count_of_continuous_requests_to_jump_up_in_dvfs_level_table.
- * 对 "连续" 的 requests_to_jump_up_in_dvfs_level_table 计数.
- */
- unsigned int m_count_of_requests_to_jump_up;
-
- /**
- * count_of_continuous_requests_to_jump_down_in_dvfs_level_table.
- * 对 "连续" 的 requests_to_jump_down_in_dvfs_level_table 计数.
- */
- unsigned int m_count_of_requests_to_jump_down;
-};
-
-int mali_dvfs_init(struct device *dev);
-
-void mali_dvfs_term(struct device *dev);
-
-bool mali_dvfs_is_enabled(struct device *dev);
-
-void mali_dvfs_enable(struct device *dev);
-
-void mali_dvfs_disable(struct device *dev);
-
-unsigned int mali_dvfs_utilisation(struct device *dev);
-
-int mali_dvfs_event(struct device *dev, u32 utilisation);
-
-#endif /*_MALI_DVFS_H_*/
+++ /dev/null
-/*
- * This confidential and proprietary software may be used only as
- * authorised by a licensing agreement from ARM Limited
- * (C) COPYRIGHT 2009-2012 ARM Limited
- * ALL RIGHTS RESERVED
- * The entire notice above must be reproduced on all authorised
- * copies and copies may only be made to the extent permitted
- * by a licensing agreement from ARM Limited.
- */
-
-/*
- * @file mali_platform.c
- * Platform specific Mali driver functions
- * for a default platform
- */
-
-/* #define ENABLE_DEBUG_LOG */
-#include "custom_log.h"
-
-#include <linux/workqueue.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/gfp.h>
-#include <linux/fs.h>
-#include <linux/clk.h>
-#include <linux/device.h>
-#include <linux/regulator/driver.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/cpufreq.h>
-#include <linux/of.h>
-
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_platform.h"
-
-u32 mali_group_error;
-
-/*
- * anchor_of_device_of_mali_gpu.
- */
-static struct device *mali_dev;
-
-/*
- * 设置 current_dvfs_level.
- *
- * @param level
- * 待设置为 current 的 dvfs_level 实例,
- * 在 dvfs_level_list 中的 index,
- * 即 index_of_new_current_level.
- *
- * @return
- * 0, 成功.
- * 其他 value, 失败.
- */
-int mali_set_level(struct device *dev, int level)
-{
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- /* gpu_clk_freq_of_new_current_level. */
- unsigned long freq;
- int ret;
- /* index_of_old_current_level. */
- unsigned int current_level;
-
- _mali_osk_mutex_wait(drv_data->clock_set_lock);
-
- current_level = drv_data->dvfs.current_level;
- freq = drv_data->fv_info[level].freq;
-
- if (level == current_level) {
- D("we are already in the target level, to exit.");
- _mali_osk_mutex_signal(drv_data->clock_set_lock);
- return 0;
- }
-
- /* .KP : 调用 dvfs_module 的接口, 将 cpu_clk 设置为 'freq'. */
- ret = dvfs_clk_set_rate(drv_data->clk, freq);
- if (ret) {
- _mali_osk_mutex_signal(drv_data->clock_set_lock);
- return ret;
- }
-
- D("have set gpu_clk to %lu of new_level %d, the old_level is %d.",
- freq,
- level,
- current_level);
- /* update index_of_current_dvfs_level. */
- drv_data->dvfs.current_level = level;
-
- _mali_osk_mutex_signal(drv_data->clock_set_lock);
-
- return 0;
-}
-
-/*
- * 初始化 gpu_dvfs_node 和 gpu_power_domain.
- */
-static int mali_clock_init(struct device *dev)
-{
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- int err;
- unsigned long rate = 200 * 1000 * 1000;
-
- D("to get clk_mali.");
- drv_data->clock = clk_get(drv_data->dev, "clk_mali");
- if (IS_ERR_OR_NULL(drv_data->clock)) {
- err = PTR_ERR(drv_data->clock);
-
- drv_data->clock = NULL;
- E("fail to get clk_mali, err : %d", err);
- return err;
- }
- D("to preare and enable clk_mali.");
- err = clk_prepare_enable(drv_data->clock);
- if (err) {
- E("Failed to prepare and enable clock (%d)\n", err);
- return err;
- }
- I("to set freq_of_clk_gpu to %lu.", rate);
- err = clk_set_rate(drv_data->clock, rate);
- if (err) {
- E("Failed to set clock.");
- return err;
- }
-
- D("success to init clk_mali.");
- return 0;
-}
-
-static void mali_clock_term(struct device *dev)
-{
-}
-
-/*---------------------------------------------------------------------------*/
-
-static ssize_t show_available_frequencies(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- ssize_t ret = 0;
- u32 i;
-
- for (i = 0; i < drv_data->fv_info_length; i++)
- ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%lu\n",
- drv_data->fv_info[i].freq);
-
- return ret;
-}
-
-static ssize_t show_clock(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
-
- return scnprintf(buf,
- PAGE_SIZE,
- "%lu\n",
- dvfs_clk_get_rate(drv_data->clk));
-}
-
-static ssize_t set_clock(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
- unsigned long freq;
- ssize_t ret;
- u32 level;
-
- ret = kstrtoul(buf, 10, &freq);
- if (ret)
- return ret;
-
- for (level = drv_data->fv_info_length - 1; level > 0; level--) {
- unsigned long tmp = drv_data->fv_info[level].freq;
-
- if (tmp <= freq)
- break;
- }
-
- dev_info(dev, "Using fv_info table %d: for %lu Hz\n", level, freq);
-
- ret = mali_set_level(dev, level);
- if (ret)
- return ret;
-
- return count;
-}
-
-static ssize_t show_dvfs_enable(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return scnprintf(buf, PAGE_SIZE, "%u\n", mali_dvfs_is_enabled(dev));
-}
-
-static ssize_t set_dvfs_enable(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
-{
- unsigned long enable;
- ssize_t ret;
-
- ret = kstrtoul(buf, 0, &enable);
- if (ret)
- return ret;
-
- if (enable == 1)
- mali_dvfs_enable(dev);
- else if (enable == 0)
- mali_dvfs_disable(dev);
- else
- return -EINVAL;
-
- return count;
-}
-
-static ssize_t show_utilisation(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return scnprintf(buf, PAGE_SIZE, "%u\n", mali_dvfs_utilisation(dev));
-}
-
-static ssize_t error_count_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return sprintf(buf, "%d\n", mali_group_error);
-}
-
-static DEVICE_ATTR(available_frequencies,
- S_IRUGO,
- show_available_frequencies,
- NULL);
-static DEVICE_ATTR(clock, S_IRUGO | S_IWUSR, show_clock, set_clock);
-static DEVICE_ATTR(dvfs_enable,
- S_IRUGO | S_IWUSR,
- show_dvfs_enable,
- set_dvfs_enable);
-static DEVICE_ATTR(utilisation, S_IRUGO, show_utilisation, NULL);
-static DEVICE_ATTR(error_count, 0644, error_count_show, NULL);
-
-static struct attribute *mali_sysfs_entries[] = {
- &dev_attr_available_frequencies.attr,
- &dev_attr_clock.attr,
- &dev_attr_dvfs_enable.attr,
- &dev_attr_utilisation.attr,
- &dev_attr_error_count.attr,
- NULL,
-};
-
-static const struct attribute_group mali_attr_group = {
- .attrs = mali_sysfs_entries,
-};
-
-/*
- * 创建 sysfs_nodes_of_platform_dependent_part.
- */
-static int mali_create_sysfs(struct device *dev)
-{
- int ret;
-
- ret = sysfs_create_group(&dev->kobj, &mali_attr_group);
- if (ret)
- dev_err(dev, "create sysfs group error, %d\n", ret);
-
- return ret;
-}
-
-static void mali_remove_sysfs(struct device *dev)
-{
- sysfs_remove_group(&dev->kobj, &mali_attr_group);
-}
-
-/*---------------------------------------------------------------------------*/
-
-/*
- * 对 platform_device_of_mali_gpu,
- * 完成仅和 platform_dependent_part 有关的初始化.
- */
-_mali_osk_errcode_t mali_platform_init(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- /* mali_driver_private_data. */
- struct mali_platform_drv_data *mali_drv_data;
- int ret;
-
- mali_drv_data = devm_kzalloc(dev, sizeof(*mali_drv_data), GFP_KERNEL);
- if (!mali_drv_data)
- return _MALI_OSK_ERR_NOMEM;
-
- dev_set_drvdata(dev, mali_drv_data);
-
- mali_drv_data->dev = dev;
-
- mali_dev = dev;
-
- D("to c all mali_clock_init.");
- ret = mali_clock_init(dev);
- if (ret)
- goto err_init;
-
- D("to call mali_dvfs_init.");
- ret = mali_dvfs_init(dev);
- if (ret)
- goto err_init;
-
- D("to call mali_create_sysfs.");
- ret = mali_create_sysfs(dev);
- if (ret)
- goto term_clk;
-
- mali_drv_data->clock_set_lock =
- _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_ORDERED,
- _MALI_OSK_LOCK_ORDER_UTILIZATION);
-
- return 0;
-term_clk:
- mali_clock_term(dev);
-err_init:
- return _MALI_OSK_ERR_FAULT;
-}
-
-_mali_osk_errcode_t mali_platform_deinit(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(dev);
-
- mali_remove_sysfs(dev);
-
- mali_clock_term(dev);
- _mali_osk_mutex_term(drv_data->clock_set_lock);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------------*/
-
-/*
- * 对 gpu_power_domain(mali_power_domain),
- * "上电, 开 clk" / "下电, 关 clk".
- * @param bpower_off
- * true, 下电.
- * false, 对 gpu_power_domain 上电.
- */
- #if 0
-static _mali_osk_errcode_t mali_power_domain_control(bool bpower_off)
-{
- struct mali_platform_drv_data *drv_data = dev_get_drvdata(mali_dev);
-
- /* 若要 上电, 则 ... */
- if (!bpower_off) {
- if (!drv_data->power_state) {
- D("to ENABLE clk to gpu_dvfs_node.");
- dvfs_clk_prepare_enable(drv_data->clk);
-
- if (drv_data->pd) {
- D("to power UP gpu_power_domain.");
- clk_prepare_enable(drv_data->pd);
- }
-
- drv_data->power_state = true;
- }
- } else {
- if (drv_data->power_state) {
- D("to DISABLE clk to gpu_dvfs_node.");
- dvfs_clk_disable_unprepare(drv_data->clk);
-
- if (drv_data->pd) {
- D("to power DOWN gpu_power_domain.");
- clk_disable_unprepare(drv_data->pd);
- }
-
- drv_data->power_state = false;
- }
- }
-
- return 0;
-}
-#endif
-_mali_osk_errcode_t mali_platform_power_mode_change(
- enum mali_power_mode power_mode)
-{
- return 0;
-}
-
-/*---------------------------------------------------------------------------*/
-
-/*
- * 将注册到 common_part 中的, 对 mali_utilization_event 的 handler,
- * 即 common_part 会直接将 mali_utilization_event 通知回调到本函数.
- */
-void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data)
-{
- if (data->utilization_pp > 256)
- return;
-
- /* dev_dbg(mali_dev, "utilization:%d\r\n", data->utilization_pp); */
-
- mali_dvfs_event(mali_dev, data->utilization_pp);
-}
+++ /dev/null
-/*
- * This confidential and proprietary software may be used only as
- * authorised by a licensing agreement from ARM Limited
- * (C) COPYRIGHT 2009-2012 ARM Limited
- * ALL RIGHTS RESERVED
- * The entire notice above must be reproduced on all authorised
- * copies and copies may only be made to the extent permitted
- * by a licensing agreement from ARM Limited.
- */
-
-/**
- * @file mali_platform.h
- * Platform specific Mali driver functions
- */
-
-#ifndef __MALI_PLATFORM_H__
-#define __MALI_PLATFORM_H__
-
-#include "mali_dvfs.h"
-#include "mali_osk.h"
-#include <linux/mali/mali_utgard.h>
-#include <linux/rockchip/dvfs.h>
-#include <linux/cpufreq.h>
-#include <linux/regulator/consumer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief
- * description of power change reasons
- */
-enum mali_power_mode {
- MALI_POWER_MODE_ON, /**< Power Mali on */
- MALI_POWER_MODE_LIGHT_SLEEP, /**< Mali has been idle for a short time, or runtime PM suspend */
- MALI_POWER_MODE_DEEP_SLEEP, /**< Mali has been idle for a long time, or OS suspend */
-};
-
-/**
- * dvfs_level_t, 标识一个 dvfs_level (的具体配置).
- * .DP : dvfs_level.
- */
-struct mali_fv_info {
- /**
- * 当前 dvfs_level 使用的 gpu_clk_freq.
- */
- unsigned long freq;
- /**
- * .DP : min_mali_utilization_in_percentage_in_this_level.
- * 若当前的 mali_utilization_in_percentage
- * 小于 min_mali_utilization_in_percentage_in_this_level,
- * 则触发一次 requests_to_jump_down_in_dvfs_level_table,
- * 当 对 requests_to_jump_down_in_dvfs_level_table 的连续计数
- * (.DP : continuous_count_of_requests_to_jump_down) 达到一定数值,
- * 则 dvfs_facility 会下跳一个 level.
- */
- unsigned int min;
- /**
- * .DP : max_mali_utilization_in_percentage_in_this_level.
- * 若当前的 mali_utilization_in_percentage
- * 大于 max_mali_utilization_in_percentage_in_this_level,
- * 则触发一次 requests_to_jump_up_in_dvfs_level_table,
- * 当 对 requests_to_jump_up_in_dvfs_level_table 的连续计数
- * (.DP : continuous_count_of_requests_to_jump_up) 达到一定数值,
- * 则 dvfs_facility 会上跳一个 level.
- */
- unsigned int max;
-};
-
-/**
- * mali_driver_private_data_t.
- * 和 平台相关的 mali_driver 的私有数据,
- * 包含 clk, power_domain handles, mali_dvfs_facility 等.
- *
- * 该类型在 platform_dependent_part 中定义,
- * 显然也只会在 platform_dependent_part 中使用.
- */
-struct mali_platform_drv_data {
- /**
- * gpu_dvfs_node
- */
- struct dvfs_node *clk;
-
- /**
- * gpu_power_domain.
- */
- struct clk *pd;
-
- /**
- * available_dvfs_level_list.
- * 将用于保存 系统配置支持的所有 dvfs_level.
- * .R : 实际上, 放在 mali_dvfs_context 中为宜.
- */
- struct mali_fv_info *fv_info;
- /**
- * len_of_available_dvfs_level_list, 也即 根据系统配置得到的 available_dvfs_level 的个数.
- */
- unsigned int fv_info_length;
-
- /**
- * mali_dvfs_context.
- */
- struct mali_dvfs dvfs;
-
- /**
- * device_of_mali_gpu.
- */
- struct device *dev;
-
- /**
- * gpu 是否 "被上电, 且被送入 clk".
- */
- bool power_state;
-
- _mali_osk_mutex_t *clock_set_lock;
-
- /*-------------------------------------------------------*/
-
- /**
- * clk_mali.
- */
- struct clk *clock;
-
- struct regulator *regulator;
-};
-
-/** @brief Platform specific setup and initialisation of MALI
- *
- * This is called from the entrypoint of the driver to initialize the platform
- *
- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_platform_init(struct platform_device *pdev);
-
-/** @brief Platform specific deinitialisation of MALI
- *
- * This is called on the exit of the driver to terminate the platform
- *
- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_platform_deinit(struct platform_device *pdev);
-
-/** @brief Platform specific powerdown sequence of MALI
- *
- * Notification from the Mali device driver stating the new desired power mode.
- * MALI_POWER_MODE_ON must be obeyed, while the other modes are optional.
- * @param power_mode defines the power modes
- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_platform_power_mode_change(
- enum mali_power_mode power_mode);
-
-
-/**
- * @brief
- * Platform specific handling
- * of GPU utilization data
- *
- * When GPU utilization data is enabled,
- * this function
- * will be periodically called.
- *
- * @param utilization
- * The workload utilization
- * of the Mali GPU.
- * 0 = no utilization,
- * 256 = full utilization.
- */
-void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data);
-
-int mali_set_level(struct device *dev, int level);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
+++ /dev/null
-/*
- * This confidential and proprietary software may be used only as
- * authorised by a licensing agreement from ARM Limited
- * (C) COPYRIGHT 2009-2010, 2012 ARM Limited
- * ALL RIGHTS RESERVED
- * The entire notice above must be reproduced on all authorised
- * copies and copies may only be made to the extent permitted
- * by a licensing agreement from ARM Limited.
- */
-
-
-/**
- * @file rk3066.c
- * 实现 rk30_platform 中的 platform_specific_strategy_callbacks,
- * 实际上也是 platform_dependent_part 的顶层.
- *
- * mali_device_driver(mdd) 包含两部分 :
- * .DP : platform_dependent_part :
- * 依赖 platform 部分,
- * 源码在 <mdd_src_dir>/mali/platform/<platform_name> 目录下.
- * .DP : common_parts : ARM 实现的通用的部分.
- */
-
-#define ENABLE_DEBUG_LOG
-#include "custom_log.h"
-
-#include <linux/platform_device.h>
-#include <linux/version.h>
-#include <linux/pm.h>
-#include <linux/of.h>
-#ifdef CONFIG_PM_RUNTIME
-#include <linux/pm_runtime.h>
-#endif
-#include <linux/workqueue.h>
-#include <linux/dma-mapping.h>
-#include <linux/pm_runtime.h>
-#include <linux/rockchip/cpu.h>
-
-#include <linux/mali/mali_utgard.h>
-#include "mali_kernel_common.h"
-#include "mali_platform.h"
-
-#ifdef CONFIG_PM_RUNTIME
-static int mali_runtime_suspend(struct device *device)
-{
- int ret = 0;
-
- MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
-
- if (NULL != device->driver &&
- NULL != device->driver->pm &&
- NULL != device->driver->pm->runtime_suspend) {
- /* Need to notify Mali driver about this event */
- ret = device->driver->pm->runtime_suspend(device);
- }
-
- mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
-
- return ret;
-}
-
-static int mali_runtime_resume(struct device *device)
-{
- int ret = 0;
-
- MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
-
- mali_platform_power_mode_change(MALI_POWER_MODE_ON);
-
- if (NULL != device->driver &&
- NULL != device->driver->pm &&
- NULL != device->driver->pm->runtime_resume) {
- /* Need to notify Mali driver about this event */
- ret = device->driver->pm->runtime_resume(device);
- }
-
- return ret;
-}
-
-static int mali_runtime_idle(struct device *device)
-{
- int ret = 0;
-
- MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
-
- if (NULL != device->driver &&
- NULL != device->driver->pm &&
- NULL != device->driver->pm->runtime_idle) {
- /* Need to notify Mali driver about this event */
- ret = device->driver->pm->runtime_idle(device);
- if (0 != ret)
- return ret;
- }
-
- pm_runtime_suspend(device);
-
- return 0;
-}
-#endif
-
-static int mali_os_suspend(struct device *device)
-{
- int ret = 0;
-
- MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
-
- if (NULL != device->driver &&
- NULL != device->driver->pm &&
- NULL != device->driver->pm->suspend) {
- /* Need to notify Mali driver about this event */
- ret = device->driver->pm->suspend(device);
- }
-
- mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
-
- return ret;
-}
-
-static int mali_os_resume(struct device *device)
-{
- int ret = 0;
-
- MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n"));
-
- mali_platform_power_mode_change(MALI_POWER_MODE_ON);
-
- if (NULL != device->driver &&
- NULL != device->driver->pm &&
- NULL != device->driver->pm->resume) {
- /* Need to notify Mali driver about this event */
- ret = device->driver->pm->resume(device);
- }
-
- return ret;
-}
-
-static int mali_os_freeze(struct device *device)
-{
- int ret = 0;
-
- MALI_DEBUG_PRINT(4, ("mali_os_freeze() called\n"));
-
- if (NULL != device->driver &&
- NULL != device->driver->pm &&
- NULL != device->driver->pm->freeze) {
- /* Need to notify Mali driver about this event */
- ret = device->driver->pm->freeze(device);
- }
-
- return ret;
-}
-
-static int mali_os_thaw(struct device *device)
-{
- int ret = 0;
-
- MALI_DEBUG_PRINT(4, ("mali_os_thaw() called\n"));
-
- if (NULL != device->driver &&
- NULL != device->driver->pm &&
- NULL != device->driver->pm->thaw) {
- /* Need to notify Mali driver about this event */
- ret = device->driver->pm->thaw(device);
- }
-
- return ret;
-}
-
-static const struct dev_pm_ops mali_gpu_device_type_pm_ops = {
- .suspend = mali_os_suspend,
- .resume = mali_os_resume,
- .freeze = mali_os_freeze,
- .thaw = mali_os_thaw,
-#ifdef CONFIG_PM_RUNTIME
- .runtime_suspend = mali_runtime_suspend,
- .runtime_resume = mali_runtime_resume,
- .runtime_idle = mali_runtime_idle,
-#endif
-};
-
-static const struct device_type mali_gpu_device_device_type = {
- .pm = &mali_gpu_device_type_pm_ops,
-};
-
-/**
- * platform_specific_data_of_platform_device_of_mali_gpu.
- *
- * 类型 'struct mali_gpu_device_data' 由 common_part 定义,
- * 实例也将被 common_part 引用,
- * 比如通知 mali_utilization_event 等.
- */
-static const struct mali_gpu_device_data mali_gpu_data = {
- .shared_mem_size = 1024 * 1024 * 1024, /* 1GB */
- .fb_start = 0x40000000,
- .fb_size = 0xb1000000,
- .max_job_runtime = 100, /* 100 ms */
- /* .utilization_interval = 0, */ /* 0ms */
- .utilization_callback = mali_gpu_utilization_handler,
-};
-
-static void mali_platform_device_add_config(struct platform_device *pdev)
-{
- pdev->name = MALI_GPU_NAME_UTGARD,
- pdev->id = 0;
- pdev->dev.type = &mali_gpu_device_device_type;
- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask,
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-}
-
-/*---------------------------------------------------------------------------*/
-
-/**
- * 将被 common_part 回调的, 对 platform_device_of_mali_gpu 初始化的策略回调实现.
- *
- * .DP : platform_specific_strategy_callbacks_called_by_common_part,
- * platform_specific_strategy_callbacks :
- * 被 common_part 调用的 平台相关的策略回调.
- */
-int mali_platform_device_init(struct platform_device *pdev)
-{
- int err = 0;
-
- D("to add data to platform_device..");
- /* 将 platform_specific_data 添加到 platform_device_of_mali_gpu.
- * 这里的 platform_specific_data 的类型由 common_part 定义. */
- err = platform_device_add_data(pdev, &mali_gpu_data,
- sizeof(mali_gpu_data));
- if (err == 0) {
- D("to init internal_platform_specific_code.");
- /* .KP : 初始化 platform_device_of_mali_gpu 中,
- * 仅和 platform_dependent_part 相关的部分. */
- err = mali_platform_init(pdev);
- if (err == 0) {
-#ifdef CONFIG_PM_RUNTIME
- pm_runtime_set_autosuspend_delay(&(pdev->dev), 1000);
- pm_runtime_use_autosuspend(&(pdev->dev));
- pm_runtime_enable(&(pdev->dev));
-#endif
- return 0;
- }
- }
-
- return err;
-}
-
-/**
- * 将被 common_part 回调的, 对 platform_device_of_mali_gpu 终止化的策略回调实现.
- */
-void mali_platform_device_deinit(struct platform_device *pdev)
-{
- MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
-
- mali_platform_deinit(pdev);
-}
+++ /dev/null
-/* ----------------------------------------------------------------------------
- * File: rk_ext.h
- *
- * Desc: rk_ext_on_mali_ko 中的 通行定义等.
- *
- * Usage:
- *
- * Note:
- *
- * Author: ChenZhen
- *
- * Log:
- *
- * ----------------------------------------------------------------------------
- */
-
-#ifndef __RK_EXT_H__
-#define __RK_EXT_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*---------------------------------------------------------------------------*/
-
-/** version of rk_ext on mali_ko, aka. rk_ko_ver. */
-#define RK_KO_VER (5)
-
-/*---------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __RK_EXT_H__ */
-