1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-01 08:42:12 +02:00

Merge git://git.denx.de/u-boot-x86

This commit is contained in:
Tom Rini
2017-08-26 15:10:40 -04:00
39 changed files with 162 additions and 269 deletions

View File

@@ -202,47 +202,6 @@ static int pci_rom_load(struct pci_rom_header *rom_header,
struct vbe_mode_info mode_info;
int vbe_get_video_info(struct graphic_device *gdev)
{
#ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE
struct vesa_mode_info *vesa = &mode_info.vesa;
gdev->winSizeX = vesa->x_resolution;
gdev->winSizeY = vesa->y_resolution;
gdev->plnSizeX = vesa->x_resolution;
gdev->plnSizeY = vesa->y_resolution;
gdev->gdfBytesPP = vesa->bits_per_pixel / 8;
switch (vesa->bits_per_pixel) {
case 32:
case 24:
gdev->gdfIndex = GDF_32BIT_X888RGB;
break;
case 16:
gdev->gdfIndex = GDF_16BIT_565RGB;
break;
default:
gdev->gdfIndex = GDF__8BIT_INDEX;
break;
}
gdev->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS;
gdev->pciBase = vesa->phys_base_ptr;
gdev->frameAdrs = vesa->phys_base_ptr;
gdev->memSize = vesa->bytes_per_scanline * vesa->y_resolution;
gdev->vprBase = vesa->phys_base_ptr;
gdev->cprBase = vesa->phys_base_ptr;
return gdev->winSizeX ? 0 : -ENOSYS;
#else
return -ENOSYS;
#endif
}
void setup_video(struct screen_info *screen_info)
{
struct vesa_mode_info *vesa = &mode_info.vesa;

View File

@@ -64,15 +64,20 @@ config DM_SERIAL
implements serial_putc() etc. The uclass interface is
defined in include/serial.h.
config SERIAL_IRQ_BUFFER
bool "Enable RX interrupt buffer for serial input"
config SERIAL_RX_BUFFER
bool "Enable RX buffer for serial input"
depends on DM_SERIAL
default n
help
Enable RX interrupt buffer support for the serial driver.
This enables pasting longer strings, even when the RX FIFO
of the UART is not big enough (e.g. 16 bytes on the normal
NS16550).
Enable RX buffer support for the serial driver. This enables
pasting longer strings, even when the RX FIFO of the UART is
not big enough (e.g. 16 bytes on the normal NS16550).
config SERIAL_RX_BUFFER_SIZE
int "RX buffer size"
depends on SERIAL_RX_BUFFER
default 256
help
The size of the RX buffer (needs to be power of 2)
config SPL_DM_SERIAL
bool "Enable Driver Model for serial drivers in SPL"

View File

@@ -314,80 +314,6 @@ DEBUG_UART_FUNCS
#endif
#ifdef CONFIG_DM_SERIAL
#if CONFIG_IS_ENABLED(SERIAL_IRQ_BUFFER)
#define BUF_COUNT 256
static void rx_fifo_to_buf(struct udevice *dev)
{
struct NS16550 *const com_port = dev_get_priv(dev);
struct ns16550_platdata *plat = dev->platdata;
/* Read all available chars into buffer */
while ((serial_in(&com_port->lsr) & UART_LSR_DR)) {
plat->buf[plat->wr_ptr++] = serial_in(&com_port->rbr);
plat->wr_ptr %= BUF_COUNT;
}
}
static int rx_pending(struct udevice *dev)
{
struct ns16550_platdata *plat = dev->platdata;
/*
* At startup it may happen, that some already received chars are
* "stuck" in the RX FIFO, even with the interrupt enabled. This
* RX FIFO flushing makes sure, that these chars are read out and
* the RX interrupts works as expected.
*/
rx_fifo_to_buf(dev);
return plat->rd_ptr != plat->wr_ptr ? 1 : 0;
}
static int rx_get(struct udevice *dev)
{
struct ns16550_platdata *plat = dev->platdata;
char val;
val = plat->buf[plat->rd_ptr++];
plat->rd_ptr %= BUF_COUNT;
return val;
}
void ns16550_handle_irq(void *data)
{
struct udevice *dev = (struct udevice *)data;
struct NS16550 *const com_port = dev_get_priv(dev);
/* Check if interrupt is pending */
if (serial_in(&com_port->iir) & UART_IIR_NO_INT)
return;
/* Flush all available characters from the RX FIFO into the RX buffer */
rx_fifo_to_buf(dev);
}
#else /* CONFIG_SERIAL_IRQ_BUFFER */
static int rx_pending(struct udevice *dev)
{
struct NS16550 *const com_port = dev_get_priv(dev);
return serial_in(&com_port->lsr) & UART_LSR_DR ? 1 : 0;
}
static int rx_get(struct udevice *dev)
{
struct NS16550 *const com_port = dev_get_priv(dev);
return serial_in(&com_port->rbr);
}
#endif /* CONFIG_SERIAL_IRQ_BUFFER */
static int ns16550_serial_putc(struct udevice *dev, const char ch)
{
struct NS16550 *const com_port = dev_get_priv(dev);
@@ -413,17 +339,19 @@ static int ns16550_serial_pending(struct udevice *dev, bool input)
struct NS16550 *const com_port = dev_get_priv(dev);
if (input)
return rx_pending(dev);
return serial_in(&com_port->lsr) & UART_LSR_DR ? 1 : 0;
else
return serial_in(&com_port->lsr) & UART_LSR_THRE ? 0 : 1;
}
static int ns16550_serial_getc(struct udevice *dev)
{
if (!ns16550_serial_pending(dev, true))
struct NS16550 *const com_port = dev_get_priv(dev);
if (!(serial_in(&com_port->lsr) & UART_LSR_DR))
return -EAGAIN;
return rx_get(dev);
return serial_in(&com_port->rbr);
}
static int ns16550_serial_setbrg(struct udevice *dev, int baudrate)
@@ -446,40 +374,9 @@ int ns16550_serial_probe(struct udevice *dev)
com_port->plat = dev_get_platdata(dev);
NS16550_init(com_port, -1);
#if CONFIG_IS_ENABLED(SERIAL_IRQ_BUFFER)
if (gd->flags & GD_FLG_RELOC) {
struct ns16550_platdata *plat = dev->platdata;
/* Allocate the RX buffer */
plat->buf = malloc(BUF_COUNT);
/* Install the interrupt handler */
irq_install_handler(plat->irq, ns16550_handle_irq, dev);
/* Enable RX interrupts */
serial_out(UART_IER_RDI, &com_port->ier);
}
#endif
return 0;
}
#if CONFIG_IS_ENABLED(SERIAL_PRESENT) && \
(!defined(CONFIG_TPL_BUILD) || defined(CONFIG_TPL_DM_SERIAL))
static int ns16550_serial_remove(struct udevice *dev)
{
#if CONFIG_IS_ENABLED(SERIAL_IRQ_BUFFER)
if (gd->flags & GD_FLG_RELOC) {
struct ns16550_platdata *plat = dev->platdata;
irq_free_handler(plat->irq);
}
#endif
return 0;
}
#endif
#if CONFIG_IS_ENABLED(OF_CONTROL)
enum {
PORT_NS16550 = 0,
@@ -561,15 +458,6 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
if (port_type == PORT_JZ4780)
plat->fcr |= UART_FCR_UME;
#if CONFIG_IS_ENABLED(SERIAL_IRQ_BUFFER)
plat->irq = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"interrupts", 0);
if (!plat->irq) {
debug("ns16550 interrupt not provided\n");
return -EINVAL;
}
#endif
return 0;
}
#endif
@@ -617,7 +505,6 @@ U_BOOT_DRIVER(ns16550_serial) = {
#endif
.priv_auto_alloc_size = sizeof(struct NS16550),
.probe = ns16550_serial_probe,
.remove = ns16550_serial_remove,
.ops = &ns16550_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@@ -160,7 +160,7 @@ static void _serial_puts(struct udevice *dev, const char *str)
_serial_putc(dev, *str++);
}
static int _serial_getc(struct udevice *dev)
static int __serial_getc(struct udevice *dev)
{
struct dm_serial_ops *ops = serial_get_ops(dev);
int err;
@@ -174,7 +174,7 @@ static int _serial_getc(struct udevice *dev)
return err >= 0 ? err : 0;
}
static int _serial_tstc(struct udevice *dev)
static int __serial_tstc(struct udevice *dev)
{
struct dm_serial_ops *ops = serial_get_ops(dev);
@@ -184,6 +184,44 @@ static int _serial_tstc(struct udevice *dev)
return 1;
}
#if CONFIG_IS_ENABLED(SERIAL_RX_BUFFER)
static int _serial_tstc(struct udevice *dev)
{
struct serial_dev_priv *upriv = dev_get_uclass_priv(dev);
/* Read all available chars into the RX buffer */
while (__serial_tstc(dev)) {
upriv->buf[upriv->wr_ptr++] = __serial_getc(dev);
upriv->wr_ptr %= CONFIG_SERIAL_RX_BUFFER_SIZE;
}
return upriv->rd_ptr != upriv->wr_ptr ? 1 : 0;
}
static int _serial_getc(struct udevice *dev)
{
struct serial_dev_priv *upriv = dev_get_uclass_priv(dev);
char val;
val = upriv->buf[upriv->rd_ptr++];
upriv->rd_ptr %= CONFIG_SERIAL_RX_BUFFER_SIZE;
return val;
}
#else /* CONFIG_IS_ENABLED(SERIAL_RX_BUFFER) */
static int _serial_getc(struct udevice *dev)
{
return __serial_getc(dev);
}
static int _serial_tstc(struct udevice *dev)
{
return __serial_tstc(dev);
}
#endif /* CONFIG_IS_ENABLED(SERIAL_RX_BUFFER) */
void serial_putc(char ch)
{
if (gd->cur_serial_dev)
@@ -359,6 +397,12 @@ static int serial_post_probe(struct udevice *dev)
sdev.puts = serial_stub_puts;
sdev.getc = serial_stub_getc;
sdev.tstc = serial_stub_tstc;
#if CONFIG_IS_ENABLED(SERIAL_RX_BUFFER)
/* Allocate the RX buffer */
upriv->buf = malloc(CONFIG_SERIAL_RX_BUFFER_SIZE);
#endif
stdio_register_dev(&sdev, &upriv->sdev);
#endif
return 0;

View File

@@ -126,8 +126,6 @@ static int ich_init_controller(struct udevice *dev,
if (plat->ich_version == ICHV_7) {
struct ich7_spi_regs *ich7_spi = sbase;
ich7_spi = (struct ich7_spi_regs *)sbase;
ctlr->ichspi_lock = readw(&ich7_spi->spis) & SPIS_LOCK;
ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu);
ctlr->menubytes = sizeof(ich7_spi->opmenu);
ctlr->optype = offsetof(struct ich7_spi_regs, optype);
@@ -142,7 +140,6 @@ static int ich_init_controller(struct udevice *dev,
} else if (plat->ich_version == ICHV_9) {
struct ich9_spi_regs *ich9_spi = sbase;
ctlr->ichspi_lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu);
ctlr->menubytes = sizeof(ich9_spi->opmenu);
ctlr->optype = offsetof(struct ich9_spi_regs, optype);
@@ -187,6 +184,23 @@ static inline void spi_use_in(struct spi_trans *trans, unsigned bytes)
trans->bytesin -= bytes;
}
static bool spi_lock_status(struct ich_spi_platdata *plat, void *sbase)
{
int lock = 0;
if (plat->ich_version == ICHV_7) {
struct ich7_spi_regs *ich7_spi = sbase;
lock = readw(&ich7_spi->spis) & SPIS_LOCK;
} else if (plat->ich_version == ICHV_9) {
struct ich9_spi_regs *ich9_spi = sbase;
lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
}
return lock != 0;
}
static void spi_setup_type(struct spi_trans *trans, int data_bytes)
{
trans->type = 0xFF;
@@ -220,14 +234,15 @@ static void spi_setup_type(struct spi_trans *trans, int data_bytes)
}
}
static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans)
static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
bool lock)
{
uint16_t optypes;
uint8_t opmenu[ctlr->menubytes];
trans->opcode = trans->out[0];
spi_use_out(trans, 1);
if (!ctlr->ichspi_lock) {
if (!lock) {
/* The lock is off, so just use index 0. */
ich_writeb(ctlr, trans->opcode, ctlr->opmenu);
optypes = ich_readw(ctlr, ctlr->optype);
@@ -323,6 +338,21 @@ static int ich_status_poll(struct ich_spi_priv *ctlr, u16 bitmask,
return -ETIMEDOUT;
}
void ich_spi_config_opcode(struct udevice *dev)
{
struct ich_spi_priv *ctlr = dev_get_priv(dev);
/*
* PREOP, OPTYPE, OPMENU1/OPMENU2 registers can be locked down
* to prevent accidental or intentional writes. Before they get
* locked down, these registers should be initialized properly.
*/
ich_writew(ctlr, SPI_OPPREFIX, ctlr->preop);
ich_writew(ctlr, SPI_OPTYPE, ctlr->optype);
ich_writel(ctlr, SPI_OPMENU_LOWER, ctlr->opmenu);
ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32));
}
static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
@@ -337,6 +367,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
struct spi_trans *trans = &ctlr->trans;
unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END);
int using_cmd = 0;
bool lock = spi_lock_status(plat, ctlr->base);
int ret;
/* We don't support writing partial bytes */
@@ -400,7 +431,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
spi_setup_type(trans, using_cmd ? bytes : 0);
opcode_index = spi_setup_opcode(ctlr, trans);
opcode_index = spi_setup_opcode(ctlr, trans, lock);
if (opcode_index < 0)
return -EINVAL;
with_address = spi_setup_offset(trans);
@@ -413,7 +444,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
* in order to prevent the Management Engine from
* issuing a transaction between WREN and DATA.
*/
if (!ctlr->ichspi_lock)
if (!lock)
ich_writew(ctlr, trans->opcode, ctlr->preop);
return 0;
}
@@ -539,56 +570,6 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
return 0;
}
/*
* This uses the SPI controller from the Intel Cougar Point and Panther Point
* PCH to write-protect portions of the SPI flash until reboot. The changes
* don't actually take effect until the HSFS[FLOCKDN] bit is set, but that's
* done elsewhere.
*/
int spi_write_protect_region(struct udevice *dev, uint32_t lower_limit,
uint32_t length, int hint)
{
struct udevice *bus = dev->parent;
struct ich_spi_priv *ctlr = dev_get_priv(bus);
uint32_t tmplong;
uint32_t upper_limit;
if (!ctlr->pr) {
printf("%s: operation not supported on this chipset\n",
__func__);
return -ENOSYS;
}
if (length == 0 ||
lower_limit > (0xFFFFFFFFUL - length) + 1 ||
hint < 0 || hint > 4) {
printf("%s(0x%x, 0x%x, %d): invalid args\n", __func__,
lower_limit, length, hint);
return -EPERM;
}
upper_limit = lower_limit + length - 1;
/*
* Determine bits to write, as follows:
* 31 Write-protection enable (includes erase operation)
* 30:29 reserved
* 28:16 Upper Limit (FLA address bits 24:12, with 11:0 == 0xfff)
* 15 Read-protection enable
* 14:13 reserved
* 12:0 Lower Limit (FLA address bits 24:12, with 11:0 == 0x000)
*/
tmplong = 0x80000000 |
((upper_limit & 0x01fff000) << 4) |
((lower_limit & 0x01fff000) >> 12);
printf("%s: writing 0x%08x to %p\n", __func__, tmplong,
&ctlr->pr[hint]);
ctlr->pr[hint] = tmplong;
return 0;
}
static int ich_spi_probe(struct udevice *dev)
{
struct ich_spi_platdata *plat = dev_get_platdata(dev);
@@ -619,16 +600,11 @@ static int ich_spi_probe(struct udevice *dev)
static int ich_spi_remove(struct udevice *bus)
{
struct ich_spi_priv *ctlr = dev_get_priv(bus);
/*
* Configure SPI controller so that the Linux MTD driver can fully
* access the SPI NOR chip
*/
ich_writew(ctlr, SPI_OPPREFIX, ctlr->preop);
ich_writew(ctlr, SPI_OPTYPE, ctlr->optype);
ich_writel(ctlr, SPI_OPMENU_LOWER, ctlr->opmenu);
ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32));
ich_spi_config_opcode(bus);
return 0;
}

View File

@@ -177,8 +177,6 @@ struct ich_spi_platdata {
};
struct ich_spi_priv {
int ichspi_lock;
int locked;
int opmenu;
int menubytes;
void *base; /* Base of register set */