1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * (C) Copyright 2014
3*4882a593Smuzhiyun * NVIDIA Corporation <www.nvidia.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <common.h>
9*4882a593Smuzhiyun #include <dm.h>
10*4882a593Smuzhiyun #include <errno.h>
11*4882a593Smuzhiyun #include <asm/gpio.h>
12*4882a593Smuzhiyun #include <asm/io.h>
13*4882a593Smuzhiyun #include <asm/arch/pinmux.h>
14*4882a593Smuzhiyun #include <asm/arch/clock.h>
15*4882a593Smuzhiyun #include <asm/arch/mc.h>
16*4882a593Smuzhiyun #include <asm/arch-tegra/clk_rst.h>
17*4882a593Smuzhiyun #include <asm/arch-tegra/pmc.h>
18*4882a593Smuzhiyun #include <power/as3722.h>
19*4882a593Smuzhiyun #include <power/pmic.h>
20*4882a593Smuzhiyun #include "pinmux-config-nyan-big.h"
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun /*
23*4882a593Smuzhiyun * Routine: pinmux_init
24*4882a593Smuzhiyun * Description: Do individual peripheral pinmux configs
25*4882a593Smuzhiyun */
pinmux_init(void)26*4882a593Smuzhiyun void pinmux_init(void)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun gpio_config_table(nyan_big_gpio_inits,
29*4882a593Smuzhiyun ARRAY_SIZE(nyan_big_gpio_inits));
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun pinmux_config_pingrp_table(nyan_big_pingrps,
32*4882a593Smuzhiyun ARRAY_SIZE(nyan_big_pingrps));
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun pinmux_config_drvgrp_table(nyan_big_drvgrps,
35*4882a593Smuzhiyun ARRAY_SIZE(nyan_big_drvgrps));
36*4882a593Smuzhiyun }
37*4882a593Smuzhiyun
tegra_board_id(void)38*4882a593Smuzhiyun int tegra_board_id(void)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun static const int vector[] = {TEGRA_GPIO(Q, 3), TEGRA_GPIO(T, 1),
41*4882a593Smuzhiyun TEGRA_GPIO(X, 1), TEGRA_GPIO(X, 4),
42*4882a593Smuzhiyun -1};
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun gpio_claim_vector(vector, "board_id%d");
45*4882a593Smuzhiyun return gpio_get_values_as_int(vector);
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
tegra_lcd_pmic_init(int board_id)48*4882a593Smuzhiyun int tegra_lcd_pmic_init(int board_id)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun struct udevice *dev;
51*4882a593Smuzhiyun int ret;
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun ret = uclass_get_device_by_driver(UCLASS_PMIC,
54*4882a593Smuzhiyun DM_GET_DRIVER(pmic_as3722), &dev);
55*4882a593Smuzhiyun if (ret) {
56*4882a593Smuzhiyun debug("%s: Failed to find PMIC\n", __func__);
57*4882a593Smuzhiyun return ret;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun if (board_id == 0)
61*4882a593Smuzhiyun pmic_reg_write(dev, 0x00, 0x3c);
62*4882a593Smuzhiyun else
63*4882a593Smuzhiyun pmic_reg_write(dev, 0x00, 0x50);
64*4882a593Smuzhiyun pmic_reg_write(dev, 0x12, 0x10);
65*4882a593Smuzhiyun pmic_reg_write(dev, 0x0c, 0x07);
66*4882a593Smuzhiyun pmic_reg_write(dev, 0x20, 0x10);
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun return 0;
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun /* Setup required information for Linux kernel */
setup_kernel_info(void)72*4882a593Smuzhiyun static void setup_kernel_info(void)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun struct mc_ctlr *mc = (void *)NV_PA_MC_BASE;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun /* The kernel graphics driver needs this region locked down */
77*4882a593Smuzhiyun writel(0, &mc->mc_video_protect_bom);
78*4882a593Smuzhiyun writel(0, &mc->mc_video_protect_size_mb);
79*4882a593Smuzhiyun writel(1, &mc->mc_video_protect_reg_ctrl);
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun /*
83*4882a593Smuzhiyun * We need to take ALL audio devices conntected to AHUB (AUDIO, APBIF,
84*4882a593Smuzhiyun * I2S, DAM, AMX, ADX, SPDIF, AFC) out of reset and enable the clocks.
85*4882a593Smuzhiyun * Otherwise reading AHUB devices will hang when the kernel boots.
86*4882a593Smuzhiyun */
enable_required_clocks(void)87*4882a593Smuzhiyun static void enable_required_clocks(void)
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun static enum periph_id ids[] = {
90*4882a593Smuzhiyun PERIPH_ID_I2S0,
91*4882a593Smuzhiyun PERIPH_ID_I2S1,
92*4882a593Smuzhiyun PERIPH_ID_I2S2,
93*4882a593Smuzhiyun PERIPH_ID_I2S3,
94*4882a593Smuzhiyun PERIPH_ID_I2S4,
95*4882a593Smuzhiyun PERIPH_ID_AUDIO,
96*4882a593Smuzhiyun PERIPH_ID_APBIF,
97*4882a593Smuzhiyun PERIPH_ID_DAM0,
98*4882a593Smuzhiyun PERIPH_ID_DAM1,
99*4882a593Smuzhiyun PERIPH_ID_DAM2,
100*4882a593Smuzhiyun PERIPH_ID_AMX0,
101*4882a593Smuzhiyun PERIPH_ID_AMX1,
102*4882a593Smuzhiyun PERIPH_ID_ADX0,
103*4882a593Smuzhiyun PERIPH_ID_ADX1,
104*4882a593Smuzhiyun PERIPH_ID_SPDIF,
105*4882a593Smuzhiyun PERIPH_ID_AFC0,
106*4882a593Smuzhiyun PERIPH_ID_AFC1,
107*4882a593Smuzhiyun PERIPH_ID_AFC2,
108*4882a593Smuzhiyun PERIPH_ID_AFC3,
109*4882a593Smuzhiyun PERIPH_ID_AFC4,
110*4882a593Smuzhiyun PERIPH_ID_AFC5,
111*4882a593Smuzhiyun PERIPH_ID_EXTPERIPH1
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun int i;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(ids); i++)
116*4882a593Smuzhiyun clock_enable(ids[i]);
117*4882a593Smuzhiyun udelay(2);
118*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(ids); i++)
119*4882a593Smuzhiyun reset_set_enable(ids[i], 0);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
nvidia_board_init(void)122*4882a593Smuzhiyun int nvidia_board_init(void)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun clock_start_periph_pll(PERIPH_ID_EXTPERIPH1, CLOCK_ID_OSC, 12000000);
125*4882a593Smuzhiyun clock_start_periph_pll(PERIPH_ID_I2S1, CLOCK_ID_OSC, 1500000);
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun /* For external MAX98090 audio codec */
128*4882a593Smuzhiyun clock_external_output(1);
129*4882a593Smuzhiyun setup_kernel_info();
130*4882a593Smuzhiyun enable_required_clocks();
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun return 0;
133*4882a593Smuzhiyun }
134