2 * Copyright (C) 2012 Samsung Electronics
4 * Author: InKi Dae <inki.dae@samsung.com>
5 * Author: Donghwa Lee <dh09.lee@samsung.com>
7 * SPDX-License-Identifier: GPL-2.0+
12 #include <linux/err.h>
13 #include <asm/arch/dsim.h>
14 #include <asm/arch/mipi_dsim.h>
15 #include <asm/arch/power.h>
16 #include <asm/arch/cpu.h>
17 #include <asm/arch/clk.h>
19 #include "exynos_mipi_dsi_lowlevel.h"
20 #include "exynos_mipi_dsi_common.h"
22 #define master_to_driver(a) (a->dsim_lcd_drv)
23 #define master_to_device(a) (a->dsim_lcd_dev)
25 static struct exynos_platform_mipi_dsim *dsim_pd;
27 struct mipi_dsim_ddi {
29 struct list_head list;
30 struct mipi_dsim_lcd_device *dsim_lcd_dev;
31 struct mipi_dsim_lcd_driver *dsim_lcd_drv;
34 static LIST_HEAD(dsim_ddi_list);
35 static LIST_HEAD(dsim_lcd_dev_list);
37 int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
39 struct mipi_dsim_ddi *dsim_ddi;
42 debug("mipi_dsim_lcd_device is NULL.\n");
47 debug("dsim_lcd_device name is NULL.\n");
51 dsim_ddi = kzalloc(sizeof(struct mipi_dsim_ddi), GFP_KERNEL);
53 debug("failed to allocate dsim_ddi object.\n");
57 dsim_ddi->dsim_lcd_dev = lcd_dev;
59 list_add_tail(&dsim_ddi->list, &dsim_ddi_list);
65 *exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
67 struct mipi_dsim_ddi *dsim_ddi;
68 struct mipi_dsim_lcd_device *lcd_dev;
70 list_for_each_entry(dsim_ddi, &dsim_ddi_list, list) {
71 lcd_dev = dsim_ddi->dsim_lcd_dev;
75 if (lcd_drv->id >= 0) {
76 if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0 &&
77 lcd_drv->id == lcd_dev->id) {
79 * bus_id would be used to identify
82 dsim_ddi->bus_id = lcd_dev->bus_id;
87 if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0) {
89 * bus_id would be used to identify
92 dsim_ddi->bus_id = lcd_dev->bus_id;
99 list_del(&dsim_ddi_list);
105 int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
107 struct mipi_dsim_ddi *dsim_ddi;
110 debug("mipi_dsim_lcd_driver is NULL.\n");
114 if (!lcd_drv->name) {
115 debug("dsim_lcd_driver name is NULL.\n");
119 dsim_ddi = exynos_mipi_dsi_find_lcd_device(lcd_drv);
121 debug("mipi_dsim_ddi object not found.\n");
125 dsim_ddi->dsim_lcd_drv = lcd_drv;
127 debug("registered panel driver(%s) to mipi-dsi driver.\n",
135 *exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
138 struct mipi_dsim_ddi *dsim_ddi;
139 struct mipi_dsim_lcd_driver *lcd_drv;
140 struct mipi_dsim_lcd_device *lcd_dev;
142 list_for_each_entry(dsim_ddi, &dsim_ddi_list, list) {
143 lcd_drv = dsim_ddi->dsim_lcd_drv;
144 lcd_dev = dsim_ddi->dsim_lcd_dev;
145 if (!lcd_drv || !lcd_dev)
148 debug("lcd_drv->id = %d, lcd_dev->id = %d\n",
149 lcd_drv->id, lcd_dev->id);
151 if ((strcmp(lcd_drv->name, name) == 0)) {
152 lcd_dev->master = dsim;
154 dsim->dsim_lcd_dev = lcd_dev;
155 dsim->dsim_lcd_drv = lcd_drv;
164 /* define MIPI-DSI Master operations. */
165 static struct mipi_dsim_master_ops master_ops = {
166 .cmd_write = exynos_mipi_dsi_wr_data,
167 .get_dsim_frame_done = exynos_mipi_dsi_get_frame_done_status,
168 .clear_dsim_frame_done = exynos_mipi_dsi_clear_frame_done,
171 int exynos_mipi_dsi_init(void)
173 struct mipi_dsim_device *dsim;
174 struct mipi_dsim_config *dsim_config;
175 struct mipi_dsim_ddi *dsim_ddi;
177 dsim = kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNEL);
179 debug("failed to allocate dsim object.\n");
183 /* get mipi_dsim_config. */
184 dsim_config = dsim_pd->dsim_config;
185 if (dsim_config == NULL) {
186 debug("failed to get dsim config data.\n");
191 dsim->dsim_config = dsim_config;
192 dsim->master_ops = &master_ops;
194 /* bind lcd ddi matched with panel name. */
195 dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name);
197 debug("mipi_dsim_ddi object not found.\n");
200 if (dsim_pd->lcd_power)
201 dsim_pd->lcd_power();
203 if (dsim_pd->mipi_power)
204 dsim_pd->mipi_power();
206 /* phy_enable(unsigned int dev_index, unsigned int enable) */
207 if (dsim_pd->phy_enable)
208 dsim_pd->phy_enable(0, 1);
212 exynos_mipi_dsi_init_dsim(dsim);
213 exynos_mipi_dsi_init_link(dsim);
214 exynos_mipi_dsi_set_hs_enable(dsim);
216 /* set display timing. */
217 exynos_mipi_dsi_set_display_mode(dsim, dsim->dsim_config);
219 /* initialize mipi-dsi client(lcd panel). */
220 if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->mipi_panel_init) {
221 dsim_ddi->dsim_lcd_drv->mipi_panel_init(dsim);
222 dsim_ddi->dsim_lcd_drv->mipi_display_on(dsim);
225 debug("mipi-dsi driver(%s mode) has been probed.\n",
226 (dsim_config->e_interface == DSIM_COMMAND) ?
232 void exynos_set_dsim_platform_data(struct exynos_platform_mipi_dsim *pd)
235 debug("pd is NULL\n");