diff options
author | Daniel Golle <daniel@makrotopia.org> | 2022-03-21 01:16:48 +0000 |
---|---|---|
committer | Daniel Golle <daniel@makrotopia.org> | 2022-03-21 13:11:56 +0000 |
commit | 786bf7fdaca4c75e7eba6e9aa3a8b5775fd21186 (patch) | |
tree | 926fecb2b1f6ce1e42ba7ef4c7aab8e68dfd214c /target/linux/layerscape/patches-5.4/805-display-0003-drm-bridge-add-Cadence-MHDP-HDMI-DP-API.patch | |
parent | 9470160c350d15f765c33d6c1db15d6c4709a64c (diff) | |
download | upstream-786bf7fdaca4c75e7eba6e9aa3a8b5775fd21186.tar.gz upstream-786bf7fdaca4c75e7eba6e9aa3a8b5775fd21186.tar.bz2 upstream-786bf7fdaca4c75e7eba6e9aa3a8b5775fd21186.zip |
kernel: delete Linux 5.4 config and patches
As the upcoming release will be based on Linux 5.10 only, remove all
kernel configuration as well as patches for Linux 5.4.
There were no targets still actively using Linux 5.4.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
(cherry picked from commit 3a14580411adfb75f9a44eded9f41245b9e44606)
Diffstat (limited to 'target/linux/layerscape/patches-5.4/805-display-0003-drm-bridge-add-Cadence-MHDP-HDMI-DP-API.patch')
-rw-r--r-- | target/linux/layerscape/patches-5.4/805-display-0003-drm-bridge-add-Cadence-MHDP-HDMI-DP-API.patch | 4241 |
1 files changed, 0 insertions, 4241 deletions
diff --git a/target/linux/layerscape/patches-5.4/805-display-0003-drm-bridge-add-Cadence-MHDP-HDMI-DP-API.patch b/target/linux/layerscape/patches-5.4/805-display-0003-drm-bridge-add-Cadence-MHDP-HDMI-DP-API.patch deleted file mode 100644 index 14089a7b36..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0003-drm-bridge-add-Cadence-MHDP-HDMI-DP-API.patch +++ /dev/null @@ -1,4241 +0,0 @@ -From d94a1a8c31cab273b3409c9c380a8089a794f592 Mon Sep 17 00:00:00 2001 -From: Sandor Yu <Sandor.yu@nxp.com> -Date: Wed, 10 Jul 2019 14:22:12 +0800 -Subject: [PATCH] drm: bridge: add Cadence MHDP HDMI/DP API - -Changes made in the low level driver (cdn-dp-reg.*): -- moved it to from drivers/gpu/drm/rockchip to - drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c and - include/drm/bridge/cdns-mhdp-common.h -- functions for sending/receiving commands are now public -- added functions for reading registers and link training adjustment - -Changes made in RK's driver (cdn-dp-core.*): -- Moved audio_info and audio_pdev fields from cdn_dp_device to - cdns_mhdp_device structure. - -Signed-off-by: Quentin Schulz<quentin.schulz@free-electrons.com> -Signed-off-by: Piotr Sroka <piotrs@cadence.com> -Signed-off-by: Damian Kos <dkos@cadence.com> -Signed-off-by: Sandor Yu <Sandor.yu@nxp.com> ---- - drivers/gpu/drm/bridge/Kconfig | 2 + - drivers/gpu/drm/bridge/Makefile | 1 + - drivers/gpu/drm/bridge/cadence/Kconfig | 7 + - drivers/gpu/drm/bridge/cadence/Makefile | 3 + - drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 1165 +++++++++++++++++++++ - drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c | 296 ++++++ - drivers/gpu/drm/bridge/cadence/cdns-mhdp.h | 209 ++++ - drivers/gpu/drm/rockchip/Kconfig | 4 +- - drivers/gpu/drm/rockchip/Makefile | 2 +- - drivers/gpu/drm/rockchip/cdn-dp-core.c | 48 +- - drivers/gpu/drm/rockchip/cdn-dp-core.h | 5 +- - drivers/gpu/drm/rockchip/cdn-dp-reg.c | 968 ----------------- - drivers/gpu/drm/rockchip/cdn-dp-reg.h | 546 ---------- - include/drm/bridge/cdns-mhdp-cbs.h | 29 + - include/drm/bridge/cdns-mhdp-common.h | 704 +++++++++++++ - 15 files changed, 2446 insertions(+), 1543 deletions(-) - create mode 100644 drivers/gpu/drm/bridge/cadence/Kconfig - create mode 100644 drivers/gpu/drm/bridge/cadence/Makefile - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp.h - delete mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c - delete mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h - create mode 100644 include/drm/bridge/cdns-mhdp-cbs.h - create mode 100644 include/drm/bridge/cdns-mhdp-common.h - ---- a/drivers/gpu/drm/bridge/Kconfig -+++ b/drivers/gpu/drm/bridge/Kconfig -@@ -154,6 +154,8 @@ source "drivers/gpu/drm/bridge/analogix/ - - source "drivers/gpu/drm/bridge/adv7511/Kconfig" - -+source "drivers/gpu/drm/bridge/cadence/Kconfig" -+ - source "drivers/gpu/drm/bridge/synopsys/Kconfig" - - endmenu ---- a/drivers/gpu/drm/bridge/Makefile -+++ b/drivers/gpu/drm/bridge/Makefile -@@ -16,4 +16,5 @@ obj-$(CONFIG_DRM_ANALOGIX_DP) += analogi - obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ - obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o - obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o -+obj-y += cadence/ - obj-y += synopsys/ ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/Kconfig -@@ -0,0 +1,7 @@ -+config DRM_CDNS_MHDP -+ tristate "Cadence MHDP COMMON API driver" -+ select DRM_KMS_HELPER -+ select DRM_PANEL_BRIDGE -+ depends on OF -+ help -+ Support Cadence MHDP API library. ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/Makefile -@@ -0,0 +1,3 @@ -+#ccflags-y := -Iinclude/drm -+ -+obj-$(CONFIG_DRM_CDNS_MHDP) += cdns-mhdp-common.o cdns-mhdp-hdmi.o ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -@@ -0,0 +1,1165 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd -+ * Author: Chris Zhong <zyw@rock-chips.com> -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/clk.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <linux/io.h> -+#include <linux/iopoll.h> -+#include <linux/reset.h> -+ -+#include <asm/unaligned.h> -+ -+#include <drm/bridge/cdns-mhdp-common.h> -+#include <drm/drm_modes.h> -+#include <drm/drm_print.h> -+ -+#define CDNS_DP_SPDIF_CLK 200000000 -+#define FW_ALIVE_TIMEOUT_US 1000000 -+#define MAILBOX_RETRY_US 1000 -+#define MAILBOX_TIMEOUT_US 5000000 -+#define LINK_TRAINING_RETRY_MS 20 -+#define LINK_TRAINING_TIMEOUT_MS 500 -+ -+static inline u32 get_unaligned_be24(const void *p) -+{ -+ const u8 *_p = p; -+ -+ return _p[0] << 16 | _p[1] << 8 | _p[2]; -+} -+ -+static inline void put_unaligned_be24(u32 val, void *p) -+{ -+ u8 *_p = p; -+ -+ _p[0] = val >> 16; -+ _p[1] = val >> 8; -+ _p[2] = val; -+} -+ -+void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk) -+{ -+ writel(clk / 1000000, mhdp->regs + SW_CLK_H); -+} -+EXPORT_SYMBOL(cdns_mhdp_set_fw_clk); -+ -+void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val; -+ -+ val = DPTX_FRMR_DATA_CLK_RSTN_EN | -+ DPTX_FRMR_DATA_CLK_EN | -+ DPTX_PHY_DATA_RSTN_EN | -+ DPTX_PHY_DATA_CLK_EN | -+ DPTX_PHY_CHAR_RSTN_EN | -+ DPTX_PHY_CHAR_CLK_EN | -+ SOURCE_AUX_SYS_CLK_RSTN_EN | -+ SOURCE_AUX_SYS_CLK_EN | -+ DPTX_SYS_CLK_RSTN_EN | -+ DPTX_SYS_CLK_EN | -+ CFG_DPTX_VIF_CLK_RSTN_EN | -+ CFG_DPTX_VIF_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_DPTX_CAR); -+ -+ val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_PHY_CAR); -+ -+ val = SOURCE_PKT_SYS_RSTN_EN | -+ SOURCE_PKT_SYS_CLK_EN | -+ SOURCE_PKT_DATA_RSTN_EN | -+ SOURCE_PKT_DATA_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_PKT_CAR); -+ -+ val = SPDIF_CDR_CLK_RSTN_EN | -+ SPDIF_CDR_CLK_EN | -+ SOURCE_AIF_SYS_RSTN_EN | -+ SOURCE_AIF_SYS_CLK_EN | -+ SOURCE_AIF_CLK_RSTN_EN | -+ SOURCE_AIF_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_AIF_CAR); -+ -+ val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN | -+ SOURCE_CIPHER_SYS_CLK_EN | -+ SOURCE_CIPHER_CHAR_CLK_RSTN_EN | -+ SOURCE_CIPHER_CHAR_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_CIPHER_CAR); -+ -+ val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN | -+ SOURCE_CRYPTO_SYS_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_CRYPTO_CAR); -+ -+ /* enable Mailbox and PIF interrupt */ -+ writel(0, mhdp->regs + APB_INT_MASK); -+} -+EXPORT_SYMBOL(cdns_mhdp_clock_reset); -+ -+int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp) -+{ -+ int val, ret; -+ -+ ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_EMPTY_ADDR, -+ val, !val, MAILBOX_RETRY_US, -+ MAILBOX_TIMEOUT_US); -+ if (ret < 0) -+ return ret; -+ -+ return readl(mhdp->regs + MAILBOX0_RD_DATA) & 0xff; -+} -+EXPORT_SYMBOL(cdns_mhdp_mailbox_read); -+ -+static int cdp_dp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val) -+{ -+ int ret, full; -+ -+ ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_FULL_ADDR, -+ full, !full, MAILBOX_RETRY_US, -+ MAILBOX_TIMEOUT_US); -+ if (ret < 0) -+ return ret; -+ -+ writel(val, mhdp->regs + MAILBOX0_WR_DATA); -+ -+ return 0; -+} -+ -+int cdns_mhdp_mailbox_validate_receive(struct cdns_mhdp_device *mhdp, -+ u8 module_id, u8 opcode, -+ u16 req_size) -+{ -+ u32 mbox_size, i; -+ u8 header[4]; -+ int ret; -+ -+ /* read the header of the message */ -+ for (i = 0; i < 4; i++) { -+ ret = cdns_mhdp_mailbox_read(mhdp); -+ if (ret < 0) -+ return ret; -+ -+ header[i] = ret; -+ } -+ -+ mbox_size = get_unaligned_be16(header + 2); -+ -+ if (opcode != header[0] || module_id != header[1] || -+ req_size != mbox_size) { -+ /* -+ * If the message in mailbox is not what we want, we need to -+ * clear the mailbox by reading its contents. -+ */ -+ for (i = 0; i < mbox_size; i++) -+ if (cdns_mhdp_mailbox_read(mhdp) < 0) -+ break; -+ -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(cdns_mhdp_mailbox_validate_receive); -+ -+int cdns_mhdp_mailbox_read_receive(struct cdns_mhdp_device *mhdp, -+ u8 *buff, u16 buff_size) -+{ -+ u32 i; -+ int ret; -+ -+ for (i = 0; i < buff_size; i++) { -+ ret = cdns_mhdp_mailbox_read(mhdp); -+ if (ret < 0) -+ return ret; -+ -+ buff[i] = ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(cdns_mhdp_mailbox_read_receive); -+ -+int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id, -+ u8 opcode, u16 size, u8 *message) -+{ -+ u8 header[4]; -+ int ret, i; -+ -+ header[0] = opcode; -+ header[1] = module_id; -+ put_unaligned_be16(size, header + 2); -+ -+ for (i = 0; i < 4; i++) { -+ ret = cdp_dp_mailbox_write(mhdp, header[i]); -+ if (ret) -+ return ret; -+ } -+ -+ for (i = 0; i < size; i++) { -+ ret = cdp_dp_mailbox_write(mhdp, message[i]); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(cdns_mhdp_mailbox_send); -+ -+int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr) -+{ -+ u8 msg[4], resp[8]; -+ u32 val; -+ int ret; -+ -+ if (addr == 0) { -+ ret = -EINVAL; -+ goto err_reg_read; -+ } -+ -+ put_unaligned_be32(addr, msg); -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL, -+ GENERAL_READ_REGISTER, -+ sizeof(msg), msg); -+ if (ret) -+ goto err_reg_read; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_GENERAL, -+ GENERAL_READ_REGISTER, -+ sizeof(resp)); -+ if (ret) -+ goto err_reg_read; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, resp, sizeof(resp)); -+ if (ret) -+ goto err_reg_read; -+ -+ /* Returned address value should be the same as requested */ -+ if (memcmp(msg, resp, sizeof(msg))) { -+ ret = -EINVAL; -+ goto err_reg_read; -+ } -+ -+ val = get_unaligned_be32(resp + 4); -+ -+ return val; -+err_reg_read: -+ DRM_DEV_ERROR(mhdp->dev, "Failed to read register.\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_reg_read); -+ -+int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u32 addr, u32 val) -+{ -+ u8 msg[8]; -+ -+ put_unaligned_be32(addr, msg); -+ put_unaligned_be32(val, msg + 4); -+ -+ return cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL, -+ GENERAL_WRITE_REGISTER, sizeof(msg), msg); -+} -+EXPORT_SYMBOL(cdns_mhdp_reg_write); -+ -+int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr, -+ u8 start_bit, u8 bits_no, u32 val) -+{ -+ u8 field[8]; -+ -+ put_unaligned_be16(addr, field); -+ field[2] = start_bit; -+ field[3] = bits_no; -+ put_unaligned_be32(val, field + 4); -+ -+ return cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_FIELD, sizeof(field), field); -+} -+EXPORT_SYMBOL(cdns_mhdp_reg_write_bit); -+ -+int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp, -+ u32 addr, u8 *data, u16 len) -+{ -+ u8 msg[5], reg[5]; -+ int ret; -+ -+ put_unaligned_be16(len, msg); -+ put_unaligned_be24(addr, msg + 2); -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_DPCD, sizeof(msg), msg); -+ if (ret) -+ goto err_dpcd_read; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_DPCD, -+ sizeof(reg) + len); -+ if (ret) -+ goto err_dpcd_read; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ goto err_dpcd_read; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, data, len); -+ -+err_dpcd_read: -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_dpcd_read); -+ -+int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value) -+{ -+ u8 msg[6], reg[5]; -+ int ret; -+ -+ put_unaligned_be16(1, msg); -+ put_unaligned_be24(addr, msg + 2); -+ msg[5] = value; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_DPCD, sizeof(msg), msg); -+ if (ret) -+ goto err_dpcd_write; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_DPCD, sizeof(reg)); -+ if (ret) -+ goto err_dpcd_write; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ goto err_dpcd_write; -+ -+ if (addr != get_unaligned_be24(reg + 2)) -+ ret = -EINVAL; -+ -+err_dpcd_write: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "dpcd write failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_dpcd_write); -+ -+int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, -+ u32 i_size, const u32 *d_mem, u32 d_size) -+{ -+ u32 reg; -+ int i, ret; -+ -+ /* reset ucpu before load firmware*/ -+ writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET, -+ mhdp->regs + APB_CTRL); -+ -+ for (i = 0; i < i_size; i += 4) -+ writel(*i_mem++, mhdp->regs + ADDR_IMEM + i); -+ -+ for (i = 0; i < d_size; i += 4) -+ writel(*d_mem++, mhdp->regs + ADDR_DMEM + i); -+ -+ /* un-reset ucpu */ -+ writel(0, mhdp->regs + APB_CTRL); -+ -+ /* check the keep alive register to make sure fw working */ -+ ret = readx_poll_timeout(readl, mhdp->regs + KEEP_ALIVE, -+ reg, reg, 2000, FW_ALIVE_TIMEOUT_US); -+ if (ret < 0) { -+ DRM_DEV_ERROR(mhdp->dev, "failed to loaded the FW reg = %x\n", -+ reg); -+ return -EINVAL; -+ } -+ -+ reg = readl(mhdp->regs + VER_L) & 0xff; -+ mhdp->fw_version = reg; -+ reg = readl(mhdp->regs + VER_H) & 0xff; -+ mhdp->fw_version |= reg << 8; -+ reg = readl(mhdp->regs + VER_LIB_L_ADDR) & 0xff; -+ mhdp->fw_version |= reg << 16; -+ reg = readl(mhdp->regs + VER_LIB_H_ADDR) & 0xff; -+ mhdp->fw_version |= reg << 24; -+ -+ DRM_DEV_DEBUG(mhdp->dev, "firmware version: %x\n", mhdp->fw_version); -+ -+ return 0; -+} -+EXPORT_SYMBOL(cdns_mhdp_load_firmware); -+ -+int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable) -+{ -+ u8 msg[5]; -+ int ret, i; -+ -+ msg[0] = GENERAL_MAIN_CONTROL; -+ msg[1] = MB_MODULE_ID_GENERAL; -+ msg[2] = 0; -+ msg[3] = 1; -+ msg[4] = enable ? FW_ACTIVE : FW_STANDBY; -+ -+ for (i = 0; i < sizeof(msg); i++) { -+ ret = cdp_dp_mailbox_write(mhdp, msg[i]); -+ if (ret) -+ goto err_set_firmware_active; -+ } -+ -+ /* read the firmware state */ -+ for (i = 0; i < sizeof(msg); i++) { -+ ret = cdns_mhdp_mailbox_read(mhdp); -+ if (ret < 0) -+ goto err_set_firmware_active; -+ -+ msg[i] = ret; -+ } -+ -+ ret = 0; -+ -+err_set_firmware_active: -+ if (ret < 0) -+ DRM_DEV_ERROR(mhdp->dev, "set firmware active failed\n"); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_set_firmware_active); -+ -+int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip) -+{ -+ u8 msg[8]; -+ int ret; -+ -+ msg[0] = CDNS_DP_MAX_LINK_RATE; -+ msg[1] = lanes | SCRAMBLER_EN; -+ msg[2] = VOLTAGE_LEVEL_2; -+ msg[3] = PRE_EMPHASIS_LEVEL_3; -+ msg[4] = PTS1 | PTS2 | PTS3 | PTS4; -+ msg[5] = FAST_LT_NOT_SUPPORT; -+ msg[6] = flip ? LANE_MAPPING_FLIPPED : LANE_MAPPING_NORMAL; -+ msg[7] = ENHANCED; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_SET_HOST_CAPABILITIES, -+ sizeof(msg), msg); -+ if (ret) -+ goto err_set_host_cap; -+ -+/* TODO Sandor */ -+// ret = cdns_mhdp_reg_write(mhdp, DP_AUX_SWAP_INVERSION_CONTROL, -+// AUX_HOST_INVERT); -+ -+err_set_host_cap: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "set host cap failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_set_host_cap); -+ -+int cdns_mhdp_event_config(struct cdns_mhdp_device *mhdp) -+{ -+ u8 msg[5]; -+ int ret; -+ -+ memset(msg, 0, sizeof(msg)); -+ -+ msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_ENABLE_EVENT, sizeof(msg), msg); -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "set event config failed: %d\n", ret); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_event_config); -+ -+u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp) -+{ -+ return readl(mhdp->regs + SW_EVENTS0); -+} -+EXPORT_SYMBOL(cdns_mhdp_get_event); -+ -+int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp) -+{ -+ u8 status; -+ int ret; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_HPD_STATE, 0, NULL); -+ if (ret) -+ goto err_get_hpd; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_HPD_STATE, -+ sizeof(status)); -+ if (ret) -+ goto err_get_hpd; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, &status, sizeof(status)); -+ if (ret) -+ goto err_get_hpd; -+ -+ return status; -+ -+err_get_hpd: -+ DRM_DEV_ERROR(mhdp->dev, "get hpd status failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_get_hpd_status); -+ -+int cdns_mhdp_get_edid_block(void *data, u8 *edid, -+ unsigned int block, size_t length) -+{ -+ struct cdns_mhdp_device *mhdp = data; -+ u8 msg[2], reg[2], i; -+ int ret; -+ -+ for (i = 0; i < 4; i++) { -+ msg[0] = block / 2; -+ msg[1] = block % 2; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_GET_EDID, sizeof(msg), msg); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, -+ MB_MODULE_ID_DP_TX, -+ DPTX_GET_EDID, -+ sizeof(reg) + length); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, edid, length); -+ if (ret) -+ continue; -+ -+ if (reg[0] == length && reg[1] == block / 2) -+ break; -+ } -+ -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "get block[%d] edid failed: %d\n", -+ block, ret); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_get_edid_block); -+ -+static int cdns_mhdp_training_start(struct cdns_mhdp_device *mhdp) -+{ -+ unsigned long timeout; -+ u8 msg, event[2]; -+ int ret; -+ -+ msg = LINK_TRAINING_RUN; -+ -+ /* start training */ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_TRAINING_CONTROL, sizeof(msg), &msg); -+ if (ret) -+ goto err_training_start; -+ -+ timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS); -+ while (time_before(jiffies, timeout)) { -+ msleep(LINK_TRAINING_RETRY_MS); -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_EVENT, 0, NULL); -+ if (ret) -+ goto err_training_start; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, -+ MB_MODULE_ID_DP_TX, -+ DPTX_READ_EVENT, -+ sizeof(event)); -+ if (ret) -+ goto err_training_start; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, event, -+ sizeof(event)); -+ if (ret) -+ goto err_training_start; -+ -+ if (event[1] & EQ_PHASE_FINISHED) -+ return 0; -+ } -+ -+ ret = -ETIMEDOUT; -+ -+err_training_start: -+ DRM_DEV_ERROR(mhdp->dev, "training failed: %d\n", ret); -+ return ret; -+} -+ -+static int cdns_mhdp_get_training_status(struct cdns_mhdp_device *mhdp) -+{ -+ u8 status[10]; -+ int ret; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_LINK_STAT, 0, NULL); -+ if (ret) -+ goto err_get_training_status; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_LINK_STAT, -+ sizeof(status)); -+ if (ret) -+ goto err_get_training_status; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, status, sizeof(status)); -+ if (ret) -+ goto err_get_training_status; -+ -+ mhdp->dp.link.rate = drm_dp_bw_code_to_link_rate(status[0]); -+ mhdp->dp.link.num_lanes = status[1]; -+ -+err_get_training_status: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "get training status failed: %d\n", -+ ret); -+ return ret; -+} -+ -+int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp) -+{ -+ int ret; -+ -+ ret = cdns_mhdp_training_start(mhdp); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "Failed to start training %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = cdns_mhdp_get_training_status(mhdp); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "Failed to get training stat %d\n", -+ ret); -+ return ret; -+ } -+ -+ DRM_DEV_DEBUG_KMS(mhdp->dev, "rate:0x%x, lanes:%d\n", mhdp->dp.link.rate, -+ mhdp->dp.link.num_lanes); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_train_link); -+ -+int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active) -+{ -+ u8 msg; -+ int ret; -+ -+ msg = !!active; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_SET_VIDEO, sizeof(msg), &msg); -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "set video status failed: %d\n", ret); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_set_video_status); -+ -+static int cdns_mhdp_get_msa_misc(struct video_info *video, -+ struct drm_display_mode *mode) -+{ -+ u32 msa_misc; -+ u8 val[2] = {0}; -+ -+ switch (video->color_fmt) { -+ case PXL_RGB: -+ case Y_ONLY: -+ val[0] = 0; -+ break; -+ /* set YUV default color space conversion to BT601 */ -+ case YCBCR_4_4_4: -+ val[0] = 6 + BT_601 * 8; -+ break; -+ case YCBCR_4_2_2: -+ val[0] = 5 + BT_601 * 8; -+ break; -+ case YCBCR_4_2_0: -+ val[0] = 5; -+ break; -+ }; -+ -+ switch (video->color_depth) { -+ case 6: -+ val[1] = 0; -+ break; -+ case 8: -+ val[1] = 1; -+ break; -+ case 10: -+ val[1] = 2; -+ break; -+ case 12: -+ val[1] = 3; -+ break; -+ case 16: -+ val[1] = 4; -+ break; -+ }; -+ -+ msa_misc = 2 * val[0] + 32 * val[1] + -+ ((video->color_fmt == Y_ONLY) ? (1 << 14) : 0); -+ -+ return msa_misc; -+} -+ -+int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp) -+{ -+ struct video_info *video = &mhdp->video_info; -+ struct drm_display_mode *mode = &mhdp->mode; -+ u64 symbol; -+ u32 val, link_rate, rem; -+ u8 bit_per_pix, tu_size_reg = TU_SIZE; -+ int ret; -+ -+ bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ? -+ (video->color_depth * 2) : (video->color_depth * 3); -+ -+ link_rate = mhdp->dp.link.rate / 1000; -+ -+ ret = cdns_mhdp_reg_write(mhdp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE); -+ if (ret) -+ goto err_config_video; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HSYNC2VSYNC_POL_CTRL, 0); -+ if (ret) -+ goto err_config_video; -+ -+ /* -+ * get a best tu_size and valid symbol: -+ * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32 -+ * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes) -+ * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set -+ * TU += 2 and repeat 2nd step. -+ */ -+ do { -+ tu_size_reg += 2; -+ symbol = tu_size_reg * mode->clock * bit_per_pix; -+ do_div(symbol, mhdp->dp.link.num_lanes * link_rate * 8); -+ rem = do_div(symbol, 1000); -+ if (tu_size_reg > 64) { -+ ret = -EINVAL; -+ DRM_DEV_ERROR(mhdp->dev, -+ "tu error, clk:%d, lanes:%d, rate:%d\n", -+ mode->clock, mhdp->dp.link.num_lanes, -+ link_rate); -+ goto err_config_video; -+ } -+ } while ((symbol <= 1) || (tu_size_reg - symbol < 4) || -+ (rem > 850) || (rem < 100)); -+ -+ val = symbol + (tu_size_reg << 8); -+ val |= TU_CNT_RST_EN; -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_TU, val); -+ if (ret) -+ goto err_config_video; -+ -+ /* set the FIFO Buffer size */ -+ val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate; -+ val /= (mhdp->dp.link.num_lanes * link_rate); -+ val = div_u64(8 * (symbol + 1), bit_per_pix) - val; -+ val += 2; -+ ret = cdns_mhdp_reg_write(mhdp, DP_VC_TABLE(15), val); -+ -+ switch (video->color_depth) { -+ case 6: -+ val = BCS_6; -+ break; -+ case 8: -+ val = BCS_8; -+ break; -+ case 10: -+ val = BCS_10; -+ break; -+ case 12: -+ val = BCS_12; -+ break; -+ case 16: -+ val = BCS_16; -+ break; -+ }; -+ -+ val += video->color_fmt << 8; -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_PXL_REPR, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0; -+ val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0; -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_SP, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = (mode->hsync_start - mode->hdisplay) << 16; -+ val |= mode->htotal - mode->hsync_end; -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRONT_BACK_PORCH, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->hdisplay * bit_per_pix / 8; -+ ret = cdns_mhdp_reg_write(mhdp, DP_BYTE_COUNT, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_HORIZONTAL_0, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->hsync_end - mode->hsync_start; -+ val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_HORIZONTAL_1, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vtotal; -+ val |= (mode->vtotal - mode->vsync_start) << 16; -+ ret = cdns_mhdp_reg_write(mhdp, MSA_VERTICAL_0, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vsync_end - mode->vsync_start; -+ val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_VERTICAL_1, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = cdns_mhdp_get_msa_misc(video, mode); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_MISC, val); -+ if (ret) -+ goto err_config_video; -+ -+ ret = cdns_mhdp_reg_write(mhdp, STREAM_CONFIG, 1); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->hsync_end - mode->hsync_start; -+ val |= mode->hdisplay << 16; -+ ret = cdns_mhdp_reg_write(mhdp, DP_HORIZONTAL, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vdisplay; -+ val |= (mode->vtotal - mode->vsync_start) << 16; -+ ret = cdns_mhdp_reg_write(mhdp, DP_VERTICAL_0, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vtotal; -+ ret = cdns_mhdp_reg_write(mhdp, DP_VERTICAL_1, val); -+ if (ret) -+ goto err_config_video; -+ -+ ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 2, 1, 0); -+ -+err_config_video: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "config video failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_config_video); -+ -+int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) -+{ -+ int ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, 0); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "audio stop failed: %d\n", ret); -+ return ret; -+ } -+ -+ writel(0, mhdp->regs + SPDIF_CTRL_ADDR); -+ -+ /* clearn the audio config and reset */ -+ writel(0, mhdp->regs + AUDIO_SRC_CNTL); -+ writel(0, mhdp->regs + AUDIO_SRC_CNFG); -+ writel(AUDIO_SW_RST, mhdp->regs + AUDIO_SRC_CNTL); -+ writel(0, mhdp->regs + AUDIO_SRC_CNTL); -+ -+ /* reset smpl2pckt component */ -+ writel(0, mhdp->regs + SMPL2PKT_CNTL); -+ writel(AUDIO_SW_RST, mhdp->regs + SMPL2PKT_CNTL); -+ writel(0, mhdp->regs + SMPL2PKT_CNTL); -+ -+ /* reset FIFO */ -+ writel(AUDIO_SW_RST, mhdp->regs + FIFO_CNTL); -+ writel(0, mhdp->regs + FIFO_CNTL); -+ -+ if (audio->format == AFMT_SPDIF) -+ clk_disable_unprepare(mhdp->spdif_clk); -+ -+ return 0; -+} -+EXPORT_SYMBOL(cdns_mhdp_audio_stop); -+ -+int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable) -+{ -+ int ret; -+ -+ ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 4, 1, enable); -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "audio mute failed: %d\n", ret); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_audio_mute); -+ -+static void cdns_mhdp_audio_config_i2s(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) -+{ -+ int sub_pckt_num = 1, i2s_port_en_val = 0xf, i; -+ u32 val; -+ -+ if (audio->channels == 2) { -+ if (mhdp->dp.link.num_lanes == 1) -+ sub_pckt_num = 2; -+ else -+ sub_pckt_num = 4; -+ -+ i2s_port_en_val = 1; -+ } else if (audio->channels == 4) { -+ i2s_port_en_val = 3; -+ } -+ -+ writel(0x0, mhdp->regs + SPDIF_CTRL_ADDR); -+ -+ writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); -+ -+ val = MAX_NUM_CH(audio->channels); -+ val |= NUM_OF_I2S_PORTS(audio->channels); -+ val |= AUDIO_TYPE_LPCM; -+ val |= CFG_SUB_PCKT_NUM(sub_pckt_num); -+ writel(val, mhdp->regs + SMPL2PKT_CNFG); -+ -+ if (audio->sample_width == 16) -+ val = 0; -+ else if (audio->sample_width == 24) -+ val = 1 << 9; -+ else -+ val = 2 << 9; -+ -+ val |= AUDIO_CH_NUM(audio->channels); -+ val |= I2S_DEC_PORT_EN(i2s_port_en_val); -+ val |= TRANS_SMPL_WIDTH_32; -+ writel(val, mhdp->regs + AUDIO_SRC_CNFG); -+ -+ for (i = 0; i < (audio->channels + 1) / 2; i++) { -+ if (audio->sample_width == 16) -+ val = (0x02 << 8) | (0x02 << 20); -+ else if (audio->sample_width == 24) -+ val = (0x0b << 8) | (0x0b << 20); -+ -+ val |= ((2 * i) << 4) | ((2 * i + 1) << 16); -+ writel(val, mhdp->regs + STTS_BIT_CH(i)); -+ } -+ -+ switch (audio->sample_rate) { -+ case 32000: -+ val = SAMPLING_FREQ(3) | -+ ORIGINAL_SAMP_FREQ(0xc); -+ break; -+ case 44100: -+ val = SAMPLING_FREQ(0) | -+ ORIGINAL_SAMP_FREQ(0xf); -+ break; -+ case 48000: -+ val = SAMPLING_FREQ(2) | -+ ORIGINAL_SAMP_FREQ(0xd); -+ break; -+ case 88200: -+ val = SAMPLING_FREQ(8) | -+ ORIGINAL_SAMP_FREQ(0x7); -+ break; -+ case 96000: -+ val = SAMPLING_FREQ(0xa) | -+ ORIGINAL_SAMP_FREQ(5); -+ break; -+ case 176400: -+ val = SAMPLING_FREQ(0xc) | -+ ORIGINAL_SAMP_FREQ(3); -+ break; -+ case 192000: -+ val = SAMPLING_FREQ(0xe) | -+ ORIGINAL_SAMP_FREQ(1); -+ break; -+ } -+ val |= 4; -+ writel(val, mhdp->regs + COM_CH_STTS_BITS); -+ -+ writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); -+ writel(I2S_DEC_START, mhdp->regs + AUDIO_SRC_CNTL); -+} -+ -+static void cdns_mhdp_audio_config_spdif(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val; -+ -+ writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); -+ -+ val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4); -+ writel(val, mhdp->regs + SMPL2PKT_CNFG); -+ writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); -+ -+ val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS; -+ writel(val, mhdp->regs + SPDIF_CTRL_ADDR); -+ -+ clk_prepare_enable(mhdp->spdif_clk); -+ clk_set_rate(mhdp->spdif_clk, CDNS_DP_SPDIF_CLK); -+} -+ -+int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) -+{ -+ int ret; -+ -+ /* reset the spdif clk before config */ -+ if (audio->format == AFMT_SPDIF) { -+ reset_control_assert(mhdp->spdif_rst); -+ reset_control_deassert(mhdp->spdif_rst); -+ } -+ -+ ret = cdns_mhdp_reg_write(mhdp, CM_LANE_CTRL, LANE_REF_CYC); -+ if (ret) -+ goto err_audio_config; -+ -+ ret = cdns_mhdp_reg_write(mhdp, CM_CTRL, 0); -+ if (ret) -+ goto err_audio_config; -+ -+ if (audio->format == AFMT_I2S) -+ cdns_mhdp_audio_config_i2s(mhdp, audio); -+ else if (audio->format == AFMT_SPDIF) -+ cdns_mhdp_audio_config_spdif(mhdp); -+ -+ ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN); -+ -+err_audio_config: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "audio config failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_audio_config); -+ -+int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, -+ u8 nlanes, u16 udelay, u8 *lanes_data, u8 *dpcd) -+{ -+ u8 payload[7]; -+ u8 hdr[5]; /* For DPCD read response header */ -+ u32 addr; -+ u8 const nregs = 6; /* Registers 0x202-0x207 */ -+ int ret; -+ -+ if (nlanes != 4 && nlanes != 2 && nlanes != 1) { -+ DRM_DEV_ERROR(mhdp->dev, "invalid number of lanes: %d\n", -+ nlanes); -+ ret = -EINVAL; -+ goto err_adjust_lt; -+ } -+ -+ payload[0] = nlanes; -+ put_unaligned_be16(udelay, payload + 1); -+ memcpy(payload + 3, lanes_data, nlanes); -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_ADJUST_LT, -+ sizeof(payload), payload); -+ if (ret) -+ goto err_adjust_lt; -+ -+ /* Yes, read the DPCD read command response */ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_DPCD, -+ sizeof(hdr) + nregs); -+ if (ret) -+ goto err_adjust_lt; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, hdr, sizeof(hdr)); -+ if (ret) -+ goto err_adjust_lt; -+ -+ addr = get_unaligned_be24(hdr + 2); -+ if (addr != DP_LANE0_1_STATUS) -+ goto err_adjust_lt; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, dpcd, nregs); -+ -+err_adjust_lt: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "Failed to adjust Link Training.\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_adjust_lt); -+ -+int cdns_phy_reg_write(struct cdns_mhdp_device *mhdp, u32 addr, u32 val) -+{ -+ return cdns_mhdp_reg_write(mhdp, ADDR_PHY_AFE + (addr << 2), val); -+} -+EXPORT_SYMBOL(cdns_phy_reg_write); -+ -+u32 cdns_phy_reg_read(struct cdns_mhdp_device *mhdp, u32 addr) -+{ -+ return cdns_mhdp_reg_read(mhdp, ADDR_PHY_AFE + (addr << 2)); -+} -+EXPORT_SYMBOL(cdns_phy_reg_read); -+ -+int cdns_mhdp_read_hpd(struct cdns_mhdp_device *mhdp) -+{ -+ u8 status; -+ int ret; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL, GENERAL_GET_HPD_STATE, -+ 0, NULL); -+ if (ret) -+ goto err_get_hpd; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_GENERAL, -+ GENERAL_GET_HPD_STATE, sizeof(status)); -+ if (ret) -+ goto err_get_hpd; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, &status, sizeof(status)); -+ if (ret) -+ goto err_get_hpd; -+ -+ return status; -+ -+err_get_hpd: -+ DRM_ERROR("read hpd failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_read_hpd); -+ -+bool cdns_mhdp_check_alive(struct cdns_mhdp_device *mhdp) -+{ -+ u32 alive, newalive; -+ u8 retries_left = 10; -+ -+ alive = readl(mhdp->regs + KEEP_ALIVE); -+ -+ while (retries_left--) { -+ udelay(2); -+ -+ newalive = readl(mhdp->regs + KEEP_ALIVE); -+ if (alive == newalive) -+ continue; -+ return true; -+ } -+ return false; -+} -+EXPORT_SYMBOL(cdns_mhdp_check_alive); ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c -@@ -0,0 +1,296 @@ -+/* -+ * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#include <drm/drmP.h> -+#include <linux/io.h> -+#include <drm/bridge/cdns-mhdp-common.h> -+ -+int cdns_hdmi_get_edid_block(void *data, u8 *edid, -+ u32 block, size_t length) -+{ -+ struct cdns_mhdp_device *mhdp = data; -+ u8 msg[2], reg[5], i; -+ int ret; -+ -+ for (i = 0; i < 4; i++) { -+ msg[0] = block / 2; -+ msg[1] = block % 2; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX, HDMI_TX_EDID, -+ sizeof(msg), msg); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_HDMI_TX, -+ HDMI_TX_EDID, sizeof(reg) + length); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, edid, length); -+ if (ret) -+ continue; -+ -+ if ((reg[3] << 8 | reg[4]) == length) -+ break; -+ } -+ -+ if (ret) -+ DRM_ERROR("get block[%d] edid failed: %d\n", block, ret); -+ return ret; -+} -+ -+int cdns_hdmi_scdc_read(struct cdns_mhdp_device *mhdp, u8 addr, u8 *data) -+{ -+ u8 msg[4], reg[6]; -+ int ret; -+ -+ msg[0] = 0x54; -+ msg[1] = addr; -+ msg[2] = 0; -+ msg[3] = 1; -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX, HDMI_TX_READ, -+ sizeof(msg), msg); -+ if (ret) -+ goto err_scdc_read; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_HDMI_TX, -+ HDMI_TX_READ, sizeof(reg)); -+ if (ret) -+ goto err_scdc_read; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ goto err_scdc_read; -+ -+ *data = reg[5]; -+ -+err_scdc_read: -+ if (ret) -+ DRM_ERROR("scdc read failed: %d\n", ret); -+ return ret; -+} -+ -+int cdns_hdmi_scdc_write(struct cdns_mhdp_device *mhdp, u8 addr, u8 value) -+{ -+ u8 msg[5], reg[5]; -+ int ret; -+ -+ msg[0] = 0x54; -+ msg[1] = addr; -+ msg[2] = 0; -+ msg[3] = 1; -+ msg[4] = value; -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE, -+ sizeof(msg), msg); -+ if (ret) -+ goto err_scdc_write; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_HDMI_TX, -+ HDMI_TX_WRITE, sizeof(reg)); -+ if (ret) -+ goto err_scdc_write; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ goto err_scdc_write; -+ -+ if (reg[0] != 0) -+ ret = -EINVAL; -+ -+err_scdc_write: -+ if (ret) -+ DRM_ERROR("scdc write failed: %d\n", ret); -+ return ret; -+} -+ -+int cdns_hdmi_ctrl_init(struct cdns_mhdp_device *mhdp, -+ int protocol, -+ u32 char_rate) -+{ -+ u32 reg0; -+ u32 reg1; -+ u32 val; -+ int ret; -+ -+ /* Set PHY to HDMI data */ -+ ret = cdns_mhdp_reg_write(mhdp, PHY_DATA_SEL, F_SOURCE_PHY_MHDP_SEL(1)); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_HPD, -+ F_HPD_VALID_WIDTH(4) | F_HPD_GLITCH_WIDTH(0)); -+ if (ret < 0) -+ return ret; -+ -+ /* open CARS */ -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_PHY_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_HDTX_CAR, 0xFF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_PKT_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_AIF_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_CIPHER_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_CRYPTO_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_CEC_CAR, 3); -+ if (ret < 0) -+ return ret; -+ -+ reg0 = reg1 = 0x7c1f; -+ if (protocol == MODE_HDMI_2_0 && char_rate >= 340000) { -+ reg0 = 0; -+ reg1 = 0xFFFFF; -+ } -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CLOCK_REG_0, reg0); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CLOCK_REG_1, reg1); -+ if (ret < 0) -+ return ret; -+ -+ /* set hdmi mode and preemble mode data enable */ -+ val = F_HDMI_MODE(protocol) | F_HDMI2_PREAMBLE_EN(1) | F_DATA_EN(1) | -+ F_HDMI2_CTRL_IL_MODE(1) | F_BCH_EN(1) | F_PIC_3D(0XF); -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+ -+ return ret; -+} -+ -+int cdns_hdmi_mode_config(struct cdns_mhdp_device *mhdp, -+ struct drm_display_mode *mode, -+ struct video_info *video_info) -+{ -+ int ret; -+ u32 val; -+ u32 vsync_lines = mode->vsync_end - mode->vsync_start; -+ u32 eof_lines = mode->vsync_start - mode->vdisplay; -+ u32 sof_lines = mode->vtotal - mode->vsync_end; -+ u32 hblank = mode->htotal - mode->hdisplay; -+ u32 hactive = mode->hdisplay; -+ u32 vblank = mode->vtotal - mode->vdisplay; -+ u32 vactive = mode->vdisplay; -+ u32 hfront = mode->hsync_start - mode->hdisplay; -+ u32 hback = mode->htotal - mode->hsync_end; -+ u32 vfront = eof_lines; -+ u32 hsync = hblank - hfront - hback; -+ u32 vsync = vsync_lines; -+ u32 vback = sof_lines; -+ u32 v_h_polarity = ((mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1) + -+ ((mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : 2); -+ -+ ret = cdns_mhdp_reg_write(mhdp, SCHEDULER_H_SIZE, (hactive << 16) + hblank); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, SCHEDULER_V_SIZE, (vactive << 16) + vblank); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_FRONT_WIDTH, (vfront << 16) + hfront); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_SYNC_WIDTH, (vsync << 16) + hsync); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_BACK_WIDTH, (vback << 16) + hback); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HSYNC2VSYNC_POL_CTRL, v_h_polarity); -+ if (ret < 0) -+ return ret; -+ -+ /* Reset Data Enable */ -+ val = cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER); -+ val &= ~F_DATA_EN(1); -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+ if (ret < 0) -+ return ret; -+ -+ /* Set bpc */ -+ val &= ~F_VIF_DATA_WIDTH(3); -+ switch (video_info->color_depth) { -+ case 10: -+ val |= F_VIF_DATA_WIDTH(1); -+ break; -+ case 12: -+ val |= F_VIF_DATA_WIDTH(2); -+ break; -+ case 16: -+ val |= F_VIF_DATA_WIDTH(3); -+ break; -+ case 8: -+ default: -+ val |= F_VIF_DATA_WIDTH(0); -+ break; -+ } -+ -+ /* select color encoding */ -+ val &= ~F_HDMI_ENCODING(3); -+ switch (video_info->color_fmt) { -+ case YCBCR_4_4_4: -+ val |= F_HDMI_ENCODING(2); -+ break; -+ case YCBCR_4_2_2: -+ val |= F_HDMI_ENCODING(1); -+ break; -+ case YCBCR_4_2_0: -+ val |= F_HDMI_ENCODING(3); -+ break; -+ case PXL_RGB: -+ default: -+ val |= F_HDMI_ENCODING(0); -+ break; -+ } -+ -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+ if (ret < 0) -+ return ret; -+ -+ /* set data enable */ -+ val |= F_DATA_EN(1); -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+ -+ return ret; -+} -+ -+int cdns_hdmi_disable_gcp(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val; -+ -+ val = cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER); -+ val &= ~F_GCP_EN(1); -+ -+ return cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+} -+ -+int cdns_hdmi_enable_gcp(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val; -+ -+ val = cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER); -+ val |= F_GCP_EN(1); -+ -+ return cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+} ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp.h -@@ -0,0 +1,209 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Cadence MHDP DP MST bridge driver. -+ * -+ * Copyright: 2018 Cadence Design Systems, Inc. -+ * -+ * Author: Quentin Schulz <quentin.schulz@free-electrons.com> -+ */ -+ -+ -+#ifndef CDNS_MHDP_H -+#define CDNS_MHDP_H -+ -+#include <drm/drm_dp_mst_helper.h> -+ -+#define CDNS_APB_CFG 0x00000 -+#define CDNS_APB_CTRL (CDNS_APB_CFG + 0x00) -+#define CDNS_MAILBOX_FULL (CDNS_APB_CFG + 0x08) -+#define CDNS_MAILBOX_EMPTY (CDNS_APB_CFG + 0x0c) -+#define CDNS_MAILBOX_TX_DATA (CDNS_APB_CFG + 0x10) -+#define CDNS_MAILBOX_RX_DATA (CDNS_APB_CFG + 0x14) -+#define CDNS_KEEP_ALIVE (CDNS_APB_CFG + 0x18) -+#define CDNS_KEEP_ALIVE_MASK GENMASK(7, 0) -+ -+#define CDNS_MB_INT_MASK (CDNS_APB_CFG + 0x34) -+ -+#define CDNS_SW_CLK_L (CDNS_APB_CFG + 0x3c) -+#define CDNS_SW_CLK_H (CDNS_APB_CFG + 0x40) -+#define CDNS_SW_EVENT0 (CDNS_APB_CFG + 0x44) -+#define CDNS_DPTX_HPD BIT(0) -+ -+#define CDNS_SW_EVENT1 (CDNS_APB_CFG + 0x48) -+#define CDNS_SW_EVENT2 (CDNS_APB_CFG + 0x4c) -+#define CDNS_SW_EVENT3 (CDNS_APB_CFG + 0x50) -+ -+#define CDNS_APB_INT_MASK (CDNS_APB_CFG + 0x6C) -+#define CDNS_APB_INT_MASK_MAILBOX_INT BIT(0) -+#define CDNS_APB_INT_MASK_SW_EVENT_INT BIT(1) -+ -+#define CDNS_DPTX_CAR (CDNS_APB_CFG + 0x904) -+#define CDNS_VIF_CLK_EN BIT(0) -+#define CDNS_VIF_CLK_RSTN BIT(1) -+ -+#define CDNS_SOURCE_VIDEO_IF(s) (0x00b00 + (s * 0x20)) -+#define CDNS_BND_HSYNC2VSYNC(s) (CDNS_SOURCE_VIDEO_IF(s) + \ -+ 0x00) -+#define CDNS_IP_DTCT_WIN GENMASK(11, 0) -+#define CDNS_IP_DET_INTERLACE_FORMAT BIT(12) -+#define CDNS_IP_BYPASS_V_INTERFACE BIT(13) -+ -+#define CDNS_HSYNC2VSYNC_POL_CTRL(s) (CDNS_SOURCE_VIDEO_IF(s) + \ -+ 0x10) -+#define CDNS_H2V_HSYNC_POL_ACTIVE_LOW BIT(1) -+#define CDNS_H2V_VSYNC_POL_ACTIVE_LOW BIT(2) -+ -+#define CDNS_DPTX_PHY_CONFIG 0x02000 -+#define CDNS_PHY_TRAINING_EN BIT(0) -+#define CDNS_PHY_TRAINING_TYPE(x) (((x) & GENMASK(3, 0)) << 1) -+#define CDNS_PHY_SCRAMBLER_BYPASS BIT(5) -+#define CDNS_PHY_ENCODER_BYPASS BIT(6) -+#define CDNS_PHY_SKEW_BYPASS BIT(7) -+#define CDNS_PHY_TRAINING_AUTO BIT(8) -+#define CDNS_PHY_LANE0_SKEW(x) (((x) & GENMASK(2, 0)) << 9) -+#define CDNS_PHY_LANE1_SKEW(x) (((x) & GENMASK(2, 0)) << 12) -+#define CDNS_PHY_LANE2_SKEW(x) (((x) & GENMASK(2, 0)) << 15) -+#define CDNS_PHY_LANE3_SKEW(x) (((x) & GENMASK(2, 0)) << 18) -+#define CDNS_PHY_COMMON_CONFIG (CDNS_PHY_LANE1_SKEW(1) | \ -+ CDNS_PHY_LANE2_SKEW(2) | \ -+ CDNS_PHY_LANE3_SKEW(3)) -+#define CDNS_PHY_10BIT_EN BIT(21) -+ -+#define CDNS_DPTX_FRAMER 0x02200 -+#define CDNS_DP_FRAMER_GLOBAL_CONFIG (CDNS_DPTX_FRAMER + 0x00) -+#define CDNS_DP_NUM_LANES(x) (x - 1) -+#define CDNS_DP_MST_EN BIT(2) -+#define CDNS_DP_FRAMER_EN BIT(3) -+#define CDNS_DP_RATE_GOVERNOR_EN BIT(4) -+#define CDNS_DP_NO_VIDEO_MODE BIT(5) -+#define CDNS_DP_DISABLE_PHY_RST BIT(6) -+#define CDNS_DP_WR_FAILING_EDGE_VSYNC BIT(7) -+ -+#define CDNS_DP_SW_RESET (CDNS_DPTX_FRAMER + 0x04) -+#define CDNS_DP_FRAMER_TU (CDNS_DPTX_FRAMER + 0x08) -+#define CDNS_DP_FRAMER_TU_SIZE(x) (((x) & GENMASK(6, 0)) << 8) -+#define CDNS_DP_FRAMER_TU_VS(x) ((x) & GENMASK(5, 0)) -+#define CDNS_DP_FRAMER_TU_CNT_RST_EN BIT(15) -+ -+#define CDNS_DPTX_STREAM(s) (0x03000 + s * 0x80) -+#define CDNS_DP_MSA_HORIZONTAL_0(s) (CDNS_DPTX_STREAM(s) + 0x00) -+#define CDNS_DP_MSAH0_H_TOTAL(x) (x) -+#define CDNS_DP_MSAH0_HSYNC_START(x) ((x) << 16) -+ -+#define CDNS_DP_MSA_HORIZONTAL_1(s) (CDNS_DPTX_STREAM(s) + 0x04) -+#define CDNS_DP_MSAH1_HSYNC_WIDTH(x) (x) -+#define CDNS_DP_MSAH1_HSYNC_POL_LOW BIT(15) -+#define CDNS_DP_MSAH1_HDISP_WIDTH(x) ((x) << 16) -+ -+#define CDNS_DP_MSA_VERTICAL_0(s) (CDNS_DPTX_STREAM(s) + 0x08) -+#define CDNS_DP_MSAV0_V_TOTAL(x) (x) -+#define CDNS_DP_MSAV0_VSYNC_START(x) ((x) << 16) -+ -+#define CDNS_DP_MSA_VERTICAL_1(s) (CDNS_DPTX_STREAM(s) + 0x0c) -+#define CDNS_DP_MSAV1_VSYNC_WIDTH(x) (x) -+#define CDNS_DP_MSAV1_VSYNC_POL_LOW BIT(15) -+#define CDNS_DP_MSAV1_VDISP_WIDTH(x) ((x) << 16) -+ -+#define CDNS_DP_MSA_MISC(s) (CDNS_DPTX_STREAM(s) + 0x10) -+#define CDNS_DP_STREAM_CONFIGs(s) (CDNS_DPTX_STREAM(s) + 0x14) -+#define CDNS_DP_STREAM_CONFIG_2(s) (CDNS_DPTX_STREAM(s) + 0x2c) -+#define CDNS_DP_SC2_TU_VS_DIFF(x) ((x) << 8) -+ -+#define CDNS_DP_HORIZONTAL(s) (CDNS_DPTX_STREAM(s) + 0x30) -+#define CDNS_DP_H_HSYNC_WIDTH(x) (x) -+#define CDNS_DP_H_H_TOTAL(x) ((x) << 16) -+ -+#define CDNS_DP_VERTICAL_0(s) (CDNS_DPTX_STREAM(s) + 0x34) -+#define CDNS_DP_V0_VHEIGHT(x) (x) -+#define CDNS_DP_V0_VSTART(x) ((x) << 16) -+ -+#define CDNS_DP_VERTICAL_1(s) (CDNS_DPTX_STREAM(s) + 0x38) -+#define CDNS_DP_V1_VTOTAL(x) (x) -+#define CDNS_DP_V1_VTOTAL_EVEN BIT(16) -+ -+#define CDNS_DP_FRAMER_PXL_REPR(s) (CDNS_DPTX_STREAM(s) + 0x4c) -+#define CDNS_DP_FRAMER_6_BPC BIT(0) -+#define CDNS_DP_FRAMER_8_BPC BIT(1) -+#define CDNS_DP_FRAMER_10_BPC BIT(2) -+#define CDNS_DP_FRAMER_12_BPC BIT(3) -+#define CDNS_DP_FRAMER_16_BPC BIT(4) -+#define CDNS_DP_FRAMER_PXL_FORMAT 0x8 -+#define CDNS_DP_FRAMER_RGB BIT(0) -+#define CDNS_DP_FRAMER_YCBCR444 BIT(1) -+#define CDNS_DP_FRAMER_YCBCR422 BIT(2) -+#define CDNS_DP_FRAMER_YCBCR420 BIT(3) -+#define CDNS_DP_FRAMER_Y_ONLY BIT(4) -+ -+#define CDNS_DP_FRAMER_SP(s) (CDNS_DPTX_STREAM(s) + 0x10) -+#define CDNS_DP_FRAMER_VSYNC_POL_LOW BIT(0) -+#define CDNS_DP_FRAMER_HSYNC_POL_LOW BIT(1) -+#define CDNS_DP_FRAMER_INTERLACE BIT(2) -+ -+#define CDNS_DP_LINE_THRESH(s) (CDNS_DPTX_STREAM(s) + 0x64) -+#define CDNS_DP_ACTIVE_LINE_THRESH(x) (x) -+ -+#define CDNS_DP_VB_ID(s) (CDNS_DPTX_STREAM(s) + 0x68) -+#define CDNS_DP_VB_ID_INTERLACED BIT(2) -+#define CDNS_DP_VB_ID_COMPRESSED BIT(6) -+ -+#define CDNS_DP_FRONT_BACK_PORCH(s) (CDNS_DPTX_STREAM(s) + 0x78) -+#define CDNS_DP_BACK_PORCH(x) (x) -+#define CDNS_DP_FRONT_PORCH(x) ((x) << 16) -+ -+#define CDNS_DP_BYTE_COUNT(s) (CDNS_DPTX_STREAM(s) + 0x7c) -+#define CDNS_DP_BYTE_COUNT_BYTES_IN_CHUNK_SHIFT 16 -+ -+#define CDNS_DP_MST_STREAM_CONFIG(s) (CDNS_DPTX_STREAM(s) + 0x14) -+#define CDNS_DP_MST_STRM_CFG_STREAM_EN BIT(0) -+#define CDNS_DP_MST_STRM_CFG_NO_VIDEO BIT(1) -+ -+#define CDNS_DP_MST_SLOT_ALLOCATE(s) (CDNS_DPTX_STREAM(s) + 0x44) -+#define CDNS_DP_S_ALLOC_START_SLOT(x) (x) -+#define CDNS_DP_S_ALLOC_END_SLOT(x) ((x) << 8) -+ -+#define CDNS_DP_RATE_GOVERNING(s) (CDNS_DPTX_STREAM(s) + 0x48) -+#define CDNS_DP_RG_TARG_AV_SLOTS_Y(x) (x) -+#define CDNS_DP_RG_TARG_AV_SLOTS_X(x) (x << 4) -+#define CDNS_DP_RG_ENABLE BIT(10) -+ -+#define CDNS_DP_MTPH_CONTROL 0x2264 -+#define CDNS_DP_MTPH_ECF_EN BIT(0) -+#define CDNS_DP_MTPH_ACT_EN BIT(1) -+#define CDNS_DP_MTPH_LVP_EN BIT(2) -+ -+#define CDNS_DP_MTPH_STATUS 0x226C -+#define CDNS_DP_MTPH_ACT_STATUS BIT(0) -+ -+ -+#define CDNS_DPTX_GLOBAL 0x02300 -+#define CDNS_DP_LANE_EN (CDNS_DPTX_GLOBAL + 0x00) -+#define CDNS_DP_LANE_EN_LANES(x) GENMASK(x - 1, 0) -+#define CDNS_DP_ENHNCD (CDNS_DPTX_GLOBAL + 0x04) -+ -+ -+#define to_mhdp_connector(x) container_of(x, struct cdns_mhdp_connector, base) -+#define to_mhdp_bridge(x) container_of(x, struct cdns_mhdp_bridge, base) -+#define mgr_to_mhdp(x) container_of(x, struct cdns_mhdp_device, mst_mgr) -+ -+#define CDNS_MHDP_MAX_STREAMS 4 -+ -+enum pixel_format { -+ PIXEL_FORMAT_RGB = 1, -+ PIXEL_FORMAT_YCBCR_444 = 2, -+ PIXEL_FORMAT_YCBCR_422 = 4, -+ PIXEL_FORMAT_YCBCR_420 = 8, -+ PIXEL_FORMAT_Y_ONLY = 16, -+}; -+ -+ -+int cdns_mhdp_mst_init(struct cdns_mhdp_device *mhdp); -+void cdns_mhdp_mst_deinit(struct cdns_mhdp_device *mhdp); -+bool cdns_mhdp_mst_probe(struct cdns_mhdp_device *mhdp); -+enum pixel_format cdns_mhdp_get_pxlfmt(u32 color_formats); -+u32 cdns_mhdp_get_bpp(u32 bpc, u32 color_formats); -+void cdns_mhdp_configure_video(struct drm_bridge *bridge); -+void cdns_mhdp_mst_enable(struct drm_bridge *bridge); -+void cdns_mhdp_mst_disable(struct drm_bridge *bridge); -+void cdns_mhdp_enable(struct drm_bridge *bridge); -+ -+#endif ---- a/drivers/gpu/drm/rockchip/Kconfig -+++ b/drivers/gpu/drm/rockchip/Kconfig -@@ -29,7 +29,9 @@ config ROCKCHIP_ANALOGIX_DP - - config ROCKCHIP_CDN_DP - bool "Rockchip cdn DP" -- depends on EXTCON=y || (EXTCON=m && DRM_ROCKCHIP=m) -+ depends on DRM_ROCKCHIP -+ select EXTCON -+ select DRM_CDNS_MHDP - help - This selects support for Rockchip SoC specific extensions - for the cdn DP driver. If you want to enable Dp on ---- a/drivers/gpu/drm/rockchip/Makefile -+++ b/drivers/gpu/drm/rockchip/Makefile -@@ -8,7 +8,7 @@ rockchipdrm-y := rockchip_drm_drv.o rock - rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o - - rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o --rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o -+rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o - rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o - rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o - rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o ---- a/drivers/gpu/drm/rockchip/cdn-dp-core.c -+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c -@@ -25,7 +25,7 @@ - #include "rockchip_drm_vop.h" - - #define connector_to_dp(c) \ -- container_of(c, struct cdn_dp_device, mhdp.connector) -+ container_of(c, struct cdn_dp_device, mhdp.connector.base) - - #define encoder_to_dp(c) \ - container_of(c, struct cdn_dp_device, encoder) -@@ -283,7 +283,7 @@ static int cdn_dp_connector_mode_valid(s - { - struct cdn_dp_device *dp = connector_to_dp(connector); - struct drm_display_info *display_info = -- &dp->mhdp.connector.display_info; -+ &dp->mhdp.connector.base.display_info; - u32 requested, actual, rate, sink_max, source_max = 0; - u8 lanes, bpc; - -@@ -379,7 +379,7 @@ static int cdn_dp_get_sink_capability(st - } - - kfree(dp->edid); -- dp->edid = drm_do_get_edid(&dp->mhdp.connector, -+ dp->edid = drm_do_get_edid(&dp->mhdp.connector.base, - cdns_mhdp_get_edid_block, &dp->mhdp); - return 0; - } -@@ -485,8 +485,8 @@ static int cdn_dp_disable(struct cdn_dp_ - cdns_mhdp_set_firmware_active(&dp->mhdp, false); - cdn_dp_clk_disable(dp); - dp->active = false; -- dp->mhdp.link.rate = 0; -- dp->mhdp.link.num_lanes = 0; -+ dp->mhdp.dp.link.rate = 0; -+ dp->mhdp.dp.link.num_lanes = 0; - if (!dp->connected) { - kfree(dp->edid); - dp->edid = NULL; -@@ -551,7 +551,7 @@ static void cdn_dp_encoder_mode_set(stru - { - struct cdn_dp_device *dp = encoder_to_dp(encoder); - struct drm_display_info *display_info = -- &dp->mhdp.connector.display_info; -+ &dp->mhdp.connector.base.display_info; - struct video_info *video = &dp->mhdp.video_info; - - switch (display_info->bpc) { -@@ -579,7 +579,7 @@ static bool cdn_dp_check_link_status(str - struct cdn_dp_port *port = cdn_dp_connected_port(dp); - u8 sink_lanes = drm_dp_max_lane_count(dp->dpcd); - -- if (!port || !dp->mhdp.link.rate || !dp->mhdp.link.num_lanes) -+ if (!port || !dp->mhdp.dp.link.rate || !dp->mhdp.dp.link.num_lanes) - return false; - - if (cdns_mhdp_dpcd_read(&dp->mhdp, DP_LANE0_1_STATUS, link_status, -@@ -808,7 +808,7 @@ static int cdn_dp_audio_hw_params(struct - - ret = cdns_mhdp_audio_config(&dp->mhdp, &audio); - if (!ret) -- dp->audio_info = audio; -+ dp->mhdp.audio_info = audio; - - out: - mutex_unlock(&dp->lock); -@@ -824,9 +824,9 @@ static void cdn_dp_audio_shutdown(struct - if (!dp->active) - goto out; - -- ret = cdns_mhdp_audio_stop(&dp->mhdp, &dp->audio_info); -+ ret = cdns_mhdp_audio_stop(&dp->mhdp, &dp->mhdp.audio_info); - if (!ret) -- dp->audio_info.format = AFMT_UNUSED; -+ dp->mhdp.audio_info.format = AFMT_UNUSED; - out: - mutex_unlock(&dp->lock); - } -@@ -855,8 +855,8 @@ static int cdn_dp_audio_get_eld(struct d - { - struct cdn_dp_device *dp = dev_get_drvdata(dev); - -- memcpy(buf, dp->mhdp.connector.eld, -- min(sizeof(dp->mhdp.connector.eld), len)); -+ memcpy(buf, dp->mhdp.connector.base.eld, -+ min(sizeof(dp->mhdp.connector.base.eld), len)); - - return 0; - } -@@ -878,11 +878,11 @@ static int cdn_dp_audio_codec_init(struc - .max_i2s_channels = 8, - }; - -- dp->audio_pdev = platform_device_register_data( -- dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, -- &codec_data, sizeof(codec_data)); -+ dp->mhdp.audio_pdev = platform_device_register_data( -+ dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, -+ &codec_data, sizeof(codec_data)); - -- return PTR_ERR_OR_ZERO(dp->audio_pdev); -+ return PTR_ERR_OR_ZERO(dp->mhdp.audio_pdev); - } - - static int cdn_dp_request_firmware(struct cdn_dp_device *dp) -@@ -928,7 +928,7 @@ static void cdn_dp_pd_event_work(struct - { - struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device, - event_work); -- struct drm_connector *connector = &dp->mhdp.connector; -+ struct drm_connector *connector = &dp->mhdp.connector.base; - enum drm_connector_status old_status; - struct device *dev = dp->mhdp.dev; - -@@ -966,8 +966,8 @@ static void cdn_dp_pd_event_work(struct - - /* Enabled and connected with a sink, re-train if requested */ - } else if (!cdn_dp_check_link_status(dp)) { -- unsigned int rate = dp->mhdp.link.rate; -- unsigned int lanes = dp->mhdp.link.num_lanes; -+ unsigned int rate = dp->mhdp.dp.link.rate; -+ unsigned int lanes = dp->mhdp.dp.link.num_lanes; - struct drm_display_mode *mode = &dp->mhdp.mode; - - DRM_DEV_INFO(dev, "Connected with sink. Re-train link\n"); -@@ -980,8 +980,8 @@ static void cdn_dp_pd_event_work(struct - - /* If training result is changed, update the video config */ - if (mode->clock && -- (rate != dp->mhdp.link.rate || -- lanes != dp->mhdp.link.num_lanes)) { -+ (rate != dp->mhdp.dp.link.rate || -+ lanes != dp->mhdp.dp.link.num_lanes)) { - ret = cdns_mhdp_config_video(&dp->mhdp); - if (ret) { - dp->connected = false; -@@ -1054,7 +1054,7 @@ static int cdn_dp_bind(struct device *de - - drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs); - -- connector = &dp->mhdp.connector; -+ connector = &dp->mhdp.connector.base; - connector->polled = DRM_CONNECTOR_POLL_HPD; - connector->dpms = DRM_MODE_DPMS_OFF; - -@@ -1105,7 +1105,7 @@ static void cdn_dp_unbind(struct device - { - struct cdn_dp_device *dp = dev_get_drvdata(dev); - struct drm_encoder *encoder = &dp->encoder; -- struct drm_connector *connector = &dp->mhdp.connector; -+ struct drm_connector *connector = &dp->mhdp.connector.base; - - cancel_work_sync(&dp->event_work); - cdn_dp_encoder_disable(encoder); -@@ -1209,7 +1209,7 @@ static int cdn_dp_remove(struct platform - { - struct cdn_dp_device *dp = platform_get_drvdata(pdev); - -- platform_device_unregister(dp->audio_pdev); -+ platform_device_unregister(dp->mhdp.audio_pdev); - cdn_dp_suspend(dp->mhdp.dev); - component_del(&pdev->dev, &cdn_dp_component_ops); - ---- a/drivers/gpu/drm/rockchip/cdn-dp-core.h -+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h -@@ -7,12 +7,13 @@ - #ifndef _CDN_DP_CORE_H - #define _CDN_DP_CORE_H - -+#include <drm/bridge/cdns-mhdp-common.h> -+#include <drm/drmP.h> - #include <drm/drm_dp_helper.h> - #include <drm/drm_panel.h> - #include <drm/drm_probe_helper.h> - - #include "rockchip_drm_drv.h" --#include "cdn-dp-reg.h" - - #define MAX_PHY 2 - -@@ -37,7 +38,6 @@ struct cdn_dp_device { - struct cdns_mhdp_device mhdp; - struct drm_device *drm_dev; - struct drm_encoder encoder; -- struct platform_device *audio_pdev; - struct work_struct event_work; - struct edid *edid; - -@@ -56,7 +56,6 @@ struct cdn_dp_device { - struct reset_control *dptx_rst; - struct reset_control *apb_rst; - struct reset_control *core_rst; -- struct audio_info audio_info; - struct cdn_dp_port *port[MAX_PHY]; - u8 ports; - u8 lanes; ---- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c -+++ /dev/null -@@ -1,968 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-only --/* -- * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd -- * Author: Chris Zhong <zyw@rock-chips.com> -- */ -- --#include <linux/clk.h> --#include <linux/device.h> --#include <linux/delay.h> --#include <linux/io.h> --#include <linux/iopoll.h> --#include <linux/reset.h> -- --#include "cdn-dp-core.h" --#include "cdn-dp-reg.h" -- --#define CDNS_DP_SPDIF_CLK 200000000 --#define FW_ALIVE_TIMEOUT_US 1000000 --#define MAILBOX_RETRY_US 1000 --#define MAILBOX_TIMEOUT_US 5000000 --#define LINK_TRAINING_RETRY_MS 20 --#define LINK_TRAINING_TIMEOUT_MS 500 -- --void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk) --{ -- writel(clk / 1000000, mhdp->regs + SW_CLK_H); --} -- --void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp) --{ -- u32 val; -- -- val = DPTX_FRMR_DATA_CLK_RSTN_EN | -- DPTX_FRMR_DATA_CLK_EN | -- DPTX_PHY_DATA_RSTN_EN | -- DPTX_PHY_DATA_CLK_EN | -- DPTX_PHY_CHAR_RSTN_EN | -- DPTX_PHY_CHAR_CLK_EN | -- SOURCE_AUX_SYS_CLK_RSTN_EN | -- SOURCE_AUX_SYS_CLK_EN | -- DPTX_SYS_CLK_RSTN_EN | -- DPTX_SYS_CLK_EN | -- CFG_DPTX_VIF_CLK_RSTN_EN | -- CFG_DPTX_VIF_CLK_EN; -- writel(val, mhdp->regs + SOURCE_DPTX_CAR); -- -- val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN; -- writel(val, mhdp->regs + SOURCE_PHY_CAR); -- -- val = SOURCE_PKT_SYS_RSTN_EN | -- SOURCE_PKT_SYS_CLK_EN | -- SOURCE_PKT_DATA_RSTN_EN | -- SOURCE_PKT_DATA_CLK_EN; -- writel(val, mhdp->regs + SOURCE_PKT_CAR); -- -- val = SPDIF_CDR_CLK_RSTN_EN | -- SPDIF_CDR_CLK_EN | -- SOURCE_AIF_SYS_RSTN_EN | -- SOURCE_AIF_SYS_CLK_EN | -- SOURCE_AIF_CLK_RSTN_EN | -- SOURCE_AIF_CLK_EN; -- writel(val, mhdp->regs + SOURCE_AIF_CAR); -- -- val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN | -- SOURCE_CIPHER_SYS_CLK_EN | -- SOURCE_CIPHER_CHAR_CLK_RSTN_EN | -- SOURCE_CIPHER_CHAR_CLK_EN; -- writel(val, mhdp->regs + SOURCE_CIPHER_CAR); -- -- val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN | -- SOURCE_CRYPTO_SYS_CLK_EN; -- writel(val, mhdp->regs + SOURCE_CRYPTO_CAR); -- -- /* enable Mailbox and PIF interrupt */ -- writel(0, mhdp->regs + APB_INT_MASK); --} -- --static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp) --{ -- int val, ret; -- -- ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_EMPTY_ADDR, -- val, !val, MAILBOX_RETRY_US, -- MAILBOX_TIMEOUT_US); -- if (ret < 0) -- return ret; -- -- return readl(mhdp->regs + MAILBOX0_RD_DATA) & 0xff; --} -- --static int cdp_dp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val) --{ -- int ret, full; -- -- ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_FULL_ADDR, -- full, !full, MAILBOX_RETRY_US, -- MAILBOX_TIMEOUT_US); -- if (ret < 0) -- return ret; -- -- writel(val, mhdp->regs + MAILBOX0_WR_DATA); -- -- return 0; --} -- --static int cdns_mhdp_mailbox_validate_receive(struct cdns_mhdp_device *mhdp, -- u8 module_id, u8 opcode, -- u16 req_size) --{ -- u32 mbox_size, i; -- u8 header[4]; -- int ret; -- -- /* read the header of the message */ -- for (i = 0; i < 4; i++) { -- ret = cdns_mhdp_mailbox_read(mhdp); -- if (ret < 0) -- return ret; -- -- header[i] = ret; -- } -- -- mbox_size = (header[2] << 8) | header[3]; -- -- if (opcode != header[0] || module_id != header[1] || -- req_size != mbox_size) { -- /* -- * If the message in mailbox is not what we want, we need to -- * clear the mailbox by reading its contents. -- */ -- for (i = 0; i < mbox_size; i++) -- if (cdns_mhdp_mailbox_read(mhdp) < 0) -- break; -- -- return -EINVAL; -- } -- -- return 0; --} -- --static int cdns_mhdp_mailbox_read_receive(struct cdns_mhdp_device *mhdp, -- u8 *buff, u16 buff_size) --{ -- u32 i; -- int ret; -- -- for (i = 0; i < buff_size; i++) { -- ret = cdns_mhdp_mailbox_read(mhdp); -- if (ret < 0) -- return ret; -- -- buff[i] = ret; -- } -- -- return 0; --} -- --static int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id, -- u8 opcode, u16 size, u8 *message) --{ -- u8 header[4]; -- int ret, i; -- -- header[0] = opcode; -- header[1] = module_id; -- header[2] = (size >> 8) & 0xff; -- header[3] = size & 0xff; -- -- for (i = 0; i < 4; i++) { -- ret = cdp_dp_mailbox_write(mhdp, header[i]); -- if (ret) -- return ret; -- } -- -- for (i = 0; i < size; i++) { -- ret = cdp_dp_mailbox_write(mhdp, message[i]); -- if (ret) -- return ret; -- } -- -- return 0; --} -- --static int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u16 addr, u32 val) --{ -- u8 msg[6]; -- -- msg[0] = (addr >> 8) & 0xff; -- msg[1] = addr & 0xff; -- msg[2] = (val >> 24) & 0xff; -- msg[3] = (val >> 16) & 0xff; -- msg[4] = (val >> 8) & 0xff; -- msg[5] = val & 0xff; -- return cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_REGISTER, sizeof(msg), msg); --} -- --static int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr, -- u8 start_bit, u8 bits_no, u32 val) --{ -- u8 field[8]; -- -- field[0] = (addr >> 8) & 0xff; -- field[1] = addr & 0xff; -- field[2] = start_bit; -- field[3] = bits_no; -- field[4] = (val >> 24) & 0xff; -- field[5] = (val >> 16) & 0xff; -- field[6] = (val >> 8) & 0xff; -- field[7] = val & 0xff; -- -- return cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_FIELD, sizeof(field), field); --} -- --int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp, -- u32 addr, u8 *data, u16 len) --{ -- u8 msg[5], reg[5]; -- int ret; -- -- msg[0] = (len >> 8) & 0xff; -- msg[1] = len & 0xff; -- msg[2] = (addr >> 16) & 0xff; -- msg[3] = (addr >> 8) & 0xff; -- msg[4] = addr & 0xff; -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_DPCD, sizeof(msg), msg); -- if (ret) -- goto err_dpcd_read; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_DPCD, -- sizeof(reg) + len); -- if (ret) -- goto err_dpcd_read; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -- if (ret) -- goto err_dpcd_read; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, data, len); -- --err_dpcd_read: -- return ret; --} -- --int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value) --{ -- u8 msg[6], reg[5]; -- int ret; -- -- msg[0] = 0; -- msg[1] = 1; -- msg[2] = (addr >> 16) & 0xff; -- msg[3] = (addr >> 8) & 0xff; -- msg[4] = addr & 0xff; -- msg[5] = value; -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_DPCD, sizeof(msg), msg); -- if (ret) -- goto err_dpcd_write; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_DPCD, sizeof(reg)); -- if (ret) -- goto err_dpcd_write; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -- if (ret) -- goto err_dpcd_write; -- -- if (addr != (reg[2] << 16 | reg[3] << 8 | reg[4])) -- ret = -EINVAL; -- --err_dpcd_write: -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "dpcd write failed: %d\n", ret); -- return ret; --} -- --int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, -- u32 i_size, const u32 *d_mem, u32 d_size) --{ -- u32 reg; -- int i, ret; -- -- /* reset ucpu before load firmware*/ -- writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET, -- mhdp->regs + APB_CTRL); -- -- for (i = 0; i < i_size; i += 4) -- writel(*i_mem++, mhdp->regs + ADDR_IMEM + i); -- -- for (i = 0; i < d_size; i += 4) -- writel(*d_mem++, mhdp->regs + ADDR_DMEM + i); -- -- /* un-reset ucpu */ -- writel(0, mhdp->regs + APB_CTRL); -- -- /* check the keep alive register to make sure fw working */ -- ret = readx_poll_timeout(readl, mhdp->regs + KEEP_ALIVE, -- reg, reg, 2000, FW_ALIVE_TIMEOUT_US); -- if (ret < 0) { -- DRM_DEV_ERROR(mhdp->dev, "failed to loaded the FW reg = %x\n", -- reg); -- return -EINVAL; -- } -- -- reg = readl(mhdp->regs + VER_L) & 0xff; -- mhdp->fw_version = reg; -- reg = readl(mhdp->regs + VER_H) & 0xff; -- mhdp->fw_version |= reg << 8; -- reg = readl(mhdp->regs + VER_LIB_L_ADDR) & 0xff; -- mhdp->fw_version |= reg << 16; -- reg = readl(mhdp->regs + VER_LIB_H_ADDR) & 0xff; -- mhdp->fw_version |= reg << 24; -- -- DRM_DEV_DEBUG(mhdp->dev, "firmware version: %x\n", mhdp->fw_version); -- -- return 0; --} -- --int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable) --{ -- u8 msg[5]; -- int ret, i; -- -- msg[0] = GENERAL_MAIN_CONTROL; -- msg[1] = MB_MODULE_ID_GENERAL; -- msg[2] = 0; -- msg[3] = 1; -- msg[4] = enable ? FW_ACTIVE : FW_STANDBY; -- -- for (i = 0; i < sizeof(msg); i++) { -- ret = cdp_dp_mailbox_write(mhdp, msg[i]); -- if (ret) -- goto err_set_firmware_active; -- } -- -- /* read the firmware state */ -- for (i = 0; i < sizeof(msg); i++) { -- ret = cdns_mhdp_mailbox_read(mhdp); -- if (ret < 0) -- goto err_set_firmware_active; -- -- msg[i] = ret; -- } -- -- ret = 0; -- --err_set_firmware_active: -- if (ret < 0) -- DRM_DEV_ERROR(mhdp->dev, "set firmware active failed\n"); -- return ret; --} -- --int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip) --{ -- u8 msg[8]; -- int ret; -- -- msg[0] = CDNS_DP_MAX_LINK_RATE; -- msg[1] = lanes | SCRAMBLER_EN; -- msg[2] = VOLTAGE_LEVEL_2; -- msg[3] = PRE_EMPHASIS_LEVEL_3; -- msg[4] = PTS1 | PTS2 | PTS3 | PTS4; -- msg[5] = FAST_LT_NOT_SUPPORT; -- msg[6] = flip ? LANE_MAPPING_FLIPPED : LANE_MAPPING_NORMAL; -- msg[7] = ENHANCED; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_SET_HOST_CAPABILITIES, -- sizeof(msg), msg); -- if (ret) -- goto err_set_host_cap; -- -- ret = cdns_mhdp_reg_write(mhdp, DP_AUX_SWAP_INVERSION_CONTROL, -- AUX_HOST_INVERT); -- --err_set_host_cap: -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "set host cap failed: %d\n", ret); -- return ret; --} -- --int cdns_mhdp_event_config(struct cdns_mhdp_device *mhdp) --{ -- u8 msg[5]; -- int ret; -- -- memset(msg, 0, sizeof(msg)); -- -- msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_ENABLE_EVENT, sizeof(msg), msg); -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "set event config failed: %d\n", ret); -- -- return ret; --} -- --u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp) --{ -- return readl(mhdp->regs + SW_EVENTS0); --} -- --int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp) --{ -- u8 status; -- int ret; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_HPD_STATE, 0, NULL); -- if (ret) -- goto err_get_hpd; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_HPD_STATE, -- sizeof(status)); -- if (ret) -- goto err_get_hpd; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, &status, sizeof(status)); -- if (ret) -- goto err_get_hpd; -- -- return status; -- --err_get_hpd: -- DRM_DEV_ERROR(mhdp->dev, "get hpd status failed: %d\n", ret); -- return ret; --} -- --int cdns_mhdp_get_edid_block(void *data, u8 *edid, -- unsigned int block, size_t length) --{ -- struct cdns_mhdp_device *mhdp = data; -- u8 msg[2], reg[2], i; -- int ret; -- -- for (i = 0; i < 4; i++) { -- msg[0] = block / 2; -- msg[1] = block % 2; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_GET_EDID, sizeof(msg), msg); -- if (ret) -- continue; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, -- MB_MODULE_ID_DP_TX, -- DPTX_GET_EDID, -- sizeof(reg) + length); -- if (ret) -- continue; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -- if (ret) -- continue; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, edid, length); -- if (ret) -- continue; -- -- if (reg[0] == length && reg[1] == block / 2) -- break; -- } -- -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "get block[%d] edid failed: %d\n", -- block, ret); -- -- return ret; --} -- --static int cdns_mhdp_training_start(struct cdns_mhdp_device *mhdp) --{ -- unsigned long timeout; -- u8 msg, event[2]; -- int ret; -- -- msg = LINK_TRAINING_RUN; -- -- /* start training */ -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_TRAINING_CONTROL, sizeof(msg), &msg); -- if (ret) -- goto err_training_start; -- -- timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS); -- while (time_before(jiffies, timeout)) { -- msleep(LINK_TRAINING_RETRY_MS); -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_EVENT, 0, NULL); -- if (ret) -- goto err_training_start; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, -- MB_MODULE_ID_DP_TX, -- DPTX_READ_EVENT, -- sizeof(event)); -- if (ret) -- goto err_training_start; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, event, -- sizeof(event)); -- if (ret) -- goto err_training_start; -- -- if (event[1] & EQ_PHASE_FINISHED) -- return 0; -- } -- -- ret = -ETIMEDOUT; -- --err_training_start: -- DRM_DEV_ERROR(mhdp->dev, "training failed: %d\n", ret); -- return ret; --} -- --static int cdns_mhdp_get_training_status(struct cdns_mhdp_device *mhdp) --{ -- u8 status[10]; -- int ret; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, DPTX_READ_LINK_STAT, -- 0, NULL); -- if (ret) -- goto err_get_training_status; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_LINK_STAT, -- sizeof(status)); -- if (ret) -- goto err_get_training_status; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, status, sizeof(status)); -- if (ret) -- goto err_get_training_status; -- -- mhdp->link.rate = drm_dp_bw_code_to_link_rate(status[0]); -- mhdp->link.num_lanes = status[1]; -- --err_get_training_status: -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "get training status failed: %d\n", ret); -- return ret; --} -- --int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp) --{ -- int ret; -- -- ret = cdns_mhdp_training_start(mhdp); -- if (ret) { -- DRM_DEV_ERROR(mhdp->dev, "Failed to start training %d\n", ret); -- return ret; -- } -- -- ret = cdns_mhdp_get_training_status(mhdp); -- if (ret) { -- DRM_DEV_ERROR(mhdp->dev, "Failed to get training stat %d\n", ret); -- return ret; -- } -- -- DRM_DEV_DEBUG_KMS(mhdp->dev, "rate:0x%x, lanes:%d\n", mhdp->link.rate, -- mhdp->link.num_lanes); -- return ret; --} -- --int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active) --{ -- u8 msg; -- int ret; -- -- msg = !!active; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO, -- sizeof(msg), &msg); -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "set video status failed: %d\n", ret); -- -- return ret; --} -- --static int cdns_mhdp_get_msa_misc(struct video_info *video, -- struct drm_display_mode *mode) --{ -- u32 msa_misc; -- u8 val[2] = {0}; -- -- switch (video->color_fmt) { -- case PXL_RGB: -- case Y_ONLY: -- val[0] = 0; -- break; -- /* set YUV default color space conversion to BT601 */ -- case YCBCR_4_4_4: -- val[0] = 6 + BT_601 * 8; -- break; -- case YCBCR_4_2_2: -- val[0] = 5 + BT_601 * 8; -- break; -- case YCBCR_4_2_0: -- val[0] = 5; -- break; -- }; -- -- switch (video->color_depth) { -- case 6: -- val[1] = 0; -- break; -- case 8: -- val[1] = 1; -- break; -- case 10: -- val[1] = 2; -- break; -- case 12: -- val[1] = 3; -- break; -- case 16: -- val[1] = 4; -- break; -- }; -- -- msa_misc = 2 * val[0] + 32 * val[1] + -- ((video->color_fmt == Y_ONLY) ? (1 << 14) : 0); -- -- return msa_misc; --} -- --int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp) --{ -- struct video_info *video = &mhdp->video_info; -- struct drm_display_mode *mode = &mhdp->mode; -- u64 symbol; -- u32 val, link_rate, rem; -- u8 bit_per_pix, tu_size_reg = TU_SIZE; -- int ret; -- -- bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ? -- (video->color_depth * 2) : (video->color_depth * 3); -- -- link_rate = mhdp->link.rate / 1000; -- -- ret = cdns_mhdp_reg_write(mhdp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE); -- if (ret) -- goto err_config_video; -- -- ret = cdns_mhdp_reg_write(mhdp, HSYNC2VSYNC_POL_CTRL, 0); -- if (ret) -- goto err_config_video; -- -- /* -- * get a best tu_size and valid symbol: -- * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32 -- * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes) -- * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set -- * TU += 2 and repeat 2nd step. -- */ -- do { -- tu_size_reg += 2; -- symbol = tu_size_reg * mode->clock * bit_per_pix; -- do_div(symbol, mhdp->link.num_lanes * link_rate * 8); -- rem = do_div(symbol, 1000); -- if (tu_size_reg > 64) { -- ret = -EINVAL; -- DRM_DEV_ERROR(mhdp->dev, -- "tu error, clk:%d, lanes:%d, rate:%d\n", -- mode->clock, mhdp->link.num_lanes, -- link_rate); -- goto err_config_video; -- } -- } while ((symbol <= 1) || (tu_size_reg - symbol < 4) || -- (rem > 850) || (rem < 100)); -- -- val = symbol + (tu_size_reg << 8); -- val |= TU_CNT_RST_EN; -- ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_TU, val); -- if (ret) -- goto err_config_video; -- -- /* set the FIFO Buffer size */ -- val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate; -- val /= (mhdp->link.num_lanes * link_rate); -- val = div_u64(8 * (symbol + 1), bit_per_pix) - val; -- val += 2; -- ret = cdns_mhdp_reg_write(mhdp, DP_VC_TABLE(15), val); -- -- switch (video->color_depth) { -- case 6: -- val = BCS_6; -- break; -- case 8: -- val = BCS_8; -- break; -- case 10: -- val = BCS_10; -- break; -- case 12: -- val = BCS_12; -- break; -- case 16: -- val = BCS_16; -- break; -- }; -- -- val += video->color_fmt << 8; -- ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_PXL_REPR, val); -- if (ret) -- goto err_config_video; -- -- val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0; -- val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0; -- ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_SP, val); -- if (ret) -- goto err_config_video; -- -- val = (mode->hsync_start - mode->hdisplay) << 16; -- val |= mode->htotal - mode->hsync_end; -- ret = cdns_mhdp_reg_write(mhdp, DP_FRONT_BACK_PORCH, val); -- if (ret) -- goto err_config_video; -- -- val = mode->hdisplay * bit_per_pix / 8; -- ret = cdns_mhdp_reg_write(mhdp, DP_BYTE_COUNT, val); -- if (ret) -- goto err_config_video; -- -- val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16); -- ret = cdns_mhdp_reg_write(mhdp, MSA_HORIZONTAL_0, val); -- if (ret) -- goto err_config_video; -- -- val = mode->hsync_end - mode->hsync_start; -- val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15); -- ret = cdns_mhdp_reg_write(mhdp, MSA_HORIZONTAL_1, val); -- if (ret) -- goto err_config_video; -- -- val = mode->vtotal; -- val |= (mode->vtotal - mode->vsync_start) << 16; -- ret = cdns_mhdp_reg_write(mhdp, MSA_VERTICAL_0, val); -- if (ret) -- goto err_config_video; -- -- val = mode->vsync_end - mode->vsync_start; -- val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15); -- ret = cdns_mhdp_reg_write(mhdp, MSA_VERTICAL_1, val); -- if (ret) -- goto err_config_video; -- -- val = cdns_mhdp_get_msa_misc(video, mode); -- ret = cdns_mhdp_reg_write(mhdp, MSA_MISC, val); -- if (ret) -- goto err_config_video; -- -- ret = cdns_mhdp_reg_write(mhdp, STREAM_CONFIG, 1); -- if (ret) -- goto err_config_video; -- -- val = mode->hsync_end - mode->hsync_start; -- val |= mode->hdisplay << 16; -- ret = cdns_mhdp_reg_write(mhdp, DP_HORIZONTAL, val); -- if (ret) -- goto err_config_video; -- -- val = mode->vdisplay; -- val |= (mode->vtotal - mode->vsync_start) << 16; -- ret = cdns_mhdp_reg_write(mhdp, DP_VERTICAL_0, val); -- if (ret) -- goto err_config_video; -- -- val = mode->vtotal; -- ret = cdns_mhdp_reg_write(mhdp, DP_VERTICAL_1, val); -- if (ret) -- goto err_config_video; -- -- ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 2, 1, 0); -- --err_config_video: -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "config video failed: %d\n", ret); -- return ret; --} -- --int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio) --{ -- int ret; -- -- ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, 0); -- if (ret) { -- DRM_DEV_ERROR(mhdp->dev, "audio stop failed: %d\n", ret); -- return ret; -- } -- -- writel(0, mhdp->regs + SPDIF_CTRL_ADDR); -- -- /* clearn the audio config and reset */ -- writel(0, mhdp->regs + AUDIO_SRC_CNTL); -- writel(0, mhdp->regs + AUDIO_SRC_CNFG); -- writel(AUDIO_SW_RST, mhdp->regs + AUDIO_SRC_CNTL); -- writel(0, mhdp->regs + AUDIO_SRC_CNTL); -- -- /* reset smpl2pckt component */ -- writel(0, mhdp->regs + SMPL2PKT_CNTL); -- writel(AUDIO_SW_RST, mhdp->regs + SMPL2PKT_CNTL); -- writel(0, mhdp->regs + SMPL2PKT_CNTL); -- -- /* reset FIFO */ -- writel(AUDIO_SW_RST, mhdp->regs + FIFO_CNTL); -- writel(0, mhdp->regs + FIFO_CNTL); -- -- if (audio->format == AFMT_SPDIF) -- clk_disable_unprepare(mhdp->spdif_clk); -- -- return 0; --} -- --int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable) --{ -- int ret; -- -- ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 4, 1, enable); -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "audio mute failed: %d\n", ret); -- -- return ret; --} -- --static void cdns_mhdp_audio_config_i2s(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio) --{ -- int sub_pckt_num = 1, i2s_port_en_val = 0xf, i; -- u32 val; -- -- if (audio->channels == 2) { -- if (mhdp->link.num_lanes == 1) -- sub_pckt_num = 2; -- else -- sub_pckt_num = 4; -- -- i2s_port_en_val = 1; -- } else if (audio->channels == 4) { -- i2s_port_en_val = 3; -- } -- -- writel(0x0, mhdp->regs + SPDIF_CTRL_ADDR); -- -- writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); -- -- val = MAX_NUM_CH(audio->channels); -- val |= NUM_OF_I2S_PORTS(audio->channels); -- val |= AUDIO_TYPE_LPCM; -- val |= CFG_SUB_PCKT_NUM(sub_pckt_num); -- writel(val, mhdp->regs + SMPL2PKT_CNFG); -- -- if (audio->sample_width == 16) -- val = 0; -- else if (audio->sample_width == 24) -- val = 1 << 9; -- else -- val = 2 << 9; -- -- val |= AUDIO_CH_NUM(audio->channels); -- val |= I2S_DEC_PORT_EN(i2s_port_en_val); -- val |= TRANS_SMPL_WIDTH_32; -- writel(val, mhdp->regs + AUDIO_SRC_CNFG); -- -- for (i = 0; i < (audio->channels + 1) / 2; i++) { -- if (audio->sample_width == 16) -- val = (0x02 << 8) | (0x02 << 20); -- else if (audio->sample_width == 24) -- val = (0x0b << 8) | (0x0b << 20); -- -- val |= ((2 * i) << 4) | ((2 * i + 1) << 16); -- writel(val, mhdp->regs + STTS_BIT_CH(i)); -- } -- -- switch (audio->sample_rate) { -- case 32000: -- val = SAMPLING_FREQ(3) | -- ORIGINAL_SAMP_FREQ(0xc); -- break; -- case 44100: -- val = SAMPLING_FREQ(0) | -- ORIGINAL_SAMP_FREQ(0xf); -- break; -- case 48000: -- val = SAMPLING_FREQ(2) | -- ORIGINAL_SAMP_FREQ(0xd); -- break; -- case 88200: -- val = SAMPLING_FREQ(8) | -- ORIGINAL_SAMP_FREQ(0x7); -- break; -- case 96000: -- val = SAMPLING_FREQ(0xa) | -- ORIGINAL_SAMP_FREQ(5); -- break; -- case 176400: -- val = SAMPLING_FREQ(0xc) | -- ORIGINAL_SAMP_FREQ(3); -- break; -- case 192000: -- val = SAMPLING_FREQ(0xe) | -- ORIGINAL_SAMP_FREQ(1); -- break; -- } -- val |= 4; -- writel(val, mhdp->regs + COM_CH_STTS_BITS); -- -- writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); -- writel(I2S_DEC_START, mhdp->regs + AUDIO_SRC_CNTL); --} -- --static void cdns_mhdp_audio_config_spdif(struct cdns_mhdp_device *mhdp) --{ -- u32 val; -- -- writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); -- -- val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4); -- writel(val, mhdp->regs + SMPL2PKT_CNFG); -- writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); -- -- val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS; -- writel(val, mhdp->regs + SPDIF_CTRL_ADDR); -- -- clk_prepare_enable(mhdp->spdif_clk); -- clk_set_rate(mhdp->spdif_clk, CDNS_DP_SPDIF_CLK); --} -- --int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio) --{ -- int ret; -- -- /* reset the spdif clk before config */ -- if (audio->format == AFMT_SPDIF) { -- reset_control_assert(mhdp->spdif_rst); -- reset_control_deassert(mhdp->spdif_rst); -- } -- -- ret = cdns_mhdp_reg_write(mhdp, CM_LANE_CTRL, LANE_REF_CYC); -- if (ret) -- goto err_audio_config; -- -- ret = cdns_mhdp_reg_write(mhdp, CM_CTRL, 0); -- if (ret) -- goto err_audio_config; -- -- if (audio->format == AFMT_I2S) -- cdns_mhdp_audio_config_i2s(mhdp, audio); -- else if (audio->format == AFMT_SPDIF) -- cdns_mhdp_audio_config_spdif(mhdp); -- -- ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN); -- --err_audio_config: -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "audio config failed: %d\n", ret); -- return ret; --} ---- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h -+++ /dev/null -@@ -1,546 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-only */ --/* -- * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd -- * Author: Chris Zhong <zyw@rock-chips.com> -- */ -- --#ifndef _CDN_DP_REG_H --#define _CDN_DP_REG_H -- --#include <linux/bitops.h> -- --#define ADDR_IMEM 0x10000 --#define ADDR_DMEM 0x20000 -- --/* APB CFG addr */ --#define APB_CTRL 0 --#define XT_INT_CTRL 0x04 --#define MAILBOX_FULL_ADDR 0x08 --#define MAILBOX_EMPTY_ADDR 0x0c --#define MAILBOX0_WR_DATA 0x10 --#define MAILBOX0_RD_DATA 0x14 --#define KEEP_ALIVE 0x18 --#define VER_L 0x1c --#define VER_H 0x20 --#define VER_LIB_L_ADDR 0x24 --#define VER_LIB_H_ADDR 0x28 --#define SW_DEBUG_L 0x2c --#define SW_DEBUG_H 0x30 --#define MAILBOX_INT_MASK 0x34 --#define MAILBOX_INT_STATUS 0x38 --#define SW_CLK_L 0x3c --#define SW_CLK_H 0x40 --#define SW_EVENTS0 0x44 --#define SW_EVENTS1 0x48 --#define SW_EVENTS2 0x4c --#define SW_EVENTS3 0x50 --#define XT_OCD_CTRL 0x60 --#define APB_INT_MASK 0x6c --#define APB_STATUS_MASK 0x70 -- --/* audio decoder addr */ --#define AUDIO_SRC_CNTL 0x30000 --#define AUDIO_SRC_CNFG 0x30004 --#define COM_CH_STTS_BITS 0x30008 --#define STTS_BIT_CH(x) (0x3000c + ((x) << 2)) --#define SPDIF_CTRL_ADDR 0x3004c --#define SPDIF_CH1_CS_3100_ADDR 0x30050 --#define SPDIF_CH1_CS_6332_ADDR 0x30054 --#define SPDIF_CH1_CS_9564_ADDR 0x30058 --#define SPDIF_CH1_CS_12796_ADDR 0x3005c --#define SPDIF_CH1_CS_159128_ADDR 0x30060 --#define SPDIF_CH1_CS_191160_ADDR 0x30064 --#define SPDIF_CH2_CS_3100_ADDR 0x30068 --#define SPDIF_CH2_CS_6332_ADDR 0x3006c --#define SPDIF_CH2_CS_9564_ADDR 0x30070 --#define SPDIF_CH2_CS_12796_ADDR 0x30074 --#define SPDIF_CH2_CS_159128_ADDR 0x30078 --#define SPDIF_CH2_CS_191160_ADDR 0x3007c --#define SMPL2PKT_CNTL 0x30080 --#define SMPL2PKT_CNFG 0x30084 --#define FIFO_CNTL 0x30088 --#define FIFO_STTS 0x3008c -- --/* source pif addr */ --#define SOURCE_PIF_WR_ADDR 0x30800 --#define SOURCE_PIF_WR_REQ 0x30804 --#define SOURCE_PIF_RD_ADDR 0x30808 --#define SOURCE_PIF_RD_REQ 0x3080c --#define SOURCE_PIF_DATA_WR 0x30810 --#define SOURCE_PIF_DATA_RD 0x30814 --#define SOURCE_PIF_FIFO1_FLUSH 0x30818 --#define SOURCE_PIF_FIFO2_FLUSH 0x3081c --#define SOURCE_PIF_STATUS 0x30820 --#define SOURCE_PIF_INTERRUPT_SOURCE 0x30824 --#define SOURCE_PIF_INTERRUPT_MASK 0x30828 --#define SOURCE_PIF_PKT_ALLOC_REG 0x3082c --#define SOURCE_PIF_PKT_ALLOC_WR_EN 0x30830 --#define SOURCE_PIF_SW_RESET 0x30834 -- --/* bellow registers need access by mailbox */ --/* source car addr */ --#define SOURCE_HDTX_CAR 0x0900 --#define SOURCE_DPTX_CAR 0x0904 --#define SOURCE_PHY_CAR 0x0908 --#define SOURCE_CEC_CAR 0x090c --#define SOURCE_CBUS_CAR 0x0910 --#define SOURCE_PKT_CAR 0x0918 --#define SOURCE_AIF_CAR 0x091c --#define SOURCE_CIPHER_CAR 0x0920 --#define SOURCE_CRYPTO_CAR 0x0924 -- --/* clock meters addr */ --#define CM_CTRL 0x0a00 --#define CM_I2S_CTRL 0x0a04 --#define CM_SPDIF_CTRL 0x0a08 --#define CM_VID_CTRL 0x0a0c --#define CM_LANE_CTRL 0x0a10 --#define I2S_NM_STABLE 0x0a14 --#define I2S_NCTS_STABLE 0x0a18 --#define SPDIF_NM_STABLE 0x0a1c --#define SPDIF_NCTS_STABLE 0x0a20 --#define NMVID_MEAS_STABLE 0x0a24 --#define I2S_MEAS 0x0a40 --#define SPDIF_MEAS 0x0a80 --#define NMVID_MEAS 0x0ac0 -- --/* source vif addr */ --#define BND_HSYNC2VSYNC 0x0b00 --#define HSYNC2VSYNC_F1_L1 0x0b04 --#define HSYNC2VSYNC_F2_L1 0x0b08 --#define HSYNC2VSYNC_STATUS 0x0b0c --#define HSYNC2VSYNC_POL_CTRL 0x0b10 -- --/* dptx phy addr */ --#define DP_TX_PHY_CONFIG_REG 0x2000 --#define DP_TX_PHY_SW_RESET 0x2004 --#define DP_TX_PHY_SCRAMBLER_SEED 0x2008 --#define DP_TX_PHY_TRAINING_01_04 0x200c --#define DP_TX_PHY_TRAINING_05_08 0x2010 --#define DP_TX_PHY_TRAINING_09_10 0x2014 --#define TEST_COR 0x23fc -- --/* dptx hpd addr */ --#define HPD_IRQ_DET_MIN_TIMER 0x2100 --#define HPD_IRQ_DET_MAX_TIMER 0x2104 --#define HPD_UNPLGED_DET_MIN_TIMER 0x2108 --#define HPD_STABLE_TIMER 0x210c --#define HPD_FILTER_TIMER 0x2110 --#define HPD_EVENT_MASK 0x211c --#define HPD_EVENT_DET 0x2120 -- --/* dpyx framer addr */ --#define DP_FRAMER_GLOBAL_CONFIG 0x2200 --#define DP_SW_RESET 0x2204 --#define DP_FRAMER_TU 0x2208 --#define DP_FRAMER_PXL_REPR 0x220c --#define DP_FRAMER_SP 0x2210 --#define AUDIO_PACK_CONTROL 0x2214 --#define DP_VC_TABLE(x) (0x2218 + ((x) << 2)) --#define DP_VB_ID 0x2258 --#define DP_MTPH_LVP_CONTROL 0x225c --#define DP_MTPH_SYMBOL_VALUES 0x2260 --#define DP_MTPH_ECF_CONTROL 0x2264 --#define DP_MTPH_ACT_CONTROL 0x2268 --#define DP_MTPH_STATUS 0x226c --#define DP_INTERRUPT_SOURCE 0x2270 --#define DP_INTERRUPT_MASK 0x2274 --#define DP_FRONT_BACK_PORCH 0x2278 --#define DP_BYTE_COUNT 0x227c -- --/* dptx stream addr */ --#define MSA_HORIZONTAL_0 0x2280 --#define MSA_HORIZONTAL_1 0x2284 --#define MSA_VERTICAL_0 0x2288 --#define MSA_VERTICAL_1 0x228c --#define MSA_MISC 0x2290 --#define STREAM_CONFIG 0x2294 --#define AUDIO_PACK_STATUS 0x2298 --#define VIF_STATUS 0x229c --#define PCK_STUFF_STATUS_0 0x22a0 --#define PCK_STUFF_STATUS_1 0x22a4 --#define INFO_PACK_STATUS 0x22a8 --#define RATE_GOVERNOR_STATUS 0x22ac --#define DP_HORIZONTAL 0x22b0 --#define DP_VERTICAL_0 0x22b4 --#define DP_VERTICAL_1 0x22b8 --#define DP_BLOCK_SDP 0x22bc -- --/* dptx glbl addr */ --#define DPTX_LANE_EN 0x2300 --#define DPTX_ENHNCD 0x2304 --#define DPTX_INT_MASK 0x2308 --#define DPTX_INT_STATUS 0x230c -- --/* dp aux addr */ --#define DP_AUX_HOST_CONTROL 0x2800 --#define DP_AUX_INTERRUPT_SOURCE 0x2804 --#define DP_AUX_INTERRUPT_MASK 0x2808 --#define DP_AUX_SWAP_INVERSION_CONTROL 0x280c --#define DP_AUX_SEND_NACK_TRANSACTION 0x2810 --#define DP_AUX_CLEAR_RX 0x2814 --#define DP_AUX_CLEAR_TX 0x2818 --#define DP_AUX_TIMER_STOP 0x281c --#define DP_AUX_TIMER_CLEAR 0x2820 --#define DP_AUX_RESET_SW 0x2824 --#define DP_AUX_DIVIDE_2M 0x2828 --#define DP_AUX_TX_PREACHARGE_LENGTH 0x282c --#define DP_AUX_FREQUENCY_1M_MAX 0x2830 --#define DP_AUX_FREQUENCY_1M_MIN 0x2834 --#define DP_AUX_RX_PRE_MIN 0x2838 --#define DP_AUX_RX_PRE_MAX 0x283c --#define DP_AUX_TIMER_PRESET 0x2840 --#define DP_AUX_NACK_FORMAT 0x2844 --#define DP_AUX_TX_DATA 0x2848 --#define DP_AUX_RX_DATA 0x284c --#define DP_AUX_TX_STATUS 0x2850 --#define DP_AUX_RX_STATUS 0x2854 --#define DP_AUX_RX_CYCLE_COUNTER 0x2858 --#define DP_AUX_MAIN_STATES 0x285c --#define DP_AUX_MAIN_TIMER 0x2860 --#define DP_AUX_AFE_OUT 0x2864 -- --/* crypto addr */ --#define CRYPTO_HDCP_REVISION 0x5800 --#define HDCP_CRYPTO_CONFIG 0x5804 --#define CRYPTO_INTERRUPT_SOURCE 0x5808 --#define CRYPTO_INTERRUPT_MASK 0x580c --#define CRYPTO22_CONFIG 0x5818 --#define CRYPTO22_STATUS 0x581c --#define SHA_256_DATA_IN 0x583c --#define SHA_256_DATA_OUT_(x) (0x5850 + ((x) << 2)) --#define AES_32_KEY_(x) (0x5870 + ((x) << 2)) --#define AES_32_DATA_IN 0x5880 --#define AES_32_DATA_OUT_(x) (0x5884 + ((x) << 2)) --#define CRYPTO14_CONFIG 0x58a0 --#define CRYPTO14_STATUS 0x58a4 --#define CRYPTO14_PRNM_OUT 0x58a8 --#define CRYPTO14_KM_0 0x58ac --#define CRYPTO14_KM_1 0x58b0 --#define CRYPTO14_AN_0 0x58b4 --#define CRYPTO14_AN_1 0x58b8 --#define CRYPTO14_YOUR_KSV_0 0x58bc --#define CRYPTO14_YOUR_KSV_1 0x58c0 --#define CRYPTO14_MI_0 0x58c4 --#define CRYPTO14_MI_1 0x58c8 --#define CRYPTO14_TI_0 0x58cc --#define CRYPTO14_KI_0 0x58d0 --#define CRYPTO14_KI_1 0x58d4 --#define CRYPTO14_BLOCKS_NUM 0x58d8 --#define CRYPTO14_KEY_MEM_DATA_0 0x58dc --#define CRYPTO14_KEY_MEM_DATA_1 0x58e0 --#define CRYPTO14_SHA1_MSG_DATA 0x58e4 --#define CRYPTO14_SHA1_V_VALUE_(x) (0x58e8 + ((x) << 2)) --#define TRNG_CTRL 0x58fc --#define TRNG_DATA_RDY 0x5900 --#define TRNG_DATA 0x5904 -- --/* cipher addr */ --#define HDCP_REVISION 0x60000 --#define INTERRUPT_SOURCE 0x60004 --#define INTERRUPT_MASK 0x60008 --#define HDCP_CIPHER_CONFIG 0x6000c --#define AES_128_KEY_0 0x60010 --#define AES_128_KEY_1 0x60014 --#define AES_128_KEY_2 0x60018 --#define AES_128_KEY_3 0x6001c --#define AES_128_RANDOM_0 0x60020 --#define AES_128_RANDOM_1 0x60024 --#define CIPHER14_KM_0 0x60028 --#define CIPHER14_KM_1 0x6002c --#define CIPHER14_STATUS 0x60030 --#define CIPHER14_RI_PJ_STATUS 0x60034 --#define CIPHER_MODE 0x60038 --#define CIPHER14_AN_0 0x6003c --#define CIPHER14_AN_1 0x60040 --#define CIPHER22_AUTH 0x60044 --#define CIPHER14_R0_DP_STATUS 0x60048 --#define CIPHER14_BOOTSTRAP 0x6004c -- --#define DPTX_FRMR_DATA_CLK_RSTN_EN BIT(11) --#define DPTX_FRMR_DATA_CLK_EN BIT(10) --#define DPTX_PHY_DATA_RSTN_EN BIT(9) --#define DPTX_PHY_DATA_CLK_EN BIT(8) --#define DPTX_PHY_CHAR_RSTN_EN BIT(7) --#define DPTX_PHY_CHAR_CLK_EN BIT(6) --#define SOURCE_AUX_SYS_CLK_RSTN_EN BIT(5) --#define SOURCE_AUX_SYS_CLK_EN BIT(4) --#define DPTX_SYS_CLK_RSTN_EN BIT(3) --#define DPTX_SYS_CLK_EN BIT(2) --#define CFG_DPTX_VIF_CLK_RSTN_EN BIT(1) --#define CFG_DPTX_VIF_CLK_EN BIT(0) -- --#define SOURCE_PHY_RSTN_EN BIT(1) --#define SOURCE_PHY_CLK_EN BIT(0) -- --#define SOURCE_PKT_SYS_RSTN_EN BIT(3) --#define SOURCE_PKT_SYS_CLK_EN BIT(2) --#define SOURCE_PKT_DATA_RSTN_EN BIT(1) --#define SOURCE_PKT_DATA_CLK_EN BIT(0) -- --#define SPDIF_CDR_CLK_RSTN_EN BIT(5) --#define SPDIF_CDR_CLK_EN BIT(4) --#define SOURCE_AIF_SYS_RSTN_EN BIT(3) --#define SOURCE_AIF_SYS_CLK_EN BIT(2) --#define SOURCE_AIF_CLK_RSTN_EN BIT(1) --#define SOURCE_AIF_CLK_EN BIT(0) -- --#define SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN BIT(3) --#define SOURCE_CIPHER_SYS_CLK_EN BIT(2) --#define SOURCE_CIPHER_CHAR_CLK_RSTN_EN BIT(1) --#define SOURCE_CIPHER_CHAR_CLK_EN BIT(0) -- --#define SOURCE_CRYPTO_SYS_CLK_RSTN_EN BIT(1) --#define SOURCE_CRYPTO_SYS_CLK_EN BIT(0) -- --#define APB_IRAM_PATH BIT(2) --#define APB_DRAM_PATH BIT(1) --#define APB_XT_RESET BIT(0) -- --#define MAILBOX_INT_MASK_BIT BIT(1) --#define PIF_INT_MASK_BIT BIT(0) --#define ALL_INT_MASK 3 -- --/* mailbox */ --#define MB_OPCODE_ID 0 --#define MB_MODULE_ID 1 --#define MB_SIZE_MSB_ID 2 --#define MB_SIZE_LSB_ID 3 --#define MB_DATA_ID 4 -- --#define MB_MODULE_ID_DP_TX 0x01 --#define MB_MODULE_ID_HDCP_TX 0x07 --#define MB_MODULE_ID_HDCP_RX 0x08 --#define MB_MODULE_ID_HDCP_GENERAL 0x09 --#define MB_MODULE_ID_GENERAL 0x0a -- --/* general opcode */ --#define GENERAL_MAIN_CONTROL 0x01 --#define GENERAL_TEST_ECHO 0x02 --#define GENERAL_BUS_SETTINGS 0x03 --#define GENERAL_TEST_ACCESS 0x04 -- --#define DPTX_SET_POWER_MNG 0x00 --#define DPTX_SET_HOST_CAPABILITIES 0x01 --#define DPTX_GET_EDID 0x02 --#define DPTX_READ_DPCD 0x03 --#define DPTX_WRITE_DPCD 0x04 --#define DPTX_ENABLE_EVENT 0x05 --#define DPTX_WRITE_REGISTER 0x06 --#define DPTX_READ_REGISTER 0x07 --#define DPTX_WRITE_FIELD 0x08 --#define DPTX_TRAINING_CONTROL 0x09 --#define DPTX_READ_EVENT 0x0a --#define DPTX_READ_LINK_STAT 0x0b --#define DPTX_SET_VIDEO 0x0c --#define DPTX_SET_AUDIO 0x0d --#define DPTX_GET_LAST_AUX_STAUS 0x0e --#define DPTX_SET_LINK_BREAK_POINT 0x0f --#define DPTX_FORCE_LANES 0x10 --#define DPTX_HPD_STATE 0x11 -- --#define FW_STANDBY 0 --#define FW_ACTIVE 1 -- --#define DPTX_EVENT_ENABLE_HPD BIT(0) --#define DPTX_EVENT_ENABLE_TRAINING BIT(1) -- --#define LINK_TRAINING_NOT_ACTIVE 0 --#define LINK_TRAINING_RUN 1 --#define LINK_TRAINING_RESTART 2 -- --#define CONTROL_VIDEO_IDLE 0 --#define CONTROL_VIDEO_VALID 1 -- --#define TU_CNT_RST_EN BIT(15) --#define VIF_BYPASS_INTERLACE BIT(13) --#define INTERLACE_FMT_DET BIT(12) --#define INTERLACE_DTCT_WIN 0x20 -- --#define DP_FRAMER_SP_INTERLACE_EN BIT(2) --#define DP_FRAMER_SP_HSP BIT(1) --#define DP_FRAMER_SP_VSP BIT(0) -- --/* capability */ --#define AUX_HOST_INVERT 3 --#define FAST_LT_SUPPORT 1 --#define FAST_LT_NOT_SUPPORT 0 --#define LANE_MAPPING_NORMAL 0x1b --#define LANE_MAPPING_FLIPPED 0xe4 --#define ENHANCED 1 --#define SCRAMBLER_EN BIT(4) -- --#define FULL_LT_STARTED BIT(0) --#define FASE_LT_STARTED BIT(1) --#define CLK_RECOVERY_FINISHED BIT(2) --#define EQ_PHASE_FINISHED BIT(3) --#define FASE_LT_START_FINISHED BIT(4) --#define CLK_RECOVERY_FAILED BIT(5) --#define EQ_PHASE_FAILED BIT(6) --#define FASE_LT_FAILED BIT(7) -- --#define DPTX_HPD_EVENT BIT(0) --#define DPTX_TRAINING_EVENT BIT(1) --#define HDCP_TX_STATUS_EVENT BIT(4) --#define HDCP2_TX_IS_KM_STORED_EVENT BIT(5) --#define HDCP2_TX_STORE_KM_EVENT BIT(6) --#define HDCP_TX_IS_RECEIVER_ID_VALID_EVENT BIT(7) -- --#define TU_SIZE 30 --#define CDNS_DP_MAX_LINK_RATE DP_LINK_BW_5_4 -- --/* audio */ --#define AUDIO_PACK_EN BIT(8) --#define SAMPLING_FREQ(x) (((x) & 0xf) << 16) --#define ORIGINAL_SAMP_FREQ(x) (((x) & 0xf) << 24) --#define SYNC_WR_TO_CH_ZERO BIT(1) --#define I2S_DEC_START BIT(1) --#define AUDIO_SW_RST BIT(0) --#define SMPL2PKT_EN BIT(1) --#define MAX_NUM_CH(x) (((x) & 0x1f) - 1) --#define NUM_OF_I2S_PORTS(x) ((((x) / 2 - 1) & 0x3) << 5) --#define AUDIO_TYPE_LPCM (2 << 7) --#define CFG_SUB_PCKT_NUM(x) ((((x) - 1) & 0x7) << 11) --#define AUDIO_CH_NUM(x) ((((x) - 1) & 0x1f) << 2) --#define TRANS_SMPL_WIDTH_16 0 --#define TRANS_SMPL_WIDTH_24 BIT(11) --#define TRANS_SMPL_WIDTH_32 (2 << 11) --#define I2S_DEC_PORT_EN(x) (((x) & 0xf) << 17) --#define SPDIF_ENABLE BIT(21) --#define SPDIF_AVG_SEL BIT(20) --#define SPDIF_JITTER_BYPASS BIT(19) --#define SPDIF_FIFO_MID_RANGE(x) (((x) & 0xff) << 11) --#define SPDIF_JITTER_THRSH(x) (((x) & 0xff) << 3) --#define SPDIF_JITTER_AVG_WIN(x) ((x) & 0x7) -- --/* Reference cycles when using lane clock as reference */ --#define LANE_REF_CYC 0x8000 -- --enum voltage_swing_level { -- VOLTAGE_LEVEL_0, -- VOLTAGE_LEVEL_1, -- VOLTAGE_LEVEL_2, -- VOLTAGE_LEVEL_3, --}; -- --enum pre_emphasis_level { -- PRE_EMPHASIS_LEVEL_0, -- PRE_EMPHASIS_LEVEL_1, -- PRE_EMPHASIS_LEVEL_2, -- PRE_EMPHASIS_LEVEL_3, --}; -- --enum pattern_set { -- PTS1 = BIT(0), -- PTS2 = BIT(1), -- PTS3 = BIT(2), -- PTS4 = BIT(3), -- DP_NONE = BIT(4) --}; -- --enum vic_color_depth { -- BCS_6 = 0x1, -- BCS_8 = 0x2, -- BCS_10 = 0x4, -- BCS_12 = 0x8, -- BCS_16 = 0x10, --}; -- --enum vic_bt_type { -- BT_601 = 0x0, -- BT_709 = 0x1, --}; -- --enum audio_format { -- AFMT_I2S = 0, -- AFMT_SPDIF = 1, -- AFMT_UNUSED, --}; -- --struct audio_info { -- enum audio_format format; -- int sample_rate; -- int channels; -- int sample_width; --}; -- --enum vic_pxl_encoding_format { -- PXL_RGB = 0x1, -- YCBCR_4_4_4 = 0x2, -- YCBCR_4_2_2 = 0x4, -- YCBCR_4_2_0 = 0x8, -- Y_ONLY = 0x10, --}; -- --struct video_info { -- bool h_sync_polarity; -- bool v_sync_polarity; -- bool interlaced; -- int color_depth; -- enum vic_pxl_encoding_format color_fmt; --}; -- --struct cdns_mhdp_host { -- unsigned int link_rate; -- u8 lanes_cnt; -- u8 volt_swing; -- u8 pre_emphasis; -- u8 pattern_supp; -- u8 fast_link; -- u8 lane_mapping; -- u8 enhanced; --}; -- --struct cdns_mhdp_sink { -- unsigned int link_rate; -- u8 lanes_cnt; -- u8 pattern_supp; -- u8 fast_link; -- u8 enhanced; --}; -- --struct cdns_mhdp_device { -- void __iomem *regs; -- -- struct device *dev; -- -- struct drm_dp_link link; -- struct drm_connector connector; -- struct clk *spdif_clk; -- struct reset_control *spdif_rst; -- -- struct drm_dp_aux aux; -- struct cdns_mhdp_host host; -- struct cdns_mhdp_sink sink; -- struct drm_bridge bridge; -- struct phy *phy; -- void __iomem *dbg_regs; -- -- struct video_info video_info; -- struct drm_display_mode mode; -- unsigned int fw_version; --}; -- --void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp); --void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk); --int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, -- u32 i_size, const u32 *d_mem, u32 d_size); --int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable); --int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip); --int cdns_mhdp_event_config(struct cdns_mhdp_device *mhdp); --u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp); --int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp); --int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value); --int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp, -- u32 addr, u8 *data, u16 len); --int cdns_mhdp_get_edid_block(void *mhdp, u8 *edid, -- unsigned int block, size_t length); --int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp); --int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active); --int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp); --int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio); --int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable); --int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio); --#endif /* _CDN_DP_REG_H */ ---- /dev/null -+++ b/include/drm/bridge/cdns-mhdp-cbs.h -@@ -0,0 +1,29 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Cadence MHDP DP bridge callbacks. -+ * -+ * Copyright: 2018 Cadence Design Systems, Inc. -+ * -+ * Author: Piotr Sroka <piotrs@cadence.com> -+ */ -+ -+#ifndef CDNS_MHDP_CBS_H -+#define CDNS_MHDP_CBS_H -+ -+#include <drm/drm_bridge.h> -+ -+struct cdns_mhdp_mst_cbs_funcs { -+ struct drm_encoder *(*create_mst_encoder)(void *priv_data, -+ struct drm_bridge *bridge); -+ void (*destroy_mst_encoder)(void *priv_data, struct drm_bridge *bridge); -+}; -+ -+struct cdns_mhdp_mst_cbs { -+ struct cdns_mhdp_mst_cbs_funcs funcs; -+ void *priv_data; -+}; -+ -+int mhdp_bridge_attach_mst_cbs(struct drm_bridge *bridge, -+ struct cdns_mhdp_mst_cbs *cbs); -+ -+#endif ---- /dev/null -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -0,0 +1,704 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd -+ * Author: Chris Zhong <zyw@rock-chips.com> -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef CDNS_MHDP_COMMON_H_ -+#define CDNS_MHDP_COMMON_H_ -+ -+#include <drm/bridge/cdns-mhdp-cbs.h> -+#include <drm/drm_bridge.h> -+#include <drm/drm_connector.h> -+#include <drm/drm_dp_helper.h> -+#include <drm/drm_dp_mst_helper.h> -+ -+#include <linux/bitops.h> -+ -+#define ADDR_IMEM 0x10000 -+#define ADDR_DMEM 0x20000 -+#define ADDR_PHY_AFE 0x80000 -+ -+/* APB CFG addr */ -+#define APB_CTRL 0 -+#define XT_INT_CTRL 0x04 -+#define MAILBOX_FULL_ADDR 0x08 -+#define MAILBOX_EMPTY_ADDR 0x0c -+#define MAILBOX0_WR_DATA 0x10 -+#define MAILBOX0_RD_DATA 0x14 -+#define KEEP_ALIVE 0x18 -+#define VER_L 0x1c -+#define VER_H 0x20 -+#define VER_LIB_L_ADDR 0x24 -+#define VER_LIB_H_ADDR 0x28 -+#define SW_DEBUG_L 0x2c -+#define SW_DEBUG_H 0x30 -+#define MAILBOX_INT_MASK 0x34 -+#define MAILBOX_INT_STATUS 0x38 -+#define SW_CLK_L 0x3c -+#define SW_CLK_H 0x40 -+#define SW_EVENTS0 0x44 -+#define SW_EVENTS1 0x48 -+#define SW_EVENTS2 0x4c -+#define SW_EVENTS3 0x50 -+#define XT_OCD_CTRL 0x60 -+#define APB_INT_MASK 0x6c -+#define APB_STATUS_MASK 0x70 -+ -+/* audio decoder addr */ -+#define AUDIO_SRC_CNTL 0x30000 -+#define AUDIO_SRC_CNFG 0x30004 -+#define COM_CH_STTS_BITS 0x30008 -+#define STTS_BIT_CH(x) (0x3000c + ((x) << 2)) -+#define SPDIF_CTRL_ADDR 0x3004c -+#define SPDIF_CH1_CS_3100_ADDR 0x30050 -+#define SPDIF_CH1_CS_6332_ADDR 0x30054 -+#define SPDIF_CH1_CS_9564_ADDR 0x30058 -+#define SPDIF_CH1_CS_12796_ADDR 0x3005c -+#define SPDIF_CH1_CS_159128_ADDR 0x30060 -+#define SPDIF_CH1_CS_191160_ADDR 0x30064 -+#define SPDIF_CH2_CS_3100_ADDR 0x30068 -+#define SPDIF_CH2_CS_6332_ADDR 0x3006c -+#define SPDIF_CH2_CS_9564_ADDR 0x30070 -+#define SPDIF_CH2_CS_12796_ADDR 0x30074 -+#define SPDIF_CH2_CS_159128_ADDR 0x30078 -+#define SPDIF_CH2_CS_191160_ADDR 0x3007c -+#define SMPL2PKT_CNTL 0x30080 -+#define SMPL2PKT_CNFG 0x30084 -+#define FIFO_CNTL 0x30088 -+#define FIFO_STTS 0x3008c -+ -+/* source pif addr */ -+#define SOURCE_PIF_WR_ADDR 0x30800 -+#define SOURCE_PIF_WR_REQ 0x30804 -+#define SOURCE_PIF_RD_ADDR 0x30808 -+#define SOURCE_PIF_RD_REQ 0x3080c -+#define SOURCE_PIF_DATA_WR 0x30810 -+#define SOURCE_PIF_DATA_RD 0x30814 -+#define SOURCE_PIF_FIFO1_FLUSH 0x30818 -+#define SOURCE_PIF_FIFO2_FLUSH 0x3081c -+#define SOURCE_PIF_STATUS 0x30820 -+#define SOURCE_PIF_INTERRUPT_SOURCE 0x30824 -+#define SOURCE_PIF_INTERRUPT_MASK 0x30828 -+#define SOURCE_PIF_PKT_ALLOC_REG 0x3082c -+#define SOURCE_PIF_PKT_ALLOC_WR_EN 0x30830 -+#define SOURCE_PIF_SW_RESET 0x30834 -+ -+/* bellow registers need access by mailbox */ -+/* source phy comp */ -+#define PHY_DATA_SEL 0x0818 -+#define LANES_CONFIG 0x0814 -+ -+/* source car addr */ -+#define SOURCE_HDTX_CAR 0x0900 -+#define SOURCE_DPTX_CAR 0x0904 -+#define SOURCE_PHY_CAR 0x0908 -+#define SOURCE_CEC_CAR 0x090c -+#define SOURCE_CBUS_CAR 0x0910 -+#define SOURCE_PKT_CAR 0x0918 -+#define SOURCE_AIF_CAR 0x091c -+#define SOURCE_CIPHER_CAR 0x0920 -+#define SOURCE_CRYPTO_CAR 0x0924 -+ -+/* mhdp tx_top_comp */ -+#define SCHEDULER_H_SIZE 0x1000 -+#define SCHEDULER_V_SIZE 0x1004 -+#define HDTX_SIGNAL_FRONT_WIDTH 0x100c -+#define HDTX_SIGNAL_SYNC_WIDTH 0x1010 -+#define HDTX_SIGNAL_BACK_WIDTH 0x1014 -+#define HDTX_CONTROLLER 0x1018 -+#define HDTX_HPD 0x1020 -+#define HDTX_CLOCK_REG_0 0x1024 -+#define HDTX_CLOCK_REG_1 0x1028 -+ -+/* clock meters addr */ -+#define CM_CTRL 0x0a00 -+#define CM_I2S_CTRL 0x0a04 -+#define CM_SPDIF_CTRL 0x0a08 -+#define CM_VID_CTRL 0x0a0c -+#define CM_LANE_CTRL 0x0a10 -+#define I2S_NM_STABLE 0x0a14 -+#define I2S_NCTS_STABLE 0x0a18 -+#define SPDIF_NM_STABLE 0x0a1c -+#define SPDIF_NCTS_STABLE 0x0a20 -+#define NMVID_MEAS_STABLE 0x0a24 -+#define I2S_MEAS 0x0a40 -+#define SPDIF_MEAS 0x0a80 -+#define NMVID_MEAS 0x0ac0 -+ -+/* source vif addr */ -+#define BND_HSYNC2VSYNC 0x0b00 -+#define HSYNC2VSYNC_F1_L1 0x0b04 -+#define HSYNC2VSYNC_F2_L1 0x0b08 -+#define HSYNC2VSYNC_STATUS 0x0b0c -+#define HSYNC2VSYNC_POL_CTRL 0x0b10 -+ -+/* dptx phy addr */ -+#define DP_TX_PHY_CONFIG_REG 0x2000 -+#define DP_TX_PHY_SW_RESET 0x2004 -+#define DP_TX_PHY_SCRAMBLER_SEED 0x2008 -+#define DP_TX_PHY_TRAINING_01_04 0x200c -+#define DP_TX_PHY_TRAINING_05_08 0x2010 -+#define DP_TX_PHY_TRAINING_09_10 0x2014 -+#define TEST_COR 0x23fc -+ -+/* dptx hpd addr */ -+#define HPD_IRQ_DET_MIN_TIMER 0x2100 -+#define HPD_IRQ_DET_MAX_TIMER 0x2104 -+#define HPD_UNPLGED_DET_MIN_TIMER 0x2108 -+#define HPD_STABLE_TIMER 0x210c -+#define HPD_FILTER_TIMER 0x2110 -+#define HPD_EVENT_MASK 0x211c -+#define HPD_EVENT_DET 0x2120 -+ -+/* dpyx framer addr */ -+#define DP_FRAMER_GLOBAL_CONFIG 0x2200 -+#define DP_SW_RESET 0x2204 -+#define DP_FRAMER_TU 0x2208 -+#define DP_FRAMER_PXL_REPR 0x220c -+#define DP_FRAMER_SP 0x2210 -+#define AUDIO_PACK_CONTROL 0x2214 -+#define DP_VC_TABLE(x) (0x2218 + ((x) << 2)) -+#define DP_VB_ID 0x2258 -+#define DP_MTPH_LVP_CONTROL 0x225c -+#define DP_MTPH_SYMBOL_VALUES 0x2260 -+#define DP_MTPH_ECF_CONTROL 0x2264 -+#define DP_MTPH_ACT_CONTROL 0x2268 -+#define DP_MTPH_STATUS 0x226c -+#define DP_INTERRUPT_SOURCE 0x2270 -+#define DP_INTERRUPT_MASK 0x2274 -+#define DP_FRONT_BACK_PORCH 0x2278 -+#define DP_BYTE_COUNT 0x227c -+ -+/* dptx stream addr */ -+#define MSA_HORIZONTAL_0 0x2280 -+#define MSA_HORIZONTAL_1 0x2284 -+#define MSA_VERTICAL_0 0x2288 -+#define MSA_VERTICAL_1 0x228c -+#define MSA_MISC 0x2290 -+#define STREAM_CONFIG 0x2294 -+#define AUDIO_PACK_STATUS 0x2298 -+#define VIF_STATUS 0x229c -+#define PCK_STUFF_STATUS_0 0x22a0 -+#define PCK_STUFF_STATUS_1 0x22a4 -+#define INFO_PACK_STATUS 0x22a8 -+#define RATE_GOVERNOR_STATUS 0x22ac -+#define DP_HORIZONTAL 0x22b0 -+#define DP_VERTICAL_0 0x22b4 -+#define DP_VERTICAL_1 0x22b8 -+#define DP_BLOCK_SDP 0x22bc -+ -+/* dptx glbl addr */ -+#define DPTX_LANE_EN 0x2300 -+#define DPTX_ENHNCD 0x2304 -+#define DPTX_INT_MASK 0x2308 -+#define DPTX_INT_STATUS 0x230c -+ -+/* dp aux addr */ -+#define DP_AUX_HOST_CONTROL 0x2800 -+#define DP_AUX_INTERRUPT_SOURCE 0x2804 -+#define DP_AUX_INTERRUPT_MASK 0x2808 -+#define DP_AUX_SWAP_INVERSION_CONTROL 0x280c -+#define DP_AUX_SEND_NACK_TRANSACTION 0x2810 -+#define DP_AUX_CLEAR_RX 0x2814 -+#define DP_AUX_CLEAR_TX 0x2818 -+#define DP_AUX_TIMER_STOP 0x281c -+#define DP_AUX_TIMER_CLEAR 0x2820 -+#define DP_AUX_RESET_SW 0x2824 -+#define DP_AUX_DIVIDE_2M 0x2828 -+#define DP_AUX_TX_PREACHARGE_LENGTH 0x282c -+#define DP_AUX_FREQUENCY_1M_MAX 0x2830 -+#define DP_AUX_FREQUENCY_1M_MIN 0x2834 -+#define DP_AUX_RX_PRE_MIN 0x2838 -+#define DP_AUX_RX_PRE_MAX 0x283c -+#define DP_AUX_TIMER_PRESET 0x2840 -+#define DP_AUX_NACK_FORMAT 0x2844 -+#define DP_AUX_TX_DATA 0x2848 -+#define DP_AUX_RX_DATA 0x284c -+#define DP_AUX_TX_STATUS 0x2850 -+#define DP_AUX_RX_STATUS 0x2854 -+#define DP_AUX_RX_CYCLE_COUNTER 0x2858 -+#define DP_AUX_MAIN_STATES 0x285c -+#define DP_AUX_MAIN_TIMER 0x2860 -+#define DP_AUX_AFE_OUT 0x2864 -+ -+/* crypto addr */ -+#define CRYPTO_HDCP_REVISION 0x5800 -+#define HDCP_CRYPTO_CONFIG 0x5804 -+#define CRYPTO_INTERRUPT_SOURCE 0x5808 -+#define CRYPTO_INTERRUPT_MASK 0x580c -+#define CRYPTO22_CONFIG 0x5818 -+#define CRYPTO22_STATUS 0x581c -+#define SHA_256_DATA_IN 0x583c -+#define SHA_256_DATA_OUT_(x) (0x5850 + ((x) << 2)) -+#define AES_32_KEY_(x) (0x5870 + ((x) << 2)) -+#define AES_32_DATA_IN 0x5880 -+#define AES_32_DATA_OUT_(x) (0x5884 + ((x) << 2)) -+#define CRYPTO14_CONFIG 0x58a0 -+#define CRYPTO14_STATUS 0x58a4 -+#define CRYPTO14_PRNM_OUT 0x58a8 -+#define CRYPTO14_KM_0 0x58ac -+#define CRYPTO14_KM_1 0x58b0 -+#define CRYPTO14_AN_0 0x58b4 -+#define CRYPTO14_AN_1 0x58b8 -+#define CRYPTO14_YOUR_KSV_0 0x58bc -+#define CRYPTO14_YOUR_KSV_1 0x58c0 -+#define CRYPTO14_MI_0 0x58c4 -+#define CRYPTO14_MI_1 0x58c8 -+#define CRYPTO14_TI_0 0x58cc -+#define CRYPTO14_KI_0 0x58d0 -+#define CRYPTO14_KI_1 0x58d4 -+#define CRYPTO14_BLOCKS_NUM 0x58d8 -+#define CRYPTO14_KEY_MEM_DATA_0 0x58dc -+#define CRYPTO14_KEY_MEM_DATA_1 0x58e0 -+#define CRYPTO14_SHA1_MSG_DATA 0x58e4 -+#define CRYPTO14_SHA1_V_VALUE_(x) (0x58e8 + ((x) << 2)) -+#define TRNG_CTRL 0x58fc -+#define TRNG_DATA_RDY 0x5900 -+#define TRNG_DATA 0x5904 -+ -+/* cipher addr */ -+#define HDCP_REVISION 0x60000 -+#define INTERRUPT_SOURCE 0x60004 -+#define INTERRUPT_MASK 0x60008 -+#define HDCP_CIPHER_CONFIG 0x6000c -+#define AES_128_KEY_0 0x60010 -+#define AES_128_KEY_1 0x60014 -+#define AES_128_KEY_2 0x60018 -+#define AES_128_KEY_3 0x6001c -+#define AES_128_RANDOM_0 0x60020 -+#define AES_128_RANDOM_1 0x60024 -+#define CIPHER14_KM_0 0x60028 -+#define CIPHER14_KM_1 0x6002c -+#define CIPHER14_STATUS 0x60030 -+#define CIPHER14_RI_PJ_STATUS 0x60034 -+#define CIPHER_MODE 0x60038 -+#define CIPHER14_AN_0 0x6003c -+#define CIPHER14_AN_1 0x60040 -+#define CIPHER22_AUTH 0x60044 -+#define CIPHER14_R0_DP_STATUS 0x60048 -+#define CIPHER14_BOOTSTRAP 0x6004c -+ -+#define DPTX_FRMR_DATA_CLK_RSTN_EN BIT(11) -+#define DPTX_FRMR_DATA_CLK_EN BIT(10) -+#define DPTX_PHY_DATA_RSTN_EN BIT(9) -+#define DPTX_PHY_DATA_CLK_EN BIT(8) -+#define DPTX_PHY_CHAR_RSTN_EN BIT(7) -+#define DPTX_PHY_CHAR_CLK_EN BIT(6) -+#define SOURCE_AUX_SYS_CLK_RSTN_EN BIT(5) -+#define SOURCE_AUX_SYS_CLK_EN BIT(4) -+#define DPTX_SYS_CLK_RSTN_EN BIT(3) -+#define DPTX_SYS_CLK_EN BIT(2) -+#define CFG_DPTX_VIF_CLK_RSTN_EN BIT(1) -+#define CFG_DPTX_VIF_CLK_EN BIT(0) -+ -+#define SOURCE_PHY_RSTN_EN BIT(1) -+#define SOURCE_PHY_CLK_EN BIT(0) -+ -+#define SOURCE_PKT_SYS_RSTN_EN BIT(3) -+#define SOURCE_PKT_SYS_CLK_EN BIT(2) -+#define SOURCE_PKT_DATA_RSTN_EN BIT(1) -+#define SOURCE_PKT_DATA_CLK_EN BIT(0) -+ -+#define SPDIF_CDR_CLK_RSTN_EN BIT(5) -+#define SPDIF_CDR_CLK_EN BIT(4) -+#define SOURCE_AIF_SYS_RSTN_EN BIT(3) -+#define SOURCE_AIF_SYS_CLK_EN BIT(2) -+#define SOURCE_AIF_CLK_RSTN_EN BIT(1) -+#define SOURCE_AIF_CLK_EN BIT(0) -+ -+#define SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN BIT(3) -+#define SOURCE_CIPHER_SYS_CLK_EN BIT(2) -+#define SOURCE_CIPHER_CHAR_CLK_RSTN_EN BIT(1) -+#define SOURCE_CIPHER_CHAR_CLK_EN BIT(0) -+ -+#define SOURCE_CRYPTO_SYS_CLK_RSTN_EN BIT(1) -+#define SOURCE_CRYPTO_SYS_CLK_EN BIT(0) -+ -+#define APB_IRAM_PATH BIT(2) -+#define APB_DRAM_PATH BIT(1) -+#define APB_XT_RESET BIT(0) -+ -+#define MAILBOX_INT_MASK_BIT BIT(1) -+#define PIF_INT_MASK_BIT BIT(0) -+#define ALL_INT_MASK 3 -+ -+/* mailbox */ -+#define MB_OPCODE_ID 0 -+#define MB_MODULE_ID 1 -+#define MB_SIZE_MSB_ID 2 -+#define MB_SIZE_LSB_ID 3 -+#define MB_DATA_ID 4 -+ -+#define MB_MODULE_ID_DP_TX 0x01 -+#define MB_MODULE_ID_HDMI_TX 0x03 -+#define MB_MODULE_ID_HDCP_TX 0x07 -+#define MB_MODULE_ID_HDCP_RX 0x08 -+#define MB_MODULE_ID_HDCP_GENERAL 0x09 -+#define MB_MODULE_ID_GENERAL 0x0A -+ -+/* general opcode */ -+#define GENERAL_MAIN_CONTROL 0x01 -+#define GENERAL_TEST_ECHO 0x02 -+#define GENERAL_BUS_SETTINGS 0x03 -+#define GENERAL_TEST_ACCESS 0x04 -+#define GENERAL_WRITE_REGISTER 0x05 -+#define GENERAL_WRITE_FIELD 0x06 -+#define GENERAL_READ_REGISTER 0x07 -+#define GENERAL_GET_HPD_STATE 0x11 -+ -+/* DPTX opcode */ -+#define DPTX_SET_POWER_MNG 0x00 -+#define DPTX_SET_HOST_CAPABILITIES 0x01 -+#define DPTX_GET_EDID 0x02 -+#define DPTX_READ_DPCD 0x03 -+#define DPTX_WRITE_DPCD 0x04 -+#define DPTX_ENABLE_EVENT 0x05 -+#define DPTX_WRITE_REGISTER 0x06 -+#define DPTX_READ_REGISTER 0x07 -+#define DPTX_WRITE_FIELD 0x08 -+#define DPTX_TRAINING_CONTROL 0x09 -+#define DPTX_READ_EVENT 0x0a -+#define DPTX_READ_LINK_STAT 0x0b -+#define DPTX_SET_VIDEO 0x0c -+#define DPTX_SET_AUDIO 0x0d -+#define DPTX_GET_LAST_AUX_STAUS 0x0e -+#define DPTX_SET_LINK_BREAK_POINT 0x0f -+#define DPTX_FORCE_LANES 0x10 -+#define DPTX_HPD_STATE 0x11 -+#define DPTX_ADJUST_LT 0x12 -+ -+/* HDMI TX opcode */ -+#define HDMI_TX_READ 0x00 -+#define HDMI_TX_WRITE 0x01 -+#define HDMI_TX_UPDATE_READ 0x02 -+#define HDMI_TX_EDID 0x03 -+#define HDMI_TX_EVENTS 0x04 -+#define HDMI_TX_HPD_STATUS 0x05 -+#define HDMI_TX_DEBUG_ECHO 0xAA -+#define HDMI_TX_TEST 0xBB -+#define HDMI_TX_EDID_INTERNAL 0xF0 -+ -+#define FW_STANDBY 0 -+#define FW_ACTIVE 1 -+ -+#define DPTX_EVENT_ENABLE_HPD BIT(0) -+#define DPTX_EVENT_ENABLE_TRAINING BIT(1) -+ -+#define LINK_TRAINING_NOT_ACTIVE 0 -+#define LINK_TRAINING_RUN 1 -+#define LINK_TRAINING_RESTART 2 -+ -+#define CONTROL_VIDEO_IDLE 0 -+#define CONTROL_VIDEO_VALID 1 -+ -+#define TU_CNT_RST_EN BIT(15) -+#define VIF_BYPASS_INTERLACE BIT(13) -+#define INTERLACE_FMT_DET BIT(12) -+#define INTERLACE_DTCT_WIN 0x20 -+ -+#define DP_FRAMER_SP_INTERLACE_EN BIT(2) -+#define DP_FRAMER_SP_HSP BIT(1) -+#define DP_FRAMER_SP_VSP BIT(0) -+ -+/* capability */ -+#define AUX_HOST_INVERT 3 -+#define FAST_LT_SUPPORT 1 -+#define FAST_LT_NOT_SUPPORT 0 -+#define LANE_MAPPING_NORMAL 0x1b -+#define LANE_MAPPING_FLIPPED 0xe4 -+#define ENHANCED 1 -+#define SCRAMBLER_EN BIT(4) -+ -+#define FULL_LT_STARTED BIT(0) -+#define FASE_LT_STARTED BIT(1) -+#define CLK_RECOVERY_FINISHED BIT(2) -+#define EQ_PHASE_FINISHED BIT(3) -+#define FASE_LT_START_FINISHED BIT(4) -+#define CLK_RECOVERY_FAILED BIT(5) -+#define EQ_PHASE_FAILED BIT(6) -+#define FASE_LT_FAILED BIT(7) -+ -+#define DPTX_HPD_EVENT BIT(0) -+#define DPTX_TRAINING_EVENT BIT(1) -+#define HDCP_TX_STATUS_EVENT BIT(4) -+#define HDCP2_TX_IS_KM_STORED_EVENT BIT(5) -+#define HDCP2_TX_STORE_KM_EVENT BIT(6) -+#define HDCP_TX_IS_RECEIVER_ID_VALID_EVENT BIT(7) -+ -+#define TU_SIZE 30 -+#define CDNS_DP_MAX_LINK_RATE DP_LINK_BW_5_4 -+ -+#define F_HDMI_ENCODING(x) (((x) & ((1 << 2) - 1)) << 16) -+#define F_VIF_DATA_WIDTH(x) (((x) & ((1 << 2) - 1)) << 2) -+#define F_HDMI_MODE(x) (((x) & ((1 << 2) - 1)) << 0) -+#define F_GCP_EN(x) (((x) & ((1 << 1) - 1)) << 12) -+#define F_DATA_EN(x) (((x) & ((1 << 1) - 1)) << 15) -+#define F_HDMI2_PREAMBLE_EN(x) (((x) & ((1 << 1) - 1)) << 18) -+#define F_PIC_3D(x) (((x) & ((1 << 4) - 1)) << 7) -+#define F_BCH_EN(x) (((x) & ((1 << 1) - 1)) << 11) -+#define F_SOURCE_PHY_MHDP_SEL(x) (((x) & ((1 << 2) - 1)) << 3) -+#define F_HPD_VALID_WIDTH(x) (((x) & ((1 << 12) - 1)) << 0) -+#define F_HPD_GLITCH_WIDTH(x) (((x) & ((1 << 8) - 1)) << 12) -+#define F_HDMI2_CTRL_IL_MODE(x) (((x) & ((1 << 1) - 1)) << 19) -+#define F_SOURCE_PHY_LANE0_SWAP(x) (((x) & ((1 << 2) - 1)) << 0) -+#define F_SOURCE_PHY_LANE1_SWAP(x) (((x) & ((1 << 2) - 1)) << 2) -+#define F_SOURCE_PHY_LANE2_SWAP(x) (((x) & ((1 << 2) - 1)) << 4) -+#define F_SOURCE_PHY_LANE3_SWAP(x) (((x) & ((1 << 2) - 1)) << 6) -+#define F_SOURCE_PHY_COMB_BYPASS(x) (((x) & ((1 << 1) - 1)) << 21) -+#define F_SOURCE_PHY_20_10(x) (((x) & ((1 << 1) - 1)) << 22) -+#define F_PKT_ALLOC_ADDRESS(x) (((x) & ((1 << 4) - 1)) << 0) -+#define F_ACTIVE_IDLE_TYPE(x) (((x) & ((1 << 1) - 1)) << 17) -+#define F_FIFO1_FLUSH(x) (((x) & ((1 << 1) - 1)) << 0) -+#define F_PKT_ALLOC_WR_EN(x) (((x) & ((1 << 1) - 1)) << 0) -+#define F_DATA_WR(x) (x) -+#define F_WR_ADDR(x) (((x) & ((1 << 4) - 1)) << 0) -+#define F_HOST_WR(x) (((x) & ((1 << 1) - 1)) << 0) -+#define F_TYPE_VALID(x) (((x) & ((1 << 1) - 1)) << 16) -+#define F_PACKET_TYPE(x) (((x) & ((1 << 8) - 1)) << 8) -+ -+/* audio */ -+#define AUDIO_PACK_EN BIT(8) -+#define SAMPLING_FREQ(x) (((x) & 0xf) << 16) -+#define ORIGINAL_SAMP_FREQ(x) (((x) & 0xf) << 24) -+#define SYNC_WR_TO_CH_ZERO BIT(1) -+#define I2S_DEC_START BIT(1) -+#define AUDIO_SW_RST BIT(0) -+#define SMPL2PKT_EN BIT(1) -+#define MAX_NUM_CH(x) (((x) & 0x1f) - 1) -+#define NUM_OF_I2S_PORTS(x) ((((x) / 2 - 1) & 0x3) << 5) -+#define AUDIO_TYPE_LPCM (2 << 7) -+#define CFG_SUB_PCKT_NUM(x) ((((x) - 1) & 0x7) << 11) -+#define AUDIO_CH_NUM(x) ((((x) - 1) & 0x1f) << 2) -+#define TRANS_SMPL_WIDTH_16 0 -+#define TRANS_SMPL_WIDTH_24 BIT(11) -+#define TRANS_SMPL_WIDTH_32 (2 << 11) -+#define I2S_DEC_PORT_EN(x) (((x) & 0xf) << 17) -+#define SPDIF_ENABLE BIT(21) -+#define SPDIF_AVG_SEL BIT(20) -+#define SPDIF_JITTER_BYPASS BIT(19) -+#define SPDIF_FIFO_MID_RANGE(x) (((x) & 0xff) << 11) -+#define SPDIF_JITTER_THRSH(x) (((x) & 0xff) << 3) -+#define SPDIF_JITTER_AVG_WIN(x) ((x) & 0x7) -+ -+/* Reference cycles when using lane clock as reference */ -+#define LANE_REF_CYC 0x8000 -+ -+#define HOTPLUG_DEBOUNCE_MS 200 -+ -+enum voltage_swing_level { -+ VOLTAGE_LEVEL_0, -+ VOLTAGE_LEVEL_1, -+ VOLTAGE_LEVEL_2, -+ VOLTAGE_LEVEL_3, -+}; -+ -+enum pre_emphasis_level { -+ PRE_EMPHASIS_LEVEL_0, -+ PRE_EMPHASIS_LEVEL_1, -+ PRE_EMPHASIS_LEVEL_2, -+ PRE_EMPHASIS_LEVEL_3, -+}; -+ -+enum pattern_set { -+ PTS1 = BIT(0), -+ PTS2 = BIT(1), -+ PTS3 = BIT(2), -+ PTS4 = BIT(3), -+ DP_NONE = BIT(4) -+}; -+ -+enum vic_color_depth { -+ BCS_6 = 0x1, -+ BCS_8 = 0x2, -+ BCS_10 = 0x4, -+ BCS_12 = 0x8, -+ BCS_16 = 0x10, -+}; -+ -+enum vic_bt_type { -+ BT_601 = 0x0, -+ BT_709 = 0x1, -+}; -+ -+enum audio_format { -+ AFMT_I2S = 0, -+ AFMT_SPDIF = 1, -+ AFMT_UNUSED, -+}; -+ -+enum { -+ MODE_DVI, -+ MODE_HDMI_1_4, -+ MODE_HDMI_2_0, -+}; -+ -+struct audio_info { -+ enum audio_format format; -+ int sample_rate; -+ int channels; -+ int sample_width; -+}; -+ -+enum vic_pxl_encoding_format { -+ PXL_RGB = 0x1, -+ YCBCR_4_4_4 = 0x2, -+ YCBCR_4_2_2 = 0x4, -+ YCBCR_4_2_0 = 0x8, -+ Y_ONLY = 0x10, -+}; -+ -+struct video_info { -+ bool h_sync_polarity; -+ bool v_sync_polarity; -+ bool interlaced; -+ int color_depth; -+ enum vic_pxl_encoding_format color_fmt; -+}; -+ -+struct cdns_mhdp_host { -+ unsigned int link_rate; -+ u8 lanes_cnt; -+ u8 volt_swing; -+ u8 pre_emphasis; -+ u8 pattern_supp; -+ u8 fast_link; -+ u8 lane_mapping; -+ u8 enhanced; -+}; -+ -+struct cdns_mhdp_sink { -+ unsigned int link_rate; -+ u8 lanes_cnt; -+ u8 pattern_supp; -+ u8 fast_link; -+ u8 enhanced; -+}; -+ -+struct cdns_mhdp_bridge; -+struct cdns_mhdp_connector; -+ -+struct cdns_mhdp_bridge { -+ struct cdns_mhdp_device *mhdp; -+ struct drm_bridge base; -+ int pbn; -+ int8_t stream_id; -+ struct cdns_mhdp_connector *connector; -+ bool is_active; -+}; -+ -+struct cdns_mhdp_connector { -+ struct drm_connector base; -+ bool is_mst_connector; -+ struct drm_dp_mst_port *port; -+ struct cdns_mhdp_bridge *bridge; -+}; -+ -+struct cdns_mhdp_device { -+ void __iomem *regs; -+ -+ struct device *dev; -+ -+ struct cdns_mhdp_connector connector; -+ struct clk *spdif_clk; -+ struct reset_control *spdif_rst; -+ -+ struct platform_device *audio_pdev; -+ struct audio_info audio_info; -+ -+ struct cdns_mhdp_bridge bridge; -+ struct phy *phy; -+ -+ struct video_info video_info; -+ struct drm_display_mode mode; -+ unsigned int fw_version; -+ -+ struct drm_dp_mst_topology_mgr mst_mgr; -+ struct delayed_work hotplug_work; -+ -+ bool link_up; -+ bool power_up; -+ bool plugged; -+ -+ union { -+ struct _dp_data { -+ struct drm_dp_link link; -+ struct drm_dp_aux aux; -+ struct cdns_mhdp_host host; -+ struct cdns_mhdp_sink sink; -+ struct cdns_mhdp_mst_cbs cbs; -+ bool is_mst; -+ bool can_mst; -+ u32 lane_mapping; -+ u32 link_rate; -+ u32 num_lanes; -+ } dp; -+ struct _hdmi_data { -+ u32 char_rate; -+ u32 hdmi_type; -+ } hdmi; -+ }; -+}; -+ -+void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp); -+void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk); -+int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, -+ u32 i_size, const u32 *d_mem, u32 d_size); -+int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable); -+int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip); -+int cdns_mhdp_event_config(struct cdns_mhdp_device *mhdp); -+u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value); -+int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp, -+ u32 addr, u8 *data, u16 len); -+int cdns_mhdp_get_edid_block(void *mhdp, u8 *edid, -+ unsigned int block, size_t length); -+int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active); -+int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio); -+int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable); -+int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio); -+int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr); -+int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u32 addr, u32 val); -+int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr, -+ u8 start_bit, u8 bits_no, u32 val); -+int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, u8 nlanes, -+ u16 udelay, u8 *lanes_data, -+ u8 *dpcd); -+ -+int cdns_mhdp_read_hpd(struct cdns_mhdp_device *mhdp); -+u32 cdns_phy_reg_read(struct cdns_mhdp_device *mhdp, u32 addr); -+int cdns_phy_reg_write(struct cdns_mhdp_device *mhdp, u32 addr, u32 val); -+int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id, -+ u8 opcode, u16 size, u8 *message); -+int cdns_mhdp_mailbox_read_receive(struct cdns_mhdp_device *mhdp, -+ u8 *buff, u16 buff_size); -+int cdns_mhdp_mailbox_validate_receive(struct cdns_mhdp_device *mhdp, -+ u8 module_id, u8 opcode, -+ u16 req_size); -+int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp); -+ -+int cdns_hdmi_get_edid_block(void *data, u8 *edid, u32 block, size_t length); -+int cdns_hdmi_scdc_read(struct cdns_mhdp_device *mhdp, u8 addr, u8 *data); -+int cdns_hdmi_scdc_write(struct cdns_mhdp_device *mhdp, u8 addr, u8 value); -+int cdns_hdmi_ctrl_init(struct cdns_mhdp_device *mhdp, int protocol, u32 char_rate); -+int cdns_hdmi_mode_config(struct cdns_mhdp_device *mhdp, struct drm_display_mode *mode, -+ struct video_info *video_info); -+int cdns_hdmi_disable_gcp(struct cdns_mhdp_device *mhdp); -+int cdns_hdmi_enable_gcp(struct cdns_mhdp_device *mhdp); -+ -+bool cdns_mhdp_check_alive(struct cdns_mhdp_device *mhdp); -+#endif /* CDNS_MHDP_COMMON_H_ */ |