diff mbox

[U-Boot,17/20] tegra: nyan-big: Add additional clock and kernel init

Message ID 1424212195-7501-18-git-send-email-sjg@chromium.org
State Superseded
Delegated to: Tom Warren
Headers show

Commit Message

Simon Glass Feb. 17, 2015, 10:29 p.m. UTC
We need to turn on all audio-related clocks for the kernel to boot.
Otherwise it will hang when trying to enable audio.

Also for Linux set up the ODMDATA and graphics driver video protection.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 board/nvidia/nyan-big/nyan-big.c | 76 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

Comments

Stephen Warren Feb. 25, 2015, 11:23 p.m. UTC | #1
On 02/17/2015 03:29 PM, Simon Glass wrote:
> We need to turn on all audio-related clocks for the kernel to boot.
> Otherwise it will hang when trying to enable audio.

This certainly isn't true for the upstream kernel; is this some bug in 
the ChromeOS kernel? If so, we should explicitly call this out in the 
commit description.

> Also for Linux set up the ODMDATA and graphics driver video protection.

Why doesn't ODMDATA come from the BCT? The way this is suppose to work 
is that the boot ROM copies the BCT into IRAM, and U-Boot (or indeed any 
bootloader) copies the ODMDATA field from the BCT in IRAM into the PMC 
scratch20 register. This logic is already all in place in U-Boot, and 
indeed any NVIDIA-authored bootloader AFAIK.

Is this U-Boot port intended to run as a Coreboot payload rather than 
natively, and Coreboot is somehow corrupting the copy of the BCT in 
IRAM? If so, we should explicitly call this out in the commit description.

I would personally want to (be able to) make my SPI flash r/w and 
replace Coreboot with U-Boot. Perhaps we need different board names for 
those two use-cases; something like nyan-big for the Coreboot payload, 
and nyan-big-native for the version you'd write directly into SPI?
Simon Glass March 29, 2015, 1:02 p.m. UTC | #2
Hi Stephen,

On 25 February 2015 at 16:23, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 02/17/2015 03:29 PM, Simon Glass wrote:
>>
>> We need to turn on all audio-related clocks for the kernel to boot.
>> Otherwise it will hang when trying to enable audio.
>
>
> This certainly isn't true for the upstream kernel; is this some bug in the
> ChromeOS kernel? If so, we should explicitly call this out in the commit
> description.

OK I'll adjust the commit message. At some point perhaps this problem
will go away. Chrome OS is running kernel v3.10 on this device.

>
>> Also for Linux set up the ODMDATA and graphics driver video protection.
>
>
> Why doesn't ODMDATA come from the BCT? The way this is suppose to work is
> that the boot ROM copies the BCT into IRAM, and U-Boot (or indeed any
> bootloader) copies the ODMDATA field from the BCT in IRAM into the PMC
> scratch20 register. This logic is already all in place in U-Boot, and indeed
> any NVIDIA-authored bootloader AFAIK.

OK, so perhaps I can just drop this code. It might just be a hack in Coreboot.

>
> Is this U-Boot port intended to run as a Coreboot payload rather than
> natively, and Coreboot is somehow corrupting the copy of the BCT in IRAM? If
> so, we should explicitly call this out in the commit description.

No, there really isn't any point in running U-Boot as a Coreboot
payload, since U-Boot can do all the init itself. This series is for
running U-Boot stand-alone on Nyan-big.

>
> I would personally want to (be able to) make my SPI flash r/w and replace
> Coreboot with U-Boot. Perhaps we need different board names for those two
> use-cases; something like nyan-big for the Coreboot payload, and
> nyan-big-native for the version you'd write directly into SPI?

See above... if we can get the display stuff merged then I could do
this also. But without a display it's missing a big piece.

Regards,
Simon
diff mbox

Patch

diff --git a/board/nvidia/nyan-big/nyan-big.c b/board/nvidia/nyan-big/nyan-big.c
index ae8874b..987ec7c 100644
--- a/board/nvidia/nyan-big/nyan-big.c
+++ b/board/nvidia/nyan-big/nyan-big.c
@@ -8,7 +8,12 @@ 
 #include <common.h>
 #include <errno.h>
 #include <asm/gpio.h>
+#include <asm/io.h>
 #include <asm/arch/pinmux.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/mc.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra/pmc.h>
 #include <power/as3722.h>
 #include <power/pmic.h>
 #include "pinmux-config-nyan-big.h"
@@ -57,3 +62,74 @@  int tegra_lcd_pmic_init(int board_id)
 
 	return 0;
 }
+
+/* Setup required information for Linux kernel */
+static void setup_kernel_info(void)
+{
+	struct pmc_ctlr *pmc = (void *)NV_PA_PMC_BASE;
+	struct mc_ctlr *mc = (void *)NV_PA_MC_BASE;
+
+	/*
+	 * pmc.odmdata: [18:19]: console type, [15:17]: UART id
+	 * TODO: Derive this from the current settings
+	 */
+	writel(0x80080000, &pmc->pmc_scratch20);
+
+	/* The kernel graphics driver needs this region locked down */
+	writel(0, &mc->mc_video_protect_bom);
+	writel(0, &mc->mc_video_protect_size_mb);
+	writel(1, &mc->mc_video_protect_reg_ctrl);
+}
+
+/*
+ * We need to take ALL audio devices conntected to AHUB (AUDIO, APBIF,
+ * I2S, DAM, AMX, ADX, SPDIF, AFC) out of reset and enable the clocks.
+ * Otherwise reading AHUB devices will hang when the kernel boots.
+ */
+static void enable_required_clocks(void)
+{
+	static enum periph_id ids[] = {
+		PERIPH_ID_I2S0,
+		PERIPH_ID_I2S1,
+		PERIPH_ID_I2S2,
+		PERIPH_ID_I2S3,
+		PERIPH_ID_I2S4,
+		PERIPH_ID_AUDIO,
+		PERIPH_ID_APBIF,
+		PERIPH_ID_DAM0,
+		PERIPH_ID_DAM1,
+		PERIPH_ID_DAM2,
+		PERIPH_ID_AMX0,
+		PERIPH_ID_AMX1,
+		PERIPH_ID_ADX0,
+		PERIPH_ID_ADX1,
+		PERIPH_ID_SPDIF,
+		PERIPH_ID_AFC0,
+		PERIPH_ID_AFC1,
+		PERIPH_ID_AFC2,
+		PERIPH_ID_AFC3,
+		PERIPH_ID_AFC4,
+		PERIPH_ID_AFC5,
+		PERIPH_ID_EXTPERIPH1
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ids); i++)
+		clock_enable(ids[i]);
+	udelay(2);
+	for (i = 0; i < ARRAY_SIZE(ids); i++)
+		reset_set_enable(ids[i], 0);
+}
+
+int nvidia_board_init(void)
+{
+	clock_start_periph_pll(PERIPH_ID_EXTPERIPH1, CLOCK_ID_OSC, 12000000);
+	clock_start_periph_pll(PERIPH_ID_I2S1, CLOCK_ID_OSC, 1500000);
+
+	/* For external MAX98090 audio codec */
+	clock_external_output(1);
+	setup_kernel_info();
+	enable_required_clocks();
+
+	return 0;
+}