1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include "i915_drv.h" 7 #include "i915_reg.h" 8 9 #include "intel_de.h" 10 #include "intel_display.h" 11 #include "intel_dkl_phy.h" 12 #include "intel_dkl_phy_regs.h" 13 14 static void 15 dkl_phy_set_hip_idx(struct drm_i915_private *i915, i915_reg_t reg, int idx) 16 { 17 enum tc_port tc_port = DKL_REG_TC_PORT(reg); 18 19 drm_WARN_ON(&i915->drm, tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS); 20 21 intel_de_write(i915, 22 HIP_INDEX_REG(tc_port), 23 HIP_INDEX_VAL(tc_port, idx)); 24 } 25 26 /** 27 * intel_dkl_phy_read - read a Dekel PHY register 28 * @i915: i915 device instance 29 * @reg: Dekel PHY register 30 * @ln: lane instance of @reg 31 * 32 * Read the @reg Dekel PHY register. 33 * 34 * Returns the read value. 35 */ 36 u32 37 intel_dkl_phy_read(struct drm_i915_private *i915, i915_reg_t reg, int ln) 38 { 39 u32 val; 40 41 spin_lock(&i915->display.dkl.phy_lock); 42 43 dkl_phy_set_hip_idx(i915, reg, ln); 44 val = intel_de_read(i915, reg); 45 46 spin_unlock(&i915->display.dkl.phy_lock); 47 48 return val; 49 } 50 51 /** 52 * intel_dkl_phy_write - write a Dekel PHY register 53 * @i915: i915 device instance 54 * @reg: Dekel PHY register 55 * @ln: lane instance of @reg 56 * @val: value to write 57 * 58 * Write @val to the @reg Dekel PHY register. 59 */ 60 void 61 intel_dkl_phy_write(struct drm_i915_private *i915, i915_reg_t reg, int ln, u32 val) 62 { 63 spin_lock(&i915->display.dkl.phy_lock); 64 65 dkl_phy_set_hip_idx(i915, reg, ln); 66 intel_de_write(i915, reg, val); 67 68 spin_unlock(&i915->display.dkl.phy_lock); 69 } 70 71 /** 72 * intel_dkl_phy_rmw - read-modify-write a Dekel PHY register 73 * @i915: i915 device instance 74 * @reg: Dekel PHY register 75 * @ln: lane instance of @reg 76 * @clear: mask to clear 77 * @set: mask to set 78 * 79 * Read the @reg Dekel PHY register, clearing then setting the @clear/@set bits in it, and writing 80 * this value back to the register if the value differs from the read one. 81 */ 82 void 83 intel_dkl_phy_rmw(struct drm_i915_private *i915, i915_reg_t reg, int ln, u32 clear, u32 set) 84 { 85 spin_lock(&i915->display.dkl.phy_lock); 86 87 dkl_phy_set_hip_idx(i915, reg, ln); 88 intel_de_rmw(i915, reg, clear, set); 89 90 spin_unlock(&i915->display.dkl.phy_lock); 91 } 92 93 /** 94 * intel_dkl_phy_posting_read - do a posting read from a Dekel PHY register 95 * @i915: i915 device instance 96 * @reg: Dekel PHY register 97 * @ln: lane instance of @reg 98 * 99 * Read the @reg Dekel PHY register without returning the read value. 100 */ 101 void 102 intel_dkl_phy_posting_read(struct drm_i915_private *i915, i915_reg_t reg, int ln) 103 { 104 spin_lock(&i915->display.dkl.phy_lock); 105 106 dkl_phy_set_hip_idx(i915, reg, ln); 107 intel_de_posting_read(i915, reg); 108 109 spin_unlock(&i915->display.dkl.phy_lock); 110 } 111