linux/drivers/gpu/drm/rockchip/cdn-dp-reg.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
   4 * Author: Chris Zhong <zyw@rock-chips.com>
   5 */
   6
   7#include <linux/clk.h>
   8#include <linux/device.h>
   9#include <linux/delay.h>
  10#include <linux/io.h>
  11#include <linux/iopoll.h>
  12#include <linux/reset.h>
  13
  14#include "cdn-dp-core.h"
  15#include "cdn-dp-reg.h"
  16
  17#define CDN_DP_SPDIF_CLK                200000000
  18#define FW_ALIVE_TIMEOUT_US             1000000
  19#define MAILBOX_RETRY_US                1000
  20#define MAILBOX_TIMEOUT_US              5000000
  21#define LINK_TRAINING_RETRY_MS          20
  22#define LINK_TRAINING_TIMEOUT_MS        500
  23
  24void cdn_dp_set_fw_clk(struct cdn_dp_device *dp, unsigned long clk)
  25{
  26        writel(clk / 1000000, dp->regs + SW_CLK_H);
  27}
  28
  29void cdn_dp_clock_reset(struct cdn_dp_device *dp)
  30{
  31        u32 val;
  32
  33        val = DPTX_FRMR_DATA_CLK_RSTN_EN |
  34              DPTX_FRMR_DATA_CLK_EN |
  35              DPTX_PHY_DATA_RSTN_EN |
  36              DPTX_PHY_DATA_CLK_EN |
  37              DPTX_PHY_CHAR_RSTN_EN |
  38              DPTX_PHY_CHAR_CLK_EN |
  39              SOURCE_AUX_SYS_CLK_RSTN_EN |
  40              SOURCE_AUX_SYS_CLK_EN |
  41              DPTX_SYS_CLK_RSTN_EN |
  42              DPTX_SYS_CLK_EN |
  43              CFG_DPTX_VIF_CLK_RSTN_EN |
  44              CFG_DPTX_VIF_CLK_EN;
  45        writel(val, dp->regs + SOURCE_DPTX_CAR);
  46
  47        val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN;
  48        writel(val, dp->regs + SOURCE_PHY_CAR);
  49
  50        val = SOURCE_PKT_SYS_RSTN_EN |
  51              SOURCE_PKT_SYS_CLK_EN |
  52              SOURCE_PKT_DATA_RSTN_EN |
  53              SOURCE_PKT_DATA_CLK_EN;
  54        writel(val, dp->regs + SOURCE_PKT_CAR);
  55
  56        val = SPDIF_CDR_CLK_RSTN_EN |
  57              SPDIF_CDR_CLK_EN |
  58              SOURCE_AIF_SYS_RSTN_EN |
  59              SOURCE_AIF_SYS_CLK_EN |
  60              SOURCE_AIF_CLK_RSTN_EN |
  61              SOURCE_AIF_CLK_EN;
  62        writel(val, dp->regs + SOURCE_AIF_CAR);
  63
  64        val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN |
  65              SOURCE_CIPHER_SYS_CLK_EN |
  66              SOURCE_CIPHER_CHAR_CLK_RSTN_EN |
  67              SOURCE_CIPHER_CHAR_CLK_EN;
  68        writel(val, dp->regs + SOURCE_CIPHER_CAR);
  69
  70        val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN |
  71              SOURCE_CRYPTO_SYS_CLK_EN;
  72        writel(val, dp->regs + SOURCE_CRYPTO_CAR);
  73
  74        /* enable Mailbox and PIF interrupt */
  75        writel(0, dp->regs + APB_INT_MASK);
  76}
  77
  78static int cdn_dp_mailbox_read(struct cdn_dp_device *dp)
  79{
  80        int val, ret;
  81
  82        ret = readx_poll_timeout(readl, dp->regs + MAILBOX_EMPTY_ADDR,
  83                                 val, !val, MAILBOX_RETRY_US,
  84                                 MAILBOX_TIMEOUT_US);
  85        if (ret < 0)
  86                return ret;
  87
  88        return readl(dp->regs + MAILBOX0_RD_DATA) & 0xff;
  89}
  90
  91static int cdp_dp_mailbox_write(struct cdn_dp_device *dp, u8 val)
  92{
  93        int ret, full;
  94
  95        ret = readx_poll_timeout(readl, dp->regs + MAILBOX_FULL_ADDR,
  96                                 full, !full, MAILBOX_RETRY_US,
  97                                 MAILBOX_TIMEOUT_US);
  98        if (ret < 0)
  99                return ret;
 100
 101        writel(val, dp->regs + MAILBOX0_WR_DATA);
 102
 103        return 0;
 104}
 105
 106static int cdn_dp_mailbox_validate_receive(struct cdn_dp_device *dp,
 107                                           u8 module_id, u8 opcode,
 108                                           u16 req_size)
 109{
 110        u32 mbox_size, i;
 111        u8 header[4];
 112        int ret;
 113
 114        /* read the header of the message */
 115        for (i = 0; i < 4; i++) {
 116                ret = cdn_dp_mailbox_read(dp);
 117                if (ret < 0)
 118                        return ret;
 119
 120                header[i] = ret;
 121        }
 122
 123        mbox_size = (header[2] << 8) | header[3];
 124
 125        if (opcode != header[0] || module_id != header[1] ||
 126            req_size != mbox_size) {
 127                /*
 128                 * If the message in mailbox is not what we want, we need to
 129                 * clear the mailbox by reading its contents.
 130                 */
 131                for (i = 0; i < mbox_size; i++)
 132                        if (cdn_dp_mailbox_read(dp) < 0)
 133                                break;
 134
 135                return -EINVAL;
 136        }
 137
 138        return 0;
 139}
 140
 141static int cdn_dp_mailbox_read_receive(struct cdn_dp_device *dp,
 142                                       u8 *buff, u16 buff_size)
 143{
 144        u32 i;
 145        int ret;
 146
 147        for (i = 0; i < buff_size; i++) {
 148                ret = cdn_dp_mailbox_read(dp);
 149                if (ret < 0)
 150                        return ret;
 151
 152                buff[i] = ret;
 153        }
 154
 155        return 0;
 156}
 157
 158static int cdn_dp_mailbox_send(struct cdn_dp_device *dp, u8 module_id,
 159                               u8 opcode, u16 size, u8 *message)
 160{
 161        u8 header[4];
 162        int ret, i;
 163
 164        header[0] = opcode;
 165        header[1] = module_id;
 166        header[2] = (size >> 8) & 0xff;
 167        header[3] = size & 0xff;
 168
 169        for (i = 0; i < 4; i++) {
 170                ret = cdp_dp_mailbox_write(dp, header[i]);
 171                if (ret)
 172                        return ret;
 173        }
 174
 175        for (i = 0; i < size; i++) {
 176                ret = cdp_dp_mailbox_write(dp, message[i]);
 177                if (ret)
 178                        return ret;
 179        }
 180
 181        return 0;
 182}
 183
 184static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
 185{
 186        u8 msg[6];
 187
 188        msg[0] = (addr >> 8) & 0xff;
 189        msg[1] = addr & 0xff;
 190        msg[2] = (val >> 24) & 0xff;
 191        msg[3] = (val >> 16) & 0xff;
 192        msg[4] = (val >> 8) & 0xff;
 193        msg[5] = val & 0xff;
 194        return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_REGISTER,
 195                                   sizeof(msg), msg);
 196}
 197
 198static int cdn_dp_reg_write_bit(struct cdn_dp_device *dp, u16 addr,
 199                                u8 start_bit, u8 bits_no, u32 val)
 200{
 201        u8 field[8];
 202
 203        field[0] = (addr >> 8) & 0xff;
 204        field[1] = addr & 0xff;
 205        field[2] = start_bit;
 206        field[3] = bits_no;
 207        field[4] = (val >> 24) & 0xff;
 208        field[5] = (val >> 16) & 0xff;
 209        field[6] = (val >> 8) & 0xff;
 210        field[7] = val & 0xff;
 211
 212        return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_FIELD,
 213                                   sizeof(field), field);
 214}
 215
 216int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
 217{
 218        u8 msg[5], reg[5];
 219        int ret;
 220
 221        msg[0] = (len >> 8) & 0xff;
 222        msg[1] = len & 0xff;
 223        msg[2] = (addr >> 16) & 0xff;
 224        msg[3] = (addr >> 8) & 0xff;
 225        msg[4] = addr & 0xff;
 226        ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_DPCD,
 227                                  sizeof(msg), msg);
 228        if (ret)
 229                goto err_dpcd_read;
 230
 231        ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
 232                                              DPTX_READ_DPCD,
 233                                              sizeof(reg) + len);
 234        if (ret)
 235                goto err_dpcd_read;
 236
 237        ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
 238        if (ret)
 239                goto err_dpcd_read;
 240
 241        ret = cdn_dp_mailbox_read_receive(dp, data, len);
 242
 243err_dpcd_read:
 244        return ret;
 245}
 246
 247int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
 248{
 249        u8 msg[6], reg[5];
 250        int ret;
 251
 252        msg[0] = 0;
 253        msg[1] = 1;
 254        msg[2] = (addr >> 16) & 0xff;
 255        msg[3] = (addr >> 8) & 0xff;
 256        msg[4] = addr & 0xff;
 257        msg[5] = value;
 258        ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_DPCD,
 259                                  sizeof(msg), msg);
 260        if (ret)
 261                goto err_dpcd_write;
 262
 263        ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
 264                                              DPTX_WRITE_DPCD, sizeof(reg));
 265        if (ret)
 266                goto err_dpcd_write;
 267
 268        ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
 269        if (ret)
 270                goto err_dpcd_write;
 271
 272        if (addr != (reg[2] << 16 | reg[3] << 8 | reg[4]))
 273                ret = -EINVAL;
 274
 275err_dpcd_write:
 276        if (ret)
 277                DRM_DEV_ERROR(dp->dev, "dpcd write failed: %d\n", ret);
 278        return ret;
 279}
 280
 281int cdn_dp_load_firmware(struct cdn_dp_device *dp, const u32 *i_mem,
 282                         u32 i_size, const u32 *d_mem, u32 d_size)
 283{
 284        u32 reg;
 285        int i, ret;
 286
 287        /* reset ucpu before load firmware*/
 288        writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET,
 289               dp->regs + APB_CTRL);
 290
 291        for (i = 0; i < i_size; i += 4)
 292                writel(*i_mem++, dp->regs + ADDR_IMEM + i);
 293
 294        for (i = 0; i < d_size; i += 4)
 295                writel(*d_mem++, dp->regs + ADDR_DMEM + i);
 296
 297        /* un-reset ucpu */
 298        writel(0, dp->regs + APB_CTRL);
 299
 300        /* check the keep alive register to make sure fw working */
 301        ret = readx_poll_timeout(readl, dp->regs + KEEP_ALIVE,
 302                                 reg, reg, 2000, FW_ALIVE_TIMEOUT_US);
 303        if (ret < 0) {
 304                DRM_DEV_ERROR(dp->dev, "failed to loaded the FW reg = %x\n",
 305                              reg);
 306                return -EINVAL;
 307        }
 308
 309        reg = readl(dp->regs + VER_L) & 0xff;
 310        dp->fw_version = reg;
 311        reg = readl(dp->regs + VER_H) & 0xff;
 312        dp->fw_version |= reg << 8;
 313        reg = readl(dp->regs + VER_LIB_L_ADDR) & 0xff;
 314        dp->fw_version |= reg << 16;
 315        reg = readl(dp->regs + VER_LIB_H_ADDR) & 0xff;
 316        dp->fw_version |= reg << 24;
 317
 318        DRM_DEV_DEBUG(dp->dev, "firmware version: %x\n", dp->fw_version);
 319
 320        return 0;
 321}
 322
 323int cdn_dp_set_firmware_active(struct cdn_dp_device *dp, bool enable)
 324{
 325        u8 msg[5];
 326        int ret, i;
 327
 328        msg[0] = GENERAL_MAIN_CONTROL;
 329        msg[1] = MB_MODULE_ID_GENERAL;
 330        msg[2] = 0;
 331        msg[3] = 1;
 332        msg[4] = enable ? FW_ACTIVE : FW_STANDBY;
 333
 334        for (i = 0; i < sizeof(msg); i++) {
 335                ret = cdp_dp_mailbox_write(dp, msg[i]);
 336                if (ret)
 337                        goto err_set_firmware_active;
 338        }
 339
 340        /* read the firmware state */
 341        for (i = 0; i < sizeof(msg); i++)  {
 342                ret = cdn_dp_mailbox_read(dp);
 343                if (ret < 0)
 344                        goto err_set_firmware_active;
 345
 346                msg[i] = ret;
 347        }
 348
 349        ret = 0;
 350
 351err_set_firmware_active:
 352        if (ret < 0)
 353                DRM_DEV_ERROR(dp->dev, "set firmware active failed\n");
 354        return ret;
 355}
 356
 357int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip)
 358{
 359        u8 msg[8];
 360        int ret;
 361
 362        msg[0] = CDN_DP_MAX_LINK_RATE;
 363        msg[1] = lanes | SCRAMBLER_EN;
 364        msg[2] = VOLTAGE_LEVEL_2;
 365        msg[3] = PRE_EMPHASIS_LEVEL_3;
 366        msg[4] = PTS1 | PTS2 | PTS3 | PTS4;
 367        msg[5] = FAST_LT_NOT_SUPPORT;
 368        msg[6] = flip ? LANE_MAPPING_FLIPPED : LANE_MAPPING_NORMAL;
 369        msg[7] = ENHANCED;
 370
 371        ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
 372                                  DPTX_SET_HOST_CAPABILITIES,
 373                                  sizeof(msg), msg);
 374        if (ret)
 375                goto err_set_host_cap;
 376
 377        ret = cdn_dp_reg_write(dp, DP_AUX_SWAP_INVERSION_CONTROL,
 378                               AUX_HOST_INVERT);
 379
 380err_set_host_cap:
 381        if (ret)
 382                DRM_DEV_ERROR(dp->dev, "set host cap failed: %d\n", ret);
 383        return ret;
 384}
 385
 386int cdn_dp_event_config(struct cdn_dp_device *dp)
 387{
 388        u8 msg[5];
 389        int ret;
 390
 391        memset(msg, 0, sizeof(msg));
 392
 393        msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING;
 394
 395        ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_ENABLE_EVENT,
 396                                  sizeof(msg), msg);
 397        if (ret)
 398                DRM_DEV_ERROR(dp->dev, "set event config failed: %d\n", ret);
 399
 400        return ret;
 401}
 402
 403u32 cdn_dp_get_event(struct cdn_dp_device *dp)
 404{
 405        return readl(dp->regs + SW_EVENTS0);
 406}
 407
 408int cdn_dp_get_hpd_status(struct cdn_dp_device *dp)
 409{
 410        u8 status;
 411        int ret;
 412
 413        ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_HPD_STATE,
 414                                  0, NULL);
 415        if (ret)
 416                goto err_get_hpd;
 417
 418        ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
 419                                              DPTX_HPD_STATE, sizeof(status));
 420        if (ret)
 421                goto err_get_hpd;
 422
 423        ret = cdn_dp_mailbox_read_receive(dp, &status, sizeof(status));
 424        if (ret)
 425                goto err_get_hpd;
 426
 427        return status;
 428
 429err_get_hpd:
 430        DRM_DEV_ERROR(dp->dev, "get hpd status failed: %d\n", ret);
 431        return ret;
 432}
 433
 434int cdn_dp_get_edid_block(void *data, u8 *edid,
 435                          unsigned int block, size_t length)
 436{
 437        struct cdn_dp_device *dp = data;
 438        u8 msg[2], reg[2], i;
 439        int ret;
 440
 441        for (i = 0; i < 4; i++) {
 442                msg[0] = block / 2;
 443                msg[1] = block % 2;
 444
 445                ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_GET_EDID,
 446                                          sizeof(msg), msg);
 447                if (ret)
 448                        continue;
 449
 450                ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
 451                                                      DPTX_GET_EDID,
 452                                                      sizeof(reg) + length);
 453                if (ret)
 454                        continue;
 455
 456                ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
 457                if (ret)
 458                        continue;
 459
 460                ret = cdn_dp_mailbox_read_receive(dp, edid, length);
 461                if (ret)
 462                        continue;
 463
 464                if (reg[0] == length && reg[1] == block / 2)
 465                        break;
 466        }
 467
 468        if (ret)
 469                DRM_DEV_ERROR(dp->dev, "get block[%d] edid failed: %d\n", block,
 470                              ret);
 471
 472        return ret;
 473}
 474
 475static int cdn_dp_training_start(struct cdn_dp_device *dp)
 476{
 477        unsigned long timeout;
 478        u8 msg, event[2];
 479        int ret;
 480
 481        msg = LINK_TRAINING_RUN;
 482
 483        /* start training */
 484        ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_TRAINING_CONTROL,
 485                                  sizeof(msg), &msg);
 486        if (ret)
 487                goto err_training_start;
 488
 489        timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS);
 490        while (time_before(jiffies, timeout)) {
 491                msleep(LINK_TRAINING_RETRY_MS);
 492                ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
 493                                          DPTX_READ_EVENT, 0, NULL);
 494                if (ret)
 495                        goto err_training_start;
 496
 497                ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
 498                                                      DPTX_READ_EVENT,
 499                                                      sizeof(event));
 500                if (ret)
 501                        goto err_training_start;
 502
 503                ret = cdn_dp_mailbox_read_receive(dp, event, sizeof(event));
 504                if (ret)
 505                        goto err_training_start;
 506
 507                if (event[1] & EQ_PHASE_FINISHED)
 508                        return 0;
 509        }
 510
 511        ret = -ETIMEDOUT;
 512
 513err_training_start:
 514        DRM_DEV_ERROR(dp->dev, "training failed: %d\n", ret);
 515        return ret;
 516}
 517
 518static int cdn_dp_get_training_status(struct cdn_dp_device *dp)
 519{
 520        u8 status[10];
 521        int ret;
 522
 523        ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_LINK_STAT,
 524                                  0, NULL);
 525        if (ret)
 526                goto err_get_training_status;
 527
 528        ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
 529                                              DPTX_READ_LINK_STAT,
 530                                              sizeof(status));
 531        if (ret)
 532                goto err_get_training_status;
 533
 534        ret = cdn_dp_mailbox_read_receive(dp, status, sizeof(status));
 535        if (ret)
 536                goto err_get_training_status;
 537
 538        dp->link.rate = drm_dp_bw_code_to_link_rate(status[0]);
 539        dp->link.num_lanes = status[1];
 540
 541err_get_training_status:
 542        if (ret)
 543                DRM_DEV_ERROR(dp->dev, "get training status failed: %d\n", ret);
 544        return ret;
 545}
 546
 547int cdn_dp_train_link(struct cdn_dp_device *dp)
 548{
 549        int ret;
 550
 551        ret = cdn_dp_training_start(dp);
 552        if (ret) {
 553                DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
 554                return ret;
 555        }
 556
 557        ret = cdn_dp_get_training_status(dp);
 558        if (ret) {
 559                DRM_DEV_ERROR(dp->dev, "Failed to get training stat %d\n", ret);
 560                return ret;
 561        }
 562
 563        DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->link.rate,
 564                          dp->link.num_lanes);
 565        return ret;
 566}
 567
 568int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
 569{
 570        u8 msg;
 571        int ret;
 572
 573        msg = !!active;
 574
 575        ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO,
 576                                  sizeof(msg), &msg);
 577        if (ret)
 578                DRM_DEV_ERROR(dp->dev, "set video status failed: %d\n", ret);
 579
 580        return ret;
 581}
 582
 583static int cdn_dp_get_msa_misc(struct video_info *video,
 584                               struct drm_display_mode *mode)
 585{
 586        u32 msa_misc;
 587        u8 val[2] = {0};
 588
 589        switch (video->color_fmt) {
 590        case PXL_RGB:
 591        case Y_ONLY:
 592                val[0] = 0;
 593                break;
 594        /* set YUV default color space conversion to BT601 */
 595        case YCBCR_4_4_4:
 596                val[0] = 6 + BT_601 * 8;
 597                break;
 598        case YCBCR_4_2_2:
 599                val[0] = 5 + BT_601 * 8;
 600                break;
 601        case YCBCR_4_2_0:
 602                val[0] = 5;
 603                break;
 604        };
 605
 606        switch (video->color_depth) {
 607        case 6:
 608                val[1] = 0;
 609                break;
 610        case 8:
 611                val[1] = 1;
 612                break;
 613        case 10:
 614                val[1] = 2;
 615                break;
 616        case 12:
 617                val[1] = 3;
 618                break;
 619        case 16:
 620                val[1] = 4;
 621                break;
 622        };
 623
 624        msa_misc = 2 * val[0] + 32 * val[1] +
 625                   ((video->color_fmt == Y_ONLY) ? (1 << 14) : 0);
 626
 627        return msa_misc;
 628}
 629
 630int cdn_dp_config_video(struct cdn_dp_device *dp)
 631{
 632        struct video_info *video = &dp->video_info;
 633        struct drm_display_mode *mode = &dp->mode;
 634        u64 symbol;
 635        u32 val, link_rate, rem;
 636        u8 bit_per_pix, tu_size_reg = TU_SIZE;
 637        int ret;
 638
 639        bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ?
 640                      (video->color_depth * 2) : (video->color_depth * 3);
 641
 642        link_rate = dp->link.rate / 1000;
 643
 644        ret = cdn_dp_reg_write(dp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE);
 645        if (ret)
 646                goto err_config_video;
 647
 648        ret = cdn_dp_reg_write(dp, HSYNC2VSYNC_POL_CTRL, 0);
 649        if (ret)
 650                goto err_config_video;
 651
 652        /*
 653         * get a best tu_size and valid symbol:
 654         * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32
 655         * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes)
 656         * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set
 657         *    TU += 2 and repeat 2nd step.
 658         */
 659        do {
 660                tu_size_reg += 2;
 661                symbol = tu_size_reg * mode->clock * bit_per_pix;
 662                do_div(symbol, dp->link.num_lanes * link_rate * 8);
 663                rem = do_div(symbol, 1000);
 664                if (tu_size_reg > 64) {
 665                        ret = -EINVAL;
 666                        DRM_DEV_ERROR(dp->dev,
 667                                      "tu error, clk:%d, lanes:%d, rate:%d\n",
 668                                      mode->clock, dp->link.num_lanes,
 669                                      link_rate);
 670                        goto err_config_video;
 671                }
 672        } while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
 673                 (rem > 850) || (rem < 100));
 674
 675        val = symbol + (tu_size_reg << 8);
 676        val |= TU_CNT_RST_EN;
 677        ret = cdn_dp_reg_write(dp, DP_FRAMER_TU, val);
 678        if (ret)
 679                goto err_config_video;
 680
 681        /* set the FIFO Buffer size */
 682        val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
 683        val /= (dp->link.num_lanes * link_rate);
 684        val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
 685        val += 2;
 686        ret = cdn_dp_reg_write(dp, DP_VC_TABLE(15), val);
 687
 688        switch (video->color_depth) {
 689        case 6:
 690                val = BCS_6;
 691                break;
 692        case 8:
 693                val = BCS_8;
 694                break;
 695        case 10:
 696                val = BCS_10;
 697                break;
 698        case 12:
 699                val = BCS_12;
 700                break;
 701        case 16:
 702                val = BCS_16;
 703                break;
 704        };
 705
 706        val += video->color_fmt << 8;
 707        ret = cdn_dp_reg_write(dp, DP_FRAMER_PXL_REPR, val);
 708        if (ret)
 709                goto err_config_video;
 710
 711        val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0;
 712        val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0;
 713        ret = cdn_dp_reg_write(dp, DP_FRAMER_SP, val);
 714        if (ret)
 715                goto err_config_video;
 716
 717        val = (mode->hsync_start - mode->hdisplay) << 16;
 718        val |= mode->htotal - mode->hsync_end;
 719        ret = cdn_dp_reg_write(dp, DP_FRONT_BACK_PORCH, val);
 720        if (ret)
 721                goto err_config_video;
 722
 723        val = mode->hdisplay * bit_per_pix / 8;
 724        ret = cdn_dp_reg_write(dp, DP_BYTE_COUNT, val);
 725        if (ret)
 726                goto err_config_video;
 727
 728        val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16);
 729        ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_0, val);
 730        if (ret)
 731                goto err_config_video;
 732
 733        val = mode->hsync_end - mode->hsync_start;
 734        val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15);
 735        ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_1, val);
 736        if (ret)
 737                goto err_config_video;
 738
 739        val = mode->vtotal;
 740        val |= (mode->vtotal - mode->vsync_start) << 16;
 741        ret = cdn_dp_reg_write(dp, MSA_VERTICAL_0, val);
 742        if (ret)
 743                goto err_config_video;
 744
 745        val = mode->vsync_end - mode->vsync_start;
 746        val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15);
 747        ret = cdn_dp_reg_write(dp, MSA_VERTICAL_1, val);
 748        if (ret)
 749                goto err_config_video;
 750
 751        val = cdn_dp_get_msa_misc(video, mode);
 752        ret = cdn_dp_reg_write(dp, MSA_MISC, val);
 753        if (ret)
 754                goto err_config_video;
 755
 756        ret = cdn_dp_reg_write(dp, STREAM_CONFIG, 1);
 757        if (ret)
 758                goto err_config_video;
 759
 760        val = mode->hsync_end - mode->hsync_start;
 761        val |= mode->hdisplay << 16;
 762        ret = cdn_dp_reg_write(dp, DP_HORIZONTAL, val);
 763        if (ret)
 764                goto err_config_video;
 765
 766        val = mode->vdisplay;
 767        val |= (mode->vtotal - mode->vsync_start) << 16;
 768        ret = cdn_dp_reg_write(dp, DP_VERTICAL_0, val);
 769        if (ret)
 770                goto err_config_video;
 771
 772        val = mode->vtotal;
 773        ret = cdn_dp_reg_write(dp, DP_VERTICAL_1, val);
 774        if (ret)
 775                goto err_config_video;
 776
 777        ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 2, 1, 0);
 778
 779err_config_video:
 780        if (ret)
 781                DRM_DEV_ERROR(dp->dev, "config video failed: %d\n", ret);
 782        return ret;
 783}
 784
 785int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio)
 786{
 787        int ret;
 788
 789        ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, 0);
 790        if (ret) {
 791                DRM_DEV_ERROR(dp->dev, "audio stop failed: %d\n", ret);
 792                return ret;
 793        }
 794
 795        writel(0, dp->regs + SPDIF_CTRL_ADDR);
 796
 797        /* clearn the audio config and reset */
 798        writel(0, dp->regs + AUDIO_SRC_CNTL);
 799        writel(0, dp->regs + AUDIO_SRC_CNFG);
 800        writel(AUDIO_SW_RST, dp->regs + AUDIO_SRC_CNTL);
 801        writel(0, dp->regs + AUDIO_SRC_CNTL);
 802
 803        /* reset smpl2pckt component  */
 804        writel(0, dp->regs + SMPL2PKT_CNTL);
 805        writel(AUDIO_SW_RST, dp->regs + SMPL2PKT_CNTL);
 806        writel(0, dp->regs + SMPL2PKT_CNTL);
 807
 808        /* reset FIFO */
 809        writel(AUDIO_SW_RST, dp->regs + FIFO_CNTL);
 810        writel(0, dp->regs + FIFO_CNTL);
 811
 812        if (audio->format == AFMT_SPDIF)
 813                clk_disable_unprepare(dp->spdif_clk);
 814
 815        return 0;
 816}
 817
 818int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable)
 819{
 820        int ret;
 821
 822        ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 4, 1, enable);
 823        if (ret)
 824                DRM_DEV_ERROR(dp->dev, "audio mute failed: %d\n", ret);
 825
 826        return ret;
 827}
 828
 829static void cdn_dp_audio_config_i2s(struct cdn_dp_device *dp,
 830                                    struct audio_info *audio)
 831{
 832        int sub_pckt_num = 1, i2s_port_en_val = 0xf, i;
 833        u32 val;
 834
 835        if (audio->channels == 2) {
 836                if (dp->link.num_lanes == 1)
 837                        sub_pckt_num = 2;
 838                else
 839                        sub_pckt_num = 4;
 840
 841                i2s_port_en_val = 1;
 842        } else if (audio->channels == 4) {
 843                i2s_port_en_val = 3;
 844        }
 845
 846        writel(0x0, dp->regs + SPDIF_CTRL_ADDR);
 847
 848        writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
 849
 850        val = MAX_NUM_CH(audio->channels);
 851        val |= NUM_OF_I2S_PORTS(audio->channels);
 852        val |= AUDIO_TYPE_LPCM;
 853        val |= CFG_SUB_PCKT_NUM(sub_pckt_num);
 854        writel(val, dp->regs + SMPL2PKT_CNFG);
 855
 856        if (audio->sample_width == 16)
 857                val = 0;
 858        else if (audio->sample_width == 24)
 859                val = 1 << 9;
 860        else
 861                val = 2 << 9;
 862
 863        val |= AUDIO_CH_NUM(audio->channels);
 864        val |= I2S_DEC_PORT_EN(i2s_port_en_val);
 865        val |= TRANS_SMPL_WIDTH_32;
 866        writel(val, dp->regs + AUDIO_SRC_CNFG);
 867
 868        for (i = 0; i < (audio->channels + 1) / 2; i++) {
 869                if (audio->sample_width == 16)
 870                        val = (0x02 << 8) | (0x02 << 20);
 871                else if (audio->sample_width == 24)
 872                        val = (0x0b << 8) | (0x0b << 20);
 873
 874                val |= ((2 * i) << 4) | ((2 * i + 1) << 16);
 875                writel(val, dp->regs + STTS_BIT_CH(i));
 876        }
 877
 878        switch (audio->sample_rate) {
 879        case 32000:
 880                val = SAMPLING_FREQ(3) |
 881                      ORIGINAL_SAMP_FREQ(0xc);
 882                break;
 883        case 44100:
 884                val = SAMPLING_FREQ(0) |
 885                      ORIGINAL_SAMP_FREQ(0xf);
 886                break;
 887        case 48000:
 888                val = SAMPLING_FREQ(2) |
 889                      ORIGINAL_SAMP_FREQ(0xd);
 890                break;
 891        case 88200:
 892                val = SAMPLING_FREQ(8) |
 893                      ORIGINAL_SAMP_FREQ(0x7);
 894                break;
 895        case 96000:
 896                val = SAMPLING_FREQ(0xa) |
 897                      ORIGINAL_SAMP_FREQ(5);
 898                break;
 899        case 176400:
 900                val = SAMPLING_FREQ(0xc) |
 901                      ORIGINAL_SAMP_FREQ(3);
 902                break;
 903        case 192000:
 904                val = SAMPLING_FREQ(0xe) |
 905                      ORIGINAL_SAMP_FREQ(1);
 906                break;
 907        }
 908        val |= 4;
 909        writel(val, dp->regs + COM_CH_STTS_BITS);
 910
 911        writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
 912        writel(I2S_DEC_START, dp->regs + AUDIO_SRC_CNTL);
 913}
 914
 915static void cdn_dp_audio_config_spdif(struct cdn_dp_device *dp)
 916{
 917        u32 val;
 918
 919        writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
 920
 921        val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4);
 922        writel(val, dp->regs + SMPL2PKT_CNFG);
 923        writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
 924
 925        val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
 926        writel(val, dp->regs + SPDIF_CTRL_ADDR);
 927
 928        clk_prepare_enable(dp->spdif_clk);
 929        clk_set_rate(dp->spdif_clk, CDN_DP_SPDIF_CLK);
 930}
 931
 932int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio)
 933{
 934        int ret;
 935
 936        /* reset the spdif clk before config */
 937        if (audio->format == AFMT_SPDIF) {
 938                reset_control_assert(dp->spdif_rst);
 939                reset_control_deassert(dp->spdif_rst);
 940        }
 941
 942        ret = cdn_dp_reg_write(dp, CM_LANE_CTRL, LANE_REF_CYC);
 943        if (ret)
 944                goto err_audio_config;
 945
 946        ret = cdn_dp_reg_write(dp, CM_CTRL, 0);
 947        if (ret)
 948                goto err_audio_config;
 949
 950        if (audio->format == AFMT_I2S)
 951                cdn_dp_audio_config_i2s(dp, audio);
 952        else if (audio->format == AFMT_SPDIF)
 953                cdn_dp_audio_config_spdif(dp);
 954
 955        ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN);
 956
 957err_audio_config:
 958        if (ret)
 959                DRM_DEV_ERROR(dp->dev, "audio config failed: %d\n", ret);
 960        return ret;
 961}
 962