Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * i.MX8 NWL MIPI DSI host driver
   4 *
   5 * Copyright (C) 2017 NXP
   6 * Copyright (C) 2020 Purism SPC
   7 */
   8
   9#include <linux/bitfield.h>
  10#include <linux/bits.h>
  11#include <linux/clk.h>
  12#include <linux/irq.h>
  13#include <linux/math64.h>
  14#include <linux/mfd/syscon.h>
  15#include <linux/media-bus-format.h>
  16#include <linux/module.h>
  17#include <linux/mux/consumer.h>
  18#include <linux/of.h>
  19#include <linux/phy/phy.h>
  20#include <linux/platform_device.h>
  21#include <linux/regmap.h>
  22#include <linux/reset.h>
  23#include <linux/sys_soc.h>
  24#include <linux/time64.h>
  25
  26#include <drm/drm_atomic_state_helper.h>
  27#include <drm/drm_bridge.h>
  28#include <drm/drm_mipi_dsi.h>
  29#include <drm/drm_of.h>
  30#include <drm/drm_print.h>
  31
  32#include <video/mipi_display.h>
  33
  34#include "nwl-dsi.h"
  35
  36#define DRV_NAME "nwl-dsi"
  37
  38/* i.MX8 NWL quirks */
  39/* i.MX8MQ errata E11418 */
  40#define E11418_HS_MODE_QUIRK	BIT(0)
  41
  42#define NWL_DSI_MIPI_FIFO_TIMEOUT msecs_to_jiffies(500)
  43
  44enum transfer_direction {
  45	DSI_PACKET_SEND,
  46	DSI_PACKET_RECEIVE,
  47};
  48
  49#define NWL_DSI_ENDPOINT_LCDIF 0
  50#define NWL_DSI_ENDPOINT_DCSS 1
  51
  52struct nwl_dsi_transfer {
  53	const struct mipi_dsi_msg *msg;
  54	struct mipi_dsi_packet packet;
  55	struct completion completed;
  56
  57	int status; /* status of transmission */
  58	enum transfer_direction direction;
  59	bool need_bta;
  60	u8 cmd;
  61	u16 rx_word_count;
  62	size_t tx_len; /* in bytes */
  63	size_t rx_len; /* in bytes */
  64};
  65
  66struct nwl_dsi {
  67	struct drm_bridge bridge;
  68	struct mipi_dsi_host dsi_host;
  69	struct device *dev;
  70	struct phy *phy;
  71	union phy_configure_opts phy_cfg;
  72	unsigned int quirks;
  73
  74	struct regmap *regmap;
  75	int irq;
  76	/*
  77	 * The DSI host controller needs this reset sequence according to NWL:
  78	 * 1. Deassert pclk reset to get access to DSI regs
  79	 * 2. Configure DSI Host and DPHY and enable DPHY
  80	 * 3. Deassert ESC and BYTE resets to allow host TX operations)
  81	 * 4. Send DSI cmds to configure peripheral (handled by panel drv)
  82	 * 5. Deassert DPI reset so DPI receives pixels and starts sending
  83	 *    DSI data
  84	 *
  85	 * TODO: Since panel_bridges do their DSI setup in enable we
  86	 * currently have 4. and 5. swapped.
  87	 */
  88	struct reset_control *rst_byte;
  89	struct reset_control *rst_esc;
  90	struct reset_control *rst_dpi;
  91	struct reset_control *rst_pclk;
  92	struct mux_control *mux;
  93
  94	/* DSI clocks */
  95	struct clk *phy_ref_clk;
  96	struct clk *rx_esc_clk;
  97	struct clk *tx_esc_clk;
  98	struct clk *core_clk;
  99	/*
 100	 * hardware bug: the i.MX8MQ needs this clock on during reset
 101	 * even when not using LCDIF.
 102	 */
 103	struct clk *lcdif_clk;
 104
 105	/* dsi lanes */
 106	u32 lanes;
 107	enum mipi_dsi_pixel_format format;
 108	struct drm_display_mode mode;
 109	unsigned long dsi_mode_flags;
 110	int error;
 111
 112	struct nwl_dsi_transfer *xfer;
 113};
 114
 115static const struct regmap_config nwl_dsi_regmap_config = {
 116	.reg_bits = 16,
 117	.val_bits = 32,
 118	.reg_stride = 4,
 119	.max_register = NWL_DSI_IRQ_MASK2,
 120	.name = DRV_NAME,
 121};
 122
 123static inline struct nwl_dsi *bridge_to_dsi(struct drm_bridge *bridge)
 124{
 125	return container_of(bridge, struct nwl_dsi, bridge);
 126}
 127
 128static int nwl_dsi_clear_error(struct nwl_dsi *dsi)
 129{
 130	int ret = dsi->error;
 131
 132	dsi->error = 0;
 133	return ret;
 134}
 135
 136static void nwl_dsi_write(struct nwl_dsi *dsi, unsigned int reg, u32 val)
 137{
 138	int ret;
 139
 140	if (dsi->error)
 141		return;
 142
 143	ret = regmap_write(dsi->regmap, reg, val);
 144	if (ret < 0) {
 145		DRM_DEV_ERROR(dsi->dev,
 146			      "Failed to write NWL DSI reg 0x%x: %d\n", reg,
 147			      ret);
 148		dsi->error = ret;
 149	}
 150}
 151
 152static u32 nwl_dsi_read(struct nwl_dsi *dsi, u32 reg)
 153{
 154	unsigned int val;
 155	int ret;
 156
 157	if (dsi->error)
 158		return 0;
 159
 160	ret = regmap_read(dsi->regmap, reg, &val);
 161	if (ret < 0) {
 162		DRM_DEV_ERROR(dsi->dev, "Failed to read NWL DSI reg 0x%x: %d\n",
 163			      reg, ret);
 164		dsi->error = ret;
 165	}
 166	return val;
 167}
 168
 169static int nwl_dsi_get_dpi_pixel_format(enum mipi_dsi_pixel_format format)
 170{
 171	switch (format) {
 172	case MIPI_DSI_FMT_RGB565:
 173		return NWL_DSI_PIXEL_FORMAT_16;
 174	case MIPI_DSI_FMT_RGB666:
 175		return NWL_DSI_PIXEL_FORMAT_18L;
 176	case MIPI_DSI_FMT_RGB666_PACKED:
 177		return NWL_DSI_PIXEL_FORMAT_18;
 178	case MIPI_DSI_FMT_RGB888:
 179		return NWL_DSI_PIXEL_FORMAT_24;
 180	default:
 181		return -EINVAL;
 182	}
 183}
 184
 185/*
 186 * ps2bc - Picoseconds to byte clock cycles
 187 */
 188static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
 189{
 190	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
 191
 192	return DIV64_U64_ROUND_UP(ps * dsi->mode.clock * bpp,
 193				  dsi->lanes * 8ULL * NSEC_PER_SEC);
 194}
 195
 196/*
 197 * ui2bc - UI time periods to byte clock cycles
 198 */
 199static u32 ui2bc(unsigned int ui)
 200{
 201	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
 202}
 203
 204/*
 205 * us2bc - micro seconds to lp clock cycles
 206 */
 207static u32 us2lp(u32 lp_clk_rate, unsigned long us)
 208{
 209	return DIV_ROUND_UP(us * lp_clk_rate, USEC_PER_SEC);
 210}
 211
 212static int nwl_dsi_config_host(struct nwl_dsi *dsi)
 213{
 214	u32 cycles;
 215	struct phy_configure_opts_mipi_dphy *cfg = &dsi->phy_cfg.mipi_dphy;
 216
 217	if (dsi->lanes < 1 || dsi->lanes > 4)
 218		return -EINVAL;
 219
 220	DRM_DEV_DEBUG_DRIVER(dsi->dev, "DSI Lanes %d\n", dsi->lanes);
 221	nwl_dsi_write(dsi, NWL_DSI_CFG_NUM_LANES, dsi->lanes - 1);
 222
 223	if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
 224		nwl_dsi_write(dsi, NWL_DSI_CFG_NONCONTINUOUS_CLK, 0x01);
 225		nwl_dsi_write(dsi, NWL_DSI_CFG_AUTOINSERT_EOTP, 0x01);
 226	} else {
 227		nwl_dsi_write(dsi, NWL_DSI_CFG_NONCONTINUOUS_CLK, 0x00);
 228		nwl_dsi_write(dsi, NWL_DSI_CFG_AUTOINSERT_EOTP, 0x00);
 229	}
 230
 231	/* values in byte clock cycles */
 232	cycles = ui2bc(cfg->clk_pre);
 233	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
 234	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
 235	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
 236	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
 237	cycles += ui2bc(cfg->clk_pre);
 238	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
 239	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
 240	cycles = ps2bc(dsi, cfg->hs_exit);
 241	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap: 0x%x\n", cycles);
 242	nwl_dsi_write(dsi, NWL_DSI_CFG_TX_GAP, cycles);
 243
 244	nwl_dsi_write(dsi, NWL_DSI_CFG_EXTRA_CMDS_AFTER_EOTP, 0x01);
 245	nwl_dsi_write(dsi, NWL_DSI_CFG_HTX_TO_COUNT, 0x00);
 246	nwl_dsi_write(dsi, NWL_DSI_CFG_LRX_H_TO_COUNT, 0x00);
 247	nwl_dsi_write(dsi, NWL_DSI_CFG_BTA_H_TO_COUNT, 0x00);
 248	/* In LP clock cycles */
 249	cycles = us2lp(cfg->lp_clk_rate, cfg->wakeup);
 250	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_twakeup: 0x%x\n", cycles);
 251	nwl_dsi_write(dsi, NWL_DSI_CFG_TWAKEUP, cycles);
 252
 253	return nwl_dsi_clear_error(dsi);
 254}
 255
 256static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
 257{
 258	u32 mode;
 259	int color_format;
 260	bool burst_mode;
 261	int hfront_porch, hback_porch, vfront_porch, vback_porch;
 262	int hsync_len, vsync_len;
 263
 264	hfront_porch = dsi->mode.hsync_start - dsi->mode.hdisplay;
 265	hsync_len = dsi->mode.hsync_end - dsi->mode.hsync_start;
 266	hback_porch = dsi->mode.htotal - dsi->mode.hsync_end;
 267
 268	vfront_porch = dsi->mode.vsync_start - dsi->mode.vdisplay;
 269	vsync_len = dsi->mode.vsync_end - dsi->mode.vsync_start;
 270	vback_porch = dsi->mode.vtotal - dsi->mode.vsync_end;
 271
 272	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hfront_porch = %d\n", hfront_porch);
 273	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hback_porch = %d\n", hback_porch);
 274	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hsync_len = %d\n", hsync_len);
 275	DRM_DEV_DEBUG_DRIVER(dsi->dev, "hdisplay = %d\n", dsi->mode.hdisplay);
 276	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vfront_porch = %d\n", vfront_porch);
 277	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vback_porch = %d\n", vback_porch);
 278	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vsync_len = %d\n", vsync_len);
 279	DRM_DEV_DEBUG_DRIVER(dsi->dev, "vactive = %d\n", dsi->mode.vdisplay);
 280	DRM_DEV_DEBUG_DRIVER(dsi->dev, "clock = %d kHz\n", dsi->mode.clock);
 281
 282	color_format = nwl_dsi_get_dpi_pixel_format(dsi->format);
 283	if (color_format < 0) {
 284		DRM_DEV_ERROR(dsi->dev, "Invalid color format 0x%x\n",
 285			      dsi->format);
 286		return color_format;
 287	}
 288	DRM_DEV_DEBUG_DRIVER(dsi->dev, "pixel fmt = %d\n", dsi->format);
 289
 290	nwl_dsi_write(dsi, NWL_DSI_INTERFACE_COLOR_CODING, NWL_DSI_DPI_24_BIT);
 291	nwl_dsi_write(dsi, NWL_DSI_PIXEL_FORMAT, color_format);
 292	/*
 293	 * Adjusting input polarity based on the video mode results in
 294	 * a black screen so always pick active low:
 295	 */
 296	nwl_dsi_write(dsi, NWL_DSI_VSYNC_POLARITY,
 297		      NWL_DSI_VSYNC_POLARITY_ACTIVE_LOW);
 298	nwl_dsi_write(dsi, NWL_DSI_HSYNC_POLARITY,
 299		      NWL_DSI_HSYNC_POLARITY_ACTIVE_LOW);
 300
 301	burst_mode = (dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
 302		     !(dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE);
 303
 304	if (burst_mode) {
 305		nwl_dsi_write(dsi, NWL_DSI_VIDEO_MODE, NWL_DSI_VM_BURST_MODE);
 306		nwl_dsi_write(dsi, NWL_DSI_PIXEL_FIFO_SEND_LEVEL, 256);
 307	} else {
 308		mode = ((dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) ?
 309				NWL_DSI_VM_BURST_MODE_WITH_SYNC_PULSES :
 310				NWL_DSI_VM_NON_BURST_MODE_WITH_SYNC_EVENTS);
 311		nwl_dsi_write(dsi, NWL_DSI_VIDEO_MODE, mode);
 312		nwl_dsi_write(dsi, NWL_DSI_PIXEL_FIFO_SEND_LEVEL,
 313			      dsi->mode.hdisplay);
 314	}
 315
 316	nwl_dsi_write(dsi, NWL_DSI_HFP, hfront_porch);
 317	nwl_dsi_write(dsi, NWL_DSI_HBP, hback_porch);
 318	nwl_dsi_write(dsi, NWL_DSI_HSA, hsync_len);
 319
 320	nwl_dsi_write(dsi, NWL_DSI_ENABLE_MULT_PKTS, 0x0);
 321	nwl_dsi_write(dsi, NWL_DSI_BLLP_MODE, 0x1);
 322	nwl_dsi_write(dsi, NWL_DSI_USE_NULL_PKT_BLLP, 0x0);
 323	nwl_dsi_write(dsi, NWL_DSI_VC, 0x0);
 324
 325	nwl_dsi_write(dsi, NWL_DSI_PIXEL_PAYLOAD_SIZE, dsi->mode.hdisplay);
 326	nwl_dsi_write(dsi, NWL_DSI_VACTIVE, dsi->mode.vdisplay - 1);
 327	nwl_dsi_write(dsi, NWL_DSI_VBP, vback_porch);
 328	nwl_dsi_write(dsi, NWL_DSI_VFP, vfront_porch);
 329
 330	return nwl_dsi_clear_error(dsi);
 331}
 332
 333static int nwl_dsi_init_interrupts(struct nwl_dsi *dsi)
 334{
 335	u32 irq_enable = ~(u32)(NWL_DSI_TX_PKT_DONE_MASK |
 336				NWL_DSI_RX_PKT_HDR_RCVD_MASK |
 337				NWL_DSI_TX_FIFO_OVFLW_MASK |
 338				NWL_DSI_HS_TX_TIMEOUT_MASK);
 339
 340	nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, irq_enable);
 341	nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK2, 0x7);
 342
 343	return nwl_dsi_clear_error(dsi);
 344}
 345
 346static int nwl_dsi_host_attach(struct mipi_dsi_host *dsi_host,
 347			       struct mipi_dsi_device *device)
 348{
 349	struct nwl_dsi *dsi = container_of(dsi_host, struct nwl_dsi, dsi_host);
 350	struct device *dev = dsi->dev;
 351
 352	DRM_DEV_INFO(dev, "lanes=%u, format=0x%x flags=0x%lx\n", device->lanes,
 353		     device->format, device->mode_flags);
 354
 355	if (device->lanes < 1 || device->lanes > 4)
 356		return -EINVAL;
 357
 358	dsi->lanes = device->lanes;
 359	dsi->format = device->format;
 360	dsi->dsi_mode_flags = device->mode_flags;
 361
 362	return 0;
 363}
 364
 365static bool nwl_dsi_read_packet(struct nwl_dsi *dsi, u32 status)
 366{
 367	struct device *dev = dsi->dev;
 368	struct nwl_dsi_transfer *xfer = dsi->xfer;
 369	int err;
 370	u8 *payload = xfer->msg->rx_buf;
 371	u32 val;
 372	u16 word_count;
 373	u8 channel;
 374	u8 data_type;
 375
 376	xfer->status = 0;
 377
 378	if (xfer->rx_word_count == 0) {
 379		if (!(status & NWL_DSI_RX_PKT_HDR_RCVD))
 380			return false;
 381		/* Get the RX header and parse it */
 382		val = nwl_dsi_read(dsi, NWL_DSI_RX_PKT_HEADER);
 383		err = nwl_dsi_clear_error(dsi);
 384		if (err)
 385			xfer->status = err;
 386		word_count = NWL_DSI_WC(val);
 387		channel = NWL_DSI_RX_VC(val);
 388		data_type = NWL_DSI_RX_DT(val);
 389
 390		if (channel != xfer->msg->channel) {
 391			DRM_DEV_ERROR(dev,
 392				      "[%02X] Channel mismatch (%u != %u)\n",
 393				      xfer->cmd, channel, xfer->msg->channel);
 394			xfer->status = -EINVAL;
 395			return true;
 396		}
 397
 398		switch (data_type) {
 399		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
 400		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
 401			if (xfer->msg->rx_len > 1) {
 402				/* read second byte */
 403				payload[1] = word_count >> 8;
 404				++xfer->rx_len;
 405			}
 406			fallthrough;
 407		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
 408		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
 409			if (xfer->msg->rx_len > 0) {
 410				/* read first byte */
 411				payload[0] = word_count & 0xff;
 412				++xfer->rx_len;
 413			}
 414			xfer->status = xfer->rx_len;
 415			return true;
 416		case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
 417			word_count &= 0xff;
 418			DRM_DEV_ERROR(dev, "[%02X] DSI error report: 0x%02x\n",
 419				      xfer->cmd, word_count);
 420			xfer->status = -EPROTO;
 421			return true;
 422		}
 423
 424		if (word_count > xfer->msg->rx_len) {
 425			DRM_DEV_ERROR(dev,
 426				"[%02X] Receive buffer too small: %zu (< %u)\n",
 427				xfer->cmd, xfer->msg->rx_len, word_count);
 428			xfer->status = -EINVAL;
 429			return true;
 430		}
 431
 432		xfer->rx_word_count = word_count;
 433	} else {
 434		/* Set word_count from previous header read */
 435		word_count = xfer->rx_word_count;
 436	}
 437
 438	/* If RX payload is not yet received, wait for it */
 439	if (!(status & NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD))
 440		return false;
 441
 442	/* Read the RX payload */
 443	while (word_count >= 4) {
 444		val = nwl_dsi_read(dsi, NWL_DSI_RX_PAYLOAD);
 445		payload[0] = (val >> 0) & 0xff;
 446		payload[1] = (val >> 8) & 0xff;
 447		payload[2] = (val >> 16) & 0xff;
 448		payload[3] = (val >> 24) & 0xff;
 449		payload += 4;
 450		xfer->rx_len += 4;
 451		word_count -= 4;
 452	}
 453
 454	if (word_count > 0) {
 455		val = nwl_dsi_read(dsi, NWL_DSI_RX_PAYLOAD);
 456		switch (word_count) {
 457		case 3:
 458			payload[2] = (val >> 16) & 0xff;
 459			++xfer->rx_len;
 460			fallthrough;
 461		case 2:
 462			payload[1] = (val >> 8) & 0xff;
 463			++xfer->rx_len;
 464			fallthrough;
 465		case 1:
 466			payload[0] = (val >> 0) & 0xff;
 467			++xfer->rx_len;
 468			break;
 469		}
 470	}
 471
 472	xfer->status = xfer->rx_len;
 473	err = nwl_dsi_clear_error(dsi);
 474	if (err)
 475		xfer->status = err;
 476
 477	return true;
 478}
 479
 480static void nwl_dsi_finish_transmission(struct nwl_dsi *dsi, u32 status)
 481{
 482	struct nwl_dsi_transfer *xfer = dsi->xfer;
 483	bool end_packet = false;
 484
 485	if (!xfer)
 486		return;
 487
 488	if (xfer->direction == DSI_PACKET_SEND &&
 489	    status & NWL_DSI_TX_PKT_DONE) {
 490		xfer->status = xfer->tx_len;
 491		end_packet = true;
 492	} else if (status & NWL_DSI_DPHY_DIRECTION &&
 493		   ((status & (NWL_DSI_RX_PKT_HDR_RCVD |
 494			       NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD)))) {
 495		end_packet = nwl_dsi_read_packet(dsi, status);
 496	}
 497
 498	if (end_packet)
 499		complete(&xfer->completed);
 500}
 501
 502static void nwl_dsi_begin_transmission(struct nwl_dsi *dsi)
 503{
 504	struct nwl_dsi_transfer *xfer = dsi->xfer;
 505	struct mipi_dsi_packet *pkt = &xfer->packet;
 506	const u8 *payload;
 507	size_t length;
 508	u16 word_count;
 509	u8 hs_mode;
 510	u32 val;
 511	u32 hs_workaround = 0;
 512
 513	/* Send the payload, if any */
 514	length = pkt->payload_length;
 515	payload = pkt->payload;
 516
 517	while (length >= 4) {
 518		val = *(u32 *)payload;
 519		hs_workaround |= !(val & 0xFFFF00);
 520		nwl_dsi_write(dsi, NWL_DSI_TX_PAYLOAD, val);
 521		payload += 4;
 522		length -= 4;
 523	}
 524	/* Send the rest of the payload */
 525	val = 0;
 526	switch (length) {
 527	case 3:
 528		val |= payload[2] << 16;
 529		fallthrough;
 530	case 2:
 531		val |= payload[1] << 8;
 532		hs_workaround |= !(val & 0xFFFF00);
 533		fallthrough;
 534	case 1:
 535		val |= payload[0];
 536		nwl_dsi_write(dsi, NWL_DSI_TX_PAYLOAD, val);
 537		break;
 538	}
 539	xfer->tx_len = pkt->payload_length;
 540
 541	/*
 542	 * Send the header
 543	 * header[0] = Virtual Channel + Data Type
 544	 * header[1] = Word Count LSB (LP) or first param (SP)
 545	 * header[2] = Word Count MSB (LP) or second param (SP)
 546	 */
 547	word_count = pkt->header[1] | (pkt->header[2] << 8);
 548	if (hs_workaround && (dsi->quirks & E11418_HS_MODE_QUIRK)) {
 549		DRM_DEV_DEBUG_DRIVER(dsi->dev,
 550				     "Using hs mode workaround for cmd 0x%x\n",
 551				     xfer->cmd);
 552		hs_mode = 1;
 553	} else {
 554		hs_mode = (xfer->msg->flags & MIPI_DSI_MSG_USE_LPM) ? 0 : 1;
 555	}
 556	val = NWL_DSI_WC(word_count) | NWL_DSI_TX_VC(xfer->msg->channel) |
 557	      NWL_DSI_TX_DT(xfer->msg->type) | NWL_DSI_HS_SEL(hs_mode) |
 558	      NWL_DSI_BTA_TX(xfer->need_bta);
 559	nwl_dsi_write(dsi, NWL_DSI_PKT_CONTROL, val);
 560
 561	/* Send packet command */
 562	nwl_dsi_write(dsi, NWL_DSI_SEND_PACKET, 0x1);
 563}
 564
 565static ssize_t nwl_dsi_host_transfer(struct mipi_dsi_host *dsi_host,
 566				     const struct mipi_dsi_msg *msg)
 567{
 568	struct nwl_dsi *dsi = container_of(dsi_host, struct nwl_dsi, dsi_host);
 569	struct nwl_dsi_transfer xfer;
 570	ssize_t ret = 0;
 571
 572	/* Create packet to be sent */
 573	dsi->xfer = &xfer;
 574	ret = mipi_dsi_create_packet(&xfer.packet, msg);
 575	if (ret < 0) {
 576		dsi->xfer = NULL;
 577		return ret;
 578	}
 579
 580	if ((msg->type & MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM ||
 581	     msg->type & MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM ||
 582	     msg->type & MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM ||
 583	     msg->type & MIPI_DSI_DCS_READ) &&
 584	    msg->rx_len > 0 && msg->rx_buf)
 585		xfer.direction = DSI_PACKET_RECEIVE;
 586	else
 587		xfer.direction = DSI_PACKET_SEND;
 588
 589	xfer.need_bta = (xfer.direction == DSI_PACKET_RECEIVE);
 590	xfer.need_bta |= (msg->flags & MIPI_DSI_MSG_REQ_ACK) ? 1 : 0;
 591	xfer.msg = msg;
 592	xfer.status = -ETIMEDOUT;
 593	xfer.rx_word_count = 0;
 594	xfer.rx_len = 0;
 595	xfer.cmd = 0x00;
 596	if (msg->tx_len > 0)
 597		xfer.cmd = ((u8 *)(msg->tx_buf))[0];
 598	init_completion(&xfer.completed);
 599
 600	ret = clk_prepare_enable(dsi->rx_esc_clk);
 601	if (ret < 0) {
 602		DRM_DEV_ERROR(dsi->dev, "Failed to enable rx_esc clk: %zd\n",
 603			      ret);
 604		return ret;
 605	}
 606	DRM_DEV_DEBUG_DRIVER(dsi->dev, "Enabled rx_esc clk @%lu Hz\n",
 607			     clk_get_rate(dsi->rx_esc_clk));
 608
 609	/* Initiate the DSI packet transmision */
 610	nwl_dsi_begin_transmission(dsi);
 611
 612	if (!wait_for_completion_timeout(&xfer.completed,
 613					 NWL_DSI_MIPI_FIFO_TIMEOUT)) {
 614		DRM_DEV_ERROR(dsi_host->dev, "[%02X] DSI transfer timed out\n",
 615			      xfer.cmd);
 616		ret = -ETIMEDOUT;
 617	} else {
 618		ret = xfer.status;
 619	}
 620
 621	clk_disable_unprepare(dsi->rx_esc_clk);
 622
 623	return ret;
 624}
 625
 626static const struct mipi_dsi_host_ops nwl_dsi_host_ops = {
 627	.attach = nwl_dsi_host_attach,
 628	.transfer = nwl_dsi_host_transfer,
 629};
 630
 631static irqreturn_t nwl_dsi_irq_handler(int irq, void *data)
 632{
 633	u32 irq_status;
 634	struct nwl_dsi *dsi = data;
 635
 636	irq_status = nwl_dsi_read(dsi, NWL_DSI_IRQ_STATUS);
 637
 638	if (irq_status & NWL_DSI_TX_FIFO_OVFLW)
 639		DRM_DEV_ERROR_RATELIMITED(dsi->dev, "tx fifo overflow\n");
 640
 641	if (irq_status & NWL_DSI_HS_TX_TIMEOUT)
 642		DRM_DEV_ERROR_RATELIMITED(dsi->dev, "HS tx timeout\n");
 643
 644	if (irq_status & NWL_DSI_TX_PKT_DONE ||
 645	    irq_status & NWL_DSI_RX_PKT_HDR_RCVD ||
 646	    irq_status & NWL_DSI_RX_PKT_PAYLOAD_DATA_RCVD)
 647		nwl_dsi_finish_transmission(dsi, irq_status);
 648
 649	return IRQ_HANDLED;
 650}
 651
 652static int nwl_dsi_mode_set(struct nwl_dsi *dsi)
 653{
 654	struct device *dev = dsi->dev;
 655	union phy_configure_opts *phy_cfg = &dsi->phy_cfg;
 656	int ret;
 657
 658	if (!dsi->lanes) {
 659		DRM_DEV_ERROR(dev, "Need DSI lanes: %d\n", dsi->lanes);
 660		return -EINVAL;
 661	}
 662
 663	ret = phy_init(dsi->phy);
 664	if (ret < 0) {
 665		DRM_DEV_ERROR(dev, "Failed to init DSI phy: %d\n", ret);
 666		return ret;
 667	}
 668
 669	ret = phy_set_mode(dsi->phy, PHY_MODE_MIPI_DPHY);
 670	if (ret < 0) {
 671		DRM_DEV_ERROR(dev, "Failed to set DSI phy mode: %d\n", ret);
 672		goto uninit_phy;
 673	}
 674
 675	ret = phy_configure(dsi->phy, phy_cfg);
 676	if (ret < 0) {
 677		DRM_DEV_ERROR(dev, "Failed to configure DSI phy: %d\n", ret);
 678		goto uninit_phy;
 679	}
 680
 681	ret = clk_prepare_enable(dsi->tx_esc_clk);
 682	if (ret < 0) {
 683		DRM_DEV_ERROR(dsi->dev, "Failed to enable tx_esc clk: %d\n",
 684			      ret);
 685		goto uninit_phy;
 686	}
 687	DRM_DEV_DEBUG_DRIVER(dsi->dev, "Enabled tx_esc clk @%lu Hz\n",
 688			     clk_get_rate(dsi->tx_esc_clk));
 689
 690	ret = nwl_dsi_config_host(dsi);
 691	if (ret < 0) {
 692		DRM_DEV_ERROR(dev, "Failed to set up DSI: %d", ret);
 693		goto disable_clock;
 694	}
 695
 696	ret = nwl_dsi_config_dpi(dsi);
 697	if (ret < 0) {
 698		DRM_DEV_ERROR(dev, "Failed to set up DPI: %d", ret);
 699		goto disable_clock;
 700	}
 701
 702	ret = phy_power_on(dsi->phy);
 703	if (ret < 0) {
 704		DRM_DEV_ERROR(dev, "Failed to power on DPHY (%d)\n", ret);
 705		goto disable_clock;
 706	}
 707
 708	ret = nwl_dsi_init_interrupts(dsi);
 709	if (ret < 0)
 710		goto power_off_phy;
 711
 712	return ret;
 713
 714power_off_phy:
 715	phy_power_off(dsi->phy);
 716disable_clock:
 717	clk_disable_unprepare(dsi->tx_esc_clk);
 718uninit_phy:
 719	phy_exit(dsi->phy);
 720
 721	return ret;
 722}
 723
 724static int nwl_dsi_disable(struct nwl_dsi *dsi)
 725{
 726	struct device *dev = dsi->dev;
 727
 728	DRM_DEV_DEBUG_DRIVER(dev, "Disabling clocks and phy\n");
 729
 730	phy_power_off(dsi->phy);
 731	phy_exit(dsi->phy);
 732
 733	/* Disabling the clock before the phy breaks enabling dsi again */
 734	clk_disable_unprepare(dsi->tx_esc_clk);
 735
 736	return 0;
 737}
 738
 739static void
 740nwl_dsi_bridge_atomic_disable(struct drm_bridge *bridge,
 741			      struct drm_bridge_state *old_bridge_state)
 742{
 743	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
 744	int ret;
 745
 746	nwl_dsi_disable(dsi);
 747
 748	ret = reset_control_assert(dsi->rst_dpi);
 749	if (ret < 0) {
 750		DRM_DEV_ERROR(dsi->dev, "Failed to assert DPI: %d\n", ret);
 751		return;
 752	}
 753	ret = reset_control_assert(dsi->rst_byte);
 754	if (ret < 0) {
 755		DRM_DEV_ERROR(dsi->dev, "Failed to assert ESC: %d\n", ret);
 756		return;
 757	}
 758	ret = reset_control_assert(dsi->rst_esc);
 759	if (ret < 0) {
 760		DRM_DEV_ERROR(dsi->dev, "Failed to assert BYTE: %d\n", ret);
 761		return;
 762	}
 763	ret = reset_control_assert(dsi->rst_pclk);
 764	if (ret < 0) {
 765		DRM_DEV_ERROR(dsi->dev, "Failed to assert PCLK: %d\n", ret);
 766		return;
 767	}
 768
 769	clk_disable_unprepare(dsi->core_clk);
 770	clk_disable_unprepare(dsi->lcdif_clk);
 771
 772	pm_runtime_put(dsi->dev);
 773}
 774
 775static int nwl_dsi_get_dphy_params(struct nwl_dsi *dsi,
 776				   const struct drm_display_mode *mode,
 777				   union phy_configure_opts *phy_opts)
 778{
 779	unsigned long rate;
 780	int ret;
 781
 782	if (dsi->lanes < 1 || dsi->lanes > 4)
 783		return -EINVAL;
 784
 785	/*
 786	 * So far the DPHY spec minimal timings work for both mixel
 787	 * dphy and nwl dsi host
 788	 */
 789	ret = phy_mipi_dphy_get_default_config(mode->clock * 1000,
 790		mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes,
 791		&phy_opts->mipi_dphy);
 792	if (ret < 0)
 793		return ret;
 794
 795	rate = clk_get_rate(dsi->tx_esc_clk);
 796	DRM_DEV_DEBUG_DRIVER(dsi->dev, "LP clk is @%lu Hz\n", rate);
 797	phy_opts->mipi_dphy.lp_clk_rate = rate;
 798
 799	return 0;
 800}
 801
 802static enum drm_mode_status
 803nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
 804			  const struct drm_display_info *info,
 805			  const struct drm_display_mode *mode)
 806{
 807	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
 808	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
 809
 810	if (mode->clock * bpp > 15000000 * dsi->lanes)
 811		return MODE_CLOCK_HIGH;
 812
 813	if (mode->clock * bpp < 80000 * dsi->lanes)
 814		return MODE_CLOCK_LOW;
 815
 816	return MODE_OK;
 817}
 818
 819static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge,
 820				       struct drm_bridge_state *bridge_state,
 821				       struct drm_crtc_state *crtc_state,
 822				       struct drm_connector_state *conn_state)
 823{
 824	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
 825
 826	/* At least LCDIF + NWL needs active high sync */
 827	adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
 828	adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
 829
 830	/*
 831	 * Do a full modeset if crtc_state->active is changed to be true.
 832	 * This ensures our ->mode_set() is called to get the DSI controller
 833	 * and the PHY ready to send DCS commands, when only the connector's
 834	 * DPMS is brought out of "Off" status.
 835	 */
 836	if (crtc_state->active_changed && crtc_state->active)
 837		crtc_state->mode_changed = true;
 838
 839	return 0;
 840}
 841
 842static void
 843nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
 844			const struct drm_display_mode *mode,
 845			const struct drm_display_mode *adjusted_mode)
 846{
 847	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
 848	struct device *dev = dsi->dev;
 849	union phy_configure_opts new_cfg;
 850	unsigned long phy_ref_rate;
 851	int ret;
 852
 853	ret = nwl_dsi_get_dphy_params(dsi, adjusted_mode, &new_cfg);
 854	if (ret < 0)
 855		return;
 856
 857	phy_ref_rate = clk_get_rate(dsi->phy_ref_clk);
 858	DRM_DEV_DEBUG_DRIVER(dev, "PHY at ref rate: %lu\n", phy_ref_rate);
 859	/* Save the new desired phy config */
 860	memcpy(&dsi->phy_cfg, &new_cfg, sizeof(new_cfg));
 861
 862	drm_mode_copy(&dsi->mode, adjusted_mode);
 863	drm_mode_debug_printmodeline(adjusted_mode);
 864
 865	if (pm_runtime_resume_and_get(dev) < 0)
 866		return;
 867
 868	if (clk_prepare_enable(dsi->lcdif_clk) < 0)
 869		goto runtime_put;
 870	if (clk_prepare_enable(dsi->core_clk) < 0)
 871		goto runtime_put;
 872
 873	/* Step 1 from DSI reset-out instructions */
 874	ret = reset_control_deassert(dsi->rst_pclk);
 875	if (ret < 0) {
 876		DRM_DEV_ERROR(dev, "Failed to deassert PCLK: %d\n", ret);
 877		goto runtime_put;
 878	}
 879
 880	/* Step 2 from DSI reset-out instructions */
 881	nwl_dsi_mode_set(dsi);
 882
 883	/* Step 3 from DSI reset-out instructions */
 884	ret = reset_control_deassert(dsi->rst_esc);
 885	if (ret < 0) {
 886		DRM_DEV_ERROR(dev, "Failed to deassert ESC: %d\n", ret);
 887		goto runtime_put;
 888	}
 889	ret = reset_control_deassert(dsi->rst_byte);
 890	if (ret < 0) {
 891		DRM_DEV_ERROR(dev, "Failed to deassert BYTE: %d\n", ret);
 892		goto runtime_put;
 893	}
 894
 895	return;
 896
 897runtime_put:
 898	pm_runtime_put_sync(dev);
 899}
 900
 901static void
 902nwl_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
 903			     struct drm_bridge_state *old_bridge_state)
 904{
 905	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
 906	int ret;
 907
 908	/* Step 5 from DSI reset-out instructions */
 909	ret = reset_control_deassert(dsi->rst_dpi);
 910	if (ret < 0)
 911		DRM_DEV_ERROR(dsi->dev, "Failed to deassert DPI: %d\n", ret);
 912}
 913
 914static int nwl_dsi_bridge_attach(struct drm_bridge *bridge,
 915				 enum drm_bridge_attach_flags flags)
 916{
 917	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
 918	struct drm_bridge *panel_bridge;
 919
 920	panel_bridge = devm_drm_of_get_bridge(dsi->dev, dsi->dev->of_node, 1, 0);
 921	if (IS_ERR(panel_bridge))
 922		return PTR_ERR(panel_bridge);
 923
 924	return drm_bridge_attach(bridge->encoder, panel_bridge, bridge, flags);
 925}
 926
 927static u32 *nwl_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
 928						 struct drm_bridge_state *bridge_state,
 929						 struct drm_crtc_state *crtc_state,
 930						 struct drm_connector_state *conn_state,
 931						 u32 output_fmt,
 932						 unsigned int *num_input_fmts)
 933{
 934	u32 *input_fmts, input_fmt;
 935
 936	*num_input_fmts = 0;
 937
 938	switch (output_fmt) {
 939	/* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
 940	case MEDIA_BUS_FMT_FIXED:
 941		input_fmt = MEDIA_BUS_FMT_RGB888_1X24;
 942		break;
 943	case MEDIA_BUS_FMT_RGB888_1X24:
 944	case MEDIA_BUS_FMT_RGB666_1X18:
 945	case MEDIA_BUS_FMT_RGB565_1X16:
 946		input_fmt = output_fmt;
 947		break;
 948	default:
 949		return NULL;
 950	}
 951
 952	input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL);
 953	if (!input_fmts)
 954		return NULL;
 955	input_fmts[0] = input_fmt;
 956	*num_input_fmts = 1;
 957
 958	return input_fmts;
 959}
 960
 961static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
 962	.atomic_duplicate_state	= drm_atomic_helper_bridge_duplicate_state,
 963	.atomic_destroy_state	= drm_atomic_helper_bridge_destroy_state,
 964	.atomic_reset		= drm_atomic_helper_bridge_reset,
 965	.atomic_check		= nwl_dsi_bridge_atomic_check,
 966	.atomic_enable		= nwl_dsi_bridge_atomic_enable,
 967	.atomic_disable		= nwl_dsi_bridge_atomic_disable,
 968	.atomic_get_input_bus_fmts = nwl_bridge_atomic_get_input_bus_fmts,
 969	.mode_set		= nwl_dsi_bridge_mode_set,
 970	.mode_valid		= nwl_dsi_bridge_mode_valid,
 971	.attach			= nwl_dsi_bridge_attach,
 972};
 973
 974static int nwl_dsi_parse_dt(struct nwl_dsi *dsi)
 975{
 976	struct platform_device *pdev = to_platform_device(dsi->dev);
 977	struct clk *clk;
 978	void __iomem *base;
 979	int ret;
 980
 981	dsi->phy = devm_phy_get(dsi->dev, "dphy");
 982	if (IS_ERR(dsi->phy)) {
 983		ret = PTR_ERR(dsi->phy);
 984		if (ret != -EPROBE_DEFER)
 985			DRM_DEV_ERROR(dsi->dev, "Could not get PHY: %d\n", ret);
 986		return ret;
 987	}
 988
 989	clk = devm_clk_get(dsi->dev, "lcdif");
 990	if (IS_ERR(clk)) {
 991		ret = PTR_ERR(clk);
 992		DRM_DEV_ERROR(dsi->dev, "Failed to get lcdif clock: %d\n",
 993			      ret);
 994		return ret;
 995	}
 996	dsi->lcdif_clk = clk;
 997
 998	clk = devm_clk_get(dsi->dev, "core");
 999	if (IS_ERR(clk)) {
1000		ret = PTR_ERR(clk);
1001		DRM_DEV_ERROR(dsi->dev, "Failed to get core clock: %d\n",
1002			      ret);
1003		return ret;
1004	}
1005	dsi->core_clk = clk;
1006
1007	clk = devm_clk_get(dsi->dev, "phy_ref");
1008	if (IS_ERR(clk)) {
1009		ret = PTR_ERR(clk);
1010		DRM_DEV_ERROR(dsi->dev, "Failed to get phy_ref clock: %d\n",
1011			      ret);
1012		return ret;
1013	}
1014	dsi->phy_ref_clk = clk;
1015
1016	clk = devm_clk_get(dsi->dev, "rx_esc");
1017	if (IS_ERR(clk)) {
1018		ret = PTR_ERR(clk);
1019		DRM_DEV_ERROR(dsi->dev, "Failed to get rx_esc clock: %d\n",
1020			      ret);
1021		return ret;
1022	}
1023	dsi->rx_esc_clk = clk;
1024
1025	clk = devm_clk_get(dsi->dev, "tx_esc");
1026	if (IS_ERR(clk)) {
1027		ret = PTR_ERR(clk);
1028		DRM_DEV_ERROR(dsi->dev, "Failed to get tx_esc clock: %d\n",
1029			      ret);
1030		return ret;
1031	}
1032	dsi->tx_esc_clk = clk;
1033
1034	dsi->mux = devm_mux_control_get(dsi->dev, NULL);
1035	if (IS_ERR(dsi->mux)) {
1036		ret = PTR_ERR(dsi->mux);
1037		if (ret != -EPROBE_DEFER)
1038			DRM_DEV_ERROR(dsi->dev, "Failed to get mux: %d\n", ret);
1039		return ret;
1040	}
1041
1042	base = devm_platform_ioremap_resource(pdev, 0);
1043	if (IS_ERR(base))
1044		return PTR_ERR(base);
1045
1046	dsi->regmap =
1047		devm_regmap_init_mmio(dsi->dev, base, &nwl_dsi_regmap_config);
1048	if (IS_ERR(dsi->regmap)) {
1049		ret = PTR_ERR(dsi->regmap);
1050		DRM_DEV_ERROR(dsi->dev, "Failed to create NWL DSI regmap: %d\n",
1051			      ret);
1052		return ret;
1053	}
1054
1055	dsi->irq = platform_get_irq(pdev, 0);
1056	if (dsi->irq < 0) {
1057		DRM_DEV_ERROR(dsi->dev, "Failed to get device IRQ: %d\n",
1058			      dsi->irq);
1059		return dsi->irq;
1060	}
1061
1062	dsi->rst_pclk = devm_reset_control_get_exclusive(dsi->dev, "pclk");
1063	if (IS_ERR(dsi->rst_pclk)) {
1064		DRM_DEV_ERROR(dsi->dev, "Failed to get pclk reset: %ld\n",
1065			      PTR_ERR(dsi->rst_pclk));
1066		return PTR_ERR(dsi->rst_pclk);
1067	}
1068	dsi->rst_byte = devm_reset_control_get_exclusive(dsi->dev, "byte");
1069	if (IS_ERR(dsi->rst_byte)) {
1070		DRM_DEV_ERROR(dsi->dev, "Failed to get byte reset: %ld\n",
1071			      PTR_ERR(dsi->rst_byte));
1072		return PTR_ERR(dsi->rst_byte);
1073	}
1074	dsi->rst_esc = devm_reset_control_get_exclusive(dsi->dev, "esc");
1075	if (IS_ERR(dsi->rst_esc)) {
1076		DRM_DEV_ERROR(dsi->dev, "Failed to get esc reset: %ld\n",
1077			      PTR_ERR(dsi->rst_esc));
1078		return PTR_ERR(dsi->rst_esc);
1079	}
1080	dsi->rst_dpi = devm_reset_control_get_exclusive(dsi->dev, "dpi");
1081	if (IS_ERR(dsi->rst_dpi)) {
1082		DRM_DEV_ERROR(dsi->dev, "Failed to get dpi reset: %ld\n",
1083			      PTR_ERR(dsi->rst_dpi));
1084		return PTR_ERR(dsi->rst_dpi);
1085	}
1086	return 0;
1087}
1088
1089static int nwl_dsi_select_input(struct nwl_dsi *dsi)
1090{
1091	struct device_node *remote;
1092	u32 use_dcss = 1;
1093	int ret;
1094
1095	remote = of_graph_get_remote_node(dsi->dev->of_node, 0,
1096					  NWL_DSI_ENDPOINT_LCDIF);
1097	if (remote) {
1098		use_dcss = 0;
1099	} else {
1100		remote = of_graph_get_remote_node(dsi->dev->of_node, 0,
1101						  NWL_DSI_ENDPOINT_DCSS);
1102		if (!remote) {
1103			DRM_DEV_ERROR(dsi->dev,
1104				      "No valid input endpoint found\n");
1105			return -EINVAL;
1106		}
1107	}
1108
1109	DRM_DEV_INFO(dsi->dev, "Using %s as input source\n",
1110		     (use_dcss) ? "DCSS" : "LCDIF");
1111	ret = mux_control_try_select(dsi->mux, use_dcss);
1112	if (ret < 0)
1113		DRM_DEV_ERROR(dsi->dev, "Failed to select input: %d\n", ret);
1114
1115	of_node_put(remote);
1116	return ret;
1117}
1118
1119static int nwl_dsi_deselect_input(struct nwl_dsi *dsi)
1120{
1121	int ret;
1122
1123	ret = mux_control_deselect(dsi->mux);
1124	if (ret < 0)
1125		DRM_DEV_ERROR(dsi->dev, "Failed to deselect input: %d\n", ret);
1126
1127	return ret;
1128}
1129
1130static const struct drm_bridge_timings nwl_dsi_timings = {
1131	.input_bus_flags = DRM_BUS_FLAG_DE_LOW,
1132};
1133
1134static const struct of_device_id nwl_dsi_dt_ids[] = {
1135	{ .compatible = "fsl,imx8mq-nwl-dsi", },
1136	{ /* sentinel */ }
1137};
1138MODULE_DEVICE_TABLE(of, nwl_dsi_dt_ids);
1139
1140static const struct soc_device_attribute nwl_dsi_quirks_match[] = {
1141	{ .soc_id = "i.MX8MQ", .revision = "2.0",
1142	  .data = (void *)E11418_HS_MODE_QUIRK },
1143	{ /* sentinel. */ }
1144};
1145
1146static int nwl_dsi_probe(struct platform_device *pdev)
1147{
1148	struct device *dev = &pdev->dev;
1149	const struct soc_device_attribute *attr;
1150	struct nwl_dsi *dsi;
1151	int ret;
1152
1153	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
1154	if (!dsi)
1155		return -ENOMEM;
1156
1157	dsi->dev = dev;
1158
1159	ret = nwl_dsi_parse_dt(dsi);
1160	if (ret)
1161		return ret;
1162
1163	ret = devm_request_irq(dev, dsi->irq, nwl_dsi_irq_handler, 0,
1164			       dev_name(dev), dsi);
1165	if (ret < 0) {
1166		DRM_DEV_ERROR(dev, "Failed to request IRQ %d: %d\n", dsi->irq,
1167			      ret);
1168		return ret;
1169	}
1170
1171	dsi->dsi_host.ops = &nwl_dsi_host_ops;
1172	dsi->dsi_host.dev = dev;
1173	ret = mipi_dsi_host_register(&dsi->dsi_host);
1174	if (ret) {
1175		DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret);
1176		return ret;
1177	}
1178
1179	attr = soc_device_match(nwl_dsi_quirks_match);
1180	if (attr)
1181		dsi->quirks = (uintptr_t)attr->data;
1182
1183	dsi->bridge.driver_private = dsi;
1184	dsi->bridge.funcs = &nwl_dsi_bridge_funcs;
1185	dsi->bridge.of_node = dev->of_node;
1186	dsi->bridge.timings = &nwl_dsi_timings;
1187
1188	dev_set_drvdata(dev, dsi);
1189	pm_runtime_enable(dev);
1190
1191	ret = nwl_dsi_select_input(dsi);
1192	if (ret < 0) {
1193		pm_runtime_disable(dev);
1194		mipi_dsi_host_unregister(&dsi->dsi_host);
1195		return ret;
1196	}
1197
1198	drm_bridge_add(&dsi->bridge);
1199	return 0;
1200}
1201
1202static void nwl_dsi_remove(struct platform_device *pdev)
1203{
1204	struct nwl_dsi *dsi = platform_get_drvdata(pdev);
1205
1206	nwl_dsi_deselect_input(dsi);
1207	mipi_dsi_host_unregister(&dsi->dsi_host);
1208	drm_bridge_remove(&dsi->bridge);
1209	pm_runtime_disable(&pdev->dev);
1210}
1211
1212static struct platform_driver nwl_dsi_driver = {
1213	.probe		= nwl_dsi_probe,
1214	.remove_new	= nwl_dsi_remove,
1215	.driver		= {
1216		.of_match_table = nwl_dsi_dt_ids,
1217		.name	= DRV_NAME,
1218	},
1219};
1220
1221module_platform_driver(nwl_dsi_driver);
1222
1223MODULE_AUTHOR("NXP Semiconductor");
1224MODULE_AUTHOR("Purism SPC");
1225MODULE_DESCRIPTION("Northwest Logic MIPI-DSI driver");
1226MODULE_LICENSE("GPL"); /* GPLv2 or later */