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