From 708c5cde4b1c1ae4ca228ecd42e2244154e557b0 Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Sat, 24 Feb 2018 10:44:13 +0800 Subject: [PATCH] vpu: update mem_pd control for g12a PD#156734: vpu: update mem_pd control for g12a also add vpu power on init function to avoid uboot coupling Change-Id: Idcf435d7ec2c0e49f2b115102fba10ae9ee86b9d Signed-off-by: Evoke Zhang --- MAINTAINERS | 4 + drivers/amlogic/media/common/vpu/Makefile | 2 +- drivers/amlogic/media/common/vpu/vpu.c | 66 +++- drivers/amlogic/media/common/vpu/vpu.h | 11 + drivers/amlogic/media/common/vpu/vpu_ctrl.h | 47 ++- drivers/amlogic/media/common/vpu/vpu_module.h | 21 +- .../amlogic/media/common/vpu/vpu_power_init.c | 282 ++++++++++++++++++ drivers/amlogic/media/common/vpu/vpu_reg.c | 46 +++ drivers/amlogic/media/common/vpu/vpu_reg.h | 50 +++- include/linux/amlogic/media/vpu/vpu.h | 17 +- 10 files changed, 533 insertions(+), 13 deletions(-) create mode 100644 drivers/amlogic/media/common/vpu/vpu_power_init.c diff --git a/MAINTAINERS b/MAINTAINERS index 292cbfd5ef4b..92cf8294d0b7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14301,3 +14301,7 @@ F: include/dt-bindings/gpio/* AMLOGIC GPU CONFIG M: Jiyu Yang F: arch/arm64/boot/dts/amlogic/mesong12a-dvalin.dtsi + +AMLOGIC VPU DRIVER +M: Evoke Zhang +F: drivers/amlogic/media/common/vpu/vpu_power_init.c diff --git a/drivers/amlogic/media/common/vpu/Makefile b/drivers/amlogic/media/common/vpu/Makefile index 988a9eba10ac..b8352bc4dbc4 100644 --- a/drivers/amlogic/media/common/vpu/Makefile +++ b/drivers/amlogic/media/common/vpu/Makefile @@ -1,2 +1,2 @@ -obj-$(CONFIG_AMLOGIC_VPU) += vpu.o vpu_reg.o +obj-$(CONFIG_AMLOGIC_VPU) += vpu.o vpu_reg.o vpu_power_init.o diff --git a/drivers/amlogic/media/common/vpu/vpu.c b/drivers/amlogic/media/common/vpu/vpu.c index e37a04300d63..03232313eb2c 100644 --- a/drivers/amlogic/media/common/vpu/vpu.c +++ b/drivers/amlogic/media/common/vpu/vpu.c @@ -758,7 +758,7 @@ static ssize_t vpu_mem_debug(struct class *class, struct class_attribute *attr, { unsigned int tmp[2]; unsigned int _reg0, _reg1, _reg2; - int ret = 0; + int ret = 0, i; _reg0 = HHI_VPU_MEM_PD_REG0; _reg1 = HHI_VPU_MEM_PD_REG1; @@ -784,6 +784,11 @@ static ssize_t vpu_mem_debug(struct class *class, struct class_attribute *attr, VPUERR("invalid parameters\n"); } break; + case 'i': + VPUPR("vpu modules:\n"); + for (i = VPU_VIU_OSD1; i < VPU_MOD_MAX; i++) + pr_info(" [%02d] %s\n", i, vpu_mod_table[i]); + break; default: VPUERR("wrong mem_pd command\n"); break; @@ -1132,6 +1137,37 @@ static void vpu_clktree_init(struct device *dev) VPUPR("clktree_init\n"); } +static int vpu_power_init_check(void) +{ + unsigned int val; + int ret = 0; + + val = vpu_hiu_getb(HHI_VPU_CLK_CNTL, 31, 1); + if (val) { + if (vpu_hiu_getb(HHI_VPU_CLK_CNTL, 24, 1) == 0) + ret = 1; + } else { + if (vpu_hiu_getb(HHI_VPU_CLK_CNTL, 8, 1) == 0) + ret = 1; + } + + return ret; +} + +static void vpu_power_init(void) +{ + int ret = 0; + + ret = vpu_chip_valid_check(); + if (ret) + return; + + vpu_conf.data->power_on(); + vpu_mem_pd_init_off(); + vpu_clk_gate_init_off(); + vpu_module_init_config(); +} + static struct vpu_data_s vpu_data_gxb = { .chip_type = VPU_CHIP_GXBB, .chip_name = "gxbb", @@ -1149,6 +1185,9 @@ static struct vpu_data_s vpu_data_gxb = { sizeof(vpu_clk_gate_gxb) / sizeof(struct vpu_ctrl_s), .mem_pd_table = vpu_mem_pd_gxb, .clk_gate_table = vpu_clk_gate_gxb, + + .power_on = vpu_power_on_gx, + .power_off = vpu_power_off_gx, }; static struct vpu_data_s vpu_data_gxtvbb = { @@ -1168,6 +1207,9 @@ static struct vpu_data_s vpu_data_gxtvbb = { sizeof(vpu_clk_gate_gxl) / sizeof(struct vpu_ctrl_s), .mem_pd_table = vpu_mem_pd_gxtvbb, .clk_gate_table = vpu_clk_gate_gxl, + + .power_on = vpu_power_on_gx, + .power_off = vpu_power_off_gx, }; static struct vpu_data_s vpu_data_gxl = { @@ -1187,6 +1229,9 @@ static struct vpu_data_s vpu_data_gxl = { sizeof(vpu_clk_gate_gxl) / sizeof(struct vpu_ctrl_s), .mem_pd_table = vpu_mem_pd_gxl, .clk_gate_table = vpu_clk_gate_gxl, + + .power_on = vpu_power_on_gx, + .power_off = vpu_power_off_gx, }; static struct vpu_data_s vpu_data_gxm = { @@ -1206,6 +1251,9 @@ static struct vpu_data_s vpu_data_gxm = { sizeof(vpu_clk_gate_gxl) / sizeof(struct vpu_ctrl_s), .mem_pd_table = vpu_mem_pd_gxl, .clk_gate_table = vpu_clk_gate_gxl, + + .power_on = vpu_power_on_gx, + .power_off = vpu_power_off_gx, }; static struct vpu_data_s vpu_data_txlx = { @@ -1225,6 +1273,9 @@ static struct vpu_data_s vpu_data_txlx = { sizeof(vpu_clk_gate_txlx) / sizeof(struct vpu_ctrl_s), .mem_pd_table = vpu_mem_pd_txlx, .clk_gate_table = vpu_clk_gate_txlx, + + .power_on = vpu_power_on_txlx, + .power_off = vpu_power_off_txlx, }; static struct vpu_data_s vpu_data_axg = { @@ -1244,6 +1295,9 @@ static struct vpu_data_s vpu_data_axg = { sizeof(vpu_clk_gate_axg) / sizeof(struct vpu_ctrl_s), .mem_pd_table = vpu_mem_pd_axg, .clk_gate_table = vpu_clk_gate_axg, + + .power_on = vpu_power_on_txlx, + .power_off = vpu_power_off_txlx, }; static struct vpu_data_s vpu_data_g12a = { @@ -1258,11 +1312,14 @@ static struct vpu_data_s vpu_data_g12a = { .mem_pd_reg2_valid = 1, .mem_pd_table_cnt = - sizeof(vpu_mem_pd_gxl) / sizeof(struct vpu_ctrl_s), + sizeof(vpu_mem_pd_g12a) / sizeof(struct vpu_ctrl_s), .clk_gate_table_cnt = sizeof(vpu_clk_gate_gxl) / sizeof(struct vpu_ctrl_s), - .mem_pd_table = vpu_mem_pd_gxl, + .mem_pd_table = vpu_mem_pd_g12a, .clk_gate_table = vpu_clk_gate_gxl, + + .power_on = vpu_power_on_txlx, + .power_off = vpu_power_off_txlx, }; static const struct of_device_id vpu_of_table[] = { @@ -1334,8 +1391,11 @@ static int vpu_probe(struct platform_device *pdev) get_vpu_config(pdev); + ret = vpu_power_init_check(); vpu_clktree_init(&pdev->dev); set_vpu_clk(vpu_conf.clk_level); + if (ret) + vpu_power_init(); creat_vpu_debug_class(); diff --git a/drivers/amlogic/media/common/vpu/vpu.h b/drivers/amlogic/media/common/vpu/vpu.h index 3d5f977c2de8..d4d02b2b6e07 100644 --- a/drivers/amlogic/media/common/vpu/vpu.h +++ b/drivers/amlogic/media/common/vpu/vpu.h @@ -70,6 +70,9 @@ struct vpu_data_s { unsigned int clk_gate_table_cnt; struct vpu_ctrl_s *mem_pd_table; struct vpu_ctrl_s *clk_gate_table; + + void (*power_on)(void); + void (*power_off)(void); }; struct vpu_conf_s { @@ -96,4 +99,12 @@ extern int vpu_debug_print_flag; extern int vpu_chip_valid_check(void); extern void vpu_ctrl_probe(void); +extern void vpu_mem_pd_init_off(void); +extern void vpu_clk_gate_init_off(void); +extern void vpu_module_init_config(void); +extern void vpu_power_on_gx(void); +extern void vpu_power_off_gx(void); +extern void vpu_power_on_txlx(void); +extern void vpu_power_off_txlx(void); + #endif diff --git a/drivers/amlogic/media/common/vpu/vpu_ctrl.h b/drivers/amlogic/media/common/vpu/vpu_ctrl.h index 73215a76a9a0..66315450c49a 100644 --- a/drivers/amlogic/media/common/vpu/vpu_ctrl.h +++ b/drivers/amlogic/media/common/vpu/vpu_ctrl.h @@ -189,7 +189,7 @@ static struct vpu_ctrl_s vpu_mem_pd_gxl[] = { {VPU_VENCP, HHI_VPU_MEM_PD_REG1, 20, 2}, {VPU_VENCL, HHI_VPU_MEM_PD_REG1, 22, 2}, {VPU_VENCI, HHI_VPU_MEM_PD_REG1, 24, 2}, - {VPU_VIU1_WM, HHI_VPU_MEM_PD_REG2, 0, 2}, + {VPU_VIU_WM, HHI_VPU_MEM_PD_REG2, 0, 2}, {VPU_MOD_MAX, VPU_REG_END, 0, 0}, }; @@ -223,7 +223,7 @@ static struct vpu_ctrl_s vpu_mem_pd_txlx[] = { {VPU_VENCI, HHI_VPU_MEM_PD_REG1, 24, 2}, {VPU_LDIM_STTS, HHI_VPU_MEM_PD_REG1, 28, 2}, {VPU_XVYCC_LUT, HHI_VPU_MEM_PD_REG1, 30, 2}, - {VPU_VIU1_WM, HHI_VPU_MEM_PD_REG2, 0, 2}, + {VPU_VIU_WM, HHI_VPU_MEM_PD_REG2, 0, 2}, {VPU_MOD_MAX, VPU_REG_END, 0, 0}, }; @@ -236,6 +236,49 @@ static struct vpu_ctrl_s vpu_mem_pd_axg[] = { {VPU_MOD_MAX, VPU_REG_END, 0, 0}, }; +static struct vpu_ctrl_s vpu_mem_pd_g12a[] = { + /* vpu module, reg, bit, len */ + {VPU_VIU_OSD1, HHI_VPU_MEM_PD_REG0, 0, 2}, + {VPU_VIU_OSD2, HHI_VPU_MEM_PD_REG0, 2, 2}, + {VPU_VIU_VD1, HHI_VPU_MEM_PD_REG0, 4, 2}, + {VPU_VIU_VD2, HHI_VPU_MEM_PD_REG0, 6, 2}, + {VPU_VIU_CHROMA, HHI_VPU_MEM_PD_REG0, 8, 2}, + {VPU_VIU_OFIFO, HHI_VPU_MEM_PD_REG0, 10, 2}, + {VPU_VIU_SCALE, HHI_VPU_MEM_PD_REG0, 12, 2}, + {VPU_VIU_OSD_SCALE, HHI_VPU_MEM_PD_REG0, 14, 2}, + {VPU_VIU_VDIN0, HHI_VPU_MEM_PD_REG0, 16, 2}, + {VPU_VIU_VDIN1, HHI_VPU_MEM_PD_REG0, 18, 2}, + {VPU_VIU_SRSCL, HHI_VPU_MEM_PD_REG0, 20, 2}, + {VPU_AFBC_DEC1, HHI_VPU_MEM_PD_REG0, 22, 2}, + {VPU_VIU_DI_SCALE, HHI_VPU_MEM_PD_REG0, 24, 2}, + {VPU_DI_PRE, HHI_VPU_MEM_PD_REG0, 26, 2}, + {VPU_DI_POST, HHI_VPU_MEM_PD_REG0, 28, 2}, + {VPU_SHARP, HHI_VPU_MEM_PD_REG0, 30, 2}, + {VPU_VIU2_OSD1, HHI_VPU_MEM_PD_REG1, 0, 2}, + {VPU_VIU2_OFIFO, HHI_VPU_MEM_PD_REG1, 2, 2}, + {VPU_VKSTONE, HHI_VPU_MEM_PD_REG1, 4, 2}, + {VPU_DOLBY_CORE3, HHI_VPU_MEM_PD_REG1, 6, 2}, + {VPU_DOLBY0, HHI_VPU_MEM_PD_REG1, 8, 2}, + {VPU_DOLBY1A, HHI_VPU_MEM_PD_REG1, 10, 2}, + {VPU_DOLBY1B, HHI_VPU_MEM_PD_REG1, 12, 2}, + {VPU_VPU_ARB, HHI_VPU_MEM_PD_REG1, 14, 2}, + {VPU_AFBC_DEC, HHI_VPU_MEM_PD_REG1, 16, 2}, + {VPU_VD2_SCALE, HHI_VPU_MEM_PD_REG1, 18, 2}, + {VPU_VENCP, HHI_VPU_MEM_PD_REG1, 20, 2}, + {VPU_VENCL, HHI_VPU_MEM_PD_REG1, 22, 2}, + {VPU_VENCI, HHI_VPU_MEM_PD_REG1, 24, 2}, + {VPU_VD2_OSD2_SCALE, HHI_VPU_MEM_PD_REG1, 30, 2}, + {VPU_VIU_WM, HHI_VPU_MEM_PD_REG2, 0, 2}, + {VPU_VIU_OSD3, HHI_VPU_MEM_PD_REG2, 4, 2}, + {VPU_VIU_OSD4, HHI_VPU_MEM_PD_REG2, 6, 2}, + {VPU_MAIL_AFBCD, HHI_VPU_MEM_PD_REG2, 8, 2}, + {VPU_VD1_SCALE, HHI_VPU_MEM_PD_REG2, 10, 2}, + {VPU_OSD_BLD34, HHI_VPU_MEM_PD_REG2, 12, 2}, + {VPU_PRIME_DOLBY_RAM, HHI_VPU_MEM_PD_REG2, 14, 2}, + {VPU_VD2_OFIFO, HHI_VPU_MEM_PD_REG2, 16, 2}, + {VPU_RDMA, HHI_VPU_MEM_PD_REG2, 30, 2}, + {VPU_MOD_MAX, VPU_REG_END, 0, 0}, +}; /* ******************************************************* */ /* VPU clock gate table */ diff --git a/drivers/amlogic/media/common/vpu/vpu_module.h b/drivers/amlogic/media/common/vpu/vpu_module.h index d78b21a1ccef..c896af5f5b27 100644 --- a/drivers/amlogic/media/common/vpu/vpu_module.h +++ b/drivers/amlogic/media/common/vpu/vpu_module.h @@ -35,6 +35,7 @@ static char *vpu_mod_table[] = { "viu_super_scaler", "viu_osd_super_scaler", "afbc_dec1", + "viu_di_scaler", "di_pre", "di_post", "viu_sharpness_line_buffer", @@ -52,28 +53,40 @@ static char *vpu_mod_table[] = { "dolby_1a", "dolby_1b", "vpu_arb", - "afbc_dec", + "afbc_dec0", "osd_afbcd", + "vd2_scaler", "vencp", "vencl", "venci", "ldim_stts", + "tv_decoder_cvd2", "xvycc_lut", + "vd2_osd2_scaler", + + "viu_water_mark", + "tcon", + "viu_osd3", + "viu_osd4", + "mail_afbcd", + "vd1_scaler", + "osd_bld34", + "prime_dolby_ram", + "vd2_ofifo", + "rdma", - "viu1_water_mark", "vpu_mod_max", /* for clk_gate */ "vpu_top", "vpu_clkb", - "vpu_rdma", "vpu_misc", "venc_dac", "vlock", "di", "vpp", - "none", + "vpu_max", "none", "none", }; diff --git a/drivers/amlogic/media/common/vpu/vpu_power_init.c b/drivers/amlogic/media/common/vpu/vpu_power_init.c new file mode 100644 index 000000000000..c59aa6cab34e --- /dev/null +++ b/drivers/amlogic/media/common/vpu/vpu_power_init.c @@ -0,0 +1,282 @@ +/* + * drivers/amlogic/media/common/vpu/vpu_power_init.c + * + * Copyright (C) 2017 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vpu_reg.h" +#include "vpu.h" + +void vpu_mem_pd_init_off(void) +{ + return; + + VPUPR("%s\n", __func__); +} + +void vpu_clk_gate_init_off(void) +{ + VPUPR("%s\n", __func__); + + switch (vpu_conf.data->chip_type) { + case VPU_CHIP_TXLX: + /* dolby core1 */ + vpu_vcbus_setb(DOLBY_TV_CLKGATE_CTRL, 1, 10, 2); + vpu_vcbus_setb(DOLBY_TV_CLKGATE_CTRL, 1, 2, 2); + vpu_vcbus_setb(DOLBY_TV_CLKGATE_CTRL, 1, 4, 2); + /* dolby core2 */ + vpu_vcbus_setb(DOLBY_CORE2A_CLKGATE_CTRL, 1, 10, 2); + vpu_vcbus_setb(DOLBY_CORE2A_CLKGATE_CTRL, 1, 2, 2); + vpu_vcbus_setb(DOLBY_CORE2A_CLKGATE_CTRL, 1, 4, 2); + /* dolby core3 */ + vpu_vcbus_setb(DOLBY_CORE3_CLKGATE_CTRL, 0, 1, 1); + vpu_vcbus_setb(DOLBY_CORE3_CLKGATE_CTRL, 1, 2, 2); + break; + case VPU_CHIP_GXM: + vpu_vcbus_write(DOLBY_CORE1_CLKGATE_CTRL, 0x55555555); + vpu_vcbus_write(DOLBY_CORE2A_CLKGATE_CTRL, 0x55555555); + vpu_vcbus_write(DOLBY_CORE3_CLKGATE_CTRL, 0x55555555); + break; + default: + break; + } + + if (vpu_debug_print_flag) + VPUPR("%s finish\n", __func__); +} + +void vpu_module_init_config(void) +{ + VPUPR("%s\n", __func__); + + /* dmc_arb_config */ + vpu_vcbus_write(VPU_RDARB_MODE_L1C1, 0x210000); + vpu_vcbus_write(VPU_RDARB_MODE_L1C2, 0x10000); + vpu_vcbus_write(VPU_RDARB_MODE_L2C1, 0x900000); + vpu_vcbus_write(VPU_WRARB_MODE_L2C1, 0x20000); + + if (vpu_debug_print_flag) + VPUPR("%s finish\n", __func__); +} + +void vpu_power_on_gx(void) +{ + struct vpu_ctrl_s *table; + unsigned int _reg, _bit, _len; + int i = 0, cnt; + + VPUPR("vpu_power_on\n"); + + vpu_ao_setb(AO_RTI_GEN_PWR_SLEEP0, 0, 8, 1); /* [8] power on */ + udelay(20); + + /* power up memories */ + cnt = vpu_conf.data->mem_pd_table_cnt; + table = vpu_conf.data->mem_pd_table; + while (i < cnt) { + if (table[i].vmod == VPU_MOD_MAX) + break; + _reg = table[i].reg; + _bit = table[i].bit; + _len = table[i].len; + vpu_hiu_setb(_reg, 0x0, _bit, _len); + udelay(5); + i++; + } + for (i = 8; i < 16; i++) { + vpu_hiu_setb(HHI_MEM_PD_REG0, 0, i, 1); + udelay(5); + } + udelay(20); + + /* Reset VIU + VENC */ + /* Reset VENCI + VENCP + VADC + VENCL */ + /* Reset HDMI-APB + HDMI-SYS + HDMI-TX + HDMI-CEC */ + vpu_cbus_clr_mask(RESET0_LEVEL, ((1<<5) | (1<<10) | (1<<19) | (1<<13))); + vpu_cbus_clr_mask(RESET1_LEVEL, (1<<5)); + vpu_cbus_clr_mask(RESET2_LEVEL, (1<<15)); + vpu_cbus_clr_mask(RESET4_LEVEL, ((1<<6) | (1<<7) | (1<<13) | (1<<5) | + (1<<9) | (1<<4) | (1<<12))); + vpu_cbus_clr_mask(RESET7_LEVEL, (1<<7)); + + /* Remove VPU_HDMI ISO */ + vpu_ao_setb(AO_RTI_GEN_PWR_SLEEP0, 0, 9, 1); /* [9] VPU_HDMI */ + + /* release Reset */ + vpu_cbus_set_mask(RESET0_LEVEL, ((1 << 5) | (1<<10) | (1<<19) | + (1<<13))); + vpu_cbus_set_mask(RESET1_LEVEL, (1<<5)); + vpu_cbus_set_mask(RESET2_LEVEL, (1<<15)); + vpu_cbus_set_mask(RESET4_LEVEL, ((1<<6) | (1<<7) | (1<<13) | (1<<5) | + (1<<9) | (1<<4) | (1<<12))); + vpu_cbus_set_mask(RESET7_LEVEL, (1<<7)); + + if (vpu_debug_print_flag) + VPUPR("%s finish\n", __func__); +} + +void vpu_power_off_gx(void) +{ + struct vpu_ctrl_s *table; + unsigned int _reg, _bit, _len; + int i = 0, cnt; + + VPUPR("vpu_power_off\n"); + + /* Power down VPU_HDMI */ + /* Enable Isolation */ + vpu_ao_setb(AO_RTI_GEN_PWR_SLEEP0, 1, 9, 1); /* ISO */ + udelay(20); + + /* power down memories */ + cnt = vpu_conf.data->mem_pd_table_cnt; + table = vpu_conf.data->mem_pd_table; + while (i < cnt) { + if (table[i].vmod == VPU_MOD_MAX) + break; + _reg = table[i].reg; + _bit = table[i].bit; + _len = table[i].len; + vpu_hiu_setb(_reg, 0x3, _bit, _len); + udelay(5); + i++; + } + for (i = 8; i < 16; i++) { + vpu_hiu_setb(HHI_MEM_PD_REG0, 0x1, i, 1); + udelay(5); + } + udelay(20); + + /* Power down VPU domain */ + vpu_ao_setb(AO_RTI_GEN_PWR_SLEEP0, 1, 8, 1); /* PDN */ + + vpu_hiu_setb(HHI_VAPBCLK_CNTL, 0, 8, 1); + vpu_hiu_setb(HHI_VPU_CLK_CNTL, 0, 8, 1); + + if (vpu_debug_print_flag) + VPUPR("%s finish\n", __func__); +} + +void vpu_power_on_txlx(void) +{ + struct vpu_ctrl_s *table; + unsigned int _reg, _bit, _len; + int i = 0, cnt; + + VPUPR("vpu_power_on\n"); + + vpu_ao_setb(AO_RTI_GEN_PWR_SLEEP0, 0, 8, 1); /* [8] power on */ + udelay(20); + + /* power up memories */ + cnt = vpu_conf.data->mem_pd_table_cnt; + table = vpu_conf.data->mem_pd_table; + while (i < cnt) { + if (table[i].vmod == VPU_MOD_MAX) + break; + _reg = table[i].reg; + _bit = table[i].bit; + _len = table[i].len; + vpu_hiu_setb(_reg, 0x0, _bit, _len); + udelay(5); + i++; + } + for (i = 8; i < 16; i++) { + vpu_hiu_setb(HHI_MEM_PD_REG0, 0, i, 1); + udelay(5); + } + udelay(20); + + /* Reset VIU + VENC */ + /* Reset VENCI + VENCP + VADC + VENCL */ + /* Reset HDMI-APB + HDMI-SYS + HDMI-TX + HDMI-CEC */ + vpu_cbus_clr_mask(RESET0_LEVEL_TXLX, ((1<<5) | (1<<10) | (1<<19) | + (1<<13))); + vpu_cbus_clr_mask(RESET1_LEVEL_TXLX, (1<<5)); + vpu_cbus_clr_mask(RESET2_LEVEL_TXLX, (1<<15)); + vpu_cbus_clr_mask(RESET4_LEVEL_TXLX, ((1<<6) | (1<<7) | (1<<13) | + (1<<5) | (1<<9) | (1<<4) | (1<<12))); + vpu_cbus_clr_mask(RESET7_LEVEL_TXLX, (1<<7)); + + /* Remove VPU_HDMI ISO */ + vpu_ao_setb(AO_RTI_GEN_PWR_SLEEP0, 0, 9, 1); /* [9] VPU_HDMI */ + + /* release Reset */ + vpu_cbus_set_mask(RESET0_LEVEL_TXLX, ((1 << 5) | (1<<10) | (1<<19) | + (1<<13))); + vpu_cbus_set_mask(RESET1_LEVEL_TXLX, (1<<5)); + vpu_cbus_set_mask(RESET2_LEVEL_TXLX, (1<<15)); + vpu_cbus_set_mask(RESET4_LEVEL_TXLX, ((1<<6) | (1<<7) | (1<<13) | + (1<<5) | (1<<9) | (1<<4) | (1<<12))); + vpu_cbus_set_mask(RESET7_LEVEL_TXLX, (1<<7)); + + if (vpu_debug_print_flag) + VPUPR("%s finish\n", __func__); +} + +void vpu_power_off_txlx(void) +{ + struct vpu_ctrl_s *table; + unsigned int _reg, _bit, _len; + int i = 0, cnt; + + VPUPR("vpu_power_off\n"); + + /* Power down VPU_HDMI */ + /* Enable Isolation */ + vpu_ao_setb(AO_RTI_GEN_PWR_SLEEP0, 1, 9, 1); /* ISO */ + udelay(20); + + /* power down memories */ + cnt = vpu_conf.data->mem_pd_table_cnt; + table = vpu_conf.data->mem_pd_table; + while (i < cnt) { + if (table[i].vmod == VPU_MOD_MAX) + break; + _reg = table[i].reg; + _bit = table[i].bit; + _len = table[i].len; + vpu_hiu_setb(_reg, 0x3, _bit, _len); + udelay(5); + i++; + } + for (i = 8; i < 16; i++) { + vpu_hiu_setb(HHI_MEM_PD_REG0, 0x1, i, 1); + udelay(5); + } + udelay(20); + + /* Power down VPU domain */ + vpu_ao_setb(AO_RTI_GEN_PWR_SLEEP0, 1, 8, 1); /* PDN */ + + vpu_hiu_setb(HHI_VAPBCLK_CNTL, 0, 8, 1); + vpu_hiu_setb(HHI_VPU_CLK_CNTL, 0, 8, 1); + + if (vpu_debug_print_flag) + VPUPR("%s finish\n", __func__); +} + diff --git a/drivers/amlogic/media/common/vpu/vpu_reg.c b/drivers/amlogic/media/common/vpu/vpu_reg.c index 3e6f61fb3921..d70a37beedf4 100644 --- a/drivers/amlogic/media/common/vpu/vpu_reg.c +++ b/drivers/amlogic/media/common/vpu/vpu_reg.c @@ -98,3 +98,49 @@ void vpu_vcbus_clr_mask(unsigned int _reg, unsigned int _mask) vpu_vcbus_write(_reg, (vpu_vcbus_read(_reg) & (~(_mask)))); } +unsigned int vpu_ao_read(unsigned int _reg) +{ + return aml_read_aobus(_reg); +}; + +void vpu_ao_write(unsigned int _reg, unsigned int _value) +{ + aml_write_aobus(_reg, _value); +}; + +void vpu_ao_setb(unsigned int _reg, unsigned int _value, + unsigned int _start, unsigned int _len) +{ + vpu_ao_write(_reg, ((vpu_ao_read(_reg) & + ~(((1L << (_len))-1) << (_start))) | + (((_value)&((1L<<(_len))-1)) << (_start)))); +} + +unsigned int vpu_cbus_read(unsigned int _reg) +{ + return aml_read_cbus(_reg); +}; + +void vpu_cbus_write(unsigned int _reg, unsigned int _value) +{ + aml_write_cbus(_reg, _value); +}; + +void vpu_cbus_setb(unsigned int _reg, unsigned int _value, + unsigned int _start, unsigned int _len) +{ + vpu_cbus_write(_reg, ((vpu_cbus_read(_reg) & + ~(((1L << (_len))-1) << (_start))) | + (((_value)&((1L<<(_len))-1)) << (_start)))); +} + +void vpu_cbus_set_mask(unsigned int _reg, unsigned int _mask) +{ + vpu_cbus_write(_reg, (vpu_cbus_read(_reg) | (_mask))); +} + +void vpu_cbus_clr_mask(unsigned int _reg, unsigned int _mask) +{ + vpu_cbus_write(_reg, (vpu_cbus_read(_reg) & (~(_mask)))); +} + diff --git a/drivers/amlogic/media/common/vpu/vpu_reg.h b/drivers/amlogic/media/common/vpu/vpu_reg.h index 8e3e21e5f665..e734195dda44 100644 --- a/drivers/amlogic/media/common/vpu/vpu_reg.h +++ b/drivers/amlogic/media/common/vpu/vpu_reg.h @@ -28,7 +28,7 @@ * ********************************* */ -#define AO_RTI_GEN_PWR_SLEEP0 ((0x00 << 10) | (0x3a << 2)) +#define AO_RTI_GEN_PWR_SLEEP0 (0x3a << 2) /* HHI bus */ #define HHI_GP1_PLL_CNTL 0x16 @@ -71,6 +71,31 @@ #define RESET6_LEVEL 0x1126 #define RESET7_LEVEL 0x1127 +#define RESET0_REGISTER_TXLX 0x0401 +#define RESET1_REGISTER_TXLX 0x0402 +#define RESET2_REGISTER_TXLX 0x0403 +#define RESET3_REGISTER_TXLX 0x0404 +#define RESET4_REGISTER_TXLX 0x0405 +#define RESET5_REGISTER_TXLX 0x0406 +#define RESET6_REGISTER_TXLX 0x0407 +#define RESET7_REGISTER_TXLX 0x0408 +#define RESET0_MASK_TXLX 0x0410 +#define RESET1_MASK_TXLX 0x0411 +#define RESET2_MASK_TXLX 0x0412 +#define RESET3_MASK_TXLX 0x0413 +#define RESET4_MASK_TXLX 0x0414 +#define RESET5_MASK_TXLX 0x0415 +#define RESET6_MASK_TXLX 0x0416 +#define RESET7_MASK_TXLX 0x0418 +#define RESET0_LEVEL_TXLX 0x0420 +#define RESET1_LEVEL_TXLX 0x0421 +#define RESET2_LEVEL_TXLX 0x0422 +#define RESET3_LEVEL_TXLX 0x0423 +#define RESET4_LEVEL_TXLX 0x0424 +#define RESET5_LEVEL_TXLX 0x0425 +#define RESET6_LEVEL_TXLX 0x0426 +#define RESET7_LEVEL_TXLX 0x0427 + /* vpu clk gate */ /* hiu_bus */ #define HHI_GCLK_OTHER 0x54 @@ -95,6 +120,17 @@ #define VPP_OSDSR_GCLK_CTRL 0x1d78 #define VPP_XVYCC_GCLK_CTRL 0x1d79 +#define DOLBY_TV_CLKGATE_CTRL 0x33f1 +#define DOLBY_CORE1_CLKGATE_CTRL 0x33f2 +#define DOLBY_CORE2A_CLKGATE_CTRL 0x3432 +#define DOLBY_CORE3_CLKGATE_CTRL 0x36f0 + +#define VPU_RDARB_MODE_L1C1 0x2790 +#define VPU_RDARB_MODE_L1C2 0x2799 +#define VPU_RDARB_MODE_L2C1 0x279d +#define VPU_WRARB_MODE_L2C1 0x27a2 + + extern unsigned int vpu_hiu_read(unsigned int _reg); extern void vpu_hiu_write(unsigned int _reg, unsigned int _value); extern void vpu_hiu_setb(unsigned int _reg, unsigned int _value, @@ -113,4 +149,16 @@ extern unsigned int vpu_vcbus_getb(unsigned int _reg, extern void vpu_vcbus_set_mask(unsigned int _reg, unsigned int _mask); extern void vpu_vcbus_clr_mask(unsigned int _reg, unsigned int _mask); +extern unsigned int vpu_ao_read(unsigned int _reg); +extern void vpu_ao_write(unsigned int _reg, unsigned int _value); +extern void vpu_ao_setb(unsigned int _reg, unsigned int _value, + unsigned int _start, unsigned int _len); + +extern unsigned int vpu_cbus_read(unsigned int _reg); +extern void vpu_cbus_write(unsigned int _reg, unsigned int _value); +extern void vpu_cbus_setb(unsigned int _reg, unsigned int _value, + unsigned int _start, unsigned int _len); +extern void vpu_cbus_set_mask(unsigned int _reg, unsigned int _mask); +extern void vpu_cbus_clr_mask(unsigned int _reg, unsigned int _mask); + #endif diff --git a/include/linux/amlogic/media/vpu/vpu.h b/include/linux/amlogic/media/vpu/vpu.h index 0fa66d838043..e5735695458a 100644 --- a/include/linux/amlogic/media/vpu/vpu.h +++ b/include/linux/amlogic/media/vpu/vpu.h @@ -35,6 +35,7 @@ enum vpu_mod_e { VPU_VIU_SRSCL, /* reg0[21:20] //GXBB, GXTVBB, TXLX */ VPU_VIU_OSDSR, /* reg0[23:22] //GXBB */ VPU_AFBC_DEC1, /* reg0[23:22] //GXTVBB, TXLX */ + VPU_VIU_DI_SCALE, /* reg0[25:24] //G12A */ VPU_DI_PRE, /* reg0[27:26] //common */ VPU_DI_POST, /* reg0[29:28] //common */ VPU_SHARP, /* reg0[31:30] //common */ @@ -54,19 +55,31 @@ enum vpu_mod_e { VPU_VPU_ARB, /* reg1[15:14] //GXBB, GXTVBB, GXL, TXLX */ VPU_AFBC_DEC, /* reg1[17:16] //GXBB, GXTVBB, TXL, TXLX */ VPU_OSD_AFBCD, /* reg1[19:18] //TXLX */ + VPU_VD2_SCALE, /* reg1[19:18] //G12A */ VPU_VENCP, /* reg1[21:20] //common */ VPU_VENCL, /* reg1[23:22] //common */ VPU_VENCI, /* reg1[25:24] //common */ VPU_LDIM_STTS, /* reg1[29:28] //GXTVBB, GXL, TXL, TXLX */ + VPU_TV_DEC_CVD2, /* reg1[29:28] */ VPU_XVYCC_LUT, /* reg1[31:30] //GXTVBB, GXL, TXL, TXLX */ + VPU_VD2_OSD2_SCALE, /* reg1[31:30] //G12A */ + + VPU_VIU_WM, /* reg2[1:0] //GXL, TXL, TXLX */ + VPU_TCON, /* reg2[3:2] //TXHD */ + VPU_VIU_OSD3, /* reg2[5:4] //G12A */ + VPU_VIU_OSD4, /* reg2[7:6] //G12A */ + VPU_MAIL_AFBCD, /* reg2[9:8] //G12A */ + VPU_VD1_SCALE, /* reg2[11:10] //G12A */ + VPU_OSD_BLD34, /* reg2[13:12] //G12A */ + VPU_PRIME_DOLBY_RAM, /* reg2[15:14] //G12A */ + VPU_VD2_OFIFO, /* reg2[17:16] //G12A */ + VPU_RDMA, /* reg2[31:30] //G12A */ - VPU_VIU1_WM, /* reg2[1:0] //GXL, TXL, TXLX */ VPU_MOD_MAX, /* for clk_gate */ VPU_VPU_TOP, VPU_VPU_CLKB, - VPU_RDMA, VPU_MISC, /* hs,vs,interrupt */ VPU_VENC_DAC, VPU_VLOCK,