/*
 * drivers/amlogic/media/frame_provider/decoder/utils/vdec_power_ctrl.c
 *
 * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
 *
 * 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.
 *
 */

#define DEBUG
#include "vdec_power_ctrl.h"
#include <linux/amlogic/media/utils/vdec_reg.h>
#include <linux/amlogic/power_ctrl.h>
//#include <dt-bindings/power/sc2-pd.h>
//#include <linux/amlogic/pwr_ctrl.h>
#include <linux/amlogic/power_domain.h>
#include <dt-bindings/power/sc2-pd.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include "../../../common/media_clock/switch/amports_gate.h"
#include "../../../common/chips/decoder_cpu_ver_info.h"
#include "../../../common/media_clock/clk/clk.h"

#define HEVC_TEST_LIMIT		(100)
#define GXBB_REV_A_MINOR	(0xa)

#define PDID_DSP            0
#define PDID_DOS_HCODEC             1
#define PDID_DOS_HEVC               2
#define PDID_DOS_VDEC               3
#define PDID_DOS_WAVE               4

extern int no_powerdown;
extern int hevc_max_reset_count;

struct pm_name_s {
	int type;
	const char *name;
};

static const struct pm_name_s pm_name[] = {
	{PM_POWER_CTRL_RW_REG,		"legacy"},
	{PM_POWER_CTRL_API,		"power-ctrl-api"},
	{PM_POWER_DOMAIN,		"power-domain"},
	{PM_POWER_DOMAIN_SEC_API,	"pd-sec-api"},
	{PM_POWER_DOMAIN_NONSEC_API,	"pd-non-sec-api"},
};

const char *get_pm_name(int type)
{
	const char *name = "unknown";
	int i, size = ARRAY_SIZE(pm_name);

	for (i = 0; i < size; i++) {
		if (type == pm_name[i].type)
			name = pm_name[i].name;
	}

	return name;
}
EXPORT_SYMBOL(get_pm_name);

static struct pm_pd_s pm_domain_data[] = {
	{ .name = "pwrc-vdec", },
	{ .name = "pwrc-hcodec",},
	{ .name = "pwrc-vdec-2", },
	{ .name = "pwrc-hevc", },
	{ .name = "pwrc-hevc-b", },
	{ .name = "pwrc-wave", },
};

static void pm_vdec_power_switch(struct pm_pd_s *pd, int id, bool on)
{
	struct device *dev = pd[id].dev;

	if (on)
		pm_runtime_get_sync(dev);
	else
		pm_runtime_put_sync(dev);

	pr_debug("the %-15s power %s\n",
		pd[id].name, on ? "on" : "off");
}

static int pm_vdec_power_domain_init(struct device *dev)
{
	int i, err;
	const struct power_manager_s *pm = of_device_get_match_data(dev);
	struct pm_pd_s *pd = pm->pd_data;

	for (i = 0; i < ARRAY_SIZE(pm_domain_data); i++) {
		pd[i].dev = dev_pm_domain_attach_by_name(dev, pd[i].name);
		if (IS_ERR_OR_NULL(pd[i].dev)) {
			err = PTR_ERR(pd[i].dev);
			dev_err(dev, "Get %s failed, pm-domain: %d\n",
				pd[i].name, err);
			continue;
		}

		pd[i].link = device_link_add(dev, pd[i].dev,
					     DL_FLAG_PM_RUNTIME |
					     DL_FLAG_STATELESS);
		if (IS_ERR_OR_NULL(pd[i].link)) {
			dev_err(dev, "Adding %s device link failed!\n",
				pd[i].name);
			return -ENODEV;
		}

		pr_debug("power domain: name: %s, dev: %px, link: %px\n",
			pd[i].name, pd[i].dev, pd[i].link);
	}

	return 0;
}

static void pm_vdec_power_domain_relese(struct device *dev)
{
	int i;
	const struct power_manager_s *pm = of_device_get_match_data(dev);
	struct pm_pd_s *pd = pm->pd_data;

	for (i = 0; i < ARRAY_SIZE(pm_domain_data); i++) {
		if (!IS_ERR_OR_NULL(pd[i].link))
			device_link_del(pd[i].link);

		if (!IS_ERR_OR_NULL(pd[i].dev))
			dev_pm_domain_detach(pd[i].dev, true);
	}
}

