Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Cadence MHDP8546 DP bridge driver.
   4 *
   5 * Copyright (C) 2020 Cadence Design Systems, Inc.
   6 *
   7 * Authors: Quentin Schulz <quentin.schulz@free-electrons.com>
   8 *          Swapnil Jakhade <sjakhade@cadence.com>
   9 *          Yuti Amonkar <yamonkar@cadence.com>
  10 *          Tomi Valkeinen <tomi.valkeinen@ti.com>
  11 *          Jyri Sarha <jsarha@ti.com>
  12 *
  13 * TODO:
  14 *     - Implement optimized mailbox communication using mailbox interrupts
  15 *     - Add support for power management
  16 *     - Add support for features like audio, MST and fast link training
  17 *     - Implement request_fw_cancel to handle HW_STATE
  18 *     - Fix asynchronous loading of firmware implementation
  19 *     - Add DRM helper function for cdns_mhdp_lower_link_rate
  20 */
  21
  22#include <linux/clk.h>
  23#include <linux/delay.h>
  24#include <linux/err.h>
  25#include <linux/firmware.h>
  26#include <linux/io.h>
  27#include <linux/iopoll.h>
  28#include <linux/irq.h>
  29#include <linux/media-bus-format.h>
  30#include <linux/module.h>
  31#include <linux/of.h>
  32#include <linux/phy/phy.h>
  33#include <linux/phy/phy-dp.h>
  34#include <linux/platform_device.h>
  35#include <linux/slab.h>
  36#include <linux/wait.h>
  37
  38#include <drm/display/drm_dp_helper.h>
  39#include <drm/display/drm_hdcp_helper.h>
  40#include <drm/drm_atomic.h>
  41#include <drm/drm_atomic_helper.h>
  42#include <drm/drm_atomic_state_helper.h>
  43#include <drm/drm_bridge.h>
  44#include <drm/drm_connector.h>
  45#include <drm/drm_edid.h>
  46#include <drm/drm_modeset_helper_vtables.h>
  47#include <drm/drm_print.h>
  48#include <drm/drm_probe_helper.h>
  49
  50#include <asm/unaligned.h>
  51
  52#include "cdns-mhdp8546-core.h"
  53#include "cdns-mhdp8546-hdcp.h"
  54#include "cdns-mhdp8546-j721e.h"
  55
  56static void cdns_mhdp_bridge_hpd_enable(struct drm_bridge *bridge)
  57{
  58	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
  59
  60	/* Enable SW event interrupts */
  61	if (mhdp->bridge_attached)
  62		writel(readl(mhdp->regs + CDNS_APB_INT_MASK) &
  63		       ~CDNS_APB_INT_MASK_SW_EVENT_INT,
  64		       mhdp->regs + CDNS_APB_INT_MASK);
  65}
  66
  67static void cdns_mhdp_bridge_hpd_disable(struct drm_bridge *bridge)
  68{
  69	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
  70
  71	writel(readl(mhdp->regs + CDNS_APB_INT_MASK) |
  72	       CDNS_APB_INT_MASK_SW_EVENT_INT,
  73	       mhdp->regs + CDNS_APB_INT_MASK);
  74}
  75
  76static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
  77{
  78	int ret, empty;
  79
  80	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
  81
  82	ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_EMPTY,
  83				 empty, !empty, MAILBOX_RETRY_US,
  84				 MAILBOX_TIMEOUT_US);
  85	if (ret < 0)
  86		return ret;
  87
  88	return readl(mhdp->regs + CDNS_MAILBOX_RX_DATA) & 0xff;
  89}
  90
  91static int cdns_mhdp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val)
  92{
  93	int ret, full;
  94
  95	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
  96
  97	ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_FULL,
  98				 full, !full, MAILBOX_RETRY_US,
  99				 MAILBOX_TIMEOUT_US);
 100	if (ret < 0)
 101		return ret;
 102
 103	writel(val, mhdp->regs + CDNS_MAILBOX_TX_DATA);
 104
 105	return 0;
 106}
 107
 108static int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_device *mhdp,
 109					 u8 module_id, u8 opcode,
 110					 u16 req_size)
 111{
 112	u32 mbox_size, i;
 113	u8 header[4];
 114	int ret;
 115
 116	/* read the header of the message */
 117	for (i = 0; i < sizeof(header); i++) {
 118		ret = cdns_mhdp_mailbox_read(mhdp);
 119		if (ret < 0)
 120			return ret;
 121
 122		header[i] = ret;
 123	}
 124
 125	mbox_size = get_unaligned_be16(header + 2);
 126
 127	if (opcode != header[0] || module_id != header[1] ||
 128	    req_size != mbox_size) {
 129		/*
 130		 * If the message in mailbox is not what we want, we need to
 131		 * clear the mailbox by reading its contents.
 132		 */
 133		for (i = 0; i < mbox_size; i++)
 134			if (cdns_mhdp_mailbox_read(mhdp) < 0)
 135				break;
 136
 137		return -EINVAL;
 138	}
 139
 140	return 0;
 141}
 142
 143static int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_device *mhdp,
 144				       u8 *buff, u16 buff_size)
 145{
 146	u32 i;
 147	int ret;
 148
 149	for (i = 0; i < buff_size; i++) {
 150		ret = cdns_mhdp_mailbox_read(mhdp);
 151		if (ret < 0)
 152			return ret;
 153
 154		buff[i] = ret;
 155	}
 156
 157	return 0;
 158}
 159
 160static int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id,
 161				  u8 opcode, u16 size, u8 *message)
 162{
 163	u8 header[4];
 164	int ret, i;
 165
 166	header[0] = opcode;
 167	header[1] = module_id;
 168	put_unaligned_be16(size, header + 2);
 169
 170	for (i = 0; i < sizeof(header); i++) {
 171		ret = cdns_mhdp_mailbox_write(mhdp, header[i]);
 172		if (ret)
 173			return ret;
 174	}
 175
 176	for (i = 0; i < size; i++) {
 177		ret = cdns_mhdp_mailbox_write(mhdp, message[i]);
 178		if (ret)
 179			return ret;
 180	}
 181
 182	return 0;
 183}
 184
 185static
 186int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr, u32 *value)
 187{
 188	u8 msg[4], resp[8];
 189	int ret;
 190
 191	put_unaligned_be32(addr, msg);
 192
 193	mutex_lock(&mhdp->mbox_mutex);
 194
 195	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL,
 196				     GENERAL_REGISTER_READ,
 197				     sizeof(msg), msg);
 198	if (ret)
 199		goto out;
 200
 201	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_GENERAL,
 202					    GENERAL_REGISTER_READ,
 203					    sizeof(resp));
 204	if (ret)
 205		goto out;
 206
 207	ret = cdns_mhdp_mailbox_recv_data(mhdp, resp, sizeof(resp));
 208	if (ret)
 209		goto out;
 210
 211	/* Returned address value should be the same as requested */
 212	if (memcmp(msg, resp, sizeof(msg))) {
 213		ret = -EINVAL;
 214		goto out;
 215	}
 216
 217	*value = get_unaligned_be32(resp + 4);
 218
 219out:
 220	mutex_unlock(&mhdp->mbox_mutex);
 221	if (ret) {
 222		dev_err(mhdp->dev, "Failed to read register\n");
 223		*value = 0;
 224	}
 225
 226	return ret;
 227}
 228
 229static
 230int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u16 addr, u32 val)
 231{
 232	u8 msg[6];
 233	int ret;
 234
 235	put_unaligned_be16(addr, msg);
 236	put_unaligned_be32(val, msg + 2);
 237
 238	mutex_lock(&mhdp->mbox_mutex);
 239
 240	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
 241				     DPTX_WRITE_REGISTER, sizeof(msg), msg);
 242
 243	mutex_unlock(&mhdp->mbox_mutex);
 244
 245	return ret;
 246}
 247
 248static
 249int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr,
 250			    u8 start_bit, u8 bits_no, u32 val)
 251{
 252	u8 field[8];
 253	int ret;
 254
 255	put_unaligned_be16(addr, field);
 256	field[2] = start_bit;
 257	field[3] = bits_no;
 258	put_unaligned_be32(val, field + 4);
 259
 260	mutex_lock(&mhdp->mbox_mutex);
 261
 262	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
 263				     DPTX_WRITE_FIELD, sizeof(field), field);
 264
 265	mutex_unlock(&mhdp->mbox_mutex);
 266
 267	return ret;
 268}
 269
 270static
 271int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp,
 272			u32 addr, u8 *data, u16 len)
 273{
 274	u8 msg[5], reg[5];
 275	int ret;
 276
 277	put_unaligned_be16(len, msg);
 278	put_unaligned_be24(addr, msg + 2);
 279
 280	mutex_lock(&mhdp->mbox_mutex);
 281
 282	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
 283				     DPTX_READ_DPCD, sizeof(msg), msg);
 284	if (ret)
 285		goto out;
 286
 287	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
 288					    DPTX_READ_DPCD,
 289					    sizeof(reg) + len);
 290	if (ret)
 291		goto out;
 292
 293	ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
 294	if (ret)
 295		goto out;
 296
 297	ret = cdns_mhdp_mailbox_recv_data(mhdp, data, len);
 298
 299out:
 300	mutex_unlock(&mhdp->mbox_mutex);
 301
 302	return ret;
 303}
 304
 305static
 306int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value)
 307{
 308	u8 msg[6], reg[5];
 309	int ret;
 310
 311	put_unaligned_be16(1, msg);
 312	put_unaligned_be24(addr, msg + 2);
 313	msg[5] = value;
 314
 315	mutex_lock(&mhdp->mbox_mutex);
 316
 317	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
 318				     DPTX_WRITE_DPCD, sizeof(msg), msg);
 319	if (ret)
 320		goto out;
 321
 322	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
 323					    DPTX_WRITE_DPCD, sizeof(reg));
 324	if (ret)
 325		goto out;
 326
 327	ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
 328	if (ret)
 329		goto out;
 330
 331	if (addr != get_unaligned_be24(reg + 2))
 332		ret = -EINVAL;
 333
 334out:
 335	mutex_unlock(&mhdp->mbox_mutex);
 336
 337	if (ret)
 338		dev_err(mhdp->dev, "dpcd write failed: %d\n", ret);
 339	return ret;
 340}
 341
 342static
 343int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable)
 344{
 345	u8 msg[5];
 346	int ret, i;
 347
 348	msg[0] = GENERAL_MAIN_CONTROL;
 349	msg[1] = MB_MODULE_ID_GENERAL;
 350	msg[2] = 0;
 351	msg[3] = 1;
 352	msg[4] = enable ? FW_ACTIVE : FW_STANDBY;
 353
 354	mutex_lock(&mhdp->mbox_mutex);
 355
 356	for (i = 0; i < sizeof(msg); i++) {
 357		ret = cdns_mhdp_mailbox_write(mhdp, msg[i]);
 358		if (ret)
 359			goto out;
 360	}
 361
 362	/* read the firmware state */
 363	ret = cdns_mhdp_mailbox_recv_data(mhdp, msg, sizeof(msg));
 364	if (ret)
 365		goto out;
 366
 367	ret = 0;
 368
 369out:
 370	mutex_unlock(&mhdp->mbox_mutex);
 371
 372	if (ret < 0)
 373		dev_err(mhdp->dev, "set firmware active failed\n");
 374	return ret;
 375}
 376
 377static
 378int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp)
 379{
 380	u8 status;
 381	int ret;
 382
 383	mutex_lock(&mhdp->mbox_mutex);
 384
 385	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
 386				     DPTX_HPD_STATE, 0, NULL);
 387	if (ret)
 388		goto err_get_hpd;
 389
 390	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
 391					    DPTX_HPD_STATE,
 392					    sizeof(status));
 393	if (ret)
 394		goto err_get_hpd;
 395
 396	ret = cdns_mhdp_mailbox_recv_data(mhdp, &status, sizeof(status));
 397	if (ret)
 398		goto err_get_hpd;
 399
 400	mutex_unlock(&mhdp->mbox_mutex);
 401
 402	dev_dbg(mhdp->dev, "%s: HPD %splugged\n", __func__,
 403		status ? "" : "un");
 404
 405	return status;
 406
 407err_get_hpd:
 408	mutex_unlock(&mhdp->mbox_mutex);
 409
 410	return ret;
 411}
 412
 413static
 414int cdns_mhdp_get_edid_block(void *data, u8 *edid,
 415			     unsigned int block, size_t length)
 416{
 417	struct cdns_mhdp_device *mhdp = data;
 418	u8 msg[2], reg[2], i;
 419	int ret;
 420
 421	mutex_lock(&mhdp->mbox_mutex);
 422
 423	for (i = 0; i < 4; i++) {
 424		msg[0] = block / 2;
 425		msg[1] = block % 2;
 426
 427		ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
 428					     DPTX_GET_EDID, sizeof(msg), msg);
 429		if (ret)
 430			continue;
 431
 432		ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
 433						    DPTX_GET_EDID,
 434						    sizeof(reg) + length);
 435		if (ret)
 436			continue;
 437
 438		ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
 439		if (ret)
 440			continue;
 441
 442		ret = cdns_mhdp_mailbox_recv_data(mhdp, edid, length);
 443		if (ret)
 444			continue;
 445
 446		if (reg[0] == length && reg[1] == block / 2)
 447			break;
 448	}
 449
 450	mutex_unlock(&mhdp->mbox_mutex);
 451
 452	if (ret)
 453		dev_err(mhdp->dev, "get block[%d] edid failed: %d\n",
 454			block, ret);
 455
 456	return ret;
 457}
 458
 459static
 460int cdns_mhdp_read_hpd_event(struct cdns_mhdp_device *mhdp)
 461{
 462	u8 event = 0;
 463	int ret;
 464
 465	mutex_lock(&mhdp->mbox_mutex);
 466
 467	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
 468				     DPTX_READ_EVENT, 0, NULL);
 469	if (ret)
 470		goto out;
 471
 472	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
 473					    DPTX_READ_EVENT, sizeof(event));
 474	if (ret < 0)
 475		goto out;
 476
 477	ret = cdns_mhdp_mailbox_recv_data(mhdp, &event, sizeof(event));
 478out:
 479	mutex_unlock(&mhdp->mbox_mutex);
 480
 481	if (ret < 0)
 482		return ret;
 483
 484	dev_dbg(mhdp->dev, "%s: %s%s%s%s\n", __func__,
 485		(event & DPTX_READ_EVENT_HPD_TO_HIGH) ? "TO_HIGH " : "",
 486		(event & DPTX_READ_EVENT_HPD_TO_LOW) ? "TO_LOW " : "",
 487		(event & DPTX_READ_EVENT_HPD_PULSE) ? "PULSE " : "",
 488		(event & DPTX_READ_EVENT_HPD_STATE) ? "HPD_STATE " : "");
 489
 490	return event;
 491}
 492
 493static
 494int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, unsigned int nlanes,
 495			unsigned int udelay, const u8 *lanes_data,
 496			u8 link_status[DP_LINK_STATUS_SIZE])
 497{
 498	u8 payload[7];
 499	u8 hdr[5]; /* For DPCD read response header */
 500	u32 addr;
 501	int ret;
 502
 503	if (nlanes != 4 && nlanes != 2 && nlanes != 1) {
 504		dev_err(mhdp->dev, "invalid number of lanes: %u\n", nlanes);
 505		ret = -EINVAL;
 506		goto out;
 507	}
 508
 509	payload[0] = nlanes;
 510	put_unaligned_be16(udelay, payload + 1);
 511	memcpy(payload + 3, lanes_data, nlanes);
 512
 513	mutex_lock(&mhdp->mbox_mutex);
 514
 515	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
 516				     DPTX_ADJUST_LT,
 517				     sizeof(payload), payload);
 518	if (ret)
 519		goto out;
 520
 521	/* Yes, read the DPCD read command response */
 522	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
 523					    DPTX_READ_DPCD,
 524					    sizeof(hdr) + DP_LINK_STATUS_SIZE);
 525	if (ret)
 526		goto out;
 527
 528	ret = cdns_mhdp_mailbox_recv_data(mhdp, hdr, sizeof(hdr));
 529	if (ret)
 530		goto out;
 531
 532	addr = get_unaligned_be24(hdr + 2);
 533	if (addr != DP_LANE0_1_STATUS)
 534		goto out;
 535
 536	ret = cdns_mhdp_mailbox_recv_data(mhdp, link_status,
 537					  DP_LINK_STATUS_SIZE);
 538
 539out:
 540	mutex_unlock(&mhdp->mbox_mutex);
 541
 542	if (ret)
 543		dev_err(mhdp->dev, "Failed to adjust Link Training.\n");
 544
 545	return ret;
 546}
 547
 548/**
 549 * cdns_mhdp_link_power_up() - power up a DisplayPort link
 550 * @aux: DisplayPort AUX channel
 551 * @link: pointer to a structure containing the link configuration
 552 *
 553 * Returns 0 on success or a negative error code on failure.
 554 */
 555static
 556int cdns_mhdp_link_power_up(struct drm_dp_aux *aux, struct cdns_mhdp_link *link)
 557{
 558	u8 value;
 559	int err;
 560
 561	/* DP_SET_POWER register is only available on DPCD v1.1 and later */
 562	if (link->revision < 0x11)
 563		return 0;
 564
 565	err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
 566	if (err < 0)
 567		return err;
 568
 569	value &= ~DP_SET_POWER_MASK;
 570	value |= DP_SET_POWER_D0;
 571
 572	err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
 573	if (err < 0)
 574		return err;
 575
 576	/*
 577	 * According to the DP 1.1 specification, a "Sink Device must exit the
 578	 * power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink
 579	 * Control Field" (register 0x600).
 580	 */
 581	usleep_range(1000, 2000);
 582
 583	return 0;
 584}
 585
 586/**
 587 * cdns_mhdp_link_power_down() - power down a DisplayPort link
 588 * @aux: DisplayPort AUX channel
 589 * @link: pointer to a structure containing the link configuration
 590 *
 591 * Returns 0 on success or a negative error code on failure.
 592 */
 593static
 594int cdns_mhdp_link_power_down(struct drm_dp_aux *aux,
 595			      struct cdns_mhdp_link *link)
 596{
 597	u8 value;
 598	int err;
 599
 600	/* DP_SET_POWER register is only available on DPCD v1.1 and later */
 601	if (link->revision < 0x11)
 602		return 0;
 603
 604	err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
 605	if (err < 0)
 606		return err;
 607
 608	value &= ~DP_SET_POWER_MASK;
 609	value |= DP_SET_POWER_D3;
 610
 611	err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
 612	if (err < 0)
 613		return err;
 614
 615	return 0;
 616}
 617
 618/**
 619 * cdns_mhdp_link_configure() - configure a DisplayPort link
 620 * @aux: DisplayPort AUX channel
 621 * @link: pointer to a structure containing the link configuration
 622 *
 623 * Returns 0 on success or a negative error code on failure.
 624 */
 625static
 626int cdns_mhdp_link_configure(struct drm_dp_aux *aux,
 627			     struct cdns_mhdp_link *link)
 628{
 629	u8 values[2];
 630	int err;
 631
 632	values[0] = drm_dp_link_rate_to_bw_code(link->rate);
 633	values[1] = link->num_lanes;
 634
 635	if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
 636		values[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
 637
 638	err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, values, sizeof(values));
 639	if (err < 0)
 640		return err;
 641
 642	return 0;
 643}
 644
 645static unsigned int cdns_mhdp_max_link_rate(struct cdns_mhdp_device *mhdp)
 646{
 647	return min(mhdp->host.link_rate, mhdp->sink.link_rate);
 648}
 649
 650static u8 cdns_mhdp_max_num_lanes(struct cdns_mhdp_device *mhdp)
 651{
 652	return min(mhdp->sink.lanes_cnt, mhdp->host.lanes_cnt);
 653}
 654
 655static u8 cdns_mhdp_eq_training_pattern_supported(struct cdns_mhdp_device *mhdp)
 656{
 657	return fls(mhdp->host.pattern_supp & mhdp->sink.pattern_supp);
 658}
 659
 660static bool cdns_mhdp_get_ssc_supported(struct cdns_mhdp_device *mhdp)
 661{
 662	/* Check if SSC is supported by both sides */
 663	return mhdp->host.ssc && mhdp->sink.ssc;
 664}
 665
 666static enum drm_connector_status cdns_mhdp_detect(struct cdns_mhdp_device *mhdp)
 667{
 668	dev_dbg(mhdp->dev, "%s: %d\n", __func__, mhdp->plugged);
 669
 670	if (mhdp->plugged)
 671		return connector_status_connected;
 672	else
 673		return connector_status_disconnected;
 674}
 675
 676static int cdns_mhdp_check_fw_version(struct cdns_mhdp_device *mhdp)
 677{
 678	u32 major_num, minor_num, revision;
 679	u32 fw_ver, lib_ver;
 680
 681	fw_ver = (readl(mhdp->regs + CDNS_VER_H) << 8)
 682	       | readl(mhdp->regs + CDNS_VER_L);
 683
 684	lib_ver = (readl(mhdp->regs + CDNS_LIB_H_ADDR) << 8)
 685		| readl(mhdp->regs + CDNS_LIB_L_ADDR);
 686
 687	if (lib_ver < 33984) {
 688		/*
 689		 * Older FW versions with major number 1, used to store FW
 690		 * version information by storing repository revision number
 691		 * in registers. This is for identifying these FW versions.
 692		 */
 693		major_num = 1;
 694		minor_num = 2;
 695		if (fw_ver == 26098) {
 696			revision = 15;
 697		} else if (lib_ver == 0 && fw_ver == 0) {
 698			revision = 17;
 699		} else {
 700			dev_err(mhdp->dev, "Unsupported FW version: fw_ver = %u, lib_ver = %u\n",
 701				fw_ver, lib_ver);
 702			return -ENODEV;
 703		}
 704	} else {
 705		/* To identify newer FW versions with major number 2 onwards. */
 706		major_num = fw_ver / 10000;
 707		minor_num = (fw_ver / 100) % 100;
 708		revision = (fw_ver % 10000) % 100;
 709	}
 710
 711	dev_dbg(mhdp->dev, "FW version: v%u.%u.%u\n", major_num, minor_num,
 712		revision);
 713	return 0;
 714}
 715
 716static int cdns_mhdp_fw_activate(const struct firmware *fw,
 717				 struct cdns_mhdp_device *mhdp)
 718{
 719	unsigned int reg;
 720	int ret;
 721
 722	/* Release uCPU reset and stall it. */
 723	writel(CDNS_CPU_STALL, mhdp->regs + CDNS_APB_CTRL);
 724
 725	memcpy_toio(mhdp->regs + CDNS_MHDP_IMEM, fw->data, fw->size);
 726
 727	/* Leave debug mode, release stall */
 728	writel(0, mhdp->regs + CDNS_APB_CTRL);
 729
 730	/*
 731	 * Wait for the KEEP_ALIVE "message" on the first 8 bits.
 732	 * Updated each sched "tick" (~2ms)
 733	 */
 734	ret = readl_poll_timeout(mhdp->regs + CDNS_KEEP_ALIVE, reg,
 735				 reg & CDNS_KEEP_ALIVE_MASK, 500,
 736				 CDNS_KEEP_ALIVE_TIMEOUT);
 737	if (ret) {
 738		dev_err(mhdp->dev,
 739			"device didn't give any life sign: reg %d\n", reg);
 740		return ret;
 741	}
 742
 743	ret = cdns_mhdp_check_fw_version(mhdp);
 744	if (ret)
 745		return ret;
 746
 747	/* Init events to 0 as it's not cleared by FW at boot but on read */
 748	readl(mhdp->regs + CDNS_SW_EVENT0);
 749	readl(mhdp->regs + CDNS_SW_EVENT1);
 750	readl(mhdp->regs + CDNS_SW_EVENT2);
 751	readl(mhdp->regs + CDNS_SW_EVENT3);
 752
 753	/* Activate uCPU */
 754	ret = cdns_mhdp_set_firmware_active(mhdp, true);
 755	if (ret)
 756		return ret;
 757
 758	spin_lock(&mhdp->start_lock);
 759
 760	mhdp->hw_state = MHDP_HW_READY;
 761
 762	/*
 763	 * Here we must keep the lock while enabling the interrupts
 764	 * since it would otherwise be possible that interrupt enable
 765	 * code is executed after the bridge is detached. The similar
 766	 * situation is not possible in attach()/detach() callbacks
 767	 * since the hw_state changes from MHDP_HW_READY to
 768	 * MHDP_HW_STOPPED happens only due to driver removal when
 769	 * bridge should already be detached.
 770	 */
 771	cdns_mhdp_bridge_hpd_enable(&mhdp->bridge);
 772
 773	spin_unlock(&mhdp->start_lock);
 774
 775	wake_up(&mhdp->fw_load_wq);
 776	dev_dbg(mhdp->dev, "DP FW activated\n");
 777
 778	return 0;
 779}
 780
 781static void cdns_mhdp_fw_cb(const struct firmware *fw, void *context)
 782{
 783	struct cdns_mhdp_device *mhdp = context;
 784	bool bridge_attached;
 785	int ret;
 786
 787	dev_dbg(mhdp->dev, "firmware callback\n");
 788
 789	if (!fw || !fw->data) {
 790		dev_err(mhdp->dev, "%s: No firmware.\n", __func__);
 791		return;
 792	}
 793
 794	ret = cdns_mhdp_fw_activate(fw, mhdp);
 795
 796	release_firmware(fw);
 797
 798	if (ret)
 799		return;
 800
 801	/*
 802	 *  XXX how to make sure the bridge is still attached when
 803	 *      calling drm_kms_helper_hotplug_event() after releasing
 804	 *      the lock? We should not hold the spin lock when
 805	 *      calling drm_kms_helper_hotplug_event() since it may
 806	 *      cause a dead lock. FB-dev console calls detect from the
 807	 *      same thread just down the call stack started here.
 808	 */
 809	spin_lock(&mhdp->start_lock);
 810	bridge_attached = mhdp->bridge_attached;
 811	spin_unlock(&mhdp->start_lock);
 812	if (bridge_attached) {
 813		if (mhdp->connector.dev)
 814			drm_kms_helper_hotplug_event(mhdp->bridge.dev);
 815		else
 816			drm_bridge_hpd_notify(&mhdp->bridge, cdns_mhdp_detect(mhdp));
 817	}
 818}
 819
 820static int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp)
 821{
 822	int ret;
 823
 824	ret = request_firmware_nowait(THIS_MODULE, true, FW_NAME, mhdp->dev,
 825				      GFP_KERNEL, mhdp, cdns_mhdp_fw_cb);
 826	if (ret) {
 827		dev_err(mhdp->dev, "failed to load firmware (%s), ret: %d\n",
 828			FW_NAME, ret);
 829		return ret;
 830	}
 831
 832	return 0;
 833}
 834
 835static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux,
 836				  struct drm_dp_aux_msg *msg)
 837{
 838	struct cdns_mhdp_device *mhdp = dev_get_drvdata(aux->dev);
 839	int ret;
 840
 841	if (msg->request != DP_AUX_NATIVE_WRITE &&
 842	    msg->request != DP_AUX_NATIVE_READ)
 843		return -EOPNOTSUPP;
 844
 845	if (msg->request == DP_AUX_NATIVE_WRITE) {
 846		const u8 *buf = msg->buffer;
 847		unsigned int i;
 848
 849		for (i = 0; i < msg->size; ++i) {
 850			ret = cdns_mhdp_dpcd_write(mhdp,
 851						   msg->address + i, buf[i]);
 852			if (!ret)
 853				continue;
 854
 855			dev_err(mhdp->dev,
 856				"Failed to write DPCD addr %u\n",
 857				msg->address + i);
 858
 859			return ret;
 860		}
 861	} else {
 862		ret = cdns_mhdp_dpcd_read(mhdp, msg->address,
 863					  msg->buffer, msg->size);
 864		if (ret) {
 865			dev_err(mhdp->dev,
 866				"Failed to read DPCD addr %u\n",
 867				msg->address);
 868
 869			return ret;
 870		}
 871	}
 872
 873	return msg->size;
 874}
 875
 876static int cdns_mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 877{
 878	union phy_configure_opts phy_cfg;
 879	u32 reg32;
 880	int ret;
 881
 882	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 883			   DP_TRAINING_PATTERN_DISABLE);
 884
 885	/* Reset PHY configuration */
 886	reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
 887	if (!mhdp->host.scrambler)
 888		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
 889
 890	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
 891
 892	cdns_mhdp_reg_write(mhdp, CDNS_DP_ENHNCD,
 893			    mhdp->sink.enhanced & mhdp->host.enhanced);
 894
 895	cdns_mhdp_reg_write(mhdp, CDNS_DP_LANE_EN,
 896			    CDNS_DP_LANE_EN_LANES(mhdp->link.num_lanes));
 897
 898	cdns_mhdp_link_configure(&mhdp->aux, &mhdp->link);
 899	phy_cfg.dp.link_rate = mhdp->link.rate / 100;
 900	phy_cfg.dp.lanes = mhdp->link.num_lanes;
 901
 902	memset(phy_cfg.dp.voltage, 0, sizeof(phy_cfg.dp.voltage));
 903	memset(phy_cfg.dp.pre, 0, sizeof(phy_cfg.dp.pre));
 904
 905	phy_cfg.dp.ssc = cdns_mhdp_get_ssc_supported(mhdp);
 906	phy_cfg.dp.set_lanes = true;
 907	phy_cfg.dp.set_rate = true;
 908	phy_cfg.dp.set_voltages = true;
 909	ret = phy_configure(mhdp->phy,  &phy_cfg);
 910	if (ret) {
 911		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
 912			__func__, ret);
 913		return ret;
 914	}
 915
 916	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG,
 917			    CDNS_PHY_COMMON_CONFIG |
 918			    CDNS_PHY_TRAINING_EN |
 919			    CDNS_PHY_TRAINING_TYPE(1) |
 920			    CDNS_PHY_SCRAMBLER_BYPASS);
 921
 922	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 923			   DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE);
 924
 925	return 0;
 926}
 927
 928static void cdns_mhdp_get_adjust_train(struct cdns_mhdp_device *mhdp,
 929				       u8 link_status[DP_LINK_STATUS_SIZE],
 930				       u8 lanes_data[CDNS_DP_MAX_NUM_LANES],
 931				       union phy_configure_opts *phy_cfg)
 932{
 933	u8 adjust, max_pre_emph, max_volt_swing;
 934	u8 set_volt, set_pre;
 935	unsigned int i;
 936
 937	max_pre_emph = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis)
 938			   << DP_TRAIN_PRE_EMPHASIS_SHIFT;
 939	max_volt_swing = CDNS_VOLT_SWING(mhdp->host.volt_swing);
 940
 941	for (i = 0; i < mhdp->link.num_lanes; i++) {
 942		/* Check if Voltage swing and pre-emphasis are within limits */
 943		adjust = drm_dp_get_adjust_request_voltage(link_status, i);
 944		set_volt = min(adjust, max_volt_swing);
 945
 946		adjust = drm_dp_get_adjust_request_pre_emphasis(link_status, i);
 947		set_pre = min(adjust, max_pre_emph)
 948			  >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
 949
 950		/*
 951		 * Voltage swing level and pre-emphasis level combination is
 952		 * not allowed: leaving pre-emphasis as-is, and adjusting
 953		 * voltage swing.
 954		 */
 955		if (set_volt + set_pre > 3)
 956			set_volt = 3 - set_pre;
 957
 958		phy_cfg->dp.voltage[i] = set_volt;
 959		lanes_data[i] = set_volt;
 960
 961		if (set_volt == max_volt_swing)
 962			lanes_data[i] |= DP_TRAIN_MAX_SWING_REACHED;
 963
 964		phy_cfg->dp.pre[i] = set_pre;
 965		lanes_data[i] |= (set_pre << DP_TRAIN_PRE_EMPHASIS_SHIFT);
 966
 967		if (set_pre == (max_pre_emph >> DP_TRAIN_PRE_EMPHASIS_SHIFT))
 968			lanes_data[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 969	}
 970}
 971
 972static
 973void cdns_mhdp_set_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE],
 974					  unsigned int lane, u8 volt)
 975{
 976	unsigned int s = ((lane & 1) ?
 977			  DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
 978			  DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
 979	unsigned int idx = DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS + (lane >> 1);
 980
 981	link_status[idx] &= ~(DP_ADJUST_VOLTAGE_SWING_LANE0_MASK << s);
 982	link_status[idx] |= volt << s;
 983}
 984
 985static
 986void cdns_mhdp_set_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE],
 987					       unsigned int lane, u8 pre_emphasis)
 988{
 989	unsigned int s = ((lane & 1) ?
 990			  DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
 991			  DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
 992	unsigned int idx = DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS + (lane >> 1);
 993
 994	link_status[idx] &= ~(DP_ADJUST_PRE_EMPHASIS_LANE0_MASK << s);
 995	link_status[idx] |= pre_emphasis << s;
 996}
 997
 998static void cdns_mhdp_adjust_requested_eq(struct cdns_mhdp_device *mhdp,
 999					  u8 link_status[DP_LINK_STATUS_SIZE])
1000{
1001	u8 max_pre = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis);
1002	u8 max_volt = CDNS_VOLT_SWING(mhdp->host.volt_swing);
1003	unsigned int i;
1004	u8 volt, pre;
1005
1006	for (i = 0; i < mhdp->link.num_lanes; i++) {
1007		volt = drm_dp_get_adjust_request_voltage(link_status, i);
1008		pre = drm_dp_get_adjust_request_pre_emphasis(link_status, i);
1009		if (volt + pre > 3)
1010			cdns_mhdp_set_adjust_request_voltage(link_status, i,
1011							     3 - pre);
1012		if (mhdp->host.volt_swing & CDNS_FORCE_VOLT_SWING)
1013			cdns_mhdp_set_adjust_request_voltage(link_status, i,
1014							     max_volt);
1015		if (mhdp->host.pre_emphasis & CDNS_FORCE_PRE_EMPHASIS)
1016			cdns_mhdp_set_adjust_request_pre_emphasis(link_status,
1017								  i, max_pre);
1018	}
1019}
1020
1021static void cdns_mhdp_print_lt_status(const char *prefix,
1022				      struct cdns_mhdp_device *mhdp,
1023				      union phy_configure_opts *phy_cfg)
1024{
1025	char vs[8] = "0/0/0/0";
1026	char pe[8] = "0/0/0/0";
1027	unsigned int i;
1028
1029	for (i = 0; i < mhdp->link.num_lanes; i++) {
1030		vs[i * 2] = '0' + phy_cfg->dp.voltage[i];
1031		pe[i * 2] = '0' + phy_cfg->dp.pre[i];
1032	}
1033
1034	vs[i * 2 - 1] = '\0';
1035	pe[i * 2 - 1] = '\0';
1036
1037	dev_dbg(mhdp->dev, "%s, %u lanes, %u Mbps, vs %s, pe %s\n",
1038		prefix,
1039		mhdp->link.num_lanes, mhdp->link.rate / 100,
1040		vs, pe);
1041}
1042
1043static bool cdns_mhdp_link_training_channel_eq(struct cdns_mhdp_device *mhdp,
1044					       u8 eq_tps,
1045					       unsigned int training_interval)
1046{
1047	u8 lanes_data[CDNS_DP_MAX_NUM_LANES], fail_counter_short = 0;
1048	u8 link_status[DP_LINK_STATUS_SIZE];
1049	union phy_configure_opts phy_cfg;
1050	u32 reg32;
1051	int ret;
1052	bool r;
1053
1054	dev_dbg(mhdp->dev, "Starting EQ phase\n");
1055
1056	/* Enable link training TPS[eq_tps] in PHY */
1057	reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_EN |
1058		CDNS_PHY_TRAINING_TYPE(eq_tps);
1059	if (eq_tps != 4)
1060		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
1061	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
1062
1063	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
1064			   (eq_tps != 4) ? eq_tps | DP_LINK_SCRAMBLING_DISABLE :
1065			   CDNS_DP_TRAINING_PATTERN_4);
1066
1067	drm_dp_dpcd_read_link_status(&mhdp->aux, link_status);
1068
1069	do {
1070		cdns_mhdp_get_adjust_train(mhdp, link_status, lanes_data,
1071					   &phy_cfg);
1072		phy_cfg.dp.lanes = mhdp->link.num_lanes;
1073		phy_cfg.dp.ssc = cdns_mhdp_get_ssc_supported(mhdp);
1074		phy_cfg.dp.set_lanes = false;
1075		phy_cfg.dp.set_rate = false;
1076		phy_cfg.dp.set_voltages = true;
1077		ret = phy_configure(mhdp->phy,  &phy_cfg);
1078		if (ret) {
1079			dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
1080				__func__, ret);
1081			goto err;
1082		}
1083
1084		cdns_mhdp_adjust_lt(mhdp, mhdp->link.num_lanes,
1085				    training_interval, lanes_data, link_status);
1086
1087		r = drm_dp_clock_recovery_ok(link_status, mhdp->link.num_lanes);
1088		if (!r)
1089			goto err;
1090
1091		if (drm_dp_channel_eq_ok(link_status, mhdp->link.num_lanes)) {
1092			cdns_mhdp_print_lt_status("EQ phase ok", mhdp,
1093						  &phy_cfg);
1094			return true;
1095		}
1096
1097		fail_counter_short++;
1098
1099		cdns_mhdp_adjust_requested_eq(mhdp, link_status);
1100	} while (fail_counter_short < 5);
1101
1102err:
1103	cdns_mhdp_print_lt_status("EQ phase failed", mhdp, &phy_cfg);
1104
1105	return false;
1106}
1107
1108static void cdns_mhdp_adjust_requested_cr(struct cdns_mhdp_device *mhdp,
1109					  u8 link_status[DP_LINK_STATUS_SIZE],
1110					  u8 *req_volt, u8 *req_pre)
1111{
1112	const u8 max_volt = CDNS_VOLT_SWING(mhdp->host.volt_swing);
1113	const u8 max_pre = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis);
1114	unsigned int i;
1115
1116	for (i = 0; i < mhdp->link.num_lanes; i++) {
1117		u8 val;
1118
1119		val = mhdp->host.volt_swing & CDNS_FORCE_VOLT_SWING ?
1120		      max_volt : req_volt[i];
1121		cdns_mhdp_set_adjust_request_voltage(link_status, i, val);
1122
1123		val = mhdp->host.pre_emphasis & CDNS_FORCE_PRE_EMPHASIS ?
1124		      max_pre : req_pre[i];
1125		cdns_mhdp_set_adjust_request_pre_emphasis(link_status, i, val);
1126	}
1127}
1128
1129static
1130void cdns_mhdp_validate_cr(struct cdns_mhdp_device *mhdp, bool *cr_done,
1131			   bool *same_before_adjust, bool *max_swing_reached,
1132			   u8 before_cr[CDNS_DP_MAX_NUM_LANES],
1133			   u8 after_cr[DP_LINK_STATUS_SIZE], u8 *req_volt,
1134			   u8 *req_pre)
1135{
1136	const u8 max_volt = CDNS_VOLT_SWING(mhdp->host.volt_swing);
1137	const u8 max_pre = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis);
1138	bool same_pre, same_volt;
1139	unsigned int i;
1140	u8 adjust;
1141
1142	*same_before_adjust = false;
1143	*max_swing_reached = false;
1144	*cr_done = drm_dp_clock_recovery_ok(after_cr, mhdp->link.num_lanes);
1145
1146	for (i = 0; i < mhdp->link.num_lanes; i++) {
1147		adjust = drm_dp_get_adjust_request_voltage(after_cr, i);
1148		req_volt[i] = min(adjust, max_volt);
1149
1150		adjust = drm_dp_get_adjust_request_pre_emphasis(after_cr, i) >>
1151		      DP_TRAIN_PRE_EMPHASIS_SHIFT;
1152		req_pre[i] = min(adjust, max_pre);
1153
1154		same_pre = (before_cr[i] & DP_TRAIN_PRE_EMPHASIS_MASK) ==
1155			   req_pre[i] << DP_TRAIN_PRE_EMPHASIS_SHIFT;
1156		same_volt = (before_cr[i] & DP_TRAIN_VOLTAGE_SWING_MASK) ==
1157			    req_volt[i];
1158		if (same_pre && same_volt)
1159			*same_before_adjust = true;
1160
1161		/* 3.1.5.2 in DP Standard v1.4. Table 3-1 */
1162		if (!*cr_done && req_volt[i] + req_pre[i] >= 3) {
1163			*max_swing_reached = true;
1164			return;
1165		}
1166	}
1167}
1168
1169static bool cdns_mhdp_link_training_cr(struct cdns_mhdp_device *mhdp)
1170{
1171	u8 lanes_data[CDNS_DP_MAX_NUM_LANES],
1172	fail_counter_short = 0, fail_counter_cr_long = 0;
1173	u8 link_status[DP_LINK_STATUS_SIZE];
1174	bool cr_done;
1175	union phy_configure_opts phy_cfg;
1176	int ret;
1177
1178	dev_dbg(mhdp->dev, "Starting CR phase\n");
1179
1180	ret = cdns_mhdp_link_training_init(mhdp);
1181	if (ret)
1182		goto err;
1183
1184	drm_dp_dpcd_read_link_status(&mhdp->aux, link_status);
1185
1186	do {
1187		u8 requested_adjust_volt_swing[CDNS_DP_MAX_NUM_LANES] = {};
1188		u8 requested_adjust_pre_emphasis[CDNS_DP_MAX_NUM_LANES] = {};
1189		bool same_before_adjust, max_swing_reached;
1190
1191		cdns_mhdp_get_adjust_train(mhdp, link_status, lanes_data,
1192					   &phy_cfg);
1193		phy_cfg.dp.lanes = mhdp->link.num_lanes;
1194		phy_cfg.dp.ssc = cdns_mhdp_get_ssc_supported(mhdp);
1195		phy_cfg.dp.set_lanes = false;
1196		phy_cfg.dp.set_rate = false;
1197		phy_cfg.dp.set_voltages = true;
1198		ret = phy_configure(mhdp->phy,  &phy_cfg);
1199		if (ret) {
1200			dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
1201				__func__, ret);
1202			goto err;
1203		}
1204
1205		cdns_mhdp_adjust_lt(mhdp, mhdp->link.num_lanes, 100,
1206				    lanes_data, link_status);
1207
1208		cdns_mhdp_validate_cr(mhdp, &cr_done, &same_before_adjust,
1209				      &max_swing_reached, lanes_data,
1210				      link_status,
1211				      requested_adjust_volt_swing,
1212				      requested_adjust_pre_emphasis);
1213
1214		if (max_swing_reached) {
1215			dev_err(mhdp->dev, "CR: max swing reached\n");
1216			goto err;
1217		}
1218
1219		if (cr_done) {
1220			cdns_mhdp_print_lt_status("CR phase ok", mhdp,
1221						  &phy_cfg);
1222			return true;
1223		}
1224
1225		/* Not all CR_DONE bits set */
1226		fail_counter_cr_long++;
1227
1228		if (same_before_adjust) {
1229			fail_counter_short++;
1230			continue;
1231		}
1232
1233		fail_counter_short = 0;
1234		/*
1235		 * Voltage swing/pre-emphasis adjust requested
1236		 * during CR phase
1237		 */
1238		cdns_mhdp_adjust_requested_cr(mhdp, link_status,
1239					      requested_adjust_volt_swing,
1240					      requested_adjust_pre_emphasis);
1241	} while (fail_counter_short < 5 && fail_counter_cr_long < 10);
1242
1243err:
1244	cdns_mhdp_print_lt_status("CR phase failed", mhdp, &phy_cfg);
1245
1246	return false;
1247}
1248
1249static void cdns_mhdp_lower_link_rate(struct cdns_mhdp_link *link)
1250{
1251	switch (drm_dp_link_rate_to_bw_code(link->rate)) {
1252	case DP_LINK_BW_2_7:
1253		link->rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_1_62);
1254		break;
1255	case DP_LINK_BW_5_4:
1256		link->rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_2_7);
1257		break;
1258	case DP_LINK_BW_8_1:
1259		link->rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4);
1260		break;
1261	}
1262}
1263
1264static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp,
1265				   unsigned int training_interval)
1266{
1267	u32 reg32;
1268	const u8 eq_tps = cdns_mhdp_eq_training_pattern_supported(mhdp);
1269	int ret;
1270
1271	while (1) {
1272		if (!cdns_mhdp_link_training_cr(mhdp)) {
1273			if (drm_dp_link_rate_to_bw_code(mhdp->link.rate) !=
1274			    DP_LINK_BW_1_62) {
1275				dev_dbg(mhdp->dev,
1276					"Reducing link rate during CR phase\n");
1277				cdns_mhdp_lower_link_rate(&mhdp->link);
1278
1279				continue;
1280			} else if (mhdp->link.num_lanes > 1) {
1281				dev_dbg(mhdp->dev,
1282					"Reducing lanes number during CR phase\n");
1283				mhdp->link.num_lanes >>= 1;
1284				mhdp->link.rate = cdns_mhdp_max_link_rate(mhdp);
1285
1286				continue;
1287			}
1288
1289			dev_err(mhdp->dev,
1290				"Link training failed during CR phase\n");
1291			goto err;
1292		}
1293
1294		if (cdns_mhdp_link_training_channel_eq(mhdp, eq_tps,
1295						       training_interval))
1296			break;
1297
1298		if (mhdp->link.num_lanes > 1) {
1299			dev_dbg(mhdp->dev,
1300				"Reducing lanes number during EQ phase\n");
1301			mhdp->link.num_lanes >>= 1;
1302
1303			continue;
1304		} else if (drm_dp_link_rate_to_bw_code(mhdp->link.rate) !=
1305			   DP_LINK_BW_1_62) {
1306			dev_dbg(mhdp->dev,
1307				"Reducing link rate during EQ phase\n");
1308			cdns_mhdp_lower_link_rate(&mhdp->link);
1309			mhdp->link.num_lanes = cdns_mhdp_max_num_lanes(mhdp);
1310
1311			continue;
1312		}
1313
1314		dev_err(mhdp->dev, "Link training failed during EQ phase\n");
1315		goto err;
1316	}
1317
1318	dev_dbg(mhdp->dev, "Link training ok. Lanes: %u, Rate %u Mbps\n",
1319		mhdp->link.num_lanes, mhdp->link.rate / 100);
1320
1321	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
1322			   mhdp->host.scrambler ? 0 :
1323			   DP_LINK_SCRAMBLING_DISABLE);
1324
1325	ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &reg32);
1326	if (ret < 0) {
1327		dev_err(mhdp->dev,
1328			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
1329			ret);
1330		return ret;
1331	}
1332	reg32 &= ~GENMASK(1, 0);
1333	reg32 |= CDNS_DP_NUM_LANES(mhdp->link.num_lanes);
1334	reg32 |= CDNS_DP_WR_FAILING_EDGE_VSYNC;
1335	reg32 |= CDNS_DP_FRAMER_EN;
1336	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, reg32);
1337
1338	/* Reset PHY config */
1339	reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
1340	if (!mhdp->host.scrambler)
1341		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
1342	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
1343
1344	return 0;
1345err:
1346	/* Reset PHY config */
1347	reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
1348	if (!mhdp->host.scrambler)
1349		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
1350	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
1351
1352	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
1353			   DP_TRAINING_PATTERN_DISABLE);
1354
1355	return -EIO;
1356}
1357
1358static u32 cdns_mhdp_get_training_interval_us(struct cdns_mhdp_device *mhdp,
1359					      u32 interval)
1360{
1361	if (interval == 0)
1362		return 400;
1363	if (interval < 5)
1364		return 4000 << (interval - 1);
1365	dev_err(mhdp->dev,
1366		"wrong training interval returned by DPCD: %d\n", interval);
1367	return 0;
1368}
1369
1370static void cdns_mhdp_fill_host_caps(struct cdns_mhdp_device *mhdp)
1371{
1372	unsigned int link_rate;
1373
1374	/* Get source capabilities based on PHY attributes */
1375
1376	mhdp->host.lanes_cnt = mhdp->phy->attrs.bus_width;
1377	if (!mhdp->host.lanes_cnt)
1378		mhdp->host.lanes_cnt = 4;
1379
1380	link_rate = mhdp->phy->attrs.max_link_rate;
1381	if (!link_rate)
1382		link_rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_8_1);
1383	else
1384		/* PHY uses Mb/s, DRM uses tens of kb/s. */
1385		link_rate *= 100;
1386
1387	mhdp->host.link_rate = link_rate;
1388	mhdp->host.volt_swing = CDNS_VOLT_SWING(3);
1389	mhdp->host.pre_emphasis = CDNS_PRE_EMPHASIS(3);
1390	mhdp->host.pattern_supp = CDNS_SUPPORT_TPS(1) |
1391				  CDNS_SUPPORT_TPS(2) | CDNS_SUPPORT_TPS(3) |
1392				  CDNS_SUPPORT_TPS(4);
1393	mhdp->host.lane_mapping = CDNS_LANE_MAPPING_NORMAL;
1394	mhdp->host.fast_link = false;
1395	mhdp->host.enhanced = true;
1396	mhdp->host.scrambler = true;
1397	mhdp->host.ssc = false;
1398}
1399
1400static void cdns_mhdp_fill_sink_caps(struct cdns_mhdp_device *mhdp,
1401				     u8 dpcd[DP_RECEIVER_CAP_SIZE])
1402{
1403	mhdp->sink.link_rate = mhdp->link.rate;
1404	mhdp->sink.lanes_cnt = mhdp->link.num_lanes;
1405	mhdp->sink.enhanced = !!(mhdp->link.capabilities &
1406				 DP_LINK_CAP_ENHANCED_FRAMING);
1407
1408	/* Set SSC support */
1409	mhdp->sink.ssc = !!(dpcd[DP_MAX_DOWNSPREAD] &
1410				  DP_MAX_DOWNSPREAD_0_5);
1411
1412	/* Set TPS support */
1413	mhdp->sink.pattern_supp = CDNS_SUPPORT_TPS(1) | CDNS_SUPPORT_TPS(2);
1414	if (drm_dp_tps3_supported(dpcd))
1415		mhdp->sink.pattern_supp |= CDNS_SUPPORT_TPS(3);
1416	if (drm_dp_tps4_supported(dpcd))
1417		mhdp->sink.pattern_supp |= CDNS_SUPPORT_TPS(4);
1418
1419	/* Set fast link support */
1420	mhdp->sink.fast_link = !!(dpcd[DP_MAX_DOWNSPREAD] &
1421				  DP_NO_AUX_HANDSHAKE_LINK_TRAINING);
1422}
1423
1424static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
1425{
1426	u8 dpcd[DP_RECEIVER_CAP_SIZE], amp[2];
1427	u32 resp, interval, interval_us;
1428	u8 ext_cap_chk = 0;
1429	unsigned int addr;
1430	int err;
1431
1432	WARN_ON(!mutex_is_locked(&mhdp->link_mutex));
1433
1434	drm_dp_dpcd_readb(&mhdp->aux, DP_TRAINING_AUX_RD_INTERVAL,
1435			  &ext_cap_chk);
1436
1437	if (ext_cap_chk & DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT)
1438		addr = DP_DP13_DPCD_REV;
1439	else
1440		addr = DP_DPCD_REV;
1441
1442	err = drm_dp_dpcd_read(&mhdp->aux, addr, dpcd, DP_RECEIVER_CAP_SIZE);
1443	if (err < 0) {
1444		dev_err(mhdp->dev, "Failed to read receiver capabilities\n");
1445		return err;
1446	}
1447
1448	mhdp->link.revision = dpcd[0];
1449	mhdp->link.rate = drm_dp_bw_code_to_link_rate(dpcd[1]);
1450	mhdp->link.num_lanes = dpcd[2] & DP_MAX_LANE_COUNT_MASK;
1451
1452	if (dpcd[2] & DP_ENHANCED_FRAME_CAP)
1453		mhdp->link.capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
1454
1455	dev_dbg(mhdp->dev, "Set sink device power state via DPCD\n");
1456	cdns_mhdp_link_power_up(&mhdp->aux, &mhdp->link);
1457
1458	cdns_mhdp_fill_sink_caps(mhdp, dpcd);
1459
1460	mhdp->link.rate = cdns_mhdp_max_link_rate(mhdp);
1461	mhdp->link.num_lanes = cdns_mhdp_max_num_lanes(mhdp);
1462
1463	/* Disable framer for link training */
1464	err = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
1465	if (err < 0) {
1466		dev_err(mhdp->dev,
1467			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
1468			err);
1469		return err;
1470	}
1471
1472	resp &= ~CDNS_DP_FRAMER_EN;
1473	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
1474
1475	/* Spread AMP if required, enable 8b/10b coding */
1476	amp[0] = cdns_mhdp_get_ssc_supported(mhdp) ? DP_SPREAD_AMP_0_5 : 0;
1477	amp[1] = DP_SET_ANSI_8B10B;
1478	drm_dp_dpcd_write(&mhdp->aux, DP_DOWNSPREAD_CTRL, amp, 2);
1479
1480	if (mhdp->host.fast_link & mhdp->sink.fast_link) {
1481		dev_err(mhdp->dev, "fastlink not supported\n");
1482		return -EOPNOTSUPP;
1483	}
1484
1485	interval = dpcd[DP_TRAINING_AUX_RD_INTERVAL] & DP_TRAINING_AUX_RD_MASK;
1486	interval_us = cdns_mhdp_get_training_interval_us(mhdp, interval);
1487	if (!interval_us ||
1488	    cdns_mhdp_link_training(mhdp, interval_us)) {
1489		dev_err(mhdp->dev, "Link training failed. Exiting.\n");
1490		return -EIO;
1491	}
1492
1493	mhdp->link_up = true;
1494
1495	return 0;
1496}
1497
1498static void cdns_mhdp_link_down(struct cdns_mhdp_device *mhdp)
1499{
1500	WARN_ON(!mutex_is_locked(&mhdp->link_mutex));
1501
1502	if (mhdp->plugged)
1503		cdns_mhdp_link_power_down(&mhdp->aux, &mhdp->link);
1504
1505	mhdp->link_up = false;
1506}
1507
1508static struct edid *cdns_mhdp_get_edid(struct cdns_mhdp_device *mhdp,
1509				       struct drm_connector *connector)
1510{
1511	if (!mhdp->plugged)
1512		return NULL;
1513
1514	return drm_do_get_edid(connector, cdns_mhdp_get_edid_block, mhdp);
1515}
1516
1517static int cdns_mhdp_get_modes(struct drm_connector *connector)
1518{
1519	struct cdns_mhdp_device *mhdp = connector_to_mhdp(connector);
1520	struct edid *edid;
1521	int num_modes;
1522
1523	if (!mhdp->plugged)
1524		return 0;
1525
1526	edid = cdns_mhdp_get_edid(mhdp, connector);
1527	if (!edid) {
1528		dev_err(mhdp->dev, "Failed to read EDID\n");
1529		return 0;
1530	}
1531
1532	drm_connector_update_edid_property(connector, edid);
1533	num_modes = drm_add_edid_modes(connector, edid);
1534	kfree(edid);
1535
1536	/*
1537	 * HACK: Warn about unsupported display formats until we deal
1538	 *       with them correctly.
1539	 */
1540	if (connector->display_info.color_formats &&
1541	    !(connector->display_info.color_formats &
1542	      mhdp->display_fmt.color_format))
1543		dev_warn(mhdp->dev,
1544			 "%s: No supported color_format found (0x%08x)\n",
1545			__func__, connector->display_info.color_formats);
1546
1547	if (connector->display_info.bpc &&
1548	    connector->display_info.bpc < mhdp->display_fmt.bpc)
1549		dev_warn(mhdp->dev, "%s: Display bpc only %d < %d\n",
1550			 __func__, connector->display_info.bpc,
1551			 mhdp->display_fmt.bpc);
1552
1553	return num_modes;
1554}
1555
1556static int cdns_mhdp_connector_detect(struct drm_connector *conn,
1557				      struct drm_modeset_acquire_ctx *ctx,
1558				      bool force)
1559{
1560	struct cdns_mhdp_device *mhdp = connector_to_mhdp(conn);
1561
1562	return cdns_mhdp_detect(mhdp);
1563}
1564
1565static u32 cdns_mhdp_get_bpp(struct cdns_mhdp_display_fmt *fmt)
1566{
1567	u32 bpp;
1568
1569	if (fmt->y_only)
1570		return fmt->bpc;
1571
1572	switch (fmt->color_format) {
1573	case DRM_COLOR_FORMAT_RGB444:
1574	case DRM_COLOR_FORMAT_YCBCR444:
1575		bpp = fmt->bpc * 3;
1576		break;
1577	case DRM_COLOR_FORMAT_YCBCR422:
1578		bpp = fmt->bpc * 2;
1579		break;
1580	case DRM_COLOR_FORMAT_YCBCR420:
1581		bpp = fmt->bpc * 3 / 2;
1582		break;
1583	default:
1584		bpp = fmt->bpc * 3;
1585		WARN_ON(1);
1586	}
1587	return bpp;
1588}
1589
1590static
1591bool cdns_mhdp_bandwidth_ok(struct cdns_mhdp_device *mhdp,
1592			    const struct drm_display_mode *mode,
1593			    unsigned int lanes, unsigned int rate)
1594{
1595	u32 max_bw, req_bw, bpp;
1596
1597	/*
1598	 * mode->clock is expressed in kHz. Multiplying by bpp and dividing by 8
1599	 * we get the number of kB/s. DisplayPort applies a 8b-10b encoding, the
1600	 * value thus equals the bandwidth in 10kb/s units, which matches the
1601	 * units of the rate parameter.
1602	 */
1603
1604	bpp = cdns_mhdp_get_bpp(&mhdp->display_fmt);
1605	req_bw = mode->clock * bpp / 8;
1606	max_bw = lanes * rate;
1607	if (req_bw > max_bw) {
1608		dev_dbg(mhdp->dev,
1609			"Unsupported Mode: %s, Req BW: %u, Available Max BW:%u\n",
1610			mode->name, req_bw, max_bw);
1611
1612		return false;
1613	}
1614
1615	return true;
1616}
1617
1618static
1619enum drm_mode_status cdns_mhdp_mode_valid(struct drm_connector *conn,
1620					  struct drm_display_mode *mode)
1621{
1622	struct cdns_mhdp_device *mhdp = connector_to_mhdp(conn);
1623
1624	mutex_lock(&mhdp->link_mutex);
1625
1626	if (!cdns_mhdp_bandwidth_ok(mhdp, mode, mhdp->link.num_lanes,
1627				    mhdp->link.rate)) {
1628		mutex_unlock(&mhdp->link_mutex);
1629		return MODE_CLOCK_HIGH;
1630	}
1631
1632	mutex_unlock(&mhdp->link_mutex);
1633	return MODE_OK;
1634}
1635
1636static int cdns_mhdp_connector_atomic_check(struct drm_connector *conn,
1637					    struct drm_atomic_state *state)
1638{
1639	struct cdns_mhdp_device *mhdp = connector_to_mhdp(conn);
1640	struct drm_connector_state *old_state, *new_state;
1641	struct drm_crtc_state *crtc_state;
1642	u64 old_cp, new_cp;
1643
1644	if (!mhdp->hdcp_supported)
1645		return 0;
1646
1647	old_state = drm_atomic_get_old_connector_state(state, conn);
1648	new_state = drm_atomic_get_new_connector_state(state, conn);
1649	old_cp = old_state->content_protection;
1650	new_cp = new_state->content_protection;
1651
1652	if (old_state->hdcp_content_type != new_state->hdcp_content_type &&
1653	    new_cp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
1654		new_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
1655		goto mode_changed;
1656	}
1657
1658	if (!new_state->crtc) {
1659		if (old_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
1660			new_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
1661		return 0;
1662	}
1663
1664	if (old_cp == new_cp ||
1665	    (old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
1666	     new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED))
1667		return 0;
1668
1669mode_changed:
1670	crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc);
1671	crtc_state->mode_changed = true;
1672
1673	return 0;
1674}
1675
1676static const struct drm_connector_helper_funcs cdns_mhdp_conn_helper_funcs = {
1677	.detect_ctx = cdns_mhdp_connector_detect,
1678	.get_modes = cdns_mhdp_get_modes,
1679	.mode_valid = cdns_mhdp_mode_valid,
1680	.atomic_check = cdns_mhdp_connector_atomic_check,
1681};
1682
1683static const struct drm_connector_funcs cdns_mhdp_conn_funcs = {
1684	.fill_modes = drm_helper_probe_single_connector_modes,
1685	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1686	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1687	.reset = drm_atomic_helper_connector_reset,
1688	.destroy = drm_connector_cleanup,
1689};
1690
1691static int cdns_mhdp_connector_init(struct cdns_mhdp_device *mhdp)
1692{
1693	u32 bus_format = MEDIA_BUS_FMT_RGB121212_1X36;
1694	struct drm_connector *conn = &mhdp->connector;
1695	struct drm_bridge *bridge = &mhdp->bridge;
1696	int ret;
1697
1698	if (!bridge->encoder) {
1699		dev_err(mhdp->dev, "Parent encoder object not found");
1700		return -ENODEV;
1701	}
1702
1703	conn->polled = DRM_CONNECTOR_POLL_HPD;
1704
1705	ret = drm_connector_init(bridge->dev, conn, &cdns_mhdp_conn_funcs,
1706				 DRM_MODE_CONNECTOR_DisplayPort);
1707	if (ret) {
1708		dev_err(mhdp->dev, "Failed to initialize connector with drm\n");
1709		return ret;
1710	}
1711
1712	drm_connector_helper_add(conn, &cdns_mhdp_conn_helper_funcs);
1713
1714	ret = drm_display_info_set_bus_formats(&conn->display_info,
1715					       &bus_format, 1);
1716	if (ret)
1717		return ret;
1718
1719	ret = drm_connector_attach_encoder(conn, bridge->encoder);
1720	if (ret) {
1721		dev_err(mhdp->dev, "Failed to attach connector to encoder\n");
1722		return ret;
1723	}
1724
1725	if (mhdp->hdcp_supported)
1726		ret = drm_connector_attach_content_protection_property(conn, true);
1727
1728	return ret;
1729}
1730
1731static int cdns_mhdp_attach(struct drm_bridge *bridge,
1732			    enum drm_bridge_attach_flags flags)
1733{
1734	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
1735	bool hw_ready;
1736	int ret;
1737
1738	dev_dbg(mhdp->dev, "%s\n", __func__);
1739
1740	mhdp->aux.drm_dev = bridge->dev;
1741	ret = drm_dp_aux_register(&mhdp->aux);
1742	if (ret < 0)
1743		return ret;
1744
1745	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
1746		ret = cdns_mhdp_connector_init(mhdp);
1747		if (ret)
1748			goto aux_unregister;
1749	}
1750
1751	spin_lock(&mhdp->start_lock);
1752
1753	mhdp->bridge_attached = true;
1754	hw_ready = mhdp->hw_state == MHDP_HW_READY;
1755
1756	spin_unlock(&mhdp->start_lock);
1757
1758	/* Enable SW event interrupts */
1759	if (hw_ready)
1760		cdns_mhdp_bridge_hpd_enable(bridge);
1761
1762	return 0;
1763aux_unregister:
1764	drm_dp_aux_unregister(&mhdp->aux);
1765	return ret;
1766}
1767
1768static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
1769				      const struct drm_display_mode *mode)
1770{
1771	unsigned int dp_framer_sp = 0, msa_horizontal_1,
1772		msa_vertical_1, bnd_hsync2vsync, hsync2vsync_pol_ctrl,
1773		misc0 = 0, misc1 = 0, pxl_repr,
1774		front_porch, back_porch, msa_h0, msa_v0, hsync, vsync,
1775		dp_vertical_1;
1776	u8 stream_id = mhdp->stream_id;
1777	u32 bpp, bpc, pxlfmt, framer;
1778	int ret;
1779
1780	pxlfmt = mhdp->display_fmt.color_format;
1781	bpc = mhdp->display_fmt.bpc;
1782
1783	/*
1784	 * If YCBCR supported and stream not SD, use ITU709
1785	 * Need to handle ITU version with YCBCR420 when supported
1786	 */
1787	if ((pxlfmt == DRM_COLOR_FORMAT_YCBCR444 ||
1788	     pxlfmt == DRM_COLOR_FORMAT_YCBCR422) && mode->crtc_vdisplay >= 720)
1789		misc0 = DP_YCBCR_COEFFICIENTS_ITU709;
1790
1791	bpp = cdns_mhdp_get_bpp(&mhdp->display_fmt);
1792
1793	switch (pxlfmt) {
1794	case DRM_COLOR_FORMAT_RGB444:
1795		pxl_repr = CDNS_DP_FRAMER_RGB << CDNS_DP_FRAMER_PXL_FORMAT;
1796		misc0 |= DP_COLOR_FORMAT_RGB;
1797		break;
1798	case DRM_COLOR_FORMAT_YCBCR444:
1799		pxl_repr = CDNS_DP_FRAMER_YCBCR444 << CDNS_DP_FRAMER_PXL_FORMAT;
1800		misc0 |= DP_COLOR_FORMAT_YCbCr444 | DP_TEST_DYNAMIC_RANGE_CEA;
1801		break;
1802	case DRM_COLOR_FORMAT_YCBCR422:
1803		pxl_repr = CDNS_DP_FRAMER_YCBCR422 << CDNS_DP_FRAMER_PXL_FORMAT;
1804		misc0 |= DP_COLOR_FORMAT_YCbCr422 | DP_TEST_DYNAMIC_RANGE_CEA;
1805		break;
1806	case DRM_COLOR_FORMAT_YCBCR420:
1807		pxl_repr = CDNS_DP_FRAMER_YCBCR420 << CDNS_DP_FRAMER_PXL_FORMAT;
1808		break;
1809	default:
1810		pxl_repr = CDNS_DP_FRAMER_Y_ONLY << CDNS_DP_FRAMER_PXL_FORMAT;
1811	}
1812
1813	switch (bpc) {
1814	case 6:
1815		misc0 |= DP_TEST_BIT_DEPTH_6;
1816		pxl_repr |= CDNS_DP_FRAMER_6_BPC;
1817		break;
1818	case 8:
1819		misc0 |= DP_TEST_BIT_DEPTH_8;
1820		pxl_repr |= CDNS_DP_FRAMER_8_BPC;
1821		break;
1822	case 10:
1823		misc0 |= DP_TEST_BIT_DEPTH_10;
1824		pxl_repr |= CDNS_DP_FRAMER_10_BPC;
1825		break;
1826	case 12:
1827		misc0 |= DP_TEST_BIT_DEPTH_12;
1828		pxl_repr |= CDNS_DP_FRAMER_12_BPC;
1829		break;
1830	case 16:
1831		misc0 |= DP_TEST_BIT_DEPTH_16;
1832		pxl_repr |= CDNS_DP_FRAMER_16_BPC;
1833		break;
1834	}
1835
1836	bnd_hsync2vsync = CDNS_IP_BYPASS_V_INTERFACE;
1837	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1838		bnd_hsync2vsync |= CDNS_IP_DET_INTERLACE_FORMAT;
1839
1840	cdns_mhdp_reg_write(mhdp, CDNS_BND_HSYNC2VSYNC(stream_id),
1841			    bnd_hsync2vsync);
1842
1843	hsync2vsync_pol_ctrl = 0;
1844	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1845		hsync2vsync_pol_ctrl |= CDNS_H2V_HSYNC_POL_ACTIVE_LOW;
1846	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1847		hsync2vsync_pol_ctrl |= CDNS_H2V_VSYNC_POL_ACTIVE_LOW;
1848	cdns_mhdp_reg_write(mhdp, CDNS_HSYNC2VSYNC_POL_CTRL(stream_id),
1849			    hsync2vsync_pol_ctrl);
1850
1851	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_PXL_REPR(stream_id), pxl_repr);
1852
1853	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1854		dp_framer_sp |= CDNS_DP_FRAMER_INTERLACE;
1855	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1856		dp_framer_sp |= CDNS_DP_FRAMER_HSYNC_POL_LOW;
1857	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1858		dp_framer_sp |= CDNS_DP_FRAMER_VSYNC_POL_LOW;
1859	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_SP(stream_id), dp_framer_sp);
1860
1861	front_porch = mode->crtc_hsync_start - mode->crtc_hdisplay;
1862	back_porch = mode->crtc_htotal - mode->crtc_hsync_end;
1863	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRONT_BACK_PORCH(stream_id),
1864			    CDNS_DP_FRONT_PORCH(front_porch) |
1865			    CDNS_DP_BACK_PORCH(back_porch));
1866
1867	cdns_mhdp_reg_write(mhdp, CDNS_DP_BYTE_COUNT(stream_id),
1868			    mode->crtc_hdisplay * bpp / 8);
1869
1870	msa_h0 = mode->crtc_htotal - mode->crtc_hsync_start;
1871	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_0(stream_id),
1872			    CDNS_DP_MSAH0_H_TOTAL(mode->crtc_htotal) |
1873			    CDNS_DP_MSAH0_HSYNC_START(msa_h0));
1874
1875	hsync = mode->crtc_hsync_end - mode->crtc_hsync_start;
1876	msa_horizontal_1 = CDNS_DP_MSAH1_HSYNC_WIDTH(hsync) |
1877			   CDNS_DP_MSAH1_HDISP_WIDTH(mode->crtc_hdisplay);
1878	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1879		msa_horizontal_1 |= CDNS_DP_MSAH1_HSYNC_POL_LOW;
1880	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_1(stream_id),
1881			    msa_horizontal_1);
1882
1883	msa_v0 = mode->crtc_vtotal - mode->crtc_vsync_start;
1884	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_0(stream_id),
1885			    CDNS_DP_MSAV0_V_TOTAL(mode->crtc_vtotal) |
1886			    CDNS_DP_MSAV0_VSYNC_START(msa_v0));
1887
1888	vsync = mode->crtc_vsync_end - mode->crtc_vsync_start;
1889	msa_vertical_1 = CDNS_DP_MSAV1_VSYNC_WIDTH(vsync) |
1890			 CDNS_DP_MSAV1_VDISP_WIDTH(mode->crtc_vdisplay);
1891	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1892		msa_vertical_1 |= CDNS_DP_MSAV1_VSYNC_POL_LOW;
1893	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_1(stream_id),
1894			    msa_vertical_1);
1895
1896	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
1897	    mode->crtc_vtotal % 2 == 0)
1898		misc1 = DP_TEST_INTERLACED;
1899	if (mhdp->display_fmt.y_only)
1900		misc1 |= CDNS_DP_TEST_COLOR_FORMAT_RAW_Y_ONLY;
1901	/* Use VSC SDP for Y420 */
1902	if (pxlfmt == DRM_COLOR_FORMAT_YCBCR420)
1903		misc1 = CDNS_DP_TEST_VSC_SDP;
1904
1905	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_MISC(stream_id),
1906			    misc0 | (misc1 << 8));
1907
1908	cdns_mhdp_reg_write(mhdp, CDNS_DP_HORIZONTAL(stream_id),
1909			    CDNS_DP_H_HSYNC_WIDTH(hsync) |
1910			    CDNS_DP_H_H_TOTAL(mode->crtc_hdisplay));
1911
1912	cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_0(stream_id),
1913			    CDNS_DP_V0_VHEIGHT(mode->crtc_vdisplay) |
1914			    CDNS_DP_V0_VSTART(msa_v0));
1915
1916	dp_vertical_1 = CDNS_DP_V1_VTOTAL(mode->crtc_vtotal);
1917	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
1918	    mode->crtc_vtotal % 2 == 0)
1919		dp_vertical_1 |= CDNS_DP_V1_VTOTAL_EVEN;
1920
1921	cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_1(stream_id), dp_vertical_1);
1922
1923	cdns_mhdp_reg_write_bit(mhdp, CDNS_DP_VB_ID(stream_id), 2, 1,
1924				(mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1925				CDNS_DP_VB_ID_INTERLACED : 0);
1926
1927	ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &framer);
1928	if (ret < 0) {
1929		dev_err(mhdp->dev,
1930			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
1931			ret);
1932		return;
1933	}
1934	framer |= CDNS_DP_FRAMER_EN;
1935	framer &= ~CDNS_DP_NO_VIDEO_MODE;
1936	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, framer);
1937}
1938
1939static void cdns_mhdp_sst_enable(struct cdns_mhdp_device *mhdp,
1940				 const struct drm_display_mode *mode)
1941{
1942	u32 rate, vs, required_bandwidth, available_bandwidth;
1943	s32 line_thresh1, line_thresh2, line_thresh = 0;
1944	int pxlclock = mode->crtc_clock;
1945	u32 tu_size = 64;
1946	u32 bpp;
1947
1948	/* Get rate in MSymbols per second per lane */
1949	rate = mhdp->link.rate / 1000;
1950
1951	bpp = cdns_mhdp_get_bpp(&mhdp->display_fmt);
1952
1953	required_bandwidth = pxlclock * bpp / 8;
1954	available_bandwidth = mhdp->link.num_lanes * rate;
1955
1956	vs = tu_size * required_bandwidth / available_bandwidth;
1957	vs /= 1000;
1958
1959	if (vs == tu_size)
1960		vs = tu_size - 1;
1961
1962	line_thresh1 = ((vs + 1) << 5) * 8 / bpp;
1963	line_thresh2 = (pxlclock << 5) / 1000 / rate * (vs + 1) - (1 << 5);
1964	line_thresh = line_thresh1 - line_thresh2 / (s32)mhdp->link.num_lanes;
1965	line_thresh = (line_thresh >> 5) + 2;
1966
1967	mhdp->stream_id = 0;
1968
1969	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_TU,
1970			    CDNS_DP_FRAMER_TU_VS(vs) |
1971			    CDNS_DP_FRAMER_TU_SIZE(tu_size) |
1972			    CDNS_DP_FRAMER_TU_CNT_RST_EN);
1973
1974	cdns_mhdp_reg_write(mhdp, CDNS_DP_LINE_THRESH(0),
1975			    line_thresh & GENMASK(5, 0));
1976
1977	cdns_mhdp_reg_write(mhdp, CDNS_DP_STREAM_CONFIG_2(0),
1978			    CDNS_DP_SC2_TU_VS_DIFF((tu_size - vs > 3) ?
1979						   0 : tu_size - vs));
1980
1981	cdns_mhdp_configure_video(mhdp, mode);
1982}
1983
1984static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
1985				    struct drm_bridge_state *bridge_state)
1986{
1987	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
1988	struct drm_atomic_state *state = bridge_state->base.state;
1989	struct cdns_mhdp_bridge_state *mhdp_state;
1990	struct drm_crtc_state *crtc_state;
1991	struct drm_connector *connector;
1992	struct drm_connector_state *conn_state;
1993	struct drm_bridge_state *new_state;
1994	const struct drm_display_mode *mode;
1995	u32 resp;
1996	int ret;
1997
1998	dev_dbg(mhdp->dev, "bridge enable\n");
1999
2000	mutex_lock(&mhdp->link_mutex);
2001
2002	if (mhdp->plugged && !mhdp->link_up) {
2003		ret = cdns_mhdp_link_up(mhdp);
2004		if (ret < 0)
2005			goto out;
2006	}
2007
2008	if (mhdp->info && mhdp->info->ops && mhdp->info->ops->enable)
2009		mhdp->info->ops->enable(mhdp);
2010
2011	/* Enable VIF clock for stream 0 */
2012	ret = cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp);
2013	if (ret < 0) {
2014		dev_err(mhdp->dev, "Failed to read CDNS_DPTX_CAR %d\n", ret);
2015		goto out;
2016	}
2017
2018	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
2019			    resp | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN);
2020
2021	connector = drm_atomic_get_new_connector_for_encoder(state,
2022							     bridge->encoder);
2023	if (WARN_ON(!connector))
2024		goto out;
2025
2026	conn_state = drm_atomic_get_new_connector_state(state, connector);
2027	if (WARN_ON(!conn_state))
2028		goto out;
2029
2030	if (mhdp->hdcp_supported &&
2031	    mhdp->hw_state == MHDP_HW_READY &&
2032	    conn_state->content_protection ==
2033	    DRM_MODE_CONTENT_PROTECTION_DESIRED) {
2034		mutex_unlock(&mhdp->link_mutex);
2035		cdns_mhdp_hdcp_enable(mhdp, conn_state->hdcp_content_type);
2036		mutex_lock(&mhdp->link_mutex);
2037	}
2038
2039	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
2040	if (WARN_ON(!crtc_state))
2041		goto out;
2042
2043	mode = &crtc_state->adjusted_mode;
2044
2045	new_state = drm_atomic_get_new_bridge_state(state, bridge);
2046	if (WARN_ON(!new_state))
2047		goto out;
2048
2049	if (!cdns_mhdp_bandwidth_ok(mhdp, mode, mhdp->link.num_lanes,
2050				    mhdp->link.rate)) {
2051		ret = -EINVAL;
2052		goto out;
2053	}
2054
2055	cdns_mhdp_sst_enable(mhdp, mode);
2056
2057	mhdp_state = to_cdns_mhdp_bridge_state(new_state);
2058
2059	mhdp_state->current_mode = drm_mode_duplicate(bridge->dev, mode);
2060	drm_mode_set_name(mhdp_state->current_mode);
2061
2062	dev_dbg(mhdp->dev, "%s: Enabling mode %s\n", __func__, mode->name);
2063
2064	mhdp->bridge_enabled = true;
2065
2066out:
2067	mutex_unlock(&mhdp->link_mutex);
2068	if (ret < 0)
2069		schedule_work(&mhdp->modeset_retry_work);
2070}
2071
2072static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,
2073				     struct drm_bridge_state *bridge_state)
2074{
2075	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
2076	u32 resp;
2077
2078	dev_dbg(mhdp->dev, "%s\n", __func__);
2079
2080	mutex_lock(&mhdp->link_mutex);
2081
2082	if (mhdp->hdcp_supported)
2083		cdns_mhdp_hdcp_disable(mhdp);
2084
2085	mhdp->bridge_enabled = false;
2086	cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
2087	resp &= ~CDNS_DP_FRAMER_EN;
2088	resp |= CDNS_DP_NO_VIDEO_MODE;
2089	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
2090
2091	cdns_mhdp_link_down(mhdp);
2092
2093	/* Disable VIF clock for stream 0 */
2094	cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp);
2095	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
2096			    resp & ~(CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN));
2097
2098	if (mhdp->info && mhdp->info->ops && mhdp->info->ops->disable)
2099		mhdp->info->ops->disable(mhdp);
2100
2101	mutex_unlock(&mhdp->link_mutex);
2102}
2103
2104static void cdns_mhdp_detach(struct drm_bridge *bridge)
2105{
2106	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
2107
2108	dev_dbg(mhdp->dev, "%s\n", __func__);
2109
2110	drm_dp_aux_unregister(&mhdp->aux);
2111
2112	spin_lock(&mhdp->start_lock);
2113
2114	mhdp->bridge_attached = false;
2115
2116	spin_unlock(&mhdp->start_lock);
2117
2118	writel(~0, mhdp->regs + CDNS_APB_INT_MASK);
2119}
2120
2121static struct drm_bridge_state *
2122cdns_mhdp_bridge_atomic_duplicate_state(struct drm_bridge *bridge)
2123{
2124	struct cdns_mhdp_bridge_state *state;
2125
2126	state = kzalloc(sizeof(*state), GFP_KERNEL);
2127	if (!state)
2128		return NULL;
2129
2130	__drm_atomic_helper_bridge_duplicate_state(bridge, &state->base);
2131
2132	return &state->base;
2133}
2134
2135static void
2136cdns_mhdp_bridge_atomic_destroy_state(struct drm_bridge *bridge,
2137				      struct drm_bridge_state *state)
2138{
2139	struct cdns_mhdp_bridge_state *cdns_mhdp_state;
2140
2141	cdns_mhdp_state = to_cdns_mhdp_bridge_state(state);
2142
2143	if (cdns_mhdp_state->current_mode) {
2144		drm_mode_destroy(bridge->dev, cdns_mhdp_state->current_mode);
2145		cdns_mhdp_state->current_mode = NULL;
2146	}
2147
2148	kfree(cdns_mhdp_state);
2149}
2150
2151static struct drm_bridge_state *
2152cdns_mhdp_bridge_atomic_reset(struct drm_bridge *bridge)
2153{
2154	struct cdns_mhdp_bridge_state *cdns_mhdp_state;
2155
2156	cdns_mhdp_state = kzalloc(sizeof(*cdns_mhdp_state), GFP_KERNEL);
2157	if (!cdns_mhdp_state)
2158		return NULL;
2159
2160	__drm_atomic_helper_bridge_reset(bridge, &cdns_mhdp_state->base);
2161
2162	return &cdns_mhdp_state->base;
2163}
2164
2165static u32 *cdns_mhdp_get_input_bus_fmts(struct drm_bridge *bridge,
2166					 struct drm_bridge_state *bridge_state,
2167					 struct drm_crtc_state *crtc_state,
2168					 struct drm_connector_state *conn_state,
2169					 u32 output_fmt,
2170					 unsigned int *num_input_fmts)
2171{
2172	u32 *input_fmts;
2173
2174	*num_input_fmts = 0;
2175
2176	input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL);
2177	if (!input_fmts)
2178		return NULL;
2179
2180	*num_input_fmts = 1;
2181	input_fmts[0] = MEDIA_BUS_FMT_RGB121212_1X36;
2182
2183	return input_fmts;
2184}
2185
2186static int cdns_mhdp_atomic_check(struct drm_bridge *bridge,
2187				  struct drm_bridge_state *bridge_state,
2188				  struct drm_crtc_state *crtc_state,
2189				  struct drm_connector_state *conn_state)
2190{
2191	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
2192	const struct drm_display_mode *mode = &crtc_state->adjusted_mode;
2193
2194	mutex_lock(&mhdp->link_mutex);
2195
2196	if (!cdns_mhdp_bandwidth_ok(mhdp, mode, mhdp->link.num_lanes,
2197				    mhdp->link.rate)) {
2198		dev_err(mhdp->dev, "%s: Not enough BW for %s (%u lanes at %u Mbps)\n",
2199			__func__, mode->name, mhdp->link.num_lanes,
2200			mhdp->link.rate / 100);
2201		mutex_unlock(&mhdp->link_mutex);
2202		return -EINVAL;
2203	}
2204
2205	/*
2206	 * There might be flags negotiation supported in future.
2207	 * Set the bus flags in atomic_check statically for now.
2208	 */
2209	if (mhdp->info)
2210		bridge_state->input_bus_cfg.flags = *mhdp->info->input_bus_flags;
2211
2212	mutex_unlock(&mhdp->link_mutex);
2213	return 0;
2214}
2215
2216static enum drm_connector_status cdns_mhdp_bridge_detect(struct drm_bridge *bridge)
2217{
2218	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
2219
2220	return cdns_mhdp_detect(mhdp);
2221}
2222
2223static struct edid *cdns_mhdp_bridge_get_edid(struct drm_bridge *bridge,
2224					      struct drm_connector *connector)
2225{
2226	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
2227
2228	return cdns_mhdp_get_edid(mhdp, connector);
2229}
2230
2231static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = {
2232	.atomic_enable = cdns_mhdp_atomic_enable,
2233	.atomic_disable = cdns_mhdp_atomic_disable,
2234	.atomic_check = cdns_mhdp_atomic_check,
2235	.attach = cdns_mhdp_attach,
2236	.detach = cdns_mhdp_detach,
2237	.atomic_duplicate_state = cdns_mhdp_bridge_atomic_duplicate_state,
2238	.atomic_destroy_state = cdns_mhdp_bridge_atomic_destroy_state,
2239	.atomic_reset = cdns_mhdp_bridge_atomic_reset,
2240	.atomic_get_input_bus_fmts = cdns_mhdp_get_input_bus_fmts,
2241	.detect = cdns_mhdp_bridge_detect,
2242	.get_edid = cdns_mhdp_bridge_get_edid,
2243	.hpd_enable = cdns_mhdp_bridge_hpd_enable,
2244	.hpd_disable = cdns_mhdp_bridge_hpd_disable,
2245};
2246
2247static bool cdns_mhdp_detect_hpd(struct cdns_mhdp_device *mhdp, bool *hpd_pulse)
2248{
2249	int hpd_event, hpd_status;
2250
2251	*hpd_pulse = false;
2252
2253	hpd_event = cdns_mhdp_read_hpd_event(mhdp);
2254
2255	/* Getting event bits failed, bail out */
2256	if (hpd_event < 0) {
2257		dev_warn(mhdp->dev, "%s: read event failed: %d\n",
2258			 __func__, hpd_event);
2259		return false;
2260	}
2261
2262	hpd_status = cdns_mhdp_get_hpd_status(mhdp);
2263	if (hpd_status < 0) {
2264		dev_warn(mhdp->dev, "%s: get hpd status failed: %d\n",
2265			 __func__, hpd_status);
2266		return false;
2267	}
2268
2269	if (hpd_event & DPTX_READ_EVENT_HPD_PULSE)
2270		*hpd_pulse = true;
2271
2272	return !!hpd_status;
2273}
2274
2275static int cdns_mhdp_update_link_status(struct cdns_mhdp_device *mhdp)
2276{
2277	struct cdns_mhdp_bridge_state *cdns_bridge_state;
2278	struct drm_display_mode *current_mode;
2279	bool old_plugged = mhdp->plugged;
2280	struct drm_bridge_state *state;
2281	u8 status[DP_LINK_STATUS_SIZE];
2282	bool hpd_pulse;
2283	int ret = 0;
2284
2285	mutex_lock(&mhdp->link_mutex);
2286
2287	mhdp->plugged = cdns_mhdp_detect_hpd(mhdp, &hpd_pulse);
2288
2289	if (!mhdp->plugged) {
2290		cdns_mhdp_link_down(mhdp);
2291		mhdp->link.rate = mhdp->host.link_rate;
2292		mhdp->link.num_lanes = mhdp->host.lanes_cnt;
2293		goto out;
2294	}
2295
2296	/*
2297	 * If we get a HPD pulse event and we were and still are connected,
2298	 * check the link status. If link status is ok, there's nothing to do
2299	 * as we don't handle DP interrupts. If link status is bad, continue
2300	 * with full link setup.
2301	 */
2302	if (hpd_pulse && old_plugged == mhdp->plugged) {
2303		ret = drm_dp_dpcd_read_link_status(&mhdp->aux, status);
2304
2305		/*
2306		 * If everything looks fine, just return, as we don't handle
2307		 * DP IRQs.
2308		 */
2309		if (ret > 0 &&
2310		    drm_dp_channel_eq_ok(status, mhdp->link.num_lanes) &&
2311		    drm_dp_clock_recovery_ok(status, mhdp->link.num_lanes))
2312			goto out;
2313
2314		/* If link is bad, mark link as down so that we do a new LT */
2315		mhdp->link_up = false;
2316	}
2317
2318	if (!mhdp->link_up) {
2319		ret = cdns_mhdp_link_up(mhdp);
2320		if (ret < 0)
2321			goto out;
2322	}
2323
2324	if (mhdp->bridge_enabled) {
2325		state = drm_priv_to_bridge_state(mhdp->bridge.base.state);
2326		if (!state) {
2327			ret = -EINVAL;
2328			goto out;
2329		}
2330
2331		cdns_bridge_state = to_cdns_mhdp_bridge_state(state);
2332		if (!cdns_bridge_state) {
2333			ret = -EINVAL;
2334			goto out;
2335		}
2336
2337		current_mode = cdns_bridge_state->current_mode;
2338		if (!current_mode) {
2339			ret = -EINVAL;
2340			goto out;
2341		}
2342
2343		if (!cdns_mhdp_bandwidth_ok(mhdp, current_mode, mhdp->link.num_lanes,
2344					    mhdp->link.rate)) {
2345			ret = -EINVAL;
2346			goto out;
2347		}
2348
2349		dev_dbg(mhdp->dev, "%s: Enabling mode %s\n", __func__,
2350			current_mode->name);
2351
2352		cdns_mhdp_sst_enable(mhdp, current_mode);
2353	}
2354out:
2355	mutex_unlock(&mhdp->link_mutex);
2356	return ret;
2357}
2358
2359static void cdns_mhdp_modeset_retry_fn(struct work_struct *work)
2360{
2361	struct cdns_mhdp_device *mhdp;
2362	struct drm_connector *conn;
2363
2364	mhdp = container_of(work, typeof(*mhdp), modeset_retry_work);
2365
2366	conn = &mhdp->connector;
2367
2368	/* Grab the locks before changing connector property */
2369	mutex_lock(&conn->dev->mode_config.mutex);
2370
2371	/*
2372	 * Set connector link status to BAD and send a Uevent to notify
2373	 * userspace to do a modeset.
2374	 */
2375	drm_connector_set_link_status_property(conn, DRM_MODE_LINK_STATUS_BAD);
2376	mutex_unlock(&conn->dev->mode_config.mutex);
2377
2378	/* Send Hotplug uevent so userspace can reprobe */
2379	drm_kms_helper_hotplug_event(mhdp->bridge.dev);
2380}
2381
2382static irqreturn_t cdns_mhdp_irq_handler(int irq, void *data)
2383{
2384	struct cdns_mhdp_device *mhdp = data;
2385	u32 apb_stat, sw_ev0;
2386	bool bridge_attached;
2387
2388	apb_stat = readl(mhdp->regs + CDNS_APB_INT_STATUS);
2389	if (!(apb_stat & CDNS_APB_INT_MASK_SW_EVENT_INT))
2390		return IRQ_NONE;
2391
2392	sw_ev0 = readl(mhdp->regs + CDNS_SW_EVENT0);
2393
2394	/*
2395	 *  Calling drm_kms_helper_hotplug_event() when not attached
2396	 *  to drm device causes an oops because the drm_bridge->dev
2397	 *  is NULL. See cdns_mhdp_fw_cb() comments for details about the
2398	 *  problems related drm_kms_helper_hotplug_event() call.
2399	 */
2400	spin_lock(&mhdp->start_lock);
2401	bridge_attached = mhdp->bridge_attached;
2402	spin_unlock(&mhdp->start_lock);
2403
2404	if (bridge_attached && (sw_ev0 & CDNS_DPTX_HPD)) {
2405		schedule_work(&mhdp->hpd_work);
2406	}
2407
2408	if (sw_ev0 & ~CDNS_DPTX_HPD) {
2409		mhdp->sw_events |= (sw_ev0 & ~CDNS_DPTX_HPD);
2410		wake_up(&mhdp->sw_events_wq);
2411	}
2412
2413	return IRQ_HANDLED;
2414}
2415
2416u32 cdns_mhdp_wait_for_sw_event(struct cdns_mhdp_device *mhdp, u32 event)
2417{
2418	u32 ret;
2419
2420	ret = wait_event_timeout(mhdp->sw_events_wq,
2421				 mhdp->sw_events & event,
2422				 msecs_to_jiffies(500));
2423	if (!ret) {
2424		dev_dbg(mhdp->dev, "SW event 0x%x timeout\n", event);
2425		goto sw_event_out;
2426	}
2427
2428	ret = mhdp->sw_events;
2429	mhdp->sw_events &= ~event;
2430
2431sw_event_out:
2432	return ret;
2433}
2434
2435static void cdns_mhdp_hpd_work(struct work_struct *work)
2436{
2437	struct cdns_mhdp_device *mhdp = container_of(work,
2438						     struct cdns_mhdp_device,
2439						     hpd_work);
2440	int ret;
2441
2442	ret = cdns_mhdp_update_link_status(mhdp);
2443	if (mhdp->connector.dev) {
2444		if (ret < 0)
2445			schedule_work(&mhdp->modeset_retry_work);
2446		else
2447			drm_kms_helper_hotplug_event(mhdp->bridge.dev);
2448	} else {
2449		drm_bridge_hpd_notify(&mhdp->bridge, cdns_mhdp_detect(mhdp));
2450	}
2451}
2452
2453static int cdns_mhdp_probe(struct platform_device *pdev)
2454{
2455	struct device *dev = &pdev->dev;
2456	struct cdns_mhdp_device *mhdp;
2457	unsigned long rate;
2458	struct clk *clk;
2459	int ret;
2460	int irq;
2461
2462	mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL);
2463	if (!mhdp)
2464		return -ENOMEM;
2465
2466	clk = devm_clk_get(dev, NULL);
2467	if (IS_ERR(clk)) {
2468		dev_err(dev, "couldn't get clk: %ld\n", PTR_ERR(clk));
2469		return PTR_ERR(clk);
2470	}
2471
2472	mhdp->clk = clk;
2473	mhdp->dev = dev;
2474	mutex_init(&mhdp->mbox_mutex);
2475	mutex_init(&mhdp->link_mutex);
2476	spin_lock_init(&mhdp->start_lock);
2477
2478	drm_dp_aux_init(&mhdp->aux);
2479	mhdp->aux.dev = dev;
2480	mhdp->aux.transfer = cdns_mhdp_transfer;
2481
2482	mhdp->regs = devm_platform_ioremap_resource(pdev, 0);
2483	if (IS_ERR(mhdp->regs)) {
2484		dev_err(dev, "Failed to get memory resource\n");
2485		return PTR_ERR(mhdp->regs);
2486	}
2487
2488	mhdp->sapb_regs = devm_platform_ioremap_resource_byname(pdev, "mhdptx-sapb");
2489	if (IS_ERR(mhdp->sapb_regs)) {
2490		mhdp->hdcp_supported = false;
2491		dev_warn(dev,
2492			 "Failed to get SAPB memory resource, HDCP not supported\n");
2493	} else {
2494		mhdp->hdcp_supported = true;
2495	}
2496
2497	mhdp->phy = devm_of_phy_get_by_index(dev, pdev->dev.of_node, 0);
2498	if (IS_ERR(mhdp->phy)) {
2499		dev_err(dev, "no PHY configured\n");
2500		return PTR_ERR(mhdp->phy);
2501	}
2502
2503	platform_set_drvdata(pdev, mhdp);
2504
2505	mhdp->info = of_device_get_match_data(dev);
2506
2507	clk_prepare_enable(clk);
2508
2509	pm_runtime_enable(dev);
2510	ret = pm_runtime_resume_and_get(dev);
2511	if (ret < 0) {
2512		dev_err(dev, "pm_runtime_resume_and_get failed\n");
2513		pm_runtime_disable(dev);
2514		goto clk_disable;
2515	}
2516
2517	if (mhdp->info && mhdp->info->ops && mhdp->info->ops->init) {
2518		ret = mhdp->info->ops->init(mhdp);
2519		if (ret != 0) {
2520			dev_err(dev, "MHDP platform initialization failed: %d\n",
2521				ret);
2522			goto runtime_put;
2523		}
2524	}
2525
2526	rate = clk_get_rate(clk);
2527	writel(rate % 1000000, mhdp->regs + CDNS_SW_CLK_L);
2528	writel(rate / 1000000, mhdp->regs + CDNS_SW_CLK_H);
2529
2530	dev_dbg(dev, "func clk rate %lu Hz\n", rate);
2531
2532	writel(~0, mhdp->regs + CDNS_APB_INT_MASK);
2533
2534	irq = platform_get_irq(pdev, 0);
2535	ret = devm_request_threaded_irq(mhdp->dev, irq, NULL,
2536					cdns_mhdp_irq_handler, IRQF_ONESHOT,
2537					"mhdp8546", mhdp);
2538	if (ret) {
2539		dev_err(dev, "cannot install IRQ %d\n", irq);
2540		ret = -EIO;
2541		goto plat_fini;
2542	}
2543
2544	cdns_mhdp_fill_host_caps(mhdp);
2545
2546	/* Initialize link rate and num of lanes to host values */
2547	mhdp->link.rate = mhdp->host.link_rate;
2548	mhdp->link.num_lanes = mhdp->host.lanes_cnt;
2549
2550	/* The only currently supported format */
2551	mhdp->display_fmt.y_only = false;
2552	mhdp->display_fmt.color_format = DRM_COLOR_FORMAT_RGB444;
2553	mhdp->display_fmt.bpc = 8;
2554
2555	mhdp->bridge.of_node = pdev->dev.of_node;
2556	mhdp->bridge.funcs = &cdns_mhdp_bridge_funcs;
2557	mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
2558			   DRM_BRIDGE_OP_HPD;
2559	mhdp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
2560
2561	ret = phy_init(mhdp->phy);
2562	if (ret) {
2563		dev_err(mhdp->dev, "Failed to initialize PHY: %d\n", ret);
2564		goto plat_fini;
2565	}
2566
2567	/* Initialize the work for modeset in case of link train failure */
2568	INIT_WORK(&mhdp->modeset_retry_work, cdns_mhdp_modeset_retry_fn);
2569	INIT_WORK(&mhdp->hpd_work, cdns_mhdp_hpd_work);
2570
2571	init_waitqueue_head(&mhdp->fw_load_wq);
2572	init_waitqueue_head(&mhdp->sw_events_wq);
2573
2574	ret = cdns_mhdp_load_firmware(mhdp);
2575	if (ret)
2576		goto phy_exit;
2577
2578	if (mhdp->hdcp_supported)
2579		cdns_mhdp_hdcp_init(mhdp);
2580
2581	drm_bridge_add(&mhdp->bridge);
2582
2583	return 0;
2584
2585phy_exit:
2586	phy_exit(mhdp->phy);
2587plat_fini:
2588	if (mhdp->info && mhdp->info->ops && mhdp->info->ops->exit)
2589		mhdp->info->ops->exit(mhdp);
2590runtime_put:
2591	pm_runtime_put_sync(dev);
2592	pm_runtime_disable(dev);
2593clk_disable:
2594	clk_disable_unprepare(mhdp->clk);
2595
2596	return ret;
2597}
2598
2599static void cdns_mhdp_remove(struct platform_device *pdev)
2600{
2601	struct cdns_mhdp_device *mhdp = platform_get_drvdata(pdev);
2602	unsigned long timeout = msecs_to_jiffies(100);
2603	int ret;
2604
2605	drm_bridge_remove(&mhdp->bridge);
2606
2607	ret = wait_event_timeout(mhdp->fw_load_wq,
2608				 mhdp->hw_state == MHDP_HW_READY,
2609				 timeout);
2610	spin_lock(&mhdp->start_lock);
2611	mhdp->hw_state = MHDP_HW_STOPPED;
2612	spin_unlock(&mhdp->start_lock);
2613
2614	if (ret == 0) {
2615		dev_err(mhdp->dev, "%s: Timeout waiting for fw loading\n",
2616			__func__);
2617	} else {
2618		ret = cdns_mhdp_set_firmware_active(mhdp, false);
2619		if (ret)
2620			dev_err(mhdp->dev, "Failed to stop firmware (%pe)\n",
2621				ERR_PTR(ret));
2622	}
2623
2624	phy_exit(mhdp->phy);
2625
2626	if (mhdp->info && mhdp->info->ops && mhdp->info->ops->exit)
2627		mhdp->info->ops->exit(mhdp);
2628
2629	pm_runtime_put_sync(&pdev->dev);
2630	pm_runtime_disable(&pdev->dev);
2631
2632	cancel_work_sync(&mhdp->modeset_retry_work);
2633	flush_work(&mhdp->hpd_work);
2634	/* Ignoring mhdp->hdcp.check_work and mhdp->hdcp.prop_work here. */
2635
2636	clk_disable_unprepare(mhdp->clk);
2637}
2638
2639static const struct of_device_id mhdp_ids[] = {
2640	{ .compatible = "cdns,mhdp8546", },
2641#ifdef CONFIG_DRM_CDNS_MHDP8546_J721E
2642	{ .compatible = "ti,j721e-mhdp8546",
2643	  .data = &(const struct cdns_mhdp_platform_info) {
2644		  .input_bus_flags = &mhdp_ti_j721e_bridge_input_bus_flags,
2645		  .ops = &mhdp_ti_j721e_ops,
2646	  },
2647	},
2648#endif
2649	{ /* sentinel */ }
2650};
2651MODULE_DEVICE_TABLE(of, mhdp_ids);
2652
2653static struct platform_driver mhdp_driver = {
2654	.driver	= {
2655		.name		= "cdns-mhdp8546",
2656		.of_match_table	= mhdp_ids,
2657	},
2658	.probe	= cdns_mhdp_probe,
2659	.remove_new = cdns_mhdp_remove,
2660};
2661module_platform_driver(mhdp_driver);
2662
2663MODULE_FIRMWARE(FW_NAME);
2664
2665MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
2666MODULE_AUTHOR("Swapnil Jakhade <sjakhade@cadence.com>");
2667MODULE_AUTHOR("Yuti Amonkar <yamonkar@cadence.com>");
2668MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
2669MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
2670MODULE_DESCRIPTION("Cadence MHDP8546 DP bridge driver");
2671MODULE_LICENSE("GPL");
2672MODULE_ALIAS("platform:cdns-mhdp8546");