~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to .pc/linaro-patches-1.5.0/0046-dsi-add-transfer-done-callback.patch/hw/display/dsi.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * MIPI DSI interface.
3
 
 *
4
 
 * Copyright (C) 2008-2010 Nokia Corporation
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the GNU General Public License as
8
 
 * published by the Free Software Foundation; either version 2 or
9
 
 * (at your option) any later version of the License.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License along
17
 
 * with this program; if not, write to the Free Software Foundation, Inc.,
18
 
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
 
 */
20
 
#include "hw/dsi.h"
21
 
 
22
 
#define DSI_ERROR_NODEVICE(channel) \
23
 
    fprintf(stderr, "%s: no device attached on virtual channel %d\n", \
24
 
            __FUNCTION__, channel)
25
 
#define DSI_EXTRACTPARAM(var, data, nb) \
26
 
    { \
27
 
        int i; \
28
 
        for (i = nb; i--; data >>= 8) \
29
 
        var = (var << 8) | (data & 0xff); \
30
 
    }
31
 
 
32
 
struct DSIHost {
33
 
    BusState qbus;
34
 
    DSIDevice *device[4];
35
 
    dsi_te_trigger_cb te_trigger;
36
 
    dsi_get_drawfn_cb get_drawfn;
37
 
};
38
 
 
39
 
static Property dsi_props[] = {
40
 
    DEFINE_PROP_UINT8("virtual_channel", DSIDevice, vchannel, 0),
41
 
    DEFINE_PROP_END_OF_LIST()
42
 
};
43
 
 
44
 
#define TYPE_DSI_BUS "dsi-bus"
45
 
#define DSI_BUS(obj) OBJECT_CHECK(DSIHost, (obj), TYPE_DSI_BUS)
46
 
 
47
 
static const TypeInfo dsi_bus_info = {
48
 
    .name = TYPE_DSI_BUS,
49
 
    .parent = TYPE_BUS,
50
 
    .instance_size = sizeof(DSIHost),
51
 
};
52
 
 
53
 
DSIHost *dsi_init_host(DeviceState *parent, const char *name,
54
 
                       dsi_te_trigger_cb te_trigger_cb,
55
 
                       dsi_get_drawfn_cb get_drawfn_cb)
56
 
{
57
 
    DSIHost *host = FROM_QBUS(DSIHost, qbus_create(TYPE_DSI_BUS, parent, name));
58
 
    host->te_trigger = te_trigger_cb;
59
 
    host->get_drawfn = get_drawfn_cb;
60
 
    return host;
61
 
}
62
 
 
63
 
uint32_t dsi_short_write(DSIHost *host, uint32_t data)
64
 
{
65
 
    DSIDevice *dev = host->device[(data >> 6) & 3];
66
 
    if (dev) {
67
 
        DSIDeviceClass *dc = DSI_DEVICE_GET_CLASS(dev);
68
 
        uint16_t payload = data >> 8;
69
 
        switch (data & 0x3f) { /* id */
70
 
        case 0x05: /* short_write_0 */
71
 
            dc->write(dev, payload & 0xff, 1);
72
 
            break;
73
 
        case 0x06: /* read */
74
 
            return dc->read(dev, payload & 0xff, 1);
75
 
        case 0x15: /* short_write_1 */
76
 
            dc->write(dev, payload, 2);
77
 
            break;
78
 
        case 0x37: /* set maximum return packet size */
79
 
            dev->max_return_size = data;
80
 
            break;
81
 
        default:
82
 
            hw_error("%s: unknown/unimplemented DSI id (0x%02x)",
83
 
                     __FUNCTION__, data & 0x3f);
84
 
            break;
85
 
        }
86
 
    } else {
87
 
        DSI_ERROR_NODEVICE((data >> 6) & 3);
88
 
    }
89
 
    return 0;
90
 
}
91
 
 
92
 
void dsi_long_write(DSIHost *host, uint32_t header, uint32_t payload,
93
 
                    uint32_t counter)
94
 
{
95
 
    DSIDevice *dev = host->device[(header >> 6) & 3];
96
 
    if (dev) {
97
 
        DSIDeviceClass *dc = DSI_DEVICE_GET_CLASS(dev);
98
 
        switch (header & 0x3f) { /* id */
99
 
        case 0x09: /* null packet */
100
 
            /* ignore */
101
 
            break;
102
 
        case 0x39: /* long write */
103
 
            dc->write(dev, payload, counter > 4 ? 4 : counter);
104
 
            break;
105
 
        default:
106
 
            hw_error("%s: unknown/unimplemented DSI id (0x%02x)",
107
 
                     __FUNCTION__, header & 0x3f);
108
 
            break;
109
 
        }
110
 
    } else {
111
 
        DSI_ERROR_NODEVICE((header >> 6) & 3);
112
 
    }
113
 
}
114
 
 
115
 
