/*
 *
 * (C) COPYRIGHT 2015 ARM Limited. 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.
 *
 * A copy of the licence is included with the program, and can also be obtained
 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 *
 */



#include <mali_kbase.h>
#include <mali_kbase_defs.h>
#include <backend/gpu/mali_kbase_device_internal.h>
#include <backend/gpu/mali_kbase_pm_internal.h>
#include <linux/pm_runtime.h>
#include <linux/suspend.h>
#include <linux/delay.h>
#include <linux/io.h>

void *reg_base_hiubus = NULL;
u32  override_value_aml = 0;
static int first = 1;

static void  Mali_pwr_on_with_kdev ( struct kbase_device *kbdev, uint32_t  mask)
{
    uint32_t    part1_done;
    part1_done = 0;
    Mali_WrReg(0x0, 0x0, 0x0000024, 0xffffffff); // clear interrupts

    if ((mask & 0x1) != 0 ) {
        Mali_WrReg(0x0, 0x0, 0x00000190, 0xffffffff);    // Power on all cores
        Mali_WrReg(0x0, 0x0, 0x00000194, 0xffffffff);    // Power on all cores
        Mali_WrReg(0x0, 0x0, 0x000001a0, 0xffffffff);    // Power on all cores
        Mali_WrReg(0x0, 0x0, 0x000001a4, 0xffffffff);    // Power on all cores
    }

    if ( (mask >> 1) != 0 ) {
        Mali_WrReg(0x0, 0x0, 0x00000180, mask >> 1);    // Power on all cores
        Mali_WrReg(0x0, 0x0, 0x00000184, 0x0);    // Power on all cores
    }

    if ( mask != 0 ) {
        udelay(10);
        part1_done = Mali_RdReg(0x0, 0x0, 0x0000020);
        //printk("%s, %d\n", __func__, __LINE__);
        while((part1_done ==0)) { part1_done = Mali_RdReg(0x0, 0x0, 0x00000020); udelay(10); }
        //printk("Mali_pwr_on:gpu_irq : %x\n", part1_done);
        Mali_WrReg(0x0, 0x0, 0x0000024, 0xffffffff); // clear interrupts
    }
}

static void gpu_power_main( struct kbase_device *kbdev) {

    Mali_pwr_on ( 0x7);

    printk("%s, %d\n", __func__, __LINE__);
}

static int pm_callback_power_on(struct kbase_device *kbdev)
{
	int ret;
	struct platform_device *pdev = to_platform_device(kbdev->dev);
	struct resource *reg_res;
	u64 core_ready;
	u64 l2_ready;
	u64 tiler_ready;
	u32 value;

    //printk("20151013, %s, %d\n", __FILE__, __LINE__);
    if (first == 0) goto ret;

    reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
    if (!reg_res) {
        dev_err(kbdev->dev, "Invalid register resource\n");
        ret = -ENOENT;
    }
    //printk("%s, %d\n", __FILE__, __LINE__);
    if (NULL == reg_base_hiubus) 
        reg_base_hiubus = ioremap(reg_res->start, resource_size(reg_res));

    //printk("%s, %d\n", __FILE__, __LINE__);
    if (NULL == reg_base_hiubus) {
        dev_err(kbdev->dev, "Invalid register resource\n");
        ret = -ENOENT;
    }

    //printk("%s, %d\n", __FILE__, __LINE__);

//JOHNT
    // Level reset mail

    // Level reset mail
    //Wr(P_RESET2_MASK, ~(0x1<<14));
    //Wr(P_RESET2_LEVEL, ~(0x1<<14));

    //Wr(P_RESET2_LEVEL, 0xffffffff);
    //Wr(P_RESET0_LEVEL, 0xffffffff);

    value = Rd(RESET0_MASK);
    value = value & (~(0x1<<20));
    //printk("line(%d), value=%x\n", __LINE__, value);
    Wr(RESET0_MASK, value);

    value = Rd(RESET0_LEVEL);
    value = value & (~(0x1<<20));
    //printk("line(%d), value=%x\n", __LINE__, value);
    Wr(RESET0_LEVEL, value);
///////////////
    value = Rd(RESET2_MASK);
    value = value & (~(0x1<<14));
    //printk("line(%d), value=%x\n", __LINE__, value);
    Wr(RESET2_MASK, value);

    value = Rd(RESET2_LEVEL);
    value = value & (~(0x1<<14));
    //printk("line(%d), value=%x\n", __LINE__, value);
    Wr(RESET2_LEVEL, value);

    value = Rd(RESET0_LEVEL);
    value = value | ((0x1<<20));
    //printk("line(%d), value=%x\n", __LINE__, value);
    Wr(RESET0_LEVEL, value);

    value = Rd(RESET2_LEVEL);
    value = value | ((0x1<<14));
    //printk("line(%d), value=%x\n", __LINE__, value);
    Wr(RESET2_LEVEL, value);

    udelay(10); // OR POLL for reset done

    kbase_reg_write(kbdev, GPU_CONTROL_REG(PWR_KEY), 0x2968A819, NULL);
    kbase_reg_write(kbdev, GPU_CONTROL_REG(PWR_OVERRIDE1), 0xfff | (0x20<<16), NULL);

    gpu_power_main(kbdev);
    //printk("set PWR_ORRIDE, reg=%p, reg_start=%llx, reg_size=%zx, reg_mapped=%p\n",
    //        kbdev->reg, kbdev->reg_start, kbdev->reg_size, reg_base_hiubus);
	dev_dbg(kbdev->dev, "pm_callback_power_on %p\n",
			(void *)kbdev->dev->pm_domain);

    first = 0;
    //printk("%s, %d\n", __FILE__, __LINE__);
ret:
	ret = pm_runtime_get_sync(kbdev->dev);
    udelay(100);
#if 1

    core_ready = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_SHADER);
    l2_ready = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_L2);
    tiler_ready = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_TILER);
    //printk("core_ready=%llx, l2_ready=%llx, tiler_ready=%llx\n", core_ready, l2_ready, tiler_ready);
