* [PATCH v4] xilinx_spi: Splitted into generic, of and platform driver, added support for DS570
From: Richard Röjfors @ 2009-09-28 14:22 UTC (permalink / raw)
To: spi-devel-general; +Cc: linuxppc-dev, Andrew Morton, dbrownell, John Linn
This patch splits xilinx_spi into three parts, an OF and a platform
driver and generic part.
The generic part now also works on X86, it supports accessing the IP
booth big and little endian. There is also support for 16 and 32 bit
SPI for the Xilinx SPI IP DS570
Signed-off-by: Richard Röjfors <richard.rojfors@mocean-labs.com>
---
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 2c733c2..ecabc12 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -218,8 +218,8 @@ config SPI_TXX9
SPI driver for Toshiba TXx9 MIPS SoCs
config SPI_XILINX
- tristate "Xilinx SPI controller"
- depends on (XILINX_VIRTEX || MICROBLAZE) && EXPERIMENTAL
+ tristate "Xilinx SPI controller common module"
+ depends on HAS_IOMEM && EXPERIMENTAL
select SPI_BITBANG
help
This exposes the SPI controller IP from the Xilinx EDK.
@@ -227,6 +227,21 @@ config SPI_XILINX
See the "OPB Serial Peripheral Interface (SPI) (v1.00e)"
Product Specification document (DS464) for hardware details.
+ Or for the DS570, see "XPS Serial Peripheral Interface (SPI) (v2.00b)"
+
+config SPI_XILINX_OF
+ tristate "Xilinx SPI controller OF device"
+ depends on SPI_XILINX && XILINX_VIRTEX
+ help
+ This is the OF driver for the SPI controller IP from the Xilinx EDK.
+
+config SPI_XILINX_PLTFM
+ tristate "Xilinx SPI controller platform device"
+ depends on SPI_XILINX
+ help
+ This is the platform driver for the SPI controller IP
+ from the Xilinx EDK.
+
#
# Add new SPI master controllers in alphabetical order above this line
#
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 3de408d..5a91cf5 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -30,6 +30,8 @@ obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
obj-$(CONFIG_SPI_TXX9) += spi_txx9.o
obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o
+obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o
+obj-$(CONFIG_SPI_XILINX_PLTFM) += xilinx_spi_pltfm.o
obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o
# ... add above this line ...
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
index 46b8c5c..b1fcc00 100644
--- a/drivers/spi/xilinx_spi.c
+++ b/drivers/spi/xilinx_spi.c
@@ -14,22 +14,35 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-
-#include <linux/of_platform.h>
-#include <linux/of_device.h>
-#include <linux/of_spi.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/io.h>
-#define XILINX_SPI_NAME "xilinx_spi"
+#include "xilinx_spi.h"
+
+struct xilinx_spi {
+ /* bitbang has to be first */
+ struct spi_bitbang bitbang;
+ struct completion done;
+ struct resource mem; /* phys mem */
+ void __iomem *regs; /* virt. address of the control registers */
+ u32 irq;
+ u8 *rx_ptr; /* pointer in the Tx buffer */
+ const u8 *tx_ptr; /* pointer in the Rx buffer */
+ int remaining_bytes; /* the number of bytes left to transfer */
+ /* offset to the XSPI regs, these might vary... */
+ u8 bits_per_word;
+ bool big_endian; /* The device could be accessed big or little
+ * endian
+ */
+};
+
/* Register definitions as per "OPB Serial Peripheral Interface (SPI) (v1.00e)
* Product Specification", DS464
*/
-#define XSPI_CR_OFFSET 0x62 /* 16-bit Control Register */
+#define XSPI_CR_OFFSET 0x60 /* Control Register */
#define XSPI_CR_ENABLE 0x02
#define XSPI_CR_MASTER_MODE 0x04
@@ -40,8 +53,9 @@
#define XSPI_CR_RXFIFO_RESET 0x40
#define XSPI_CR_MANUAL_SSELECT 0x80
#define XSPI_CR_TRANS_INHIBIT 0x100
+#define XSPI_CR_LSB_FIRST 0x200
-#define XSPI_SR_OFFSET 0x67 /* 8-bit Status Register */
+#define XSPI_SR_OFFSET 0x64 /* Status Register */
#define XSPI_SR_RX_EMPTY_MASK 0x01 /* Receive FIFO is empty */
#define XSPI_SR_RX_FULL_MASK 0x02 /* Receive FIFO is full */
@@ -49,8 +63,8 @@
#define XSPI_SR_TX_FULL_MASK 0x08 /* Transmit FIFO is full */
#define XSPI_SR_MODE_FAULT_MASK 0x10 /* Mode fault error */
-#define XSPI_TXD_OFFSET 0x6b /* 8-bit Data Transmit Register */
-#define XSPI_RXD_OFFSET 0x6f /* 8-bit Data Receive Register */
+#define XSPI_TXD_OFFSET 0x68 /* Data Transmit Register */
+#define XSPI_RXD_OFFSET 0x6C /* Data Receive Register */
#define XSPI_SSR_OFFSET 0x70 /* 32-bit Slave Select Register */
@@ -70,43 +84,72 @@
#define XSPI_INTR_TX_UNDERRUN 0x08 /* TxFIFO was underrun */
#define XSPI_INTR_RX_FULL 0x10 /* RxFIFO is full */
#define XSPI_INTR_RX_OVERRUN 0x20 /* RxFIFO was overrun */
+#define XSPI_INTR_TX_HALF_EMPTY 0x40 /* TxFIFO is half empty */
#define XIPIF_V123B_RESETR_OFFSET 0x40 /* IPIF reset register */
#define XIPIF_V123B_RESET_MASK 0x0a /* the value to write */
-struct xilinx_spi {
- /* bitbang has to be first */
- struct spi_bitbang bitbang;
- struct completion done;
+/* to follow are some functions that does little of big endian read and
+ * write depending on the config of the device.
+ */
+static inline void xspi_write8(struct xilinx_spi *xspi, u32 offs, u8 val)
+{
+ iowrite8(val, xspi->regs + offs + ((xspi->big_endian) ? 3 : 0));
+}
- void __iomem *regs; /* virt. address of the control registers */
+static inline void xspi_write16(struct xilinx_spi *xspi, u32 offs, u16 val)
+{
+ if (xspi->big_endian)
+ iowrite16be(val, xspi->regs + offs + 2);
+ else
+ iowrite16(val, xspi->regs + offs);
+}
- u32 irq;
+static inline void xspi_write32(struct xilinx_spi *xspi, u32 offs, u32 val)
+{
+ if (xspi->big_endian)
+ iowrite32be(val, xspi->regs + offs);
+ else
+ iowrite32(val, xspi->regs + offs);
+}
- u32 speed_hz; /* SCK has a fixed frequency of speed_hz Hz */
+static inline u8 xspi_read8(struct xilinx_spi *xspi, u32 offs)
+{
+ return ioread8(xspi->regs + offs + ((xspi->big_endian) ? 3 : 0));
+}
- u8 *rx_ptr; /* pointer in the Tx buffer */
- const u8 *tx_ptr; /* pointer in the Rx buffer */
- int remaining_bytes; /* the number of bytes left to transfer */
-};
+static inline u16 xspi_read16(struct xilinx_spi *xspi, u32 offs)
+{
+ if (xspi->big_endian)
+ return ioread16be(xspi->regs + offs + 2);
+ else
+ return ioread16(xspi->regs + offs);
+}
+
+static inline u32 xspi_read32(struct xilinx_spi *xspi, u32 offs)
+{
+ if (xspi->big_endian)
+ return ioread32be(xspi->regs + offs);
+ else
+ return ioread32(xspi->regs + offs);
+}
-static void xspi_init_hw(void __iomem *regs_base)
+static void xspi_init_hw(struct xilinx_spi *xspi)
{
/* Reset the SPI device */
- out_be32(regs_base + XIPIF_V123B_RESETR_OFFSET,
- XIPIF_V123B_RESET_MASK);
+ xspi_write32(xspi, XIPIF_V123B_RESETR_OFFSET, XIPIF_V123B_RESET_MASK);
/* Disable all the interrupts just in case */
- out_be32(regs_base + XIPIF_V123B_IIER_OFFSET, 0);
+ xspi_write32(xspi, XIPIF_V123B_IIER_OFFSET, 0);
/* Enable the global IPIF interrupt */
- out_be32(regs_base + XIPIF_V123B_DGIER_OFFSET,
- XIPIF_V123B_GINTR_ENABLE);
+ xspi_write32(xspi, XIPIF_V123B_DGIER_OFFSET, XIPIF_V123B_GINTR_ENABLE);
/* Deselect the slave on the SPI bus */
- out_be32(regs_base + XSPI_SSR_OFFSET, 0xffff);
+ xspi_write32(xspi, XSPI_SSR_OFFSET, 0xffff);
/* Disable the transmitter, enable Manual Slave Select Assertion,
* put SPI controller into master mode, and enable it */
- out_be16(regs_base + XSPI_CR_OFFSET,
- XSPI_CR_TRANS_INHIBIT | XSPI_CR_MANUAL_SSELECT
- | XSPI_CR_MASTER_MODE | XSPI_CR_ENABLE);
+ xspi_write16(xspi, XSPI_CR_OFFSET,
+ XSPI_CR_TRANS_INHIBIT | XSPI_CR_MANUAL_SSELECT |
+ XSPI_CR_MASTER_MODE | XSPI_CR_ENABLE | XSPI_CR_TXFIFO_RESET |
+ XSPI_CR_RXFIFO_RESET);
}
static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)
@@ -115,16 +158,16 @@ static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)
if (is_on == BITBANG_CS_INACTIVE) {
/* Deselect the slave on the SPI bus */
- out_be32(xspi->regs + XSPI_SSR_OFFSET, 0xffff);
+ xspi_write32(xspi, XSPI_SSR_OFFSET, 0xffff);
} else if (is_on == BITBANG_CS_ACTIVE) {
/* Set the SPI clock phase and polarity */
- u16 cr = in_be16(xspi->regs + XSPI_CR_OFFSET)
+ u16 cr = xspi_read16(xspi, XSPI_CR_OFFSET)
& ~XSPI_CR_MODE_MASK;
if (spi->mode & SPI_CPHA)
cr |= XSPI_CR_CPHA;
if (spi->mode & SPI_CPOL)
cr |= XSPI_CR_CPOL;
- out_be16(xspi->regs + XSPI_CR_OFFSET, cr);
+ xspi_write16(xspi, XSPI_CR_OFFSET, cr);
/* We do not check spi->max_speed_hz here as the SPI clock
* frequency is not software programmable (the IP block design
@@ -132,24 +175,27 @@ static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)
*/
/* Activate the chip select */
- out_be32(xspi->regs + XSPI_SSR_OFFSET,
+ xspi_write32(xspi, XSPI_SSR_OFFSET,
~(0x0001 << spi->chip_select));
}
}
/* spi_bitbang requires custom setup_transfer() to be defined if there is a
* custom txrx_bufs(). We have nothing to setup here as the SPI IP block
- * supports just 8 bits per word, and SPI clock can't be changed in software.
- * Check for 8 bits per word. Chip select delay calculations could be
+ * supports 8 or 16 bits per word, which can not be changed in software.
+ * SPI clock can't be changed in software.
+ * Check for correct bits per word. Chip select delay calculations could be
* added here as soon as bitbang_work() can be made aware of the delay value.
*/
static int xilinx_spi_setup_transfer(struct spi_device *spi,
- struct spi_transfer *t)
+ struct spi_transfer *t)
{
u8 bits_per_word;
+ struct xilinx_spi *xspi = spi_master_get_devdata(spi->master);
- bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
- if (bits_per_word != 8) {
+ bits_per_word = (t->bits_per_word) ? t->bits_per_word :
+ spi->bits_per_word;
+ if (bits_per_word != xspi->bits_per_word) {
dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
__func__, bits_per_word);
return -EINVAL;
@@ -160,34 +206,50 @@ static int xilinx_spi_setup_transfer(struct spi_device *spi,
static int xilinx_spi_setup(struct spi_device *spi)
{
- struct spi_bitbang *bitbang;
- struct xilinx_spi *xspi;
- int retval;
-
- xspi = spi_master_get_devdata(spi->master);
- bitbang = &xspi->bitbang;
-
- retval = xilinx_spi_setup_transfer(spi, NULL);
- if (retval < 0)
- return retval;
-
+ /* always return 0, we can not check the number of bits.
+ * There are cases when SPI setup is called before any driver is
+ * there, in that case the SPI core defaults to 8 bits, which we
+ * do not support in some cases. But if we return an error, the
+ * SPI device would not be registered and no driver can get hold of it
+ * When the driver is there, it will call SPI setup again with the
+ * correct number of bits per transfer.
+ * If a driver setups with the wrong bit number, it will fail when
+ * it tries to do a transfer
+ */
return 0;
}
static void xilinx_spi_fill_tx_fifo(struct xilinx_spi *xspi)
{
u8 sr;
+ u8 wsize;
+ if (xspi->bits_per_word == 8)
+ wsize = 1;
+ else if (xspi->bits_per_word == 16)
+ wsize = 2;
+ else
+ wsize = 4;
/* Fill the Tx FIFO with as many bytes as possible */
- sr = in_8(xspi->regs + XSPI_SR_OFFSET);
- while ((sr & XSPI_SR_TX_FULL_MASK) == 0 && xspi->remaining_bytes > 0) {
+ sr = xspi_read8(xspi, XSPI_SR_OFFSET);
+ while ((sr & XSPI_SR_TX_FULL_MASK) == 0 &&
+ xspi->remaining_bytes > 0) {
if (xspi->tx_ptr) {
- out_8(xspi->regs + XSPI_TXD_OFFSET, *xspi->tx_ptr++);
- } else {
- out_8(xspi->regs + XSPI_TXD_OFFSET, 0);
- }
- xspi->remaining_bytes--;
- sr = in_8(xspi->regs + XSPI_SR_OFFSET);
+ if (wsize == 1)
+ xspi_write8(xspi, XSPI_TXD_OFFSET,
+ *xspi->tx_ptr);
+ else if (wsize == 2)
+ xspi_write16(xspi, XSPI_TXD_OFFSET,
+ *(u16 *)(xspi->tx_ptr));
+ else if (wsize == 4)
+ xspi_write32(xspi, XSPI_TXD_OFFSET,
+ *(u32 *)(xspi->tx_ptr));
+
+ xspi->tx_ptr += wsize;
+ } else
+ xspi_write8(xspi, XSPI_TXD_OFFSET, 0);
+ xspi->remaining_bytes -= wsize;
+ sr = xspi_read8(xspi, XSPI_SR_OFFSET);
}
}
@@ -209,23 +271,22 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
/* Enable the transmit empty interrupt, which we use to determine
* progress on the transmission.
*/
- ipif_ier = in_be32(xspi->regs + XIPIF_V123B_IIER_OFFSET);
- out_be32(xspi->regs + XIPIF_V123B_IIER_OFFSET,
+ ipif_ier = xspi_read32(xspi, XIPIF_V123B_IIER_OFFSET);
+ xspi_write32(xspi, XIPIF_V123B_IIER_OFFSET,
ipif_ier | XSPI_INTR_TX_EMPTY);
/* Start the transfer by not inhibiting the transmitter any longer */
- cr = in_be16(xspi->regs + XSPI_CR_OFFSET) & ~XSPI_CR_TRANS_INHIBIT;
- out_be16(xspi->regs + XSPI_CR_OFFSET, cr);
+ cr = xspi_read16(xspi, XSPI_CR_OFFSET) & ~XSPI_CR_TRANS_INHIBIT;
+ xspi_write16(xspi, XSPI_CR_OFFSET, cr);
wait_for_completion(&xspi->done);
/* Disable the transmit empty interrupt */
- out_be32(xspi->regs + XIPIF_V123B_IIER_OFFSET, ipif_ier);
+ xspi_write32(xspi, XIPIF_V123B_IIER_OFFSET, ipif_ier);
return t->len - xspi->remaining_bytes;
}
-
/* This driver supports single master mode only. Hence Tx FIFO Empty
* is the only interrupt we care about.
* Receive FIFO Overrun, Transmit FIFO Underrun, Mode Fault, and Slave Mode
@@ -237,32 +298,50 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id)
u32 ipif_isr;
/* Get the IPIF interrupts, and clear them immediately */
- ipif_isr = in_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET);
- out_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET, ipif_isr);
+ ipif_isr = xspi_read32(xspi, XIPIF_V123B_IISR_OFFSET);
+ xspi_write32(xspi, XIPIF_V123B_IISR_OFFSET, ipif_isr);
if (ipif_isr & XSPI_INTR_TX_EMPTY) { /* Transmission completed */
u16 cr;
u8 sr;
+ u8 rsize;
+ if (xspi->bits_per_word == 8)
+ rsize = 1;
+ else if (xspi->bits_per_word == 16)
+ rsize = 2;
+ else
+ rsize = 4;
/* A transmit has just completed. Process received data and
* check for more data to transmit. Always inhibit the
* transmitter while the Isr refills the transmit register/FIFO,
* or make sure it is stopped if we're done.
*/
- cr = in_be16(xspi->regs + XSPI_CR_OFFSET);
- out_be16(xspi->regs + XSPI_CR_OFFSET,
- cr | XSPI_CR_TRANS_INHIBIT);
+ cr = xspi_read16(xspi, XSPI_CR_OFFSET);
+ xspi_write16(xspi, XSPI_CR_OFFSET, cr | XSPI_CR_TRANS_INHIBIT);
/* Read out all the data from the Rx FIFO */
- sr = in_8(xspi->regs + XSPI_SR_OFFSET);
+ sr = xspi_read8(xspi, XSPI_SR_OFFSET);
while ((sr & XSPI_SR_RX_EMPTY_MASK) == 0) {
- u8 data;
+ u32 data;
+ if (rsize == 1)
+ data = xspi_read8(xspi, XSPI_RXD_OFFSET);
+ else if (rsize == 2)
+ data = xspi_read16(xspi, XSPI_RXD_OFFSET);
+ else
+ data = xspi_read32(xspi, XSPI_RXD_OFFSET);
- data = in_8(xspi->regs + XSPI_RXD_OFFSET);
if (xspi->rx_ptr) {
- *xspi->rx_ptr++ = data;
+ if (rsize == 1)
+ *xspi->rx_ptr = data & 0xff;
+ else if (rsize == 2)
+ *(u16 *)(xspi->rx_ptr) = data & 0xffff;
+ else
+ *((u32 *)(xspi->rx_ptr)) = data;
+ xspi->rx_ptr += rsize;
}
- sr = in_8(xspi->regs + XSPI_SR_OFFSET);
+
+ sr = xspi_read8(xspi, XSPI_SR_OFFSET);
}
/* See if there is more data to send */
@@ -271,7 +350,7 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id)
/* Start the transfer by not inhibiting the
* transmitter any longer
*/
- out_be16(xspi->regs + XSPI_CR_OFFSET, cr);
+ xspi_write16(xspi, XSPI_CR_OFFSET, cr);
} else {
/* No more data to send.
* Indicate the transfer is completed.
@@ -279,44 +358,21 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id)
complete(&xspi->done);
}
}
-
return IRQ_HANDLED;
}
-static int __init xilinx_spi_of_probe(struct of_device *ofdev,
- const struct of_device_id *match)
+struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
+ u32 irq, s16 bus_num, u16 num_chipselect, u8 bits_per_word,
+ bool big_endian)
{
struct spi_master *master;
struct xilinx_spi *xspi;
- struct resource r_irq_struct;
- struct resource r_mem_struct;
-
- struct resource *r_irq = &r_irq_struct;
- struct resource *r_mem = &r_mem_struct;
- int rc = 0;
- const u32 *prop;
- int len;
-
- /* Get resources(memory, IRQ) associated with the device */
- master = spi_alloc_master(&ofdev->dev, sizeof(struct xilinx_spi));
-
- if (master == NULL) {
- return -ENOMEM;
- }
+ int ret = 0;
- dev_set_drvdata(&ofdev->dev, master);
+ master = spi_alloc_master(dev, sizeof(struct xilinx_spi));
- rc = of_address_to_resource(ofdev->node, 0, r_mem);
- if (rc) {
- dev_warn(&ofdev->dev, "invalid address\n");
- goto put_master;
- }
-
- rc = of_irq_to_resource(ofdev->node, 0, r_irq);
- if (rc == NO_IRQ) {
- dev_warn(&ofdev->dev, "no IRQ found\n");
- goto put_master;
- }
+ if (master == NULL)
+ return ERR_PTR(-ENOMEM);
/* the spi->mode bits understood by this driver: */
master->mode_bits = SPI_CPOL | SPI_CPHA;
@@ -329,128 +385,73 @@ static int __init xilinx_spi_of_probe(struct of_device *ofdev,
xspi->bitbang.master->setup = xilinx_spi_setup;
init_completion(&xspi->done);
- xspi->irq = r_irq->start;
-
- if (!request_mem_region(r_mem->start,
- r_mem->end - r_mem->start + 1, XILINX_SPI_NAME)) {
- rc = -ENXIO;
- dev_warn(&ofdev->dev, "memory request failure\n");
+ if (!request_mem_region(mem->start, resource_size(mem),
+ XILINX_SPI_NAME)) {
+ ret = -ENXIO;
goto put_master;
}
- xspi->regs = ioremap(r_mem->start, r_mem->end - r_mem->start + 1);
+ xspi->regs = ioremap(mem->start, resource_size(mem));
if (xspi->regs == NULL) {
- rc = -ENOMEM;
- dev_warn(&ofdev->dev, "ioremap failure\n");
- goto release_mem;
+ ret = -ENOMEM;
+ dev_warn(dev, "ioremap failure\n");
+ goto map_failed;
}
- xspi->irq = r_irq->start;
- /* dynamic bus assignment */
- master->bus_num = -1;
+ master->bus_num = bus_num;
+ master->num_chipselect = num_chipselect;
- /* number of slave select bits is required */
- prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len);
- if (!prop || len < sizeof(*prop)) {
- dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n");
- goto unmap_io;
- }
- master->num_chipselect = *prop;
+ xspi->mem = *mem;
+ xspi->irq = irq;
+ xspi->bits_per_word = bits_per_word;
+ xspi->big_endian = big_endian;
/* SPI controller initializations */
- xspi_init_hw(xspi->regs);
+ xspi_init_hw(xspi);
/* Register for SPI Interrupt */
- rc = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi);
- if (rc != 0) {
- dev_warn(&ofdev->dev, "irq request failure: %d\n", xspi->irq);
+ ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi);
+ if (ret != 0)
goto unmap_io;
- }
- rc = spi_bitbang_start(&xspi->bitbang);
- if (rc != 0) {
- dev_err(&ofdev->dev, "spi_bitbang_start FAILED\n");
+ ret = spi_bitbang_start(&xspi->bitbang);
+ if (ret != 0) {
+ dev_err(dev, "spi_bitbang_start FAILED\n");
goto free_irq;
}
- dev_info(&ofdev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n",
- (unsigned int)r_mem->start, (u32)xspi->regs, xspi->irq);
-
- /* Add any subnodes on the SPI bus */
- of_register_spi_devices(master, ofdev->node);
-
- return rc;
+ dev_info(dev, "at 0x%08X mapped to 0x%08X, irq=%d\n",
+ (u32)mem->start, (u32)xspi->regs, xspi->irq);
+ return master;
free_irq:
free_irq(xspi->irq, xspi);
unmap_io:
iounmap(xspi->regs);
-release_mem:
- release_mem_region(r_mem->start, resource_size(r_mem));
+map_failed:
+ release_mem_region(mem->start, resource_size(mem));
put_master:
spi_master_put(master);
- return rc;
+ return ERR_PTR(ret);
}
+EXPORT_SYMBOL(xilinx_spi_init);
-static int __devexit xilinx_spi_remove(struct of_device *ofdev)
+void xilinx_spi_deinit(struct spi_master *master)
{
struct xilinx_spi *xspi;
- struct spi_master *master;
- struct resource r_mem;
- master = platform_get_drvdata(ofdev);
xspi = spi_master_get_devdata(master);
spi_bitbang_stop(&xspi->bitbang);
free_irq(xspi->irq, xspi);
iounmap(xspi->regs);
- if (!of_address_to_resource(ofdev->node, 0, &r_mem))
- release_mem_region(r_mem.start, resource_size(&r_mem));
- dev_set_drvdata(&ofdev->dev, 0);
- spi_master_put(xspi->bitbang.master);
-
- return 0;
-}
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:" XILINX_SPI_NAME);
-
-static int __exit xilinx_spi_of_remove(struct of_device *op)
-{
- return xilinx_spi_remove(op);
-}
-
-static struct of_device_id xilinx_spi_of_match[] = {
- { .compatible = "xlnx,xps-spi-2.00.a", },
- { .compatible = "xlnx,xps-spi-2.00.b", },
- {}
-};
-
-MODULE_DEVICE_TABLE(of, xilinx_spi_of_match);
-
-static struct of_platform_driver xilinx_spi_of_driver = {
- .owner = THIS_MODULE,
- .name = "xilinx-xps-spi",
- .match_table = xilinx_spi_of_match,
- .probe = xilinx_spi_of_probe,
- .remove = __exit_p(xilinx_spi_of_remove),
- .driver = {
- .name = "xilinx-xps-spi",
- .owner = THIS_MODULE,
- },
-};
-static int __init xilinx_spi_init(void)
-{
- return of_register_platform_driver(&xilinx_spi_of_driver);
+ release_mem_region(xspi->mem.start, resource_size(&xspi->mem));
+ spi_master_put(xspi->bitbang.master);
}
-module_init(xilinx_spi_init);
+EXPORT_SYMBOL(xilinx_spi_deinit);
-static void __exit xilinx_spi_exit(void)
-{
- of_unregister_platform_driver(&xilinx_spi_of_driver);
-}
-module_exit(xilinx_spi_exit);
MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
MODULE_DESCRIPTION("Xilinx SPI driver");
MODULE_LICENSE("GPL");
+
diff --git a/drivers/spi/xilinx_spi.h b/drivers/spi/xilinx_spi.h
new file mode 100644
index 0000000..e0ad67e
--- /dev/null
+++ b/drivers/spi/xilinx_spi.h
@@ -0,0 +1,33 @@
+/*
+ * xilinx_spi.h
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _XILINX_SPI_H_
+#define _XILINX_SPI_H_ 1
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/spi/xilinx_spi.h>
+
+#define XILINX_SPI_NAME "xilinx_spi"
+
+struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
+ u32 irq, s16 bus_num, u16 num_chipselect, u8 bits_per_word,
+ bool big_endian);
+
+void xilinx_spi_deinit(struct spi_master *master);
+#endif
diff --git a/drivers/spi/xilinx_spi_of.c b/drivers/spi/xilinx_spi_of.c
new file mode 100644
index 0000000..f101a9f
--- /dev/null
+++ b/drivers/spi/xilinx_spi_of.c
@@ -0,0 +1,120 @@
+/*
+ * xilinx_spi_of.c
+ *
+ * Xilinx SPI controller driver (master mode only)
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * 2002-2007 (c) MontaVista Software, Inc. 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/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+#include <linux/of_spi.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+
+#include "xilinx_spi.h"
+
+
+static int __init xilinx_spi_of_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct resource r_irq_struct;
+ struct resource r_mem_struct;
+ struct spi_master *master;
+
+ struct resource *r_irq = &r_irq_struct;
+ struct resource *r_mem = &r_mem_struct;
+ int rc = 0;
+ const u32 *prop;
+ int len;
+
+ rc = of_address_to_resource(ofdev->node, 0, r_mem);
+ if (rc) {
+ dev_warn(&ofdev->dev, "invalid address\n");
+ return rc;
+ }
+
+ rc = of_irq_to_resource(ofdev->node, 0, r_irq);
+ if (rc == NO_IRQ) {
+ dev_warn(&ofdev->dev, "no IRQ found\n");
+ return -ENODEV;
+ }
+
+ /* number of slave select bits is required */
+ prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len);
+ if (!prop || len < sizeof(*prop)) {
+ dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n");
+ return -EINVAL;
+ }
+ master = xilinx_spi_init(&ofdev->dev, r_mem, r_irq->start, -1, *prop, 8,
+ true);
+ if (IS_ERR(master))
+ return PTR_ERR(master);
+
+ dev_set_drvdata(&ofdev->dev, master);
+
+ /* Add any subnodes on the SPI bus */
+ of_register_spi_devices(master, ofdev->node);
+
+ return 0;
+}
+
+static int __devexit xilinx_spi_remove(struct of_device *ofdev)
+{
+ xilinx_spi_deinit(dev_get_drvdata(&ofdev->dev));
+ dev_set_drvdata(&ofdev->dev, 0);
+ return 0;
+}
+
+static int __exit xilinx_spi_of_remove(struct of_device *op)
+{
+ return xilinx_spi_remove(op);
+}
+
+static struct of_device_id xilinx_spi_of_match[] = {
+ { .compatible = "xlnx,xps-spi-2.00.a", },
+ { .compatible = "xlnx,xps-spi-2.00.b", },
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, xilinx_spi_of_match);
+
+static struct of_platform_driver xilinx_spi_of_driver = {
+ .owner = THIS_MODULE,
+ .name = "xilinx-xps-spi",
+ .match_table = xilinx_spi_of_match,
+ .probe = xilinx_spi_of_probe,
+ .remove = __exit_p(xilinx_spi_of_remove),
+ .driver = {
+ .name = "xilinx-xps-spi",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init xilinx_spi_of_init(void)
+{
+ return of_register_platform_driver(&xilinx_spi_of_driver);
+}
+module_init(xilinx_spi_of_init);
+
+static void __exit xilinx_spi_of_exit(void)
+{
+ of_unregister_platform_driver(&xilinx_spi_of_driver);
+}
+module_exit(xilinx_spi_of_exit);
+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
+MODULE_DESCRIPTION("Xilinx SPI driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/spi/xilinx_spi_pltfm.c b/drivers/spi/xilinx_spi_pltfm.c
new file mode 100644
index 0000000..81ac297
--- /dev/null
+++ b/drivers/spi/xilinx_spi_pltfm.c
@@ -0,0 +1,104 @@
+/*
+ * xilinx_spi_pltfm.c Support for Xilinx SPI platform devices
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * Xilinx SPI devices as platform devices
+ *
+ * Inspired by xilinx_spi.c, 2002-2007 (c) MontaVista Software, Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/spi/xilinx_spi.h>
+
+#include "xilinx_spi.h"
+
+static int __devinit xilinx_spi_probe(struct platform_device *dev)
+{
+ struct xspi_platform_data *pdata;
+ struct resource *r;
+ int irq;
+ struct spi_master *master;
+ u8 i;
+
+ pdata = dev->dev.platform_data;
+ if (pdata == NULL)
+ return -ENODEV;
+
+ r = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (r == NULL)
+ return -ENODEV;
+
+ irq = platform_get_irq(dev, 0);
+ if (irq < 0)
+ return -ENXIO;
+
+ master = xilinx_spi_init(&dev->dev, r, irq, dev->id,
+ pdata->num_chipselect, pdata->bits_per_word, false);
+ if (IS_ERR(master))
+ return PTR_ERR(master);
+
+ for (i = 0; i < pdata->num_devices; i++)
+ spi_new_device(master, pdata->devices + i);
+
+ platform_set_drvdata(dev, master);
+ return 0;
+}
+
+static int __devexit xilinx_spi_remove(struct platform_device *dev)
+{
+ xilinx_spi_deinit(platform_get_drvdata(dev));
+ platform_set_drvdata(dev, 0);
+
+ return 0;
+}
+
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:" XILINX_SPI_NAME);
+
+static struct platform_driver xilinx_spi_driver = {
+ .probe = xilinx_spi_probe,
+ .remove = __devexit_p(xilinx_spi_remove),
+ .driver = {
+ .name = XILINX_SPI_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init xilinx_spi_pltfm_init(void)
+{
+ return platform_driver_register(&xilinx_spi_driver);
+}
+module_init(xilinx_spi_pltfm_init);
+
+static void __exit xilinx_spi_pltfm_exit(void)
+{
+ platform_driver_unregister(&xilinx_spi_driver);
+}
+module_exit(xilinx_spi_pltfm_exit);
+
+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
+MODULE_DESCRIPTION("Xilinx SPI platform driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/include/linux/spi/xilinx_spi.h b/include/linux/spi/xilinx_spi.h
new file mode 100644
index 0000000..03e1301
--- /dev/null
+++ b/include/linux/spi/xilinx_spi.h
@@ -0,0 +1,19 @@
+#ifndef __LINUX_SPI_XILINX_SPI_H
+#define __LINUX_SPI_XILINX_SPI_H
+
+/**
+ * struct xspi_platform_data - Platform data of the Xilinx SPI driver
+ * @num_chipselect: Number of chip select by the IP
+ * @bits_per_word: Number of bits per word. 8/16/32, Note that the DS464
+ * only support 8bit SPI.
+ * @devices: Devices to add when the driver is probed.
+ * @num_devices: Number of devices in the devices array.
+ */
+struct xspi_platform_data {
+ u16 num_chipselect;
+ u8 bits_per_word;
+ struct spi_board_info *devices;
+ u8 num_devices;
+};
+
+#endif /* __LINUX_SPI_XILINX_SPI_H */
^ permalink raw reply related
* RE: [PATCH v4] xilinx_spi: Splitted into generic, of and platform driver, added support for DS570
From: John Linn @ 2009-09-28 15:41 UTC (permalink / raw)
To: Richard Röjfors, spi-devel-general
Cc: linuxppc-dev, Andrew Morton, dbrownell
In-Reply-To: <4AC0C699.2070506@mocean-labs.com>
> -----Original Message-----
> From: Richard R=F6jfors [mailto:richard.rojfors@mocean-labs.com]
> Sent: Monday, September 28, 2009 8:22 AM
> To: spi-devel-general@lists.sourceforge.net
> Cc: linuxppc-dev@ozlabs.org; dbrownell@users.sourceforge.net; Andrew Mort=
on; John Linn
> Subject: [PATCH v4] xilinx_spi: Splitted into generic, of and platform dr=
iver, added support for
> DS570
> =
> This patch splits xilinx_spi into three parts, an OF and a platform
> driver and generic part.
> =
> The generic part now also works on X86, it supports accessing the IP
> booth big and little endian. There is also support for 16 and 32 bit
> SPI for the Xilinx SPI IP DS570
> =
> Signed-off-by: Richard R=F6jfors <richard.rojfors@mocean-labs.com>
> ---
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 2c733c2..ecabc12 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -218,8 +218,8 @@ config SPI_TXX9
> SPI driver for Toshiba TXx9 MIPS SoCs
> =
<snip>
> =
> -struct xilinx_spi {
> - /* bitbang has to be first */
> - struct spi_bitbang bitbang;
> - struct completion done;
> +/* to follow are some functions that does little of big endian read and
> + * write depending on the config of the device.
> + */
> +static inline void xspi_write8(struct xilinx_spi *xspi, u32 offs, u8 val=
)
> +{
> + iowrite8(val, xspi->regs + offs + ((xspi->big_endian) ? 3 : 0));
> +}
> =
> - void __iomem *regs; /* virt. address of the control registers */
> +static inline void xspi_write16(struct xilinx_spi *xspi, u32 offs, u16 v=
al)
> +{
> + if (xspi->big_endian)
> + iowrite16be(val, xspi->regs + offs + 2);
> + else
> + iowrite16(val, xspi->regs + offs);
> +}
Hi Richard,
If you're worried about efficiency (the reason for 16 and 32 bit xfers), wh=
y wouldn't you do the big-endian vs little endian I/O decision at compile t=
ime rather than run time?
The big_endian variable is not a constant boolean, I don't know if that cou=
ld help so that the compiler optimizes this check away? Or maybe it is alr=
eady and I'm just missing that?
> =
> - u32 irq;
> +static inline void xspi_write32(struct xilinx_spi *xspi, u32 offs, u32 v=
al)
> +{
> + if (xspi->big_endian)
> + iowrite32be(val, xspi->regs + offs);
> + else
> + iowrite32(val, xspi->regs + offs);
> +}
> =
> - u32 speed_hz; /* SCK has a fixed frequency of speed_hz Hz */
> +static inline u8 xspi_read8(struct xilinx_spi *xspi, u32 offs)
> +{
> + return ioread8(xspi->regs + offs + ((xspi->big_endian) ? 3 : 0));
> +}
> =
> - u8 *rx_ptr; /* pointer in the Tx buffer */
> - const u8 *tx_ptr; /* pointer in the Rx buffer */
> - int remaining_bytes; /* the number of bytes left to transfer */
> -};
<snip>
> -
> /* This driver supports single master mode only. Hence Tx FIFO Empty
> * is the only interrupt we care about.
> * Receive FIFO Overrun, Transmit FIFO Underrun, Mode Fault, and Slave M=
ode
> @@ -237,32 +298,50 @@ static irqreturn_t xilinx_spi_irq(int irq, void *de=
v_id)
> u32 ipif_isr;
> =
> /* Get the IPIF interrupts, and clear them immediately */
> - ipif_isr =3D in_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET);
> - out_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET, ipif_isr);
> + ipif_isr =3D xspi_read32(xspi, XIPIF_V123B_IISR_OFFSET);
> + xspi_write32(xspi, XIPIF_V123B_IISR_OFFSET, ipif_isr);
> =
> if (ipif_isr & XSPI_INTR_TX_EMPTY) { /* Transmission completed */
> u16 cr;
> u8 sr;
> + u8 rsize;
> + if (xspi->bits_per_word =3D=3D 8)
> + rsize =3D 1;
> + else if (xspi->bits_per_word =3D=3D 16)
> + rsize =3D 2;
> + else
> + rsize =3D 4;
> =
> /* A transmit has just completed. Process received data and
> * check for more data to transmit. Always inhibit the
> * transmitter while the Isr refills the transmit register/FIFO,
> * or make sure it is stopped if we're done.
> */
> - cr =3D in_be16(xspi->regs + XSPI_CR_OFFSET);
> - out_be16(xspi->regs + XSPI_CR_OFFSET,
> - cr | XSPI_CR_TRANS_INHIBIT);
> + cr =3D xspi_read16(xspi, XSPI_CR_OFFSET);
> + xspi_write16(xspi, XSPI_CR_OFFSET, cr | XSPI_CR_TRANS_INHIBIT);
> =
> /* Read out all the data from the Rx FIFO */
> - sr =3D in_8(xspi->regs + XSPI_SR_OFFSET);
> + sr =3D xspi_read8(xspi, XSPI_SR_OFFSET);
> while ((sr & XSPI_SR_RX_EMPTY_MASK) =3D=3D 0) {
> - u8 data;
> + u32 data;
> + if (rsize =3D=3D 1)
> + data =3D xspi_read8(xspi, XSPI_RXD_OFFSET);
> + else if (rsize =3D=3D 2)
> + data =3D xspi_read16(xspi, XSPI_RXD_OFFSET);
> + else
> + data =3D xspi_read32(xspi, XSPI_RXD_OFFSET);
> =
> - data =3D in_8(xspi->regs + XSPI_RXD_OFFSET);
> if (xspi->rx_ptr) {
> - *xspi->rx_ptr++ =3D data;
> + if (rsize =3D=3D 1)
> + *xspi->rx_ptr =3D data & 0xff;
> + else if (rsize =3D=3D 2)
> + *(u16 *)(xspi->rx_ptr) =3D data & 0xffff;
> + else
> + *((u32 *)(xspi->rx_ptr)) =3D data;
> + xspi->rx_ptr +=3D rsize;
Maybe I'm out of line here...
I'm wondering if this is going to be any more efficient that just using 8 b=
it accesses as it seems like the amount of run-time decisions being made is=
quite a few. I guess it depends on how many bytes are being transferred a=
s with big transfers maybe it will pay off.
In my opinion, which isn't worth much many times :), sometimes the flexibil=
ity with soft logic, like this is a pain for testability and increases comp=
lexity. If there's reasonable performance gains then maybe it's a good trad=
eoff. =
Do you know how much performance gain there is or is expected as maybe you'=
ve seen the pay off already?
Thanks,
John
> }
> - sr =3D in_8(xspi->regs + XSPI_SR_OFFSET);
> +
> + sr =3D xspi_read8(xspi, XSPI_SR_OFFSET);
> }
> =
> /* See if there is more data to send */
> @@ -271,7 +350,7 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_=
id)
> /* Start the transfer by not inhibiting the
> * transmitter any longer
> */
> - out_be16(xspi->regs + XSPI_CR_OFFSET, cr);
> + xspi_write16(xspi, XSPI_CR_OFFSET, cr);
> } else {
> /* No more data to send.
> * Indicate the transfer is completed.
> @@ -279,44 +358,21 @@ static irqreturn_t xilinx_spi_irq(int irq, void *de=
v_id)
> complete(&xspi->done);
> }
> }
> -
> return IRQ_HANDLED;
> }
> =
This email and any attachments are intended for the sole use of the named r=
ecipient(s) and contain(s) confidential information that may be proprietary=
, privileged or copyrighted under applicable law. If you are not the intend=
ed recipient, do not read, copy, or forward this email message or any attac=
hments. Delete this email message and any attachments immediately.
^ permalink raw reply
* Re: warning: allocated section `.data_nosave' not in segment
From: Sean MacLennan @ 2009-09-28 15:53 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20090928013654.466c9b72@opus.seanm.ca>
I looked into it some more.... the patch converts this section:
. = ALIGN(PAGE_SIZE);
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
__nosave_begin = .;
*(.data.nosave)
. = ALIGN(PAGE_SIZE);
__nosave_end = .;
}
to:
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
NOSAVE_DATA
}
If you expand the NOSAVE_DATA macro, you get:
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
. = ALIGN(PAGE_SIZE);
VMLINUX_SYMBOL(__nosave_begin) = .;
*(.data.nosave)
. = ALIGN(PAGE_SIZE);
VMLINUX_SYMBOL(__nosave_end) = .;
}
If you ignore the VMLINUX_SYMBOL, the only difference is moving the
ALIGN inside the brackets. If I move the ALIGN back where it was, then
the warning goes away.
But other sections moved the ALIGN without an issue. Could it be a
compiler problem? We are using version 4.0.0 (DENX ELDK 4.1 4.0.0).
Cheers,
Sean
^ permalink raw reply
* Re: [PATCH 1/8] powerpc/cpm: Remove SPI defines and spi structs
From: Anton Vorontsov @ 2009-09-28 17:34 UTC (permalink / raw)
To: Kumar Gala
Cc: David Brownell, Greg Kroah-Hartman, linux-kernel, linuxppc-dev,
spi-devel-general, Andrew Morton
In-Reply-To: <C37BD1BB-7F53-4CC7-ABB0-BBBDDAC5C052@kernel.crashing.org>
On Fri, Aug 28, 2009 at 12:45:34AM -0500, Kumar Gala wrote:
>
> On Aug 18, 2009, at 5:04 PM, Anton Vorontsov wrote:
>
> >When cpm2.h included into spi_mpc8xxx driver, the SPI defines
> >in the header conflict with defines in the driver.
> >
> >We don't need them in the header file, so remove them. Plus
> >remove "struct spi", we'll use a better version in the driver.
> >
> >Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> >---
> >arch/powerpc/include/asm/cpm1.h | 45
> >---------------------------------------
> >arch/powerpc/include/asm/cpm2.h | 39
> >---------------------------------
> >2 files changed, 0 insertions(+), 84 deletions(-)
>
> applied to next
I can't find it in 2.6.32-rc1. Somehow it got lost from your next tree?
The same for all powerpc patches from this series.
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: warning: allocated section `.data_nosave' not in segment
From: Segher Boessenkool @ 2009-09-28 20:56 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev
In-Reply-To: <20090928115316.7e0b7db9@lappy.seanm.ca>
> If you ignore the VMLINUX_SYMBOL, the only difference is moving the
> ALIGN inside the brackets. If I move the ALIGN back where it was, then
> the warning goes away.
>
> But other sections moved the ALIGN without an issue. Could it be a
> compiler problem? We are using version 4.0.0 (DENX ELDK 4.1 4.0.0).
The compiler version is probably not relevant; the binutils versions
might be though. But, it seems to me the patch was simply botched,
the ALIGN() should not have moved.
Look at the output of "ld -M" (the ld command with all the args that
are used during the compile, with -M added) to see what's up; or maybe
readelf can tell you already.
Segher
^ permalink raw reply
* Re: Market research for new PowerPC system
From: Chris Friesen @ 2009-09-28 23:01 UTC (permalink / raw)
To: Konstantinos Margaritis; +Cc: debian-powerpc, linuxppc-dev, opensuse-ppc
In-Reply-To: <0046254A-432D-4AE3-9B9F-C0D30311B7D7@codex.gr>
On 09/26/2009 05:38 AM, Konstantinos Margaritis wrote:
> I'm considering funding the design & production of a new PowerPC
> system (well, the motherboard, the rest are typical pc stuff and a
> case).
It might be interesting as a low-power system. For a development box,
this looks more interesting:
http://www.fixstars.com/en/products/powerstation/specs.html
$1250 USD gets you two dual-core 2.5GHz 970MP chips.
Chris
^ permalink raw reply
* Re: warning: allocated section `.data_nosave' not in segment
From: Sean MacLennan @ 2009-09-28 23:24 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev
In-Reply-To: <903BCD86-DE53-48AB-89CF-78248D7F6115@kernel.crashing.org>
Here is the ld -M output for the "bad" compile:
.data_nosave 0xc0376790 0x870 load address 0x00376790
0xc0377000 . = ALIGN (0x1000)
*fill* 0xc0376790 0x870 00
0xc0377000 __nosave_begin = .
*(.data.nosave)
0xc0377000 . = ALIGN (0x1000)
0xc0377000 __nosave_end = .
0xc0377000 . = ALIGN (0x1000)
0xc0377000 _edata = .
0xc0377000 PROVIDE (edata, .)
0xc0377000 . = ALIGN (0x0)
0xc0377000 __bss_start = .
0xc0377000 . = ALIGN (0x0)
.sbss 0xc0377000 0xad0 load address 0x00377000
Here is the ld -M output for a "good" compile (i.e. align before
the .data_nosave:
0xc0377000 . = ALIGN (0x1000)
.data_nosave 0xc0377000 0x0 load address 0x00377000
0xc0377000 __nosave_begin = .
*(.data.nosave)
0xc0377000 . = ALIGN (0x1000)
0xc0377000 __nosave_end = .
0xc0377000 . = ALIGN (0x1000)
0xc0377000 _edata = .
0xc0377000 PROVIDE (edata, .)
0xc0377000 . = ALIGN (0x0)
0xc0377000 __bss_start = .
0xc0377000 . = ALIGN (0x0)
.sbss 0xc0377000 0xad0 load address 0x00377000
It looks like putting the align before the .data.nosave puts all the
labels at the same address. Putting it *after* allows the .data_nosave
to be in a different page than the labels.
I can provide more info if needed. But it looks like everything is
nicely aligned, until the data_nosave, which needs the alignment. The
section before it is one of the few with stuff in it.
Cheers,
Sean
^ permalink raw reply
* Re: linux-next: tree build failure
From: Hollis Blanchard @ 2009-09-29 0:00 UTC (permalink / raw)
To: Stephen Rothwell
Cc: linux-kernel, kvm-ppc, linux-next, Jan Beulich, Andrew Morton,
ppc-dev
In-Reply-To: <20090924152102.8d7d40cf.sfr@canb.auug.org.au>
On Thu, 2009-09-24 at 15:21 +1000, Stephen Rothwell wrote:
> Hi all,
>
> Today's linux-next build (powerpc ppc44x_defconfig) failed like this:
>
> In file included from arch/powerpc/kvm/booke.c:31:
> arch/powerpc/kvm/timing.h: In function 'kvmppc_account_exit_stat':
> arch/powerpc/kvm/timing.h:51: error: bit-field '<anonymous>' width not an integer constant
> In file included from arch/powerpc/kvm/booke.h:26,
> from arch/powerpc/kvm/booke_emulate.c:23:
> arch/powerpc/kvm/timing.h: In function 'kvmppc_account_exit_stat':
> arch/powerpc/kvm/timing.h:51: error: bit-field '<anonymous>' width not an integer constant
>
> Presumably caused by commit 8c87df457cb58fe75b9b893007917cf8095660a0
> ("BUILD_BUG_ON(): fix it and a couple of bogus uses of it").
First, I think there is a real bug here, and the code should read like
this (to match the comment):
/* type has to be known at build time for optimization */
- BUILD_BUG_ON(__builtin_constant_p(type));
+ BUILD_BUG_ON(!__builtin_constant_p(type));
However, I get the same build error *both* ways, i.e.
__builtin_constant_p(type) evaluates to both 0 and 1? Either that, or
the new BUILD_BUG_ON() macro isn't working...
> I applied the following patch for today. This inline function is
> only called from one place in one file ...
It's also called via kvmppc_account_exit() from a number of places.
--
Hollis Blanchard
IBM Linux Technology Center
^ permalink raw reply
* Re: warning: allocated section `.data_nosave' not in segment
From: Segher Boessenkool @ 2009-09-29 0:29 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev
In-Reply-To: <20090928192454.4dc937c9@lappy.seanm.ca>
> Here is the ld -M output for the "bad" compile:
>
> .data_nosave 0xc0376790 0x870 load address 0x00376790
> 0xc0377000 . = ALIGN (0x1000)
> *fill* 0xc0376790 0x870 00
Ah right. Having the ALIGN() inside the output section causes the linker
to put some filler in there, which makes it a non-empty section, but this
section isn't assigned to a segment so you get a warning from the linker.
I think the proper way to do this is to not put the ALIGN() before the
output section, nor inside it, but _on_ it, like
.data_nosave : ALIGN(0x1000) { .... }
Segher
^ permalink raw reply
* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Rex Feany @ 2009-09-29 1:21 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <1253843480.7103.492.camel@pasglop>
Thus spake Benjamin Herrenschmidt (benh@kernel.crashing.org):
> On Thu, 2009-09-24 at 18:35 -0700, Rex Feany wrote:
> >
> > Then I can boot and get to a shell, but userspace is slow. 8 seconds
> > to mount
> > /proc (vs. less then a second using my old kernel)! Maybe this is an
> > unrelated issue? I'm pretty clueless about the details, I'm sorry.
> > PG_arch_1 is used to prevent a cache flush unless it is actually
> > needed?
> > Then why would changing the location of the tlbil_va() make a
> > difference?
>
> I think there's more finishyness to 8xx than we thought. IE. That
> tlbil_va might have more reasons to be there than what the comment
> seems to advertize. Can you try to move it even higher up ? IE.
> Unconditionally at the beginning of set_pte_filter ?
>
> Also, if that doesn't help, can you try putting one in
> set_access_flags_filter() just below ?
>
> (Beware that there's two different versions of both functions, only the
> first one is compiled/used on 8xx).
>
> It's going to be hard for me to get that "right" since I don't really
> know what's going on with the core here, but I suppose if we get it
> moving along with extra tlb invalidations, that should be "good enough"
> until somebody who really knows what's going on comes up with possibly
> a better fix.
I've tried sticking tlbil_va() in those places, nothing seems to help.
In some cases userspace is slow, in other cases userspace is faster and
unstable: sometimes commands hang, sometimes I am able to ctrl-c and
and kill it, sometimes I get other strange crashes or falures (so far no
kernel oopses though).
take care!
/rex.
^ permalink raw reply
* Re: Market research for new PowerPC system
From: Brian Morris @ 2009-09-29 3:54 UTC (permalink / raw)
To: Guennadi Liakhovetski
Cc: Konstantinos Margaritis, debian-powerpc, linuxppc-dev,
opensuse-ppc
In-Reply-To: <Pine.LNX.4.64.0909261949240.4273@axis700.grange>
[-- Attachment #1: Type: text/plain, Size: 6781 bytes --]
one other idea (sorry)
Debian is not providing an altivec optimized version. If you want that you
have to go with Gentoo. If you were building cpu optimized from the ground
up with the libaltivec and perhaps the c++ altivec libraries (that require
translation for the changed library calls to all the source codes that use
them -- ughh) -- it would be a lot more interesting. I've thought about
doing the Gentoo but its a lot of compiling, especially on slower cpus (I've
had some experience with fink and macports in MacOSX which want that too)
On Sat, Sep 26, 2009 at 10:58 AM, Guennadi Liakhovetski <
g.liakhovetski@gmx.de> wrote:
> On Sat, 26 Sep 2009, Konstantinos Margaritis wrote:
>
> > (Sorry for the cross-posting, please ignore if you are not interested in
> this,
> > CC me as I'm not subscribed)
> > Hi,
> >
> > First some introductions. I'm Konstantinos Margaritis, a long time
> > Amiga/BeOS/Linux user/developer and a PowerPC fan, former Debian
> Developer,
> > also a SIMD/AltiVec fanatic and the author of libfreevec. I've posted
> this on
> > the following sites:
> >
> >
> http://amigaworld.net/modules/newbb/viewtopic.php?mode=viewtopic&topic_id=29594&forum=33&start=0&viewmode=flat&order=0
> >
> > http://www.amiga.org/forums/showthread.php?t=49424
> >
> >
> http://www.morphzone.org/modules/newbb_plus/viewtopic.php?topic_id=6465&forum=11
> >
> >
> http://aros-exec.org/modules/newbb/viewtopic.php?viewmode=flat&topic_id=3768&forum=4
> >
> >
> http://www.haiku-os.org/community/forum/market_research_new_powerpc_system#comment-12604
> >
> > To anyone who is not a PowerPC user, it might seem like crazy, but here
> it
> > goes:
> >
> > I'm considering funding the design & production of a new PowerPC system
> (well,
> > the motherboard, the rest are typical pc stuff and a case). No this is
> not a
> > joke, I've been wanting to do this for a long time, and perhaps the
> chance
> > will be given to me now. But before I spend any money on this, I want to
> do a
> > little market research first. I know the market is literally "dying" for
> a new
> > powerpc motherboard, but exactly how many are there that want to buy one?
>
> Ok, just a short comment. In principle I like diversity, competition, etc.
> And it was somewhat sad when Apple abandoned ppc. But honestly - why
> should I be buying a ppc desktop system? If we restrict our comparison to
> Linux, because that's what I'm using, what advantages would a ppc system
> give me over a comparable in price ix86 system? This is not meant
> negatively, I just have not followed recent ppc CPUs from the "desktop"
> range, so, this is a real honest question. Would such a system provide
> more MIPS per Watt at the same price? Or more periferals? Or some specific
> hardware blocks unavailable or unsupported om ix86?
>
> Thanks
> Guennadi
>
> >
> > Ok, let's give some rough specs first. I'm considering 3 choices -not in
> order
> > of probability/importance:
> >
> > 1. MPC8640D-based. It will be dual core at 1Ghz -most likely, higher
> > frequencies are much more expensive and the cost of the final board would
> be
> > prohibitive.
> > 2. MPC8610-based. Single core at 1Ghz, slightly less expensive, and
> includes a
> > 2D DIU display unit -quite fast, but no 3D unfortunately.
> > 3. QorIQ P1022-based. Again dual core at 1Ghz (1055Mhz to be precise).
> Apart
> > from the much lower chip price, this one includes dual gigabit ethernet,
> dual
> > SATA, USB 2.0 and a 2D DIU display unit (same as the MPC8610). So this
> one
> > would lower the cost of the board quite much. Disadvantages: No AltiVec
> unit
> > (it sucks I know), though it includes an SPE unit which is not that bad,
> and
> > availability will be in Q3/Q4 2010, so that's a long wait.
> >
> > Now, the end motherboard will probably be MicroATX (in the 8640D/8610
> case) or
> > PicoITX (in the P1022 case), and it will definitely include:
> >
> > * SATA connectors
> > * USB (possibly 2 back and 2 front, but that's discussable)
> > * Dual gigabit (at least one will be there, in the case of the MPC8640D
> we
> > might even have 4!!!)
> > * Sound (of course, SPDIF support will definitely be there)
> > * 1 PCI-e slot 1x
> > * 1 PCI-e slot (4x in the P1022 case, 8x in the MPC86xx cases)
> >
> > Ok, what I want to know is if people would really really buy one of
> these. End
> > price is estimated to be ~around~ 350EUR for the P1022 board or ~500EUR
> > (definitely more in the case of 8640D) in the case of the other boards.
> > Besides being more expensive, the MPC86xx chips, don't include SATA, USB
> and
> > only one of ethernet/sound (quad-gige in MPC8640D case, or sound in the
> case
> > of MPC8610). I know this sounds a lot, but it's the reality, there is not
> > enough funding to build enormous amounts of units and bring the prices
> down
> > substantially, we have to start low and build up from there. In case you
> are
> > wondering, yes, the boards will be designed/produced by bPlan and funded
> by my
> > company (Codex).
> >
> > Support for OSes: Linux definitely, Haiku most probably and there is a
> > possibility of supporting AmigaOS/MorphOS, which will depend on the
> actual
> > feedback I get from those users.
> >
> > I would like to make a list of everyone that is really interested in such
> a
> > system, so it would really help me make a decision sooner rather than
> later if
> > you would send me a few personal details to markos@codex.gr with subject
> > "PowerPC board":
> >
> > * Name
> > * Country
> > * email (definitely, I'd have to reach you back!)
> > * Phone/Skype (optional, please include international prefix)
> > * Forum you saw this post (ok, Morphzone in this case)
> > * OS of preference
> > * board you would be most interested in (MPC8610/MPC8640D/P1022)
> > * preferred price (please have in mind the estimated price quotes I
> mentioned,
> > it might be lower but that's not very probable)
> > * Other notes/comments
> >
> > Also, I found out that I had to state my case on many forums to prove
> that
> > this is not vapourware. Well, it will not be vapourware, if I get
> feedback. So
> > far the feedback I got can be summarized here:
> >
> > http://www.codex.gr/index.php?pageID=&blogItem=60
> >
> > Thanks a lot for your time and I hope this system becomes a reality.
> >
> > Konstantinos Margaritis
> >
> > Codex
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
>
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
>
>
> --
> To UNSUBSCRIBE, email to debian-powerpc-REQUEST@lists.debian.org
> with a subject of "unsubscribe". Trouble? Contact
> listmaster@lists.debian.org
>
>
[-- Attachment #2: Type: text/html, Size: 8892 bytes --]
^ permalink raw reply
* Re: Market research for new PowerPC system
From: Chris "Bigguy" @ 2009-09-29 3:45 UTC (permalink / raw)
To: Konstantinos Margaritis, Chris Friesen
Cc: debian-powerpc, linuxppc-dev, opensuse-ppc
In-Reply-To: <4AC14047.30501@nortel.com>
Speaking for myself, and I'm a small-time consultant to the local Small-Off=
ice Home-Office market, I would wholeheartedly welcome the arrival to the m=
arket of a PowerPC/Power motherboard. I would commission local builders to=
create servers and desktops that would have that one extra layer of protec=
tion from malware.=0A=0AI believe it would also give developers a platform =
to hone their skills on a native platform for the embedded market.=0A=0AI w=
holeheartedly endorse the creation of a PowerPC/POWER motherboard. I'll be=
one of the first customers.=0A=0AAll my best - Chris Reich; Rochester, New=
York=0A=0A=0A=0A--- On Mon, 9/28/09, Chris Friesen <cfriesen@nortel.com> w=
rote:=0A=0A> From: Chris Friesen <cfriesen@nortel.com>=0A> Subject: Re: Mar=
ket research for new PowerPC system=0A> To: "Konstantinos Margaritis" <mark=
os@codex.gr>=0A> Cc: linuxppc-dev@lists.ozlabs.org, debian-powerpc@lists.de=
bian.org, opensuse-ppc@opensuse.org=0A> Date: Monday, September 28, 2009, 7=
:01 PM=0A> On 09/26/2009 05:38 AM, Konstantinos=0A> Margaritis wrote:=0A> =
=0A> > I'm considering funding the design & production of=0A> a new PowerPC=
=A0 =0A> > system (well, the motherboard, the rest are typical pc=0A> stuff=
and a=A0 =0A> > case).=0A> =0A> It might be interesting as a low-power sys=
tem.=A0 For a=0A> development box,=0A> this looks more interesting:=0A> =0A=
> http://www.fixstars.com/en/products/powerstation/specs.html=0A> =0A> $125=
0 USD gets you two dual-core 2.5GHz 970MP chips.=0A> =0A> Chris=0A> =0A> =
=0A> -- =0A> To UNSUBSCRIBE, email to debian-powerpc-REQUEST@lists.debian.o=
rg=0A> with a subject of "unsubscribe". Trouble? Contact listmaster@lists.d=
ebian.org=0A> =0A>
^ permalink raw reply
* Re: Market research for new PowerPC system
From: Brian Morris @ 2009-09-29 3:46 UTC (permalink / raw)
To: Guennadi Liakhovetski
Cc: Konstantinos Margaritis, debian-powerpc, linuxppc-dev,
opensuse-ppc
In-Reply-To: <Pine.LNX.4.64.0909261949240.4273@axis700.grange>
[-- Attachment #1: Type: text/plain, Size: 7025 bytes --]
I think that you should start out with something of the sub-netbook type.
These are the next generation and coming up very soon. For a home computer
you need at least dual core and at those speeds it will need a very low
price and small footprint.
If you could sneak in on the sub-net quick perhaps power could become 2nd to
ARM as AMD is to Intel. Intel is trying to sneak in but there could be some
anti-trust issues, especially if there are other contenders (maybe).
Its really too too bad PA-SEMI killed by apple last year. I am still mad
about that. That was a really really nice cpu, 2ghz and 7watt and 64bit.
Should have been illegal.
The first subnetbook may likely be an apple product, and a tablet with an
optional separate keyboard and a 9.5 inch screen, and the ARM cpu...
On Sat, Sep 26, 2009 at 10:58 AM, Guennadi Liakhovetski <
g.liakhovetski@gmx.de> wrote:
> On Sat, 26 Sep 2009, Konstantinos Margaritis wrote:
>
> > (Sorry for the cross-posting, please ignore if you are not interested in
> this,
> > CC me as I'm not subscribed)
> > Hi,
> >
> > First some introductions. I'm Konstantinos Margaritis, a long time
> > Amiga/BeOS/Linux user/developer and a PowerPC fan, former Debian
> Developer,
> > also a SIMD/AltiVec fanatic and the author of libfreevec. I've posted
> this on
> > the following sites:
> >
> >
> http://amigaworld.net/modules/newbb/viewtopic.php?mode=viewtopic&topic_id=29594&forum=33&start=0&viewmode=flat&order=0
> >
> > http://www.amiga.org/forums/showthread.php?t=49424
> >
> >
> http://www.morphzone.org/modules/newbb_plus/viewtopic.php?topic_id=6465&forum=11
> >
> >
> http://aros-exec.org/modules/newbb/viewtopic.php?viewmode=flat&topic_id=3768&forum=4
> >
> >
> http://www.haiku-os.org/community/forum/market_research_new_powerpc_system#comment-12604
> >
> > To anyone who is not a PowerPC user, it might seem like crazy, but here
> it
> > goes:
> >
> > I'm considering funding the design & production of a new PowerPC system
> (well,
> > the motherboard, the rest are typical pc stuff and a case). No this is
> not a
> > joke, I've been wanting to do this for a long time, and perhaps the
> chance
> > will be given to me now. But before I spend any money on this, I want to
> do a
> > little market research first. I know the market is literally "dying" for
> a new
> > powerpc motherboard, but exactly how many are there that want to buy one?
>
> Ok, just a short comment. In principle I like diversity, competition, etc.
> And it was somewhat sad when Apple abandoned ppc. But honestly - why
> should I be buying a ppc desktop system? If we restrict our comparison to
> Linux, because that's what I'm using, what advantages would a ppc system
> give me over a comparable in price ix86 system? This is not meant
> negatively, I just have not followed recent ppc CPUs from the "desktop"
> range, so, this is a real honest question. Would such a system provide
> more MIPS per Watt at the same price? Or more periferals? Or some specific
> hardware blocks unavailable or unsupported om ix86?
>
> Thanks
> Guennadi
>
> >
> > Ok, let's give some rough specs first. I'm considering 3 choices -not in
> order
> > of probability/importance:
> >
> > 1. MPC8640D-based. It will be dual core at 1Ghz -most likely, higher
> > frequencies are much more expensive and the cost of the final board would
> be
> > prohibitive.
> > 2. MPC8610-based. Single core at 1Ghz, slightly less expensive, and
> includes a
> > 2D DIU display unit -quite fast, but no 3D unfortunately.
> > 3. QorIQ P1022-based. Again dual core at 1Ghz (1055Mhz to be precise).
> Apart
> > from the much lower chip price, this one includes dual gigabit ethernet,
> dual
> > SATA, USB 2.0 and a 2D DIU display unit (same as the MPC8610). So this
> one
> > would lower the cost of the board quite much. Disadvantages: No AltiVec
> unit
> > (it sucks I know), though it includes an SPE unit which is not that bad,
> and
> > availability will be in Q3/Q4 2010, so that's a long wait.
> >
> > Now, the end motherboard will probably be MicroATX (in the 8640D/8610
> case) or
> > PicoITX (in the P1022 case), and it will definitely include:
> >
> > * SATA connectors
> > * USB (possibly 2 back and 2 front, but that's discussable)
> > * Dual gigabit (at least one will be there, in the case of the MPC8640D
> we
> > might even have 4!!!)
> > * Sound (of course, SPDIF support will definitely be there)
> > * 1 PCI-e slot 1x
> > * 1 PCI-e slot (4x in the P1022 case, 8x in the MPC86xx cases)
> >
> > Ok, what I want to know is if people would really really buy one of
> these. End
> > price is estimated to be ~around~ 350EUR for the P1022 board or ~500EUR
> > (definitely more in the case of 8640D) in the case of the other boards.
> > Besides being more expensive, the MPC86xx chips, don't include SATA, USB
> and
> > only one of ethernet/sound (quad-gige in MPC8640D case, or sound in the
> case
> > of MPC8610). I know this sounds a lot, but it's the reality, there is not
> > enough funding to build enormous amounts of units and bring the prices
> down
> > substantially, we have to start low and build up from there. In case you
> are
> > wondering, yes, the boards will be designed/produced by bPlan and funded
> by my
> > company (Codex).
> >
> > Support for OSes: Linux definitely, Haiku most probably and there is a
> > possibility of supporting AmigaOS/MorphOS, which will depend on the
> actual
> > feedback I get from those users.
> >
> > I would like to make a list of everyone that is really interested in such
> a
> > system, so it would really help me make a decision sooner rather than
> later if
> > you would send me a few personal details to markos@codex.gr with subject
> > "PowerPC board":
> >
> > * Name
> > * Country
> > * email (definitely, I'd have to reach you back!)
> > * Phone/Skype (optional, please include international prefix)
> > * Forum you saw this post (ok, Morphzone in this case)
> > * OS of preference
> > * board you would be most interested in (MPC8610/MPC8640D/P1022)
> > * preferred price (please have in mind the estimated price quotes I
> mentioned,
> > it might be lower but that's not very probable)
> > * Other notes/comments
> >
> > Also, I found out that I had to state my case on many forums to prove
> that
> > this is not vapourware. Well, it will not be vapourware, if I get
> feedback. So
> > far the feedback I got can be summarized here:
> >
> > http://www.codex.gr/index.php?pageID=&blogItem=60
> >
> > Thanks a lot for your time and I hope this system becomes a reality.
> >
> > Konstantinos Margaritis
> >
> > Codex
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
>
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
>
>
> --
> To UNSUBSCRIBE, email to debian-powerpc-REQUEST@lists.debian.org
> with a subject of "unsubscribe". Trouble? Contact
> listmaster@lists.debian.org
>
>
[-- Attachment #2: Type: text/html, Size: 9183 bytes --]
^ permalink raw reply
* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Joakim Tjernlund @ 2009-09-29 6:26 UTC (permalink / raw)
To: Rex Feany; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <20090929012106.GA22798@compile2.chatsunix.int.mrv.com>
>
> Thus spake Benjamin Herrenschmidt (benh@kernel.crashing.org):
>
> > On Thu, 2009-09-24 at 18:35 -0700, Rex Feany wrote:
> > >
> > > Then I can boot and get to a shell, but userspace is slow. 8 seconds
> > > to mount
> > > /proc (vs. less then a second using my old kernel)! Maybe this is an
> > > unrelated issue? I'm pretty clueless about the details, I'm sorry.
> > > PG_arch_1 is used to prevent a cache flush unless it is actually
> > > needed?
> > > Then why would changing the location of the tlbil_va() make a
> > > difference?
> >
> > I think there's more finishyness to 8xx than we thought. IE. That
> > tlbil_va might have more reasons to be there than what the comment
> > seems to advertize. Can you try to move it even higher up ? IE.
> > Unconditionally at the beginning of set_pte_filter ?
> >
> > Also, if that doesn't help, can you try putting one in
> > set_access_flags_filter() just below ?
> >
> > (Beware that there's two different versions of both functions, only the
> > first one is compiled/used on 8xx).
> >
> > It's going to be hard for me to get that "right" since I don't really
> > know what's going on with the core here, but I suppose if we get it
> > moving along with extra tlb invalidations, that should be "good enough"
> > until somebody who really knows what's going on comes up with possibly
> > a better fix.
>
> I've tried sticking tlbil_va() in those places, nothing seems to help.
> In some cases userspace is slow, in other cases userspace is faster and
> unstable: sometimes commands hang, sometimes I am able to ctrl-c and
> and kill it, sometimes I get other strange crashes or falures (so far no
> kernel oopses though).
This is exactly what you get when the "cache insn does not update DAR" bug hits
you.
^ permalink raw reply
* Re: [PATCH v4] xilinx_spi: Splitted into generic, of and platform driver, added support for DS570
From: Richard Röjfors @ 2009-09-29 6:34 UTC (permalink / raw)
To: John Linn; +Cc: spi-devel-general, Andrew Morton, dbrownell, linuxppc-dev
In-Reply-To: <8741a4f8-b490-4754-a674-71ea2ee1385a@SG2EHSMHS011.ehs.local>
On 9/28/09 5:41 PM, John Linn wrote:
>> -----Original Message-----
>> From: Richard Röjfors [mailto:richard.rojfors@mocean-labs.com]
>> Sent: Monday, September 28, 2009 8:22 AM
>> To: spi-devel-general@lists.sourceforge.net
>> Cc: linuxppc-dev@ozlabs.org; dbrownell@users.sourceforge.net; Andrew Morton; John Linn
>> Subject: [PATCH v4] xilinx_spi: Splitted into generic, of and platform driver, added support for
>> DS570
>>
>> This patch splits xilinx_spi into three parts, an OF and a platform
>> driver and generic part.
>>
>> The generic part now also works on X86, it supports accessing the IP
>> booth big and little endian. There is also support for 16 and 32 bit
>> SPI for the Xilinx SPI IP DS570
>>
>> Signed-off-by: Richard Röjfors <richard.rojfors@mocean-labs.com>
>> ---
>> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
>> index 2c733c2..ecabc12 100644
>> --- a/drivers/spi/Kconfig
>> +++ b/drivers/spi/Kconfig
>> @@ -218,8 +218,8 @@ config SPI_TXX9
>> SPI driver for Toshiba TXx9 MIPS SoCs
>>
>
> <snip>
>
>>
>> -struct xilinx_spi {
>> - /* bitbang has to be first */
>> - struct spi_bitbang bitbang;
>> - struct completion done;
>> +/* to follow are some functions that does little of big endian read and
>> + * write depending on the config of the device.
>> + */
>> +static inline void xspi_write8(struct xilinx_spi *xspi, u32 offs, u8 val)
>> +{
>> + iowrite8(val, xspi->regs + offs + ((xspi->big_endian) ? 3 : 0));
>> +}
>>
>> - void __iomem *regs; /* virt. address of the control registers */
>> +static inline void xspi_write16(struct xilinx_spi *xspi, u32 offs, u16 val)
>> +{
>> + if (xspi->big_endian)
>> + iowrite16be(val, xspi->regs + offs + 2);
>> + else
>> + iowrite16(val, xspi->regs + offs);
>> +}
>
>
> Hi Richard,
Hi John,
Thanks for the quick feedback.
> If you're worried about efficiency (the reason for 16 and 32 bit xfers), why wouldn't you do the big-endian vs little endian I/O decision at compile time rather than run time?
I'm afraid we can't do it compile time, if we want to be flexible. As
example;
The IP is big endian, in our case the PCI interface flips the byte
order. But the PCI interface might be setup differently ->would be
accessed big endian even on a little endian machine.
We could use callbacks set up during probe, instead of having the
if-sentence. But I don't think the callback solution could be slower (if
talking performance), since the compiler can't inline them, the current
functions could be inlined if the compiler feels like it.
> The big_endian variable is not a constant boolean, I don't know if that could help so that the compiler optimizes this check away? Or maybe it is already and I'm just missing that?
>
>>
>> - u32 irq;
>> +static inline void xspi_write32(struct xilinx_spi *xspi, u32 offs, u32 val)
>> +{
>> + if (xspi->big_endian)
>> + iowrite32be(val, xspi->regs + offs);
>> + else
>> + iowrite32(val, xspi->regs + offs);
>> +}
>>
>> - u32 speed_hz; /* SCK has a fixed frequency of speed_hz Hz */
>> +static inline u8 xspi_read8(struct xilinx_spi *xspi, u32 offs)
>> +{
>> + return ioread8(xspi->regs + offs + ((xspi->big_endian) ? 3 : 0));
>> +}
>>
>> - u8 *rx_ptr; /* pointer in the Tx buffer */
>> - const u8 *tx_ptr; /* pointer in the Rx buffer */
>> - int remaining_bytes; /* the number of bytes left to transfer */
>> -};
>
> <snip>
>
>> -
>> /* This driver supports single master mode only. Hence Tx FIFO Empty
>> * is the only interrupt we care about.
>> * Receive FIFO Overrun, Transmit FIFO Underrun, Mode Fault, and Slave Mode
>> @@ -237,32 +298,50 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id)
>> u32 ipif_isr;
>>
>> /* Get the IPIF interrupts, and clear them immediately */
>> - ipif_isr = in_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET);
>> - out_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET, ipif_isr);
>> + ipif_isr = xspi_read32(xspi, XIPIF_V123B_IISR_OFFSET);
>> + xspi_write32(xspi, XIPIF_V123B_IISR_OFFSET, ipif_isr);
>>
>> if (ipif_isr & XSPI_INTR_TX_EMPTY) { /* Transmission completed */
>> u16 cr;
>> u8 sr;
>> + u8 rsize;
>> + if (xspi->bits_per_word == 8)
>> + rsize = 1;
>> + else if (xspi->bits_per_word == 16)
>> + rsize = 2;
>> + else
>> + rsize = 4;
>>
>> /* A transmit has just completed. Process received data and
>> * check for more data to transmit. Always inhibit the
>> * transmitter while the Isr refills the transmit register/FIFO,
>> * or make sure it is stopped if we're done.
>> */
>> - cr = in_be16(xspi->regs + XSPI_CR_OFFSET);
>> - out_be16(xspi->regs + XSPI_CR_OFFSET,
>> - cr | XSPI_CR_TRANS_INHIBIT);
>> + cr = xspi_read16(xspi, XSPI_CR_OFFSET);
>> + xspi_write16(xspi, XSPI_CR_OFFSET, cr | XSPI_CR_TRANS_INHIBIT);
>>
>> /* Read out all the data from the Rx FIFO */
>> - sr = in_8(xspi->regs + XSPI_SR_OFFSET);
>> + sr = xspi_read8(xspi, XSPI_SR_OFFSET);
>> while ((sr & XSPI_SR_RX_EMPTY_MASK) == 0) {
>> - u8 data;
>> + u32 data;
>> + if (rsize == 1)
>> + data = xspi_read8(xspi, XSPI_RXD_OFFSET);
>> + else if (rsize == 2)
>> + data = xspi_read16(xspi, XSPI_RXD_OFFSET);
>> + else
>> + data = xspi_read32(xspi, XSPI_RXD_OFFSET);
>>
>> - data = in_8(xspi->regs + XSPI_RXD_OFFSET);
>> if (xspi->rx_ptr) {
>> - *xspi->rx_ptr++ = data;
>> + if (rsize == 1)
>> + *xspi->rx_ptr = data & 0xff;
>> + else if (rsize == 2)
>> + *(u16 *)(xspi->rx_ptr) = data & 0xffff;
>> + else
>> + *((u32 *)(xspi->rx_ptr)) = data;
>> + xspi->rx_ptr += rsize;
>
> Maybe I'm out of line here...
>
> I'm wondering if this is going to be any more efficient that just using 8 bit accesses
We can not do 8 bit accesses if the IP is set up to do 16/32bit SPI,
then the TX/RX registers are as wide as the bit setup.
We could do 32 bit reads from the registers, then we waste some cycles
on the PLB bus, but have slightly simpler code.
> as it seems like the amount of run-time decisions being made is quite a few. I guess it depends on how many bytes are being transferred as with big transfers maybe it will pay off.
>
> In my opinion, which isn't worth much many times :), sometimes the flexibility with soft logic, like this is a pain for testability and increases complexity. If there's reasonable performance gains then maybe it's a good tradeoff.
>
> Do you know how much performance gain there is or is expected as maybe you've seen the pay off already?
I haven't done any measurements, and we are basically only controlling
GPIO so performance is not an issue for us. I just didn't want do make
it slower. I think you have more experience here. Do you think it's
better to just do 32bit reads to make the code simple? If so I will
update the code.
Thanks
--Richard
^ permalink raw reply
* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Benjamin Herrenschmidt @ 2009-09-29 7:07 UTC (permalink / raw)
To: Rex Feany; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <20090929012106.GA22798@compile2.chatsunix.int.mrv.com>
On Mon, 2009-09-28 at 18:21 -0700, Rex Feany wrote:
> > It's going to be hard for me to get that "right" since I don't really
> > know what's going on with the core here, but I suppose if we get it
> > moving along with extra tlb invalidations, that should be "good enough"
> > until somebody who really knows what's going on comes up with possibly
> > a better fix.
>
> I've tried sticking tlbil_va() in those places, nothing seems to help.
> In some cases userspace is slow, in other cases userspace is faster and
> unstable: sometimes commands hang, sometimes I am able to ctrl-c and
> and kill it, sometimes I get other strange crashes or falures (so far no
> kernel oopses though).
And you are positive that with 2.6.31 and your other patch, it works
both fast and stable ? This is strange... the code should be mostly
identical. I'll have a second look and see if I can get you a patch that
reproduce -exactly- the behaviour of 2.6.31 plus your patch.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Benjamin Herrenschmidt @ 2009-09-29 7:07 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: linuxppc-dev@ozlabs.org, Rex Feany
In-Reply-To: <OF1870F4D5.BB673882-ONC1257640.00233638-C1257640.00236DC9@transmode.se>
On Tue, 2009-09-29 at 08:26 +0200, Joakim Tjernlund wrote:
> > I've tried sticking tlbil_va() in those places, nothing seems to
> help.
> > In some cases userspace is slow, in other cases userspace is faster
> and
> > unstable: sometimes commands hang, sometimes I am able to ctrl-c and
> > and kill it, sometimes I get other strange crashes or falures (so
> far no
> > kernel oopses though).
>
> This is exactly what you get when the "cache insn does not update DAR"
> bug hits
> you.
But then why was it working fine before ? Or it wasn't ?
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Joakim Tjernlund @ 2009-09-29 8:13 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev@ozlabs.org, Rex Feany
In-Reply-To: <1254208057.5771.7.camel@pasglop>
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote on 29/09/2009 09:07:37:
>
> On Tue, 2009-09-29 at 08:26 +0200, Joakim Tjernlund wrote:
> > > I've tried sticking tlbil_va() in those places, nothing seems to
> > help.
> > > In some cases userspace is slow, in other cases userspace is faster
> > and
> > > unstable: sometimes commands hang, sometimes I am able to ctrl-c and
> > > and kill it, sometimes I get other strange crashes or falures (so
> > far no
> > > kernel oopses though).
> >
> > This is exactly what you get when the "cache insn does not update DAR"
> > bug hits
> > you.
>
> But then why was it working fine before ? Or it wasn't ?
hmm, yes. You do get this and mysterious SEGV if you hit the but so does
other bugs too so this is probably due to missing invalidation.
I suspect that something like below will fix the problem and
is the "correct" fix(untested, not even compiled):
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 52ff8c5..f579a11 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -428,7 +428,7 @@ DataStoreTLBMiss:
* set. All other Linux PTE bits control the behavior
* of the MMU.
*/
-2: li r11, 0x00f0
+ li r11, 0x00f0
rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
DO_8xx_CPU6(0x3d80, r3)
mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
@@ -441,7 +441,23 @@ DataStoreTLBMiss:
lwz r3, 8(r0)
#endif
rfi
+2:
+ /* Copy 20 msb from MD_EPN to DAR since the dcxx instructions fails
+ * to update DAR when they cause a DTLB Miss.
+ */
+ mfspr r11, SPRN_MD_EPN
+ mfspr r10, SPRN_DAR
+ rlwimi r10, r11, 0, 0, 19
+ mtspr SPRN_DAR, r10
+ mfspr r10, SPRN_M_TW /* Restore registers */
+ lwz r11, 0(r0)
+ mtcr r11
+ lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+ lwz r3, 8(r0)
+#endif
+ b DataAccess
/* This is an instruction TLB error on the MPC8xx. This could be due
* to many reasons, such as executing guarded memory or illegal instruction
* addresses. There is nothing to do but handle a big time error fault.
^ permalink raw reply related
* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Benjamin Herrenschmidt @ 2009-09-29 8:16 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: linuxppc-dev@ozlabs.org, Rex Feany
In-Reply-To: <OF490DC464.F75531A6-ONC1257640.002AC41C-C1257640.002D2820@transmode.se>
> hmm, yes. You do get this and mysterious SEGV if you hit the but so does
> other bugs too so this is probably due to missing invalidation.
>
> I suspect that something like below will fix the problem and
> is the "correct" fix(untested, not even compiled):
Ok but do we also still have to worry about the "unpopulated" TLB
entries and invalidate them somehow when populating ?
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Joakim Tjernlund @ 2009-09-29 8:24 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev@ozlabs.org, Rex Feany
In-Reply-To: <1254212198.5256.0.camel@pasglop>
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote on 29/09/2009 10:16:38:
>
>
> > hmm, yes. You do get this and mysterious SEGV if you hit the but so does
> > other bugs too so this is probably due to missing invalidation.
> >
> > I suspect that something like below will fix the problem and
> > is the "correct" fix(untested, not even compiled):
>
> Ok but do we also still have to worry about the "unpopulated" TLB
> entries and invalidate them somehow when populating ?
No, this patch is to not populate the MMU with invalid entries at
all. Hopefully you can remove those invalidate 8xx TLBs hacks
you currently have.
Jocke
^ permalink raw reply
* Re: linux-next: tree build failure
From: Jan Beulich @ 2009-09-29 9:28 UTC (permalink / raw)
To: sfr, hollisb; +Cc: akpm, linux-next, linuxppc-dev, linux-kernel, kvm-ppc
>>> Hollis Blanchard 09/29/09 2:00 AM >>>
>First, I think there is a real bug here, and the code should read like
>this (to match the comment):
> /* type has to be known at build time for optimization */
>- BUILD_BUG_ON(__builtin_constant_p(type));
>+ BUILD_BUG_ON(!__builtin_constant_p(type));
>
>However, I get the same build error *both* ways, i.e.
>__builtin_constant_p(type) evaluates to both 0 and 1? Either that, or
>the new BUILD_BUG_ON() macro isn't working...
No, at this point of the compilation process it's neither zero nor one,
it's simply considered non-constant by the compiler at that stage
(this builtin is used for optimization, not during parsing, and the
error gets generated when the body of the function gets parsed,
not when code gets generated from it).
Jan
^ permalink raw reply
* Re: linux-next: tree build failure
From: roel kluin @ 2009-09-29 9:51 UTC (permalink / raw)
To: Jan Beulich
Cc: sfr, hollisb, linux-kernel, kvm-ppc, linux-next, akpm,
linuxppc-dev
In-Reply-To: <4AC1E15502000078000516B5@vpn.id2.novell.com>
On Tue, Sep 29, 2009 at 11:28 AM, Jan Beulich <jbeulich@novell.com> wrote:
>>>> Hollis Blanchard =A009/29/09 2:00 AM >>>
>>First, I think there is a real bug here, and the code should read like
>>this (to match the comment):
>> =A0 =A0/* type has to be known at build time for optimization */
>>- =A0 =A0BUILD_BUG_ON(__builtin_constant_p(type));
>>+ =A0 =A0BUILD_BUG_ON(!__builtin_constant_p(type));
>>
>>However, I get the same build error *both* ways, i.e.
>>__builtin_constant_p(type) evaluates to both 0 and 1? Either that, or
>>the new BUILD_BUG_ON() macro isn't working...
>
> No, at this point of the compilation process it's neither zero nor one,
> it's simply considered non-constant by the compiler at that stage
> (this builtin is used for optimization, not during parsing, and the
> error gets generated when the body of the function gets parsed,
> not when code gets generated from it).
>
> Jan
then maybe
if(__builtin_constant_p(type))
BUILD_BUG_ON(1);
would work?
Roel
^ permalink raw reply
* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Joakim Tjernlund @ 2009-09-29 11:56 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev@ozlabs.org, Rex Feany
In-Reply-To: <1254212198.5256.0.camel@pasglop>
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote on 29/09/2009 10:16:38:
>
>
> > hmm, yes. You do get this and mysterious SEGV if you hit the but so does
> > other bugs too so this is probably due to missing invalidation.
> >
> > I suspect that something like below will fix the problem and
> > is the "correct" fix(untested, not even compiled):
>
> Ok but do we also still have to worry about the "unpopulated" TLB
> entries and invalidate them somehow when populating ?
Since I am probably the only one that knows about DAR problem I figured
I should take a stab at it. This is not tested, but I hope Rex and the list
can do that. Once this works as it should, we can remove all special handling
for 8xx in copy_tofrom_user() and friends.
No sign-off yet, want some confirmation first.
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 4dd38f1..691ebd3 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -774,7 +774,14 @@ restore:
lwz r11,_CTR(r1)
mtspr SPRN_XER,r10
mtctr r11
-
+#ifdef CONFIG_8xx
+ /* Tag DAR with a well know value.
+ * This needs to match head_8xx.S and
+ * do_page_fault()
+ */
+ li r10, 0xf0
+ mtspr SPRN_DAR, r10
+#endif
PPC405_ERR77(0,r1)
BEGIN_FTR_SECTION
lwarx r11,0,r1
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 52ff8c5..418ea96 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -39,6 +39,15 @@
#else
#define DO_8xx_CPU6(val, reg)
#endif
+
+/* DAR needs to be tagged with a known value so that the
+ * DataTLB Miss/Error and do_page_fault() can recognize a
+ * buggy dcbx instruction and workaround the problem.
+ * dcbf, dcbi, dcbst, dcbz instructions do not update DAR
+ * when trapping into a Data TLB Miss/Error. See
+ * DataStoreTLBMiss and DataTLBError for details
+ */
+
__HEAD
_ENTRY(_stext);
_ENTRY(_start);
@@ -428,7 +437,8 @@ DataStoreTLBMiss:
* set. All other Linux PTE bits control the behavior
* of the MMU.
*/
-2: li r11, 0x00f0
+ li r11, 0x00f0
+ mtspr SPRN_DAR, r11 /* Tag DAR */
rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
DO_8xx_CPU6(0x3d80, r3)
mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
@@ -441,7 +451,15 @@ DataStoreTLBMiss:
lwz r3, 8(r0)
#endif
rfi
-
+2:
+ mfspr r10, SPRN_M_TW /* Restore registers */
+ lwz r11, 0(r0)
+ mtcr r11
+ lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+ lwz r3, 8(r0)
+#endif
+ b DataAccess
/* This is an instruction TLB error on the MPC8xx. This could be due
* to many reasons, such as executing guarded memory or illegal instruction
* addresses. There is nothing to do but handle a big time error fault.
@@ -492,6 +510,8 @@ DataTLBError:
* assuming we only use the dcbi instruction on kernel addresses.
*/
mfspr r10, SPRN_DAR
+ cmpwi cr0, r10, 0xf0 /* check it DAR holds a tag */
+ beq- 2f
rlwinm r11, r10, 0, 0, 19
ori r11, r11, MD_EVALID
mfspr r10, SPRN_M_CASID
@@ -547,6 +567,7 @@ DataTLBError:
* of the MMU.
*/
li r11, 0x00f0
+ mtspr SPRN_DAR, r11 /* Tag DAR */
rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
DO_8xx_CPU6(0x3d80, r3)
mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 7699394..be779b2 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -125,6 +125,32 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
int trap = TRAP(regs);
int is_exec = trap == 0x400;
+#if defined(CONFIG_8xx)
+/*
+ Workarund DTLB Miss/Error, as these do not update DAR
+ for dcbf, dcbi, dcbst, dcbz instructions
+ This relies on every exception tagging DAR with 0xf0
+ before returning (rfi)
+ DAR as passed as address to this function.
+ */
+#define RA(inst) (((inst) & 0x001F0000) >> 16)
+#define RB(inst) (((inst) & 0x0000F800) >> 11)
+ {
+ unsigned long ra, rb, dar, insns;
+
+ if (trap == 0x300 && address == 0xf0) {
+ insns = *((unsigned long *)regs->nip);
+ /* Really check if it is an dcbf, dcbi, dcbst, dcbz insns ? */
+ ra = RA(insns); /* Reg Ra */
+ rb = RB(insns); /* Reg Rb */
+ dar = regs->gpr[rb];
+ if (ra)
+ dar += regs->gpr[ra];
+ /* regs->dar = dar; perhaps */
+ address = dar;
+ }
+ }
+#endif
#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
/*
* Fortunately the bit assignments in SRR1 for an instruction
^ permalink raw reply related
* [PATCH 1/1] powerpc: Add kdump support to Collaborative Memory Manager
From: Brian King @ 2009-09-29 14:46 UTC (permalink / raw)
To: benh; +Cc: brking, linuxppc-dev
When running Active Memory Sharing, the Collaborative Memory Manager (CMM)
may mark some pages as "loaned" with the hypervisor. Periodically, the
CMM will query the hypervisor for a loan request, which is a single signed
value. When kexec'ing into a kdump kernel, the CMM driver in the kdump
kernel is not aware of the pages the previous kernel had marked as "loaned",
so the hypervisor and the CMM driver are out of sync. Fix the CMM driver
to handle this scenario by ignoring requests to decrease the number of loaned
pages if we don't think we have any pages loaned. Pages that are marked as
"loaned" which are not in the balloon will automatically get switched to "active"
the next time we touch the page. This also fixes the case where totalram_pages
is smaller than min_mem_mb, which can occur during kdump.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
---
arch/powerpc/platforms/pseries/Kconfig | 2 +-
arch/powerpc/platforms/pseries/cmm.c | 29 +++++++++++++++++++----------
2 files changed, 20 insertions(+), 11 deletions(-)
diff -puN arch/powerpc/platforms/pseries/cmm.c~powerpc_cmm_fix_kdump arch/powerpc/platforms/pseries/cmm.c
--- linux-2.6/arch/powerpc/platforms/pseries/cmm.c~powerpc_cmm_fix_kdump 2009-09-24 16:35:00.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/platforms/pseries/cmm.c 2009-09-25 10:24:19.000000000 -0500
@@ -229,8 +229,9 @@ static void cmm_get_mpp(void)
{
int rc;
struct hvcall_mpp_data mpp_data;
- unsigned long active_pages_target;
- signed long page_loan_request;
+ signed long active_pages_target, page_loan_request, target;
+ signed long total_pages = totalram_pages + loaned_pages;
+ signed long min_mem_pages = (min_mem_mb * 1024 * 1024) / PAGE_SIZE;
rc = h_get_mpp(&mpp_data);
@@ -238,17 +239,25 @@ static void cmm_get_mpp(void)
return;
page_loan_request = div_s64((s64)mpp_data.loan_request, PAGE_SIZE);
- loaned_pages_target = page_loan_request + loaned_pages;
- if (loaned_pages_target > oom_freed_pages)
- loaned_pages_target -= oom_freed_pages;
+ target = page_loan_request + (signed long)loaned_pages;
+
+ if (target < 0 || total_pages < min_mem_pages)
+ target = 0;
+
+ if (target > oom_freed_pages)
+ target -= oom_freed_pages;
else
- loaned_pages_target = 0;
+ target = 0;
+
+ active_pages_target = total_pages - target;
+
+ if (min_mem_pages > active_pages_target)
+ target = total_pages - min_mem_pages;
- active_pages_target = totalram_pages + loaned_pages - loaned_pages_target;
+ if (target < 0)
+ target = 0;
- if ((min_mem_mb * 1024 * 1024) > (active_pages_target * PAGE_SIZE))
- loaned_pages_target = totalram_pages + loaned_pages -
- ((min_mem_mb * 1024 * 1024) / PAGE_SIZE);
+ loaned_pages_target = target;
cmm_dbg("delta = %ld, loaned = %lu, target = %lu, oom = %lu, totalram = %lu\n",
page_loan_request, loaned_pages, loaned_pages_target,
diff -puN arch/powerpc/platforms/pseries/Kconfig~powerpc_cmm_fix_kdump arch/powerpc/platforms/pseries/Kconfig
--- linux-2.6/arch/powerpc/platforms/pseries/Kconfig~powerpc_cmm_fix_kdump 2009-09-24 16:35:00.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/platforms/pseries/Kconfig 2009-09-24 16:35:00.000000000 -0500
@@ -59,7 +59,7 @@ config PPC_SMLPAR
config CMM
tristate "Collaborative memory management"
- depends on PPC_SMLPAR && !CRASH_DUMP
+ depends on PPC_SMLPAR
default y
help
Select this option, if you want to enable the kernel interface
_
^ permalink raw reply
* RE: [PATCH v4] xilinx_spi: Splitted into generic, of and platform driver, added support for DS570
From: John Linn @ 2009-09-29 15:14 UTC (permalink / raw)
To: Richard Röjfors
Cc: spi-devel-general, Andrew Morton, dbrownell, linuxppc-dev
In-Reply-To: <4AC1AA82.3040406@mocean-labs.com>
> -----Original Message-----
> From: Richard R=F6jfors [mailto:richard.rojfors@mocean-labs.com]
> Sent: Tuesday, September 29, 2009 12:35 AM
> To: John Linn
> Cc: spi-devel-general@lists.sourceforge.net; linuxppc-dev@ozlabs.org;
> dbrownell@users.sourceforge.net; Andrew Morton
> Subject: Re: [PATCH v4] xilinx_spi: Splitted into generic, of and platfor=
m driver, added support for
> DS570
> =
> On 9/28/09 5:41 PM, John Linn wrote:
> >> -----Original Message-----
> >> From: Richard R=F6jfors [mailto:richard.rojfors@mocean-labs.com]
> >> Sent: Monday, September 28, 2009 8:22 AM
> >> To: spi-devel-general@lists.sourceforge.net
> >> Cc: linuxppc-dev@ozlabs.org; dbrownell@users.sourceforge.net; Andrew M=
orton; John Linn
> >> Subject: [PATCH v4] xilinx_spi: Splitted into generic, of and platform=
driver, added support for
> >> DS570
> >>
> >> This patch splits xilinx_spi into three parts, an OF and a platform
> >> driver and generic part.
> >>
> >> The generic part now also works on X86, it supports accessing the IP
> >> booth big and little endian. There is also support for 16 and 32 bit
> >> SPI for the Xilinx SPI IP DS570
> >>
> >> Signed-off-by: Richard R=F6jfors <richard.rojfors@mocean-labs.com>
> >> ---
> >> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> >> index 2c733c2..ecabc12 100644
> >> --- a/drivers/spi/Kconfig
> >> +++ b/drivers/spi/Kconfig
> >> @@ -218,8 +218,8 @@ config SPI_TXX9
> >> SPI driver for Toshiba TXx9 MIPS SoCs
> >>
> >
> > <snip>
> >
> >>
> >> -struct xilinx_spi {
> >> - /* bitbang has to be first */
> >> - struct spi_bitbang bitbang;
> >> - struct completion done;
> >> +/* to follow are some functions that does little of big endian read a=
nd
> >> + * write depending on the config of the device.
> >> + */
> >> +static inline void xspi_write8(struct xilinx_spi *xspi, u32 offs, u8 =
val)
> >> +{
> >> + iowrite8(val, xspi->regs + offs + ((xspi->big_endian) ? 3 : 0));
> >> +}
> >>
> >> - void __iomem *regs; /* virt. address of the control registers */
> >> +static inline void xspi_write16(struct xilinx_spi *xspi, u32 offs, u1=
6 val)
> >> +{
> >> + if (xspi->big_endian)
> >> + iowrite16be(val, xspi->regs + offs + 2);
> >> + else
> >> + iowrite16(val, xspi->regs + offs);
> >> +}
> >
> >
> > Hi Richard,
> =
> Hi John,
> =
> Thanks for the quick feedback.
No problem. I thought at 1st that the point of the new code was performance=
, but it sounds like you're trying to make sure the driver will work with a=
system that can be built in many different permutations.
> =
> > If you're worried about efficiency (the reason for 16 and 32 bit xfers)=
, why wouldn't you do the
> big-endian vs little endian I/O decision at compile time rather than run =
time?
> =
> I'm afraid we can't do it compile time, if we want to be flexible. As
> example;
> The IP is big endian, in our case the PCI interface flips the byte
> order. But the PCI interface might be setup differently ->would be
> accessed big endian even on a little endian machine.
> =
Ok I see the flexibility requirements.
> We could use callbacks set up during probe, instead of having the
> if-sentence. But I don't think the callback solution could be slower (if
> talking performance), since the compiler can't inline them, the current
> functions could be inlined if the compiler feels like it.
> =
> =
> > The big_endian variable is not a constant boolean, I don't know if that=
could help so that the
> compiler optimizes this check away? Or maybe it is already and I'm just =
missing that?
> >
> >>
> >> - u32 irq;
> >> +static inline void xspi_write32(struct xilinx_spi *xspi, u32 offs, u3=
2 val)
> >> +{
> >> + if (xspi->big_endian)
> >> + iowrite32be(val, xspi->regs + offs);
> >> + else
> >> + iowrite32(val, xspi->regs + offs);
> >> +}
> >>
> >> - u32 speed_hz; /* SCK has a fixed frequency of speed_hz Hz */
> >> +static inline u8 xspi_read8(struct xilinx_spi *xspi, u32 offs)
> >> +{
> >> + return ioread8(xspi->regs + offs + ((xspi->big_endian) ? 3 : 0));
> >> +}
> >>
> >> - u8 *rx_ptr; /* pointer in the Tx buffer */
> >> - const u8 *tx_ptr; /* pointer in the Rx buffer */
> >> - int remaining_bytes; /* the number of bytes left to transfer */
> >> -};
> >
> > <snip>
> >
> >> -
> >> /* This driver supports single master mode only. Hence Tx FIFO Empty
> >> * is the only interrupt we care about.
> >> * Receive FIFO Overrun, Transmit FIFO Underrun, Mode Fault, and Slav=
e Mode
> >> @@ -237,32 +298,50 @@ static irqreturn_t xilinx_spi_irq(int irq, void =
*dev_id)
> >> u32 ipif_isr;
> >>
> >> /* Get the IPIF interrupts, and clear them immediately */
> >> - ipif_isr =3D in_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET);
> >> - out_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET, ipif_isr);
> >> + ipif_isr =3D xspi_read32(xspi, XIPIF_V123B_IISR_OFFSET);
> >> + xspi_write32(xspi, XIPIF_V123B_IISR_OFFSET, ipif_isr);
> >>
> >> if (ipif_isr & XSPI_INTR_TX_EMPTY) { /* Transmission completed */
> >> u16 cr;
> >> u8 sr;
> >> + u8 rsize;
> >> + if (xspi->bits_per_word =3D=3D 8)
> >> + rsize =3D 1;
> >> + else if (xspi->bits_per_word =3D=3D 16)
> >> + rsize =3D 2;
> >> + else
> >> + rsize =3D 4;
> >>
> >> /* A transmit has just completed. Process received data and
> >> * check for more data to transmit. Always inhibit the
> >> * transmitter while the Isr refills the transmit register/FIFO,
> >> * or make sure it is stopped if we're done.
> >> */
> >> - cr =3D in_be16(xspi->regs + XSPI_CR_OFFSET);
> >> - out_be16(xspi->regs + XSPI_CR_OFFSET,
> >> - cr | XSPI_CR_TRANS_INHIBIT);
> >> + cr =3D xspi_read16(xspi, XSPI_CR_OFFSET);
> >> + xspi_write16(xspi, XSPI_CR_OFFSET, cr | XSPI_CR_TRANS_INHIBIT);
> >>
> >> /* Read out all the data from the Rx FIFO */
> >> - sr =3D in_8(xspi->regs + XSPI_SR_OFFSET);
> >> + sr =3D xspi_read8(xspi, XSPI_SR_OFFSET);
> >> while ((sr & XSPI_SR_RX_EMPTY_MASK) =3D=3D 0) {
> >> - u8 data;
> >> + u32 data;
> >> + if (rsize =3D=3D 1)
> >> + data =3D xspi_read8(xspi, XSPI_RXD_OFFSET);
> >> + else if (rsize =3D=3D 2)
> >> + data =3D xspi_read16(xspi, XSPI_RXD_OFFSET);
> >> + else
> >> + data =3D xspi_read32(xspi, XSPI_RXD_OFFSET);
> >>
> >> - data =3D in_8(xspi->regs + XSPI_RXD_OFFSET);
> >> if (xspi->rx_ptr) {
> >> - *xspi->rx_ptr++ =3D data;
> >> + if (rsize =3D=3D 1)
> >> + *xspi->rx_ptr =3D data & 0xff;
> >> + else if (rsize =3D=3D 2)
> >> + *(u16 *)(xspi->rx_ptr) =3D data & 0xffff;
> >> + else
> >> + *((u32 *)(xspi->rx_ptr)) =3D data;
> >> + xspi->rx_ptr +=3D rsize;
> >
> > Maybe I'm out of line here...
> >
> > I'm wondering if this is going to be any more efficient that just using=
8 bit accesses
> =
> We can not do 8 bit accesses if the IP is set up to do 16/32bit SPI,
> then the TX/RX registers are as wide as the bit setup.
> =
> We could do 32 bit reads from the registers, then we waste some cycles
> on the PLB bus, but have slightly simpler code.
Looking at the IP spec, it looks like 32 bit operations to registers should=
work and that sounds like the right direction to go (32 bit only).
Doing 32 bit operations on the PLB, rather than 8 bit operations, won't was=
te any cycles on the bus as you're on the bus either way so it can't be use=
d by any other device, it's just how many byte lanes are being used on the =
bus.
> =
> > as it seems like the amount of run-time decisions being made is quite a=
few. I guess it depends on
> how many bytes are being transferred as with big transfers maybe it will =
pay off.
> >
> > In my opinion, which isn't worth much many times :), sometimes the flex=
ibility with soft logic,
> like this is a pain for testability and increases complexity. If there's =
reasonable performance gains
> then maybe it's a good tradeoff.
> >
> > Do you know how much performance gain there is or is expected as maybe =
you've seen the pay off
> already?
> =
> I haven't done any measurements, and we are basically only controlling
> GPIO so performance is not an issue for us. I just didn't want do make
> it slower. I think you have more experience here. Do you think it's
> better to just do 32bit reads to make the code simple? If so I will
> update the code.
Yes, 32 ops.
If you get a new driver that's ready, I can hopefully find some time to tes=
t it in our automated test with the SPI EEPROM.
> =
> Thanks
> --Richard
This email and any attachments are intended for the sole use of the named r=
ecipient(s) and contain(s) confidential information that may be proprietary=
, privileged or copyrighted under applicable law. If you are not the intend=
ed recipient, do not read, copy, or forward this email message or any attac=
hments. Delete this email message and any attachments immediately.
^ 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