-rw-r--r-- | drivers/frame_provider/decoder/utils/Makefile | 1 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/utils/vdec.c | 689 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/utils/vdec_power_ctrl.c | 801 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/utils/vdec_power_ctrl.h | 107 | ||||
-rw-r--r-- | drivers/stream_input/amports/amstream.c | 1 |
5 files changed, 935 insertions, 664 deletions
diff --git a/drivers/frame_provider/decoder/utils/vdec.c b/drivers/frame_provider/decoder/utils/vdec.c index a8a4b74..e219e44 100644 --- a/drivers/frame_provider/decoder/utils/vdec.c +++ b/drivers/frame_provider/decoder/utils/vdec.c @@ -83,12 +83,10 @@ #ifdef CONFIG_AMLOGIC_IONVIDEO #include <linux/amlogic/media/video_sink/ionvideo_ext.h> #endif -#include <linux/pm.h> -#include <linux/pm_domain.h> -#include <linux/pm_runtime.h> - -/* wait other module to support this function */ -#define is_support_power_ctrl() 0 +//#include <dt-bindings/power/sc2-pd.h> +#include <linux/amlogic/pwr_ctrl.h> +#include <linux/of_device.h> +#include "vdec_power_ctrl.h" static DEFINE_MUTEX(vdec_mutex); @@ -109,9 +107,11 @@ static unsigned int clk_config; */ static unsigned int debug; -static int hevc_max_reset_count; +int hevc_max_reset_count; +EXPORT_SYMBOL(hevc_max_reset_count); -static int no_powerdown; +int no_powerdown; +EXPORT_SYMBOL(no_powerdown); static int parallel_decode = 1; static int fps_detection; static int fps_clear; @@ -136,8 +136,6 @@ static int enable_mvdec_info = 1; int decode_underflow = 0; -static bool disable_power_domain; - #define CANVAS_MAX_SIZE (AMVDEC_CANVAS_MAX1 - AMVDEC_CANVAS_START_INDEX + 1 + AMVDEC_CANVAS_MAX2 + 1) struct am_reg { @@ -161,27 +159,6 @@ struct decode_fps_s { u32 fps; }; -enum vdec_pd_e { - PD_VDEC, - PD_HCODEC, - PD_HEVC, - PD_WAVE, - PD_MAX -}; - -struct vdec_pwrc_s { - u8 *name; - struct device *dev; - struct device_link *link; -}; - -static struct vdec_pwrc_s vdec_pd[] = { - { .name = "pwrc-vdec", }, - { .name = "pwrc-hcodec",}, - { .name = "pwrc-hevc", }, - { .name = "pwrc-wave", }, -}; - struct vdec_core_s { struct list_head connected_vdec_list; spinlock_t lock; @@ -210,7 +187,7 @@ struct vdec_core_s { struct decode_fps_s decode_fps[MAX_INSTANCE_MUN]; unsigned long buff_flag; unsigned long stream_buff_flag; - struct vdec_pwrc_s *pd; + struct power_manager_s *pm; }; struct canvas_status_s { @@ -862,13 +839,6 @@ void update_vdec_clk_config_settings(unsigned int config) } EXPORT_SYMBOL(update_vdec_clk_config_settings); -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); -} - struct device *get_codec_cma_device(void) { return vdec_core->cma_dev; @@ -1071,8 +1041,9 @@ struct vdec_s *vdec_create(struct stream_port_s *port, } } - pr_debug("vdec_create instance %p, total %d\n", vdec, - atomic_read(&vdec_core->vdec_nr)); + pr_debug("vdec_create instance %p, total %d, PM: %s\n", vdec, + atomic_read(&vdec_core->vdec_nr), + get_pm_name(vdec_core->pm->pm_type)); //trace_vdec_create(vdec); /*DEBUG_TMP*/ @@ -3161,66 +3132,6 @@ static int vdec_core_thread(void *data) } #if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ -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; -} - void vdec_power_reset(void) { /* enable vdec1 isolation */ @@ -3267,17 +3178,9 @@ void vdec_power_reset(void) } EXPORT_SYMBOL(vdec_power_reset); -static void vdec_power_switch(struct vdec_pwrc_s *pd, int id, bool on); void vdec_poweron(enum vdec_type_e core) { - void *decomp_addr = NULL; - dma_addr_t decomp_dma_addr; - u32 decomp_addr_aligned = 0; - int hevc_loop = 0; - int sleep_val, iso_val; - bool is_power_ctrl_ver2 = false; - if (core >= VDEC_MAX) return; @@ -3294,270 +3197,7 @@ void vdec_poweron(enum vdec_type_e core) return; } - /* power domain check. */ - if (!disable_power_domain && vdec_core->pd) { - int pd_id = 0; - - if (core == VDEC_1) { - amports_switch_gate("clk_vdec_mux", 1); - vdec_clock_hi_enable(); - pd_id = PD_VDEC; - } else if (core == VDEC_HCODEC) { - hcodec_clock_enable(); - pd_id = PD_HCODEC; - } else if (core == VDEC_HEVC) { - /* 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(); - pd_id = PD_HEVC; - } - - vdec_power_switch(vdec_core->pd, pd_id, true); - mutex_unlock(&vdec_mutex); - - return; - } - - 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() && - (core == VDEC_HEVC)) { - decomp_addr = codec_mm_dma_alloc_coherent(MEM_NAME, - SZ_64K + SZ_4K, &decomp_dma_addr, GFP_KERNEL, 0); - - 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 (core == 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)) { - mutex_unlock(&vdec_mutex); - 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)) { - mutex_unlock(&vdec_mutex); - 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 (core == 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 (core == 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)) { - mutex_unlock(&vdec_mutex); - 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)) { - mutex_unlock(&vdec_mutex); - 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 (core == 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)) { - mutex_unlock(&vdec_mutex); - 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)) { - mutex_unlock(&vdec_mutex); - 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++; - - mutex_unlock(&vdec_mutex); - - 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; - } - - vdec_poweroff(VDEC_HEVC); - - mdelay(10); - - mutex_lock(&vdec_mutex); - } - } - - 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_NAME, - SZ_64K + SZ_4K, decomp_addr, decomp_dma_addr, 0); + vdec_core->pm->power_on(vdec_core->cma_dev, core); mutex_unlock(&vdec_mutex); } @@ -3565,8 +3205,6 @@ EXPORT_SYMBOL(vdec_poweron); void vdec_poweroff(enum vdec_type_e core) { - int sleep_val, iso_val; - bool is_power_ctrl_ver2 = false; if (core >= VDEC_MAX) return; @@ -3578,226 +3216,15 @@ void vdec_poweroff(enum vdec_type_e core) return; } - /* power domain check. */ - if (!disable_power_domain && vdec_core->pd) { - int pd_id = 0; - - if (core == VDEC_1) { - vdec_clock_off(); - pd_id = PD_VDEC; - } else if (core == VDEC_HCODEC) { - hcodec_clock_off(); - pd_id = PD_HCODEC; - } else if (core == VDEC_HEVC) { - /* disable hevc clock */ - hevc_clock_off(); - if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) - hevc_back_clock_off(); - pd_id = PD_HEVC; - } - - vdec_power_switch(vdec_core->pd, pd_id, false); - mutex_unlock(&vdec_mutex); - - return; - } - - 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 (core == VDEC_1) { - sleep_val = is_power_ctrl_ver2 ? 0x2 : 0xc; - iso_val = is_power_ctrl_ver2 ? 0x2 : 0xc0; - - /* disable VDEC_1 DMC REQ*/ -#ifdef CONFIG_AMLOGIC_POWER - if (is_support_power_ctrl()) { - if (power_ctrl_iso_mask(false, iso_val, 0)) { - mutex_unlock(&vdec_mutex); - 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)) { - mutex_unlock(&vdec_mutex); - 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 (core == 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 (core == 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)) { - mutex_unlock(&vdec_mutex); - 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)) { - mutex_unlock(&vdec_mutex); - 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 (core == 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)) { - mutex_unlock(&vdec_mutex); - 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(); + vdec_core->pm->power_off(vdec_core->cma_dev, core); - /* hevc power off */ -#ifdef CONFIG_AMLOGIC_POWER - if (is_support_power_ctrl()) { - if (power_ctrl_sleep_mask(false, sleep_val, 0)) { - mutex_unlock(&vdec_mutex); - 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; - } - } - } mutex_unlock(&vdec_mutex); } EXPORT_SYMBOL(vdec_poweroff); bool vdec_on(enum vdec_type_e core) { - bool ret = false; - - if (core == 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 (core == 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 (core == 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 (core == 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; + return vdec_core->pm->power_state(vdec_core->cma_dev, core); } EXPORT_SYMBOL(vdec_on); @@ -4989,65 +4416,6 @@ struct device *get_vdec_device(void) } EXPORT_SYMBOL(get_vdec_device); -static void vdec_power_switch(struct vdec_pwrc_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 vdec_power_domain_init(struct device *dev, - struct vdec_pwrc_s **pd_out) -{ - int i, err; - struct vdec_pwrc_s *pd = vdec_pd; - - for (i = 0; i < ARRAY_SIZE(vdec_pd); 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); - } - - *pd_out = pd; - - return 0; -} - -static void vdec_power_domain_remove(struct vdec_pwrc_s *pd) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(vdec_pd); 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 int vdec_probe(struct platform_device *pdev) { s32 i, r; @@ -5128,12 +4496,13 @@ static int vdec_probe(struct platform_device *pdev) WQ_MEM_RECLAIM |WQ_HIGHPRI/*high priority*/, "vdec-work"); /*work queue priority lower than vdec-core.*/ - /* init power domains. */ - if (of_property_read_bool(pdev->dev.of_node, "power-domains")) { - r = vdec_power_domain_init(&pdev->dev, &vdec_core->pd); + /* power manager init. */ + vdec_core->pm = (struct power_manager_s *) + of_device_get_match_data(&pdev->dev); + if (vdec_core->pm->init) { + r = vdec_core->pm->init(&pdev->dev); if (r) { - vdec_power_domain_remove(vdec_core->pd); - pr_err("vdec power domain init failed\n"); + pr_err("vdec power manager init failed\n"); return r; } } @@ -5160,21 +4529,14 @@ static int vdec_remove(struct platform_device *pdev) destroy_workqueue(vdec_core->vdec_core_wq); - if (vdec_core->pd) - vdec_power_domain_remove(vdec_core->pd); + if (vdec_core->pm->release) + vdec_core->pm->release(&pdev->dev); class_unregister(&vdec_class); return 0; } -static const struct of_device_id amlogic_vdec_dt_match[] = { - { - .compatible = "amlogic, vdec", - }, - {}, -}; - static struct mconfig vdec_configs[] = { MC_PU32("debug_trace_num", &debug_trace_num), MC_PI32("hevc_max_reset_count", &hevc_max_reset_count), @@ -5184,12 +4546,14 @@ static struct mconfig vdec_configs[] = { }; static struct mconfig_node vdec_node; +extern const struct of_device_id amlogic_vdec_matches[]; + static struct platform_driver vdec_driver = { .probe = vdec_probe, .remove = vdec_remove, .driver = { .name = "vdec", - .of_match_table = amlogic_vdec_dt_match, + .of_match_table = amlogic_vdec_matches, } }; @@ -5377,7 +4741,6 @@ module_param(fps_detection, int, 0664); module_param(fps_clear, int, 0664); module_param(force_nosecure_even_drm, int, 0664); module_param(disable_switch_single_to_mult, int, 0664); -module_param(disable_power_domain, bool, 0664); module_param(frameinfo_flag, int, 0664); MODULE_PARM_DESC(frameinfo_flag, |