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