linux/drivers/media/platform/xilinx/xilinx-dprxss.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Xilinx DP Rx Subsystem
   4 *
   5 * Copyright (C) 2020 Xilinx, Inc.
   6 *
   7 * Author: Rajesh Gugulothu <gugulothu.rajesh@xilinx.com>
   8 *
   9 */
  10#include <linux/bitfield.h>
  11#include <linux/clk.h>
  12#include <linux/device.h>
  13#include <linux/interrupt.h>
  14#include <linux/module.h>
  15#include <linux/of_irq.h>
  16#include <linux/of_address.h>
  17#include <linux/phy/phy.h>
  18#include <linux/phy/phy-dp.h>
  19#include <linux/platform_device.h>
  20#include <linux/types.h>
  21#include <linux/v4l2-dv-timings.h>
  22#include <linux/v4l2-subdev.h>
  23
  24#include <drm/drm_dp_helper.h>
  25#include <dt-bindings/media/xilinx-vip.h>
  26
  27#include <media/v4l2-dv-timings.h>
  28#include <media/v4l2-event.h>
  29#include <media/v4l2-subdev.h>
  30
  31#include "xilinx-vip.h"
  32
  33/* DP Rx subsysetm register map, bitmask, and offsets. */
  34#define XDPRX_LINK_ENABLE_REG           0x000
  35#define XDPRX_AUX_CLKDIV_REG            0x004
  36#define XDPRX_AUX_DEFER_COUNT           6
  37#define XDPRX_AUX_DEFER_SHIFT           24
  38#define XDPRX_AUX_DEFER_MASK            GENMASK(27, 24)
  39
  40#define XDPRX_LINERST_DIS_REG           0x008
  41#define XDPRX_DTG_REG                   0x00c
  42#define XDPRX_DTG_DIS_MASK              GENMASK(31, 1)
  43
  44#define XDPRX_PIXEL_WIDTH_REG           0x010
  45#define XDPRX_INTR_MASK_REG             0x014
  46#define XDPRX_INTR_POWER_MASK           BIT(1)
  47#define XDPRX_INTR_NOVID_MASK           BIT(2)
  48#define XDPRX_INTR_VBLANK_MASK          BIT(3)
  49#define XDPRX_INTR_TRLOST_MASK          BIT(4)
  50#define XDPRX_INTR_VID_MASK             BIT(6)
  51#define XDPRX_INTR_TRDONE_MASK          BIT(14)
  52#define XDPRX_INTR_BWCHANGE_MASK        BIT(15)
  53#define XDPRX_INTR_TP1_MASK             BIT(16)
  54#define XDPRX_INTR_T2_MASK              BIT(17)
  55#define XDPRX_INTR_TP3_MASK             BIT(18)
  56#define XDPRX_INTR_LINKQUAL_MASK        BIT(29)
  57#define XDPRX_INTR_UNPLUG_MASK          BIT(31)
  58#define XDPRX_INTR_CRCTST_MASK          BIT(30)
  59#define XDPRX_INTR_TRNG_MASK            (XDPRX_INTR_TP1_MASK | \
  60                                         XDPRX_INTR_T2_MASK |\
  61                                         XDPRX_INTR_TP3_MASK | \
  62                                         XDPRX_INTR_POWER_MASK |\
  63                                         XDPRX_INTR_CRCTST_MASK |\
  64                                         XDPRX_INTR_BWCHANGE_MASK)
  65#define XDPRX_INTR_ALL_MASK             0xffffffff
  66
  67#define XDPRX_SOFT_RST_REG              0x01c
  68#define XDPRX_SOFT_VIDRST_MASK          BIT(0)
  69#define XDPRX_SOFT_AUXRST_MASK          BIT(7)
  70
  71#define XDPRX_HPD_INTR_REG              0x02c
  72#define XDPRX_HPD_INTR_MASK             BIT(1)
  73#define XDPRX_HPD_PULSE_MASK            GENMASK(31, 16)
  74
  75#define XDPRX_INTR_CAUSE_REG            0x040
  76#define XDPRX_INTR_CAUSE1_REG           0x048
  77#define XDPRX_CRC_CONFIG_REG            0x074
  78#define XDPRX_CRC_EN_MASK               BIT(5)
  79
  80#define XDPRX_LOCAL_EDID_REG            0x084
  81#define XDPRX_VIDEO_UNSUPPORTED_REG     0x094
  82#define XDPRX_VRD_BWSET_REG             0x09c
  83#define XDPRX_LANE_CNT_REG              0x0a0
  84#define XDPRX_EFRAME_CAP_MASK           BIT(7)
  85#define XDPRX_LNCNT_TPS3_MASK           BIT(6)
  86
  87#define XDPRX_TP_SET_REG                0x0a4
  88#define XDPRX_AUX_RDINT_SHIFT           8
  89#define XDPRX_AUX_RDINT_16MS            4
  90#define XDPRX_AUX_READINTRVL_REG        BIT(15)
  91
  92#define XDPRX_CTRL_DPCD_REG             0x0b8
  93#define XDPRX_MST_CAP_REG               0x0d0
  94#define XDPRX_SINK_COUNT_REG            0x0d4
  95
  96#define XDPRX_PHY_REG                   0x200
  97#define XDPRX_PHY_GTPLLRST_MASK         BIT(0)
  98#define XDPRX_PHY_GTRXRST_MASK          BIT(1)
  99#define XDPRX_PHYRST_TRITER_MASK        BIT(23)
 100#define XDPRX_PHYRST_RATECHANGE_MASK    BIT(24)
 101#define XDPRX_PHYRST_TP1START_MASK      BIT(25)
 102#define XDPRX_PHYRST_ENBL_MASK          0x0
 103#define XDPRX_PHY_INIT_MASK             GENMASK(29, 27)
 104
 105#define XDPRX_MINVOLT_SWING_REG         0x214
 106#define XDPRX_VS_PE_SHIFT               12
 107#define XDPRX_VS_SWEEP_CNTSHIFT         4
 108#define XDPRX_VS_CROPT_SHIFT            2
 109#define XDPRX_VS_CROPT_INC4CNT          1
 110#define XDPRX_MIN_VS_MASK               (1 | (XDPRX_VS_CROPT_INC4CNT << \
 111                                         XDPRX_VS_CROPT_SHIFT) | \
 112                                         (4 << XDPRX_VS_SWEEP_CNTSHIFT) | \
 113                                         (1 << XDPRX_VS_PE_SHIFT))
 114
 115#define XDPRX_CDRCTRL_CFG_REG           0x21c
 116/* CDR tDLOCK calibration value */
 117#define XDPRX_CDRCTRL_TDLOCK_VAL        0x1388
 118#define XDPRX_CDRCTRL_DIS_TIMEOUT       BIT(30)
 119
 120#define XDPRX_BSIDLE_TIME_REG           0x220
 121#define XDPRX_BSIDLE_TMOUT_VAL          0x047868C0
 122
 123#define XDPRX_LINK_BW_REG               0x400
 124#define XDPRX_LANE_COUNT_REG            0x404
 125#define XDPRX_MSA_HRES_REG              0x500
 126#define XDPRX_MSA_VHEIGHT_REG           0x514
 127#define XDPRX_MSA_HTOTAL_REG            0x510
 128#define XDPRX_MSA_VTOTAL_REG            0x524
 129#define XDPRX_MSA_MISC0_REG             0x528
 130#define XDPRX_MSA_FMT_MASK              GENMASK(2, 1)
 131#define XDPRX_MSA_BPC_MASK              GENMASK(7, 5)
 132#define XDPRX_COLOR_DEPTH_SHIFT         5
 133#define XDPRX_COLOR_FMT_SHIFT           1
 134
 135#define XDPRX_MSA_MISC1_REG             0x52c
 136#define XDPRX_INTERLACE_MASK            BIT(0)
 137
 138#define XDPRX_MSA_MVID_REG              0x530
 139#define XDPRX_MSA_NVID_REG              0x534
 140#define XDPRX_INTR_ERRORCNT_MASK        BIT(28)
 141#define XDPRX_INTR_LANESET_MASK         BIT(30)
 142
 143#define XDPRX_COLOR_FORMAT_RGB          0x0
 144#define XDPRX_COLOR_FORMAT_422          0x1
 145#define XDPRX_COLOR_FORMAT_444          0x2
 146#define MHZ                             1000000
 147#define XDPRX_MAX_LANE_COUNT            4
 148
 149#define XDPRX_EDID_NUM_BLOCKS           3
 150#define XDPRX_EDID_BLOCK_SIZE           128
 151#define XDPRX_EDID_LENGTH               (XDPRX_EDID_BLOCK_SIZE * \
 152                                         XDPRX_EDID_NUM_BLOCKS * 4)
 153/*
 154 * IRQ_HPD pulse for upstream device is 5ms as per
 155 * the VESA standard
 156 */
 157#define XDPRX_HPD_PLUSE_5000            5000
 158/*
 159 * low going IRQ_HPD generated for upstream device
 160 * as per the VESA standard
 161 */
 162#define XDPRX_HPD_PLUSE_750             750
 163
 164/**
 165 * struct xdprxss_state - DP Rx Subsystem device structure
 166 * @dev: Platform structure
 167 * @subdev: The v4l2 subdev structure
 168 * @event: Holds the video unlock event
 169 * @detected_timings: Detected Video timings
 170 * @phy: pointer to phy instance
 171 * @pad: media pad
 172 * @axi_clk: Axi lite interface clock
 173 * @rx_lnk_clk: DP Rx GT clock
 174 * @rx_vid_clk: DP RX Video clock
 175 * @dp_base: Base address of DP Rx Subsystem
 176 * @edid_base: Bare Address of EDID block
 177 * @lock: Lock is used for width, height, framerate variables
 178 * @format: Active V4L2 format on each pad
 179 * @frame_interval: Captures the frame rate
 180 * @max_linkrate: Maximum supported link rate
 181 * @max_lanecount: Maximux supported lane count
 182 * @bpc: Bits per component
 183 * @hdcp_enable: To indicate hdcp enabled or not
 184 * @audio_enable: To indicate audio enabled or not
 185 * @valid_stream: To indicate valid video
 186 * @streaming: Flag for storing streaming state
 187 * This structure contains the device driver related parameters
 188 */
 189struct xdprxss_state {
 190        struct device *dev;
 191        struct v4l2_subdev subdev;
 192        struct v4l2_event event;
 193        struct v4l2_dv_timings detected_timings;
 194        struct phy *phy[XDPRX_MAX_LANE_COUNT];
 195        struct media_pad pad;
 196        struct clk *axi_clk;
 197        struct clk *rx_lnk_clk;
 198        struct clk *rx_vid_clk;
 199        void __iomem *dp_base;
 200        void __iomem *edid_base;
 201        /* protects width, height, framerate variables */
 202        spinlock_t lock;
 203        struct v4l2_mbus_framefmt format;
 204        unsigned int frame_interval;
 205        u32 max_linkrate;
 206        u32 max_lanecount;
 207        u32 bpc;
 208        bool hdcp_enable;
 209        bool audio_enable;
 210        unsigned int valid_stream : 1;
 211        unsigned int streaming : 1;
 212};
 213
 214/*
 215 * This is a default EDID data loaded to EDID memory. It allows the source
 216 * to get edid before application start on DP Rx.User can load their
 217 * custom EDID data using set_edid functions call
 218 */
 219static u8 xilinx_edid[384] = {
 220        0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x47, 0x41,
 221        0x4c, 0x35, 0x37, 0x30, 0x20, 0x1b, 0x01, 0x04, 0xb5, 0x46, 0x27, 0x78,
 222        0x3a, 0x76, 0x45, 0xae, 0x51, 0x33, 0xba, 0x26, 0x0d, 0x50, 0x54, 0xa5,
 223        0x4b, 0x00, 0x81, 0x00, 0xb3, 0x00, 0xd1, 0x00, 0xa9, 0x40, 0x81, 0x80,
 224        0xd1, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x4d, 0xd0, 0x00, 0xa0, 0xf0, 0x70,
 225        0x3e, 0x80, 0x30, 0x20, 0x35, 0x00, 0xba, 0x89, 0x21, 0x00, 0x00, 0x1a,
 226        0x00, 0x00, 0x00, 0xff, 0x00, 0x46, 0x46, 0x4e, 0x58, 0x4d, 0x37, 0x38,
 227        0x37, 0x30, 0x37, 0x35, 0x4c, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
 228        0x45, 0x4c, 0x4c, 0x20, 0x55, 0x50, 0x33, 0x32, 0x31, 0x38, 0x4b, 0x0a,
 229        0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x4b, 0x1e, 0xb4, 0x6c, 0x01, 0x0a,
 230        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x02, 0x70, 0x02, 0x03, 0x1d, 0xf1,
 231        0x50, 0x10, 0x1f, 0x20, 0x05, 0x14, 0x04, 0x13, 0x12, 0x11, 0x03, 0x02,
 232        0x16, 0x15, 0x07, 0x06, 0x01, 0x23, 0x09, 0x1f, 0x07, 0x83, 0x01, 0x00,
 233        0x00, 0xa3, 0x66, 0x00, 0xa0, 0xf0, 0x70, 0x1f, 0x80, 0x30, 0x20, 0x35,
 234        0x00, 0xba, 0x89, 0x21, 0x00, 0x00, 0x1a, 0x56, 0x5e, 0x00, 0xa0, 0xa0,
 235        0xa0, 0x29, 0x50, 0x30, 0x20, 0x35, 0x00, 0xba, 0x89, 0x21, 0x00, 0x00,
 236        0x1a, 0x7c, 0x39, 0x00, 0xA0, 0x80, 0x38, 0x1f, 0x40, 0x30, 0x20, 0x3a,
 237        0x00, 0xba, 0x89, 0x21, 0x00, 0x00, 0x1a, 0xa8, 0x16, 0x00, 0xa0, 0x80,
 238        0x38, 0x13, 0x40, 0x30, 0x20, 0x3a, 0x00, 0xba, 0x89, 0x21, 0x00, 0x00,
 239        0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 240        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 241        0x00, 0x00, 0x00, 0x47, 0x70, 0x12, 0x79, 0x00, 0x00, 0x12, 0x00, 0x16,
 242        0x82, 0x10, 0x10, 0x00, 0xff, 0x0e, 0xdf, 0x10, 0x00, 0x00, 0x00, 0x00,
 243        0x00, 0x44, 0x45, 0x4c, 0x47, 0x41, 0x4c, 0x35, 0x37, 0x30, 0x03, 0x01,
 244        0x50, 0x70, 0x92, 0x01, 0x84, 0xff, 0x1d, 0xc7, 0x00, 0x1d, 0x80, 0x09,
 245        0x00, 0xdf, 0x10, 0x2f, 0x00, 0x02, 0x00, 0x04, 0x00, 0xc1, 0x42, 0x01,
 246        0x84, 0xff, 0x1d, 0xc7, 0x00, 0x2f, 0x80, 0x1f, 0x00, 0xdf, 0x10, 0x30,
 247        0x00, 0x02, 0x00, 0x04, 0x00, 0xa8, 0x4e, 0x01, 0x04, 0xff, 0x0e, 0xc7,
 248        0x00, 0x2f, 0x80, 0x1f, 0x00, 0xdf, 0x10, 0x61, 0x00, 0x02, 0x00, 0x09,
 249        0x00, 0x97, 0x9d, 0x01, 0x04, 0xff, 0x0e, 0xc7, 0x00, 0x2f, 0x80, 0x1f,
 250        0x00, 0xdf, 0x10, 0x2f, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
 251        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x90,
 252};
 253
 254static const u32 xdprxss_supported_mbus_fmts[] = {
 255        MEDIA_BUS_FMT_UYVY8_1X16,
 256        MEDIA_BUS_FMT_VUY8_1X24,
 257        MEDIA_BUS_FMT_RBG888_1X24,
 258        MEDIA_BUS_FMT_UYVY10_1X20,
 259        MEDIA_BUS_FMT_VUY10_1X30,
 260        MEDIA_BUS_FMT_RBG101010_1X30,
 261};
 262
 263#define XLNX_V4L2_DV_BT_2048X1080P60 { \
 264        .type = V4L2_DV_BT_656_1120, \
 265        V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \
 266                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 267                148500000, 88, 44, 20, 4, 5, 36, 0, 0, 0, \
 268                V4L2_DV_BT_STD_CEA861) \
 269}
 270
 271#define XLNX_V4L2_DV_BT_2048X1080I50 { \
 272        .type = V4L2_DV_BT_656_1120, \
 273        V4L2_INIT_BT_TIMINGS(2048, 1080, 1, \
 274                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 275                74250000, 274, 44, 274, 2, 5, 15, 3, 5, 15, \
 276                V4L2_DV_BT_STD_CEA861) \
 277}
 278
 279#define XLNX_V4L2_DV_BT_2048X1080I60 { \
 280        .type = V4L2_DV_BT_656_1120, \
 281        V4L2_INIT_BT_TIMINGS(2048, 1080, 1, \
 282                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 283                74250000, 66, 20, 66, 2, 5, 15, 3, 5, 15, \
 284                V4L2_DV_BT_STD_CEA861) \
 285}
 286
 287#define XLNX_V4L2_DV_BT_2048X1080P50 { \
 288        .type = V4L2_DV_BT_656_1120, \
 289        V4L2_INIT_BT_TIMINGS(2048, 1080, 0, \
 290                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 291                148500000, 400, 44, 148, 4, 5, 36, 0, 0, 0, \
 292                V4L2_DV_BT_STD_CEA861) \
 293}
 294
 295#define XLNX_V4L2_DV_BT_7680X4320P30 { \
 296        .type = V4L2_DV_BT_656_1120, \
 297        V4L2_INIT_BT_TIMINGS(7680, 4320, 0, \
 298                V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
 299                74250000, 552, 176, 592, 16, 20, 44, 0, 0, 0, \
 300                V4L2_DV_BT_STD_CEA861) \
 301}
 302
 303static const struct v4l2_dv_timings fmt_cap[] = {
 304        V4L2_DV_BT_CEA_1280X720P25,
 305        V4L2_DV_BT_CEA_1280X720P30,
 306        V4L2_DV_BT_CEA_1280X720P50,
 307        V4L2_DV_BT_CEA_1280X720P60,
 308        V4L2_DV_BT_CEA_1920X1080P25,
 309        V4L2_DV_BT_CEA_1920X1080P30,
 310        V4L2_DV_BT_CEA_1920X1080P50,
 311        V4L2_DV_BT_CEA_1920X1080P60,
 312        V4L2_DV_BT_CEA_1920X1080I50,
 313        V4L2_DV_BT_CEA_1920X1080I60,
 314        V4L2_DV_BT_CEA_3840X2160P30,
 315        V4L2_DV_BT_CEA_3840X2160P50,
 316        V4L2_DV_BT_CEA_3840X2160P60,
 317        V4L2_DV_BT_CEA_4096X2160P25,
 318        V4L2_DV_BT_CEA_4096X2160P30,
 319        V4L2_DV_BT_CEA_4096X2160P50,
 320        V4L2_DV_BT_CEA_4096X2160P60,
 321
 322        XLNX_V4L2_DV_BT_2048X1080I50,
 323        XLNX_V4L2_DV_BT_2048X1080I60,
 324        XLNX_V4L2_DV_BT_2048X1080P50,
 325        XLNX_V4L2_DV_BT_2048X1080P60,
 326        XLNX_V4L2_DV_BT_7680X4320P30,
 327};
 328
 329struct xdprxss_dv_map {
 330        u32 width;
 331        u32 height;
 332        u32 fps;
 333        struct v4l2_dv_timings timing;
 334};
 335
 336static const struct xdprxss_dv_map xdprxss_dv_timings[] = {
 337        /* HD - 1280x720p25 */
 338        { 1280, 720, 25, V4L2_DV_BT_CEA_1280X720P25 },
 339        /* HD - 1280x720p30 */
 340        { 1280, 720, 30, V4L2_DV_BT_CEA_1280X720P30 },
 341        /* HD - 1280x720p50 */
 342        { 1280, 720, 50, V4L2_DV_BT_CEA_1280X720P50 },
 343        /* HD - 1280x720p60 */
 344        { 1280, 720, 60, V4L2_DV_BT_CEA_1280X720P60 },
 345        /* HD - 1920x1080p25 */
 346        { 1920, 1080, 25, V4L2_DV_BT_CEA_1920X1080P25 },
 347        /* HD - 1920x1080p30 */
 348        { 1920, 1080, 30, V4L2_DV_BT_CEA_1920X1080P30 },
 349        /* HD - 1920x1080p50 */
 350        { 1920, 1080, 50, V4L2_DV_BT_CEA_1920X1080P50 },
 351        /* HD - 1920x1080p60 */
 352        { 1920, 1080, 60, V4L2_DV_BT_CEA_1920X1080P60 },
 353        /* HD - 1920x1080i50 */
 354        { 1920, 540, 25, V4L2_DV_BT_CEA_1920X1080I50 },
 355        /* HD - 1920x1080i59.94 */
 356        /* HD - 1920x1080i60 */
 357        { 1920, 540, 30, V4L2_DV_BT_CEA_1920X1080I60 },
 358        { 3840, 2160, 30, V4L2_DV_BT_CEA_3840X2160P30 },
 359        { 3840, 2160, 50, V4L2_DV_BT_CEA_3840X2160P50 },
 360        { 3840, 2160, 60, V4L2_DV_BT_CEA_3840X2160P60 },
 361        { 4096, 2160, 25, V4L2_DV_BT_CEA_4096X2160P25 },
 362        { 4096, 2160, 30, V4L2_DV_BT_CEA_4096X2160P30 },
 363        { 4096, 2160, 50, V4L2_DV_BT_CEA_4096X2160P50 },
 364        { 4096, 2160, 60, V4L2_DV_BT_CEA_4096X2160P60 },
 365        /* HD - 2048x1080i50 */
 366        { 2048, 540, 25, XLNX_V4L2_DV_BT_2048X1080I50 },
 367        /* HD - 2048x1080i59.94 */
 368        /* HD - 2048x1080i60 */
 369        { 2048, 540, 30, XLNX_V4L2_DV_BT_2048X1080I60 },
 370        /* 3G - 2048x1080p50 */
 371        { 2048, 1080, 50, XLNX_V4L2_DV_BT_2048X1080P50 },
 372        /* 3G - 2048x1080p59.94 */
 373        /* 3G - 2048x1080p60 */
 374        { 2048, 1080, 60, XLNX_V4L2_DV_BT_2048X1080P60 },
 375        { 7680, 4320, 30, XLNX_V4L2_DV_BT_7680X4320P30 }
 376};
 377
 378static inline struct xdprxss_state *
 379to_xdprxssstate(struct v4l2_subdev *subdev)
 380{
 381        return container_of(subdev, struct xdprxss_state, subdev);
 382}
 383
 384/* Register related operations */
 385static inline u32 xdprxss_read(struct xdprxss_state *xdprxss, u32 addr)
 386{
 387        return ioread32(xdprxss->dp_base + addr);
 388}
 389
 390static inline void xdprxss_write(struct xdprxss_state *xdprxss, u32 addr,
 391                                 u32 value)
 392{
 393        iowrite32(value, xdprxss->dp_base + addr);
 394}
 395
 396static inline void xdprxss_clr(struct xdprxss_state *xdprxss, u32 addr,
 397                               u32 clr)
 398{
 399        xdprxss_write(xdprxss, addr, xdprxss_read(xdprxss, addr) & ~clr);
 400}
 401
 402static inline void xdprxss_set(struct xdprxss_state *xdprxss, u32 addr,
 403                               u32 set)
 404{
 405        xdprxss_write(xdprxss, addr, xdprxss_read(xdprxss, addr) | set);
 406}
 407
 408static inline void xdprxss_dpcd_update_start(struct xdprxss_state *xdprxss)
 409{
 410        iowrite32(0x1, xdprxss->dp_base + XDPRX_CTRL_DPCD_REG);
 411}
 412
 413static inline void xdprxss_dpcd_update_end(struct xdprxss_state *xdprxss)
 414{
 415        iowrite32(0x0, xdprxss->dp_base + XDPRX_CTRL_DPCD_REG);
 416}
 417
 418/**
 419 * xdprxss_dpcd_update - Update the DPCD registers
 420 * @xdprxss: pointer to driver state
 421 * @addr: DPCD register address
 422 * @val: Value to be override
 423 * This function is used to override the DPCD registers set.
 424 * DPCD register set is ranges from 0x084-0x0f0.
 425 * Register 0x0B8(direct_dpcd_access) must be set to 1 to
 426 * override DPCD values
 427 */
 428static inline void xdprxss_dpcd_update(struct xdprxss_state *xdprxss,
 429                                       u32 addr, u32 val)
 430{
 431        xdprxss_write(xdprxss, addr, val);
 432}
 433
 434/**
 435 * xdprxss_get_stream_properties - Get DP Rx stream properties
 436 * @state: pointer to driver state
 437 * This function decodes the stream to get stream properties
 438 * like width, height, format, picture type (interlaced/progressive),etc.
 439 *
 440 * Return: 0 for success else errors
 441 */
 442static int xdprxss_get_stream_properties(struct xdprxss_state *state)
 443{
 444        struct v4l2_mbus_framefmt *format = &state->format;
 445        struct v4l2_bt_timings *bt = &state->detected_timings.bt;
 446
 447        u32 rxmsa_mvid, rxmsa_nvid, rxmsa_misc, recv_clk_freq, linkrate;
 448        u16 vres_total, hres_total, framerate, lanecount;
 449        u8 pixel_width, fmt;
 450        u16 read_val;
 451
 452        rxmsa_mvid = xdprxss_read(state, XDPRX_MSA_MVID_REG);
 453        rxmsa_nvid = xdprxss_read(state, XDPRX_MSA_NVID_REG);
 454
 455        bt->width = xdprxss_read(state, XDPRX_MSA_HRES_REG);
 456
 457        bt->height = xdprxss_read(state, XDPRX_MSA_VHEIGHT_REG);
 458        rxmsa_misc = xdprxss_read(state, XDPRX_MSA_MISC0_REG);
 459
 460        vres_total = xdprxss_read(state, XDPRX_MSA_VTOTAL_REG);
 461        hres_total = xdprxss_read(state, XDPRX_MSA_HTOTAL_REG);
 462        linkrate = xdprxss_read(state, XDPRX_LINK_BW_REG);
 463        lanecount = xdprxss_read(state, XDPRX_LANE_COUNT_REG);
 464
 465        recv_clk_freq = (linkrate * 27 * rxmsa_mvid) / rxmsa_nvid;
 466
 467        if (recv_clk_freq > 540 && lanecount == 4)
 468                pixel_width = 0x4;
 469        else if (recv_clk_freq > 270 && (lanecount != 1))
 470                pixel_width = 0x2;
 471        else
 472                pixel_width = 0x1;
 473
 474        framerate = (recv_clk_freq * MHZ) / (hres_total * vres_total);
 475        framerate = roundup(framerate, 5);
 476        xdprxss_write(state, XDPRX_LINERST_DIS_REG, 0x1);
 477        /* set pixel mode as per lane count and reset the DTG */
 478        read_val = xdprxss_read(state, XDPRX_DTG_REG);
 479        xdprxss_write(state, XDPRX_DTG_REG, (read_val & XDPRX_DTG_DIS_MASK));
 480        xdprxss_write(state, XDPRX_PIXEL_WIDTH_REG, pixel_width);
 481        read_val = xdprxss_read(state, XDPRX_DTG_REG);
 482        xdprxss_write(state, XDPRX_DTG_REG, (read_val | 0x1));
 483        fmt = FIELD_GET(XDPRX_MSA_FMT_MASK, rxmsa_misc);
 484        state->bpc = FIELD_GET(XDPRX_MSA_BPC_MASK, rxmsa_misc);
 485
 486        switch (fmt) {
 487        case XDPRX_COLOR_FORMAT_422:
 488                if (state->bpc == 10)
 489                        format->code = MEDIA_BUS_FMT_UYVY10_1X20;
 490                else
 491                        format->code = MEDIA_BUS_FMT_UYVY8_1X16;
 492                break;
 493        case XDPRX_COLOR_FORMAT_444:
 494                if (state->bpc == 10)
 495                        format->code = MEDIA_BUS_FMT_VUY10_1X30;
 496                else
 497                        format->code = MEDIA_BUS_FMT_VUY8_1X24;
 498                break;
 499        case XDPRX_COLOR_FORMAT_RGB:
 500                if (state->bpc == 10)
 501                        format->code = MEDIA_BUS_FMT_RBG101010_1X30;
 502                else
 503                        format->code = MEDIA_BUS_FMT_RBG888_1X24;
 504                break;
 505        default:
 506                dev_err(state->dev, "Unsupported color format\n");
 507
 508                return -EINVAL;
 509        }
 510
 511        spin_lock(&state->lock);
 512        format->width = bt->width;
 513        format->height = bt->height;
 514        format->colorspace = V4L2_COLORSPACE_REC709;
 515        format->xfer_func = V4L2_XFER_FUNC_DEFAULT;
 516        format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
 517        format->quantization = V4L2_QUANTIZATION_DEFAULT;
 518        format->field = V4L2_FIELD_NONE;
 519        state->frame_interval = framerate;
 520        spin_unlock(&state->lock);
 521
 522        dev_dbg(state->dev, "detected properties : width %d height %d\n",
 523                bt->width, bt->height);
 524
 525        return 0;
 526}
 527
 528static void xdprxss_set_training_params(struct xdprxss_state *xdprxss)
 529{
 530        unsigned int offset;
 531
 532        /*
 533         * This register is used to set a minimum value which which must be met
 534         * As per the Display Port protocol.The internal logic forces training
 535         * to fail until this value is met.Please refer to PG 300
 536         * https://www.xilinx.com/support/documentation/ip_documentation/dp_rx_subsystem/v2_1/pg233-displayport-rx-subsystem.pdf
 537         */
 538        xdprxss_write(xdprxss, XDPRX_MINVOLT_SWING_REG, XDPRX_MIN_VS_MASK);
 539        xdprxss_write(xdprxss, XDPRX_AUX_CLKDIV_REG,
 540                      xdprxss_read(xdprxss, XDPRX_AUX_CLKDIV_REG) |
 541                      FIELD_PREP(XDPRX_AUX_DEFER_MASK, XDPRX_AUX_DEFER_COUNT));
 542
 543        xdprxss_dpcd_update_start(xdprxss);
 544        xdprxss_dpcd_update(xdprxss, XDPRX_TP_SET_REG,
 545                            (XDPRX_AUX_RDINT_16MS << XDPRX_AUX_RDINT_SHIFT) |
 546                            XDPRX_AUX_READINTRVL_REG);
 547        xdprxss_dpcd_update_end(xdprxss);
 548
 549        xdprxss_clr(xdprxss, XDPRX_INTR_MASK_REG, XDPRX_INTR_ALL_MASK);
 550
 551        /* Load edid data to EDID memory block */
 552        for (offset = 0; offset < XDPRX_EDID_LENGTH; offset = offset + 4) {
 553                iowrite32((uint32_t)xilinx_edid[offset / 4],
 554                          xdprxss->edid_base + offset);
 555        }
 556        xdprxss_write(xdprxss, XDPRX_LOCAL_EDID_REG, 0x1);
 557
 558        /* Disable all the interrupts */
 559        xdprxss_set(xdprxss, XDPRX_INTR_MASK_REG, XDPRX_INTR_ALL_MASK);
 560
 561        /* Enable trainng related interrupts */
 562        xdprxss_clr(xdprxss, XDPRX_INTR_MASK_REG, XDPRX_INTR_TRNG_MASK);
 563        xdprxss_write(xdprxss, XDPRX_AUX_CLKDIV_REG,
 564                      xdprxss_read(xdprxss, XDPRX_AUX_CLKDIV_REG) |
 565                      FIELD_PREP(XDPRX_AUX_DEFER_MASK, XDPRX_AUX_DEFER_COUNT));
 566        xdprxss_write(xdprxss, XDPRX_BSIDLE_TIME_REG, XDPRX_BSIDLE_TMOUT_VAL);
 567        xdprxss_clr(xdprxss, XDPRX_CRC_CONFIG_REG, XDPRX_CRC_EN_MASK);
 568        xdprxss_write(xdprxss, XDPRX_LINK_ENABLE_REG, 0x1);
 569}
 570
 571static void xdprxss_core_init(struct xdprxss_state *xdprxss)
 572{
 573        unsigned long axi_clk;
 574
 575        u32 max_lanecount = xdprxss->max_lanecount;
 576
 577        xdprxss_dpcd_update_start(xdprxss);
 578        xdprxss_dpcd_update(xdprxss,
 579                            XDPRX_VRD_BWSET_REG, xdprxss->max_linkrate);
 580        max_lanecount |= (XDPRX_EFRAME_CAP_MASK | XDPRX_LNCNT_TPS3_MASK);
 581        xdprxss_dpcd_update(xdprxss, XDPRX_LANE_CNT_REG, max_lanecount);
 582        xdprxss_dpcd_update_end(xdprxss);
 583        xdprxss_write(xdprxss, XDPRX_LINK_ENABLE_REG, 0x0);
 584        axi_clk = clk_get_rate(xdprxss->axi_clk);
 585        xdprxss_write(xdprxss, XDPRX_AUX_CLKDIV_REG, axi_clk / MHZ);
 586        /* Put both GT RX/TX and CPLL into reset */
 587        xdprxss_write(xdprxss, XDPRX_PHY_REG, XDPRX_PHY_GTPLLRST_MASK |
 588                      XDPRX_PHY_GTRXRST_MASK);
 589        /* Release CPLL reset */
 590        xdprxss_write(xdprxss, XDPRX_PHY_REG, XDPRX_PHY_GTRXRST_MASK);
 591        /*
 592         * Remove the reset from the PHY and configure to issue reset after
 593         * every training iteration, link rate change, and start of training
 594         * pattern
 595         */
 596        xdprxss_write(xdprxss, XDPRX_PHY_REG,
 597                      XDPRX_PHYRST_ENBL_MASK |
 598                      XDPRX_PHYRST_TRITER_MASK |
 599                      XDPRX_PHYRST_RATECHANGE_MASK |
 600                      XDPRX_PHYRST_TP1START_MASK);
 601        xdprxss_write(xdprxss, XDPRX_MST_CAP_REG, 0x0);
 602        xdprxss_write(xdprxss, XDPRX_SINK_COUNT_REG, 1);
 603        xdprxss_set_training_params(xdprxss);
 604}
 605
 606static void xdprxss_irq_unplug(struct xdprxss_state *state)
 607{
 608        dev_dbg(state->dev, "Asserted cable unplug interrupt\n");
 609
 610        xdprxss_set(state, XDPRX_SOFT_RST_REG, XDPRX_SOFT_VIDRST_MASK);
 611        xdprxss_clr(state, XDPRX_SOFT_RST_REG, XDPRX_SOFT_VIDRST_MASK);
 612
 613        xdprxss_set(state, XDPRX_INTR_MASK_REG, XDPRX_INTR_ALL_MASK);
 614        xdprxss_clr(state, XDPRX_INTR_MASK_REG, XDPRX_INTR_TRNG_MASK);
 615        /*
 616         * In a scenario, where the cable is plugged-in but the training
 617         * is lost, the software is expected to assert a HPD upon the
 618         * occurrence of a TRAINING_LOST interrupt, so that the Source
 619         * can retrain the link.
 620         */
 621        xdprxss_write(state, XDPRX_HPD_INTR_REG,
 622                      FIELD_PREP(XDPRX_HPD_PULSE_MASK, XDPRX_HPD_PLUSE_5000) |
 623                      XDPRX_HPD_INTR_MASK);
 624}
 625
 626static void xdprxss_irq_tp1(struct xdprxss_state *state)
 627{
 628        union phy_configure_opts phy_opts = { 0 };
 629        struct phy_configure_opts_dp *phy_cfg = &phy_opts.dp;
 630        u32 linkrate;
 631        unsigned int i;
 632
 633        dev_dbg(state->dev, "Asserted traning pattern 1\n");
 634
 635        linkrate = xdprxss_read(state, XDPRX_LINK_BW_REG);
 636
 637        switch (linkrate) {
 638        case DP_LINK_BW_1_62:
 639        case DP_LINK_BW_2_7:
 640        case DP_LINK_BW_5_4:
 641        case DP_LINK_BW_8_1:
 642                phy_cfg->link_rate = linkrate * 270;
 643                break;
 644        default:
 645                dev_err(state->dev, "invalid link rate\n");
 646                break;
 647        }
 648        phy_cfg->set_rate = 1;
 649        for (i = 0; i < state->max_lanecount; i++)
 650                phy_configure(state->phy[i], &phy_opts);
 651
 652        /* Initialize phy logic of DP-RX core */
 653        xdprxss_write(state, XDPRX_PHY_REG, XDPRX_PHY_INIT_MASK);
 654        phy_reset(state->phy[0]);
 655        xdprxss_clr(state, XDPRX_INTR_MASK_REG, XDPRX_INTR_ALL_MASK);
 656}
 657
 658static void xdprxss_training_failure(struct xdprxss_state *state)
 659{
 660        dev_dbg(state->dev, "Traning Lost !!\n");
 661        state->valid_stream = false;
 662
 663        xdprxss_write(state, XDPRX_HPD_INTR_REG,
 664                      FIELD_PREP(XDPRX_HPD_PULSE_MASK, XDPRX_HPD_PLUSE_750) |
 665                      XDPRX_HPD_INTR_MASK);
 666
 667        /* reset the aux logic */
 668        xdprxss_set(state, XDPRX_SOFT_RST_REG, XDPRX_SOFT_AUXRST_MASK);
 669        xdprxss_clr(state, XDPRX_SOFT_RST_REG, XDPRX_SOFT_AUXRST_MASK);
 670}
 671
 672static void xdprxss_irq_no_video(struct xdprxss_state *state)
 673{
 674        dev_dbg(state->dev, "No Valid video received !!\n");
 675
 676        xdprxss_write(state, XDPRX_VIDEO_UNSUPPORTED_REG, 0x1);
 677        xdprxss_clr(state, XDPRX_INTR_MASK_REG, XDPRX_INTR_VBLANK_MASK);
 678        xdprxss_set(state, XDPRX_INTR_MASK_REG, XDPRX_INTR_NOVID_MASK);
 679        /* reset the dtg core */
 680        xdprxss_set(state, XDPRX_DTG_REG, 0x0);
 681        xdprxss_set(state, XDPRX_DTG_REG, 0x1);
 682
 683        /* reset the video logic */
 684        xdprxss_set(state, XDPRX_SOFT_RST_REG, XDPRX_SOFT_VIDRST_MASK);
 685        xdprxss_clr(state, XDPRX_SOFT_RST_REG, XDPRX_SOFT_VIDRST_MASK);
 686
 687        /* notify source change event */
 688        memset(&state->event, 0, sizeof(state->event));
 689        state->event.type = V4L2_EVENT_SOURCE_CHANGE;
 690        state->event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
 691        v4l2_subdev_notify_event(&state->subdev, &state->event);
 692        state->valid_stream = false;
 693}
 694
 695static void xdprxss_irq_valid_video(struct xdprxss_state *state)
 696{
 697        dev_dbg(state->dev, "Valid Video received !!\n");
 698        xdprxss_write(state, XDPRX_VIDEO_UNSUPPORTED_REG, 0x0);
 699
 700        if (!xdprxss_get_stream_properties(state)) {
 701                memset(&state->event, 0, sizeof(state->event));
 702                state->event.type = V4L2_EVENT_SOURCE_CHANGE;
 703                state->event.u.src_change.changes =
 704                                V4L2_EVENT_SRC_CH_RESOLUTION;
 705                v4l2_subdev_notify_event(&state->subdev, &state->event);
 706                state->valid_stream = true;
 707        } else {
 708                dev_err(state->dev, "Unable to get stream properties!\n");
 709                state->valid_stream = false;
 710        }
 711}
 712
 713static irqreturn_t xdprxss_irq_handler(int irq, void *dev_id)
 714{
 715        struct xdprxss_state *state = (struct xdprxss_state *)dev_id;
 716        u32 status;
 717
 718        status = xdprxss_read(state, XDPRX_INTR_CAUSE_REG);
 719        status &= ~xdprxss_read(state, XDPRX_INTR_MASK_REG);
 720
 721        if (!status)
 722                return IRQ_NONE;
 723
 724        if (status & XDPRX_INTR_UNPLUG_MASK)
 725                xdprxss_irq_unplug(state);
 726        if (status & XDPRX_INTR_TP1_MASK)
 727                xdprxss_irq_tp1(state);
 728        if (status & XDPRX_INTR_TRLOST_MASK)
 729                xdprxss_training_failure(state);
 730        if (status & XDPRX_INTR_NOVID_MASK)
 731                xdprxss_irq_no_video(state);
 732        if (status & XDPRX_INTR_VID_MASK)
 733                xdprxss_irq_valid_video(state);
 734#ifdef DEBUG
 735        if (status & XDPRX_INTR_TRDONE_MASK)
 736                dev_dbg(state->dev, "DP Link training is done !!\n");
 737#endif
 738
 739        return IRQ_HANDLED;
 740}
 741
 742/**
 743 * xdprxss_subscribe_event - Subscribe to video source change event
 744 * @sd: V4L2 Sub device
 745 * @fh: V4L2 File Handle
 746 * @sub: Subcribe event structure
 747 *
 748 * Return: 0 on success, errors otherwise
 749 */
 750static int xdprxss_subscribe_event(struct v4l2_subdev *sd,
 751                                   struct v4l2_fh *fh,
 752                                   struct v4l2_event_subscription *sub)
 753{
 754        int ret;
 755        struct xdprxss_state *xdprxss = to_xdprxssstate(sd);
 756
 757        dev_dbg(xdprxss->dev, "Event subscribed : 0x%08x\n", sub->type);
 758
 759        switch (sub->type) {
 760        case V4L2_EVENT_SOURCE_CHANGE:
 761                ret = v4l2_src_change_event_subscribe(fh, sub);
 762                break;
 763        default:
 764                ret = -EINVAL;
 765        }
 766
 767        return ret;
 768}
 769
 770static int xdprxss_s_stream(struct v4l2_subdev *sd, int enable)
 771{
 772        struct xdprxss_state *xdprxss = to_xdprxssstate(sd);
 773
 774        /* DP does not need to be enabled when we start streaming */
 775        if (enable == xdprxss->streaming)
 776                return 0;
 777
 778        if (enable && !xdprxss->valid_stream)
 779                return -EINVAL;
 780
 781        xdprxss->streaming = enable;
 782
 783        return 0;
 784}
 785
 786/**
 787 * xdprxss_g_input_status - It is used to determine if the video signal
 788 * is present / locked onto or not.
 789 *
 790 * @sd: V4L2 Sub device
 791 * @status: status of signal locked
 792 *
 793 * This is used to determine if the valid video signal is present and
 794 * locked onto by the DP Rx xdprxss or not .
 795 *
 796 * Return: zero on success
 797 */
 798static int xdprxss_g_input_status(struct v4l2_subdev *sd, u32 *status)
 799{
 800        struct xdprxss_state *xdprxss = to_xdprxssstate(sd);
 801
 802        if (!xdprxss->valid_stream)
 803                *status = V4L2_IN_ST_NO_SYNC | V4L2_IN_ST_NO_SIGNAL;
 804        else
 805                *status = 0;
 806
 807        return 0;
 808}
 809
 810static struct v4l2_mbus_framefmt *
 811__xdprxss_get_pad_format(struct xdprxss_state *xdprxss,
 812                         struct v4l2_subdev_pad_config *cfg,
 813                         unsigned int pad, u32 which)
 814{
 815        struct v4l2_mbus_framefmt *format;
 816
 817        switch (which) {
 818        case V4L2_SUBDEV_FORMAT_TRY:
 819                format = v4l2_subdev_get_try_format(&xdprxss->subdev, cfg, pad);
 820                break;
 821        case V4L2_SUBDEV_FORMAT_ACTIVE:
 822                format = &xdprxss->format;
 823                break;
 824        default:
 825                format = NULL;
 826                break;
 827        }
 828
 829        return format;
 830}
 831
 832/**
 833 * xdprxss_init_cfg - Initialise the pad format config to default
 834 * @sd: Pointer to V4L2 Sub device structure
 835 * @cfg: Pointer to sub device pad information structure
 836 *
 837 * This function is used to initialize the pad format with the default
 838 * values.
 839 *
 840 * Return: 0 on success
 841 */
 842static int xdprxss_init_cfg(struct v4l2_subdev *sd,
 843                            struct v4l2_subdev_pad_config *cfg)
 844{
 845        struct xdprxss_state *xdprxss = to_xdprxssstate(sd);
 846        struct v4l2_mbus_framefmt *format;
 847
 848        format = v4l2_subdev_get_try_format(sd, cfg, 0);
 849
 850        if (!xdprxss->valid_stream)
 851                *format = xdprxss->format;
 852
 853        return 0;
 854}
 855
 856/**
 857 * xdprxss_getset_format - This is used to set and get the pad format
 858 * @sd: Pointer to V4L2 Sub device structure
 859 * @cfg: Pointer to sub device pad information structure
 860 * @fmt: Pointer to pad level media bus format
 861 *
 862 * This function is used to set the pad format.
 863 * Since the pad format is fixed in hardware, it can't be
 864 * modified on run time.
 865 *
 866 * Return: 0 on success
 867 */
 868static int xdprxss_getset_format(struct v4l2_subdev *sd,
 869                                 struct v4l2_subdev_pad_config *cfg,
 870                                 struct v4l2_subdev_format *fmt)
 871{
 872        struct xdprxss_state *xdprxss = to_xdprxssstate(sd);
 873        struct v4l2_mbus_framefmt *format;
 874
 875        if (!xdprxss->valid_stream) {
 876                dev_err(xdprxss->dev, "Video not locked!\n");
 877                return -EINVAL;
 878        }
 879
 880        dev_dbg(xdprxss->dev,
 881                "set width %d height %d code %d field %d colorspace %d\n",
 882                fmt->format.width, fmt->format.height,
 883                fmt->format.code, fmt->format.field,
 884                fmt->format.colorspace);
 885        format = __xdprxss_get_pad_format(xdprxss, cfg,
 886                                          fmt->pad, fmt->which);
 887        if (!format)
 888                return -EINVAL;
 889
 890        fmt->format = *format;
 891
 892        return 0;
 893}
 894
 895/**
 896 * xdprxss_enum_mbus_code - Handle pixel format enumeration
 897 * @sd: pointer to v4l2 subdev structure
 898 * @cfg: V4L2 subdev pad configuration
 899 * @code: pointer to v4l2_subdev_mbus_code_enum structure
 900 *
 901 * Return: -EINVAL or zero on success
 902 */
 903static int xdprxss_enum_mbus_code(struct v4l2_subdev *sd,
 904                                  struct v4l2_subdev_pad_config *cfg,
 905                                  struct v4l2_subdev_mbus_code_enum *code)
 906{
 907        struct xdprxss_state *xdprxss = to_xdprxssstate(sd);
 908        u32 index = code->index;
 909        u32 base = 0;
 910
 911        if (xdprxss->bpc == 8)
 912                base = 0;
 913
 914        if (xdprxss->bpc == 10)
 915                base = 3;
 916
 917        if (code->pad || index >= 3)
 918                return -EINVAL;
 919
 920        code->code = xdprxss_supported_mbus_fmts[base + index];
 921
 922        return 0;
 923}
 924
 925/**
 926 * xdprxss_enum_dv_timings - Enumerate all the supported DV timings
 927 * @sd: pointer to v4l2 subdev structure
 928 * @timings: DV timings structure to be returned.
 929 *
 930 * Return: -EINVAL incase of invalid index and pad or zero on success
 931 */
 932static int xdprxss_enum_dv_timings(struct v4l2_subdev *sd,
 933                                   struct v4l2_enum_dv_timings *timings)
 934{
 935        if (timings->index >= ARRAY_SIZE(fmt_cap))
 936                return -EINVAL;
 937
 938        if (timings->pad != 0)
 939                return -EINVAL;
 940
 941        timings->timings = fmt_cap[timings->index];
 942
 943        return 0;
 944}
 945
 946/**
 947 * xdprxss_get_dv_timings_cap - This is used to set the dv timing
 948 * capabilities
 949 * @subdev: Pointer to V4L2 Sub device structure
 950 * @cap: Pointer to dv timing capability structure
 951 *
 952 * Return: -EINVAL incase of invalid pad or zero on success
 953 */
 954static int xdprxss_get_dv_timings_cap(struct v4l2_subdev *subdev,
 955                                      struct v4l2_dv_timings_cap *cap)
 956{
 957        struct v4l2_dv_timings_cap xdprxss_dv_timings_cap = {
 958                .type = V4L2_DV_BT_656_1120,
 959                .reserved = { 0 },
 960                V4L2_INIT_BT_TIMINGS
 961                (800, 7680,
 962                600, 4320,
 963                25000000, 297000000,
 964                V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
 965                V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT,
 966                V4L2_DV_BT_CAP_INTERLACED | V4L2_DV_BT_CAP_PROGRESSIVE |
 967                V4L2_DV_BT_CAP_REDUCED_BLANKING |
 968                V4L2_DV_BT_CAP_CUSTOM
 969                )
 970        };
 971
 972        if (cap->pad != 0)
 973                return -EINVAL;
 974
 975        *cap = xdprxss_dv_timings_cap;
 976
 977        return 0;
 978}
 979
 980static int xdprxss_query_dv_timings(struct v4l2_subdev *sd,
 981                                    struct v4l2_dv_timings *timings)
 982{
 983        struct xdprxss_state *state = to_xdprxssstate(sd);
 984        unsigned int i;
 985
 986        if (!timings)
 987                return -EINVAL;
 988
 989        if (!state->valid_stream)
 990                return -ENOLCK;
 991        for (i = 0; i < ARRAY_SIZE(xdprxss_dv_timings); i++) {
 992                if (state->format.width == xdprxss_dv_timings[i].width &&
 993                    state->format.height == xdprxss_dv_timings[i].height &&
 994                    state->frame_interval == xdprxss_dv_timings[i].fps) {
 995                        *timings = xdprxss_dv_timings[i].timing;
 996                        return 0;
 997                }
 998        }
 999
1000        return -ERANGE;
1001}
1002
1003/* ------------------------------------------------------------
1004 * Media Operations
1005 */
1006
1007static const struct media_entity_operations xdprxss_media_ops = {
1008        .link_validate = v4l2_subdev_link_validate
1009};
1010
1011static const struct v4l2_subdev_core_ops xdprxss_core_ops = {
1012        .subscribe_event        = xdprxss_subscribe_event,
1013        .unsubscribe_event      = v4l2_event_subdev_unsubscribe,
1014};
1015
1016static const struct v4l2_subdev_video_ops xdprxss_video_ops = {
1017        .query_dv_timings       = xdprxss_query_dv_timings,
1018        .s_stream               = xdprxss_s_stream,
1019        .g_input_status         = xdprxss_g_input_status,
1020};
1021
1022static const struct v4l2_subdev_pad_ops xdprxss_pad_ops = {
1023        .init_cfg               = xdprxss_init_cfg,
1024        .enum_mbus_code         = xdprxss_enum_mbus_code,
1025        .get_fmt                = xdprxss_getset_format,
1026        .set_fmt                = xdprxss_getset_format,
1027        .enum_dv_timings        = xdprxss_enum_dv_timings,
1028        .dv_timings_cap         = xdprxss_get_dv_timings_cap,
1029};
1030
1031static const struct v4l2_subdev_ops xdprxss_ops = {
1032        .core   = &xdprxss_core_ops,
1033        .video  = &xdprxss_video_ops,
1034        .pad    = &xdprxss_pad_ops
1035};
1036
1037/* ----------------------------------------------------------------
1038 * Platform Device Driver
1039 */
1040static int xdprxss_parse_of(struct xdprxss_state *xdprxss)
1041{
1042        struct device_node *node = xdprxss->dev->of_node;
1043        u32 val = 0;
1044        int ret;
1045
1046        ret = of_property_read_u32(node, "xlnx,bpc", &xdprxss->bpc);
1047        if (ret < 0) {
1048                if (ret != -EINVAL) {
1049                        dev_err(xdprxss->dev, "failed to get xlnx,bpp\n");
1050                        return ret;
1051                }
1052        }
1053        /*
1054         * TODO : For now driver supports only 8, 10 bpc.
1055         * In future, driver may add with other bpc support
1056         */
1057        if (xdprxss->bpc != 8 && xdprxss->bpc != 10) {
1058                dev_err(xdprxss->dev, "unsupported bpc = %u\n", xdprxss->bpc);
1059                return -EINVAL;
1060        }
1061
1062        xdprxss->hdcp_enable = of_property_read_bool(node, "xlnx,hdcp-enable");
1063        /* TODO : This driver does not support HDCP feature */
1064        if (xdprxss->hdcp_enable) {
1065                dev_err(xdprxss->dev, "hdcp unsupported\n");
1066                return -EINVAL;
1067        }
1068
1069        xdprxss->audio_enable = of_property_read_bool(node,
1070                                                      "xlnx,audio-enable");
1071        /* TODO : This driver does not support audio */
1072        if (xdprxss->audio_enable) {
1073                dev_err(xdprxss->dev, "audio unsupported\n");
1074                return -EINVAL;
1075        }
1076
1077        ret = of_property_read_u32(node, "xlnx,link-rate", &val);
1078        if (ret < 0) {
1079                dev_err(xdprxss->dev, "xlnx,link-rate property not found\n");
1080                return ret;
1081        }
1082        if (!(val == DP_LINK_BW_1_62 ||
1083              val == DP_LINK_BW_2_7 ||
1084              val == DP_LINK_BW_5_4 ||
1085              val == DP_LINK_BW_8_1)) {
1086                dev_err(xdprxss->dev, "invalid link rate\n");
1087                return -EINVAL;
1088        }
1089        xdprxss->max_linkrate = val;
1090
1091        ret = of_property_read_u32(node, "xlnx,lane-count", &val);
1092        if (ret < 0) {
1093                dev_err(xdprxss->dev, "xlnx,lane-count property not found\n");
1094                return ret;
1095        }
1096        if (val < 1 && val > 4) {
1097                dev_err(xdprxss->dev, "invalid lane count\n");
1098                return -EINVAL;
1099        }
1100        xdprxss->max_lanecount = val;
1101
1102        ret = of_property_read_u32(node, "xlnx,mode", &val);
1103        if (ret < 0) {
1104                dev_err(xdprxss->dev, "xlnx,mode property not found\n");
1105                return ret;
1106        }
1107        if (val > 0) {
1108                dev_err(xdprxss->dev, "driver does't support MST mode\n");
1109                return -EINVAL;
1110        }
1111
1112        return 0;
1113}
1114
1115static int xdprxss_probe(struct platform_device *pdev)
1116{
1117        struct v4l2_subdev *subdev;
1118        struct xdprxss_state *xdprxss;
1119        struct device_node *node;
1120        struct device *dev = &pdev->dev;
1121        struct resource *res;
1122        int ret, irq;
1123        unsigned int i = 0, j;
1124
1125        xdprxss = devm_kzalloc(dev, sizeof(*xdprxss), GFP_KERNEL);
1126        if (!xdprxss)
1127                return -ENOMEM;
1128
1129        xdprxss->dev = &pdev->dev;
1130        node = xdprxss->dev->of_node;
1131
1132        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dp_base");
1133        xdprxss->dp_base = devm_ioremap_resource(dev, res);
1134        if (IS_ERR(xdprxss->dp_base)) {
1135                dev_err(dev, "couldn't map DisplayPort registers\n");
1136                return -ENODEV;
1137        }
1138
1139        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "edid_base");
1140        xdprxss->edid_base = devm_ioremap_resource(dev, res);
1141        if (IS_ERR(xdprxss->edid_base)) {
1142                dev_err(dev, "Couldn't map EDID IP memory\n");
1143                return -ENOENT;
1144        }
1145
1146        xdprxss->axi_clk = devm_clk_get(dev, "s_axi_aclk");
1147        if (IS_ERR(xdprxss->axi_clk)) {
1148                ret = PTR_ERR(xdprxss->axi_clk);
1149                dev_err(&pdev->dev, "failed to get s_axi_clk (%d)\n", ret);
1150                return ret;
1151        }
1152
1153        xdprxss->rx_lnk_clk = devm_clk_get(dev, "rx_lnk_clk");
1154        if (IS_ERR(xdprxss->rx_lnk_clk)) {
1155                ret = PTR_ERR(xdprxss->rx_lnk_clk);
1156                dev_err(&pdev->dev, "failed to get rx_lnk_clk (%d)\n", ret);
1157                return ret;
1158        }
1159
1160        xdprxss->rx_vid_clk = devm_clk_get(dev, "rx_vid_clk");
1161        if (IS_ERR(xdprxss->rx_vid_clk)) {
1162                ret = PTR_ERR(xdprxss->rx_vid_clk);
1163                dev_err(&pdev->dev, "failed to get rx_vid_clk (%d)\n", ret);
1164                return ret;
1165        }
1166
1167        ret = xdprxss_parse_of(xdprxss);
1168        if (ret < 0)
1169                goto clk_err;
1170
1171        /* acquire vphy lanes */
1172        for (i = 0; i < xdprxss->max_lanecount; i++) {
1173                char phy_name[16];
1174
1175                snprintf(phy_name, sizeof(phy_name), "dp-phy%d", i);
1176                xdprxss->phy[i] = devm_phy_get(xdprxss->dev, phy_name);
1177                if (IS_ERR(xdprxss->phy[i])) {
1178                        ret = PTR_ERR(xdprxss->phy[i]);
1179                        xdprxss->phy[i] = NULL;
1180                        if (ret == -EPROBE_DEFER)
1181                                dev_info(dev, "phy not ready -EPROBE_DEFER\n");
1182                        if (ret != -EPROBE_DEFER)
1183                                dev_err(dev,
1184                                        "failed to get phy lane %s i %d\n",
1185                                        phy_name, i);
1186                        goto error_phy;
1187                }
1188                ret = phy_init(xdprxss->phy[i]);
1189                if (ret) {
1190                        dev_err(dev,
1191                                "failed to init phy lane %d\n", i);
1192                        goto error_phy;
1193                }
1194        }
1195
1196        ret = clk_prepare_enable(xdprxss->axi_clk);
1197        if (ret) {
1198                dev_err(dev, "failed to enable axi_clk (%d)\n", ret);
1199                goto error_phy;
1200        }
1201
1202        ret = clk_prepare_enable(xdprxss->rx_lnk_clk);
1203        if (ret) {
1204                dev_err(dev, "failed to enable rx_lnk_clk (%d)\n", ret);
1205                goto rx_lnk_clk_err;
1206        }
1207
1208        ret = clk_prepare_enable(xdprxss->rx_vid_clk);
1209        if (ret) {
1210                dev_err(dev, "failed to enable rx_vid_clk (%d)\n", ret);
1211                goto rx_vid_clk_err;
1212        }
1213
1214        spin_lock_init(&xdprxss->lock);
1215
1216        /* Initialize the DP core */
1217        xdprxss_core_init(xdprxss);
1218
1219        /* Initialize V4L2 subdevice and media entity */
1220        xdprxss->pad.flags = MEDIA_PAD_FL_SOURCE;
1221
1222        /* Initialize V4L2 subdevice and media entity */
1223        subdev = &xdprxss->subdev;
1224        v4l2_subdev_init(subdev, &xdprxss_ops);
1225        subdev->dev = &pdev->dev;
1226        strscpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
1227
1228        subdev->flags = V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1229
1230        subdev->entity.ops = &xdprxss_media_ops;
1231
1232        v4l2_set_subdevdata(subdev, xdprxss);
1233        ret = media_entity_pads_init(&subdev->entity, 1, &xdprxss->pad);
1234        if (ret < 0)
1235                goto error;
1236
1237        /* Register interrupt handler */
1238        irq = irq_of_parse_and_map(node, 0);
1239        ret = devm_request_irq(xdprxss->dev, irq, xdprxss_irq_handler,
1240                               IRQF_SHARED, subdev->name, xdprxss);
1241        if (ret) {
1242                dev_err(dev, "Err = %d Interrupt handler reg failed!\n",
1243                        ret);
1244                goto error;
1245        }
1246
1247        platform_set_drvdata(pdev, xdprxss);
1248
1249        ret = v4l2_async_register_subdev(subdev);
1250        if (ret < 0) {
1251                dev_err(dev, "failed to register subdev\n");
1252                goto error;
1253        }
1254
1255        return 0;
1256
1257error:
1258        media_entity_cleanup(&subdev->entity);
1259clk_err:
1260        clk_disable_unprepare(xdprxss->rx_vid_clk);
1261rx_vid_clk_err:
1262        clk_disable_unprepare(xdprxss->rx_lnk_clk);
1263rx_lnk_clk_err:
1264        clk_disable_unprepare(xdprxss->axi_clk);
1265error_phy:
1266        dev_dbg(dev, " %s error_phy:\n", __func__);
1267        /* release the lanes that we did get, if we did not get all lanes */
1268        for (j = 0; j < i; j++) {
1269                if (xdprxss->phy[j]) {
1270                        dev_dbg(dev,
1271                                "phy_exit() xdprxss->phy[%d] = %p\n",
1272                                j, xdprxss->phy[j]);
1273                        phy_exit(xdprxss->phy[j]);
1274                        xdprxss->phy[j] = NULL;
1275                }
1276        }
1277
1278        return ret;
1279}
1280
1281static int xdprxss_remove(struct platform_device *pdev)
1282{
1283        struct xdprxss_state *xdprxss = platform_get_drvdata(pdev);
1284        struct v4l2_subdev *subdev = &xdprxss->subdev;
1285        unsigned int i;
1286
1287        v4l2_async_unregister_subdev(subdev);
1288        media_entity_cleanup(&subdev->entity);
1289        clk_disable_unprepare(xdprxss->rx_vid_clk);
1290        clk_disable_unprepare(xdprxss->rx_lnk_clk);
1291        clk_disable_unprepare(xdprxss->axi_clk);
1292        for (i = 0; i < XDPRX_MAX_LANE_COUNT; i++) {
1293                phy_exit(xdprxss->phy[i]);
1294                xdprxss->phy[i] = NULL;
1295        }
1296        return 0;
1297}
1298
1299static const struct of_device_id xdprxss_of_id_table[] = {
1300        { .compatible = "xlnx,v-dp-rxss-3.0", },
1301        { /* end of table */ }
1302};
1303MODULE_DEVICE_TABLE(of, xdprxss_of_id_table);
1304
1305static struct platform_driver xdprxss_driver = {
1306        .driver = {
1307                .name           = "xilinx-dprxss",
1308                .of_match_table = xdprxss_of_id_table,
1309        },
1310        .probe                  = xdprxss_probe,
1311        .remove                 = xdprxss_remove,
1312};
1313
1314module_platform_driver(xdprxss_driver);
1315
1316MODULE_AUTHOR("Rajesh Gugulothu <gugulothu.rajesh@xilinx.com");
1317MODULE_DESCRIPTION("Xilinx DP Rx Subsystem Driver");
1318MODULE_LICENSE("GPL v2");
1319