* by a licensing agreement from ARM Limited.
*/
-/*author by xxm 2012-12-1*/
+
+/**
+ * @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"
-#include <linux/workqueue.h>
-#include <linux/dma-mapping.h>
-static int num_cores_total;
-static int num_cores_enabled;
-static void mali_platform_device_release(struct device *device);
-static int mali_os_suspend(struct device *device);
-static int mali_os_resume(struct device *device);
-static int mali_os_freeze(struct device *device);
-static int mali_os_thaw(struct device *device);
#ifdef CONFIG_PM_RUNTIME
-static int mali_runtime_suspend(struct device *device);
-static int mali_runtime_resume(struct device *device);
-static int mali_runtime_idle(struct device *device);
-#endif
+static int mali_runtime_suspend(struct device *device)
+{
+ int ret = 0;
-/*#include "arm_core_scaling.h"*/
-void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data);
+ MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
-static struct work_struct wq_work;
+ 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);
+ }
-static 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
-};
+ mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
+
+ return ret;
+}
-static struct device_type mali_gpu_device_device_type =
+static int mali_runtime_resume(struct device *device)
{
- .pm = &mali_gpu_device_type_pm_ops,
-};
+ int ret = 0;
-static u64 dma_dmamask = DMA_BIT_MASK(32);
+ MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
-static struct mali_gpu_device_data mali_gpu_data =
-{
- .shared_mem_size = 1024* 1024 * 1024, /* 1GB */
- .fb_start = 0x40000000,
- .fb_size = 0xb1000000,
- .utilization_interval = 0, /* 0ms */
- .utilization_callback = mali_gpu_utilization_handler,
-};
-static void mali_platform_device_add_config(struct platform_device *pdev)
-{
- pdev->dev.id = 0;
- pdev->dev.release = mali_platform_device_release;
- pdev->dev.type = &mali_gpu_device_device_type;
- pdev->dev.dma_mask = &dma_dmamask;
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-}
-static void set_num_cores(struct work_struct *work)
-{
- int err = mali_perf_set_num_pp_cores(num_cores_enabled);
- MALI_DEBUG_ASSERT(0 == err);
- MALI_IGNORE(err);
-}
-static void enable_one_core(void)
-{
- if (num_cores_enabled < num_cores_total)
- {
- ++num_cores_enabled;
- schedule_work(&wq_work);
- MALI_DEBUG_PRINT(3, ("Core scaling: Enabling one more core\n"));
- }
+ mali_platform_power_mode_change(MALI_POWER_MODE_ON);
- MALI_DEBUG_ASSERT( 1 <= num_cores_enabled);
- MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
-}
-static void disable_one_core(void)
-{
- if (1 < num_cores_enabled)
- {
- --num_cores_enabled;
- schedule_work(&wq_work);
- MALI_DEBUG_PRINT(3, ("Core scaling: Disabling one core\n"));
+ 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);
}
- MALI_DEBUG_ASSERT( 1 <= num_cores_enabled);
- MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
+ return ret;
}
-static void enable_max_num_cores(void)
-{
- if (num_cores_enabled < num_cores_total)
- {
- num_cores_enabled = num_cores_total;
- schedule_work(&wq_work);
- MALI_DEBUG_PRINT(3, ("Core scaling: Enabling maximum number of cores\n"));
- }
- MALI_DEBUG_ASSERT(num_cores_total == num_cores_enabled);
-}
-void mali_core_scaling_init(int num_pp_cores)
+static int mali_runtime_idle(struct device *device)
{
- INIT_WORK(&wq_work, set_num_cores);
+ int ret = 0;
- num_cores_total = num_pp_cores;
- num_cores_enabled = num_pp_cores;
+ MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
- /* NOTE: Mali is not fully initialized at this point. */
-}
-void mali_core_scaling_term(void)
-{
- flush_scheduled_work();
-}
-#define PERCENT_OF(percent, max) ((int) ((percent)*(max)/100.0 + 0.5))
-void mali_core_scaling_update(struct mali_gpu_utilization_data *data)
-{
- /*
- * This function implements a very trivial PP core scaling algorithm.
- *
- * It is _NOT_ of production quality.
- * The only intention behind this algorithm is to exercise and test the
- * core scaling functionality of the driver.
- * It is _NOT_ tuned for neither power saving nor performance!
- *
- * Other metrics than PP utilization need to be considered as well
- * in order to make a good core scaling algorithm.
- */
-
- MALI_DEBUG_PRINT(3, ("Utilization: (%3d, %3d, %3d), cores enabled: %d/%d\n", data->utilization_gpu, data->utilization_gp, data->utilization_pp, num_cores_enabled, num_cores_total));
-
- /* NOTE: this function is normally called directly from the utilization callback which is in
- * timer context. */
-
- if ( PERCENT_OF(90, 256) < data->utilization_pp)
- {
- enable_max_num_cores();
- }
- else if (PERCENT_OF(50, 256) < data->utilization_pp)
- {
- enable_one_core();
- }
- else if (PERCENT_OF(40, 256) < data->utilization_pp)
- {
- /* do nothing */
- }
- else if (PERCENT_OF( 0, 256) < data->utilization_pp)
- {
- disable_one_core();
- }
- else
- {
- /* do nothing */
- }
-}
-int mali_platform_device_register(struct platform_device *pdev)
-{
- int err = 0;
- int num_pp_cores = 0;
- MALI_PRINT(("mali_platform_device_register() called\n"));
-
- num_pp_cores = 1;
-
- mali_platform_device_add_config(pdev);
-
- err = platform_device_add_data(pdev, &mali_gpu_data, sizeof(mali_gpu_data));
-
- if (0 == err)
- {
- err = mali_platform_init();
- if(0 == err)
- {
-#ifdef CONFIG_PM_RUNTIME
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
- pm_runtime_set_autosuspend_delay(&(pdev->dev), 1000);
- pm_runtime_use_autosuspend(&(pdev->dev));
-#endif
- pm_runtime_enable(&(pdev->dev));
-#endif
- mali_core_scaling_init(num_pp_cores);
- return 0;
- }
+ 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;
}
- return err;
-}
-void mali_platform_device_unregister(struct platform_device *pdev)
-{
- MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
- mali_platform_deinit();
- mali_core_scaling_term();
-}
+ pm_runtime_suspend(device);
-static void mali_platform_device_release(struct device *device)
-{
- MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
+ return 0;
}
+#endif
+
static int mali_os_suspend(struct device *device)
{
int ret = 0;
- MALI_DEBUG_PRINT(2, ("mali_os_suspend() called\n"));
-
+ MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
+
if (NULL != device->driver &&
NULL != device->driver->pm &&
- NULL != device->driver->pm->suspend)
- {
+ NULL != device->driver->pm->suspend) {
/* Need to notify Mali driver about this event */
ret = device->driver->pm->suspend(device);
}
{
int ret = 0;
- MALI_DEBUG_PRINT(2, ("mali_os_resume() called\n"));
+ 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)
- {
+ NULL != device->driver->pm->resume) {
/* Need to notify Mali driver about this event */
ret = device->driver->pm->resume(device);
}
if (NULL != device->driver &&
NULL != device->driver->pm &&
- NULL != device->driver->pm->freeze)
- {
+ NULL != device->driver->pm->freeze) {
/* Need to notify Mali driver about this event */
ret = device->driver->pm->freeze(device);
}
if (NULL != device->driver &&
NULL != device->driver->pm &&
- NULL != device->driver->pm->thaw)
- {
+ 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
-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);
- }
+ .runtime_suspend = mali_runtime_suspend,
+ .runtime_resume = mali_runtime_resume,
+ .runtime_idle = mali_runtime_idle,
+#endif
+};
- mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
+static const struct device_type mali_gpu_device_device_type = {
+ .pm = &mali_gpu_device_type_pm_ops,
+};
- return ret;
-}
+/**
+ * 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 int mali_runtime_resume(struct device *device)
+static void mali_platform_device_add_config(struct platform_device *pdev)
{
- 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;
+ 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);
}
-static int mali_runtime_idle(struct device *device)
+/*---------------------------------------------------------------------------*/
+
+/**
+ * 将被 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 ret = 0;
- MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
+ int err = 0;
- 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;
+ 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;
}
}
- pm_runtime_suspend(device);
-
- return 0;
+ return err;
}
-#endif
-void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data)
+
+/**
+ * 将被 common_part 回调的, 对 platform_device_of_mali_gpu 终止化的策略回调实现.
+ */
+void mali_platform_device_deinit(struct platform_device *pdev)
{
- mali_core_scaling_update(data);
-}
+ MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
+ mali_platform_deinit(pdev);
+}