summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--drivers/frame_provider/decoder/utils/Makefile1
-rw-r--r--drivers/frame_provider/decoder/utils/vdec.c689
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_power_ctrl.c801
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_power_ctrl.h107
-rw-r--r--drivers/stream_input/amports/amstream.c1
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,