File Index
Files and directories
Sign in
FILE

dw-mipi-dsi2.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c C
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2024, Fuzhou Rockchip Electronics Co., Ltd
   4 *
   5 * Modified by Heiko Stuebner <heiko.stuebner@cherry.de>
   6 * This generic Synopsys DesignWare MIPI DSI2 host driver is based on the
   7 * Rockchip version from rockchip/dw-mipi-dsi2.c converted to use bridge APIs.
   8 */
   9
  10#include <linux/bitfield.h>
  11#include <linux/clk.h>
  12#include <linux/export.h>
  13#include <linux/iopoll.h>
  14#include <linux/media-bus-format.h>
  15#include <linux/module.h>
  16#include <linux/platform_device.h>
  17#include <linux/pm_runtime.h>
  18#include <linux/reset.h>
  19
  20#include <video/mipi_display.h>
  21
  22#include <drm/bridge/dw_mipi_dsi2.h>
  23#include <drm/drm_atomic_helper.h>
  24#include <drm/drm_bridge.h>
  25#include <drm/drm_mipi_dsi.h>
  26#include <drm/drm_of.h>
  27#include <drm/drm_print.h>
  28
  29#define DSI2_PWR_UP			0x000c
  30#define RESET				0
  31#define POWER_UP			BIT(0)
  32#define CMD_TX_MODE(x)			FIELD_PREP(BIT(24), x)
  33#define DSI2_SOFT_RESET			0x0010
  34#define SYS_RSTN			BIT(2)
  35#define PHY_RSTN			BIT(1)
  36#define IPI_RSTN			BIT(0)
  37#define INT_ST_MAIN			0x0014
  38#define DSI2_MODE_CTRL			0x0018
  39#define DSI2_MODE_STATUS		0x001c
  40#define DSI2_CORE_STATUS		0x0020
  41#define PRI_RD_DATA_AVAIL		BIT(26)
  42#define PRI_FIFOS_NOT_EMPTY		BIT(25)
  43#define PRI_BUSY			BIT(24)
  44#define CRI_RD_DATA_AVAIL		BIT(18)
  45#define CRT_FIFOS_NOT_EMPTY		BIT(17)
  46#define CRI_BUSY			BIT(16)
  47#define IPI_FIFOS_NOT_EMPTY		BIT(9)
  48#define IPI_BUSY			BIT(8)
  49#define CORE_FIFOS_NOT_EMPTY		BIT(1)
  50#define CORE_BUSY			BIT(0)
  51#define MANUAL_MODE_CFG			0x0024
  52#define MANUAL_MODE_EN			BIT(0)
  53#define DSI2_TIMEOUT_HSTX_CFG		0x0048
  54#define TO_HSTX(x)			FIELD_PREP(GENMASK(15, 0), x)
  55#define DSI2_TIMEOUT_HSTXRDY_CFG	0x004c
  56#define TO_HSTXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
  57#define DSI2_TIMEOUT_LPRX_CFG		0x0050
  58#define TO_LPRXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
  59#define DSI2_TIMEOUT_LPTXRDY_CFG	0x0054
  60#define TO_LPTXRDY(x)			FIELD_PREP(GENMASK(15, 0), x)
  61#define DSI2_TIMEOUT_LPTXTRIG_CFG	0x0058
  62#define TO_LPTXTRIG(x)			FIELD_PREP(GENMASK(15, 0), x)
  63#define DSI2_TIMEOUT_LPTXULPS_CFG	0x005c
  64#define TO_LPTXULPS(x)			FIELD_PREP(GENMASK(15, 0), x)
  65#define DSI2_TIMEOUT_BTA_CFG		0x60
  66#define TO_BTA(x)			FIELD_PREP(GENMASK(15, 0), x)
  67
  68#define DSI2_PHY_MODE_CFG		0x0100
  69#define PPI_WIDTH(x)			FIELD_PREP(GENMASK(9, 8), x)
  70#define PHY_LANES(x)			FIELD_PREP(GENMASK(5, 4), (x) - 1)
  71#define PHY_TYPE(x)			FIELD_PREP(BIT(0), x)
  72#define DSI2_PHY_CLK_CFG		0X0104
  73#define PHY_LPTX_CLK_DIV(x)		FIELD_PREP(GENMASK(12, 8), x)
  74#define CLK_TYPE_MASK			BIT(0)
  75#define NON_CONTINUOUS_CLK		BIT(0)
  76#define CONTINUOUS_CLK			0
  77#define DSI2_PHY_LP2HS_MAN_CFG		0x010c
  78#define PHY_LP2HS_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
  79#define DSI2_PHY_HS2LP_MAN_CFG		0x0114
  80#define PHY_HS2LP_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
  81#define DSI2_PHY_MAX_RD_T_MAN_CFG	0x011c
  82#define PHY_MAX_RD_TIME(x)		FIELD_PREP(GENMASK(26, 0), x)
  83#define DSI2_PHY_ESC_CMD_T_MAN_CFG	0x0124
  84#define PHY_ESC_CMD_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
  85#define DSI2_PHY_ESC_BYTE_T_MAN_CFG	0x012c
  86#define PHY_ESC_BYTE_TIME(x)		FIELD_PREP(GENMASK(28, 0), x)
  87
  88#define DSI2_PHY_IPI_RATIO_MAN_CFG	0x0134
  89#define PHY_IPI_RATIO(x)		FIELD_PREP(GENMASK(21, 0), x)
  90#define DSI2_PHY_SYS_RATIO_MAN_CFG	0x013C
  91#define PHY_SYS_RATIO(x)		FIELD_PREP(GENMASK(16, 0), x)
  92
  93#define DSI2_DSI_GENERAL_CFG		0x0200
  94#define BTA_EN				BIT(1)
  95#define EOTP_TX_EN			BIT(0)
  96#define DSI2_DSI_VCID_CFG		0x0204
  97#define TX_VCID(x)			FIELD_PREP(GENMASK(1, 0), x)
  98#define DSI2_DSI_SCRAMBLING_CFG		0x0208
  99#define SCRAMBLING_SEED(x)		FIELD_PREP(GENMASK(31, 16), x)
 100#define SCRAMBLING_EN			BIT(0)
 101#define DSI2_DSI_VID_TX_CFG		0x020c
 102#define LPDT_DISPLAY_CMD_EN		BIT(20)
 103#define BLK_VFP_HS_EN			BIT(14)
 104#define BLK_VBP_HS_EN			BIT(13)
 105#define BLK_VSA_HS_EN			BIT(12)
 106#define BLK_HFP_HS_EN			BIT(6)
 107#define BLK_HBP_HS_EN			BIT(5)
 108#define BLK_HSA_HS_EN			BIT(4)
 109#define VID_MODE_TYPE(x)		FIELD_PREP(GENMASK(1, 0), x)
 110#define DSI2_CRI_TX_HDR			0x02c0
 111#define CMD_TX_MODE(x)			FIELD_PREP(BIT(24), x)
 112#define DSI2_CRI_TX_PLD			0x02c4
 113#define DSI2_CRI_RX_HDR			0x02c8
 114#define DSI2_CRI_RX_PLD			0x02cc
 115
 116#define DSI2_IPI_COLOR_MAN_CFG		0x0300
 117#define IPI_DEPTH(x)			FIELD_PREP(GENMASK(7, 4), x)
 118#define IPI_DEPTH_5_6_5_BITS		0x02
 119#define IPI_DEPTH_6_BITS		0x03
 120#define IPI_DEPTH_8_BITS		0x05
 121#define IPI_DEPTH_10_BITS		0x06
 122#define IPI_FORMAT(x)			FIELD_PREP(GENMASK(3, 0), x)
 123#define IPI_FORMAT_RGB			0x0
 124#define IPI_FORMAT_DSC			0x0b
 125#define DSI2_IPI_VID_HSA_MAN_CFG	0x0304
 126#define VID_HSA_TIME(x)			FIELD_PREP(GENMASK(29, 0), x)
 127#define DSI2_IPI_VID_HBP_MAN_CFG	0x030c
 128#define VID_HBP_TIME(x)			FIELD_PREP(GENMASK(29, 0), x)
 129#define DSI2_IPI_VID_HACT_MAN_CFG	0x0314
 130#define VID_HACT_TIME(x)		FIELD_PREP(GENMASK(29, 0), x)
 131#define DSI2_IPI_VID_HLINE_MAN_CFG	0x031c
 132#define VID_HLINE_TIME(x)		FIELD_PREP(GENMASK(29, 0), x)
 133#define DSI2_IPI_VID_VSA_MAN_CFG	0x0324
 134#define VID_VSA_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
 135#define DSI2_IPI_VID_VBP_MAN_CFG	0X032C
 136#define VID_VBP_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
 137#define DSI2_IPI_VID_VACT_MAN_CFG	0X0334
 138#define VID_VACT_LINES(x)		FIELD_PREP(GENMASK(13, 0), x)
 139#define DSI2_IPI_VID_VFP_MAN_CFG	0X033C
 140#define VID_VFP_LINES(x)		FIELD_PREP(GENMASK(9, 0), x)
 141#define DSI2_IPI_PIX_PKT_CFG		0x0344
 142#define MAX_PIX_PKT(x)			FIELD_PREP(GENMASK(15, 0), x)
 143
 144#define DSI2_INT_ST_PHY			0x0400
 145#define DSI2_INT_MASK_PHY		0x0404
 146#define DSI2_INT_ST_TO			0x0410
 147#define DSI2_INT_MASK_TO		0x0414
 148#define DSI2_INT_ST_ACK			0x0420
 149#define DSI2_INT_MASK_ACK		0x0424
 150#define DSI2_INT_ST_IPI			0x0430
 151#define DSI2_INT_MASK_IPI		0x0434
 152#define DSI2_INT_ST_FIFO		0x0440
 153#define DSI2_INT_MASK_FIFO		0x0444
 154#define DSI2_INT_ST_PRI			0x0450
 155#define DSI2_INT_MASK_PRI		0x0454
 156#define DSI2_INT_ST_CRI			0x0460
 157#define DSI2_INT_MASK_CRI		0x0464
 158#define DSI2_INT_FORCE_CRI		0x0468
 159#define DSI2_MAX_REGISGER		DSI2_INT_FORCE_CRI
 160
 161#define MODE_STATUS_TIMEOUT_US		10000
 162#define CMD_PKT_STATUS_TIMEOUT_US	20000
 163
 164enum vid_mode_type {
 165	VID_MODE_TYPE_NON_BURST_SYNC_PULSES,
 166	VID_MODE_TYPE_NON_BURST_SYNC_EVENTS,
 167	VID_MODE_TYPE_BURST,
 168};
 169
 170enum mode_ctrl {
 171	IDLE_MODE,
 172	AUTOCALC_MODE,
 173	COMMAND_MODE,
 174	VIDEO_MODE,
 175	DATA_STREAM_MODE,
 176	VIDEO_TEST_MODE,
 177	DATA_STREAM_TEST_MODE,
 178};
 179
 180enum ppi_width {
 181	PPI_WIDTH_8_BITS,
 182	PPI_WIDTH_16_BITS,
 183	PPI_WIDTH_32_BITS,
 184};
 185
 186struct cmd_header {
 187	u8 cmd_type;
 188	u8 delay;
 189	u8 payload_length;
 190};
 191
 192struct dw_mipi_dsi2 {
 193	struct drm_bridge bridge;
 194	struct mipi_dsi_host dsi_host;
 195	struct drm_bridge *panel_bridge;
 196	struct device *dev;
 197	struct regmap *regmap;
 198	struct clk *pclk;
 199	struct clk *sys_clk;
 200
 201	unsigned int lane_mbps; /* per lane */
 202	u32 channel;
 203	u32 lanes;
 204	u32 format;
 205	unsigned long mode_flags;
 206
 207	struct drm_display_mode mode;
 208	const struct dw_mipi_dsi2_plat_data *plat_data;
 209};
 210
 211static inline struct dw_mipi_dsi2 *host_to_dsi2(struct mipi_dsi_host *host)
 212{
 213	return container_of(host, struct dw_mipi_dsi2, dsi_host);
 214}
 215
 216static inline struct dw_mipi_dsi2 *bridge_to_dsi2(struct drm_bridge *bridge)
 217{
 218	return container_of(bridge, struct dw_mipi_dsi2, bridge);
 219}
 220
 221static int cri_fifos_wait_avail(struct dw_mipi_dsi2 *dsi2)
 222{
 223	u32 sts, mask;
 224	int ret;
 225
 226	mask = CRI_BUSY | CRT_FIFOS_NOT_EMPTY;
 227	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_CORE_STATUS, sts,
 228				       !(sts & mask), 0, CMD_PKT_STATUS_TIMEOUT_US);
 229	if (ret < 0) {
 230		dev_err(dsi2->dev, "command interface is busy\n");
 231		return ret;
 232	}
 233
 234	return 0;
 235}
 236
 237static void dw_mipi_dsi2_set_vid_mode(struct dw_mipi_dsi2 *dsi2)
 238{
 239	u32 val = 0, mode;
 240	int ret;
 241
 242	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP)
 243		val |= BLK_HFP_HS_EN;
 244
 245	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP)
 246		val |= BLK_HBP_HS_EN;
 247
 248	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HSA)
 249		val |= BLK_HSA_HS_EN;
 250
 251	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
 252		val |= VID_MODE_TYPE_BURST;
 253	else if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
 254		val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES;
 255	else
 256		val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
 257
 258	regmap_write(dsi2->regmap, DSI2_DSI_VID_TX_CFG, val);
 259
 260	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, VIDEO_MODE);
 261	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
 262				       mode, mode & VIDEO_MODE,
 263				       1000, MODE_STATUS_TIMEOUT_US);
 264	if (ret < 0)
 265		dev_err(dsi2->dev, "failed to enter video mode\n");
 266}
 267
 268static void dw_mipi_dsi2_set_data_stream_mode(struct dw_mipi_dsi2 *dsi2)
 269{
 270	u32 mode;
 271	int ret;
 272
 273	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, DATA_STREAM_MODE);
 274	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
 275				       mode, mode & DATA_STREAM_MODE,
 276				       1000, MODE_STATUS_TIMEOUT_US);
 277	if (ret < 0)
 278		dev_err(dsi2->dev, "failed to enter data stream mode\n");
 279}
 280
 281static void dw_mipi_dsi2_set_cmd_mode(struct dw_mipi_dsi2 *dsi2)
 282{
 283	u32 mode;
 284	int ret;
 285
 286	regmap_write(dsi2->regmap, DSI2_MODE_CTRL, COMMAND_MODE);
 287	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_MODE_STATUS,
 288				       mode, mode & COMMAND_MODE,
 289				       1000, MODE_STATUS_TIMEOUT_US);
 290	if (ret < 0)
 291		dev_err(dsi2->dev, "failed to enter data stream mode\n");
 292}
 293
 294static void dw_mipi_dsi2_host_softrst(struct dw_mipi_dsi2 *dsi2)
 295{
 296	regmap_write(dsi2->regmap, DSI2_SOFT_RESET, 0x0);
 297	usleep_range(50, 100);
 298	regmap_write(dsi2->regmap, DSI2_SOFT_RESET,
 299		     SYS_RSTN | PHY_RSTN | IPI_RSTN);
 300}
 301
 302static void dw_mipi_dsi2_phy_clk_mode_cfg(struct dw_mipi_dsi2 *dsi2)
 303{
 304	u32 sys_clk, esc_clk_div;
 305	u32 val = 0;
 306
 307	/*
 308	 * clk_type should be NON_CONTINUOUS_CLK before
 309	 * initial deskew calibration be sent.
 310	 */
 311	val |= NON_CONTINUOUS_CLK;
 312
 313	/* The maximum value of the escape clock frequency is 20MHz */
 314	sys_clk = clk_get_rate(dsi2->sys_clk) / USEC_PER_SEC;
 315	esc_clk_div = DIV_ROUND_UP(sys_clk, 20 * 2);
 316	val |= PHY_LPTX_CLK_DIV(esc_clk_div);
 317
 318	regmap_write(dsi2->regmap, DSI2_PHY_CLK_CFG, val);
 319}
 320
 321static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2)
 322{
 323	struct drm_display_mode *mode = &dsi2->mode;
 324	u64 sys_clk = clk_get_rate(dsi2->sys_clk);
 325	u64 pixel_clk, ipi_clk, phy_hsclk;
 326	u64 tmp;
 327
 328	/*
 329	 * in DPHY mode, the phy_hstx_clk is exactly 1/16 the Lane high-speed
 330	 * data rate; In CPHY mode, the phy_hstx_clk is exactly 1/7 the trio
 331	 * high speed symbol rate.
 332	 */
 333	phy_hsclk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
 334
 335	/* IPI_RATIO_MAN_CFG = PHY_HSTX_CLK / IPI_CLK */
 336	pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
 337	ipi_clk = pixel_clk / 4;
 338
 339	tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, ipi_clk);
 340	regmap_write(dsi2->regmap, DSI2_PHY_IPI_RATIO_MAN_CFG,
 341		     PHY_IPI_RATIO(tmp));
 342
 343	/*
 344	 * SYS_RATIO_MAN_CFG = MIPI_DCPHY_HSCLK_Freq / MIPI_DCPHY_HSCLK_Freq
 345	 */
 346	tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, sys_clk);
 347	regmap_write(dsi2->regmap, DSI2_PHY_SYS_RATIO_MAN_CFG,
 348		     PHY_SYS_RATIO(tmp));
 349}
 350
 351static void dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(struct dw_mipi_dsi2 *dsi2)
 352{
 353	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
 354	struct dw_mipi_dsi2_phy_timing timing;
 355	int ret;
 356
 357	ret = phy_ops->get_timing(dsi2->plat_data->priv_data,
 358				  dsi2->lane_mbps, &timing);
 359	if (ret)
 360		dev_err(dsi2->dev, "Retrieving phy timings failed\n");
 361
 362	regmap_write(dsi2->regmap, DSI2_PHY_LP2HS_MAN_CFG, PHY_LP2HS_TIME(timing.data_lp2hs));
 363	regmap_write(dsi2->regmap, DSI2_PHY_HS2LP_MAN_CFG, PHY_HS2LP_TIME(timing.data_hs2lp));
 364}
 365
 366static void dw_mipi_dsi2_phy_init(struct dw_mipi_dsi2 *dsi2)
 367{
 368	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
 369	struct dw_mipi_dsi2_phy_iface iface;
 370	u32 val = 0;
 371
 372	phy_ops->get_interface(dsi2->plat_data->priv_data, &iface);
 373
 374	switch (iface.ppi_width) {
 375	case 8:
 376		val |= PPI_WIDTH(PPI_WIDTH_8_BITS);
 377		break;
 378	case 16:
 379		val |= PPI_WIDTH(PPI_WIDTH_16_BITS);
 380		break;
 381	case 32:
 382		val |= PPI_WIDTH(PPI_WIDTH_32_BITS);
 383		break;
 384	default:
 385		/* Caught in probe */
 386		break;
 387	}
 388
 389	val |= PHY_LANES(dsi2->lanes);
 390	val |= PHY_TYPE(DW_MIPI_DSI2_DPHY);
 391	regmap_write(dsi2->regmap, DSI2_PHY_MODE_CFG, val);
 392
 393	dw_mipi_dsi2_phy_clk_mode_cfg(dsi2);
 394	dw_mipi_dsi2_phy_ratio_cfg(dsi2);
 395	dw_mipi_dsi2_lp2hs_or_hs2lp_cfg(dsi2);
 396
 397	/* phy configuration 8 - 10 */
 398}
 399
 400static void dw_mipi_dsi2_tx_option_set(struct dw_mipi_dsi2 *dsi2)
 401{
 402	u32 val;
 403
 404	val = BTA_EN | EOTP_TX_EN;
 405
 406	if (dsi2->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
 407		val &= ~EOTP_TX_EN;
 408
 409	regmap_write(dsi2->regmap, DSI2_DSI_GENERAL_CFG, val);
 410	regmap_write(dsi2->regmap, DSI2_DSI_VCID_CFG, TX_VCID(dsi2->channel));
 411}
 412
 413static void dw_mipi_dsi2_ipi_color_coding_cfg(struct dw_mipi_dsi2 *dsi2)
 414{
 415	u32 val, color_depth;
 416
 417	switch (dsi2->format) {
 418	case MIPI_DSI_FMT_RGB666:
 419	case MIPI_DSI_FMT_RGB666_PACKED:
 420		color_depth = IPI_DEPTH_6_BITS;
 421		break;
 422	case MIPI_DSI_FMT_RGB565:
 423		color_depth = IPI_DEPTH_5_6_5_BITS;
 424		break;
 425	case MIPI_DSI_FMT_RGB888:
 426	default:
 427		color_depth = IPI_DEPTH_8_BITS;
 428		break;
 429	}
 430
 431	val = IPI_DEPTH(color_depth) |
 432	      IPI_FORMAT(IPI_FORMAT_RGB);
 433	regmap_write(dsi2->regmap, DSI2_IPI_COLOR_MAN_CFG, val);
 434}
 435
 436static void dw_mipi_dsi2_vertical_timing_config(struct dw_mipi_dsi2 *dsi2,
 437						const struct drm_display_mode *mode)
 438{
 439	u32 vactive, vsa, vfp, vbp;
 440
 441	vactive = mode->vdisplay;
 442	vsa = mode->vsync_end - mode->vsync_start;
 443	vfp = mode->vsync_start - mode->vdisplay;
 444	vbp = mode->vtotal - mode->vsync_end;
 445
 446	regmap_write(dsi2->regmap, DSI2_IPI_VID_VSA_MAN_CFG, VID_VSA_LINES(vsa));
 447	regmap_write(dsi2->regmap, DSI2_IPI_VID_VBP_MAN_CFG, VID_VBP_LINES(vbp));
 448	regmap_write(dsi2->regmap, DSI2_IPI_VID_VACT_MAN_CFG, VID_VACT_LINES(vactive));
 449	regmap_write(dsi2->regmap, DSI2_IPI_VID_VFP_MAN_CFG, VID_VFP_LINES(vfp));
 450}
 451
 452static void dw_mipi_dsi2_ipi_set(struct dw_mipi_dsi2 *dsi2)
 453{
 454	struct drm_display_mode *mode = &dsi2->mode;
 455	u32 hline, hsa, hbp, hact;
 456	u64 hline_time, hsa_time, hbp_time, hact_time, tmp;
 457	u64 pixel_clk, phy_hs_clk;
 458	u16 val;
 459
 460	val = mode->hdisplay;
 461
 462	regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, MAX_PIX_PKT(val));
 463
 464	dw_mipi_dsi2_ipi_color_coding_cfg(dsi2);
 465
 466	/*
 467	 * if the controller is intended to operate in data stream mode,
 468	 * no more steps are required.
 469	 */
 470	if (!(dsi2->mode_flags & MIPI_DSI_MODE_VIDEO))
 471		return;
 472
 473	hact = mode->hdisplay;
 474	hsa = mode->hsync_end - mode->hsync_start;
 475	hbp = mode->htotal - mode->hsync_end;
 476	hline = mode->htotal;
 477
 478	pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
 479
 480	phy_hs_clk = DIV_ROUND_CLOSEST_ULL(dsi2->lane_mbps * USEC_PER_SEC, 16);
 481
 482	tmp = hsa * phy_hs_clk;
 483	hsa_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
 484	regmap_write(dsi2->regmap, DSI2_IPI_VID_HSA_MAN_CFG, VID_HSA_TIME(hsa_time));
 485
 486	tmp = hbp * phy_hs_clk;
 487	hbp_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
 488	regmap_write(dsi2->regmap, DSI2_IPI_VID_HBP_MAN_CFG, VID_HBP_TIME(hbp_time));
 489
 490	tmp = hact * phy_hs_clk;
 491	hact_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
 492	regmap_write(dsi2->regmap, DSI2_IPI_VID_HACT_MAN_CFG, VID_HACT_TIME(hact_time));
 493
 494	tmp = hline * phy_hs_clk;
 495	hline_time = DIV_ROUND_CLOSEST_ULL(tmp << 16, pixel_clk);
 496	regmap_write(dsi2->regmap, DSI2_IPI_VID_HLINE_MAN_CFG, VID_HLINE_TIME(hline_time));
 497
 498	dw_mipi_dsi2_vertical_timing_config(dsi2, mode);
 499}
 500
 501static void
 502dw_mipi_dsi2_work_mode(struct dw_mipi_dsi2 *dsi2, u32 mode)
 503{
 504	/*
 505	 * select controller work in Manual mode
 506	 * Manual: MANUAL_MODE_EN
 507	 * Automatic: 0
 508	 */
 509	regmap_write(dsi2->regmap, MANUAL_MODE_CFG, mode);
 510}
 511
 512static int dw_mipi_dsi2_host_attach(struct mipi_dsi_host *host,
 513				    struct mipi_dsi_device *device)
 514{
 515	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
 516	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
 517	struct drm_bridge *bridge;
 518	int ret;
 519
 520	if (device->lanes > dsi2->plat_data->max_data_lanes) {
 521		dev_err(dsi2->dev, "the number of data lanes(%u) is too many\n",
 522			device->lanes);
 523		return -EINVAL;
 524	}
 525
 526	dsi2->lanes = device->lanes;
 527	dsi2->channel = device->channel;
 528	dsi2->format = device->format;
 529	dsi2->mode_flags = device->mode_flags;
 530
 531	bridge = devm_drm_of_get_bridge(dsi2->dev, dsi2->dev->of_node, 1, 0);
 532	if (IS_ERR(bridge))
 533		return PTR_ERR(bridge);
 534
 535	bridge->pre_enable_prev_first = true;
 536	dsi2->panel_bridge = bridge;
 537
 538	drm_bridge_add(&dsi2->bridge);
 539
 540	if (pdata->host_ops && pdata->host_ops->attach) {
 541		ret = pdata->host_ops->attach(pdata->priv_data, device);
 542		if (ret < 0)
 543			return ret;
 544	}
 545
 546	return 0;
 547}
 548
 549static int dw_mipi_dsi2_host_detach(struct mipi_dsi_host *host,
 550				    struct mipi_dsi_device *device)
 551{
 552	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
 553	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
 554	int ret;
 555
 556	if (pdata->host_ops && pdata->host_ops->detach) {
 557		ret = pdata->host_ops->detach(pdata->priv_data, device);
 558		if (ret < 0)
 559			return ret;
 560	}
 561
 562	drm_bridge_remove(&dsi2->bridge);
 563
 564	drm_of_panel_bridge_remove(host->dev->of_node, 1, 0);
 565
 566	return 0;
 567}
 568
 569static int dw_mipi_dsi2_gen_pkt_hdr_write(struct dw_mipi_dsi2 *dsi2,
 570					  u32 hdr_val, bool lpm)
 571{
 572	int ret;
 573
 574	regmap_write(dsi2->regmap, DSI2_CRI_TX_HDR, hdr_val | CMD_TX_MODE(lpm));
 575
 576	ret = cri_fifos_wait_avail(dsi2);
 577	if (ret) {
 578		dev_err(dsi2->dev, "failed to write command header\n");
 579		return ret;
 580	}
 581
 582	return 0;
 583}
 584
 585static int dw_mipi_dsi2_write(struct dw_mipi_dsi2 *dsi2,
 586			      const struct mipi_dsi_packet *packet, bool lpm)
 587{
 588	const u8 *tx_buf = packet->payload;
 589	int len = packet->payload_length, pld_data_bytes = sizeof(u32);
 590	__le32 word;
 591
 592	/* Send payload */
 593	while (len) {
 594		if (len < pld_data_bytes) {
 595			word = 0;
 596			memcpy(&word, tx_buf, len);
 597			regmap_write(dsi2->regmap, DSI2_CRI_TX_PLD, le32_to_cpu(word));
 598			len = 0;
 599		} else {
 600			memcpy(&word, tx_buf, pld_data_bytes);
 601			regmap_write(dsi2->regmap, DSI2_CRI_TX_PLD, le32_to_cpu(word));
 602			tx_buf += pld_data_bytes;
 603			len -= pld_data_bytes;
 604		}
 605	}
 606
 607	word = 0;
 608	memcpy(&word, packet->header, sizeof(packet->header));
 609	return dw_mipi_dsi2_gen_pkt_hdr_write(dsi2, le32_to_cpu(word), lpm);
 610}
 611
 612static int dw_mipi_dsi2_read(struct dw_mipi_dsi2 *dsi2,
 613			     const struct mipi_dsi_msg *msg)
 614{
 615	u8 *payload = msg->rx_buf;
 616	int i, j, ret, len = msg->rx_len;
 617	u8 data_type;
 618	u16 wc;
 619	u32 val;
 620
 621	ret = regmap_read_poll_timeout(dsi2->regmap, DSI2_CORE_STATUS,
 622				       val, val & CRI_RD_DATA_AVAIL,
 623				       100, CMD_PKT_STATUS_TIMEOUT_US);
 624	if (ret) {
 625		dev_err(dsi2->dev, "CRI has no available read data\n");
 626		return ret;
 627	}
 628
 629	regmap_read(dsi2->regmap, DSI2_CRI_RX_HDR, &val);
 630	data_type = val & 0x3f;
 631
 632	if (mipi_dsi_packet_format_is_short(data_type)) {
 633		for (i = 0; i < len && i < 2; i++)
 634			payload[i] = (val >> (8 * (i + 1))) & 0xff;
 635
 636		return 0;
 637	}
 638
 639	wc = (val >> 8) & 0xffff;
 640	/* Receive payload */
 641	for (i = 0; i < len && i < wc; i += 4) {
 642		regmap_read(dsi2->regmap, DSI2_CRI_RX_PLD, &val);
 643		for (j = 0; j < 4 && j + i < len && j + i < wc; j++)
 644			payload[i + j] = val >> (8 * j);
 645	}
 646
 647	return 0;
 648}
 649
 650static ssize_t dw_mipi_dsi2_host_transfer(struct mipi_dsi_host *host,
 651					  const struct mipi_dsi_msg *msg)
 652{
 653	struct dw_mipi_dsi2 *dsi2 = host_to_dsi2(host);
 654	bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM;
 655	struct mipi_dsi_packet packet;
 656	int ret, nb_bytes;
 657
 658	regmap_update_bits(dsi2->regmap, DSI2_DSI_VID_TX_CFG,
 659			   LPDT_DISPLAY_CMD_EN,
 660			   lpm ? LPDT_DISPLAY_CMD_EN : 0);
 661
 662	/* create a packet to the DSI protocol */
 663	ret = mipi_dsi_create_packet(&packet, msg);
 664	if (ret) {
 665		dev_err(dsi2->dev, "failed to create packet: %d\n", ret);
 666		return ret;
 667	}
 668
 669	ret = cri_fifos_wait_avail(dsi2);
 670	if (ret)
 671		return ret;
 672
 673	ret = dw_mipi_dsi2_write(dsi2, &packet, lpm);
 674	if (ret)
 675		return ret;
 676
 677	if (msg->rx_buf && msg->rx_len) {
 678		ret = dw_mipi_dsi2_read(dsi2, msg);
 679		if (ret < 0)
 680			return ret;
 681		nb_bytes = msg->rx_len;
 682	} else {
 683		nb_bytes = packet.size;
 684	}
 685
 686	return nb_bytes;
 687}
 688
 689static const struct mipi_dsi_host_ops dw_mipi_dsi2_host_ops = {
 690	.attach = dw_mipi_dsi2_host_attach,
 691	.detach = dw_mipi_dsi2_host_detach,
 692	.transfer = dw_mipi_dsi2_host_transfer,
 693};
 694
 695static u32 *
 696dw_mipi_dsi2_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
 697					      struct drm_bridge_state *bridge_state,
 698					      struct drm_crtc_state *crtc_state,
 699					      struct drm_connector_state *conn_state,
 700					      u32 output_fmt,
 701					      unsigned int *num_input_fmts)
 702{
 703	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
 704	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
 705	u32 *input_fmts;
 706
 707	if (pdata->get_input_bus_fmts)
 708		return pdata->get_input_bus_fmts(pdata->priv_data,
 709						 bridge, bridge_state,
 710						 crtc_state, conn_state,
 711						 output_fmt, num_input_fmts);
 712
 713	/* Fall back to MEDIA_BUS_FMT_FIXED as the only input format. */
 714	input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
 715	if (!input_fmts)
 716		return NULL;
 717	input_fmts[0] = MEDIA_BUS_FMT_FIXED;
 718	*num_input_fmts = 1;
 719
 720	return input_fmts;
 721}
 722
 723static int dw_mipi_dsi2_bridge_atomic_check(struct drm_bridge *bridge,
 724					    struct drm_bridge_state *bridge_state,
 725					    struct drm_crtc_state *crtc_state,
 726					    struct drm_connector_state *conn_state)
 727{
 728	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
 729	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
 730	bool ret;
 731
 732	bridge_state->input_bus_cfg.flags =
 733		DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE;
 734
 735	if (pdata->mode_fixup) {
 736		ret = pdata->mode_fixup(pdata->priv_data, &crtc_state->mode,
 737					&crtc_state->adjusted_mode);
 738		if (!ret) {
 739			DRM_DEBUG_DRIVER("failed to fixup mode " DRM_MODE_FMT "\n",
 740					 DRM_MODE_ARG(&crtc_state->mode));
 741			return -EINVAL;
 742		}
 743	}
 744
 745	return 0;
 746}
 747
 748static void dw_mipi_dsi2_bridge_post_atomic_disable(struct drm_bridge *bridge,
 749						    struct drm_atomic_state *state)
 750{
 751	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
 752	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
 753
 754	regmap_write(dsi2->regmap, DSI2_IPI_PIX_PKT_CFG, 0);
 755
 756	/*
 757	 * Switch to command mode before panel-bridge post_disable &
 758	 * panel unprepare.
 759	 * Note: panel-bridge disable & panel disable has been called
 760	 * before by the drm framework.
 761	 */
 762	dw_mipi_dsi2_set_cmd_mode(dsi2);
 763
 764	regmap_write(dsi2->regmap, DSI2_PWR_UP, RESET);
 765
 766	if (phy_ops->power_off)
 767		phy_ops->power_off(dsi2->plat_data->priv_data);
 768
 769	clk_disable_unprepare(dsi2->sys_clk);
 770	clk_disable_unprepare(dsi2->pclk);
 771	pm_runtime_put(dsi2->dev);
 772}
 773
 774static unsigned int dw_mipi_dsi2_get_lanes(struct dw_mipi_dsi2 *dsi2)
 775{
 776	/* single-dsi, so no other instance to consider */
 777	return dsi2->lanes;
 778}
 779
 780static void dw_mipi_dsi2_mode_set(struct dw_mipi_dsi2 *dsi2,
 781				  const struct drm_display_mode *adjusted_mode)
 782{
 783	const struct dw_mipi_dsi2_phy_ops *phy_ops = dsi2->plat_data->phy_ops;
 784	void *priv_data = dsi2->plat_data->priv_data;
 785	u32 lanes = dw_mipi_dsi2_get_lanes(dsi2);
 786	int ret;
 787
 788	clk_prepare_enable(dsi2->pclk);
 789	clk_prepare_enable(dsi2->sys_clk);
 790
 791	ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, dsi2->mode_flags,
 792				     lanes, dsi2->format, &dsi2->lane_mbps);
 793	if (ret)
 794		DRM_DEBUG_DRIVER("Phy get_lane_mbps() failed\n");
 795
 796	pm_runtime_get_sync(dsi2->dev);
 797
 798	dw_mipi_dsi2_host_softrst(dsi2);
 799	regmap_write(dsi2->regmap, DSI2_PWR_UP, RESET);
 800
 801	dw_mipi_dsi2_work_mode(dsi2, MANUAL_MODE_EN);
 802	dw_mipi_dsi2_phy_init(dsi2);
 803
 804	if (phy_ops->power_on)
 805		phy_ops->power_on(dsi2->plat_data->priv_data);
 806
 807	dw_mipi_dsi2_tx_option_set(dsi2);
 808
 809	/*
 810	 * initial deskew calibration is send after phy_power_on,
 811	 * then we can configure clk_type.
 812	 */
 813
 814	regmap_update_bits(dsi2->regmap, DSI2_PHY_CLK_CFG, CLK_TYPE_MASK,
 815			   dsi2->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS ? NON_CONTINUOUS_CLK :
 816									      CONTINUOUS_CLK);
 817
 818	regmap_write(dsi2->regmap, DSI2_PWR_UP, POWER_UP);
 819	dw_mipi_dsi2_set_cmd_mode(dsi2);
 820
 821	dw_mipi_dsi2_ipi_set(dsi2);
 822}
 823
 824static void dw_mipi_dsi2_bridge_atomic_pre_enable(struct drm_bridge *bridge,
 825						  struct drm_atomic_state *state)
 826{
 827	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
 828
 829	/* Power up the dsi ctl into a command mode */
 830	dw_mipi_dsi2_mode_set(dsi2, &dsi2->mode);
 831}
 832
 833static void dw_mipi_dsi2_bridge_mode_set(struct drm_bridge *bridge,
 834					 const struct drm_display_mode *mode,
 835					 const struct drm_display_mode *adjusted_mode)
 836{
 837	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
 838
 839	/* Store the display mode for later use in pre_enable callback */
 840	drm_mode_copy(&dsi2->mode, adjusted_mode);
 841}
 842
 843static void dw_mipi_dsi2_bridge_atomic_enable(struct drm_bridge *bridge,
 844					      struct drm_atomic_state *state)
 845{
 846	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
 847
 848	/* Switch to video mode for panel-bridge enable & panel enable */
 849	if (dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)
 850		dw_mipi_dsi2_set_vid_mode(dsi2);
 851	else
 852		dw_mipi_dsi2_set_data_stream_mode(dsi2);
 853}
 854
 855static enum drm_mode_status
 856dw_mipi_dsi2_bridge_mode_valid(struct drm_bridge *bridge,
 857			       const struct drm_display_info *info,
 858			       const struct drm_display_mode *mode)
 859{
 860	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
 861	const struct dw_mipi_dsi2_plat_data *pdata = dsi2->plat_data;
 862	enum drm_mode_status mode_status = MODE_OK;
 863
 864	if (pdata->mode_valid)
 865		mode_status = pdata->mode_valid(pdata->priv_data, mode,
 866						dsi2->mode_flags,
 867						dw_mipi_dsi2_get_lanes(dsi2),
 868						dsi2->format);
 869
 870	return mode_status;
 871}
 872
 873static int dw_mipi_dsi2_bridge_attach(struct drm_bridge *bridge,
 874				      struct drm_encoder *encoder,
 875				      enum drm_bridge_attach_flags flags)
 876{
 877	struct dw_mipi_dsi2 *dsi2 = bridge_to_dsi2(bridge);
 878
 879	/* Set the encoder type as caller does not know it */
 880	encoder->encoder_type = DRM_MODE_ENCODER_DSI;
 881
 882	/* Attach the panel-bridge to the dsi bridge */
 883	return drm_bridge_attach(encoder, dsi2->panel_bridge, bridge,
 884				 flags);
 885}
 886
 887static const struct drm_bridge_funcs dw_mipi_dsi2_bridge_funcs = {
 888	.atomic_duplicate_state	= drm_atomic_helper_bridge_duplicate_state,
 889	.atomic_destroy_state	= drm_atomic_helper_bridge_destroy_state,
 890	.atomic_get_input_bus_fmts = dw_mipi_dsi2_bridge_atomic_get_input_bus_fmts,
 891	.atomic_check		= dw_mipi_dsi2_bridge_atomic_check,
 892	.atomic_reset		= drm_atomic_helper_bridge_reset,
 893	.atomic_pre_enable	= dw_mipi_dsi2_bridge_atomic_pre_enable,
 894	.atomic_enable		= dw_mipi_dsi2_bridge_atomic_enable,
 895	.atomic_post_disable	= dw_mipi_dsi2_bridge_post_atomic_disable,
 896	.mode_set		= dw_mipi_dsi2_bridge_mode_set,
 897	.mode_valid		= dw_mipi_dsi2_bridge_mode_valid,
 898	.attach			= dw_mipi_dsi2_bridge_attach,
 899};
 900
 901static const struct regmap_config dw_mipi_dsi2_regmap_config = {
 902	.name = "dsi2-host",
 903	.reg_bits = 32,
 904	.val_bits = 32,
 905	.reg_stride = 4,
 906	.fast_io = true,
 907};
 908
 909static struct dw_mipi_dsi2 *
 910__dw_mipi_dsi2_probe(struct platform_device *pdev,
 911		     const struct dw_mipi_dsi2_plat_data *plat_data)
 912{
 913	struct device *dev = &pdev->dev;
 914	struct reset_control *apb_rst;
 915	struct dw_mipi_dsi2 *dsi2;
 916	int ret;
 917
 918	dsi2 = devm_drm_bridge_alloc(dev, struct dw_mipi_dsi2, bridge,
 919				     &dw_mipi_dsi2_bridge_funcs);
 920	if (IS_ERR(dsi2))
 921		return ERR_CAST(dsi2);
 922
 923	dsi2->dev = dev;
 924	dsi2->plat_data = plat_data;
 925
 926	if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps ||
 927	    !plat_data->phy_ops->get_timing)
 928		return dev_err_ptr_probe(dev, -ENODEV, "Phy not properly configured\n");
 929
 930	if (!plat_data->regmap) {
 931		void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
 932
 933		if (IS_ERR(base))
 934			return dev_err_cast_probe(dev, base, "failed to registers\n");
 935
 936		dsi2->regmap = devm_regmap_init_mmio(dev, base,
 937						     &dw_mipi_dsi2_regmap_config);
 938		if (IS_ERR(dsi2->regmap))
 939			return dev_err_cast_probe(dev, dsi2->regmap, "failed to init regmap\n");
 940	} else {
 941		dsi2->regmap = plat_data->regmap;
 942	}
 943
 944	dsi2->pclk = devm_clk_get(dev, "pclk");
 945	if (IS_ERR(dsi2->pclk))
 946		return dev_err_cast_probe(dev, dsi2->pclk, "Unable to get pclk\n");
 947
 948	dsi2->sys_clk = devm_clk_get(dev, "sys");
 949	if (IS_ERR(dsi2->sys_clk))
 950		return dev_err_cast_probe(dev, dsi2->sys_clk, "Unable to get sys_clk\n");
 951
 952	/*
 953	 * Note that the reset was not defined in the initial device tree, so
 954	 * we have to be prepared for it not being found.
 955	 */
 956	apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb");
 957	if (IS_ERR(apb_rst))
 958		return dev_err_cast_probe(dev, apb_rst, "Unable to get reset control\n");
 959
 960	if (apb_rst) {
 961		ret = clk_prepare_enable(dsi2->pclk);
 962		if (ret) {
 963			dev_err(dev, "%s: Failed to enable pclk\n", __func__);
 964			return ERR_PTR(ret);
 965		}
 966
 967		reset_control_assert(apb_rst);
 968		usleep_range(10, 20);
 969		reset_control_deassert(apb_rst);
 970
 971		clk_disable_unprepare(dsi2->pclk);
 972	}
 973
 974	devm_pm_runtime_enable(dev);
 975
 976	dsi2->dsi_host.ops = &dw_mipi_dsi2_host_ops;
 977	dsi2->dsi_host.dev = dev;
 978	ret = mipi_dsi_host_register(&dsi2->dsi_host);
 979	if (ret) {
 980		dev_err(dev, "Failed to register MIPI host: %d\n", ret);
 981		pm_runtime_disable(dev);
 982		return ERR_PTR(ret);
 983	}
 984
 985	dsi2->bridge.driver_private = dsi2;
 986	dsi2->bridge.of_node = pdev->dev.of_node;
 987
 988	return dsi2;
 989}
 990
 991static void __dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2)
 992{
 993	mipi_dsi_host_unregister(&dsi2->dsi_host);
 994}
 995
 996/*
 997 * Probe/remove API, used to create the bridge instance.
 998 */
 999struct dw_mipi_dsi2 *
