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->max_rate = drm_dp_bw_code_to_link_rate(status[0]);
 539        dp->max_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->max_rate,
 564                          dp->max_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->max_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 = (u64)tu_size_reg * mode->clock * bit_per_pix;
 662                do_div(symbol, dp->max_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->max_lanes, link_rate);
 669                        goto err_config_video;
 670                }
 671        } while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
 672                 (rem > 850) || (rem < 100));
 673
 674        val = symbol + (tu_size_reg << 8);
 675        val |= TU_CNT_RST_EN;
 676        ret = cdn_dp_reg_write(dp, DP_FRAMER_TU, val);
 677        if (ret)
 678                goto err_config_video;
 679
 680        /* set the FIFO Buffer size */
 681        val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
 682        val /= (dp->max_lanes * link_rate);
 683        val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
 684        val += 2;
 685        ret = cdn_dp_reg_write(dp, DP_VC_TABLE(15), val);
 686
 687        switch (video->color_depth) {
 688        case 6:
 689                val = BCS_6;
 690                break;
 691        case 8:
 692                val = BCS_8;
 693                break;
 694        case 10:
 695                val = BCS_10;
 696                break;
 697        case 12:
 698                val = BCS_12;
 699                break;
 700        case 16:
 701                val = BCS_16;
 702                break;
 703        }
 704
 705        val += video->color_fmt << 8;
 706        ret = cdn_dp_reg_write(dp, DP_FRAMER_PXL_REPR, val);
 707        if (ret)
 708                goto err_config_video;
 709
 710        val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0;
 711        val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0;
 712        ret = cdn_dp_reg_write(dp, DP_FRAMER_SP, val);
 713        if (ret)
 714                goto err_config_video;
 715
 716        val = (mode->hsync_start - mode->hdisplay) << 16;
 717        val |= mode->htotal - mode->hsync_end;
 718        ret = cdn_dp_reg_write(dp, DP_FRONT_BACK_PORCH, val);
 719        if (ret)
 720                goto err_config_video;
 721
 722        val = mode->hdisplay * bit_per_pix / 8;
 723        ret = cdn_dp_reg_write(dp, DP_BYTE_COUNT, val);
 724        if (ret)
 725                goto err_config_video;
 726
 727        val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16);
 728        ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_0, val);
 729        if (ret)
 730                goto err_config_video;
 731
 732        val = mode->hsync_end - mode->hsync_start;
 733        val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15);
 734        ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_1, val);
 735        if (ret)
 736                goto err_config_video;
 737
 738        val = mode->vtotal;
 739        val |= (mode->vtotal - mode->vsync_start) << 16;
 740        ret = cdn_dp_reg_write(dp, MSA_VERTICAL_0, val);
 741        if (ret)
 742                goto err_config_video;
 743
 744        val = mode->vsync_end - mode->vsync_start;
 745        val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15);
 746        ret = cdn_dp_reg_write(dp, MSA_VERTICAL_1, val);
 747        if (ret)
 748                goto err_config_video;
 749
 750        val = cdn_dp_get_msa_misc(video, mode);
 751        ret = cdn_dp_reg_write(dp, MSA_MISC, val);
 752        if (ret)
 753                goto err_config_video;
 754
 755        ret = cdn_dp_reg_write(dp, STREAM_CONFIG, 1);
 756        if (ret)
 757                goto err_config_video;
 758
 759        val = mode->hsync_end - mode->hsync_start;
 760        val |= mode->hdisplay << 16;
 761        ret = cdn_dp_reg_write(dp, DP_HORIZONTAL, val);
 762        if (ret)
 763                goto err_config_video;
 764
 765        val = mode->vdisplay;
 766        val |= (mode->vtotal - mode->vsync_start) << 16;
 767        ret = cdn_dp_reg_write(dp, DP_VERTICAL_0, val);
 768        if (ret)
 769                goto err_config_video;
 770
 771        val = mode->vtotal;
 772        ret = cdn_dp_reg_write(dp, DP_VERTICAL_1, val);
 773        if (ret)
 774                goto err_config_video;
 775
 776        ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 2, 1, 0);
 777
 778err_config_video:
 779        if (ret)
 780                DRM_DEV_ERROR(dp->dev, "config video failed: %d\n", ret);
 781        return ret;
 782}
 783
 784int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio)
 785{
 786        int ret;
 787
 788        ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, 0);
 789        if (ret) {
 790                DRM_DEV_ERROR(dp->dev, "audio stop failed: %d\n", ret);
 791                return ret;
 792        }
 793
 794        writel(0, dp->regs + SPDIF_CTRL_ADDR);
 795
 796        /* clearn the audio config and reset */
 797        writel(0, dp->regs + AUDIO_SRC_CNTL);
 798        writel(0, dp->regs + AUDIO_SRC_CNFG);
 799        writel(AUDIO_SW_RST, dp->regs + AUDIO_SRC_CNTL);
 800        writel(0, dp->regs + AUDIO_SRC_CNTL);
 801
 802        /* reset smpl2pckt component  */
 803        writel(0, dp->regs + SMPL2PKT_CNTL);
 804        writel(AUDIO_SW_RST, dp->regs + SMPL2PKT_CNTL);
 805        writel(0, dp->regs + SMPL2PKT_CNTL);
 806
 807        /* reset FIFO */
 808        writel(AUDIO_SW_RST, dp->regs + FIFO_CNTL);
 809        writel(0, dp->regs + FIFO_CNTL);
 810
 811        if (audio->format == AFMT_SPDIF)
 812                clk_disable_unprepare(dp->spdif_clk);
 813
 814        return 0;
 815}
 816
 817int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable)
 818{
 819        int ret;
 820
 821        ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 4, 1, enable);
 822        if (ret)
 823                DRM_DEV_ERROR(dp->dev, "audio mute failed: %d\n", ret);
 824
 825        return ret;
 826}
 827
 828static void cdn_dp_audio_config_i2s(struct cdn_dp_device *dp,
 829                                    struct audio_info *audio)
 830{
 831        int sub_pckt_num = 1, i2s_port_en_val = 0xf, i;
 832        u32 val;
 833
 834        if (audio->channels == 2) {
 835                if (dp->max_lanes == 1)
 836                        sub_pckt_num = 2;
 837                else
 838                        sub_pckt_num = 4;
 839
 840                i2s_port_en_val = 1;
 841        } else if (audio->channels == 4) {
 842                i2s_port_en_val = 3;
 843        }
 844
 845        writel(0x0, dp->regs + SPDIF_CTRL_ADDR);
 846
 847        writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
 848
 849        val = MAX_NUM_CH(audio->channels);
 850        val |= NUM_OF_I2S_PORTS(audio->channels);
 851        val |= AUDIO_TYPE_LPCM;
 852        val |= CFG_SUB_PCKT_NUM(sub_pckt_num);
 853        writel(val, dp->regs + SMPL2PKT_CNFG);
 854
 855        if (audio->sample_width == 16)
 856                val = 0;
 857        else if (audio->sample_width == 24)
 858                val = 1 << 9;
 859        else
 860                val = 2 << 9;
 861
 862        val |= AUDIO_CH_NUM(audio->channels);
 863        val |= I2S_DEC_PORT_EN(i2s_port_en_val);
 864        val |= TRANS_SMPL_WIDTH_32;
 865        writel(val, dp->regs + AUDIO_SRC_CNFG);
 866
 867        for (i = 0; i < (audio->channels + 1) / 2; i++) {
 868                if (audio->sample_width == 16)
 869                        val = (0x02 << 8) | (0x02 << 20);
 870                else if (audio->sample_width == 24)
 871                        val = (0x0b << 8) | (0x0b << 20);
 872
 873                val |= ((2 * i) << 4) | ((2 * i + 1) << 16);
 874                writel(val, dp->regs + STTS_BIT_CH(i));
 875        }
 876
 877        switch (audio->sample_rate) {
 878        case 32000:
 879                val = SAMPLING_FREQ(3) |
 880                      ORIGINAL_SAMP_FREQ(0xc);
 881                break;
 882        case 44100:
 883                val = SAMPLING_FREQ(0) |
 884                      ORIGINAL_SAMP_FREQ(0xf);
 885                break;
 886        case 48000:
 887                val = SAMPLING_FREQ(2) |
 888                      ORIGINAL_SAMP_FREQ(0xd);
 889                break;
 890        case 88200:
 891                val = SAMPLING_FREQ(8) |
 892                      ORIGINAL_SAMP_FREQ(0x7);
 893                break;
 894        case 96000:
 895                val = SAMPLING_FREQ(0xa) |
 896                      ORIGINAL_SAMP_FREQ(5);
 897                break;
 898        case 176400:
 899                val = SAMPLING_FREQ(0xc) |
 900                      ORIGINAL_SAMP_FREQ(3);
 901                break;
 902        case 192000:
 903                val = SAMPLING_FREQ(0xe) |
 904                      ORIGINAL_SAMP_FREQ(1);
 905                break;
 906        }
 907        val |= 4;
 908        writel(val, dp->regs + COM_CH_STTS_BITS);
 909
 910        writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
 911        writel(I2S_DEC_START, dp->regs + AUDIO_SRC_CNTL);
 912}
 913
 914static void cdn_dp_audio_config_spdif(struct cdn_dp_device *dp)
 915{
 916        u32 val;
 917
 918        writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
 919
 920        val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4);
 921        writel(val, dp->regs + SMPL2PKT_CNFG);
 922        writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
 923
 924        val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
 925        writel(val, dp->regs + SPDIF_CTRL_ADDR);
 926
 927        clk_prepare_enable(dp->spdif_clk);
 928        clk_set_rate(dp->spdif_clk, CDN_DP_SPDIF_CLK);
 929}
 930
 931int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio)
 932{
 933        int ret;
 934
 935        /* reset the spdif clk before config */
 936        if (audio->format == AFMT_SPDIF) {
 937                reset_control_assert(dp->spdif_rst);
 938                reset_control_deassert(dp->spdif_rst);
 939        }
 940
 941        ret = cdn_dp_reg_write(dp, CM_LANE_CTRL, LANE_REF_CYC);
 942        if (ret)
 943                goto err_audio_config;
 944
 945        ret = cdn_dp_reg_write(dp, CM_CTRL, 0);
 946        if (ret)
 947                goto err_audio_config;
 948
 949        if (audio->format == AFMT_I2S)
 950                cdn_dp_audio_config_i2s(dp, audio);
 951        else if (audio->format == AFMT_SPDIF)
 952                cdn_dp_audio_config_spdif(dp);
 953
 954        ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN);
 955
 956err_audio_config:
 957        if (ret)
 958                DRM_DEV_ERROR(dp->dev, "audio config failed: %d\n", ret);
 959        return ret;
 960}
 961