~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/drivers/video/exynos_mipi_dsi.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2012 Samsung Electronics
 
3
 *
 
4
 * Author: InKi Dae <inki.dae@samsung.com>
 
5
 * Author: Donghwa Lee <dh09.lee@samsung.com>
 
6
 *
 
7
 * SPDX-License-Identifier:     GPL-2.0+
 
8
 */
 
9
 
 
10
#include <common.h>
 
11
#include <malloc.h>
 
12
#include <fdtdec.h>
 
13
#include <libfdt.h>
 
14
#include <linux/err.h>
 
15
#include <asm/arch/dsim.h>
 
16
#include <asm/arch/mipi_dsim.h>
 
17
#include <asm/arch/power.h>
 
18
#include <asm/arch/cpu.h>
 
19
#include <asm/arch/clk.h>
 
20
 
 
21
#include "exynos_mipi_dsi_lowlevel.h"
 
22
#include "exynos_mipi_dsi_common.h"
 
23
 
 
24
#define master_to_driver(a)     (a->dsim_lcd_drv)
 
25
#define master_to_device(a)     (a->dsim_lcd_dev)
 
26
 
 
27
DECLARE_GLOBAL_DATA_PTR;
 
28
 
 
29
static struct exynos_platform_mipi_dsim *dsim_pd;
 
30
#ifdef CONFIG_OF_CONTROL
 
31
static struct mipi_dsim_config dsim_config_dt;
 
32
static struct exynos_platform_mipi_dsim dsim_platform_data_dt;
 
33
static struct mipi_dsim_lcd_device mipi_lcd_device_dt;
 
34
#endif
 
35
 
 
36
struct mipi_dsim_ddi {
 
37
        int                             bus_id;
 
38
        struct list_head                list;
 
39
        struct mipi_dsim_lcd_device     *dsim_lcd_dev;
 
40
        struct mipi_dsim_lcd_driver     *dsim_lcd_drv;
 
41
};
 
42
 
 
43
static LIST_HEAD(dsim_ddi_list);
 
44
static LIST_HEAD(dsim_lcd_dev_list);
 
45
 
 
46
int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
 
47
{
 
48
        struct mipi_dsim_ddi *dsim_ddi;
 
49
 
 
50
        if (!lcd_dev) {
 
51
                debug("mipi_dsim_lcd_device is NULL.\n");
 
52
                return -EFAULT;
 
53
        }
 
54
 
 
55
        if (!lcd_dev->name) {
 
56
                debug("dsim_lcd_device name is NULL.\n");
 
57
                return -EFAULT;
 
58
        }
 
59
 
 
60
        dsim_ddi = kzalloc(sizeof(struct mipi_dsim_ddi), GFP_KERNEL);
 
61
        if (!dsim_ddi) {
 
62
                debug("failed to allocate dsim_ddi object.\n");
 
63
                return -EFAULT;
 
64
        }
 
65
 
 
66
        dsim_ddi->dsim_lcd_dev = lcd_dev;
 
67
 
 
68
        list_add_tail(&dsim_ddi->list, &dsim_ddi_list);
 
69
 
 
70
        return 0;
 
71
}
 
72
 
 
73
struct mipi_dsim_ddi
 
74
        *exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
 
75
{
 
76
        struct mipi_dsim_ddi *dsim_ddi;
 
77
        struct mipi_dsim_lcd_device *lcd_dev;
 
78
 
 
79
        list_for_each_entry(dsim_ddi, &dsim_ddi_list, list) {
 
80
                lcd_dev = dsim_ddi->dsim_lcd_dev;
 
81
                if (!lcd_dev)
 
82
                        continue;
 
83
 
 
84
                if (lcd_drv->id >= 0) {
 
85
                        if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0 &&
 
86
                                        lcd_drv->id == lcd_dev->id) {
 
87
                                /**
 
88
                                 * bus_id would be used to identify
 
89
                                 * connected bus.
 
90
                                 */
 
91
                                dsim_ddi->bus_id = lcd_dev->bus_id;
 
92
 
 
93
                                return dsim_ddi;
 
94
                        }
 
95
                } else {
 
96
                        if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0) {
 
97
                                /**
 
98
                                 * bus_id would be used to identify
 
99
                                 * connected bus.
 
100
                                 */
 
101
                                dsim_ddi->bus_id = lcd_dev->bus_id;
 
102
 
 
103
                                return dsim_ddi;
 
104
                        }
 
105
                }
 
106
 
 
107
                kfree(dsim_ddi);
 
108
                list_del(&dsim_ddi_list);
 
109
        }
 
110
 
 
111
        return NULL;
 
112
}
 
113
 
 
114
int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
 
