1c943b494SChandan Uddaraju // SPDX-License-Identifier: GPL-2.0-only 2c943b494SChandan Uddaraju /* 3c943b494SChandan Uddaraju * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. 4c943b494SChandan Uddaraju */ 5c943b494SChandan Uddaraju 6c943b494SChandan Uddaraju #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__ 7c943b494SChandan Uddaraju 8c943b494SChandan Uddaraju #include <linux/delay.h> 9c943b494SChandan Uddaraju #include <linux/iopoll.h> 10937f941cSStephen Boyd #include <linux/phy/phy.h> 11937f941cSStephen Boyd #include <linux/phy/phy-dp.h> 12c943b494SChandan Uddaraju #include <linux/rational.h> 13*5b529e8dSThomas Zimmermann #include <drm/dp/drm_dp_helper.h> 14937f941cSStephen Boyd #include <drm/drm_print.h> 15c943b494SChandan Uddaraju 16c943b494SChandan Uddaraju #include "dp_catalog.h" 17c943b494SChandan Uddaraju #include "dp_reg.h" 18c943b494SChandan Uddaraju 19c943b494SChandan Uddaraju #define POLLING_SLEEP_US 1000 20c943b494SChandan Uddaraju #define POLLING_TIMEOUT_US 10000 21c943b494SChandan Uddaraju 22c943b494SChandan Uddaraju #define SCRAMBLER_RESET_COUNT_VALUE 0xFC 23c943b494SChandan Uddaraju 24c943b494SChandan Uddaraju #define DP_INTERRUPT_STATUS_ACK_SHIFT 1 25c943b494SChandan Uddaraju #define DP_INTERRUPT_STATUS_MASK_SHIFT 2 26c943b494SChandan Uddaraju 27c943b494SChandan Uddaraju #define DP_INTERRUPT_STATUS1 \ 28c943b494SChandan Uddaraju (DP_INTR_AUX_I2C_DONE| \ 29c943b494SChandan Uddaraju DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \ 30c943b494SChandan Uddaraju DP_INTR_NACK_DEFER | DP_INTR_WRONG_DATA_CNT | \ 31c943b494SChandan Uddaraju DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER | \ 32c943b494SChandan Uddaraju DP_INTR_PLL_UNLOCKED | DP_INTR_AUX_ERROR) 33c943b494SChandan Uddaraju 34c943b494SChandan Uddaraju #define DP_INTERRUPT_STATUS1_ACK \ 35c943b494SChandan Uddaraju (DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_ACK_SHIFT) 36c943b494SChandan Uddaraju #define DP_INTERRUPT_STATUS1_MASK \ 37c943b494SChandan Uddaraju (DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_MASK_SHIFT) 38c943b494SChandan Uddaraju 39c943b494SChandan Uddaraju #define DP_INTERRUPT_STATUS2 \ 40c943b494SChandan Uddaraju (DP_INTR_READY_FOR_VIDEO | DP_INTR_IDLE_PATTERN_SENT | \ 41c943b494SChandan Uddaraju DP_INTR_FRAME_END | DP_INTR_CRC_UPDATED) 42c943b494SChandan Uddaraju 43c943b494SChandan Uddaraju #define DP_INTERRUPT_STATUS2_ACK \ 44c943b494SChandan Uddaraju (DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_ACK_SHIFT) 45c943b494SChandan Uddaraju #define DP_INTERRUPT_STATUS2_MASK \ 46c943b494SChandan Uddaraju (DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT) 47c943b494SChandan Uddaraju 48c943b494SChandan Uddaraju struct dp_catalog_private { 49c943b494SChandan Uddaraju struct device *dev; 50c943b494SChandan Uddaraju struct dp_io *io; 51d13e36d7SAbhinav Kumar u32 (*audio_map)[DP_AUDIO_SDP_HEADER_MAX]; 52c943b494SChandan Uddaraju struct dp_catalog dp_catalog; 53c943b494SChandan Uddaraju u8 aux_lut_cfg_index[PHY_AUX_CFG_MAX]; 54c943b494SChandan Uddaraju }; 55c943b494SChandan Uddaraju 560f6090f3SAbhinav Kumar void dp_catalog_snapshot(struct dp_catalog *dp_catalog, struct msm_disp_state *disp_state) 570f6090f3SAbhinav Kumar { 580f6090f3SAbhinav Kumar struct dp_catalog_private *catalog = container_of(dp_catalog, 590f6090f3SAbhinav Kumar struct dp_catalog_private, dp_catalog); 60060c160fSBjorn Andersson struct dss_io_data *dss = &catalog->io->dp_controller; 610f6090f3SAbhinav Kumar 62060c160fSBjorn Andersson msm_disp_snapshot_add_block(disp_state, dss->ahb.len, dss->ahb.base, "dp_ahb"); 63060c160fSBjorn Andersson msm_disp_snapshot_add_block(disp_state, dss->aux.len, dss->aux.base, "dp_aux"); 64060c160fSBjorn Andersson msm_disp_snapshot_add_block(disp_state, dss->link.len, dss->link.base, "dp_link"); 65060c160fSBjorn Andersson msm_disp_snapshot_add_block(disp_state, dss->p0.len, dss->p0.base, "dp_p0"); 660f6090f3SAbhinav Kumar } 670f6090f3SAbhinav Kumar 68c943b494SChandan Uddaraju static inline u32 dp_read_aux(struct dp_catalog_private *catalog, u32 offset) 69c943b494SChandan Uddaraju { 70060c160fSBjorn Andersson return readl_relaxed(catalog->io->dp_controller.aux.base + offset); 71c943b494SChandan Uddaraju } 72c943b494SChandan Uddaraju 73c943b494SChandan Uddaraju static inline void dp_write_aux(struct dp_catalog_private *catalog, 74c943b494SChandan Uddaraju u32 offset, u32 data) 75c943b494SChandan Uddaraju { 76c943b494SChandan Uddaraju /* 77c943b494SChandan Uddaraju * To make sure aux reg writes happens before any other operation, 78c943b494SChandan Uddaraju * this function uses writel() instread of writel_relaxed() 79c943b494SChandan Uddaraju */ 80060c160fSBjorn Andersson writel(data, catalog->io->dp_controller.aux.base + offset); 81c943b494SChandan Uddaraju } 82c943b494SChandan Uddaraju 83c943b494SChandan Uddaraju static inline u32 dp_read_ahb(struct dp_catalog_private *catalog, u32 offset) 84c943b494SChandan Uddaraju { 85060c160fSBjorn Andersson return readl_relaxed(catalog->io->dp_controller.ahb.base + offset); 86c943b494SChandan Uddaraju } 87c943b494SChandan Uddaraju 88c943b494SChandan Uddaraju static inline void dp_write_ahb(struct dp_catalog_private *catalog, 89c943b494SChandan Uddaraju u32 offset, u32 data) 90c943b494SChandan Uddaraju { 91c943b494SChandan Uddaraju /* 92c943b494SChandan Uddaraju * To make sure phy reg writes happens before any other operation, 93c943b494SChandan Uddaraju * this function uses writel() instread of writel_relaxed() 94c943b494SChandan Uddaraju */ 95060c160fSBjorn Andersson writel(data, catalog->io->dp_controller.ahb.base + offset); 96c943b494SChandan Uddaraju } 97c943b494SChandan Uddaraju 98c943b494SChandan Uddaraju static inline void dp_write_p0(struct dp_catalog_private *catalog, 99c943b494SChandan Uddaraju u32 offset, u32 data) 100c943b494SChandan Uddaraju { 101c943b494SChandan Uddaraju /* 102c943b494SChandan Uddaraju * To make sure interface reg writes happens before any other operation, 103c943b494SChandan Uddaraju * this function uses writel() instread of writel_relaxed() 104c943b494SChandan Uddaraju */ 105060c160fSBjorn Andersson writel(data, catalog->io->dp_controller.p0.base + offset); 106c943b494SChandan Uddaraju } 107c943b494SChandan Uddaraju 108c943b494SChandan Uddaraju static inline u32 dp_read_p0(struct dp_catalog_private *catalog, 109c943b494SChandan Uddaraju u32 offset) 110c943b494SChandan Uddaraju { 111c943b494SChandan Uddaraju /* 112c943b494SChandan Uddaraju * To make sure interface reg writes happens before any other operation, 113c943b494SChandan Uddaraju * this function uses writel() instread of writel_relaxed() 114c943b494SChandan Uddaraju */ 115060c160fSBjorn Andersson return readl_relaxed(catalog->io->dp_controller.p0.base + offset); 116c943b494SChandan Uddaraju } 117c943b494SChandan Uddaraju 118c943b494SChandan Uddaraju static inline u32 dp_read_link(struct dp_catalog_private *catalog, u32 offset) 119c943b494SChandan Uddaraju { 120060c160fSBjorn Andersson return readl_relaxed(catalog->io->dp_controller.link.base + offset); 121c943b494SChandan Uddaraju } 122c943b494SChandan Uddaraju 123c943b494SChandan Uddaraju static inline void dp_write_link(struct dp_catalog_private *catalog, 124c943b494SChandan Uddaraju u32 offset, u32 data) 125c943b494SChandan Uddaraju { 126c943b494SChandan Uddaraju /* 127c943b494SChandan Uddaraju * To make sure link reg writes happens before any other operation, 128c943b494SChandan Uddaraju * this function uses writel() instread of writel_relaxed() 129c943b494SChandan Uddaraju */ 130060c160fSBjorn Andersson writel(data, catalog->io->dp_controller.link.base + offset); 131c943b494SChandan Uddaraju } 132c943b494SChandan Uddaraju 133c943b494SChandan Uddaraju /* aux related catalog functions */ 134c943b494SChandan Uddaraju u32 dp_catalog_aux_read_data(struct dp_catalog *dp_catalog) 135c943b494SChandan Uddaraju { 136c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 137c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 138c943b494SChandan Uddaraju 139c943b494SChandan Uddaraju return dp_read_aux(catalog, REG_DP_AUX_DATA); 140c943b494SChandan Uddaraju } 141c943b494SChandan Uddaraju 142c943b494SChandan Uddaraju int dp_catalog_aux_write_data(struct dp_catalog *dp_catalog) 143c943b494SChandan Uddaraju { 144c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 145c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 146c943b494SChandan Uddaraju 147c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_AUX_DATA, dp_catalog->aux_data); 148c943b494SChandan Uddaraju return 0; 149c943b494SChandan Uddaraju } 150c943b494SChandan Uddaraju 151c943b494SChandan Uddaraju int dp_catalog_aux_write_trans(struct dp_catalog *dp_catalog) 152c943b494SChandan Uddaraju { 153c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 154c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 155c943b494SChandan Uddaraju 156c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, dp_catalog->aux_data); 157c943b494SChandan Uddaraju return 0; 158c943b494SChandan Uddaraju } 159c943b494SChandan Uddaraju 160c943b494SChandan Uddaraju int dp_catalog_aux_clear_trans(struct dp_catalog *dp_catalog, bool read) 161c943b494SChandan Uddaraju { 162c943b494SChandan Uddaraju u32 data; 163c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 164c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 165c943b494SChandan Uddaraju 166c943b494SChandan Uddaraju if (read) { 167c943b494SChandan Uddaraju data = dp_read_aux(catalog, REG_DP_AUX_TRANS_CTRL); 168c943b494SChandan Uddaraju data &= ~DP_AUX_TRANS_CTRL_GO; 169c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, data); 170c943b494SChandan Uddaraju } else { 171c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, 0); 172c943b494SChandan Uddaraju } 173c943b494SChandan Uddaraju return 0; 174c943b494SChandan Uddaraju } 175c943b494SChandan Uddaraju 176c943b494SChandan Uddaraju int dp_catalog_aux_clear_hw_interrupts(struct dp_catalog *dp_catalog) 177c943b494SChandan Uddaraju { 178c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 179c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 180c943b494SChandan Uddaraju 181c943b494SChandan Uddaraju dp_read_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_STATUS); 182c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f); 183c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f); 184c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0); 185c943b494SChandan Uddaraju return 0; 186c943b494SChandan Uddaraju } 187c943b494SChandan Uddaraju 1889fc41843SKuogee Hsieh /** 1899fc41843SKuogee Hsieh * dp_catalog_aux_reset() - reset AUX controller 1909fc41843SKuogee Hsieh * 1912eb4bfc0SLee Jones * @dp_catalog: DP catalog structure 1929fc41843SKuogee Hsieh * 1939fc41843SKuogee Hsieh * return: void 1949fc41843SKuogee Hsieh * 1959fc41843SKuogee Hsieh * This function reset AUX controller 1969fc41843SKuogee Hsieh * 1979fc41843SKuogee Hsieh * NOTE: reset AUX controller will also clear any pending HPD related interrupts 1989fc41843SKuogee Hsieh * 1999fc41843SKuogee Hsieh */ 200c943b494SChandan Uddaraju void dp_catalog_aux_reset(struct dp_catalog *dp_catalog) 201c943b494SChandan Uddaraju { 202c943b494SChandan Uddaraju u32 aux_ctrl; 203c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 204c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 205c943b494SChandan Uddaraju 206c943b494SChandan Uddaraju aux_ctrl = dp_read_aux(catalog, REG_DP_AUX_CTRL); 207c943b494SChandan Uddaraju 208c943b494SChandan Uddaraju aux_ctrl |= DP_AUX_CTRL_RESET; 209c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl); 210c943b494SChandan Uddaraju usleep_range(1000, 1100); /* h/w recommended delay */ 211c943b494SChandan Uddaraju 212c943b494SChandan Uddaraju aux_ctrl &= ~DP_AUX_CTRL_RESET; 213c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl); 214c943b494SChandan Uddaraju } 215c943b494SChandan Uddaraju 216c943b494SChandan Uddaraju void dp_catalog_aux_enable(struct dp_catalog *dp_catalog, bool enable) 217c943b494SChandan Uddaraju { 218c943b494SChandan Uddaraju u32 aux_ctrl; 219c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 220c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 221c943b494SChandan Uddaraju 222c943b494SChandan Uddaraju aux_ctrl = dp_read_aux(catalog, REG_DP_AUX_CTRL); 223c943b494SChandan Uddaraju 224c943b494SChandan Uddaraju if (enable) { 225c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_TIMEOUT_COUNT, 0xffff); 226c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_AUX_LIMITS, 0xffff); 227c943b494SChandan Uddaraju aux_ctrl |= DP_AUX_CTRL_ENABLE; 228c943b494SChandan Uddaraju } else { 229c943b494SChandan Uddaraju aux_ctrl &= ~DP_AUX_CTRL_ENABLE; 230c943b494SChandan Uddaraju } 231c943b494SChandan Uddaraju 232c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl); 233c943b494SChandan Uddaraju } 234c943b494SChandan Uddaraju 235937f941cSStephen Boyd void dp_catalog_aux_update_cfg(struct dp_catalog *dp_catalog) 236c943b494SChandan Uddaraju { 237c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 238c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 239937f941cSStephen Boyd struct dp_io *dp_io = catalog->io; 240937f941cSStephen Boyd struct phy *phy = dp_io->phy; 241c943b494SChandan Uddaraju 242937f941cSStephen Boyd phy_calibrate(phy); 243c943b494SChandan Uddaraju } 244c943b494SChandan Uddaraju 245c943b494SChandan Uddaraju static void dump_regs(void __iomem *base, int len) 246c943b494SChandan Uddaraju { 247c943b494SChandan Uddaraju int i; 248c943b494SChandan Uddaraju u32 x0, x4, x8, xc; 249c943b494SChandan Uddaraju u32 addr_off = 0; 250c943b494SChandan Uddaraju 251c943b494SChandan Uddaraju len = DIV_ROUND_UP(len, 16); 252c943b494SChandan Uddaraju for (i = 0; i < len; i++) { 253c943b494SChandan Uddaraju x0 = readl_relaxed(base + addr_off); 254c943b494SChandan Uddaraju x4 = readl_relaxed(base + addr_off + 0x04); 255c943b494SChandan Uddaraju x8 = readl_relaxed(base + addr_off + 0x08); 256c943b494SChandan Uddaraju xc = readl_relaxed(base + addr_off + 0x0c); 257c943b494SChandan Uddaraju 258c943b494SChandan Uddaraju pr_info("%08x: %08x %08x %08x %08x", addr_off, x0, x4, x8, xc); 259c943b494SChandan Uddaraju addr_off += 16; 260c943b494SChandan Uddaraju } 261c943b494SChandan Uddaraju } 262c943b494SChandan Uddaraju 263c943b494SChandan Uddaraju void dp_catalog_dump_regs(struct dp_catalog *dp_catalog) 264c943b494SChandan Uddaraju { 265c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 266c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 267060c160fSBjorn Andersson struct dss_io_data *io = &catalog->io->dp_controller; 268c943b494SChandan Uddaraju 269c943b494SChandan Uddaraju pr_info("AHB regs\n"); 270060c160fSBjorn Andersson dump_regs(io->ahb.base, io->ahb.len); 271c943b494SChandan Uddaraju 272c943b494SChandan Uddaraju pr_info("AUXCLK regs\n"); 273060c160fSBjorn Andersson dump_regs(io->aux.base, io->aux.len); 274c943b494SChandan Uddaraju 275c943b494SChandan Uddaraju pr_info("LCLK regs\n"); 276060c160fSBjorn Andersson dump_regs(io->link.base, io->link.len); 277c943b494SChandan Uddaraju 278c943b494SChandan Uddaraju pr_info("P0CLK regs\n"); 279060c160fSBjorn Andersson dump_regs(io->p0.base, io->p0.len); 280c943b494SChandan Uddaraju } 281c943b494SChandan Uddaraju 28224c7861bSStephen Boyd u32 dp_catalog_aux_get_irq(struct dp_catalog *dp_catalog) 283c943b494SChandan Uddaraju { 284c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 285c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 286c943b494SChandan Uddaraju u32 intr, intr_ack; 287c943b494SChandan Uddaraju 288c943b494SChandan Uddaraju intr = dp_read_ahb(catalog, REG_DP_INTR_STATUS); 289c943b494SChandan Uddaraju intr &= ~DP_INTERRUPT_STATUS1_MASK; 290c943b494SChandan Uddaraju intr_ack = (intr & DP_INTERRUPT_STATUS1) 291c943b494SChandan Uddaraju << DP_INTERRUPT_STATUS_ACK_SHIFT; 292c943b494SChandan Uddaraju dp_write_ahb(catalog, REG_DP_INTR_STATUS, intr_ack | 293c943b494SChandan Uddaraju DP_INTERRUPT_STATUS1_MASK); 294c943b494SChandan Uddaraju 295c943b494SChandan Uddaraju return intr; 296c943b494SChandan Uddaraju 297c943b494SChandan Uddaraju } 298c943b494SChandan Uddaraju 299c943b494SChandan Uddaraju /* controller related catalog functions */ 300c943b494SChandan Uddaraju void dp_catalog_ctrl_update_transfer_unit(struct dp_catalog *dp_catalog, 301c943b494SChandan Uddaraju u32 dp_tu, u32 valid_boundary, 302c943b494SChandan Uddaraju u32 valid_boundary2) 303c943b494SChandan Uddaraju { 304c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 305c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 306c943b494SChandan Uddaraju 307c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_VALID_BOUNDARY, valid_boundary); 308c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_TU, dp_tu); 309c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_VALID_BOUNDARY_2, valid_boundary2); 310c943b494SChandan Uddaraju } 311c943b494SChandan Uddaraju 312c943b494SChandan Uddaraju void dp_catalog_ctrl_state_ctrl(struct dp_catalog *dp_catalog, u32 state) 313c943b494SChandan Uddaraju { 314c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 315c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 316c943b494SChandan Uddaraju 317c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_STATE_CTRL, state); 318c943b494SChandan Uddaraju } 319c943b494SChandan Uddaraju 320c943b494SChandan Uddaraju void dp_catalog_ctrl_config_ctrl(struct dp_catalog *dp_catalog, u32 cfg) 321c943b494SChandan Uddaraju { 322c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 323c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 324c943b494SChandan Uddaraju 325c943b494SChandan Uddaraju DRM_DEBUG_DP("DP_CONFIGURATION_CTRL=0x%x\n", cfg); 326c943b494SChandan Uddaraju 327c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_CONFIGURATION_CTRL, cfg); 328c943b494SChandan Uddaraju } 329c943b494SChandan Uddaraju 330c943b494SChandan Uddaraju void dp_catalog_ctrl_lane_mapping(struct dp_catalog *dp_catalog) 331c943b494SChandan Uddaraju { 332c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 333c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 334c943b494SChandan Uddaraju u32 ln_0 = 0, ln_1 = 1, ln_2 = 2, ln_3 = 3; /* One-to-One mapping */ 335c943b494SChandan Uddaraju u32 ln_mapping; 336c943b494SChandan Uddaraju 337c943b494SChandan Uddaraju ln_mapping = ln_0 << LANE0_MAPPING_SHIFT; 338c943b494SChandan Uddaraju ln_mapping |= ln_1 << LANE1_MAPPING_SHIFT; 339c943b494SChandan Uddaraju ln_mapping |= ln_2 << LANE2_MAPPING_SHIFT; 340c943b494SChandan Uddaraju ln_mapping |= ln_3 << LANE3_MAPPING_SHIFT; 341c943b494SChandan Uddaraju 342c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING, 343c943b494SChandan Uddaraju ln_mapping); 344c943b494SChandan Uddaraju } 345c943b494SChandan Uddaraju 346c943b494SChandan Uddaraju void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog, 347c943b494SChandan Uddaraju bool enable) 348c943b494SChandan Uddaraju { 349c943b494SChandan Uddaraju u32 mainlink_ctrl; 350c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 351c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 352c943b494SChandan Uddaraju 353601f0479SMaitreyee Rao DRM_DEBUG_DP("enable=%d\n", enable); 354c943b494SChandan Uddaraju if (enable) { 355c943b494SChandan Uddaraju /* 356c943b494SChandan Uddaraju * To make sure link reg writes happens before other operation, 357c943b494SChandan Uddaraju * dp_write_link() function uses writel() 358c943b494SChandan Uddaraju */ 3598ede2eccSKuogee Hsieh mainlink_ctrl = dp_read_link(catalog, REG_DP_MAINLINK_CTRL); 3608ede2eccSKuogee Hsieh 3618ede2eccSKuogee Hsieh mainlink_ctrl &= ~(DP_MAINLINK_CTRL_RESET | 362c943b494SChandan Uddaraju DP_MAINLINK_CTRL_ENABLE); 3638ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl); 3648ede2eccSKuogee Hsieh 3658ede2eccSKuogee Hsieh mainlink_ctrl |= DP_MAINLINK_CTRL_RESET; 3668ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl); 3678ede2eccSKuogee Hsieh 3688ede2eccSKuogee Hsieh mainlink_ctrl &= ~DP_MAINLINK_CTRL_RESET; 3698ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl); 3708ede2eccSKuogee Hsieh 3718ede2eccSKuogee Hsieh mainlink_ctrl |= (DP_MAINLINK_CTRL_ENABLE | 3728ede2eccSKuogee Hsieh DP_MAINLINK_FB_BOUNDARY_SEL); 3738ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl); 374c943b494SChandan Uddaraju } else { 375c943b494SChandan Uddaraju mainlink_ctrl = dp_read_link(catalog, REG_DP_MAINLINK_CTRL); 376c943b494SChandan Uddaraju mainlink_ctrl &= ~DP_MAINLINK_CTRL_ENABLE; 377c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl); 378c943b494SChandan Uddaraju } 379c943b494SChandan Uddaraju } 380c943b494SChandan Uddaraju 381c943b494SChandan Uddaraju void dp_catalog_ctrl_config_misc(struct dp_catalog *dp_catalog, 382c943b494SChandan Uddaraju u32 colorimetry_cfg, 383c943b494SChandan Uddaraju u32 test_bits_depth) 384c943b494SChandan Uddaraju { 385c943b494SChandan Uddaraju u32 misc_val; 386c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 387c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 388c943b494SChandan Uddaraju 389c943b494SChandan Uddaraju misc_val = dp_read_link(catalog, REG_DP_MISC1_MISC0); 390c943b494SChandan Uddaraju 391c943b494SChandan Uddaraju /* clear bpp bits */ 392c943b494SChandan Uddaraju misc_val &= ~(0x07 << DP_MISC0_TEST_BITS_DEPTH_SHIFT); 393c943b494SChandan Uddaraju misc_val |= colorimetry_cfg << DP_MISC0_COLORIMETRY_CFG_SHIFT; 394c943b494SChandan Uddaraju misc_val |= test_bits_depth << DP_MISC0_TEST_BITS_DEPTH_SHIFT; 395c943b494SChandan Uddaraju /* Configure clock to synchronous mode */ 396c943b494SChandan Uddaraju misc_val |= DP_MISC0_SYNCHRONOUS_CLK; 397c943b494SChandan Uddaraju 398c943b494SChandan Uddaraju DRM_DEBUG_DP("misc settings = 0x%x\n", misc_val); 399c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_MISC1_MISC0, misc_val); 400c943b494SChandan Uddaraju } 401c943b494SChandan Uddaraju 402c943b494SChandan Uddaraju void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, 403c943b494SChandan Uddaraju u32 rate, u32 stream_rate_khz, 404c943b494SChandan Uddaraju bool fixed_nvid) 405c943b494SChandan Uddaraju { 406c943b494SChandan Uddaraju u32 pixel_m, pixel_n; 407937f941cSStephen Boyd u32 mvid, nvid, pixel_div = 0, dispcc_input_rate; 408c943b494SChandan Uddaraju u32 const nvid_fixed = DP_LINK_CONSTANT_N_VALUE; 409c943b494SChandan Uddaraju u32 const link_rate_hbr2 = 540000; 410c943b494SChandan Uddaraju u32 const link_rate_hbr3 = 810000; 411c943b494SChandan Uddaraju unsigned long den, num; 412c943b494SChandan Uddaraju 413c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 414c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 415c943b494SChandan Uddaraju 416937f941cSStephen Boyd if (rate == link_rate_hbr3) 417c943b494SChandan Uddaraju pixel_div = 6; 418937f941cSStephen Boyd else if (rate == 1620000 || rate == 270000) 419c943b494SChandan Uddaraju pixel_div = 2; 420937f941cSStephen Boyd else if (rate == link_rate_hbr2) 421c943b494SChandan Uddaraju pixel_div = 4; 422c943b494SChandan Uddaraju else 423c943b494SChandan Uddaraju DRM_ERROR("Invalid pixel mux divider\n"); 424c943b494SChandan Uddaraju 425c943b494SChandan Uddaraju dispcc_input_rate = (rate * 10) / pixel_div; 426c943b494SChandan Uddaraju 427c943b494SChandan Uddaraju rational_best_approximation(dispcc_input_rate, stream_rate_khz, 428c943b494SChandan Uddaraju (unsigned long)(1 << 16) - 1, 429c943b494SChandan Uddaraju (unsigned long)(1 << 16) - 1, &den, &num); 430c943b494SChandan Uddaraju 431c943b494SChandan Uddaraju den = ~(den - num); 432c943b494SChandan Uddaraju den = den & 0xFFFF; 433c943b494SChandan Uddaraju pixel_m = num; 434c943b494SChandan Uddaraju pixel_n = den; 435c943b494SChandan Uddaraju 436c943b494SChandan Uddaraju mvid = (pixel_m & 0xFFFF) * 5; 437c943b494SChandan Uddaraju nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF); 438c943b494SChandan Uddaraju 439c943b494SChandan Uddaraju if (nvid < nvid_fixed) { 440c943b494SChandan Uddaraju u32 temp; 441c943b494SChandan Uddaraju 442c943b494SChandan Uddaraju temp = (nvid_fixed / nvid) * nvid; 443c943b494SChandan Uddaraju mvid = (nvid_fixed / nvid) * mvid; 444c943b494SChandan Uddaraju nvid = temp; 445c943b494SChandan Uddaraju } 446c943b494SChandan Uddaraju 447c943b494SChandan Uddaraju if (link_rate_hbr2 == rate) 448c943b494SChandan Uddaraju nvid *= 2; 449c943b494SChandan Uddaraju 450c943b494SChandan Uddaraju if (link_rate_hbr3 == rate) 451c943b494SChandan Uddaraju nvid *= 3; 452c943b494SChandan Uddaraju 453c943b494SChandan Uddaraju DRM_DEBUG_DP("mvid=0x%x, nvid=0x%x\n", mvid, nvid); 454c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_SOFTWARE_MVID, mvid); 455c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_SOFTWARE_NVID, nvid); 456c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_DSC_DTO, 0x0); 457c943b494SChandan Uddaraju } 458c943b494SChandan Uddaraju 459c943b494SChandan Uddaraju int dp_catalog_ctrl_set_pattern(struct dp_catalog *dp_catalog, 460c943b494SChandan Uddaraju u32 pattern) 461c943b494SChandan Uddaraju { 462c943b494SChandan Uddaraju int bit, ret; 463c943b494SChandan Uddaraju u32 data; 464c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 465c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 466c943b494SChandan Uddaraju 467c943b494SChandan Uddaraju bit = BIT(pattern - 1); 468c943b494SChandan Uddaraju DRM_DEBUG_DP("hw: bit=%d train=%d\n", bit, pattern); 4698ede2eccSKuogee Hsieh dp_catalog_ctrl_state_ctrl(dp_catalog, bit); 470c943b494SChandan Uddaraju 471c943b494SChandan Uddaraju bit = BIT(pattern - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT; 472c943b494SChandan Uddaraju 473c943b494SChandan Uddaraju /* Poll for mainlink ready status */ 474060c160fSBjorn Andersson ret = readx_poll_timeout(readl, catalog->io->dp_controller.link.base + 475c943b494SChandan Uddaraju REG_DP_MAINLINK_READY, 476c943b494SChandan Uddaraju data, data & bit, 477c943b494SChandan Uddaraju POLLING_SLEEP_US, POLLING_TIMEOUT_US); 478c943b494SChandan Uddaraju if (ret < 0) { 479c943b494SChandan Uddaraju DRM_ERROR("set pattern for link_train=%d failed\n", pattern); 480c943b494SChandan Uddaraju return ret; 481c943b494SChandan Uddaraju } 482c943b494SChandan Uddaraju return 0; 483c943b494SChandan Uddaraju } 484c943b494SChandan Uddaraju 4859fc41843SKuogee Hsieh /** 4869fc41843SKuogee Hsieh * dp_catalog_ctrl_reset() - reset DP controller 4879fc41843SKuogee Hsieh * 4889fc41843SKuogee Hsieh * @dp_catalog: DP catalog structure 4899fc41843SKuogee Hsieh * 4909fc41843SKuogee Hsieh * return: void 4919fc41843SKuogee Hsieh * 4929fc41843SKuogee Hsieh * This function reset the DP controller 4939fc41843SKuogee Hsieh * 4949fc41843SKuogee Hsieh * NOTE: reset DP controller will also clear any pending HPD related interrupts 4959fc41843SKuogee Hsieh * 4969fc41843SKuogee Hsieh */ 497c943b494SChandan Uddaraju void dp_catalog_ctrl_reset(struct dp_catalog *dp_catalog) 498c943b494SChandan Uddaraju { 499c943b494SChandan Uddaraju u32 sw_reset; 500c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 501c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 502c943b494SChandan Uddaraju 503c943b494SChandan Uddaraju sw_reset = dp_read_ahb(catalog, REG_DP_SW_RESET); 504c943b494SChandan Uddaraju 505c943b494SChandan Uddaraju sw_reset |= DP_SW_RESET; 506c943b494SChandan Uddaraju dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset); 507c943b494SChandan Uddaraju usleep_range(1000, 1100); /* h/w recommended delay */ 508c943b494SChandan Uddaraju 509c943b494SChandan Uddaraju sw_reset &= ~DP_SW_RESET; 510c943b494SChandan Uddaraju dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset); 511c943b494SChandan Uddaraju } 512c943b494SChandan Uddaraju 513c943b494SChandan Uddaraju bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog) 514c943b494SChandan Uddaraju { 515c943b494SChandan Uddaraju u32 data; 516c943b494SChandan Uddaraju int ret; 517c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 518c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 519c943b494SChandan Uddaraju 520c943b494SChandan Uddaraju /* Poll for mainlink ready status */ 521060c160fSBjorn Andersson ret = readl_poll_timeout(catalog->io->dp_controller.link.base + 522c943b494SChandan Uddaraju REG_DP_MAINLINK_READY, 523c943b494SChandan Uddaraju data, data & DP_MAINLINK_READY_FOR_VIDEO, 524c943b494SChandan Uddaraju POLLING_SLEEP_US, POLLING_TIMEOUT_US); 525c943b494SChandan Uddaraju if (ret < 0) { 526c943b494SChandan Uddaraju DRM_ERROR("mainlink not ready\n"); 527c943b494SChandan Uddaraju return false; 528c943b494SChandan Uddaraju } 529c943b494SChandan Uddaraju 530c943b494SChandan Uddaraju return true; 531c943b494SChandan Uddaraju } 532c943b494SChandan Uddaraju 533c943b494SChandan Uddaraju void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, 534c943b494SChandan Uddaraju bool enable) 535c943b494SChandan Uddaraju { 536c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 537c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 538c943b494SChandan Uddaraju 539c943b494SChandan Uddaraju if (enable) { 540c943b494SChandan Uddaraju dp_write_ahb(catalog, REG_DP_INTR_STATUS, 541c943b494SChandan Uddaraju DP_INTERRUPT_STATUS1_MASK); 542c943b494SChandan Uddaraju dp_write_ahb(catalog, REG_DP_INTR_STATUS2, 543c943b494SChandan Uddaraju DP_INTERRUPT_STATUS2_MASK); 544c943b494SChandan Uddaraju } else { 545c943b494SChandan Uddaraju dp_write_ahb(catalog, REG_DP_INTR_STATUS, 0x00); 546c943b494SChandan Uddaraju dp_write_ahb(catalog, REG_DP_INTR_STATUS2, 0x00); 547c943b494SChandan Uddaraju } 548c943b494SChandan Uddaraju } 549c943b494SChandan Uddaraju 550220b856aSTanmay Shah void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, 551220b856aSTanmay Shah u32 intr_mask, bool en) 552c943b494SChandan Uddaraju { 553c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 554c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 555c943b494SChandan Uddaraju 556220b856aSTanmay Shah u32 config = dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK); 557220b856aSTanmay Shah 558220b856aSTanmay Shah config = (en ? config | intr_mask : config & ~intr_mask); 559220b856aSTanmay Shah 560601f0479SMaitreyee Rao DRM_DEBUG_DP("intr_mask=%#x config=%#x\n", intr_mask, config); 561220b856aSTanmay Shah dp_write_aux(catalog, REG_DP_DP_HPD_INT_MASK, 562220b856aSTanmay Shah config & DP_DP_HPD_INT_MASK); 563220b856aSTanmay Shah } 564220b856aSTanmay Shah 565220b856aSTanmay Shah void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) 566220b856aSTanmay Shah { 567220b856aSTanmay Shah struct dp_catalog_private *catalog = container_of(dp_catalog, 568220b856aSTanmay Shah struct dp_catalog_private, dp_catalog); 569220b856aSTanmay Shah 570c943b494SChandan Uddaraju u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER); 571c943b494SChandan Uddaraju 572f21c8a27SKuogee Hsieh /* enable HPD plug and unplug interrupts */ 573220b856aSTanmay Shah dp_catalog_hpd_config_intr(dp_catalog, 574f21c8a27SKuogee Hsieh DP_DP_HPD_PLUG_INT_MASK | DP_DP_HPD_UNPLUG_INT_MASK, true); 575c943b494SChandan Uddaraju 576220b856aSTanmay Shah /* Configure REFTIMER and enable it */ 577220b856aSTanmay Shah reftimer |= DP_DP_HPD_REFTIMER_ENABLE; 578c943b494SChandan Uddaraju dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); 579220b856aSTanmay Shah 580c943b494SChandan Uddaraju /* Enable HPD */ 581220b856aSTanmay Shah dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); 582c943b494SChandan Uddaraju } 583220b856aSTanmay Shah 584231a04fcSKuogee Hsieh u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog) 58519e52bcbSKuogee Hsieh { 58619e52bcbSKuogee Hsieh struct dp_catalog_private *catalog = container_of(dp_catalog, 58719e52bcbSKuogee Hsieh struct dp_catalog_private, dp_catalog); 58819e52bcbSKuogee Hsieh u32 status; 58919e52bcbSKuogee Hsieh 59019e52bcbSKuogee Hsieh status = dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS); 591601f0479SMaitreyee Rao DRM_DEBUG_DP("aux status: %#x\n", status); 59219e52bcbSKuogee Hsieh status >>= DP_DP_HPD_STATE_STATUS_BITS_SHIFT; 59319e52bcbSKuogee Hsieh status &= DP_DP_HPD_STATE_STATUS_BITS_MASK; 59419e52bcbSKuogee Hsieh 59519e52bcbSKuogee Hsieh return status; 59619e52bcbSKuogee Hsieh } 59719e52bcbSKuogee Hsieh 598220b856aSTanmay Shah u32 dp_catalog_hpd_get_intr_status(struct dp_catalog *dp_catalog) 599220b856aSTanmay Shah { 600220b856aSTanmay Shah struct dp_catalog_private *catalog = container_of(dp_catalog, 601220b856aSTanmay Shah struct dp_catalog_private, dp_catalog); 602220b856aSTanmay Shah int isr = 0; 603220b856aSTanmay Shah 604220b856aSTanmay Shah isr = dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS); 605220b856aSTanmay Shah dp_write_aux(catalog, REG_DP_DP_HPD_INT_ACK, 606220b856aSTanmay Shah (isr & DP_DP_HPD_INT_MASK)); 607220b856aSTanmay Shah 608220b856aSTanmay Shah return isr; 609c943b494SChandan Uddaraju } 610c943b494SChandan Uddaraju 611c943b494SChandan Uddaraju int dp_catalog_ctrl_get_interrupt(struct dp_catalog *dp_catalog) 612c943b494SChandan Uddaraju { 613c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 614c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 615c943b494SChandan Uddaraju u32 intr, intr_ack; 616c943b494SChandan Uddaraju 617c943b494SChandan Uddaraju intr = dp_read_ahb(catalog, REG_DP_INTR_STATUS2); 618c943b494SChandan Uddaraju intr &= ~DP_INTERRUPT_STATUS2_MASK; 619c943b494SChandan Uddaraju intr_ack = (intr & DP_INTERRUPT_STATUS2) 620c943b494SChandan Uddaraju << DP_INTERRUPT_STATUS_ACK_SHIFT; 621c943b494SChandan Uddaraju dp_write_ahb(catalog, REG_DP_INTR_STATUS2, 622c943b494SChandan Uddaraju intr_ack | DP_INTERRUPT_STATUS2_MASK); 623c943b494SChandan Uddaraju 624c943b494SChandan Uddaraju return intr; 625c943b494SChandan Uddaraju } 626c943b494SChandan Uddaraju 627c943b494SChandan Uddaraju void dp_catalog_ctrl_phy_reset(struct dp_catalog *dp_catalog) 628c943b494SChandan Uddaraju { 629c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 630c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 631c943b494SChandan Uddaraju 632c943b494SChandan Uddaraju dp_write_ahb(catalog, REG_DP_PHY_CTRL, 633937f941cSStephen Boyd DP_PHY_CTRL_SW_RESET | DP_PHY_CTRL_SW_RESET_PLL); 634c943b494SChandan Uddaraju usleep_range(1000, 1100); /* h/w recommended delay */ 635c943b494SChandan Uddaraju dp_write_ahb(catalog, REG_DP_PHY_CTRL, 0x0); 636c943b494SChandan Uddaraju } 637c943b494SChandan Uddaraju 638c943b494SChandan Uddaraju int dp_catalog_ctrl_update_vx_px(struct dp_catalog *dp_catalog, 639c943b494SChandan Uddaraju u8 v_level, u8 p_level) 640c943b494SChandan Uddaraju { 641c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 642c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 643937f941cSStephen Boyd struct dp_io *dp_io = catalog->io; 644937f941cSStephen Boyd struct phy *phy = dp_io->phy; 645937f941cSStephen Boyd struct phy_configure_opts_dp *opts_dp = &dp_io->phy_opts.dp; 646c943b494SChandan Uddaraju 647937f941cSStephen Boyd /* TODO: Update for all lanes instead of just first one */ 648937f941cSStephen Boyd opts_dp->voltage[0] = v_level; 649937f941cSStephen Boyd opts_dp->pre[0] = p_level; 650937f941cSStephen Boyd opts_dp->set_voltages = 1; 651937f941cSStephen Boyd phy_configure(phy, &dp_io->phy_opts); 652937f941cSStephen Boyd opts_dp->set_voltages = 0; 653c943b494SChandan Uddaraju 654c943b494SChandan Uddaraju return 0; 655c943b494SChandan Uddaraju } 656c943b494SChandan Uddaraju 657c943b494SChandan Uddaraju void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog *dp_catalog, 658c943b494SChandan Uddaraju u32 pattern) 659c943b494SChandan Uddaraju { 660c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 661c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 662c943b494SChandan Uddaraju u32 value = 0x0; 663c943b494SChandan Uddaraju 664c943b494SChandan Uddaraju /* Make sure to clear the current pattern before starting a new one */ 665c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_STATE_CTRL, 0x0); 666c943b494SChandan Uddaraju 667601f0479SMaitreyee Rao DRM_DEBUG_DP("pattern: %#x\n", pattern); 668c943b494SChandan Uddaraju switch (pattern) { 6698ede2eccSKuogee Hsieh case DP_PHY_TEST_PATTERN_D10_2: 670c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_STATE_CTRL, 671c943b494SChandan Uddaraju DP_STATE_CTRL_LINK_TRAINING_PATTERN1); 6728ede2eccSKuogee Hsieh break; 6738ede2eccSKuogee Hsieh case DP_PHY_TEST_PATTERN_ERROR_COUNT: 6748ede2eccSKuogee Hsieh value &= ~(1 << 16); 6758ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, 6768ede2eccSKuogee Hsieh value); 6778ede2eccSKuogee Hsieh value |= SCRAMBLER_RESET_COUNT_VALUE; 6788ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, 6798ede2eccSKuogee Hsieh value); 6808ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_MAINLINK_LEVELS, 6818ede2eccSKuogee Hsieh DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2); 6828ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_STATE_CTRL, 6838ede2eccSKuogee Hsieh DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE); 6848ede2eccSKuogee Hsieh break; 6858ede2eccSKuogee Hsieh case DP_PHY_TEST_PATTERN_PRBS7: 686c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_STATE_CTRL, 687c943b494SChandan Uddaraju DP_STATE_CTRL_LINK_PRBS7); 6888ede2eccSKuogee Hsieh break; 6898ede2eccSKuogee Hsieh case DP_PHY_TEST_PATTERN_80BIT_CUSTOM: 690c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_STATE_CTRL, 691c943b494SChandan Uddaraju DP_STATE_CTRL_LINK_TEST_CUSTOM_PATTERN); 692c943b494SChandan Uddaraju /* 00111110000011111000001111100000 */ 693c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0, 694c943b494SChandan Uddaraju 0x3E0F83E0); 695c943b494SChandan Uddaraju /* 00001111100000111110000011111000 */ 696c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1, 697c943b494SChandan Uddaraju 0x0F83E0F8); 698c943b494SChandan Uddaraju /* 1111100000111110 */ 699c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2, 700c943b494SChandan Uddaraju 0x0000F83E); 7018ede2eccSKuogee Hsieh break; 7028ede2eccSKuogee Hsieh case DP_PHY_TEST_PATTERN_CP2520: 7038ede2eccSKuogee Hsieh value = dp_read_link(catalog, REG_DP_MAINLINK_CTRL); 7048ede2eccSKuogee Hsieh value &= ~DP_MAINLINK_CTRL_SW_BYPASS_SCRAMBLER; 7058ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value); 7068ede2eccSKuogee Hsieh 707c943b494SChandan Uddaraju value = DP_HBR2_ERM_PATTERN; 708c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, 709c943b494SChandan Uddaraju value); 710c943b494SChandan Uddaraju value |= SCRAMBLER_RESET_COUNT_VALUE; 711c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, 712c943b494SChandan Uddaraju value); 713c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_MAINLINK_LEVELS, 714c943b494SChandan Uddaraju DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2); 715c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_STATE_CTRL, 716c943b494SChandan Uddaraju DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE); 7178ede2eccSKuogee Hsieh value = dp_read_link(catalog, REG_DP_MAINLINK_CTRL); 7188ede2eccSKuogee Hsieh value |= DP_MAINLINK_CTRL_ENABLE; 7198ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value); 7208ede2eccSKuogee Hsieh break; 7218ede2eccSKuogee Hsieh case DP_PHY_TEST_PATTERN_SEL_MASK: 7228ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_MAINLINK_CTRL, 7238ede2eccSKuogee Hsieh DP_MAINLINK_CTRL_ENABLE); 7248ede2eccSKuogee Hsieh dp_write_link(catalog, REG_DP_STATE_CTRL, 7258ede2eccSKuogee Hsieh DP_STATE_CTRL_LINK_TRAINING_PATTERN4); 7268ede2eccSKuogee Hsieh break; 727c943b494SChandan Uddaraju default: 728601f0479SMaitreyee Rao DRM_DEBUG_DP("No valid test pattern requested: %#x\n", pattern); 7298ede2eccSKuogee Hsieh break; 730c943b494SChandan Uddaraju } 731c943b494SChandan Uddaraju } 732c943b494SChandan Uddaraju 733c943b494SChandan Uddaraju u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog *dp_catalog) 734c943b494SChandan Uddaraju { 735c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 736c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 737c943b494SChandan Uddaraju 738c943b494SChandan Uddaraju return dp_read_link(catalog, REG_DP_MAINLINK_READY); 739c943b494SChandan Uddaraju } 740c943b494SChandan Uddaraju 741c943b494SChandan Uddaraju /* panel related catalog functions */ 742c943b494SChandan Uddaraju int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog) 743c943b494SChandan Uddaraju { 744c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 745c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 746c943b494SChandan Uddaraju 747c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_TOTAL_HOR_VER, 748c943b494SChandan Uddaraju dp_catalog->total); 749c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_START_HOR_VER_FROM_SYNC, 750c943b494SChandan Uddaraju dp_catalog->sync_start); 751c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, 752c943b494SChandan Uddaraju dp_catalog->width_blanking); 753c943b494SChandan Uddaraju dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, dp_catalog->dp_active); 754f9a39932SBjorn Andersson dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0); 755c943b494SChandan Uddaraju return 0; 756c943b494SChandan Uddaraju } 757c943b494SChandan Uddaraju 758c943b494SChandan Uddaraju void dp_catalog_panel_tpg_enable(struct dp_catalog *dp_catalog, 759c943b494SChandan Uddaraju struct drm_display_mode *drm_mode) 760c943b494SChandan Uddaraju { 761c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 762c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 763c943b494SChandan Uddaraju u32 hsync_period, vsync_period; 764c943b494SChandan Uddaraju u32 display_v_start, display_v_end; 765c943b494SChandan Uddaraju u32 hsync_start_x, hsync_end_x; 766c943b494SChandan Uddaraju u32 v_sync_width; 767c943b494SChandan Uddaraju u32 hsync_ctl; 768c943b494SChandan Uddaraju u32 display_hctl; 769c943b494SChandan Uddaraju 770c943b494SChandan Uddaraju /* TPG config parameters*/ 771c943b494SChandan Uddaraju hsync_period = drm_mode->htotal; 772c943b494SChandan Uddaraju vsync_period = drm_mode->vtotal; 773c943b494SChandan Uddaraju 774c943b494SChandan Uddaraju display_v_start = ((drm_mode->vtotal - drm_mode->vsync_start) * 775c943b494SChandan Uddaraju hsync_period); 776c943b494SChandan Uddaraju display_v_end = ((vsync_period - (drm_mode->vsync_start - 777c943b494SChandan Uddaraju drm_mode->vdisplay)) 778c943b494SChandan Uddaraju * hsync_period) - 1; 779c943b494SChandan Uddaraju 780c943b494SChandan Uddaraju display_v_start += drm_mode->htotal - drm_mode->hsync_start; 781c943b494SChandan Uddaraju display_v_end -= (drm_mode->hsync_start - drm_mode->hdisplay); 782c943b494SChandan Uddaraju 783c943b494SChandan Uddaraju hsync_start_x = drm_mode->htotal - drm_mode->hsync_start; 784c943b494SChandan Uddaraju hsync_end_x = hsync_period - (drm_mode->hsync_start - 785c943b494SChandan Uddaraju drm_mode->hdisplay) - 1; 786c943b494SChandan Uddaraju 787c943b494SChandan Uddaraju v_sync_width = drm_mode->vsync_end - drm_mode->vsync_start; 788c943b494SChandan Uddaraju 789c943b494SChandan Uddaraju hsync_ctl = (hsync_period << 16) | 790c943b494SChandan Uddaraju (drm_mode->hsync_end - drm_mode->hsync_start); 791c943b494SChandan Uddaraju display_hctl = (hsync_end_x << 16) | hsync_start_x; 792c943b494SChandan Uddaraju 793c943b494SChandan Uddaraju 794c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0x0); 795c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_HSYNC_CTL, hsync_ctl); 796c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F0, vsync_period * 797c943b494SChandan Uddaraju hsync_period); 798c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F0, v_sync_width * 799c943b494SChandan Uddaraju hsync_period); 800c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F1, 0); 801c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F1, 0); 802c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_HCTL, display_hctl); 803c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_HCTL, 0); 804c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F0, display_v_start); 805c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F0, display_v_end); 806c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F1, 0); 807c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F1, 0); 808c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F0, 0); 809c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F0, 0); 810c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F1, 0); 811c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F1, 0); 812c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_INTF_POLARITY_CTL, 0); 813c943b494SChandan Uddaraju 814c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL, 815c943b494SChandan Uddaraju DP_TPG_CHECKERED_RECT_PATTERN); 816c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_TPG_VIDEO_CONFIG, 817c943b494SChandan Uddaraju DP_TPG_VIDEO_CONFIG_BPP_8BIT | 818c943b494SChandan Uddaraju DP_TPG_VIDEO_CONFIG_RGB); 819c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_BIST_ENABLE, 820c943b494SChandan Uddaraju DP_BIST_ENABLE_DPBIST_EN); 821c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN, 822c943b494SChandan Uddaraju DP_TIMING_ENGINE_EN_EN); 823c943b494SChandan Uddaraju DRM_DEBUG_DP("%s: enabled tpg\n", __func__); 824c943b494SChandan Uddaraju } 825c943b494SChandan Uddaraju 826c943b494SChandan Uddaraju void dp_catalog_panel_tpg_disable(struct dp_catalog *dp_catalog) 827c943b494SChandan Uddaraju { 828c943b494SChandan Uddaraju struct dp_catalog_private *catalog = container_of(dp_catalog, 829c943b494SChandan Uddaraju struct dp_catalog_private, dp_catalog); 830c943b494SChandan Uddaraju 831c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL, 0x0); 832c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_BIST_ENABLE, 0x0); 833c943b494SChandan Uddaraju dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN, 0x0); 834c943b494SChandan Uddaraju } 835c943b494SChandan Uddaraju 836c943b494SChandan Uddaraju struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io *io) 837c943b494SChandan Uddaraju { 838c943b494SChandan Uddaraju struct dp_catalog_private *catalog; 839c943b494SChandan Uddaraju 840c943b494SChandan Uddaraju if (!io) { 841c943b494SChandan Uddaraju DRM_ERROR("invalid input\n"); 842c943b494SChandan Uddaraju return ERR_PTR(-EINVAL); 843c943b494SChandan Uddaraju } 844c943b494SChandan Uddaraju 845c943b494SChandan Uddaraju catalog = devm_kzalloc(dev, sizeof(*catalog), GFP_KERNEL); 846c943b494SChandan Uddaraju if (!catalog) 847c943b494SChandan Uddaraju return ERR_PTR(-ENOMEM); 848c943b494SChandan Uddaraju 849c943b494SChandan Uddaraju catalog->dev = dev; 850c943b494SChandan Uddaraju catalog->io = io; 851c943b494SChandan Uddaraju 852c943b494SChandan Uddaraju return &catalog->dp_catalog; 853c943b494SChandan Uddaraju } 854d13e36d7SAbhinav Kumar 855d13e36d7SAbhinav Kumar void dp_catalog_audio_get_header(struct dp_catalog *dp_catalog) 856d13e36d7SAbhinav Kumar { 857d13e36d7SAbhinav Kumar struct dp_catalog_private *catalog; 858d13e36d7SAbhinav Kumar u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX]; 859d13e36d7SAbhinav Kumar enum dp_catalog_audio_sdp_type sdp; 860d13e36d7SAbhinav Kumar enum dp_catalog_audio_header_type header; 861d13e36d7SAbhinav Kumar 862d13e36d7SAbhinav Kumar if (!dp_catalog) 863d13e36d7SAbhinav Kumar return; 864d13e36d7SAbhinav Kumar 865d13e36d7SAbhinav Kumar catalog = container_of(dp_catalog, 866d13e36d7SAbhinav Kumar struct dp_catalog_private, dp_catalog); 867d13e36d7SAbhinav Kumar 868d13e36d7SAbhinav Kumar sdp_map = catalog->audio_map; 869d13e36d7SAbhinav Kumar sdp = dp_catalog->sdp_type; 870d13e36d7SAbhinav Kumar header = dp_catalog->sdp_header; 871d13e36d7SAbhinav Kumar 872d13e36d7SAbhinav Kumar dp_catalog->audio_data = dp_read_link(catalog, 873d13e36d7SAbhinav Kumar sdp_map[sdp][header]); 874d13e36d7SAbhinav Kumar } 875d13e36d7SAbhinav Kumar 876d13e36d7SAbhinav Kumar void dp_catalog_audio_set_header(struct dp_catalog *dp_catalog) 877d13e36d7SAbhinav Kumar { 878d13e36d7SAbhinav Kumar struct dp_catalog_private *catalog; 879d13e36d7SAbhinav Kumar u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX]; 880d13e36d7SAbhinav Kumar enum dp_catalog_audio_sdp_type sdp; 881d13e36d7SAbhinav Kumar enum dp_catalog_audio_header_type header; 882d13e36d7SAbhinav Kumar u32 data; 883d13e36d7SAbhinav Kumar 884d13e36d7SAbhinav Kumar if (!dp_catalog) 885d13e36d7SAbhinav Kumar return; 886d13e36d7SAbhinav Kumar 887d13e36d7SAbhinav Kumar catalog = container_of(dp_catalog, 888d13e36d7SAbhinav Kumar struct dp_catalog_private, dp_catalog); 889d13e36d7SAbhinav Kumar 890d13e36d7SAbhinav Kumar sdp_map = catalog->audio_map; 891d13e36d7SAbhinav Kumar sdp = dp_catalog->sdp_type; 892d13e36d7SAbhinav Kumar header = dp_catalog->sdp_header; 893d13e36d7SAbhinav Kumar data = dp_catalog->audio_data; 894d13e36d7SAbhinav Kumar 895d13e36d7SAbhinav Kumar dp_write_link(catalog, sdp_map[sdp][header], data); 896d13e36d7SAbhinav Kumar } 897d13e36d7SAbhinav Kumar 898d13e36d7SAbhinav Kumar void dp_catalog_audio_config_acr(struct dp_catalog *dp_catalog) 899d13e36d7SAbhinav Kumar { 900d13e36d7SAbhinav Kumar struct dp_catalog_private *catalog; 901d13e36d7SAbhinav Kumar u32 acr_ctrl, select; 902d13e36d7SAbhinav Kumar 903d13e36d7SAbhinav Kumar if (!dp_catalog) 904d13e36d7SAbhinav Kumar return; 905d13e36d7SAbhinav Kumar 906d13e36d7SAbhinav Kumar catalog = container_of(dp_catalog, 907d13e36d7SAbhinav Kumar struct dp_catalog_private, dp_catalog); 908d13e36d7SAbhinav Kumar 909d13e36d7SAbhinav Kumar select = dp_catalog->audio_data; 910d13e36d7SAbhinav Kumar acr_ctrl = select << 4 | BIT(31) | BIT(8) | BIT(14); 911d13e36d7SAbhinav Kumar 912601f0479SMaitreyee Rao DRM_DEBUG_DP("select: %#x, acr_ctrl: %#x\n", select, acr_ctrl); 913d13e36d7SAbhinav Kumar 914d13e36d7SAbhinav Kumar dp_write_link(catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl); 915d13e36d7SAbhinav Kumar } 916d13e36d7SAbhinav Kumar 917d13e36d7SAbhinav Kumar void dp_catalog_audio_enable(struct dp_catalog *dp_catalog) 918d13e36d7SAbhinav Kumar { 919d13e36d7SAbhinav Kumar struct dp_catalog_private *catalog; 920d13e36d7SAbhinav Kumar bool enable; 921d13e36d7SAbhinav Kumar u32 audio_ctrl; 922d13e36d7SAbhinav Kumar 923d13e36d7SAbhinav Kumar if (!dp_catalog) 924d13e36d7SAbhinav Kumar return; 925d13e36d7SAbhinav Kumar 926d13e36d7SAbhinav Kumar catalog = container_of(dp_catalog, 927d13e36d7SAbhinav Kumar struct dp_catalog_private, dp_catalog); 928d13e36d7SAbhinav Kumar 929d13e36d7SAbhinav Kumar enable = !!dp_catalog->audio_data; 930d13e36d7SAbhinav Kumar audio_ctrl = dp_read_link(catalog, MMSS_DP_AUDIO_CFG); 931d13e36d7SAbhinav Kumar 932d13e36d7SAbhinav Kumar if (enable) 933d13e36d7SAbhinav Kumar audio_ctrl |= BIT(0); 934d13e36d7SAbhinav Kumar else 935d13e36d7SAbhinav Kumar audio_ctrl &= ~BIT(0); 936d13e36d7SAbhinav Kumar 937d13e36d7SAbhinav Kumar DRM_DEBUG_DP("dp_audio_cfg = 0x%x\n", audio_ctrl); 938d13e36d7SAbhinav Kumar 939d13e36d7SAbhinav Kumar dp_write_link(catalog, MMSS_DP_AUDIO_CFG, audio_ctrl); 940d13e36d7SAbhinav Kumar /* make sure audio engine is disabled */ 941d13e36d7SAbhinav Kumar wmb(); 942d13e36d7SAbhinav Kumar } 943d13e36d7SAbhinav Kumar 944d13e36d7SAbhinav Kumar void dp_catalog_audio_config_sdp(struct dp_catalog *dp_catalog) 945d13e36d7SAbhinav Kumar { 946d13e36d7SAbhinav Kumar struct dp_catalog_private *catalog; 947d13e36d7SAbhinav Kumar u32 sdp_cfg = 0; 948d13e36d7SAbhinav Kumar u32 sdp_cfg2 = 0; 949d13e36d7SAbhinav Kumar 950d13e36d7SAbhinav Kumar if (!dp_catalog) 951d13e36d7SAbhinav Kumar return; 952d13e36d7SAbhinav Kumar 953d13e36d7SAbhinav Kumar catalog = container_of(dp_catalog, 954d13e36d7SAbhinav Kumar struct dp_catalog_private, dp_catalog); 955d13e36d7SAbhinav Kumar 956d13e36d7SAbhinav Kumar sdp_cfg = dp_read_link(catalog, MMSS_DP_SDP_CFG); 957d13e36d7SAbhinav Kumar /* AUDIO_TIMESTAMP_SDP_EN */ 958d13e36d7SAbhinav Kumar sdp_cfg |= BIT(1); 959d13e36d7SAbhinav Kumar /* AUDIO_STREAM_SDP_EN */ 960d13e36d7SAbhinav Kumar sdp_cfg |= BIT(2); 961d13e36d7SAbhinav Kumar /* AUDIO_COPY_MANAGEMENT_SDP_EN */ 962d13e36d7SAbhinav Kumar sdp_cfg |= BIT(5); 963d13e36d7SAbhinav Kumar /* AUDIO_ISRC_SDP_EN */ 964d13e36d7SAbhinav Kumar sdp_cfg |= BIT(6); 965d13e36d7SAbhinav Kumar /* AUDIO_INFOFRAME_SDP_EN */ 966d13e36d7SAbhinav Kumar sdp_cfg |= BIT(20); 967d13e36d7SAbhinav Kumar 968d13e36d7SAbhinav Kumar DRM_DEBUG_DP("sdp_cfg = 0x%x\n", sdp_cfg); 969d13e36d7SAbhinav Kumar 970d13e36d7SAbhinav Kumar dp_write_link(catalog, MMSS_DP_SDP_CFG, sdp_cfg); 971d13e36d7SAbhinav Kumar 972d13e36d7SAbhinav Kumar sdp_cfg2 = dp_read_link(catalog, MMSS_DP_SDP_CFG2); 973d13e36d7SAbhinav Kumar /* IFRM_REGSRC -> Do not use reg values */ 974d13e36d7SAbhinav Kumar sdp_cfg2 &= ~BIT(0); 975d13e36d7SAbhinav Kumar /* AUDIO_STREAM_HB3_REGSRC-> Do not use reg values */ 976d13e36d7SAbhinav Kumar sdp_cfg2 &= ~BIT(1); 977d13e36d7SAbhinav Kumar 978d13e36d7SAbhinav Kumar DRM_DEBUG_DP("sdp_cfg2 = 0x%x\n", sdp_cfg2); 979d13e36d7SAbhinav Kumar 980d13e36d7SAbhinav Kumar dp_write_link(catalog, MMSS_DP_SDP_CFG2, sdp_cfg2); 981d13e36d7SAbhinav Kumar } 982d13e36d7SAbhinav Kumar 983d13e36d7SAbhinav Kumar void dp_catalog_audio_init(struct dp_catalog *dp_catalog) 984d13e36d7SAbhinav Kumar { 985d13e36d7SAbhinav Kumar struct dp_catalog_private *catalog; 986d13e36d7SAbhinav Kumar 987d13e36d7SAbhinav Kumar static u32 sdp_map[][DP_AUDIO_SDP_HEADER_MAX] = { 988d13e36d7SAbhinav Kumar { 989d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_STREAM_0, 990d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_STREAM_1, 991d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_STREAM_1, 992d13e36d7SAbhinav Kumar }, 993d13e36d7SAbhinav Kumar { 994d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_TIMESTAMP_0, 995d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_TIMESTAMP_1, 996d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_TIMESTAMP_1, 997d13e36d7SAbhinav Kumar }, 998d13e36d7SAbhinav Kumar { 999d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_INFOFRAME_0, 1000d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_INFOFRAME_1, 1001d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_INFOFRAME_1, 1002d13e36d7SAbhinav Kumar }, 1003d13e36d7SAbhinav Kumar { 1004d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_COPYMANAGEMENT_0, 1005d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_COPYMANAGEMENT_1, 1006d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_COPYMANAGEMENT_1, 1007d13e36d7SAbhinav Kumar }, 1008d13e36d7SAbhinav Kumar { 1009d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_ISRC_0, 1010d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_ISRC_1, 1011d13e36d7SAbhinav Kumar MMSS_DP_AUDIO_ISRC_1, 1012d13e36d7SAbhinav Kumar }, 1013d13e36d7SAbhinav Kumar }; 1014d13e36d7SAbhinav Kumar 1015d13e36d7SAbhinav Kumar if (!dp_catalog) 1016d13e36d7SAbhinav Kumar return; 1017d13e36d7SAbhinav Kumar 1018d13e36d7SAbhinav Kumar catalog = container_of(dp_catalog, 1019d13e36d7SAbhinav Kumar struct dp_catalog_private, dp_catalog); 1020d13e36d7SAbhinav Kumar 1021d13e36d7SAbhinav Kumar catalog->audio_map = sdp_map; 1022d13e36d7SAbhinav Kumar } 1023d13e36d7SAbhinav Kumar 1024d13e36d7SAbhinav Kumar void dp_catalog_audio_sfe_level(struct dp_catalog *dp_catalog) 1025d13e36d7SAbhinav Kumar { 1026d13e36d7SAbhinav Kumar struct dp_catalog_private *catalog; 1027d13e36d7SAbhinav Kumar u32 mainlink_levels, safe_to_exit_level; 1028d13e36d7SAbhinav Kumar 1029d13e36d7SAbhinav Kumar if (!dp_catalog) 1030d13e36d7SAbhinav Kumar return; 1031d13e36d7SAbhinav Kumar 1032d13e36d7SAbhinav Kumar catalog = container_of(dp_catalog, 1033d13e36d7SAbhinav Kumar struct dp_catalog_private, dp_catalog); 1034d13e36d7SAbhinav Kumar 1035d13e36d7SAbhinav Kumar safe_to_exit_level = dp_catalog->audio_data; 1036d13e36d7SAbhinav Kumar mainlink_levels = dp_read_link(catalog, REG_DP_MAINLINK_LEVELS); 1037d13e36d7SAbhinav Kumar mainlink_levels &= 0xFE0; 1038d13e36d7SAbhinav Kumar mainlink_levels |= safe_to_exit_level; 1039d13e36d7SAbhinav Kumar 1040d13e36d7SAbhinav Kumar DRM_DEBUG_DP("mainlink_level = 0x%x, safe_to_exit_level = 0x%x\n", 1041d13e36d7SAbhinav Kumar mainlink_levels, safe_to_exit_level); 1042d13e36d7SAbhinav Kumar 1043d13e36d7SAbhinav Kumar dp_write_link(catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels); 1044d13e36d7SAbhinav Kumar } 1045