Hi Stephen, On Wed, Oct 3, 2012 at 11:23 AM, Stephen Warren <swar...@wwwdotorg.org> wrote: > On 10/02/2012 04:45 PM, Tom Warren wrote: >> This provides SPL support for T30 boards - AVP early init, plus >> CPU (A9) init/jump to main U-Boot. > >> diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c >> b/arch/arm/cpu/arm720t/tegra30/cpu.c
>> +static int get_chip_type(void) >> +{ >> + /* >> + * T30 has two options. We will return TEGRA_SOC_T30 until >> + * we have the fdt set up when it may change to >> + * TEGRA_SOC_T30_408MHZ depending on what we set PLLP to. >> + */ > > I'm not sure what the FDT has to do with it? Certainly at this point in > the series, I doubt that comment is accurate. Do we actually reprogram > the PLLs based on FDT later? Yes, and that changes the SOC here. It's a bit odd but the AVP couldn't know what speed we wanted so we updated it later when the Cortex-A9 was running. > >> + if (clock_get_rate(CLOCK_ID_PERIPH) == 408000000) >> + return TEGRA_SOC_T30_408MHZ; >> + else >> + return TEGRA_SOC_T30; > > I thought we'd decided not to support one of those options, but perhaps > it's used somewhere... Yes, in fact we started using 408MHz exclusively. Not sure if that is possible upstream - unless anyone knows for sure I suggest we leave it as is and remove it later if no one needs it. > >> +static void adjust_pllp_out_freqs(void) >> +{ >> + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr >> *)NV_PA_CLK_RST_BASE; >> + struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_PERIPH]; >> + u32 reg; >> + >> + /* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */ >> + reg = readl(&pll->pll_out[0]); /* OUTA, contains OUT2 / OUT1 */ >> + reg |= (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) | PLLP_OUT2_OVR >> + | (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) | PLLP_OUT1_OVR; >> + writel(reg, &pll->pll_out[0]); >> + >> + reg = readl(&pll->pll_out[1]); /* OUTB, contains OUT4 / OUT3 */ >> + reg |= (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) | PLLP_OUT4_OVR >> + | (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) | PLLP_OUT3_OVR; >> + writel(reg, &pll->pll_out[1]); >> +} > > I don't think that code is ever used, since init_pllx() below is only > ever called with slow==1, so never calls it. This probably came from this function that we had in arch/arm/cpu/armv7/tegra-common/board.c: void arch_full_speed(void) { ap20_init_pllx(0); debug("CPU at %d\n", clock_get_rate(CLOCK_ID_XCPU)); debug("Memory at %d\n", clock_get_rate(CLOCK_ID_MEMORY)); debug("Periph at %d\n", clock_get_rate(CLOCK_ID_PERIPH)); } It was called from board/nvidia/common/board. If you like, take a look at the chromeos-v2011.06 branch of U-Boot for anything about this. > >> +void tegra_i2c_ll_write_addr(uint addr, uint config) >> +{ >> + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; >> + >> + writel(addr, ®->cmd_addr0); >> + writel(config, ®->cnfg); >> +} >> + >> +void tegra_i2c_ll_write_data(uint data, uint config) >> +{ >> + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; >> + >> + writel(data, ®->cmd_data1); >> + writel(config, ®->cnfg); >> +} Well this is a lot better than the ugliness I had. I don't think you can put this into the i2c driver since the AVP doesn't have it, right? >> + >> +static void enable_cpu_power_rail(void) >> +{ >> + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; >> + u32 reg; >> + >> + debug("enable_cpu_power_rail entry\n"); >> + reg = readl(&pmc->pmc_cntrl); >> + reg |= CPUPWRREQ_OE; >> + writel(reg, &pmc->pmc_cntrl); >> + >> + /* >> + * Pulse PWRREQ via I2C. We need to find out what this is >> + * doing, tidy up the code and maybe find a better place for it. >> + */ >> + tegra_i2c_ll_write_addr(0x005a, 0x0002); >> + tegra_i2c_ll_write_data(0x2328, 0x0a02); > > With a TPS65911x attached to the DVC I2C bus, that sets VDD to 1.4V (I > assume that's both the VDD1 and VDD2 outputs, but the PMIC datasheet > isn't too clear on that at a quick glance), and: > >> + udelay(1000); >> + tegra_i2c_ll_write_data(0x0127, 0x0a02); > > ... and this enables the VDD regulator. > > So, this is: > a) Entirely specific to a TPS65911x regulator. I think this warrants a > very large FIXME comment. > b) Nothing to do with pulsing PWRREQ via I2C. > c) Really should be done via programming the EEPROM on the PMIC so that > SW doesn't have to do this, but I guess that didn't happen. > >> +static void reset_A9_cpu(int reset) >> +{ >> + /* >> + * NOTE: Regardless of whether the request is to hold the CPU in reset >> + * or take it out of reset, every processor in the CPU complex >> + * except the master (CPU 0) will be held in reset because the >> + * AVP only talks to the master. The AVP does not know that there >> + * are multiple processors in the CPU complex. >> + */ > > At least the last sentence there is false; this code is running on the > AVP and there's explicit code above that determines the number of CPUs > in the main CPU complex (get_num_cpus) and sets separate reset bits for > each of them (enable_cpu_clock). Oh, and ~7 lines below, there's a loop > over num_cpus: > >> + int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug; >> + int num_cpus = get_num_cpus(); >> + int cpu; >> + >> + debug("reset_a9_cpu entry\n"); >> + /* Hold CPUs 1 onwards in reset, and CPU 0 if asked */ >> + for (cpu = 1; cpu < num_cpus; cpu++) >> + reset_cmplx_set_enable(cpu, mask, 1); >> + reset_cmplx_set_enable(0, mask, reset); > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot