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