* [PATCH 4/6] SPI: S3C64XX: Correction for 16,32 bits bus width
[not found] <1OrKX4-0007cO-1K>
@ 2010-09-03 1:36 ` Jassi Brar
[not found] ` <1283477814-31228-1-git-send-email-jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Jassi Brar @ 2010-09-03 1:36 UTC (permalink / raw)
To: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
Cc: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f
We can't do without setting channel and bus width to
same size.
Inorder to do that, define a new callback to be used
to do read/write of appropriate widths.
Signed-off-by: Jassi Brar <jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
drivers/spi/spi_s3c64xx.c | 78 +++++++++++++++++++++++++++++++++++++-------
1 files changed, 65 insertions(+), 13 deletions(-)
diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
index 39816bb..8aa9f85 100644
--- a/drivers/spi/spi_s3c64xx.c
+++ b/drivers/spi/spi_s3c64xx.c
@@ -174,12 +174,59 @@ struct s3c64xx_spi_driver_data {
unsigned state;
unsigned cur_mode, cur_bpw;
unsigned cur_speed;
+ void (*do_xfer)(void *ptr, void *fifo, unsigned sz, bool rd);
};
static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
.name = "samsung-spi-dma",
};
+static void s3c64xx_spi_xfer8(void *ptr, void __iomem *fifo,
+ unsigned len, bool read)
+{
+ u8 *buf = (u8 *)ptr;
+ int i = 0;
+
+ if (read)
+ while (i < len)
+ buf[i++] = readb(fifo);
+ else
+ while (i < len)
+ writeb(buf[i++], fifo);
+}
+
+static void s3c64xx_spi_xfer16(void *ptr, void __iomem *fifo,
+ unsigned len, bool read)
+{
+ u16 *buf = (u16 *)ptr;
+ int i = 0;
+
+ len /= 2;
+
+ if (read)
+ while (i < len)
+ buf[i++] = readw(fifo);
+ else
+ while (i < len)
+ writew(buf[i++], fifo);
+}
+
+static void s3c64xx_spi_xfer32(void *ptr, void __iomem *fifo,
+ unsigned len, bool read)
+{
+ u32 *buf = (u32 *)ptr;
+ int i = 0;
+
+ len /= 4;
+
+ if (read)
+ while (i < len)
+ buf[i++] = readl(fifo);
+ else
+ while (i < len)
+ writel(buf[i++], fifo);
+}
+
static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
{
struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
@@ -260,10 +307,8 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
xfer->tx_dma, xfer->len);
s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
} else {
- unsigned char *buf = (unsigned char *) xfer->tx_buf;
- int i = 0;
- while (i < xfer->len)
- writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA);
+ sdd->do_xfer((void *)xfer->tx_buf,
+ regs + S3C64XX_SPI_TX_DATA, xfer->len, false);
}
}
@@ -360,20 +405,14 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
return -EIO;
}
} else {
- unsigned char *buf;
- int i;
-
/* If it was only Tx */
if (xfer->rx_buf == NULL) {
sdd->state &= ~TXBUSY;
return 0;
}
- i = 0;
- buf = xfer->rx_buf;
- while (i < xfer->len)
- buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA);
-
+ sdd->do_xfer(xfer->rx_buf,
+ regs + S3C64XX_SPI_RX_DATA, xfer->len, true);
sdd->state &= ~RXBUSY;
}
@@ -423,15 +462,20 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
switch (sdd->cur_bpw) {
case 32:
val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD;
+ val |= S3C64XX_SPI_MODE_CH_TSZ_WORD;
+ sdd->do_xfer = s3c64xx_spi_xfer32;
break;
case 16:
val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD;
+ val |= S3C64XX_SPI_MODE_CH_TSZ_HALFWORD;
+ sdd->do_xfer = s3c64xx_spi_xfer16;
break;
default:
val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE;
+ val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE;
+ sdd->do_xfer = s3c64xx_spi_xfer8;
break;
}
- val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */
writel(val, regs + S3C64XX_SPI_MODE_CFG);
@@ -610,6 +654,14 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
bpw = xfer->bits_per_word ? : spi->bits_per_word;
speed = xfer->speed_hz ? : spi->max_speed_hz;
+ if (bpw != 8 && xfer->len % (bpw / 8)) {
+ dev_err(&spi->dev,
+ "Xfer length(%u) not a multiple of word size(%u)\n",
+ xfer->len, bpw / 8);
+ status = -EIO;
+ goto out;
+ }
+
if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
sdd->cur_bpw = bpw;
sdd->cur_speed = speed;
--
1.6.2.5
------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:
Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 4/6] SPI: S3C64XX: Correction for 16,32 bits bus width
[not found] ` <1283477814-31228-1-git-send-email-jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2010-09-09 5:07 ` Grant Likely
[not found] ` <20100909050723.GF11833-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Grant Likely @ 2010-09-09 5:07 UTC (permalink / raw)
To: Jassi Brar
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f
On Fri, Sep 03, 2010 at 10:36:54AM +0900, Jassi Brar wrote:
> We can't do without setting channel and bus width to
> same size.
> Inorder to do that, define a new callback to be used
> to do read/write of appropriate widths.
>
> Signed-off-by: Jassi Brar <jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
> drivers/spi/spi_s3c64xx.c | 78 +++++++++++++++++++++++++++++++++++++-------
> 1 files changed, 65 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
> index 39816bb..8aa9f85 100644
> --- a/drivers/spi/spi_s3c64xx.c
> +++ b/drivers/spi/spi_s3c64xx.c
> @@ -174,12 +174,59 @@ struct s3c64xx_spi_driver_data {
> unsigned state;
> unsigned cur_mode, cur_bpw;
> unsigned cur_speed;
> + void (*do_xfer)(void *ptr, void *fifo, unsigned sz, bool rd);
Looking at the code; it appears that it would be better to have
separate read and write transfer hooks.
> };
>
> static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
> .name = "samsung-spi-dma",
> };
>
> +static void s3c64xx_spi_xfer8(void *ptr, void __iomem *fifo,
> + unsigned len, bool read)
> +{
> + u8 *buf = (u8 *)ptr;
ptr is already a void* which makes this an unnecessary cast.
> + int i = 0;
> +
> + if (read)
> + while (i < len)
> + buf[i++] = readb(fifo);
perhaps ioread8_rep() instead of open-coding? If so, then
ioread*_rep() and iowrite*_rep() can be used in all these cases.
In fact, the 8, 16 and 32 versions have the same signature and so
could possibly be used directly without these hooks.
g.
> + else
> + while (i < len)
> + writeb(buf[i++], fifo);
> +}
> +
> +static void s3c64xx_spi_xfer16(void *ptr, void __iomem *fifo,
> + unsigned len, bool read)
> +{
> + u16 *buf = (u16 *)ptr;
> + int i = 0;
> +
> + len /= 2;
> +
> + if (read)
> + while (i < len)
> + buf[i++] = readw(fifo);
> + else
> + while (i < len)
> + writew(buf[i++], fifo);
> +}
> +
> +static void s3c64xx_spi_xfer32(void *ptr, void __iomem *fifo,
> + unsigned len, bool read)
> +{
> + u32 *buf = (u32 *)ptr;
> + int i = 0;
> +
> + len /= 4;
> +
> + if (read)
> + while (i < len)
> + buf[i++] = readl(fifo);
> + else
> + while (i < len)
> + writel(buf[i++], fifo);
> +}
> +
> static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
> {
> struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
> @@ -260,10 +307,8 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
> xfer->tx_dma, xfer->len);
> s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> } else {
> - unsigned char *buf = (unsigned char *) xfer->tx_buf;
> - int i = 0;
> - while (i < xfer->len)
> - writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA);
> + sdd->do_xfer((void *)xfer->tx_buf,
> + regs + S3C64XX_SPI_TX_DATA, xfer->len, false);
> }
> }
>
> @@ -360,20 +405,14 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
> return -EIO;
> }
> } else {
> - unsigned char *buf;
> - int i;
> -
> /* If it was only Tx */
> if (xfer->rx_buf == NULL) {
> sdd->state &= ~TXBUSY;
> return 0;
> }
>
> - i = 0;
> - buf = xfer->rx_buf;
> - while (i < xfer->len)
> - buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA);
> -
> + sdd->do_xfer(xfer->rx_buf,
> + regs + S3C64XX_SPI_RX_DATA, xfer->len, true);
> sdd->state &= ~RXBUSY;
> }
>
> @@ -423,15 +462,20 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
> switch (sdd->cur_bpw) {
> case 32:
> val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD;
> + val |= S3C64XX_SPI_MODE_CH_TSZ_WORD;
> + sdd->do_xfer = s3c64xx_spi_xfer32;
> break;
> case 16:
> val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD;
> + val |= S3C64XX_SPI_MODE_CH_TSZ_HALFWORD;
> + sdd->do_xfer = s3c64xx_spi_xfer16;
> break;
> default:
> val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE;
> + val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE;
> + sdd->do_xfer = s3c64xx_spi_xfer8;
> break;
> }
> - val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */
>
> writel(val, regs + S3C64XX_SPI_MODE_CFG);
>
> @@ -610,6 +654,14 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
> bpw = xfer->bits_per_word ? : spi->bits_per_word;
> speed = xfer->speed_hz ? : spi->max_speed_hz;
>
> + if (bpw != 8 && xfer->len % (bpw / 8)) {
> + dev_err(&spi->dev,
> + "Xfer length(%u) not a multiple of word size(%u)\n",
> + xfer->len, bpw / 8);
> + status = -EIO;
> + goto out;
> + }
> +
> if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
> sdd->cur_bpw = bpw;
> sdd->cur_speed = speed;
> --
> 1.6.2.5
>
------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:
Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/2] SPI: S3C64XX: Correction for 16,32 bits bus width
@ 2010-09-09 7:18 Jassi Brar
[not found] ` <1284016737-21620-1-git-send-email-jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Jassi Brar @ 2010-09-09 7:18 UTC (permalink / raw)
To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E
We can't do without setting channel and bus width to
same size. Inorder to do that, use loop read/writes in
polling mode and appropriate burst size in DMA mode.
Signed-off-by: Jassi Brar <jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
drivers/spi/spi_s3c64xx.c | 76 ++++++++++++++++++++++++++++++++++++---------
1 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
index 39816bb..3ff335d 100644
--- a/drivers/spi/spi_s3c64xx.c
+++ b/drivers/spi/spi_s3c64xx.c
@@ -255,15 +255,35 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
chcfg |= S3C64XX_SPI_CH_TXCH_ON;
if (dma_mode) {
modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
- s3c2410_dma_config(sdd->tx_dmach, 1);
+ switch (sdd->cur_bpw) {
+ case 32:
+ s3c2410_dma_config(sdd->tx_dmach, 4);
+ break;
+ case 16:
+ s3c2410_dma_config(sdd->tx_dmach, 2);
+ break;
+ default:
+ s3c2410_dma_config(sdd->tx_dmach, 1);
+ break;
+ }
s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
xfer->tx_dma, xfer->len);
s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
} else {
- unsigned char *buf = (unsigned char *) xfer->tx_buf;
- int i = 0;
- while (i < xfer->len)
- writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA);
+ switch (sdd->cur_bpw) {
+ case 32:
+ iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
+ xfer->tx_buf, xfer->len / 4);
+ break;
+ case 16:
+ iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
+ xfer->tx_buf, xfer->len / 2);
+ break;
+ default:
+ iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
+ xfer->tx_buf, xfer->len);
+ break;
+ }
}
}
@@ -280,7 +300,17 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
| S3C64XX_SPI_PACKET_CNT_EN,
regs + S3C64XX_SPI_PACKET_CNT);
- s3c2410_dma_config(sdd->rx_dmach, 1);
+ switch (sdd->cur_bpw) {
+ case 32:
+ s3c2410_dma_config(sdd->rx_dmach, 4);
+ break;
+ case 16:
+ s3c2410_dma_config(sdd->rx_dmach, 2);
+ break;
+ default:
+ s3c2410_dma_config(sdd->rx_dmach, 1);
+ break;
+ }
s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
xfer->rx_dma, xfer->len);
s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
@@ -360,20 +390,26 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
return -EIO;
}
} else {
- unsigned char *buf;
- int i;
-
/* If it was only Tx */
if (xfer->rx_buf == NULL) {
sdd->state &= ~TXBUSY;
return 0;
}
- i = 0;
- buf = xfer->rx_buf;
- while (i < xfer->len)
- buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA);
-
+ switch (sdd->cur_bpw) {
+ case 32:
+ ioread32_rep(regs + S3C64XX_SPI_RX_DATA,
+ xfer->rx_buf, xfer->len / 4);
+ break;
+ case 16:
+ ioread16_rep(regs + S3C64XX_SPI_RX_DATA,
+ xfer->rx_buf, xfer->len / 2);
+ break;
+ default:
+ ioread8_rep(regs + S3C64XX_SPI_RX_DATA,
+ xfer->rx_buf, xfer->len);
+ break;
+ }
sdd->state &= ~RXBUSY;
}
@@ -423,15 +459,17 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
switch (sdd->cur_bpw) {
case 32:
val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD;
+ val |= S3C64XX_SPI_MODE_CH_TSZ_WORD;
break;
case 16:
val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD;
+ val |= S3C64XX_SPI_MODE_CH_TSZ_HALFWORD;
break;
default:
val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE;
+ val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE;
break;
}
- val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */
writel(val, regs + S3C64XX_SPI_MODE_CFG);
@@ -610,6 +648,14 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
bpw = xfer->bits_per_word ? : spi->bits_per_word;
speed = xfer->speed_hz ? : spi->max_speed_hz;
+ if (bpw != 8 && xfer->len % (bpw / 8)) {
+ dev_err(&spi->dev,
+ "Xfer length(%u) not a multiple of word size(%u)\n",
+ xfer->len, bpw / 8);
+ status = -EIO;
+ goto out;
+ }
+
if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
sdd->cur_bpw = bpw;
sdd->cur_speed = speed;
--
1.6.2.5
------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:
Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 4/6] SPI: S3C64XX: Correction for 16,32 bits bus width
[not found] ` <20100909050723.GF11833-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
@ 2010-09-09 7:29 ` Jassi Brar
0 siblings, 0 replies; 9+ messages in thread
From: Jassi Brar @ 2010-09-09 7:29 UTC (permalink / raw)
To: Grant Likely
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f
On Thu, Sep 9, 2010 at 2:07 PM, Grant Likely <grant.likely@secretlab.ca> wrote:
> On Fri, Sep 03, 2010 at 10:36:54AM +0900, Jassi Brar wrote:
>> We can't do without setting channel and bus width to
>> same size.
>> Inorder to do that, define a new callback to be used
>> to do read/write of appropriate widths.
>>
>> Signed-off-by: Jassi Brar <jassi.brar@samsung.com>
>> ---
>> drivers/spi/spi_s3c64xx.c | 78 +++++++++++++++++++++++++++++++++++++-------
>> 1 files changed, 65 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
>> index 39816bb..8aa9f85 100644
>> --- a/drivers/spi/spi_s3c64xx.c
>> +++ b/drivers/spi/spi_s3c64xx.c
>> @@ -174,12 +174,59 @@ struct s3c64xx_spi_driver_data {
>> unsigned state;
>> unsigned cur_mode, cur_bpw;
>> unsigned cur_speed;
>> + void (*do_xfer)(void *ptr, void *fifo, unsigned sz, bool rd);
>
> Looking at the code; it appears that it would be better to have
> separate read and write transfer hooks.
>
>> };
>>
>> static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
>> .name = "samsung-spi-dma",
>> };
>>
>> +static void s3c64xx_spi_xfer8(void *ptr, void __iomem *fifo,
>> + unsigned len, bool read)
>> +{
>> + u8 *buf = (u8 *)ptr;
>
> ptr is already a void* which makes this an unnecessary cast.
>
>> + int i = 0;
>> +
>> + if (read)
>> + while (i < len)
>> + buf[i++] = readb(fifo);
>
> perhaps ioread8_rep() instead of open-coding? If so, then
> ioread*_rep() and iowrite*_rep() can be used in all these cases.
>
> In fact, the 8, 16 and 32 versions have the same signature and so
> could possibly be used directly without these hooks.
Great idea. I have rather avoided new callbacks and directly used the
ioread*_rep
calls. Also, I had missed setting appropriate bus width while in DMA mode.
Resending this again.
Thanks.
------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:
Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] SPI: S3C64XX: Correction for 16,32 bits bus width
[not found] ` <1284016737-21620-1-git-send-email-jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2010-09-09 14:51 ` Grant Likely
[not found] ` <20100909145115.GA5652-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Grant Likely @ 2010-09-09 14:51 UTC (permalink / raw)
To: Jassi Brar
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E
On Thu, Sep 09, 2010 at 04:18:57PM +0900, Jassi Brar wrote:
> We can't do without setting channel and bus width to
> same size. Inorder to do that, use loop read/writes in
> polling mode and appropriate burst size in DMA mode.
>
> Signed-off-by: Jassi Brar <jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Looks pretty good to me. A couple of minor comments below.
g.
> ---
> drivers/spi/spi_s3c64xx.c | 76 ++++++++++++++++++++++++++++++++++++---------
> 1 files changed, 61 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
> index 39816bb..3ff335d 100644
> --- a/drivers/spi/spi_s3c64xx.c
> +++ b/drivers/spi/spi_s3c64xx.c
> @@ -255,15 +255,35 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
> chcfg |= S3C64XX_SPI_CH_TXCH_ON;
> if (dma_mode) {
> modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
> - s3c2410_dma_config(sdd->tx_dmach, 1);
> + switch (sdd->cur_bpw) {
> + case 32:
> + s3c2410_dma_config(sdd->tx_dmach, 4);
> + break;
> + case 16:
> + s3c2410_dma_config(sdd->tx_dmach, 2);
> + break;
> + default:
> + s3c2410_dma_config(sdd->tx_dmach, 1);
> + break;
> + }
Nit: switch statements like this tend to obscure the fact that the same
function is called each time with a different value. How about the
following:
width = 1;
if (sdd->cur_bpw == 32)
width = 4;
if (sdd->cur_bpw == 16)
width = 2;
s3c2410_dma_config(sdd->tx_dmach, width);
It's also more concise.
> s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
> xfer->tx_dma, xfer->len);
> s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> } else {
> - unsigned char *buf = (unsigned char *) xfer->tx_buf;
> - int i = 0;
> - while (i < xfer->len)
> - writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA);
> + switch (sdd->cur_bpw) {
> + case 32:
> + iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
> + xfer->tx_buf, xfer->len / 4);
> + break;
> + case 16:
> + iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
> + xfer->tx_buf, xfer->len / 2);
> + break;
> + default:
> + iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
> + xfer->tx_buf, xfer->len);
> + break;
> + }
> }
> }
>
> @@ -280,7 +300,17 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
> writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
> | S3C64XX_SPI_PACKET_CNT_EN,
> regs + S3C64XX_SPI_PACKET_CNT);
> - s3c2410_dma_config(sdd->rx_dmach, 1);
> + switch (sdd->cur_bpw) {
> + case 32:
> + s3c2410_dma_config(sdd->rx_dmach, 4);
> + break;
> + case 16:
> + s3c2410_dma_config(sdd->rx_dmach, 2);
> + break;
> + default:
> + s3c2410_dma_config(sdd->rx_dmach, 1);
> + break;
> + }
Ditto here
> s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
> xfer->rx_dma, xfer->len);
> s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
> @@ -360,20 +390,26 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
> return -EIO;
> }
> } else {
> - unsigned char *buf;
> - int i;
> -
> /* If it was only Tx */
> if (xfer->rx_buf == NULL) {
> sdd->state &= ~TXBUSY;
> return 0;
> }
>
> - i = 0;
> - buf = xfer->rx_buf;
> - while (i < xfer->len)
> - buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA);
> -
> + switch (sdd->cur_bpw) {
> + case 32:
> + ioread32_rep(regs + S3C64XX_SPI_RX_DATA,
> + xfer->rx_buf, xfer->len / 4);
> + break;
> + case 16:
> + ioread16_rep(regs + S3C64XX_SPI_RX_DATA,
> + xfer->rx_buf, xfer->len / 2);
> + break;
> + default:
> + ioread8_rep(regs + S3C64XX_SPI_RX_DATA,
> + xfer->rx_buf, xfer->len);
> + break;
> + }
> sdd->state &= ~RXBUSY;
> }
>
> @@ -423,15 +459,17 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
> switch (sdd->cur_bpw) {
> case 32:
> val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD;
> + val |= S3C64XX_SPI_MODE_CH_TSZ_WORD;
> break;
> case 16:
> val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD;
> + val |= S3C64XX_SPI_MODE_CH_TSZ_HALFWORD;
> break;
> default:
> val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE;
> + val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE;
> break;
> }
> - val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */
>
> writel(val, regs + S3C64XX_SPI_MODE_CFG);
>
> @@ -610,6 +648,14 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
> bpw = xfer->bits_per_word ? : spi->bits_per_word;
> speed = xfer->speed_hz ? : spi->max_speed_hz;
>
> + if (bpw != 8 && xfer->len % (bpw / 8)) {
The (bpw != 8) test is superfluous.
> + dev_err(&spi->dev,
> + "Xfer length(%u) not a multiple of word size(%u)\n",
> + xfer->len, bpw / 8);
> + status = -EIO;
> + goto out;
> + }
> +
> if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
> sdd->cur_bpw = bpw;
> sdd->cur_speed = speed;
> --
> 1.6.2.5
>
------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:
Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] SPI: S3C64XX: Correction for 16,32 bits bus width
[not found] ` <20100909145115.GA5652-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
@ 2010-09-09 15:07 ` Jassi Brar
[not found] ` <AANLkTim-gpnfsvWrFnJBcE9DcWFsh8soJwq4gL_bMpMv-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Jassi Brar @ 2010-09-09 15:07 UTC (permalink / raw)
To: Grant Likely
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E
On Thu, Sep 9, 2010 at 11:51 PM, Grant Likely <grant.likely@secretlab.ca> wrote:
> On Thu, Sep 09, 2010 at 04:18:57PM +0900, Jassi Brar wrote:
>> We can't do without setting channel and bus width to
>> same size. Inorder to do that, use loop read/writes in
>> polling mode and appropriate burst size in DMA mode.
>>
>> Signed-off-by: Jassi Brar <jassi.brar@samsung.com>
>
> Looks pretty good to me. A couple of minor comments below.
>
> g.
>
>> ---
>> drivers/spi/spi_s3c64xx.c | 76 ++++++++++++++++++++++++++++++++++++---------
>> 1 files changed, 61 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
>> index 39816bb..3ff335d 100644
>> --- a/drivers/spi/spi_s3c64xx.c
>> +++ b/drivers/spi/spi_s3c64xx.c
>> @@ -255,15 +255,35 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>> chcfg |= S3C64XX_SPI_CH_TXCH_ON;
>> if (dma_mode) {
>> modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
>> - s3c2410_dma_config(sdd->tx_dmach, 1);
>> + switch (sdd->cur_bpw) {
>> + case 32:
>> + s3c2410_dma_config(sdd->tx_dmach, 4);
>> + break;
>> + case 16:
>> + s3c2410_dma_config(sdd->tx_dmach, 2);
>> + break;
>> + default:
>> + s3c2410_dma_config(sdd->tx_dmach, 1);
>> + break;
>> + }
>
> Nit: switch statements like this tend to obscure the fact that the same
> function is called each time with a different value. How about the
> following:
>
> width = 1;
> if (sdd->cur_bpw == 32)
> width = 4;
> if (sdd->cur_bpw == 16)
> width = 2;
> s3c2410_dma_config(sdd->tx_dmach, width);
>
> It's also more concise.
yuck! why didn't i do
s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8); ??
>
>> s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
>> xfer->tx_dma, xfer->len);
>> s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
>> } else {
>> - unsigned char *buf = (unsigned char *) xfer->tx_buf;
>> - int i = 0;
>> - while (i < xfer->len)
>> - writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA);
>> + switch (sdd->cur_bpw) {
>> + case 32:
>> + iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
>> + xfer->tx_buf, xfer->len / 4);
>> + break;
>> + case 16:
>> + iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
>> + xfer->tx_buf, xfer->len / 2);
>> + break;
>> + default:
>> + iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
>> + xfer->tx_buf, xfer->len);
>> + break;
>> + }
>> }
>> }
>>
>> @@ -280,7 +300,17 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>> writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
>> | S3C64XX_SPI_PACKET_CNT_EN,
>> regs + S3C64XX_SPI_PACKET_CNT);
>> - s3c2410_dma_config(sdd->rx_dmach, 1);
>> + switch (sdd->cur_bpw) {
>> + case 32:
>> + s3c2410_dma_config(sdd->rx_dmach, 4);
>> + break;
>> + case 16:
>> + s3c2410_dma_config(sdd->rx_dmach, 2);
>> + break;
>> + default:
>> + s3c2410_dma_config(sdd->rx_dmach, 1);
>> + break;
>> + }
>
> Ditto here
>
>> s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
>> xfer->rx_dma, xfer->len);
>> s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
>> @@ -360,20 +390,26 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
>> return -EIO;
>> }
>> } else {
>> - unsigned char *buf;
>> - int i;
>> -
>> /* If it was only Tx */
>> if (xfer->rx_buf == NULL) {
>> sdd->state &= ~TXBUSY;
>> return 0;
>> }
>>
>> - i = 0;
>> - buf = xfer->rx_buf;
>> - while (i < xfer->len)
>> - buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA);
>> -
>> + switch (sdd->cur_bpw) {
>> + case 32:
>> + ioread32_rep(regs + S3C64XX_SPI_RX_DATA,
>> + xfer->rx_buf, xfer->len / 4);
>> + break;
>> + case 16:
>> + ioread16_rep(regs + S3C64XX_SPI_RX_DATA,
>> + xfer->rx_buf, xfer->len / 2);
>> + break;
>> + default:
>> + ioread8_rep(regs + S3C64XX_SPI_RX_DATA,
>> + xfer->rx_buf, xfer->len);
>> + break;
>> + }
>> sdd->state &= ~RXBUSY;
>> }
>>
>> @@ -423,15 +459,17 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
>> switch (sdd->cur_bpw) {
>> case 32:
>> val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD;
>> + val |= S3C64XX_SPI_MODE_CH_TSZ_WORD;
>> break;
>> case 16:
>> val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD;
>> + val |= S3C64XX_SPI_MODE_CH_TSZ_HALFWORD;
>> break;
>> default:
>> val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE;
>> + val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE;
>> break;
>> }
>> - val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */
>>
>> writel(val, regs + S3C64XX_SPI_MODE_CFG);
>>
>> @@ -610,6 +648,14 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
>> bpw = xfer->bits_per_word ? : spi->bits_per_word;
>> speed = xfer->speed_hz ? : spi->max_speed_hz;
>>
>> + if (bpw != 8 && xfer->len % (bpw / 8)) {
>
> The (bpw != 8) test is superfluous.
xfer->len % (bpw / 8) always evaluate to true(error hence) when bpw==8
so we wanna avoid that case
thanks
------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:
Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
_______________________________________________
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] SPI: S3C64XX: Correction for 16,32 bits bus width
[not found] ` <AANLkTim-gpnfsvWrFnJBcE9DcWFsh8soJwq4gL_bMpMv-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2010-09-09 16:00 ` Grant Likely
[not found] ` <20100909160051.GA6273-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Grant Likely @ 2010-09-09 16:00 UTC (permalink / raw)
To: Jassi Brar
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E
On Fri, Sep 10, 2010 at 12:07:50AM +0900, Jassi Brar wrote:
> On Thu, Sep 9, 2010 at 11:51 PM, Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> wrote:
> > On Thu, Sep 09, 2010 at 04:18:57PM +0900, Jassi Brar wrote:
[...]
> > Nit: switch statements like this tend to obscure the fact that the same
> > function is called each time with a different value. How about the
> > following:
> >
> > width = 1;
> > if (sdd->cur_bpw == 32)
> > width = 4;
> > if (sdd->cur_bpw == 16)
> > width = 2;
> > s3c2410_dma_config(sdd->tx_dmach, width);
> >
> > It's also more concise.
>
> yuck! why didn't i do
> s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8); ??
Heh, very true!
> >> @@ -610,6 +648,14 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
> >> bpw = xfer->bits_per_word ? : spi->bits_per_word;
> >> speed = xfer->speed_hz ? : spi->max_speed_hz;
> >>
> >> + if (bpw != 8 && xfer->len % (bpw / 8)) {
> >
> > The (bpw != 8) test is superfluous.
>
> xfer->len % (bpw / 8) always evaluate to true(error hence) when bpw==8
> so we wanna avoid that case
When bpw == 8, the equation reduces to (len % 1), which will always
evaluate to 0 (false) for integer len.
g.
------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:
Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/6] SPI: S3C64XX: Correction for 16,32 bits bus width
[not found] ` <20100909160051.GA6273-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
@ 2010-09-09 23:55 ` Jassi Brar
[not found] ` <1284076549-17715-1-git-send-email-jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
0 siblings, 1 reply; 9+ messages in thread
From: Jassi Brar @ 2010-09-09 23:55 UTC (permalink / raw)
To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E
We can't do without setting channel and bus width to
same size. Inorder to do that, use loop read/writes in
polling mode and appropriate burst size in DMA mode.
Signed-off-by: Jassi Brar <jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
drivers/spi/spi_s3c64xx.c | 56 +++++++++++++++++++++++++++++++++------------
1 files changed, 41 insertions(+), 15 deletions(-)
diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
index 39816bb..cf45e01 100644
--- a/drivers/spi/spi_s3c64xx.c
+++ b/drivers/spi/spi_s3c64xx.c
@@ -255,15 +255,25 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
chcfg |= S3C64XX_SPI_CH_TXCH_ON;
if (dma_mode) {
modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
- s3c2410_dma_config(sdd->tx_dmach, 1);
+ s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
xfer->tx_dma, xfer->len);
s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
} else {
- unsigned char *buf = (unsigned char *) xfer->tx_buf;
- int i = 0;
- while (i < xfer->len)
- writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA);
+ switch (sdd->cur_bpw) {
+ case 32:
+ iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
+ xfer->tx_buf, xfer->len / 4);
+ break;
+ case 16:
+ iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
+ xfer->tx_buf, xfer->len / 2);
+ break;
+ default:
+ iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
+ xfer->tx_buf, xfer->len);
+ break;
+ }
}
}
@@ -280,7 +290,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
| S3C64XX_SPI_PACKET_CNT_EN,
regs + S3C64XX_SPI_PACKET_CNT);
- s3c2410_dma_config(sdd->rx_dmach, 1);
+ s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);
s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
xfer->rx_dma, xfer->len);
s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
@@ -360,20 +370,26 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
return -EIO;
}
} else {
- unsigned char *buf;
- int i;
-
/* If it was only Tx */
if (xfer->rx_buf == NULL) {
sdd->state &= ~TXBUSY;
return 0;
}
- i = 0;
- buf = xfer->rx_buf;
- while (i < xfer->len)
- buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA);
-
+ switch (sdd->cur_bpw) {
+ case 32:
+ ioread32_rep(regs + S3C64XX_SPI_RX_DATA,
+ xfer->rx_buf, xfer->len / 4);
+ break;
+ case 16:
+ ioread16_rep(regs + S3C64XX_SPI_RX_DATA,
+ xfer->rx_buf, xfer->len / 2);
+ break;
+ default:
+ ioread8_rep(regs + S3C64XX_SPI_RX_DATA,
+ xfer->rx_buf, xfer->len);
+ break;
+ }
sdd->state &= ~RXBUSY;
}
@@ -423,15 +439,17 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
switch (sdd->cur_bpw) {
case 32:
val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD;
+ val |= S3C64XX_SPI_MODE_CH_TSZ_WORD;
break;
case 16:
val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD;
+ val |= S3C64XX_SPI_MODE_CH_TSZ_HALFWORD;
break;
default:
val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE;
+ val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE;
break;
}
- val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */
writel(val, regs + S3C64XX_SPI_MODE_CFG);
@@ -610,6 +628,14 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
bpw = xfer->bits_per_word ? : spi->bits_per_word;
speed = xfer->speed_hz ? : spi->max_speed_hz;
+ if (xfer->len % (bpw / 8)) {
+ dev_err(&spi->dev,
+ "Xfer length(%u) not a multiple of word size(%u)\n",
+ xfer->len, bpw / 8);
+ status = -EIO;
+ goto out;
+ }
+
if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
sdd->cur_bpw = bpw;
sdd->cur_speed = speed;
--
1.6.2.5
------------------------------------------------------------------------------
Automate Storage Tiering Simply
Optimize IT performance and efficiency through flexible, powerful,
automated storage tiering capabilities. View this brief to learn how
you can reduce costs and improve performance.
http://p.sf.net/sfu/dell-sfdev2dev
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 4/6] SPI: S3C64XX: Correction for 16,32 bits bus width
[not found] ` <1284076549-17715-1-git-send-email-jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2010-09-10 18:00 ` Grant Likely
0 siblings, 0 replies; 9+ messages in thread
From: Grant Likely @ 2010-09-10 18:00 UTC (permalink / raw)
To: Jassi Brar
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E
On Fri, Sep 10, 2010 at 08:55:49AM +0900, Jassi Brar wrote:
> We can't do without setting channel and bus width to
> same size. Inorder to do that, use loop read/writes in
> polling mode and appropriate burst size in DMA mode.
>
> Signed-off-by: Jassi Brar <jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
applied to -next branch. Thanks.
g.
> ---
> drivers/spi/spi_s3c64xx.c | 56 +++++++++++++++++++++++++++++++++------------
> 1 files changed, 41 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
> index 39816bb..cf45e01 100644
> --- a/drivers/spi/spi_s3c64xx.c
> +++ b/drivers/spi/spi_s3c64xx.c
> @@ -255,15 +255,25 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
> chcfg |= S3C64XX_SPI_CH_TXCH_ON;
> if (dma_mode) {
> modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
> - s3c2410_dma_config(sdd->tx_dmach, 1);
> + s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
> s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
> xfer->tx_dma, xfer->len);
> s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
> } else {
> - unsigned char *buf = (unsigned char *) xfer->tx_buf;
> - int i = 0;
> - while (i < xfer->len)
> - writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA);
> + switch (sdd->cur_bpw) {
> + case 32:
> + iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
> + xfer->tx_buf, xfer->len / 4);
> + break;
> + case 16:
> + iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
> + xfer->tx_buf, xfer->len / 2);
> + break;
> + default:
> + iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
> + xfer->tx_buf, xfer->len);
> + break;
> + }
> }
> }
>
> @@ -280,7 +290,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
> writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
> | S3C64XX_SPI_PACKET_CNT_EN,
> regs + S3C64XX_SPI_PACKET_CNT);
> - s3c2410_dma_config(sdd->rx_dmach, 1);
> + s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);
> s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
> xfer->rx_dma, xfer->len);
> s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
> @@ -360,20 +370,26 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
> return -EIO;
> }
> } else {
> - unsigned char *buf;
> - int i;
> -
> /* If it was only Tx */
> if (xfer->rx_buf == NULL) {
> sdd->state &= ~TXBUSY;
> return 0;
> }
>
> - i = 0;
> - buf = xfer->rx_buf;
> - while (i < xfer->len)
> - buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA);
> -
> + switch (sdd->cur_bpw) {
> + case 32:
> + ioread32_rep(regs + S3C64XX_SPI_RX_DATA,
> + xfer->rx_buf, xfer->len / 4);
> + break;
> + case 16:
> + ioread16_rep(regs + S3C64XX_SPI_RX_DATA,
> + xfer->rx_buf, xfer->len / 2);
> + break;
> + default:
> + ioread8_rep(regs + S3C64XX_SPI_RX_DATA,
> + xfer->rx_buf, xfer->len);
> + break;
> + }
> sdd->state &= ~RXBUSY;
> }
>
> @@ -423,15 +439,17 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
> switch (sdd->cur_bpw) {
> case 32:
> val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD;
> + val |= S3C64XX_SPI_MODE_CH_TSZ_WORD;
> break;
> case 16:
> val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD;
> + val |= S3C64XX_SPI_MODE_CH_TSZ_HALFWORD;
> break;
> default:
> val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE;
> + val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE;
> break;
> }
> - val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */
>
> writel(val, regs + S3C64XX_SPI_MODE_CFG);
>
> @@ -610,6 +628,14 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
> bpw = xfer->bits_per_word ? : spi->bits_per_word;
> speed = xfer->speed_hz ? : spi->max_speed_hz;
>
> + if (xfer->len % (bpw / 8)) {
> + dev_err(&spi->dev,
> + "Xfer length(%u) not a multiple of word size(%u)\n",
> + xfer->len, bpw / 8);
> + status = -EIO;
> + goto out;
> + }
> +
> if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
> sdd->cur_bpw = bpw;
> sdd->cur_speed = speed;
> --
> 1.6.2.5
>
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing
http://p.sf.net/sfu/novell-sfdev2dev
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-09-10 18:00 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-09 7:18 [PATCH 1/2] SPI: S3C64XX: Correction for 16,32 bits bus width Jassi Brar
[not found] ` <1284016737-21620-1-git-send-email-jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2010-09-09 14:51 ` Grant Likely
[not found] ` <20100909145115.GA5652-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-09-09 15:07 ` Jassi Brar
[not found] ` <AANLkTim-gpnfsvWrFnJBcE9DcWFsh8soJwq4gL_bMpMv-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-09-09 16:00 ` Grant Likely
[not found] ` <20100909160051.GA6273-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-09-09 23:55 ` [PATCH 4/6] " Jassi Brar
[not found] ` <1284076549-17715-1-git-send-email-jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2010-09-10 18:00 ` Grant Likely
[not found] <1OrKX4-0007cO-1K>
2010-09-03 1:36 ` Jassi Brar
[not found] ` <1283477814-31228-1-git-send-email-jassi.brar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2010-09-09 5:07 ` Grant Likely
[not found] ` <20100909050723.GF11833-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-09-09 7:29 ` Jassi Brar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).