Commit 02ffb580 authored by Tom Rini's avatar Tom Rini
parents 57cc4e64 a5e1bcde
......@@ -45,11 +45,6 @@ void __udelay(unsigned long usec)
os_usleep(usec);
}
unsigned long __attribute__((no_instrument_function)) timer_get_us(void)
{
return os_get_nsec() / 1000;
}
int cleanup_before_linux(void)
{
return 0;
......
......@@ -24,6 +24,7 @@
#include <asm/sections.h>
#include <asm/state.h>
#include <os.h>
#include <rtc_def.h>
/* Operating System Interface */
......@@ -537,3 +538,20 @@ int os_jump_to_image(const void *dest, int size)
return unlink(fname);
}
void os_localtime(struct rtc_time *rt)
{
time_t t = time(NULL);
struct tm *tm;
tm = localtime(&t);
rt->tm_sec = tm->tm_sec;
rt->tm_min = tm->tm_min;
rt->tm_hour = tm->tm_hour;
rt->tm_mday = tm->tm_mday;
rt->tm_mon = tm->tm_mon + 1;
rt->tm_year = tm->tm_year + 1900;
rt->tm_wday = tm->tm_wday;
rt->tm_yday = tm->tm_yday;
rt->tm_isdst = tm->tm_isdst;
}
......@@ -77,12 +77,18 @@ int sandbox_main_loop_init(void)
struct sandbox_state *state = state_get_current();
/* Execute command if required */
if (state->cmd) {
int retval;
if (state->cmd || state->run_distro_boot) {
int retval = 0;
cli_init();
retval = run_command_list(state->cmd, -1, 0);
if (state->cmd)
retval = run_command_list(state->cmd, -1, 0);
if (state->run_distro_boot)
retval = cli_simple_run_command("run distro_bootcmd",
0);
if (!state->interactive)
os_exit(retval);
}
......@@ -90,6 +96,14 @@ int sandbox_main_loop_init(void)
return 0;
}
static int sandbox_cmdline_cb_boot(struct sandbox_state *state,
const char *arg)
{
state->run_distro_boot = true;
return 0;
}
SANDBOX_CMDLINE_OPT_SHORT(boot, 'b', 0, "Run distro boot commands");
static int sandbox_cmdline_cb_command(struct sandbox_state *state,
const char *arg)
{
......
......@@ -8,7 +8,9 @@
aliases {
eth5 = "/eth@90000000";
i2c0 = &i2c_0;
pci0 = &pci;
rtc0 = &rtc_0;
};
chosen {
......@@ -90,7 +92,7 @@
num-gpios = <10>;
};
i2c@0 {
i2c_0: i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0 0>;
......@@ -105,6 +107,14 @@
sandbox,size = <128>;
};
};
rtc_0: rtc@43 {
reg = <0x43>;
compatible = "sandbox-rtc";
emul {
compatible = "sandbox,i2c-rtc";
};
};
};
spi@0 {
......
......@@ -12,4 +12,6 @@
void sandbox_eth_disable_response(int index, bool disable);
void sandbox_eth_skip_timeout(void);
#endif /* __ETH_H */
/*
* Simulate an I2C real time clock
*
* Copyright (c) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __asm_rtc_h
#define __asm_rtc_h
/* Register numbers in the sandbox RTC */
enum {
REG_SEC = 5,
REG_MIN,
REG_HOUR,
REG_MDAY,
REG_MON,
REG_YEAR,
REG_WDAY,
REG_RESET = 0x20,
REG_COUNT = 0x80,
};
#endif
......@@ -42,6 +42,7 @@ struct sandbox_spi_info {
struct sandbox_state {
const char *cmd; /* Command to execute */
bool interactive; /* Enable cmdline after execute */
bool run_distro_boot; /* Automatically run distro bootcommands */
const char *fdt_fname; /* Filename of FDT binary */
const char *parse_err; /* Error to report from parsing */
int argc; /* Program arguments */
......
......@@ -17,6 +17,16 @@
#define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM
#define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL
/**
* sandbox_i2c_set_test_mode() - set test mode for running unit tests
*
* See sandbox_i2c_xfer() for the behaviour changes.
*
* @bus: sandbox I2C bus to adjust
* @test_mode: true to select test mode, false to run normally
*/
void sandbox_i2c_set_test_mode(struct udevice *bus, bool test_mode);
enum sandbox_i2c_eeprom_test_mode {
SIE_TEST_MODE_NONE,
/* Permits read/write of only one byte per I2C transaction */
......@@ -28,4 +38,33 @@ void sandbox_i2c_eeprom_set_test_mode(struct udevice *dev,
void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len);
/*
* sandbox_timer_add_offset()
*
* Allow tests to add to the time reported through lib/time.c functions
* offset: number of milliseconds to advance the system time
*/
void sandbox_timer_add_offset(unsigned long offset);
/**
* sandbox_i2c_rtc_set_offset() - set the time offset from system/base time
*
* @dev: RTC device to adjust
* @use_system_time: true to use system time, false to use @base_time
* @offset: RTC offset from current system/base time (-1 for no
* change)
* @return old value of RTC offset
*/
long sandbox_i2c_rtc_set_offset(struct udevice *dev, bool use_system_time,
int offset);
/**
* sandbox_i2c_rtc_get_set_base_time() - get and set the base time
*
* @dev: RTC device to adjust
* @base_time: New base system time (set to -1 for no change)
* @return old base time
*/
long sandbox_i2c_rtc_get_set_base_time(struct udevice *dev, long base_time);
#endif
......@@ -7,6 +7,7 @@
#include <cros_ec.h>
#include <dm.h>
#include <os.h>
#include <asm/test.h>
#include <asm/u-boot-sandbox.h>
/*
......@@ -25,9 +26,17 @@ void flush_cache(unsigned long start, unsigned long size)
{
}
/* system timer offset in ms */
static unsigned long sandbox_timer_offset;
void sandbox_timer_add_offset(unsigned long offset)
{
sandbox_timer_offset += offset;
}
unsigned long timer_read_counter(void)
{
return os_get_nsec() / 1000;
return os_get_nsec() / 1000 + sandbox_timer_offset * 1000;
}
int dram_init(void)
......
......@@ -10,6 +10,7 @@
*/
#include <common.h>
#include <command.h>
#include <dm.h>
#include <rtc.h>
#include <i2c.h>
......@@ -33,10 +34,18 @@ static int do_date(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct rtc_time tm;
int rcode = 0;
int old_bus;
int old_bus __maybe_unused;
/* switch to correct I2C bus */
#ifdef CONFIG_SYS_I2C
#ifdef CONFIG_DM_I2C
struct udevice *dev;
rcode = uclass_get_device(UCLASS_RTC, 0, &dev);
if (rcode) {
printf("Cannot find RTC: err=%d\n", rcode);
return CMD_RET_FAILURE;
}
#elif defined(CONFIG_SYS_I2C)
old_bus = i2c_get_bus_num();
i2c_set_bus_num(CONFIG_SYS_RTC_BUS_NUM);
#else
......@@ -48,32 +57,50 @@ static int do_date(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
case 2: /* set date & time */
if (strcmp(argv[1],"reset") == 0) {
puts ("Reset RTC...\n");
rtc_reset ();
#ifdef CONFIG_DM_I2C
rcode = dm_rtc_reset(dev);
if (!rcode)
rcode = dm_rtc_set(dev, &default_tm);
#else
rtc_reset();
rcode = rtc_set(&default_tm);
#endif
if (rcode)
puts("## Failed to set date after RTC reset\n");
} else {
/* initialize tm with current time */
rcode = rtc_get (&tm);
if(!rcode) {
#ifdef CONFIG_DM_I2C
rcode = dm_rtc_get(dev, &tm);
#else
rcode = rtc_get(&tm);
#endif
if (!rcode) {
/* insert new date & time */
if (mk_date (argv[1], &tm) != 0) {
if (mk_date(argv[1], &tm) != 0) {
puts ("## Bad date format\n");
break;
}
/* and write to RTC */
rcode = rtc_set (&tm);
if(rcode)
puts("## Set date failed\n");
#ifdef CONFIG_DM_I2C
rcode = dm_rtc_set(dev, &tm);
#else
rcode = rtc_set(&tm);
#endif
if (rcode) {
printf("## Set date failed: err=%d\n",
rcode);
}
} else {
puts("## Get date failed\n");
}
}
/* FALL TROUGH */
case 1: /* get date & time */
rcode = rtc_get (&tm);
#ifdef CONFIG_DM_I2C
rcode = dm_rtc_get(dev, &tm);
#else
rcode = rtc_get(&tm);
#endif
if (rcode) {
puts("## Get date failed\n");
break;
......@@ -93,11 +120,11 @@ static int do_date(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
/* switch back to original I2C bus */
#ifdef CONFIG_SYS_I2C
i2c_set_bus_num(old_bus);
#else
#elif !defined(CONFIG_DM_I2C)
I2C_SET_BUS(old_bus);
#endif
return rcode;
return rcode ? CMD_RET_FAILURE : 0;
}
/*
......@@ -201,7 +228,7 @@ int mk_date (const char *datestr, struct rtc_time *tmp)
tmp->tm_min = val;
/* calculate day of week */
GregorianDay (tmp);
rtc_calc_weekday(tmp);
return (0);
default:
......
......@@ -1533,7 +1533,7 @@ int fdt_setup_simplefb_node(void *fdt, int node, u64 base_address, u32 width,
if (ret < 0)
return ret;
snprintf(name, sizeof(name), "framebuffer@%llx", base_address);
snprintf(name, sizeof(name), "framebuffer@%" PRIx64, base_address);
ret = fdt_set_name(fdt, node, name);
if (ret < 0)
return ret;
......
......@@ -533,7 +533,7 @@ void genimg_print_time(time_t timestamp)
#ifndef USE_HOSTCC
struct rtc_time tm;
to_tm(timestamp, &tm);
rtc_to_tm(timestamp, &tm);
printf("%4d-%02d-%02d %2d:%02d:%02d UTC\n",
tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
......
......@@ -946,13 +946,18 @@ static int usb_setup_descriptor(struct usb_device *dev, bool do_read)
* send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is
* only 18 bytes long, this will terminate with a short packet. But if
* the maxpacket size is 8 or 16 the device may be waiting to transmit
* some more, or keeps on retransmitting the 8 byte header. */
* some more, or keeps on retransmitting the 8 byte header.
*/
dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */
/* Default to 64 byte max packet size */
dev->maxpacketsize = PACKET_SIZE_64;
dev->epmaxpacketin[0] = 64;
dev->epmaxpacketout[0] = 64;
if (dev->speed == USB_SPEED_LOW) {
dev->descriptor.bMaxPacketSize0 = 8;
dev->maxpacketsize = PACKET_SIZE_8;
} else {
dev->descriptor.bMaxPacketSize0 = 64;
dev->maxpacketsize = PACKET_SIZE_64;
}
dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
if (do_read) {
int err;
......
......@@ -26,3 +26,5 @@ CONFIG_TPM_TIS_SANDBOX=y
CONFIG_SOUND=y
CONFIG_CMD_SOUND=y
CONFIG_SOUND_SANDBOX=y
CONFIG_DM_RTC=y
CONFIG_CMD_UT_TIME=y
......@@ -41,18 +41,19 @@ static int i2c_gpio_sda_get(struct gpio_desc *sda)
static void i2c_gpio_sda_set(struct gpio_desc *sda, int bit)
{
if (bit) {
if (bit)
dm_gpio_set_dir_flags(sda, GPIOD_IS_IN);
} else {
else
dm_gpio_set_dir_flags(sda, GPIOD_IS_OUT);
dm_gpio_set_value(sda, 0);
}
}
static void i2c_gpio_scl_set(struct gpio_desc *scl, int bit)
{
dm_gpio_set_dir_flags(scl, GPIOD_IS_OUT);
dm_gpio_set_value(scl, bit);
ulong flags = GPIOD_IS_OUT;
if (bit)
flags |= GPIOD_IS_OUT_ACTIVE;
dm_gpio_set_dir_flags(scl, flags);
}
static void i2c_gpio_write_bit(struct gpio_desc *scl, struct gpio_desc *sda,
......
......@@ -186,6 +186,25 @@ int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer,
}
}
int dm_i2c_reg_read(struct udevice *dev, uint offset)
{
uint8_t val;
int ret;
ret = dm_i2c_read(dev, offset, &val, 1);
if (ret < 0)
return ret;
return val;
}
int dm_i2c_reg_write(struct udevice *dev, uint offset, uint value)
{
uint8_t val = value;
return dm_i2c_write(dev, offset, &val, 1);
}
/**
* i2c_probe_chip() - probe for a chip on a bus
*
......
......@@ -18,8 +18,8 @@
DECLARE_GLOBAL_DATA_PTR;
struct dm_sandbox_i2c_emul_priv {
struct udevice *emul;
struct sandbox_i2c_priv {
bool test_mode;
};
static int get_emul(struct udevice *dev, struct udevice **devp,
......@@ -47,17 +47,25 @@ static int get_emul(struct udevice *dev, struct udevice **devp,
return 0;
}
void sandbox_i2c_set_test_mode(struct udevice *bus, bool test_mode)
{
struct sandbox_i2c_priv *priv = dev_get_priv(bus);
priv->test_mode = test_mode;
}
static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
int nmsgs)
{
struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
struct sandbox_i2c_priv *priv = dev_get_priv(bus);
struct dm_i2c_ops *ops;
struct udevice *emul, *dev;
bool is_read;
int ret;
/* Special test code to return success but with no emulation */
if (msg->addr == SANDBOX_I2C_TEST_ADDR)
if (priv->test_mode && msg->addr == SANDBOX_I2C_TEST_ADDR)
return 0;
ret = i2c_get_chip(bus, msg->addr, 1, &dev);
......@@ -68,13 +76,18 @@ static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
if (ret)
return ret;
/*
* For testing, don't allow writing above 100KHz for writes and
* 400KHz for reads
*/
is_read = nmsgs > 1;
if (i2c->speed_hz > (is_read ? 400000 : 100000))
return -EINVAL;
if (priv->test_mode) {
/*
* For testing, don't allow writing above 100KHz for writes and
* 400KHz for reads.
*/
is_read = nmsgs > 1;
if (i2c->speed_hz > (is_read ? 400000 : 100000)) {
debug("%s: Max speed exceeded\n", __func__);
return -EINVAL;
}
}
return ops->xfer(emul, msg, nmsgs);
}
......@@ -92,4 +105,5 @@ U_BOOT_DRIVER(i2c_sandbox) = {
.id = UCLASS_I2C,
.of_match = sandbox_i2c_ids,
.ops = &sandbox_i2c_ops,
.priv_auto_alloc_size = sizeof(struct sandbox_i2c_priv),
};
......@@ -986,7 +986,8 @@ int cros_ec_register(struct udevice *dev)
}
/* Remember this device for use by the cros_ec command */
debug("Google Chrome EC CROS-EC driver ready, id '%s'\n", id);
debug("Google Chrome EC v%d CROS-EC driver ready, id '%s'\n",
cdev->protocol_version, id);
return 0;
}
......
......@@ -25,6 +25,8 @@ int cros_ec_spi_packet(struct udevice *udev, int out_bytes, int in_bytes)
{
struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
struct spi_slave *slave = dev_get_parentdata(dev->dev);
ulong start;
uint8_t byte;
int rv;
/* Do the transfer */
......@@ -33,10 +35,25 @@ int cros_ec_spi_packet(struct udevice *udev, int out_bytes, int in_bytes)
return -1;
}
rv = spi_xfer(slave, max(out_bytes, in_bytes) * 8,
dev->dout, dev->din,
SPI_XFER_BEGIN | SPI_XFER_END);
rv = spi_xfer(slave, out_bytes * 8, dev->dout, NULL, SPI_XFER_BEGIN);
if (rv)
goto done;
start = get_timer(0);
while (1) {
rv = spi_xfer(slave, 8, NULL, &byte, 0);
if (byte == SPI_PREAMBLE_END_BYTE)
break;
if (rv)
goto done;
if (get_timer(start) > 100) {
rv = -ETIMEDOUT;
goto done;
}
}
rv = spi_xfer(slave, in_bytes * 8, NULL, dev->din, 0);
done:
spi_xfer(slave, 0, NULL, NULL, SPI_XFER_END);
spi_release_bus(slave);
if (rv) {
......
......@@ -53,10 +53,10 @@ int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
{
struct spi_slave *slave;
struct udevice *bus;
char name[20], *str;
char name[30], *str;
int ret;
snprintf(name, sizeof(name), "%d:%d", busnum, cs);
snprintf(name, sizeof(name), "spi_flash@%d:%d", busnum, cs);
str = strdup(name);
ret = spi_get_bus_and_cs(busnum, cs, max_hz, spi_mode,
"spi_flash_std", str, &bus, &slave);
......
......@@ -11,6 +11,7 @@
#include <dm.h>
#include <malloc.h>
#include <net.h>
#include <asm/test.h>
DECLARE_GLOBAL_DATA_PTR;
......@@ -30,6 +31,7 @@ struct eth_sandbox_priv {
};
static bool disabled[8] = {false};
static bool skip_timeout;
/*
* sandbox_eth_disable_response()
......@@ -42,6 +44,16 @@ void sandbox_eth_disable_response(int index, bool disable)
disabled[index] = disable;
}
/*
* sandbox_eth_skip_timeout()
*
* When the first packet read is attempted, fast-forward time
*/
void sandbox_eth_skip_timeout(void)
{
skip_timeout = true;
}
static int sb_eth_start(struct udevice *dev)
{
struct eth_sandbox_priv *priv = dev_get_priv(dev);
......@@ -144,6 +156,11 @@ static int sb_eth_recv(struct udevice *dev, uchar **packetp)
{
struct eth_sandbox_priv *priv = dev_get_priv(dev);
if (skip_timeout) {
sandbox_timer_add_offset(10000UL);
skip_timeout = false;
}
if (priv->recv_packet_length) {
int lcl_recv_packet_length = priv->recv_packet_length;
......
config DM_RTC
bool "Enable Driver Model for RTC drivers"
depends on DM
help
Enable drver model for real-time-clock drivers. The RTC uclass
then provides the rtc_get()/rtc_set() interface, delegating to
drivers to perform the actual functions. See rtc.h for a
description of the API.
......@@ -7,6 +7,8 @@
#ccflags-y += -DDEBUG
obj-$(CONFIG_DM_RTC) += rtc-uclass.o
obj-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o
obj-$(CONFIG_RTC_BFIN) += bfin_rtc.o
obj-y += date.o
......@@ -24,6 +26,7 @@ obj-$(CONFIG_RTC_DS164x) += ds164x.o
obj-$(CONFIG_RTC_DS174x) += ds174x.o
obj-$(CONFIG_RTC_DS3231) += ds3231.o
obj-$(CONFIG_RTC_FTRTC010) += ftrtc010.o
obj-$(CONFIG_SANDBOX) += i2c_rtc_emul.o
obj-$(CONFIG_RTC_IMXDI) += imxdi.o
obj-$(CONFIG_RTC_ISL1208) += isl1208.o
obj-$(CONFIG_RTC_M41T11) += m41t11.o
......@@ -49,4 +52,5 @@ obj-$(CONFIG_RTC_RTC4543) += rtc4543.o
obj-$(CONFIG_RTC_RV3029) += rv3029.o
obj-$(CONFIG_RTC_RX8025) += rx8025.o
obj-$(CONFIG_RTC_S3C24X0) += s3c24x0_rtc.o
obj-$(CONFIG_SANDBOX) += sandbox_rtc.o
obj-$(CONFIG_RTC_X1205) += x1205.o
......@@ -44,7 +44,7 @@ int rtc_get (struct rtc_time *tmp)
} while (tim!=tim2);
off = readl(&gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
/* off==0 means time is invalid, but we ignore that */
to_tm (tim+off, tmp);
rtc_to_tm(tim+off, tmp);
return 0;
}
......@@ -54,8 +54,7 @@ int rtc_set (struct rtc_time *tmp)
at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR;
ulong tim;
tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
tim = rtc_mktime(tmp);
/* clear alarm, set prescaler to 32768, clear counter */
writel(32768+AT91_RTT_RTTRST, &rtt->mr);
......
......@@ -67,8 +67,7 @@ int rtc_set(struct rtc_time *tmp)
wait_for_complete();
/* Calculate number of seconds this incoming time represents */
remain = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
remain = rtc_mktime(tmp);
/* Figure out how many days since epoch */
days = remain / NUM_SECS_IN_DAY;
......@@ -114,7 +113,7 @@ int rtc_get(struct rtc_time *tmp)
/* Calculate the total number of seconds since epoch */
time_in_sec = (tm_sec) + MIN_TO_SECS(tm_min) + HRS_TO_SECS(tm_hr) + DAYS_TO_SECS(tm_day);
to_tm(time_in_sec, tmp);
rtc_to_tm(time_in_sec, tmp);
return 0;
}
......
......@@ -11,6 +11,7 @@
#include <common.h>
#include <command.h>
#include <errno.h>
#include <rtc.h>
#if defined(CONFIG_CMD_DATE) || defined(CONFIG_TIMESTAMP)
......@@ -30,13 +31,15 @@ static int month_days[12] = {
/*
* This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
*/
void GregorianDay(struct rtc_time * tm)
int rtc_calc_weekday(struct rtc_time *tm)
{
int leapsToDate;
int lastYear;
int day;
int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
if (tm->tm_year < 1753)
return -EINVAL;
lastYear=tm->tm_year-1;
/*
......@@ -64,9 +67,11 @@ void GregorianDay(struct rtc_time * tm)
day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday;
tm->tm_wday=day%7;
return 0;
}
void to_tm(int tim, struct rtc_time * tm)
int rtc_to_tm(int tim, struct rtc_time *tm)