4
* Copyright (C) 2008-2010 Nokia Corporation
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.
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.
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.
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) \
28
for (i = nb; i--; data >>= 8) \
29
var = (var << 8) | (data & 0xff); \
35
dsi_te_trigger_cb te_trigger;
36
dsi_get_drawfn_cb get_drawfn;
39
static Property dsi_props[] = {
40
DEFINE_PROP_UINT8("virtual_channel", DSIDevice, vchannel, 0),
41
DEFINE_PROP_END_OF_LIST()
44
#define TYPE_DSI_BUS "dsi-bus"
45
#define DSI_BUS(obj) OBJECT_CHECK(DSIHost, (obj), TYPE_DSI_BUS)
47
static const TypeInfo dsi_bus_info = {
50
.instance_size = sizeof(DSIHost),
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)
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;
63
uint32_t dsi_short_write(DSIHost *host, uint32_t data)
65
DSIDevice *dev = host->device[(data >> 6) & 3];
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);
74
return dc->read(dev, payload & 0xff, 1);
75
case 0x15: /* short_write_1 */
76
dc->write(dev, payload, 2);
78
case 0x37: /* set maximum return packet size */
79
dev->max_return_size = data;
82
hw_error("%s: unknown/unimplemented DSI id (0x%02x)",
83
__FUNCTION__, data & 0x3f);
87
DSI_ERROR_NODEVICE((data >> 6) & 3);
92
void dsi_long_write(DSIHost *host, uint32_t header, uint32_t payload,
95
DSIDevice *dev = host->device[(header >> 6) & 3];
97
DSIDeviceClass *dc = DSI_DEVICE_GET_CLASS(dev);
98
switch (header & 0x3f) { /* id */
99
case 0x09: /* null packet */
102
case 0x39: /* long write */
103
dc->write(dev, payload, counter > 4 ? 4 : counter);
106
hw_error("%s: unknown/unimplemented DSI id (0x%02x)",
107
__FUNCTION__, header & 0x3f);
111
DSI_ERROR_NODEVICE((header >> 6) & 3);
115
int dsi_blt(DSIHost *host, int vc, void *data, int width, int height,
116
int col_pitch, int row_pitch, int format)
118
if (vc >= 0 && vc < 4) {
119
DSIDevice *dev = host->device[vc];
121
DSIDeviceClass *dc = DSI_DEVICE_GET_CLASS(dev);
122
return dc->blt(dev, data, width, height,
123
col_pitch, row_pitch, format);
125
DSI_ERROR_NODEVICE(vc);
128
hw_error("%s: invalid virtual channel id (%d)\n", __FUNCTION__, vc);
133
void dsi_te_trigger(const DSIDevice *dev)
135
if (dev && dev->host && dev->host->te_trigger) {
136
dev->host->te_trigger(dev->host->qbus.parent, dev->vchannel);
140
drawfn dsi_get_drawfn(const DSIDevice *dev, int format, int bpp)
142
if (dev && dev->host && dev->host->get_drawfn) {
143
return dev->host->get_drawfn(dev->host->qbus.parent, format, bpp);
148
static void dsi_common_reset(DeviceState *dev)
150
DSICommonDevice *s = DSI_COMMON_DEVICE_FROM_QDEV(dev);
151
DSICommonDeviceClass *dcc = DSI_COMMON_DEVICE_GET_CLASS(dev);
171
static void dsi_common_write(DSIDevice *dev, uint32_t data, int len)
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;
182
case 0x10: /* enter sleep */
184
s->powermode &= ~0x10;
185
if ((x ^ s->powermode) && dcc->powermode_changed) {
186
dcc->powermode_changed(s);
189
case 0x11: /* exit sleep */
191
s->powermode |= 0x10;
193
if ((x ^ s->powermode) && dcc->powermode_changed) {
194
dcc->powermode_changed(s);
197
case 0x28: /* display off */
199
s->powermode &= ~0x04;
200
if ((x ^ s->powermode) && dcc->powermode_changed) {
201
dcc->powermode_changed(s);
204
case 0x29: /* display on */
206
s->powermode |= 0x04;
207
if ((x ^ s->powermode) && dcc->powermode_changed) {
208
dcc->powermode_changed(s);
211
case 0x2a: /* set column address */
212
if (s->bs == bs_cmd) {
216
DSI_EXTRACTPARAM(s->sc, data, 2);
217
DSI_EXTRACTPARAM(s->ec, data, 1);
221
DSI_EXTRACTPARAM(s->ec, data, 1);
225
case 0x2b: /* set page address */
226
if (s->bs == bs_cmd) {
230
DSI_EXTRACTPARAM(s->sp, data, 2);
231
DSI_EXTRACTPARAM(s->ep, data, 1);
235
DSI_EXTRACTPARAM(s->ep, data, 1);
239
case 0x34: /* disable tear effect control */
242
if ((x ^ s->te_mode) && dcc->temode_changed) {
243
dcc->temode_changed(s);
246
case 0x35: /* enable tear effect control */
248
s->te_mode = (data & 0x01) ? te_hvsync : te_vsync;
249
if ((x ^ s->te_mode) && dcc->temode_changed) {
250
dcc->temode_changed(s);
253
case 0x36: /* set address mode */
254
s->addrmode = data & 0xff;
256
case 0x3a: /* set pixel format */
257
switch ((data >> 4) & 7) {
268
s->bpp_dpi = 4; /* faster to process than 3 */
271
hw_error("%s: unsupported dpi pixel format %d",
272
__FUNCTION__, (data >> 4) & 7);
275
switch ((data & 7)) {
286
s->bpp_dbi = 4; /* faster to process than 3 */
289
hw_error("%s: unsupported dbi pixel format %d",
290
__FUNCTION__, data & 7);
296
if (s->bs == bs_cmd) {
297
data = (data << 8) | s->cmd;
300
dcc->write(s, data, len);
302
hw_error("%s: unknown command 0x%02x\n", __FUNCTION__, s->cmd);
308
static uint32_t dsi_common_read(DSIDevice *dev, uint32_t data, int len)
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__);
315
s->cmd = data & 0xff;
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);
325
return dcc->read(s, data, len);
327
hw_error("%s: unknown command 0x%02x\n", __FUNCTION__, s->cmd);
334
static int dsi_device_init(DeviceState *dev)
336
DSIDevice *dsi_dev = DSI_DEVICE_FROM_QDEV(dev);
337
DSIDeviceClass *dc = DSI_DEVICE_GET_CLASS(dsi_dev);
338
return dc->init(dsi_dev);
341
DeviceState *dsi_create_device_noinit(DSIHost *host, const char *name, int vc)
343
if (host->device[vc]) {
344
hw_error("%s: virtual channel %d already has a device attached\n",
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;
355
DeviceState *dsi_create_device(DSIHost *host, const char *name, int vc)
357
DeviceState *dev = dsi_create_device_noinit(host, name, vc);
358
qdev_init_nofail(dev);
362
DeviceState *dsi_create_common_device_noinit(DSIHost *host, const char *name,
365
return dsi_create_device_noinit(host, name, vc);
368
DeviceState *dsi_create_common_device(DSIHost *host, const char *name, int vc)
370
DeviceState *dev = dsi_create_common_device_noinit(host, name, vc);
371
qdev_init_nofail(dev);
375
static void dsi_device_class_init(ObjectClass *klass, void *data)
377
DeviceClass *k = DEVICE_CLASS(klass);
378
k->init = dsi_device_init;
379
k->bus_type = TYPE_DSI_BUS;
380
k->props = dsi_props;
383
static void dsi_common_device_class_init(ObjectClass *klass, void *data)
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;
392
static TypeInfo dsi_device_type_info = {
393
.name = TYPE_DSI_DEVICE,
394
.parent = TYPE_DEVICE,
395
.instance_size = sizeof(DSIDevice),
397
.class_size = sizeof(DSIDeviceClass),
398
.class_init = dsi_device_class_init,
401
static TypeInfo dsi_common_device_type_info = {
402
.name = TYPE_DSI_COMMON_DEVICE,
403
.parent = TYPE_DSI_DEVICE,
404
.instance_size = sizeof(DSICommonDevice),
406
.class_size = sizeof(DSICommonDeviceClass),
407
.class_init = dsi_common_device_class_init,
410
static void dsi_register_types(void)
412
type_register_static(&dsi_bus_info);
413
type_register_static(&dsi_device_type_info);
414
type_register_static(&dsi_common_device_type_info);
417
type_init(dsi_register_types)