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
 527void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
 528{
 529        u32 reg;
 530
 531        reg = bwtype;
 532        if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
 533                writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
 534}
 535
 536void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
 537{
 538        u32 reg;
 539
 540        reg = readl(dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
 541        *bwtype = reg;
 542}
 543
 544void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
 545{
 546        u32 reg;
 547
 548        reg = count;
 549        writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
 550}
 551
 552void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
 553{
 554        u32 reg;
 555
 556        reg = readl(dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
 557        *count = reg;
 558}
 559
 560void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
 561                                      bool enable)
 562{
 563        u32 reg;
 564
 565        if (enable) {
 566                reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 567                reg |= ENHANCED;
 568                writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 569        } else {
 570                reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 571                reg &= ~ENHANCED;
 572                writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 573        }
 574}
 575
 576void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
 577                                      enum pattern_set pattern)
 578{
 579        u32 reg;
 580
 581        switch (pattern) {
 582        case PRBS7:
 583                reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
 584                writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 585                break;
 586        case D10_2:
 587                reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
 588                writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 589                break;
 590        case TRAINING_PTN1:
 591                reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
 592                writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 593                break;
 594        case TRAINING_PTN2:
 595                reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
 596                writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 597                break;
 598        case DP_NONE:
 599                reg = SCRAMBLING_ENABLE |
 600                        LINK_QUAL_PATTERN_SET_DISABLE |
 601                        SW_TRAINING_PATTERN_SET_NORMAL;
 602                writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 603                break;
 604        default:
 605                break;
 606        }
 607}
 608
 609void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
 610                                        u32 level)
 611{
 612        u32 reg;
 613
 614        reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
 615        reg &= ~PRE_EMPHASIS_SET_MASK;
 616        reg |= level << PRE_EMPHASIS_SET_SHIFT;
 617        writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
 618}
 619
 620void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
 621                                        u32 level)
 622{
 623        u32 reg;
 624
 625        reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
 626        reg &= ~PRE_EMPHASIS_SET_MASK;
 627        reg |= level << PRE_EMPHASIS_SET_SHIFT;
 628        writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
 629}
 630
 631void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
 632                                        u32 level)
 633{
 634        u32 reg;
 635
 636        reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
 637        reg &= ~PRE_EMPHASIS_SET_MASK;
 638        reg |= level << PRE_EMPHASIS_SET_SHIFT;
 639        writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
 640}
 641
 642void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
 643                                        u32 level)
 644{
 645        u32 reg;
 646
 647        reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
 648        reg &= ~PRE_EMPHASIS_SET_MASK;
 649        reg |= level << PRE_EMPHASIS_SET_SHIFT;
 650        writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
 651}
 652
 653void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
 654                                         u32 training_lane)
 655{
 656        u32 reg;
 657
 658        reg = training_lane;
 659        writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
 660}
 661
 662void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
 663                                         u32 training_lane)
 664{
 665        u32 reg;
 666
 667        reg = training_lane;
 668        writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
 669}
 670
 671void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
 672                                         u32 training_lane)
 673{
 674        u32 reg;
 675
 676        reg = training_lane;
 677        writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
 678}
 679
 680void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
 681                                         u32 training_lane)
 682{
 683        u32 reg;
 684
 685        reg = training_lane;
 686        writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
 687}
 688
 689u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp)
 690{
 691        return readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
 692}
 693
 694u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp)
 695{
 696        return readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
 697}
 698
 699u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp)
 700{
 701        return readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
 702}
 703
 704u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp)
 705{
 706        return readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
 707}
 708
 709void analogix_dp_reset_macro(struct analogix_dp_device *dp)
 710{
 711        u32 reg;
 712
 713        reg = readl(dp->reg_base + ANALOGIX_DP_PHY_TEST);
 714        reg |= MACRO_RST;
 715        writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
 716
 717        /* 10 us is the minimum reset time. */
 718        usleep_range(10, 20);
 719
 720        reg &= ~MACRO_RST;
 721        writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
 722}
 723
 724void analogix_dp_init_video(struct analogix_dp_device *dp)
 725{
 726        u32 reg;
 727
 728        reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
 729        writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
 730
 731        reg = 0x0;
 732        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
 733
 734        reg = CHA_CRI(4) | CHA_CTRL;
 735        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
 736
 737        reg = 0x0;
 738        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 739
 740        reg = VID_HRES_TH(2) | VID_VRES_TH(0);
 741        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_8);
 742}
 743
 744void analogix_dp_set_video_color_format(struct analogix_dp_device *dp)
 745{
 746        u32 reg;
 747
 748        /* Configure the input color depth, color space, dynamic range */
 749        reg = (dp->video_info.dynamic_range << IN_D_RANGE_SHIFT) |
 750                (dp->video_info.color_depth << IN_BPC_SHIFT) |
 751                (dp->video_info.color_space << IN_COLOR_F_SHIFT);
 752        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_2);
 753
 754        /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
 755        reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
 756        reg &= ~IN_YC_COEFFI_MASK;
 757        if (dp->video_info.ycbcr_coeff)
 758                reg |= IN_YC_COEFFI_ITU709;
 759        else
 760                reg |= IN_YC_COEFFI_ITU601;
 761        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
 762}
 763
 764int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp)
 765{
 766        u32 reg;
 767
 768        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
 769        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
 770
 771        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
 772
 773        if (!(reg & DET_STA)) {
 774                dev_dbg(dp->dev, "Input stream clock not detected.\n");
 775                return -EINVAL;
 776        }
 777
 778        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
 779        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
 780
 781        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
 782        dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
 783
 784        if (reg & CHA_STA) {
 785                dev_dbg(dp->dev, "Input stream clk is changing\n");
 786                return -EINVAL;
 787        }
 788
 789        return 0;
 790}
 791
 792void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
 793                                 enum clock_recovery_m_value_type type,
 794                                 u32 m_value, u32 n_value)
 795{
 796        u32 reg;
 797
 798        if (type == REGISTER_M) {
 799                reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 800                reg |= FIX_M_VID;
 801                writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 802                reg = m_value & 0xff;
 803                writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_0);
 804                reg = (m_value >> 8) & 0xff;
 805                writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_1);
 806                reg = (m_value >> 16) & 0xff;
 807                writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_2);
 808
 809                reg = n_value & 0xff;
 810                writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_0);
 811                reg = (n_value >> 8) & 0xff;
 812                writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_1);
 813                reg = (n_value >> 16) & 0xff;
 814                writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_2);
 815        } else  {
 816                reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 817                reg &= ~FIX_M_VID;
 818                writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
 819
 820                writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_0);
 821                writel(0x80, dp->reg_base + ANALOGIX_DP_N_VID_1);
 822                writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_2);
 823        }
 824}
 825
 826void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type)
 827{
 828        u32 reg;
 829
 830        if (type == VIDEO_TIMING_FROM_CAPTURE) {
 831                reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 832                reg &= ~FORMAT_SEL;
 833                writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 834        } else {
 835                reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 836                reg |= FORMAT_SEL;
 837                writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 838        }
 839}
 840
 841void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enable)
 842{
 843        u32 reg;
 844
 845        if (enable) {
 846                reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
 847                reg &= ~VIDEO_MODE_MASK;
 848                reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
 849                writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
 850        } else {
 851                reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
 852                reg &= ~VIDEO_MODE_MASK;
 853                reg |= VIDEO_MODE_SLAVE_MODE;
 854                writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
 855        }
 856}
 857
 858void analogix_dp_start_video(struct analogix_dp_device *dp)
 859{
 860        u32 reg;
 861
 862        reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
 863        reg |= VIDEO_EN;
 864        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
 865}
 866
 867int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp)
 868{
 869        u32 reg;
 870
 871        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 872        writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 873
 874        reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 875        if (!(reg & STRM_VALID)) {
 876                dev_dbg(dp->dev, "Input video stream is not detected.\n");
 877                return -EINVAL;
 878        }
 879
 880        return 0;
 881}
 882
 883void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
 884{
 885        u32 reg;
 886
 887        reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
 888        if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
 889                reg &= ~(RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N);
 890        } else {
 891                reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
 892                reg |= MASTER_VID_FUNC_EN_N;
 893        }
 894        writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
 895
 896        reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 897        reg &= ~INTERACE_SCAN_CFG;
 898        reg |= (dp->video_info.interlaced << 2);
 899        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 900
 901        reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 902        reg &= ~VSYNC_POLARITY_CFG;
 903        reg |= (dp->video_info.v_sync_polarity << 1);
 904        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 905
 906        reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 907        reg &= ~HSYNC_POLARITY_CFG;
 908        reg |= (dp->video_info.h_sync_polarity << 0);
 909        writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 910
 911        reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
 912        writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
 913}
 914
 915void analogix_dp_enable_scrambling(struct analogix_dp_device *dp)
 916{
 917        u32 reg;
 918
 919        reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 920        reg &= ~SCRAMBLING_DISABLE;
 921        writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 922}
 923
 924void analogix_dp_disable_scrambling(struct analogix_dp_device *dp)
 925{
 926        u32 reg;
 927
 928        reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 929        reg |= SCRAMBLING_DISABLE;
 930        writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
 931}
 932
 933void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp)
 934{
 935        writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
 936}
 937
 938static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
 939{
 940        ssize_t val;
 941        u8 status;
 942
 943        val = drm_dp_dpcd_readb(&dp->aux, DP_PSR_STATUS, &status);
 944        if (val < 0) {
 945                dev_err(dp->dev, "PSR_STATUS read failed ret=%zd", val);
 946                return val;
 947        }
 948        return status;
 949}
 950
 951int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
 952                             struct dp_sdp *vsc, bool blocking)
 953{
 954        unsigned int val;
 955        int ret;
 956        ssize_t psr_status;
 957
 958        /* don't send info frame */
 959        val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
 960        val &= ~IF_EN;
 961        writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
 962
 963        /* configure single frame update mode */
 964        writel(PSR_FRAME_UP_TYPE_BURST | PSR_CRC_SEL_HARDWARE,
 965               dp->reg_base + ANALOGIX_DP_PSR_FRAME_UPDATE_CTRL);
 966
 967        /* configure VSC HB0~HB3 */
 968        writel(vsc->sdp_header.HB0, dp->reg_base + ANALOGIX_DP_SPD_HB0);
 969        writel(vsc->sdp_header.HB1, dp->reg_base + ANALOGIX_DP_SPD_HB1);
 970        writel(vsc->sdp_header.HB2, dp->reg_base + ANALOGIX_DP_SPD_HB2);
 971        writel(vsc->sdp_header.HB3, dp->reg_base + ANALOGIX_DP_SPD_HB3);
 972
 973        /* configure reused VSC PB0~PB3, magic number from vendor */
 974        writel(0x00, dp->reg_base + ANALOGIX_DP_SPD_PB0);
 975        writel(0x16, dp->reg_base + ANALOGIX_DP_SPD_PB1);
 976        writel(0xCE, dp->reg_base + ANALOGIX_DP_SPD_PB2);
 977        writel(0x5D, dp->reg_base + ANALOGIX_DP_SPD_PB3);
 978
 979        /* configure DB0 / DB1 values */
 980        writel(vsc->db[0], dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB0);
 981        writel(vsc->db[1], dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB1);
 982
 983        /* set reuse spd inforframe */
 984        val = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
 985        val |= REUSE_SPD_EN;
 986        writel(val, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
 987
 988        /* mark info frame update */
 989        val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
 990        val = (val | IF_UP) & ~IF_EN;
 991        writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
 992
 993        /* send info frame */
 994        val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
 995        val |= IF_EN;
 996        writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
 997
 998        if (!blocking)
 999                return 0;
1000
1001        ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
1002                psr_status >= 0 &&
1003                ((vsc->db[1] && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
1004                (!vsc->db[1] && psr_status == DP_PSR_SINK_INACTIVE)), 1500,
1005                DP_TIMEOUT_PSR_LOOP_MS * 1000);
1006        if (ret) {
1007                dev_warn(dp->dev, "Failed to apply PSR %d\n", ret);
1008                return ret;
1009        }
1010        return 0;
1011}
1012
1013ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
1014                             struct drm_dp_aux_msg *msg)
1015{
1016        u32 reg;
1017        u32 status_reg;
1018        u8 *buffer = msg->buffer;
1019        unsigned int i;
1020        int num_transferred = 0;
1021        int ret;
1022
1023        /* Buffer size of AUX CH is 16 bytes */
1024        if (WARN_ON(msg->size > 16))
1025                return -E2BIG;
1026
1027        /* Clear AUX CH data buffer */
1028        reg = BUF_CLR;
1029        writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
1030
1031        switch (msg->request & ~DP_AUX_I2C_MOT) {
1032        case DP_AUX_I2C_WRITE:
1033                reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_I2C_TRANSACTION;
1034                if (msg->request & DP_AUX_I2C_MOT)
1035                        reg |= AUX_TX_COMM_MOT;
1036                break;
1037
1038        case DP_AUX_I2C_READ:
1039                reg = AUX_TX_COMM_READ | AUX_TX_COMM_I2C_TRANSACTION;
1040                if (msg->request & DP_AUX_I2C_MOT)
1041                        reg |= AUX_TX_COMM_MOT;
1042                break;
1043
1044        case DP_AUX_NATIVE_WRITE:
1045                reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_DP_TRANSACTION;
1046                break;
1047
1048        case DP_AUX_NATIVE_READ:
1049                reg = AUX_TX_COMM_READ | AUX_TX_COMM_DP_TRANSACTION;
1050                break;
1051
1052        default:
1053                return -EINVAL;
1054        }
1055
1056        reg |= AUX_LENGTH(msg->size);
1057        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
1058
1059        /* Select DPCD device address */
1060        reg = AUX_ADDR_7_0(msg->address);
1061        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
1062        reg = AUX_ADDR_15_8(msg->address);
1063        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
1064        reg = AUX_ADDR_19_16(msg->address);
1065        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
1066
1067        if (!(msg->request & DP_AUX_I2C_READ)) {
1068                for (i = 0; i < msg->size; i++) {
1069                        reg = buffer[i];
1070                        writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
1071                               4 * i);
1072                        num_transferred++;
1073                }
1074        }
1075
1076        /* Enable AUX CH operation */
1077        reg = AUX_EN;
1078
1079        /* Zero-sized messages specify address-only transactions. */
1080        if (msg->size < 1)
1081                reg |= ADDR_ONLY;
1082
1083        writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
1084
1085        ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2,
1086                                 reg, !(reg & AUX_EN), 25, 500 * 1000);
1087        if (ret) {
1088                dev_err(dp->dev, "AUX CH enable timeout!\n");
1089                goto aux_error;
1090        }
1091
1092        /* TODO: Wait for an interrupt instead of looping? */
1093        /* Is AUX CH command reply received? */
1094        ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_INT_STA,
1095                                 reg, reg & RPLY_RECEIV, 10, 20 * 1000);
1096        if (ret) {
1097                dev_err(dp->dev, "AUX CH cmd reply timeout!\n");
1098                goto aux_error;
1099        }
1100
1101        /* Clear interrupt source for AUX CH command reply */
1102        writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
1103
1104        /* Clear interrupt source for AUX CH access error */
1105        reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
1106        status_reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
1107        if ((reg & AUX_ERR) || (status_reg & AUX_STATUS_MASK)) {
1108                writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
1109
1110                dev_warn(dp->dev, "AUX CH error happened: %#x (%d)\n",
1111                         status_reg & AUX_STATUS_MASK, !!(reg & AUX_ERR));
1112                goto aux_error;
1113        }
1114
1115        if (msg->request & DP_AUX_I2C_READ) {
1116                for (i = 0; i < msg->size; i++) {
1117                        reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
1118                                    4 * i);
1119                        buffer[i] = (unsigned char)reg;
1120                        num_transferred++;
1121                }
1122        }
1123
1124        /* Check if Rx sends defer */
1125        reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM);
1126        if (reg == AUX_RX_COMM_AUX_DEFER)
1127                msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
1128        else if (reg == AUX_RX_COMM_I2C_DEFER)
1129                msg->reply = DP_AUX_I2C_REPLY_DEFER;
1130        else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE ||
1131                 (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_READ)
1132                msg->reply = DP_AUX_I2C_REPLY_ACK;
1133        else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_WRITE ||
1134                 (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
1135                msg->reply = DP_AUX_NATIVE_REPLY_ACK;
1136
1137        return num_transferred > 0 ? num_transferred : -EBUSY;
1138
1139aux_error:
1140        /* if aux err happen, reset aux */
1141        analogix_dp_init_aux(dp);
1142
1143        return -EREMOTEIO;
1144}
1145