17258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee/* linux/drivers/video/exynos/exynos_mipi_dsi.c 27258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * 37258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * Samsung SoC MIPI-DSIM driver. 47258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * 57258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * Copyright (c) 2012 Samsung Electronics Co., Ltd 67258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * 77258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * InKi Dae, <inki.dae@samsung.com> 87258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * Donghwa Lee, <dh09.lee@samsung.com> 97258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * 107258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * This program is free software; you can redistribute it and/or modify 117258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * it under the terms of the GNU General Public License version 2 as 127258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * published by the Free Software Foundation. 137258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee*/ 147258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 157258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/module.h> 167258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/kernel.h> 177258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/errno.h> 187258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/clk.h> 197258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/mutex.h> 207258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/wait.h> 217258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/fs.h> 227258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/mm.h> 237258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/fb.h> 247258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/ctype.h> 257258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/platform_device.h> 267258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/io.h> 277258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/irq.h> 287258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/memory.h> 297258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/delay.h> 307258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/interrupt.h> 317258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/kthread.h> 327258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/notifier.h> 337e0be9f9f7cba3356f75b86737dbe3a005da067eSylwester Nawrocki#include <linux/phy/phy.h> 347258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/regulator/consumer.h> 357258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <linux/pm_runtime.h> 366637eca322e912bf4e272ab33447bdafea2658e8Sachin Kamat#include <linux/err.h> 377258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 387258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include <video/exynos_mipi_dsim.h> 397258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 407258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include "exynos_mipi_dsi_common.h" 417258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#include "exynos_mipi_dsi_lowlevel.h" 427258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 437258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestruct mipi_dsim_ddi { 447258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee int bus_id; 457258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct list_head list; 467258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_device *dsim_lcd_dev; 477258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_driver *dsim_lcd_drv; 487258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee}; 497258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 507258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic LIST_HEAD(dsim_ddi_list); 517258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 527258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic DEFINE_MUTEX(mipi_dsim_lock); 537258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 547258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic struct mipi_dsim_platform_data *to_dsim_plat(struct platform_device 557258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee *pdev) 567258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 577258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return pdev->dev.platform_data; 587258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 597258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 607258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic struct regulator_bulk_data supplies[] = { 6166685aa00bf9970be8be3783dbc3b59f69968214Donghwa Lee { .supply = "vdd11", }, 627258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee { .supply = "vdd18", }, 637258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee}; 647258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 657258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic int exynos_mipi_regulator_enable(struct mipi_dsim_device *dsim) 667258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 677258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee int ret; 687258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 697258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_lock(&dsim->lock); 707258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies); 717258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_unlock(&dsim->lock); 727258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 737258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return ret; 747258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 757258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 767258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic int exynos_mipi_regulator_disable(struct mipi_dsim_device *dsim) 777258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 787258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee int ret; 797258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 807258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_lock(&dsim->lock); 817258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies); 827258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_unlock(&dsim->lock); 837258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 847258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return ret; 857258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 867258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 877258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee/* update all register settings to MIPI DSI controller. */ 887258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic void exynos_mipi_update_cfg(struct mipi_dsim_device *dsim) 897258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 907258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* 917258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * data from Display controller(FIMD) is not transferred in video mode 927258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * but in case of command mode, all settings is not updated to 937258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * registers. 947258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee */ 957258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_dsi_stand_by(dsim, 0); 967258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 977258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_dsi_init_dsim(dsim); 987258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_dsi_init_link(dsim); 997258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1007258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_dsi_set_hs_enable(dsim); 1017258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1027258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* set display timing. */ 1037258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_dsi_set_display_mode(dsim, dsim->dsim_config); 1047258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 105113b66844ccd6eb3525c50a506e90b03155fdaf4Donghwa Lee exynos_mipi_dsi_init_interrupt(dsim); 106113b66844ccd6eb3525c50a506e90b03155fdaf4Donghwa Lee 1077258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* 1087258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * data from Display controller(FIMD) is transferred in video mode 109ff0c26424c1d993d8d1e04f72f1d428e935798daMasanari Iida * but in case of command mode, all settings are updated to registers. 1107258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee */ 1117258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_dsi_stand_by(dsim, 1); 1127258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 1137258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1147258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic int exynos_mipi_dsi_early_blank_mode(struct mipi_dsim_device *dsim, 1157258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee int power) 1167258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 1177258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv; 1187258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev; 1197258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1207258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee switch (power) { 1217258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee case FB_BLANK_POWERDOWN: 1227258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (dsim->suspended) 1237258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 1247258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1257258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (client_drv && client_drv->suspend) 1267258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee client_drv->suspend(client_dev); 1277258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1287258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee clk_disable(dsim->clock); 1297258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1307258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_regulator_disable(dsim); 1317258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1327258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->suspended = true; 1337258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1347258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee break; 1357258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee default: 1367258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee break; 1377258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 1387258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1397258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 1407258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 1417258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1427258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power) 1437258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 1447258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv; 1457258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev; 1467258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1477258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee switch (power) { 1487258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee case FB_BLANK_UNBLANK: 1497258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (!dsim->suspended) 1507258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 1517258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1527258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* lcd panel power on. */ 1537258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (client_drv && client_drv->power_on) 1547258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee client_drv->power_on(client_dev, 1); 1557258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 15691d1cfa8779e1929167a7cf1e5825462af7d6e4aDonghwa Lee exynos_mipi_regulator_enable(dsim); 1577258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1587258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* enable MIPI-DSI PHY. */ 1597e0be9f9f7cba3356f75b86737dbe3a005da067eSylwester Nawrocki phy_power_on(dsim->phy); 1607258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1617258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee clk_enable(dsim->clock); 1627258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1637258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_update_cfg(dsim); 1647258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1657258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* set lcd panel sequence commands. */ 1667258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (client_drv && client_drv->set_sequence) 1677258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee client_drv->set_sequence(client_dev); 1687258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1697258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->suspended = false; 1707258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1717258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee break; 1727258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee case FB_BLANK_NORMAL: 1737258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* TODO. */ 1747258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee break; 1757258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee default: 1767258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee break; 1777258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 1787258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1797258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 1807258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 1817258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1827258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leeint exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev) 1837258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 1847258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_ddi *dsim_ddi; 1857258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1867258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (!lcd_dev->name) { 1877258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee pr_err("dsim_lcd_device name is NULL.\n"); 1887258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return -EFAULT; 1897258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 1907258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1917258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_ddi = kzalloc(sizeof(struct mipi_dsim_ddi), GFP_KERNEL); 1927258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (!dsim_ddi) { 1937258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee pr_err("failed to allocate dsim_ddi object.\n"); 1947258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return -ENOMEM; 1957258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 1967258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1977258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_ddi->dsim_lcd_dev = lcd_dev; 1987258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 1997258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_lock(&mipi_dsim_lock); 2007258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee list_add_tail(&dsim_ddi->list, &dsim_ddi_list); 2017258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_unlock(&mipi_dsim_lock); 2027258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2037258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 2047258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 2057258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2064c4ceee0de69616f98240cbe3f5a4ed6d1973c63Sachin Kamatstatic struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device( 2074c4ceee0de69616f98240cbe3f5a4ed6d1973c63Sachin Kamat struct mipi_dsim_lcd_driver *lcd_drv) 2087258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 2097258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_ddi *dsim_ddi, *next; 2107258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_device *lcd_dev; 2117258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2127258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_lock(&mipi_dsim_lock); 2137258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2147258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) { 2157258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (!dsim_ddi) 2167258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee goto out; 2177258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2187258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee lcd_dev = dsim_ddi->dsim_lcd_dev; 2197258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (!lcd_dev) 2207258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee continue; 2217258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2227258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0) { 2237258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /** 2247258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * bus_id would be used to identify 2257258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee * connected bus. 2267258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee */ 2277258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_ddi->bus_id = lcd_dev->bus_id; 2287258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_unlock(&mipi_dsim_lock); 2297258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2307258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return dsim_ddi; 2317258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 2327258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2337258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee list_del(&dsim_ddi->list); 2347258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee kfree(dsim_ddi); 2357258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 2367258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2377258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leeout: 2387258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_unlock(&mipi_dsim_lock); 2397258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2407258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return NULL; 2417258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 2427258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2437258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leeint exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv) 2447258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 2457258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_ddi *dsim_ddi; 2467258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2477258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (!lcd_drv->name) { 2487258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee pr_err("dsim_lcd_driver name is NULL.\n"); 2497258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return -EFAULT; 2507258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 2517258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2527258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_ddi = exynos_mipi_dsi_find_lcd_device(lcd_drv); 2537258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (!dsim_ddi) { 2547258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee pr_err("mipi_dsim_ddi object not found.\n"); 2557258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return -EFAULT; 2567258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 2577258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2587258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_ddi->dsim_lcd_drv = lcd_drv; 2597258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2607258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee pr_info("registered panel driver(%s) to mipi-dsi driver.\n", 2617258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee lcd_drv->name); 2627258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2637258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 2647258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2657258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 2667258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2674c4ceee0de69616f98240cbe3f5a4ed6d1973c63Sachin Kamatstatic struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi( 2684c4ceee0de69616f98240cbe3f5a4ed6d1973c63Sachin Kamat struct mipi_dsim_device *dsim, 2697258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee const char *name) 2707258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 2717258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_ddi *dsim_ddi, *next; 2727258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_driver *lcd_drv; 2737258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_device *lcd_dev; 2747258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee int ret; 2757258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2767258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_lock(&dsim->lock); 2777258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2787258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) { 2797258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee lcd_drv = dsim_ddi->dsim_lcd_drv; 2807258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee lcd_dev = dsim_ddi->dsim_lcd_dev; 2817258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (!lcd_drv || !lcd_dev || 2827258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee (dsim->id != dsim_ddi->bus_id)) 2837258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee continue; 2847258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2857258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_dbg(dsim->dev, "lcd_drv->id = %d, lcd_dev->id = %d\n", 2867258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee lcd_drv->id, lcd_dev->id); 2877258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_dbg(dsim->dev, "lcd_dev->bus_id = %d, dsim->id = %d\n", 2887258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee lcd_dev->bus_id, dsim->id); 2897258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2907258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if ((strcmp(lcd_drv->name, name) == 0)) { 2917258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee lcd_dev->master = dsim; 2927258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2937258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee lcd_dev->dev.parent = dsim->dev; 2947258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_set_name(&lcd_dev->dev, "%s", lcd_drv->name); 2957258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 2967258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee ret = device_register(&lcd_dev->dev); 2977258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (ret < 0) { 2987258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_err(dsim->dev, 2997258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee "can't register %s, status %d\n", 3007258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_name(&lcd_dev->dev), ret); 3017258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_unlock(&dsim->lock); 3027258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3037258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return NULL; 3047258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 3057258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3067258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->dsim_lcd_dev = lcd_dev; 3077258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->dsim_lcd_drv = lcd_drv; 3087258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3097258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_unlock(&dsim->lock); 3107258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3117258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return dsim_ddi; 3127258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 3137258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 3147258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3157258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_unlock(&dsim->lock); 3167258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3177258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return NULL; 3187258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 3197258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3207258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee/* define MIPI-DSI Master operations. */ 3217258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic struct mipi_dsim_master_ops master_ops = { 3227258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee .cmd_read = exynos_mipi_dsi_rd_data, 3237258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee .cmd_write = exynos_mipi_dsi_wr_data, 3247258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee .get_dsim_frame_done = exynos_mipi_dsi_get_frame_done_status, 3257258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee .clear_dsim_frame_done = exynos_mipi_dsi_clear_frame_done, 3267258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee .set_early_blank_mode = exynos_mipi_dsi_early_blank_mode, 3277258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee .set_blank_mode = exynos_mipi_dsi_blank_mode, 3287258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee}; 3297258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3307258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic int exynos_mipi_dsi_probe(struct platform_device *pdev) 3317258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 3327258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct resource *res; 3337258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_device *dsim; 3347258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_config *dsim_config; 3357258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_platform_data *dsim_pd; 3367258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_ddi *dsim_ddi; 3377258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee int ret = -EINVAL; 3387258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 339f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat dsim = devm_kzalloc(&pdev->dev, sizeof(struct mipi_dsim_device), 340f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat GFP_KERNEL); 3417258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (!dsim) { 3427258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_err(&pdev->dev, "failed to allocate dsim object.\n"); 3437258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return -ENOMEM; 3447258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 3457258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3467258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->pd = to_dsim_plat(pdev); 3477258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->dev = &pdev->dev; 3487258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->id = pdev->id; 3497258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3507258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* get mipi_dsim_platform_data. */ 3517258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd; 3527258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (dsim_pd == NULL) { 3537258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_err(&pdev->dev, "failed to get platform data for dsim.\n"); 354f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat return -EINVAL; 3557258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 3567258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* get mipi_dsim_config. */ 3577258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_config = dsim_pd->dsim_config; 3587258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (dsim_config == NULL) { 3597258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_err(&pdev->dev, "failed to get dsim config data.\n"); 360f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat return -EINVAL; 3617258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 3627258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3637258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->dsim_config = dsim_config; 3647258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->master_ops = &master_ops; 3657258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3667258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_init(&dsim->lock); 3677258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 368f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(supplies), 369f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat supplies); 3707258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (ret) { 3717258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret); 372f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat return ret; 3737258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 3747258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3757e0be9f9f7cba3356f75b86737dbe3a005da067eSylwester Nawrocki dsim->phy = devm_phy_get(&pdev->dev, "dsim"); 3767e0be9f9f7cba3356f75b86737dbe3a005da067eSylwester Nawrocki if (IS_ERR(dsim->phy)) 3777e0be9f9f7cba3356f75b86737dbe3a005da067eSylwester Nawrocki return PTR_ERR(dsim->phy); 3787e0be9f9f7cba3356f75b86737dbe3a005da067eSylwester Nawrocki 379f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat dsim->clock = devm_clk_get(&pdev->dev, "dsim0"); 3807258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (IS_ERR(dsim->clock)) { 3817258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_err(&pdev->dev, "failed to get dsim clock source\n"); 382f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat return -ENODEV; 3837258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 3847258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3857258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee clk_enable(dsim->clock); 3867258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3877258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 3887258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3896637eca322e912bf4e272ab33447bdafea2658e8Sachin Kamat dsim->reg_base = devm_ioremap_resource(&pdev->dev, res); 3906637eca322e912bf4e272ab33447bdafea2658e8Sachin Kamat if (IS_ERR(dsim->reg_base)) { 3916637eca322e912bf4e272ab33447bdafea2658e8Sachin Kamat ret = PTR_ERR(dsim->reg_base); 392f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat goto error; 3937258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 3947258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3957258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee mutex_init(&dsim->lock); 3967258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 3977258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* bind lcd ddi matched with panel name. */ 3987258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name); 3997258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (!dsim_ddi) { 4007258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n"); 40136141e5692b42da5b010675b6e68e2292367eb9cPeter Senna Tschudin ret = -EINVAL; 402f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat goto error; 4037258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 4047258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4057258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->irq = platform_get_irq(pdev, 0); 4060c980826211611178b6d76b246d00a4c840f21e5Sachin Kamat if (IS_ERR_VALUE(dsim->irq)) { 4077258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_err(&pdev->dev, "failed to request dsim irq resource\n"); 4087258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee ret = -EINVAL; 409f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat goto error; 4107258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 4117258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 412b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki init_completion(&dsim_wr_comp); 413b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki init_completion(&dsim_rd_comp); 414b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki platform_set_drvdata(pdev, dsim); 415b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki 416f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat ret = devm_request_irq(&pdev->dev, dsim->irq, 417f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat exynos_mipi_dsi_interrupt_handler, 418b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki IRQF_SHARED, dev_name(&pdev->dev), dsim); 4197258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (ret != 0) { 4207258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dev_err(&pdev->dev, "failed to request dsim irq\n"); 4217258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee ret = -EINVAL; 422f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamat goto error; 4237258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 4247258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 425b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki /* enable interrupts */ 4267258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_dsi_init_interrupt(dsim); 4277258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4287258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* initialize mipi-dsi client(lcd panel). */ 4297258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->probe) 4307258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_ddi->dsim_lcd_drv->probe(dsim_ddi->dsim_lcd_dev); 4317258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 432b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki /* in case mipi-dsi has been enabled by bootloader */ 433b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki if (dsim_pd->enabled) { 434b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki exynos_mipi_regulator_enable(dsim); 435b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki goto done; 436b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki } 4377258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4387258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* lcd panel power on. */ 4397258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->power_on) 4407258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_ddi->dsim_lcd_drv->power_on(dsim_ddi->dsim_lcd_dev, 1); 4417258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4427258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_regulator_enable(dsim); 4437258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4447258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* enable MIPI-DSI PHY. */ 4457e0be9f9f7cba3356f75b86737dbe3a005da067eSylwester Nawrocki phy_power_on(dsim->phy); 4467258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4477258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_update_cfg(dsim); 4487258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4497258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* set lcd panel sequence commands. */ 4507258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->set_sequence) 4517258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_ddi->dsim_lcd_drv->set_sequence(dsim_ddi->dsim_lcd_dev); 4527258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4537258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->suspended = false; 4547258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 455b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrockidone: 4567258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee platform_set_drvdata(pdev, dsim); 4577258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4584907cb7b193a4f91c1fd30cf679c035e3644c64dAnatol Pomozov dev_dbg(&pdev->dev, "%s() completed successfully (%s mode)\n", __func__, 459b89e1399bab8bf72762948d251e69df50a9d6d85Sylwester Nawrocki dsim_config->e_interface == DSIM_COMMAND ? "CPU" : "RGB"); 4607258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4617258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 4627258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 463f18acdeacbcf038df3c9b03a96193cb01ca45cbbSachin Kamaterror: 4647258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee clk_disable(dsim->clock); 4657258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return ret; 4667258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 4677258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 46848c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic int exynos_mipi_dsi_remove(struct platform_device *pdev) 4697258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 4707258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_device *dsim = platform_get_drvdata(pdev); 4717258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_ddi *dsim_ddi, *next; 4727258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_driver *dsim_lcd_drv; 4737258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4747258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee clk_disable(dsim->clock); 4757258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4767258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) { 4777258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (dsim_ddi) { 4787258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (dsim->id != dsim_ddi->bus_id) 4797258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee continue; 4807258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4817258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_lcd_drv = dsim_ddi->dsim_lcd_drv; 4827258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4837258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (dsim_lcd_drv->remove) 4847258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim_lcd_drv->remove(dsim_ddi->dsim_lcd_dev); 4857258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4867258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee kfree(dsim_ddi); 4877258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 4887258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee } 4897258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4907258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 4917258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 4927258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 4933bfc9b835a8729f8a44de56930c1652293cfbf57Sylwester Nawrocki#ifdef CONFIG_PM_SLEEP 4943bfc9b835a8729f8a44de56930c1652293cfbf57Sylwester Nawrockistatic int exynos_mipi_dsi_suspend(struct device *dev) 4957258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 4963bfc9b835a8729f8a44de56930c1652293cfbf57Sylwester Nawrocki struct platform_device *pdev = to_platform_device(dev); 4977258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_device *dsim = platform_get_drvdata(pdev); 4987258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv; 4997258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev; 5007258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5017258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee disable_irq(dsim->irq); 5027258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5037258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (dsim->suspended) 5047258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 5057258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5067258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (client_drv && client_drv->suspend) 5077258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee client_drv->suspend(client_dev); 5087258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5097e0be9f9f7cba3356f75b86737dbe3a005da067eSylwester Nawrocki /* disable MIPI-DSI PHY. */ 5107e0be9f9f7cba3356f75b86737dbe3a005da067eSylwester Nawrocki phy_power_off(dsim->phy); 5117258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5127258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee clk_disable(dsim->clock); 5137258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5147258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_regulator_disable(dsim); 5157258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5167258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->suspended = true; 5177258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5187258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 5197258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 5207258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5213bfc9b835a8729f8a44de56930c1652293cfbf57Sylwester Nawrockistatic int exynos_mipi_dsi_resume(struct device *dev) 5227258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee{ 5233bfc9b835a8729f8a44de56930c1652293cfbf57Sylwester Nawrocki struct platform_device *pdev = to_platform_device(dev); 5247258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_device *dsim = platform_get_drvdata(pdev); 5257258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv; 5267258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev; 5277258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5287258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee enable_irq(dsim->irq); 5297258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5307258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (!dsim->suspended) 5317258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 5327258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5337258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* lcd panel power on. */ 5347258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (client_drv && client_drv->power_on) 5357258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee client_drv->power_on(client_dev, 1); 5367258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5377258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_regulator_enable(dsim); 5387258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5397258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* enable MIPI-DSI PHY. */ 5407e0be9f9f7cba3356f75b86737dbe3a005da067eSylwester Nawrocki phy_power_on(dsim->phy); 5417258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5427258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee clk_enable(dsim->clock); 5437258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5447258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee exynos_mipi_update_cfg(dsim); 5457258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5467258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee /* set lcd panel sequence commands. */ 5477258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee if (client_drv && client_drv->set_sequence) 5487258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee client_drv->set_sequence(client_dev); 5497258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5507258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee dsim->suspended = false; 5517258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5527258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee return 0; 5537258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee} 5547258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee#endif 5557258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5563bfc9b835a8729f8a44de56930c1652293cfbf57Sylwester Nawrockistatic const struct dev_pm_ops exynos_mipi_dsi_pm_ops = { 5573bfc9b835a8729f8a44de56930c1652293cfbf57Sylwester Nawrocki SET_SYSTEM_SLEEP_PM_OPS(exynos_mipi_dsi_suspend, exynos_mipi_dsi_resume) 5583bfc9b835a8729f8a44de56930c1652293cfbf57Sylwester Nawrocki}; 5593bfc9b835a8729f8a44de56930c1652293cfbf57Sylwester Nawrocki 5607258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leestatic struct platform_driver exynos_mipi_dsi_driver = { 5617258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee .probe = exynos_mipi_dsi_probe, 56248c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartman .remove = exynos_mipi_dsi_remove, 5637258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee .driver = { 5647258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee .name = "exynos-mipi-dsim", 5657258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee .owner = THIS_MODULE, 5663bfc9b835a8729f8a44de56930c1652293cfbf57Sylwester Nawrocki .pm = &exynos_mipi_dsi_pm_ops, 5677258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee }, 5687258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee}; 5697258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5707258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Leemodule_platform_driver(exynos_mipi_dsi_driver); 5717258cc14f310b912b6fea5421aedb9beb69d8581Donghwa Lee 5727258cc14f310b912b6fea5421aedb9beb69d8581Donghwa LeeMODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>"); 5737258cc14f310b912b6fea5421aedb9beb69d8581Donghwa LeeMODULE_DESCRIPTION("Samusung SoC MIPI-DSI driver"); 5747258cc14f310b912b6fea5421aedb9beb69d8581Donghwa LeeMODULE_LICENSE("GPL"); 575