xref: /linux/drivers/gpu/drm/i915/display/intel_dkl_phy.c (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
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  */
intel_dkl_phy_init(struct intel_display * display)18 void intel_dkl_phy_init(struct intel_display *display)
19 {
20 	spin_lock_init(&display->dkl.phy_lock);
21 }
22 
23 static void
dkl_phy_set_hip_idx(struct intel_display * display,struct intel_dkl_phy_reg reg)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
intel_dkl_phy_read(struct intel_display * display,struct intel_dkl_phy_reg reg)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
intel_dkl_phy_write(struct intel_display * display,struct intel_dkl_phy_reg reg,u32 val)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
intel_dkl_phy_rmw(struct intel_display * display,struct intel_dkl_phy_reg reg,u32 clear,u32 set)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
intel_dkl_phy_posting_read(struct intel_display * display,struct intel_dkl_phy_reg reg)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