root/drivers/gpu/drm/rockchip/cdn-dp-reg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cdn_dp_set_fw_clk
  2. cdn_dp_clock_reset
  3. cdn_dp_mailbox_read
  4. cdp_dp_mailbox_write
  5. cdn_dp_mailbox_validate_receive
  6. cdn_dp_mailbox_read_receive
  7. cdn_dp_mailbox_send
  8. cdn_dp_reg_write
  9. cdn_dp_reg_write_bit
  10. cdn_dp_dpcd_read
  11. cdn_dp_dpcd_write
  12. cdn_dp_load_firmware
  13. cdn_dp_set_firmware_active
  14. cdn_dp_set_host_cap
  15. cdn_dp_event_config
  16. cdn_dp_get_event
  17. cdn_dp_get_hpd_status
  18. cdn_dp_get_edid_block
  19. cdn_dp_training_start
  20. cdn_dp_get_training_status
  21. cdn_dp_train_link
  22. cdn_dp_set_video_status
  23. cdn_dp_get_msa_misc
  24. cdn_dp_config_video
  25. cdn_dp_audio_stop
  26. cdn_dp_audio_mute
  27. cdn_dp_audio_config_i2s
  28. cdn_dp_audio_config_spdif
  29. cdn_dp_audio_config

   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 
  24 void 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 
  29 void 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 
  78 static 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 
  91 static 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 
 106 static 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 
 141 static 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 
 158 static 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 
 184 static 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 
 198 static 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 
 216 int 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 
 243 err_dpcd_read:
 244         return ret;
 245 }
 246 
 247 int 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 
 275 err_dpcd_write:
 276         if (ret)
 277                 DRM_DEV_ERROR(dp->dev, "dpcd write failed: %d\n", ret);
 278         return ret;
 279 }
 280 
 281 int 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 
 323 int 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 
 351 err_set_firmware_active:
 352         if (ret < 0)
 353                 DRM_DEV_ERROR(dp->dev, "set firmware active failed\n");
 354         return ret;
 355 }
 356 
 357 int 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 
 380 err_set_host_cap:
 381         if (ret)
 382                 DRM_DEV_ERROR(dp->dev, "set host cap failed: %d\n", ret);
 383         return ret;
 384 }
 385 
 386 int 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 
 403 u32 cdn_dp_get_event(struct cdn_dp_device *dp)
 404 {
 405         return readl(dp->regs + SW_EVENTS0);
 406 }
 407 
 408 int 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 
 429 err_get_hpd:
 430         DRM_DEV_ERROR(dp->dev, "get hpd status failed: %d\n", ret);
 431         return ret;
 432 }
 433 
 434 int 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 
 475 static 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 
 513 err_training_start:
 514         DRM_DEV_ERROR(dp->dev, "training failed: %d\n", ret);
 515         return ret;
 516 }
 517 
 518 static 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 
 541 err_get_training_status:
 542         if (ret)
 543                 DRM_DEV_ERROR(dp->dev, "get training status failed: %d\n", ret);
 544         return ret;
 545 }
 546 
 547 int 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 
 568 int 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 
 583 static 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 
 630 int 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 
 779 err_config_video:
 780         if (ret)
 781                 DRM_DEV_ERROR(dp->dev, "config video failed: %d\n", ret);
 782         return ret;
 783 }
 784 
 785 int 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 
 818 int 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 
 829 static 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 
 915 static 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 
 932 int 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 
 957 err_audio_config:
 958         if (ret)
 959                 DRM_DEV_ERROR(dp->dev, "audio config failed: %d\n", ret);
 960         return ret;
 961 }

/* [<][>][^][v][top][bottom][index][help] */