#endif
	dev_dbg(kbdev->dev, "pm_runtime_get returned %d\n", ret);

	return 1;
}

static void pm_callback_power_off(struct kbase_device *kbdev)
{
    //printk("%s, %d\n", __FILE__, __LINE__);
#if 0
    iounmap(reg_base_hiubus);
    reg_base_hiubus = NULL;
#endif
	u64 core_ready  = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_SHADER);
	u64 l2_ready    = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_L2);
	u64 tiler_ready = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_TILER);

	dev_dbg(kbdev->dev, "pm_callback_power_off\n");
	if (core_ready)
		kbase_pm_invoke(kbdev, KBASE_PM_CORE_SHADER, core_ready, ACTION_PWROFF);

	if (l2_ready)
		kbase_pm_invoke(kbdev, KBASE_PM_CORE_L2, l2_ready, ACTION_PWROFF);

	if (tiler_ready)
		kbase_pm_invoke(kbdev, KBASE_PM_CORE_TILER, tiler_ready, ACTION_PWROFF);

	pm_runtime_put_autosuspend(kbdev->dev);
}

int kbase_device_runtime_init(struct kbase_device *kbdev)
{
	dev_dbg(kbdev->dev, "kbase_device_runtime_init\n");
	pm_runtime_enable(kbdev->dev);

	return 0;
}

void kbase_device_runtime_disable(struct kbase_device *kbdev)
{
	dev_dbg(kbdev->dev, "kbase_device_runtime_disable\n");
	pm_runtime_disable(kbdev->dev);
}

static int pm_callback_runtime_on(struct kbase_device *kbdev)
{
	dev_dbg(kbdev->dev, "pm_callback_runtime_on\n");

	return 0;
}

static void pm_callback_runtime_off(struct kbase_device *kbdev)
{
	dev_dbg(kbdev->dev, "pm_callback_runtime_off\n");
}

static void pm_callback_resume(struct kbase_device *kbdev)
{
	int ret = pm_callback_runtime_on(kbdev);

	WARN_ON(ret);
}

static void pm_callback_suspend(struct kbase_device *kbdev)
{
	pm_callback_runtime_off(kbdev);
}

struct kbase_pm_callback_conf pm_callbacks = {
	.power_on_callback = pm_callback_power_on,
	.power_off_callback = pm_callback_power_off,
	.power_suspend_callback = pm_callback_suspend,
	.power_resume_callback = pm_callback_resume,
#ifdef KBASE_PM_RUNTIME
	.power_runtime_init_callback = kbase_device_runtime_init,
	.power_runtime_term_callback = kbase_device_runtime_disable,
	.power_runtime_on_callback = pm_callback_runtime_on,
	.power_runtime_off_callback = pm_callback_runtime_off,
#else				/* KBASE_PM_RUNTIME */
	.power_runtime_init_callback = NULL,
	.power_runtime_term_callback = NULL,
	.power_runtime_on_callback = NULL,
	.power_runtime_off_callback = NULL,
#endif				/* KBASE_PM_RUNTIME */
};


