From: Damian Kos <dkos@cadence.com>
To: "David Airlie" <airlied@linux.ie>,
"Rob Herring" <robh+dt@kernel.org>,
"Mark Rutland" <mark.rutland@arm.com>,
"Gustavo Padovan" <gustavo@padovan.org>,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Sean Paul" <seanpaul@chromium.org>,
"Sandy Huang" <hjc@rock-chips.com>,
"Heiko Stübner" <heiko@sntech.de>,
"Damian Kos" <dkos@cadence.com>,
dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-rockchip@lists.infradead.org
Cc: ltyrala@cadence.com, pgaj@cadence.com, stelford@cadence.com
Subject: [PATCH 11/12] drm/rockchip: added implementation for a few FW commands.
Date: Tue, 3 Jul 2018 11:02:22 +0100 [thread overview]
Message-ID: <1530612152-27555-12-git-send-email-dkos@cadence.com> (raw)
In-Reply-To: <1530612152-27555-1-git-send-email-dkos@cadence.com>
Added support for a register read, register write and register field write
commands.
Added support for adjust link training command.
Updated cdn_dp_get_event function, so it reads all SW event registers.
Added definitions mostly for Framer and Streamer.
Signed-off-by: Damian Kos <dkos@cadence.com>
---
drivers/gpu/drm/rockchip/cdn-dp-reg.c | 167 ++++++++++++++++++++++++++++++++-
drivers/gpu/drm/rockchip/cdn-dp-reg.h | 143 +++++++++++++++++++++++++++-
2 files changed, 305 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
index eb3042c..b061cfc 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
@@ -410,7 +410,10 @@ int cdn_dp_event_config(struct cdn_dp_device *dp)
u32 cdn_dp_get_event(struct cdn_dp_device *dp)
{
- return readl(dp->regs + SW_EVENTS0);
+ return readl(dp->regs + SW_EVENTS0)
+ | (readl(dp->regs + SW_EVENTS1) << 8)
+ | (readl(dp->regs + SW_EVENTS2) << 16)
+ | (readl(dp->regs + SW_EVENTS3) << 24);
}
int cdn_dp_get_hpd_status(struct cdn_dp_device *dp)
@@ -981,3 +984,165 @@ int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio)
DRM_DEV_ERROR(dp->dev, "audio config failed: %d\n", ret);
return ret;
}
+
+int cdn_dp_register_read(struct cdn_dp_device *dp, u32 addr, u32 *value)
+{
+ u8 msg[4], resp[8];
+ int ret;
+
+ if (addr == 0) {
+ ret = -EINVAL;
+ goto err_register_read;
+ }
+
+ msg[0] = (u8)(addr >> 24);
+ msg[1] = (u8)(addr >> 16);
+ msg[2] = (u8)(addr >> 8);
+ msg[3] = (u8)addr;
+
+ ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_GENERAL,
+ GENERAL_REGISTER_READ,
+ sizeof(msg), msg);
+ if (ret)
+ goto err_register_read;
+
+ ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_GENERAL,
+ GENERAL_REGISTER_READ,
+ sizeof(resp));
+ if (ret)
+ goto err_register_read;
+
+ ret = cdn_dp_mailbox_read_receive(dp, resp, sizeof(resp));
+ if (ret)
+ goto err_register_read;
+
+ /* Returned address value should be the same as requested */
+ if (memcmp(msg, resp, sizeof(msg))) {
+ ret = -EINVAL;
+ goto err_register_read;
+ }
+
+ *value = (resp[4] << 24) | (resp[5] << 16) | (resp[6] << 8) | resp[7];
+
+err_register_read:
+ if (ret) {
+ DRM_DEV_ERROR(dp->dev, "Failed to read register.\n");
+ *value = 0;
+ }
+
+ return ret;
+}
+
+int cdn_dp_register_write(struct cdn_dp_device *dp, u32 addr, u32 value)
+{
+ u8 msg[8];
+ int ret;
+
+ if (addr == 0)
+ return -EINVAL;
+
+ msg[0] = (u8)(addr >> 24);
+ msg[1] = (u8)(addr >> 16);
+ msg[2] = (u8)(addr >> 8);
+ msg[3] = (u8)addr;
+ msg[4] = (u8)(value >> 24);
+ msg[5] = (u8)(value >> 16);
+ msg[6] = (u8)(value >> 8);
+ msg[7] = (u8)value;
+
+ ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_GENERAL,
+ GENERAL_REGISTER_WRITE,
+ sizeof(msg), msg);
+ if (ret)
+ DRM_DEV_ERROR(dp->dev, "Failed to write register.\n");
+
+ return ret;
+}
+
+int cdn_dp_register_write_field(struct cdn_dp_device *dp, u32 addr,
+ u8 index, u8 nbits, u32 value)
+{
+ u8 msg[10];
+ int ret;
+
+ if (addr == 0)
+ return -EINVAL;
+
+ msg[0] = (u8)(addr >> 24);
+ msg[1] = (u8)(addr >> 16);
+ msg[2] = (u8)(addr >> 8);
+ msg[3] = (u8)addr;
+ msg[4] = index;
+ msg[5] = nbits;
+ msg[6] = (u8)(value >> 24);
+ msg[7] = (u8)(value >> 16);
+ msg[8] = (u8)(value >> 8);
+ msg[9] = (u8)value;
+
+ ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_GENERAL,
+ GENERAL_REGISTER_WRITE_FIELD,
+ sizeof(msg), msg);
+ if (ret)
+ DRM_DEV_ERROR(dp->dev, "Failed to write register field.\n");
+
+ return ret;
+}
+/* rep should be a pointer already allocated with .regs of size 6 */
+int cdn_dp_adjust_lt(struct cdn_dp_device *dp, u8 nlanes,
+ u16 udelay, u8 *lanes_data,
+ u8 *dpcd)
+{
+ u8 payload[10];
+ 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(dp->dev, "invalid number of lanes: %d\n", nlanes);
+ ret = -EINVAL;
+ goto err_adjust_lt;
+ }
+
+ payload[0] = nlanes;
+ payload[1] = (u8)(udelay >> 8);
+ payload[2] = (u8)udelay;
+
+ payload[3] = lanes_data[0];
+ if (nlanes > 1)
+ payload[4] = lanes_data[1];
+ if (nlanes > 2) {
+ payload[5] = lanes_data[2];
+ payload[6] = lanes_data[3];
+ }
+
+ ret = cdn_dp_mailbox_send(dp, 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 = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
+ DPTX_READ_DPCD,
+ sizeof(hdr) + nregs);
+ if (ret)
+ goto err_adjust_lt;
+
+ ret = cdn_dp_mailbox_read_receive(dp, hdr, sizeof(hdr));
+ if (ret)
+ goto err_adjust_lt;
+
+ addr = (hdr[2] << 24) | (hdr[3] << 8) | hdr[4];
+ if (addr != DP_LANE0_1_STATUS)
+ goto err_adjust_lt;
+
+ ret = cdn_dp_mailbox_read_receive(dp, dpcd, nregs);
+
+err_adjust_lt:
+ if (ret)
+ DRM_DEV_ERROR(dp->dev, "Failed to adjust Link Training.\n");
+
+ return ret;
+}
+
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.h b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
index c4bbb4a..b5472ad 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
@@ -156,6 +156,14 @@
#define DP_FRONT_BACK_PORCH 0x2278
#define DP_BYTE_COUNT 0x227c
+/* dptx framer global config fields */
+#define DP_FRAMER_NUM_LANES(x) (x - 1)
+#define DP_FRAMER_EN BIT(3)
+#define DP_FRAMER_RATE_GOVERNOR_EN BIT(4)
+#define DP_FRAMER_NO_VIDEO_MODE BIT(5)
+#define DP_FRAMER_DISABLE_PHY_RST BIT(6)
+#define DP_FRAMER_WR_FAILING_EDGE_VSYNC BIT(7)
+
/* dptx stream addr */
#define MSA_HORIZONTAL_0 0x2280
#define MSA_HORIZONTAL_1 0x2284
@@ -323,10 +331,13 @@
#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_MAIN_CONTROL 0x01
+#define GENERAL_TEST_ECHO 0x02
+#define GENERAL_BUS_SETTINGS 0x03
+#define GENERAL_TEST_ACCESS 0x04
+#define GENERAL_REGISTER_WRITE 0x05
+#define GENERAL_REGISTER_WRITE_FIELD 0x06
+#define GENERAL_REGISTER_READ 0x07
#define DPTX_SET_POWER_MNG 0x00
#define DPTX_SET_HOST_CAPABILITIES 0x01
@@ -346,6 +357,7 @@
#define DPTX_SET_LINK_BREAK_POINT 0x0f
#define DPTX_FORCE_LANES 0x10
#define DPTX_HPD_STATE 0x11
+#define DPTX_ADJUST_LT 0x12
#define FW_STANDBY 0
#define FW_ACTIVE 1
@@ -424,6 +436,122 @@
/* Reference cycles when using lane clock as reference */
#define LANE_REF_CYC 0x8000
+#define CDN_DPTX_FRAMER 0x02200
+#define CDN_DP_FRAMER_GLOBAL_CONFIG (CDN_DPTX_FRAMER + 0x00)
+#define CDN_DP_NUM_LANES(x) (x - 1)
+#define CDN_DP_FRAMER_EN BIT(3)
+#define CDN_DP_RATE_GOVERNOR_EN BIT(4)
+#define CDN_DP_NO_VIDEO_MODE BIT(5)
+#define CDN_DP_DISABLE_PHY_RST BIT(6)
+#define CDN_DP_WR_FAILING_EDGE_VSYNC BIT(7)
+
+#define CDN_DP_SW_RESET (CDN_DPTX_FRAMER + 0x04)
+#define CDN_DP_FRAMER_TU (CDN_DPTX_FRAMER + 0x08)
+#define CDN_DP_FRAMER_TU_SIZE(x) (((x) & GENMASK(6, 0)) << 8)
+#define CDN_DP_FRAMER_TU_VS(x) ((x) & GENMASK(5, 0))
+#define CDN_DP_FRAMER_TU_CNT_RST_EN BIT(15)
+
+#define CDN_DPTX_STREAM 0x03000
+#define CDN_DP_MSA_HORIZONTAL_0 (CDN_DPTX_STREAM + 0x00)
+#define CDN_DP_MSAH0_H_TOTAL(x) (x)
+#define CDN_DP_MSAH0_HSYNC_START(x) ((x) << 16)
+
+#define CDN_DP_MSA_HORIZONTAL_1 (CDN_DPTX_STREAM + 0x04)
+#define CDN_DP_MSAH1_HSYNC_WIDTH(x) (x)
+#define CDN_DP_MSAH1_HSYNC_POL_LOW BIT(15)
+#define CDN_DP_MSAH1_HDISP_WIDTH(x) ((x) << 16)
+
+#define CDN_DP_MSA_VERTICAL_0 (CDN_DPTX_STREAM + 0x08)
+#define CDN_DP_MSAV0_V_TOTAL(x) (x)
+#define CDN_DP_MSAV0_VSYNC_START(x) ((x) << 16)
+
+#define CDN_DP_MSA_VERTICAL_1 (CDN_DPTX_STREAM + 0x0c)
+#define CDN_DP_MSAV1_VSYNC_WIDTH(x) (x)
+#define CDN_DP_MSAV1_VSYNC_POL_LOW BIT(15)
+#define CDN_DP_MSAV1_VDISP_WIDTH(x) ((x) << 16)
+
+#define CDN_DP_MSA_MISC (CDN_DPTX_STREAM + 0x10)
+#define CDN_DP_STREAM_CONFIG (CDN_DPTX_STREAM + 0x14)
+#define CDN_DP_RATE_GOVERNOR_STATUS (CDN_DPTX_STREAM + 0x2c)
+#define CDN_DP_RG_TU_VS_DIFF(x) ((x) << 8)
+
+#define CDN_DP_HORIZONTAL (CDN_DPTX_STREAM + 0x30)
+#define CDN_DP_H_HSYNC_WIDTH(x) (x)
+#define CDN_DP_H_H_TOTAL(x) ((x) << 16)
+
+#define CDN_DP_VERTICAL_0 (CDN_DPTX_STREAM + 0x34)
+#define CDN_DP_V0_VHEIGHT(x) (x)
+#define CDN_DP_V0_VSTART(x) ((x) << 16)
+
+#define CDN_DP_VERTICAL_1 (CDN_DPTX_STREAM + 0x38)
+#define CDN_DP_V1_VTOTAL(x) (x)
+#define CDN_DP_V1_VTOTAL_EVEN BIT(16)
+
+#define CDN_DP_FRAMER_PXL_REPR (CDN_DPTX_STREAM + 0x4c)
+#define CDN_DP_FRAMER_6_BPC BIT(0)
+#define CDN_DP_FRAMER_8_BPC BIT(1)
+#define CDN_DP_FRAMER_10_BPC BIT(2)
+#define CDN_DP_FRAMER_12_BPC BIT(3)
+#define CDN_DP_FRAMER_16_BPC BIT(4)
+#define CDN_DP_FRAMER_PXL_FORMAT 0x8
+#define CDN_DP_FRAMER_RGB BIT(0)
+#define CDN_DP_FRAMER_YCBCR444 BIT(1)
+#define CDN_DP_FRAMER_YCBCR422 BIT(2)
+#define CDN_DP_FRAMER_YCBCR420 BIT(3)
+#define CDN_DP_FRAMER_Y_ONLY BIT(4)
+
+#define CDN_DP_FRAMER_SP (CDN_DPTX_STREAM + 0x10)
+#define CDN_DP_FRAMER_VSYNC_POL_LOW BIT(0)
+#define CDN_DP_FRAMER_HSYNC_POL_LOW BIT(1)
+#define CDN_DP_FRAMER_INTERLACE BIT(2)
+
+#define CDN_DP_LINE_THRESH (CDN_DPTX_STREAM + 0x64)
+#define CDN_DP_VB_ID (CDN_DPTX_STREAM + 0x68)
+#define CDN_DP_VB_ID_INTERLACED BIT(2)
+
+#define CDN_DP_FRONT_BACK_PORCH (CDN_DPTX_STREAM + 0x78)
+#define CDN_DP_BACK_PORCH(x) (x)
+#define CDN_DP_FRONT_PORCH(x) ((x) << 16)
+
+#define CDN_DP_BYTE_COUNT (CDN_DPTX_STREAM + 0x7c)
+
+#define CDN_DPTX_GLOBAL 0x02300
+#define CDN_DP_LANE_EN (CDN_DPTX_GLOBAL + 0x00)
+#define CDN_DP_LANE_EN_LANES(x) GENMASK(x - 1, 0)
+#define CDN_DP_ENHNCD (CDN_DPTX_GLOBAL + 0x04)
+
+#define CDN_SOURCE_VIDEO_INTERFACE 0x00b00
+#define CDN_BND_HSYNC2VSYNC (CDN_SOURCE_VIDEO_INTERFACE + 0x00)
+#define CDN_IP_DTCT_WIN GENMASK(11, 0)
+#define CDN_IP_DET_INTERLACE_FORMAT BIT(12)
+#define CDN_IP_BYPASS_V_INTERFACE BIT(13)
+
+#define CDN_HSYNC2VSYNC_POL_CTRL (CDN_SOURCE_VIDEO_INTERFACE + 0x10)
+#define CDN_H2V_HSYNC_POL_ACTIVE_LOW BIT(1)
+#define CDN_H2V_VSYNC_POL_ACTIVE_LOW BIT(2)
+
+#define CDN_DPTX_PHY_CONFIG 0x02000
+#define CDN_PHY_TRAINING_EN BIT(0)
+#define CDN_PHY_TRAINING_TYPE(x) (((x) & GENMASK(3, 0)) << 1)
+#define CDN_PHY_SCRAMBLER_BYPASS BIT(5)
+#define CDN_PHY_ENCODER_BYPASS BIT(6)
+#define CDN_PHY_SKEW_BYPASS BIT(7)
+#define CDN_PHY_TRAINING_AUTO BIT(8)
+#define CDN_PHY_LANE0_SKEW(x) (((x) & GENMASK(2, 0)) << 9)
+#define CDN_PHY_LANE1_SKEW(x) (((x) & GENMASK(2, 0)) << 12)
+#define CDN_PHY_LANE2_SKEW(x) (((x) & GENMASK(2, 0)) << 15)
+#define CDN_PHY_LANE3_SKEW(x) (((x) & GENMASK(2, 0)) << 18)
+#define CDN_PHY_COMMON_CONFIG (CDN_PHY_LANE1_SKEW(1) | CDN_PHY_LANE2_SKEW(2) | CDN_PHY_LANE3_SKEW(3))
+#define CDN_PHY_10BIT_EN BIT(21)
+
+#define CDN_PRE_EMPHASIS(x) ((x) & GENMASK(1, 0))
+#define CDN_FORCE_PRE_EMPHASIS BIT(2)
+
+#define CDN_VOLT_SWING(x) ((x) & GENMASK(1, 0))
+#define CDN_FORCE_VOLT_SWING BIT(2)
+
+#define CDN_DP_TRAINING_PATTERN_4 0x7
+
enum voltage_swing_level {
VOLTAGE_LEVEL_0,
VOLTAGE_LEVEL_1,
@@ -479,4 +607,11 @@ int cdn_dp_get_edid_block(void *dp, u8 *edid,
int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio);
int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable);
int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio);
+int cdn_dp_register_read(struct cdn_dp_device *dp, u32 addr, u32 *value);
+int cdn_dp_register_write(struct cdn_dp_device *dp, u32 addr, u32 value);
+int cdn_dp_register_write_field(struct cdn_dp_device *dp, u32 addr,
+ u8 index, u8 nbits, u32 value);
+int cdn_dp_adjust_lt(struct cdn_dp_device *dp, u8 nlanes,
+ u16 udelay, u8 *lanes_data,
+ u8 *dpcd);
#endif /* _CDN_DP_REG_H */
--
1.7.1
next prev parent reply other threads:[~2018-07-03 10:02 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-03 10:02 [PATCH 00/12] drm: add support for Cadence MHDP DPI/DP bridge Damian Kos
2018-07-03 10:02 ` [PATCH 01/12] HACK: increase timeout for drm_atomic_helper_wait_for_vblanks Damian Kos
2018-07-03 10:02 ` [PATCH 02/12] drm/dp: make dp_link_status and dp_get_lane_status usable from outside of the core Damian Kos
2018-07-03 10:02 ` [PATCH 03/12] drm/dp: add helpers for drm_dp_set_adjust_request_pre_emphasis and drm_dp_set_adjust_request_voltage Damian Kos
2018-07-04 8:16 ` Daniel Vetter
2018-07-03 10:02 ` [PATCH 04/12] drm/dp: fix training interval formula for DP 1.3+ Damian Kos
2018-07-03 10:02 ` [PATCH 05/12] drm/dp: fix link probing for devices supporting DP 1.4+ Damian Kos
2018-07-03 10:02 ` [PATCH 06/12] drm/dp: fix drm_dp_link_power_* for DP 1.2+ Damian Kos
2018-07-03 10:02 ` [PATCH 07/12] drm/dp: fix drm_dp_link_train_clock_recovery_delay for DP 1.4 Damian Kos
2018-07-03 10:02 ` [PATCH 08/12] drm/dp: add max number of lanes supported Damian Kos
2018-07-03 10:02 ` [PATCH 09/12] drm/dp: add pixel encoding and colorimetry format indicator field in MISC1 Damian Kos
2018-07-03 10:02 ` [PATCH 10/12] dt-bindings: drm/bridge: Document Cadence MHDP bridge bindings Damian Kos
2018-07-16 21:14 ` Rob Herring
2018-07-03 10:02 ` Damian Kos [this message]
2018-07-03 10:02 ` [PATCH 12/12] drm/rockchip: add support for CDNS MHDP IP controller Damian Kos
2018-07-03 11:03 ` Heiko Stübner
2018-07-03 14:06 ` Damian Kos
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1530612152-27555-12-git-send-email-dkos@cadence.com \
--to=dkos@cadence.com \
--cc=airlied@linux.ie \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=gustavo@padovan.org \
--cc=heiko@sntech.de \
--cc=hjc@rock-chips.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=ltyrala@cadence.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mark.rutland@arm.com \
--cc=pgaj@cadence.com \
--cc=robh+dt@kernel.org \
--cc=seanpaul@chromium.org \
--cc=stelford@cadence.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).