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