static void pm_vdec_clock_on(int id)
{
	if (id == VDEC_1) {
		amports_switch_gate("clk_vdec_mux", 1);
		vdec_clock_hi_enable();
	} else if (id == VDEC_HCODEC) {
		hcodec_clock_enable();
	} else if (id == VDEC_HEVC) {
		/* enable hevc clock */
		if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2 &&
			(get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5) &&
			(get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D))
			amports_switch_gate("clk_hevcf_mux", 1);
		else
			amports_switch_gate("clk_hevc_mux", 1);
		if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
			!is_hevc_front_back_clk_combined())
			amports_switch_gate("clk_hevcb_mux", 1);

		hevc_clock_hi_enable();

		if (!is_hevc_front_back_clk_combined())
			hevc_back_clock_hi_enable();
	}
}

static void pm_vdec_clock_off(int id)
{
	if (id == VDEC_1) {
		vdec_clock_off();
	} else if (id == VDEC_HCODEC) {
		hcodec_clock_off();
	} else if (id == VDEC_HEVC) {
		/* disable hevc clock */
		hevc_clock_off();
		if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
			!is_hevc_front_back_clk_combined())
			hevc_back_clock_off();
	}
}

static void pm_vdec_power_domain_power_on(struct device *dev, int id)
{
	const struct power_manager_s *pm = of_device_get_match_data(dev);

	pm_vdec_clock_on(id);
	pm_vdec_power_switch(pm->pd_data, id, true);
}

static void pm_vdec_power_domain_power_off(struct device *dev, int id)
{
	const struct power_manager_s *pm = of_device_get_match_data(dev);

	pm_vdec_clock_off(id);
	pm_vdec_power_switch(pm->pd_data, id, false);
}

static bool pm_vdec_power_domain_power_state(struct device *dev, int id)
{
	const struct power_manager_s *pm = of_device_get_match_data(dev);

	return pm_runtime_active(pm->pd_data[id].dev);
}

static bool test_hevc(u32 decomp_addr, u32 us_delay)
{
	int i;

	/* SW_RESET IPP */
	WRITE_VREG(HEVCD_IPP_TOP_CNTL, 1);
	WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0);

	/* initialize all canvas table */
	WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0);
	for (i = 0; i < 32; i++)
		WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
			0x1 | (i << 8) | decomp_addr);
	WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 1);
	WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
	for (i = 0; i < 32; i++)
		WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);

	/* Initialize mcrcc */
	WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2);
	WRITE_VREG(HEVCD_MCRCC_CTL2, 0x0);
	WRITE_VREG(HEVCD_MCRCC_CTL3, 0x0);
	WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0);

	/* Decomp initialize */
	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x0);
	WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0x0);

	/* Frame level initialization */
	WRITE_VREG(HEVCD_IPP_TOP_FRMCONFIG, 0x100 | (0x100 << 16));
	WRITE_VREG(HEVCD_IPP_TOP_TILECONFIG3, 0x0);
	WRITE_VREG(HEVCD_IPP_TOP_LCUCONFIG, 0x1 << 5);
	WRITE_VREG(HEVCD_IPP_BITDEPTH_CONFIG, 0x2 | (0x2 << 2));

	WRITE_VREG(HEVCD_IPP_CONFIG, 0x0);
	WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE, 0x0);

	/* Enable SWIMP mode */
	WRITE_VREG(HEVCD_IPP_SWMPREDIF_CONFIG, 0x1);

	/* Enable frame */
	WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0x2);
	WRITE_VREG(HEVCD_IPP_TOP_FRMCTL, 0x1);

	/* Send SW-command CTB info */
	WRITE_VREG(HEVCD_IPP_SWMPREDIF_CTBINFO, 0x1 << 31);

	/* Send PU_command */
	WRITE_VREG(HEVCD_IPP_SWMPREDIF_PUINFO0, (0x4 << 9) | (0x4 << 16));
	WRITE_VREG(HEVCD_IPP_SWMPREDIF_PUINFO1, 0x1 << 3);
	WRITE_VREG(HEVCD_IPP_SWMPREDIF_PUINFO2, 0x0);
	WRITE_VREG(HEVCD_IPP_SWMPREDIF_PUINFO3, 0x0);

	udelay(us_delay);

	WRITE_VREG(HEVCD_IPP_DBG_SEL, 0x2 << 4);

	return (READ_VREG(HEVCD_IPP_DBG_DATA) & 3) == 1;
}

