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:
@@ -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;
|
||||
|
@@ -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"
|
||||
|
@@ -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,
|
||||
};
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
Reference in New Issue
Block a user