int dsi_blt(DSIHost *host, int vc, void *data, int width, int height,
116
 
            int col_pitch, int row_pitch, int format)
117
 
{
118
 
    if (vc >= 0 && vc < 4) {
119
 
        DSIDevice *dev = host->device[vc];
120
 
        if (dev) {
121
 
            DSIDeviceClass *dc = DSI_DEVICE_GET_CLASS(dev);
122
 
            return dc->blt(dev, data, width, height,
123
 
                           col_pitch, row_pitch, format);
124
 
        } else {
125
 
            DSI_ERROR_NODEVICE(vc);
126
 
        }
127
 
    } else {
128
 
        hw_error("%s: invalid virtual channel id (%d)\n", __FUNCTION__, vc);
129
 
    }
130
 
    return 0;
131
 
}
132
 
 
133
 
void dsi_te_trigger(const DSIDevice *dev)
134
 
{
135
 
    if (dev && dev->host && dev->host->te_trigger) {
136
 
        dev->host->te_trigger(dev->host->qbus.parent, dev->vchannel);
137
 
    }
138
 
}
139
 
 
140
 
drawfn dsi_get_drawfn(const DSIDevice *dev, int format, int bpp)
141
 
{
142
 
    if (dev && dev->host && dev->host->get_drawfn) {
143
 
        return dev->host->get_drawfn(dev->host->qbus.parent, format, bpp);
144
 
    }
145
 
    return NULL;
146
 
}
147
 
 
148
 
static void dsi_common_reset(DeviceState *dev)
149
 
{
150
 
    DSICommonDevice *s = DSI_COMMON_DEVICE_FROM_QDEV(dev);
151
 
    DSICommonDeviceClass *dcc = DSI_COMMON_DEVICE_GET_CLASS(dev);
152
 
    s->bs = bs_cmd;
153
 
    s->cmd = 0;
154
 
    s->powermode = 0x08;
155
 
    s->addrmode = 0;
156
 
    s->bpp_dbi = 0;
157
 
    s->bpp_dpi = 0;
158
 
    s->dr = 0;
159
 
    s->sc = 0;
160
 
    s->ec = 0;
161
 
    s->cc = 0;
162
 
    s->sp = 0;
163
 
    s->ep = 0;
164
 
    s->cp = 0;
165
 
    s->te_mode = te_off;
166
 
    if (dcc->reset) {
167
 
        dcc->reset(s);
168
 
    }
169
 
}
170
 
 
171
 
static void dsi_common_write(DSIDevice *dev, uint32_t data, int len)
172
 
