diff options
author | Jun Tian <jun.j.tian@intel.com> | 2014-05-12 11:54:46 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-15 16:19:00 -0400 |
commit | 49a75c444fcf07fdde2ec74428b6b1b9ff1c6b15 (patch) | |
tree | 96dd3d0e6f959544d039aaeee54ffeaa57ba0dbe /drivers/platform/goldfish | |
parent | 0cc6c3ab3cdbcf8a4a103d27599a6d0b44a6c315 (diff) |
goldfish: 64-bit pipe driver for goldfish platform
Support 64-bit channel and address for the goldfish pipe driver.
Signed-off-by: Jun Tian <jun.j.tian@intel.com>
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Brian Wood <brian.j.wood@intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/platform/goldfish')
-rw-r--r-- | drivers/platform/goldfish/goldfish_pipe.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/drivers/platform/goldfish/goldfish_pipe.c b/drivers/platform/goldfish/goldfish_pipe.c index 4f5aa831f549..f33c6e0e7fb0 100644 --- a/drivers/platform/goldfish/goldfish_pipe.c +++ b/drivers/platform/goldfish/goldfish_pipe.c | |||
@@ -66,8 +66,14 @@ | |||
66 | #define PIPE_REG_COMMAND 0x00 /* write: value = command */ | 66 | #define PIPE_REG_COMMAND 0x00 /* write: value = command */ |
67 | #define PIPE_REG_STATUS 0x04 /* read */ | 67 | #define PIPE_REG_STATUS 0x04 /* read */ |
68 | #define PIPE_REG_CHANNEL 0x08 /* read/write: channel id */ | 68 | #define PIPE_REG_CHANNEL 0x08 /* read/write: channel id */ |
69 | #ifdef CONFIG_64BIT | ||
70 | #define PIPE_REG_CHANNEL_HIGH 0x30 /* read/write: channel id */ | ||
71 | #endif | ||
69 | #define PIPE_REG_SIZE 0x0c /* read/write: buffer size */ | 72 | #define PIPE_REG_SIZE 0x0c /* read/write: buffer size */ |
70 | #define PIPE_REG_ADDRESS 0x10 /* write: physical address */ | 73 | #define PIPE_REG_ADDRESS 0x10 /* write: physical address */ |
74 | #ifdef CONFIG_64BIT | ||
75 | #define PIPE_REG_ADDRESS_HIGH 0x34 /* write: physical address */ | ||
76 | #endif | ||
71 | #define PIPE_REG_WAKES 0x14 /* read: wake flags */ | 77 | #define PIPE_REG_WAKES 0x14 /* read: wake flags */ |
72 | #define PIPE_REG_PARAMS_ADDR_LOW 0x18 /* read/write: batch data address */ | 78 | #define PIPE_REG_PARAMS_ADDR_LOW 0x18 /* read/write: batch data address */ |
73 | #define PIPE_REG_PARAMS_ADDR_HIGH 0x1c /* read/write: batch data address */ | 79 | #define PIPE_REG_PARAMS_ADDR_HIGH 0x1c /* read/write: batch data address */ |
@@ -109,9 +115,9 @@ | |||
109 | #define PIPE_WAKE_WRITE (1 << 2) /* pipe can now be written to */ | 115 | #define PIPE_WAKE_WRITE (1 << 2) /* pipe can now be written to */ |
110 | 116 | ||
111 | struct access_params { | 117 | struct access_params { |
112 | u32 channel; | 118 | unsigned long channel; |
113 | u32 size; | 119 | u32 size; |
114 | u32 address; | 120 | unsigned long address; |
115 | u32 cmd; | 121 | u32 cmd; |
116 | u32 result; | 122 | u32 result; |
117 | /* reserved for future extension */ | 123 | /* reserved for future extension */ |
@@ -155,7 +161,10 @@ static u32 goldfish_cmd_status(struct goldfish_pipe *pipe, u32 cmd) | |||
155 | struct goldfish_pipe_dev *dev = pipe->dev; | 161 | struct goldfish_pipe_dev *dev = pipe->dev; |
156 | 162 | ||
157 | spin_lock_irqsave(&dev->lock, flags); | 163 | spin_lock_irqsave(&dev->lock, flags); |
158 | writel((u32)pipe, dev->base + PIPE_REG_CHANNEL); | 164 | writel((u32)(u64)pipe, dev->base + PIPE_REG_CHANNEL); |
165 | #ifdef CONFIG_64BIT | ||
166 | writel((u32)((u64)pipe >> 32), dev->base + PIPE_REG_CHANNEL_HIGH); | ||
167 | #endif | ||
159 | writel(cmd, dev->base + PIPE_REG_COMMAND); | 168 | writel(cmd, dev->base + PIPE_REG_COMMAND); |
160 | status = readl(dev->base + PIPE_REG_STATUS); | 169 | status = readl(dev->base + PIPE_REG_STATUS); |
161 | spin_unlock_irqrestore(&dev->lock, flags); | 170 | spin_unlock_irqrestore(&dev->lock, flags); |
@@ -168,7 +177,10 @@ static void goldfish_cmd(struct goldfish_pipe *pipe, u32 cmd) | |||
168 | struct goldfish_pipe_dev *dev = pipe->dev; | 177 | struct goldfish_pipe_dev *dev = pipe->dev; |
169 | 178 | ||
170 | spin_lock_irqsave(&dev->lock, flags); | 179 | spin_lock_irqsave(&dev->lock, flags); |
171 | writel((u32)pipe, dev->base + PIPE_REG_CHANNEL); | 180 | writel((u32)(u64)pipe, dev->base + PIPE_REG_CHANNEL); |
181 | #ifdef CONFIG_64BIT | ||
182 | writel((u32)((u64)pipe >> 32), dev->base + PIPE_REG_CHANNEL_HIGH); | ||
183 | #endif | ||
172 | writel(cmd, dev->base + PIPE_REG_COMMAND); | 184 | writel(cmd, dev->base + PIPE_REG_COMMAND); |
173 | spin_unlock_irqrestore(&dev->lock, flags); | 185 | spin_unlock_irqrestore(&dev->lock, flags); |
174 | } | 186 | } |
@@ -322,9 +334,15 @@ static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer, | |||
322 | spin_lock_irqsave(&dev->lock, irq_flags); | 334 | spin_lock_irqsave(&dev->lock, irq_flags); |
323 | if (access_with_param(dev, CMD_WRITE_BUFFER + cmd_offset, | 335 | if (access_with_param(dev, CMD_WRITE_BUFFER + cmd_offset, |
324 | address, avail, pipe, &status)) { | 336 | address, avail, pipe, &status)) { |
325 | writel((u32)pipe, dev->base + PIPE_REG_CHANNEL); | 337 | writel((u32)(u64)pipe, dev->base + PIPE_REG_CHANNEL); |
338 | #ifdef CONFIG_64BIT | ||
339 | writel((u32)((u64)pipe >> 32), dev->base + PIPE_REG_CHANNEL_HIGH); | ||
340 | #endif | ||
326 | writel(avail, dev->base + PIPE_REG_SIZE); | 341 | writel(avail, dev->base + PIPE_REG_SIZE); |
327 | writel(address, dev->base + PIPE_REG_ADDRESS); | 342 | writel(address, dev->base + PIPE_REG_ADDRESS); |
343 | #ifdef CONFIG_64BIT | ||
344 | writel((u32)((u64)address >> 32), dev->base + PIPE_REG_ADDRESS_HIGH); | ||
345 | #endif | ||
328 | writel(CMD_WRITE_BUFFER + cmd_offset, | 346 | writel(CMD_WRITE_BUFFER + cmd_offset, |
329 | dev->base + PIPE_REG_COMMAND); | 347 | dev->base + PIPE_REG_COMMAND); |
330 | status = readl(dev->base + PIPE_REG_STATUS); | 348 | status = readl(dev->base + PIPE_REG_STATUS); |
@@ -447,7 +465,12 @@ static irqreturn_t goldfish_pipe_interrupt(int irq, void *dev_id) | |||
447 | /* First read the channel, 0 means the end of the list */ | 465 | /* First read the channel, 0 means the end of the list */ |
448 | struct goldfish_pipe *pipe; | 466 | struct goldfish_pipe *pipe; |
449 | unsigned long wakes; | 467 | unsigned long wakes; |
450 | unsigned long channel = readl(dev->base + PIPE_REG_CHANNEL); | 468 | unsigned long channel = 0; |
469 | |||
470 | #ifdef CONFIG_64BIT | ||
471 | channel = (u64)readl(dev->base + PIPE_REG_CHANNEL_HIGH) << 32; | ||
472 | #endif | ||
473 | channel |= readl(dev->base + PIPE_REG_CHANNEL); | ||
451 | 474 | ||
452 | if (channel == 0) | 475 | if (channel == 0) |
453 | break; | 476 | break; |