lkml.org 
[lkml]   [2018]   [Jul]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 11/12] drm/rockchip: added implementation for a few FW commands.
    Date
    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
    \
     
     \ /
      Last update: 2018-07-03 12:05    [W:3.454 / U:0.168 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site