static bool hevc_workaround_needed(void)
{
	return (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_GXBB) &&
		(get_meson_cpu_version(MESON_CPU_VERSION_LVL_MINOR)
			== GXBB_REV_A_MINOR);
}

static void pm_vdec_legacy_power_off(struct device *dev, int id);

static void pm_vdec_legacy_power_on(struct device *dev, int id)
{
	void *decomp_addr = NULL;
	ulong decomp_dma_addr;
	ulong mem_handle;
	u32 decomp_addr_aligned = 0;
	int hevc_loop = 0;
	int sleep_val, iso_val;
	bool is_power_ctrl_ver2 = false;

	is_power_ctrl_ver2 =
		((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
		(get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1)) ? true : false;

	if (hevc_workaround_needed() &&
		(id == VDEC_HEVC)) {
		decomp_addr = codec_mm_dma_alloc_coherent(&mem_handle,
			&decomp_dma_addr, SZ_64K + SZ_4K, "vdec_prealloc");
		if (decomp_addr) {
			decomp_addr_aligned = ALIGN(decomp_dma_addr, SZ_64K);
			memset((u8 *)decomp_addr +
				(decomp_addr_aligned - decomp_dma_addr),
				0xff, SZ_4K);
		} else
			pr_err("vdec: alloc HEVC gxbb decomp buffer failed.\n");
	}

	if (id == VDEC_1) {
		sleep_val = is_power_ctrl_ver2 ? 0x2 : 0xc;
		iso_val = is_power_ctrl_ver2 ? 0x2 : 0xc0;

		/* vdec1 power on */
#ifdef CONFIG_AMLOGIC_POWER
		if (is_support_power_ctrl()) {
			if (power_ctrl_sleep_mask(true, sleep_val, 0)) {
				pr_err("vdec-1 power on ctrl sleep fail.\n");
				return;
			}
		} else {
			WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
				READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & ~sleep_val);
		}
#else
		WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
			READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & ~sleep_val);
#endif
		/* wait 10uS */
		udelay(10);
		/* vdec1 soft reset */
		WRITE_VREG(DOS_SW_RESET0, 0xfffffffc);
		WRITE_VREG(DOS_SW_RESET0, 0);
		/* enable vdec1 clock */
		/*
		 *add power on vdec clock level setting,only for m8 chip,
		 * m8baby and m8m2 can dynamic adjust vdec clock,
		 * power on with default clock level
		 */
		amports_switch_gate("clk_vdec_mux", 1);
		vdec_clock_hi_enable();
		/* power up vdec memories */
		WRITE_VREG(DOS_MEM_PD_VDEC, 0);

		/* remove vdec1 isolation */
#ifdef CONFIG_AMLOGIC_POWER
		if (is_support_power_ctrl()) {
			if (power_ctrl_iso_mask(true, iso_val, 0)) {
				pr_err("vdec-1 power on ctrl iso fail.\n");
				return;
			}
		} else {
			WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
				READ_AOREG(AO_RTI_GEN_PWR_ISO0) & ~iso_val);
		}
#else
		WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
			READ_AOREG(AO_RTI_GEN_PWR_ISO0) & ~iso_val);
