mb/google/cherry: support max98390 audio amp

The Cherry follower projects may choose Max98390 for audio output
so we have to add a new config CHERRY_USE_MAX98390. Also, the
'dojo' device is the first one to use it.

BUG=b:204391159
BRANCH=cherry
TEST=emerge-cherry coreboot
TEST=Verify beep function through CLI in depthcharge successfully

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
Change-Id: I9b6bc5a5520292dd502b0389217f5062479b4490
Reviewed-on: https://review.coreboot.org/c/coreboot/+/63083
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/mainboard/google/cherry/Kconfig b/src/mainboard/google/cherry/Kconfig
index e45b259..51ad029 100644
--- a/src/mainboard/google/cherry/Kconfig
+++ b/src/mainboard/google/cherry/Kconfig
@@ -57,11 +57,18 @@
 	hex
 	default 0x0
 
-config CHERRY_USE_RT1011
-	bool
-	default n
+choice
+	prompt "Speaker AMP for Cherry"
+	default CHERRY_USE_RT1019 if BOARD_GOOGLE_CHERRY || BOARD_GOOGLE_TOMATO
+	default CHERRY_USE_MAX98390 if BOARD_GOOGLE_DOJO
 
+config CHERRY_USE_RT1011
+	bool "RT1011"
 config CHERRY_USE_RT1019
-	bool
-	default y
+	bool "RT1019"
+config CHERRY_USE_MAX98390
+	bool "MAX98390"
+
+endchoice
+
 endif
diff --git a/src/mainboard/google/cherry/chromeos.c b/src/mainboard/google/cherry/chromeos.c
index 13b673c..301a0bc 100644
--- a/src/mainboard/google/cherry/chromeos.c
+++ b/src/mainboard/google/cherry/chromeos.c
@@ -47,12 +47,18 @@
 		{GPIO_EN_SPK.id, ACTIVE_HIGH, -1, "speaker enable"},
 	};
 
+	struct lb_gpio spk_gpios[] = {
+		{GPIO_EN_SPK.id, ACTIVE_HIGH, -1, "speaker enable"},
+	};
+
 	lb_add_gpios(gpios, chromeos_gpios, ARRAY_SIZE(chromeos_gpios));
 
 	if (CONFIG(CHERRY_USE_RT1019))
 		lb_add_gpios(gpios, rt1019_gpios, ARRAY_SIZE(rt1019_gpios));
 	else if (CONFIG(CHERRY_USE_RT1011))
 		lb_add_gpios(gpios, rt1011_gpios, ARRAY_SIZE(rt1011_gpios));
+	else if (CONFIG(CHERRY_USE_MAX98390))
+		lb_add_gpios(gpios, spk_gpios, ARRAY_SIZE(spk_gpios));
 }
 
 int tis_plat_irq_status(void)
diff --git a/src/mainboard/google/cherry/mainboard.c b/src/mainboard/google/cherry/mainboard.c
index 92d8ee1..3fb599b 100644
--- a/src/mainboard/google/cherry/mainboard.c
+++ b/src/mainboard/google/cherry/mainboard.c
@@ -92,6 +92,27 @@
 	return true;
 }
 
+static void configure_i2s(void)
+{
+	/* Audio PWR */
+	mtcmos_audio_power_on();
+	mtcmos_protect_audio_bus();
+
+	/* SoC I2S */
+	gpio_set_mode(GPIO(GPIO_02), PAD_GPIO_02_FUNC_TDMIN_LRCK);
+	gpio_set_mode(GPIO(GPIO_03), PAD_GPIO_03_FUNC_TDMIN_BCK);
+	gpio_set_mode(GPIO(I2SO2_D0), PAD_I2SO2_D0_FUNC_I2SO2_D0);
+}
+
+static void configure_audio(void)
+{
+	if (CONFIG(CHERRY_USE_RT1011) || CONFIG(CHERRY_USE_MAX98390))
+		mtk_i2c_bus_init(I2C2, I2C_SPEED_FAST);
+
+	if (CONFIG(CHERRY_USE_MAX98390))
+		configure_i2s();
+}
+
 static void mainboard_init(struct device *dev)
 {
 	if (display_init_required())
@@ -103,9 +124,7 @@
 	mtk_msdc_configure_sdcard();
 	setup_usb_host();
 
-	/* for audio usage */
-	if (CONFIG(CHERRY_USE_RT1011))
-		mtk_i2c_bus_init(I2C2, I2C_SPEED_FAST);
+	configure_audio();
 
 	if (dpm_init())
 		printk(BIOS_ERR, "dpm init failed, DVFS may not work\n");
diff --git a/src/soc/mediatek/mt8195/include/soc/addressmap.h b/src/soc/mediatek/mt8195/include/soc/addressmap.h
index f2714da..a5c4b0d 100644
--- a/src/soc/mediatek/mt8195/include/soc/addressmap.h
+++ b/src/soc/mediatek/mt8195/include/soc/addressmap.h
@@ -49,6 +49,7 @@
 	SSPM_SRAM_BASE		= IO_PHYS + 0x00400000,
 	SSPM_CFG_BASE		= IO_PHYS + 0x00440000,
 	SCP_CFG_BASE		= IO_PHYS + 0x00700000,
+	SCP_ADSP_CFG_BASE	= IO_PHYS + 0x00720000,
 	DPM_PM_SRAM_BASE	= IO_PHYS + 0x00900000,
 	DPM_DM_SRAM_BASE	= IO_PHYS + 0x00920000,
 	DPM_CFG_BASE		= IO_PHYS + 0x00940000,
diff --git a/src/soc/mediatek/mt8195/pll.c b/src/soc/mediatek/mt8195/pll.c
index df4ae30..046008c 100644
--- a/src/soc/mediatek/mt8195/pll.c
+++ b/src/soc/mediatek/mt8195/pll.c
@@ -28,6 +28,14 @@
 check_member(mt8195_pericfg_ao_regs, peri_module_sw_cg_0_set, 0x0010);
 static struct mt8195_pericfg_ao_regs *const mt8195_pericfg_ao = (void *)PERICFG_AO_BASE;
 
+struct mt8195_scp_adsp_regs {
+	u32 reserved1[96];
+	u32 audiodsp_ck_cg;	/* 0x180 */
+};
+check_member(mt8195_scp_adsp_regs, audiodsp_ck_cg, 0x0180);
+static struct mt8195_scp_adsp_regs *const mt8195_scp_adsp =
+	(void *)SCP_ADSP_CFG_BASE;
+
 enum mux_id {
 	TOP_AXI_SEL,
 	TOP_SPM_SEL,
@@ -760,6 +768,12 @@
 
 	/* turn off unused clock */
 	write32(&mt8195_pericfg_ao->peri_module_sw_cg_0_set, 0x10);
+
+	/* scp_dsp for audio */
+	clrbits32(&mt8195_scp_adsp->audiodsp_ck_cg, BIT(0));
+
+	/* audio 26M */
+	setbits32(&mt8195_infracfg_ao->module_sw_cg_2_clr, BIT(4));
 }
 
 void mt_pll_raise_little_cpu_freq(u32 freq)