{
173
 
    uint8_t x;
174
 
    DSICommonDevice *s = FROM_DSI_DEVICE(DSICommonDevice, dev);
175
 
    DSICommonDeviceClass *dcc = DSI_COMMON_DEVICE_GET_CLASS(s);
176
 
    if  (s->bs == bs_cmd) {
177
 
        s->cmd = data & 0xff;
178
 
        data >>= 8;
179
 
        len--;
180
 
    }
181
 
    switch (s->cmd) {
182
 
    case 0x10: /* enter sleep */
183
 
        x = s->powermode;
184
 
        s->powermode &= ~0x10;
185
 
        if ((x ^ s->powermode) && dcc->powermode_changed) {
186
 
            dcc->powermode_changed(s);
187
 
        }
188
 
        break;
189
 
    case 0x11: /* exit sleep */
190
 
        x = s->powermode;
191
 
        s->powermode |= 0x10;
192
 
        s->dr ^= 0xe0;
193
 
        if ((x ^ s->powermode) && dcc->powermode_changed) {
194
 
            dcc->powermode_changed(s);
195
 
        }
196
 
        break;
197
 
    case 0x28: /* display off */
198
 
        x = s->powermode;
199
 
        s->powermode &= ~0x04;
200
 
        if ((x ^ s->powermode) && dcc->powermode_changed) {
201
 
            dcc->powermode_changed(s);
202
 
        }
203
 
        break;
204
 
    case 0x29: /* display on */
205
 
        x = s->powermode;
206
 
        s->powermode |= 0x04;
207
 
        if ((x ^ s->powermode) && dcc->powermode_changed) {
208
 
            dcc->powermode_changed(s);
209
 
        }
210
 
        break;
211
 
    case 0x2a: /* set column address */
212
 
        if (s->bs == bs_cmd) {
213
 
            s->bs = bs_data;
214
 
            s->sc = 0;
215
 
            s->ec = 0;
216
 
            DSI_EXTRACTPARAM(s->sc, data, 2);
217
 
            DSI_EXTRACTPARAM(s->ec, data, 1);
218
 
            s->cc = s->sc;
219
 
        } else {
220
 
            s->bs = bs_cmd;
221
 
            DSI_EXTRACTPARAM(s->ec, data, 1);
222
 
            s->cc = s->sc;
223
 
        }
224
 
        break;
225
 
    case 0x2b: /* set page address */
226
 
        if (s->bs == bs_cmd) {
227
 
            s->bs = bs_data;
228
 
            s->sp = 0;
229
 
            s->ep = 0;
230
 
            DSI_EXTRACTPARAM(s->sp, data, 2);
231
 
            DSI_EXTRACTPARAM(s->ep, data, 1);
232
 
            s->cp = s->sp;
233
 
        } else {
234
 
            s->bs = bs_cmd;
235
 
            DSI_EXTRACTPARAM(s->ep, data, 1);
236
 
            s->cp = s->sp;
237
 
        }
238
 
        break;
239
 
    case 0x34: /* disable tear effect control */
240
 
        x = s->te_mode;
241
 
        s->te_mode = te_off;
242
 
        if ((x ^ s->te_mode) && dcc->temode_changed) {
243
 
            dcc->temode_changed(s);
244
 
        }
245
 
        break;
246
 
    case 0x35: /* enable tear effect control */
247
 
        x = s->te_mode;
248
 
        s->te_mode = (data & 0x01) ? te_hvsync : te_vsync;
249
 
        if ((x ^ s->te_mode) && dcc->temode_changed) {
250
 
            dcc->temode_changed(s);
251
 
        }
252
 
        break;
253
 
    case 0x36: /* set address mode */
254
 
        s->addrmode = data & 0xff;
255
 
        break;
256
 
    case 0x3a: /* set pixel format */
257
 
        switch ((data >> 4) & 7) {
258
 
        case 0:
259
 
            s->bpp_dpi = 0;
260
 
            break;
261
 
        case 2: /* 8bpp */
262
 
            s->bpp_dpi = 1;
263
 
            break;
264
 
        case 5: /* 16bpp */
265
 
            s->bpp_dpi = 2;
266
 
            break;
267
 
        case 7: /* 24bpp */
268
 
            s->bpp_dpi = 4; /* faster to process than 3 */
269
 
            break;
270
 
        default:
271
 
            hw_error("%s: unsupported dpi pixel format %d",
272
 
                     __FUNCTION__, (data >> 4) & 7);
273
 
            break;
274
 
        }
275
 
        switch ((data & 7)) {
276
 
        case 0:
277
 
            s->bpp_dbi = 0;
278
 
            break;
279
 
        case 2: /* 8bpp */
280
 
            s->bpp_dbi = 1;
281
 
            break;
282
 
        case 5: /* 16bpp */
283
 
            s->bpp_dbi = 2;
284
 
            break;
285
 
        case 7: /* 24bpp */
286
 
            s->bpp_dbi = 4; /* faster to process than 3 */
287
 
            break;
288
 
        default:
289
 
            hw_error("%s: unsupported dbi pixel format %d",
290
 
                     __FUNCTION__, data & 7);
291
 
            break;
292
 
        }
293
 
        break;
294
 
    default:
295
 
        if (dcc->write) {
296
 
            if (s->bs == bs_cmd) {
297
 
                data = (data << 8) | s->cmd;
298
 
                len++;
299
 
            }
300
 
            dcc->write(s, data, len);
301
 
        } else {
302
 
            hw_error("%s: unknown command 0x%02x\n", __FUNCTION__, s->cmd);
303
 
        }
304
 
        break;
305
 
    }
306
 
}
307
 
 
308
 
static uint32_t dsi_common_read(DSIDevice *dev, uint32_t data, int len)
309
 
