From 80402876b5daa9e9389fd4fab5f539d89c37fa7f Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Tue, 5 Nov 2013 09:44:46 -0800 Subject: [PATCH] tegra124: more display PLL setup and clock hardcode removal. Set up two new PLLs in the early clock code. Clear reset and enable clocks using the standrd function called from mainboard_init. Remove more hardcodes from display startup. This should be the end of moving clock code around. Next step is to remove all the display programming hardcodes for front porch, back porch, etc. and use the settings from the coreboot device tree. BUG=None TEST=Build, boot, see graphics BRANCH=None Change-Id: I324e57f665bbd11c1d09fb4b9ec14646d0785e5f Signed-off-by: Ronald G. Minnich Reviewed-on: https://chromium-review.googlesource.com/175732 Reviewed-by: Ronald Minnich Commit-Queue: Ronald Minnich Tested-by: Ronald Minnich --- src/mainboard/google/nyan/mainboard.c | 8 +- src/soc/nvidia/tegra124/clk_rst.h | 6 +- src/soc/nvidia/tegra124/clock.c | 29 +++++-- src/soc/nvidia/tegra124/displayhack.c | 88 +-------------------- src/soc/nvidia/tegra124/include/soc/clock.h | 1 - 5 files changed, 34 insertions(+), 98 deletions(-) diff --git a/src/mainboard/google/nyan/mainboard.c b/src/mainboard/google/nyan/mainboard.c index d27d49ccb6..3f7a7327d3 100644 --- a/src/mainboard/google/nyan/mainboard.c +++ b/src/mainboard/google/nyan/mainboard.c @@ -54,8 +54,10 @@ static void set_clock_sources(void) CLK_DIVIDER(TEGRA_PLLP_KHZ, 408000), &clk_rst->clk_src_host1x); - /* DISP1 doesn't support a divisor. Use PLLC which runs at 600MHz. */ - clock_configure_source(disp1, PLLC, 600000); + /* DISP1 doesn't support a divisor. Use PLLD2_OUT0 which runs at 570MHz. */ + clrsetbits_le32(&clk_rst->clk_src_disp1, + CLK_SOURCE_MASK | CLK_DIVISOR_MASK, + 5 /*PLLD2_OUT0 */ << CLK_SOURCE_SHIFT); } static void setup_pinmux(void) @@ -207,7 +209,7 @@ static void mainboard_init(device_t dev) CLK_H_PMC | CLK_H_MEM | CLK_H_USB3, CLK_U_I2C3 | CLK_U_CSITE | CLK_U_SDMMC3, CLK_V_I2C4, - CLK_W_DVFS, 0); + CLK_W_DVFS, CLK_X_DPAUX | CLK_X_SOR0); usb_setup_utmip1(); /* USB2 is the camera, we don't need it in firmware */ diff --git a/src/soc/nvidia/tegra124/clk_rst.h b/src/soc/nvidia/tegra124/clk_rst.h index f52fb92651..660aa871fc 100644 --- a/src/soc/nvidia/tegra124/clk_rst.h +++ b/src/soc/nvidia/tegra124/clk_rst.h @@ -269,11 +269,13 @@ struct __attribute__ ((__packed__)) clk_rst_ctlr { u32 _rsv31; /* 0x554 */ u32 super_gr3d_clk_div; /* _SUPER_GR3D_CLK_DIVIDER, 0x558 */ u32 spare_reg0; /* _SPARE_REG0, 0x55c */ - u32 _rsv32[12]; /* 0x560-58c */ + u32 _rsv32[4]; /* 0x560-0x56c */ + u32 plld2_ss_cfg; /* _PLLD2_SS_CFG 0x570 */ + u32 _rsv32_1[7]; /* 0x574-58c */ u32 plldp_base; /* _PLLDP_BASE, 0x590 */ u32 plldp_misc; /* _PLLDP_MISC, 0x594 */ u32 plldp_ss_cfg; /* _PLLDP_SS_CFG, 0x598 */ - u32 _rsrv321[25]; + u32 _rsrv32_2[25]; u32 clk_src_xusb_core_host; /* _CLK_SOURCE_XUSB_CORE_HOST 0x600 */ u32 clk_src_xusb_falcon; /* _CLK_SOURCE_XUSB_FALCON 0x604 */ u32 clk_src_xusb_fs; /* _CLK_SOURCE_XUSB_FS 0x608 */ diff --git a/src/soc/nvidia/tegra124/clock.c b/src/soc/nvidia/tegra124/clock.c index eb8bd7ac7c..93ef2a2451 100644 --- a/src/soc/nvidia/tegra124/clock.c +++ b/src/soc/nvidia/tegra124/clock.c @@ -89,6 +89,7 @@ struct { struct pllpad_dividers plld; /* target: 925 MHz */ struct pllu_dividers pllu; /* target; 960 MHz */ struct pllcx_dividers plldp; /* target; 270 MHz */ + struct pllcx_dividers plld2; /* target; 570 MHz */ } static const osc_table[16] = { [OSC_FREQ_OSC12]{ .khz = 12000, @@ -98,6 +99,7 @@ struct { .plld = {.n = 925, .m = 12, .p = 0, .cpcon = 12}, .pllu = {.n = 80, .m = 1, .p = 0, .cpcon = 3}, .plldp = {.n = 90, .m = 1, .p = 3}, /* 270 MHz */ + .plld2 = {.n = 95, .m = 1, .p = 1}, /* 570 MHz */ }, [OSC_FREQ_OSC13]{ .khz = 13000, @@ -107,6 +109,7 @@ struct { .plld = {.n = 925, .m = 13, .p = 0, .cpcon = 12}, .pllu = {.n = 960, .m = 13, .p = 0, .cpcon = 12}, .plldp = {.n = 83, .m = 1, .p = 3}, /* 269.75 MHz */ + .plld2 = {.n = 88, .m = 1, .p = 1}, /* 572 MHz */ }, [OSC_FREQ_OSC16P8]{ .khz = 16800, @@ -115,7 +118,8 @@ struct { .pllc = {.n = 250, .m = 7, .p = 0}, .plld = {.n = 936, .m = 17, .p = 0, .cpcon = 12},/* 924.9 MHz */ .pllu = {.n = 400, .m = 7, .p = 0, .cpcon = 8}, - .plldp = {.n = 67, .m = 1, .p = 3}, /* 268 MHz */ + .plldp = {.n = 64, .m = 1, .p = 3}, /* 268.8 MHz */ + .plld2 = {.n = 68, .m = 1, .p = 1}, /* 571.2 MHz */ }, [OSC_FREQ_OSC19P2]{ .khz = 19200, @@ -124,7 +128,8 @@ struct { .pllc = {.n = 125, .m = 4, .p = 0}, .plld = {.n = 819, .m = 17, .p = 0, .cpcon = 12},/* 924.9 MHz */ .pllu = {.n = 50, .m = 1, .p = 0, .cpcon = 2}, - .plldp = {.n = 57, .m = 1, .p = 3}, /* 270.75 MHz */ + .plldp = {.n = 56, .m = 1, .p = 3}, /* 270.75 MHz */ + .plld2 = {.n = 59, .m = 1, .p = 1}, /* 570 MHz */ }, [OSC_FREQ_OSC26]{ .khz = 26000, @@ -133,7 +138,8 @@ struct { .pllc = {.n = 23, .m = 1, .p = 0}, /* 598 MHz */ .plld = {.n = 925, .m = 26, .p = 0, .cpcon = 12}, .pllu = {.n = 480, .m = 13, .p = 0, .cpcon = 8}, - .plldp = {.n = 41, .m = 1, .p = 3}, /* 266.50 MHz */ + .plldp = {.n = 83, .m = 2, .p = 3}, /* 266.50 MHz */ + .plld2 = {.n = 88, .m = 2, .p = 1}, /* 570 MHz */ }, [OSC_FREQ_OSC38P4]{ .khz = 38400, @@ -142,7 +148,8 @@ struct { .pllc = {.n = 125, .m = 4, .p = 0}, .plld = {.n = 819, .m = 17, .p = 0, .cpcon = 12},/* 924.9 MHz */ .pllu = {.n = 50, .m = 1, .p = 0, .cpcon = 2}, - .plldp = {.n = 28, .m = 1, .p = 3}, /* 266 MHz */ + .plldp = {.n = 56, .m = 2, .p = 3}, /* 268 MHz */ + .plld2 = {.n = 59, .m = 2, .p = 1}, /* 566 MHz */ }, [OSC_FREQ_OSC48]{ .khz = 48000, @@ -151,7 +158,8 @@ struct { .pllc = {.n = 50, .m = 1, .p = 0}, .plld = {.n = 925, .m = 12, .p = 0, .cpcon = 12}, .pllu = {.n = 80, .m = 1, .p = 0, .cpcon = 3}, - .plldp = {.n = 22, .m = 1, .p = 3}, /* 264 MHz */ + .plldp = {.n = 90, .m = 4, .p = 3}, /* 264 MHz */ + .plld2 = {.n = 95, .m = 4, .p = 1}, /* 570 MHz */ }, }; @@ -213,6 +221,7 @@ void sor_clock_stop(void) void sor_clock_start(void) { + /* uses PLLP, has a non-standard bit layout. */ setbits_le32(&clk_rst->clk_src_sor, SOR0_CLK_SEL0); } @@ -267,7 +276,7 @@ static void init_utmip_pll(void) * need to set in here, but it makes sense just to restrict all the * special bits to this one function. */ -void graphics_clock(void) +static void graphics_pll(void) { int osc = clock_get_osc_bits(); u32 *cfg = &clk_rst->plldp_ss_cfg; @@ -287,6 +296,13 @@ void graphics_clock(void) /* leave dither and undoc bits set, release clamp */ scfg = (1<<28) | (1<<24); writel(scfg, cfg); + + /* a few more undocumented bits. Sorry. */ + writel(0x13400000, &clk_rst->plld2_ss_cfg); // undocumented + init_pll(&clk_rst->plld2_base, &clk_rst->plld2_misc, osc_table[osc].plld2); + writel(0x13800000, &clk_rst->plld2_ss_cfg); // undocumented + udelay(10); // wait for plld2 ready + } /* Initialize the UART and put it on CLK_M so we can use it during clock_init(). @@ -405,6 +421,7 @@ void clock_init(void) init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, osc_table[osc].plld); init_pll(&clk_rst->pllu_base, &clk_rst->pllu_misc, osc_table[osc].pllu); init_utmip_pll(); + graphics_pll(); val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT); writel(val, &clk_rst->clk_sys_rate); diff --git a/src/soc/nvidia/tegra124/displayhack.c b/src/soc/nvidia/tegra124/displayhack.c index 88ff177143..72834f0235 100644 --- a/src/soc/nvidia/tegra124/displayhack.c +++ b/src/soc/nvidia/tegra124/displayhack.c @@ -50,9 +50,7 @@ int dpaux_read(u32 addr, u32 size, u8 * data); void init_dca_regs(void) { -// u32 val; - - printk(BIOS_SPEW, "JZ: %s: entry\n", __func__); + printk(BIOS_SPEW, "%s: entry\n", __func__); #if 1 #define DCA_WRITE(reg, val) \ @@ -346,23 +344,9 @@ void init_dca_regs(void) void init_sor_regs(void) { - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)TEGRA_CLK_RST_BASE; printk(BIOS_SPEW, "JZ: %s: entry\n", __func__); -#define SWR_SOR0_RST (1 << 22) -#define CLK_ENB_SOR0 SWR_SOR0_RST -// REG(CLK_RST_CONTROLLER_RST_DEVICES_X_0, SWR_SOR0_RST, 1) -// REG(CLK_RST_CONTROLLER_RST_DEVICES_X_0, SWR_SOR0_RST, 0) -// REG(CLK_RST_CONTROLLER_CLK_OUT_ENB_X_0, CLK_ENB_SOR0, 1) -// REG(CLK_RST_CONTROLLER_CLK_SOURCE_SOR0_0, 0) //0x60006414 - setbits_le32(&clkrst->rst_devices_x, SWR_SOR0_RST); // Set Reset - clrbits_le32(&clkrst->rst_devices_x, SWR_SOR0_RST); // Clear Reset - setbits_le32(&clkrst->clk_out_enb_x, CLK_ENB_SOR0); // Set Enable - WRITEL(0x0, (void *)(0x60006000 + 0x414)); // CLK_SOURCE_SOR0 = PLLP - - //WRITEL(0xc000c000, (0x60006000 + 0x414)); // CLK_SOURCE_SOR0 = CLK_M - #if 1 #define SOR_WRITE(reg, val) \ { \ @@ -508,19 +492,8 @@ void init_sor_regs(void) void init_dpaux_regs(void) { - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)TEGRA_CLK_RST_BASE; -// u32 val; - printk(BIOS_SPEW, "JZ: %s: entry\n", __func__); - -#define SWR_DPAUX_RST (1 << 21) -#define CLK_ENB_DPAUX SWR_DPAUX_RST -// REG(CLK_RST_CONTROLLER_RST_DEVICES_X_0, SWR_DPAUX_RST, 1) -// REG(CLK_RST_CONTROLLER_RST_DEVICES_X_0, SWR_DPAUX_RST, 0) -// REG(CLK_RST_CONTROLLER_CLK_OUT_ENB_X_0, CLK_ENB_DPAUX, 1) - setbits_le32(&clkrst->rst_devices_x, SWR_DPAUX_RST); // Set Reset - clrbits_le32(&clkrst->rst_devices_x, SWR_DPAUX_RST); // Clear Reset - setbits_le32(&clkrst->clk_out_enb_x, CLK_ENB_DPAUX); // Set Enable + printk(BIOS_SPEW, "%s: entry\n", __func__); #if 1 #define DPAUX_WRITE(reg, val) \ @@ -614,30 +587,8 @@ static void dp_io_set_dpd(u32 power_down) void dp_io_powerup(void) { -//E_DPD = PMC.dpd2_status[25] -//PDBG = SOR_NV_PDISP_SOR_PLL2_0.AUX6(1) | SEQ.POWERDOWN_MACRO(1) & -//SOR_NV_PDISP_SOR_PLL2_0.AUX2(0) -//PDPLL = SOR_NV_PDISP_SOR_PLL0_0.PWR(1) | SEQ.PDPLL(0) & ~ SOR_NV_PDISP_SOR_PLL2_0.AUX1(0) -//VCOPD = SOR_NV_PDISP_SOR_PLL0_0.VCOPD(1) -//CAPPD = SOR_NV_PDISP_SOR_PLL2_0.AUX8(1) | SEQ.ASSERT_PLL_RESET(0) & -//~ SOR_NV_PDISP_SOR_PLL2_0.AUX1(0) -//PDPORT = SOR_NV_PDISP_SOR_PLL2_0.AUX7(1) | SEQ.PDPORT(1) & -//~ SOR_NV_PDISP_SOR_DP_LINKCTL0_0.ENABLE(0) -//PDCAL = SOR_NV_PDISP_SOR_DP_PADCTL0_0.PAD_CAL_PD(1) - -// struct clk_rst_ctlr *clkrst = -// (struct clk_rst_ctlr *)TEGRA_CLK_RST_BASE; - - printk(BIOS_SPEW, "%s: entry\n", __func__); -#if 0 - printk(BIOS_SPEW, "JZ: %s: %d: do nothing, ret\n", __func__, __LINE__); - return; -#endif - sor_clock_stop(); - graphics_clock(); - SOR_WRITE(SOR_NV_PDISP_SOR_CLK_CNTRL_0, (6 << 2) | 2);//select PLLDP, lowest speed(6x) SOR_WRITE(SOR_NV_PDISP_SOR_DP_PADCTL0_0, 0x00800000); //set PDCAL SOR_WRITE(SOR_NV_PDISP_SOR_PLL0_0, 0x050003D5); //set PWR,VCOPD @@ -645,7 +596,6 @@ void dp_io_powerup(void) SOR_WRITE(SOR_NV_PDISP_SOR_PLL2_0, 0x01C20000); //set AUX1,6,7,8; clr AUX2 SOR_WRITE(SOR_NV_PDISP_SOR_PLL3_0, 0x38002220); - //REG(SOR_NV_PDISP_SOR_PLL3_0,PLLVDD_MODE, V1_8) dp_io_set_dpd(0); udelay(1); //Deassert E_DPD to enable core logic circuits, and wait for > 5us @@ -690,8 +640,6 @@ static int dpaux_check(u32 bytes, u32 data, u32 mask) printk(BIOS_SPEW, "******AuxRead Error:%04x: status %08x\n", 0x202, status); else { - //temp = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0] ; - //memcpy(&temp, buf, 4); temp = DPAUX_READ(DPAUX_DP_AUXDATA_READ_W0); if ((temp & mask) != (data & mask)) { printk(BIOS_SPEW, "AuxCheck ERROR:(r_data) %08x & (mask) %08x != " @@ -765,7 +713,6 @@ static int dp_training(u32 level, u32 check, u32 speed) u32 cnt = 0; u32 cfg, cfg_d = 0; u32 wcfg; -// u32 status = 0; u8 buf[16]; while (cnt <= 5) { @@ -851,11 +798,6 @@ void dp_link_training(u32 lanes, u32 speed) udelay(100); sor_clock_start(); -#if 0 - reg_val = readl((void *)(0x60006000 + 0x414)); - reg_val |= SOR0_CLK_SEL0; - writel(reg_val, (void *)(0x60006000 + 0x414)); -#endif SOR_WRITE(SOR_NV_PDISP_SOR_DP_LINKCTL0_0, (((0xF >> (4 - lanes)) << 16) | 1)); @@ -870,10 +812,6 @@ void dp_link_training(u32 lanes, u32 speed) printk(BIOS_SPEW, "set link rate and lane number: %dMHz, %d lanes\n", (speed * 27), lanes); -// printk(BIOS_SPEW,"JZ: dbg ret\n"); -// return; - -// %d = (%lanes<<8) | %speed dpaux_write(0x100, 2, ((lanes << 8) | speed)); printk(BIOS_SPEW, "precharge lane 10us\n"); reg_val = SOR_READ(SOR_NV_PDISP_SOR_DP_PADCTL0_0); @@ -926,7 +864,6 @@ static u32 div_f(u32 a, u32 b, u32 one) u32 dp_setup_timing(u32 panel_id, u32 width, u32 height); u32 dp_setup_timing(u32 panel_id, u32 width, u32 height) { - u32 reg_val; u32 pclk_freq = 0; /////////////////////////////////////////// @@ -969,27 +906,6 @@ u32 dp_setup_timing(u32 panel_id, u32 width, u32 height) return pclk_freq; } -// clock(plld2, %PLL_FREQ) // PLL_FREQ = 570 - writel(0, (void *)(0x60006000 + 0x4bc)); // plld2_misc - writel(0x13400000, (void *)(0x60006000 + 0x570)); // plld2_ss_cfg - writel(0x8008010c, (void *)(0x60006000 + 0x4b8)); // plld2_base - writel(0x80105F01, (void *)(0x60006000 + 0x4b8));// plld2_base: 12 * 95 / 2 = 570 - writel(0x40000000, (void *)(0x60006000 + 0x4bc)); // misc: enable lock - writel(0x80105f01, (void *)(0x60006000 + 0x4b8)); // base: enable - writel(0xc0105f01, (void *)(0x60006000 + 0x4b8)); // base: check lock - writel(0x58105f01, (void *)(0x60006000 + 0x4b8)); // base: disable bypass - writel(0x13800000, (void *)(0x60006000 + 0x570)); // plld2_ss_cfg - udelay(10); // wait for plld2 ready - -// REG(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1_0, DISP1_CLK_SRC, PLLD2_OUT0) -#define DISP1_CLK_SRC (0x7 << 29) -#define PLLD2_OUT0 (0x5 << 29) - reg_val = readl((void *)(0x60006000 + 0x138)); - reg_val &= ~DISP1_CLK_SRC; - reg_val |= PLLD2_OUT0; - writel(reg_val, (void *)(0x60006000 + 0x138)); - udelay(10); - PLL_FREQ = PLL_FREQ * 1000000; pclk_freq = PLL_FREQ / PLL_DIV; PLL_FREQ_I = PLL_FREQ / 1000000; diff --git a/src/soc/nvidia/tegra124/include/soc/clock.h b/src/soc/nvidia/tegra124/include/soc/clock.h index 231343b603..58ce0988c2 100644 --- a/src/soc/nvidia/tegra124/include/soc/clock.h +++ b/src/soc/nvidia/tegra124/include/soc/clock.h @@ -241,7 +241,6 @@ void clock_init(void); void clock_init_arm_generic_timer(void); void sor_clock_stop(void); void sor_clock_start(void); -void graphics_clock(void); #endif /* __SOC_NVIDIA_TEGRA124_CLOCK_H__ */