From 74bcc029c6ab942f252477a74102877f7d093388 Mon Sep 17 00:00:00 2001 From: mcampbellsmith Date: Wed, 20 Nov 2013 22:34:44 +1100 Subject: mali: bulk import of r3p2-01rel3 drivers from i9300-update12 Courtesy of a similar commit from OMNI ROM. Requires updated mali blobs Change-Id: I9ee55b653b57b7c390f8e0e8cd4fc068f1c751c3 --- .../r3p2/mali/platform/pegasus-m400/exynos4.c | 405 +++++++++++++++++++++ 1 file changed, 405 insertions(+) create mode 100644 drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c (limited to 'drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c') diff --git a/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c new file mode 100644 index 0000000..bf83249 --- /dev/null +++ b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c @@ -0,0 +1,405 @@ +/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4.c + * + * Copyright 2011 by S.LSI. Samsung Electronics Inc. + * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea + * + * Samsung SoC Mali400 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. + */ + +/** + * @file exynos4.c + * Platform specific Mali driver functions for the exynos 4XXX based platforms + */ +#include +#include +#include +#include + +#ifdef CONFIG_PM_RUNTIME +#include +#endif + +#ifdef CONFIG_MALI_DVFS +#include "mali_kernel_utilization.h" +#endif /* CONFIG_MALI_DVFS */ + +#include +#include "mali_kernel_common.h" +#include "mali_kernel_linux.h" +#include "mali_pm.h" + +#include + +#include "exynos4_pmm.h" + +#if defined(CONFIG_PM_RUNTIME) +/* We does not need PM NOTIFIER in r3p2 DDK */ +//#define USE_PM_NOTIFIER +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) +struct exynos_pm_domain; +extern struct exynos_pm_domain exynos4_pd_g3d; +void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, struct exynos_pm_domain *pd); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) +extern struct platform_device exynos4_device_pd[]; +#else +extern struct platform_device s5pv310_device_pd[]; +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */ + +static void mali_platform_device_release(struct device *device); + +#if defined(CONFIG_PM_RUNTIME) +#if defined(USE_PM_NOTIFIER) +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); + +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 +#endif + +#if defined(CONFIG_ARCH_S5PV310) && !defined(CONFIG_BOARD_HKDKC210) + +/* This is for other SMDK boards */ +#define MALI_BASE_IRQ 232 + +#else + +/* This is for the Odroid boards */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +#define MALI_BASE_IRQ 182 +#else +#define MALI_BASE_IRQ 150 +#endif + +#endif + +#define MALI_GP_IRQ MALI_BASE_IRQ + 9 +#define MALI_PP0_IRQ MALI_BASE_IRQ + 5 +#define MALI_PP1_IRQ MALI_BASE_IRQ + 6 +#define MALI_PP2_IRQ MALI_BASE_IRQ + 7 +#define MALI_PP3_IRQ MALI_BASE_IRQ + 8 +#define MALI_GP_MMU_IRQ MALI_BASE_IRQ + 4 +#define MALI_PP0_MMU_IRQ MALI_BASE_IRQ + 0 +#define MALI_PP1_MMU_IRQ MALI_BASE_IRQ + 1 +#define MALI_PP2_MMU_IRQ MALI_BASE_IRQ + 2 +#define MALI_PP3_MMU_IRQ MALI_BASE_IRQ + 3 + +static struct resource mali_gpu_resources[] = +{ + MALI_GPU_RESOURCES_MALI400_MP4(0x13000000, + MALI_GP_IRQ, MALI_GP_MMU_IRQ, + MALI_PP0_IRQ, MALI_PP0_MMU_IRQ, + MALI_PP1_IRQ, MALI_PP1_MMU_IRQ, + MALI_PP2_IRQ, MALI_PP2_MMU_IRQ, + MALI_PP3_IRQ, MALI_PP3_MMU_IRQ) +}; + +#ifdef CONFIG_PM_RUNTIME +#if defined(USE_PM_NOTIFIER) +static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy); + +static struct notifier_block mali_pwr_notif_block = { + .notifier_call = mali_pwr_suspend_notifier +}; +#endif +#endif /* CONFIG_PM_RUNTIME */ + +#if 0 +static struct dev_pm_ops mali_gpu_device_type_pm_ops = +{ +#ifndef CONFIG_PM_RUNTIME + .suspend = mali_os_suspend, + .resume = mali_os_resume, +#endif + .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 +}; +#endif + +#if defined(USE_PM_NOTIFIER) +static struct device_type mali_gpu_device_device_type = +{ + .pm = &mali_gpu_device_type_pm_ops, +}; +#endif + +static struct platform_device mali_gpu_device = +{ + .name = "mali_dev", /* MALI_SEC MALI_GPU_NAME_UTGARD, */ + .id = 0, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) + /* Set in mali_platform_device_register() for these kernels */ +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) + .dev.parent = &exynos4_device_pd[PD_G3D].dev, +#else + .dev.parent = &s5pv310_device_pd[PD_G3D].dev, +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */ + .dev.release = mali_platform_device_release, +#if 0 + /* + * We temporarily make use of a device type so that we can control the Mali power + * from within the mali.ko (since the default platform bus implementation will not do that). + * Ideally .dev.pm_domain should be used instead, as this is the new framework designed + * to control the power of devices. + */ + .dev.type = &mali_gpu_device_device_type, /* We should probably use the pm_domain instead of type on newer kernels */ +#endif +}; + +static struct mali_gpu_device_data mali_gpu_data = +{ + .shared_mem_size = 256 * 1024 * 1024, /* 256MB */ + .fb_start = 0x40000000, + .fb_size = 0xb1000000, + .utilization_interval = 100, /* 100ms */ + .utilization_callback = mali_gpu_utilization_handler, +}; + +int mali_platform_device_register(void) +{ + int err; + + MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n")); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) + exynos_pm_add_dev_to_genpd(&mali_gpu_device, &exynos4_pd_g3d); +#endif + + /* Connect resources to the device */ + err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0])); + if (0 == err) + { + err = platform_device_add_data(&mali_gpu_device, &mali_gpu_data, sizeof(mali_gpu_data)); + if (0 == err) + { +#ifdef CONFIG_PM_RUNTIME +#if defined(USE_PM_NOTIFIER) + err = register_pm_notifier(&mali_pwr_notif_block); + if (err) + { + goto plat_init_err; + } +#endif +#endif /* CONFIG_PM_RUNTIME */ + + /* Register the platform device */ + err = platform_device_register(&mali_gpu_device); + if (0 == err) + { + mali_platform_init(&(mali_gpu_device.dev)); + +#ifdef CONFIG_PM_RUNTIME +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000); + pm_runtime_use_autosuspend(&(mali_gpu_device.dev)); +#endif + pm_runtime_enable(&(mali_gpu_device.dev)); +#endif + + return 0; + } + } + +#ifdef CONFIG_PM_RUNTIME +#if defined(USE_PM_NOTIFIER) +plat_init_err: + unregister_pm_notifier(&mali_pwr_notif_block); +#endif +#endif /* CONFIG_PM_RUNTIME */ + platform_device_unregister(&mali_gpu_device); + } + + return err; +} + +void mali_platform_device_unregister(void) +{ + MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n")); + +#ifdef CONFIG_PM_RUNTIME +#if defined(USE_PM_NOTIFIER) + unregister_pm_notifier(&mali_pwr_notif_block); +#endif +#endif /* CONFIG_PM_RUNTIME */ + + mali_platform_deinit(&(mali_gpu_device.dev)); + + platform_device_unregister(&mali_gpu_device); +} + +static void mali_platform_device_release(struct device *device) +{ + MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n")); +} + +#ifdef CONFIG_PM_RUNTIME +#if defined(USE_PM_NOTIFIER) +static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy) +{ + int err = 0; + switch (event) + { + case PM_SUSPEND_PREPARE: + mali_pm_os_suspend(); + err = mali_os_suspend(&(mali_platform_device->dev)); + break; + + case PM_POST_SUSPEND: + err = mali_os_resume(&(mali_platform_device->dev)); + mali_pm_os_resume(); + break; + default: + break; + } + return err; +} + +static int mali_os_suspend(struct device *device) +{ + int ret = 0; + MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n")); + +#ifdef CONFIG_MALI_DVFS + mali_utilization_suspend(); +#endif + + if (NULL != device && + 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(device, 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")); +#ifdef CONFIG_REGULATOR + mali_regulator_enable(); + g3d_power_domain_control(1); +#endif + mali_platform_power_mode_change(device, MALI_POWER_MODE_ON); + + if (NULL != device && + 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 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(device, 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(device, 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) +{ + MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n")); + if (NULL != device->driver && + NULL != device->driver->pm && + NULL != device->driver->pm->runtime_idle) + { + int ret = 0; + /* Need to notify Mali driver about this event */ + ret = device->driver->pm->runtime_idle(device); + if (0 != ret) + { + return ret; + } + } + + return 1; +} + +#endif /* USE_PM_NOTIFIER */ +#endif /* CONFIG_PM_RUNTIME */ -- cgit v1.1