#endif
		/* reset DOS top registers */
		WRITE_VREG(DOS_VDEC_MCRCC_STALL_CTRL, 0);
	} else if (id == VDEC_2) {
		if (has_vdec2()) {
			/* vdec2 power on */
			WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
					READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) &
					~0x30);
			/* wait 10uS */
			udelay(10);
			/* vdec2 soft reset */
			WRITE_VREG(DOS_SW_RESET2, 0xffffffff);
			WRITE_VREG(DOS_SW_RESET2, 0);
			/* enable vdec1 clock */
			vdec2_clock_hi_enable();
			/* power up vdec memories */
			WRITE_VREG(DOS_MEM_PD_VDEC2, 0);
			/* remove vdec2 isolation */
			WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
					READ_AOREG(AO_RTI_GEN_PWR_ISO0) &
					~0x300);
			/* reset DOS top registers */
			WRITE_VREG(DOS_VDEC2_MCRCC_STALL_CTRL, 0);
		}
	} else if (id == VDEC_HCODEC) {
		if (has_hdec()) {
			sleep_val = is_power_ctrl_ver2 ? 0x1 : 0x3;
			iso_val = is_power_ctrl_ver2 ? 0x1 : 0x30;

			/* hcodec power on */
#ifdef CONFIG_AMLOGIC_POWER
			if (is_support_power_ctrl()) {
				if (power_ctrl_sleep_mask(true, sleep_val, 0)) {
					pr_err("hcodec power on ctrl sleep fail.\n");
					return;
				}
			} else {
				WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
					READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & ~sleep_val);
			}
#else
			WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
				READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & ~sleep_val);
#endif
			/* wait 10uS */
			udelay(10);
			/* hcodec soft reset */
			WRITE_VREG(DOS_SW_RESET1, 0xffffffff);
			WRITE_VREG(DOS_SW_RESET1, 0);
			/* enable hcodec clock */
			hcodec_clock_enable();
			/* power up hcodec memories */
			WRITE_VREG(DOS_MEM_PD_HCODEC, 0);
			/* remove hcodec isolation */
#ifdef CONFIG_AMLOGIC_POWER
			if (is_support_power_ctrl()) {
				if (power_ctrl_iso_mask(true, iso_val, 0)) {
					pr_err("hcodec power on ctrl iso fail.\n");
					return;
				}
			} else {
				WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
					READ_AOREG(AO_RTI_GEN_PWR_ISO0) & ~iso_val);
			}
#else
			WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
				READ_AOREG(AO_RTI_GEN_PWR_ISO0) & ~iso_val);
#endif
		}
	} else if (id == VDEC_HEVC) {
		if (has_hevc_vdec()) {
			bool hevc_fixed = false;

			sleep_val = is_power_ctrl_ver2 ? 0x4 : 0xc0;
			iso_val = is_power_ctrl_ver2 ? 0x4 : 0xc00;

			while (!hevc_fixed) {
				/* hevc power on */
#ifdef CONFIG_AMLOGIC_POWER
				if (is_support_power_ctrl()) {
					if (power_ctrl_sleep_mask(true, sleep_val, 0)) {
						pr_err("hevc power on ctrl sleep fail.\n");
						return;
					}
				} else {
					WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
						READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & ~sleep_val);
				}
#else
				WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
					READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & ~sleep_val);
#endif
				/* wait 10uS */
				udelay(10);
				/* hevc soft reset */
				WRITE_VREG(DOS_SW_RESET3, 0xffffffff);
				WRITE_VREG(DOS_SW_RESET3, 0);
				/* enable hevc clock */
				amports_switch_gate("clk_hevc_mux", 1);
				if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
					amports_switch_gate("clk_hevcb_mux", 1);
				hevc_clock_hi_enable();
				hevc_back_clock_hi_enable();
				/* power up hevc memories */
				WRITE_VREG(DOS_MEM_PD_HEVC, 0);
				/* remove hevc isolation */
#ifdef CONFIG_AMLOGIC_POWER
				if (is_support_power_ctrl()) {
					if (power_ctrl_iso_mask(true, iso_val, 0)) {
						pr_err("hevc power on ctrl iso fail.\n");
						return;
					}
				} else {
					WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
						READ_AOREG(AO_RTI_GEN_PWR_ISO0) & ~iso_val);
				}