115
{
 
116
        struct mipi_dsim_ddi *dsim_ddi;
 
117
 
 
118
        if (!lcd_drv) {
 
119
                debug("mipi_dsim_lcd_driver is NULL.\n");
 
120
                return -EFAULT;
 
121
        }
 
122
 
 
123
        if (!lcd_drv->name) {
 
124
                debug("dsim_lcd_driver name is NULL.\n");
 
125
                return -EFAULT;
 
126
        }
 
127
 
 
128
        dsim_ddi = exynos_mipi_dsi_find_lcd_device(lcd_drv);
 
129
        if (!dsim_ddi) {
 
130
                debug("mipi_dsim_ddi object not found.\n");
 
131
                return -EFAULT;
 
132
        }
 
133
 
 
134
        dsim_ddi->dsim_lcd_drv = lcd_drv;
 
135
 
 
136
        debug("registered panel driver(%s) to mipi-dsi driver.\n",
 
137
                lcd_drv->name);
 
138
 
 
139
        return 0;
 
140
 
 
141
}
 
142
 
 
143
struct mipi_dsim_ddi
 
144
        *exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
 
145
                        const char *name)
 
146
{
 
147
        struct mipi_dsim_ddi *dsim_ddi;
 
148
        struct mipi_dsim_lcd_driver *lcd_drv;
 
149
        struct mipi_dsim_lcd_device *lcd_dev;
 
150
 
 
151
        list_for_each_entry(dsim_ddi, &dsim_ddi_list, list) {
 
152
                lcd_drv = dsim_ddi->dsim_lcd_drv;
 
153
                lcd_dev = dsim_ddi->dsim_lcd_dev;
 
154
                if (!lcd_drv || !lcd_dev)
 
155
                        continue;
 
156
 
 
157
                debug("lcd_drv->id = %d, lcd_dev->id = %d\n",
 
158
                                        lcd_drv->id, lcd_dev->id);
 
159
 
 
160
                if ((strcmp(lcd_drv->name, name) == 0)) {
 
161
                        lcd_dev->master = dsim;
 
162
 
 
163
                        dsim->dsim_lcd_dev = lcd_dev;
 
164
                        dsim->dsim_lcd_drv = lcd_drv;
 
165
 
 
166
                        return dsim_ddi;
 
167
                }
 
168
        }
 
169
 
 
170
        return NULL;
 
171
}
 
172
 
 
173
/* define MIPI-DSI Master operations. */
 
174
static struct mipi_dsim_master_ops master_ops = {
 
175
        .cmd_write                      = exynos_mipi_dsi_wr_data,
 
176
        .get_dsim_frame_done            = exynos_mipi_dsi_get_frame_done_status,
 
177
        .clear_dsim_frame_done          = exynos_mipi_dsi_clear_frame_done,
 
178
};
 
179
 
 
180
int exynos_mipi_dsi_init(void)
 
181
{
 
182
        struct mipi_dsim_device *dsim;
 
183
        struct mipi_dsim_config *dsim_config;
 
184
        struct mipi_dsim_ddi *dsim_ddi;
 
185
 
 
186
        dsim = kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNEL);
 
187
        if (!dsim) {
 
188
                debug("failed to allocate dsim object.\n");
 
189
                return -EFAULT;
 
190
        }
 
191
 
 
192
        /* get mipi_dsim_config. */
 
193
        dsim_config = dsim_pd->dsim_config;
 
194
        if (dsim_config == NULL) {
 
195
                debug("failed to get dsim config data.\n");
 
196
                return -EFAULT;
 
197
        }
 
198
 
 
199
        dsim->pd = dsim_pd;
 
200
        dsim->dsim_config = dsim_config;
 
201
        dsim->master_ops = &master_ops;
 
202
 
 
203
        /* bind lcd ddi matched with panel name. */
 
204
        dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name);
 
205
        if (!dsim_ddi) {
 
206
                debug("mipi_dsim_ddi object not found.\n");
 
207
                return -ENOSYS;
 
208
        }
 
209
        if (dsim_pd->lcd_power)
 
210
                dsim_pd->lcd_power();
 
211
 
 
212
        if (dsim_pd->mipi_power)
 
213
                dsim_pd->mipi_power();
 
214
 
 
215
        /* phy_enable(unsigned int dev_index, unsigned int enable) */
 
216
        if (dsim_pd->phy_enable)
 
217
                dsim_pd->phy_enable(0, 1);
 
218
 
 
219
        set_mipi_clk();
 
220
 
 
221
        exynos_mipi_dsi_init_dsim(dsim);
 
222
        exynos_mipi_dsi_init_link(dsim);
 
223
        exynos_mipi_dsi_set_hs_enable(dsim);
 
224
 
 
225
        /* set display timing. */
 
226
        exynos_mipi_dsi_set_display_mode(dsim, dsim->dsim_config);
 
227
 
 
228
        /* initialize mipi-dsi client(lcd panel). */
 
229
        if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->mipi_panel_init) {
 
230
                dsim_ddi->dsim_lcd_drv->mipi_panel_init(dsim);
 
231
                dsim_ddi->dsim_lcd_drv->mipi_display_on(dsim);
 
232
        }
 
233
 
 
234
        debug("mipi-dsi driver(%s mode) has been probed.\n",
 
235
                (dsim_config->e_interface == DSIM_COMMAND) ?
 
236
                        "CPU" : "RGB");
 
237
 
 
238
        return 0;
 
239
}
 
240
 
 
241
void exynos_set_dsim_platform_data(struct exynos_platform_mipi_dsim *pd)
 
