aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--drivers/dma/shdma.c8
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c121
-rw-r--r--drivers/serial/sh-sci.c42
-rw-r--r--drivers/serial/sh-sci.h29
-rw-r--r--drivers/sh/Makefile5
-rw-r--r--drivers/video/Kconfig8
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/sh_mipi_dsi.c505
10 files changed, 664 insertions, 59 deletions
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 9e01e96fee94..8344375dc015 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -128,7 +128,7 @@ config TXX9_DMAC
128 128
129config SH_DMAE 129config SH_DMAE
130 tristate "Renesas SuperH DMAC support" 130 tristate "Renesas SuperH DMAC support"
131 depends on SUPERH && SH_DMA 131 depends on (SUPERH && SH_DMA) || (ARM && ARCH_SHMOBILE)
132 depends on !SH_DMA_API 132 depends on !SH_DMA_API
133 select DMA_ENGINE 133 select DMA_ENGINE
134 help 134 help
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index a2a519fd2a24..fb64cf36ba61 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -816,7 +816,7 @@ static irqreturn_t sh_dmae_interrupt(int irq, void *data)
816 return ret; 816 return ret;
817} 817}
818 818
819#if defined(CONFIG_CPU_SH4) 819#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
820static irqreturn_t sh_dmae_err(int irq, void *data) 820static irqreturn_t sh_dmae_err(int irq, void *data)
821{ 821{
822 struct sh_dmae_device *shdev = (struct sh_dmae_device *)data; 822 struct sh_dmae_device *shdev = (struct sh_dmae_device *)data;
@@ -1057,7 +1057,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
1057 /* Default transfer size of 32 bytes requires 32-byte alignment */ 1057 /* Default transfer size of 32 bytes requires 32-byte alignment */
1058 shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE; 1058 shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE;
1059 1059
1060#if defined(CONFIG_CPU_SH4) 1060#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
1061 chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); 1061 chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
1062 1062
1063 if (!chanirq_res) 1063 if (!chanirq_res)
@@ -1082,7 +1082,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
1082 1082
1083#else 1083#else
1084 chanirq_res = errirq_res; 1084 chanirq_res = errirq_res;
1085#endif /* CONFIG_CPU_SH4 */ 1085#endif /* CONFIG_CPU_SH4 || CONFIG_ARCH_SHMOBILE */
1086 1086
1087 if (chanirq_res->start == chanirq_res->end && 1087 if (chanirq_res->start == chanirq_res->end &&
1088 !platform_get_resource(pdev, IORESOURCE_IRQ, 1)) { 1088 !platform_get_resource(pdev, IORESOURCE_IRQ, 1)) {
@@ -1129,7 +1129,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
1129chan_probe_err: 1129chan_probe_err:
1130 sh_dmae_chan_remove(shdev); 1130 sh_dmae_chan_remove(shdev);
1131eirqres: 1131eirqres:
1132#if defined(CONFIG_CPU_SH4) 1132#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
1133 free_irq(errirq, shdev); 1133 free_irq(errirq, shdev);
1134eirq_err: 1134eirq_err:
1135#endif 1135#endif
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index bceafbfa7268..29e01f6238a7 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -549,7 +549,7 @@ config I2C_SH7760
549 549
550config I2C_SH_MOBILE 550config I2C_SH_MOBILE
551 tristate "SuperH Mobile I2C Controller" 551 tristate "SuperH Mobile I2C Controller"
552 depends on SUPERH 552 depends on SUPERH || ARCH_SHMOBILE
553 help 553 help
554 If you say yes to this option, support will be included for the 554 If you say yes to this option, support will be included for the
555 built-in I2C interface on the Renesas SH-Mobile processor. 555 built-in I2C interface on the Renesas SH-Mobile processor.
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index ffb405d7c6f2..598c49acaeb5 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -119,8 +119,10 @@ struct sh_mobile_i2c_data {
119 struct i2c_adapter adap; 119 struct i2c_adapter adap;
120 120
121 struct clk *clk; 121 struct clk *clk;
122 u_int8_t icic;
122 u_int8_t iccl; 123 u_int8_t iccl;
123 u_int8_t icch; 124 u_int8_t icch;
125 u_int8_t flags;
124 126
125 spinlock_t lock; 127 spinlock_t lock;
126 wait_queue_head_t wait; 128 wait_queue_head_t wait;
@@ -129,15 +131,17 @@ struct sh_mobile_i2c_data {
129 int sr; 131 int sr;
130}; 132};
131 133
134#define IIC_FLAG_HAS_ICIC67 (1 << 0)
135
132#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ 136#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */
133 137
134/* Register offsets */ 138/* Register offsets */
135#define ICDR(pd) (pd->reg + 0x00) 139#define ICDR 0x00
136#define ICCR(pd) (pd->reg + 0x04) 140#define ICCR 0x04
137#define ICSR(pd) (pd->reg + 0x08) 141#define ICSR 0x08
138#define ICIC(pd) (pd->reg + 0x0c) 142#define ICIC 0x0c
139#define ICCL(pd) (pd->reg + 0x10) 143#define ICCL 0x10
140#define ICCH(pd) (pd->reg + 0x14) 144#define ICCH 0x14
141 145
142/* Register bits */ 146/* Register bits */
143#define ICCR_ICE 0x80 147#define ICCR_ICE 0x80
@@ -155,11 +159,32 @@ struct sh_mobile_i2c_data {
155#define ICSR_WAIT 0x02 159#define ICSR_WAIT 0x02
156#define ICSR_DTE 0x01 160#define ICSR_DTE 0x01
157 161
162#define ICIC_ICCLB8 0x80
163#define ICIC_ICCHB8 0x40
158#define ICIC_ALE 0x08 164#define ICIC_ALE 0x08
159#define ICIC_TACKE 0x04 165#define ICIC_TACKE 0x04
160#define ICIC_WAITE 0x02 166#define ICIC_WAITE 0x02
161#define ICIC_DTEE 0x01 167#define ICIC_DTEE 0x01
162 168
169static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data)
170{
171 if (offs == ICIC)
172 data |= pd->icic;
173
174 iowrite8(data, pd->reg + offs);
175}
176
177static unsigned char iic_rd(struct sh_mobile_i2c_data *pd, int offs)
178{
179 return ioread8(pd->reg + offs);
180}
181
182static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs,
183 unsigned char set, unsigned char clr)
184{
185 iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr);
186}
187
163static void activate_ch(struct sh_mobile_i2c_data *pd) 188static void activate_ch(struct sh_mobile_i2c_data *pd)
164{ 189{
165 unsigned long i2c_clk; 190 unsigned long i2c_clk;
@@ -187,6 +212,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
187 else 212 else
188 pd->iccl = (u_int8_t)(num/denom); 213 pd->iccl = (u_int8_t)(num/denom);
189 214
215 /* one more bit of ICCL in ICIC */
216 if (pd->flags & IIC_FLAG_HAS_ICIC67) {
217 if ((num/denom) > 0xff)
218 pd->icic |= ICIC_ICCLB8;
219 else
220 pd->icic &= ~ICIC_ICCLB8;
221 }
222
190 /* Calculate the value for icch. From the data sheet: 223 /* Calculate the value for icch. From the data sheet:
191 icch = (p clock / transfer rate) * (H / (L + H)) */ 224 icch = (p clock / transfer rate) * (H / (L + H)) */
192 num = i2c_clk * 4; 225 num = i2c_clk * 4;
@@ -196,25 +229,33 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
196 else 229 else
197 pd->icch = (u_int8_t)(num/denom); 230 pd->icch = (u_int8_t)(num/denom);
198 231
232 /* one more bit of ICCH in ICIC */
233 if (pd->flags & IIC_FLAG_HAS_ICIC67) {
234 if ((num/denom) > 0xff)
235 pd->icic |= ICIC_ICCHB8;
236 else
237 pd->icic &= ~ICIC_ICCHB8;
238 }
239
199 /* Enable channel and configure rx ack */ 240 /* Enable channel and configure rx ack */
200 iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); 241 iic_set_clr(pd, ICCR, ICCR_ICE, 0);
201 242
202 /* Mask all interrupts */ 243 /* Mask all interrupts */
203 iowrite8(0, ICIC(pd)); 244 iic_wr(pd, ICIC, 0);
204 245
205 /* Set the clock */ 246 /* Set the clock */
206 iowrite8(pd->iccl, ICCL(pd)); 247 iic_wr(pd, ICCL, pd->iccl);
207 iowrite8(pd->icch, ICCH(pd)); 248 iic_wr(pd, ICCH, pd->icch);
208} 249}
209 250
210static void deactivate_ch(struct sh_mobile_i2c_data *pd) 251static void deactivate_ch(struct sh_mobile_i2c_data *pd)
211{ 252{
212 /* Clear/disable interrupts */ 253 /* Clear/disable interrupts */
213 iowrite8(0, ICSR(pd)); 254 iic_wr(pd, ICSR, 0);
214 iowrite8(0, ICIC(pd)); 255 iic_wr(pd, ICIC, 0);
215 256
216 /* Disable channel */ 257 /* Disable channel */
217 iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); 258 iic_set_clr(pd, ICCR, 0, ICCR_ICE);
218 259
219 /* Disable clock and mark device as idle */ 260 /* Disable clock and mark device as idle */
220 clk_disable(pd->clk); 261 clk_disable(pd->clk);
@@ -233,35 +274,35 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
233 274
234 switch (op) { 275 switch (op) {
235 case OP_START: /* issue start and trigger DTE interrupt */ 276 case OP_START: /* issue start and trigger DTE interrupt */
236 iowrite8(0x94, ICCR(pd)); 277 iic_wr(pd, ICCR, 0x94);
237 break; 278 break;
238 case OP_TX_FIRST: /* disable DTE interrupt and write data */ 279 case OP_TX_FIRST: /* disable DTE interrupt and write data */
239 iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE, ICIC(pd)); 280 iic_wr(pd, ICIC, ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
240 iowrite8(data, ICDR(pd)); 281 iic_wr(pd, ICDR, data);
241 break; 282 break;
242 case OP_TX: /* write data */ 283 case OP_TX: /* write data */
243 iowrite8(data, ICDR(pd)); 284 iic_wr(pd, ICDR, data);
244 break; 285 break;
245 case OP_TX_STOP: /* write data and issue a stop afterwards */ 286 case OP_TX_STOP: /* write data and issue a stop afterwards */
246 iowrite8(data, ICDR(pd)); 287 iic_wr(pd, ICDR, data);
247 iowrite8(0x90, ICCR(pd)); 288 iic_wr(pd, ICCR, 0x90);
248 break; 289 break;
249 case OP_TX_TO_RX: /* select read mode */ 290 case OP_TX_TO_RX: /* select read mode */
250 iowrite8(0x81, ICCR(pd)); 291 iic_wr(pd, ICCR, 0x81);
251 break; 292 break;
252 case OP_RX: /* just read data */ 293 case OP_RX: /* just read data */
253 ret = ioread8(ICDR(pd)); 294 ret = iic_rd(pd, ICDR);
254 break; 295 break;
255 case OP_RX_STOP: /* enable DTE interrupt, issue stop */ 296 case OP_RX_STOP: /* enable DTE interrupt, issue stop */
256 iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, 297 iic_wr(pd, ICIC,
257 ICIC(pd)); 298 ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
258 iowrite8(0xc0, ICCR(pd)); 299 iic_wr(pd, ICCR, 0xc0);
259 break; 300 break;
260 case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */ 301 case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */
261 iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, 302 iic_wr(pd, ICIC,
262 ICIC(pd)); 303 ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
263 ret = ioread8(ICDR(pd)); 304 ret = iic_rd(pd, ICDR);
264 iowrite8(0xc0, ICCR(pd)); 305 iic_wr(pd, ICCR, 0xc0);
265 break; 306 break;
266 } 307 }
267 308
@@ -367,7 +408,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
367 unsigned char sr; 408 unsigned char sr;
368 int wakeup; 409 int wakeup;
369 410
370 sr = ioread8(ICSR(pd)); 411 sr = iic_rd(pd, ICSR);
371 pd->sr |= sr; /* remember state */ 412 pd->sr |= sr; /* remember state */
372 413
373 dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr, 414 dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr,
@@ -376,7 +417,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
376 417
377 if (sr & (ICSR_AL | ICSR_TACK)) { 418 if (sr & (ICSR_AL | ICSR_TACK)) {
378 /* don't interrupt transaction - continue to issue stop */ 419 /* don't interrupt transaction - continue to issue stop */
379 iowrite8(sr & ~(ICSR_AL | ICSR_TACK), ICSR(pd)); 420 iic_wr(pd, ICSR, sr & ~(ICSR_AL | ICSR_TACK));
380 wakeup = 0; 421 wakeup = 0;
381 } else if (pd->msg->flags & I2C_M_RD) 422 } else if (pd->msg->flags & I2C_M_RD)
382 wakeup = sh_mobile_i2c_isr_rx(pd); 423 wakeup = sh_mobile_i2c_isr_rx(pd);
@@ -384,7 +425,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
384 wakeup = sh_mobile_i2c_isr_tx(pd); 425 wakeup = sh_mobile_i2c_isr_tx(pd);
385 426
386 if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */ 427 if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */
387 iowrite8(sr & ~ICSR_WAIT, ICSR(pd)); 428 iic_wr(pd, ICSR, sr & ~ICSR_WAIT);
388 429
389 if (wakeup) { 430 if (wakeup) {
390 pd->sr |= SW_DONE; 431 pd->sr |= SW_DONE;
@@ -402,21 +443,21 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
402 } 443 }
403 444
404 /* Initialize channel registers */ 445 /* Initialize channel registers */
405 iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); 446 iic_set_clr(pd, ICCR, 0, ICCR_ICE);
406 447
407 /* Enable channel and configure rx ack */ 448 /* Enable channel and configure rx ack */
408 iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); 449 iic_set_clr(pd, ICCR, ICCR_ICE, 0);
409 450
410 /* Set the clock */ 451 /* Set the clock */
411 iowrite8(pd->iccl, ICCL(pd)); 452 iic_wr(pd, ICCL, pd->iccl);
412 iowrite8(pd->icch, ICCH(pd)); 453 iic_wr(pd, ICCH, pd->icch);
413 454
414 pd->msg = usr_msg; 455 pd->msg = usr_msg;
415 pd->pos = -1; 456 pd->pos = -1;
416 pd->sr = 0; 457 pd->sr = 0;
417 458
418 /* Enable all interrupts to begin with */ 459 /* Enable all interrupts to begin with */
419 iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE | ICIC_DTEE, ICIC(pd)); 460 iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
420 return 0; 461 return 0;
421} 462}
422 463
@@ -451,7 +492,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
451 492
452 retry_count = 1000; 493 retry_count = 1000;
453again: 494again:
454 val = ioread8(ICSR(pd)); 495 val = iic_rd(pd, ICSR);
455 496
456 dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); 497 dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
457 498
@@ -576,6 +617,12 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
576 goto err_irq; 617 goto err_irq;
577 } 618 }
578 619
620 /* The IIC blocks on SH-Mobile ARM processors
621 * come with two new bits in ICIC.
622 */
623 if (size > 0x17)
624 pd->flags |= IIC_FLAG_HAS_ICIC67;
625
579 /* Enable Runtime PM for this device. 626 /* Enable Runtime PM for this device.
580 * 627 *
581 * Also tell the Runtime PM core to ignore children 628 * Also tell the Runtime PM core to ignore children
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 5f90fcd7d107..c291b3add1d2 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -346,6 +346,27 @@ static int scif_rxfill(struct uart_port *port)
346 return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; 346 return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
347 } 347 }
348} 348}
349#elif defined(CONFIG_ARCH_SH7372)
350static int scif_txfill(struct uart_port *port)
351{
352 if (port->type == PORT_SCIFA)
353 return sci_in(port, SCFDR) >> 8;
354 else
355 return sci_in(port, SCTFDR);
356}
357
358static int scif_txroom(struct uart_port *port)
359{
360 return port->fifosize - scif_txfill(port);
361}
362
363static int scif_rxfill(struct uart_port *port)
364{
365 if (port->type == PORT_SCIFA)
366 return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
367 else
368 return sci_in(port, SCRFDR);
369}
349#else 370#else
350static int scif_txfill(struct uart_port *port) 371static int scif_txfill(struct uart_port *port)
351{ 372{
@@ -683,7 +704,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
683 u16 ssr = sci_in(port, SCxSR); 704 u16 ssr = sci_in(port, SCxSR);
684 705
685 /* Disable future Rx interrupts */ 706 /* Disable future Rx interrupts */
686 if (port->type == PORT_SCIFA) { 707 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
687 disable_irq_nosync(irq); 708 disable_irq_nosync(irq);
688 scr |= 0x4000; 709 scr |= 0x4000;
689 } else { 710 } else {
@@ -928,7 +949,7 @@ static void sci_dma_tx_complete(void *arg)
928 949
929 if (!uart_circ_empty(xmit)) { 950 if (!uart_circ_empty(xmit)) {
930 schedule_work(&s->work_tx); 951 schedule_work(&s->work_tx);
931 } else if (port->type == PORT_SCIFA) { 952 } else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
932 u16 ctrl = sci_in(port, SCSCR); 953 u16 ctrl = sci_in(port, SCSCR);
933 sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE); 954 sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE);
934 } 955 }
@@ -1184,7 +1205,7 @@ static void sci_start_tx(struct uart_port *port)
1184 unsigned short ctrl; 1205 unsigned short ctrl;
1185 1206
1186#ifdef CONFIG_SERIAL_SH_SCI_DMA 1207#ifdef CONFIG_SERIAL_SH_SCI_DMA
1187 if (port->type == PORT_SCIFA) { 1208 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
1188 u16 new, scr = sci_in(port, SCSCR); 1209 u16 new, scr = sci_in(port, SCSCR);
1189 if (s->chan_tx) 1210 if (s->chan_tx)
1190 new = scr | 0x8000; 1211 new = scr | 0x8000;
@@ -1197,7 +1218,7 @@ static void sci_start_tx(struct uart_port *port)
1197 s->cookie_tx < 0) 1218 s->cookie_tx < 0)
1198 schedule_work(&s->work_tx); 1219 schedule_work(&s->work_tx);
1199#endif 1220#endif
1200 if (!s->chan_tx || port->type == PORT_SCIFA) { 1221 if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
1201 /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ 1222 /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
1202 ctrl = sci_in(port, SCSCR); 1223 ctrl = sci_in(port, SCSCR);
1203 sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE); 1224 sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE);
@@ -1210,7 +1231,7 @@ static void sci_stop_tx(struct uart_port *port)
1210 1231
1211 /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ 1232 /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
1212 ctrl = sci_in(port, SCSCR); 1233 ctrl = sci_in(port, SCSCR);
1213 if (port->type == PORT_SCIFA) 1234 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
1214 ctrl &= ~0x8000; 1235 ctrl &= ~0x8000;
1215 ctrl &= ~SCI_CTRL_FLAGS_TIE; 1236 ctrl &= ~SCI_CTRL_FLAGS_TIE;
1216 sci_out(port, SCSCR, ctrl); 1237 sci_out(port, SCSCR, ctrl);
@@ -1222,7 +1243,7 @@ static void sci_start_rx(struct uart_port *port)
1222 1243
1223 /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ 1244 /* Set RIE (Receive Interrupt Enable) bit in SCSCR */
1224 ctrl |= sci_in(port, SCSCR); 1245 ctrl |= sci_in(port, SCSCR);
1225 if (port->type == PORT_SCIFA) 1246 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
1226 ctrl &= ~0x4000; 1247 ctrl &= ~0x4000;
1227 sci_out(port, SCSCR, ctrl); 1248 sci_out(port, SCSCR, ctrl);
1228} 1249}
@@ -1233,7 +1254,7 @@ static void sci_stop_rx(struct uart_port *port)
1233 1254
1234 /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ 1255 /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */
1235 ctrl = sci_in(port, SCSCR); 1256 ctrl = sci_in(port, SCSCR);
1236 if (port->type == PORT_SCIFA) 1257 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
1237 ctrl &= ~0x4000; 1258 ctrl &= ~0x4000;
1238 ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); 1259 ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE);
1239 sci_out(port, SCSCR, ctrl); 1260 sci_out(port, SCSCR, ctrl);
@@ -1271,7 +1292,7 @@ static void rx_timer_fn(unsigned long arg)
1271 struct uart_port *port = &s->port; 1292 struct uart_port *port = &s->port;
1272 u16 scr = sci_in(port, SCSCR); 1293 u16 scr = sci_in(port, SCSCR);
1273 1294
1274 if (port->type == PORT_SCIFA) { 1295 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
1275 scr &= ~0x4000; 1296 scr &= ~0x4000;
1276 enable_irq(s->irqs[1]); 1297 enable_irq(s->irqs[1]);
1277 } 1298 }
@@ -1524,6 +1545,8 @@ static const char *sci_type(struct uart_port *port)
1524 return "scif"; 1545 return "scif";
1525 case PORT_SCIFA: 1546 case PORT_SCIFA:
1526 return "scifa"; 1547 return "scifa";
1548 case PORT_SCIFB:
1549 return "scifb";
1527 } 1550 }
1528 1551
1529 return NULL; 1552 return NULL;
@@ -1612,6 +1635,9 @@ static int __devinit sci_init_single(struct platform_device *dev,
1612 port->line = index; 1635 port->line = index;
1613 1636
1614 switch (p->type) { 1637 switch (p->type) {
1638 case PORT_SCIFB:
1639 port->fifosize = 256;
1640 break;
1615 case PORT_SCIFA: 1641 case PORT_SCIFA:
1616 port->fifosize = 64; 1642 port->fifosize = 64;
1617 break; 1643 break;
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index f70c49f915fa..9b52f77a9305 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -322,7 +322,7 @@
322#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ 322#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
323 static inline unsigned int sci_##name##_in(struct uart_port *port) \ 323 static inline unsigned int sci_##name##_in(struct uart_port *port) \
324 { \ 324 { \
325 if (port->type == PORT_SCIF) { \ 325 if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
326 SCI_IN(scif_size, scif_offset) \ 326 SCI_IN(scif_size, scif_offset) \
327 } else { /* PORT_SCI or PORT_SCIFA */ \ 327 } else { /* PORT_SCI or PORT_SCIFA */ \
328 SCI_IN(sci_size, sci_offset); \ 328 SCI_IN(sci_size, sci_offset); \
@@ -330,7 +330,7 @@
330 } \ 330 } \
331 static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ 331 static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
332 { \ 332 { \
333 if (port->type == PORT_SCIF) { \ 333 if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
334 SCI_OUT(scif_size, scif_offset, value) \ 334 SCI_OUT(scif_size, scif_offset, value) \
335 } else { /* PORT_SCI or PORT_SCIFA */ \ 335 } else { /* PORT_SCI or PORT_SCIFA */ \
336 SCI_OUT(sci_size, sci_offset, value); \ 336 SCI_OUT(sci_size, sci_offset, value); \
@@ -384,8 +384,12 @@
384 defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 384 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
385 defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 385 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
386 defined(CONFIG_ARCH_SH7367) || \ 386 defined(CONFIG_ARCH_SH7367) || \
387 defined(CONFIG_ARCH_SH7377) || \ 387 defined(CONFIG_ARCH_SH7377)
388 defined(CONFIG_ARCH_SH7372) 388#define SCIF_FNS(name, scif_offset, scif_size) \
389 CPU_SCIF_FNS(name, scif_offset, scif_size)
390#elif defined(CONFIG_ARCH_SH7372)
391#define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \
392 CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size)
389#define SCIF_FNS(name, scif_offset, scif_size) \ 393#define SCIF_FNS(name, scif_offset, scif_size) \
390 CPU_SCIF_FNS(name, scif_offset, scif_size) 394 CPU_SCIF_FNS(name, scif_offset, scif_size)
391#else 395#else
@@ -422,8 +426,7 @@
422 defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 426 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
423 defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 427 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
424 defined(CONFIG_ARCH_SH7367) || \ 428 defined(CONFIG_ARCH_SH7367) || \
425 defined(CONFIG_ARCH_SH7377) || \ 429 defined(CONFIG_ARCH_SH7377)
426 defined(CONFIG_ARCH_SH7372)
427 430
428SCIF_FNS(SCSMR, 0x00, 16) 431SCIF_FNS(SCSMR, 0x00, 16)
429SCIF_FNS(SCBRR, 0x04, 8) 432SCIF_FNS(SCBRR, 0x04, 8)
@@ -436,6 +439,20 @@ SCIF_FNS(SCFDR, 0x1c, 16)
436SCIF_FNS(SCxTDR, 0x20, 8) 439SCIF_FNS(SCxTDR, 0x20, 8)
437SCIF_FNS(SCxRDR, 0x24, 8) 440SCIF_FNS(SCxRDR, 0x24, 8)
438SCIF_FNS(SCLSR, 0x00, 0) 441SCIF_FNS(SCLSR, 0x00, 0)
442#elif defined(CONFIG_ARCH_SH7372)
443SCIF_FNS(SCSMR, 0x00, 16)
444SCIF_FNS(SCBRR, 0x04, 8)
445SCIF_FNS(SCSCR, 0x08, 16)
446SCIF_FNS(SCTDSR, 0x0c, 16)
447SCIF_FNS(SCFER, 0x10, 16)
448SCIF_FNS(SCxSR, 0x14, 16)
449SCIF_FNS(SCFCR, 0x18, 16)
450SCIF_FNS(SCFDR, 0x1c, 16)
451SCIF_FNS(SCTFDR, 0x38, 16)
452SCIF_FNS(SCRFDR, 0x3c, 16)
453SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8)
454SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8)
455SCIF_FNS(SCLSR, 0x00, 0)
439#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ 456#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
440 defined(CONFIG_CPU_SUBTYPE_SH7724) 457 defined(CONFIG_CPU_SUBTYPE_SH7724)
441SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) 458SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile
index 78bb5127abd0..08fc653a825c 100644
--- a/drivers/sh/Makefile
+++ b/drivers/sh/Makefile
@@ -1,9 +1,10 @@
1# 1#
2# Makefile for the SuperH specific drivers. 2# Makefile for the SuperH specific drivers.
3# 3#
4obj-y := clk.o intc.o
5
4obj-$(CONFIG_SUPERHYWAY) += superhyway/ 6obj-$(CONFIG_SUPERHYWAY) += superhyway/
5obj-$(CONFIG_MAPLE) += maple/ 7obj-$(CONFIG_MAPLE) += maple/
8
6obj-$(CONFIG_GENERIC_GPIO) += pfc.o 9obj-$(CONFIG_GENERIC_GPIO) += pfc.o
7obj-$(CONFIG_SUPERH) += clk.o
8obj-$(CONFIG_SH_CLK_CPG) += clk-cpg.o 10obj-$(CONFIG_SH_CLK_CPG) += clk-cpg.o
9obj-y += intc.o
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3d94a1471724..a9f9e5eaa040 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1895,6 +1895,13 @@ config FB_W100
1895 1895
1896 If unsure, say N. 1896 If unsure, say N.
1897 1897
1898config SH_MIPI_DSI
1899 tristate
1900 depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
1901
1902config SH_LCD_MIPI_DSI
1903 bool
1904
1898config FB_SH_MOBILE_LCDC 1905config FB_SH_MOBILE_LCDC
1899 tristate "SuperH Mobile LCDC framebuffer support" 1906 tristate "SuperH Mobile LCDC framebuffer support"
1900 depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK 1907 depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
@@ -1903,6 +1910,7 @@ config FB_SH_MOBILE_LCDC
1903 select FB_SYS_IMAGEBLIT 1910 select FB_SYS_IMAGEBLIT
1904 select FB_SYS_FOPS 1911 select FB_SYS_FOPS
1905 select FB_DEFERRED_IO 1912 select FB_DEFERRED_IO
1913 select SH_MIPI_DSI if SH_LCD_MIPI_DSI
1906 ---help--- 1914 ---help---
1907 Frame buffer driver for the on-chip SH-Mobile LCD controller. 1915 Frame buffer driver for the on-chip SH-Mobile LCD controller.
1908 1916
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ddc2af2ba45b..3c3bf867ef18 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -123,6 +123,7 @@ obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
123obj-$(CONFIG_FB_PS3) += ps3fb.o 123obj-$(CONFIG_FB_PS3) += ps3fb.o
124obj-$(CONFIG_FB_SM501) += sm501fb.o 124obj-$(CONFIG_FB_SM501) += sm501fb.o
125obj-$(CONFIG_FB_XILINX) += xilinxfb.o 125obj-$(CONFIG_FB_XILINX) += xilinxfb.o
126obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o
126obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o 127obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
127obj-$(CONFIG_FB_OMAP) += omap/ 128obj-$(CONFIG_FB_OMAP) += omap/
128obj-y += omap2/ 129obj-y += omap2/
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
new file mode 100644
index 000000000000..017ae9f47d36
--- /dev/null
+++ b/drivers/video/sh_mipi_dsi.c
@@ -0,0 +1,505 @@
1/*
2 * Renesas SH-mobile MIPI DSI support
3 *
4 * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This is free software; you can redistribute it and/or modify
7 * it under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/clk.h>
12#include <linux/delay.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17#include <linux/string.h>
18#include <linux/types.h>
19
20#include <video/mipi_display.h>
21#include <video/sh_mipi_dsi.h>
22#include <video/sh_mobile_lcdc.h>
23
24#define CMTSRTCTR 0x80d0
25#define CMTSRTREQ 0x8070
26
27#define DSIINTE 0x0060
28
29/* E.g., sh7372 has 2 MIPI-DSIs - one for each LCDC */
30#define MAX_SH_MIPI_DSI 2
31
32struct sh_mipi {
33 void __iomem *base;
34 struct clk *dsit_clk;
35 struct clk *dsip_clk;
36};
37
38static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI];
39
40/* Protect the above array */
41static DEFINE_MUTEX(array_lock);
42
43static struct sh_mipi *sh_mipi_by_handle(int handle)
44{
45 if (handle >= ARRAY_SIZE(mipi_dsi) || handle < 0)
46 return NULL;
47
48 return mipi_dsi[handle];
49}
50
51static int sh_mipi_send_short(struct sh_mipi *mipi, u8 dsi_cmd,
52 u8 cmd, u8 param)
53{
54 u32 data = (dsi_cmd << 24) | (cmd << 16) | (param << 8);
55 int cnt = 100;
56
57 /* transmit a short packet to LCD panel */
58 iowrite32(1 | data, mipi->base + 0x80d0); /* CMTSRTCTR */
59 iowrite32(1, mipi->base + 0x8070); /* CMTSRTREQ */
60
61 while ((ioread32(mipi->base + 0x8070) & 1) && --cnt)
62 udelay(1);
63
64 return cnt ? 0 : -ETIMEDOUT;
65}
66
67#define LCD_CHAN2MIPI(c) ((c) < LCDC_CHAN_MAINLCD || (c) > LCDC_CHAN_SUBLCD ? \
68 -EINVAL : (c) - 1)
69
70static int sh_mipi_dcs(int handle, u8 cmd)
71{
72 struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle));
73 if (!mipi)
74 return -ENODEV;
75 return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE, cmd, 0);
76}
77
78static int sh_mipi_dcs_param(int handle, u8 cmd, u8 param)
79{
80 struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle));
81 if (!mipi)
82 return -ENODEV;
83 return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd,
84 param);
85}
86
87static void sh_mipi_dsi_enable(struct sh_mipi *mipi, bool enable)
88{
89 /*
90 * enable LCDC data tx, transition to LPS after completion of each HS
91 * packet
92 */
93 iowrite32(0x00000002 | enable, mipi->base + 0x8000); /* DTCTR */
94}
95
96static void sh_mipi_shutdown(struct platform_device *pdev)
97{
98 struct sh_mipi *mipi = platform_get_drvdata(pdev);
99
100 sh_mipi_dsi_enable(mipi, false);
101}
102
103static void mipi_display_on(void *arg)
104{
105 struct sh_mipi *mipi = arg;
106
107 sh_mipi_dsi_enable(mipi, true);
108}
109
110static void mipi_display_off(void *arg)
111{
112 struct sh_mipi *mipi = arg;
113
114 sh_mipi_dsi_enable(mipi, false);
115}
116
117static int __init sh_mipi_setup(struct sh_mipi *mipi,
118 struct sh_mipi_dsi_info *pdata)
119{
120 void __iomem *base = mipi->base;
121 struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan;
122 u32 pctype, datatype, pixfmt;
123 u32 linelength;
124 bool yuv;
125
126 /* Select data format */
127 switch (pdata->data_format) {
128 case MIPI_RGB888:
129 pctype = 0;
130 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
131 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
132 linelength = ch->lcd_cfg.xres * 3;
133 yuv = false;
134 break;
135 case MIPI_RGB565:
136 pctype = 1;
137 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
138 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
139 linelength = ch->lcd_cfg.xres * 2;
140 yuv = false;
141 break;
142 case MIPI_RGB666_LP:
143 pctype = 2;
144 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
145 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
146 linelength = ch->lcd_cfg.xres * 3;
147 yuv = false;
148 break;
149 case MIPI_RGB666:
150 pctype = 3;
151 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
152 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
153 linelength = (ch->lcd_cfg.xres * 18 + 7) / 8;
154 yuv = false;
155 break;
156 case MIPI_BGR888:
157 pctype = 8;
158 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
159 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
160 linelength = ch->lcd_cfg.xres * 3;
161 yuv = false;
162 break;
163 case MIPI_BGR565:
164 pctype = 9;
165 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
166 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
167 linelength = ch->lcd_cfg.xres * 2;
168 yuv = false;
169 break;
170 case MIPI_BGR666_LP:
171 pctype = 0xa;
172 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
173 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
174 linelength = ch->lcd_cfg.xres * 3;
175 yuv = false;
176 break;
177 case MIPI_BGR666:
178 pctype = 0xb;
179 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
180 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
181 linelength = (ch->lcd_cfg.xres * 18 + 7) / 8;
182 yuv = false;
183 break;
184 case MIPI_YUYV:
185 pctype = 4;
186 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
187 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
188 linelength = ch->lcd_cfg.xres * 2;
189 yuv = true;
190 break;
191 case MIPI_UYVY:
192 pctype = 5;
193 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
194 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
195 linelength = ch->lcd_cfg.xres * 2;
196 yuv = true;
197 break;
198 case MIPI_YUV420_L:
199 pctype = 6;
200 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
201 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
202 linelength = (ch->lcd_cfg.xres * 12 + 7) / 8;
203 yuv = true;
204 break;
205 case MIPI_YUV420:
206 pctype = 7;
207 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
208 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
209 /* Length of U/V line */
210 linelength = (ch->lcd_cfg.xres + 1) / 2;
211 yuv = true;
212 break;
213 default:
214 return -EINVAL;
215 }
216
217 if ((yuv && ch->interface_type != YUV422) ||
218 (!yuv && ch->interface_type != RGB24))
219 return -EINVAL;
220
221 /* reset DSI link */
222 iowrite32(0x00000001, base); /* SYSCTRL */
223 /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */
224 udelay(50);
225 iowrite32(0x00000000, base); /* SYSCTRL */
226
227 /* setup DSI link */
228
229 /*
230 * Default = ULPS enable |
231 * Contention detection enabled |
232 * EoT packet transmission enable |
233 * CRC check enable |
234 * ECC check enable
235 * additionally enable first two lanes
236 */
237 iowrite32(0x00003703, base + 0x04); /* SYSCONF */
238 /*
239 * T_wakeup = 0x7000
240 * T_hs-trail = 3
241 * T_hs-prepare = 3
242 * T_clk-trail = 3
243 * T_clk-prepare = 2
244 */
245 iowrite32(0x70003332, base + 0x08); /* TIMSET */
246 /* no responses requested */
247 iowrite32(0x00000000, base + 0x18); /* RESREQSET0 */
248 /* request response to packets of type 0x28 */
249 iowrite32(0x00000100, base + 0x1c); /* RESREQSET1 */
250 /* High-speed transmission timeout, default 0xffffffff */
251 iowrite32(0x0fffffff, base + 0x20); /* HSTTOVSET */
252 /* LP reception timeout, default 0xffffffff */
253 iowrite32(0x0fffffff, base + 0x24); /* LPRTOVSET */
254 /* Turn-around timeout, default 0xffffffff */
255 iowrite32(0x0fffffff, base + 0x28); /* TATOVSET */
256 /* Peripheral reset timeout, default 0xffffffff */
257 iowrite32(0x0fffffff, base + 0x2c); /* PRTOVSET */
258 /* Enable timeout counters */
259 iowrite32(0x00000f00, base + 0x30); /* DSICTRL */
260 /* Interrupts not used, disable all */
261 iowrite32(0, base + DSIINTE);
262 /* DSI-Tx bias on */
263 iowrite32(0x00000001, base + 0x70); /* PHYCTRL */
264 udelay(200);
265 /* Deassert resets, power on, set multiplier */
266 iowrite32(0x03070b01, base + 0x70); /* PHYCTRL */
267
268 /* setup l-bridge */
269
270 /*
271 * Enable transmission of all packets,
272 * transmit LPS after each HS packet completion
273 */
274 iowrite32(0x00000006, base + 0x8000); /* DTCTR */
275 /* VSYNC width = 2 (<< 17) */
276 iowrite32(0x00040000 | (pctype << 12) | datatype, base + 0x8020); /* VMCTR1 */
277 /*
278 * Non-burst mode with sync pulses: VSE and HSE are output,
279 * HSA period allowed, no commands in LP
280 */
281 iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */
282 /*
283 * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see
284 * sh_mobile_lcdc_info.ch[0].lcd_cfg.xres), HSALEN = 1 - default
285 * (unused, since VMCTR2[HSABM] = 0)
286 */
287 iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */
288
289 msleep(5);
290
291 /* setup LCD panel */
292
293 /* cf. drivers/video/omap/lcd_mipid.c */
294 sh_mipi_dcs(ch->chan, MIPI_DCS_EXIT_SLEEP_MODE);
295 msleep(120);
296 /*
297 * [7] - Page Address Mode
298 * [6] - Column Address Mode
299 * [5] - Page / Column Address Mode
300 * [4] - Display Device Line Refresh Order
301 * [3] - RGB/BGR Order
302 * [2] - Display Data Latch Data Order
303 * [1] - Flip Horizontal
304 * [0] - Flip Vertical
305 */
306 sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
307 /* cf. set_data_lines() */
308 sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_PIXEL_FORMAT,
309 pixfmt << 4);
310 sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON);
311
312 return 0;
313}
314
315static int __init sh_mipi_probe(struct platform_device *pdev)
316{
317 struct sh_mipi *mipi;
318 struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
319 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
320 unsigned long rate, f_current;
321 int idx = pdev->id, ret;
322 char dsip_clk[] = "dsi.p_clk";
323
324 if (!res || idx >= ARRAY_SIZE(mipi_dsi) || !pdata)
325 return -ENODEV;
326
327 mutex_lock(&array_lock);
328 if (idx < 0)
329 for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++)
330 ;
331
332 if (idx == ARRAY_SIZE(mipi_dsi)) {
333 ret = -EBUSY;
334 goto efindslot;
335 }
336
337 mipi = kzalloc(sizeof(*mipi), GFP_KERNEL);
338 if (!mipi) {
339 ret = -ENOMEM;
340 goto ealloc;
341 }
342
343 if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
344 dev_err(&pdev->dev, "MIPI register region already claimed\n");
345 ret = -EBUSY;
346 goto ereqreg;
347 }
348
349 mipi->base = ioremap(res->start, resource_size(res));
350 if (!mipi->base) {
351 ret = -ENOMEM;
352 goto emap;
353 }
354
355 mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk");
356 if (IS_ERR(mipi->dsit_clk)) {
357 ret = PTR_ERR(mipi->dsit_clk);
358 goto eclktget;
359 }
360
361 f_current = clk_get_rate(mipi->dsit_clk);
362 /* 80MHz required by the datasheet */
363 rate = clk_round_rate(mipi->dsit_clk, 80000000);
364 if (rate > 0 && rate != f_current)
365 ret = clk_set_rate(mipi->dsit_clk, rate);
366 else
367 ret = rate;
368 if (ret < 0)
369 goto esettrate;
370
371 dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate);
372
373 sprintf(dsip_clk, "dsi%1.1dp_clk", idx);
374 mipi->dsip_clk = clk_get(&pdev->dev, dsip_clk);
375 if (IS_ERR(mipi->dsip_clk)) {
376 ret = PTR_ERR(mipi->dsip_clk);
377 goto eclkpget;
378 }
379
380 f_current = clk_get_rate(mipi->dsip_clk);
381 /* Between 10 and 50MHz */
382 rate = clk_round_rate(mipi->dsip_clk, 24000000);
383 if (rate > 0 && rate != f_current)
384 ret = clk_set_rate(mipi->dsip_clk, rate);
385 else
386 ret = rate;
387 if (ret < 0)
388 goto esetprate;
389
390 dev_dbg(&pdev->dev, "DSI-P clk %lu -> %lu\n", f_current, rate);
391
392 msleep(10);
393
394 ret = clk_enable(mipi->dsit_clk);
395 if (ret < 0)
396 goto eclkton;
397
398 ret = clk_enable(mipi->dsip_clk);
399 if (ret < 0)
400 goto eclkpon;
401
402 mipi_dsi[idx] = mipi;
403
404 ret = sh_mipi_setup(mipi, pdata);
405 if (ret < 0)
406 goto emipisetup;
407
408 mutex_unlock(&array_lock);
409 platform_set_drvdata(pdev, mipi);
410
411 /* Set up LCDC callbacks */
412 pdata->lcd_chan->board_cfg.board_data = mipi;
413 pdata->lcd_chan->board_cfg.display_on = mipi_display_on;
414 pdata->lcd_chan->board_cfg.display_off = mipi_display_off;
415
416 return 0;
417
418emipisetup:
419 mipi_dsi[idx] = NULL;
420 clk_disable(mipi->dsip_clk);
421eclkpon:
422 clk_disable(mipi->dsit_clk);
423eclkton:
424esetprate:
425 clk_put(mipi->dsip_clk);
426eclkpget:
427esettrate:
428 clk_put(mipi->dsit_clk);
429eclktget:
430 iounmap(mipi->base);
431emap:
432 release_mem_region(res->start, resource_size(res));
433ereqreg:
434 kfree(mipi);
435ealloc:
436efindslot:
437 mutex_unlock(&array_lock);
438
439 return ret;
440}
441
442static int __exit sh_mipi_remove(struct platform_device *pdev)
443{
444 struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
445 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
446 struct sh_mipi *mipi = platform_get_drvdata(pdev);
447 int i, ret;
448
449 mutex_lock(&array_lock);
450
451 for (i = 0; i < ARRAY_SIZE(mipi_dsi) && mipi_dsi[i] != mipi; i++)
452 ;
453
454 if (i == ARRAY_SIZE(mipi_dsi)) {
455 ret = -EINVAL;
456 } else {
457 ret = 0;
458 mipi_dsi[i] = NULL;
459 }
460
461 mutex_unlock(&array_lock);
462
463 if (ret < 0)
464 return ret;
465
466 pdata->lcd_chan->board_cfg.display_on = NULL;
467 pdata->lcd_chan->board_cfg.display_off = NULL;
468 pdata->lcd_chan->board_cfg.board_data = NULL;
469
470 clk_disable(mipi->dsip_clk);
471 clk_disable(mipi->dsit_clk);
472 clk_put(mipi->dsit_clk);
473 clk_put(mipi->dsip_clk);
474 iounmap(mipi->base);
475 if (res)
476 release_mem_region(res->start, resource_size(res));
477 platform_set_drvdata(pdev, NULL);
478 kfree(mipi);
479
480 return 0;
481}
482
483static struct platform_driver sh_mipi_driver = {
484 .remove = __exit_p(sh_mipi_remove),
485 .shutdown = sh_mipi_shutdown,
486 .driver = {
487 .name = "sh-mipi-dsi",
488 },
489};
490
491static int __init sh_mipi_init(void)
492{
493 return platform_driver_probe(&sh_mipi_driver, sh_mipi_probe);
494}
495module_init(sh_mipi_init);
496
497static void __exit sh_mipi_exit(void)
498{
499 platform_driver_unregister(&sh_mipi_driver);
500}
501module_exit(sh_mipi_exit);
502
503MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
504MODULE_DESCRIPTION("SuperH / ARM-shmobile MIPI DSI driver");
505MODULE_LICENSE("GPL v2");