#else
				WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
					READ_AOREG(AO_RTI_GEN_PWR_ISO0) & ~iso_val);
#endif
				if (!hevc_workaround_needed())
					break;

				if (decomp_addr)
					hevc_fixed = test_hevc(
						decomp_addr_aligned, 20);

				if (!hevc_fixed) {
					hevc_loop++;
					if (hevc_loop >= HEVC_TEST_LIMIT) {
						pr_warn("hevc power sequence over limit\n");
						pr_warn("=====================================================\n");
						pr_warn(" This chip is identified to have HW failure.\n");
						pr_warn(" Please contact sqa-platform to replace the platform.\n");
						pr_warn("=====================================================\n");

						panic("Force panic for chip detection !!!\n");

						break;
					}

					pm_vdec_legacy_power_off(NULL, VDEC_HEVC);

					mdelay(10);
				}
			}

			if (hevc_loop > hevc_max_reset_count)
				hevc_max_reset_count = hevc_loop;

			WRITE_VREG(DOS_SW_RESET3, 0xffffffff);
			udelay(10);
			WRITE_VREG(DOS_SW_RESET3, 0);
		}
	}

	if (decomp_addr)
		codec_mm_dma_free_coherent(mem_handle);
}

static void pm_vdec_legacy_power_off(struct device *dev, int id)
{
	int sleep_val, iso_val;
	bool is_power_ctrl_ver2 = false;

	is_power_ctrl_ver2 =
		((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
		(get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1)) ? true : false;

	if (id == VDEC_1) {
		sleep_val = is_power_ctrl_ver2 ? 0x2 : 0xc;
		iso_val = is_power_ctrl_ver2 ? 0x2 : 0xc0;

		/* enable vdec1 isolation */
#ifdef CONFIG_AMLOGIC_POWER
		if (is_support_power_ctrl()) {
			if (power_ctrl_iso_mask(false, iso_val, 0)) {
				pr_err("vdec-1 power off ctrl iso fail.\n");
				return;
			}
		} else {
			WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
				READ_AOREG(AO_RTI_GEN_PWR_ISO0) | iso_val);
		}
#else
		WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
			READ_AOREG(AO_RTI_GEN_PWR_ISO0) | iso_val);
#endif
		/* power off vdec1 memories */
		WRITE_VREG(DOS_MEM_PD_VDEC, 0xffffffffUL);
		/* disable vdec1 clock */
		vdec_clock_off();
		/* vdec1 power off */
#ifdef CONFIG_AMLOGIC_POWER
		if (is_support_power_ctrl()) {
			if (power_ctrl_sleep_mask(false, sleep_val, 0)) {
				pr_err("vdec-1 power off ctrl sleep fail.\n");
				return;
			}
		} else {
			WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
				READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | sleep_val);
		}
#else
		WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
			READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | sleep_val);
#endif
	} else if (id == VDEC_2) {
		if (has_vdec2()) {
			/* enable vdec2 isolation */
			WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
					READ_AOREG(AO_RTI_GEN_PWR_ISO0) |
					0x300);
			/* power off vdec2 memories */
			WRITE_VREG(DOS_MEM_PD_VDEC2, 0xffffffffUL);
			/* disable vdec2 clock */
			vdec2_clock_off();
			/* vdec2 power off */
			WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
					READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) |
					0x30);
		}
	} else if (id == VDEC_HCODEC) {
		if (has_hdec()) {
			sleep_val = is_power_ctrl_ver2 ? 0x1 : 0x3;
			iso_val = is_power_ctrl_ver2 ? 0x1 : 0x30;

			/* enable hcodec isolation */
#ifdef CONFIG_AMLOGIC_POWER
			if (is_support_power_ctrl()) {
				if (power_ctrl_iso_mask(false, iso_val, 0)) {
					pr_err("hcodec power off ctrl iso fail.\n");
					return;
				}
			} else {
				WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
					READ_AOREG(AO_RTI_GEN_PWR_ISO0) | iso_val);
			}
#else
			WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
				READ_AOREG(AO_RTI_GEN_PWR_ISO0) | iso_val);