242
{
 
243
        if (pd == NULL) {
 
244
                debug("pd is NULL\n");
 
245
                return;
 
246
        }
 
247
 
 
248
        dsim_pd = pd;
 
249
}
 
250
 
 
251
#ifdef CONFIG_OF_CONTROL
 
252
int exynos_dsim_config_parse_dt(const void *blob)
 
253
{
 
254
        int node;
 
255
 
 
256
        node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS_MIPI_DSI);
 
257
        if (node <= 0) {
 
258
                printf("exynos_mipi_dsi: Can't get device node for mipi dsi\n");
 
259
                return -ENODEV;
 
260
        }
 
261
 
 
262
        dsim_config_dt.e_interface = fdtdec_get_int(blob, node,
 
263
                                "samsung,dsim-config-e-interface", 0);
 
264
 
 
265
        dsim_config_dt.e_virtual_ch = fdtdec_get_int(blob, node,
 
266
                                "samsung,dsim-config-e-virtual-ch", 0);
 
267
 
 
268
        dsim_config_dt.e_pixel_format = fdtdec_get_int(blob, node,
 
269
                                "samsung,dsim-config-e-pixel-format", 0);
 
270
 
 
271
        dsim_config_dt.e_burst_mode = fdtdec_get_int(blob, node,
 
272
                                "samsung,dsim-config-e-burst-mode", 0);
 
273
 
 
274
        dsim_config_dt.e_no_data_lane = fdtdec_get_int(blob, node,
 
275
                                "samsung,dsim-config-e-no-data-lane", 0);
 
276
 
 
277
        dsim_config_dt.e_byte_clk = fdtdec_get_int(blob, node,
 
278
                                "samsung,dsim-config-e-byte-clk", 0);
 
279
 
 
280
        dsim_config_dt.hfp = fdtdec_get_int(blob, node,
 
281
                                "samsung,dsim-config-hfp", 0);
 
282
 
 
283
        dsim_config_dt.p = fdtdec_get_int(blob, node,
 
284
                                          "samsung,dsim-config-p", 0);
 
285
        dsim_config_dt.m = fdtdec_get_int(blob, node,
 
286
                                          "samsung,dsim-config-m", 0);
 
287
        dsim_config_dt.s = fdtdec_get_int(blob, node,
 
288
                                          "samsung,dsim-config-s", 0);
 
289
 
 
290
        dsim_config_dt.pll_stable_time = fdtdec_get_int(blob, node,
 
291
                                "samsung,dsim-config-pll-stable-time", 0);
 
292
 
 
293
        dsim_config_dt.esc_clk = fdtdec_get_int(blob, node,
 
294
                                "samsung,dsim-config-esc-clk", 0);
 
295
 
 
296
        dsim_config_dt.stop_holding_cnt = fdtdec_get_int(blob, node,
 
297
                                "samsung,dsim-config-stop-holding-cnt", 0);
 
298
 
 
299
        dsim_config_dt.bta_timeout = fdtdec_get_int(blob, node,
 
300
                                "samsung,dsim-config-bta-timeout", 0);
 
301
 
 
302
        dsim_config_dt.rx_timeout = fdtdec_get_int(blob, node,
 
303
                                "samsung,dsim-config-rx-timeout", 0);
 
304
 
 
305
        mipi_lcd_device_dt.name = fdtdec_get_config_string(blob,
 
306
                                "samsung,dsim-device-name");
 
307
 
 
308
        mipi_lcd_device_dt.id = fdtdec_get_int(blob, node,
 
309
                                "samsung,dsim-device-id", 0);
 
310
 
 
311
        mipi_lcd_device_dt.bus_id = fdtdec_get_int(blob, node,
 
312
                                "samsung,dsim-device-bus_id", 0);
 
313
 
 
314
        mipi_lcd_device_dt.reverse_panel = fdtdec_get_int(blob, node,
 
315
                                "samsung,dsim-device-reverse-panel", 0);
 
316
 
 
317
        return 0;
 
318
}
 
319
 
 
320
void exynos_init_dsim_platform_data(vidinfo_t *vid)
 
321
{
 
322
        if (exynos_dsim_config_parse_dt(gd->fdt_blob))
 
323
                debug("Can't get proper dsim config.\n");
 
324
 
 
325
        strcpy(dsim_platform_data_dt.lcd_panel_name, mipi_lcd_device_dt.name);
 
326
        dsim_platform_data_dt.dsim_config = &dsim_config_dt;
 
327
        dsim_platform_data_dt.mipi_power = mipi_power;
 
328
        dsim_platform_data_dt.phy_enable = set_mipi_phy_ctrl;
 
329
        dsim_platform_data_dt.lcd_panel_info = (void *)vid;
 
330
 
 
331
        mipi_lcd_device_dt.platform_data = (void *)&dsim_platform_data_dt;
 
332
        exynos_mipi_dsi_register_lcd_device(&mipi_lcd_device_dt);
 
333
 
 
334
        dsim_pd = &dsim_platform_data_dt;
 
335
}
 
336
#endif