1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <ddk/binding.h>
6#include <ddk/debug.h>
7#include <ddk/protocol/platform-defs.h>
8#include <ddk/protocol/platform-device.h>
9#include <stdlib.h>
10#include <stdio.h>
11#include <string.h>
12#include <unistd.h>
13#include <hw/reg.h>
14#include <ddk/protocol/i2c.h>
15#include <ddk/protocol/gpio.h>
16
17#include "dsi.h"
18#include "adv7533.h"
19
20static zx_status_t dsi_get_display_timing(dsi_t* dsi) {
21    zx_status_t status;
22    uint8_t* edid_buf = adv7533_get_edid_buffer();
23    uint8_t num_dtd = 0;
24
25    if (edid_buf == 0) {
26        zxlogf(ERROR, "%s: No EDID available\n", __FUNCTION__);
27        return ZX_ERR_NOT_FOUND;
28    }
29
30    dsi->std_raw_dtd = calloc(1, sizeof(detailed_timing_t));
31    dsi->std_disp_timing = calloc(1, sizeof(disp_timing_t));
32    if (dsi->std_raw_dtd == 0 || dsi->std_disp_timing == 0) {
33        return ZX_ERR_NO_MEMORY;
34    }
35
36    edid_parse_std_display_timing(edid_buf, dsi->std_raw_dtd, dsi->std_disp_timing);
37
38    if ( (status = edid_get_num_dtd(edid_buf, &num_dtd)) != ZX_OK) {
39        zxlogf(ERROR, "Something went wrong with reading number of DTD\n");
40        return status;
41    }
42
43    if (num_dtd == 0) {
44        zxlogf(ERROR, "No DTD Founds!!\n");
45        return ZX_ERR_INTERNAL;
46    }
47
48    zxlogf(INFO, "Number of DTD found was %d\n", num_dtd);
49    dsi->raw_dtd = calloc(num_dtd, sizeof(detailed_timing_t));
50    dsi->disp_timing = calloc(num_dtd, sizeof(disp_timing_t));
51    if (dsi->raw_dtd == 0 || dsi->disp_timing == 0) {
52        return ZX_ERR_NO_MEMORY;
53    }
54
55    edid_parse_display_timing(edid_buf, dsi->raw_dtd, dsi->disp_timing, num_dtd);
56
57    return ZX_OK;
58}
59
60/* Unknown DPHY.  Use hardcoded values from Android source code for now */
61static void dsi_dphy_write(dsi_t* dsi, uint32_t reg, uint32_t val)
62{
63
64    // Select phy register
65    DW_DSI_WRITE32(DW_DSI_PHY_TST_CTRL1, (reg | DW_DSI_PHY_TST_CTRL1_TESTEN));
66    // pulse
67    DW_DSI_WRITE32(DW_DSI_PHY_TST_CTRL0, DW_DSI_PHY_TST_CTRL0_TSTCLK);
68    DW_DSI_WRITE32(DW_DSI_PHY_TST_CTRL0, DW_DSI_PHY_TST_CTRL0_TSTCLR);
69
70    // write value (for the register selected above)
71    DW_DSI_WRITE32(DW_DSI_PHY_TST_CTRL1, val);
72
73    // pulse
74    DW_DSI_WRITE32(DW_DSI_PHY_TST_CTRL0, DW_DSI_PHY_TST_CTRL0_TSTCLK);
75    DW_DSI_WRITE32(DW_DSI_PHY_TST_CTRL0, DW_DSI_PHY_TST_CTRL0_TSTCLR);
76}
77
78static void dsi_configure_dphy_pll(dsi_t* dsi) {
79    uint32_t i;
80    uint32_t tmp = 0;
81
82    dsi_dphy_write(dsi, 0x14, (0x1 << 4) + (0x0 << 3) + (0x0 << 2) + 0x0);
83    dsi_dphy_write(dsi, 0x15, 0x2d);
84    dsi_dphy_write(dsi, 0x16, (0x1 << 5) + (0x0 << 4) +0x1);
85    dsi_dphy_write(dsi, 0x17, 0x2);
86    dsi_dphy_write(dsi, 0x1D, 0x55);
87    dsi_dphy_write(dsi, 0x1E, (0x3 << 5) + (0x1 << 4) + (0x1 << 3) + (0x0 << 2) + (0x0 << 1) + 0x1);
88    dsi_dphy_write(dsi, 0x1F, 0x5a);
89    dsi_dphy_write(dsi, 0x20, (0x0));
90    dsi_dphy_write(dsi, 0x21, 0x28);
91    dsi_dphy_write(dsi, 0x22, 0xc);
92    dsi_dphy_write(dsi, 0x23, 0x9);
93    dsi_dphy_write(dsi, 0x24, 0x1a);
94    dsi_dphy_write(dsi, 0x25, 0xa);
95
96    for (i = 0; i < DS_NUM_LANES; i++) {
97        tmp = 0x30 + (i << 4);
98        dsi_dphy_write(dsi, tmp, 0x3c);
99        tmp = 0x31 + (i << 4);
100        dsi_dphy_write(dsi, tmp, 0x0);
101        dsi_dphy_write(dsi, tmp, 0xc);
102        tmp = 0x33 + (i << 4);
103        dsi_dphy_write(dsi, tmp, 0x8);
104        tmp = 0x34 + (i << 4);
105        dsi_dphy_write(dsi, tmp, 0xb);
106        tmp = 0x35 + (i << 4);
107        dsi_dphy_write(dsi, tmp, 0xb);
108        tmp = 0x36 + (i << 4);
109        dsi_dphy_write(dsi, tmp, 0x3);
110        tmp = 0x37 + (i << 4);
111        dsi_dphy_write(dsi, tmp, 0x4);
112    }
113}
114
115static void hdmi_gpio_init(dsi_t* dsi) {
116    gpio_protocol_t* gpios = dsi->hdmi_gpio.gpios;
117    gpio_config_out(&gpios[GPIO_MUX], 0);
118    gpio_config_out(&gpios[GPIO_PD], 0);
119    gpio_config_in(&gpios[GPIO_INT], GPIO_NO_PULL);
120    gpio_write(&gpios[GPIO_MUX], 0);
121}
122
123static void dsi_release(void* ctx) {
124    dsi_t* dsi = ctx;
125    mmio_buffer_release(&dsi->mmio);
126    free(dsi);
127}
128
129static zx_status_t dsi_get_protocol(void* ctx, uint32_t proto_id, void* out) {
130        return ZX_OK;
131}
132
133static zx_protocol_device_t dsi_device_proto = {
134    .version = DEVICE_OPS_VERSION,
135    .get_protocol = dsi_get_protocol,
136    .release = dsi_release,
137};
138
139static zx_status_t dsi_mipi_test(dsi_t* dsi) {
140
141    // enable video mode
142    DW_DSI_SET_BITS32(DW_DSI_MODE_CFG, 0x0, 1, 0);
143
144    // configure dpi color coding
145    DW_DSI_SET_BITS32(DW_DSI_DPI_COLOR_CODING, 0x5, 4, 0);
146
147    DW_DSI_SET_BITS32(DW_DSI_VID_MODE_CFG, 1, 1, 16);
148
149    return ZX_OK;
150}
151
152static zx_status_t dsi_configure_dphy(dsi_t* dsi) {
153    uint32_t tmp = 0;
154
155    // D-PHY shutdown and reset
156    DW_DSI_WRITE32(DW_DSI_PHY_RSTZ, DW_DSI_PHY_RSTZ_SHUTDOWN);
157
158    // Configure number of lanes
159    DW_DSI_SET_BITS32(DW_DSI_PHY_IF_CFG, (DS_NUM_LANES - 1), 2, 0);
160
161    // Configure TX_EST to frequency lower than 20MHz. Since byte clock is limited to 187.5MHz,
162    // write 0x09 will always generate clock less than 20MHz
163    DW_DSI_SET_BITS32(DW_DSI_CLKMGR_CFG, 0x09, 8, 0);
164
165    // Configure PHY PLL values
166    dsi_configure_dphy_pll(dsi);
167
168    // Enable PHY
169    DW_DSI_WRITE32(DW_DSI_PHY_RSTZ, DW_DSI_PHY_RSTZ_ENABLE);
170
171    // Wait for it to compelete
172    // TODO: Define some sort of timeout
173    tmp = DW_DSI_READ32(DW_DSI_PHY_STATUS);
174    while ((tmp & DW_DSI_PHY_STATUS_PHY_LOCKED) != DW_DSI_PHY_STATUS_PHY_LOCKED) {
175        usleep(1000);
176        tmp = DW_DSI_READ32(DW_DSI_PHY_STATUS);
177    }
178
179    /* Wait for all four lan*/
180    // TODO: Define some sort of timeout
181    tmp = DW_DSI_READ32(DW_DSI_PHY_STATUS);
182    while ((tmp & DW_DSI_PHY_STATUS_ALLSTOP) != DW_DSI_PHY_STATUS_ALLSTOP) {
183        usleep(1000);
184        tmp = DW_DSI_READ32(DW_DSI_PHY_STATUS);
185    }
186
187    return ZX_OK;
188}
189
190static void dsi_configure_dpi_interface(dsi_t* dsi) {
191    // Configure the virtual channel of the generated packets (0 since single display mode)
192    DW_DSI_SET_BITS32(DW_DSI_DPI_VCID, 0x0, 2, 0);
193
194    // Configure bpp (bits per pixel). Set to 24 bit
195    DW_DSI_SET_BITS32(DW_DSI_DPI_COLOR_CODING, DSI_COLOR_CODE_24BITS, 4, 0);
196
197    // Configure the polarity of dpidataen (active high)
198    DW_DSI_SET_BITS32(DW_DSI_DPI_CFG_POL, DSI_CFG_POL_ACTIVE_HIGH, 1,
199        DW_DSI_DPI_CFG_POL_DATAEN_START);
200
201    // Configure the polarity of vsync (active high)
202    DW_DSI_SET_BITS32(DW_DSI_DPI_CFG_POL, DSI_CFG_POL_ACTIVE_HIGH, 1,
203        DW_DSI_DPI_CFG_POL_VSYNC_START);
204
205    // Configure the polarity of hsync (active high)
206    DW_DSI_SET_BITS32(DW_DSI_DPI_CFG_POL, DSI_CFG_POL_ACTIVE_HIGH, 1,
207        DW_DSI_DPI_CFG_POL_HSYNC_START);
208
209    // Configure the polarity of shutd (active high)
210    DW_DSI_SET_BITS32(DW_DSI_DPI_CFG_POL, DSI_CFG_POL_ACTIVE_HIGH, 1,
211        DW_DSI_DPI_CFG_POL_SHUTD_START);
212
213    // Configure the polarity of colorm (active high)
214    DW_DSI_SET_BITS32(DW_DSI_DPI_CFG_POL, DSI_CFG_POL_ACTIVE_HIGH, 1,
215        DW_DSI_DPI_CFG_POL_COLORM_START);
216
217}
218
219static zx_status_t dsi_mipi_init(dsi_t* dsi) {
220    uint64_t pixel_clk = 0;
221    uint32_t hdisplay;
222    uint32_t vdisplay;
223    uint32_t hsync_start;
224    uint32_t hsync_end;
225    uint32_t htotal;
226    uint32_t vsync_start;
227    uint32_t vsync_end;
228    uint32_t vtotal;
229    uint32_t hfp;
230    uint32_t hbp;
231    uint32_t vfp;
232    uint32_t vbp;
233    uint32_t hpw;
234    uint32_t vpw;
235    uint32_t hsa_time;
236    uint32_t hbp_time;
237    uint32_t hline_time;
238
239    /* Below values are calculatd based on PHY parameters which we don't know */
240    uint32_t clk_lane_lp2hs_time = 0x3f;
241    uint32_t clk_lane_hs2lp_time = 0x3a;
242    uint32_t data_lane_lp2hs_time = 0x68;
243    uint32_t data_lane_hs2lp_time = 0x13;
244
245    // reset core
246    DW_DSI_WRITE32(DW_DSI_PWR_UP, 0);
247
248    // Configure DPHY
249    dsi_configure_dphy(dsi);
250
251    /* MIPI-DSI Spec Section 3.1.1 */
252    dsi_configure_dpi_interface(dsi);
253
254    // Configure low-power transitions whenever possible
255    DW_DSI_SET_BITS32(DW_DSI_VID_MODE_CFG, DW_DSI_VID_MODE_CFG_ALL_LP,
256        DW_DSI_VID_MODE_CFG_LP_ALL_BITS, DW_DSI_VID_MODE_CFG_LP_ALL_START);
257
258    // Configure whether controller should request ack msg at end of frame (no need)
259    DW_DSI_SET_BITS32(DW_DSI_VID_MODE_CFG, 0x0, DW_DSI_VID_MODE_CFG_FRAME_ACK_BITS,
260        DW_DSI_VID_MODE_CFG_FRAME_ACK_START);
261
262    // Configure commands to be sent in low power mode only
263    DW_DSI_SET_BITS32(DW_DSI_VID_MODE_CFG, 0x1, DW_DSI_VID_MODE_CFG_LP_CMD_BITS,
264        DW_DSI_VID_MODE_CFG_LP_CMD_START);
265
266    // set mode to Non-burst with sync pulses
267    DW_DSI_SET_BITS32(DW_DSI_VID_MODE_CFG, DSI_NON_BURST_SYNC_PULSES,
268        DW_DSI_VID_MODE_CFG_MODE_BITS, DW_DSI_VID_MODE_CFG_MODE_START);
269
270    // Set number of pixel in a single video packet
271    DW_DSI_SET_BITS32(DW_DSI_VID_PKT_SIZE, dsi->std_disp_timing->HActive,
272        DW_DSI_VID_PKT_SIZE_BITS, DW_DSI_VID_PKT_SIZE_START);
273
274    // Configure number of packets to be transmitted per video line (0 for single transmission)
275    DW_DSI_WRITE32(DW_DSI_VID_NUM_CHUNKS, 0);
276
277    // Disable null packet
278    DW_DSI_WRITE32(DW_DSI_VID_NULL_SIZE, 0);
279
280    /* TODO: fix blank display bug when set backlight*/
281    DW_DSI_SET_BITS32(DW_DSI_DPI_LP_CMD_TIM, 0x4, 8, 16);
282
283    /* for dsi read, BTA enable*/
284    DW_DSI_SET_BITS32(DW_DSI_PCKHDL_CFG, 0x1, 1, 2);
285
286    // Define DPI Horizontal and Vertical timing configuration
287
288
289    // TODO: This is a hardcoded value in the Android source.
290    // Supposed to be: pixel_clk = dsi->std_disp_timing->pixel_clk * 10000;
291    pixel_clk = 144000000;
292    hdisplay = dsi->std_disp_timing->HActive;
293    vdisplay = dsi->std_disp_timing->VActive;
294    hsync_start = dsi->std_disp_timing->HActive + dsi->std_disp_timing->HSyncOffset;
295    vsync_start = dsi->std_disp_timing->VActive + dsi->std_disp_timing->VSyncOffset;
296    hsync_end = hsync_start + dsi->std_disp_timing->HSyncPulseWidth;
297    vsync_end = vsync_start + dsi->std_disp_timing->VSyncPulseWidth;
298    htotal = dsi->std_disp_timing->HActive + dsi->std_disp_timing->HBlanking;
299    vtotal = dsi->std_disp_timing->VActive + dsi->std_disp_timing->VBlanking;
300
301    hfp = hsync_start - hdisplay;
302    hbp = htotal - hsync_end;
303    hpw = hsync_end - hsync_start;
304    vfp = vsync_start - vdisplay;
305    vbp = vtotal - vsync_end;
306    vpw = vsync_end - vsync_start;
307
308    hsa_time = (hpw * LANE_BYTE_CLOCK) / pixel_clk;
309    hbp_time = (hbp * LANE_BYTE_CLOCK) / pixel_clk;
310    hline_time = ROUND1((hpw + hbp + hfp + hdisplay) * LANE_BYTE_CLOCK, pixel_clk);
311
312    DW_DSI_SET_BITS32(DW_DSI_VID_HSA_TIME, hsa_time, 12, 0);
313    DW_DSI_SET_BITS32(DW_DSI_VID_HBP_TIME, hbp_time, 12, 0);
314    DW_DSI_SET_BITS32(DW_DSI_VID_HLINE_TIME, hline_time, 15, 0);
315
316    /* Define the Vertical line configuration*/
317    DW_DSI_SET_BITS32(DW_DSI_VID_VSA_LINES, vpw, 10, 0);
318    DW_DSI_SET_BITS32(DW_DSI_VID_VBP_LINES, vbp, 10, 0);
319    DW_DSI_SET_BITS32(DW_DSI_VID_VFP_LINES, vfp, 10, 0);
320    DW_DSI_SET_BITS32(DW_DSI_VID_VACTIVE_LINES, vdisplay, 14, 0);
321    DW_DSI_SET_BITS32(DW_DSI_TO_CNT_CFG, 0x7FF, 16, 0);
322
323    /* Configure core's phy parameters*/
324    DW_DSI_SET_BITS32(DW_DSI_PHY_TMR_LPCLK_CFG, clk_lane_lp2hs_time, 10, 0);
325    DW_DSI_SET_BITS32(DW_DSI_PHY_TMR_LPCLK_CFG, clk_lane_hs2lp_time, 10, 16);
326
327    DW_DSI_SET_BITS32(DW_DSI_PHY_TMR_RD_CFG, 0x7FFF, 15, 0);
328    DW_DSI_SET_BITS32(DW_DSI_PHY_TMR_CFG, data_lane_lp2hs_time, 10, 0);
329    DW_DSI_SET_BITS32(DW_DSI_PHY_TMR_CFG, data_lane_hs2lp_time, 10, 16);
330
331    /* Waking up Core*/
332    DW_DSI_SET_BITS32(DW_DSI_PWR_UP, 0x1, 1, 0);
333
334    /* Make sure we are in video mode  */
335    DW_DSI_SET_BITS32(DW_DSI_MODE_CFG, 0x0, 1, 0);
336
337    /* Enable EoTp Transmission */
338    DW_DSI_SET_BITS32(DW_DSI_PCKHDL_CFG, 0x1, 1, 0);
339
340    /* Generate High Speed clock, Continuous clock */
341    DW_DSI_SET_BITS32(DW_DSI_LPCLK_CTRL, 0x1, 2, 0);
342
343    return ZX_OK;
344}
345
346static zx_status_t dsi_bind(void* ctx, zx_device_t* parent) {
347    zxlogf(INFO, "dsi_bind\n");
348
349    dsi_t* dsi = calloc(1, sizeof(dsi_t));
350    if (!dsi) {
351        return ZX_ERR_NO_MEMORY;
352    }
353
354    zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_DEV, &dsi->pdev);
355    if (status != ZX_OK) {
356        goto fail;
357    }
358    dsi->parent = parent;
359
360    status = pdev_map_mmio_buffer2(&dsi->pdev, 0, ZX_CACHE_POLICY_UNCACHED_DEVICE,
361                                  &dsi->mmio);
362    if (status != ZX_OK) {
363        zxlogf(ERROR, "dsi_bind: pdev_map_mmio_buffer failed\n");
364        goto fail;
365    }
366
367    /* Obtain the I2C devices */
368    if (pdev_get_protocol(&dsi->pdev, ZX_PROTOCOL_I2C, 0, &dsi->i2c_dev.i2c_main) != ZX_OK) {
369        zxlogf(ERROR, "%s: Could not obtain I2C Protocol\n", __FUNCTION__);
370        goto fail;
371    }
372    if (pdev_get_protocol(&dsi->pdev, ZX_PROTOCOL_I2C, 1, &dsi->i2c_dev.i2c_cec) != ZX_OK) {
373        zxlogf(ERROR, "%s: Could not obtain I2C Protocol\n", __FUNCTION__);
374        goto fail;
375    }
376    if (pdev_get_protocol(&dsi->pdev, ZX_PROTOCOL_I2C, 2, &dsi->i2c_dev.i2c_edid) != ZX_OK) {
377        zxlogf(ERROR, "%s: Could not obtain I2C Protocol\n", __FUNCTION__);
378        goto fail;
379    }
380
381    /* Obtain the GPIO devices */
382    for (uint32_t i = 0; i < countof(dsi->hdmi_gpio.gpios); i++) {
383        if (pdev_get_protocol(&dsi->pdev, ZX_PROTOCOL_GPIO, i, &dsi->hdmi_gpio.gpios[i]) != ZX_OK) {
384            zxlogf(ERROR, "%s: Could not obtain GPIO Protocol\n", __FUNCTION__);
385            goto fail;
386        }
387    }
388
389    hdmi_gpio_init(dsi);
390
391    if ( (status = adv7533_init(dsi)) != ZX_OK) {
392        zxlogf(ERROR, "%s: Error in ADV7533 Initialization %d\n", __FUNCTION__, status);
393        goto fail;
394    }
395    dsi_get_display_timing(dsi);
396    dsi_mipi_init(dsi);
397    hdmi_init(dsi);
398    dsi_mipi_test(dsi);
399
400    // dsi_mipi_init(dsi);
401    zxlogf(INFO, "MIPI Initialized. Version is 0x%x\n", readl(dsi->mmio.vaddr));
402
403    device_add_args_t args = {
404        .version = DEVICE_ADD_ARGS_VERSION,
405        .name = "dsi",
406        .ctx = dsi,
407        .ops = &dsi_device_proto,
408        .proto_id = 0,
409        .proto_ops = 0,
410    };
411
412    status = device_add(parent, &args, &dsi->zxdev);
413    if (status != ZX_OK) {
414        goto fail;
415    }
416
417    return ZX_OK;
418
419fail:
420    zxlogf(ERROR, "dsi3_bind failed %d\n", status);
421    dsi_release(dsi);
422    return status;
423
424}
425
426static zx_driver_ops_t dsi_driver_ops = {
427    .version = DRIVER_OPS_VERSION,
428    .bind = dsi_bind,
429};
430
431// The formatter does not play nice with these macros.
432// clang-format off
433ZIRCON_DRIVER_BEGIN(dsi, dsi_driver_ops, "zircon", "0.1", 3)
434    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_GENERIC),
435    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_GENERIC),
436    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_DSI),
437ZIRCON_DRIVER_END(dsi)
438// clang-format on
439