Rev 4560 | Rev 6084 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4560 | Rev 5060 | ||
---|---|---|---|
Line 32... | Line 32... | ||
32 | #include |
32 | #include |
33 | #include "intel_drv.h" |
33 | #include "intel_drv.h" |
34 | #include |
34 | #include |
35 | #include "i915_drv.h" |
35 | #include "i915_drv.h" |
Line 36... | Line -... | ||
36 | - | ||
37 | enum disp_clk { |
- | |
38 | CDCLK, |
- | |
39 | CZCLK |
- | |
40 | }; |
- | |
41 | 36 | ||
42 | struct gmbus_port { |
37 | struct gmbus_port { |
43 | const char *name; |
38 | const char *name; |
44 | int reg; |
39 | int reg; |
Line 61... | Line 56... | ||
61 | to_intel_gmbus(struct i2c_adapter *i2c) |
56 | to_intel_gmbus(struct i2c_adapter *i2c) |
62 | { |
57 | { |
63 | return container_of(i2c, struct intel_gmbus, adapter); |
58 | return container_of(i2c, struct intel_gmbus, adapter); |
64 | } |
59 | } |
Line 65... | Line -... | ||
65 | - | ||
66 | static int get_disp_clk_div(struct drm_i915_private *dev_priv, |
- | |
67 | enum disp_clk clk) |
- | |
68 | { |
- | |
69 | u32 reg_val; |
- | |
70 | int clk_ratio; |
- | |
71 | - | ||
72 | reg_val = I915_READ(CZCLK_CDCLK_FREQ_RATIO); |
- | |
73 | - | ||
74 | if (clk == CDCLK) |
- | |
75 | clk_ratio = |
- | |
76 | ((reg_val & CDCLK_FREQ_MASK) >> CDCLK_FREQ_SHIFT) + 1; |
- | |
77 | else |
- | |
78 | clk_ratio = (reg_val & CZCLK_FREQ_MASK) + 1; |
- | |
79 | - | ||
80 | return clk_ratio; |
- | |
81 | } |
- | |
82 | - | ||
83 | static void gmbus_set_freq(struct drm_i915_private *dev_priv) |
- | |
84 | { |
- | |
85 | int vco, gmbus_freq = 0, cdclk_div; |
- | |
86 | - | ||
87 | BUG_ON(!IS_VALLEYVIEW(dev_priv->dev)); |
- | |
88 | - | ||
89 | vco = valleyview_get_vco(dev_priv); |
- | |
90 | - | ||
91 | /* Get the CDCLK divide ratio */ |
- | |
92 | cdclk_div = get_disp_clk_div(dev_priv, CDCLK); |
- | |
93 | - | ||
94 | /* |
- | |
95 | * Program the gmbus_freq based on the cdclk frequency. |
- | |
96 | * BSpec erroneously claims we should aim for 4MHz, but |
- | |
97 | * in fact 1MHz is the correct frequency. |
- | |
98 | */ |
- | |
99 | if (cdclk_div) |
- | |
100 | gmbus_freq = (vco << 1) / cdclk_div; |
- | |
101 | - | ||
102 | if (WARN_ON(gmbus_freq == 0)) |
- | |
103 | return; |
- | |
104 | - | ||
105 | I915_WRITE(GMBUSFREQ_VLV, gmbus_freq); |
- | |
106 | } |
- | |
107 | 60 | ||
108 | void |
61 | void |
109 | intel_i2c_reset(struct drm_device *dev) |
62 | intel_i2c_reset(struct drm_device *dev) |
110 | { |
63 | { |
Line 111... | Line -... | ||
111 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
112 | - | ||
113 | /* |
- | |
114 | * In BIOS-less system, program the correct gmbus frequency |
- | |
115 | * before reading edid. |
- | |
116 | */ |
- | |
117 | if (IS_VALLEYVIEW(dev)) |
- | |
118 | gmbus_set_freq(dev_priv); |
64 | struct drm_i915_private *dev_priv = dev->dev_private; |
119 | 65 | ||
120 | I915_WRITE(dev_priv->gpio_mmio_base + GMBUS0, 0); |
66 | I915_WRITE(dev_priv->gpio_mmio_base + GMBUS0, 0); |
Line 121... | Line 67... | ||
121 | I915_WRITE(dev_priv->gpio_mmio_base + GMBUS4, 0); |
67 | I915_WRITE(dev_priv->gpio_mmio_base + GMBUS4, 0); |
Line 256... | Line 202... | ||
256 | algo->udelay = I2C_RISEFALL_TIME; |
202 | algo->udelay = I2C_RISEFALL_TIME; |
257 | algo->timeout = usecs_to_jiffies(2200); |
203 | algo->timeout = usecs_to_jiffies(2200); |
258 | algo->data = bus; |
204 | algo->data = bus; |
259 | } |
205 | } |
Line 260... | Line -... | ||
260 | - | ||
261 | /* |
- | |
262 | * gmbus on gen4 seems to be able to generate legacy interrupts even when in MSI |
- | |
263 | * mode. This results in spurious interrupt warnings if the legacy irq no. is |
- | |
264 | * shared with another device. The kernel then disables that interrupt source |
- | |
265 | * and so prevents the other device from working properly. |
- | |
266 | */ |
- | |
267 | #define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5) |
206 | |
268 | static int |
207 | static int |
269 | gmbus_wait_hw_status(struct drm_i915_private *dev_priv, |
208 | gmbus_wait_hw_status(struct drm_i915_private *dev_priv, |
270 | u32 gmbus2_status, |
209 | u32 gmbus2_status, |
271 | u32 gmbus4_irq_en) |
210 | u32 gmbus4_irq_en) |