File: | dev/pci/drm/i915/display/icl_dsi.c |
Warning: | line 190, column 27 Value stored to 'i915' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright © 2018 Intel Corporation |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
11 | * The above copyright notice and this permission notice (including the next |
12 | * paragraph) shall be included in all copies or substantial portions of the |
13 | * Software. |
14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
21 | * DEALINGS IN THE SOFTWARE. |
22 | * |
23 | * Authors: |
24 | * Madhav Chauhan <madhav.chauhan@intel.com> |
25 | * Jani Nikula <jani.nikula@intel.com> |
26 | */ |
27 | |
28 | #include <drm/drm_atomic_helper.h> |
29 | #include <drm/drm_mipi_dsi.h> |
30 | |
31 | #include "intel_atomic.h" |
32 | #include "intel_combo_phy.h" |
33 | #include "intel_connector.h" |
34 | #include "intel_ddi.h" |
35 | #include "intel_dsi.h" |
36 | #include "intel_panel.h" |
37 | #include "intel_vdsc.h" |
38 | |
39 | static int header_credits_available(struct drm_i915_privateinteldrm_softc *dev_priv, |
40 | enum transcoder dsi_trans) |
41 | { |
42 | return (intel_de_read(dev_priv, DSI_CMD_TXCTL(dsi_trans)((const i915_reg_t){ .reg = (((0x6b0d0) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b8d0) - (0x6b0d0)))) })) & FREE_HEADER_CREDIT_MASK(0x1f << 8)) |
43 | >> FREE_HEADER_CREDIT_SHIFT0x8; |
44 | } |
45 | |
46 | static int payload_credits_available(struct drm_i915_privateinteldrm_softc *dev_priv, |
47 | enum transcoder dsi_trans) |
48 | { |
49 | return (intel_de_read(dev_priv, DSI_CMD_TXCTL(dsi_trans)((const i915_reg_t){ .reg = (((0x6b0d0) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b8d0) - (0x6b0d0)))) })) & FREE_PLOAD_CREDIT_MASK(0xff << 0)) |
50 | >> FREE_PLOAD_CREDIT_SHIFT0; |
51 | } |
52 | |
53 | static void wait_for_header_credits(struct drm_i915_privateinteldrm_softc *dev_priv, |
54 | enum transcoder dsi_trans) |
55 | { |
56 | if (wait_for_us(header_credits_available(dev_priv, dsi_trans) >=({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 100))) ? 1 : -1 ] __attribute__((__unused__)); if ((100) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((100)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((header_credits_available (dev_priv, dsi_trans) >= 0x10))) { ret__ = 0; break; } if ( expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; } ); else ret__ = ({ int cpu, ret, timeout = ((100)) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof (struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock(); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile("" : : : "memory"); if ((header_credits_available (dev_priv, dsi_trans) >= 0x10)) { ret = 0; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if ( !(0)) { ; if (__builtin_expect(!!(cpu != (({struct cpu_info * __ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof (struct cpu_info, ci_self))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = (({struct cpu_info *__ci; asm volatile( "movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); base = local_clock (); } } } ret; }); ret__; }) |
57 | MAX_HEADER_CREDIT, 100)({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 100))) ? 1 : -1 ] __attribute__((__unused__)); if ((100) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((100)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((header_credits_available (dev_priv, dsi_trans) >= 0x10))) { ret__ = 0; break; } if ( expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; } ); else ret__ = ({ int cpu, ret, timeout = ((100)) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof (struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock(); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile("" : : : "memory"); if ((header_credits_available (dev_priv, dsi_trans) >= 0x10)) { ret = 0; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if ( !(0)) { ; if (__builtin_expect(!!(cpu != (({struct cpu_info * __ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof (struct cpu_info, ci_self))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = (({struct cpu_info *__ci; asm volatile( "movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); base = local_clock (); } } } ret; }); ret__; })) |
58 | drm_err(&dev_priv->drm, "DSI header credits not released\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DSI header credits not released\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
59 | } |
60 | |
61 | static void wait_for_payload_credits(struct drm_i915_privateinteldrm_softc *dev_priv, |
62 | enum transcoder dsi_trans) |
63 | { |
64 | if (wait_for_us(payload_credits_available(dev_priv, dsi_trans) >=({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 100))) ? 1 : -1 ] __attribute__((__unused__)); if ((100) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((100)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((payload_credits_available (dev_priv, dsi_trans) >= 0x40))) { ret__ = 0; break; } if ( expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; } ); else ret__ = ({ int cpu, ret, timeout = ((100)) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof (struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock(); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile("" : : : "memory"); if ((payload_credits_available (dev_priv, dsi_trans) >= 0x40)) { ret = 0; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if ( !(0)) { ; if (__builtin_expect(!!(cpu != (({struct cpu_info * __ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof (struct cpu_info, ci_self))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = (({struct cpu_info *__ci; asm volatile( "movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); base = local_clock (); } } } ret; }); ret__; }) |
65 | MAX_PLOAD_CREDIT, 100)({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 100))) ? 1 : -1 ] __attribute__((__unused__)); if ((100) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((100)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((payload_credits_available (dev_priv, dsi_trans) >= 0x40))) { ret__ = 0; break; } if ( expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; } ); else ret__ = ({ int cpu, ret, timeout = ((100)) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof (struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock(); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile("" : : : "memory"); if ((payload_credits_available (dev_priv, dsi_trans) >= 0x40)) { ret = 0; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if ( !(0)) { ; if (__builtin_expect(!!(cpu != (({struct cpu_info * __ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof (struct cpu_info, ci_self))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = (({struct cpu_info *__ci; asm volatile( "movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); base = local_clock (); } } } ret; }); ret__; })) |
66 | drm_err(&dev_priv->drm, "DSI payload credits not released\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DSI payload credits not released\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
67 | } |
68 | |
69 | static enum transcoder dsi_port_to_transcoder(enum port port) |
70 | { |
71 | if (port == PORT_A) |
72 | return TRANSCODER_DSI_0; |
73 | else |
74 | return TRANSCODER_DSI_1; |
75 | } |
76 | |
77 | static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder) |
78 | { |
79 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
80 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
81 | struct mipi_dsi_device *dsi; |
82 | enum port port; |
83 | enum transcoder dsi_trans; |
84 | int ret; |
85 | |
86 | /* wait for header/payload credits to be released */ |
87 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
88 | dsi_trans = dsi_port_to_transcoder(port); |
89 | wait_for_header_credits(dev_priv, dsi_trans); |
90 | wait_for_payload_credits(dev_priv, dsi_trans); |
91 | } |
92 | |
93 | /* send nop DCS command */ |
94 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
95 | dsi = intel_dsi->dsi_hosts[port]->device; |
96 | dsi->mode_flags |= MIPI_DSI_MODE_LPM(1 << 0); |
97 | dsi->channel = 0; |
98 | ret = mipi_dsi_dcs_nop(dsi); |
99 | if (ret < 0) |
100 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "error sending DCS NOP command\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__) |
101 | "error sending DCS NOP command\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "error sending DCS NOP command\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
102 | } |
103 | |
104 | /* wait for header credits to be released */ |
105 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
106 | dsi_trans = dsi_port_to_transcoder(port); |
107 | wait_for_header_credits(dev_priv, dsi_trans); |
108 | } |
109 | |
110 | /* wait for LP TX in progress bit to be cleared */ |
111 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
112 | dsi_trans = dsi_port_to_transcoder(port); |
113 | if (wait_for_us(!(intel_de_read(dev_priv, DSI_LP_MSG(dsi_trans)) &({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 20))) ? 1 : -1 ] __attribute__((__unused__)); if ((20) > 10 ) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((20)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((!(intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x6b0d8) + ((dsi_trans ) - TRANSCODER_DSI_0) * ((0x6b8d8) - (0x6b0d8)))) })) & ( 1 << 17))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ( { int cpu, ret, timeout = ((20)) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({struct cpu_info *__ci; asm volatile ("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock (); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile ("" : : : "memory"); if ((!(intel_de_read(dev_priv, ((const i915_reg_t ){ .reg = (((0x6b0d8) + ((dsi_trans) - TRANSCODER_DSI_0) * (( 0x6b8d8) - (0x6b0d8)))) })) & (1 << 17)))) { ret = 0 ; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect(!!(cpu != (( {struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = ( ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; }); ret__ ; }) |
114 | LPTX_IN_PROGRESS), 20)({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 20))) ? 1 : -1 ] __attribute__((__unused__)); if ((20) > 10 ) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((20)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((!(intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x6b0d8) + ((dsi_trans ) - TRANSCODER_DSI_0) * ((0x6b8d8) - (0x6b0d8)))) })) & ( 1 << 17))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ( { int cpu, ret, timeout = ((20)) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({struct cpu_info *__ci; asm volatile ("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock (); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile ("" : : : "memory"); if ((!(intel_de_read(dev_priv, ((const i915_reg_t ){ .reg = (((0x6b0d8) + ((dsi_trans) - TRANSCODER_DSI_0) * (( 0x6b8d8) - (0x6b0d8)))) })) & (1 << 17)))) { ret = 0 ; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect(!!(cpu != (( {struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = ( ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; }); ret__ ; })) |
115 | drm_err(&dev_priv->drm, "LPTX bit not cleared\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "LPTX bit not cleared\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
116 | } |
117 | } |
118 | |
119 | static bool_Bool add_payld_to_queue(struct intel_dsi_host *host, const u8 *data, |
120 | u32 len) |
121 | { |
122 | struct intel_dsi *intel_dsi = host->intel_dsi; |
123 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(intel_dsi->base.base.dev); |
124 | enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); |
125 | int free_credits; |
126 | int i, j; |
127 | |
128 | for (i = 0; i < len; i += 4) { |
129 | u32 tmp = 0; |
130 | |
131 | free_credits = payload_credits_available(dev_priv, dsi_trans); |
132 | if (free_credits < 1) { |
133 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Payload credit not available\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__) |
134 | "Payload credit not available\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Payload credit not available\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
135 | return false0; |
136 | } |
137 | |
138 | for (j = 0; j < min_t(u32, len - i, 4)({ u32 __min_a = (len - i); u32 __min_b = (4); __min_a < __min_b ? __min_a : __min_b; }); j++) |
139 | tmp |= *data++ << 8 * j; |
140 | |
141 | intel_de_write(dev_priv, DSI_CMD_TXPYLD(dsi_trans)((const i915_reg_t){ .reg = (((0x6b104) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b904) - (0x6b104)))) }), tmp); |
142 | } |
143 | |
144 | return true1; |
145 | } |
146 | |
147 | static int dsi_send_pkt_hdr(struct intel_dsi_host *host, |
148 | struct mipi_dsi_packet pkt, bool_Bool enable_lpdt) |
149 | { |
150 | struct intel_dsi *intel_dsi = host->intel_dsi; |
151 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(intel_dsi->base.base.dev); |
152 | enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); |
153 | u32 tmp; |
154 | int free_credits; |
155 | |
156 | /* check if header credit available */ |
157 | free_credits = header_credits_available(dev_priv, dsi_trans); |
158 | if (free_credits < 1) { |
159 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "send pkt header failed, not enough hdr credits\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__) |
160 | "send pkt header failed, not enough hdr credits\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "send pkt header failed, not enough hdr credits\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
161 | return -1; |
162 | } |
163 | |
164 | tmp = intel_de_read(dev_priv, DSI_CMD_TXHDR(dsi_trans)((const i915_reg_t){ .reg = (((0x6b100) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b900) - (0x6b100)))) })); |
165 | |
166 | if (pkt.payload) |
167 | tmp |= PAYLOAD_PRESENT(1 << 31); |
168 | else |
169 | tmp &= ~PAYLOAD_PRESENT(1 << 31); |
170 | |
171 | tmp &= ~VBLANK_FENCE(1 << 29); |
172 | |
173 | if (enable_lpdt) |
174 | tmp |= LP_DATA_TRANSFER(1 << 30); |
175 | |
176 | tmp &= ~(PARAM_WC_MASK(0xffff << 8) | VC_MASK(0x3 << 6) | DT_MASK(0x3f << 0)); |
177 | tmp |= ((pkt.header[0] & VC_MASK(0x3 << 6)) << VC_SHIFT6); |
178 | tmp |= ((pkt.header[0] & DT_MASK(0x3f << 0)) << DT_SHIFT0); |
179 | tmp |= (pkt.header[1] << PARAM_WC_LOWER_SHIFT8); |
180 | tmp |= (pkt.header[2] << PARAM_WC_UPPER_SHIFT16); |
181 | intel_de_write(dev_priv, DSI_CMD_TXHDR(dsi_trans)((const i915_reg_t){ .reg = (((0x6b100) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b900) - (0x6b100)))) }), tmp); |
182 | |
183 | return 0; |
184 | } |
185 | |
186 | static int dsi_send_pkt_payld(struct intel_dsi_host *host, |
187 | struct mipi_dsi_packet pkt) |
188 | { |
189 | struct intel_dsi *intel_dsi = host->intel_dsi; |
190 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(intel_dsi->base.base.dev); |
Value stored to 'i915' during its initialization is never read | |
191 | |
192 | /* payload queue can accept *256 bytes*, check limit */ |
193 | if (pkt.payload_length > MAX_PLOAD_CREDIT0x40 * 4) { |
194 | drm_err(&i915->drm, "payload size exceeds max queue limit\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "payload size exceeds max queue limit\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
195 | return -1; |
196 | } |
197 | |
198 | /* load data into command payload queue */ |
199 | if (!add_payld_to_queue(host, pkt.payload, |
200 | pkt.payload_length)) { |
201 | drm_err(&i915->drm, "adding payload to queue failed\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "adding payload to queue failed\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
202 | return -1; |
203 | } |
204 | |
205 | return 0; |
206 | } |
207 | |
208 | static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) |
209 | { |
210 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
211 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
212 | enum phy phy; |
213 | u32 tmp; |
214 | int lane; |
215 | |
216 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else { |
217 | /* |
218 | * Program voltage swing and pre-emphasis level values as per |
219 | * table in BSPEC under DDI buffer programing |
220 | */ |
221 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + (0x880 + (0) * 0x100) + 4 * ( 5))) })); |
222 | tmp &= ~(SCALING_MODE_SEL_MASK(0x7 << 18) | RTERM_SELECT_MASK(0x7 << 3)); |
223 | tmp |= SCALING_MODE_SEL(0x2)((0x2) << 18); |
224 | tmp |= TAP2_DISABLE(1 << 30) | TAP3_DISABLE(1 << 29); |
225 | tmp |= RTERM_SELECT(0x6)((0x6) << 3); |
226 | intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x680 + 4 * (5))) }), tmp); |
227 | |
228 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW5_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (5))) })); |
229 | tmp &= ~(SCALING_MODE_SEL_MASK(0x7 << 18) | RTERM_SELECT_MASK(0x7 << 3)); |
230 | tmp |= SCALING_MODE_SEL(0x2)((0x2) << 18); |
231 | tmp |= TAP2_DISABLE(1 << 30) | TAP3_DISABLE(1 << 29); |
232 | tmp |= RTERM_SELECT(0x6)((0x6) << 3); |
233 | intel_de_write(dev_priv, ICL_PORT_TX_DW5_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (5))) }), tmp); |
234 | |
235 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW2_LN0(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + (0x880 + (0) * 0x100) + 4 * ( 2))) })); |
236 | tmp &= ~(SWING_SEL_LOWER_MASK(0x7 << 11) | SWING_SEL_UPPER_MASK(1 << 15) | |
237 | RCOMP_SCALAR_MASK(0xFF << 0)); |
238 | tmp |= SWING_SEL_UPPER(0x2)(((0x2) >> 3) << 15); |
239 | tmp |= SWING_SEL_LOWER(0x2)(((0x2) & 0x7) << 11); |
240 | tmp |= RCOMP_SCALAR(0x98)((0x98) << 0); |
241 | intel_de_write(dev_priv, ICL_PORT_TX_DW2_GRP(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x680 + 4 * (2))) }), tmp); |
242 | |
243 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW2_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (2))) })); |
244 | tmp &= ~(SWING_SEL_LOWER_MASK(0x7 << 11) | SWING_SEL_UPPER_MASK(1 << 15) | |
245 | RCOMP_SCALAR_MASK(0xFF << 0)); |
246 | tmp |= SWING_SEL_UPPER(0x2)(((0x2) >> 3) << 15); |
247 | tmp |= SWING_SEL_LOWER(0x2)(((0x2) & 0x7) << 11); |
248 | tmp |= RCOMP_SCALAR(0x98)((0x98) << 0); |
249 | intel_de_write(dev_priv, ICL_PORT_TX_DW2_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (2))) }), tmp); |
250 | |
251 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW4_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (4))) })); |
252 | tmp &= ~(POST_CURSOR_1_MASK(0x3F << 12) | POST_CURSOR_2_MASK(0x3F << 6) | |
253 | CURSOR_COEFF_MASK(0x3F << 0)); |
254 | tmp |= POST_CURSOR_1(0x0)((0x0) << 12); |
255 | tmp |= POST_CURSOR_2(0x0)((0x0) << 6); |
256 | tmp |= CURSOR_COEFF(0x3f)((0x3f) << 0); |
257 | intel_de_write(dev_priv, ICL_PORT_TX_DW4_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (4))) }), tmp); |
258 | |
259 | for (lane = 0; lane <= 3; lane++) { |
260 | /* Bspec: must not use GRP register for write */ |
261 | tmp = intel_de_read(dev_priv, |
262 | ICL_PORT_TX_DW4_LN(lane, phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + (0x880 + (lane) * 0x100) + 4 * (4))) })); |
263 | tmp &= ~(POST_CURSOR_1_MASK(0x3F << 12) | POST_CURSOR_2_MASK(0x3F << 6) | |
264 | CURSOR_COEFF_MASK(0x3F << 0)); |
265 | tmp |= POST_CURSOR_1(0x0)((0x0) << 12); |
266 | tmp |= POST_CURSOR_2(0x0)((0x0) << 6); |
267 | tmp |= CURSOR_COEFF(0x3f)((0x3f) << 0); |
268 | intel_de_write(dev_priv, |
269 | ICL_PORT_TX_DW4_LN(lane, phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + (0x880 + (lane) * 0x100) + 4 * (4))) }), tmp); |
270 | } |
271 | } |
272 | } |
273 | |
274 | static void configure_dual_link_mode(struct intel_encoder *encoder, |
275 | const struct intel_crtc_state *pipe_config) |
276 | { |
277 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
278 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
279 | u32 dss_ctl1; |
280 | |
281 | dss_ctl1 = intel_de_read(dev_priv, DSS_CTL1((const i915_reg_t){ .reg = (0x67400) })); |
282 | dss_ctl1 |= SPLITTER_ENABLE(1 << 31); |
283 | dss_ctl1 &= ~OVERLAP_PIXELS_MASK(0xf << 16); |
284 | dss_ctl1 |= OVERLAP_PIXELS(intel_dsi->pixel_overlap)((intel_dsi->pixel_overlap) << 16); |
285 | |
286 | if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK1) { |
287 | const struct drm_display_mode *adjusted_mode = |
288 | &pipe_config->hw.adjusted_mode; |
289 | u32 dss_ctl2; |
290 | u16 hactive = adjusted_mode->crtc_hdisplay; |
291 | u16 dl_buffer_depth; |
292 | |
293 | dss_ctl1 &= ~DUAL_LINK_MODE_INTERLEAVE(1 << 24); |
294 | dl_buffer_depth = hactive / 2 + intel_dsi->pixel_overlap; |
295 | |
296 | if (dl_buffer_depth > MAX_DL_BUFFER_TARGET_DEPTH0x5a0) |
297 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DL buffer depth exceed max value\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__) |
298 | "DL buffer depth exceed max value\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DL buffer depth exceed max value\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
299 | |
300 | dss_ctl1 &= ~LEFT_DL_BUF_TARGET_DEPTH_MASK(0xfff << 0); |
301 | dss_ctl1 |= LEFT_DL_BUF_TARGET_DEPTH(dl_buffer_depth)((dl_buffer_depth) << 0); |
302 | dss_ctl2 = intel_de_read(dev_priv, DSS_CTL2((const i915_reg_t){ .reg = (0x67404) })); |
303 | dss_ctl2 &= ~RIGHT_DL_BUF_TARGET_DEPTH_MASK(0xfff << 0); |
304 | dss_ctl2 |= RIGHT_DL_BUF_TARGET_DEPTH(dl_buffer_depth)((dl_buffer_depth) << 0); |
305 | intel_de_write(dev_priv, DSS_CTL2((const i915_reg_t){ .reg = (0x67404) }), dss_ctl2); |
306 | } else { |
307 | /* Interleave */ |
308 | dss_ctl1 |= DUAL_LINK_MODE_INTERLEAVE(1 << 24); |
309 | } |
310 | |
311 | intel_de_write(dev_priv, DSS_CTL1((const i915_reg_t){ .reg = (0x67400) }), dss_ctl1); |
312 | } |
313 | |
314 | /* aka DSI 8X clock */ |
315 | static int afe_clk(struct intel_encoder *encoder, |
316 | const struct intel_crtc_state *crtc_state) |
317 | { |
318 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
319 | int bpp; |
320 | |
321 | if (crtc_state->dsc.compression_enable) |
322 | bpp = crtc_state->dsc.compressed_bpp; |
323 | else |
324 | bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); |
325 | |
326 | return DIV_ROUND_CLOSEST(intel_dsi->pclk * bpp, intel_dsi->lane_count)(((intel_dsi->pclk * bpp) + ((intel_dsi->lane_count) / 2 )) / (intel_dsi->lane_count)); |
327 | } |
328 | |
329 | static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder, |
330 | const struct intel_crtc_state *crtc_state) |
331 | { |
332 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
333 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
334 | enum port port; |
335 | int afe_clk_khz; |
336 | u32 esc_clk_div_m; |
337 | |
338 | afe_clk_khz = afe_clk(encoder, crtc_state); |
339 | esc_clk_div_m = DIV_ROUND_UP(afe_clk_khz, DSI_MAX_ESC_CLK)(((afe_clk_khz) + ((20000) - 1)) / (20000)); |
340 | |
341 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
342 | intel_de_write(dev_priv, ICL_DSI_ESC_CLK_DIV(port)((const i915_reg_t){ .reg = (((0x6b090) + ((port)) * ((0x6b890 ) - (0x6b090)))) }), |
343 | esc_clk_div_m & ICL_ESC_CLK_DIV_MASK0x1ff); |
344 | intel_de_posting_read(dev_priv, ICL_DSI_ESC_CLK_DIV(port)((const i915_reg_t){ .reg = (((0x6b090) + ((port)) * ((0x6b890 ) - (0x6b090)))) })); |
345 | } |
346 | |
347 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
348 | intel_de_write(dev_priv, ICL_DPHY_ESC_CLK_DIV(port)((const i915_reg_t){ .reg = (((0x162190) + ((port)) * ((0x6C190 ) - (0x162190)))) }), |
349 | esc_clk_div_m & ICL_ESC_CLK_DIV_MASK0x1ff); |
350 | intel_de_posting_read(dev_priv, ICL_DPHY_ESC_CLK_DIV(port)((const i915_reg_t){ .reg = (((0x162190) + ((port)) * ((0x6C190 ) - (0x162190)))) })); |
351 | } |
352 | } |
353 | |
354 | static void get_dsi_io_power_domains(struct drm_i915_privateinteldrm_softc *dev_priv, |
355 | struct intel_dsi *intel_dsi) |
356 | { |
357 | enum port port; |
358 | |
359 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
360 | drm_WARN_ON(&dev_priv->drm, intel_dsi->io_wakeref[port])({ int __ret = !!((intel_dsi->io_wakeref[port])); if (__ret ) printf("%s %s: " "%s", dev_driver_string(((&dev_priv-> drm))->dev), "", "drm_WARN_ON(" "intel_dsi->io_wakeref[port]" ")"); __builtin_expect(!!(__ret), 0); }); |
361 | intel_dsi->io_wakeref[port] = |
362 | intel_display_power_get(dev_priv, |
363 | port == PORT_A ? |
364 | POWER_DOMAIN_PORT_DDI_A_IO : |
365 | POWER_DOMAIN_PORT_DDI_B_IO); |
366 | } |
367 | } |
368 | |
369 | static void gen11_dsi_enable_io_power(struct intel_encoder *encoder) |
370 | { |
371 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
372 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
373 | enum port port; |
374 | u32 tmp; |
375 | |
376 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
377 | tmp = intel_de_read(dev_priv, ICL_DSI_IO_MODECTL(port)((const i915_reg_t){ .reg = (((0x6B094) + (port) * ((0x6B894) - (0x6B094)))) })); |
378 | tmp |= COMBO_PHY_MODE_DSI(1 << 0); |
379 | intel_de_write(dev_priv, ICL_DSI_IO_MODECTL(port)((const i915_reg_t){ .reg = (((0x6B094) + (port) * ((0x6B894) - (0x6B094)))) }), tmp); |
380 | } |
381 | |
382 | get_dsi_io_power_domains(dev_priv, intel_dsi); |
383 | } |
384 | |
385 | static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) |
386 | { |
387 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
388 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
389 | enum phy phy; |
390 | |
391 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else |
392 | intel_combo_phy_power_up_lanes(dev_priv, phy, true1, |
393 | intel_dsi->lane_count, false0); |
394 | } |
395 | |
396 | static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder) |
397 | { |
398 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
399 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
400 | enum phy phy; |
401 | u32 tmp; |
402 | int lane; |
403 | |
404 | /* Step 4b(i) set loadgen select for transmit and aux lanes */ |
405 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else { |
406 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW4_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (4))) })); |
407 | tmp &= ~LOADGEN_SELECT(1 << 31); |
408 | intel_de_write(dev_priv, ICL_PORT_TX_DW4_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (4))) }), tmp); |
409 | for (lane = 0; lane <= 3; lane++) { |
410 | tmp = intel_de_read(dev_priv, |
411 | ICL_PORT_TX_DW4_LN(lane, phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + (0x880 + (lane) * 0x100) + 4 * (4))) })); |
412 | tmp &= ~LOADGEN_SELECT(1 << 31); |
413 | if (lane != 2) |
414 | tmp |= LOADGEN_SELECT(1 << 31); |
415 | intel_de_write(dev_priv, |
416 | ICL_PORT_TX_DW4_LN(lane, phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + (0x880 + (lane) * 0x100) + 4 * (4))) }), tmp); |
417 | } |
418 | } |
419 | |
420 | /* Step 4b(ii) set latency optimization for transmit and aux lanes */ |
421 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else { |
422 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW2_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (2))) })); |
423 | tmp &= ~FRC_LATENCY_OPTIM_MASK(0x7 << 8); |
424 | tmp |= FRC_LATENCY_OPTIM_VAL(0x5)((0x5) << 8); |
425 | intel_de_write(dev_priv, ICL_PORT_TX_DW2_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (2))) }), tmp); |
426 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW2_LN0(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + (0x880 + (0) * 0x100) + 4 * ( 2))) })); |
427 | tmp &= ~FRC_LATENCY_OPTIM_MASK(0x7 << 8); |
428 | tmp |= FRC_LATENCY_OPTIM_VAL(0x5)((0x5) << 8); |
429 | intel_de_write(dev_priv, ICL_PORT_TX_DW2_GRP(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x680 + 4 * (2))) }), tmp); |
430 | |
431 | /* For EHL, TGL, set latency optimization for PCS_DW1 lanes */ |
432 | if (IS_ELKHARTLAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_ELKHARTLAKE) || (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 12)) { |
433 | tmp = intel_de_read(dev_priv, |
434 | ICL_PORT_PCS_DW1_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x300 + 4 * (1))) })); |
435 | tmp &= ~LATENCY_OPTIM_MASK(0x3 << 2); |
436 | tmp |= LATENCY_OPTIM_VAL(0)((0) << 2); |
437 | intel_de_write(dev_priv, ICL_PORT_PCS_DW1_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x300 + 4 * (1))) }), |
438 | tmp); |
439 | |
440 | tmp = intel_de_read(dev_priv, |
441 | ICL_PORT_PCS_DW1_LN0(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + (0x800 + (0) * 0x100) + 4 * ( 1))) })); |
442 | tmp &= ~LATENCY_OPTIM_MASK(0x3 << 2); |
443 | tmp |= LATENCY_OPTIM_VAL(0x1)((0x1) << 2); |
444 | intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x600 + 4 * (1))) }), |
445 | tmp); |
446 | } |
447 | } |
448 | |
449 | } |
450 | |
451 | static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder) |
452 | { |
453 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
454 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
455 | u32 tmp; |
456 | enum phy phy; |
457 | |
458 | /* clear common keeper enable bit */ |
459 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else { |
460 | tmp = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN0(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + (0x800 + (0) * 0x100) + 4 * ( 1))) })); |
461 | tmp &= ~COMMON_KEEPER_EN(1 << 26); |
462 | intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x600 + 4 * (1))) }), tmp); |
463 | tmp = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x300 + 4 * (1))) })); |
464 | tmp &= ~COMMON_KEEPER_EN(1 << 26); |
465 | intel_de_write(dev_priv, ICL_PORT_PCS_DW1_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x300 + 4 * (1))) }), tmp); |
466 | } |
467 | |
468 | /* |
469 | * Set SUS Clock Config bitfield to 11b |
470 | * Note: loadgen select program is done |
471 | * as part of lane phy sequence configuration |
472 | */ |
473 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else { |
474 | tmp = intel_de_read(dev_priv, ICL_PORT_CL_DW5(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 4 * (5))) })); |
475 | tmp |= SUS_CLOCK_CONFIG(3 << 0); |
476 | intel_de_write(dev_priv, ICL_PORT_CL_DW5(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 4 * (5))) }), tmp); |
477 | } |
478 | |
479 | /* Clear training enable to change swing values */ |
480 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else { |
481 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + (0x880 + (0) * 0x100) + 4 * ( 5))) })); |
482 | tmp &= ~TX_TRAINING_EN(1 << 31); |
483 | intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x680 + 4 * (5))) }), tmp); |
484 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW5_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (5))) })); |
485 | tmp &= ~TX_TRAINING_EN(1 << 31); |
486 | intel_de_write(dev_priv, ICL_PORT_TX_DW5_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (5))) }), tmp); |
487 | } |
488 | |
489 | /* Program swing and de-emphasis */ |
490 | dsi_program_swing_and_deemphasis(encoder); |
491 | |
492 | /* Set training enable to trigger update */ |
493 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else { |
494 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + (0x880 + (0) * 0x100) + 4 * ( 5))) })); |
495 | tmp |= TX_TRAINING_EN(1 << 31); |
496 | intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x680 + 4 * (5))) }), tmp); |
497 | tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW5_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (5))) })); |
498 | tmp |= TX_TRAINING_EN(1 << 31); |
499 | intel_de_write(dev_priv, ICL_PORT_TX_DW5_AUX(phy)((const i915_reg_t){ .reg = (((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x380 + 4 * (5))) }), tmp); |
500 | } |
501 | } |
502 | |
503 | static void gen11_dsi_enable_ddi_buffer(struct intel_encoder *encoder) |
504 | { |
505 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
506 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
507 | u32 tmp; |
508 | enum port port; |
509 | |
510 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
511 | tmp = intel_de_read(dev_priv, DDI_BUF_CTL(port)((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) })); |
512 | tmp |= DDI_BUF_CTL_ENABLE(1 << 31); |
513 | intel_de_write(dev_priv, DDI_BUF_CTL(port)((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) }), tmp); |
514 | |
515 | if (wait_for_us(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) &({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 500))) ? 1 : -1 ] __attribute__((__unused__)); if ((500) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((500)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((!(intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & (1 << 7))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ({ int cpu, ret, timeout = ((500 )) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (( {struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock(); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile("" : : : "memory" ); if ((!(intel_de_read(dev_priv, ((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & ( 1 << 7)))) { ret = 0; break; } if (now - base >= timeout ) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect (!!(cpu != (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; } ); ret__; }) |
516 | DDI_BUF_IS_IDLE),({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 500))) ? 1 : -1 ] __attribute__((__unused__)); if ((500) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((500)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((!(intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & (1 << 7))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ({ int cpu, ret, timeout = ((500 )) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (( {struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock(); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile("" : : : "memory" ); if ((!(intel_de_read(dev_priv, ((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & ( 1 << 7)))) { ret = 0; break; } if (now - base >= timeout ) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect (!!(cpu != (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; } ); ret__; }) |
517 | 500)({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 500))) ? 1 : -1 ] __attribute__((__unused__)); if ((500) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((500)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if (((!(intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & (1 << 7))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ({ int cpu, ret, timeout = ((500 )) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (( {struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock(); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile("" : : : "memory" ); if ((!(intel_de_read(dev_priv, ((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & ( 1 << 7)))) { ret = 0; break; } if (now - base >= timeout ) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect (!!(cpu != (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; } ); ret__; })) |
518 | drm_err(&dev_priv->drm, "DDI port:%c buffer idle\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DDI port:%c buffer idle\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , ((port ) + 'A')) |
519 | port_name(port))printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DDI port:%c buffer idle\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , ((port ) + 'A')); |
520 | } |
521 | } |
522 | |
523 | static void |
524 | gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder, |
525 | const struct intel_crtc_state *crtc_state) |
526 | { |
527 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
528 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
529 | u32 tmp; |
530 | enum port port; |
531 | enum phy phy; |
532 | |
533 | /* Program T-INIT master registers */ |
534 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
535 | tmp = intel_de_read(dev_priv, ICL_DSI_T_INIT_MASTER(port)((const i915_reg_t){ .reg = (((0x6b088) + (port) * ((0x6b888) - (0x6b088)))) })); |
536 | tmp &= ~MASTER_INIT_TIMER_MASK(0xffff << 0); |
537 | tmp |= intel_dsi->init_count; |
538 | intel_de_write(dev_priv, ICL_DSI_T_INIT_MASTER(port)((const i915_reg_t){ .reg = (((0x6b088) + (port) * ((0x6b888) - (0x6b088)))) }), tmp); |
539 | } |
540 | |
541 | /* Program DPHY clock lanes timings */ |
542 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
543 | intel_de_write(dev_priv, DPHY_CLK_TIMING_PARAM(port)((const i915_reg_t){ .reg = (((0x162180) + (port) * ((0x6c180 ) - (0x162180)))) }), |
544 | intel_dsi->dphy_reg); |
545 | |
546 | /* shadow register inside display core */ |
547 | intel_de_write(dev_priv, DSI_CLK_TIMING_PARAM(port)((const i915_reg_t){ .reg = (((0x6b080) + (port) * ((0x6b880) - (0x6b080)))) }), |
548 | intel_dsi->dphy_reg); |
549 | } |
550 | |
551 | /* Program DPHY data lanes timings */ |
552 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
553 | intel_de_write(dev_priv, DPHY_DATA_TIMING_PARAM(port)((const i915_reg_t){ .reg = (((0x162184) + (port) * ((0x6c184 ) - (0x162184)))) }), |
554 | intel_dsi->dphy_data_lane_reg); |
555 | |
556 | /* shadow register inside display core */ |
557 | intel_de_write(dev_priv, DSI_DATA_TIMING_PARAM(port)((const i915_reg_t){ .reg = (((0x6B084) + (port) * ((0x6B884) - (0x6B084)))) }), |
558 | intel_dsi->dphy_data_lane_reg); |
559 | } |
560 | |
561 | /* |
562 | * If DSI link operating at or below an 800 MHz, |
563 | * TA_SURE should be override and programmed to |
564 | * a value '0' inside TA_PARAM_REGISTERS otherwise |
565 | * leave all fields at HW default values. |
566 | */ |
567 | if (IS_GEN(dev_priv, 11)(0 + (&(dev_priv)->__info)->gen == (11))) { |
568 | if (afe_clk(encoder, crtc_state) <= 800000) { |
569 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
570 | tmp = intel_de_read(dev_priv, |
571 | DPHY_TA_TIMING_PARAM(port)((const i915_reg_t){ .reg = (((0x162188) + (port) * ((0x6c188 ) - (0x162188)))) })); |
572 | tmp &= ~TA_SURE_MASK(0x1f << 16); |
573 | tmp |= TA_SURE_OVERRIDE(1 << 31) | TA_SURE(0)((0) << 16); |
574 | intel_de_write(dev_priv, |
575 | DPHY_TA_TIMING_PARAM(port)((const i915_reg_t){ .reg = (((0x162188) + (port) * ((0x6c188 ) - (0x162188)))) }), |
576 | tmp); |
577 | |
578 | /* shadow register inside display core */ |
579 | tmp = intel_de_read(dev_priv, |
580 | DSI_TA_TIMING_PARAM(port)((const i915_reg_t){ .reg = (((0x6b098) + (port) * ((0x6b898) - (0x6b098)))) })); |
581 | tmp &= ~TA_SURE_MASK(0x1f << 16); |
582 | tmp |= TA_SURE_OVERRIDE(1 << 31) | TA_SURE(0)((0) << 16); |
583 | intel_de_write(dev_priv, |
584 | DSI_TA_TIMING_PARAM(port)((const i915_reg_t){ .reg = (((0x6b098) + (port) * ((0x6b898) - (0x6b098)))) }), tmp); |
585 | } |
586 | } |
587 | } |
588 | |
589 | if (IS_ELKHARTLAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_ELKHARTLAKE)) { |
590 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else { |
591 | tmp = intel_de_read(dev_priv, ICL_DPHY_CHKN(phy)((const i915_reg_t){ .reg = ((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x194) })); |
592 | tmp |= ICL_DPHY_CHKN_AFE_OVER_PPI_STRAP((u32)((1UL << (7)) + 0)); |
593 | intel_de_write(dev_priv, ICL_DPHY_CHKN(phy)((const i915_reg_t){ .reg = ((((const u32 []){ 0x162000, 0x6C000 , 0x160000, 0x161000 })[phy]) + 0x194) }), tmp); |
594 | } |
595 | } |
596 | } |
597 | |
598 | static void gen11_dsi_gate_clocks(struct intel_encoder *encoder) |
599 | { |
600 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
601 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
602 | u32 tmp; |
603 | enum phy phy; |
604 | |
605 | mutex_lock(&dev_priv->dpll.lock)rw_enter_write(&dev_priv->dpll.lock); |
606 | tmp = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0((const i915_reg_t){ .reg = (0x164280) })); |
607 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else |
608 | tmp |= ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)(1 << (((const u32 []){ 10, 11, 24 })[phy])); |
609 | |
610 | intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0((const i915_reg_t){ .reg = (0x164280) }), tmp); |
611 | mutex_unlock(&dev_priv->dpll.lock)rw_exit_write(&dev_priv->dpll.lock); |
612 | } |
613 | |
614 | static void gen11_dsi_ungate_clocks(struct intel_encoder *encoder) |
615 | { |
616 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
617 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
618 | u32 tmp; |
619 | enum phy phy; |
620 | |
621 | mutex_lock(&dev_priv->dpll.lock)rw_enter_write(&dev_priv->dpll.lock); |
622 | tmp = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0((const i915_reg_t){ .reg = (0x164280) })); |
623 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else |
624 | tmp &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)(1 << (((const u32 []){ 10, 11, 24 })[phy])); |
625 | |
626 | intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0((const i915_reg_t){ .reg = (0x164280) }), tmp); |
627 | mutex_unlock(&dev_priv->dpll.lock)rw_exit_write(&dev_priv->dpll.lock); |
628 | } |
629 | |
630 | static void gen11_dsi_map_pll(struct intel_encoder *encoder, |
631 | const struct intel_crtc_state *crtc_state) |
632 | { |
633 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
634 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
635 | struct intel_shared_dpll *pll = crtc_state->shared_dpll; |
636 | enum phy phy; |
637 | u32 val; |
638 | |
639 | mutex_lock(&dev_priv->dpll.lock)rw_enter_write(&dev_priv->dpll.lock); |
640 | |
641 | val = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0((const i915_reg_t){ .reg = (0x164280) })); |
642 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else { |
643 | val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy)(3 << ((phy) * 2)); |
644 | val |= ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy)((pll->info->id) << ((phy) * 2)); |
645 | } |
646 | intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0((const i915_reg_t){ .reg = (0x164280) }), val); |
647 | |
648 | for_each_dsi_phy(phy, intel_dsi->phys)for ((phy) = PHY_A; (phy) < I915_MAX_PHYS; (phy)++) if (!( (intel_dsi->phys) & (1UL << (phy)))) {} else { |
649 | if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 12) |
650 | val |= ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)(1 << (((const u32 []){ 10, 11, 24 })[phy])); |
651 | else |
652 | val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)(1 << (((const u32 []){ 10, 11, 24 })[phy])); |
653 | } |
654 | intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0((const i915_reg_t){ .reg = (0x164280) }), val); |
655 | |
656 | intel_de_posting_read(dev_priv, ICL_DPCLKA_CFGCR0((const i915_reg_t){ .reg = (0x164280) })); |
657 | |
658 | mutex_unlock(&dev_priv->dpll.lock)rw_exit_write(&dev_priv->dpll.lock); |
659 | } |
660 | |
661 | static void |
662 | gen11_dsi_configure_transcoder(struct intel_encoder *encoder, |
663 | const struct intel_crtc_state *pipe_config) |
664 | { |
665 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
666 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
667 | struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (pipe_config->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
668 | enum pipe pipe = intel_crtc->pipe; |
669 | u32 tmp; |
670 | enum port port; |
671 | enum transcoder dsi_trans; |
672 | |
673 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
674 | dsi_trans = dsi_port_to_transcoder(port); |
675 | tmp = intel_de_read(dev_priv, DSI_TRANS_FUNC_CONF(dsi_trans)((const i915_reg_t){ .reg = (((0x6b030) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b830) - (0x6b030)))) })); |
676 | |
677 | if (intel_dsi->eotp_pkt) |
678 | tmp &= ~EOTP_DISABLED(1 << 0); |
679 | else |
680 | tmp |= EOTP_DISABLED(1 << 0); |
681 | |
682 | /* enable link calibration if freq > 1.5Gbps */ |
683 | if (afe_clk(encoder, pipe_config) >= 1500 * 1000) { |
684 | tmp &= ~LINK_CALIBRATION_MASK(0x3 << 4); |
685 | tmp |= CALIBRATION_ENABLED_INITIAL_ONLY(0x2 << 4); |
686 | } |
687 | |
688 | /* configure continuous clock */ |
689 | tmp &= ~CONTINUOUS_CLK_MASK(0x3 << 8); |
690 | if (intel_dsi->clock_stop) |
691 | tmp |= CLK_ENTER_LP_AFTER_DATA(0x0 << 8); |
692 | else |
693 | tmp |= CLK_HS_CONTINUOUS(0x3 << 8); |
694 | |
695 | /* configure buffer threshold limit to minimum */ |
696 | tmp &= ~PIX_BUF_THRESHOLD_MASK(0x3 << 10); |
697 | tmp |= PIX_BUF_THRESHOLD_1_4(0x0 << 10); |
698 | |
699 | /* set virtual channel to '0' */ |
700 | tmp &= ~PIX_VIRT_CHAN_MASK(0x3 << 12); |
701 | tmp |= PIX_VIRT_CHAN(0)((0) << 12); |
702 | |
703 | /* program BGR transmission */ |
704 | if (intel_dsi->bgr_enabled) |
705 | tmp |= BGR_TRANSMISSION(1 << 15); |
706 | |
707 | /* select pixel format */ |
708 | tmp &= ~PIX_FMT_MASK(0x3 << 16); |
709 | if (pipe_config->dsc.compression_enable) { |
710 | tmp |= PIX_FMT_COMPRESSED(0x6 << 16); |
711 | } else { |
712 | switch (intel_dsi->pixel_format) { |
713 | default: |
714 | MISSING_CASE(intel_dsi->pixel_format)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "intel_dsi->pixel_format", (long)(intel_dsi->pixel_format )); __builtin_expect(!!(__ret), 0); }); |
715 | fallthroughdo {} while (0); |
716 | case MIPI_DSI_FMT_RGB565: |
717 | tmp |= PIX_FMT_RGB565(0x0 << 16); |
718 | break; |
719 | case MIPI_DSI_FMT_RGB666_PACKED: |
720 | tmp |= PIX_FMT_RGB666_PACKED(0x1 << 16); |
721 | break; |
722 | case MIPI_DSI_FMT_RGB666: |
723 | tmp |= PIX_FMT_RGB666_LOOSE(0x2 << 16); |
724 | break; |
725 | case MIPI_DSI_FMT_RGB888: |
726 | tmp |= PIX_FMT_RGB888(0x3 << 16); |
727 | break; |
728 | } |
729 | } |
730 | |
731 | if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 12) { |
732 | if (is_vid_mode(intel_dsi)) |
733 | tmp |= BLANKING_PACKET_ENABLE(1 << 2); |
734 | } |
735 | |
736 | /* program DSI operation mode */ |
737 | if (is_vid_mode(intel_dsi)) { |
738 | tmp &= ~OP_MODE_MASK(0x3 << 28); |
739 | switch (intel_dsi->video_mode_format) { |
740 | default: |
741 | MISSING_CASE(intel_dsi->video_mode_format)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "intel_dsi->video_mode_format", (long)(intel_dsi->video_mode_format )); __builtin_expect(!!(__ret), 0); }); |
742 | fallthroughdo {} while (0); |
743 | case VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS(2 << 0): |
744 | tmp |= VIDEO_MODE_SYNC_EVENT(0x2 << 28); |
745 | break; |
746 | case VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE(1 << 0): |
747 | tmp |= VIDEO_MODE_SYNC_PULSE(0x3 << 28); |
748 | break; |
749 | } |
750 | } else { |
751 | /* |
752 | * FIXME: Retrieve this info from VBT. |
753 | * As per the spec when dsi transcoder is operating |
754 | * in TE GATE mode, TE comes from GPIO |
755 | * which is UTIL PIN for DSI 0. |
756 | * Also this GPIO would not be used for other |
757 | * purposes is an assumption. |
758 | */ |
759 | tmp &= ~OP_MODE_MASK(0x3 << 28); |
760 | tmp |= CMD_MODE_TE_GATE(0x1 << 28); |
761 | tmp |= TE_SOURCE_GPIO(1 << 27); |
762 | } |
763 | |
764 | intel_de_write(dev_priv, DSI_TRANS_FUNC_CONF(dsi_trans)((const i915_reg_t){ .reg = (((0x6b030) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b830) - (0x6b030)))) }), tmp); |
765 | } |
766 | |
767 | /* enable port sync mode if dual link */ |
768 | if (intel_dsi->dual_link) { |
769 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
770 | dsi_trans = dsi_port_to_transcoder(port); |
771 | tmp = intel_de_read(dev_priv, |
772 | TRANS_DDI_FUNC_CTL2(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60404) + ((&(dev_priv)-> __info)->display_mmio_offset))) })); |
773 | tmp |= PORT_SYNC_MODE_ENABLE((u32)((1UL << (4)) + 0)); |
774 | intel_de_write(dev_priv, |
775 | TRANS_DDI_FUNC_CTL2(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60404) + ((&(dev_priv)-> __info)->display_mmio_offset))) }), tmp); |
776 | } |
777 | |
778 | /* configure stream splitting */ |
779 | configure_dual_link_mode(encoder, pipe_config); |
780 | } |
781 | |
782 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
783 | dsi_trans = dsi_port_to_transcoder(port); |
784 | |
785 | /* select data lane width */ |
786 | tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60400) + ((&(dev_priv)-> __info)->display_mmio_offset))) })); |
787 | tmp &= ~DDI_PORT_WIDTH_MASK(7 << 1); |
788 | tmp |= DDI_PORT_WIDTH(intel_dsi->lane_count)(((intel_dsi->lane_count) - 1) << 1); |
789 | |
790 | /* select input pipe */ |
791 | tmp &= ~TRANS_DDI_EDP_INPUT_MASK(7 << 12); |
792 | switch (pipe) { |
793 | default: |
794 | MISSING_CASE(pipe)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n" , "pipe", (long)(pipe)); __builtin_expect(!!(__ret), 0); }); |
795 | fallthroughdo {} while (0); |
796 | case PIPE_A: |
797 | tmp |= TRANS_DDI_EDP_INPUT_A_ON(0 << 12); |
798 | break; |
799 | case PIPE_B: |
800 | tmp |= TRANS_DDI_EDP_INPUT_B_ONOFF(5 << 12); |
801 | break; |
802 | case PIPE_C: |
803 | tmp |= TRANS_DDI_EDP_INPUT_C_ONOFF(6 << 12); |
804 | break; |
805 | case PIPE_D: |
806 | tmp |= TRANS_DDI_EDP_INPUT_D_ONOFF(7 << 12); |
807 | break; |
808 | } |
809 | |
810 | /* enable DDI buffer */ |
811 | tmp |= TRANS_DDI_FUNC_ENABLE(1 << 31); |
812 | intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60400) + ((&(dev_priv)-> __info)->display_mmio_offset))) }), tmp); |
813 | } |
814 | |
815 | /* wait for link ready */ |
816 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
817 | dsi_trans = dsi_port_to_transcoder(port); |
818 | if (wait_for_us((intel_de_read(dev_priv, DSI_TRANS_FUNC_CONF(dsi_trans)) &({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 2500))) ? 1 : -1 ] __attribute__((__unused__)); if ((2500) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((2500)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if ((((intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x6b030) + ((dsi_trans ) - TRANSCODER_DSI_0) * ((0x6b830) - (0x6b030)))) })) & ( 1 << 20))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ( { int cpu, ret, timeout = ((2500)) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({struct cpu_info *__ci; asm volatile ("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock (); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile ("" : : : "memory"); if (((intel_de_read(dev_priv, ((const i915_reg_t ){ .reg = (((0x6b030) + ((dsi_trans) - TRANSCODER_DSI_0) * (( 0x6b830) - (0x6b030)))) })) & (1 << 20)))) { ret = 0 ; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect(!!(cpu != (( {struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = ( ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; }); ret__ ; }) |
819 | LINK_READY), 2500)({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 2500))) ? 1 : -1 ] __attribute__((__unused__)); if ((2500) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((2500)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if ((((intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x6b030) + ((dsi_trans ) - TRANSCODER_DSI_0) * ((0x6b830) - (0x6b030)))) })) & ( 1 << 20))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ( { int cpu, ret, timeout = ((2500)) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({struct cpu_info *__ci; asm volatile ("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock (); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile ("" : : : "memory"); if (((intel_de_read(dev_priv, ((const i915_reg_t ){ .reg = (((0x6b030) + ((dsi_trans) - TRANSCODER_DSI_0) * (( 0x6b830) - (0x6b030)))) })) & (1 << 20)))) { ret = 0 ; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect(!!(cpu != (( {struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = ( ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; }); ret__ ; })) |
820 | drm_err(&dev_priv->drm, "DSI link not ready\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DSI link not ready\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
821 | } |
822 | } |
823 | |
824 | static void |
825 | gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, |
826 | const struct intel_crtc_state *crtc_state) |
827 | { |
828 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
829 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
830 | const struct drm_display_mode *adjusted_mode = |
831 | &crtc_state->hw.adjusted_mode; |
832 | enum port port; |
833 | enum transcoder dsi_trans; |
834 | /* horizontal timings */ |
835 | u16 htotal, hactive, hsync_start, hsync_end, hsync_size; |
836 | u16 hback_porch; |
837 | /* vertical timings */ |
838 | u16 vtotal, vactive, vsync_start, vsync_end, vsync_shift; |
839 | int mul = 1, div = 1; |
840 | |
841 | /* |
842 | * Adjust horizontal timings (htotal, hsync_start, hsync_end) to account |
843 | * for slower link speed if DSC is enabled. |
844 | * |
845 | * The compression frequency ratio is the ratio between compressed and |
846 | * non-compressed link speeds, and simplifies down to the ratio between |
847 | * compressed and non-compressed bpp. |
848 | */ |
849 | if (crtc_state->dsc.compression_enable) { |
850 | mul = crtc_state->dsc.compressed_bpp; |
851 | div = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); |
852 | } |
853 | |
854 | hactive = adjusted_mode->crtc_hdisplay; |
855 | |
856 | if (is_vid_mode(intel_dsi)) |
857 | htotal = DIV_ROUND_UP(adjusted_mode->crtc_htotal * mul, div)(((adjusted_mode->crtc_htotal * mul) + ((div) - 1)) / (div )); |
858 | else |
859 | htotal = DIV_ROUND_UP((hactive + 160) * mul, div)((((hactive + 160) * mul) + ((div) - 1)) / (div)); |
860 | |
861 | hsync_start = DIV_ROUND_UP(adjusted_mode->crtc_hsync_start * mul, div)(((adjusted_mode->crtc_hsync_start * mul) + ((div) - 1)) / (div)); |
862 | hsync_end = DIV_ROUND_UP(adjusted_mode->crtc_hsync_end * mul, div)(((adjusted_mode->crtc_hsync_end * mul) + ((div) - 1)) / ( div)); |
863 | hsync_size = hsync_end - hsync_start; |
864 | hback_porch = (adjusted_mode->crtc_htotal - |
865 | adjusted_mode->crtc_hsync_end); |
866 | vactive = adjusted_mode->crtc_vdisplay; |
867 | |
868 | if (is_vid_mode(intel_dsi)) { |
869 | vtotal = adjusted_mode->crtc_vtotal; |
870 | } else { |
871 | int bpp, line_time_us, byte_clk_period_ns; |
872 | |
873 | if (crtc_state->dsc.compression_enable) |
874 | bpp = crtc_state->dsc.compressed_bpp; |
875 | else |
876 | bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); |
877 | |
878 | byte_clk_period_ns = 1000000 / afe_clk(encoder, crtc_state); |
879 | line_time_us = (htotal * (bpp / 8) * byte_clk_period_ns) / (1000 * intel_dsi->lane_count); |
880 | vtotal = vactive + DIV_ROUND_UP(400, line_time_us)(((400) + ((line_time_us) - 1)) / (line_time_us)); |
881 | } |
882 | vsync_start = adjusted_mode->crtc_vsync_start; |
883 | vsync_end = adjusted_mode->crtc_vsync_end; |
884 | vsync_shift = hsync_start - htotal / 2; |
885 | |
886 | if (intel_dsi->dual_link) { |
887 | hactive /= 2; |
888 | if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK1) |
889 | hactive += intel_dsi->pixel_overlap; |
890 | htotal /= 2; |
891 | } |
892 | |
893 | /* minimum hactive as per bspec: 256 pixels */ |
894 | if (adjusted_mode->crtc_hdisplay < 256) |
895 | drm_err(&dev_priv->drm, "hactive is less then 256 pixels\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "hactive is less then 256 pixels\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
896 | |
897 | /* if RGB666 format, then hactive must be multiple of 4 pixels */ |
898 | if (intel_dsi->pixel_format == MIPI_DSI_FMT_RGB666 && hactive % 4 != 0) |
899 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "hactive pixels are not multiple of 4\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__) |
900 | "hactive pixels are not multiple of 4\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "hactive pixels are not multiple of 4\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
901 | |
902 | /* program TRANS_HTOTAL register */ |
903 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
904 | dsi_trans = dsi_port_to_transcoder(port); |
905 | intel_de_write(dev_priv, HTOTAL(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60000) + ((&(dev_priv)-> __info)->display_mmio_offset))) }), |
906 | (hactive - 1) | ((htotal - 1) << 16)); |
907 | } |
908 | |
909 | /* TRANS_HSYNC register to be programmed only for video mode */ |
910 | if (is_vid_mode(intel_dsi)) { |
911 | if (intel_dsi->video_mode_format == |
912 | VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE(1 << 0)) { |
913 | /* BSPEC: hsync size should be atleast 16 pixels */ |
914 | if (hsync_size < 16) |
915 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "hsync size < 16 pixels\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__) |
916 | "hsync size < 16 pixels\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "hsync size < 16 pixels\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
917 | } |
918 | |
919 | if (hback_porch < 16) |
920 | drm_err(&dev_priv->drm, "hback porch < 16 pixels\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "hback porch < 16 pixels\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
921 | |
922 | if (intel_dsi->dual_link) { |
923 | hsync_start /= 2; |
924 | hsync_end /= 2; |
925 | } |
926 | |
927 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
928 | dsi_trans = dsi_port_to_transcoder(port); |
929 | intel_de_write(dev_priv, HSYNC(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60008) + ((&(dev_priv)-> __info)->display_mmio_offset))) }), |
930 | (hsync_start - 1) | ((hsync_end - 1) << 16)); |
931 | } |
932 | } |
933 | |
934 | /* program TRANS_VTOTAL register */ |
935 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
936 | dsi_trans = dsi_port_to_transcoder(port); |
937 | /* |
938 | * FIXME: Programing this by assuming progressive mode, since |
939 | * non-interlaced info from VBT is not saved inside |
940 | * struct drm_display_mode. |
941 | * For interlace mode: program required pixel minus 2 |
942 | */ |
943 | intel_de_write(dev_priv, VTOTAL(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x6000c) + ((&(dev_priv)-> __info)->display_mmio_offset))) }), |
944 | (vactive - 1) | ((vtotal - 1) << 16)); |
945 | } |
946 | |
947 | if (vsync_end < vsync_start || vsync_end > vtotal) |
948 | drm_err(&dev_priv->drm, "Invalid vsync_end value\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid vsync_end value\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
949 | |
950 | if (vsync_start < vactive) |
951 | drm_err(&dev_priv->drm, "vsync_start less than vactive\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "vsync_start less than vactive\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
952 | |
953 | /* program TRANS_VSYNC register for video mode only */ |
954 | if (is_vid_mode(intel_dsi)) { |
955 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
956 | dsi_trans = dsi_port_to_transcoder(port); |
957 | intel_de_write(dev_priv, VSYNC(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60014) + ((&(dev_priv)-> __info)->display_mmio_offset))) }), |
958 | (vsync_start - 1) | ((vsync_end - 1) << 16)); |
959 | } |
960 | } |
961 | |
962 | /* |
963 | * FIXME: It has to be programmed only for video modes and interlaced |
964 | * modes. Put the check condition here once interlaced |
965 | * info available as described above. |
966 | * program TRANS_VSYNCSHIFT register |
967 | */ |
968 | if (is_vid_mode(intel_dsi)) { |
969 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
970 | dsi_trans = dsi_port_to_transcoder(port); |
971 | intel_de_write(dev_priv, VSYNCSHIFT(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60028) + ((&(dev_priv)-> __info)->display_mmio_offset))) }), |
972 | vsync_shift); |
973 | } |
974 | } |
975 | |
976 | /* program TRANS_VBLANK register, should be same as vtotal programmed */ |
977 | if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 12) { |
978 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
979 | dsi_trans = dsi_port_to_transcoder(port); |
980 | intel_de_write(dev_priv, VBLANK(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60010) + ((&(dev_priv)-> __info)->display_mmio_offset))) }), |
981 | (vactive - 1) | ((vtotal - 1) << 16)); |
982 | } |
983 | } |
984 | } |
985 | |
986 | static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder) |
987 | { |
988 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
989 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
990 | enum port port; |
991 | enum transcoder dsi_trans; |
992 | u32 tmp; |
993 | |
994 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
995 | dsi_trans = dsi_port_to_transcoder(port); |
996 | tmp = intel_de_read(dev_priv, PIPECONF(dsi_trans)((const i915_reg_t){ .reg = ((&(dev_priv)->__info)-> pipe_offsets[dsi_trans] - (&(dev_priv)->__info)->pipe_offsets [PIPE_A] + (0x70008) + ((&(dev_priv)->__info)->display_mmio_offset )) })); |
997 | tmp |= PIPECONF_ENABLE(1 << 31); |
998 | intel_de_write(dev_priv, PIPECONF(dsi_trans)((const i915_reg_t){ .reg = ((&(dev_priv)->__info)-> pipe_offsets[dsi_trans] - (&(dev_priv)->__info)->pipe_offsets [PIPE_A] + (0x70008) + ((&(dev_priv)->__info)->display_mmio_offset )) }), tmp); |
999 | |
1000 | /* wait for transcoder to be enabled */ |
1001 | if (intel_de_wait_for_set(dev_priv, PIPECONF(dsi_trans)((const i915_reg_t){ .reg = ((&(dev_priv)->__info)-> pipe_offsets[dsi_trans] - (&(dev_priv)->__info)->pipe_offsets [PIPE_A] + (0x70008) + ((&(dev_priv)->__info)->display_mmio_offset )) }), |
1002 | I965_PIPECONF_ACTIVE(1 << 30), 10)) |
1003 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DSI transcoder not enabled\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__) |
1004 | "DSI transcoder not enabled\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DSI transcoder not enabled\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
1005 | } |
1006 | } |
1007 | |
1008 | static void gen11_dsi_setup_timeouts(struct intel_encoder *encoder, |
1009 | const struct intel_crtc_state *crtc_state) |
1010 | { |
1011 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1012 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1013 | enum port port; |
1014 | enum transcoder dsi_trans; |
1015 | u32 tmp, hs_tx_timeout, lp_rx_timeout, ta_timeout, divisor, mul; |
1016 | |
1017 | /* |
1018 | * escape clock count calculation: |
1019 | * BYTE_CLK_COUNT = TIME_NS/(8 * UI) |
1020 | * UI (nsec) = (10^6)/Bitrate |
1021 | * TIME_NS = (BYTE_CLK_COUNT * 8 * 10^6)/ Bitrate |
1022 | * ESCAPE_CLK_COUNT = TIME_NS/ESC_CLK_NS |
1023 | */ |
1024 | divisor = intel_dsi_tlpx_ns(intel_dsi) * afe_clk(encoder, crtc_state) * 1000; |
1025 | mul = 8 * 1000000; |
1026 | hs_tx_timeout = DIV_ROUND_UP(intel_dsi->hs_tx_timeout * mul,(((intel_dsi->hs_tx_timeout * mul) + ((divisor) - 1)) / (divisor )) |
1027 | divisor)(((intel_dsi->hs_tx_timeout * mul) + ((divisor) - 1)) / (divisor )); |
1028 | lp_rx_timeout = DIV_ROUND_UP(intel_dsi->lp_rx_timeout * mul, divisor)(((intel_dsi->lp_rx_timeout * mul) + ((divisor) - 1)) / (divisor )); |
1029 | ta_timeout = DIV_ROUND_UP(intel_dsi->turn_arnd_val * mul, divisor)(((intel_dsi->turn_arnd_val * mul) + ((divisor) - 1)) / (divisor )); |
1030 | |
1031 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1032 | dsi_trans = dsi_port_to_transcoder(port); |
1033 | |
1034 | /* program hst_tx_timeout */ |
1035 | tmp = intel_de_read(dev_priv, DSI_HSTX_TO(dsi_trans)((const i915_reg_t){ .reg = (((0x6b044) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b844) - (0x6b044)))) })); |
1036 | tmp &= ~HSTX_TIMEOUT_VALUE_MASK(0xffff << 16); |
1037 | tmp |= HSTX_TIMEOUT_VALUE(hs_tx_timeout)((hs_tx_timeout) << 16); |
1038 | intel_de_write(dev_priv, DSI_HSTX_TO(dsi_trans)((const i915_reg_t){ .reg = (((0x6b044) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b844) - (0x6b044)))) }), tmp); |
1039 | |
1040 | /* FIXME: DSI_CALIB_TO */ |
1041 | |
1042 | /* program lp_rx_host timeout */ |
1043 | tmp = intel_de_read(dev_priv, DSI_LPRX_HOST_TO(dsi_trans)((const i915_reg_t){ .reg = (((0x6b048) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b848) - (0x6b048)))) })); |
1044 | tmp &= ~LPRX_TIMEOUT_VALUE_MASK(0xffff << 0); |
1045 | tmp |= LPRX_TIMEOUT_VALUE(lp_rx_timeout)((lp_rx_timeout) << 0); |
1046 | intel_de_write(dev_priv, DSI_LPRX_HOST_TO(dsi_trans)((const i915_reg_t){ .reg = (((0x6b048) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b848) - (0x6b048)))) }), tmp); |
1047 | |
1048 | /* FIXME: DSI_PWAIT_TO */ |
1049 | |
1050 | /* program turn around timeout */ |
1051 | tmp = intel_de_read(dev_priv, DSI_TA_TO(dsi_trans)((const i915_reg_t){ .reg = (((0x6b04c) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b84c) - (0x6b04c)))) })); |
1052 | tmp &= ~TA_TIMEOUT_VALUE_MASK(0xffff << 0); |
1053 | tmp |= TA_TIMEOUT_VALUE(ta_timeout)((ta_timeout) << 0); |
1054 | intel_de_write(dev_priv, DSI_TA_TO(dsi_trans)((const i915_reg_t){ .reg = (((0x6b04c) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b84c) - (0x6b04c)))) }), tmp); |
1055 | } |
1056 | } |
1057 | |
1058 | static void gen11_dsi_config_util_pin(struct intel_encoder *encoder, |
1059 | bool_Bool enable) |
1060 | { |
1061 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1062 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1063 | u32 tmp; |
1064 | |
1065 | /* |
1066 | * used as TE i/p for DSI0, |
1067 | * for dual link/DSI1 TE is from slave DSI1 |
1068 | * through GPIO. |
1069 | */ |
1070 | if (is_vid_mode(intel_dsi) || (intel_dsi->ports & BIT(PORT_B)(1UL << (PORT_B)))) |
1071 | return; |
1072 | |
1073 | tmp = intel_de_read(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) })); |
1074 | |
1075 | if (enable) { |
1076 | tmp |= UTIL_PIN_DIRECTION_INPUT(1 << 19); |
1077 | tmp |= UTIL_PIN_ENABLE(1 << 31); |
1078 | } else { |
1079 | tmp &= ~UTIL_PIN_ENABLE(1 << 31); |
1080 | } |
1081 | intel_de_write(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) }), tmp); |
1082 | } |
1083 | |
1084 | static void |
1085 | gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, |
1086 | const struct intel_crtc_state *crtc_state) |
1087 | { |
1088 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1089 | |
1090 | /* step 4a: power up all lanes of the DDI used by DSI */ |
1091 | gen11_dsi_power_up_lanes(encoder); |
1092 | |
1093 | /* step 4b: configure lane sequencing of the Combo-PHY transmitters */ |
1094 | gen11_dsi_config_phy_lanes_sequence(encoder); |
1095 | |
1096 | /* step 4c: configure voltage swing and skew */ |
1097 | gen11_dsi_voltage_swing_program_seq(encoder); |
1098 | |
1099 | /* enable DDI buffer */ |
1100 | gen11_dsi_enable_ddi_buffer(encoder); |
1101 | |
1102 | /* setup D-PHY timings */ |
1103 | gen11_dsi_setup_dphy_timings(encoder, crtc_state); |
1104 | |
1105 | /* Since transcoder is configured to take events from GPIO */ |
1106 | gen11_dsi_config_util_pin(encoder, true1); |
1107 | |
1108 | /* step 4h: setup DSI protocol timeouts */ |
1109 | gen11_dsi_setup_timeouts(encoder, crtc_state); |
1110 | |
1111 | /* Step (4h, 4i, 4j, 4k): Configure transcoder */ |
1112 | gen11_dsi_configure_transcoder(encoder, crtc_state); |
1113 | |
1114 | /* Step 4l: Gate DDI clocks */ |
1115 | if (IS_GEN(dev_priv, 11)(0 + (&(dev_priv)->__info)->gen == (11))) |
1116 | gen11_dsi_gate_clocks(encoder); |
1117 | } |
1118 | |
1119 | static void gen11_dsi_powerup_panel(struct intel_encoder *encoder) |
1120 | { |
1121 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1122 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1123 | struct mipi_dsi_device *dsi; |
1124 | enum port port; |
1125 | enum transcoder dsi_trans; |
1126 | u32 tmp; |
1127 | int ret; |
1128 | |
1129 | /* set maximum return packet size */ |
1130 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1131 | dsi_trans = dsi_port_to_transcoder(port); |
1132 | |
1133 | /* |
1134 | * FIXME: This uses the number of DW's currently in the payload |
1135 | * receive queue. This is probably not what we want here. |
1136 | */ |
1137 | tmp = intel_de_read(dev_priv, DSI_CMD_RXCTL(dsi_trans)((const i915_reg_t){ .reg = (((0x6b0d4) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b8d4) - (0x6b0d4)))) })); |
1138 | tmp &= NUMBER_RX_PLOAD_DW_MASK(0xff << 0); |
1139 | /* multiply "Number Rx Payload DW" by 4 to get max value */ |
1140 | tmp = tmp * 4; |
1141 | dsi = intel_dsi->dsi_hosts[port]->device; |
1142 | ret = mipi_dsi_set_maximum_return_packet_size(dsi, tmp); |
1143 | if (ret < 0) |
1144 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "error setting max return pkt size%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , tmp) |
1145 | "error setting max return pkt size%d\n", tmp)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "error setting max return pkt size%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , tmp); |
1146 | } |
1147 | |
1148 | /* panel power on related mipi dsi vbt sequences */ |
1149 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_ON); |
1150 | intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay); |
1151 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); |
1152 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); |
1153 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON); |
1154 | |
1155 | /* ensure all panel commands dispatched before enabling transcoder */ |
1156 | wait_for_cmds_dispatched_to_panel(encoder); |
1157 | } |
1158 | |
1159 | static void gen11_dsi_pre_pll_enable(struct intel_atomic_state *state, |
1160 | struct intel_encoder *encoder, |
1161 | const struct intel_crtc_state *crtc_state, |
1162 | const struct drm_connector_state *conn_state) |
1163 | { |
1164 | /* step2: enable IO power */ |
1165 | gen11_dsi_enable_io_power(encoder); |
1166 | |
1167 | /* step3: enable DSI PLL */ |
1168 | gen11_dsi_program_esc_clk_div(encoder, crtc_state); |
1169 | } |
1170 | |
1171 | static void gen11_dsi_pre_enable(struct intel_atomic_state *state, |
1172 | struct intel_encoder *encoder, |
1173 | const struct intel_crtc_state *pipe_config, |
1174 | const struct drm_connector_state *conn_state) |
1175 | { |
1176 | /* step3b */ |
1177 | gen11_dsi_map_pll(encoder, pipe_config); |
1178 | |
1179 | /* step4: enable DSI port and DPHY */ |
1180 | gen11_dsi_enable_port_and_phy(encoder, pipe_config); |
1181 | |
1182 | /* step5: program and powerup panel */ |
1183 | gen11_dsi_powerup_panel(encoder); |
1184 | |
1185 | intel_dsc_enable(encoder, pipe_config); |
1186 | |
1187 | /* step6c: configure transcoder timings */ |
1188 | gen11_dsi_set_transcoder_timings(encoder, pipe_config); |
1189 | } |
1190 | |
1191 | static void gen11_dsi_enable(struct intel_atomic_state *state, |
1192 | struct intel_encoder *encoder, |
1193 | const struct intel_crtc_state *crtc_state, |
1194 | const struct drm_connector_state *conn_state) |
1195 | { |
1196 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1197 | |
1198 | drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder)({ int __ret = !!((crtc_state->has_pch_encoder)); if (__ret ) printf("%s %s: " "%s", dev_driver_string(((state->base.dev ))->dev), "", "drm_WARN_ON(" "crtc_state->has_pch_encoder" ")"); __builtin_expect(!!(__ret), 0); }); |
1199 | |
1200 | /* step6d: enable dsi transcoder */ |
1201 | gen11_dsi_enable_transcoder(encoder); |
1202 | |
1203 | /* step7: enable backlight */ |
1204 | intel_panel_enable_backlight(crtc_state, conn_state); |
1205 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON); |
1206 | |
1207 | intel_crtc_vblank_on(crtc_state); |
1208 | } |
1209 | |
1210 | static void gen11_dsi_disable_transcoder(struct intel_encoder *encoder) |
1211 | { |
1212 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1213 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1214 | enum port port; |
1215 | enum transcoder dsi_trans; |
1216 | u32 tmp; |
1217 | |
1218 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1219 | dsi_trans = dsi_port_to_transcoder(port); |
1220 | |
1221 | /* disable transcoder */ |
1222 | tmp = intel_de_read(dev_priv, PIPECONF(dsi_trans)((const i915_reg_t){ .reg = ((&(dev_priv)->__info)-> pipe_offsets[dsi_trans] - (&(dev_priv)->__info)->pipe_offsets [PIPE_A] + (0x70008) + ((&(dev_priv)->__info)->display_mmio_offset )) })); |
1223 | tmp &= ~PIPECONF_ENABLE(1 << 31); |
1224 | intel_de_write(dev_priv, PIPECONF(dsi_trans)((const i915_reg_t){ .reg = ((&(dev_priv)->__info)-> pipe_offsets[dsi_trans] - (&(dev_priv)->__info)->pipe_offsets [PIPE_A] + (0x70008) + ((&(dev_priv)->__info)->display_mmio_offset )) }), tmp); |
1225 | |
1226 | /* wait for transcoder to be disabled */ |
1227 | if (intel_de_wait_for_clear(dev_priv, PIPECONF(dsi_trans)((const i915_reg_t){ .reg = ((&(dev_priv)->__info)-> pipe_offsets[dsi_trans] - (&(dev_priv)->__info)->pipe_offsets [PIPE_A] + (0x70008) + ((&(dev_priv)->__info)->display_mmio_offset )) }), |
1228 | I965_PIPECONF_ACTIVE(1 << 30), 50)) |
1229 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DSI trancoder not disabled\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__) |
1230 | "DSI trancoder not disabled\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DSI trancoder not disabled\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
1231 | } |
1232 | } |
1233 | |
1234 | static void gen11_dsi_powerdown_panel(struct intel_encoder *encoder) |
1235 | { |
1236 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1237 | |
1238 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_OFF); |
1239 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET); |
1240 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_OFF); |
1241 | |
1242 | /* ensure cmds dispatched to panel */ |
1243 | wait_for_cmds_dispatched_to_panel(encoder); |
1244 | } |
1245 | |
1246 | static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder) |
1247 | { |
1248 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1249 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1250 | enum port port; |
1251 | enum transcoder dsi_trans; |
1252 | u32 tmp; |
1253 | |
1254 | /* disable periodic update mode */ |
1255 | if (is_cmd_mode(intel_dsi)) { |
1256 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1257 | tmp = intel_de_read(dev_priv, DSI_CMD_FRMCTL(port)((const i915_reg_t){ .reg = (((0x6b034) + (port) * ((0x6b834) - (0x6b034)))) })); |
1258 | tmp &= ~DSI_PERIODIC_FRAME_UPDATE_ENABLE(1 << 29); |
1259 | intel_de_write(dev_priv, DSI_CMD_FRMCTL(port)((const i915_reg_t){ .reg = (((0x6b034) + (port) * ((0x6b834) - (0x6b034)))) }), tmp); |
1260 | } |
1261 | } |
1262 | |
1263 | /* put dsi link in ULPS */ |
1264 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1265 | dsi_trans = dsi_port_to_transcoder(port); |
1266 | tmp = intel_de_read(dev_priv, DSI_LP_MSG(dsi_trans)((const i915_reg_t){ .reg = (((0x6b0d8) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b8d8) - (0x6b0d8)))) })); |
1267 | tmp |= LINK_ENTER_ULPS(1 << 0); |
1268 | tmp &= ~LINK_ULPS_TYPE_LP11(1 << 8); |
1269 | intel_de_write(dev_priv, DSI_LP_MSG(dsi_trans)((const i915_reg_t){ .reg = (((0x6b0d8) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b8d8) - (0x6b0d8)))) }), tmp); |
1270 | |
1271 | if (wait_for_us((intel_de_read(dev_priv, DSI_LP_MSG(dsi_trans)) &({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 10))) ? 1 : -1 ] __attribute__((__unused__)); if ((10) > 10 ) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((10)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if ((((intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x6b0d8) + ((dsi_trans ) - TRANSCODER_DSI_0) * ((0x6b8d8) - (0x6b0d8)))) })) & ( 1 << 16))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ( { int cpu, ret, timeout = ((10)) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({struct cpu_info *__ci; asm volatile ("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock (); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile ("" : : : "memory"); if (((intel_de_read(dev_priv, ((const i915_reg_t ){ .reg = (((0x6b0d8) + ((dsi_trans) - TRANSCODER_DSI_0) * (( 0x6b8d8) - (0x6b0d8)))) })) & (1 << 16)))) { ret = 0 ; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect(!!(cpu != (( {struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = ( ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; }); ret__ ; }) |
1272 | LINK_IN_ULPS),({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 10))) ? 1 : -1 ] __attribute__((__unused__)); if ((10) > 10 ) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((10)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if ((((intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x6b0d8) + ((dsi_trans ) - TRANSCODER_DSI_0) * ((0x6b8d8) - (0x6b0d8)))) })) & ( 1 << 16))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ( { int cpu, ret, timeout = ((10)) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({struct cpu_info *__ci; asm volatile ("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock (); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile ("" : : : "memory"); if (((intel_de_read(dev_priv, ((const i915_reg_t ){ .reg = (((0x6b0d8) + ((dsi_trans) - TRANSCODER_DSI_0) * (( 0x6b8d8) - (0x6b0d8)))) })) & (1 << 16)))) { ret = 0 ; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect(!!(cpu != (( {struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = ( ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; }); ret__ ; }) |
1273 | 10)({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 10))) ? 1 : -1 ] __attribute__((__unused__)); if ((10) > 10 ) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw (), 1000ll * (((10)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if ((((intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x6b0d8) + ((dsi_trans ) - TRANSCODER_DSI_0) * ((0x6b8d8) - (0x6b0d8)))) })) & ( 1 << 16))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range(wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ( { int cpu, ret, timeout = ((10)) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({struct cpu_info *__ci; asm volatile ("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock (); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile ("" : : : "memory"); if (((intel_de_read(dev_priv, ((const i915_reg_t ){ .reg = (((0x6b0d8) + ((dsi_trans) - TRANSCODER_DSI_0) * (( 0x6b8d8) - (0x6b0d8)))) })) & (1 << 16)))) { ret = 0 ; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect(!!(cpu != (( {struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = ( ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; }); ret__ ; })) |
1274 | drm_err(&dev_priv->drm, "DSI link not in ULPS\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DSI link not in ULPS\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
1275 | } |
1276 | |
1277 | /* disable ddi function */ |
1278 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1279 | dsi_trans = dsi_port_to_transcoder(port); |
1280 | tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60400) + ((&(dev_priv)-> __info)->display_mmio_offset))) })); |
1281 | tmp &= ~TRANS_DDI_FUNC_ENABLE(1 << 31); |
1282 | intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60400) + ((&(dev_priv)-> __info)->display_mmio_offset))) }), tmp); |
1283 | } |
1284 | |
1285 | /* disable port sync mode if dual link */ |
1286 | if (intel_dsi->dual_link) { |
1287 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1288 | dsi_trans = dsi_port_to_transcoder(port); |
1289 | tmp = intel_de_read(dev_priv, |
1290 | TRANS_DDI_FUNC_CTL2(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60404) + ((&(dev_priv)-> __info)->display_mmio_offset))) })); |
1291 | tmp &= ~PORT_SYNC_MODE_ENABLE((u32)((1UL << (4)) + 0)); |
1292 | intel_de_write(dev_priv, |
1293 | TRANS_DDI_FUNC_CTL2(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60404) + ((&(dev_priv)-> __info)->display_mmio_offset))) }), tmp); |
1294 | } |
1295 | } |
1296 | } |
1297 | |
1298 | static void gen11_dsi_disable_port(struct intel_encoder *encoder) |
1299 | { |
1300 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1301 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1302 | u32 tmp; |
1303 | enum port port; |
1304 | |
1305 | gen11_dsi_ungate_clocks(encoder); |
1306 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1307 | tmp = intel_de_read(dev_priv, DDI_BUF_CTL(port)((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) })); |
1308 | tmp &= ~DDI_BUF_CTL_ENABLE(1 << 31); |
1309 | intel_de_write(dev_priv, DDI_BUF_CTL(port)((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) }), tmp); |
1310 | |
1311 | if (wait_for_us((intel_de_read(dev_priv, DDI_BUF_CTL(port)) &({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 8))) ? 1 : -1 ] __attribute__((__unused__)); if ((8) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw( ), 1000ll * (((8)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if ((((intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & (1 << 7))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ({ int cpu, ret, timeout = ((8) ) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({ struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock(); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile("" : : : "memory" ); if (((intel_de_read(dev_priv, ((const i915_reg_t){ .reg = ( ((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & (1 << 7)))) { ret = 0; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect (!!(cpu != (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; } ); ret__; }) |
1312 | DDI_BUF_IS_IDLE),({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 8))) ? 1 : -1 ] __attribute__((__unused__)); if ((8) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw( ), 1000ll * (((8)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if ((((intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & (1 << 7))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ({ int cpu, ret, timeout = ((8) ) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({ struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock(); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile("" : : : "memory" ); if (((intel_de_read(dev_priv, ((const i915_reg_t){ .reg = ( ((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & (1 << 7)))) { ret = 0; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect (!!(cpu != (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; } ); ret__; }) |
1313 | 8)({ int ret__; extern char _ctassert[(!(!__builtin_constant_p( 8))) ? 1 : -1 ] __attribute__((__unused__)); if ((8) > 10) ret__ = ({ const ktime_t end__ = ktime_add_ns(ktime_get_raw( ), 1000ll * (((8)))); long wait__ = ((10)); int ret__; assertwaitok (); for (;;) { const _Bool expired__ = ktime_after(ktime_get_raw (), end__); ; __asm volatile("" : : : "memory"); if ((((intel_de_read (dev_priv, ((const i915_reg_t){ .reg = (((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & (1 << 7))))) { ret__ = 0; break; } if (expired__) { ret__ = -60; break; } usleep_range (wait__, wait__ * 2); if (wait__ < ((10))) wait__ <<= 1; } ret__; }); else ret__ = ({ int cpu, ret, timeout = ((8) ) * 1000; u64 base; do { } while (0); if (!(0)) { ; cpu = (({ struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_cpuid); } base = local_clock(); for (;;) { u64 now = local_clock(); if (!(0)) ; __asm volatile("" : : : "memory" ); if (((intel_de_read(dev_priv, ((const i915_reg_t){ .reg = ( ((0x64000) + (port) * ((0x64100) - (0x64000)))) })) & (1 << 7)))) { ret = 0; break; } if (now - base >= timeout) { ret = -60; break; } cpu_relax(); if (!(0)) { ; if (__builtin_expect (!!(cpu != (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid)), 0)) { timeout -= now - base; cpu = (({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self ))); __ci;})->ci_cpuid); base = local_clock(); } } } ret; } ); ret__; })) |
1314 | drm_err(&dev_priv->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DDI port:%c buffer not idle\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , ((port ) + 'A')) |
1315 | "DDI port:%c buffer not idle\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DDI port:%c buffer not idle\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , ((port ) + 'A')) |
1316 | port_name(port))printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DDI port:%c buffer not idle\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , ((port ) + 'A')); |
1317 | } |
1318 | gen11_dsi_gate_clocks(encoder); |
1319 | } |
1320 | |
1321 | static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) |
1322 | { |
1323 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1324 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1325 | enum port port; |
1326 | u32 tmp; |
1327 | |
1328 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1329 | intel_wakeref_t wakeref; |
1330 | |
1331 | wakeref = fetch_and_zero(&intel_dsi->io_wakeref[port])({ typeof(*&intel_dsi->io_wakeref[port]) __T = *(& intel_dsi->io_wakeref[port]); *(&intel_dsi->io_wakeref [port]) = (typeof(*&intel_dsi->io_wakeref[port]))0; __T ; }); |
1332 | intel_display_power_put(dev_priv, |
1333 | port == PORT_A ? |
1334 | POWER_DOMAIN_PORT_DDI_A_IO : |
1335 | POWER_DOMAIN_PORT_DDI_B_IO, |
1336 | wakeref); |
1337 | } |
1338 | |
1339 | /* set mode to DDI */ |
1340 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1341 | tmp = intel_de_read(dev_priv, ICL_DSI_IO_MODECTL(port)((const i915_reg_t){ .reg = (((0x6B094) + (port) * ((0x6B894) - (0x6B094)))) })); |
1342 | tmp &= ~COMBO_PHY_MODE_DSI(1 << 0); |
1343 | intel_de_write(dev_priv, ICL_DSI_IO_MODECTL(port)((const i915_reg_t){ .reg = (((0x6B094) + (port) * ((0x6B894) - (0x6B094)))) }), tmp); |
1344 | } |
1345 | } |
1346 | |
1347 | static void gen11_dsi_disable(struct intel_atomic_state *state, |
1348 | struct intel_encoder *encoder, |
1349 | const struct intel_crtc_state *old_crtc_state, |
1350 | const struct drm_connector_state *old_conn_state) |
1351 | { |
1352 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1353 | |
1354 | /* step1: turn off backlight */ |
1355 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); |
1356 | intel_panel_disable_backlight(old_conn_state); |
1357 | |
1358 | /* step2d,e: disable transcoder and wait */ |
1359 | gen11_dsi_disable_transcoder(encoder); |
1360 | |
1361 | /* step2f,g: powerdown panel */ |
1362 | gen11_dsi_powerdown_panel(encoder); |
1363 | |
1364 | /* step2h,i,j: deconfig trancoder */ |
1365 | gen11_dsi_deconfigure_trancoder(encoder); |
1366 | |
1367 | /* step3: disable port */ |
1368 | gen11_dsi_disable_port(encoder); |
1369 | |
1370 | gen11_dsi_config_util_pin(encoder, false0); |
1371 | |
1372 | /* step4: disable IO power */ |
1373 | gen11_dsi_disable_io_power(encoder); |
1374 | } |
1375 | |
1376 | static void gen11_dsi_post_disable(struct intel_atomic_state *state, |
1377 | struct intel_encoder *encoder, |
1378 | const struct intel_crtc_state *old_crtc_state, |
1379 | const struct drm_connector_state *old_conn_state) |
1380 | { |
1381 | intel_crtc_vblank_off(old_crtc_state); |
1382 | |
1383 | intel_dsc_disable(old_crtc_state); |
1384 | |
1385 | skl_scaler_disable(old_crtc_state); |
1386 | } |
1387 | |
1388 | static enum drm_mode_status gen11_dsi_mode_valid(struct drm_connector *connector, |
1389 | struct drm_display_mode *mode) |
1390 | { |
1391 | /* FIXME: DSC? */ |
1392 | return intel_dsi_mode_valid(connector, mode); |
1393 | } |
1394 | |
1395 | static void gen11_dsi_get_timings(struct intel_encoder *encoder, |
1396 | struct intel_crtc_state *pipe_config) |
1397 | { |
1398 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1399 | struct drm_display_mode *adjusted_mode = |
1400 | &pipe_config->hw.adjusted_mode; |
1401 | |
1402 | if (pipe_config->dsc.compressed_bpp) { |
1403 | int div = pipe_config->dsc.compressed_bpp; |
1404 | int mul = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); |
1405 | |
1406 | adjusted_mode->crtc_htotal = |
1407 | DIV_ROUND_UP(adjusted_mode->crtc_htotal * mul, div)(((adjusted_mode->crtc_htotal * mul) + ((div) - 1)) / (div )); |
1408 | adjusted_mode->crtc_hsync_start = |
1409 | DIV_ROUND_UP(adjusted_mode->crtc_hsync_start * mul, div)(((adjusted_mode->crtc_hsync_start * mul) + ((div) - 1)) / (div)); |
1410 | adjusted_mode->crtc_hsync_end = |
1411 | DIV_ROUND_UP(adjusted_mode->crtc_hsync_end * mul, div)(((adjusted_mode->crtc_hsync_end * mul) + ((div) - 1)) / ( div)); |
1412 | } |
1413 | |
1414 | if (intel_dsi->dual_link) { |
1415 | adjusted_mode->crtc_hdisplay *= 2; |
1416 | if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK1) |
1417 | adjusted_mode->crtc_hdisplay -= |
1418 | intel_dsi->pixel_overlap; |
1419 | adjusted_mode->crtc_htotal *= 2; |
1420 | } |
1421 | adjusted_mode->crtc_hblank_start = adjusted_mode->crtc_hdisplay; |
1422 | adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_htotal; |
1423 | |
1424 | if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE0) { |
1425 | if (intel_dsi->dual_link) { |
1426 | adjusted_mode->crtc_hsync_start *= 2; |
1427 | adjusted_mode->crtc_hsync_end *= 2; |
1428 | } |
1429 | } |
1430 | adjusted_mode->crtc_vblank_start = adjusted_mode->crtc_vdisplay; |
1431 | adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vtotal; |
1432 | } |
1433 | |
1434 | static bool_Bool gen11_dsi_is_periodic_cmd_mode(struct intel_dsi *intel_dsi) |
1435 | { |
1436 | struct drm_device *dev = intel_dsi->base.base.dev; |
1437 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
1438 | enum transcoder dsi_trans; |
1439 | u32 val; |
1440 | |
1441 | if (intel_dsi->ports == BIT(PORT_B)(1UL << (PORT_B))) |
1442 | dsi_trans = TRANSCODER_DSI_1; |
1443 | else |
1444 | dsi_trans = TRANSCODER_DSI_0; |
1445 | |
1446 | val = intel_de_read(dev_priv, DSI_TRANS_FUNC_CONF(dsi_trans)((const i915_reg_t){ .reg = (((0x6b030) + ((dsi_trans) - TRANSCODER_DSI_0 ) * ((0x6b830) - (0x6b030)))) })); |
1447 | return (val & DSI_PERIODIC_FRAME_UPDATE_ENABLE(1 << 29)); |
1448 | } |
1449 | |
1450 | static void gen11_dsi_get_config(struct intel_encoder *encoder, |
1451 | struct intel_crtc_state *pipe_config) |
1452 | { |
1453 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
1454 | struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (pipe_config->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );}); |
1455 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1456 | |
1457 | intel_dsc_get_config(encoder, pipe_config); |
1458 | |
1459 | /* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */ |
1460 | pipe_config->port_clock = intel_dpll_get_freq(i915, |
1461 | pipe_config->shared_dpll); |
1462 | |
1463 | pipe_config->hw.adjusted_mode.crtc_clock = intel_dsi->pclk; |
1464 | if (intel_dsi->dual_link) |
1465 | pipe_config->hw.adjusted_mode.crtc_clock *= 2; |
1466 | |
1467 | gen11_dsi_get_timings(encoder, pipe_config); |
1468 | pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI)(1UL << (INTEL_OUTPUT_DSI)); |
1469 | pipe_config->pipe_bpp = bdw_get_pipemisc_bpp(crtc); |
1470 | |
1471 | if (gen11_dsi_is_periodic_cmd_mode(intel_dsi)) |
1472 | pipe_config->mode_flags |= I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE(1<<5); |
1473 | } |
1474 | |
1475 | static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder, |
1476 | struct intel_crtc_state *crtc_state) |
1477 | { |
1478 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1479 | struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; |
1480 | int dsc_max_bpc = INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 12 ? 12 : 10; |
1481 | bool_Bool use_dsc; |
1482 | int ret; |
1483 | |
1484 | use_dsc = intel_bios_get_dsc_params(encoder, crtc_state, dsc_max_bpc); |
1485 | if (!use_dsc) |
1486 | return 0; |
1487 | |
1488 | if (crtc_state->pipe_bpp < 8 * 3) |
1489 | return -EINVAL22; |
1490 | |
1491 | /* FIXME: split only when necessary */ |
1492 | if (crtc_state->dsc.slice_count > 1) |
1493 | crtc_state->dsc.dsc_split = true1; |
1494 | |
1495 | vdsc_cfg->convert_rgb = true1; |
1496 | |
1497 | ret = intel_dsc_compute_params(encoder, crtc_state); |
1498 | if (ret) |
1499 | return ret; |
1500 | |
1501 | /* DSI specific sanity checks on the common code */ |
1502 | drm_WARN_ON(&dev_priv->drm, vdsc_cfg->vbr_enable)({ int __ret = !!((vdsc_cfg->vbr_enable)); if (__ret) printf ("%s %s: " "%s", dev_driver_string(((&dev_priv->drm))-> dev), "", "drm_WARN_ON(" "vdsc_cfg->vbr_enable" ")"); __builtin_expect (!!(__ret), 0); }); |
1503 | drm_WARN_ON(&dev_priv->drm, vdsc_cfg->simple_422)({ int __ret = !!((vdsc_cfg->simple_422)); if (__ret) printf ("%s %s: " "%s", dev_driver_string(((&dev_priv->drm))-> dev), "", "drm_WARN_ON(" "vdsc_cfg->simple_422" ")"); __builtin_expect (!!(__ret), 0); }); |
1504 | drm_WARN_ON(&dev_priv->drm,({ int __ret = !!((vdsc_cfg->pic_width % vdsc_cfg->slice_width )); if (__ret) printf("%s %s: " "%s", dev_driver_string(((& dev_priv->drm))->dev), "", "drm_WARN_ON(" "vdsc_cfg->pic_width % vdsc_cfg->slice_width" ")"); __builtin_expect(!!(__ret), 0); }) |
1505 | vdsc_cfg->pic_width % vdsc_cfg->slice_width)({ int __ret = !!((vdsc_cfg->pic_width % vdsc_cfg->slice_width )); if (__ret) printf("%s %s: " "%s", dev_driver_string(((& dev_priv->drm))->dev), "", "drm_WARN_ON(" "vdsc_cfg->pic_width % vdsc_cfg->slice_width" ")"); __builtin_expect(!!(__ret), 0); }); |
1506 | drm_WARN_ON(&dev_priv->drm, vdsc_cfg->slice_height < 8)({ int __ret = !!((vdsc_cfg->slice_height < 8)); if (__ret ) printf("%s %s: " "%s", dev_driver_string(((&dev_priv-> drm))->dev), "", "drm_WARN_ON(" "vdsc_cfg->slice_height < 8" ")"); __builtin_expect(!!(__ret), 0); }); |
1507 | drm_WARN_ON(&dev_priv->drm,({ int __ret = !!((vdsc_cfg->pic_height % vdsc_cfg->slice_height )); if (__ret) printf("%s %s: " "%s", dev_driver_string(((& dev_priv->drm))->dev), "", "drm_WARN_ON(" "vdsc_cfg->pic_height % vdsc_cfg->slice_height" ")"); __builtin_expect(!!(__ret), 0); }) |
1508 | vdsc_cfg->pic_height % vdsc_cfg->slice_height)({ int __ret = !!((vdsc_cfg->pic_height % vdsc_cfg->slice_height )); if (__ret) printf("%s %s: " "%s", dev_driver_string(((& dev_priv->drm))->dev), "", "drm_WARN_ON(" "vdsc_cfg->pic_height % vdsc_cfg->slice_height" ")"); __builtin_expect(!!(__ret), 0); }); |
1509 | |
1510 | ret = drm_dsc_compute_rc_parameters(vdsc_cfg); |
1511 | if (ret) |
1512 | return ret; |
1513 | |
1514 | crtc_state->dsc.compression_enable = true1; |
1515 | |
1516 | return 0; |
1517 | } |
1518 | |
1519 | static int gen11_dsi_compute_config(struct intel_encoder *encoder, |
1520 | struct intel_crtc_state *pipe_config, |
1521 | struct drm_connector_state *conn_state) |
1522 | { |
1523 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
1524 | struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,({ const __typeof( ((struct intel_dsi *)0)->base ) *__mptr = (encoder); (struct intel_dsi *)( (char *)__mptr - __builtin_offsetof (struct intel_dsi, base) );}) |
1525 | base)({ const __typeof( ((struct intel_dsi *)0)->base ) *__mptr = (encoder); (struct intel_dsi *)( (char *)__mptr - __builtin_offsetof (struct intel_dsi, base) );}); |
1526 | struct intel_connector *intel_connector = intel_dsi->attached_connector; |
1527 | const struct drm_display_mode *fixed_mode = |
1528 | intel_connector->panel.fixed_mode; |
1529 | struct drm_display_mode *adjusted_mode = |
1530 | &pipe_config->hw.adjusted_mode; |
1531 | int ret; |
1532 | |
1533 | pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; |
1534 | intel_fixed_panel_mode(fixed_mode, adjusted_mode); |
1535 | |
1536 | ret = intel_pch_panel_fitting(pipe_config, conn_state); |
1537 | if (ret) |
1538 | return ret; |
1539 | |
1540 | adjusted_mode->flags = 0; |
1541 | |
1542 | /* Dual link goes to trancoder DSI'0' */ |
1543 | if (intel_dsi->ports == BIT(PORT_B)(1UL << (PORT_B))) |
1544 | pipe_config->cpu_transcoder = TRANSCODER_DSI_1; |
1545 | else |
1546 | pipe_config->cpu_transcoder = TRANSCODER_DSI_0; |
1547 | |
1548 | if (intel_dsi->pixel_format == MIPI_DSI_FMT_RGB888) |
1549 | pipe_config->pipe_bpp = 24; |
1550 | else |
1551 | pipe_config->pipe_bpp = 18; |
1552 | |
1553 | pipe_config->clock_set = true1; |
1554 | |
1555 | if (gen11_dsi_dsc_compute_config(encoder, pipe_config)) |
1556 | drm_dbg_kms(&i915->drm, "Attempting to use DSC failed\n")drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Attempting to use DSC failed\n" ); |
1557 | |
1558 | pipe_config->port_clock = afe_clk(encoder, pipe_config) / 5; |
1559 | |
1560 | /* |
1561 | * In case of TE GATE cmd mode, we |
1562 | * receive TE from the slave if |
1563 | * dual link is enabled |
1564 | */ |
1565 | if (is_cmd_mode(intel_dsi)) { |
1566 | if (intel_dsi->ports == (BIT(PORT_B)(1UL << (PORT_B)) | BIT(PORT_A)(1UL << (PORT_A)))) |
1567 | pipe_config->mode_flags |= |
1568 | I915_MODE_FLAG_DSI_USE_TE1(1<<4) | |
1569 | I915_MODE_FLAG_DSI_USE_TE0(1<<3); |
1570 | else if (intel_dsi->ports == BIT(PORT_B)(1UL << (PORT_B))) |
1571 | pipe_config->mode_flags |= |
1572 | I915_MODE_FLAG_DSI_USE_TE1(1<<4); |
1573 | else |
1574 | pipe_config->mode_flags |= |
1575 | I915_MODE_FLAG_DSI_USE_TE0(1<<3); |
1576 | } |
1577 | |
1578 | return 0; |
1579 | } |
1580 | |
1581 | static void gen11_dsi_get_power_domains(struct intel_encoder *encoder, |
1582 | struct intel_crtc_state *crtc_state) |
1583 | { |
1584 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(encoder->base.dev); |
1585 | |
1586 | get_dsi_io_power_domains(i915, |
1587 | enc_to_intel_dsi(encoder)); |
1588 | } |
1589 | |
1590 | static bool_Bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, |
1591 | enum pipe *pipe) |
1592 | { |
1593 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(encoder->base.dev); |
1594 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
1595 | enum transcoder dsi_trans; |
1596 | intel_wakeref_t wakeref; |
1597 | enum port port; |
1598 | bool_Bool ret = false0; |
1599 | u32 tmp; |
1600 | |
1601 | wakeref = intel_display_power_get_if_enabled(dev_priv, |
1602 | encoder->power_domain); |
1603 | if (!wakeref) |
1604 | return false0; |
1605 | |
1606 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1607 | dsi_trans = dsi_port_to_transcoder(port); |
1608 | tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans)((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> trans_offsets[(dsi_trans)] - (&(dev_priv)->__info)-> trans_offsets[TRANSCODER_A] + (0x60400) + ((&(dev_priv)-> __info)->display_mmio_offset))) })); |
1609 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK(7 << 12)) { |
1610 | case TRANS_DDI_EDP_INPUT_A_ON(0 << 12): |
1611 | *pipe = PIPE_A; |
1612 | break; |
1613 | case TRANS_DDI_EDP_INPUT_B_ONOFF(5 << 12): |
1614 | *pipe = PIPE_B; |
1615 | break; |
1616 | case TRANS_DDI_EDP_INPUT_C_ONOFF(6 << 12): |
1617 | *pipe = PIPE_C; |
1618 | break; |
1619 | case TRANS_DDI_EDP_INPUT_D_ONOFF(7 << 12): |
1620 | *pipe = PIPE_D; |
1621 | break; |
1622 | default: |
1623 | drm_err(&dev_priv->drm, "Invalid PIPE input\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid PIPE input\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
1624 | goto out; |
1625 | } |
1626 | |
1627 | tmp = intel_de_read(dev_priv, PIPECONF(dsi_trans)((const i915_reg_t){ .reg = ((&(dev_priv)->__info)-> pipe_offsets[dsi_trans] - (&(dev_priv)->__info)->pipe_offsets [PIPE_A] + (0x70008) + ((&(dev_priv)->__info)->display_mmio_offset )) })); |
1628 | ret = tmp & PIPECONF_ENABLE(1 << 31); |
1629 | } |
1630 | out: |
1631 | intel_display_power_put(dev_priv, encoder->power_domain, wakeref); |
1632 | return ret; |
1633 | } |
1634 | |
1635 | static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder) |
1636 | { |
1637 | intel_encoder_destroy(encoder); |
1638 | } |
1639 | |
1640 | static const struct drm_encoder_funcs gen11_dsi_encoder_funcs = { |
1641 | .destroy = gen11_dsi_encoder_destroy, |
1642 | }; |
1643 | |
1644 | static const struct drm_connector_funcs gen11_dsi_connector_funcs = { |
1645 | .detect = intel_panel_detect, |
1646 | .late_register = intel_connector_register, |
1647 | .early_unregister = intel_connector_unregister, |
1648 | .destroy = intel_connector_destroy, |
1649 | .fill_modes = drm_helper_probe_single_connector_modes, |
1650 | .atomic_get_property = intel_digital_connector_atomic_get_property, |
1651 | .atomic_set_property = intel_digital_connector_atomic_set_property, |
1652 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
1653 | .atomic_duplicate_state = intel_digital_connector_duplicate_state, |
1654 | }; |
1655 | |
1656 | static const struct drm_connector_helper_funcs gen11_dsi_connector_helper_funcs = { |
1657 | .get_modes = intel_dsi_get_modes, |
1658 | .mode_valid = gen11_dsi_mode_valid, |
1659 | .atomic_check = intel_digital_connector_atomic_check, |
1660 | }; |
1661 | |
1662 | static int gen11_dsi_host_attach(struct mipi_dsi_host *host, |
1663 | struct mipi_dsi_device *dsi) |
1664 | { |
1665 | return 0; |
1666 | } |
1667 | |
1668 | static int gen11_dsi_host_detach(struct mipi_dsi_host *host, |
1669 | struct mipi_dsi_device *dsi) |
1670 | { |
1671 | return 0; |
1672 | } |
1673 | |
1674 | static ssize_t gen11_dsi_host_transfer(struct mipi_dsi_host *host, |
1675 | const struct mipi_dsi_msg *msg) |
1676 | { |
1677 | struct intel_dsi_host *intel_dsi_host = to_intel_dsi_host(host); |
1678 | struct mipi_dsi_packet dsi_pkt; |
1679 | ssize_t ret; |
1680 | bool_Bool enable_lpdt = false0; |
1681 | |
1682 | ret = mipi_dsi_create_packet(&dsi_pkt, msg); |
1683 | if (ret < 0) |
1684 | return ret; |
1685 | |
1686 | if (msg->flags & MIPI_DSI_MSG_USE_LPM(1 << 0)) |
1687 | enable_lpdt = true1; |
1688 | |
1689 | /* send packet header */ |
1690 | ret = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt); |
1691 | if (ret < 0) |
1692 | return ret; |
1693 | |
1694 | /* only long packet contains payload */ |
1695 | if (mipi_dsi_packet_format_is_long(msg->type)) { |
1696 | ret = dsi_send_pkt_payld(intel_dsi_host, dsi_pkt); |
1697 | if (ret < 0) |
1698 | return ret; |
1699 | } |
1700 | |
1701 | //TODO: add payload receive code if needed |
1702 | |
1703 | ret = sizeof(dsi_pkt.header) + dsi_pkt.payload_length; |
1704 | |
1705 | return ret; |
1706 | } |
1707 | |
1708 | static const struct mipi_dsi_host_ops gen11_dsi_host_ops = { |
1709 | .attach = gen11_dsi_host_attach, |
1710 | .detach = gen11_dsi_host_detach, |
1711 | .transfer = gen11_dsi_host_transfer, |
1712 | }; |
1713 | |
1714 | #define ICL_PREPARE_CNT_MAX0x7 0x7 |
1715 | #define ICL_CLK_ZERO_CNT_MAX0xf 0xf |
1716 | #define ICL_TRAIL_CNT_MAX0x7 0x7 |
1717 | #define ICL_TCLK_PRE_CNT_MAX0x3 0x3 |
1718 | #define ICL_TCLK_POST_CNT_MAX0x7 0x7 |
1719 | #define ICL_HS_ZERO_CNT_MAX0xf 0xf |
1720 | #define ICL_EXIT_ZERO_CNT_MAX0x7 0x7 |
1721 | |
1722 | static void icl_dphy_param_init(struct intel_dsi *intel_dsi) |
1723 | { |
1724 | struct drm_device *dev = intel_dsi->base.base.dev; |
1725 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); |
1726 | struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; |
1727 | u32 tlpx_ns; |
1728 | u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; |
1729 | u32 ths_prepare_ns, tclk_trail_ns; |
1730 | u32 hs_zero_cnt; |
1731 | u32 tclk_pre_cnt, tclk_post_cnt; |
1732 | |
1733 | tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); |
1734 | |
1735 | tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail)(((mipi_config->tclk_trail)>(mipi_config->ths_trail) )?(mipi_config->tclk_trail):(mipi_config->ths_trail)); |
1736 | ths_prepare_ns = max(mipi_config->ths_prepare,(((mipi_config->ths_prepare)>(mipi_config->tclk_prepare ))?(mipi_config->ths_prepare):(mipi_config->tclk_prepare )) |
1737 | mipi_config->tclk_prepare)(((mipi_config->ths_prepare)>(mipi_config->tclk_prepare ))?(mipi_config->ths_prepare):(mipi_config->tclk_prepare )); |
1738 | |
1739 | /* |
1740 | * prepare cnt in escape clocks |
1741 | * this field represents a hexadecimal value with a precision |
1742 | * of 1.2 – i.e. the most significant bit is the integer |
1743 | * and the least significant 2 bits are fraction bits. |
1744 | * so, the field can represent a range of 0.25 to 1.75 |
1745 | */ |
1746 | prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * 4, tlpx_ns)(((ths_prepare_ns * 4) + ((tlpx_ns) - 1)) / (tlpx_ns)); |
1747 | if (prepare_cnt > ICL_PREPARE_CNT_MAX0x7) { |
1748 | drm_dbg_kms(&dev_priv->drm, "prepare_cnt out of range (%d)\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "prepare_cnt out of range (%d)\n" , prepare_cnt) |
1749 | prepare_cnt)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "prepare_cnt out of range (%d)\n" , prepare_cnt); |
1750 | prepare_cnt = ICL_PREPARE_CNT_MAX0x7; |
1751 | } |
1752 | |
1753 | /* clk zero count in escape clocks */ |
1754 | clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero -(((mipi_config->tclk_prepare_clkzero - ths_prepare_ns) + ( (tlpx_ns) - 1)) / (tlpx_ns)) |
1755 | ths_prepare_ns, tlpx_ns)(((mipi_config->tclk_prepare_clkzero - ths_prepare_ns) + ( (tlpx_ns) - 1)) / (tlpx_ns)); |
1756 | if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX0xf) { |
1757 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "clk_zero_cnt out of range (%d)\n" , clk_zero_cnt) |
1758 | "clk_zero_cnt out of range (%d)\n", clk_zero_cnt)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "clk_zero_cnt out of range (%d)\n" , clk_zero_cnt); |
1759 | clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX0xf; |
1760 | } |
1761 | |
1762 | /* trail cnt in escape clocks*/ |
1763 | trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns)(((tclk_trail_ns) + ((tlpx_ns) - 1)) / (tlpx_ns)); |
1764 | if (trail_cnt > ICL_TRAIL_CNT_MAX0x7) { |
1765 | drm_dbg_kms(&dev_priv->drm, "trail_cnt out of range (%d)\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "trail_cnt out of range (%d)\n" , trail_cnt) |
1766 | trail_cnt)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "trail_cnt out of range (%d)\n" , trail_cnt); |
1767 | trail_cnt = ICL_TRAIL_CNT_MAX0x7; |
1768 | } |
1769 | |
1770 | /* tclk pre count in escape clocks */ |
1771 | tclk_pre_cnt = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns)(((mipi_config->tclk_pre) + ((tlpx_ns) - 1)) / (tlpx_ns)); |
1772 | if (tclk_pre_cnt > ICL_TCLK_PRE_CNT_MAX0x3) { |
1773 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "tclk_pre_cnt out of range (%d)\n" , tclk_pre_cnt) |
1774 | "tclk_pre_cnt out of range (%d)\n", tclk_pre_cnt)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "tclk_pre_cnt out of range (%d)\n" , tclk_pre_cnt); |
1775 | tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX0x3; |
1776 | } |
1777 | |
1778 | /* tclk post count in escape clocks */ |
1779 | tclk_post_cnt = DIV_ROUND_UP(mipi_config->tclk_post, tlpx_ns)(((mipi_config->tclk_post) + ((tlpx_ns) - 1)) / (tlpx_ns)); |
1780 | if (tclk_post_cnt > ICL_TCLK_POST_CNT_MAX0x7) { |
1781 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "tclk_post_cnt out of range (%d)\n" , tclk_post_cnt) |
1782 | "tclk_post_cnt out of range (%d)\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "tclk_post_cnt out of range (%d)\n" , tclk_post_cnt) |
1783 | tclk_post_cnt)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "tclk_post_cnt out of range (%d)\n" , tclk_post_cnt); |
1784 | tclk_post_cnt = ICL_TCLK_POST_CNT_MAX0x7; |
1785 | } |
1786 | |
1787 | /* hs zero cnt in escape clocks */ |
1788 | hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero -(((mipi_config->ths_prepare_hszero - ths_prepare_ns) + ((tlpx_ns ) - 1)) / (tlpx_ns)) |
1789 | ths_prepare_ns, tlpx_ns)(((mipi_config->ths_prepare_hszero - ths_prepare_ns) + ((tlpx_ns ) - 1)) / (tlpx_ns)); |
1790 | if (hs_zero_cnt > ICL_HS_ZERO_CNT_MAX0xf) { |
1791 | drm_dbg_kms(&dev_priv->drm, "hs_zero_cnt out of range (%d)\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "hs_zero_cnt out of range (%d)\n" , hs_zero_cnt) |
1792 | hs_zero_cnt)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "hs_zero_cnt out of range (%d)\n" , hs_zero_cnt); |
1793 | hs_zero_cnt = ICL_HS_ZERO_CNT_MAX0xf; |
1794 | } |
1795 | |
1796 | /* hs exit zero cnt in escape clocks */ |
1797 | exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns)(((mipi_config->ths_exit) + ((tlpx_ns) - 1)) / (tlpx_ns)); |
1798 | if (exit_zero_cnt > ICL_EXIT_ZERO_CNT_MAX0x7) { |
1799 | drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "exit_zero_cnt out of range (%d)\n" , exit_zero_cnt) |
1800 | "exit_zero_cnt out of range (%d)\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "exit_zero_cnt out of range (%d)\n" , exit_zero_cnt) |
1801 | exit_zero_cnt)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "exit_zero_cnt out of range (%d)\n" , exit_zero_cnt); |
1802 | exit_zero_cnt = ICL_EXIT_ZERO_CNT_MAX0x7; |
1803 | } |
1804 | |
1805 | /* clock lane dphy timings */ |
1806 | intel_dsi->dphy_reg = (CLK_PREPARE_OVERRIDE(1 << 31) | |
1807 | CLK_PREPARE(prepare_cnt)((prepare_cnt) << 28) | |
1808 | CLK_ZERO_OVERRIDE(1 << 27) | |
1809 | CLK_ZERO(clk_zero_cnt)((clk_zero_cnt) << 20) | |
1810 | CLK_PRE_OVERRIDE(1 << 19) | |
1811 | CLK_PRE(tclk_pre_cnt)((tclk_pre_cnt) << 16) | |
1812 | CLK_POST_OVERRIDE(1 << 15) | |
1813 | CLK_POST(tclk_post_cnt)((tclk_post_cnt) << 8) | |
1814 | CLK_TRAIL_OVERRIDE(1 << 7) | |
1815 | CLK_TRAIL(trail_cnt)((trail_cnt) << 0)); |
1816 | |
1817 | /* data lanes dphy timings */ |
1818 | intel_dsi->dphy_data_lane_reg = (HS_PREPARE_OVERRIDE(1 << 31) | |
1819 | HS_PREPARE(prepare_cnt)((prepare_cnt) << 24) | |
1820 | HS_ZERO_OVERRIDE(1 << 23) | |
1821 | HS_ZERO(hs_zero_cnt)((hs_zero_cnt) << 16) | |
1822 | HS_TRAIL_OVERRIDE(1 << 15) | |
1823 | HS_TRAIL(trail_cnt)((trail_cnt) << 8) | |
1824 | HS_EXIT_OVERRIDE(1 << 7) | |
1825 | HS_EXIT(exit_zero_cnt)((exit_zero_cnt) << 0)); |
1826 | |
1827 | intel_dsi_log_params(intel_dsi); |
1828 | } |
1829 | |
1830 | static void icl_dsi_add_properties(struct intel_connector *connector) |
1831 | { |
1832 | u32 allowed_scalers; |
1833 | |
1834 | allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT)(1UL << (3)) | |
1835 | BIT(DRM_MODE_SCALE_FULLSCREEN)(1UL << (1)) | |
1836 | BIT(DRM_MODE_SCALE_CENTER)(1UL << (2)); |
1837 | |
1838 | drm_connector_attach_scaling_mode_property(&connector->base, |
1839 | allowed_scalers); |
1840 | |
1841 | connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT3; |
1842 | |
1843 | drm_connector_set_panel_orientation_with_quirk(&connector->base, |
1844 | intel_dsi_get_panel_orientation(connector), |
1845 | connector->panel.fixed_mode->hdisplay, |
1846 | connector->panel.fixed_mode->vdisplay); |
1847 | } |
1848 | |
1849 | void icl_dsi_init(struct drm_i915_privateinteldrm_softc *dev_priv) |
1850 | { |
1851 | struct drm_device *dev = &dev_priv->drm; |
1852 | struct intel_dsi *intel_dsi; |
1853 | struct intel_encoder *encoder; |
1854 | struct intel_connector *intel_connector; |
1855 | struct drm_connector *connector; |
1856 | struct drm_display_mode *fixed_mode; |
1857 | enum port port; |
1858 | |
1859 | if (!intel_bios_is_dsi_present(dev_priv, &port)) |
1860 | return; |
1861 | |
1862 | intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL(0x0001 | 0x0004)); |
1863 | if (!intel_dsi) |
1864 | return; |
1865 | |
1866 | intel_connector = intel_connector_alloc(); |
1867 | if (!intel_connector) { |
1868 | kfree(intel_dsi); |
1869 | return; |
1870 | } |
1871 | |
1872 | encoder = &intel_dsi->base; |
1873 | intel_dsi->attached_connector = intel_connector; |
1874 | connector = &intel_connector->base; |
1875 | |
1876 | /* register DSI encoder with DRM subsystem */ |
1877 | drm_encoder_init(dev, &encoder->base, &gen11_dsi_encoder_funcs, |
1878 | DRM_MODE_ENCODER_DSI6, "DSI %c", port_name(port)((port) + 'A')); |
1879 | |
1880 | encoder->pre_pll_enable = gen11_dsi_pre_pll_enable; |
1881 | encoder->pre_enable = gen11_dsi_pre_enable; |
1882 | encoder->enable = gen11_dsi_enable; |
1883 | encoder->disable = gen11_dsi_disable; |
1884 | encoder->post_disable = gen11_dsi_post_disable; |
1885 | encoder->port = port; |
1886 | encoder->get_config = gen11_dsi_get_config; |
1887 | encoder->update_pipe = intel_panel_update_backlight; |
1888 | encoder->compute_config = gen11_dsi_compute_config; |
1889 | encoder->get_hw_state = gen11_dsi_get_hw_state; |
1890 | encoder->type = INTEL_OUTPUT_DSI; |
1891 | encoder->cloneable = 0; |
1892 | encoder->pipe_mask = ~0; |
1893 | encoder->power_domain = POWER_DOMAIN_PORT_DSI; |
1894 | encoder->get_power_domains = gen11_dsi_get_power_domains; |
1895 | |
1896 | /* register DSI connector with DRM subsystem */ |
1897 | drm_connector_init(dev, connector, &gen11_dsi_connector_funcs, |
1898 | DRM_MODE_CONNECTOR_DSI16); |
1899 | drm_connector_helper_add(connector, &gen11_dsi_connector_helper_funcs); |
1900 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
1901 | connector->interlace_allowed = false0; |
1902 | connector->doublescan_allowed = false0; |
1903 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
1904 | |
1905 | /* attach connector to encoder */ |
1906 | intel_connector_attach_encoder(intel_connector, encoder); |
1907 | |
1908 | mutex_lock(&dev->mode_config.mutex)rw_enter_write(&dev->mode_config.mutex); |
1909 | fixed_mode = intel_panel_vbt_fixed_mode(intel_connector); |
1910 | mutex_unlock(&dev->mode_config.mutex)rw_exit_write(&dev->mode_config.mutex); |
1911 | |
1912 | if (!fixed_mode) { |
1913 | drm_err(&dev_priv->drm, "DSI fixed mode info missing\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DSI fixed mode info missing\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__); |
1914 | goto err; |
1915 | } |
1916 | |
1917 | intel_panel_init(&intel_connector->panel, fixed_mode, NULL((void *)0)); |
1918 | intel_panel_setup_backlight(connector, INVALID_PIPE); |
1919 | |
1920 | if (dev_priv->vbt.dsi.config->dual_link) |
1921 | intel_dsi->ports = BIT(PORT_A)(1UL << (PORT_A)) | BIT(PORT_B)(1UL << (PORT_B)); |
1922 | else |
1923 | intel_dsi->ports = BIT(port)(1UL << (port)); |
1924 | |
1925 | intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports; |
1926 | intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports; |
1927 | |
1928 | for_each_dsi_port(port, intel_dsi->ports)for ((port) = PORT_A; (port) < I915_MAX_PORTS; (port)++) if (!((intel_dsi->ports) & (1UL << (port)))) {} else { |
1929 | struct intel_dsi_host *host; |
1930 | |
1931 | host = intel_dsi_host_init(intel_dsi, &gen11_dsi_host_ops, port); |
1932 | if (!host) |
1933 | goto err; |
1934 | |
1935 | intel_dsi->dsi_hosts[port] = host; |
1936 | } |
1937 | |
1938 | if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID1)) { |
1939 | drm_dbg_kms(&dev_priv->drm, "no device found\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "no device found\n" ); |
1940 | goto err; |
1941 | } |
1942 | |
1943 | icl_dphy_param_init(intel_dsi); |
1944 | |
1945 | icl_dsi_add_properties(intel_connector); |
1946 | return; |
1947 | |
1948 | err: |
1949 | drm_connector_cleanup(connector); |
1950 | drm_encoder_cleanup(&encoder->base); |
1951 | kfree(intel_dsi); |
1952 | kfree(intel_connector); |
1953 | } |