linux/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Analogix DP (Display port) core register interface driver.
   4 *
   5 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
   6 * Author: Jingoo Han <jg1.han@samsung.com>
   7 */
   8
   9#include <linux/delay.h>
  10#include <linux/device.h>
  11#include <linux/gpio/consumer.h>
  12#include <linux/io.h>
  13#include <linux/iopoll.h>
  14
  15#include <drm/bridge/analogix_dp.h>
  16
  17#include "analogix_dp_core.h"
  18#include "analogix_dp_reg.h"
  19
  20#define COMMON_INT_MASK_1       0
  21#define COMMON_INT_MASK_2       0
  22#define COMMON_INT_MASK_3       0
  23#define COMMON_INT_MASK_4       (HOTPLUG_CHG | HPD_LOST | PLUG)
  24#define INT_STA_MASK            INT_HPD
  25
  26void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable)
  27{
  28        u32 reg;
  29
  30        if (enable) {
  31                reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  32                reg |= HDCP_VIDEO_MUTE;
  33                writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  34        } else {
  35                reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  36                reg &= ~HDCP_VIDEO_MUTE;
  37                writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  38        }
  39}
  40
  41void analogix_dp_stop_video(struct analogix_dp_device *dp)
  42{
  43        u32 reg;
  44
  45        reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  46        reg &= ~VIDEO_EN;
  47        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  48}
  49
  50void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable)
  51{
  52        u32 reg;
  53
  54        if (enable)
  55                reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
  56                      LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
  57        else
  58                reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
  59                      LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
  60
  61        writel(reg, dp->reg_base + ANALOGIX_DP_LANE_MAP);
  62}
  63
  64void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
  65{
  66        u32 reg;
  67
  68        reg = TX_TERMINAL_CTRL_50_OHM;
  69        writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_1);
  70
  71        reg = SEL_24M | TX_DVDD_BIT_1_0625V;
  72        writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
  73
  74        if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
  75                reg = REF_CLK_24M;
  76                if (dp->plat_data->dev_type == RK3288_DP)
  77                        reg ^= REF_CLK_MASK;
  78
  79                writel(reg, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
  80                writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
  81                writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
  82                writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
  83                writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5);
  84        }
  85
  86        reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
  87        writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);
  88
  89        reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
  90                TX_CUR1_2X | TX_CUR_16_MA;
  91        writel(reg, dp->reg_base + ANALOGIX_DP_PLL_FILTER_CTL_1);
  92
  93        reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
  94                CH1_AMP_400_MV | CH0_AMP_400_MV;
  95        writel(reg, dp->reg_base + ANALOGIX_DP_TX_AMP_TUNING_CTL);
  96}
  97
  98void analogix_dp_init_interrupt(struct analogix_dp_device *dp)
  99{
 100        /* Set interrupt pin assertion polarity as high */
 101        writel(INT_POL1 | INT_POL0, dp->reg_base + ANALOGIX_DP_INT_CTL);
 102
 103        /* Clear pending regisers */
 104        writel(0xff, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
 105        writel(0x4f, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_2);
 106        writel(0xe0, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_3);
 107        writel(0xe7, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
 108        writel(0x63, dp->reg_base + ANALOGIX_DP_INT_STA);
 109
 110        /* 0:mask,1: unmask */
 111        writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
 112        writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
 113        writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
 114        writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
 115        writel(0x00, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
 116}
 117
 118void analogix_dp_reset(struct analogix_dp_device *dp)
 119{
 120        u32 reg;
 121
 122        analogix_dp_stop_video(dp);
 123        analogix_dp_enable_video_mute(dp, 0);
 124
 125        if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
 126                reg = RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N |
 127                        SW_FUNC_EN_N;
 128        else
 129                reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
 130                        AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
 131                        HDCP_FUNC_EN_N | SW_FUNC_EN_N;
 132
 133        writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
 134
 135        reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
 136                SERDES_FIFO_FUNC_EN_N |
 137                LS_CLK_DOMAIN_FUNC_EN_N;
 138        writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
 139
 140        usleep_range(20, 30);
 141
 142        analogix_dp_lane_swap(dp, 0);
 143
 144        writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
 145        writel(0x40, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
 146        writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 147        writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 148
 149        writel(0x0, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
 150        writel(0x0, dp->reg_base + ANALOGIX_DP_HDCP_CTL);
 151
 152        writel(0x5e, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_L);
 153        writel(0x1a, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_H);
 154
 155        writel(0x10, dp->reg_base + ANALOGIX_DP_LINK_DEBUG_CTL);
 156
 157        writel(0x0, dp->reg_base + ANALOGIX_DP_PHY_TEST);
 158
 159        writel(0x0, dp->reg_base + ANALOGIX_DP_VIDEO_FIFO_THRD);
 160        writel(0x20, dp->reg_base + ANALOGIX_DP_AUDIO_MARGIN);
 161
 162        writel(0x4, dp->reg_base + ANALOGIX_DP_M_VID_GEN_FILTER_TH);
 163        writel(0x2, dp->reg_base + ANALOGIX_DP_M_AUD_GEN_FILTER_TH);
 164
 165        writel(0x00000101, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
 166}
 167
 168void analogix_dp_swreset(struct analogix_dp_device *dp)
 169{
 170        writel(RESET_DP_TX, dp->reg_base + ANALOGIX_DP_TX_SW_RESET);
 171}
 172
 173void analogix_dp_config_interrupt(struct analogix_dp_device *dp)
 174{
 175        u32 reg;
 176
 177        /* 0: mask, 1: unmask */
 178        reg = COMMON_INT_MASK_1;
 179        writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
 180
 181        reg = COMMON_INT_MASK_2;
 182        writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
 183
 184        reg = COMMON_INT_MASK_3;
 185        writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
 186
 187        reg = COMMON_INT_MASK_4;
 188        writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
 189
 190        reg = INT_STA_MASK;
 191        writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
 192}
 193
 194void analogix_dp_mute_hpd_interrupt(struct analogix_dp_device *dp)
 195{
 196        u32 reg;
 197
 198        /* 0: mask, 1: unmask */
 199        reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
 200        reg &= ~COMMON_INT_MASK_4;
 201        writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
 202
 203        reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
 204        reg &= ~INT_STA_MASK;
 205        writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
 206}
 207
 208void analogix_dp_unmute_hpd_interrupt(struct analogix_dp_device *dp)
 209{
 210        u32 reg;
 211
 212        /* 0: mask, 1: unmask */
 213        reg = COMMON_INT_MASK_4;
 214        writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
 215
 216        reg = INT_STA_MASK;
 217        writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
 218}
 219
 220enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp)
 221{
 222        u32 reg;
 223
 224        reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
 225        if (reg & PLL_LOCK)
 226                return PLL_LOCKED;
 227        else
 228                return PLL_UNLOCKED;
 229}
 230
 231void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable)
 232{
 233        u32 reg;
 234        u32 mask = DP_PLL_PD;
 235        u32 pd_addr = ANALOGIX_DP_PLL_CTL;
 236
 237        if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
 238                pd_addr = ANALOGIX_DP_PD;
 239                mask = RK_PLL_PD;
 240        }
 241
 242        reg = readl(dp->reg_base + pd_addr);
 243        if (enable)
 244                reg |= mask;
 245        else
 246                reg &= ~mask;
 247        writel(reg, dp->reg_base + pd_addr);
 248}
 249
 250void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
 251                                       enum analog_power_block block,
 252                                       bool enable)
 253{
 254        u32 reg;
 255        u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
 256        u32 mask;
 257
 258        if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
 259                phy_pd_addr = ANALOGIX_DP_PD;
 260
 261        switch (block) {
 262        case AUX_BLOCK:
 263                if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
 264                        mask = RK_AUX_PD;
 265                else
 266                        mask = AUX_PD;
 267
 268                reg = readl(dp->reg_base + phy_pd_addr);
 269                if (enable)
 270                        reg |= mask;
 271                else
 272                        reg &= ~mask;
 273                writel(reg, dp->reg_base + phy_pd_addr);
 274                break;
 275        case CH0_BLOCK:
 276                mask = CH0_PD;
 277                reg = readl(dp->reg_base + phy_pd_addr);
 278
 279                if (enable)
 280                        reg |= mask;
 281                else
 282                        reg &= ~mask;
 283                writel(reg, dp->reg_base + phy_pd_addr);
 284                break;
 285        case CH1_BLOCK:
 286                mask = CH1_PD;
 287                reg = readl(dp->reg_base + phy_pd_addr);
 288
 289                if (enable)
 290                        reg |= mask;
 291                else
 292                        reg &= ~mask;
 293                writel(reg, dp->reg_base + phy_pd_addr);
 294                break;
 295        case CH2_BLOCK:
 296                mask = CH2_PD;
 297                reg = readl(dp->reg_base + phy_pd_addr);
 298
 299                if (enable)
 300                        reg |= mask;
 301                else
 302                        reg &= ~mask;
 303                writel(reg, dp->reg_base + phy_pd_addr);
 304                break;
 305        case CH3_BLOCK:
 306                mask = CH3_PD;
 307                reg = readl(dp->reg_base + phy_pd_addr);
 308
 309                if (enable)
 310                        reg |= mask;
 311                else
 312                        reg &= ~mask;
 313                writel(reg, dp->reg_base + phy_pd_addr);
 314                break;
 315        case ANALOG_TOTAL:
 316                /*
 317                 * There is no bit named DP_PHY_PD, so We used DP_INC_BG
 318                 * to power off everything instead of DP_PHY_PD in
 319                 * Rockchip
 320                 */
 321                if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
 322                        mask = DP_INC_BG;
 323                else
 324                        mask = DP_PHY_PD;
 325
 326                reg = readl(dp->reg_base + phy_pd_addr);
 327                if (enable)
 328                        reg |= mask;
 329                else
 330                        reg &= ~mask;
 331
 332                writel(reg, dp->reg_base + phy_pd_addr);
 333                if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
 334                        usleep_range(10, 15);
 335                break;
 336        case POWER_ALL:
 337                if (enable) {
 338                        reg = DP_ALL_PD;
 339                        writel(reg, dp->reg_base + phy_pd_addr);
 340                } else {
 341                        reg = DP_ALL_PD;
 342                        writel(reg, dp->reg_base + phy_pd_addr);
 343                        usleep_range(10, 15);
 344                        reg &= ~DP_INC_BG;
 345                        writel(reg, dp->reg_base + phy_pd_addr);
 346                        usleep_range(10, 15);
 347
 348                        writel(0x00, dp->reg_base + phy_pd_addr);
 349                }
 350                break;
 351        default:
 352                break;
 353        }
 354}
 355
 356int analogix_dp_init_analog_func(struct analogix_dp_device *dp)
 357{
 358        u32 reg;
 359        int timeout_loop = 0;
 360
 361        analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
 362
 363        reg = PLL_LOCK_CHG;
 364        writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
 365
 366        reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
 367        reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
 368        writel(reg, dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
 369
 370        /* Power up PLL */
 371        if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
 372                analogix_dp_set_pll_power_down(dp, 0);
 373
 374                while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
 375                        timeout_loop++;
 376                        if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
 377                                dev_err(dp->dev, "failed to get pll lock status\n");
 378                                return -ETIMEDOUT;
 379                        }
 380                        usleep_range(10, 20);
 381                }
 382        }
 383
 384        /* Enable Serdes FIFO function and Link symbol clock domain module */
 385        reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
 386        reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
 387                | AUX_FUNC_EN_N);
 388        writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
 389        return 0;
 390}
 391
 392void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp)
 393{
 394        u32 reg;
 395
 396        if (dp->hpd_gpiod)
 397                return;
 398
 399        reg = HOTPLUG_CHG | HPD_LOST | PLUG;
 400        writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
 401
 402        reg = INT_HPD;
 403        writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
 404}
 405
 406void analogix_dp_init_hpd(struct analogix_dp_device *dp)
 407{
 408        u32 reg;
 409
 410        if (dp->hpd_gpiod)
 411                return;
 412
 413        analogix_dp_clear_hotplug_interrupts(dp);
 414
 415        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 416        reg &= ~(F_HPD | HPD_CTRL);
 417        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 418}
 419
 420void analogix_dp_force_hpd(struct analogix_dp_device *dp)
 421{
 422        u32 reg;
 423
 424        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 425        reg = (F_HPD | HPD_CTRL);
 426        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 427}
 428
 429enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
 430{
 431        u32 reg;
 432
 433        if (dp->hpd_gpiod) {
 434                reg = gpiod_get_value(dp->hpd_gpiod);
 435                if (reg)
 436                        return DP_IRQ_TYPE_HP_CABLE_IN;
 437                else
 438                        return DP_IRQ_TYPE_HP_CABLE_OUT;
 439        } else {
 440                /* Parse hotplug interrupt status register */
 441                reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
 442
 443                if (reg & PLUG)
 444                        return DP_IRQ_TYPE_HP_CABLE_IN;
 445
 446                if (reg & HPD_LOST)
 447                        return DP_IRQ_TYPE_HP_CABLE_OUT;
 448
 449                if (reg & HOTPLUG_CHG)
 450                        return DP_IRQ_TYPE_HP_CHANGE;
 451
 452                return DP_IRQ_TYPE_UNKNOWN;
 453        }
 454}
 455
 456void analogix_dp_reset_aux(struct analogix_dp_device *dp)
 457{
 458        u32 reg;
 459
 460        /* Disable AUX channel module */
 461        reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
 462        reg |= AUX_FUNC_EN_N;
 463        writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
 464}
 465
 466void analogix_dp_init_aux(struct analogix_dp_device *dp)
 467{
 468        u32 reg;
 469
 470        /* Clear inerrupts related to AUX channel */
 471        reg = RPLY_RECEIV | AUX_ERR;
 472        writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
 473
 474        analogix_dp_set_analog_power_down(dp, AUX_BLOCK, true);
 475        usleep_range(10, 11);
 476        analogix_dp_set_analog_power_down(dp, AUX_BLOCK, false);
 477
 478        analogix_dp_reset_aux(dp);
 479
 480        /* AUX_BIT_PERIOD_EXPECTED_DELAY doesn't apply to Rockchip IP */
 481        if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
 482                reg = 0;
 483        else
 484                reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3);
 485
 486        /* Disable AUX transaction H/W retry */
 487        reg |= AUX_HW_RETRY_COUNT_SEL(0) |
 488               AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
 489
 490        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
 491
 492        /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
 493        reg = DEFER_CTRL_EN | DEFER_COUNT(1);
 494        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_DEFER_CTL);
 495
 496        /* Enable AUX channel module */
 497        reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
 498        reg &= ~AUX_FUNC_EN_N;
 499        writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
 500}
 501
 502int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp)
 503{
 504        u32 reg;
 505
 506        if (dp->hpd_gpiod) {
 507                if (gpiod_get_value(dp->hpd_gpiod))
 508                        return 0;
 509        } else {
 510                reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 511                if (reg & HPD_STATUS)
 512                        return 0;
 513        }
 514
 515        return -EINVAL;
 516}
 517
 518void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
 519{
 520        u32 reg;
 521
 522        reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
 523        reg &= ~SW_FUNC_EN_N;
 524        writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
 525}
 526
 527int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp)
 528{
 529        int reg;
 530        int retval = 0;
 531        int timeout_loop = 0;
 532
 533        /* Enable AUX CH operation */
 534        reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
 535        reg |= AUX_EN;
 536        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
 537
 538        /* Is AUX CH command reply received? */
 539        reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
 540        while (!(reg & RPLY_RECEIV)) {
 541                timeout_loop++;
 542                if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
 543                        dev_err(dp->dev, "AUX CH command reply failed!\n");
 544                        return -ETIMEDOUT;
 545                }
 546                reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
 547                usleep_range(10, 11);
 548        }
 549
 550        /* Clear interrupt source for AUX CH command reply */
 551        writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
 552
 553        /* Clear interrupt source for AUX CH access error */
 554        reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
 555        if (reg & AUX_ERR) {
 556                writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
 557                return -EREMOTEIO;
 558        }
 559
 560        /* Check AUX CH error access status */
 561        reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
 562        if ((reg & AUX_STATUS_MASK) != 0) {
 563                dev_err(dp->dev, "AUX CH error happens: %d\n\n",
 564                        reg & AUX_STATUS_MASK);
 565                return -EREMOTEIO;
 566        }
 567
 568        return retval;
 569}
 570
 571int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp,
 572                                   unsigned int reg_addr,
 573                                   unsigned char data)
 574{
 575        u32 reg;
 576        int i;
 577        int retval;
 578
 579        for (i = 0; i < 3; i++) {
 580                /* Clear AUX CH data buffer */
 581                reg = BUF_CLR;
 582                writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
 583
 584                /* Select DPCD device address */
 585                reg = AUX_ADDR_7_0(reg_addr);
 586                writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
 587                reg = AUX_ADDR_15_8(reg_addr);
 588                writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
 589                reg = AUX_ADDR_19_16(reg_addr);
 590                writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
 591
 592                /* Write data buffer */
 593                reg = (unsigned int)data;
 594                writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
 595
 596                /*
 597                 * Set DisplayPort transaction and write 1 byte
 598                 * If bit 3 is 1, DisplayPort transaction.
 599                 * If Bit 3 is 0, I2C transaction.
 600                 */
 601                reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
 602                writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
 603
 604                /* Start AUX transaction */
 605                retval = analogix_dp_start_aux_transaction(dp);
 606                if (retval == 0)
 607                        break;
 608
 609                dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 610        }
 611
 612        return retval;
 613}
 614
 615void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
 616{
 617        u32 reg;
 618
 619        reg = bwtype;
 620        if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
 621                writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
 622}
 623
 624void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
 625{
 626        u32 reg;
 627
 628        reg = readl(dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
 629        *bwtype = reg;
 630}
 631
 632void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
 633{
 634        u32 reg;
 635
 636        reg = count;
 637        writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
 638}
 639
 640void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
 641{
 642        u32 reg;
 643
 644        reg = readl(dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
 645        *count = reg;
 646}
 647
 648void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
 649                                      bool enable)
 650{
 651        u32 reg;
 652
 653        if (enable) {
 654                reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 655                reg |= ENHANCED;
 656                writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 657        } else {
 658                reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 659                reg &= ~ENHANCED;
 660                writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 661        }
 662}
 663
 664void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
 665                                      enum pattern_set pattern)
 666{
 667        u32 reg;
 668
 669        switch (pattern) {
 670        case PRBS7:
 671                reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
 672                writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 673                break;
 674        case D10_2:
 675                reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
 676                writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 677                break;
 678        case TRAINING_PTN1:
 679                reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
 680                writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 681                break;
 682        case TRAINING_PTN2:
 683                reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
 684                writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 685                break;
 686        case DP_NONE:
 687                reg = SCRAMBLING_ENABLE |
 688                        LINK_QUAL_PATTERN_SET_DISABLE |
 689                        SW_TRAINING_PATTERN_SET_NORMAL;
 690                writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 691                break;
 692        default:
 693                break;
 694        }
 695}
 696
 697void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
 698                                        u32 level)
 699{
 700        u32 reg;
 701
 702        reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
 703        reg &= ~PRE_EMPHASIS_SET_MASK;
 704        reg |= level << PRE_EMPHASIS_SET_SHIFT;
 705        writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
 706}
 707
 708void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
 709                                        u32 level)
 710{
 711        u32 reg;
 712
 713        reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
 714        reg &= ~PRE_EMPHASIS_SET_MASK;
 715        reg |= level << PRE_EMPHASIS_SET_SHIFT;
 716        writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
 717}
 718
 719void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
 720                                        u32 level)
 721{
 722        u32 reg;
 723
 724        reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
 725        reg &= ~PRE_EMPHASIS_SET_MASK;
 726        reg |= level << PRE_EMPHASIS_SET_SHIFT;
 727        writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
 728}
 729
 730void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
 731                                        u32 level)
 732{
 733        u32 reg;
 734
 735        reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
 736        reg &= ~PRE_EMPHASIS_SET_MASK;
 737        reg |= level << PRE_EMPHASIS_SET_SHIFT;
 738        writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
 739}
 740
 741void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
 742                                         u32 training_lane)
 743{
 744        u32 reg;
 745
 746        reg = training_lane;
 747        writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
 748}
 749
 750void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
 751                                         u32 training_lane)
 752{
 753        u32 reg;
 754
 755        reg = training_lane;
 756        writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
 757}
 758
 759void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
 760                                         u32 training_lane)
 761{
 762        u32 reg;
 763
 764        reg = training_lane;
 765        writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
 766}
 767
 768void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
 769                                         u32 training_lane)
 770{
 771        u32 reg;
 772
 773        reg = training_lane;
 774        writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
 775}
 776
 777u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp)
 778{
 779        return readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
 780}
 781
 782u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp)
 783{
 784        return readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
 785}
 786
 787u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp)
 788{
 789        return readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
 790}
 791
 792u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp)
 793{
 794        return readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
 795}
 796
 797void analogix_dp_reset_macro(struct analogix_dp_device *dp)
 798{
 799        u32 reg;
 800
 801        reg = readl(dp->reg_base + ANALOGIX_DP_PHY_TEST);
 802        reg |= MACRO_RST;
 803        writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
 804
 805        /* 10 us is the minimum reset time. */
 806        usleep_range(10, 20);
 807
 808        reg &= ~MACRO_RST;
 809        writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
 810}
 811
 812void analogix_dp_init_video(struct analogix_dp_device *dp)
 813{
 814        u32 reg;
 815
 816        reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
 817        writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
 818
 819        reg = 0x0;
 820        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
 821
 822        reg = CHA_CRI(4) | CHA_CTRL;
 823        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
 824
 825        reg = 0x0;
 826        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 827
 828        reg = VID_HRES_TH(2) | VID_VRES_TH(0);
 829        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_8);
 830}
 831
 832void analogix_dp_set_video_color_format(struct analogix_dp_device *dp)
 833{
 834        u32 reg;
 835
 836        /* Configure the input color depth, color space, dynamic range */
 837        reg = (dp->video_info.dynamic_range << IN_D_RANGE_SHIFT) |
 838                (dp->video_info.color_depth << IN_BPC_SHIFT) |
 839                (dp->video_info.color_space << IN_COLOR_F_SHIFT);
 840        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_2);
 841
 842        /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
 843        reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
 844        reg &= ~IN_YC_COEFFI_MASK;
 845        if (dp->video_info.ycbcr_coeff)
 846                reg |= IN_YC_COEFFI_ITU709;
 847        else
 848                reg |= IN_YC_COEFFI_ITU601;
 849        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
 850}
 851
 852int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp)
 853{
 854        u32 reg;
 855
 856        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
 857        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
 858
 859        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
 860
 861        if (!(reg & DET_STA)) {
 862                dev_dbg(dp->dev, "Input stream clock not detected.\n");
 863                return -EINVAL;
 864        }
 865
 866        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
 867        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
 868
 869        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
 870        dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
 871
 872        if (reg & CHA_STA) {
 873                dev_dbg(dp->dev, "Input stream clk is changing\n");
 874                return -EINVAL;
 875        }
 876
 877        return 0;
 878}
 879
 880void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
 881                                 enum clock_recovery_m_value_type type,
 882                                 u32 m_value, u32 n_value)
 883{
 884        u32 reg;
 885
 886        if (type == REGISTER_M) {
 887                reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 888                reg |= FIX_M_VID;
 889                writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 890                reg = m_value & 0xff;
 891                writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_0);
 892                reg = (m_value >> 8) & 0xff;
 893                writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_1);
 894                reg = (m_value >> 16) & 0xff;
 895                writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_2);
 896
 897                reg = n_value & 0xff;
 898                writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_0);
 899                reg = (n_value >> 8) & 0xff;
 900                writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_1);
 901                reg = (n_value >> 16) & 0xff;
 902                writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_2);
 903        } else  {
 904                reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 905                reg &= ~FIX_M_VID;
 906                writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 907
 908                writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_0);
 909                writel(0x80, dp->reg_base + ANALOGIX_DP_N_VID_1);
 910                writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_2);
 911        }
 912}
 913
 914void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type)
 915{
 916        u32 reg;
 917
 918        if (type == VIDEO_TIMING_FROM_CAPTURE) {
 919                reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 920                reg &= ~FORMAT_SEL;
 921                writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 922        } else {
 923                reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 924                reg |= FORMAT_SEL;
 925                writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 926        }
 927}
 928
 929void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enable)
 930{
 931        u32 reg;
 932
 933        if (enable) {
 934                reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
 935                reg &= ~VIDEO_MODE_MASK;
 936                reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
 937                writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
 938        } else {
 939                reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
 940                reg &= ~VIDEO_MODE_MASK;
 941                reg |= VIDEO_MODE_SLAVE_MODE;
 942                writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
 943        }
 944}
 945
 946void analogix_dp_start_video(struct analogix_dp_device *dp)
 947{
 948        u32 reg;
 949
 950        reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
 951        reg |= VIDEO_EN;
 952        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
 953}
 954
 955int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp)
 956{
 957        u32 reg;
 958
 959        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 960        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 961
 962        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 963        if (!(reg & STRM_VALID)) {
 964                dev_dbg(dp->dev, "Input video stream is not detected.\n");
 965                return -EINVAL;
 966        }
 967
 968        return 0;
 969}
 970
 971void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
 972{
 973        u32 reg;
 974
 975        reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
 976        if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
 977                reg &= ~(RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N);
 978        } else {
 979                reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
 980                reg |= MASTER_VID_FUNC_EN_N;
 981        }
 982        writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
 983
 984        reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 985        reg &= ~INTERACE_SCAN_CFG;
 986        reg |= (dp->video_info.interlaced << 2);
 987        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 988
 989        reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 990        reg &= ~VSYNC_POLARITY_CFG;
 991        reg |= (dp->video_info.v_sync_polarity << 1);
 992        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 993
 994        reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 995        reg &= ~HSYNC_POLARITY_CFG;
 996        reg |= (dp->video_info.h_sync_polarity << 0);
 997        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 998
 999        reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
