From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kyungmin Park Date: Fri, 15 Apr 2011 00:22:57 +0000 Subject: Re: [PATCH 1/2] video: add Samsung SoC MIPI-DSI controller driver. Message-Id: List-Id: References: <1302783320-31230-1-git-send-email-inki.dae@samsung.com> In-Reply-To: <1302783320-31230-1-git-send-email-inki.dae@samsung.com> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable To: linux-arm-kernel@lists.infradead.org Mr. Dae, If only MIPI header files are used at video, just place it under video directory. regardless this issue, how about the make a generic mipi dsi interface at v= ideo? then other soc will be helpful also. e.g., one generic MIPI DSI framework and each SoCs register the operations or override the functions or better way. No need to think/consider the samsung SOCs only. Thank you, Kyungmin Park On Thu, Apr 14, 2011 at 9:15 PM, Inki Dae wrote: > Samsung S5PV210 and EXYNOS4 SoC platform have one or two MIPI-DSI control= ler. > MIPI-DSI based LCD Panel could be used with MIPI-DSI controller driver. > this patch adds the MIPI-DSI controller driver and also this driver would > support both platforms. > > to use MIPI-DSI based LCD Panel driver, mipi_dsim_lcd_device should be > registered to MIPI-DSI Driver through s5p_mipi_dsi_register_lcd_device() = call > in machine code or machine specific somewhere first, and mipi_dsim_lcd_dr= iver > should be registered when s5p_mipi_dsi_register_lcd_driver() is called at= init > function of lcd driver, and then probe() of that driver would be called by > MIPI-DSI controller driver if lcd panel name and id of mipi_dsim_lcd_devi= ce > are same as ones of mipi_dsim_lcd_driver. > > for this, you can refer to sample lcd panel driver. > please see "Documentation/s5p_mipi_dsim/dsim_sample_lcd.c" > > Signed-off-by: Inki Dae > Signed-off-by: Kyungmin Park > --- > =A0arch/arm/plat-s5p/include/plat/mipi_dsim.h | =A0345 +++++++++++++++ > =A0arch/arm/plat-s5p/include/plat/regs-dsim.h | =A0143 ++++++ > =A0drivers/video/Kconfig =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0= =A07 + > =A0drivers/video/Makefile =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 = =A02 + > =A0drivers/video/s5p_mipi_dsi.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0481 ++++= ++++++++++++++++ > =A0drivers/video/s5p_mipi_dsi_common.c =A0 =A0 =A0 =A0| =A0655 ++++++++++= ++++++++++++++++++ > =A0drivers/video/s5p_mipi_dsi_common.h =A0 =A0 =A0 =A0| =A0 39 ++ > =A0drivers/video/s5p_mipi_dsi_lowlevel.c =A0 =A0 =A0| =A0558 ++++++++++++= +++++++++++ > =A0drivers/video/s5p_mipi_dsi_lowlevel.h =A0 =A0 =A0| =A0100 +++++ > =A09 files changed, 2330 insertions(+), 0 deletions(-) > =A0create mode 100644 arch/arm/plat-s5p/include/plat/mipi_dsim.h > =A0create mode 100644 arch/arm/plat-s5p/include/plat/regs-dsim.h > =A0create mode 100644 drivers/video/s5p_mipi_dsi.c > =A0create mode 100644 drivers/video/s5p_mipi_dsi_common.c > =A0create mode 100644 drivers/video/s5p_mipi_dsi_common.h > =A0create mode 100644 drivers/video/s5p_mipi_dsi_lowlevel.c > =A0create mode 100644 drivers/video/s5p_mipi_dsi_lowlevel.h > > diff --git a/arch/arm/plat-s5p/include/plat/mipi_dsim.h b/arch/arm/plat-s= 5p/include/plat/mipi_dsim.h > new file mode 100644 > index 0000000..0fa2d7e > --- /dev/null > +++ b/arch/arm/plat-s5p/include/plat/mipi_dsim.h > @@ -0,0 +1,345 @@ > +/* linux/arm/arch/plat-s5p/include/plat/mipi_dsim.h > + * > + * Platform data header for Samsung SoC MIPI-DSIM. > + * > + * Copyright (c) 2011 Samsung Electronics Co., Ltd > + * > + * InKi Dae > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > +*/ > + > +#ifndef _DSIM_H > +#define _DSIM_H > + > +#include > +#include > + > +#define PANEL_NAME_SIZE =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(32) > + > +enum mipi_dsim_interface_type { > + =A0 =A0 =A0 DSIM_COMMAND, > + =A0 =A0 =A0 DSIM_VIDEO > +}; > + > +enum mipi_dsim_virtual_ch_no { > + =A0 =A0 =A0 DSIM_VIRTUAL_CH_0, > + =A0 =A0 =A0 DSIM_VIRTUAL_CH_1, > + =A0 =A0 =A0 DSIM_VIRTUAL_CH_2, > + =A0 =A0 =A0 DSIM_VIRTUAL_CH_3 > +}; > + > +enum mipi_dsim_burst_mode_type { > + =A0 =A0 =A0 DSIM_NON_BURST_SYNC_EVENT, > + =A0 =A0 =A0 DSIM_NON_BURST_SYNC_PULSE =3D 2, > + =A0 =A0 =A0 DSIM_BURST, > + =A0 =A0 =A0 DSIM_NON_VIDEO_MODE > +}; > + > +enum mipi_dsim_no_of_data_lane { > + =A0 =A0 =A0 DSIM_DATA_LANE_1, > + =A0 =A0 =A0 DSIM_DATA_LANE_2, > + =A0 =A0 =A0 DSIM_DATA_LANE_3, > + =A0 =A0 =A0 DSIM_DATA_LANE_4 > +}; > + > +enum mipi_dsim_byte_clk_src { > + =A0 =A0 =A0 DSIM_PLL_OUT_DIV8, > + =A0 =A0 =A0 DSIM_EXT_CLK_DIV8, > + =A0 =A0 =A0 DSIM_EXT_CLK_BYPASS > +}; > + > +enum mipi_dsim_pixel_format { > + =A0 =A0 =A0 DSIM_CMD_3BPP, > + =A0 =A0 =A0 DSIM_CMD_8BPP, > + =A0 =A0 =A0 DSIM_CMD_12BPP, > + =A0 =A0 =A0 DSIM_CMD_16BPP, > + =A0 =A0 =A0 DSIM_VID_16BPP_565, > + =A0 =A0 =A0 DSIM_VID_18BPP_666PACKED, > + =A0 =A0 =A0 DSIM_18BPP_666LOOSELYPACKED, > + =A0 =A0 =A0 DSIM_24BPP_888 > +}; > + > +/** > + * struct mipi_dsim_config - interface for configuring mipi-dsi controll= er. > + * > + * @auto_flush: enable or disable Auto flush of MD FIFO using VSYNC puls= e. > + * @eot_disable: enable or disable EoT packet in HS mode. > + * @auto_vertical_cnt: specifies auto vertical count mode. > + * =A0 =A0 in Video mode, the vertical line transition uses line counter > + * =A0 =A0 configured by VSA, VBP, and Vertical resolution. > + * =A0 =A0 If this bit is set to '1', the line counter does not use VSA = and VBP > + * =A0 =A0 registers.(in command mode, this variable is ignored) > + * @hse: set horizontal sync event mode. > + * =A0 =A0 In VSYNC pulse and Vporch area, MIPI DSI master transfers onl= y HSYNC > + * =A0 =A0 start packet to MIPI DSI slave at MIPI DSI spec1.1r02. > + * =A0 =A0 this bit transfers HSYNC end packet in VSYNC pulse and Vporch= area > + * =A0 =A0 (in mommand mode, this variable is ignored) > + * @hfp: specifies HFP disable mode. > + * =A0 =A0 if this variable is set, DSI master ignores HFP area in VIDEO= mode. > + * =A0 =A0 (in command mode, this variable is ignored) > + * @hbp: specifies HBP disable mode. > + * =A0 =A0 if this variable is set, DSI master ignores HBP area in VIDEO= mode. > + * =A0 =A0 (in command mode, this variable is ignored) > + * @hsa: specifies HSA disable mode. > + * =A0 =A0 if this variable is set, DSI master ignores HSA area in VIDEO= mode. > + * =A0 =A0 (in command mode, this variable is ignored) > + * @e_interface: specifies interface to be used.(CPU or RGB interface) > + * @e_virtual_ch: specifies virtual channel number that main or > + * =A0 =A0 sub diaplsy uses. > + * @e_pixel_format: specifies pixel stream format for main or sub displa= y. > + * @e_burst_mode: selects Burst mode in Video mode. > + * =A0 =A0 in Non-burst mode, RGB data area is filled with RGB data and = NULL > + * =A0 =A0 packets, according to input bandwidth of RGB interface. > + * =A0 =A0 In Burst mode, RGB data area is filled with RGB data only. > + * @e_no_data_lane: specifies data lane count to be used by Master. > + * @e_byte_clk: select byte clock source. (it must be DSIM_PLL_OUT_DIV8) > + * =A0 =A0 DSIM_EXT_CLK_DIV8 and DSIM_EXT_CLK_BYPASSS are not supported. > + * @pll_stable_time: specifies the PLL Timer for stability of the ganera= ted > + * =A0 =A0 clock(System clock cycle base) > + * =A0 =A0 if the timer value goes to 0x00000000, the clock stable bit o= f status > + * =A0 =A0 and interrupt register is set. > + * @esc_clk: specifies escape clock frequency for getting the escape clo= ck > + * =A0 =A0 prescaler value. > + * @stop_holding_cnt: specifies the interval value between transmitting > + * =A0 =A0 read packet(or write "set_tear_on" command) and BTA request. > + * =A0 =A0 after transmitting read packet or write "set_tear_on" command, > + * =A0 =A0 BTA requests to D-PHY automatically. this counter value speci= fies > + * =A0 =A0 the interval between them. > + * @bta_timeout: specifies the timer for BTA. > + * =A0 =A0 this register specifies time out from BTA request to change > + * =A0 =A0 the direction with respect to Tx escape clock. > + * @rx_timeout: specifies the timer for LP Rx mode timeout. > + * =A0 =A0 this register specifies time out on how long RxValid deassert= s, > + * =A0 =A0 after RxLpdt asserts with respect to Tx escape clock. > + * =A0 =A0 - RxValid specifies Rx data valid indicator. > + * =A0 =A0 - RxLpdt specifies an indicator that D-PHY is under RxLpdt mo= de. > + * =A0 =A0 - RxValid and RxLpdt specifies signal from D-PHY. > + */ > +struct mipi_dsim_config { > + =A0 =A0 =A0 unsigned char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 auto_flus= h; > + =A0 =A0 =A0 unsigned char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 eot_disab= le; > + > + =A0 =A0 =A0 unsigned char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 auto_vert= ical_cnt; > + =A0 =A0 =A0 unsigned char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 hse; > + =A0 =A0 =A0 unsigned char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 hfp; > + =A0 =A0 =A0 unsigned char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 hbp; > + =A0 =A0 =A0 unsigned char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 hsa; > + > + =A0 =A0 =A0 enum mipi_dsim_interface_type =A0 e_interface; > + =A0 =A0 =A0 enum mipi_dsim_virtual_ch_no =A0 =A0e_virtual_ch; > + =A0 =A0 =A0 enum mipi_dsim_pixel_format =A0 =A0 e_pixel_format; > + =A0 =A0 =A0 enum mipi_dsim_burst_mode_type =A0e_burst_mode; > + =A0 =A0 =A0 enum mipi_dsim_no_of_data_lane =A0e_no_data_lane; > + =A0 =A0 =A0 enum mipi_dsim_byte_clk_src =A0 =A0 e_byte_clk; > + > + =A0 =A0 =A0 /* > + =A0 =A0 =A0 =A0* =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D> + =A0 =A0 =A0 =A0* | =A0 =A0P =A0 =A0| =A0 =A0M =A0 =A0| =A0 =A0= S =A0 =A0| =A0 =A0MHz =A0 =A0| > + =A0 =A0 =A0 =A0* ------------------------------------------- > + =A0 =A0 =A0 =A0* | =A0 =A03 =A0 =A0| =A0 100 =A0 | =A0 =A03 =A0 =A0| = =A0 =A0100 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A03 =A0 =A0| =A0 100 =A0 | =A0 =A02 =A0 =A0| = =A0 =A0200 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A03 =A0 =A0| =A0 =A063 =A0 | =A0 =A01 =A0 =A0| = =A0 =A0252 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A04 =A0 =A0| =A0 100 =A0 | =A0 =A01 =A0 =A0| = =A0 =A0300 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A04 =A0 =A0| =A0 110 =A0 | =A0 =A01 =A0 =A0| = =A0 =A0330 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 12 =A0 =A0| =A0 350 =A0 | =A0 =A01 =A0 =A0| =A0 = =A0350 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A03 =A0 =A0| =A0 100 =A0 | =A0 =A01 =A0 =A0| = =A0 =A0400 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A04 =A0 =A0| =A0 150 =A0 | =A0 =A01 =A0 =A0| = =A0 =A0450 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A03 =A0 =A0| =A0 118 =A0 | =A0 =A01 =A0 =A0| = =A0 =A0472 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 12 =A0 =A0| =A0 250 =A0 | =A0 =A00 =A0 =A0| =A0 = =A0500 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A04 =A0 =A0| =A0 100 =A0 | =A0 =A00 =A0 =A0| = =A0 =A0600 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A03 =A0 =A0| =A0 =A081 =A0 | =A0 =A00 =A0 =A0| = =A0 =A0648 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A03 =A0 =A0| =A0 =A088 =A0 | =A0 =A00 =A0 =A0| = =A0 =A0704 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A03 =A0 =A0| =A0 =A090 =A0 | =A0 =A00 =A0 =A0| = =A0 =A0720 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A03 =A0 =A0| =A0 100 =A0 | =A0 =A00 =A0 =A0| = =A0 =A0800 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 12 =A0 =A0| =A0 425 =A0 | =A0 =A00 =A0 =A0| =A0 = =A0850 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A04 =A0 =A0| =A0 150 =A0 | =A0 =A00 =A0 =A0| = =A0 =A0900 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 12 =A0 =A0| =A0 475 =A0 | =A0 =A00 =A0 =A0| =A0 = =A0950 =A0 =A0| > + =A0 =A0 =A0 =A0* | =A0 =A06 =A0 =A0| =A0 250 =A0 | =A0 =A00 =A0 =A0| = =A0 1000 =A0 =A0| > + =A0 =A0 =A0 =A0* ------------------------------------------- > + =A0 =A0 =A0 =A0*/ > + =A0 =A0 =A0 unsigned char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 p; > + =A0 =A0 =A0 unsigned short =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0m; > + =A0 =A0 =A0 unsigned char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 s; > + > + =A0 =A0 =A0 unsigned int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0pll_sta= ble_time; > + =A0 =A0 =A0 unsigned long =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 esc_clk; > + > + =A0 =A0 =A0 unsigned short =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0stop_hold= ing_cnt; > + =A0 =A0 =A0 unsigned char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bta_timeo= ut; > + =A0 =A0 =A0 unsigned short =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0rx_timeou= t; > +}; > + > +/** > + * struct mipi_dsim_device - global interface for mipi-dsi driver. > + * > + * @dev: driver model representation of the device. > + * @id: unique device id. > + * @clock: pointer to MIPI-DSI clock of clock framework. > + * @irq: interrupt number to MIPI-DSI controller. > + * @reg_base: base address to memory mapped SRF of MIPI-DSI controller. > + * =A0 =A0 (virtual address) > + * @lock: the mutex protecting this data structure. > + * @dsim_info: infomation for configuring mipi-dsi controller. > + * @master_ops: callbacks to mipi-dsi operations. > + * @dsim_lcd_dev: pointer to activated ddi device. > + * =A0 =A0 (it would be registered by mipi-dsi driver.) > + * @dsim_lcd_drv: pointer to activated_ddi driver. > + * =A0 =A0 (it would be registered by mipi-dsi driver.) > + * @lcd_info: pointer to mipi_lcd_info structure. > + * @state: specifies status of MIPI-DSI controller. > + * =A0 =A0 the status could be RESET, INIT, STOP, HSCLKEN and ULPS. > + * @resume_complete: indicates whether resume operation is completed or = not. > + * @data_lane: specifiec enabled data lane number. > + * =A0 =A0 this variable would be set by driver according to e_no_data_l= ane > + * =A0 =A0 automatically. > + * @e_clk_src: select byte clock source. > + * @pd: pointer to MIPI-DSI driver platform data. > + */ > +struct mipi_dsim_device { > + =A0 =A0 =A0 struct device =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *dev; > + =A0 =A0 =A0 int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= id; > + =A0 =A0 =A0 struct resource =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *res; > + =A0 =A0 =A0 struct clk =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*cloc= k; > + =A0 =A0 =A0 unsigned int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0irq; > + =A0 =A0 =A0 void __iomem =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*reg_ba= se; > + =A0 =A0 =A0 struct mutex =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lock; > + > + =A0 =A0 =A0 struct mipi_dsim_config =A0 =A0 =A0 =A0 *dsim_config; > + =A0 =A0 =A0 struct mipi_dsim_master_ops =A0 =A0 *master_ops; > + =A0 =A0 =A0 struct mipi_dsim_lcd_device =A0 =A0 *dsim_lcd_dev; > + =A0 =A0 =A0 struct mipi_dsim_lcd_driver =A0 =A0 *dsim_lcd_drv; > + > + =A0 =A0 =A0 unsigned int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0state; > + =A0 =A0 =A0 unsigned int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0resume_= complete; > + =A0 =A0 =A0 unsigned int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0data_la= ne; > + =A0 =A0 =A0 enum mipi_dsim_byte_clk_src =A0 =A0 e_clk_src; > + > + =A0 =A0 =A0 struct s5p_platform_mipi_dsim =A0 *pd; > +}; > + > +/** > + * struct s5p_platform_mipi_dsim - interface to platform data > + * =A0 =A0 for mipi-dsi driver. > + * > + * @lcd_panel_name: specifies lcd panel name registered to mipi-dsi driv= er. > + * =A0 =A0 lcd panel driver searched would be actived. > + * @dsim_config: pointer of structure for configuring mipi-dsi controlle= r. > + * @lcd_panel_info: pointer for lcd panel specific structure. > + * =A0 =A0 this structure specifies width, height, timing and polarity a= nd so on. > + * @mipi_power: callback pointer for enabling or disabling mipi power. > + * @phy_enable: pointer to a callback controlling D-PHY enable/reset > + */ > +struct s5p_platform_mipi_dsim { > + =A0 =A0 =A0 char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0lcd_panel_name[PANEL_NAME_SIZE]; > + > + =A0 =A0 =A0 struct mipi_dsim_config =A0 =A0 =A0 =A0 *dsim_config; > + =A0 =A0 =A0 void =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0*lcd_panel_info; > + > + =A0 =A0 =A0 int (*mipi_power)(struct platform_device *pdev, unsigned in= t enable); > + =A0 =A0 =A0 int (*phy_enable)(struct platform_device *pdev, bool on); > +}; > +/** > + * struct mipi_dsim_master_ops - callbacks to mipi-dsi operations. > + * > + * @cmd_write: transfer command to lcd panel at LP mode. > + * @cmd_read: read command from rx register. > + * @get_dsim_frame_done: get the status that all screen data have been > + * =A0 =A0 transferred to mipi-dsi. > + * @clear_dsim_frame_done: clear frame done status. > + * @get_fb_frame_done: get frame done status of display controller. > + * @trigger: trigger display controller. > + * =A0 =A0 - this one would be used only in case of CPU mode. > + */ > + > +struct mipi_dsim_master_ops { > + =A0 =A0 =A0 int (*cmd_write)(struct mipi_dsim_device *dsim, unsigned in= t data_id, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 unsigned int data0, unsigned int data1); > + =A0 =A0 =A0 int (*cmd_read)(struct mipi_dsim_device *dsim, unsigned int= data_id, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 unsigned int data0, unsigned int data1); > + =A0 =A0 =A0 int (*get_dsim_frame_done)(struct mipi_dsim_device *dsim); > + =A0 =A0 =A0 int (*clear_dsim_frame_done)(struct mipi_dsim_device *dsim); > + > + =A0 =A0 =A0 int (*get_fb_frame_done)(struct fb_info *info); > + =A0 =A0 =A0 void (*trigger)(struct fb_info *info); > +}; > + > +/** > + * device structure for mipi-dsi based lcd panel. > + * > + * @name: name of the device to use with this device, or an > + * =A0 =A0 alias for that name. > + * @dev: driver model representation of the device. > + * @id: id of device to be registered. > + * @bus_id: bus id for identifing connected bus > + * =A0 =A0 and this bus id should be same as id of mipi_dsim_device. > + * @irq: irq number for signaling when framebuffer transfer of > + * =A0 =A0 lcd panel module is completed. > + * =A0 =A0 this irq would be used only for MIPI-DSI based CPU mode lcd p= anel. > + * @master: pointer to mipi-dsi master device object. > + * @platform_data: lcd panel specific platform data. > + */ > +struct mipi_dsim_lcd_device { > + =A0 =A0 =A0 char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*name; > + =A0 =A0 =A0 struct device =A0 =A0 =A0 =A0 =A0 dev; > + =A0 =A0 =A0 int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 id; > + =A0 =A0 =A0 int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bus_id; > + =A0 =A0 =A0 int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 irq; > + > + =A0 =A0 =A0 struct mipi_dsim_device *master; > + =A0 =A0 =A0 void =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*platform_data; > +}; > + > +/** > + * driver structure for mipi-dsi based lcd panel. > + * > + * this structure should be registered by lcd panel driver. > + * mipi-dsi driver seeks lcd panel registered through name field > + * and calls these callback functions in appropriate time. > + * > + * @name: name of the driver to use with this device, or an > + * =A0 =A0 alias for that name. > + * @id: id of driver to be registered. > + * =A0 =A0 this id would be used for finding device object registered. > + */ > +struct mipi_dsim_lcd_driver { > + =A0 =A0 =A0 char =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*name; > + =A0 =A0 =A0 int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 id; > + > + =A0 =A0 =A0 int =A0 =A0 (*probe)(struct mipi_dsim_lcd_device *dsim_dev); > + =A0 =A0 =A0 int =A0 =A0 (*remove)(struct mipi_dsim_lcd_device *dsim_dev= ); > + =A0 =A0 =A0 void =A0 =A0(*shutdown)(struct mipi_dsim_lcd_device *dsim_d= ev); > + =A0 =A0 =A0 int =A0 =A0 (*suspend)(struct mipi_dsim_lcd_device *dsim_de= v); > + =A0 =A0 =A0 int =A0 =A0 (*resume)(struct mipi_dsim_lcd_device *dsim_dev= ); > +}; > + > +/** > + * register mipi_dsim_lcd_driver object defined by lcd panel driver > + * to mipi-dsi driver. > + */ > +int s5p_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 *lcd_drv); > + > +/** > + * register mipi_dsim_lcd_device to mipi-dsi master. > + */ > +int s5p_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 *lcd_dev); > + > +/** > + * enable regulators to MIPI-DSI power. > + */ > +int s5p_mipi_dsi_dphy_power(struct mipi_dsim_device *dsim, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 unsigned int enable); > + > +/** > + * s5p_dsim_phy_enable - global MIPI-DSI receiver D-PHY control > + * @pdev: MIPI-DSIM platform device > + * @on: true to enable D-PHY and deassert its reset > + * =A0 =A0 false to disable D-PHY > + */ > +int s5p_dsim_phy_enable(struct platform_device *pdev, bool on); > + > +#endif /* _DSIM_H */ > diff --git a/arch/arm/plat-s5p/include/plat/regs-dsim.h b/arch/arm/plat-s= 5p/include/plat/regs-dsim.h > new file mode 100644 > index 0000000..5f0e4fa > --- /dev/null > +++ b/arch/arm/plat-s5p/include/plat/regs-dsim.h > @@ -0,0 +1,143 @@ > +/* linux/arch/arm/plat-s5p/include/plat/regs-dsim.h > + * > + * Register definition file for Samsung MIPI-DSIM driver > + * > + * Copyright (c) 2011 Samsung Electronics Co., Ltd > + * > + * InKi Dae > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > +*/ > + > +#ifndef _REGS_DSIM_H > +#define _REGS_DSIM_H > + > +#define S5P_DSIM_STATUS =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(0x0) =A0 /* Stat= us register */ > +#define S5P_DSIM_SWRST =A0 =A0 =A0 =A0 (0x4) =A0 /* Software reset regis= ter */ > +#define S5P_DSIM_CLKCTRL =A0 =A0 =A0 (0x8) =A0 /* Clock control register= */ > +#define S5P_DSIM_TIMEOUT =A0 =A0 =A0 (0xc) =A0 /* Time out register */ > +#define S5P_DSIM_CONFIG =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(0x10) =A0/* Conf= iguration register */ > +#define S5P_DSIM_ESCMODE =A0 =A0 =A0 (0x14) =A0/* Escape mode register */ > + > +/* Main display image resolution register */ > +#define S5P_DSIM_MDRESOL =A0 =A0 =A0 (0x18) > +#define S5P_DSIM_MVPORCH =A0 =A0 =A0 (0x1c) =A0/* Main display Vporch re= gister */ > +#define S5P_DSIM_MHPORCH =A0 =A0 =A0 (0x20) =A0/* Main display Hporch re= gister */ > +#define S5P_DSIM_MSYNC =A0 =A0 =A0 =A0 (0x24) =A0/* Main display sync ar= ea register */ > + > +/* Sub display image resolution register */ > +#define S5P_DSIM_SDRESOL =A0 =A0 =A0 (0x28) > +#define S5P_DSIM_INTSRC =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(0x2c) =A0/* Inte= rrupt source register */ > +#define S5P_DSIM_INTMSK =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(0x30) =A0/* Inte= rrupt mask register */ > +#define S5P_DSIM_PKTHDR =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(0x34) =A0/* Pack= et Header FIFO register */ > +#define S5P_DSIM_PAYLOAD =A0 =A0 =A0 (0x38) =A0/* Payload FIFO register = */ > +#define S5P_DSIM_RXFIFO =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(0x3c) =A0/* Read= FIFO register */ > +#define S5P_DSIM_FIFOTHLD =A0 =A0 =A0(0x40) =A0/* FIFO threshold level r= egister */ > +#define S5P_DSIM_FIFOCTRL =A0 =A0 =A0(0x44) =A0/* FIFO status and contro= l register */ > + > +/* FIFO memory AC characteristic register */ > +#define S5P_DSIM_PLLCTRL =A0 =A0 =A0 (0x4c) =A0/* PLL control register */ > +#define S5P_DSIM_PLLTMR =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(0x50) =A0/* PLL = timer register */ > +#define S5P_DSIM_PHYACCHR =A0 =A0 =A0(0x54) =A0/* D-PHY AC characteristi= c register */ > +#define S5P_DSIM_PHYACCHR1 =A0 =A0 (0x58) =A0/* D-PHY AC characteristic = register1 */ > + > +/* DSIM_STATUS */ > +#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0) > +#define DSIM_STOP_STATE_CLK =A0 =A0(1 << 8) > +#define DSIM_TX_READY_HS_CLK =A0 (1 << 10) > + > +/* DSIM_SWRST */ > +#define DSIM_FUNCRST =A0 =A0 =A0 =A0 =A0 (1 << 16) > +#define DSIM_SWRST =A0 =A0 =A0 =A0 =A0 =A0 (1 << 0) > + > +/* S5P_DSIM_TIMEOUT */ > +#define DSIM_LPDR_TOUT_SHIFT =A0 (0) > +#define DSIM_BTA_TOUT_SHIFT =A0 =A0(16) > + > +/* S5P_DSIM_CLKCTRL */ > +#define DSIM_LANE_ESC_CLKEN_SHIFT =A0 =A0 =A0(19) > +#define DSIM_BYTE_CLKEN_SHIFT =A0 =A0 =A0 =A0 =A0(24) > +#define DSIM_BYTE_CLK_SRC_SHIFT =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(25) > +#define DSIM_PLL_BYPASS_SHIFT =A0 =A0 =A0 =A0 =A0(27) > +#define DSIM_ESC_CLKEN_SHIFT =A0 =A0 =A0 =A0 =A0 (28) > +#define DSIM_TX_REQUEST_HSCLK_SHIFT =A0 =A0(31) > +#define DSIM_LANE_ESC_CLKEN(x) =A0 =A0 =A0 =A0 (((x) & 0x1f) << \ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 DSIM_LANE_ESC_CLKEN_SHIFT) > +#define DSIM_BYTE_CLK_ENABLE =A0 =A0 =A0 =A0 =A0 (1 << DSIM_BYTE_CLKEN_S= HIFT) > +#define DSIM_BYTE_CLK_DISABLE =A0 =A0 =A0 =A0 =A0(0 << DSIM_BYTE_CLKEN_S= HIFT) > +#define DSIM_PLL_BYPASS_EXTERNAL =A0 =A0 =A0 (1 << DSIM_PLL_BYPASS_SHIFT) > +#define DSIM_ESC_CLKEN_ENABLE =A0 =A0 =A0 =A0 =A0(1 << DSIM_ESC_CLKEN_SH= IFT) > +#define DSIM_ESC_CLKEN_DISABLE =A0 =A0 =A0 =A0 (0 << DSIM_ESC_CLKEN_SHIF= T) > + > +/* S5P_DSIM_CONFIG */ > +#define DSIM_NUM_OF_DATALANE_SHIFT =A0 =A0 (5) > +#define DSIM_HSA_MODE_SHIFT =A0 =A0 =A0 =A0 =A0 =A0(20) > +#define DSIM_HBP_MODE_SHIFT =A0 =A0 =A0 =A0 =A0 =A0(21) > +#define DSIM_HFP_MODE_SHIFT =A0 =A0 =A0 =A0 =A0 =A0(22) > +#define DSIM_HSE_MODE_SHIFT =A0 =A0 =A0 =A0 =A0 =A0(23) > +#define DSIM_AUTO_MODE_SHIFT =A0 =A0 =A0 =A0 =A0 (24) > +#define DSIM_LANE_ENx(x) =A0 =A0 =A0 =A0 =A0 =A0 =A0 (((x) & 0x1f) << 0) > + > +#define DSIM_NUM_OF_DATA_LANE(x) =A0 =A0 =A0 ((x) << DSIM_NUM_OF_DATALAN= E_SHIFT) > + > +/* S5P_DSIM_ESCMODE */ > +#define DSIM_TX_LPDT_SHIFT =A0 =A0 =A0 =A0 =A0 =A0 (6) > +#define DSIM_CMD_LPDT_SHIFT =A0 =A0 =A0 =A0 =A0 =A0(7) > +#define DSIM_TX_LPDT_LP =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(= 1 << DSIM_TX_LPDT_SHIFT) > +#define DSIM_CMD_LPDT_LP =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << DSIM_CMD_LPDT= _SHIFT) > +#define DSIM_STOP_STATE_CNT_SHIFT =A0 =A0 =A0(21) > +#define DSIM_FORCE_STOP_STATE_SHIFT =A0 =A0(20) > + > +/* S5P_DSIM_MDRESOL */ > +#define DSIM_MAIN_STAND_BY =A0 =A0 =A0 =A0 =A0 =A0 (1 << 31) > +#define DSIM_MAIN_VRESOL(x) =A0 =A0 =A0 =A0 =A0 =A0(((x) & 0x7ff) << 16) > +#define DSIM_MAIN_HRESOL(x) =A0 =A0 =A0 =A0 =A0 =A0(((x) & 0X7ff) << 0) > + > +/* S5P_DSIM_MVPORCH */ > +#define DSIM_CMD_ALLOW_SHIFT =A0 =A0 =A0 =A0 =A0 (28) > +#define DSIM_STABLE_VFP_SHIFT =A0 =A0 =A0 =A0 =A0(16) > +#define DSIM_MAIN_VBP_SHIFT =A0 =A0 =A0 =A0 =A0 =A0(0) > +#define DSIM_CMD_ALLOW_MASK =A0 =A0 =A0 =A0 =A0 =A0(0xf << DSIM_CMD_ALLO= W_SHIFT) > +#define DSIM_STABLE_VFP_MASK =A0 =A0 =A0 =A0 =A0 (0x7ff << DSIM_STABLE_V= FP_SHIFT) > +#define DSIM_MAIN_VBP_MASK =A0 =A0 =A0 =A0 =A0 =A0 (0x7ff << DSIM_MAIN_V= BP_SHIFT) > + > +/* S5P_DSIM_MHPORCH */ > +#define DSIM_MAIN_HFP_SHIFT =A0 =A0 =A0 =A0 =A0 =A0(16) > +#define DSIM_MAIN_HBP_SHIFT =A0 =A0 =A0 =A0 =A0 =A0(0) > +#define DSIM_MAIN_HFP_MASK =A0 =A0 =A0 =A0 =A0 =A0 ((0xffff) << DSIM_MAI= N_HFP_SHIFT) > +#define DSIM_MAIN_HBP_MASK =A0 =A0 =A0 =A0 =A0 =A0 ((0xffff) << DSIM_MAI= N_HBP_SHIFT) > + > +/* S5P_DSIM_MSYNC */ > +#define DSIM_MAIN_VSA_SHIFT =A0 =A0 =A0 =A0 =A0 =A0(22) > +#define DSIM_MAIN_HSA_SHIFT =A0 =A0 =A0 =A0 =A0 =A0(0) > +#define DSIM_MAIN_VSA_MASK =A0 =A0 =A0 =A0 =A0 =A0 ((0x3ff) << DSIM_MAIN= _VSA_SHIFT) > +#define DSIM_MAIN_HSA_MASK =A0 =A0 =A0 =A0 =A0 =A0 ((0xffff) << DSIM_MAI= N_HSA_SHIFT) > + > +/* S5P_DSIM_SDRESOL */ > +#define DSIM_SUB_STANDY_SHIFT =A0 =A0 =A0 =A0 =A0(31) > +#define DSIM_SUB_VRESOL_SHIFT =A0 =A0 =A0 =A0 =A0(16) > +#define DSIM_SUB_HRESOL_SHIFT =A0 =A0 =A0 =A0 =A0(0) > +#define DSIM_SUB_STANDY_MASK =A0 =A0 =A0 =A0 =A0 ((0x1) << DSIM_SUB_STAN= DY_SHIFT) > +#define DSIM_SUB_VRESOL_MASK =A0 =A0 =A0 =A0 =A0 ((0x7ff) << DSIM_SUB_VR= ESOL_SHIFT) > +#define DSIM_SUB_HRESOL_MASK =A0 =A0 =A0 =A0 =A0 ((0x7ff) << DSIM_SUB_HR= ESOL_SHIFT) > + > +/* S5P_DSIM_INTSRC */ > +#define INTSRC_FRAME_DONE =A0 =A0 =A0 =A0 =A0 =A0 =A0(1 << 24) > +#define INTSRC_PLL_STABLE =A0 =A0 =A0 =A0 =A0 =A0 =A0(1 << 31) > + > +/* S5P_DSIM_INTMSK */ > +#define INTMSK_FRAME_DONE =A0 =A0 =A0 =A0 =A0 =A0 =A0(1 << 24) > + > +/* S5P_DSIM_FIFOCTRL */ > +#define SFR_HEADER_EMPTY =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << 22) > + > +/* S5P_DSIM_PHYACCHR */ > +#define DSIM_AFC_CTL(x) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(= ((x) & 0x7) << 5) > + > +/* S5P_DSIM_PLLCTRL */ > +#define DSIM_PLL_EN_SHIFT =A0 =A0 =A0 =A0 =A0 =A0 =A0(23) > +#define DSIM_FREQ_BAND_SHIFT =A0 =A0 =A0 =A0 =A0 (24) > + > +#endif /* _REGS_DSIM_H */ > diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig > index e6a8d8c..1e71a54 100644 > --- a/drivers/video/Kconfig > +++ b/drivers/video/Kconfig > @@ -2044,6 +2044,13 @@ config FB_S3C2410_DEBUG > =A0 =A0 =A0 =A0 =A0Turn on debugging messages. Note that you can set/unse= t at run time > =A0 =A0 =A0 =A0 =A0through sysfs > > +config S5P_MIPI_DSI > + =A0 =A0 =A0 tristate "Samsung SoC MIPI-DSI support." > + =A0 =A0 =A0 depends on FB_S3C && (ARCH_S5PV210 || ARCH_EXYNOS4) > + =A0 =A0 =A0 default n > + =A0 =A0 =A0 ---help--- > + =A0 =A0 =A0 =A0 This enables support for MIPI-DSI device. > + > =A0config FB_NUC900 > =A0 =A0 =A0 =A0 bool "NUC900 LCD framebuffer support" > =A0 =A0 =A0 =A0 depends on FB && ARCH_W90X900 > diff --git a/drivers/video/Makefile b/drivers/video/Makefile > index 2ea44b6..ee5a1d5 100644 > --- a/drivers/video/Makefile > +++ b/drivers/video/Makefile > @@ -119,6 +119,8 @@ obj-$(CONFIG_FB_SH7760) =A0 =A0 =A0 =A0 =A0 =A0 =A0 += =3D sh7760fb.o > =A0obj-$(CONFIG_FB_IMX) =A0 =A0 =A0 =A0 =A0 =A0 =A0+=3D imxfb.o > =A0obj-$(CONFIG_FB_S3C) =A0 =A0 =A0 =A0 =A0 =A0 +=3D s3c-fb.o > =A0obj-$(CONFIG_FB_S3C2410) =A0 =A0 =A0 =A0 +=3D s3c2410fb.o > +obj-$(CONFIG_S5P_MIPI_DSI) =A0 =A0 =A0 +=3D s5p_mipi_dsi.o s5p_mipi_dsi_= common.o \ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 s5p_mipi_dsi_lowlevel.o > =A0obj-$(CONFIG_FB_FSL_DIU) =A0 =A0 =A0 =A0 +=3D fsl-diu-fb.o > =A0obj-$(CONFIG_FB_COBALT) =A0 =A0 =A0 =A0 =A0 +=3D cobalt_lcdfb.o > =A0obj-$(CONFIG_FB_PNX4008_DUM) =A0 =A0 +=3D pnx4008/ > diff --git a/drivers/video/s5p_mipi_dsi.c b/drivers/video/s5p_mipi_dsi.c > new file mode 100644 > index 0000000..50fc00e > --- /dev/null > +++ b/drivers/video/s5p_mipi_dsi.c > @@ -0,0 +1,481 @@ > +/* linux/drivers/video/s5p_mipi_dsi.c > + * > + * Samsung SoC MIPI-DSIM driver. > + * > + * Copyright (c) 2011 Samsung Electronics Co., Ltd > + * > + * InKi Dae, > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > +*/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#include "s5p_mipi_dsi_common.h" > + > +#define master_to_driver(a) =A0 =A0(a->dsim_lcd_drv) > +#define master_to_device(a) =A0 =A0(a->dsim_lcd_dev) > + > +struct mipi_dsim_ddi { > + =A0 =A0 =A0 int =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= bus_id; > + =A0 =A0 =A0 struct list_head =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0list; > + =A0 =A0 =A0 struct mipi_dsim_lcd_device =A0 =A0 *dsim_lcd_dev; > + =A0 =A0 =A0 struct mipi_dsim_lcd_driver =A0 =A0 *dsim_lcd_drv; > +}; > + > +static LIST_HEAD(dsim_ddi_list); > +static LIST_HEAD(dsim_lcd_dev_list); > + > +static DEFINE_MUTEX(mipi_dsim_lock); > + > +static struct s5p_platform_mipi_dsim *to_dsim_plat(struct platform_devic= e *pdev) > +{ > + =A0 =A0 =A0 return (struct s5p_platform_mipi_dsim *)pdev->dev.platform_= data; > +} > + > +static irqreturn_t s5p_mipi_dsi_interrupt_handler(int irq, void *dev_id) > +{ > + =A0 =A0 =A0 return IRQ_HANDLED; > +} > + > +int s5p_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_de= v) > +{ > + =A0 =A0 =A0 struct mipi_dsim_ddi *dsim_ddi; > + > + =A0 =A0 =A0 if (!lcd_dev) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_ERR "mipi_dsim_lcd_device is NU= LL.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EFAULT; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 if (!lcd_dev->name) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_ERR "dsim_lcd_device name is NU= LL.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EFAULT; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 dsim_ddi =3D kzalloc(sizeof(struct mipi_dsim_ddi), GFP_KERN= EL); > + =A0 =A0 =A0 if (!dsim_ddi) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_ERR "failed to allocate dsim_dd= i object.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EFAULT; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 dsim_ddi->dsim_lcd_dev =3D lcd_dev; > + > + =A0 =A0 =A0 mutex_lock(&mipi_dsim_lock); > + =A0 =A0 =A0 list_add_tail(&dsim_ddi->list, &dsim_ddi_list); > + =A0 =A0 =A0 mutex_unlock(&mipi_dsim_lock); > + > + =A0 =A0 =A0 return 0; > +} > + > +struct mipi_dsim_ddi > + =A0 =A0 =A0 *s5p_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *= lcd_drv) > +{ > + =A0 =A0 =A0 struct mipi_dsim_ddi *dsim_ddi; > + =A0 =A0 =A0 struct mipi_dsim_lcd_device *lcd_dev; > + > + =A0 =A0 =A0 mutex_lock(&mipi_dsim_lock); > + > + =A0 =A0 =A0 list_for_each_entry(dsim_ddi, &dsim_ddi_list, list) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lcd_dev =3D dsim_ddi->dsim_lcd_dev; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!lcd_dev) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (lcd_drv->id >=3D 0) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((strcmp(lcd_drv->name, = lcd_dev->name)) =3D 0 && > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 lcd_drv->id =3D lcd_dev->id) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /** > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* bus_id= would be used to identify > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* connec= ted bus. > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dsim_ddi->b= us_id =3D lcd_dev->bus_id; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mutex_unloc= k(&mipi_dsim_lock); > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return dsim= _ddi; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } else { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((strcmp(lcd_drv->name, = lcd_dev->name)) =3D 0) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /** > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* bus_id= would be used to identify > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* connec= ted bus. > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dsim_ddi->b= us_id =3D lcd_dev->bus_id; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mutex_unloc= k(&mipi_dsim_lock); > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return dsim= _ddi; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 kfree(dsim_ddi); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 list_del(&dsim_ddi_list); > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 mutex_unlock(&mipi_dsim_lock); > + > + =A0 =A0 =A0 return NULL; > +} > + > +int s5p_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_dr= v) > +{ > + =A0 =A0 =A0 struct mipi_dsim_ddi *dsim_ddi; > + > + =A0 =A0 =A0 if (!lcd_drv) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_ERR "mipi_dsim_lcd_driver is NU= LL.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EFAULT; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 if (!lcd_drv->name) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_ERR "dsim_lcd_driver name is NU= LL.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EFAULT; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 dsim_ddi =3D s5p_mipi_dsi_find_lcd_device(lcd_drv); > + =A0 =A0 =A0 if (!dsim_ddi) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_ERR "mipi_dsim_ddi object not f= ound.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EFAULT; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 dsim_ddi->dsim_lcd_drv =3D lcd_drv; > + > + =A0 =A0 =A0 printk(KERN_INFO "registered panel driver(%s) to mipi-dsi d= river.\n", > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lcd_drv->name); > + > + =A0 =A0 =A0 return 0; > + > +} > + > +struct mipi_dsim_ddi > + =A0 =A0 =A0 *s5p_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 const char *name) > +{ > + =A0 =A0 =A0 struct mipi_dsim_ddi *dsim_ddi; > + =A0 =A0 =A0 struct mipi_dsim_lcd_driver *lcd_drv; > + =A0 =A0 =A0 struct mipi_dsim_lcd_device *lcd_dev; > + =A0 =A0 =A0 int ret; > + > + =A0 =A0 =A0 mutex_lock(&dsim->lock); > + > + =A0 =A0 =A0 list_for_each_entry(dsim_ddi, &dsim_ddi_list, list) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lcd_drv =3D dsim_ddi->dsim_lcd_drv; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lcd_dev =3D dsim_ddi->dsim_lcd_dev; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!lcd_drv || !lcd_dev || > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (dsim->id !=3D dsim_ddi->bu= s_id)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_dbg(dsim->dev, "lcd_drv->id =3D %d, lcd= _dev->id =3D %d\n", > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lcd_drv->id= , lcd_dev->id); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_dbg(dsim->dev, "lcd_dev->bus_id =3D %d,= dsim->id =3D %d\n", > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lcd_dev->bu= s_id, dsim->id); > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((strcmp(lcd_drv->name, name) =3D 0)) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lcd_dev->master =3D dsim; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lcd_dev->dev.parent =3D dsi= m->dev; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_set_name(&lcd_dev->dev,= "%s", lcd_drv->name); > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ret =3D device_register(&lc= d_dev->dev); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (ret < 0) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(dsi= m->dev, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 "can't register %s, status %d\n", > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 dev_name(&lcd_dev->dev), ret); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mutex_unloc= k(&dsim->lock); > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NULL; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dsim->dsim_lcd_dev =3D lcd_= dev; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dsim->dsim_lcd_drv =3D lcd_= drv; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mutex_unlock(&dsim->lock); > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return dsim_ddi; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 mutex_unlock(&dsim->lock); > + > + =A0 =A0 =A0 return NULL; > +} > + > +/* define MIPI-DSI Master operations. */ > +static struct mipi_dsim_master_ops master_ops =3D { > + =A0 =A0 =A0 .cmd_write =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D s= 5p_mipi_dsi_wr_data, > + =A0 =A0 =A0 .get_dsim_frame_done =A0 =A0 =A0 =A0 =A0 =A0=3D s5p_mipi_ds= i_get_frame_done_status, > + =A0 =A0 =A0 .clear_dsim_frame_done =A0 =A0 =A0 =A0 =A0=3D s5p_mipi_dsi_= clear_frame_done, > +}; > + > +static int s5p_mipi_dsi_probe(struct platform_device *pdev) > +{ > + =A0 =A0 =A0 struct resource *res; > + =A0 =A0 =A0 struct mipi_dsim_device *dsim; > + =A0 =A0 =A0 struct mipi_dsim_config *dsim_config; > + =A0 =A0 =A0 struct s5p_platform_mipi_dsim *dsim_pd; > + =A0 =A0 =A0 struct mipi_dsim_ddi *dsim_ddi; > + =A0 =A0 =A0 int ret =3D -1; > + > + =A0 =A0 =A0 dsim =3D kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNE= L); > + =A0 =A0 =A0 if (!dsim) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&pdev->dev, "failed to allocate dsi= m object.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EFAULT; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 dsim->pd =3D to_dsim_plat(pdev); > + =A0 =A0 =A0 dsim->dev =3D &pdev->dev; > + =A0 =A0 =A0 dsim->id =3D pdev->id; > + =A0 =A0 =A0 dsim->resume_complete =3D 0; > + > + =A0 =A0 =A0 /* get s5p_platform_mipi_dsim. */ > + =A0 =A0 =A0 dsim_pd =3D (struct s5p_platform_mipi_dsim *)dsim->pd; > + =A0 =A0 =A0 if (dsim_pd =3D NULL) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&pdev->dev, "failed to get platform= data for dsim.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EFAULT; > + =A0 =A0 =A0 } > + =A0 =A0 =A0 /* get mipi_dsim_config. */ > + =A0 =A0 =A0 dsim_config =3D dsim_pd->dsim_config; > + =A0 =A0 =A0 if (dsim_config =3D NULL) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&pdev->dev, "failed to get dsim con= fig data.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -EFAULT; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 dsim->dsim_config =3D dsim_config; > + =A0 =A0 =A0 dsim->master_ops =3D &master_ops; > + > + =A0 =A0 =A0 dsim->clock =3D clk_get(&pdev->dev, "dsim"); > + =A0 =A0 =A0 if (IS_ERR(dsim->clock)) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&pdev->dev, "failed to get dsim clo= ck source\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err_clock_get; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 clk_enable(dsim->clock); > + > + =A0 =A0 =A0 res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); > + =A0 =A0 =A0 if (!res) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&pdev->dev, "failed to get io memor= y region\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 ret =3D -EINVAL; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err_platform_get; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 res =3D request_mem_region(res->start, resource_size(res), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 dev_name(&pdev->dev)); > + =A0 =A0 =A0 if (!res) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&pdev->dev, "failed to request io m= emory region\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 ret =3D -EINVAL; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err_mem_region; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 dsim->res =3D res; > + > + =A0 =A0 =A0 dsim->reg_base =3D ioremap(res->start, resource_size(res)); > + =A0 =A0 =A0 if (!dsim->reg_base) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&pdev->dev, "failed to remap io reg= ion\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 ret =3D -EINVAL; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err_mem_region; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 /* > + =A0 =A0 =A0 =A0* in case of MIPI Video mode, > + =A0 =A0 =A0 =A0* frame done interrupt handler would be used. > + =A0 =A0 =A0 =A0*/ > + =A0 =A0 =A0 if (dsim_config->e_interface =3D DSIM_VIDEO) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dsim->irq =3D platform_get_irq(pdev, 0); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (request_irq(dsim->irq, s5p_mipi_dsi_int= errupt_handler, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 IRQF_DISABL= ED, "mipi-dsi", dsim)) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&pdev->dev, "reques= t_irq failed.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err_request_irq; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 mutex_init(&dsim->lock); > + > + =A0 =A0 =A0 if (dsim->pd->mipi_power) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dsim->pd->mipi_power(pdev, 1); > + =A0 =A0 =A0 else { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&pdev->dev, "mipi_power is NULL.\n"= ); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err_request_irq; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 /* bind lcd ddi matched with panel name. */ > + =A0 =A0 =A0 dsim_ddi =3D s5p_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_p= anel_name); > + =A0 =A0 =A0 if (!dsim_ddi) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&pdev->dev, "mipi_dsim_ddi object n= ot found.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err_bind; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 /* enable MIPI-DSI PHY. */ > + =A0 =A0 =A0 if (dsim->pd->phy_enable) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dsim->pd->phy_enable(pdev, true); > + > + =A0 =A0 =A0 s5p_mipi_dsi_init_dsim(dsim); > + =A0 =A0 =A0 s5p_mipi_dsi_init_link(dsim); > + > + =A0 =A0 =A0 s5p_mipi_dsi_set_hs_enable(dsim); > + > + =A0 =A0 =A0 /* set display timing. */ > + =A0 =A0 =A0 s5p_mipi_dsi_set_display_mode(dsim, dsim->dsim_config); > + > + =A0 =A0 =A0 platform_set_drvdata(pdev, dsim); > + > + =A0 =A0 =A0 /* initialize mipi-dsi client(lcd panel). */ > + =A0 =A0 =A0 if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->probe) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dsim_ddi->dsim_lcd_drv->probe(dsim_ddi->dsi= m_lcd_dev); > + > + =A0 =A0 =A0 dev_dbg(&pdev->dev, "mipi-dsi driver(%s mode) has been prob= ed.\n", > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 (dsim_config->e_interface =3D DSIM_COMMAND)= ? > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "CPU" : "RGB"); > + > + =A0 =A0 =A0 return 0; > + > +err_bind: > + =A0 =A0 =A0 dsim->pd->mipi_power(pdev, 0); > + > +err_request_irq: > + =A0 =A0 =A0 release_resource(dsim->res); > + =A0 =A0 =A0 kfree(dsim->res); > + > + =A0 =A0 =A0 iounmap((void __iomem *) dsim->reg_base); > + > +err_mem_region: > +err_platform_get: > + =A0 =A0 =A0 clk_disable(dsim->clock); > + > +err_clock_get: > + =A0 =A0 =A0 clk_put(dsim->clock); > + =A0 =A0 =A0 kfree(dsim); > + > + =A0 =A0 =A0 return ret; > + > +} > + > +static int __devexit s5p_mipi_dsi_remove(struct platform_device *pdev) > +{ > + =A0 =A0 =A0 struct mipi_dsim_device *dsim =3D platform_get_drvdata(pdev= ); > + =A0 =A0 =A0 struct mipi_dsim_ddi *dsim_ddi =3D NULL; > + > + =A0 =A0 =A0 if (dsim->dsim_config->e_interface =3D DSIM_VIDEO) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 free_irq(dsim->irq, dsim); > + > + =A0 =A0 =A0 iounmap(dsim->reg_base); > + > + =A0 =A0 =A0 clk_disable(dsim->clock); > + =A0 =A0 =A0 clk_put(dsim->clock); > + > + =A0 =A0 =A0 release_resource(dsim->res); > + =A0 =A0 =A0 kfree(dsim->res); > + > + =A0 =A0 =A0 list_for_each_entry(dsim_ddi, &dsim_ddi_list, list) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (dsim_ddi) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (dsim->id =3D dsim_ddi->= bus_id) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 kfree(dsim_= ddi); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dsim_ddi = =3D NULL; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 kfree(dsim); > + > + =A0 =A0 =A0 return 0; > +} > + > +#ifdef CONFIG_PM > +static int s5p_mipi_dsi_suspend(struct platform_device *pdev, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pm_message_t state) > +{ > + =A0 =A0 =A0 struct mipi_dsim_device *dsim =3D platform_get_drvdata(pdev= ); > + > + =A0 =A0 =A0 dsim->resume_complete =3D 0; > + > + =A0 =A0 =A0 if (master_to_driver(dsim) && (master_to_driver(dsim))->sus= pend) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 (master_to_driver(dsim))->suspend(master_to= _device(dsim)); > + > + =A0 =A0 =A0 clk_disable(dsim->clock); > + > + =A0 =A0 =A0 if (dsim->pd->mipi_power) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dsim->pd->mipi_power(pdev, 0); > + > + =A0 =A0 =A0 return 0; > +} > + > +static int s5p_mipi_dsi_resume(struct platform_device *pdev) > +{ > + =A0 =A0 =A0 struct mipi_dsim_device *dsim =3D platform_get_drvdata(pdev= ); > + > + =A0 =A0 =A0 if (dsim->pd->mipi_power) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dsim->pd->mipi_power(pdev, 1); > + > + =A0 =A0 =A0 clk_enable(dsim->clock); > + > + =A0 =A0 =A0 s5p_mipi_dsi_init_dsim(dsim); > + =A0 =A0 =A0 s5p_mipi_dsi_init_link(dsim); > + > + =A0 =A0 =A0 s5p_mipi_dsi_set_hs_enable(dsim); > + > + =A0 =A0 =A0 /* change cpu command transfer mode to hs. */ > + =A0 =A0 =A0 s5p_mipi_dsi_set_data_transfer_mode(dsim, 0); > + > + =A0 =A0 =A0 if (master_to_driver(dsim) && (master_to_driver(dsim))->res= ume) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 (master_to_driver(dsim))->resume(master_to_= device(dsim)); > + > + =A0 =A0 =A0 s5p_mipi_dsi_set_display_mode(dsim, dsim->dsim_config); > + > + =A0 =A0 =A0 /* change lcdc data transfer mode to hs. */ > + =A0 =A0 =A0 s5p_mipi_dsi_set_data_transfer_mode(dsim, 1); > + > + =A0 =A0 =A0 dsim->resume_complete =3D 1; > + > + =A0 =A0 =A0 return 0; > +} > +#else > +#define s5p_mipi_dsi_suspend NULL > +#define s5p_mipi_dsi_resume NULL > +#endif > + > +static struct platform_driver s5p_mipi_dsi_driver =3D { > + =A0 =A0 =A0 .probe =3D s5p_mipi_dsi_probe, > + =A0 =A0 =A0 .remove =3D __devexit_p(s5p_mipi_dsi_remove), > + =A0 =A0 =A0 .suspend =3D s5p_mipi_dsi_suspend, > + =A0 =A0 =A0 .resume =3D s5p_mipi_dsi_resume, > + =A0 =A0 =A0 .driver =3D { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0.name =3D "s5p-mipi-dsim", > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0.owner =3D THIS_MODULE, > + =A0 =A0 =A0 }, > +}; > + > +static int s5p_mipi_dsi_register(void) > +{ > + =A0 =A0 =A0 platform_driver_register(&s5p_mipi_dsi_driver); > + > + =A0 =A0 =A0 return 0; > +} > + > +static void s5p_mipi_dsi_unregister(void) > +{ > + =A0 =A0 =A0 platform_driver_unregister(&s5p_mipi_dsi_driver); > +} > + > +module_init(s5p_mipi_dsi_register); > +module_exit(s5p_mipi_dsi_unregister); > + > +MODULE_AUTHOR("InKi Dae "); > +MODULE_DESCRIPTION("Samusung SoC MIPI-DSI driver"); > +MODULE_LICENSE("GPL"); > diff --git a/drivers/video/s5p_mipi_dsi_common.c b/drivers/video/s5p_mipi= _dsi_common.c > new file mode 100644 > index 0000000..51ee4ed > --- /dev/null > +++ b/drivers/video/s5p_mipi_dsi_common.c > @@ -0,0 +1,655 @@ > +/* linux/drivers/video/s5p_mipi_dsi_common.c > + * > + * Samsung SoC MIPI-DSI common driver. > + * > + * Copyright (c) 2011 Samsung Electronics Co., Ltd > + * > + * InKi Dae, > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > +*/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include