#endif
			/* power off hcodec memories */
			WRITE_VREG(DOS_MEM_PD_HCODEC, 0xffffffffUL);
			/* disable hcodec clock */
			hcodec_clock_off();
			/* hcodec power off */
#ifdef CONFIG_AMLOGIC_POWER
			if (is_support_power_ctrl()) {
				if (power_ctrl_sleep_mask(false, sleep_val, 0)) {
					pr_err("hcodec power off ctrl sleep fail.\n");
					return;
				}
			} else {
				WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
					READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | sleep_val);
			}
#else
			WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
				READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | sleep_val);
#endif
		}
	} else if (id == VDEC_HEVC) {
		if (has_hevc_vdec()) {
			sleep_val = is_power_ctrl_ver2 ? 0x4 : 0xc0;
			iso_val = is_power_ctrl_ver2 ? 0x4 : 0xc00;

			if (no_powerdown == 0) {
				/* enable hevc isolation */
#ifdef CONFIG_AMLOGIC_POWER
				if (is_support_power_ctrl()) {
					if (power_ctrl_iso_mask(false, iso_val, 0)) {
						pr_err("hevc power off ctrl iso fail.\n");
						return;
					}
				} else {
					WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
						READ_AOREG(AO_RTI_GEN_PWR_ISO0) | iso_val);
				}
#else
				WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
					READ_AOREG(AO_RTI_GEN_PWR_ISO0) | iso_val);
#endif
				/* power off hevc memories */
				WRITE_VREG(DOS_MEM_PD_HEVC, 0xffffffffUL);

				/* disable hevc clock */
				hevc_clock_off();
				if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
					hevc_back_clock_off();

				/* hevc power off */
#ifdef CONFIG_AMLOGIC_POWER
				if (is_support_power_ctrl()) {
					if (power_ctrl_sleep_mask(false, sleep_val, 0)) {
						pr_err("hevc power off ctrl sleep fail.\n");
						return;
					}
				} else {
					WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
						READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | sleep_val);
				}
#else
				WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
					READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | sleep_val);
#endif
			} else {
				pr_info("!!!!!!!!not power down\n");
				hevc_reset_core(NULL);
				no_powerdown = 0;
			}
		}
	}
}

static bool pm_vdec_legacy_power_state(struct device *dev, int id)
{
	bool ret = false;

	if (id == VDEC_1) {
		if (((READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) &
			(((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
			(get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1))
			? 0x2 : 0xc)) == 0) &&
			(READ_HHI_REG(HHI_VDEC_CLK_CNTL) & 0x100))
			ret = true;
	} else if (id == VDEC_2) {
		if (has_vdec2()) {
			if (((READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & 0x30) == 0) &&
				(READ_HHI_REG(HHI_VDEC2_CLK_CNTL) & 0x100))
				ret = true;
		}
	} else if (id == VDEC_HCODEC) {
		if (has_hdec()) {
			if (((READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) &
				(((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
				(get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1))
				? 0x1 : 0x3)) == 0) &&
				(READ_HHI_REG(HHI_VDEC_CLK_CNTL) & 0x1000000))
				ret = true;
		}
	} else if (id == VDEC_HEVC) {
		if (has_hevc_vdec()) {
			if (((READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) &
				(((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
				(get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1))
				? 0x4 : 0xc0)) == 0) &&
				(READ_HHI_REG(HHI_VDEC2_CLK_CNTL) & 0x1000000))
				ret = true;
		}
	}

	return ret;
}

static void pm_vdec_pd_sec_api_power_on(struct device *dev, int id)
{
	int pd_id = (id == VDEC_1) ? PDID_DOS_VDEC :
		    (id == VDEC_HEVC) ? PDID_DOS_HEVC :
		    PDID_DOS_HCODEC;

	pm_vdec_clock_on(id);
	pwr_ctrl_psci_smc(pd_id, PWR_ON);
}