1000        writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
1001}
1002
1003void analogix_dp_enable_scrambling(struct analogix_dp_device *dp)
1004{
1005        u32 reg;
1006
1007        reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
1008        reg &= ~SCRAMBLING_DISABLE;
1009        writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
1010}
1011
1012void analogix_dp_disable_scrambling(struct analogix_dp_device *dp)
1013{
1014        u32 reg;
1015
1016        reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
1017        reg |= SCRAMBLING_DISABLE;
1018        writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
1019}
1020
1021void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp)
1022{
1023        writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
1024}
1025
1026static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
1027{
1028        ssize_t val;
1029        u8 status;
1030
1031        val = drm_dp_dpcd_readb(&dp->aux, DP_PSR_STATUS, &status);
1032        if (val < 0) {
1033                dev_err(dp->dev, "PSR_STATUS read failed ret=%zd", val);
1034                return val;
1035        }
1036        return status;
1037}
1038
1039int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
1040                             struct dp_sdp *vsc, bool blocking)
1041{
1042        unsigned int val;
1043        int ret;
1044        ssize_t psr_status;
1045
1046        /* don't send info frame */
1047        val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1048        val &= ~IF_EN;
1049        writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1050
1051        /* configure single frame update mode */
1052        writel(PSR_FRAME_UP_TYPE_BURST | PSR_CRC_SEL_HARDWARE,
1053               dp->reg_base + ANALOGIX_DP_PSR_FRAME_UPDATE_CTRL);
1054
1055        /* configure VSC HB0~HB3 */
1056        writel(vsc->sdp_header.HB0, dp->reg_base + ANALOGIX_DP_SPD_HB0);
1057        writel(vsc->sdp_header.HB1, dp->reg_base + ANALOGIX_DP_SPD_HB1);
1058        writel(vsc->sdp_header.HB2, dp->reg_base + ANALOGIX_DP_SPD_HB2);
1059        writel(vsc->sdp_header.HB3, dp->reg_base + ANALOGIX_DP_SPD_HB3);
1060
1061        /* configure reused VSC PB0~PB3, magic number from vendor */
1062        writel(0x00, dp->reg_base + ANALOGIX_DP_SPD_PB0);
1063        writel(0x16, dp->reg_base + ANALOGIX_DP_SPD_PB1);
1064        writel(0xCE, dp->reg_base + ANALOGIX_DP_SPD_PB2);
1065        writel(0x5D, dp->reg_base + ANALOGIX_DP_SPD_PB3);
1066
1067        /* configure DB0 / DB1 values */
1068        writel(vsc->db[0], dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB0);
1069        writel(vsc->db[1], dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB1);
1070
1071        /* set reuse spd inforframe */
1072        val = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
1073        val |= REUSE_SPD_EN;
1074        writel(val, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
1075
1076        /* mark info frame update */
1077        val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1078        val = (val | IF_UP) & ~IF_EN;
1079        writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1080
1081        /* send info frame */
1082        val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1083        val |= IF_EN;
1084        writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1085
1086        if (!blocking)
1087                return 0;
1088
1089        ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
1090                psr_status >= 0 &&
1091                ((vsc->db[1] && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
1092                (!vsc->db[1] && psr_status == DP_PSR_SINK_INACTIVE)), 1500,
1093                DP_TIMEOUT_PSR_LOOP_MS * 1000);
1094        if (ret) {
1095                dev_warn(dp->dev, "Failed to apply PSR %d\n", ret);
1096                return ret;
1097        }
1098        return 0;
1099}
1100
1101ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
1102                             struct drm_dp_aux_msg *msg)
1103{
1104        u32 reg;
1105        u32 status_reg;
1106        u8 *buffer = msg->buffer;
1107        unsigned int i;
1108        int num_transferred = 0;
1109        int ret;
1110
1111        /* Buffer size of AUX CH is 16 bytes */
1112        if (WARN_ON(msg->size > 16))
1113                return -E2BIG;
1114
1115        /* Clear AUX CH data buffer */
1116        reg = BUF_CLR;
1117        writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
1118
1119        switch (msg->request & ~DP_AUX_I2C_MOT) {
1120        case DP_AUX_I2C_WRITE:
1121                reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_I2C_TRANSACTION;
1122                if (msg->request & DP_AUX_I2C_MOT)
1123                        reg |= AUX_TX_COMM_MOT;
1124                break;
1125
1126        case DP_AUX_I2C_READ:
1127                reg = AUX_TX_COMM_READ | AUX_TX_COMM_I2C_TRANSACTION;
1128                if (msg->request & DP_AUX_I2C_MOT)
1129                        reg |= AUX_TX_COMM_MOT;
1130                break;
1131
1132        case DP_AUX_NATIVE_WRITE:
1133                reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_DP_TRANSACTION;
1134                break;
1135
1136        case DP_AUX_NATIVE_READ:
1137                reg = AUX_TX_COMM_READ | AUX_TX_COMM_DP_TRANSACTION;
1138                break;
1139
1140        default:
1141                return -EINVAL;
1142        }
1143
1144        reg |= AUX_LENGTH(msg->size);
1145        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
1146
1147        /* Select DPCD device address */
1148        reg = AUX_ADDR_7_0(msg->address);
1149        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
1150        reg = AUX_ADDR_15_8(msg->address);
1151        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
1152        reg = AUX_ADDR_19_16(msg->address);
1153        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
1154
1155        if (!(msg->request & DP_AUX_I2C_READ)) {
1156                for (i = 0; i < msg->size; i++) {
1157                        reg = buffer[i];
1158                        writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
1159                               4 * i);
1160                        num_transferred++;
1161                }
1162        }
1163
1164        /* Enable AUX CH operation */
1165        reg = AUX_EN;
1166
1167        /* Zero-sized messages specify address-only transactions. */
1168        if (msg->size < 1)
1169                reg |= ADDR_ONLY;
1170
1171        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
1172
1173        ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2,
1174                                 reg, !(reg & AUX_EN), 25, 500 * 1000);
1175        if (ret) {
1176                dev_err(dp->dev, "AUX CH enable timeout!\n");
1177                goto aux_error;
1178        }
1179
1180        /* TODO: Wait for an interrupt instead of looping? */
1181        /* Is AUX CH command reply received? */
1182        ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_INT_STA,
1183                                 reg, reg & RPLY_RECEIV, 10, 20 * 1000);
1184        if (ret) {
1185                dev_err(dp->dev, "AUX CH cmd reply timeout!\n");
1186                goto aux_error;
1187        }
1188
1189        /* Clear interrupt source for AUX CH command reply */
1190        writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
1191
1192        /* Clear interrupt source for AUX CH access error */
1193        reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
1194        status_reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
1195        if ((reg & AUX_ERR) || (status_reg & AUX_STATUS_MASK)) {
1196                writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
1197
1198                dev_warn(dp->dev, "AUX CH error happened: %#x (%d)\n",
1199                         status_reg & AUX_STATUS_MASK, !!(reg & AUX_ERR));
1200                goto aux_error;
1201        }
1202
1203        if (msg->request & DP_AUX_I2C_READ) {
1204                for (i = 0; i < msg->size; i++) {
1205                        reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
1206                                    4 * i);
1207                        buffer[i] = (unsigned char)reg;
1208                        num_transferred++;
1209                }
1210        }
1211
1212        /* Check if Rx sends defer */
1213        reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM);
1214        if (reg == AUX_RX_COMM_AUX_DEFER)
1215                msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
1216        else if (reg == AUX_RX_COMM_I2C_DEFER)
1217                msg->reply = DP_AUX_I2C_REPLY_DEFER;
1218        else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE ||
1219                 (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_READ)
1220                msg->reply = DP_AUX_I2C_REPLY_ACK;
1221        else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_WRITE ||
1222                 (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
1223                msg->reply = DP_AUX_NATIVE_REPLY_ACK;
1224
1225        return num_transferred > 0 ? num_transferred : -EBUSY;
1226
1227aux_error:
1228        /* if aux err happen, reset aux */
1229        analogix_dp_init_aux(dp);
1230
1231        return -EREMOTEIO;
1232}
1233