{
310
 
    DSICommonDevice *s = FROM_DSI_DEVICE(DSICommonDevice, dev);
311
 
    DSICommonDeviceClass *dcc = DSI_COMMON_DEVICE_GET_CLASS(s);
312
 
    if (s->bs != bs_cmd) {
313
 
        hw_error("%s: previous WRITE command not completed", __FUNCTION__);
314
 
    }
315
 
    s->cmd = data & 0xff;
316
 
    switch (s->cmd) {
317
 
    case 0x0a: /* get power mode */
318
 
        return DSI_MAKERETURNBYTE(s->powermode);
319
 
    case 0x0b: /* get address mode */
320
 
        return DSI_MAKERETURNBYTE(s->addrmode);
321
 
    case 0x0f: /* get diagnostic result */
322
 
        return DSI_MAKERETURNBYTE(s->dr);
323
 
    default:
324
 
        if (dcc->read) {
325
 
            return dcc->read(s, data, len);
326
 
        } else {
327
 
            hw_error("%s: unknown command 0x%02x\n", __FUNCTION__, s->cmd);
328
 
        }
329
 
        break;
330
 
    }
331
 
    return 0;
332
 
}
333
 
 
334
 
static int dsi_device_init(DeviceState *dev)
335
 
{
336
 
    DSIDevice *dsi_dev = DSI_DEVICE_FROM_QDEV(dev);
337
 
    DSIDeviceClass *dc = DSI_DEVICE_GET_CLASS(dsi_dev);
338
 
    return dc->init(dsi_dev);
339
 
}
340
 
 
341
 
DeviceState *dsi_create_device_noinit(DSIHost *host, const char *name, int vc)
342
 
{
343
 
    if (host->device[vc]) {
344
 
        hw_error("%s: virtual channel %d already has a device attached\n",
345
 
                 __FUNCTION__, vc);
346
 
    }
347
 
    DeviceState *dev = qdev_create(&host->qbus, name);
348
 
    qdev_prop_set_uint8(dev, "virtual_channel", vc);
349
 
    DSIDevice *dsi_dev = DSI_DEVICE_FROM_QDEV(dev);
350
 
    host->device[vc] = dsi_dev;
351
 
    dsi_dev->host = host;
352
 
    return dev;
353
 
}
354
 
 
355
 
DeviceState *dsi_create_device(DSIHost *host, const char *name, int vc)
356
 
{
357
 
    DeviceState *dev = dsi_create_device_noinit(host, name, vc);
358
 
    qdev_init_nofail(dev);
359
 
    return dev;
360
 
}
361
 
 
362
 
DeviceState *dsi_create_common_device_noinit(DSIHost *host, const char *name,
363
 
                                             int vc)
364
 
{
365
 
    return dsi_create_device_noinit(host, name, vc);
366
 
}
367
 
 
368
 
DeviceState *dsi_create_common_device(DSIHost *host, const char *name, int vc)
369
 
{
370
 
    DeviceState *dev = dsi_create_common_device_noinit(host, name, vc);
371
 
    qdev_init_nofail(dev);
372
 
    return dev;
373
 
}
374
 
 
375
 
static void dsi_device_class_init(ObjectClass *klass, void *data)
376
 
{
377
 
    DeviceClass *k = DEVICE_CLASS(klass);
378
 
    k->init = dsi_device_init;
379
 
    k->bus_type = TYPE_DSI_BUS;
380
 
    k->props = dsi_props;
381
 
}
382
 
 
383
 
static void dsi_common_device_class_init(ObjectClass *klass, void *data)
384
 
{
385
 
    DeviceClass *k = DEVICE_CLASS(klass);
386
 
    DSIDeviceClass *dc = DSI_DEVICE_CLASS(klass);
387
 
    dc->write = dsi_common_write;
388
 
    dc->read = dsi_common_read;
389
 
    k->reset = dsi_common_reset;
390
 
}
391
 
 
392
 
static TypeInfo dsi_device_type_info = {
393
 
    .name = TYPE_DSI_DEVICE,
394
 
    .parent = TYPE_DEVICE,
395
 
    .instance_size = sizeof(DSIDevice),
396
 
    .abstract = true,
397
 
    .class_size = sizeof(DSIDeviceClass),
398
 
    .class_init = dsi_device_class_init,
399
 
};
400
 
 
401
 
static TypeInfo dsi_common_device_type_info = {
402
 
    .name = TYPE_DSI_COMMON_DEVICE,
403
 
    .parent = TYPE_DSI_DEVICE,
404
 
    .instance_size = sizeof(DSICommonDevice),
405
 
    .abstract = true,
406
 
    .class_size = sizeof(DSICommonDeviceClass),
407
 
    .class_init = dsi_common_device_class_init,
408
 
};
409
 
 
410
 
static void dsi_register_types(void)
411
 
{
412
 
    type_register_static(&dsi_bus_info);
413
 
    type_register_static(&dsi_device_type_info);
414
 
    type_register_static(&dsi_common_device_type_info);
415
 
}
416
 
 
417
 
type_init(dsi_register_types)