commit
15616a0aa5
@ -0,0 +1,40 @@ |
||||
#include <config.h> |
||||
|
||||
/ { |
||||
binman { |
||||
multiple-images; |
||||
image1 { |
||||
filename = "u-boot-tegra.bin"; |
||||
pad-byte = <0xff>; |
||||
u-boot-spl { |
||||
}; |
||||
u-boot { |
||||
pos = <(CONFIG_SYS_TEXT_BASE - |
||||
CONFIG_SPL_TEXT_BASE)>; |
||||
}; |
||||
}; |
||||
|
||||
/* Same as image1 - some tools still expect the -dtb suffix */ |
||||
image2 { |
||||
filename = "u-boot-dtb-tegra.bin"; |
||||
pad-byte = <0xff>; |
||||
u-boot-spl { |
||||
}; |
||||
u-boot { |
||||
pos = <(CONFIG_SYS_TEXT_BASE - |
||||
CONFIG_SPL_TEXT_BASE)>; |
||||
}; |
||||
}; |
||||
|
||||
image3 { |
||||
filename = "u-boot-nodtb-tegra.bin"; |
||||
pad-byte = <0xff>; |
||||
u-boot-spl { |
||||
}; |
||||
u-boot-nodtb { |
||||
pos = <(CONFIG_SYS_TEXT_BASE - |
||||
CONFIG_SPL_TEXT_BASE)>; |
||||
}; |
||||
}; |
||||
}; |
||||
}; |
@ -0,0 +1,3 @@ |
||||
#include <config.h> |
||||
|
||||
#include "tegra-u-boot.dtsi" |
@ -0,0 +1,3 @@ |
||||
#include <config.h> |
||||
|
||||
#include "tegra-u-boot.dtsi" |
@ -1,8 +1,3 @@ |
||||
/ { |
||||
host1x@50000000 { |
||||
u-boot,dm-pre-reloc; |
||||
dc@54200000 { |
||||
u-boot,dm-pre-reloc; |
||||
}; |
||||
}; |
||||
}; |
||||
#include <config.h> |
||||
|
||||
#include "tegra-u-boot.dtsi" |
||||
|
@ -0,0 +1,3 @@ |
||||
#include <config.h> |
||||
|
||||
#include "tegra-u-boot.dtsi" |
@ -0,0 +1,3 @@ |
||||
#include <config.h> |
||||
|
||||
#include "tegra-u-boot.dtsi" |
@ -0,0 +1,98 @@ |
||||
/*
|
||||
* Copyright (C) EETS GmbH, 2017, Felix Brack <f.brack@eets.ch> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <dm.h> |
||||
#include <i2c.h> |
||||
#include <power/pmic.h> |
||||
#include <power/regulator.h> |
||||
#include <power/tps65910_pmic.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
static const struct pmic_child_info pmic_children_info[] = { |
||||
{ .prefix = "ldo_", .driver = TPS65910_LDO_DRIVER }, |
||||
{ .prefix = "buck_", .driver = TPS65910_BUCK_DRIVER }, |
||||
{ .prefix = "boost_", .driver = TPS65910_BOOST_DRIVER }, |
||||
{ }, |
||||
}; |
||||
|
||||
static int pmic_tps65910_reg_count(struct udevice *dev) |
||||
{ |
||||
return TPS65910_NUM_REGS; |
||||
} |
||||
|
||||
static int pmic_tps65910_write(struct udevice *dev, uint reg, const u8 *buffer, |
||||
int len) |
||||
{ |
||||
int ret; |
||||
|
||||
ret = dm_i2c_write(dev, reg, buffer, len); |
||||
if (ret) |
||||
error("%s write error on register %02x\n", dev->name, reg); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int pmic_tps65910_read(struct udevice *dev, uint reg, u8 *buffer, |
||||
int len) |
||||
{ |
||||
int ret; |
||||
|
||||
ret = dm_i2c_read(dev, reg, buffer, len); |
||||
if (ret) |
||||
error("%s read error on register %02x\n", dev->name, reg); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int pmic_tps65910_bind(struct udevice *dev) |
||||
{ |
||||
ofnode regulators_node; |
||||
int children; |
||||
|
||||
regulators_node = dev_read_subnode(dev, "regulators"); |
||||
if (!ofnode_valid(regulators_node)) { |
||||
debug("%s regulators subnode not found\n", dev->name); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
children = pmic_bind_children(dev, regulators_node, pmic_children_info); |
||||
if (!children) |
||||
debug("%s has no children (regulators)\n", dev->name); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int pmic_tps65910_probe(struct udevice *dev) |
||||
{ |
||||
/* use I2C control interface instead of I2C smartreflex interface to
|
||||
* access smartrefelex registers VDD1_OP_REG, VDD1_SR_REG, VDD2_OP_REG |
||||
* and VDD2_SR_REG |
||||
*/ |
||||
return pmic_clrsetbits(dev, TPS65910_REG_DEVICE_CTRL, 0, |
||||
TPS65910_I2C_SEL_MASK); |
||||
} |
||||
|
||||
static struct dm_pmic_ops pmic_tps65910_ops = { |
||||
.reg_count = pmic_tps65910_reg_count, |
||||
.read = pmic_tps65910_read, |
||||
.write = pmic_tps65910_write, |
||||
}; |
||||
|
||||
static const struct udevice_id pmic_tps65910_match[] = { |
||||
{ .compatible = "ti,tps65910" }, |
||||
{ /* sentinel */ } |
||||
}; |
||||
|
||||
U_BOOT_DRIVER(pmic_tps65910) = { |
||||
.name = "pmic_tps65910", |
||||
.id = UCLASS_PMIC, |
||||
.of_match = pmic_tps65910_match, |
||||
.bind = pmic_tps65910_bind, |
||||
.probe = pmic_tps65910_probe, |
||||
.ops = &pmic_tps65910_ops, |
||||
}; |
@ -0,0 +1,459 @@ |
||||
/*
|
||||
* Copyright (C) EETS GmbH, 2017, Felix Brack <f.brack@eets.ch> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <dm.h> |
||||
#include <power/pmic.h> |
||||
#include <power/regulator.h> |
||||
#include <power/tps65910_pmic.h> |
||||
|
||||
#define VOUT_CHOICE_COUNT 4 |
||||
|
||||
/*
|
||||
* struct regulator_props - Properties of a LDO and VIO SMPS regulator |
||||
* |
||||
* All of these regulators allow setting one out of four output voltages. |
||||
* These output voltages are only achievable when supplying the regulator |
||||
* with a minimum input voltage. |
||||
* |
||||
* @vin_min[]: minimum supply input voltage in uV required to achieve the |
||||
* corresponding vout[] voltage |
||||
* @vout[]: regulator output voltage in uV |
||||
* @reg: I2C register used to set regulator voltage |
||||
*/ |
||||
struct regulator_props { |
||||
int vin_min[VOUT_CHOICE_COUNT]; |
||||
int vout[VOUT_CHOICE_COUNT]; |
||||
int reg; |
||||
}; |
||||
|
||||
static const struct regulator_props ldo_props_vdig1 = { |
||||
.vin_min = { 1700000, 2100000, 2700000, 3200000 }, |
||||
.vout = { 1200000, 1500000, 1800000, 2700000 }, |
||||
.reg = TPS65910_REG_VDIG1 |
||||
}; |
||||
|
||||
static const struct regulator_props ldo_props_vdig2 = { |
||||
.vin_min = { 1700000, 1700000, 1700000, 2700000 }, |
||||
.vout = { 1000000, 1100000, 1200000, 1800000 }, |
||||
.reg = TPS65910_REG_VDIG2 |
||||
}; |
||||
|
||||
static const struct regulator_props ldo_props_vpll = { |
||||
.vin_min = { 2700000, 2700000, 2700000, 3000000 }, |
||||
.vout = { 1000000, 1100000, 1800000, 2500000 }, |
||||
.reg = TPS65910_REG_VPLL |
||||
}; |
||||
|
||||
static const struct regulator_props ldo_props_vdac = { |
||||
.vin_min = { 2700000, 3000000, 3200000, 3200000 }, |
||||
.vout = { 1800000, 2600000, 2800000, 2850000 }, |
||||
.reg = TPS65910_REG_VDAC |
||||
}; |
||||
|
||||
static const struct regulator_props ldo_props_vaux1 = { |
||||
.vin_min = { 2700000, 3200000, 3200000, 3200000 }, |
||||
.vout = { 1800000, 2500000, 2800000, 2850000 }, |
||||
.reg = TPS65910_REG_VAUX1 |
||||
}; |
||||
|
||||
static const struct regulator_props ldo_props_vaux2 = { |
||||
.vin_min = { 2700000, 3200000, 3200000, 3600000 }, |
||||
.vout = { 1800000, 2800000, 2900000, 3300000 }, |
||||
.reg = TPS65910_REG_VAUX2 |
||||
}; |
||||
|
||||
static const struct regulator_props ldo_props_vaux33 = { |
||||
.vin_min = { 2700000, 2700000, 3200000, 3600000 }, |
||||
.vout = { 1800000, 2000000, 2800000, 3300000 }, |
||||
.reg = TPS65910_REG_VAUX33 |
||||
}; |
||||
|
||||
static const struct regulator_props ldo_props_vmmc = { |
||||
.vin_min = { 2700000, 3200000, 3200000, 3600000 }, |
||||
.vout = { 1800000, 2800000, 3000000, 3300000 }, |
||||
.reg = TPS65910_REG_VMMC |
||||
}; |
||||
|
||||
static const struct regulator_props smps_props_vio = { |
||||
.vin_min = { 3200000, 3200000, 4000000, 4400000 }, |
||||
.vout = { 1500000, 1800000, 2500000, 3300000 }, |
||||
.reg = TPS65910_REG_VIO |
||||
}; |
||||
|
||||
/* lookup table of control registers indexed by regulator unit number */ |
||||
static const int ctrl_regs[] = { |
||||
TPS65910_REG_VRTC, |
||||
TPS65910_REG_VIO, |
||||
TPS65910_REG_VDD1, |
||||
TPS65910_REG_VDD2, |
||||
TPS65910_REG_VDD3, |
||||
TPS65910_REG_VDIG1, |
||||
TPS65910_REG_VDIG2, |
||||
TPS65910_REG_VPLL, |
||||
TPS65910_REG_VDAC, |
||||
TPS65910_REG_VAUX1, |
||||
TPS65910_REG_VAUX2, |
||||
TPS65910_REG_VAUX33, |
||||
TPS65910_REG_VMMC |
||||
}; |
||||
|
||||
/* supply names as used in DT */ |
||||
static const char * const supply_names[] = { |
||||
"vccio-supply", |
||||
"vcc1-supply", |
||||
"vcc2-supply", |
||||
"vcc3-supply", |
||||
"vcc4-supply", |
||||
"vcc5-supply", |
||||
"vcc6-supply", |
||||
"vcc7-supply" |
||||
}; |
||||
|
||||
/* lookup table of regulator supplies indexed by regulator unit number */ |
||||
static const int regulator_supplies[] = { |
||||
TPS65910_SUPPLY_VCC7, |
||||
TPS65910_SUPPLY_VCCIO, |
||||
TPS65910_SUPPLY_VCC1, |
||||
TPS65910_SUPPLY_VCC2, |
||||
TPS65910_SUPPLY_VCC7, |
||||
TPS65910_SUPPLY_VCC6, |
||||
TPS65910_SUPPLY_VCC6, |
||||
TPS65910_SUPPLY_VCC5, |
||||
TPS65910_SUPPLY_VCC5, |
||||
TPS65910_SUPPLY_VCC4, |
||||
TPS65910_SUPPLY_VCC4, |
||||
TPS65910_SUPPLY_VCC3, |
||||
TPS65910_SUPPLY_VCC3 |
||||
}; |
||||
|
||||
static int get_ctrl_reg_from_unit_addr(const uint unit_addr) |
||||
{ |
||||
if (unit_addr < ARRAY_SIZE(ctrl_regs)) |
||||
return ctrl_regs[unit_addr]; |
||||
return -ENXIO; |
||||
} |
||||
|
||||
static int tps65910_regulator_get_value(struct udevice *dev, |
||||
const struct regulator_props *rgp) |
||||
{ |
||||
int sel, val, vout; |
||||
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); |
||||
int vin = pdata->supply; |
||||
|
||||
val = pmic_reg_read(dev->parent, rgp->reg); |
||||
if (val < 0) |
||||
return val; |
||||
sel = (val & TPS65910_SEL_MASK) >> 2; |
||||
vout = (vin >= *(rgp->vin_min + sel)) ? *(rgp->vout + sel) : 0; |
||||
vout = ((val & TPS65910_SUPPLY_STATE_MASK) == 1) ? vout : 0; |
||||
|
||||
return vout; |
||||
} |
||||
|
||||
static int tps65910_ldo_get_value(struct udevice *dev) |
||||
{ |
||||
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); |
||||
int vin; |
||||
|
||||
if (!pdata) |
||||
return 0; |
||||
vin = pdata->supply; |
||||
|
||||
switch (pdata->unit) { |
||||
case TPS65910_UNIT_VRTC: |
||||
/* VRTC is fixed and can't be turned off */ |
||||
return (vin >= 2500000) ? 1830000 : 0; |
||||
case TPS65910_UNIT_VDIG1: |
||||
return tps65910_regulator_get_value(dev, &ldo_props_vdig1); |
||||
case TPS65910_UNIT_VDIG2: |
||||
return tps65910_regulator_get_value(dev, &ldo_props_vdig2); |
||||
case TPS65910_UNIT_VPLL: |
||||
return tps65910_regulator_get_value(dev, &ldo_props_vpll); |
||||
case TPS65910_UNIT_VDAC: |
||||
return tps65910_regulator_get_value(dev, &ldo_props_vdac); |
||||
case TPS65910_UNIT_VAUX1: |
||||
return tps65910_regulator_get_value(dev, &ldo_props_vaux1); |
||||
case TPS65910_UNIT_VAUX2: |
||||
return tps65910_regulator_get_value(dev, &ldo_props_vaux2); |
||||
case TPS65910_UNIT_VAUX33: |
||||
return tps65910_regulator_get_value(dev, &ldo_props_vaux33); |
||||
case TPS65910_UNIT_VMMC: |
||||
return tps65910_regulator_get_value(dev, &ldo_props_vmmc); |
||||
default: |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
static int tps65910_regulator_set_value(struct udevice *dev, |
||||
const struct regulator_props *ldo, |
||||
int uV) |
||||
{ |
||||
int val; |
||||
int sel = 0; |
||||
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); |
||||
|
||||
do { |
||||
/* we only allow exact voltage matches */ |
||||
if (uV == *(ldo->vout + sel)) |
||||
break; |
||||
} while (++sel < VOUT_CHOICE_COUNT); |
||||
if (sel == VOUT_CHOICE_COUNT) |
||||
return -EINVAL; |
||||
if (pdata->supply < *(ldo->vin_min + sel)) |
||||
return -EINVAL; |
||||
|
||||
val = pmic_reg_read(dev->parent, ldo->reg); |
||||
if (val < 0) |
||||
return val; |
||||
val &= ~TPS65910_SEL_MASK; |
||||
val |= sel << 2; |
||||
return pmic_reg_write(dev->parent, ldo->reg, val); |
||||
} |
||||
|
||||
static int tps65910_ldo_set_value(struct udevice *dev, int uV) |
||||
{ |
||||
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); |
||||
int vin = pdata->supply; |
||||
|
||||
switch (pdata->unit) { |
||||
case TPS65910_UNIT_VRTC: |
||||
/* VRTC is fixed to 1.83V and can't be turned off */ |
||||
if (vin < 2500000) |
||||
return -EINVAL; |
||||
return 0; |
||||
case TPS65910_UNIT_VDIG1: |
||||
return tps65910_regulator_set_value(dev, &ldo_props_vdig1, uV); |
||||
case TPS65910_UNIT_VDIG2: |
||||
return tps65910_regulator_set_value(dev, &ldo_props_vdig2, uV); |
||||
case TPS65910_UNIT_VPLL: |
||||
return tps65910_regulator_set_value(dev, &ldo_props_vpll, uV); |
||||
case TPS65910_UNIT_VDAC: |
||||
return tps65910_regulator_set_value(dev, &ldo_props_vdac, uV); |
||||
case TPS65910_UNIT_VAUX1: |
||||
return tps65910_regulator_set_value(dev, &ldo_props_vaux1, uV); |
||||
case TPS65910_UNIT_VAUX2: |
||||
return tps65910_regulator_set_value(dev, &ldo_props_vaux2, uV); |
||||
case TPS65910_UNIT_VAUX33: |
||||
return tps65910_regulator_set_value(dev, &ldo_props_vaux33, uV); |
||||
case TPS65910_UNIT_VMMC: |
||||
return tps65910_regulator_set_value(dev, &ldo_props_vmmc, uV); |
||||
default: |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
static int tps65910_get_enable(struct udevice *dev) |
||||
{ |
||||
int reg, val; |
||||
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); |
||||
|
||||
reg = get_ctrl_reg_from_unit_addr(pdata->unit); |
||||
if (reg < 0) |
||||
return reg; |
||||
|
||||
val = pmic_reg_read(dev->parent, reg); |
||||
if (val < 0) |
||||
return val; |
||||
|
||||
/* bits 1:0 of regulator control register define state */ |
||||
return ((val & TPS65910_SUPPLY_STATE_MASK) == 1); |
||||
} |
||||
|
||||
static int tps65910_set_enable(struct udevice *dev, bool enable) |
||||
{ |
||||
int reg; |
||||
uint clr, set; |
||||
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); |
||||
|
||||
reg = get_ctrl_reg_from_unit_addr(pdata->unit); |
||||
if (reg < 0) |
||||
return reg; |
||||
|
||||
if (enable) { |
||||
clr = TPS65910_SUPPLY_STATE_MASK & ~TPS65910_SUPPLY_STATE_ON; |
||||
set = TPS65910_SUPPLY_STATE_MASK & TPS65910_SUPPLY_STATE_ON; |
||||
} else { |
||||
clr = TPS65910_SUPPLY_STATE_MASK & ~TPS65910_SUPPLY_STATE_OFF; |
||||
set = TPS65910_SUPPLY_STATE_MASK & TPS65910_SUPPLY_STATE_OFF; |
||||
} |
||||
return pmic_clrsetbits(dev->parent, reg, clr, set); |
||||
} |
||||
|
||||
static int buck_get_vdd1_vdd2_value(struct udevice *dev, int reg_vdd) |
||||
{ |
||||
int gain; |
||||
int val = pmic_reg_read(dev, reg_vdd); |
||||
|
||||
if (val < 0) |
||||
return val; |
||||
gain = (val & TPS65910_GAIN_SEL_MASK) >> 6; |
||||
gain = (gain == 0) ? 1 : gain; |
||||
val = pmic_reg_read(dev, reg_vdd + 1); |
||||
if (val < 0) |
||||
return val; |
||||
if (val & TPS65910_VDD_SR_MASK) |
||||
/* use smart reflex value instead */ |
||||
val = pmic_reg_read(dev, reg_vdd + 2); |
||||
if (val < 0) |
||||
return val; |
||||
return (562500 + (val & TPS65910_VDD_SEL_MASK) * 12500) * gain; |
||||
} |
||||
|
||||
static int tps65910_buck_get_value(struct udevice *dev) |
||||
{ |
||||
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); |
||||
|
||||
switch (pdata->unit) { |
||||
case TPS65910_UNIT_VIO: |
||||
return tps65910_regulator_get_value(dev, &smps_props_vio); |
||||
case TPS65910_UNIT_VDD1: |
||||
return buck_get_vdd1_vdd2_value(dev->parent, TPS65910_REG_VDD1); |
||||
case TPS65910_UNIT_VDD2: |
||||
return buck_get_vdd1_vdd2_value(dev->parent, TPS65910_REG_VDD2); |
||||
default: |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
static int buck_set_vdd1_vdd2_value(struct udevice *dev, int uV) |
||||
{ |
||||
int ret, reg_vdd, gain; |
||||
int val; |
||||
struct dm_regulator_uclass_platdata *uc_pdata; |
||||
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); |
||||
|
||||
switch (pdata->unit) { |
||||
case TPS65910_UNIT_VDD1: |
||||
reg_vdd = TPS65910_REG_VDD1; |
||||
break; |
||||
case TPS65910_UNIT_VDD2: |
||||
reg_vdd = TPS65910_REG_VDD2; |
||||
break; |
||||
default: |
||||
return -EINVAL; |
||||
} |
||||
uc_pdata = dev_get_uclass_platdata(dev); |
||||
|
||||
/* check setpoint is within limits */ |
||||
if (uV < uc_pdata->min_uV) { |
||||
error("voltage %duV for %s too low\n", uV, dev->name); |
||||
return -EINVAL; |
||||
} |
||||
if (uV > uc_pdata->max_uV) { |
||||
error("voltage %duV for %s too high\n", uV, dev->name); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
val = pmic_reg_read(dev->parent, reg_vdd); |
||||
if (val < 0) |
||||
return val; |
||||
gain = (val & TPS65910_GAIN_SEL_MASK) >> 6; |
||||
gain = (gain == 0) ? 1 : gain; |
||||
val = ((uV / gain) - 562500) / 12500; |
||||
if (val < TPS65910_VDD_SEL_MIN || val > TPS65910_VDD_SEL_MAX) |
||||
/*
|
||||
* Neither do we change the gain, nor do we allow shutdown or |
||||
* any approximate value (for now) |
||||
*/ |
||||
return -EPERM; |
||||
val &= TPS65910_VDD_SEL_MASK; |
||||
ret = pmic_reg_write(dev->parent, reg_vdd + 1, val); |
||||
if (ret) |
||||
return ret; |
||||
return 0; |
||||
} |
||||
|
||||
static int tps65910_buck_set_value(struct udevice *dev, int uV) |
||||
{ |
||||
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); |
||||
|
||||
if (pdata->unit == TPS65910_UNIT_VIO) |
||||
return tps65910_regulator_set_value(dev, &smps_props_vio, uV); |
||||
|
||||
return buck_set_vdd1_vdd2_value(dev, uV); |
||||
} |
||||
|
||||
static int tps65910_boost_get_value(struct udevice *dev) |
||||
{ |
||||
int vout; |
||||
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); |
||||
|
||||
vout = (pdata->supply >= 3000000) ? 5000000 : 0; |
||||
return vout; |
||||
} |
||||
|
||||
static int tps65910_regulator_ofdata_to_platdata(struct udevice *dev) |
||||
{ |
||||
struct udevice *supply; |
||||
int ret; |
||||
const char *supply_name; |
||||
struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); |
||||
|
||||
pdata->unit = dev_get_driver_data(dev); |
||||
if (pdata->unit > TPS65910_UNIT_VMMC) |
||||
return -EINVAL; |
||||
supply_name = supply_names[regulator_supplies[pdata->unit]]; |
||||
|
||||
debug("Looking up supply power %s\n", supply_name); |
||||
ret = device_get_supply_regulator(dev->parent, supply_name, &supply); |
||||
if (ret) { |
||||
debug(" missing supply power %s\n", supply_name); |
||||
return ret; |
||||
} |
||||
pdata->supply = regulator_get_value(supply); |
||||
if (pdata->supply < 0) { |
||||
debug(" invalid supply voltage for regulator %s\n", |
||||
supply->name); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static const struct dm_regulator_ops tps65910_boost_ops = { |
||||
.get_value = tps65910_boost_get_value, |
||||
.get_enable = tps65910_get_enable, |
||||
.set_enable = tps65910_set_enable, |
||||
}; |
||||
|
||||
U_BOOT_DRIVER(tps65910_boost) = { |
||||
.name = TPS65910_BOOST_DRIVER, |
||||
.id = UCLASS_REGULATOR, |
||||
.ops = &tps65910_boost_ops, |
||||
.platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata), |
||||
.ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata, |
||||
}; |
||||
|
||||
static const struct dm_regulator_ops tps65910_buck_ops = { |
||||
.get_value = tps65910_buck_get_value, |
||||
.set_value = tps65910_buck_set_value, |
||||
.get_enable = tps65910_get_enable, |
||||
.set_enable = tps65910_set_enable, |
||||
}; |
||||
|
||||
U_BOOT_DRIVER(tps65910_buck) = { |
||||
.name = TPS65910_BUCK_DRIVER, |
||||
.id = UCLASS_REGULATOR, |
||||
.ops = &tps65910_buck_ops, |
||||
.platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata), |
||||
.ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata, |
||||
}; |
||||
|
||||
static const struct dm_regulator_ops tps65910_ldo_ops = { |
||||
.get_value = tps65910_ldo_get_value, |
||||
.set_value = tps65910_ldo_set_value, |
||||
.get_enable = tps65910_get_enable, |
||||
.set_enable = tps65910_set_enable, |
||||
}; |
||||
|
||||
U_BOOT_DRIVER(tps65910_ldo) = { |
||||
.name = TPS65910_LDO_DRIVER, |
||||
.id = UCLASS_REGULATOR, |
||||
.ops = &tps65910_ldo_ops, |
||||
.platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata), |
||||
.ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata, |
||||
}; |
@ -0,0 +1,93 @@ |
||||
/*
|
||||
* Symbol access for symbols set up by binman as part of the build. |
||||
* |
||||
* This allows C code to access the position of a particular part of the image |
||||
* assembled by binman. |
||||
* |
||||
* Copyright (c) 2017 Google, Inc |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef __BINMAN_SYM_H |
||||
#define __BINMAN_SYM_H |
||||
|
||||
#define BINMAN_SYM_MISSING (-1UL) |
||||
|
||||
#ifdef CONFIG_BINMAN |
||||
|
||||
/**
|
||||
* binman_symname() - Internal fnuction to get a binman symbol name |
||||
* |
||||
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl') |
||||
* @_prop_name: Property value to get from that entry (e.g. 'pos') |
||||
* @returns name of the symbol for that entry and property |
||||
*/ |
||||
#define binman_symname(_entry_name, _prop_name) \ |
||||
_binman_ ## _entry_name ## _prop_ ## _prop_name |
||||
|
||||
/**
|
||||
* binman_sym_declare() - Declare a symbol that will be used at run-time |
||||
* |
||||
* @_type: Type f the symbol (e.g. unsigned long) |
||||
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl') |
||||
* @_prop_name: Property value to get from that entry (e.g. 'pos') |
||||
*/ |
||||
#define binman_sym_declare(_type, _entry_name, _prop_name) \ |
||||
_type binman_symname(_entry_name, _prop_name) \
|
||||
__attribute__((aligned(4), unused, section(".binman_sym"))) |
||||
|
||||
/**
|
||||
* binman_sym_extern() - Declare a extern symbol that will be used at run-time |
||||
* |
||||
* @_type: Type f the symbol (e.g. unsigned long) |
||||
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl') |
||||
* @_prop_name: Property value to get from that entry (e.g. 'pos') |
||||
*/ |
||||
#define binman_sym_extern(_type, _entry_name, _prop_name) \ |
||||
extern _type binman_symname(_entry_name, _prop_name) \
|
||||
__attribute__((aligned(4), unused, section(".binman_sym"))) |
||||
|
||||
/**
|
||||
* binman_sym_declare_optional() - Declare an optional symbol |
||||
* |
||||
* If this symbol cannot be provided by binman, an error will not be generated. |
||||
* Instead the image will be assigned the value BINMAN_SYM_MISSING. |
||||
* |
||||
* @_type: Type f the symbol (e.g. unsigned long) |
||||
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl') |
||||
* @_prop_name: Property value to get from that entry (e.g. 'pos') |
||||
*/ |
||||
#define binman_sym_declare_optional(_type, _entry_name, _prop_name) \ |
||||
_type binman_symname(_entry_name, _prop_name) \
|
||||
__attribute__((aligned(4), weak, unused, \
|
||||
section(".binman_sym"))) |
||||
|
||||
/**
|
||||
* binman_sym() - Access a previously declared symbol |
||||
* |
||||
* This is used to get the value of a symbol. E.g.: |
||||
* |
||||
* ulong address = binman_sym(ulong, u_boot_spl, pos); |
||||
* |
||||
* @_type: Type f the symbol (e.g. unsigned long) |
||||
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl') |
||||
* @_prop_name: Property value to get from that entry (e.g. 'pos') |
||||
* @returns value of that property (filled in by binman) |
||||
*/ |
||||
#define binman_sym(_type, _entry_name, _prop_name) \ |
||||
(*(_type *)&binman_symname(_entry_name, _prop_name)) |
||||
|
||||
#else /* !BINMAN */ |
||||
|
||||
#define binman_sym_declare(_type, _entry_name, _prop_name) |
||||
|
||||
#define binman_sym_declare_optional(_type, _entry_name, _prop_name) |
||||
|
||||
#define binman_sym_extern(_type, _entry_name, _prop_name) |
||||
|
||||
#define binman_sym(_type, _entry_name, _prop_name) BINMAN_SYM_MISSING |
||||
|
||||
#endif /* BINMAN */ |
||||
|
||||
#endif |
@ -0,0 +1,130 @@ |
||||
/*
|
||||
* Copyright (C) EETS GmbH, 2017, Felix Brack <f.brack@eets.ch> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef __TPS65910_PMIC_H_ |
||||
#define __TPS65910_PMIC_H_ |
||||
|
||||
#define TPS65910_I2C_SEL_MASK (0x1 << 4) |
||||
#define TPS65910_VDD_SR_MASK (0x1 << 7) |
||||
#define TPS65910_GAIN_SEL_MASK (0x3 << 6) |
||||
#define TPS65910_VDD_SEL_MASK 0x7f |
||||
#define TPS65910_VDD_SEL_MIN 3 |
||||
#define TPS65910_VDD_SEL_MAX 75 |
||||
#define TPS65910_SEL_MASK (0x3 << 2) |
||||
#define TPS65910_SUPPLY_STATE_MASK 0x3 |
||||
#define TPS65910_SUPPLY_STATE_OFF 0x0 |
||||
#define TPS65910_SUPPLY_STATE_ON 0x1 |
||||
|
||||
/* i2c registers */ |
||||
enum { |
||||
TPS65910_REG_RTC_SEC = 0x00, |
||||
TPS65910_REG_RTC_MIN, |
||||
TPS65910_REG_RTC_HOUR, |
||||
TPS65910_REG_RTC_DAY, |
||||
TPS65910_REG_RTC_MONTH, |
||||
TPS65910_REG_RTC_YEAR, |
||||
TPS65910_REG_RTC_WEEK, |
||||
TPS65910_REG_RTC_ALARM_SEC = 0x08, |
||||
TPS65910_REG_RTC_ALARM_MIN, |
||||
TPS65910_REG_RTC_ALARM_HOUR, |
||||
TPS65910_REG_RTC_ALARM_DAY, |
||||
TPS65910_REG_RTC_ALARM_MONTH, |
||||
TPS65910_REG_RTC_ALARM_YEAR, |
||||
TPS65910_REG_RTC_CTRL = 0x10, |
||||
TPS65910_REG_RTC_STAT, |
||||
TPS65910_REG_RTC_INT, |
||||
TPS65910_REG_RTC_COMP_LSB, |
||||
TPS65910_REG_RTC_COMP_MSB, |
||||
TPS65910_REG_RTC_RESISTOR_PRG, |
||||
TPS65910_REG_RTC_RESET_STAT, |
||||
TPS65910_REG_BACKUP1, |
||||
TPS65910_REG_BACKUP2, |
||||
TPS65910_REG_BACKUP3, |
||||
TPS65910_REG_BACKUP4, |
||||
TPS65910_REG_BACKUP5, |
||||
TPS65910_REG_PUADEN, |
||||
TPS65910_REG_REF, |
||||
TPS65910_REG_VRTC, |
||||
TPS65910_REG_VIO = 0x20, |
||||
TPS65910_REG_VDD1, |
||||
TPS65910_REG_VDD1_VAL, |
||||
TPS65910_REG_VDD1_VAL_SR, |
||||
TPS65910_REG_VDD2, |
||||
TPS65910_REG_VDD2_VAL, |
||||
TPS65910_REG_VDD2_VAL_SR, |
||||
TPS65910_REG_VDD3, |
||||
TPS65910_REG_VDIG1 = 0x30, |
||||
TPS65910_REG_VDIG2, |
||||
TPS65910_REG_VAUX1, |
||||
TPS65910_REG_VAUX2, |
||||
TPS65910_REG_VAUX33, |
||||
TPS65910_REG_VMMC, |
||||
TPS65910_REG_VPLL, |
||||
TPS65910_REG_VDAC, |
||||
TPS65910_REG_THERM, |
||||
TPS65910_REG_BATTERY_BACKUP_CHARGE, |
||||
TPS65910_REG_DCDC_CTRL = 0x3e, |
||||
TPS65910_REG_DEVICE_CTRL, |
||||
TPS65910_REG_DEVICE_CTRL2, |
||||
TPS65910_REG_SLEEP_KEEP_LDO_ON, |
||||
TPS65910_REG_SLEEP_KEEP_RES_ON, |
||||
TPS65910_REG_SLEEP_SET_LDO_OFF, |
||||
TPS65910_REG_SLEEP_SET_RES_OFF, |
||||
TPS65910_REG_EN1_LDO_ASS, |
||||
TPS65910_REG_EM1_SMPS_ASS, |
||||
TPS65910_REG_EN2_LDO_ASS, |
||||
TPS65910_REG_EM2_SMPS_ASS, |
||||
TPS65910_REG_INT_STAT = 0x50, |
||||
TPS65910_REG_INT_MASK, |
||||
TPS65910_REG_INT_STAT2, |
||||
TPS65910_REG_INT_MASK2, |
||||
TPS65910_REG_GPIO = 0x60, |
||||
TPS65910_REG_JTAGREVNUM = 0x80, |
||||
TPS65910_NUM_REGS |
||||
}; |
||||
|
||||
/* chip supplies */ |
||||
enum { |
||||
TPS65910_SUPPLY_VCCIO = 0x00, |
||||
TPS65910_SUPPLY_VCC1, |
||||
TPS65910_SUPPLY_VCC2, |
||||
TPS65910_SUPPLY_VCC3, |
||||
TPS65910_SUPPLY_VCC4, |
||||
TPS65910_SUPPLY_VCC5, |
||||
TPS65910_SUPPLY_VCC6, |
||||
TPS65910_SUPPLY_VCC7, |
||||
TPS65910_NUM_SUPPLIES |
||||
}; |
||||
|
||||
/* regulator unit numbers */ |
||||
enum { |
||||
TPS65910_UNIT_VRTC = 0x00, |
||||
TPS65910_UNIT_VIO, |
||||
TPS65910_UNIT_VDD1, |
||||
TPS65910_UNIT_VDD2, |
||||
TPS65910_UNIT_VDD3, |
||||
TPS65910_UNIT_VDIG1, |
||||
TPS65910_UNIT_VDIG2, |
||||
TPS65910_UNIT_VPLL, |
||||
TPS65910_UNIT_VDAC, |
||||
TPS65910_UNIT_VAUX1, |
||||
TPS65910_UNIT_VAUX2, |
||||
TPS65910_UNIT_VAUX33, |
||||
TPS65910_UNIT_VMMC, |
||||
}; |
||||
|
||||
/* platform data */ |
||||
struct tps65910_regulator_pdata { |
||||
u32 supply; /* regulator supply voltage in uV */ |
||||
uint unit; /* unit-address according to DT */ |
||||
}; |
||||
|
||||
/* driver names */ |
||||
#define TPS65910_BUCK_DRIVER "tps65910_buck" |
||||
#define TPS65910_BOOST_DRIVER "tps65910_boost" |
||||
#define TPS65910_LDO_DRIVER "tps65910_ldo" |
||||
|
||||
#endif /* __TPS65910_PMIC_H_ */ |
@ -0,0 +1,129 @@ |
||||
# Copyright (c) 2016 Google, Inc |
||||
# Written by Simon Glass <sjg@chromium.org> |
||||
# |
||||
# SPDX-License-Identifier: GPL-2.0+ |
||||
# |
||||
# Handle various things related to ELF images |
||||
# |
||||
|
||||
from collections import namedtuple, OrderedDict |
||||
import command |
||||
import os |
||||
import re |
||||
import struct |
||||
|
||||
import tools |
||||
|
||||
# This is enabled from control.py |
||||
debug = False |
||||
|
||||
Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak']) |
||||
|
||||
|
||||
def GetSymbols(fname, patterns): |
||||
"""Get the symbols from an ELF file |
||||
|
||||
Args: |
||||
fname: Filename of the ELF file to read |
||||
patterns: List of regex patterns to search for, each a string |
||||
|
||||
Returns: |
||||
None, if the file does not exist, or Dict: |
||||
key: Name of symbol |
||||
value: Hex value of symbol |
||||
""" |
||||
stdout = command.Output('objdump', '-t', fname, raise_on_error=False) |
||||
lines = stdout.splitlines() |
||||
if patterns: |
||||
re_syms = re.compile('|'.join(patterns)) |
||||
else: |
||||
re_syms = None |
||||
syms = {} |
||||
syms_started = False |
||||
for line in lines: |
||||
if not line or not syms_started: |
||||
if 'SYMBOL TABLE' in line: |
||||
syms_started = True |
||||
line = None # Otherwise code coverage complains about 'continue' |
||||
continue |
||||
if re_syms and not re_syms.search(line): |
||||
continue |
||||
|
||||
space_pos = line.find(' ') |
||||
value, rest = line[:space_pos], line[space_pos + 1:] |
||||
flags = rest[:7] |
||||
parts = rest[7:].split() |
||||
section, size = parts[:2] |
||||
if len(parts) > 2: |
||||
name = parts[2] |
||||
syms[name] = Symbol(section, int(value, 16), int(size,16), |
||||
flags[1] == 'w') |
||||
return syms |
||||
|
||||
def GetSymbolAddress(fname, sym_name): |
||||
"""Get a value of a symbol from an ELF file |
||||
|
||||
Args: |
||||
fname: Filename of the ELF file to read |
||||
patterns: List of regex patterns to search for, each a string |
||||
|
||||
Returns: |
||||
Symbol value (as an integer) or None if not found |
||||
""" |
||||
syms = GetSymbols(fname, [sym_name]) |
||||
sym = syms.get(sym_name) |
||||
if not sym: |
||||
return None |
||||
return sym.address |
||||
|
||||
def LookupAndWriteSymbols(elf_fname, entry, image): |
||||
"""Replace all symbols in an entry with their correct values |
||||
|
||||
The entry contents is updated so that values for referenced symbols will be |
||||
visible at run time. This is done by finding out the symbols positions in |
||||
the entry (using the ELF file) and replacing them with values from binman's |
||||
data structures. |
||||
|
||||
Args: |
||||
elf_fname: Filename of ELF image containing the symbol information for |
||||
entry |
||||
entry: Entry to process |
||||
image: Image which can be used to lookup symbol values |
||||
""" |
||||
fname = tools.GetInputFilename(elf_fname) |
||||
syms = GetSymbols(fname, ['image', 'binman']) |
||||
if not syms: |
||||
return |
||||
base = syms.get('__image_copy_start') |
||||
if not base: |
||||
return |
||||
for name, sym in syms.iteritems(): |
||||
if name.startswith('_binman'): |
||||
msg = ("Image '%s': Symbol '%s'\n in entry '%s'" % |
||||
(image.GetPath(), name, entry.GetPath())) |
||||
offset = sym.address - base.address |
||||
if offset < 0 or offset + sym.size > entry.contents_size: |
||||
raise ValueError('%s has offset %x (size %x) but the contents ' |
||||
'size is %x' % (entry.GetPath(), offset, |
||||
sym.size, entry.contents_size)) |
||||
if sym.size == 4: |
||||
pack_string = '<I' |
||||
elif sym.size == 8: |
||||
pack_string = '<Q' |
||||
else: |
||||
raise ValueError('%s has size %d: only 4 and 8 are supported' % |
||||
(msg, sym.size)) |
||||
|
||||
# Look up the symbol in our entry tables. |
||||
value = image.LookupSymbol(name, sym.weak, msg) |
||||
if value is not None: |
||||
value += base.address |
||||
else: |
||||
value = -1 |
||||
pack_string = pack_string.lower() |
||||
value_bytes = struct.pack(pack_string, value) |
||||
if debug: |
||||
print('%s:\n insert %s, offset %x, value %x, length %d' % |
||||
(msg, name, offset, value, len(value_bytes))) |
||||
entry.data = (entry.data[:offset] + value_bytes + |
||||
entry.data[offset + sym.size:]) |
@ -0,0 +1,122 @@ |
||||
# |
||||
# Copyright (c) 2017 Google, Inc |
||||
# Written by Simon Glass <sjg@chromium.org> |
||||
# |
||||
# SPDX-License-Identifier: GPL-2.0+ |
||||
# |
||||
# Test for the elf module |
||||
|
||||
from contextlib import contextmanager |
||||
import os |
||||
import sys |
||||
import unittest |
||||
|
||||
try: |
||||
from StringIO import StringIO |
||||
except ImportError: |
||||
from io import StringIO |
||||
|
||||
import elf |
||||
|
||||
binman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) |
||||
|
||||
# Use this to suppress stdout/stderr output: |
||||
# with capture_sys_output() as (stdout, stderr) |
||||
# ...do something... |
||||
@contextmanager |
||||
def capture_sys_output(): |
||||
capture_out, capture_err = StringIO(), StringIO() |
||||
old_out, old_err = sys.stdout, sys.stderr |
||||
try: |
||||
sys.stdout, sys.stderr = capture_out, capture_err |
||||
yield capture_out, capture_err |
||||
finally: |
||||
sys.stdout, sys.stderr = old_out, old_err |
||||
|
||||
|
||||
class FakeEntry: |
||||
def __init__(self, contents_size): |
||||
self.contents_size = contents_size |
||||
self.data = 'a' * contents_size |
||||
|
||||
def GetPath(self): |
||||
return 'entry_path' |
||||
|
||||
class FakeImage: |
||||
def __init__(self, sym_value=1): |
||||
self.sym_value = sym_value |
||||
|
||||
def GetPath(self): |
||||
return 'image_path' |
||||
|
||||
def LookupSymbol(self, name, weak, msg): |
||||
return self.sym_value |
||||
|
||||
class TestElf(unittest.TestCase): |
||||
def testAllSymbols(self): |
||||
fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr') |
||||
syms = elf.GetSymbols(fname, []) |
||||
self.assertIn('.ucode', syms) |
||||
|
||||
def testRegexSymbols(self): |
||||
fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr') |
||||
syms = elf.GetSymbols(fname, ['ucode']) |
||||
self.assertIn('.ucode', syms) |
||||
syms = elf.GetSymbols(fname, ['missing']) |
||||
self.assertNotIn('.ucode', syms) |
||||
syms = elf.GetSymbols(fname, ['missing', 'ucode']) |
||||
self.assertIn('.ucode', syms) |
||||
|
||||
def testMissingFile(self): |
||||
entry = FakeEntry(10) |
||||
image = FakeImage() |
||||
with self.assertRaises(ValueError) as e: |
||||
syms = elf.LookupAndWriteSymbols('missing-file', entry, image) |
||||
self.assertIn("Filename 'missing-file' not found in input path", |
||||
str(e.exception)) |
||||
|
||||
def testOutsideFile(self): |
||||
entry = FakeEntry(10) |
||||
image = FakeImage() |
||||
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms') |
||||
with self.assertRaises(ValueError) as e: |
||||
syms = elf.LookupAndWriteSymbols(elf_fname, entry, image) |
||||
self.assertIn('entry_path has offset 4 (size 8) but the contents size ' |
||||
'is a', str(e.exception)) |
||||
|
||||
def testMissingImageStart(self): |
||||
entry = FakeEntry(10) |
||||
image = FakeImage() |
||||
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_bad') |
||||
self.assertEqual(elf.LookupAndWriteSymbols(elf_fname, entry, image), |
||||
None) |
||||
|
||||
def testBadSymbolSize(self): |
||||
entry = FakeEntry(10) |
||||
image = FakeImage() |
||||
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_size') |
||||
with self.assertRaises(ValueError) as e: |
||||
syms = elf.LookupAndWriteSymbols(elf_fname, entry, image) |
||||
self.assertIn('has size 1: only 4 and 8 are supported', |
||||
str(e.exception)) |
||||
|
||||
def testNoValue(self): |
||||
entry = FakeEntry(20) |
||||
image = FakeImage(sym_value=None) |
||||
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms') |
||||
syms = elf.LookupAndWriteSymbols(elf_fname, entry, image) |
||||
self.assertEqual(chr(255) * 16 + 'a' * 4, entry.data) |
||||
|
||||
def testDebug(self): |
||||
elf.debug = True |
||||
entry = FakeEntry(20) |
||||
image = FakeImage() |
||||
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms') |
||||
with capture_sys_output() as (stdout, stderr): |
||||
syms = elf.LookupAndWriteSymbols(elf_fname, entry, image) |
||||
elf.debug = False |
||||
self.assertTrue(len(stdout.getvalue()) > 0) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
unittest.main() |
@ -0,0 +1,17 @@ |
||||
# Copyright (c) 2016 Google, Inc |
||||
# Written by Simon Glass <sjg@chromium.org> |
||||
# |
||||
# SPDX-License-Identifier: GPL-2.0+ |
||||
# |
||||
# Entry-type module for U-Boot device tree |
||||
# |
||||
|
||||
from entry import Entry |
||||
from blob import Entry_blob |
||||
|
||||
class Entry_u_boot_spl_dtb(Entry_blob): |
||||
def __init__(self, image, etype, node): |
||||
Entry_blob.__init__(self, image, etype, node) |
||||
|
||||
def GetDefaultFilename(self): |
||||
return 'spl/u-boot-spl.dtb' |
@ -0,0 +1,17 @@ |
||||
# Copyright (c) 2016 Google, Inc |
||||
# Written by Simon Glass <sjg@chromium.org> |
||||
# |
||||
# SPDX-License-Identifier: GPL-2.0+ |
||||
# |
||||
# Entry-type module for 'u-boot-nodtb.bin' |
||||
# |
||||
|
||||
from entry import Entry |
||||
from blob import Entry_blob |
||||
|
||||
class Entry_u_boot_spl_nodtb(Entry_blob): |
||||
def __init__(self, image, etype, node): |
||||
Entry_blob.__init__(self, image, etype, node) |
||||
|
||||
def GetDefaultFilename(self): |
||||
return 'spl/u-boot-spl-nodtb.bin' |
@ -0,0 +1,46 @@ |
||||
# |
||||
# Copyright (c) 2017 Google, Inc |
||||
# Written by Simon Glass <sjg@chromium.org> |
||||
# |
||||
# SPDX-License-Identifier: GPL-2.0+ |
||||
# |
||||
# Test for the image module |
||||
|
||||
import unittest |
||||
|
||||
from image import Image |
||||
from elf_test import capture_sys_output |
||||
|
||||
class TestImage(unittest.TestCase): |
||||
def testInvalidFormat(self): |
||||
image = Image('name', 'node', test=True) |
||||
with self.assertRaises(ValueError) as e: |
||||
image.LookupSymbol('_binman_something_prop_', False, 'msg') |
||||
self.assertIn( |
||||
"msg: Symbol '_binman_something_prop_' has invalid format", |
||||
str(e.exception)) |
||||
|
||||
def testMissingSymbol(self): |
||||
image = Image('name', 'node', test=True) |
||||
image._entries = {} |
||||
with self.assertRaises(ValueError) as e: |
||||
image.LookupSymbol('_binman_type_prop_pname', False, 'msg') |
||||
self.assertIn("msg: Entry 'type' not found in list ()", |
||||
str(e.exception)) |
||||
|
||||
def testMissingSymbolOptional(self): |
||||
image = Image('name', 'node', test=True) |
||||
image._entries = {} |
||||
with capture_sys_output() as (stdout, stderr): |
||||
val = image.LookupSymbol('_binman_type_prop_pname', True, 'msg') |
||||
self.assertEqual(val, None) |
||||
self.assertEqual("Warning: msg: Entry 'type' not found in list ()\n", |
||||
stderr.getvalue()) |
||||
self.assertEqual('', stdout.getvalue()) |
||||
|
||||
def testBadProperty(self): |
||||
image = Image('name', 'node', test=True) |
||||
image._entries = {'u-boot': 1} |
||||
with self.assertRaises(ValueError) as e: |
||||
image.LookupSymbol('_binman_u_boot_prop_bad', False, 'msg') |
||||
self.assertIn("msg: No such property 'bad", str(e.exception)) |
@ -0,0 +1,13 @@ |
||||
/dts-v1/; |
||||
|
||||
/ { |
||||
#address-cells = <1>; |
||||
#size-cells = <1>; |
||||
|
||||
binman { |
||||
size = <16>; |
||||
|
||||
u-boot-spl-dtb { |
||||
}; |
||||
}; |
||||
}; |
@ -0,0 +1,11 @@ |
||||
/dts-v1/; |
||||
|
||||
/ { |
||||
#address-cells = <1>; |
||||
#size-cells = <1>; |
||||
|
||||
binman { |
||||
u-boot-spl-nodtb { |
||||
}; |
||||
}; |
||||
}; |
@ -0,0 +1,20 @@ |
||||
/dts-v1/; |
||||
|
||||
/ { |
||||
#address-cells = <1>; |
||||
#size-cells = <1>; |
||||
|
||||
binman { |
||||
pad-byte = <0xff>; |
||||
u-boot-spl { |
||||
}; |
||||
|
||||
u-boot { |
||||
pos = <20>; |
||||
}; |
||||
|
||||
u-boot-spl2 { |
||||
type = "u-boot-spl"; |
||||
}; |
||||
}; |
||||
}; |
Binary file not shown.
@ -0,0 +1,14 @@ |
||||
/*
|
||||
* Copyright (c) 2017 Google, Inc |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
* |
||||
* Simple program to create some binman symbols. This is used by binman tests. |
||||
*/ |
||||
|
||||
#define CONFIG_BINMAN |
||||
#include <binman_sym.h> |
||||
|
||||
binman_sym_declare(unsigned long, u_boot_spl, pos); |
||||
binman_sym_declare(unsigned long long, u_boot_spl2, pos); |
||||
binman_sym_declare(unsigned long, u_boot_any, pos); |
@ -0,0 +1,30 @@ |
||||
/* |
||||
* Copyright (c) 2016 Google, Inc |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") |
||||
OUTPUT_ARCH(i386) |
||||
ENTRY(_start) |
||||
|
||||
SECTIONS |
||||
{ |
||||
. = 0x00000000; |
||||
_start = .; |
||||
|
||||
. = ALIGN(4); |
||||
.text : |
||||
{ |
||||
__image_copy_start = .; |
||||
*(.text*) |
||||
} |
||||
|
||||
. = ALIGN(4); |
||||
.binman_sym_table : { |
||||
__binman_sym_start = .; |
||||
KEEP(*(SORT(.binman_sym*))); |
||||
__binman_sym_end = .; |
||||
} |
||||
|
||||
} |
Binary file not shown.
@ -0,0 +1 @@ |
||||
u_boot_binman_syms.c |
@ -0,0 +1,29 @@ |
||||
/* |
||||
* Copyright (c) 2016 Google, Inc |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") |
||||
OUTPUT_ARCH(i386) |
||||
ENTRY(_start) |
||||
|
||||
SECTIONS |
||||
{ |
||||
. = 0x00000000; |
||||
_start = .; |
||||
|
||||
. = ALIGN(4); |
||||
.text : |
||||
{ |
||||
*(.text*) |
||||
} |
||||
|
||||
. = ALIGN(4); |
||||
.binman_sym_table : { |
||||
__binman_sym_start = .; |
||||
KEEP(*(SORT(.binman_sym*))); |
||||
__binman_sym_end = .; |
||||
} |
||||
|
||||
} |
Binary file not shown.
@ -0,0 +1,12 @@ |
||||
/*
|
||||
* Copyright (c) 2017 Google, Inc |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
* |
||||
* Simple program to create some binman symbols. This is used by binman tests. |
||||
*/ |
||||
|
||||
#define CONFIG_BINMAN |
||||
#include <binman_sym.h> |
||||
|
||||
binman_sym_declare(char, u_boot_spl, pos); |
Loading…
Reference in new issue