1
From 355d6522c22ed6a1105944c1fc0db240cea1372a Mon Sep 17 00:00:00 2001
2
From: =?UTF-8?q?Juha=20Riihim=C3=A4ki?= <juha.riihimaki@nokia.com>
3
Date: Mon, 18 Feb 2013 16:58:31 +0000
4
Subject: [PATCH 46/69] dsi: add transfer done callback
6
Content-Type: text/plain; charset=UTF-8
7
Content-Transfer-Encoding: 8bit
9
Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
11
hw/display/dsi.c | 15 +++++++++++++++
12
hw/display/omap_dss.c | 35 ++++++++++++++++++++++++++++++-----
13
include/hw/dsi.h | 3 +++
14
3 files changed, 48 insertions(+), 5 deletions(-)
16
diff --git a/hw/display/dsi.c b/hw/display/dsi.c
17
index 6e7f1ca..f7af1a7 100644
18
--- a/hw/display/dsi.c
19
+++ b/hw/display/dsi.c
20
@@ -130,6 +130,21 @@ int dsi_blt(DSIHost *host, int vc, void *data, int width, int height,
24
+void dsi_bltdone(DSIHost *host, int vc)
26
+ if (vc >=0 && vc < 4) {
27
+ DSIDevice *dev = host->device[vc];
29
+ DSIDeviceClass *dc = DSI_DEVICE_GET_CLASS(dev);
32
+ DSI_ERROR_NODEVICE(vc);
35
+ hw_error("%s: invalid virtual channel id (%d)\n", __FUNCTION__, vc);
39
void dsi_te_trigger(const DSIDevice *dev)
41
if (dev && dev->host && dev->host->te_trigger) {
42
diff --git a/hw/display/omap_dss.c b/hw/display/omap_dss.c
43
index 05e457a..d8fafa3 100644
44
--- a/hw/display/omap_dss.c
45
+++ b/hw/display/omap_dss.c
46
@@ -185,6 +185,7 @@ struct omap_dss_s {
50
+ QEMUTimer *xfer_timer;
52
/* protocol engine registers */
54
@@ -400,12 +401,28 @@ static void omap_rfbi_transfer_start(struct omap_dss_s *s)
55
omap_dss_framedone(s);
58
+static void omap_dsi_transfer_stop(void *opaque)
60
+ struct omap_dss_s *s = opaque;
62
+ qemu_del_timer(s->dsi.xfer_timer);
63
+ for (i = 0; i < 4; i++) {
64
+ if ((s->dsi.vc[i].ctrl & 1) && /* VC_EN */
65
+ ((s->dsi.vc[i].te >> 30) & 3)) { /* TE_START | TE_EN */
66
+ TRACEDSI("TE data transfer ready, signaling framedone");
67
+ s->dsi.vc[i].te = 0; /* transfer complete */
68
+ omap_dss_framedone(s);
69
+ dsi_bltdone(s->dsi.host, i);
74
static void omap_dsi_transfer_start(struct omap_dss_s *s, int ch)
76
if (((s->dispc.control >> 11) & 1) && /* STALLMODE */
77
(s->dsi.ctrl & 1) && /* IF_EN */
78
(s->dsi.vc[ch].ctrl & 1) && /* VC_EN */
79
- (s->dsi.vc[ch].te >> 30) & 3) { /* TE_START | TE_EN */
80
+ ((s->dsi.vc[ch].te >> 30) & 3)) { /* TE_START | TE_EN */
81
TRACEDSI("start TE data transfer on channel %d for %d bytes",
82
ch, s->dsi.vc[ch].te & 0xffffff);
83
TRACEDSI("vc%d irqenable=0x%08x", ch, s->dsi.vc[ch].irqen);
84
@@ -417,9 +434,9 @@ static void omap_dsi_transfer_start(struct omap_dss_s *s, int ch)
86
const int format = (s->dispc.plane[0].attr >> 1) & 0xf;
87
const int col_pitch = omap_lcd_Bpp[format] +
88
- (s->dispc.plane[0].colinc - 1);
89
+ (s->dispc.plane[0].colinc - 1);
90
const int row_pitch = (s->dispc.plane[0].nx * col_pitch) +
91
- (s->dispc.plane[0].rowinc - 1);
92
+ (s->dispc.plane[0].rowinc - 1);
93
hwaddr len = row_pitch * s->dispc.plane[0].ny;
94
void *data = cpu_physical_memory_map(s->dispc.plane[0].addr[0],
96
@@ -433,8 +450,14 @@ static void omap_dsi_transfer_start(struct omap_dss_s *s, int ch)
98
cpu_physical_memory_unmap(data, len, 0, 0);
100
- s->dsi.vc[ch].te = 0; /* transfer complete */
101
- omap_dss_framedone(s);
102
+ /* We cannot signal transfer complete immediately since some
103
+ * display drivers assume transfer takes some time. Instead,
104
+ * setup a small delay and report transfer complete a bit
106
+ s->dsi.vc[ch].ctrl &= ~(0x11 << 16); /* TX/RX fifo not full */
107
+ qemu_mod_timer(s->dsi.xfer_timer,
108
+ qemu_get_clock_ns(vm_clock)
109
+ + get_ticks_per_sec() / 1000);
113
@@ -2489,6 +2512,8 @@ static int omap_dss_init(SysBusDevice *dev)
114
s->dsi.host = dsi_init_host(&dev->qdev, "omap3_dsi",
117
+ s->dsi.xfer_timer = qemu_new_timer_ns(vm_clock, omap_dsi_transfer_stop,
119
memory_region_init_io(&s->iomem_dsi, &omap_dsi_ops, s,
121
sysbus_init_mmio(dev, &s->iomem_dsi);
122
diff --git a/include/hw/dsi.h b/include/hw/dsi.h
123
index 2714ed2..d35fdb5 100644
124
--- a/include/hw/dsi.h
125
+++ b/include/hw/dsi.h
126
@@ -54,6 +54,7 @@ typedef void (*dsi_write_cb)(DSIDevice *dev, uint32_t data, int len);
127
typedef uint32_t (*dsi_read_cb)(DSIDevice *dev, uint32_t data, int len);
128
typedef int (*dsi_blt_cb)(DSIDevice *dev, void *data, int width, int height,
129
int col_pitch, int row_pitch, int format);
130
+typedef void (*dsi_bltdone_cb)(DSIDevice *dev);
132
/* common device callbacks */
133
typedef void (*dsi_common_write_cb)(DSICommonDevice *dev, uint32_t data,
134
@@ -75,6 +76,7 @@ typedef struct {
138
+ dsi_bltdone_cb bltdone;
142
@@ -126,6 +128,7 @@ void dsi_long_write(DSIHost *host, uint32_t header, uint32_t payload,
144
int dsi_blt(DSIHost *host, int vc, void *data, int width, int height,
145
int col_pitch, int row_pitch, int format);
146
+void dsi_bltdone(DSIHost *host, int vc);
148
/* device -> host functions */
149
void dsi_te_trigger(const DSIDevice *dev);