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