Yidi Lin has submitted this change. ( https://review.coreboot.org/c/coreboot/+/85188?usp=email )
Change subject: soc/mediatek/mt8196: Add MMinfra driver support ......................................................................
soc/mediatek/mt8196: Add MMinfra driver support
MMinfra is the Multimedia Infrastructure. All the Multimedia modules depend on it. This file adds some initial settings for MMinfra.
Test=Build pass BUG=b:317009620
Signed-off-by: Xueqi Zhang xueqi.zhang@mediatek.corp-partner.google.com Change-Id: Ie86f141a0957fc60d4973875c0dbcbdb57be1f75 Reviewed-on: https://review.coreboot.org/c/coreboot/+/85188 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Yidi Lin yidilin@google.com Reviewed-by: Yu-Ping Wu yupingso@google.com --- M src/soc/mediatek/mt8196/Makefile.mk M src/soc/mediatek/mt8196/bootblock.c M src/soc/mediatek/mt8196/include/soc/addressmap.h A src/soc/mediatek/mt8196/include/soc/mminfra.h A src/soc/mediatek/mt8196/mminfra.c 5 files changed, 160 insertions(+), 1 deletion(-)
Approvals: Yu-Ping Wu: Looks good to me, approved build bot (Jenkins): Verified Yidi Lin: Looks good to me, approved
diff --git a/src/soc/mediatek/mt8196/Makefile.mk b/src/soc/mediatek/mt8196/Makefile.mk index 9652a1e..13ba5c3 100644 --- a/src/soc/mediatek/mt8196/Makefile.mk +++ b/src/soc/mediatek/mt8196/Makefile.mk @@ -15,6 +15,7 @@ bootblock-y += ../common/bootblock.c bootblock.c bootblock-y += ../common/early_init.c bootblock-y += ../common/lastbus_v2.c lastbus.c +bootblock-y += mminfra.c bootblock-y += ../common/mmu_operations.c bootblock-y += mtcmos.c bootblock-$(CONFIG_PCI) += ../common/pcie.c pcie.c diff --git a/src/soc/mediatek/mt8196/bootblock.c b/src/soc/mediatek/mt8196/bootblock.c index a864bff..d675a5a 100644 --- a/src/soc/mediatek/mt8196/bootblock.c +++ b/src/soc/mediatek/mt8196/bootblock.c @@ -4,6 +4,7 @@ #include <bootblock_common.h> #include <soc/early_init.h> #include <soc/lastbus_v2.h> +#include <soc/mminfra.h> #include <soc/mmu_operations.h> #include <soc/pll.h> #include <soc/spm_mtcmos.h> @@ -17,6 +18,7 @@ mtk_wdt_init(); mt_pll_init(); mtcmos_init(); + mminfra_post_init(); mt_pll_post_init(); mtcmos_post_init(); early_init_clear(); diff --git a/src/soc/mediatek/mt8196/include/soc/addressmap.h b/src/soc/mediatek/mt8196/include/soc/addressmap.h index cc57292..3de16fd 100644 --- a/src/soc/mediatek/mt8196/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8196/include/soc/addressmap.h @@ -142,6 +142,7 @@ SSR_TOP_BASE = IO_PHYS + 0x08000000, APINFRA_SSR_AO_DEBUG_BASE = IO_PHYS + 0x080F1000, AUDIO_BASE = IO_PHYS + 0x0A110000, + VLP_AO_BASE = IO_PHYS + 0x0C000000, VLPCFG_BASE = IO_PHYS + 0x0C001000, SPM_BASE = IO_PHYS + 0x0C004000, SPM_PBUS_BASE = IO_PHYS + 0x0C00D000, @@ -171,7 +172,13 @@ MMVOTE_CAM_MAIN_R1A_BASE = IO_PHYS + 0x1A000000, MMVOTE_CCU_MAIN_BASE = IO_PHYS + 0x1C800000, MMVOTE_DISP_VDISP_AO_CONFIG_BASE = IO_PHYS + 0x1E800000, - MMUP_AO_DEBUG_BASE = IO_PHYS + 0x21A22000, + MMINFRA_CONFIG = IO_PHYS + 0x20000000, + MMINFRA_SEC_CONFIG = IO_PHYS + 0x20010000, + MMINFRA_AO_CONFIG = IO_PHYS + 0x20080000, + MMINFRA_BUS_HRE_BASE = IO_PHYS + 0x200A0000, + MMINFRA_BUS_HRE2_BASE = IO_PHYS + 0x200B0000, + MMINFRA1_CONFIG = IO_PHYS + 0x20A00000, + MMUP_AO_DEBUG_BASE = IO_PHYS + 0x21A22000, MMVOTE_BASE = IO_PHYS + 0x21B00000, MMPC_BASE = IO_PHYS + 0x21B50000, MMSYS_CONFIG_BASE = IO_PHYS + 0x22000000, diff --git a/src/soc/mediatek/mt8196/include/soc/mminfra.h b/src/soc/mediatek/mt8196/include/soc/mminfra.h new file mode 100644 index 0000000..13a4e5c --- /dev/null +++ b/src/soc/mediatek/mt8196/include/soc/mminfra.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_MMINFRA_H__ +#define __SOC_MEDIATEK_MMINFRA_H__ + +/* mminfra_ao */ +#define MMINFRA_GCE_PROT_EN (MMINFRA_AO_CONFIG + 0x428) + +/* mminfra0 */ +#define MMINFRA_MM0_GALS_PROT_RX_EN (MMINFRA_CONFIG + 0x9C0) +#define MMINFRA_MM0_GALS_PROT_RX_RDY (MMINFRA_CONFIG + 0x9C4) +#define MMINFRA_MM0_GALS_PROT_TX_EN (MMINFRA_CONFIG + 0x9C8) +#define MMINFRA_MM0_GALS_PROT_TX_RDY (MMINFRA_CONFIG + 0x9CC) +#define MMINFRA_MM1_GALS_PROT_RX_EN (MMINFRA_CONFIG + 0x9D0) +#define MMINFRA_MM1_GALS_PROT_RX_RDY (MMINFRA_CONFIG + 0x9D4) +#define MMINFRA_MM1_GALS_PROT_TX_EN (MMINFRA_CONFIG + 0x9D8) +#define MMINFRA_MM1_GALS_PROT_TX_RDY (MMINFRA_CONFIG + 0x9DC) + +#define GCE_D_SLEEPPORT_RX_EN BIT(0) +#define GCE_D_HAND_SLEEPPORT_RX_EN BIT(1) +#define GCE_D_HAND_SLEEPPORT_TX_EN BIT(2) +#define GCE_M_SLEEPPORT_RX_EN BIT(8) +#define GCE_M_HAND_SLEEPPORT_RX_EN BIT(9) +#define GCE_M_HAND_SLEEPPORT_TX_EN BIT(10) + +#define VLP_AO_RSVD6 (VLP_AO_BASE + 0x918) + +/* mmpc */ +#define MMPC_PM_BOOT_UP_PWR_CON (MMPC_BASE + 0x1B8) +#define MM_INFRA0_PM_BOOT_UP BIT(16) +#define MM_INFRA1_PM_BOOT_UP BIT(17) + +void mminfra_post_init(void); + +#endif diff --git a/src/soc/mediatek/mt8196/mminfra.c b/src/soc/mediatek/mt8196/mminfra.c new file mode 100644 index 0000000..55ddf47 --- /dev/null +++ b/src/soc/mediatek/mt8196/mminfra.c @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/mmio.h> +#include <soc/addressmap.h> +#include <soc/mminfra.h> +#include <soc/spm_mtcmos.h> +#include <stddef.h> +#include <string.h> +#include <timer.h> +#include <types.h> + +#define TIMEOUT_US 20 + +static void wait_for_write_done(u32 write_reg, u32 status_reg, u32 val) +{ + write32p(write_reg, val); + + if (!wait_us(TIMEOUT_US, read32p(status_reg) == val)) + die("Wait write done timeout\n"); +} + +static void mm_gce_lock_prot_en(void) +{ + setbits32p(MMINFRA_GCE_PROT_EN, + GCE_D_SLEEPPORT_RX_EN | GCE_D_HAND_SLEEPPORT_RX_EN | + GCE_D_HAND_SLEEPPORT_TX_EN | GCE_M_SLEEPPORT_RX_EN | + GCE_M_HAND_SLEEPPORT_RX_EN | GCE_M_HAND_SLEEPPORT_TX_EN); +} + +static void mm_gce_release_prot_en(void) +{ + write32p(MMINFRA_GCE_PROT_EN, 0); +} + +static void mm_infra0_lock_prot_en(void) +{ + wait_for_write_done(MMINFRA_MM0_GALS_PROT_TX_EN, + MMINFRA_MM0_GALS_PROT_TX_RDY, 0xff); + wait_for_write_done(MMINFRA_MM0_GALS_PROT_RX_EN, + MMINFRA_MM0_GALS_PROT_RX_RDY, 0xfffff); +} + +static void mm_infra0_release_prot_en(void) +{ + write32p(MMINFRA_MM0_GALS_PROT_RX_EN, 0); + write32p(MMINFRA_MM0_GALS_PROT_TX_EN, 0); +} + +static void mm_infra1_lock_prot_en(void) +{ + mm_gce_lock_prot_en(); + wait_for_write_done(MMINFRA_MM1_GALS_PROT_TX_EN, + MMINFRA_MM1_GALS_PROT_TX_RDY, 0x3f); + wait_for_write_done(MMINFRA_MM1_GALS_PROT_RX_EN, + MMINFRA_MM1_GALS_PROT_RX_RDY, 0xf); +} + +static void mm_infra1_release_prot_en(void) +{ + write32p(MMINFRA_MM1_GALS_PROT_RX_EN, 0); + write32p(MMINFRA_MM1_GALS_PROT_TX_EN, 0); + mm_gce_release_prot_en(); +} + +static int pd_mm_infra0_pre_on(void) +{ + setbits32p(MMPC_PM_BOOT_UP_PWR_CON, MM_INFRA0_PM_BOOT_UP | MM_INFRA1_PM_BOOT_UP); + return 0; +} + +static int pd_mm_infra0_post_on(void) +{ + mm_infra0_release_prot_en(); + return 0; +} + +static int pd_mm_infra0_pre_off(void) +{ + mm_infra0_lock_prot_en(); + return 0; +} + +static int pd_mm_infra1_post_on(void) +{ + mm_infra1_release_prot_en(); + write32p(VLP_AO_RSVD6, 0x1); + return 0; +} + +static int pd_mm_infra1_pre_off(void) +{ + mm_infra1_lock_prot_en(); + return 0; +} + +static struct mtcmos_cb mm_infra0_pb_cb = { + .pre_on = pd_mm_infra0_pre_on, + .post_on = pd_mm_infra0_post_on, + .pre_off = pd_mm_infra0_pre_off, +}; + +static struct mtcmos_cb mm_infra1_pb_cb = { + .post_on = pd_mm_infra1_post_on, + .pre_off = pd_mm_infra1_pre_off, +}; + +void mminfra_post_init(void) +{ + if (mtcmos_cb_register(MTCMOS_ID_MM_INFRA0, &mm_infra0_pb_cb)) + return; + + mtcmos_cb_register(MTCMOS_ID_MM_INFRA1, &mm_infra1_pb_cb); +}