diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_i2c.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_i2c.c | 34 |
1 files changed, 15 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index c2649c7df14c..de03989d6df3 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -38,16 +38,18 @@ | |||
38 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable) | 38 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable) |
39 | { | 39 | { |
40 | struct drm_i915_private *dev_priv = dev->dev_private; | 40 | struct drm_i915_private *dev_priv = dev->dev_private; |
41 | u32 val; | ||
41 | 42 | ||
42 | /* When using bit bashing for I2C, this bit needs to be set to 1 */ | 43 | /* When using bit bashing for I2C, this bit needs to be set to 1 */ |
43 | if (!IS_PINEVIEW(dev)) | 44 | if (!IS_PINEVIEW(dev)) |
44 | return; | 45 | return; |
46 | |||
47 | val = I915_READ(DSPCLK_GATE_D); | ||
45 | if (enable) | 48 | if (enable) |
46 | I915_WRITE(DSPCLK_GATE_D, | 49 | val |= DPCUNIT_CLOCK_GATE_DISABLE; |
47 | I915_READ(DSPCLK_GATE_D) | DPCUNIT_CLOCK_GATE_DISABLE); | ||
48 | else | 50 | else |
49 | I915_WRITE(DSPCLK_GATE_D, | 51 | val &= ~DPCUNIT_CLOCK_GATE_DISABLE; |
50 | I915_READ(DSPCLK_GATE_D) & (~DPCUNIT_CLOCK_GATE_DISABLE)); | 52 | I915_WRITE(DSPCLK_GATE_D, val); |
51 | } | 53 | } |
52 | 54 | ||
53 | /* | 55 | /* |
@@ -60,20 +62,14 @@ static int get_clock(void *data) | |||
60 | { | 62 | { |
61 | struct intel_i2c_chan *chan = data; | 63 | struct intel_i2c_chan *chan = data; |
62 | struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; | 64 | struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; |
63 | u32 val; | 65 | return (I915_READ(chan->reg) & GPIO_CLOCK_VAL_IN) != 0; |
64 | |||
65 | val = I915_READ(chan->reg); | ||
66 | return ((val & GPIO_CLOCK_VAL_IN) != 0); | ||
67 | } | 66 | } |
68 | 67 | ||
69 | static int get_data(void *data) | 68 | static int get_data(void *data) |
70 | { | 69 | { |
71 | struct intel_i2c_chan *chan = data; | 70 | struct intel_i2c_chan *chan = data; |
72 | struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; | 71 | struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; |
73 | u32 val; | 72 | return (I915_READ(chan->reg) & GPIO_DATA_VAL_IN) != 0; |
74 | |||
75 | val = I915_READ(chan->reg); | ||
76 | return ((val & GPIO_DATA_VAL_IN) != 0); | ||
77 | } | 73 | } |
78 | 74 | ||
79 | static void set_clock(void *data, int state_high) | 75 | static void set_clock(void *data, int state_high) |
@@ -94,7 +90,7 @@ static void set_clock(void *data, int state_high) | |||
94 | clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | | 90 | clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | |
95 | GPIO_CLOCK_VAL_MASK; | 91 | GPIO_CLOCK_VAL_MASK; |
96 | I915_WRITE(chan->reg, reserved | clock_bits); | 92 | I915_WRITE(chan->reg, reserved | clock_bits); |
97 | udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ | 93 | POSTING_READ(chan->reg); |
98 | } | 94 | } |
99 | 95 | ||
100 | static void set_data(void *data, int state_high) | 96 | static void set_data(void *data, int state_high) |
@@ -116,7 +112,7 @@ static void set_data(void *data, int state_high) | |||
116 | GPIO_DATA_VAL_MASK; | 112 | GPIO_DATA_VAL_MASK; |
117 | 113 | ||
118 | I915_WRITE(chan->reg, reserved | data_bits); | 114 | I915_WRITE(chan->reg, reserved | data_bits); |
119 | udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ | 115 | POSTING_READ(chan->reg); |
120 | } | 116 | } |
121 | 117 | ||
122 | /* Clears the GMBUS setup. Our driver doesn't make use of the GMBUS I2C | 118 | /* Clears the GMBUS setup. Our driver doesn't make use of the GMBUS I2C |
@@ -129,11 +125,10 @@ intel_i2c_reset_gmbus(struct drm_device *dev) | |||
129 | { | 125 | { |
130 | struct drm_i915_private *dev_priv = dev->dev_private; | 126 | struct drm_i915_private *dev_priv = dev->dev_private; |
131 | 127 | ||
132 | if (HAS_PCH_SPLIT(dev)) { | 128 | if (HAS_PCH_SPLIT(dev)) |
133 | I915_WRITE(PCH_GMBUS0, 0); | 129 | I915_WRITE(PCH_GMBUS0, 0); |
134 | } else { | 130 | else |
135 | I915_WRITE(GMBUS0, 0); | 131 | I915_WRITE(GMBUS0, 0); |
136 | } | ||
137 | } | 132 | } |
138 | 133 | ||
139 | /** | 134 | /** |
@@ -177,7 +172,7 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, | |||
177 | chan->algo.setscl = set_clock; | 172 | chan->algo.setscl = set_clock; |
178 | chan->algo.getsda = get_data; | 173 | chan->algo.getsda = get_data; |
179 | chan->algo.getscl = get_clock; | 174 | chan->algo.getscl = get_clock; |
180 | chan->algo.udelay = 20; | 175 | chan->algo.udelay = I2C_RISEFALL_TIME; |
181 | chan->algo.timeout = usecs_to_jiffies(2200); | 176 | chan->algo.timeout = usecs_to_jiffies(2200); |
182 | chan->algo.data = chan; | 177 | chan->algo.data = chan; |
183 | 178 | ||
@@ -191,9 +186,10 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, | |||
191 | /* JJJ: raise SCL and SDA? */ | 186 | /* JJJ: raise SCL and SDA? */ |
192 | intel_i2c_quirk_set(dev, true); | 187 | intel_i2c_quirk_set(dev, true); |
193 | set_data(chan, 1); | 188 | set_data(chan, 1); |
189 | udelay(I2C_RISEFALL_TIME); | ||
194 | set_clock(chan, 1); | 190 | set_clock(chan, 1); |
191 | udelay(I2C_RISEFALL_TIME); | ||
195 | intel_i2c_quirk_set(dev, false); | 192 | intel_i2c_quirk_set(dev, false); |
196 | udelay(20); | ||
197 | 193 | ||
198 | return &chan->adapter; | 194 | return &chan->adapter; |
199 | 195 | ||