diff options
author | Patrik Jakobsson <patrik.r.jakobsson@gmail.com> | 2013-09-16 12:36:37 -0400 |
---|---|---|
committer | Patrik Jakobsson <patrik.r.jakobsson@gmail.com> | 2013-11-08 10:22:08 -0500 |
commit | 86bd4103254adf7f3d32fa5c2578162c9e27b205 (patch) | |
tree | 88120a0e560f0fb2e9ad3a2ff2525fbc9e94a20e /drivers/gpu | |
parent | 2657929d4e7c0a4db5456cc2c9a230a68b07813d (diff) |
drm/gma500: Add aux device support for gmbus
Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/gma500/intel_gmbus.c | 90 |
1 files changed, 49 insertions, 41 deletions
diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c index 62cd42e88f28..566d330aaeea 100644 --- a/drivers/gpu/drm/gma500/intel_gmbus.c +++ b/drivers/gpu/drm/gma500/intel_gmbus.c | |||
@@ -51,6 +51,9 @@ | |||
51 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) | 51 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) |
52 | #define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0) | 52 | #define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0) |
53 | 53 | ||
54 | #define GMBUS_REG_READ(reg) ioread32(dev_priv->gmbus_reg + (reg)) | ||
55 | #define GMBUS_REG_WRITE(reg, val) iowrite32((val), dev_priv->gmbus_reg + (reg)) | ||
56 | |||
54 | /* Intel GPIO access functions */ | 57 | /* Intel GPIO access functions */ |
55 | 58 | ||
56 | #define I2C_RISEFALL_TIME 20 | 59 | #define I2C_RISEFALL_TIME 20 |
@@ -71,7 +74,8 @@ struct intel_gpio { | |||
71 | void | 74 | void |
72 | gma_intel_i2c_reset(struct drm_device *dev) | 75 | gma_intel_i2c_reset(struct drm_device *dev) |
73 | { | 76 | { |
74 | REG_WRITE(GMBUS0, 0); | 77 | struct drm_psb_private *dev_priv = dev->dev_private; |
78 | GMBUS_REG_WRITE(GMBUS0, 0); | ||
75 | } | 79 | } |
76 | 80 | ||
77 | static void intel_i2c_quirk_set(struct drm_psb_private *dev_priv, bool enable) | 81 | static void intel_i2c_quirk_set(struct drm_psb_private *dev_priv, bool enable) |
@@ -98,11 +102,10 @@ static void intel_i2c_quirk_set(struct drm_psb_private *dev_priv, bool enable) | |||
98 | static u32 get_reserved(struct intel_gpio *gpio) | 102 | static u32 get_reserved(struct intel_gpio *gpio) |
99 | { | 103 | { |
100 | struct drm_psb_private *dev_priv = gpio->dev_priv; | 104 | struct drm_psb_private *dev_priv = gpio->dev_priv; |
101 | struct drm_device *dev = dev_priv->dev; | ||
102 | u32 reserved = 0; | 105 | u32 reserved = 0; |
103 | 106 | ||
104 | /* On most chips, these bits must be preserved in software. */ | 107 | /* On most chips, these bits must be preserved in software. */ |
105 | reserved = REG_READ(gpio->reg) & | 108 | reserved = GMBUS_REG_READ(gpio->reg) & |
106 | (GPIO_DATA_PULLUP_DISABLE | | 109 | (GPIO_DATA_PULLUP_DISABLE | |
107 | GPIO_CLOCK_PULLUP_DISABLE); | 110 | GPIO_CLOCK_PULLUP_DISABLE); |
108 | 111 | ||
@@ -113,29 +116,26 @@ static int get_clock(void *data) | |||
113 | { | 116 | { |
114 | struct intel_gpio *gpio = data; | 117 | struct intel_gpio *gpio = data; |
115 | struct drm_psb_private *dev_priv = gpio->dev_priv; | 118 | struct drm_psb_private *dev_priv = gpio->dev_priv; |
116 | struct drm_device *dev = dev_priv->dev; | ||
117 | u32 reserved = get_reserved(gpio); | 119 | u32 reserved = get_reserved(gpio); |
118 | REG_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK); | 120 | GMBUS_REG_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK); |
119 | REG_WRITE(gpio->reg, reserved); | 121 | GMBUS_REG_WRITE(gpio->reg, reserved); |
120 | return (REG_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; | 122 | return (GMBUS_REG_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; |
121 | } | 123 | } |
122 | 124 | ||
123 | static int get_data(void *data) | 125 | static int get_data(void *data) |
124 | { | 126 | { |
125 | struct intel_gpio *gpio = data; | 127 | struct intel_gpio *gpio = data; |
126 | struct drm_psb_private *dev_priv = gpio->dev_priv; | 128 | struct drm_psb_private *dev_priv = gpio->dev_priv; |
127 | struct drm_device *dev = dev_priv->dev; | ||
128 | u32 reserved = get_reserved(gpio); | 129 | u32 reserved = get_reserved(gpio); |
129 | REG_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK); | 130 | GMBUS_REG_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK); |
130 | REG_WRITE(gpio->reg, reserved); | 131 | GMBUS_REG_WRITE(gpio->reg, reserved); |
131 | return (REG_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0; | 132 | return (GMBUS_REG_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0; |
132 | } | 133 | } |
133 | 134 | ||
134 | static void set_clock(void *data, int state_high) | 135 | static void set_clock(void *data, int state_high) |
135 | { | 136 | { |
136 | struct intel_gpio *gpio = data; | 137 | struct intel_gpio *gpio = data; |
137 | struct drm_psb_private *dev_priv = gpio->dev_priv; | 138 | struct drm_psb_private *dev_priv = gpio->dev_priv; |
138 | struct drm_device *dev = dev_priv->dev; | ||
139 | u32 reserved = get_reserved(gpio); | 139 | u32 reserved = get_reserved(gpio); |
140 | u32 clock_bits; | 140 | u32 clock_bits; |
141 | 141 | ||
@@ -145,15 +145,14 @@ static void set_clock(void *data, int state_high) | |||
145 | clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | | 145 | clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | |
146 | GPIO_CLOCK_VAL_MASK; | 146 | GPIO_CLOCK_VAL_MASK; |
147 | 147 | ||
148 | REG_WRITE(gpio->reg, reserved | clock_bits); | 148 | GMBUS_REG_WRITE(gpio->reg, reserved | clock_bits); |
149 | REG_READ(gpio->reg); /* Posting */ | 149 | GMBUS_REG_READ(gpio->reg); /* Posting */ |
150 | } | 150 | } |
151 | 151 | ||
152 | static void set_data(void *data, int state_high) | 152 | static void set_data(void *data, int state_high) |
153 | { | 153 | { |
154 | struct intel_gpio *gpio = data; | 154 | struct intel_gpio *gpio = data; |
155 | struct drm_psb_private *dev_priv = gpio->dev_priv; | 155 | struct drm_psb_private *dev_priv = gpio->dev_priv; |
156 | struct drm_device *dev = dev_priv->dev; | ||
157 | u32 reserved = get_reserved(gpio); | 156 | u32 reserved = get_reserved(gpio); |
158 | u32 data_bits; | 157 | u32 data_bits; |
159 | 158 | ||
@@ -163,8 +162,8 @@ static void set_data(void *data, int state_high) | |||
163 | data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | | 162 | data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | |
164 | GPIO_DATA_VAL_MASK; | 163 | GPIO_DATA_VAL_MASK; |
165 | 164 | ||
166 | REG_WRITE(gpio->reg, reserved | data_bits); | 165 | GMBUS_REG_WRITE(gpio->reg, reserved | data_bits); |
167 | REG_READ(gpio->reg); | 166 | GMBUS_REG_READ(gpio->reg); |
168 | } | 167 | } |
169 | 168 | ||
170 | static struct i2c_adapter * | 169 | static struct i2c_adapter * |
@@ -251,7 +250,6 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
251 | struct intel_gmbus, | 250 | struct intel_gmbus, |
252 | adapter); | 251 | adapter); |
253 | struct drm_psb_private *dev_priv = adapter->algo_data; | 252 | struct drm_psb_private *dev_priv = adapter->algo_data; |
254 | struct drm_device *dev = dev_priv->dev; | ||
255 | int i, reg_offset; | 253 | int i, reg_offset; |
256 | 254 | ||
257 | if (bus->force_bit) | 255 | if (bus->force_bit) |
@@ -260,28 +258,30 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
260 | 258 | ||
261 | reg_offset = 0; | 259 | reg_offset = 0; |
262 | 260 | ||
263 | REG_WRITE(GMBUS0 + reg_offset, bus->reg0); | 261 | GMBUS_REG_WRITE(GMBUS0 + reg_offset, bus->reg0); |
264 | 262 | ||
265 | for (i = 0; i < num; i++) { | 263 | for (i = 0; i < num; i++) { |
266 | u16 len = msgs[i].len; | 264 | u16 len = msgs[i].len; |
267 | u8 *buf = msgs[i].buf; | 265 | u8 *buf = msgs[i].buf; |
268 | 266 | ||
269 | if (msgs[i].flags & I2C_M_RD) { | 267 | if (msgs[i].flags & I2C_M_RD) { |
270 | REG_WRITE(GMBUS1 + reg_offset, | 268 | GMBUS_REG_WRITE(GMBUS1 + reg_offset, |
271 | GMBUS_CYCLE_WAIT | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | | 269 | GMBUS_CYCLE_WAIT | |
272 | (len << GMBUS_BYTE_COUNT_SHIFT) | | 270 | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | |
273 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | | 271 | (len << GMBUS_BYTE_COUNT_SHIFT) | |
274 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); | 272 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | |
275 | REG_READ(GMBUS2+reg_offset); | 273 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); |
274 | GMBUS_REG_READ(GMBUS2+reg_offset); | ||
276 | do { | 275 | do { |
277 | u32 val, loop = 0; | 276 | u32 val, loop = 0; |
278 | 277 | ||
279 | if (wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) | 278 | if (wait_for(GMBUS_REG_READ(GMBUS2 + reg_offset) & |
279 | (GMBUS_SATOER | GMBUS_HW_RDY), 50)) | ||
280 | goto timeout; | 280 | goto timeout; |
281 | if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | 281 | if (GMBUS_REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) |
282 | goto clear_err; | 282 | goto clear_err; |
283 | 283 | ||
284 | val = REG_READ(GMBUS3 + reg_offset); | 284 | val = GMBUS_REG_READ(GMBUS3 + reg_offset); |
285 | do { | 285 | do { |
286 | *buf++ = val & 0xff; | 286 | *buf++ = val & 0xff; |
287 | val >>= 8; | 287 | val >>= 8; |
@@ -295,18 +295,20 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
295 | val |= *buf++ << (8 * loop); | 295 | val |= *buf++ << (8 * loop); |
296 | } while (--len && ++loop < 4); | 296 | } while (--len && ++loop < 4); |
297 | 297 | ||
298 | REG_WRITE(GMBUS3 + reg_offset, val); | 298 | GMBUS_REG_WRITE(GMBUS3 + reg_offset, val); |
299 | REG_WRITE(GMBUS1 + reg_offset, | 299 | GMBUS_REG_WRITE(GMBUS1 + reg_offset, |
300 | (i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT) | | 300 | (i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT) | |
301 | (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | | 301 | (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | |
302 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | | 302 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | |
303 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); | 303 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); |
304 | REG_READ(GMBUS2+reg_offset); | 304 | GMBUS_REG_READ(GMBUS2+reg_offset); |
305 | 305 | ||
306 | while (len) { | 306 | while (len) { |
307 | if (wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) | 307 | if (wait_for(GMBUS_REG_READ(GMBUS2 + reg_offset) & |
308 | (GMBUS_SATOER | GMBUS_HW_RDY), 50)) | ||
308 | goto timeout; | 309 | goto timeout; |
309 | if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | 310 | if (GMBUS_REG_READ(GMBUS2 + reg_offset) & |
311 | GMBUS_SATOER) | ||
310 | goto clear_err; | 312 | goto clear_err; |
311 | 313 | ||
312 | val = loop = 0; | 314 | val = loop = 0; |
@@ -314,14 +316,14 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
314 | val |= *buf++ << (8 * loop); | 316 | val |= *buf++ << (8 * loop); |
315 | } while (--len && ++loop < 4); | 317 | } while (--len && ++loop < 4); |
316 | 318 | ||
317 | REG_WRITE(GMBUS3 + reg_offset, val); | 319 | GMBUS_REG_WRITE(GMBUS3 + reg_offset, val); |
318 | REG_READ(GMBUS2+reg_offset); | 320 | GMBUS_REG_READ(GMBUS2+reg_offset); |
319 | } | 321 | } |
320 | } | 322 | } |
321 | 323 | ||
322 | if (i + 1 < num && wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50)) | 324 | if (i + 1 < num && wait_for(GMBUS_REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50)) |
323 | goto timeout; | 325 | goto timeout; |
324 | if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | 326 | if (GMBUS_REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) |
325 | goto clear_err; | 327 | goto clear_err; |
326 | } | 328 | } |
327 | 329 | ||
@@ -332,20 +334,20 @@ clear_err: | |||
332 | * of resetting the GMBUS controller and so clearing the | 334 | * of resetting the GMBUS controller and so clearing the |
333 | * BUS_ERROR raised by the slave's NAK. | 335 | * BUS_ERROR raised by the slave's NAK. |
334 | */ | 336 | */ |
335 | REG_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); | 337 | GMBUS_REG_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); |
336 | REG_WRITE(GMBUS1 + reg_offset, 0); | 338 | GMBUS_REG_WRITE(GMBUS1 + reg_offset, 0); |
337 | 339 | ||
338 | done: | 340 | done: |
339 | /* Mark the GMBUS interface as disabled. We will re-enable it at the | 341 | /* Mark the GMBUS interface as disabled. We will re-enable it at the |
340 | * start of the next xfer, till then let it sleep. | 342 | * start of the next xfer, till then let it sleep. |
341 | */ | 343 | */ |
342 | REG_WRITE(GMBUS0 + reg_offset, 0); | 344 | GMBUS_REG_WRITE(GMBUS0 + reg_offset, 0); |
343 | return i; | 345 | return i; |
344 | 346 | ||
345 | timeout: | 347 | timeout: |
346 | DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d [%s]\n", | 348 | DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d [%s]\n", |
347 | bus->reg0 & 0xff, bus->adapter.name); | 349 | bus->reg0 & 0xff, bus->adapter.name); |
348 | REG_WRITE(GMBUS0 + reg_offset, 0); | 350 | GMBUS_REG_WRITE(GMBUS0 + reg_offset, 0); |
349 | 351 | ||
350 | /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ | 352 | /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ |
351 | bus->force_bit = intel_gpio_create(dev_priv, bus->reg0 & 0xff); | 353 | bus->force_bit = intel_gpio_create(dev_priv, bus->reg0 & 0xff); |
@@ -399,6 +401,11 @@ int gma_intel_setup_gmbus(struct drm_device *dev) | |||
399 | if (dev_priv->gmbus == NULL) | 401 | if (dev_priv->gmbus == NULL) |
400 | return -ENOMEM; | 402 | return -ENOMEM; |
401 | 403 | ||
404 | if (IS_MRST(dev)) | ||
405 | dev_priv->gmbus_reg = dev_priv->aux_reg; | ||
406 | else | ||
407 | dev_priv->gmbus_reg = dev_priv->vdc_reg; | ||
408 | |||
402 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { | 409 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { |
403 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; | 410 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; |
404 | 411 | ||
@@ -487,6 +494,7 @@ void gma_intel_teardown_gmbus(struct drm_device *dev) | |||
487 | i2c_del_adapter(&bus->adapter); | 494 | i2c_del_adapter(&bus->adapter); |
488 | } | 495 | } |
489 | 496 | ||
497 | dev_priv->gmbus_reg = NULL; /* iounmap is done in driver_unload */ | ||
490 | kfree(dev_priv->gmbus); | 498 | kfree(dev_priv->gmbus); |
491 | dev_priv->gmbus = NULL; | 499 | dev_priv->gmbus = NULL; |
492 | } | 500 | } |