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");