Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
0004  * Author: Chris Zhong <zyw@rock-chips.com>
0005  */
0006 
0007 #include <linux/clk.h>
0008 #include <linux/device.h>
0009 #include <linux/delay.h>
0010 #include <linux/io.h>
0011 #include <linux/iopoll.h>
0012 #include <linux/reset.h>
0013 
0014 #include "cdn-dp-core.h"
0015 #include "cdn-dp-reg.h"
0016 
0017 #define CDN_DP_SPDIF_CLK        200000000
0018 #define FW_ALIVE_TIMEOUT_US     1000000
0019 #define MAILBOX_RETRY_US        1000
0020 #define MAILBOX_TIMEOUT_US      5000000
0021 #define LINK_TRAINING_RETRY_MS      20
0022 #define LINK_TRAINING_TIMEOUT_MS    500
0023 
0024 void cdn_dp_set_fw_clk(struct cdn_dp_device *dp, unsigned long clk)
0025 {
0026     writel(clk / 1000000, dp->regs + SW_CLK_H);
0027 }
0028 
0029 void cdn_dp_clock_reset(struct cdn_dp_device *dp)
0030 {
0031     u32 val;
0032 
0033     val = DPTX_FRMR_DATA_CLK_RSTN_EN |
0034           DPTX_FRMR_DATA_CLK_EN |
0035           DPTX_PHY_DATA_RSTN_EN |
0036           DPTX_PHY_DATA_CLK_EN |
0037           DPTX_PHY_CHAR_RSTN_EN |
0038           DPTX_PHY_CHAR_CLK_EN |
0039           SOURCE_AUX_SYS_CLK_RSTN_EN |
0040           SOURCE_AUX_SYS_CLK_EN |
0041           DPTX_SYS_CLK_RSTN_EN |
0042           DPTX_SYS_CLK_EN |
0043           CFG_DPTX_VIF_CLK_RSTN_EN |
0044           CFG_DPTX_VIF_CLK_EN;
0045     writel(val, dp->regs + SOURCE_DPTX_CAR);
0046 
0047     val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN;
0048     writel(val, dp->regs + SOURCE_PHY_CAR);
0049 
0050     val = SOURCE_PKT_SYS_RSTN_EN |
0051           SOURCE_PKT_SYS_CLK_EN |
0052           SOURCE_PKT_DATA_RSTN_EN |
0053           SOURCE_PKT_DATA_CLK_EN;
0054     writel(val, dp->regs + SOURCE_PKT_CAR);
0055 
0056     val = SPDIF_CDR_CLK_RSTN_EN |
0057           SPDIF_CDR_CLK_EN |
0058           SOURCE_AIF_SYS_RSTN_EN |
0059           SOURCE_AIF_SYS_CLK_EN |
0060           SOURCE_AIF_CLK_RSTN_EN |
0061           SOURCE_AIF_CLK_EN;
0062     writel(val, dp->regs + SOURCE_AIF_CAR);
0063 
0064     val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN |
0065           SOURCE_CIPHER_SYS_CLK_EN |
0066           SOURCE_CIPHER_CHAR_CLK_RSTN_EN |
0067           SOURCE_CIPHER_CHAR_CLK_EN;
0068     writel(val, dp->regs + SOURCE_CIPHER_CAR);
0069 
0070     val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN |
0071           SOURCE_CRYPTO_SYS_CLK_EN;
0072     writel(val, dp->regs + SOURCE_CRYPTO_CAR);
0073 
0074     /* enable Mailbox and PIF interrupt */
0075     writel(0, dp->regs + APB_INT_MASK);
0076 }
0077 
0078 static int cdn_dp_mailbox_read(struct cdn_dp_device *dp)
0079 {
0080     int val, ret;
0081 
0082     ret = readx_poll_timeout(readl, dp->regs + MAILBOX_EMPTY_ADDR,
0083                  val, !val, MAILBOX_RETRY_US,
0084                  MAILBOX_TIMEOUT_US);
0085     if (ret < 0)
0086         return ret;
0087 
0088     return readl(dp->regs + MAILBOX0_RD_DATA) & 0xff;
0089 }
0090 
0091 static int cdp_dp_mailbox_write(struct cdn_dp_device *dp, u8 val)
0092 {
0093     int ret, full;
0094 
0095     ret = readx_poll_timeout(readl, dp->regs + MAILBOX_FULL_ADDR,
0096                  full, !full, MAILBOX_RETRY_US,
0097                  MAILBOX_TIMEOUT_US);
0098     if (ret < 0)
0099         return ret;
0100 
0101     writel(val, dp->regs + MAILBOX0_WR_DATA);
0102 
0103     return 0;
0104 }
0105 
0106 static int cdn_dp_mailbox_validate_receive(struct cdn_dp_device *dp,
0107                        u8 module_id, u8 opcode,
0108                        u16 req_size)
0109 {
0110     u32 mbox_size, i;
0111     u8 header[4];
0112     int ret;
0113 
0114     /* read the header of the message */
0115     for (i = 0; i < 4; i++) {
0116         ret = cdn_dp_mailbox_read(dp);
0117         if (ret < 0)
0118             return ret;
0119 
0120         header[i] = ret;
0121     }
0122 
0123     mbox_size = (header[2] << 8) | header[3];
0124 
0125     if (opcode != header[0] || module_id != header[1] ||
0126         req_size != mbox_size) {
0127         /*
0128          * If the message in mailbox is not what we want, we need to
0129          * clear the mailbox by reading its contents.
0130          */
0131         for (i = 0; i < mbox_size; i++)
0132             if (cdn_dp_mailbox_read(dp) < 0)
0133                 break;
0134 
0135         return -EINVAL;
0136     }
0137 
0138     return 0;
0139 }
0140 
0141 static int cdn_dp_mailbox_read_receive(struct cdn_dp_device *dp,
0142                        u8 *buff, u16 buff_size)
0143 {
0144     u32 i;
0145     int ret;
0146 
0147     for (i = 0; i < buff_size; i++) {
0148         ret = cdn_dp_mailbox_read(dp);
0149         if (ret < 0)
0150             return ret;
0151 
0152         buff[i] = ret;
0153     }
0154 
0155     return 0;
0156 }
0157 
0158 static int cdn_dp_mailbox_send(struct cdn_dp_device *dp, u8 module_id,
0159                    u8 opcode, u16 size, u8 *message)
0160 {
0161     u8 header[4];
0162     int ret, i;
0163 
0164     header[0] = opcode;
0165     header[1] = module_id;
0166     header[2] = (size >> 8) & 0xff;
0167     header[3] = size & 0xff;
0168 
0169     for (i = 0; i < 4; i++) {
0170         ret = cdp_dp_mailbox_write(dp, header[i]);
0171         if (ret)
0172             return ret;
0173     }
0174 
0175     for (i = 0; i < size; i++) {
0176         ret = cdp_dp_mailbox_write(dp, message[i]);
0177         if (ret)
0178             return ret;
0179     }
0180 
0181     return 0;
0182 }
0183 
0184 static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
0185 {
0186     u8 msg[6];
0187 
0188     msg[0] = (addr >> 8) & 0xff;
0189     msg[1] = addr & 0xff;
0190     msg[2] = (val >> 24) & 0xff;
0191     msg[3] = (val >> 16) & 0xff;
0192     msg[4] = (val >> 8) & 0xff;
0193     msg[5] = val & 0xff;
0194     return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_REGISTER,
0195                    sizeof(msg), msg);
0196 }
0197 
0198 static int cdn_dp_reg_write_bit(struct cdn_dp_device *dp, u16 addr,
0199                 u8 start_bit, u8 bits_no, u32 val)
0200 {
0201     u8 field[8];
0202 
0203     field[0] = (addr >> 8) & 0xff;
0204     field[1] = addr & 0xff;
0205     field[2] = start_bit;
0206     field[3] = bits_no;
0207     field[4] = (val >> 24) & 0xff;
0208     field[5] = (val >> 16) & 0xff;
0209     field[6] = (val >> 8) & 0xff;
0210     field[7] = val & 0xff;
0211 
0212     return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_FIELD,
0213                    sizeof(field), field);
0214 }
0215 
0216 int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
0217 {
0218     u8 msg[5], reg[5];
0219     int ret;
0220 
0221     msg[0] = (len >> 8) & 0xff;
0222     msg[1] = len & 0xff;
0223     msg[2] = (addr >> 16) & 0xff;
0224     msg[3] = (addr >> 8) & 0xff;
0225     msg[4] = addr & 0xff;
0226     ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_DPCD,
0227                   sizeof(msg), msg);
0228     if (ret)
0229         goto err_dpcd_read;
0230 
0231     ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
0232                           DPTX_READ_DPCD,
0233                           sizeof(reg) + len);
0234     if (ret)
0235         goto err_dpcd_read;
0236 
0237     ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
0238     if (ret)
0239         goto err_dpcd_read;
0240 
0241     ret = cdn_dp_mailbox_read_receive(dp, data, len);
0242 
0243 err_dpcd_read:
0244     return ret;
0245 }
0246 
0247 int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
0248 {
0249     u8 msg[6], reg[5];
0250     int ret;
0251 
0252     msg[0] = 0;
0253     msg[1] = 1;
0254     msg[2] = (addr >> 16) & 0xff;
0255     msg[3] = (addr >> 8) & 0xff;
0256     msg[4] = addr & 0xff;
0257     msg[5] = value;
0258     ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_DPCD,
0259                   sizeof(msg), msg);
0260     if (ret)
0261         goto err_dpcd_write;
0262 
0263     ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
0264                           DPTX_WRITE_DPCD, sizeof(reg));
0265     if (ret)
0266         goto err_dpcd_write;
0267 
0268     ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
0269     if (ret)
0270         goto err_dpcd_write;
0271 
0272     if (addr != (reg[2] << 16 | reg[3] << 8 | reg[4]))
0273         ret = -EINVAL;
0274 
0275 err_dpcd_write:
0276     if (ret)
0277         DRM_DEV_ERROR(dp->dev, "dpcd write failed: %d\n", ret);
0278     return ret;
0279 }
0280 
0281 int cdn_dp_load_firmware(struct cdn_dp_device *dp, const u32 *i_mem,
0282              u32 i_size, const u32 *d_mem, u32 d_size)
0283 {
0284     u32 reg;
0285     int i, ret;
0286 
0287     /* reset ucpu before load firmware*/
0288     writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET,
0289            dp->regs + APB_CTRL);
0290 
0291     for (i = 0; i < i_size; i += 4)
0292         writel(*i_mem++, dp->regs + ADDR_IMEM + i);
0293 
0294     for (i = 0; i < d_size; i += 4)
0295         writel(*d_mem++, dp->regs + ADDR_DMEM + i);
0296 
0297     /* un-reset ucpu */
0298     writel(0, dp->regs + APB_CTRL);
0299 
0300     /* check the keep alive register to make sure fw working */
0301     ret = readx_poll_timeout(readl, dp->regs + KEEP_ALIVE,
0302                  reg, reg, 2000, FW_ALIVE_TIMEOUT_US);
0303     if (ret < 0) {
0304         DRM_DEV_ERROR(dp->dev, "failed to loaded the FW reg = %x\n",
0305                   reg);
0306         return -EINVAL;
0307     }
0308 
0309     reg = readl(dp->regs + VER_L) & 0xff;
0310     dp->fw_version = reg;
0311     reg = readl(dp->regs + VER_H) & 0xff;
0312     dp->fw_version |= reg << 8;
0313     reg = readl(dp->regs + VER_LIB_L_ADDR) & 0xff;
0314     dp->fw_version |= reg << 16;
0315     reg = readl(dp->regs + VER_LIB_H_ADDR) & 0xff;
0316     dp->fw_version |= reg << 24;
0317 
0318     DRM_DEV_DEBUG(dp->dev, "firmware version: %x\n", dp->fw_version);
0319 
0320     return 0;
0321 }
0322 
0323 int cdn_dp_set_firmware_active(struct cdn_dp_device *dp, bool enable)
0324 {
0325     u8 msg[5];
0326     int ret, i;
0327 
0328     msg[0] = GENERAL_MAIN_CONTROL;
0329     msg[1] = MB_MODULE_ID_GENERAL;
0330     msg[2] = 0;
0331     msg[3] = 1;
0332     msg[4] = enable ? FW_ACTIVE : FW_STANDBY;
0333 
0334     for (i = 0; i < sizeof(msg); i++) {
0335         ret = cdp_dp_mailbox_write(dp, msg[i]);
0336         if (ret)
0337             goto err_set_firmware_active;
0338     }
0339 
0340     /* read the firmware state */
0341     for (i = 0; i < sizeof(msg); i++)  {
0342         ret = cdn_dp_mailbox_read(dp);
0343         if (ret < 0)
0344             goto err_set_firmware_active;
0345 
0346         msg[i] = ret;
0347     }
0348 
0349     ret = 0;
0350 
0351 err_set_firmware_active:
0352     if (ret < 0)
0353         DRM_DEV_ERROR(dp->dev, "set firmware active failed\n");
0354     return ret;
0355 }
0356 
0357 int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip)
0358 {
0359     u8 msg[8];
0360     int ret;
0361 
0362     msg[0] = CDN_DP_MAX_LINK_RATE;
0363     msg[1] = lanes | SCRAMBLER_EN;
0364     msg[2] = VOLTAGE_LEVEL_2;
0365     msg[3] = PRE_EMPHASIS_LEVEL_3;
0366     msg[4] = PTS1 | PTS2 | PTS3 | PTS4;
0367     msg[5] = FAST_LT_NOT_SUPPORT;
0368     msg[6] = flip ? LANE_MAPPING_FLIPPED : LANE_MAPPING_NORMAL;
0369     msg[7] = ENHANCED;
0370 
0371     ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
0372                   DPTX_SET_HOST_CAPABILITIES,
0373                   sizeof(msg), msg);
0374     if (ret)
0375         goto err_set_host_cap;
0376 
0377     ret = cdn_dp_reg_write(dp, DP_AUX_SWAP_INVERSION_CONTROL,
0378                    AUX_HOST_INVERT);
0379 
0380 err_set_host_cap:
0381     if (ret)
0382         DRM_DEV_ERROR(dp->dev, "set host cap failed: %d\n", ret);
0383     return ret;
0384 }
0385 
0386 int cdn_dp_event_config(struct cdn_dp_device *dp)
0387 {
0388     u8 msg[5];
0389     int ret;
0390 
0391     memset(msg, 0, sizeof(msg));
0392 
0393     msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING;
0394 
0395     ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_ENABLE_EVENT,
0396                   sizeof(msg), msg);
0397     if (ret)
0398         DRM_DEV_ERROR(dp->dev, "set event config failed: %d\n", ret);
0399 
0400     return ret;
0401 }
0402 
0403 u32 cdn_dp_get_event(struct cdn_dp_device *dp)
0404 {
0405     return readl(dp->regs + SW_EVENTS0);
0406 }
0407 
0408 int cdn_dp_get_hpd_status(struct cdn_dp_device *dp)
0409 {
0410     u8 status;
0411     int ret;
0412 
0413     ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_HPD_STATE,
0414                   0, NULL);
0415     if (ret)
0416         goto err_get_hpd;
0417 
0418     ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
0419                           DPTX_HPD_STATE, sizeof(status));
0420     if (ret)
0421         goto err_get_hpd;
0422 
0423     ret = cdn_dp_mailbox_read_receive(dp, &status, sizeof(status));
0424     if (ret)
0425         goto err_get_hpd;
0426 
0427     return status;
0428 
0429 err_get_hpd:
0430     DRM_DEV_ERROR(dp->dev, "get hpd status failed: %d\n", ret);
0431     return ret;
0432 }
0433 
0434 int cdn_dp_get_edid_block(void *data, u8 *edid,
0435               unsigned int block, size_t length)
0436 {
0437     struct cdn_dp_device *dp = data;
0438     u8 msg[2], reg[2], i;
0439     int ret;
0440 
0441     for (i = 0; i < 4; i++) {
0442         msg[0] = block / 2;
0443         msg[1] = block % 2;
0444 
0445         ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_GET_EDID,
0446                       sizeof(msg), msg);
0447         if (ret)
0448             continue;
0449 
0450         ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
0451                               DPTX_GET_EDID,
0452                               sizeof(reg) + length);
0453         if (ret)
0454             continue;
0455 
0456         ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
0457         if (ret)
0458             continue;
0459 
0460         ret = cdn_dp_mailbox_read_receive(dp, edid, length);
0461         if (ret)
0462             continue;
0463 
0464         if (reg[0] == length && reg[1] == block / 2)
0465             break;
0466     }
0467 
0468     if (ret)
0469         DRM_DEV_ERROR(dp->dev, "get block[%d] edid failed: %d\n", block,
0470                   ret);
0471 
0472     return ret;
0473 }
0474 
0475 static int cdn_dp_training_start(struct cdn_dp_device *dp)
0476 {
0477     unsigned long timeout;
0478     u8 msg, event[2];
0479     int ret;
0480 
0481     msg = LINK_TRAINING_RUN;
0482 
0483     /* start training */
0484     ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_TRAINING_CONTROL,
0485                   sizeof(msg), &msg);
0486     if (ret)
0487         goto err_training_start;
0488 
0489     timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS);
0490     while (time_before(jiffies, timeout)) {
0491         msleep(LINK_TRAINING_RETRY_MS);
0492         ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
0493                       DPTX_READ_EVENT, 0, NULL);
0494         if (ret)
0495             goto err_training_start;
0496 
0497         ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
0498                               DPTX_READ_EVENT,
0499                               sizeof(event));
0500         if (ret)
0501             goto err_training_start;
0502 
0503         ret = cdn_dp_mailbox_read_receive(dp, event, sizeof(event));
0504         if (ret)
0505             goto err_training_start;
0506 
0507         if (event[1] & EQ_PHASE_FINISHED)
0508             return 0;
0509     }
0510 
0511     ret = -ETIMEDOUT;
0512 
0513 err_training_start:
0514     DRM_DEV_ERROR(dp->dev, "training failed: %d\n", ret);
0515     return ret;
0516 }
0517 
0518 static int cdn_dp_get_training_status(struct cdn_dp_device *dp)
0519 {
0520     u8 status[10];
0521     int ret;
0522 
0523     ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_LINK_STAT,
0524                   0, NULL);
0525     if (ret)
0526         goto err_get_training_status;
0527 
0528     ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
0529                           DPTX_READ_LINK_STAT,
0530                           sizeof(status));
0531     if (ret)
0532         goto err_get_training_status;
0533 
0534     ret = cdn_dp_mailbox_read_receive(dp, status, sizeof(status));
0535     if (ret)
0536         goto err_get_training_status;
0537 
0538     dp->max_rate = drm_dp_bw_code_to_link_rate(status[0]);
0539     dp->max_lanes = status[1];
0540 
0541 err_get_training_status:
0542     if (ret)
0543         DRM_DEV_ERROR(dp->dev, "get training status failed: %d\n", ret);
0544     return ret;
0545 }
0546 
0547 int cdn_dp_train_link(struct cdn_dp_device *dp)
0548 {
0549     int ret;
0550 
0551     ret = cdn_dp_training_start(dp);
0552     if (ret) {
0553         DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
0554         return ret;
0555     }
0556 
0557     ret = cdn_dp_get_training_status(dp);
0558     if (ret) {
0559         DRM_DEV_ERROR(dp->dev, "Failed to get training stat %d\n", ret);
0560         return ret;
0561     }
0562 
0563     DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->max_rate,
0564               dp->max_lanes);
0565     return ret;
0566 }
0567 
0568 int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
0569 {
0570     u8 msg;
0571     int ret;
0572 
0573     msg = !!active;
0574 
0575     ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO,
0576                   sizeof(msg), &msg);
0577     if (ret)
0578         DRM_DEV_ERROR(dp->dev, "set video status failed: %d\n", ret);
0579 
0580     return ret;
0581 }
0582 
0583 static int cdn_dp_get_msa_misc(struct video_info *video,
0584                    struct drm_display_mode *mode)
0585 {
0586     u32 msa_misc;
0587     u8 val[2] = {0};
0588 
0589     switch (video->color_fmt) {
0590     case PXL_RGB:
0591     case Y_ONLY:
0592         val[0] = 0;
0593         break;
0594     /* set YUV default color space conversion to BT601 */
0595     case YCBCR_4_4_4:
0596         val[0] = 6 + BT_601 * 8;
0597         break;
0598     case YCBCR_4_2_2:
0599         val[0] = 5 + BT_601 * 8;
0600         break;
0601     case YCBCR_4_2_0:
0602         val[0] = 5;
0603         break;
0604     }
0605 
0606     switch (video->color_depth) {
0607     case 6:
0608         val[1] = 0;
0609         break;
0610     case 8:
0611         val[1] = 1;
0612         break;
0613     case 10:
0614         val[1] = 2;
0615         break;
0616     case 12:
0617         val[1] = 3;
0618         break;
0619     case 16:
0620         val[1] = 4;
0621         break;
0622     }
0623 
0624     msa_misc = 2 * val[0] + 32 * val[1] +
0625            ((video->color_fmt == Y_ONLY) ? (1 << 14) : 0);
0626 
0627     return msa_misc;
0628 }
0629 
0630 int cdn_dp_config_video(struct cdn_dp_device *dp)
0631 {
0632     struct video_info *video = &dp->video_info;
0633     struct drm_display_mode *mode = &dp->mode;
0634     u64 symbol;
0635     u32 val, link_rate, rem;
0636     u8 bit_per_pix, tu_size_reg = TU_SIZE;
0637     int ret;
0638 
0639     bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ?
0640               (video->color_depth * 2) : (video->color_depth * 3);
0641 
0642     link_rate = dp->max_rate / 1000;
0643 
0644     ret = cdn_dp_reg_write(dp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE);
0645     if (ret)
0646         goto err_config_video;
0647 
0648     ret = cdn_dp_reg_write(dp, HSYNC2VSYNC_POL_CTRL, 0);
0649     if (ret)
0650         goto err_config_video;
0651 
0652     /*
0653      * get a best tu_size and valid symbol:
0654      * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32
0655      * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes)
0656      * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set
0657      *    TU += 2 and repeat 2nd step.
0658      */
0659     do {
0660         tu_size_reg += 2;
0661         symbol = (u64)tu_size_reg * mode->clock * bit_per_pix;
0662         do_div(symbol, dp->max_lanes * link_rate * 8);
0663         rem = do_div(symbol, 1000);
0664         if (tu_size_reg > 64) {
0665             ret = -EINVAL;
0666             DRM_DEV_ERROR(dp->dev,
0667                       "tu error, clk:%d, lanes:%d, rate:%d\n",
0668                       mode->clock, dp->max_lanes, link_rate);
0669             goto err_config_video;
0670         }
0671     } while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
0672          (rem > 850) || (rem < 100));
0673 
0674     val = symbol + (tu_size_reg << 8);
0675     val |= TU_CNT_RST_EN;
0676     ret = cdn_dp_reg_write(dp, DP_FRAMER_TU, val);
0677     if (ret)
0678         goto err_config_video;
0679 
0680     /* set the FIFO Buffer size */
0681     val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
0682     val /= (dp->max_lanes * link_rate);
0683     val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
0684     val += 2;
0685     ret = cdn_dp_reg_write(dp, DP_VC_TABLE(15), val);
0686 
0687     switch (video->color_depth) {
0688     case 6:
0689         val = BCS_6;
0690         break;
0691     case 8:
0692         val = BCS_8;
0693         break;
0694     case 10:
0695         val = BCS_10;
0696         break;
0697     case 12:
0698         val = BCS_12;
0699         break;
0700     case 16:
0701         val = BCS_16;
0702         break;
0703     }
0704 
0705     val += video->color_fmt << 8;
0706     ret = cdn_dp_reg_write(dp, DP_FRAMER_PXL_REPR, val);
0707     if (ret)
0708         goto err_config_video;
0709 
0710     val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0;
0711     val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0;
0712     ret = cdn_dp_reg_write(dp, DP_FRAMER_SP, val);
0713     if (ret)
0714         goto err_config_video;
0715 
0716     val = (mode->hsync_start - mode->hdisplay) << 16;
0717     val |= mode->htotal - mode->hsync_end;
0718     ret = cdn_dp_reg_write(dp, DP_FRONT_BACK_PORCH, val);
0719     if (ret)
0720         goto err_config_video;
0721 
0722     val = mode->hdisplay * bit_per_pix / 8;
0723     ret = cdn_dp_reg_write(dp, DP_BYTE_COUNT, val);
0724     if (ret)
0725         goto err_config_video;
0726 
0727     val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16);
0728     ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_0, val);
0729     if (ret)
0730         goto err_config_video;
0731 
0732     val = mode->hsync_end - mode->hsync_start;
0733     val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15);
0734     ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_1, val);
0735     if (ret)
0736         goto err_config_video;
0737 
0738     val = mode->vtotal;
0739     val |= (mode->vtotal - mode->vsync_start) << 16;
0740     ret = cdn_dp_reg_write(dp, MSA_VERTICAL_0, val);
0741     if (ret)
0742         goto err_config_video;
0743 
0744     val = mode->vsync_end - mode->vsync_start;
0745     val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15);
0746     ret = cdn_dp_reg_write(dp, MSA_VERTICAL_1, val);
0747     if (ret)
0748         goto err_config_video;
0749 
0750     val = cdn_dp_get_msa_misc(video, mode);
0751     ret = cdn_dp_reg_write(dp, MSA_MISC, val);
0752     if (ret)
0753         goto err_config_video;
0754 
0755     ret = cdn_dp_reg_write(dp, STREAM_CONFIG, 1);
0756     if (ret)
0757         goto err_config_video;
0758 
0759     val = mode->hsync_end - mode->hsync_start;
0760     val |= mode->hdisplay << 16;
0761     ret = cdn_dp_reg_write(dp, DP_HORIZONTAL, val);
0762     if (ret)
0763         goto err_config_video;
0764 
0765     val = mode->vdisplay;
0766     val |= (mode->vtotal - mode->vsync_start) << 16;
0767     ret = cdn_dp_reg_write(dp, DP_VERTICAL_0, val);
0768     if (ret)
0769         goto err_config_video;
0770 
0771     val = mode->vtotal;
0772     ret = cdn_dp_reg_write(dp, DP_VERTICAL_1, val);
0773     if (ret)
0774         goto err_config_video;
0775 
0776     ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 2, 1, 0);
0777 
0778 err_config_video:
0779     if (ret)
0780         DRM_DEV_ERROR(dp->dev, "config video failed: %d\n", ret);
0781     return ret;
0782 }
0783 
0784 int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio)
0785 {
0786     int ret;
0787 
0788     ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, 0);
0789     if (ret) {
0790         DRM_DEV_ERROR(dp->dev, "audio stop failed: %d\n", ret);
0791         return ret;
0792     }
0793 
0794     writel(0, dp->regs + SPDIF_CTRL_ADDR);
0795 
0796     /* clearn the audio config and reset */
0797     writel(0, dp->regs + AUDIO_SRC_CNTL);
0798     writel(0, dp->regs + AUDIO_SRC_CNFG);
0799     writel(AUDIO_SW_RST, dp->regs + AUDIO_SRC_CNTL);
0800     writel(0, dp->regs + AUDIO_SRC_CNTL);
0801 
0802     /* reset smpl2pckt component  */
0803     writel(0, dp->regs + SMPL2PKT_CNTL);
0804     writel(AUDIO_SW_RST, dp->regs + SMPL2PKT_CNTL);
0805     writel(0, dp->regs + SMPL2PKT_CNTL);
0806 
0807     /* reset FIFO */
0808     writel(AUDIO_SW_RST, dp->regs + FIFO_CNTL);
0809     writel(0, dp->regs + FIFO_CNTL);
0810 
0811     if (audio->format == AFMT_SPDIF)
0812         clk_disable_unprepare(dp->spdif_clk);
0813 
0814     return 0;
0815 }
0816 
0817 int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable)
0818 {
0819     int ret;
0820 
0821     ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 4, 1, enable);
0822     if (ret)
0823         DRM_DEV_ERROR(dp->dev, "audio mute failed: %d\n", ret);
0824 
0825     return ret;
0826 }
0827 
0828 static void cdn_dp_audio_config_i2s(struct cdn_dp_device *dp,
0829                     struct audio_info *audio)
0830 {
0831     int sub_pckt_num = 1, i2s_port_en_val = 0xf, i;
0832     u32 val;
0833 
0834     if (audio->channels == 2) {
0835         if (dp->max_lanes == 1)
0836             sub_pckt_num = 2;
0837         else
0838             sub_pckt_num = 4;
0839 
0840         i2s_port_en_val = 1;
0841     } else if (audio->channels == 4) {
0842         i2s_port_en_val = 3;
0843     }
0844 
0845     writel(0x0, dp->regs + SPDIF_CTRL_ADDR);
0846 
0847     writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
0848 
0849     val = MAX_NUM_CH(audio->channels);
0850     val |= NUM_OF_I2S_PORTS(audio->channels);
0851     val |= AUDIO_TYPE_LPCM;
0852     val |= CFG_SUB_PCKT_NUM(sub_pckt_num);
0853     writel(val, dp->regs + SMPL2PKT_CNFG);
0854 
0855     if (audio->sample_width == 16)
0856         val = 0;
0857     else if (audio->sample_width == 24)
0858         val = 1 << 9;
0859     else
0860         val = 2 << 9;
0861 
0862     val |= AUDIO_CH_NUM(audio->channels);
0863     val |= I2S_DEC_PORT_EN(i2s_port_en_val);
0864     val |= TRANS_SMPL_WIDTH_32;
0865     writel(val, dp->regs + AUDIO_SRC_CNFG);
0866 
0867     for (i = 0; i < (audio->channels + 1) / 2; i++) {
0868         if (audio->sample_width == 16)
0869             val = (0x02 << 8) | (0x02 << 20);
0870         else if (audio->sample_width == 24)
0871             val = (0x0b << 8) | (0x0b << 20);
0872 
0873         val |= ((2 * i) << 4) | ((2 * i + 1) << 16);
0874         writel(val, dp->regs + STTS_BIT_CH(i));
0875     }
0876 
0877     switch (audio->sample_rate) {
0878     case 32000:
0879         val = SAMPLING_FREQ(3) |
0880               ORIGINAL_SAMP_FREQ(0xc);
0881         break;
0882     case 44100:
0883         val = SAMPLING_FREQ(0) |
0884               ORIGINAL_SAMP_FREQ(0xf);
0885         break;
0886     case 48000:
0887         val = SAMPLING_FREQ(2) |
0888               ORIGINAL_SAMP_FREQ(0xd);
0889         break;
0890     case 88200:
0891         val = SAMPLING_FREQ(8) |
0892               ORIGINAL_SAMP_FREQ(0x7);
0893         break;
0894     case 96000:
0895         val = SAMPLING_FREQ(0xa) |
0896               ORIGINAL_SAMP_FREQ(5);
0897         break;
0898     case 176400:
0899         val = SAMPLING_FREQ(0xc) |
0900               ORIGINAL_SAMP_FREQ(3);
0901         break;
0902     case 192000:
0903         val = SAMPLING_FREQ(0xe) |
0904               ORIGINAL_SAMP_FREQ(1);
0905         break;
0906     }
0907     val |= 4;
0908     writel(val, dp->regs + COM_CH_STTS_BITS);
0909 
0910     writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
0911     writel(I2S_DEC_START, dp->regs + AUDIO_SRC_CNTL);
0912 }
0913 
0914 static void cdn_dp_audio_config_spdif(struct cdn_dp_device *dp)
0915 {
0916     u32 val;
0917 
0918     writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
0919 
0920     val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4);
0921     writel(val, dp->regs + SMPL2PKT_CNFG);
0922     writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
0923 
0924     val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
0925     writel(val, dp->regs + SPDIF_CTRL_ADDR);
0926 
0927     clk_prepare_enable(dp->spdif_clk);
0928     clk_set_rate(dp->spdif_clk, CDN_DP_SPDIF_CLK);
0929 }
0930 
0931 int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio)
0932 {
0933     int ret;
0934 
0935     /* reset the spdif clk before config */
0936     if (audio->format == AFMT_SPDIF) {
0937         reset_control_assert(dp->spdif_rst);
0938         reset_control_deassert(dp->spdif_rst);
0939     }
0940 
0941     ret = cdn_dp_reg_write(dp, CM_LANE_CTRL, LANE_REF_CYC);
0942     if (ret)
0943         goto err_audio_config;
0944 
0945     ret = cdn_dp_reg_write(dp, CM_CTRL, 0);
0946     if (ret)
0947         goto err_audio_config;
0948 
0949     if (audio->format == AFMT_I2S)
0950         cdn_dp_audio_config_i2s(dp, audio);
0951     else if (audio->format == AFMT_SPDIF)
0952         cdn_dp_audio_config_spdif(dp);
0953 
0954     ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN);
0955 
0956 err_audio_config:
0957     if (ret)
0958         DRM_DEV_ERROR(dp->dev, "audio config failed: %d\n", ret);
0959     return ret;
0960 }