1000dw_mipi_dsi2_probe(struct platform_device *pdev,
1001		   const struct dw_mipi_dsi2_plat_data *plat_data)
1002{
1003	return __dw_mipi_dsi2_probe(pdev, plat_data);
1004}
1005EXPORT_SYMBOL_GPL(dw_mipi_dsi2_probe);
1006
1007void dw_mipi_dsi2_remove(struct dw_mipi_dsi2 *dsi2)
1008{
1009	__dw_mipi_dsi2_remove(dsi2);
1010}
1011EXPORT_SYMBOL_GPL(dw_mipi_dsi2_remove);
1012
1013/*
1014 * Bind/unbind API, used from platforms based on the component framework
1015 * to attach the bridge to an encoder.
1016 */
1017int dw_mipi_dsi2_bind(struct dw_mipi_dsi2 *dsi2, struct drm_encoder *encoder)
1018{
1019	return drm_bridge_attach(encoder, &dsi2->bridge, NULL, 0);
1020}
1021EXPORT_SYMBOL_GPL(dw_mipi_dsi2_bind);
1022
1023void dw_mipi_dsi2_unbind(struct dw_mipi_dsi2 *dsi2)
1024{
1025}
1026EXPORT_SYMBOL_GPL(dw_mipi_dsi2_unbind);
1027
1028MODULE_AUTHOR("Guochun Huang <hero.huang@rock-chips.com>");
1029MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@cherry.de>");
1030MODULE_DESCRIPTION("DW MIPI DSI2 host controller driver");
1031MODULE_LICENSE("GPL");
1032MODULE_ALIAS("platform:dw-mipi-dsi2");
~/ Read-only file preview.