[U-Boot] [PATCH 1/7] Tegra30: Add AVP (arm720t) files
Simon Glass
sjg at chromium.org
Thu Oct 4 03:11:00 CEST 2012
Hi Stephen,
On Wed, Oct 3, 2012 at 11:23 AM, Stephen Warren <swarren at 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 at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
Regards,
Simon
More information about the U-Boot
mailing list