1// Copyright 2018 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/debug.h>
6#include <ddk/device.h>
7#include <ddk/protocol/platform-bus.h>
8#include <ddk/protocol/platform-defs.h>
9
10#include <soc/aml-s905d2/s905d2-gpio.h>
11#include <soc/aml-s905d2/s905d2-hw.h>
12
13#include <limits.h>
14
15#include "astro.h"
16
17static const pbus_mmio_t display_mmios[] = {
18    {
19        // DSI Host Controller
20        .base = S905D2_MIPI_DSI_BASE,
21        .length = S905D2_MIPI_DSI_LENGTH,
22    },
23    {
24        // DSI PHY
25        .base = S905D2_DSI_PHY_BASE,
26        .length = S905D2_DSI_PHY_LENGTH,
27    },
28    {
29        // HHI
30        .base = S905D2_HIU_BASE,
31        .length = S905D2_HIU_LENGTH,
32    },
33    {
34        // VBUS/VPU
35        .base = S905D2_VPU_BASE,
36        .length = S905D2_VPU_LENGTH,
37    },
38    {
39        // AOBUS
40        .base = S905D2_AOBUS_BASE,
41        .length = S905D2_AOBUS_LENGTH,
42    },
43    {
44        // CBUS
45        .base = S905D2_CBUS_BASE,
46        .length = S905D2_CBUS_LENGTH,
47    },
48};
49
50static const pbus_irq_t display_irqs[] = {
51    {
52        .irq = S905D2_VIU1_VSYNC_IRQ,
53        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
54    },
55};
56
57static const pbus_gpio_t display_gpios[] = {
58    {
59        // Backlight Enable
60        .gpio = S905D2_GPIOA(10),
61    },
62    {
63        // LCD Reset
64        .gpio = S905D2_GPIOH(6),
65    },
66    {
67        // Panel detection
68        .gpio = S905D2_GPIOH(5),
69    },
70};
71
72static const pbus_bti_t display_btis[] = {
73    {
74        .iommu_index = 0,
75        .bti_id = BTI_DISPLAY,
76    },
77};
78
79static const pbus_i2c_channel_t display_i2c_channels[] = {
80    {
81        .bus_id = ASTRO_I2C_3,
82        .address = I2C_BACKLIGHT_ADDR,
83    },
84};
85
86static const uint32_t display_protocols[] = {
87    ZX_PROTOCOL_AMLOGIC_CANVAS,
88};
89
90static pbus_dev_t display_dev = {
91    .name = "display",
92    .vid = PDEV_VID_AMLOGIC,
93    .pid = PDEV_PID_AMLOGIC_S905D2,
94    .did = PDEV_DID_AMLOGIC_DISPLAY,
95    .mmios = display_mmios,
96    .mmio_count = countof(display_mmios),
97    .irqs = display_irqs,
98    .irq_count = countof(display_irqs),
99    .gpios = display_gpios,
100    .gpio_count = countof(display_gpios),
101    .i2c_channels = display_i2c_channels,
102    .i2c_channel_count = countof(display_i2c_channels),
103    .btis = display_btis,
104    .bti_count = countof(display_btis),
105    .protocols = display_protocols,
106    .protocol_count = countof(display_protocols),
107};
108
109zx_status_t aml_display_init(aml_bus_t* bus) {
110    zx_status_t status = pbus_device_add(&bus->pbus, &display_dev);
111    if (status != ZX_OK) {
112        zxlogf(ERROR, "%s: Could not add display dev: %d\n", __FUNCTION__, status);
113        return status;
114    }
115    return ZX_OK;
116}
117