Skip to content

Commit

Permalink
sunxi: read DT name from SPL eGON header
Browse files Browse the repository at this point in the history
Recent U-Boot SPL builds hold the DT filename in the SPL header, so that
the SPL knows which of the DTs it needs to load for U-Boot proper.
Teach TF to read this string from SRAM A1 (where the SPL still resides),
so that it can apply any board specific fixups based on that string.
Change the Pine64 DRAM voltage fixup to rely on that string before
changing the voltage.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
  • Loading branch information
Andre-ARM committed Jan 12, 2018
1 parent 91f2402 commit cbb89f3
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 12 deletions.
36 changes: 36 additions & 0 deletions plat/sun50iw1p1/aarch64/sunxi_common.c
Expand Up @@ -153,3 +153,39 @@ uint16_t sunxi_get_socid(void)
mmio_write_32(0x01c00024, reg & ~(1 << 15));
return reg >> 16;
}

struct spl_boot_file_head {
uint32_t jump_instruction;
uint32_t magic[2];
uint32_t check_sum;
uint32_t length;
uint8_t spl_signature[4];
uint32_t fel_script_address;
uint32_t fel_uEnv_length;
uint32_t offset_dt_name;
uint32_t reserved1;
uint32_t boot_media;
uint32_t string_pool[13];
};

#define MAGIC_eGON 0x4e4f4765 /* "eGON" */
#define MAGIC_BT0 0x3054422e /* ".BT0" */
#define MAGIC_FEL 0x4c45462e /* ".FEL" */

const char *get_dt_name(void)
{
const struct spl_boot_file_head *spl_head = (void *)0x10000;

if (spl_head->magic[0] != MAGIC_eGON)
return NULL;

if (spl_head->magic[1] != MAGIC_BT0 &&
spl_head->magic[1] != MAGIC_FEL)
return NULL;

/* We need at least U-Boot SPL version 2 for the DT name feature. */
if (spl_head->spl_signature[3] < 2)
return NULL;

return (const char *)spl_head + spl_head->offset_dt_name;
}
12 changes: 10 additions & 2 deletions plat/sun50iw1p1/bl31_sunxi_setup.c
Expand Up @@ -236,25 +236,33 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
void bl31_platform_setup(void)
{
uint16_t socid;
const char *dt_name;

/* Initialize the gic cpu and distributor interfaces */
arm_gic_init(GICC_BASE, GICD_BASE, 0, NULL, 0);
arm_gic_setup();

socid = sunxi_get_socid();

dt_name = get_dt_name();

if (dt_name)
NOTICE("DT: %s\n", dt_name);
else
NOTICE("No DT name found, skipping board specific setup.\n");

/* Detect if this SoC is a multi-cluster one. */
plat_setup_topology();

switch (socid) {
case 0x1689:
sunxi_pmic_setup();
sunxi_pmic_setup(dt_name);
break;
case 0x1718:
break;
}

sunxi_setup_clocks(socid);
sunxi_setup_clocks(socid, dt_name);

NOTICE("SCPI: dummy stub handler, implementation level: 000000\n");
}
Expand Down
2 changes: 1 addition & 1 deletion plat/sun50iw1p1/sunxi_clocks.c
Expand Up @@ -64,7 +64,7 @@ static int pll_wait_until_stable(uintptr_t addr)
return 0;
}

int sunxi_setup_clocks(uint16_t socid)
int sunxi_setup_clocks(uint16_t socid, const char *dt_name)
{
uint32_t reg;

Expand Down
17 changes: 10 additions & 7 deletions plat/sun50iw1p1/sunxi_power.c
Expand Up @@ -31,6 +31,7 @@
#include <debug.h>
#include <plat_config.h>
#include <mmio.h>
#include <string.h>
#include <sys/errno.h>
#include "sunxi_def.h"
#include "sunxi_private.h"
Expand Down Expand Up @@ -213,7 +214,7 @@ static int pmic_init(uint16_t hw_addr, uint8_t rt_addr)
}

/* Setup the PMIC: DCDC1 to 3.3V, enable DC1SW and DLDO4 */
static int pmic_setup(void)
static int pmic_setup(const char *dt_name)
{
int ret;

Expand Down Expand Up @@ -258,10 +259,12 @@ static int pmic_setup(void)
* changes. This should be further confined once we are able to
* reliably detect a Pine64 board.
*/
ret = sunxi_pmic_read(0x24); /* read DCDC5 register */
if ((ret & 0x7f) == 0x26) { /* check for 1.24V value */
NOTICE("PMIC: fixing DRAM voltage from 1.24V to 1.36V\n");
sunxi_pmic_write(0x24, 0x2c);
if (!strcmp(dt_name, "sun50i-a64-pine64-plus")) {
ret = sunxi_pmic_read(0x24); /* read DCDC5 register */
if ((ret & 0x7f) == 0x26) { /* check for 1.24V value */
NOTICE("PMIC: fixing DRAM voltage from 1.24V to 1.36V\n");
sunxi_pmic_write(0x24, 0x2c);
}
}

sunxi_pmic_write(0x15, 0x1a); /* DLDO1 = VCC3V3_HDMI voltage = 3.3V */
Expand All @@ -272,7 +275,7 @@ static int pmic_setup(void)
/*
* Program the AXP803 via the RSB bus.
*/
int sunxi_pmic_setup(void)
int sunxi_pmic_setup(const char *dt_name)
{
int ret;

Expand All @@ -292,7 +295,7 @@ int sunxi_pmic_setup(void)
}
}

ret = pmic_setup();
ret = pmic_setup(dt_name);
if (!ret)
NOTICE("PMIC: setup successful\n");
else
Expand Down
5 changes: 3 additions & 2 deletions plat/sun50iw1p1/sunxi_private.h
Expand Up @@ -57,6 +57,7 @@ void sunxi_configure_mmu_el3(unsigned long total_base,
int sunxi_config_setup(void);

uint16_t sunxi_get_socid(void);
const char *get_dt_name(void);

/* Declarations for sunxi_topology.c */
int plat_setup_topology(void);
Expand All @@ -68,12 +69,12 @@ void sunxi_io_setup(void);
void sunxi_security_setup(void);

/* Declarations for sunxi_power.c */
int sunxi_pmic_setup(void);
int sunxi_pmic_setup(const char *dt_name);
int sunxi_pmic_read(uint8_t address);
int sunxi_pmic_write(uint8_t address, uint8_t value);

void udelay(unsigned int delay);
int sunxi_setup_clocks(uint16_t socid);
int sunxi_setup_clocks(uint16_t socid, const char *dt_name);

/* Gets the SPSR for BL33 entry */
uint32_t sunxi_get_spsr_for_bl33_entry(int aarch);
Expand Down

0 comments on commit cbb89f3

Please sign in to comment.