[PATCH 02/13] powerpc/5200: LocalPlus driver: use SCLPC register structure
Roman Fietze
roman.fietze at telemotive.de
Tue Dec 22 17:59:23 EST 2009
Signed-off-by: Roman Fietze <roman.fietze at telemotive.de>
---
arch/powerpc/include/asm/mpc52xx.h | 24 ++++++++
arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 79 +++++++++++--------------
2 files changed, 59 insertions(+), 44 deletions(-)
diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/asm/mpc52xx.h
index b664ce7..57f8335 100644
--- a/arch/powerpc/include/asm/mpc52xx.h
+++ b/arch/powerpc/include/asm/mpc52xx.h
@@ -193,6 +193,30 @@ struct mpc52xx_xlb {
#define MPC52xx_XLB_CFG_PLDIS (1 << 31)
#define MPC52xx_XLB_CFG_SNOOP (1 << 15)
+/* SCLPC */
+struct mpc52xx_sclpc {
+ union {
+ u8 restart; /* 0x00 restart bit */
+ u32 packet_size; /* 0x00 packet size register */
+ } packet_size;
+ u32 start_address; /* 0x04 start Address register */
+ u32 control; /* 0x08 control register */
+ u32 enable; /* 0x0C enable register */
+ u32 unused0; /* 0x10 */
+ union {
+ u8 status; /* 0x14 status register bits */
+ u32 bytes_done; /* 0x14 bytes done register bits, read only */
+ } bytes_done_status;
+
+ u32 reserved1[(0x40-0x18) / sizeof(u32)]; /* 0x18 .. 0x3c */
+
+ u32 fifo_data; /* 0x40 FIFO data word register */
+ u32 fifo_status; /* 0x44 FIFO status register */
+ u8 fifo_control; /* 0x48 FIFO control register */
+ u8 reserved2[3];
+ u32 fifo_alarm; /* 0x4C FIFO alarm register */
+};
+
/* Clock Distribution control */
struct mpc52xx_cdm {
u32 jtag_id; /* CDM + 0x00 reg0 read only */
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
index 4c84aa5..2763d5e 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -27,20 +27,10 @@ MODULE_AUTHOR("Grant Likely <grant.likely at secretlab.ca>");
MODULE_DESCRIPTION("MPC5200 LocalPlus FIFO device driver");
MODULE_LICENSE("GPL");
-#define LPBFIFO_REG_PACKET_SIZE (0x00)
-#define LPBFIFO_REG_START_ADDRESS (0x04)
-#define LPBFIFO_REG_CONTROL (0x08)
-#define LPBFIFO_REG_ENABLE (0x0C)
-#define LPBFIFO_REG_BYTES_DONE_STATUS (0x14)
-#define LPBFIFO_REG_FIFO_DATA (0x40)
-#define LPBFIFO_REG_FIFO_STATUS (0x44)
-#define LPBFIFO_REG_FIFO_CONTROL (0x48)
-#define LPBFIFO_REG_FIFO_ALARM (0x4C)
-
struct mpc52xx_lpbfifo {
struct device *dev;
phys_addr_t regs_phys;
- void __iomem *regs;
+ struct mpc52xx_sclpc __iomem *regs;
int irq;
spinlock_t lock;
@@ -72,10 +62,10 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
int poll_dma = req->flags & MPC52XX_LPBFIFO_FLAG_POLL_DMA;
/* Set and clear the reset bits; is good practice in User Manual */
- out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+ out_be32(&lpbfifo.regs->enable, 0x01010000);
/* set master enable bit */
- out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000001);
+ out_be32(&lpbfifo.regs->enable, 0x00000001);
if (!dma) {
/* While the FIFO can be setup for transfer sizes as large as
* 16M-1, the FIFO itself is only 512 bytes deep and it does
@@ -91,14 +81,14 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
/* Load the FIFO with data */
if (write) {
- reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
+ reg = &lpbfifo.regs->fifo_data;
data = req->data + req->pos;
for (i = 0; i < transfer_size; i += 4)
out_be32(reg, *data++);
}
/* Unmask both error and completion irqs */
- out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000301);
+ out_be32(&lpbfifo.regs->enable, 0x00000301);
} else {
/* Choose the correct direction
*
@@ -108,12 +98,12 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
* is a risk of DMA not transferring the last chunk of data
*/
if (write) {
- out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1e4);
- out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 7);
+ out_be32(&lpbfifo.regs->fifo_alarm, 0x1e4);
+ out_8(&lpbfifo.regs->fifo_control, 7);
lpbfifo.bcom_cur_task = lpbfifo.bcom_tx_task;
} else {
- out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1ff);
- out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 0);
+ out_be32(&lpbfifo.regs->fifo_alarm, 0x1ff);
+ out_8(&lpbfifo.regs->fifo_control, 0);
lpbfifo.bcom_cur_task = lpbfifo.bcom_rx_task;
if (poll_dma) {
@@ -155,21 +145,21 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
/* Unmask irqs */
if (write && (!poll_dma))
bit_fields |= 0x00000100; /* completion irq too */
- out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, bit_fields);
+ out_be32(&lpbfifo.regs->enable, bit_fields);
}
/* Set transfer size, width, chip select and READ mode */
- out_be32(lpbfifo.regs + LPBFIFO_REG_START_ADDRESS,
+ out_be32(&lpbfifo.regs->start_address,
req->offset + req->pos);
- out_be32(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, transfer_size);
+ out_be32(&lpbfifo.regs->packet_size.packet_size, transfer_size);
bit_fields = req->cs << 24 | 0x000008;
if (!write)
bit_fields |= 0x010000; /* read mode */
- out_be32(lpbfifo.regs + LPBFIFO_REG_CONTROL, bit_fields);
+ out_be32(&lpbfifo.regs->control, bit_fields);
/* Kick it off */
- out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
+ out_8(&lpbfifo.regs->packet_size.restart, 0x01);
if (dma)
bcom_enable(lpbfifo.bcom_cur_task);
}
@@ -218,7 +208,7 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id)
{
struct mpc52xx_lpbfifo_request *req;
- u32 status = in_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
+ u32 status = in_8(&lpbfifo.regs->bytes_done_status.status);
void __iomem *reg;
u32 *data;
int count, i;
@@ -253,18 +243,18 @@ static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id)
/* check abort bit */
if (status & 0x10) {
- out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+ out_be32(&lpbfifo.regs->enable, 0x01010000);
do_callback = 1;
goto out;
}
/* Read result from hardware */
- count = in_be32(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
+ count = in_be32(&lpbfifo.regs->bytes_done_status.bytes_done);
count &= 0x00ffffff;
if (!dma && !write) {
/* copy the data out of the FIFO */
- reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
+ reg = &lpbfifo.regs->fifo_data;
data = req->data + req->pos;
for (i = 0; i < count; i += 4)
*data++ = in_be32(reg);
@@ -281,7 +271,7 @@ static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id)
out:
/* Clear the IRQ */
- out_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS, 0x01);
+ out_8(&lpbfifo.regs->bytes_done_status.status, 0x01);
if (dma && (status & 0x11)) {
/*
@@ -379,11 +369,11 @@ void mpc52xx_lpbfifo_poll(void)
int write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
/*
- * For more information, see comments on the "Fat Lady"
+ * For more information, see comments on the "Fat Lady"
*/
if (dma && write)
mpc52xx_lpbfifo_irq(0, NULL);
- else
+ else
mpc52xx_lpbfifo_bcom_irq(0, NULL);
}
EXPORT_SYMBOL(mpc52xx_lpbfifo_poll);
@@ -429,7 +419,7 @@ void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req)
/* Put it into reset and clear the state */
bcom_gen_bd_rx_reset(lpbfifo.bcom_rx_task);
bcom_gen_bd_tx_reset(lpbfifo.bcom_tx_task);
- out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+ out_be32(&lpbfifo.regs->enable, 0x01010000);
lpbfifo.req = NULL;
}
spin_unlock_irqrestore(&lpbfifo.lock, flags);
@@ -459,19 +449,19 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
spin_lock_init(&lpbfifo.lock);
/* Put FIFO into reset */
- out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+ out_be32(&lpbfifo.regs->enable, 0x01010000);
- /* Register the interrupt handler */
+ /* register the interrupt handler */
rc = request_irq(lpbfifo.irq, mpc52xx_lpbfifo_irq, 0,
"mpc52xx-lpbfifo", &lpbfifo);
if (rc)
goto err_irq;
/* Request the Bestcomm receive (fifo --> memory) task and IRQ */
- lpbfifo.bcom_rx_task =
- bcom_gen_bd_rx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
- BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC,
- 16*1024*1024);
+ lpbfifo.bcom_rx_task = bcom_gen_bd_rx_init(2,
+ res.start + offsetof(struct mpc52xx_sclpc, fifo_data),
+ BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC,
+ 16*1024*1024);
if (!lpbfifo.bcom_rx_task)
goto err_bcom_rx;
@@ -482,9 +472,10 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
goto err_bcom_rx_irq;
/* Request the Bestcomm transmit (memory --> fifo) task and IRQ */
- lpbfifo.bcom_tx_task =
- bcom_gen_bd_tx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
- BCOM_INITIATOR_SCLPC, BCOM_IPR_SCLPC);
+ lpbfifo.bcom_tx_task = bcom_gen_bd_tx_init(2,
+ res.start + offsetof(struct mpc52xx_sclpc, fifo_data),
+ BCOM_INITIATOR_SCLPC,
+ BCOM_IPR_SCLPC);
if (!lpbfifo.bcom_tx_task)
goto err_bcom_tx;
@@ -511,12 +502,12 @@ static int __devexit mpc52xx_lpbfifo_remove(struct of_device *op)
return 0;
/* Put FIFO in reset */
- out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
+ out_be32(&lpbfifo.regs->enable, 0x01010000);
- /* Release the bestcomm transmit task */
+ /* release the bestcomm transmit task */
free_irq(bcom_get_task_irq(lpbfifo.bcom_tx_task), &lpbfifo);
bcom_gen_bd_tx_release(lpbfifo.bcom_tx_task);
-
+
/* Release the bestcomm receive task */
free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
--
1.6.5.5
--
Roman Fietze Telemotive AG Büro Mühlhausen
Breitwiesen 73347 Mühlhausen
Tel.: +49(0)7335/18493-45 http://www.telemotive.de
More information about the Linuxppc-dev
mailing list