static void pm_vdec_pd_sec_api_power_off(struct device *dev, int id)
{
	int pd_id = (id == VDEC_1) ? PDID_DOS_VDEC :
		    (id == VDEC_HEVC) ? PDID_DOS_HEVC :
		    PDID_DOS_HCODEC;

	pm_vdec_clock_off(id);
	pwr_ctrl_psci_smc(pd_id, PWR_OFF);
}

static bool pm_vdec_pd_sec_api_power_state(struct device *dev, int id)
{
	int pd_id = (id == VDEC_1) ? PDID_DOS_VDEC :
		    (id == VDEC_HEVC) ? PDID_DOS_HEVC :
		    PDID_DOS_HCODEC;

	return !pwr_ctrl_status_psci_smc(pd_id);
}

static void pm_vdec_pd_nosec_api_power_on(struct device *dev, int id)
{
#if 0
	int pd_id = (id == VDEC_1) ? PM_DOS_VDEC :
		    (id == VDEC_HEVC) ? PM_DOS_HEVC :
			PM_DOS_HCODEC;

	pm_vdec_clock_on(id);
	power_domain_switch(pd_id, PWR_ON);
#endif
}

static void pm_vdec_pd_nosec_api_power_off(struct device *dev, int id)
{
#if 0
	int pd_id = (id == VDEC_1) ? PM_DOS_VDEC :
		    (id == VDEC_HEVC) ? PM_DOS_HEVC :
		    PM_DOS_HCODEC;

	pm_vdec_clock_off(id);
	power_domain_switch(pd_id, PWR_OFF);
#endif
}

static bool pm_vdec_pd_nosec_api_power_state(struct device *dev, int id)
{
	return pm_vdec_legacy_power_state(dev, id);
}

static const struct power_manager_s pm_rw_reg_data = {
	.pm_type	= PM_POWER_CTRL_RW_REG,
	.power_on	= pm_vdec_legacy_power_on,
	.power_off	= pm_vdec_legacy_power_off,
	.power_state	= pm_vdec_legacy_power_state,
};

static const struct power_manager_s pm_ctrl_api_data = {
	.pm_type	= PM_POWER_CTRL_API,
	.power_on	= pm_vdec_legacy_power_on,
	.power_off	= pm_vdec_legacy_power_off,
	.power_state	= pm_vdec_legacy_power_state,
};

static const struct power_manager_s pm_pd_data = {
	.pm_type	= PM_POWER_DOMAIN,
	.pd_data	= pm_domain_data,
	.init		= pm_vdec_power_domain_init,
	.release	= pm_vdec_power_domain_relese,
	.power_on	= pm_vdec_power_domain_power_on,
	.power_off	= pm_vdec_power_domain_power_off,
	.power_state	= pm_vdec_power_domain_power_state,
};

static const struct power_manager_s pm_pd_sec_api_data = {
	.pm_type	= PM_POWER_DOMAIN_SEC_API,
	.power_on	= pm_vdec_pd_sec_api_power_on,
	.power_off	= pm_vdec_pd_sec_api_power_off,
	.power_state	= pm_vdec_pd_sec_api_power_state,
};

static const struct power_manager_s pm_pd_nosec_api_data = {
	.pm_type	= PM_POWER_DOMAIN_NONSEC_API,
	.power_on	= pm_vdec_pd_nosec_api_power_on,
	.power_off	= pm_vdec_pd_nosec_api_power_off,
	.power_state	= pm_vdec_pd_nosec_api_power_state,
};

const struct of_device_id amlogic_vdec_matches[] = {
	{ .compatible = "amlogic, vdec",		.data = &pm_rw_reg_data },
	{ .compatible = "amlogic, vdec-pm-api",		.data = &pm_ctrl_api_data },
	{ .compatible = "amlogic, vdec-pm-pd",		.data = &pm_pd_data },
	{ .compatible = "amlogic, vdec-pm-pd-sec-api",	.data = &pm_pd_sec_api_data },
	{ .compatible = "amlogic, vdec-pm-pd-nsec-api",	.data = &pm_pd_nosec_api_data },
	{},
};
EXPORT_SYMBOL(amlogic_vdec_matches);

