author | Nanxin Qin <nanxin.qin@amlogic.com> | 2017-05-06 12:17:15 (GMT) |
---|---|---|
committer | Nanxin Qin <nanxin.qin@amlogic.com> | 2017-05-07 05:07:26 (GMT) |
commit | 833efe3d43f4f85ed91ea509fbc7f0ad14a621cf (patch) | |
tree | 8eb40ab99a4055d358e76f4af5f6c02fa11ea177 | |
parent | 0b016f3fbb21054dc742e63c07a73aeae1742930 (diff) | |
download | media-833efe3d43f4f85ed91ea509fbc7f0ad14a621cf.zip media-833efe3d43f4f85ed91ea509fbc7f0ad14a621cf.tar.gz media-833efe3d43f4f85ed91ea509fbc7f0ad14a621cf.tar.bz2 |
clock: optimize the media gate & clock
PD#143563: fixed the issue of the av sync when the hevc playback
Change-Id: I268fdf7c663f63cc38b5f6f1a5b552dff3b70ad6
Signed-off-by: Nanxin Qin <nanxin.qin@amlogic.com>
-rw-r--r-- | drivers/common/media_clock/clk/clk.h | 1 | ||||
-rw-r--r-- | drivers/common/media_clock/clk/clkgx.c | 416 | ||||
-rw-r--r-- | drivers/common/media_clock/switch/amports_gate.c | 41 | ||||
-rw-r--r-- | drivers/common/media_clock/switch/amports_gate.h | 8 | ||||
-rw-r--r-- | drivers/stream_input/amports/amstream.c | 13 |
5 files changed, 228 insertions, 251 deletions
diff --git a/drivers/common/media_clock/clk/clk.h b/drivers/common/media_clock/clk/clk.h index 2693763..1c979b4 100644 --- a/drivers/common/media_clock/clk/clk.h +++ b/drivers/common/media_clock/clk/clk.h @@ -56,6 +56,7 @@ void hevc_clock_enable(void); void hevc_clock_hi_enable(void); void vdec2_clock_enable(void); void vdec2_clock_hi_enable(void); +void set_clock_gate(struct gate_switch_node *nodes, int num); #endif int register_vdec_clk_mgr(int cputype[], diff --git a/drivers/common/media_clock/clk/clkgx.c b/drivers/common/media_clock/clk/clkgx.c index 52fad39..8520738 100644 --- a/drivers/common/media_clock/clk/clkgx.c +++ b/drivers/common/media_clock/clk/clkgx.c @@ -29,30 +29,16 @@ #include <linux/amlogic/media/utils/log.h> #include <linux/amlogic/media/registers/register_ops.h> - +#include "../switch/amports_gate.h" #define MHz (1000000) struct clk_mux_s { - struct clk *vdec_clk; - struct clk *hcodec_clk; - struct clk *hevc_clk; + struct gate_switch_node *vdec_mux_node; + struct gate_switch_node *hcodec_mux_node; + struct gate_switch_node *hevc_mux_node; }; struct clk_mux_s gclk; -/* -*HHI_VDEC_CLK_CNTL -*0x1078[11:9] (fclk = 2000MHz) - *0: fclk_div4 - *1: fclk_div3 - *2: fclk_div5 - *3: fclk_div7 - *4: mpll_clk_out1 - *5: mpll_clk_out2 -*0x1078[6:0] - *divider -*0x1078[8] - *enable -*/ void vdec1_set_clk(int source, int div) { @@ -83,25 +69,6 @@ void hevc_set_clk(int source, int div) } EXPORT_SYMBOL(hevc_set_clk); -void clock_set_init(struct device *dev) -{ - gclk.vdec_clk = devm_clk_get(dev, "clk_vdec_mux"); - if (IS_ERR(gclk.vdec_clk)) { - printk("get vdec clk err.\n"); - } - - gclk.hcodec_clk = devm_clk_get(dev, "clk_hcodec_mux"); - if (IS_ERR(gclk.hcodec_clk)) { - printk("get hcodec clk err.\n"); - } - - gclk.hevc_clk = devm_clk_get(dev, "clk_hevc_mux"); - if (IS_ERR(gclk.hevc_clk)) { - printk("get hevc clk err.\n"); - } -} -EXPORT_SYMBOL(clock_set_init); - void vdec_get_clk_source(int clk, int *source, int *div, int *rclk) { #define source_div4 (0) @@ -152,45 +119,6 @@ void vdec_get_clk_source(int clk, int *source, int *div, int *rclk) } EXPORT_SYMBOL(vdec_get_clk_source); -static int vdec_set_clk(int dec, int rate) -{ - struct clk *clk = NULL; - - switch (dec) { - case VDEC_1: - clk = gclk.vdec_clk; - WRITE_VREG_BITS(DOS_GCLK_EN0, 0x3ff, 0, 10); - break; - - case VDEC_HCODEC: - clk = gclk.hcodec_clk; - WRITE_VREG_BITS(DOS_GCLK_EN0, 0x7fff, 12, 15); - break; - - case VDEC_2: - clk = gclk.vdec_clk; - WRITE_VREG(DOS_GCLK_EN1, 0x3ff); - break; - - case VDEC_HEVC: - clk = gclk.hevc_clk; - WRITE_VREG(DOS_GCLK_EN3, 0xffffffff); - break; - - case VDEC_MAX: - break; - - default: - pr_info("invaild vdec type.\n"); - } - - clk_set_rate(clk, rate); - - return 0; -} - -static bool is_gp0_div2 = true; - /* set gp0 648M vdec use gp0 clk*/ #define VDEC1_648M() \ WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, (6 << 9) | (0), 0, 16) @@ -262,20 +190,6 @@ static bool is_gp0_div2 = true; #define HEVC_CLOCK_OFF() WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 0, 24, 1) static int clock_real_clk[VDEC_MAX + 1]; -static struct gp_pll_user_handle_s *gp_pll_user_vdec, *gp_pll_user_hevc; - -static int gp_pll_user_cb_vdec(struct gp_pll_user_handle_s *user, int event) -{ - pr_info("gp_pll_user_cb_vdec call\n"); - if (event == GP_PLL_USER_EVENT_GRANT) { - if (!IS_ERR(gclk.vdec_clk)) { - vdec_set_clk(VDEC_1, 648 * MHz); - pr_info("get clock : %lu\n", - clk_get_rate(gclk.vdec_clk)); - } - } - return 0; -} /* *enum vformat_e { @@ -406,45 +320,74 @@ static struct clk_set_setting clks_for_formats[] = { }; -static int vdec_clock_init(void) +void set_clock_gate(struct gate_switch_node *nodes, int num) { - gp_pll_user_vdec = gp_pll_user_register("vdec", 0, gp_pll_user_cb_vdec); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) - is_gp0_div2 = false; - else - is_gp0_div2 = true; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) { - pr_info("used fix clk for vdec clk source!\n"); - //update_vdec_clk_config_settings(1);//DEBUG_TMP - } - return (gp_pll_user_vdec) ? 0 : -ENOMEM; + struct gate_switch_node *node = NULL; + + do { + node = &nodes[num - 1]; + if (IS_ERR_OR_NULL(node)) + pr_info("get mux clk err.\n"); + + if (!strcmp(node->name, "clk_vdec_mux")) + gclk.vdec_mux_node = node; + else if (!strcmp(node->name, "clk_hcodec_mux")) + gclk.hcodec_mux_node = node; + else if (!strcmp(node->name, "clk_hevc_mux")) + gclk.hevc_mux_node = node; + } while(--num); } -#if 0 -static void update_clk_with_clk_configs(int clk, int *source, int *div, - int *rclk) +EXPORT_SYMBOL(set_clock_gate); + +static int vdec_set_clk(int dec, int rate) { - unsigned int config = 0;//get_vdec_clk_config_settings();//DEBUG_TMP + struct clk *clk = NULL; + + switch (dec) { + case VDEC_1: + clk = gclk.vdec_mux_node->clk; + WRITE_VREG_BITS(DOS_GCLK_EN0, 0x3ff, 0, 10); + break; + + case VDEC_HCODEC: + clk = gclk.hcodec_mux_node->clk; + WRITE_VREG_BITS(DOS_GCLK_EN0, 0x7fff, 12, 15); + break; - if (!config) - return; - if (config >= 10) { - int wantclk; + case VDEC_2: + clk = gclk.vdec_mux_node->clk; + WRITE_VREG(DOS_GCLK_EN1, 0x3ff); + break; - wantclk = config; - vdec_get_clk_source(wantclk, source, div, rclk); + case VDEC_HEVC: + clk = gclk.hevc_mux_node->clk; + WRITE_VREG(DOS_GCLK_EN3, 0xffffffff); + break; + + case VDEC_MAX: + break; + + default: + pr_info("invaild vdec type.\n"); + } + + if (IS_ERR_OR_NULL(clk)) { + pr_info("the mux clk err.\n"); + return -1; } + + clk_set_rate(clk, rate); + + return 0; } -#endif -#define NO_GP0_PLL 0//(get_vdec_clk_config_settings() == 1)//DEBUG_TMP -#define ALWAYS_GP0_PLL 0//(get_vdec_clk_config_settings() == 2)//DEBUG_TMP -static int vdec_clock_set(int clk) +static int vdec_clock_init(void) { - int use_gpll = 0; - int clk_seted = 0; - int pll_wait = 0; + return 0; +} +static int vdec_clock_set(int clk) +{ if (clk == 1) clk = 200; else if (clk == 2) { @@ -453,12 +396,6 @@ static int vdec_clock_set(int clk) else clk = 648; } else if (clk == 0) { - /* - *used for release gp pull. - *if used, release it. - *if not used gp pll - *do nothing. - */ if (clock_real_clk[VDEC_1] == 667 || (clock_real_clk[VDEC_1] == 648) || clock_real_clk[VDEC_1] <= 0) @@ -470,94 +407,26 @@ static int vdec_clock_set(int clk) if ((clk > 500 && clk != 667)) { if (clock_real_clk[VDEC_1] == 648) return 648; - - gp_pll_request(gp_pll_user_vdec); - - while (pll_wait++ < 1000000) { - if (clk_get_rate(gclk.vdec_clk) == 648) { - clk_seted = 1; - break; - } - udelay(1); - } - - if (!clk_seted) { - use_gpll = 0; - clk = 667; - pr_info("get pll failed used fix pll\n"); - } - } - - if (!clk_seted) {/*if 648 not set, */ - vdec_set_clk(VDEC_1, clk * MHz); - pr_info("get clock : %lu\n", clk_get_rate(gclk.vdec_clk)); + clk = 667; } - if (!use_gpll) - gp_pll_release(gp_pll_user_vdec); + vdec_set_clk(VDEC_1, clk * MHz); clock_real_clk[VDEC_1] = clk; - pr_info("vdec_clock_set to %d\n", clk); - return clk; -} + pr_info("vdec mux clock is %lu Hz\n", + clk_get_rate(gclk.vdec_mux_node->clk)); -static void vdec_clock_on(void) -{ - clk_prepare_enable(gclk.vdec_clk); -} - -static void vdec_clock_off(void) -{ - clk_disable_unprepare(gclk.vdec_clk); - clock_real_clk[VDEC_1] = 0; - gp_pll_release(gp_pll_user_vdec); -} - -static int hcodec_clock_set(int clk) -{ - clk_set_rate(gclk.hcodec_clk, clk * MHz); - clock_real_clk[VDEC_HCODEC] = clk; return clk; } -static void hcodec_clock_on(void) -{ - clk_prepare_enable(gclk.hcodec_clk); -} - -static void hcodec_clock_off(void) -{ - clk_disable_unprepare(gclk.hcodec_clk); -} - -static int gp_pll_user_cb_hevc(struct gp_pll_user_handle_s *user, int event) -{ - pr_info("gp_pll_user_cb_hevc callback\n"); - if (event == GP_PLL_USER_EVENT_GRANT) { - if (!IS_ERR(gclk.hevc_clk)) { - vdec_set_clk(VDEC_HEVC, 648 * MHz); - pr_info("get clock : %lu\n", - clk_get_rate(gclk.hevc_clk)); - } - } - - return 0; -} - static int hevc_clock_init(void) { - gp_pll_user_hevc = gp_pll_user_register("hevc", 0, gp_pll_user_cb_hevc); - - return (gp_pll_user_hevc) ? 0 : -ENOMEM; + return 0; } static int hevc_clock_set(int clk) { - int use_gpll = 0; - int clk_seted = 0; - int pll_wait = 0; - if (clk == 1) clk = 200; else if (clk == 2) { @@ -577,49 +446,150 @@ static int hevc_clock_set(int clk) if ((clk > 500 && clk != 667)) { if (clock_real_clk[VDEC_HEVC] == 648) return 648; + clk = 667; + } + + vdec_set_clk(VDEC_HEVC, clk * MHz); + + clock_real_clk[VDEC_HEVC] = clk; + + pr_info("hevc mux clock is %lu Hz\n", + clk_get_rate(gclk.hevc_mux_node->clk)); - gp_pll_request(gp_pll_user_hevc); - - while (pll_wait++ < 1000000) { - if (clk_get_rate(gclk.hevc_clk) == 648) { - clk_seted = 1; - break; - } - udelay(1); - } - - if (!clk_seted) { - use_gpll = 0; - clk = 667; - pr_info("get pll failed used fix pll\n"); - } + return clk; +} + +static int hcodec_clock_set(int clk) +{ + if (clk == 1) + clk = 200; + else if (clk == 2) { + if (clock_real_clk[VDEC_HCODEC] != 648) + clk = 500; + else + clk = 648; + } else if (clk == 0) { + if (clock_real_clk[VDEC_HCODEC] == 667 || + (clock_real_clk[VDEC_HCODEC] == 648) || + clock_real_clk[VDEC_HCODEC] <= 0) + clk = 200; + else + clk = clock_real_clk[VDEC_HCODEC]; } - if (!clk_seted) {/*if 648 not set, */ - vdec_set_clk(VDEC_HEVC, clk * MHz); - pr_info("get clock : %lu\n", clk_get_rate(gclk.hevc_clk)); + if ((clk > 500 && clk != 667)) { + if (clock_real_clk[VDEC_HCODEC] == 648) + return 648; + clk = 667; } - if (!use_gpll) - gp_pll_release(gp_pll_user_hevc); + vdec_set_clk(VDEC_HCODEC, clk * MHz); - clock_real_clk[VDEC_HEVC] = clk; - pr_info("hevc_clock_set to %d\n", clk); + clock_real_clk[VDEC_HCODEC] = clk; + + pr_info("hcodec mux clock is %lu Hz\n", + clk_get_rate(gclk.hcodec_mux_node->clk)); return clk; } +static void vdec_clock_on(void) +{ + spin_lock_irqsave(&gclk.vdec_mux_node->lock, + gclk.vdec_mux_node->flags); + if (!gclk.vdec_mux_node->ref_count) + clk_prepare_enable(gclk.vdec_mux_node->clk); + + gclk.vdec_mux_node->ref_count++; + spin_unlock_irqrestore(&gclk.vdec_mux_node->lock, + gclk.vdec_mux_node->flags); + + pr_info("the %-15s clock off, ref cnt: %d\n", + gclk.vdec_mux_node->name, + gclk.vdec_mux_node->ref_count); +} + +static void vdec_clock_off(void) +{ + spin_lock_irqsave(&gclk.vdec_mux_node->lock, + gclk.vdec_mux_node->flags); + gclk.vdec_mux_node->ref_count--; + if (!gclk.vdec_mux_node->ref_count) + clk_disable_unprepare(gclk.vdec_mux_node->clk); + + clock_real_clk[VDEC_1] = 0; + spin_unlock_irqrestore(&gclk.vdec_mux_node->lock, + gclk.vdec_mux_node->flags); + + pr_info("the %-15s clock off, ref cnt: %d\n", + gclk.vdec_mux_node->name, + gclk.vdec_mux_node->ref_count); +} + +static void hcodec_clock_on(void) +{ + spin_lock_irqsave(&gclk.hcodec_mux_node->lock, + gclk.hcodec_mux_node->flags); + if (!gclk.hcodec_mux_node->ref_count) + clk_prepare_enable(gclk.hcodec_mux_node->clk); + + gclk.hcodec_mux_node->ref_count++; + spin_unlock_irqrestore(&gclk.hcodec_mux_node->lock, + gclk.hcodec_mux_node->flags); + + pr_info("the %-15s clock off, ref cnt: %d\n", + gclk.hcodec_mux_node->name, + gclk.hcodec_mux_node->ref_count); +} + +static void hcodec_clock_off(void) +{ + spin_lock_irqsave(&gclk.hcodec_mux_node->lock, + gclk.hcodec_mux_node->flags); + gclk.hcodec_mux_node->ref_count--; + if (!gclk.hcodec_mux_node->ref_count) + clk_disable_unprepare(gclk.hcodec_mux_node->clk); + + spin_unlock_irqrestore(&gclk.hcodec_mux_node->lock, + gclk.hcodec_mux_node->flags); + + pr_info("the %-15s clock off, ref cnt: %d\n", + gclk.hcodec_mux_node->name, + gclk.hcodec_mux_node->ref_count); +} + static void hevc_clock_on(void) { - clk_prepare_enable(gclk.hevc_clk); + spin_lock_irqsave(&gclk.hevc_mux_node->lock, + gclk.hevc_mux_node->flags); + if (!gclk.hevc_mux_node->ref_count) + clk_prepare_enable(gclk.hevc_mux_node->clk); + + gclk.hevc_mux_node->ref_count++; WRITE_VREG(DOS_GCLK_EN3, 0xffffffff); + spin_unlock_irqrestore(&gclk.hevc_mux_node->lock, + gclk.hevc_mux_node->flags); + + pr_info("the %-15s clock off, ref cnt: %d\n", + gclk.hevc_mux_node->name, + gclk.hevc_mux_node->ref_count); } static void hevc_clock_off(void) { - clk_disable_unprepare(gclk.hevc_clk); - gp_pll_release(gp_pll_user_hevc); + spin_lock_irqsave(&gclk.hevc_mux_node->lock, + gclk.hevc_mux_node->flags); + gclk.hevc_mux_node->ref_count--; + if (!gclk.hevc_mux_node->ref_count) + clk_disable_unprepare(gclk.hevc_mux_node->clk); + clock_real_clk[VDEC_HEVC] = 0; + spin_unlock_irqrestore(&gclk.hevc_mux_node->lock, + gclk.hevc_mux_node->flags); + + pr_info("the %-15s clock off, ref cnt: %d\n", + gclk.hevc_mux_node->name, + gclk.hevc_mux_node->ref_count); } static int vdec_clock_get(enum vdec_type_e core) diff --git a/drivers/common/media_clock/switch/amports_gate.c b/drivers/common/media_clock/switch/amports_gate.c index a4e6b54..ade914a 100644 --- a/drivers/common/media_clock/switch/amports_gate.c +++ b/drivers/common/media_clock/switch/amports_gate.c @@ -23,20 +23,16 @@ #include "amports_gate.h" #include <linux/amlogic/media/utils/vdec_reg.h> #include "../../../stream_input/amports/amports_priv.h" +#include "../../../frame_provider/decoder/utils/vdec.h" +#include "../clk/clk.h" -#define DEBUG_REF 0 + +#define DEBUG_REF 1 #define GATE_RESET_OK -struct gate_swtch_node { - struct clk *clk; - const char *name; - spinlock_t lock; - unsigned long flags; - int ref_count; -}; #ifdef GATE_RESET_OK -struct gate_swtch_node gates[] = { +struct gate_switch_node gates[] = { { .name = "demux", }, @@ -57,7 +53,6 @@ struct gate_swtch_node gates[] = { }, }; - /* mesonstream { compatible = "amlogic, codec, streambuf"; @@ -82,7 +77,7 @@ int amports_clock_gate_init(struct device *dev) { int i; - for (i = 0; i < sizeof(gates) / sizeof(struct gate_swtch_node); i++) { + for (i = 0; i < sizeof(gates) / sizeof(struct gate_switch_node); i++) { gates[i].clk = devm_clk_get(dev, gates[i].name); if (IS_ERR_OR_NULL(gates[i].clk)) { gates[i].clk = NULL; @@ -97,29 +92,33 @@ int amports_clock_gate_init(struct device *dev) gates[i].ref_count = 0; spin_lock_init(&gates[i].lock); } + + set_clock_gate(gates, ARRAY_SIZE(gates)); + return 0; } EXPORT_SYMBOL(amports_clock_gate_init); -static int amports_gate_clk(struct gate_swtch_node *gate_node, int enable) +static int amports_gate_clk(struct gate_switch_node *gate_node, int enable) { spin_lock_irqsave(&gate_node->lock, gate_node->flags); if (enable) { - if (DEBUG_REF) - pr_info("amports_gate_reset,count: %d\n", - gate_node->ref_count); if (gate_node->ref_count == 0) clk_prepare_enable(gate_node->clk); gate_node->ref_count++; + + if (DEBUG_REF) + pr_info("the %-15s clock on, ref cnt: %d\n", + gate_node->name, gate_node->ref_count); } else { gate_node->ref_count--; - if (DEBUG_REF) - pr_info("amports_gate_reset,count: %d\n", - gate_node->ref_count); - if (gate_node->ref_count == 0) clk_disable_unprepare(gate_node->clk); + + if (DEBUG_REF) + pr_info("the %-15s clock off, ref cnt: %d\n", + gate_node->name, gate_node->ref_count); } spin_unlock_irqrestore(&gate_node->lock, gate_node->flags); return 0; @@ -129,7 +128,7 @@ int amports_switch_gate(const char *name, int enable) { int i; - for (i = 0; i < sizeof(gates) / sizeof(struct gate_swtch_node); i++) { + for (i = 0; i < sizeof(gates) / sizeof(struct gate_switch_node); i++) { if (!strcmp(name, gates[i].name)) { /*pr_info("openclose:%d gate %s control\n", enable, @@ -175,7 +174,7 @@ int amports_clock_gate_init(struct device *dev) } EXPORT_SYMBOL(amports_clock_gate_init); -static int amports_switch_gate(struct gate_swtch_node *gate_node, int enable) +static int amports_switch_gate(struct gate_switch_node *gate_node, int enable) { return 0; } diff --git a/drivers/common/media_clock/switch/amports_gate.h b/drivers/common/media_clock/switch/amports_gate.h index 53e1960..75270ab 100644 --- a/drivers/common/media_clock/switch/amports_gate.h +++ b/drivers/common/media_clock/switch/amports_gate.h @@ -19,6 +19,14 @@ #define AMPORT_GATE_H #include <linux/device.h> +struct gate_switch_node { + struct clk *clk; + const char *name; + spinlock_t lock; + unsigned long flags; + int ref_count; +}; + extern int amports_clock_gate_init(struct device *dev); extern int amports_switch_gate(const char *name, int enable); diff --git a/drivers/stream_input/amports/amstream.c b/drivers/stream_input/amports/amstream.c index 6c07f63..f1d2c74 100644 --- a/drivers/stream_input/amports/amstream.c +++ b/drivers/stream_input/amports/amstream.c @@ -1469,11 +1469,6 @@ static int amstream_open(struct inode *inode, struct file *file) priv->port = port; if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { - - amports_switch_gate("clk_vdec_mux", 1); - amports_switch_gate("clk_hcodec_mux", 1); - amports_switch_gate("clk_hevc_mux", 1); - /* TODO: mod gate */ /* switch_mod_gate_by_name("demux", 1); */ amports_switch_gate("demux", 1); @@ -1487,7 +1482,11 @@ static int amstream_open(struct inode *inode, struct file *file) /* TODO: mod gate */ /* switch_mod_gate_by_name("vdec", 1); */ amports_switch_gate("vdec", 1); + amports_switch_gate("clk_vdec_mux", 1); + amports_switch_gate("clk_hcodec_mux", 1); + if (has_hevc_vdec()) { + amports_switch_gate("clk_hevc_mux", 1); if (port->type & (PORT_TYPE_MPTS | PORT_TYPE_HEVC)) vdec_poweron(VDEC_HEVC); @@ -1586,7 +1585,7 @@ static int amstream_release(struct inode *inode, struct file *file) } port->flag = 0; - /* /timestamp_pcrscr_set(0); */ + /* timestamp_pcrscr_set(0); */ #ifdef DATA_DEBUG if (debug_filp) { @@ -1595,7 +1594,6 @@ static int amstream_release(struct inode *inode, struct file *file) debug_file_pos = 0; } #endif - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) { if (port->type & PORT_TYPE_VIDEO) { if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) { @@ -1620,6 +1618,7 @@ static int amstream_release(struct inode *inode, struct file *file) /* TODO: mod gate */ /* switch_mod_gate_by_name("vdec", 0); */ amports_switch_gate("vdec", 0); + amports_switch_gate("clk_hcodec_mux", 0); } if (port->type & PORT_TYPE_AUDIO) { |