* [PATCH 02/04] ARM i.MX25 Add SIM driver
From: Russell King - ARM Linux @ 2011-01-03 10:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20736.212.121.242.58.1294045639.squirrel@mail.fqingenieria.es>
On Mon, Jan 03, 2011 at 10:07:19AM +0100, FQ | Iban Cerro wrote:
> arch/arm/plat-mxc/Kconfig | 7 +
> arch/arm/plat-mxc/Makefile | 1 +
> arch/arm/plat-mxc/include/mach/mxc_sim.h | 319 +++++++++++
> arch/arm/plat-mxc/sim.c | 874
> ++++++++++++++++++++++++++++++
Please find somewhere under drivers/ to put... drivers. Not in arch/
thanks.
^ permalink raw reply
* [PATCH 7/7] ARM: PL011: add DMA burst threshold support for ST variants
From: Russell King - ARM Linux @ 2011-01-03 10:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110103100753.GB26785@n2100.arm.linux.org.uk>
ST Micro variants has some specific dma burst threshold compensation,
which allows them to make better use of a DMA controller. Add support
to set this up.
Based on a patch from Linus Walleij.
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/serial/amba-pl011.c | 12 ++++++++++++
include/linux/amba/serial.h | 15 +++++++++++++++
2 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 03d3285..35b389f 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -74,6 +74,7 @@ struct vendor_data {
unsigned int lcrh_tx;
unsigned int lcrh_rx;
bool oversampling;
+ bool dma_threshold;
};
static struct vendor_data vendor_arm = {
@@ -82,6 +83,7 @@ static struct vendor_data vendor_arm = {
.lcrh_tx = UART011_LCRH,
.lcrh_rx = UART011_LCRH,
.oversampling = false,
+ .dma_threshold = false,
};
static struct vendor_data vendor_st = {
@@ -90,6 +92,7 @@ static struct vendor_data vendor_st = {
.lcrh_tx = ST_UART011_LCRH_TX,
.lcrh_rx = ST_UART011_LCRH_RX,
.oversampling = true,
+ .dma_threshold = true,
};
/* Deals with DMA transactions */
@@ -527,6 +530,15 @@ static void pl011_dma_startup(struct uart_amba_port *uap)
/* Turn on DMA error (RX/TX will be enabled on demand) */
uap->dmacr |= UART011_DMAONERR;
writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+
+ /*
+ * ST Micro variants has some specific dma burst threshold
+ * compensation. Set this to 16 bytes, so burst will only
+ * be issued above/below 16 bytes.
+ */
+ if (uap->vendor->dma_threshold)
+ writew(ST_UART011_DMAWM_RX_16 | ST_UART011_DMAWM_TX_16,
+ uap->port.membase + ST_UART011_DMAWM);
}
static void pl011_dma_shutdown(struct uart_amba_port *uap)
diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h
index 577f22e..5479fdc 100644
--- a/include/linux/amba/serial.h
+++ b/include/linux/amba/serial.h
@@ -113,6 +113,21 @@
#define UART01x_LCRH_PEN 0x02
#define UART01x_LCRH_BRK 0x01
+#define ST_UART011_DMAWM_RX_1 (0 << 3)
+#define ST_UART011_DMAWM_RX_2 (1 << 3)
+#define ST_UART011_DMAWM_RX_4 (2 << 3)
+#define ST_UART011_DMAWM_RX_8 (3 << 3)
+#define ST_UART011_DMAWM_RX_16 (4 << 3)
+#define ST_UART011_DMAWM_RX_32 (5 << 3)
+#define ST_UART011_DMAWM_RX_48 (6 << 3)
+#define ST_UART011_DMAWM_TX_1 0
+#define ST_UART011_DMAWM_TX_2 1
+#define ST_UART011_DMAWM_TX_4 2
+#define ST_UART011_DMAWM_TX_8 3
+#define ST_UART011_DMAWM_TX_16 4
+#define ST_UART011_DMAWM_TX_32 5
+#define ST_UART011_DMAWM_TX_48 6
+
#define UART010_IIR_RTIS 0x08
#define UART010_IIR_TIS 0x04
#define UART010_IIR_RIS 0x02
--
1.6.2.5
^ permalink raw reply related
* [PATCH 6/7] ARM: PL011: Add support for transmit DMA
From: Russell King - ARM Linux @ 2011-01-03 10:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110103100753.GB26785@n2100.arm.linux.org.uk>
Add DMA engine support for transmit to the PL011 driver. Based on a
patch from Linus Walliej, with the following changes:
- remove RX DMA support. As PL011 doesn't give us receive timeout
interrupts, we only get notified of received data when the RX DMA
has completed. This rather sucks for interactive use of the TTY.
- remove abuse of completions. Completions are supposed to be for
events, not to tell what condition buffers are in. Replace it with
a simple 'queued' bool.
- fix locking - it is only safe to access the circular buffer with the
port lock held.
- only map the DMA buffer when required - if we're ever behind an IOMMU
this helps keep IOMMU usage down, and also ensures that we're legal
when we change the scatterlist entry length.
- fix XON/XOFF sending - we must send XON/XOFF characters out as soon
as possible - waiting for up to 4095 characters in the DMA buffer
to be sent first is not acceptable.
- fix XON/XOFF receive handling - we need to stop DMA when instructed
to by the TTY layer, and restart it again when instructed to. There
is a subtle problem here: we must not completely empty the circular
buffer with DMA, otherwise we will not be notified of XON.
- change the 'enable_dma' flag into a 'using DMA' flag, and track
whether we can use TX DMA by whether the channel pointer is non-NULL.
This gives us more control over whether we use DMA in the driver.
- we don't need to have the TX DMA buffer continually allocated for
each port - instead, allocate it when the port starts up, and free
it when it's shut down. Update the 'using DMA' flag if we get
the buffer, and adjust the TTY FIFO size appropriately.
- if we're going to use PIO to send characters, use the existing IRQ
based functionality rather than reimplementing it. This also ensures
we call uart_write_wakeup() at the appropriate time, otherwise we'll
stall.
- use DMA engine helper functions for type safety.
- fix init when built as a module - we can't have to initcall functions,
so we must settle on one. This means we can eliminate the deferred
DMA initialization.
- there is no need to terminate transfers on a failed prep_slave_sg()
call - nothing has been setup, so nothing needs to be terminated.
This avoids a potential deadlock in the DMA engine code
(tasklet->callback->failed prepare->terminate->tasklet_disable
which then ends up waiting for the tasklet to finish running.)
- Dan says that the submission callback should not return an error:
| dma_submit_error() is something I should have removed after commit
| a0587bcf "ioat1: move descriptor allocation from submit to prep" all
| errors should be notified by prep failing to return a descriptor
| handle. Negative dma_cookie_t values are only returned by the
| dma_async_memcpy* calls which translate a prep failure into -ENOMEM.
So remove the error handling at that point. This also solves the
potential deadlock mentioned in the previous comment.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/serial/amba-pl011.c | 508 ++++++++++++++++++++++++++++++++++++++++++-
include/linux/amba/serial.h | 7 +
2 files changed, 513 insertions(+), 2 deletions(-)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index f741a8b..03d3285 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -7,6 +7,7 @@
*
* Copyright 1999 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd.
+ * Copyright (C) 2010 ST-Ericsson SA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -48,6 +49,9 @@
#include <linux/amba/serial.h>
#include <linux/clk.h>
#include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
#include <asm/sizes.h>
@@ -88,6 +92,14 @@ static struct vendor_data vendor_st = {
.oversampling = true,
};
+/* Deals with DMA transactions */
+struct pl011_dmatx_data {
+ struct dma_chan *chan;
+ struct scatterlist sg;
+ char *buf;
+ bool queued;
+};
+
/*
* We wrap our port structure around the generic uart_port.
*/
@@ -95,6 +107,7 @@ struct uart_amba_port {
struct uart_port port;
struct clk *clk;
const struct vendor_data *vendor;
+ unsigned int dmacr; /* dma control reg */
unsigned int im; /* interrupt mask */
unsigned int old_status;
unsigned int fifosize; /* vendor-specific */
@@ -102,22 +115,500 @@ struct uart_amba_port {
unsigned int lcrh_rx; /* vendor-specific */
bool autorts;
char type[12];
+#ifdef CONFIG_DMA_ENGINE
+ /* DMA stuff */
+ bool using_dma;
+ struct pl011_dmatx_data dmatx;
+#endif
+};
+
+/*
+ * All the DMA operation mode stuff goes inside this ifdef.
+ * This assumes that you have a generic DMA device interface,
+ * no custom DMA interfaces are supported.
+ */
+#ifdef CONFIG_DMA_ENGINE
+
+#define PL011_DMA_BUFFER_SIZE PAGE_SIZE
+
+static void pl011_dma_probe_initcall(struct uart_amba_port *uap)
+{
+ /* DMA is the sole user of the platform data right now */
+ struct amba_pl011_data *plat = uap->port.dev->platform_data;
+ struct dma_slave_config tx_conf = {
+ .dst_addr = uap->port.mapbase + UART01x_DR,
+ .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
+ .direction = DMA_TO_DEVICE,
+ .dst_maxburst = uap->fifosize >> 1,
+ };
+ struct dma_chan *chan;
+ dma_cap_mask_t mask;
+
+ /* We need platform data */
+ if (!plat || !plat->dma_filter) {
+ dev_info(uap->port.dev, "no DMA platform data\n");
+ return;
+ }
+
+ /* Try to acquire a generic DMA engine slave channel */
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ chan = dma_request_channel(mask, plat->dma_filter, plat->dma_tx_param);
+ if (!chan) {
+ dev_err(uap->port.dev, "no TX DMA channel!\n");
+ return;
+ }
+
+ dmaengine_slave_config(chan, &tx_conf);
+ uap->dmatx.chan = chan;
+
+ dev_info(uap->port.dev, "DMA channel TX %s\n",
+ dma_chan_name(uap->dmatx.chan));
+}
+
+#ifndef MODULE
+/*
+ * Stack up the UARTs and let the above initcall be done at device
+ * initcall time, because the serial driver is called as an arch
+ * initcall, and at this time the DMA subsystem is not yet registered.
+ * At this point the driver will switch over to using DMA where desired.
+ */
+struct dma_uap {
+ struct list_head node;
+ struct uart_amba_port *uap;
};
+static LIST_HEAD(pl011_dma_uarts);
+
+static int __init pl011_dma_initcall(void)
+{
+ struct list_head *node, *tmp;
+
+ list_for_each_safe(node, tmp, &pl011_dma_uarts) {
+ struct dma_uap *dmau = list_entry(node, struct dma_uap, node);
+ pl011_dma_probe_initcall(dmau->uap);
+ list_del(node);
+ kfree(dmau);
+ }
+ return 0;
+}
+
+device_initcall(pl011_dma_initcall);
+
+static void pl011_dma_probe(struct uart_amba_port *uap)
+{
+ struct dma_uap *dmau = kzalloc(sizeof(struct dma_uap), GFP_KERNEL);
+ if (dmau) {
+ dmau->uap = uap;
+ list_add_tail(&dmau->node, &pl011_dma_uarts);
+ }
+}
+#else
+static void pl011_dma_probe(struct uart_amba_port *uap)
+{
+ pl011_dma_probe_initcall(uap);
+}
+#endif
+
+static void pl011_dma_remove(struct uart_amba_port *uap)
+{
+ /* TODO: remove the initcall if it has not yet executed */
+ if (uap->dmatx.chan)
+ dma_release_channel(uap->dmatx.chan);
+}
+
+
+/* Forward declare this for the refill routine */
+static int pl011_dma_tx_refill(struct uart_amba_port *uap);
+
+/*
+ * The current DMA TX buffer has been sent.
+ * Try to queue up another DMA buffer.
+ */
+static void pl011_dma_tx_callback(void *data)
+{
+ struct uart_amba_port *uap = data;
+ struct pl011_dmatx_data *dmatx = &uap->dmatx;
+ unsigned long flags;
+ u16 dmacr;
+
+ spin_lock_irqsave(&uap->port.lock, flags);
+ if (uap->dmatx.queued)
+ dma_unmap_sg(dmatx->chan->device->dev, &dmatx->sg, 1,
+ DMA_TO_DEVICE);
+
+ dmacr = uap->dmacr;
+ uap->dmacr = dmacr & ~UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+
+ /*
+ * If TX DMA was disabled, it means that we've stopped the DMA for
+ * some reason (eg, XOFF received, or we want to send an X-char.)
+ *
+ * Note: we need to be careful here of a potential race between DMA
+ * and the rest of the driver - if the driver disables TX DMA while
+ * a TX buffer completing, we must update the tx queued status to
+ * get further refills (hence we check dmacr).
+ */
+ if (!(dmacr & UART011_TXDMAE) || uart_tx_stopped(&uap->port) ||
+ uart_circ_empty(&uap->port.state->xmit)) {
+ uap->dmatx.queued = false;
+ spin_unlock_irqrestore(&uap->port.lock, flags);
+ return;
+ }
+
+ if (pl011_dma_tx_refill(uap) <= 0) {
+ /*
+ * We didn't queue a DMA buffer for some reason, but we
+ * have data pending to be sent. Re-enable the TX IRQ.
+ */
+ uap->im |= UART011_TXIM;
+ writew(uap->im, uap->port.membase + UART011_IMSC);
+ }
+ spin_unlock_irqrestore(&uap->port.lock, flags);
+}
+
+/*
+ * Try to refill the TX DMA buffer.
+ * Locking: called with port lock held and IRQs disabled.
+ * Returns:
+ * 1 if we queued up a TX DMA buffer.
+ * 0 if we didn't want to handle this by DMA
+ * <0 on error
+ */
+static int pl011_dma_tx_refill(struct uart_amba_port *uap)
+{
+ struct pl011_dmatx_data *dmatx = &uap->dmatx;
+ struct dma_chan *chan = dmatx->chan;
+ struct dma_device *dma_dev = chan->device;
+ struct dma_async_tx_descriptor *desc;
+ struct circ_buf *xmit = &uap->port.state->xmit;
+ unsigned int count;
+ dma_addr_t cookie;
+
+ /*
+ * Try to avoid the overhead involved in using DMA if the
+ * transaction fits in the first half of the FIFO, by using
+ * the standard interrupt handling. This ensures that we
+ * issue a uart_write_wakeup() at the appropriate time.
+ */
+ count = uart_circ_chars_pending(xmit);
+ if (count < (uap->fifosize >> 1)) {
+ uap->dmatx.queued = false;
+ return 0;
+ }
+
+ /*
+ * Bodge: don't send the last character by DMA, as this
+ * will prevent XON from notifying us to restart DMA.
+ */
+ count -= 1;
+
+ /* Else proceed to copy the TX chars to the DMA buffer and fire DMA */
+ if (count > PL011_DMA_BUFFER_SIZE)
+ count = PL011_DMA_BUFFER_SIZE;
+
+ if (xmit->tail < xmit->head)
+ memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], count);
+ else {
+ size_t first = UART_XMIT_SIZE - xmit->tail;
+ size_t second = xmit->head;
+
+ memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], first);
+ if (second)
+ memcpy(&dmatx->buf[first], &xmit->buf[0], second);
+ }
+
+ dmatx->sg.length = count;
+
+ if (dma_map_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE) != 1) {
+ uap->dmatx.queued = false;
+ dev_dbg(uap->port.dev, "unable to map TX DMA\n");
+ return -EBUSY;
+ }
+
+ desc = dma_dev->device_prep_slave_sg(chan, &dmatx->sg, 1, DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ uap->dmatx.queued = false;
+ /*
+ * If DMA cannot be used right now, we complete this
+ * transaction via IRQ and let the TTY layer retry.
+ */
+ dev_dbg(uap->port.dev, "TX DMA busy\n");
+ return -EBUSY;
+ }
+
+ /* Some data to go along to the callback */
+ desc->callback = pl011_dma_tx_callback;
+ desc->callback_param = uap;
+
+ /* All errors should happen at prepare time */
+ dmaengine_submit(desc);
+
+ /* Fire the DMA transaction */
+ dma_dev->device_issue_pending(chan);
+
+ uap->dmacr |= UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+ uap->dmatx.queued = true;
+
+ /*
+ * Now we know that DMA will fire, so advance the ring buffer
+ * with the stuff we just dispatched.
+ */
+ xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
+ uap->port.icount.tx += count;
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&uap->port);
+
+ return 1;
+}
+
+/*
+ * We received a transmit interrupt without a pending X-char but with
+ * pending characters.
+ * Locking: called with port lock held and IRQs disabled.
+ * Returns:
+ * false if we want to use PIO to transmit
+ * true if we queued a DMA buffer
+ */
+static bool pl011_dma_tx_irq(struct uart_amba_port *uap)
+{
+ if (!uap->using_dma)
+ return false;
+
+ /*
+ * If we already have a TX buffer queued, but received a
+ * TX interrupt, it will be because we've just sent an X-char.
+ * Ensure the TX DMA is enabled and the TX IRQ is disabled.
+ */
+ if (uap->dmatx.queued) {
+ uap->dmacr |= UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+ uap->im &= ~UART011_TXIM;
+ writew(uap->im, uap->port.membase + UART011_IMSC);
+ return true;
+ }
+
+ /*
+ * We don't have a TX buffer queued, so try to queue one.
+ * If we succesfully queued a buffer, mask the TX IRQ.
+ */
+ if (pl011_dma_tx_refill(uap) > 0) {
+ uap->im &= ~UART011_TXIM;
+ writew(uap->im, uap->port.membase + UART011_IMSC);
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Stop the DMA transmit (eg, due to received XOFF).
+ * Locking: called with port lock held and IRQs disabled.
+ */
+static inline void pl011_dma_tx_stop(struct uart_amba_port *uap)
+{
+ if (uap->dmatx.queued) {
+ uap->dmacr &= ~UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+ }
+}
+
+/*
+ * Try to start a DMA transmit, or in the case of an XON/OFF
+ * character queued for send, try to get that character out ASAP.
+ * Locking: called with port lock held and IRQs disabled.
+ * Returns:
+ * false if we want the TX IRQ to be enabled
+ * true if we have a buffer queued
+ */
+static inline bool pl011_dma_tx_start(struct uart_amba_port *uap)
+{
+ u16 dmacr;
+
+ if (!uap->using_dma)
+ return false;
+
+ if (!uap->port.x_char) {
+ /* no X-char, try to push chars out in DMA mode */
+ bool ret = true;
+
+ if (!uap->dmatx.queued) {
+ if (pl011_dma_tx_refill(uap) > 0) {
+ uap->im &= ~UART011_TXIM;
+ ret = true;
+ } else {
+ uap->im |= UART011_TXIM;
+ ret = false;
+ }
+ writew(uap->im, uap->port.membase + UART011_IMSC);
+ } else if (!(uap->dmacr & UART011_TXDMAE)) {
+ uap->dmacr |= UART011_TXDMAE;
+ writew(uap->dmacr,
+ uap->port.membase + UART011_DMACR);
+ }
+ return ret;
+ }
+
+ /*
+ * We have an X-char to send. Disable DMA to prevent it loading
+ * the TX fifo, and then see if we can stuff it into the FIFO.
+ */
+ dmacr = uap->dmacr;
+ uap->dmacr &= ~UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+
+ if (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) {
+ /*
+ * No space in the FIFO, so enable the transmit interrupt
+ * so we know when there is space. Note that once we've
+ * loaded the character, we should just re-enable DMA.
+ */
+ return false;
+ }
+
+ writew(uap->port.x_char, uap->port.membase + UART01x_DR);
+ uap->port.icount.tx++;
+ uap->port.x_char = 0;
+
+ /* Success - restore the DMA state */
+ uap->dmacr = dmacr;
+ writew(dmacr, uap->port.membase + UART011_DMACR);
+
+ return true;
+}
+
+/*
+ * Flush the transmit buffer.
+ * Locking: called with port lock held and IRQs disabled.
+ */
+static void pl011_dma_flush_buffer(struct uart_port *port)
+{
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
+
+ if (!uap->using_dma)
+ return;
+
+ /* Avoid deadlock with the DMA engine callback */
+ spin_unlock(&uap->port.lock);
+ dmaengine_terminate_all(uap->dmatx.chan);
+ spin_lock(&uap->port.lock);
+ if (uap->dmatx.queued) {
+ dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1,
+ DMA_TO_DEVICE);
+ uap->dmatx.queued = false;
+ uap->dmacr &= ~UART011_TXDMAE;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+ }
+}
+
+
+static void pl011_dma_startup(struct uart_amba_port *uap)
+{
+ if (!uap->dmatx.chan)
+ return;
+
+ uap->dmatx.buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL);
+ if (!uap->dmatx.buf) {
+ dev_err(uap->port.dev, "no memory for DMA TX buffer\n");
+ uap->port.fifosize = uap->fifosize;
+ return;
+ }
+
+ sg_init_one(&uap->dmatx.sg, uap->dmatx.buf, PL011_DMA_BUFFER_SIZE);
+
+ /* The DMA buffer is now the FIFO the TTY subsystem can use */
+ uap->port.fifosize = PL011_DMA_BUFFER_SIZE;
+ uap->using_dma = true;
+
+ /* Turn on DMA error (RX/TX will be enabled on demand) */
+ uap->dmacr |= UART011_DMAONERR;
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+}
+
+static void pl011_dma_shutdown(struct uart_amba_port *uap)
+{
+ if (!uap->using_dma)
+ return;
+
+ /* Disable RX and TX DMA */
+ while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
+ barrier();
+
+ spin_lock_irq(&uap->port.lock);
+ uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE);
+ writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+ spin_unlock_irq(&uap->port.lock);
+
+ /* In theory, this should already be done by pl011_dma_flush_buffer */
+ dmaengine_terminate_all(uap->dmatx.chan);
+ if (uap->dmatx.queued) {
+ dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1,
+ DMA_TO_DEVICE);
+ uap->dmatx.queued = false;
+ }
+
+ kfree(uap->dmatx.buf);
+
+ uap->using_dma = false;
+}
+
+#else
+/* Blank functions if the DMA engine is not available */
+static inline void pl011_dma_probe(struct uart_amba_port *uap)
+{
+}
+
+static inline void pl011_dma_remove(struct uart_amba_port *uap)
+{
+}
+
+static inline void pl011_dma_startup(struct uart_amba_port *uap)
+{
+}
+
+static inline void pl011_dma_shutdown(struct uart_amba_port *uap)
+{
+}
+
+static inline bool pl011_dma_tx_irq(struct uart_amba_port *uap)
+{
+ return false;
+}
+
+static inline void pl011_dma_tx_stop(struct uart_amba_port *uap)
+{
+}
+
+static inline bool pl011_dma_tx_start(struct uart_amba_port *uap)
+{
+ return false;
+}
+
+#define pl011_dma_flush_buffer NULL
+#endif
+
+
static void pl011_stop_tx(struct uart_port *port)
{
struct uart_amba_port *uap = (struct uart_amba_port *)port;
uap->im &= ~UART011_TXIM;
writew(uap->im, uap->port.membase + UART011_IMSC);
+ pl011_dma_tx_stop(uap);
}
static void pl011_start_tx(struct uart_port *port)
{
struct uart_amba_port *uap = (struct uart_amba_port *)port;
- uap->im |= UART011_TXIM;
- writew(uap->im, uap->port.membase + UART011_IMSC);
+ if (!pl011_dma_tx_start(uap)) {
+ uap->im |= UART011_TXIM;
+ writew(uap->im, uap->port.membase + UART011_IMSC);
+ }
}
static void pl011_stop_rx(struct uart_port *port)
@@ -204,6 +695,10 @@ static void pl011_tx_chars(struct uart_amba_port *uap)
return;
}
+ /* If we are using DMA mode, try to send some characters. */
+ if (pl011_dma_tx_irq(uap))
+ return;
+
count = uap->fifosize >> 1;
do {
writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
@@ -434,6 +929,9 @@ static int pl011_startup(struct uart_port *port)
*/
uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
+ /* Startup DMA */
+ pl011_dma_startup(uap);
+
/*
* Finally, enable interrupts
*/
@@ -473,6 +971,8 @@ static void pl011_shutdown(struct uart_port *port)
writew(0xffff, uap->port.membase + UART011_ICR);
spin_unlock_irq(&uap->port.lock);
+ pl011_dma_shutdown(uap);
+
/*
* Free the interrupt
*/
@@ -691,6 +1191,7 @@ static struct uart_ops amba_pl011_pops = {
.break_ctl = pl011_break_ctl,
.startup = pl011_startup,
.shutdown = pl011_shutdown,
+ .flush_buffer = pl011_dma_flush_buffer,
.set_termios = pl011_set_termios,
.type = pl011_type,
.release_port = pl010_release_port,
@@ -883,6 +1384,7 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id)
uap->port.ops = &amba_pl011_pops;
uap->port.flags = UPF_BOOT_AUTOCONF;
uap->port.line = i;
+ pl011_dma_probe(uap);
snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev));
@@ -893,6 +1395,7 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id)
if (ret) {
amba_set_drvdata(dev, NULL);
amba_ports[i] = NULL;
+ pl011_dma_remove(uap);
clk_put(uap->clk);
unmap:
iounmap(base);
@@ -916,6 +1419,7 @@ static int pl011_remove(struct amba_device *dev)
if (amba_ports[i] == uap)
amba_ports[i] = NULL;
+ pl011_dma_remove(uap);
iounmap(uap->port.membase);
clk_put(uap->clk);
kfree(uap);
diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h
index 6021588..577f22e 100644
--- a/include/linux/amba/serial.h
+++ b/include/linux/amba/serial.h
@@ -180,6 +180,13 @@ struct amba_device; /* in uncompress this is included but amba/bus.h is not */
struct amba_pl010_data {
void (*set_mctrl)(struct amba_device *dev, void __iomem *base, unsigned int mctrl);
};
+
+struct dma_chan;
+struct amba_pl011_data {
+ bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
+ void *dma_rx_param;
+ void *dma_tx_param;
+};
#endif
#endif
--
1.6.2.5
^ permalink raw reply related
* [PATCH 5/7] ARM: PL011: Ensure IRQs are disabled in UART interrupt handler
From: Russell King - ARM Linux @ 2011-01-03 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110103100753.GB26785@n2100.arm.linux.org.uk>
As the DMA support introduces a separate interrupt-time callback, our
interrupt handler will not be the only handler which takes the port
lock, so we need to ensure that IRQs are disabled. We must use the
_irqsave variant so we don't inadvertently enable interrupts.
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/serial/amba-pl011.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index f9b6b82..f741a8b 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -247,10 +247,11 @@ static void pl011_modem_status(struct uart_amba_port *uap)
static irqreturn_t pl011_int(int irq, void *dev_id)
{
struct uart_amba_port *uap = dev_id;
+ unsigned long flags;
unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
int handled = 0;
- spin_lock(&uap->port.lock);
+ spin_lock_irqsave(&uap->port.lock, flags);
status = readw(uap->port.membase + UART011_MIS);
if (status) {
@@ -275,7 +276,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
handled = 1;
}
- spin_unlock(&uap->port.lock);
+ spin_unlock_irqrestore(&uap->port.lock, flags);
return IRQ_RETVAL(handled);
}
--
1.6.2.5
^ permalink raw reply related
* [PATCH 4/7] ARM: PL011: Separate hardware FIFO size from TTY FIFO size
From: Russell King - ARM Linux @ 2011-01-03 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110103100753.GB26785@n2100.arm.linux.org.uk>
With DMA support, we need to tell the TTY subsystem that the DMA buffer
is the size of the FIFO, otherwise things like tty_wait_until_sent()
will time out too early. Keep (and use) the hardware value separately
from the port->fifosize.
This was part of a larger patch from Linus Walleij, with a little
modification.
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/serial/amba-pl011.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 6afdd9b..f9b6b82 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -97,6 +97,7 @@ struct uart_amba_port {
const struct vendor_data *vendor;
unsigned int im; /* interrupt mask */
unsigned int old_status;
+ unsigned int fifosize; /* vendor-specific */
unsigned int lcrh_tx; /* vendor-specific */
unsigned int lcrh_rx; /* vendor-specific */
bool autorts;
@@ -203,7 +204,7 @@ static void pl011_tx_chars(struct uart_amba_port *uap)
return;
}
- count = uap->port.fifosize >> 1;
+ count = uap->fifosize >> 1;
do {
writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -541,7 +542,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
if (!(termios->c_cflag & PARODD))
lcr_h |= UART01x_LCRH_EPS;
}
- if (port->fifosize > 1)
+ if (uap->fifosize > 1)
lcr_h |= UART01x_LCRH_FEN;
spin_lock_irqsave(&port->lock, flags);
@@ -871,12 +872,13 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id)
uap->vendor = vendor;
uap->lcrh_rx = vendor->lcrh_rx;
uap->lcrh_tx = vendor->lcrh_tx;
+ uap->fifosize = vendor->fifosize;
uap->port.dev = &dev->dev;
uap->port.mapbase = dev->res.start;
uap->port.membase = base;
uap->port.iotype = UPIO_MEM;
uap->port.irq = dev->irq[0];
- uap->port.fifosize = vendor->fifosize;
+ uap->port.fifosize = uap->fifosize;
uap->port.ops = &amba_pl011_pops;
uap->port.flags = UPF_BOOT_AUTOCONF;
uap->port.line = i;
--
1.6.2.5
^ permalink raw reply related
* [PATCH 3/7] ARM: PL011: Allow better handling of vendor data
From: Russell King - ARM Linux @ 2011-01-03 10:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110103100753.GB26785@n2100.arm.linux.org.uk>
Rather than copying all vendor data into the port structure, copy
just that which is frequently used, and keep a pointer to the
remaining vendor data structure. This makes it easier to add
vendor quirks in the future.
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/serial/amba-pl011.c | 51 ++++++++++++++++++++++--------------------
1 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index c77b3eb..6afdd9b 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -63,22 +63,6 @@
#define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
#define UART_DUMMY_DR_RX (1 << 16)
-/*
- * We wrap our port structure around the generic uart_port.
- */
-struct uart_amba_port {
- struct uart_port port;
- struct clk *clk;
- unsigned int im; /* interrupt mask */
- unsigned int old_status;
- unsigned int ifls; /* vendor-specific */
- unsigned int lcrh_tx; /* vendor-specific */
- unsigned int lcrh_rx; /* vendor-specific */
- bool oversampling; /* vendor-specific */
- bool autorts;
- char type[12];
-};
-
/* There is by now@least one vendor with differing details, so handle it */
struct vendor_data {
unsigned int ifls;
@@ -104,6 +88,21 @@ static struct vendor_data vendor_st = {
.oversampling = true,
};
+/*
+ * We wrap our port structure around the generic uart_port.
+ */
+struct uart_amba_port {
+ struct uart_port port;
+ struct clk *clk;
+ const struct vendor_data *vendor;
+ unsigned int im; /* interrupt mask */
+ unsigned int old_status;
+ unsigned int lcrh_tx; /* vendor-specific */
+ unsigned int lcrh_rx; /* vendor-specific */
+ bool autorts;
+ char type[12];
+};
+
static void pl011_stop_tx(struct uart_port *port)
{
struct uart_amba_port *uap = (struct uart_amba_port *)port;
@@ -397,7 +396,7 @@ static int pl011_startup(struct uart_port *port)
if (retval)
goto clk_dis;
- writew(uap->ifls, uap->port.membase + UART011_IFLS);
+ writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS);
/*
* Provoke TX FIFO interrupt into asserting.
@@ -503,13 +502,18 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned int lcr_h, old_cr;
unsigned long flags;
- unsigned int baud, quot;
+ unsigned int baud, quot, clkdiv;
+
+ if (uap->vendor->oversampling)
+ clkdiv = 8;
+ else
+ clkdiv = 16;
/*
* Ask the core to calculate the divisor for us.
*/
baud = uart_get_baud_rate(port, termios, old, 0,
- port->uartclk/(uap->oversampling ? 8 : 16));
+ port->uartclk / clkdiv);
if (baud > port->uartclk/16)
quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud);
@@ -593,8 +597,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
uap->autorts = false;
}
- if (uap->oversampling) {
- if (baud > port->uartclk/16)
+ if (uap->vendor->oversampling) {
+ if (baud > port->uartclk / 16)
old_cr |= ST_UART011_CR_OVSFACT;
else
old_cr &= ~ST_UART011_CR_OVSFACT;
@@ -767,7 +771,7 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud,
*baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd);
- if (uap->oversampling) {
+ if (uap->vendor->oversampling) {
if (readw(uap->port.membase + UART011_CR)
& ST_UART011_CR_OVSFACT)
*baud *= 2;
@@ -864,10 +868,9 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id)
goto unmap;
}
- uap->ifls = vendor->ifls;
+ uap->vendor = vendor;
uap->lcrh_rx = vendor->lcrh_rx;
uap->lcrh_tx = vendor->lcrh_tx;
- uap->oversampling = vendor->oversampling;
uap->port.dev = &dev->dev;
uap->port.mapbase = dev->res.start;
uap->port.membase = base;
--
1.6.2.5
^ permalink raw reply related
* [PATCH 2/7] ARM: PL011: Ensure error flags are clear at startup
From: Russell King - ARM Linux @ 2011-01-03 10:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110103100753.GB26785@n2100.arm.linux.org.uk>
The error flags weren't being cleared upon UART startup, which
can cause problems when we add DMA support. It's good practice
to ensure that these flags are cleared anyway, so let's do so.
This was part of a larger patch from Linus Walleij.
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/serial/amba-pl011.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 2c07939..c77b3eb 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -424,6 +424,10 @@ static int pl011_startup(struct uart_port *port)
cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
writew(cr, uap->port.membase + UART011_CR);
+ /* Clear pending error interrupts */
+ writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS,
+ uap->port.membase + UART011_ICR);
+
/*
* initialise the old status of the modem signals
*/
--
1.6.2.5
^ permalink raw reply related
* [PATCH 1/7] ARM: PL011: include revision number in boot-time port printk
From: Russell King - ARM Linux @ 2011-01-03 10:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110103100753.GB26785@n2100.arm.linux.org.uk>
Include the revision number of the PL011 primecell in the boot-time
port printk to allow proper identification of the peripheral.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/serial/amba-pl011.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 6ca7a44..2c07939 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -76,6 +76,7 @@ struct uart_amba_port {
unsigned int lcrh_rx; /* vendor-specific */
bool oversampling; /* vendor-specific */
bool autorts;
+ char type[12];
};
/* There is by now at least one vendor with differing details, so handle it */
@@ -622,7 +623,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
static const char *pl011_type(struct uart_port *port)
{
- return port->type == PORT_AMBA ? "AMBA/PL011" : NULL;
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
+ return uap->port.type == PORT_AMBA ? uap->type : NULL;
}
/*
@@ -872,6 +874,8 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id)
uap->port.flags = UPF_BOOT_AUTOCONF;
uap->port.line = i;
+ snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev));
+
amba_ports[i] = uap;
amba_set_drvdata(dev, uap);
--
1.6.2.5
^ permalink raw reply related
* [PATCH 0/7] PL011 DMA support
From: Russell King - ARM Linux @ 2011-01-03 10:07 UTC (permalink / raw)
To: linux-arm-kernel
This is another posting of the PL011 DMA patch set, with a new patch
to include the PL011 revision in the boot time messages, and fixups
to the DMA patch as a result of discussions with Dan.
Acks for patches 1 and 6 would be appreciated.
^ permalink raw reply
* [RFC PATCH] Avoid aliasing mappings in DMA coherent allocator
From: Russell King - ARM Linux @ 2011-01-03 9:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <loom.20101228T203522-493@post.gmane.org>
On Tue, Dec 28, 2010 at 09:29:58PM +0000, Janusz Krzysztofik wrote:
> Works fine on OMAP1 based Amstrad Delta, both default 2MB/2MB and shrinked
> to 1MB/1MB configurations. No need to preallocate dma coherent memory for
> camera video buffers on boot.
That's good news.
> However, in 1MB/1MB configuration it failed to allocate 600kB of
> writecombined omapfb vram, required for double-buffering, and reserving
> up to 4MB of machine's total 32MB seems too expensive.
Do you have other users of the writecombined memory? If so, what size
are they?
As the 600k allocation can only be satisfied at the beginning of the
region, we could do top-down rather than bottom-up allocation (untested):
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
index 935993e..036fdbf 100644
--- a/arch/arm/mm/vmregion.c
+++ b/arch/arm/mm/vmregion.c
@@ -38,7 +38,7 @@ struct arm_vmregion *
arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
size_t size, gfp_t gfp)
{
- unsigned long addr = head->vm_start, end = head->vm_end - size;
+ unsigned long start = head->vm_start, addr = head->vm_end;
unsigned long flags;
struct arm_vmregion *c, *new;
@@ -54,21 +54,20 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
spin_lock_irqsave(&head->vm_lock, flags);
- list_for_each_entry(c, &head->vm_list, vm_list) {
- if ((addr + size) < addr)
- goto nospc;
- if ((addr + size) <= c->vm_start)
+ addr = rounddown(addr - size, align);
+ list_for_each_entry_reverse(c, &head->vm_list, vm_list) {
+ if (addr >= c->vm_end)
goto found;
- addr = ALIGN(c->vm_end, align);
- if (addr > end)
+ addr = rounddown(c->vm_start - size, align);
+ if (addr < start)
goto nospc;
}
found:
/*
- * Insert this entry _before_ the one we found.
+ * Insert this entry after the one we found.
*/
- list_add_tail(&new->vm_list, &c->vm_list);
+ list_add(&new->vm_list, &c->vm_list);
new->vm_start = addr;
new->vm_end = addr + size;
new->vm_active = 1;
^ permalink raw reply related
* [PATCH 04/04] ARM i.MX25 Add SIM 3DS PDK
From: FQ | Iban Cerro @ 2011-01-03 9:13 UTC (permalink / raw)
To: linux-arm-kernel
Includes driver into the corresponding platform
Signed-off-by: Iban Cerro Galvez <iban@fqingenieria.es>
---
arch/arm/mach-imx/mach-mx25_3ds.c | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-imx/mach-mx25_3ds.c
b/arch/arm/mach-imx/mach-mx25_3ds.c
index 8b8e75b..2933452 100644
--- a/arch/arm/mach-imx/mach-mx25_3ds.c
+++ b/arch/arm/mach-imx/mach-mx25_3ds.c
@@ -102,6 +102,18 @@ static iomux_v3_cfg_t mx25pdk_pads[] = {
MX25_PAD_SD1_DATA1__SD1_DATA1,
MX25_PAD_SD1_DATA2__SD1_DATA2,
MX25_PAD_SD1_DATA3__SD1_DATA3,
+
+ /* SIM1 */
+ MX25_PAD_CSI_D4__SIM1_VEN0,
+ MX25_PAD_CSI_D5__SIM1_TX0,
+ MX25_PAD_CSI_D3__SIM1_RST0,
+ MX25_PAD_CSI_D2__SIM1_CLK0,
+
+ /* SIM2 */
+ MX25_PAD_CSI_MCLK__SIM2_VEN0,
+ MX25_PAD_CSI_VSYNC__SIM2_TX0,
+ MX25_PAD_CSI_D9__SIM2_RST0,
+ MX25_PAD_CSI_D8__SIM2_CLK0,
};
static const struct fec_platform_data mx25_fec_pdata __initconst = {
@@ -160,6 +172,27 @@ static const struct imx_fb_platform_data
mx25pdk_fb_pdata __initconst = {
.dmacr = 0x00020010,
};
+static struct mxc_sim_platform_data mx25_sim_data[] ={
+ {
+ .clk_rate = 5000000,
+ .clock_sim = "mxc-sim.0",
+ .power_sim = NULL,
+ .init = NULL,
+ .exit = NULL,
+ .detect = 1,
+ .sim_number = 0,
+ },
+ {
+ .clk_rate = 5000000,
+ .clock_sim = "mxc-sim.1",
+ .power_sim = NULL,
+ .init = NULL,
+ .exit = NULL,
+ .detect = 1,
+ .sim_number = 1,
+ }
+};
+
static const uint32_t mx25pdk_keymap[] = {
KEY(0, 0, KEY_UP),
KEY(0, 1, KEY_DOWN),
@@ -201,6 +234,8 @@ static void __init mx25pdk_init(void)
imx25_add_imx_keypad(&mx25pdk_keymap_data);
imx25_add_sdhci_esdhc_imx(0, NULL);
+ imx25_add_mxc_sim0(&mx25_sim_data[0]);
+ imx25_add_mxc_sim1(&mx25_sim_data[1]);
}
static void __init mx25pdk_timer_init(void)
--
1.5.4.3
^ permalink raw reply related
* [PATCH 03/04] ARM i.MX25 Add SIM Device
From: FQ | Iban Cerro @ 2011-01-03 9:11 UTC (permalink / raw)
To: linux-arm-kernel
Adds SIM device to MX25 platform
Signed-off-by: Iban Cerro Galvez <iban@fqingenieria.es>
---
arch/arm/mach-imx/devices-imx25.h | 7 +++
arch/arm/plat-mxc/devices/Kconfig | 4 ++
arch/arm/plat-mxc/devices/Makefile | 1 +
arch/arm/plat-mxc/devices/platform-mxc_sim.c | 51
+++++++++++++++++++++++
arch/arm/plat-mxc/include/mach/devices-common.h | 11 +++++
arch/arm/plat-mxc/include/mach/iomux-mx25.h | 12 +++++
arch/arm/plat-mxc/include/mach/mx25.h | 9 ++++
7 files changed, 95 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/plat-mxc/devices/platform-mxc_sim.c
diff --git a/arch/arm/mach-imx/devices-imx25.h
b/arch/arm/mach-imx/devices-imx25.h
index bde33ca..dd33c6c 100644
--- a/arch/arm/mach-imx/devices-imx25.h
+++ b/arch/arm/mach-imx/devices-imx25.h
@@ -85,3 +85,10 @@ extern const struct imx_spi_imx_data imx25_cspi_data[]
__initconst;
#define imx25_add_spi_imx0(pdata) imx25_add_spi_imx(0, pdata)
#define imx25_add_spi_imx1(pdata) imx25_add_spi_imx(1, pdata)
#define imx25_add_spi_imx2(pdata) imx25_add_spi_imx(2, pdata)
+
+extern const struct imx_mxc_sim_data imx25_mxc_sim_data[] __initconst;
+#define imx25_add_mxc_sim(id, pdata) \
+ imx_add_mxc_sim(&imx25_mxc_sim_data[id], pdata)
+#define imx25_add_mxc_sim0(pdata) imx25_add_mxc_sim(0, pdata)
+#define imx25_add_mxc_sim1(pdata) imx25_add_mxc_sim(1, pdata)
+
diff --git a/arch/arm/plat-mxc/devices/Kconfig
b/arch/arm/plat-mxc/devices/Kconfig
index 2537166..708f19c 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -71,3 +71,7 @@ config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
config IMX_HAVE_PLATFORM_SPI_IMX
bool
+
+config IMX_HAVE_PLATFORM_MXC_SIM
+ bool
+ default y if ARCH_MX25
\ No newline at end of file
diff --git a/arch/arm/plat-mxc/devices/Makefile
b/arch/arm/plat-mxc/devices/Makefile
index 75cd2ec..c8da5d3 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RNGA) +=
platform-mxc_rnga.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) +=
platform-sdhci-esdhc-imx.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_SIM) += platform-mxc_sim.o
\ No newline at end of file
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_sim.c
b/arch/arm/plat-mxc/devices/platform-mxc_sim.c
new file mode 100644
index 0000000..51d6679
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_sim.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_sim_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _SIM ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_SIM ## _hwid, \
+ }
+
+#define imx_mxc_sim_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_mxc_sim_data_entry_single(soc, _id, _hwid, _size)
+
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_mxc_sim_data imx25_mxc_sim_data[] __initconst = {
+#define imx25_mxc_sim_data_entry(_id, _hwid) \
+ imx_mxc_sim_data_entry(MX25, _id, _hwid, SZ_16K)
+ imx25_mxc_sim_data_entry(0, 1),
+ imx25_mxc_sim_data_entry(1, 2),
+};
+
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+
+struct platform_device *__init imx_add_mxc_sim(
+ const struct imx_mxc_sim_data *data,
+ const struct mxc_sim_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+ return imx_add_platform_device("mxc_sim", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
+
+
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h
b/arch/arm/plat-mxc/include/mach/devices-common.h
index 8658c9c..92b83f0 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -264,3 +264,14 @@ struct imx_spi_imx_data {
struct platform_device *__init imx_add_spi_imx(
const struct imx_spi_imx_data *data,
const struct spi_imx_master *pdata);
+
+#include <mach/mxc_sim.h>
+struct imx_mxc_sim_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ int irq;
+};
+struct platform_device *__init imx_add_mxc_sim(
+ const struct imx_mxc_sim_data *data,
+ const struct mxc_sim_platform_data *pdata);
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h
b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
index d7f52c9..ecd6b16 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx25.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
@@ -262,40 +262,52 @@
#define MX25_PAD_CSI_D2__CSI_D2 IOMUX_PAD(0x318, 0x120, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D2__UART5_RXD_MUX IOMUX_PAD(0x318, 0x120, 0x11,
0x578, 1, NO_PAD_CTRL)
#define MX25_PAD_CSI_D2__GPIO_1_27 IOMUX_PAD(0x318, 0x120, 0x15, 0, 0,
NO_PAD_CTRL)
+#define MX25_PAD_CSI_D2__SIM1_CLK0 IOMUX_PAD(0x318, 0x120, 0x04, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D3__CSI_D3 IOMUX_PAD(0x31c, 0x124, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D3__GPIO_1_28 IOMUX_PAD(0x31c, 0x124, 0x15, 0, 0,
NO_PAD_CTRL)
+#define MX25_PAD_CSI_D3__SIM1_RST0 IOMUX_PAD(0x31c, 0x124, 0x04, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D4__CSI_D4 IOMUX_PAD(0x320, 0x128, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D4__UART5_RTS IOMUX_PAD(0x320, 0x128, 0x11, 0x574,
1, NO_PAD_CTRL)
#define MX25_PAD_CSI_D4__GPIO_1_29 IOMUX_PAD(0x320, 0x128, 0x15, 0, 0,
NO_PAD_CTRL)
+#define MX25_PAD_CSI_D4__SIM1_VEN0 IOMUX_PAD(0x320, 0x128, 0x04, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D5__CSI_D5 IOMUX_PAD(0x324, 0x12c, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D5__GPIO_1_30 IOMUX_PAD(0x324, 0x12c, 0x15, 0, 0,
NO_PAD_CTRL)
+#define MX25_PAD_CSI_D5__SIM1_TX0 IOMUX_PAD(0x324, 0x12c, 0x04, 0, 0,
PAD_CTL_SRE_FAST)
#define MX25_PAD_CSI_D6__CSI_D6 IOMUX_PAD(0x328, 0x130, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D6__GPIO_1_31 IOMUX_PAD(0x328, 0x130, 0x15, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D7__CSI_D7 IOMUX_PAD(0x32c, 0x134, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D7__GPIO_1_6 IOMUX_PAD(0x32c, 0x134, 0x15, 0, 0,
NO_PAD_CTRL)
+#define MX25_PAD_CSI_D7__GPIO_1_6_PD IOMUX_PAD(0x32c, 0x134, 0x15, 0, 0,
PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_DOWN)
#define MX25_PAD_CSI_D8__CSI_D8 IOMUX_PAD(0x330, 0x138, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D8__GPIO_1_7 IOMUX_PAD(0x330, 0x138, 0x15, 0, 0,
NO_PAD_CTRL)
+#define MX25_PAD_CSI_D8__SIM2_CLK0 IOMUX_PAD(0x330, 0x138, 0x04, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D9__CSI_D9 IOMUX_PAD(0x334, 0x13c, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_D9__GPIO_4_21 IOMUX_PAD(0x334, 0x13c, 0x15, 0, 0,
NO_PAD_CTRL)
+#define MX25_PAD_CSI_D9__SIM2_RST0 IOMUX_PAD(0x334, 0x13c, 0x04, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_MCLK__CSI_MCLK IOMUX_PAD(0x338, 0x140, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_MCLK__GPIO_1_8 IOMUX_PAD(0x338, 0x140, 0x15, 0, 0,
NO_PAD_CTRL)
+#define MX25_PAD_CSI_MCLK__SIM2_VEN0 IOMUX_PAD(0x338, 0x140, 0x04, 0, 0,
NO_PAD_CTRL)
+#define MX25_PAD_CSI_MCLK__GPIO_1_8_PD IOMUX_PAD(0x338, 0x140, 0x15, 0,
0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_DOWN)
#define MX25_PAD_CSI_VSYNC__CSI_VSYNC IOMUX_PAD(0x33c, 0x144, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_VSYNC__GPIO_1_9 IOMUX_PAD(0x33c, 0x144, 0x15, 0, 0,
NO_PAD_CTRL)
+#define MX25_PAD_CSI_VSYNC__SIM2_TX0 IOMUX_PAD(0x33c, 0x144, 0x04, 0,
0, PAD_CTL_SRE_FAST)
#define MX25_PAD_CSI_HSYNC__CSI_HSYNC IOMUX_PAD(0x340, 0x148, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_CSI_HSYNC__GPIO_1_10 IOMUX_PAD(0x340, 0x148, 0x15, 0, 0,
NO_PAD_CTRL)
+#define MX25_PAD_CSI_HSYNC__GPIO_1_10_PD IOMUX_PAD(0x340, 0x148,0x15, 0,
0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_DOWN)
#define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK IOMUX_PAD(0x344, 0x14c, 0x10, 0,
0, NO_PAD_CTRL)
#define MX25_PAD_CSI_PIXCLK__GPIO_1_11 IOMUX_PAD(0x344, 0x14c, 0x15, 0,
0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_PIXCLK__GPIO_1_11_PD IOMUX_PAD(0x344, 0x14c, 0x15,
0, 0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_DOWN)
#define MX25_PAD_I2C1_CLK__I2C1_CLK IOMUX_PAD(0x348, 0x150, 0x10, 0, 0,
NO_PAD_CTRL)
#define MX25_PAD_I2C1_CLK__GPIO_1_12 IOMUX_PAD(0x348, 0x150, 0x15, 0, 0,
NO_PAD_CTRL)
diff --git a/arch/arm/plat-mxc/include/mach/mx25.h
b/arch/arm/plat-mxc/include/mach/mx25.h
index 087cd7a..5ddaed0 100644
--- a/arch/arm/plat-mxc/include/mach/mx25.h
+++ b/arch/arm/plat-mxc/include/mach/mx25.h
@@ -37,6 +37,8 @@
#define MX25_CSPI3_BASE_ADDR 0x50004000
#define MX25_CSPI2_BASE_ADDR 0x50010000
+#define MX25_SIM1_BASE_ADDR 0x50024000
+#define MX25_SIM2_BASE_ADDR 0x50028000
#define MX25_FEC_BASE_ADDR 0x50038000
#define MX25_SSI2_BASE_ADDR 0x50014000
#define MX25_SSI1_BASE_ADDR 0x50034000
@@ -57,6 +59,11 @@
#define MX25_USB_HS_BASE_ADDR (MX25_USB_BASE_ADDR + 0x0400)
#define MX25_CSI_BASE_ADDR 0x53ff8000
+#define MX25_CS0_BASE_ADDR 0xa0000000
+#define MX25_CS1_BASE_ADDR 0xa8000000
+#define MX25_CS2_BASE_ADDR 0xb0000000
+#define MX25_CS3_BASE_ADDR 0xb2000000
+
#define MX25_IO_P2V(x) IMX_IO_P2V(x)
#define MX25_IO_ADDRESS(x) IOMEM(MX25_IO_P2V(x))
@@ -74,6 +81,8 @@
#define MX25_INT_GPIO3 16
#define MX25_INT_CSI 17
#define MX25_INT_UART3 18
+#define MX25_INT_SIM1 20
+#define MX25_INT_SIM2 21
#define MX25_INT_GPIO4 23
#define MX25_INT_KPP 24
#define MX25_INT_DRYICE 25
--
1.5.4.3
^ permalink raw reply related
* [PATCH 02/04] ARM i.MX25 Add SIM driver
From: FQ | Iban Cerro @ 2011-01-03 9:07 UTC (permalink / raw)
To: linux-arm-kernel
This driver is slightly based on the Freescale original one, with several
code simplifications. We made specially emphasis in avoiding any ISO7816
code into the driver, which is not the right place to be. Driver mainly
works via ioctl to configure and then using read/write functions to
read/write smart cards.
One important consideration (not clear in the User Manual from our point
of view) is that there exist two SIM modules into the MX25 core, both of
them in different memory position. This causes all accesses to SIM modules
must be done via SIM0. This differs from the way the User Manual explains
how to access the two different SIM modules, which seems is inherited from
the MX51 core.
Signed-off-by: Iban Cerro Galvez <iban@fqingenieria.es>
---
arch/arm/plat-mxc/Kconfig | 7 +
arch/arm/plat-mxc/Makefile | 1 +
arch/arm/plat-mxc/include/mach/mxc_sim.h | 319 +++++++++++
arch/arm/plat-mxc/sim.c | 874
++++++++++++++++++++++++++++++
4 files changed, 1201 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/plat-mxc/include/mach/mxc_sim.h
create mode 100644 arch/arm/plat-mxc/sim.c
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 389f217..7b16d0d 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -74,6 +74,13 @@ config MXC_PWM
help
Enable support for the i.MX PWM controller(s).
+config MXC_SIM
+ tristate "Enable SIM driver"
+ select HAVE_SIM
+ help
+ Enable support for the i.MX SIM controller(s).
+
+
config MXC_DEBUG_BOARD
bool "Enable MXC debug board(for 3-stack)"
help
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 5fd20e9..73073fb 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_MXC_AVIC) += avic.o
obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
+obj-$(CONFIG_MXC_SIM) += sim.o
obj-$(CONFIG_MXC_PWM) += pwm.o
obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
obj-$(CONFIG_MXC_ULPI) += ulpi.o
diff --git a/arch/arm/plat-mxc/include/mach/mxc_sim.h
b/arch/arm/plat-mxc/include/mach/mxc_sim.h
new file mode 100644
index 0000000..74ff008
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_sim.h
@@ -0,0 +1,319 @@
+/*
+ * Copyright 2010-2011 FQ Ingenieria Electronica S.A.
+ *
+ * Adapted and simplify this driver to kernel mainline code style using
+ * other drivers from Freescale
+ * Jaume Ribot (jaume at fqingenieria.es)
+ * Iban Cerro Galvez (iban at fqingenieria.es)
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*!
+ * @file mxc_sim.h
+ *
+ * @brief Driver for Freescale IMX SIM interface
+ *
+ */
+
+#ifndef MXC_SIM_INTERFACE_H
+#define MXC_SIM_INTERFACE_H
+
+#define SIM_DRIVER_VERSION 0x01
+
+/* Transmit and receive buffer sizes */
+#define SIM_XMT_BUFFER_SIZE 256
+#define SIM_RCV_BUFFER_SIZE 256
+
+/*BAUD_DIVISOR */
+#define SIM_DEFAULT_BAUD_DIV 372
+
+#define WRITE_TIMEOUT 1000
+#define READ_TIMEOUT 1000
+
+
+struct mxc_sim_platform_data {
+ unsigned int clk_rate;
+ char *clock_sim;
+ char *power_sim;
+ int (*init)(struct platform_device *pdev);
+ void (*exit)(void);
+ unsigned int detect; /* 1 have detect pin, 0 not */
+ unsigned int sim_number; /* 0 or 1 */
+};
+
+typedef struct {
+ unsigned long addr;
+ unsigned long data;
+} sim_reg;
+
+/* Main SIM driver structure */
+typedef struct {
+ /*SIM number 0, 1 */
+ int sim_number;
+ /* card inserted = 1, ATR received = 2, card removed = 0 */
+ int present;
+ /* current ATR or OPS state */
+ int state;
+ /* current power state */
+ int power;
+ /* error code occured during transfer */
+ int errval;
+ /* Clock id */
+ struct clk *clk;
+ /* on off clk*/
+ uint8_t clk_flag;
+ /* frequency of clk sim */
+ uint32_t clk_sim;
+ /* value of clk divisor*/
+ int uart_div;
+ /* IO map memory */
+ struct resource *res;
+ /* Mapped address */
+ void __iomem *ioaddr; /* Mapped address */
+ int ipb_irq; /* sim ipb IRQ num */
+ int dat_irq; /* sim dat IRQ num */
+ /* async notifier for card and ATR detection */
+ struct fasync_struct *fasync;
+ /* Platform specific data */
+ struct mxc_sim_platform_data *plat_data;
+} sim_t;
+
+/* ISO7816-3 protocols */
+#define SIM_PROTOCOL_T0 0
+#define SIM_PROTOCOL_T1 1
+
+/* Transfer types for SIM_IOCTL_XFER */
+#define SIM_XFER_TYPE_TPDU 0
+#define SIM_XFER_TYPE_PTS 1
+
+/* Interface power states */
+#define SIM_POWER_OFF 0
+#define SIM_POWER_ON 1
+
+/* Return values for SIM_IOCTL_GET_PRESENSE */
+#define SIM_PRESENT_REMOVED 0
+#define SIM_PRESENT_DETECTED 1
+#define SIM_PRESENT_OPERATIONAL 2
+
+/* Return values for SIM_IOCTL_GET_ERROR */
+#define SIM_OK 0
+#define SIM_E_ACCESS 1
+#define SIM_E_TPDUSHORT 2
+#define SIM_E_PTSEMPTY 3
+#define SIM_E_INVALIDXFERTYPE 4
+#define SIM_E_INVALIDXMTLENGTH 5
+#define SIM_E_INVALIDRCVLENGTH 6
+#define SIM_E_NACK 7
+#define SIM_E_TIMEOUT 8
+#define SIM_E_NOCARD 9
+#define SIM_E_PARAM_FI_INVALID 10
+#define SIM_E_PARAM_DI_INVALID 11
+#define SIM_E_PARAM_FBYD_WITHFRACTION 12
+#define SIM_E_PARAM_FBYD_NOTDIVBY8OR12 13
+#define SIM_E_PARAM_DIVISOR_RANGE 14
+#define SIM_E_MALLOC 15
+#define SIM_E_IRQ 16
+#define SIM_E_POWERED_ON 17
+#define SIM_E_POWERED_OFF 18
+
+/* ioctl encodings */
+#define SIM_IOCTL_BASE 0xc0
+#define SIM_IOCTL_VERSION _IOR(SIM_IOCTL_BASE, 1,unsigned char)
+#define SIM_IOCTL_POWER_ON _IO(SIM_IOCTL_BASE, 2)
+#define SIM_IOCTL_POWER_OFF _IO(SIM_IOCTL_BASE, 3)
+#define SIM_IOCTL_WARM_RESET _IO(SIM_IOCTL_BASE, 4)
+#define SIM_IOCTL_COLD_RESET _IO(SIM_IOCTL_BASE, 5)
+#define SIM_IOCTL_CLK_PORT _IOW(SIM_IOCTL_BASE, 6, int)
+#define SIM_IOCTL_RST_PORT _IOW(SIM_IOCTL_BASE, 7, int)
+#define SIM_IOCTL_VCC_PORT _IOW(SIM_IOCTL_BASE, 8, int)
+#define SIM_IOCTL_SET_CLK_SIM _IOW(SIM_IOCTL_BASE, 9, unsigned long)
+#define SIM_IOCTL_SET_CLK_DIV _IOW(SIM_IOCTL_BASE, 10, int)
+#define SIM_IOCTL_GET_REG _IOW(SIM_IOCTL_BASE, 11, sim_reg)
+#define SIM_IOCTL_SET_REG _IOW(SIM_IOCTL_BASE, 12, sim_reg)
+
+/* Interface character references */
+#define SIM_IFC_TXI(letter, number) (letter + number * 4)
+#define SIM_IFC_TA1 SIM_IFC_TXI(0, 0)
+#define SIM_IFC_TB1 SIM_IFC_TXI(0, 1)
+#define SIM_IFC_TC1 SIM_IFC_TXI(0, 2)
+#define SIM_IFC_TD1 SIM_IFC_TXI(0, 3)
+#define SIM_IFC_TA2 SIM_IFC_TXI(1, 0)
+#define SIM_IFC_TB2 SIM_IFC_TXI(1, 1)
+#define SIM_IFC_TC2 SIM_IFC_TXI(1, 2)
+#define SIM_IFC_TD2 SIM_IFC_TXI(1, 3)
+#define SIM_IFC_TA3 SIM_IFC_TXI(2, 0)
+#define SIM_IFC_TB3 SIM_IFC_TXI(2, 1)
+#define SIM_IFC_TC3 SIM_IFC_TXI(2, 2)
+#define SIM_IFC_TD3 SIM_IFC_TXI(2, 3)
+#define SIM_IFC_TA4 SIM_IFC_TXI(3, 0)
+#define SIM_IFC_TB4 SIM_IFC_TXI(3, 1)
+#define SIM_IFC_TC4 SIM_IFC_TXI(3, 2)
+#define SIM_IFC_TD4 SIM_IFC_TXI(3, 3)
+
+/* ATR and OPS states */
+#define SIM_STATE_REMOVED 0
+#define SIM_STATE_OPERATIONAL_IDLE 1
+#define SIM_STATE_OPERATIONAL_COMMAND 2
+#define SIM_STATE_OPERATIONAL_RESPONSE 3
+#define SIM_STATE_OPERATIONAL_STATUS1 4
+#define SIM_STATE_OPERATIONAL_STATUS2 5
+#define SIM_STATE_OPERATIONAL_PTS 6
+#define SIM_STATE_DETECTED_ATR_T0 7
+#define SIM_STATE_DETECTED_ATR_TS 8
+#define SIM_STATE_DETECTED_ATR_TXI 9
+#define SIM_STATE_DETECTED_ATR_THB 10
+#define SIM_STATE_DETECTED_ATR_TCK 11
+
+/* Definitions of the offset of the SIM hardware registers */
+#define PORT1_CNTL 0x00 /* 00 */
+#define SETUP 0x04 /* 04 */
+#define PORT1_DETECT 0x08 /* 08 */
+#define PORT1_XMT_BUF 0x0C /* 0c */
+#define PORT1_RCV_BUF 0x10 /* 10 */
+#define PORT0_CNTL 0x14 /* 14 */
+#define CNTL 0x18 /* 18 */
+#define CLK_PRESCALER 0x1C /* 1c */
+#define RCV_THRESHOLD 0x20 /* 20 */
+#define ENABLE 0x24 /* 24 */
+#define XMT_STATUS 0x28 /* 28 */
+#define RCV_STATUS 0x2C /* 2c */
+#define INT_MASK 0x30 /* 30 */
+#define PORTO_XMT_BUF 0x34 /* 34 */
+#define PORT0_RCV_BUF 0x38 /* 38 */
+#define PORT0_DETECT 0x3C /* 3c */
+#define DATA_FORMAT 0x40 /* 40 */
+#define XMT_THRESHOLD 0x44 /* 44 */
+#define GUARD_CNTL 0x48 /* 48 */
+#define OD_CONFIG 0x4C /* 4c */
+#define RESET_CNTL 0x50 /* 50 */
+#define CHAR_WAIT 0x54 /* 54 */
+#define GPCNT 0x58 /* 58 */
+#define DIVISOR 0x5C /* 5c */
+#define BWT 0x60 /* 60 */
+#define BGT 0x64 /* 64 */
+#define BWT_H 0x68 /* 68 */
+#define XMT_FIFO_STAT 0x6C /* 6c */
+#define RCV_FIFO_CNT 0x70 /* 70 */
+#define RCV_FIFO_WPTR 0x74 /* 74 */
+#define RCV_FIFO_RPTR 0x78 /* 78 */
+
+/* SIM port[0|1]_cntl register bits */
+#define SIM_PORT_CNTL_SFPD (1<<7)
+#define SIM_PORT_CNTL_3VOLT (1<<6)
+#define SIM_PORT_CNTL_SCSP (1<<5)
+#define SIM_PORT_CNTL_SCEN (1<<4)
+#define SIM_PORT_CNTL_SRST (1<<3)
+#define SIM_PORT_CNTL_STEN (1<<2)
+#define SIM_PORT_CNTL_SVEN (1<<1)
+#define SIM_PORT_CNTL_SAPD (1<<0)
+
+#define MX25_SIM_SETUP_P1_EN (1<<1) // Port 1 enabled
+#define MX25_SIM_SETUP_AMODE_EN (1<<0) // Alternate port enabled
+
+/* SIM od_config register bits */
+#define SIM_OD_CONFIG_OD_P1 (1<<1)
+#define SIM_OD_CONFIG_OD_P0 (1<<0)
+
+/* SIM enable register bits */
+#define SIM_ENABLE_XMTEN (1<<1)
+#define SIM_ENABLE_RCVEN (1<<0)
+
+/* SIM int_mask register bits */
+#define SIM_INT_MASK_RFEM (1<<13)
+#define SIM_INT_MASK_BGTM (1<<12)
+#define SIM_INT_MASK_BWTM (1<<11)
+#define SIM_INT_MASK_RTM (1<<10)
+#define SIM_INT_MASK_CWTM (1<<9)
+#define SIM_INT_MASK_GPCM (1<<8)
+#define SIM_INT_MASK_TDTFM (1<<7)
+#define SIM_INT_MASK_TFOM (1<<6)
+#define SIM_INT_MASK_XTM (1<<5)
+#define SIM_INT_MASK_TFEIM (1<<4)
+#define SIM_INT_MASK_ETCIM (1<<3)
+#define SIM_INT_MASK_OIM (1<<2)
+#define SIM_INT_MASK_TCIM (1<<1)
+#define SIM_INT_MASK_RIM (1<<0)
+
+/* SIM xmt_status register bits */
+#define SIM_XMT_STATUS_GPCNT (1<<8)
+#define SIM_XMT_STATUS_TDTF (1<<7)
+#define SIM_XMT_STATUS_TFO (1<<6)
+#define SIM_XMT_STATUS_TC (1<<5)
+#define SIM_XMT_STATUS_ETC (1<<4)
+#define SIM_XMT_STATUS_TFE (1<<3)
+#define SIM_XMT_STATUS_XTE (1<<0)
+
+/* SIM rcv_status register bits */
+#define SIM_RCV_STATUS_BGT (1<<11)
+#define SIM_RCV_STATUS_BWT (1<<10)
+#define SIM_RCV_STATUS_RTE (1<<9)
+#define SIM_RCV_STATUS_CWT (1<<8)
+#define SIM_RCV_STATUS_CRCOK (1<<7)
+#define SIM_RCV_STATUS_LRCOK (1<<6)
+#define SIM_RCV_STATUS_RDRF (1<<5)
+#define SIM_RCV_STATUS_RFD (1<<4)
+#define SIM_RCV_STATUS_RFE (1<<1)
+#define SIM_RCV_STATUS_OEF (1<<0)
+
+/* SIM cntl register bits */
+#define SIM_CNTL_BWTEN (1<<15)
+#define SIM_CNTL_XMT_CRC_LRC (1<<14)
+#define SIM_CNTL_CRCEN (1<<13)
+#define SIM_CNTL_LRCEN (1<<12)
+#define SIM_CNTL_CWTEN (1<<11)
+#define SIM_CNTL_SAMPLE12 (1<<4)
+#define SIM_CNTL_ONACK (1<<3)
+#define SIM_CNTL_ANACK (1<<2)
+#define SIM_CNTL_ICM (1<<1)
+#define SIM_CNTL_GPCNT_CLK_SEL(x) ((x&0x03)<<9)
+#define SIM_CNTL_GPCNT_CLK_SEL_MASK (0x03<<9)
+#define SIM_CNTL_BAUD_SEL(x) ((x&0x07)<<6)
+#define SIM_CNTL_BAUD_SEL_MASK (0x07<<6)
+
+/* SIM rcv_threshold register bits */
+#define SIM_RCV_THRESHOLD_RTH(x) ((x&0x0f)<<9)
+#define SIM_RCV_THRESHOLD_RTH_MASK (0x0f<<9)
+#define SIM_RCV_THRESHOLD_RDT(x) ((x&0x1ff)<<0)
+#define SIM_RCV_THRESHOLD_RDT_MASK (0x1ff<<0)
+
+/* SIM xmt_threshold register bits */
+#define SIM_XMT_THRESHOLD_XTH(x) ((x&0x0f)<<4)
+#define SIM_XMT_THRESHOLD_XTH_MASK (0x0f<<4)
+#define SIM_XMT_THRESHOLD_TDT(x) ((x&0x0f)<<0)
+#define SIM_XMT_THRESHOLD_TDT_MASK (0x0f<<0)
+
+/* SIM guard_cntl register bits */
+#define SIM_GUARD_CNTL_RCVR11 (1<<8)
+#define SIM_GIARD_CNTL_GETU(x) (x&0xff)
+#define SIM_GIARD_CNTL_GETU_MASK (0xff)
+
+/* SIM port[0|]_detect register bits */
+#define SIM_PORT_DETECT_SPDS (1<<3)
+#define SIM_PORT_DETECT_SPDP (1<<2)
+#define SIM_PORT_DETECT_SDI (1<<1)
+#define SIM_PORT_DETECT_SDIM (1<<0)
+
+/* SIM XMT_FIFO_STAT*/
+#define SIM_XMT_FIFO_XMT_CNT_MASK (0x0f<<8)
+#define SIM_XMT_FIFO_XMT_WPTR_MASK (0x0f<<4)
+#define SIM_XMT_FIFO_XMT_RPTR_MASK (0x0f<<0)
+
+/* SIM PORT_RCV_BUF */
+#define PORT_RCV_BUF_PE (1<<8)
+#define PORT_RCV_BUF_FE (1<<9)
+#define PORT_RCV_BUF_CWT (1<<10)
+/* SIM RESET_CNTL */
+#define SIM_RESET_CNTL_DBUG (1<<6)
+#define SIM_RESET_CNTL_STOP (1<<5)
+#define SIM_RESET_CNTL_DOZE (1<<4)
+#define SIM_RESET_CNTL_KILL_CLOCK (1<<3)
+#define SIM_RESET_CNTL_SOFT_RST (1<<2)
+#define SIM_RESET_CNTL_FLUSH_XMT (1<<1)
+#define SIM_RESET_CNTL_FLUSH_RCV (1<<0)
+/* END of REGS definitions */
+#endif
diff --git a/arch/arm/plat-mxc/sim.c b/arch/arm/plat-mxc/sim.c
new file mode 100644
index 0000000..7af073c
--- /dev/null
+++ b/arch/arm/plat-mxc/sim.c
@@ -0,0 +1,874 @@
+/*
+ * Copyright 2010-2011 FQ Ingenieria Electronica S.A.
+ *
+ * Adapted and simplify this driver to kernel mainline code style using
+ * other drivers from Freescale
+ * Jaume Ribot (jaume at fqingenieria.es)
+ * Iban Cerro Galvez (iban@fqingenieria.es)
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*!
+ * @file mxc_sim.c
+ *
+ * @brief Driver for Freescale IMX SIM interface
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+
+#include <linux/sched.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/clk.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include <mach/mxc_sim.h>
+
+#define DRIVER_NAME "mxc_sim"
+#define SIM1_DEV_NAME "mxc_sim_0"
+#define SIM2_DEV_NAME "mxc_sim_1"
+
+static struct miscdevice sim_dev;
+
+#define sim_debug(fmt, ...) \
+ printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
+
+
+/* Function: sim_clear_ports
+ *
+ * Description: function to unset reset, Vcc_enable or Clk_enable
+ *
+ * Parameters:
+ * sim_t* sim pointer to SIM device handler
+ * uint32_t value value to set port
+ */
+static void sim_clear_ports(sim_t *sim, uint32_t value)
+{
+ uint32_t reg_data;
+ void __iomem *addr;
+
+#if defined(CONFIG_SOC_IMX25)
+ if (cpu_is_mx25()) {
+ addr = sim->ioaddr + PORT0_CNTL;
+ }
+#else
+ if (sim->sim_number ==0)
+ addr = sim->ioaddr + PORT0_CNTL;
+ else
+ addr = sim->ioaddr + PORT1_CNTL;
+#endif
+
+ reg_data = __raw_readl(addr);
+ reg_data &= ~value;
+ __raw_writel(reg_data, addr);
+}
+
+
+/* Function: sim_set_ports
+ *
+ * Description: function to set Reset, Vcc enable or Clk_enabble
+ *
+ * Parameters:
+ * sim_t* sim pointer to SIM device handler
+ * uint32_t value value to set port
+ */
+static void sim_set_ports(sim_t *sim, uint32_t value)
+{
+ uint32_t reg_data;
+ void __iomem *addr;
+
+#if defined(CONFIG_SOC_IMX25)
+ if (cpu_is_mx25()) {
+ addr = sim->ioaddr + PORT0_CNTL;
+ }
+#else
+ if (sim->sim_number ==0)
+ addr = sim->ioaddr + PORT0_CNTL;
+ else
+ addr = sim->ioaddr + PORT1_CNTL;
+#endif
+
+ reg_data = __raw_readl(addr);
+ reg_data |= value;
+ __raw_writel(reg_data, addr);
+
+}
+
+
+/* Function: sim_power_on
+ *
+ * Description: run the power on sequence. Follow sequence explained in
RM 39.5
+ *
+ * Parameters:
+ * sim_t* sim pointer to SIM device handler
+ */
+
+static void sim_power_on(sim_t *sim)
+{
+ uint32_t reg_data;
+
+ // Power on sequence
+ sim_debug("%s Powering on the sim port.\n", __func__);
+
+ // Enable Vcc enable port
+ sim_set_ports(sim, SIM_PORT_CNTL_SVEN);
+ msleep(10);//TODO: adjust this delay
+
+ // Enable CLK enable Port
+ sim_set_ports(sim, SIM_PORT_CNTL_SCEN);
+ msleep(10);//TODO: adjust this delay
+
+ // Configure RCV parameters
+ reg_data = SIM_RCV_THRESHOLD_RTH(0) | SIM_RCV_THRESHOLD_RDT(1);
+ __raw_writel(reg_data, sim->ioaddr + RCV_THRESHOLD);
+ __raw_writel(SIM_RCV_STATUS_RDRF, sim->ioaddr + RCV_STATUS);
+
+ //Configure int
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data &= ~SIM_INT_MASK_RIM;
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+
+ //Duplicate in function sim_start
+ __raw_writel(31, sim->ioaddr + DIVISOR);
+ reg_data = __raw_readl(sim->ioaddr + CNTL);
+ reg_data |= SIM_CNTL_SAMPLE12;
+ __raw_writel(reg_data, sim->ioaddr + CNTL);
+
+ // Enable RCV
+ reg_data = __raw_readl(sim->ioaddr + ENABLE);
+ reg_data |= SIM_ENABLE_RCVEN;
+ __raw_writel(reg_data, sim->ioaddr + ENABLE);
+
+ // Enable RST
+ sim_set_ports(sim, SIM_PORT_CNTL_SRST);
+ msleep(10);//TODO: adjust this delay
+
+ sim->power = SIM_POWER_ON;
+
+};
+
+/* Function: sim_power_off
+ *
+ * Description: run the power off sequence
+ *
+ * Parameters:
+ * sim_t* sim pointer to SIM device handler
+ */
+
+static void sim_power_off(sim_t *sim)
+{
+ uint32_t reg_data;
+
+ sim_debug("%s entering.\n", __func__);
+ /* sim_power_off sequence */
+
+ //disable clk
+ sim_clear_ports(sim, SIM_PORT_CNTL_SCEN);
+
+ reg_data = __raw_readl(sim->ioaddr + ENABLE);
+ reg_data &= ~SIM_ENABLE_RCVEN;
+ __raw_writel(reg_data, sim->ioaddr + ENABLE);
+
+ reg_data = __raw_readl(sim->ioaddr + INT_MASK);
+ reg_data |= SIM_INT_MASK_RIM;
+ __raw_writel(reg_data, sim->ioaddr + INT_MASK);
+
+ __raw_writel(0, sim->ioaddr + RCV_THRESHOLD);
+
+ //Disable RST
+ sim_clear_ports(sim, SIM_PORT_CNTL_SRST);
+ //Disable Vcc enable port
+ sim_clear_ports(sim, SIM_PORT_CNTL_SVEN);
+
+ sim->power = SIM_POWER_OFF;
+};
+
+/* Function: sim_set_clk_sim
+ *
+ * Description: Set CLK SIM frequency
+ *
+ * Parameters:
+ * sim_t* sim pointer to SIM device handler
+ */
+uint32_t sim_set_clk_sim(sim_t *sim)
+{
+ uint32_t clk_rate, clk_div = 0;
+ // get ipg_clk
+ clk_rate = clk_get_rate(sim->clk);
+ // calcule divisor
+ clk_div = clk_rate / sim->clk_sim;
+ if (clk_rate % sim->clk_sim)
+ clk_div++;
+ //write divisor
+ __raw_writel(clk_div, sim->ioaddr + CLK_PRESCALER);
+ //calculate real Value
+ clk_rate =clk_rate/clk_div;
+
+ sim_debug("%s prescaler is 0x%x.\n", __func__, clk_div);
+ sim_debug("Clk = %d Hz\n", clk_rate);
+
+ return clk_rate;
+}
+
+/* Function: sim_set_clk_uart_divisor
+ *
+ * Description: Set SIM Uart divisor frequency
+ *
+ * Parameters:
+ * sim_t* sim pointer to SIM device handler
+ */
+int sim_set_clk_uart_divisor(sim_t *sim)
+{
+ uint32_t reg, divisor;
+
+ //ajust baud_sel -> divisor register
+ reg = __raw_readl(sim->ioaddr + CNTL);
+ //ajust sample 12
+ if ((sim->uart_div % 12) == 0)
+ {
+ reg |= SIM_CNTL_SAMPLE12;
+ divisor=sim->uart_div/12;
+ }
+ else if ((sim->uart_div % 8) == 0)
+ {
+ reg &= ~SIM_CNTL_SAMPLE12;
+ divisor=sim->uart_div/8;
+ }
+ else
+ {
+ sim_debug("%s no valid divisor \n", __func__);
+ return -1;
+ }
+ // put 111 in baud_sel for use Divisor register
+ reg |= SIM_CNTL_BAUD_SEL(7);
+ __raw_writel(reg, sim->ioaddr + CNTL);
+ //ajust Divisor register
+ __raw_writel(divisor, sim->ioaddr + DIVISOR );
+ sim_debug("%s divisor is %d.\n", __func__, sim->uart_div);
+
+ return 0;
+}
+
+
+
+/* Function: sim_start
+ *
+ * Description: ramp up the SIM interface.
+ *
+ * Parameters:
+ * sim_t* sim pointer to SIM device handler
+ */
+static void sim_start(sim_t *sim)
+{
+ uint32_t reg_data = 0;
+
+ sim_debug("%s entering.\n", __func__);
+ // Configuring SIM for Operation
+ // Adjust XMT thresholds (no NACK and 4 bytes or less to activate TDTF bit
+ reg_data = SIM_XMT_THRESHOLD_XTH(0) | SIM_XMT_THRESHOLD_TDT(4);
+ __raw_writel(reg_data, sim->ioaddr + XMT_THRESHOLD);
+ // Enable SIM port N and alternate port disabled -> Only applies to MX51
+ // Always eanble port 0,
+
+ // Always enable port 0 -> Duplicated SIM core
+ __raw_writel(0x00, sim->ioaddr + SETUP);
+
+ // Adjust clock divider in function of platform definitions
+ // 66.5 / 5 -> 13.5 -> 14 (4.75MHZ initial frequency)
+ sim->clk_sim = sim->plat_data->clk_rate;
+ sim_set_clk_sim(sim);
+
+ // Adjust Control register
+ reg_data = __raw_readl(sim->ioaddr + CNTL);
+ reg_data |= SIM_CNTL_ANACK | SIM_CNTL_ICM;
+ __raw_writel(reg_data, sim->ioaddr + CNTL);
+
+ // Adjust BAUD divider
+ sim->uart_div=SIM_DEFAULT_BAUD_DIV;
+ sim_set_clk_uart_divisor(sim);
+
+ // Adjust Open Drain in Port 0 XMT configuration register
+ reg_data = __raw_readl(sim->ioaddr + OD_CONFIG);
+ reg_data |= SIM_OD_CONFIG_OD_P0 | SIM_OD_CONFIG_OD_P1;
+ __raw_writel(reg_data, sim->ioaddr + OD_CONFIG);
+
+ // Adjust Port 0
+ reg_data = __raw_readl(sim->ioaddr + PORT0_CNTL);
+ reg_data |= SIM_PORT_CNTL_3VOLT | SIM_PORT_CNTL_STEN;
+ __raw_writel(reg_data, sim->ioaddr + PORT0_CNTL);
+
+ // Since there is no PD0 layout on MX51, assume that there is a SIM card
in slot defaulty.
+ if (0 == (sim->plat_data->detect)) {
+ reg_data = __raw_readl(sim->ioaddr + PORT0_DETECT);
+ reg_data |= SIM_PORT_DETECT_SPDS;
+ __raw_writel(reg_data, sim->ioaddr + PORT0_DETECT);
+ sim->present = SIM_PRESENT_DETECTED;
+ }
+
+ // FQ enable SIM present on the future
+ if (sim->present == SIM_PRESENT_DETECTED)
+ sim_power_on(sim);
+
+};
+
+/* Function: sim_stop
+ *
+ * Description: shut down the SIM interface
+ *
+ * Parameters:
+ * sim_t* sim pointer to SIM device handler
+ */
+
+static void sim_stop(sim_t *sim)
+{
+ sim_debug("%s entering.\n", __func__);
+ __raw_writel(0, sim->ioaddr + SETUP);
+ __raw_writel(0, sim->ioaddr + ENABLE);
+ __raw_writel(0, sim->ioaddr + PORT0_CNTL);
+ __raw_writel(SIM_CNTL_ANACK | SIM_CNTL_ICM, sim->ioaddr + CNTL);
+ __raw_writel(0, sim->ioaddr + CLK_PRESCALER);
+ __raw_writel(0, sim->ioaddr + SETUP);
+ __raw_writel(0, sim->ioaddr + OD_CONFIG);
+ __raw_writel(0, sim->ioaddr + XMT_THRESHOLD);
+ //Clear XMT_STATUS
+ __raw_writel( SIM_XMT_STATUS_TDTF | SIM_XMT_STATUS_TC |
+ SIM_XMT_STATUS_ETC | SIM_XMT_STATUS_TFE , sim->ioaddr +
XMT_STATUS);
+ //Enable SOFT_RESET
+ __raw_writel(SIM_RESET_CNTL_SOFT_RST , sim->ioaddr + RESET_CNTL);
+ mdelay(1);//TODO: adjust this delay
+};
+
+/* Function: sim_data_reset
+ *
+ * Description: reset a SIM structure to default values
+ *
+ * Parameters:
+ * sim_t* sim pointer to SIM device handler
+ */
+
+static void sim_data_reset(sim_t *sim)
+{
+ sim->present = SIM_PRESENT_REMOVED;
+ sim->state = SIM_STATE_REMOVED;
+ sim->power = SIM_POWER_OFF;
+ sim->errval = SIM_OK;
+};
+
+/* Function: sim_cold_reset
+ *
+ * Description: cold reset the SIM interface, including card
+ * power down and interface hardware reset.
+ *
+ * Parameters:
+ * sim_t* sim pointer to SIM device handler
+ */
+
+static void sim_cold_reset(sim_t *sim)
+{
+ sim_debug("%s entering.\n", __func__);
+ if (sim->present != SIM_PRESENT_REMOVED) {
+ sim_power_off(sim);
+ sim_stop(sim);
+ sim_data_reset(sim);
+ sim->state = SIM_STATE_DETECTED_ATR_T0;
+ sim->present = SIM_PRESENT_DETECTED;
+ msleep(50);//TODO: adjust this delay
+ sim_start(sim);
+ sim_power_on(sim);
+ };
+};
+
+/* Function: sim_warm_reset
+ *
+ * Description: warm reset the SIM interface: just invoke the
+ * reset signal and reset the SIM structure for the interface.
+ *
+ * Parameters:
+ * sim_t* sim pointer to SIM device handler
+ */
+
+static void sim_warm_reset(sim_t *sim)
+{
+ sim_debug("%s entering.\n", __func__);
+ if (sim->present != SIM_PRESENT_REMOVED) {
+ sim_set_ports(sim,SIM_PORT_CNTL_SRST);
+ sim_data_reset(sim);
+ msleep(50);//TODO: adjust this delay
+ sim_clear_ports(sim,SIM_PORT_CNTL_SRST);
+
+ };
+};
+
+/* Function: sim_ioctl
+ *
+ * Description: handle ioctl calls
+ *
+ * Parameters: OS specific
+ */
+
+static long sim_ioctl(struct file *file, unsigned int cmd, unsigned long
arg)
+{
+ int ret=0, value=-1;
+ unsigned long real_freq;
+ unsigned char version = SIM_DRIVER_VERSION;
+ sim_t *sim = (sim_t *) file->private_data;
+ sim_reg s_reg = {0,0};
+
+ sim_debug("%s cmd %d \n", __func__, cmd);
+ switch (cmd) {
+ sim_debug("ioctl cmd %d is issued...\n", cmd);
+
+ case SIM_IOCTL_VERSION:
+ sim_debug("ioctl cmd SIM_IOCTL_VERSION\n");
+ ret = copy_to_user((unsigned char *) arg, &version,
+ sizeof(unsigned char));
+ break;
+
+ case SIM_IOCTL_POWER_ON:
+ sim_debug("ioctl cmd SIM_IOCTL_POWER_ON\n");
+ if (sim->power == SIM_POWER_ON) {
+ ret = -SIM_E_POWERED_ON;
+ break;
+ };
+ sim_power_on(sim);
+ break;
+
+ case SIM_IOCTL_POWER_OFF:
+ sim_debug("ioctl cmd SIM_IOCTL_POWER_OFF\n");
+ if (sim->power == SIM_POWER_OFF) {
+ ret = -SIM_E_POWERED_OFF;
+ break;
+ };
+ sim_power_off(sim);
+ break;
+
+ case SIM_IOCTL_COLD_RESET:
+ sim_debug("ioctl cmd SIM_IOCTL_COLD_RESET\n");
+ if (sim->power == SIM_POWER_OFF) {
+ ret = -SIM_E_POWERED_OFF;
+ break;
+ };
+ sim_cold_reset(sim);
+ break;
+
+ case SIM_IOCTL_WARM_RESET:
+ sim_debug("ioctl cmd SIM_IOCTL_WARM_RESET\n");
+ sim_warm_reset(sim);
+ if (sim->power == SIM_POWER_OFF) {
+ ret = -SIM_E_POWERED_OFF;
+ break;
+ };
+ break;
+
+ case SIM_IOCTL_CLK_PORT:
+ sim_debug("ioctl cmd SIM_IOCTL_CLK_PORT\n");
+ ret = copy_from_user(&value, (int *) arg,
+ sizeof(int));
+ if (value == 0)
+ sim_set_ports(sim, SIM_PORT_CNTL_SCEN);
+ else
+ sim_clear_ports(sim, SIM_PORT_CNTL_SCEN);
+ break;
+
+ case SIM_IOCTL_RST_PORT:
+ sim_debug("ioctl cmd SIM_IOCTL_RST_PORT\n");
+ ret = copy_from_user(&value, (int *) arg,
+ sizeof(int));
+ if (value == 0)
+ sim_set_ports(sim, SIM_PORT_CNTL_SRST);
+ else
+ sim_clear_ports(sim, SIM_PORT_CNTL_SRST);
+ break;
+
+ case SIM_IOCTL_VCC_PORT:
+ sim_debug("ioctl cmd SIM_IOCTL_VCC_PORT\n");
+ ret = copy_from_user(&value, (int *) arg,
+ sizeof(int));
+ if (value == 0)
+ sim_set_ports(sim, SIM_PORT_CNTL_SVEN);
+ else
+ sim_clear_ports(sim, SIM_PORT_CNTL_SVEN);
+ break;
+
+ case SIM_IOCTL_SET_CLK_SIM:
+ sim_debug("ioctl cmd SIM_IOCTL_SET_CLK_SIM\n");
+ ret = copy_from_user(&real_freq, (unsigned long *) arg,
+ sizeof(unsigned long));
+ if (sim->clk_sim > 0)
+ {
+ sim->clk_sim = real_freq;
+ real_freq = sim_set_clk_sim(sim);
+ }
+ else
+ {
+ sim_debug("Invalid Freq. %lu Hz\n",real_freq );
+ real_freq = -1;
+ }
+ ret = copy_to_user((unsigned long *) arg, &real_freq,
+ sizeof(unsigned long));
+ break;
+
+ case SIM_IOCTL_SET_CLK_DIV:
+ sim_debug("ioctl cmd SIM_IOCTL_SET_CLK_DIV\n");
+ ret = copy_from_user(&value, (int *) arg,
+ sizeof(int));
+ if (sim->uart_div > 0)
+ {
+ sim->uart_div = value;
+ ret = sim_set_clk_uart_divisor(sim);
+ }
+ else
+ {
+ sim_debug("Invalid DIV. %d\n",value);
+ }
+ break;
+
+ /*debug register*/
+ case SIM_IOCTL_GET_REG:
+ sim_debug("ioctl cmd SIM_IOCTL_GET_REG\n");
+ ret = copy_from_user(&s_reg, (sim_reg *) arg, sizeof(sim_reg));
+ s_reg.data =(unsigned long) __raw_readl(s_reg.addr);
+ ret = copy_to_user((sim_reg *) arg, &s_reg, sizeof(sim_reg));
+ break;
+
+ case SIM_IOCTL_SET_REG:
+ sim_debug("ioctl cmd SIM_IOCTL_SET_REG\n");
+ ret = copy_from_user(&s_reg, (sim_reg *) arg, sizeof(sim_reg));
+ __raw_writel( (uint32_t) s_reg.data, sim->ioaddr + s_reg.addr);
+ break;
+ };
+
+ return ret;
+};
+
+/* Function: sim_write
+ *
+ * Description: handle write calls
+ *
+ * Parameters: OS specific
+ */
+static ssize_t sim_write(struct file *file, const char *user_buf,
+ size_t count, loff_t *ppos)
+{
+ int ret=0, i;
+ uint32_t reg_data=0;
+ sim_t *sim = (sim_t *) file->private_data;
+ char write_buffer[SIM_XMT_BUFFER_SIZE];
+ int timeout;
+
+ sim_debug("%s entering.\n", __func__);
+
+ ret = copy_from_user(write_buffer, user_buf,count);
+ if (ret)
+ return -EFAULT;
+
+ //start XMT
+ reg_data = __raw_readl(sim->ioaddr + ENABLE);
+ reg_data |= SIM_ENABLE_XMTEN;
+ __raw_writel(reg_data, sim->ioaddr + ENABLE);
+
+ for (i=0; i < count; i++)
+ {
+ //transmit 1 Byte
+ __raw_writel( write_buffer[i],sim->ioaddr + PORT1_XMT_BUF );
+ sim_debug( "TX = %02x\n", write_buffer[i] );
+
+ // wait write 1 Byte TODO: interupts
+ timeout= WRITE_TIMEOUT;
+ do {
+ reg_data = __raw_readl( sim->ioaddr + XMT_FIFO_STAT );
+ reg_data = ( reg_data && SIM_XMT_FIFO_XMT_CNT_MASK ) >> 8;
+ sim_debug("wait write, timeout = %d", timeout );
+ timeout--;
+ }while ( reg_data > 0 && timeout != 0 );
+ }
+
+ //disable write
+ reg_data = __raw_readl( sim->ioaddr + ENABLE );
+ reg_data &= ~SIM_ENABLE_XMTEN;
+ __raw_writel( reg_data, sim->ioaddr + ENABLE );
+
+ return i;
+};
+
+/* Function: sim_read
+ *
+ * Description: handle read calls
+ *
+ * Parameters: OS specific
+ */
+static ssize_t sim_read(struct file *file, char *user_buf,
+ size_t count, loff_t *ppos)
+{
+ int ret=0;
+ char read_buffer[SIM_RCV_BUFFER_SIZE];
+ sim_t *sim = (sim_t *) file->private_data;
+ int i=0;
+ int timeout = READ_TIMEOUT;
+
+ sim_debug("%s entering.\n", __func__);
+
+ while (__raw_readl(sim->ioaddr + RCV_FIFO_CNT) != 0 && i < count &&
timeout > 0 ) {
+ uint32_t data;
+ data = __raw_readl(sim->ioaddr + PORT1_RCV_BUF);
+ sim_debug("RX = %02x\n", data);
+ //detect parity ERROR or FRAME ERROR or CWT ERROR
+ if ( data & (PORT_RCV_BUF_PE | PORT_RCV_BUF_FE | PORT_RCV_BUF_CWT ) )
+ {
+ printk(KERN_ERR "ERROR READ !\n");
+ return IRQ_HANDLED;
+ }
+ else{
+ read_buffer[i] = (char) data;
+ i++;
+ }
+ timeout--;
+ };
+ ret = copy_to_user(user_buf, read_buffer,i);
+ if (ret)
+ return -EFAULT;
+
+ return i;
+}
+
+
+/* Function: sim_open
+ *
+ * Description: ramp up interface when being opened
+ *
+ * Parameters: OS specific
+ */
+
+static int sim_open(struct inode *inode, struct file *file)
+{
+ int errval = SIM_OK;
+
+ sim_t *sim = dev_get_drvdata(sim_dev.parent);
+ file->private_data = sim;
+
+ sim_debug("%s entering.\n", __func__);
+ if (!sim->ioaddr) {
+ errval = -ENOMEM;
+ return errval;
+ }
+
+ if (!(sim->clk_flag)) {
+ sim_debug("\n%s enable the clock ret = %d\n", __func__,
clk_enable(sim->clk) );
+ sim->clk_flag = 1;
+ }
+
+ sim_start(sim);
+
+ return errval;
+};
+/* Function: sim_fasync
+ *
+ * Description: async handler
+ *
+ * Parameters: OS specific
+ */
+
+static int sim_fasync(int fd, struct file *file, int mode)
+{
+ sim_t *sim = (sim_t *) file->private_data;
+ pr_debug("%s entering.\n", __func__);
+ return fasync_helper(fd, file, mode, &sim->fasync);
+}
+/* Function: sim_release
+ *
+ * Description: shut down interface when being closed
+ *
+ * Parameters: OS specific
+ */
+
+static int sim_release(struct inode *inode, struct file *file)
+{
+ uint32_t reg_data;
+
+ sim_t *sim = (sim_t *) file->private_data;
+
+ sim_debug("%s entering.\n", __func__);
+ if (sim->clk_flag) {
+ sim_debug("\n%s disable the clock\n", __func__);
+ clk_disable(sim->clk);
+ sim->clk_flag = 0;
+ }
+
+ /* disable presense detection */
+ reg_data = __raw_readl(sim->ioaddr + PORT0_DETECT);
+ __raw_writel(reg_data | SIM_PORT_DETECT_SDIM, sim->ioaddr + PORT0_DETECT);
+
+ if (sim->present != SIM_PRESENT_REMOVED) {
+ sim_power_off(sim);
+ if (sim->fasync)
+ kill_fasync(&sim->fasync, SIGIO, POLL_IN);
+ };
+
+ sim_stop(sim);
+
+ sim_fasync(-1, file, 0);
+
+ sim_debug("exit\n");
+ return 0;
+};
+
+static const struct file_operations sim_fops = {
+ .owner = THIS_MODULE,
+ .read = sim_read,
+ .write = sim_write,
+ .open = sim_open,
+ .unlocked_ioctl = sim_ioctl,
+ .fasync = sim_fasync, // FQ commented
+ .release = sim_release
+};
+
+// TODO -> Dev name must be dynamic or include all SIM ports
+/*
+static struct miscdevice sim_dev = {
+ MISC_DYNAMIC_MINOR,
+ NULL,
+ &sim_fops,
+};
+*/
+
+/*****************************************************************************\
+ *
*
+ * Driver init/exit
*
+ *
*
+\*****************************************************************************/
+
+static int sim_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct mxc_sim_platform_data *sim_plat = pdev->dev.platform_data;
+
+ sim_t *sim = kzalloc(sizeof(sim_t), GFP_KERNEL);
+
+ if (sim == 0) {
+ ret = -ENOMEM;
+ printk(KERN_ERR "Can't get the MEMORY\n");
+ return ret;
+ };
+
+ BUG_ON(pdev == NULL);
+
+ sim->plat_data = sim_plat;
+ sim->clk_flag = 0;
+ sim->sim_number = sim->plat_data->sim_number;
+
+ printk(KERN_INFO "Trying initialize port %d...\n", sim->sim_number);
+
+ sim->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!sim->res) {
+ ret = -ENOMEM;
+ printk(KERN_ERR "Can't get the MEMORY\n");
+ goto out;
+ }
+
+ // request the sim clk and sim_serial_clk
+ sim_debug("CLK rate:%d\n", sim->plat_data->clk_rate);
+ sim->clk = clk_get_sys(sim->plat_data->clock_sim, NULL);
+ if (IS_ERR(sim->clk)) {
+ ret = PTR_ERR(sim->clk);
+ printk(KERN_ERR "Get CLK ERROR !\n");
+ goto out;
+ }
+ sim_debug("sim clock:%lu\n", clk_get_rate(sim->clk));
+
+ if (!request_mem_region(sim->res->start,
+ sim->res->end -
+ sim->res->start + 1, pdev->name)) {
+ printk(KERN_ERR "request_mem_region failed\n");
+ ret = -ENOMEM;
+ goto out1;
+ }
+
+ sim->ioaddr = (void *)ioremap(sim->res->start, sim->res->end -
+ sim->res->start + 1);
+
+ platform_set_drvdata(pdev, sim);
+ sim_dev.minor = MISC_DYNAMIC_MINOR;
+ if (sim->sim_number == 0)
+ sim_dev.name = SIM1_DEV_NAME;
+ else if (sim->sim_number == 1)
+ sim_dev.name = SIM2_DEV_NAME;
+ sim_dev.fops = &sim_fops,
+ sim_dev.parent = &(pdev->dev);
+
+ misc_register(&sim_dev);
+
+ return ret;
+
+out1:
+ clk_put(sim->clk);
+out:
+ kfree(sim);
+ return ret;
+}
+
+static int sim_remove(struct platform_device *pdev)
+{
+ sim_t *sim = platform_get_drvdata(pdev);
+
+ clk_put(sim->clk);
+
+ if (sim->ipb_irq)
+ free_irq(sim->ipb_irq, sim);
+ if (sim->dat_irq)
+ free_irq(sim->dat_irq, sim);
+
+ iounmap(sim->ioaddr);
+
+ kfree(sim);
+ release_mem_region(sim->res->start,
+ sim->res->end - sim->res->start + 1);
+
+
+ misc_deregister(&sim_dev);
+ return 0;
+}
+
+static struct platform_driver sim_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = sim_probe,
+ .remove = sim_remove,
+ .suspend = NULL,
+ .resume = NULL,
+};
+
+static int __init sim_drv_init(void)
+{
+ printk(KERN_INFO "IMX : SIM driver\n");
+
+ return platform_driver_register(&sim_driver);
+}
+
+static void __exit sim_drv_exit(void)
+{
+ platform_driver_unregister(&sim_driver);
+}
+
+module_init(sim_drv_init);
+module_exit(sim_drv_exit);
+
+MODULE_AUTHOR("FQ Ingenieria Electronica S.A.");
+MODULE_DESCRIPTION("MXC SIM Driver");
+MODULE_LICENSE("GPL");
--
1.5.4.3
^ permalink raw reply related
* [PATCH 01/04] ARM i.MX25 Add SIM clock support
From: FQ | Iban Cerro @ 2011-01-03 8:59 UTC (permalink / raw)
To: linux-arm-kernel
Adds SIM clock support
Signed-off-by: Iban Cerro Galvez <iban@fqingenieria.es>
---
arch/arm/mach-imx/clock-imx25.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-imx/clock-imx25.c
b/arch/arm/mach-imx/clock-imx25.c
index 21ef34c..f302fab 100644
--- a/arch/arm/mach-imx/clock-imx25.c
+++ b/arch/arm/mach-imx/clock-imx25.c
@@ -154,6 +154,16 @@ static unsigned long get_rate_csi(struct clk *clk)
return get_rate_per(0);
}
+static unsigned long get_rate_sim1(struct clk *clk)
+{
+ return get_rate_per(11);
+}
+
+static unsigned long get_rate_sim2(struct clk *clk)
+{
+ return get_rate_per(12);
+}
+
static unsigned long get_rate_otg(struct clk *clk)
{
unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
@@ -226,6 +236,8 @@ DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7,
get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1, NULL,
NULL);
DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, get_rate_esdhc1, NULL,
&esdhc1_ahb_clk);
+DEFINE_CLOCK(sim1_per_clk, 0, CCM_CGCR0, 11, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(sim2_per_clk, 0, CCM_CGCR0, 12, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2, NULL,
NULL);
DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0, 4, get_rate_esdhc2, NULL,
&esdhc2_ahb_clk);
@@ -262,6 +274,8 @@ DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL,
NULL);
DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL,
&csi_per_clk);
DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(can2_clk, 1, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(sim1_clk, 0, CCM_CGCR2, 7, get_rate_sim1, NULL,
&sim1_per_clk);
+DEFINE_CLOCK(sim2_clk, 0, CCM_CGCR2, 8, get_rate_sim2, NULL,
&sim2_per_clk);
#define _REGISTER_CLOCK(d, n, c) \
{ \
@@ -305,6 +319,8 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
_REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
_REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
+ _REGISTER_CLOCK("mxc-sim.0", NULL, sim1_clk)
+ _REGISTER_CLOCK("mxc-sim.1", NULL, sim2_clk)
};
int __init mx25_clocks_init(void)
--
1.5.4.3
^ permalink raw reply related
* [PATCH 00/04] ARM i.MX25 Add SIM driver support
From: FQ | Iban Cerro @ 2011-01-03 8:56 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
The following series adds support for the Freescale i.MX SIM Module. These
patches has been probed working on MX25 based platform (3DSPDK). Maybe it
can be extended to MX51 platforms with some additional modifications.
These patches has been applied against:
git://git.pengutronix.de/git/imx/linux-2.6.git
branch: imx-for-2.6.38
commit: 28a4f908acb342350b9ecbfcdf0a999cb83e05aa
Any comments/reviews are welcome
Iban Cerro
^ permalink raw reply
* SRAM performance optimization (PXA270)
From: Harald Krammer @ 2011-01-03 8:31 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
I am currently running a PXA270 520MHz system with a 104 MHz DRAM. Now I
need to optimize my system. The analysis showed me (with the help of
valgrind, gettimeofday, size,...) that a poor cache hit rate is present.
So I came to the conclusion that the SRAM will help me, because it is
clocked with 208 MHz.
Now the question: how?
My first test was to map few data of my application into the SRAM via
the mmap system call and so I got a performance boost of ~4%. I know
from my tests that the code-cache hit rate is poor too, so the code
should be placed into the SRAM. How I can do that?
My current idea is to write a so-library with code and load it into the
SRAM. The effort looks a little bit complex and the disadvantages are
debugging and core file analysis (gdb needs also patches). So in case
of any problems in the code it will be hard to find it.
BTW, -fPIC code (position-independent code) costs around 3 % performance
in my case. I have never thought about that, but it is logical.
Exists better solution?
e.g. fixed map-address with modified loader ?, or exists a kernel patch
to locate few parts of the kernel into SRAM?
Thanks for any ideas or comments
Nice greetings
Harald
--
Harald Krammer
Mobil +43.(0) 664. 130 59 58
Mail: Harald.Krammer (at) hkr.at
^ permalink raw reply
* [PATCH v2] davinci: Support various speedgrades for MityDSP-L138 and MityARM-1808 SoMs
From: Nori, Sekhar @ 2011-01-03 6:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1293720222-27299-1-git-send-email-michael.williamson@criticallink.com>
On Thu, Dec 30, 2010 at 20:13:42, Michael Williamson wrote:
> For the MityDSP-L138/MityARM-1808 SoMs, the speed grade can be determined
> from the part number string read from the factory configuration block on
> the on-board I2C PROM. Configure the maximum CPU speed based on this
> information.
>
> This patch was tested using a MityDSP-L138 at various speedgrades. Also,
> for code coverage, a bogus configuration was tested as well as a
> configuration having an unknown part number.
>
> Signed-off-by: Michael Williamson <michael.williamson@criticallink.com>
> Tested-by: Michael Williamson <michael.williamson@criticallink.com>
> ---
> static void read_factory_config(struct memory_accessor *a, void *context)
> {
> int ret;
> @@ -53,29 +117,37 @@ static void read_factory_config(struct memory_accessor *a, void *context)
> if (ret != sizeof(struct factory_config)) {
> pr_warning("MityOMAPL138: Read Factory Config Failed: %d\n",
> ret);
> - return;
> + goto bad_config;
> }
>
> if (factory_config.magic != FACTORY_CONFIG_MAGIC) {
> pr_warning("MityOMAPL138: Factory Config Magic Wrong (%X)\n",
> factory_config.magic);
> - return;
> + goto bad_config;
> }
>
> if (factory_config.version != FACTORY_CONFIG_VERSION) {
> pr_warning("MityOMAPL138: Factory Config Version Wrong (%X)\n",
> factory_config.version);
> - return;
> + goto bad_config;
> }
>
> pr_info("MityOMAPL138: Found MAC = %pM\n", factory_config.mac);
> - pr_info("MityOMAPL138: Part Number = %s\n", factory_config.partnum);
> if (is_valid_ether_addr(factory_config.mac))
> memcpy(soc_info->emac_pdata->mac_addr,
> factory_config.mac, ETH_ALEN);
> else
> pr_warning("MityOMAPL138: Invalid MAC found "
> "in factory config block\n");
> +
> + pr_info("MityOMAPL138: Part Number = %s\n", factory_config.partnum);
> + mityomapl138_cpufreq_init(factory_config.partnum);
> +
> + return;
> +
> +bad_config:
> + /* default maximum speed is valid for all platforms */
> + mityomapl138_cpufreq_init(NULL);
There should be no need to make multiple calls to mityomapl138_cpufreq_init()
Just use a variable "partnum" initialized to null which gets set to actual
partnumber only if the entire parsing suceeds. mityomapl138_cpufreq_init()
is always called with partnum as argument.
Thanks,
Sekhar
^ permalink raw reply
* [PATCH v4] davinci: Add additional JTAG code for AM-1808 and OMAP-L138 Rev 2.0 SoCs
From: Nori, Sekhar @ 2011-01-03 6:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1293720166-27261-1-git-send-email-michael.williamson@criticallink.com>
On Thu, Dec 30, 2010 at 20:12:46, Michael Williamson wrote:
> From: Sudhakar Rajashekhara <sudhakar.raj@ti.com>
>
> The JTAG variant code for Rev-2.0 silicon of the OMAP-L138 has changed.
> In addition, the variant code for the AM-1808 SoC appears to match
> the Rev-2.0 code for the OMAP-L138. Add an additional entry to support
> these chips.
>
> This patch is originally from a patch on the arago project, here:
> http://arago-project.org/git/projects/?p=linux-omapl1.git;a=commit;h=6157618435e313a444cdf059702bd34036a6e2b7
>
> Further information related to the need for this patch can be located at
> http://e2e.ti.com/support/embedded/f/354/p/67290/248486.aspx
> http://linux.davincidsp.com/pipermail/davinci-linux-open-source/2010-November/021224.html
>
> This patch was tested using an AM-1808 SoC on a MityARM-1808 SoM card. It
> was also tested using a Rev 1.0 silicon OMAP-L138 on a MityDSP-L138F card.
>
> Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com>
> Signed-off-by: Michael Williamson <michael.williamson@criticallink.com>
> Tested-by: Michael Williamson <michael.williamson@criticallink.com>
> Reported-by: Nicolas Luna <luna.id@gmail.com>
> ---
> Built against commit b411b51a71cd9c926712b33ab21d001ed7e57838 off Kevin's
> davinci-linux tree.
>
> Changes since v3:
> - change am18xx to am18x
> - add am18x tag to 0 variant per comments.
>
> arch/arm/mach-davinci/da850.c | 9 ++++++++-
> 1 files changed, 8 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
> index 78b5ae2..e489f67 100644
> --- a/arch/arm/mach-davinci/da850.c
> +++ b/arch/arm/mach-davinci/da850.c
> @@ -762,7 +762,14 @@ static struct davinci_id da850_ids[] = {
> .part_no = 0xb7d1,
> .manufacturer = 0x017, /* 0x02f >> 1 */
> .cpu_id = DAVINCI_CPU_ID_DA850,
> - .name = "da850/omap-l138",
> + .name = "da850/omap-l138/am18x",
This should be a separate patch. Can you please drop this
change from this patch.
Thanks,
Sekhar
> + },
> + {
> + .variant = 0x1,
> + .part_no = 0xb7d1,
> + .manufacturer = 0x017, /* 0x02f >> 1 */
> + .cpu_id = DAVINCI_CPU_ID_DA850,
> + .name = "da850/omap-l138/am18x",
> },
> };
>
> --
> 1.7.0.4
>
> _______________________________________________
> Davinci-linux-open-source mailing list
> Davinci-linux-open-source at linux.davincidsp.com
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
>
^ permalink raw reply
* [PATCH 1/2] davinci: Support disabling modem status interrupts on SOC UARTS
From: Nori, Sekhar @ 2011-01-03 6:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1293844317-11757-1-git-send-email-michael.williamson@criticallink.com>
Hi Michael,
On Sat, Jan 01, 2011 at 06:41:56, Michael Williamson wrote:
> On the da850/omap-l138/am18x family of SoCs, up to three on chip UARTS may be
> configured. These peripherals support the standard Tx/Rx signals as well as
> CTS/RTS hardware flow control signals. The pins on these SOC's associated with
> these signals are multiplexed; e.g., the pin providing UART0_TXD capability
> also provides SPI0 chip select line 5 output capability. The configuration of
> the pin multiplexing occurs during platform initialization (or by earlier
> bootloader operations).
>
> There is a problem with the multiplexing implementation on these SOCs. Only
> the output and output enable portions of the I/O section of the pin are
> multiplexed. All peripheral input functions remain connected to a given pin
> regardless of configuration.
>
> In many configurations of these parts, providing a UART with Tx/Rx capability
> is needed, but the HW flow control capability is not. Furthermore, the pins
> associated with the CTS inputs on these UARTS are often configured to support
> a different peripheral, and they may be active/toggling during runtime. This
> can result in false modem status (CTS) interrupts being asserted to the 8250
> driver controlling the associated Tx/Rx pins, and can impact system
> performance. This is especially true if the CTS pin is shared with something
> like a clock line as is the case with UART1 CTS and the McASP AHCLKX.
>
> The 8250 serial driver platform data does not provide a direct mechanism to
> tell the driver to disable modem status (i.e., CTS) interrupts for a given
> port. As a work-around, allow davinci platforms to override set_termios for
> configured UARTS that do not provide a true CTS input and ensure any request
> does not enable HW flow control.
>
> This patch was tested using a MityDSP-L138 SOM having UART1 enabled with the
> associated CTS pin connected to a clock (configured for the AHCLKX function).
>
> Background / problem reports related to this issue are captured in the links
> below:
> http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/36701.aspx
> http://www.mail-archive.com/davinci-linux-open-source at linux.davincidsp.com/msg19524.html
>
> Signed-off-by: Michael Williamson <michael.williamson@criticallink.com>
> Tested-by: Michael Williamson <michael.williamson@criticallink.com>
> ---
> This patch is against davinci-linux.
>
> I'm open to suggestions for reducing the patch description.
>
> I'm open to alternatives to the solution below, outside of disabling the
> UARTs in question as is done on the DA850 evm and the hawkboard (both
> of which might be able to use this patch?).
Can you please CC linux-serial on this patch? Folks on that list
will have ideas on how best to work around this issue.
I think setting the UART_BUG_NOMSR in up->bugs for these ports
(as you previously implemented on your tree) is a better patch
since it utilizes an existing established mechanism.
I understand there is no existing way to pass the bugs through
platform data, but may be that needs to be created (or may be
have a new port type for "DaVinci UART with no flow control" and
then setup up->bugs after checking for this port type).
Thanks,
Sekhar
>
> arch/arm/mach-davinci/include/mach/serial.h | 2 ++
> arch/arm/mach-davinci/serial.c | 19 +++++++++++++++++++
> 2 files changed, 21 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h
> index 8051110..db1d208 100644
> --- a/arch/arm/mach-davinci/include/mach/serial.h
> +++ b/arch/arm/mach-davinci/include/mach/serial.h
> @@ -49,6 +49,8 @@
> struct davinci_uart_config {
> /* Bit field of UARTs present; bit 0 --> UART1 */
> unsigned int enabled_uarts;
> + /* Bit field of RTS/CTS disable; bit 0 --> UART1 */
> + unsigned int disable_rtscts;
> };
>
> extern int davinci_serial_init(struct davinci_uart_config *);
> diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c
> index 1875740..738048e 100644
> --- a/arch/arm/mach-davinci/serial.c
> +++ b/arch/arm/mach-davinci/serial.c
> @@ -31,6 +31,22 @@
> #include <mach/serial.h>
> #include <mach/cputype.h>
>
> +static void davinci_set_termios_noms(struct uart_port *up,
> + struct ktermios *new,
> + struct ktermios *old)
> +{
> + /*
> + * disabling CLOCAL, or enabling CRTSCTS, will enable the modem status
> + * interrupts. If this routine is being called, the port in question
> + * does not have valid CTS/RTS pins (they are pinmuxed to some other
> + * function). Override any requested operation that may enable the
> + * interrupts.
> + */
> + new->c_cflag &= ~CRTSCTS;
> + new->c_cflag |= CLOCAL;
> + serial8250_do_set_termios(up, new, old);
> +}
> +
> static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
> int offset)
> {
> @@ -109,6 +125,9 @@ int __init davinci_serial_init(struct davinci_uart_config *info)
>
> if (p->membase && p->type != PORT_AR7)
> davinci_serial_reset(p);
> +
> + if (info->disable_rtscts & (1 << i))
> + p->set_termios = davinci_set_termios_noms;
> }
>
> return platform_device_register(soc_info->serial_dev);
> --
> 1.7.0.4
>
> _______________________________________________
> Davinci-linux-open-source mailing list
> Davinci-linux-open-source at linux.davincidsp.com
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
>
^ permalink raw reply
* [PATCH 1/3] hvc_dcc: Fix bad code generation by marking assembly volatile
From: Pavel Machek @ 2011-01-03 5:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8yazkrjkuo3.fsf@huya.qualcomm.com>
On Sun 2011-01-02 10:49:32, David Brown wrote:
> On Sun, Jan 02 2011, Pavel Machek wrote:
>
> >> > diff --git a/drivers/char/hvc_dcc.c b/drivers/char/hvc_dcc.c
> >> > index 6470f63..155ec10 100644
> >> > --- a/drivers/char/hvc_dcc.c
> >> > +++ b/drivers/char/hvc_dcc.c
> >> > @@ -33,8 +33,7 @@
> >> > static inline u32 __dcc_getstatus(void)
> >> > {
> >> > u32 __ret;
> >> > -
> >> > - asm("mrc p14, 0, %0, c0, c1, 0 @ read comms ctrl reg"
> >> > + asm volatile("mrc p14, 0, %0, c0, c1, 0 @ read comms ctrl reg"
> >> > : "=r" (__ret) : : "cc");
> >> >
> >> > return __ret;
> >
> > Is volatile needed here? If __dcc_getstatus() return value is
> > discarded, we want assembly discarded, right?
>
> That's not really the issue being fixed. Without the volatile, the
> compiler is free to cache and reuse a previously loaded status value.
> It is important that the status be read each time.
>
> I don't think there is a way of indicating that assembly needs to happen
> for each use, but that it is OK to discard if the value isn't used.
> 'volatile' is a bit overloaded.
Ok, thanks for explanation.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* [PATCH 2/7 v2] OMAP2430: hwmod data: Add McSPI
From: Paul Walmsley @ 2011-01-03 4:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20101230190320.GA2713@angua.secretlab.ca>
On Thu, 30 Dec 2010, Grant Likely wrote:
> On Wed, Dec 01, 2010 at 07:31:22PM +0530, Govindraj.R wrote:
> > From: Charulatha V <charu@ti.com>
> >
> > Update the 2430 hwmod data file with McSPI info.
> >
> > Signed-off-by: Charulatha V <charu@ti.com>
> > Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>
> Hmmm; this patch is virtually identical to the first patch in this
> series which adds 2420 hwmod support. I see a large block of
> identical data with minor differences. Surely support for these two
> chips can share the common blocks of data.
Yes, that's probably worth doing at some point, particularly for the chips
that don't have auto-generated SoC data (OMAP2420/2430/3xxx). It's
probably possible also for the auto-generated SoC data but will require
some major changes to the auto-generation scripts.
In the medium term, Thomas's upcoming conditional section patches should
reduce the runtime memory usage for hwmod data unrelated to the
currently-booted SoC down to zero.
- Paul
^ permalink raw reply
* [PATCH V3 36/63] ST SPEAr : FSMC (Flexible Static Memory Controller) NOR interface driver
From: viresh kumar @ 2011-01-03 3:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTik_NXigwhRH3KMjV3qmu-GB7m+6hzzdGY8RjBof@mail.gmail.com>
Linus,
On 12/26/2010 09:08 PM, Linus Walleij wrote:
> 2010/12/20 Viresh Kumar <viresh.kumar@st.com>:
>
(...)
>> diff --git a/arch/arm/mach-spear13xx/fsmc-nor.c b/arch/arm/mach-spear13xx/fsmc-nor.c
>> new file mode 100644
>> index 0000000..03234b6
>> --- /dev/null
>> +++ b/arch/arm/mach-spear13xx/fsmc-nor.c
>
> What is this file doing in mach-spear13xx? Several other platforms
> like U300 and Nomadik use the same NOR controller.
>
> This should be in drivers/mtd/* somewhere I believe?
>
>> @@ -0,0 +1,85 @@
>> +/*
>> + * arch/arm/mach-spear13xx/fsmc-nor.c
>> + *
>> + * FSMC (Flexible Static Memory Controller) interface for NOR
>> + *
>> + * Copyright (C) 2010 ST Microelectronics
>> + * Vipin Kumar<vipin.kumar@st.com>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/err.h>
>> +#include <linux/init.h>
>> +#include <linux/err.h>
>> +#include <linux/io.h>
>> +#include <plat/fsmc.h>
>
> Use <linux/mtd/fsmc.h> as include file, get rid of plat/fsmc.h.
> Extend that .h file with the stuff you need.
>
> We need to keep definitions for MTD NOR, NAND and OneNAND using FSMC
> in this file so as to keep things simple. One header file is enough, and it's
> very generic too, FSMC is not for plat-spear/* but also U300, Nomadik and
> Ux500.
>
Yes i agree. I will remove patches related to fsmc from this patch series and will
send them separately.
--
viresh
^ permalink raw reply
* [PATCH 1/4] ARM: Kconfig: Add audio support dependency
From: Kukjin Kim @ 2011-01-03 2:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1293172569-21465-1-git-send-email-sw.youn@samsung.com>
Seungwhan Youn wrote:
>
> This patch adds Samsung ASoC audio support dependency for Samsung SoCs.
>
> Signed-off-by: Seungwhan Youn <sw.youn@samsung.com>
> ---
> arch/arm/Kconfig | 7 +++++++
> 1 files changed, 7 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index d56d21c..ef32a61 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -647,6 +647,7 @@ config ARCH_S3C2410
> select HAVE_CLK
> select ARCH_USES_GETTIMEOFFSET
> select HAVE_S3C2410_I2C if I2C
> + select ASOC_SAMSUNG if SND_SOC
> help
> Samsung S3C2410X CPU based systems, such as the Simtec Electronics
> BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940
> or
> @@ -678,6 +679,7 @@ config ARCH_S3C64XX
> select SAMSUNG_GPIOLIB_4BIT
> select HAVE_S3C2410_I2C if I2C
> select HAVE_S3C2410_WATCHDOG if WATCHDOG
> + select ASOC_SAMSUNG if SND_SOC
> help
> Samsung S3C64XX series based systems
>
> @@ -690,6 +692,7 @@ config ARCH_S5P64X0
> select ARCH_USES_GETTIMEOFFSET
> select HAVE_S3C2410_I2C if I2C
> select HAVE_S3C_RTC if RTC_CLASS
> + select ASOC_SAMSUNG if SND_SOC
> help
> Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440,
> SMDK6450.
> @@ -701,6 +704,7 @@ config ARCH_S5P6442
> select HAVE_CLK
> select ARCH_USES_GETTIMEOFFSET
> select HAVE_S3C2410_WATCHDOG if WATCHDOG
> + select ASOC_SAMSUNG if SND_SOC
> help
> Samsung S5P6442 CPU based systems
>
> @@ -714,6 +718,7 @@ config ARCH_S5PC100
> select HAVE_S3C2410_I2C if I2C
> select HAVE_S3C_RTC if RTC_CLASS
> select HAVE_S3C2410_WATCHDOG if WATCHDOG
> + select ASOC_SAMSUNG if SND_SOC
> help
> Samsung S5PC100 series based systems
>
> @@ -729,6 +734,7 @@ config ARCH_S5PV210
> select HAVE_S3C2410_I2C if I2C
> select HAVE_S3C_RTC if RTC_CLASS
> select HAVE_S3C2410_WATCHDOG if WATCHDOG
> + select ASOC_SAMSUNG if SND_SOC
> help
> Samsung S5PV210/S5PC110 series based systems
>
> @@ -742,6 +748,7 @@ config ARCH_S5PV310
> select HAVE_S3C_RTC if RTC_CLASS
> select HAVE_S3C2410_I2C if I2C
> select HAVE_S3C2410_WATCHDOG if WATCHDOG
> + select ASOC_SAMSUNG if SND_SOC
> help
> Samsung S5PV310 series based systems
>
> --
Hi everyone,
Wow it's 2011, I hope you're happy :-)
Hmm...sorry for late.
Looks ok to me..but I know, you changed the name 'ASOC_SAMSUNG' to
'SND_SOC_SAMSUNG'.
So I'm waiting for updated patch now.
Mr. Youn, could you please update your patch against on sound-2.6 tree?
Or...Mark, what's your plan about this, please let me know.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply
* [PATCH 4/5] S5PC110: add MIPI-DSI Controller driver.
From: daeinki @ 2011-01-03 2:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <013b01cba8b7$a0bcf250$e236d6f0$%kim@samsung.com>
Kukjin Kim ? ?:
> Inki Dae wrote:
>> S5PC110 and S5PC210 SoC platform have one or two MIPI-DSI Controller.
>> MIPI-DSI Controller can be used to connect MIPI-DSI based LCD Panel.
>> this patch adds MIPI-DSI Controller driver.(or Master driver)
>>
>> Signed-off-by: Inki Dae <inki.dae@samsung.com>
>> ---
>> arch/arm/plat-s5p/include/plat/mipi-ddi.h | 54 +++
>> arch/arm/plat-s5p/include/plat/mipi-dsi.h | 450 ++++++++++++++++++++
>> arch/arm/plat-s5p/include/plat/regs-dsim.h | 299 +++++++++++++
>> drivers/video/Kconfig | 7 +
>> drivers/video/Makefile | 2 +
>> drivers/video/s5p_mipi_dsi.c | 429 +++++++++++++++++++
>> drivers/video/s5p_mipi_dsi_common.c | 630
>> ++++++++++++++++++++++++++++
>> drivers/video/s5p_mipi_dsi_common.h | 34 ++
>> drivers/video/s5p_mipi_dsi_lowlevel.c | 569
> +++++++++++++++++++++++++
>> drivers/video/s5p_mipi_dsi_lowlevel.h | 93 ++++
>> 10 files changed, 2567 insertions(+), 0 deletions(-)
>> create mode 100644 arch/arm/plat-s5p/include/plat/mipi-ddi.h
>> create mode 100644 arch/arm/plat-s5p/include/plat/mipi-dsi.h
>> create mode 100644 arch/arm/plat-s5p/include/plat/regs-dsim.h
>> create mode 100644 drivers/video/s5p_mipi_dsi.c
>> create mode 100644 drivers/video/s5p_mipi_dsi_common.c
>> create mode 100644 drivers/video/s5p_mipi_dsi_common.h
>> create mode 100644 drivers/video/s5p_mipi_dsi_lowlevel.c
>> create mode 100644 drivers/video/s5p_mipi_dsi_lowlevel.h
>>
>> diff --git a/arch/arm/plat-s5p/include/plat/mipi-ddi.h b/arch/arm/plat-
>> s5p/include/plat/mipi-ddi.h
>> new file mode 100644
>> index 0000000..3f4efb4
>> --- /dev/null
>> +++ b/arch/arm/plat-s5p/include/plat/mipi-ddi.h
>> @@ -0,0 +1,54 @@
>> +/* linux/arm/arch/plat-s5p/include/plat/mipi_ddi.h
>> + *
>> + * definitions for DDI based MIPI-DSI.
>> + *
>> + * Copyright (c) 2009 Samsung Electronics
>> + * InKi Dae <inki.dae@samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> +*/
>> +
>> +#ifndef _MIPI_DDI_H
>> +#define _MIPI_DDI_H
>> +
>> +#include <linux/lcd.h>
>> +
>> +enum mipi_ddi_interface {
>> + RGB_IF = 0x4000,
>> + I80_IF = 0x8000,
>> + YUV_601 = 0x10000,
>> + YUV_656 = 0x20000,
>> + MIPI_VIDEO = 0x1000,
>> + MIPI_COMMAND = 0x2000,
>> +};
>> +
>> +enum mipi_ddi_panel_select {
>> + DDI_MAIN_LCD = 0,
>> + DDI_SUB_LCD = 1,
>
> DDI_MAIN_LCD,
> DDI_SUB_LCD,
>
>> +};
>> +
>> +struct mipi_ddi_platform_data {
>> + /*
>> + * it is used for command mode lcd panel and
>> + * when all contents of framebuffer in panel module are transfered
>> + * to lcd panel it occurs te signal.
>> + *
>> + * note:
>> + * - in case of command mode(cpu mode), it should be triggered only
>> + * when TE signal of lcd panel and frame done interrupt of display
>> + * controller or mipi controller occurs.
>> + */
>> + unsigned int te_irq;
>> +
>> + int (*lcd_reset) (struct lcd_device *ld);
>> + int (*lcd_power_on) (struct lcd_device *ld, int enable);
>> + int (*backlight_on) (struct lcd_device *ld, int enable);
>> +
>> + unsigned int reset_delay;
>> + unsigned int power_on_delay;
>> + unsigned int power_off_delay;
>> +};
>> +
>> +#endif /* _MIPI_DDI_H */
>
> I'm not sure whether we really need above header in here.
>
they would be used for lcd panel driver.
please, see MIPI based sample lcd driver.
>> diff --git a/arch/arm/plat-s5p/include/plat/mipi-dsi.h b/arch/arm/plat-
>> s5p/include/plat/mipi-dsi.h
>> new file mode 100644
>> index 0000000..371efe4
>> --- /dev/null
>> +++ b/arch/arm/plat-s5p/include/plat/mipi-dsi.h
>
> Sometimes used MIPI DSI or MIPI DSIM...
> I think should be used same name like MIPI CSIS.
>
> If possible, please same rule...according to data sheet, MIPI DSIM is
> better.
>
as I said before, modified as "DSIM"
>> @@ -0,0 +1,450 @@
>> +/* linux/arm/arch/plat-s5p/include/plat/mipi_dsi.h
>
> mipi_dsi.h? mipi-dsi.h?
>
>> + *
>> + * Platform data header for Samsung MIPI-DSI.
>> + *
>> + * Copyright (c) 2009 Samsung Electronics
>> + * InKi Dae <inki.dae@samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> +*/
>> +
>> +#ifndef _MIPI_DSI_H
>> +#define _MIPI_DSI_H
>> +
>> +#include <linux/device.h>
>> +#include <linux/fb.h>
>> +
>> +#define PANEL_NAME_SIZE (32)
>> +
>> +enum dsim_interface_type {
>> + DSIM_COMMAND = 0,
>> + DSIM_VIDEO = 1,
>
> DSIM_COMMAND,
> DSIM_VIDEO,
>
>> +};
>> +
>> +enum dsim_state {
>> + DSIM_STATE_RESET = 0,
>> + DSIM_STATE_INIT = 1,
>> + DSIM_STATE_STOP = 2,
>> + DSIM_STATE_HSCLKEN = 3,
>> + DSIM_STATE_ULPS = 4,
>
> DSIM_STATE_RESET,
> DSIM_STATE_INIT,
> DSIM_STATE_STOP,
> DSIM_STATE_HSCLKEN,
> DSIM_STATE_ULPS,
>
>> +};
>> +
>> +enum dsim_virtual_ch_no {
>> + DSIM_VIRTUAL_CH_0 = 0,
>> + DSIM_VIRTUAL_CH_1 = 1,
>> + DSIM_VIRTUAL_CH_2 = 2,
>> + DSIM_VIRTUAL_CH_3 = 3,
>
> DSIM_VIRTUAL_CH_0,
> DSIM_VIRTUAL_CH_1,
> DSIM_VIRTUAL_CH_2,
> DSIM_VIRTUAL_CH_3,
>
> ....
>
>
> And if not used, please remove that.
> We don't need unnecessary codes.
>
>> +};
>> +
>
no, used for mipi-dsi driver.
please, see the s5p_mipi_dsi_common.c and lowlevel.c file.
and I will move this header file to driver.
> (snip)
>
>> diff --git a/arch/arm/plat-s5p/include/plat/regs-dsim.h b/arch/arm/plat-
>> s5p/include/plat/regs-dsim.h
>> new file mode 100644
>> index 0000000..fcd9c1f
>> --- /dev/null
>> +++ b/arch/arm/plat-s5p/include/plat/regs-dsim.h
>> @@ -0,0 +1,299 @@
>> +/* linux/arch/arm/plat-s5p/include/plat/regs-dsim.h
>> + *
>> + * Register definition file for Samsung MIPI-DSIM driver
>> + *
>> + * InKi Dae <inki.dae@samsung.com>, Copyright (c) 2009 Samsung
> Electronics
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> +*/
>> +
>> +#ifndef _REGS_DSIM_H
>> +#define _REGS_DSIM_H
>> +
>
> If not used some definitios, we don't need that.
> I don't think that we need every below definitions.
>
also.
>> +#define S5P_DSIM_STATUS (0x0) /* Status register */
>> +#define S5P_DSIM_SWRST (0x4) /* Software reset register
> */
>> +#define S5P_DSIM_CLKCTRL (0x8) /* Clock control register */
>> +#define S5P_DSIM_TIMEOUT (0xc) /* Time out register */
>> +#define S5P_DSIM_CONFIG (0x10) /* Configuration register */
>> +#define S5P_DSIM_ESCMODE (0x14) /* Escape mode register */
>> +
>> +/* Main display image resolution register */
>> +#define S5P_DSIM_MDRESOL (0x18)
>> +#define S5P_DSIM_MVPORCH (0x1c) /* Main display Vporch register */
>> +#define S5P_DSIM_MHPORCH (0x20) /* Main display Hporch register */
>> +#define S5P_DSIM_MSYNC (0x24) /* Main display sync area
>> register */
>> +
>> +/* Sub display image resolution register */
>> +#define S5P_DSIM_SDRESOL (0x28)
>> +#define S5P_DSIM_INTSRC (0x2c) /* Interrupt source register
> */
>> +#define S5P_DSIM_INTMSK (0x30) /* Interrupt mask register
> */
>> +#define S5P_DSIM_PKTHDR (0x34) /* Packet Header FIFO
> register
>> */
>> +#define S5P_DSIM_PAYLOAD (0x38) /* Payload FIFO register */
>> +#define S5P_DSIM_RXFIFO (0x3c) /* Read FIFO register */
>> +#define S5P_DSIM_FIFOTHLD (0x40) /* FIFO threshold level register */
>> +#define S5P_DSIM_FIFOCTRL (0x44) /* FIFO status and control register
> */
>> +
>> +/* FIFO memory AC characteristic register */
>> +#define S5P_DSIM_MEMACCHR (0x48)
>> +#define S5P_DSIM_PLLCTRL (0x4c) /* PLL control register */
>> +#define S5P_DSIM_PLLTMR (0x50) /* PLL timer register */
>> +#define S5P_DSIM_PHYACCHR (0x54) /* D-PHY AC characteristic register
> */
>> +#define S5P_DSIM_PHYACCHR1 (0x58) /* D-PHY AC characteristic register1
> */
>> +
>> +/* DSIM_SWRST */
>> +#define DSIM_FUNCRST (1 << 16)
>> +#define DSIM_SWRST (1 << 0)
>> +
>> +/* S5P_DSIM_TIMEOUT */
>> +#define DSIM_LPDR_TOUT_SHIFT (0)
>> +#define DSIM_BTA_TOUT_SHIFT (16)
>> +#define DSIM_LPDR_TOUT(x) (((x) & 0xffff) << DSIM_LPDR_TOUT_SHIFT)
>> +#define DSIM_BTA_TOUT(x) (((x) & 0xff) << DSIM_BTA_TOUT_SHIFT)
>> +
>> +/* S5P_DSIM_CLKCTRL */
>> +#define DSIM_ESC_PRESCALER_SHIFT (0)
>> +#define DSIM_LANE_ESC_CLKEN_SHIFT (19)
>> +#define DSIM_BYTE_CLKEN_SHIFT (24)
>> +#define DSIM_BYTE_CLK_SRC_SHIFT (25)
>> +#define DSIM_PLL_BYPASS_SHIFT (27)
>> +#define DSIM_ESC_CLKEN_SHIFT (28)
>> +#define DSIM_TX_REQUEST_HSCLK_SHIFT (31)
>> +#define DSIM_ESC_PRESCALER(x) (((x) & 0xffff) << \
>> + DSIM_ESC_PRESCALER_SHIFT)
>> +#define DSIM_LANE_ESC_CLKEN(x) (((x) & 0x1f) << \
>> + DSIM_LANE_ESC_CLKEN_SHIFT)
>> +#define DSIM_BYTE_CLK_ENABLE (1 << DSIM_BYTE_CLKEN_SHIFT)
>> +#define DSIM_BYTE_CLK_DISABLE (0 << DSIM_BYTE_CLKEN_SHIFT)
>> +#define DSIM_BYTE_CLKSRC(x) (((x) & 0x3) <<
> DSIM_BYTE_CLK_SRC_SHIFT)
>> +#define DSIM_PLL_BYPASS_PLL (0 << DSIM_PLL_BYPASS_SHIFT)
>> +#define DSIM_PLL_BYPASS_EXTERNAL (1 << DSIM_PLL_BYPASS_SHIFT)
>> +#define DSIM_ESC_CLKEN_ENABLE (1 << DSIM_ESC_CLKEN_SHIFT)
>> +#define DSIM_ESC_CLKEN_DISABLE (0 << DSIM_ESC_CLKEN_SHIFT)
>> +
>> +/* S5P_DSIM_CONFIG */
>> +#define DSIM_LANE_EN_SHIFT (0)
>> +#define DSIM_NUM_OF_DATALANE_SHIFT (5)
>> +#define DSIM_SUB_PIX_FORMAT_SHIFT (8)
>> +#define DSIM_MAIN_PIX_FORMAT_SHIFT (12)
>> +#define DSIM_SUB_VC_SHIFT (16)
>> +#define DSIM_MAIN_VC_SHIFT (18)
>> +#define DSIM_HSA_MODE_SHIFT (20)
>> +#define DSIM_HBP_MODE_SHIFT (21)
>> +#define DSIM_HFP_MODE_SHIFT (22)
>> +#define DSIM_HSE_MODE_SHIFT (23)
>> +#define DSIM_AUTO_MODE_SHIFT (24)
>> +#define DSIM_VIDEO_MODE_SHIFT (25)
>> +#define DSIM_BURST_MODE_SHIFT (26)
>> +#define DSIM_SYNC_INFORM_SHIFT (27)
>> +#define DSIM_EOT_R03_SHIFT (28)
>> +#define DSIM_LANE_ENx(x) ((1) << x)
>> +
>> +/* in case of Gemunus, it should be 0x1. */
>> +#define DSIM_NUM_OF_DATA_LANE(x) ((x) << 5)
>> +#define DSIM_SUB_PIX_FORMAT_3BPP (0 << 8) /* command mode only
> */
>> +#define DSIM_SUB_PIX_FORMAT_8BPP (1 << 8) /* command mode only
> */
>> +#define DSIM_SUB_PIX_FORMAT_12BPP (2 << 8) /* command mode only
> */
>> +#define DSIM_SUB_PIX_FORMAT_16BPP (3 << 8) /* command mode only
> */
>> +#define DSIM_SUB_PIX_FORMAT_16BPP_RGB (4 << 8) /* video
> mode
>> only */
>> +#define DSIM_SUB_PIX_FORMAT_18BPP_PRGB (5 << 8) /* video
> mode
>> only */
>> +#define DSIM_SUB_PIX_FORMAT_18BPP_LRGB (6 << 8) /* common */
>> +#define DSIM_SUB_PIX_FORMAT_24BPP_RGB (7 << 8) /* common */
>> +#define DSIM_MAIN_PIX_FORMAT_3BPP (0 << 12) /* command mode only
> */
>> +#define DSIM_MAIN_PIX_FORMAT_8BPP (1 << 12) /* command mode only
> */
>> +#define DSIM_MAIN_PIX_FORMAT_12BPP (2 << 12) /* command mode only
> */
>> +#define DSIM_MAIN_PIX_FORMAT_16BPP (3 << 12) /* command mode only
> */
>> +#define DSIM_MAIN_PIX_FORMAT_16BPP_RGB (4 << 12) /* video
> mode
>> only */
>> +#define DSIM_MAIN_PIX_FORMAT_18BPP_PRGB (5 << 12) /* video
> mode
>> only */
>> +#define DSIM_MAIN_PIX_FORMAT_18BPP_LRGB (6 << 12) /* common */
>> +#define DSIM_MAIN_PIX_FORMAT_24BPP_RGB (7 << 12) /* common */
>> +
>> +/* Virtual channel number for sub display */
>> +#define DSIM_SUB_VC(x) (((x) & 0x3) << 16)
>> +/* Virtual channel number for main display */
>> +#define DSIM_MAIN_VC(x) (((x) & 0x3) << 18)
>> +#define DSIM_HSA_MODE_ENABLE (1 << 20)
>> +#define DSIM_HSA_MODE_DISABLE (0 << 20)
>> +#define DSIM_HBP_MODE_ENABLE (1 << 21)
>> +#define DSIM_HBP_MODE_DISABLE (0 << 21)
>> +#define DSIM_HFP_MODE_ENABLE (1 << 22)
>> +#define DSIM_HFP_MODE_DISABLE (0 << 22)
>> +#define DSIM_HSE_MODE_ENABLE (1 << 23)
>> +#define DSIM_HSE_MODE_DISABLE (0 << 23)
>> +#define DSIM_AUTO_MODE (1 << 24)
>> +#define DSIM_CONFIGURATION_MODE (0 << 24)
>> +#define DSIM_VIDEO_MODE (1 << 25)
>> +#define DSIM_COMMAND_MODE (0 << 25)
>> +#define DSIM_BURST_MODE (1 << 26)
>> +#define DSIM_NON_BURST_MODE (0 << 26)
>> +#define DSIM_SYNC_INFORM_PULSE (1 << 27)
>> +#define DSIM_SYNC_INFORM_EVENT (0 << 27)
>> +/* enable EoT packet generation for V1.01r11 */
>> +#define DSIM_EOT_R03_ENABLE (0 << 28)
>> +/* disable EoT packet generation for V1.01r03 */
>> +#define DSIM_EOT_R03_DISABLE (1 << 28)
>> +
>> +/* S5P_DSIM_ESCMODE */
>> +#define DSIM_STOP_STATE_CNT_SHIFT (21)
>> +#define DSIM_STOP_STATE_CNT(x) (((x) & 0x3ff) << \
>> + DSIM_STOP_STATE_CNT_SHIFT)
>> +#define DSIM_FORCE_STOP_STATE_SHIFT (20)
>> +#define DSIM_FORCE_BTA_SHIFT (16)
>> +#define DSIM_CMD_LPDT_HS_MODE (0 << 7)
>> +#define DSIM_CMD_LPDT_LP_MODE (1 << 7)
>> +#define DSIM_TX_LPDT_HS_MODE (0 << 6)
>> +#define DSIM_TX_LPDT_LP_MODE (1 << 6)
>> +#define DSIM_TX_TRIGGER_RST_SHIFT (4)
>> +#define DSIM_TX_UIPS_DAT_SHIFT (3)
>> +#define DSIM_TX_UIPS_EXIT_SHIFT (2)
>> +#define DSIM_TX_UIPS_CLK_SHIFT (1)
>> +#define DSIM_TX_UIPS_CLK_EXIT_SHIFT (0)
>> +
>> +/* S5P_DSIM_MDRESOL */
>> +#define DSIM_MAIN_STAND_BY (1 << 31)
>> +#define DSIM_MAIN_NOT_READY (0 << 31)
>> +#define DSIM_MAIN_VRESOL(x) (((x) & 0x7ff) << 16)
>> +#define DSIM_MAIN_HRESOL(x) (((x) & 0X7ff) << 0)
>> +
>> +/* S5P_DSIM_MVPORCH */
>> +#define DSIM_CMD_ALLOW_SHIFT (28)
>> +#define DSIM_STABLE_VFP_SHIFT (16)
>> +#define DSIM_MAIN_VBP_SHIFT (0)
>> +#define DSIM_CMD_ALLOW_MASK (0xf << DSIM_CMD_ALLOW_SHIFT)
>> +#define DSIM_STABLE_VFP_MASK (0x7ff << DSIM_STABLE_VFP_SHIFT)
>> +#define DSIM_MAIN_VBP_MASK (0x7ff << DSIM_MAIN_VBP_SHIFT)
>> +#define DSIM_CMD_ALLOW(x) (((x) & 0xf) <<
> DSIM_CMD_ALLOW_SHIFT)
>> +#define DSIM_STABLE_VFP(x) (((x) & 0x7ff) <<
> DSIM_STABLE_VFP_SHIFT)
>> +#define DSIM_MAIN_VBP(x) (((x) & 0x7ff) <<
> DSIM_MAIN_VBP_SHIFT)
>> +
>> +/* S5P_DSIM_MHPORCH */
>> +#define DSIM_MAIN_HFP_SHIFT (16)
>> +#define DSIM_MAIN_HBP_SHIFT (0)
>> +#define DSIM_MAIN_HFP_MASK ((0xffff) << DSIM_MAIN_HFP_SHIFT)
>> +#define DSIM_MAIN_HBP_MASK ((0xffff) << DSIM_MAIN_HBP_SHIFT)
>> +#define DSIM_MAIN_HFP(x) (((x) & 0xffff) <<
> DSIM_MAIN_HFP_SHIFT)
>> +#define DSIM_MAIN_HBP(x) (((x) & 0xffff) <<
> DSIM_MAIN_HBP_SHIFT)
>> +
>> +/* S5P_DSIM_MSYNC */
>> +#define DSIM_MAIN_VSA_SHIFT (22)
>> +#define DSIM_MAIN_HSA_SHIFT (0)
>> +#define DSIM_MAIN_VSA_MASK ((0x3ff) << DSIM_MAIN_VSA_SHIFT)
>> +#define DSIM_MAIN_HSA_MASK ((0xffff) << DSIM_MAIN_HSA_SHIFT)
>> +#define DSIM_MAIN_VSA(x) (((x) & 0x3ff) <<
> DSIM_MAIN_VSA_SHIFT)
>> +#define DSIM_MAIN_HSA(x) (((x) & 0xffff) <<
> DSIM_MAIN_HSA_SHIFT)
>> +
>> +/* S5P_DSIM_SDRESOL */
>> +#define DSIM_SUB_STANDY_SHIFT (31)
>> +#define DSIM_SUB_VRESOL_SHIFT (16)
>> +#define DSIM_SUB_HRESOL_SHIFT (0)
>> +#define DSIM_SUB_STANDY_MASK ((0x1) << DSIM_SUB_STANDY_SHIFT)
>> +#define DSIM_SUB_VRESOL_MASK ((0x7ff) << DSIM_SUB_VRESOL_SHIFT)
>> +#define DSIM_SUB_HRESOL_MASK ((0x7ff) << DSIM_SUB_HRESOL_SHIFT)
>> +#define DSIM_SUB_STANDY (1 << DSIM_SUB_STANDY_SHIFT)
>> +#define DSIM_SUB_NOT_READY (0 << DSIM_SUB_STANDY_SHIFT)
>> +#define DSIM_SUB_VRESOL(x) (((x) & 0x7ff) <<
> DSIM_SUB_VRESOL_SHIFT)
>> +#define DSIM_SUB_HRESOL(x) (((x) & 0x7ff) <<
> DSIM_SUB_HRESOL_SHIFT)
>> +
>> +/* S5P_DSIM_INTSRC */
>> +#define INTSRC_ERR_CONTENT_LP1 (1 << 0)
>> +#define INTSRC_ERR_CONTENT_LP0 (1 << 1)
>> +#define INTSRC_ERR_CONTROL0 (1 << 2)
>> +#define INTSRC_ERR_CONTROL1 (1 << 3)
>> +#define INTSRC_ERR_CONTROL2 (1 << 4)
>> +#define INTSRC_ERR_CONTROL3 (1 << 5)
>> +#define INTSRC_ERR_SYNC0 (1 << 6)
>> +#define INTSRC_ERR_SYNC1 (1 << 7)
>> +#define INTSRC_ERR_SYNC2 (1 << 8)
>> +#define INTSRC_ERR_SYNC3 (1 << 9)
>> +#define INTSRC_ERR_ESC0 (1 << 10)
>> +#define INTSRC_ERR_ESC1 (1 << 11)
>> +#define INTSRC_ERR_ESC2 (1 << 12)
>> +#define INTSRC_ERR_ESC3 (1 << 13)
>> +#define INTSRC_ERR_RX_CRC (1 << 14)
>> +#define INTSRC_ERR_RX_ECC (1 << 15)
>> +#define INTSRC_RX_ACK (1 << 16)
>> +#define INTSRC_RX_TE (1 << 17)
>> +#define INTSRC_RX_DAT_DONE (1 << 18)
>> +#define INTSRC_TA_TOUT (1 << 20)
>> +#define INTSRC_LPDR_TOUT (1 << 21)
>> +#define INTSRC_FRAME_DONE (1 << 24)
>> +#define INTSRC_BUS_TURN_OVER (1 << 25)
>> +#define INTSRC_SYNC_OVERRIDE (1 << 28)
>> +#define INTSRC_SFR_FIFO_EMPTY (1 << 29)
>> +#define INTSRC_SW_RST_RELEASE (1 << 30)
>> +#define INTSRC_PLL_STABLE (1 << 31)
>> +
>> +/* S5P_DSIM_INTMSK */
>> +#define INTMSK_ERR_CONTENT_LP1 (1 << 0)
>> +#define INTMSK_ERR_CONTENT_LP0 (1 << 1)
>> +#define INTMSK_ERR_CONTROL0 (1 << 2)
>> +#define INTMSK_ERR_CONTROL1 (1 << 3)
>> +#define INTMSK_ERR_CONTROL2 (1 << 4)
>> +#define INTMSK_ERR_CONTROL3 (1 << 5)
>> +#define INTMSK_ERR_SYNC0 (1 << 6)
>> +#define INTMSK_ERR_SYNC1 (1 << 7)
>> +#define INTMSK_ERR_SYNC2 (1 << 8)
>> +#define INTMSK_ERR_SYNC3 (1 << 9)
>> +#define INTMSK_ERR_ESC0 (1 << 10)
>> +#define INTMSK_ERR_ESC1 (1 << 11)
>> +#define INTMSK_ERR_ESC2 (1 << 12)
>> +#define INTMSK_ERR_ESC3 (1 << 13)
>> +#define INTMSK_ERR_RX_CRC (1 << 14)
>> +#define INTMSK_ERR_RX_ECC (1 << 15)
>> +#define INTMSK_RX_ACK (1 << 16)
>> +#define INTMSK_RX_TE (1 << 17)
>> +#define INTMSK_RX_DAT_DONE (1 << 18)
>> +#define INTMSK_TA_TOUT (1 << 20)
>> +#define INTMSK_LPDR_TOUT (1 << 21)
>> +#define INTMSK_FRAME_DONE (1 << 24)
>> +#define INTMSK_BUS_TURN_OVER (1 << 25)
>> +#define INTMSK_SFR_FIFO_EMPTY (1 << 29)
>> +#define INTMSK_SW_RST_RELEASE (1 << 30)
>> +#define INTMSK_PLL_STABLE (1 << 31)
>> +
>> +/* S5P_DSIM_PKTHDR */
>> +#define DSIM_PACKET_HEADER_DI(x) (((x) & 0xff) << 0)
>> +/* Word count lower byte for long packet */
>> +#define DSIM_PACKET_HEADER_DAT0(x) (((x) & 0xff) << 8)
>> +/* Word count upper byte for long packet */
>> +#define DSIM_PACKET_HEADER_DAT1(x) (((x) & 0xff) << 16)
>> +
>> +/* S5P_DSIM_FIFOCTRL */
>> +#define DSIM_MAIN_DISP_FIFO (1 << 0)
>> +#define DSIM_SUB_DISP_FIFO (1 << 1)
>> +#define DSIM_I80_FIFO (1 << 2)
>> +#define DSIM_TX_SFR_FIFO (1 << 3)
>> +#define DSIM_RX_FIFO (1 << 4)
>> +#define MAIN_DISP_PAYLOAD_EMPTY (1 << 8)
>> +#define MAIN_DISP_PAYLOAD_FULL (1 << 9)
>> +#define MAIN_DISP_HEADER_EMPTY (1 << 10)
>> +#define MAIN_DISP_HEADER_FULL (1 << 11)
>> +#define SUB_DISP_PAYLOAD_EMPTY (1 << 12)
>> +#define SUB_DISP_PAYLOAD_FULL (1 << 13)
>> +#define SUB_DISP_HEADER_EMPTY (1 << 14)
>> +#define SUB_DISP_HEADER_FULL (1 << 15)
>> +#define I80_PALOAD_EMPTY (1 << 16)
>> +#define I80_PALOAD_FULL (1 << 17)
>> +#define I80_HEADER_EMPTY (1 << 18)
>> +#define I80_HEADER_FULL (1 << 19)
>> +#define SFR_PAYLOAD_EMPTY (1 << 20)
>> +#define SFR_PAYLOAD_FULL (1 << 21)
>> +#define SFR_HEADER_EMPTY (1 << 22)
>> +#define SFR_HEADER_FULL (1 << 23)
>> +#define DSIM_RX_DATA_EMPTY (1 << 24)
>> +#define DSIM_RX_DATA_FULL (1 << 25)
>> +
>> +/* S5P_DSIM_PHYACCHR */
>> +#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5)
>> +#define DSIM_AFC_ENABLE (1 << 14)
>> +#define DSIM_AFC_DISABLE (0 << 14)
>> +
>> +/* S5P_DSIM_PLLCTRL */
>> +#define DSIM_PMS_SHIFT (1)
>> +#define DSIM_PLL_EN_SHIFT (23)
>> +#define DSIM_FREQ_BAND_SHIFT (24)
>> +#define DSIM_PMS(x) (((x) & 0x7ffff) << DSIM_PMS_SHIFT)
>> +#define DSIM_FREQ_BAND(x) (((x) & 0xf) <<
> DSIM_FREQ_BAND_SHIFT)
>> +
>> +#endif /* _REGS_DSIM_H */
>> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
>> index 27c1fb4..aa305c5 100644
>> --- a/drivers/video/Kconfig
>> +++ b/drivers/video/Kconfig
>> @@ -1996,6 +1996,13 @@ config FB_S3C2410_DEBUG
>> Turn on debugging messages. Note that you can set/unset at run
> time
>> through sysfs
>>
>> +config S5P_MIPI_DSI
>
> How about S5P_MIPI_DSIM?
>
S5P_MIPI_DSIM is too long, I think DSIM is better than it.
>> + tristate "Samsung SoC MIPI-DSI support."
>> + depends on ARCH_S5PV210
>> + default n
>> + ---help---
>> + This enables support for MIPI-DSI device.
>> +
>> config FB_NUC900
>> bool "NUC900 LCD framebuffer support"
>> depends on FB && ARCH_W90X900
>
> I'm on holiday too...so don't have much time to review this.
> Will read remained part next week.
>
> (snip)
>
> Thanks.
>
Thank you for your comments and I will look forward to your next comments.
My actions is as the following.
1. corrected naming, (MIPI -> DSIM)
2. header files in plat-s5p would be moved to driver and also removed
unnecessary codes.
3. code clean.
> Best regards,
> Kgene.
> --
> Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
> SW Solution Development Team, Samsung Electronics Co., Ltd.
>
>
^ permalink raw reply
* [PATCH 5/5] S5PC110: add MIPI-DSI based sample lcd panel driver.
From: daeinki @ 2011-01-03 2:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <014101cba8b8$06318ab0$1294a010$%kim@samsung.com>
Kukjin Kim ? ?:
> Inki Dae wrote:
>> this patch addes MIPI-DSI based sample panel driver.
>> to write MIPI-DSI based lcd panel driver, you can refer to
>> this sample driver.
>>
>> Signed-off-by: Inki Dae <inki.dae@samsung.com>
>> ---
>> drivers/video/Kconfig | 7 ++
>> drivers/video/Makefile | 1 +
>> drivers/video/s5p_mipi_sample.c | 220
>> +++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 228 insertions(+), 0 deletions(-)
>> create mode 100644 drivers/video/s5p_mipi_sample.c
>>
>> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
>> index aa305c5..325ce86 100644
>> --- a/drivers/video/Kconfig
>> +++ b/drivers/video/Kconfig
>> @@ -2003,6 +2003,13 @@ config S5P_MIPI_DSI
>> ---help---
>> This enables support for MIPI-DSI device.
>>
>> +config S5P_MIPI_SAMPLE
>> + tristate "Samsung SoC MIPI-DSI based sample driver."
>> + depends on S5P_MIPI_DSI && BACKLIGHT_LCD_SUPPORT
>
> Do we really need SAMPLE driver?...
> And is this MIPI SAMPLE not MIPI DSIM sample?
>
I added this one for that someone who uses my mipi-dsi driver could
understand my driver easily. it is just for reference driver.
this sample driver has some problem?
>> + default n
>> + ---help---
>> + This enables support for MIPI-DSI based sample driver.
>> +
>> config FB_NUC900
>> bool "NUC900 LCD framebuffer support"
>> depends on FB && ARCH_W90X900
>> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
>> index f4baed6..c8ac591 100644
>> --- a/drivers/video/Makefile
>> +++ b/drivers/video/Makefile
>> @@ -117,6 +117,7 @@ obj-$(CONFIG_FB_S3C) += s3c-fb.o
>> obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
>> obj-$(CONFIG_S5P_MIPI_DSI) += s5p_mipi_dsi.o s5p_mipi_dsi_common.o \
>> s5p_mipi_dsi_lowlevel.o
>> +obj-$(CONFIG_S5P_MIPI_SAMPLE) += s5p_mipi_sample.o
>> obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
>> obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
>> obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/
>
> (snip)
>
> Happy New Year!
> Thanks.
>
> Best regards,
> Kgene.
> --
> Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
> SW Solution Development Team, Samsung Electronics Co., Ltd.
>
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox