1 /* $NetBSD: amdgpu_i2c.c,v 1.3 2018/08/27 14:04:50 riastradh Exp $ */ 2 3 /* 4 * Copyright 2007-8 Advanced Micro Devices, Inc. 5 * Copyright 2008 Red Hat Inc. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: Dave Airlie 26 * Alex Deucher 27 */ 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: amdgpu_i2c.c,v 1.3 2018/08/27 14:04:50 riastradh Exp $"); 30 31 #include <linux/export.h> 32 #include <linux/module.h> 33 34 #include <drm/drmP.h> 35 #include <drm/drm_edid.h> 36 #include <drm/amdgpu_drm.h> 37 #include "amdgpu.h" 38 #include "amdgpu_i2c.h" 39 #include "amdgpu_atombios.h" 40 #include "atom.h" 41 #include "atombios_dp.h" 42 #include "atombios_i2c.h" 43 44 /* bit banging i2c */ 45 static int amdgpu_i2c_pre_xfer(struct i2c_adapter *i2c_adap) 46 { 47 struct amdgpu_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); 48 struct amdgpu_device *adev = i2c->dev->dev_private; 49 struct amdgpu_i2c_bus_rec *rec = &i2c->rec; 50 uint32_t temp; 51 52 mutex_lock(&i2c->mutex); 53 54 /* switch the pads to ddc mode */ 55 if (rec->hw_capable) { 56 temp = RREG32(rec->mask_clk_reg); 57 temp &= ~(1 << 16); 58 WREG32(rec->mask_clk_reg, temp); 59 } 60 61 /* clear the output pin values */ 62 temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; 63 WREG32(rec->a_clk_reg, temp); 64 65 temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask; 66 WREG32(rec->a_data_reg, temp); 67 68 /* set the pins to input */ 69 temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; 70 WREG32(rec->en_clk_reg, temp); 71 72 temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask; 73 WREG32(rec->en_data_reg, temp); 74 75 /* mask the gpio pins for software use */ 76 temp = RREG32(rec->mask_clk_reg) | rec->mask_clk_mask; 77 WREG32(rec->mask_clk_reg, temp); 78 temp = RREG32(rec->mask_clk_reg); 79 80 temp = RREG32(rec->mask_data_reg) | rec->mask_data_mask; 81 WREG32(rec->mask_data_reg, temp); 82 temp = RREG32(rec->mask_data_reg); 83 84 return 0; 85 } 86 87 static void amdgpu_i2c_post_xfer(struct i2c_adapter *i2c_adap) 88 { 89 struct amdgpu_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); 90 struct amdgpu_device *adev = i2c->dev->dev_private; 91 struct amdgpu_i2c_bus_rec *rec = &i2c->rec; 92 uint32_t temp; 93 94 /* unmask the gpio pins for software use */ 95 temp = RREG32(rec->mask_clk_reg) & ~rec->mask_clk_mask; 96 WREG32(rec->mask_clk_reg, temp); 97 temp = RREG32(rec->mask_clk_reg); 98 99 temp = RREG32(rec->mask_data_reg) & ~rec->mask_data_mask; 100 WREG32(rec->mask_data_reg, temp); 101 temp = RREG32(rec->mask_data_reg); 102 103 mutex_unlock(&i2c->mutex); 104 } 105 106 static int amdgpu_i2c_get_clock(void *i2c_priv) 107 { 108 struct amdgpu_i2c_chan *i2c = i2c_priv; 109 struct amdgpu_device *adev = i2c->dev->dev_private; 110 struct amdgpu_i2c_bus_rec *rec = &i2c->rec; 111 uint32_t val; 112 113 /* read the value off the pin */ 114 val = RREG32(rec->y_clk_reg); 115 val &= rec->y_clk_mask; 116 117 return (val != 0); 118 } 119 120 121 static int amdgpu_i2c_get_data(void *i2c_priv) 122 { 123 struct amdgpu_i2c_chan *i2c = i2c_priv; 124 struct amdgpu_device *adev = i2c->dev->dev_private; 125 struct amdgpu_i2c_bus_rec *rec = &i2c->rec; 126 uint32_t val; 127 128 /* read the value off the pin */ 129 val = RREG32(rec->y_data_reg); 130 val &= rec->y_data_mask; 131 132 return (val != 0); 133 } 134 135 static void amdgpu_i2c_set_clock(void *i2c_priv, int clock) 136 { 137 struct amdgpu_i2c_chan *i2c = i2c_priv; 138 struct amdgpu_device *adev = i2c->dev->dev_private; 139 struct amdgpu_i2c_bus_rec *rec = &i2c->rec; 140 uint32_t val; 141 142 /* set pin direction */ 143 val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; 144 val |= clock ? 0 : rec->en_clk_mask; 145 WREG32(rec->en_clk_reg, val); 146 } 147 148 static void amdgpu_i2c_set_data(void *i2c_priv, int data) 149 { 150 struct amdgpu_i2c_chan *i2c = i2c_priv; 151 struct amdgpu_device *adev = i2c->dev->dev_private; 152 struct amdgpu_i2c_bus_rec *rec = &i2c->rec; 153 uint32_t val; 154 155 /* set pin direction */ 156 val = RREG32(rec->en_data_reg) & ~rec->en_data_mask; 157 val |= data ? 0 : rec->en_data_mask; 158 WREG32(rec->en_data_reg, val); 159 } 160 161 static const struct i2c_algorithm amdgpu_atombios_i2c_algo = { 162 .master_xfer = amdgpu_atombios_i2c_xfer, 163 .functionality = amdgpu_atombios_i2c_func, 164 }; 165 166 struct amdgpu_i2c_chan *amdgpu_i2c_create(struct drm_device *dev, 167 struct amdgpu_i2c_bus_rec *rec, 168 const char *name) 169 { 170 struct amdgpu_i2c_chan *i2c; 171 int ret; 172 173 /* don't add the mm_i2c bus unless hw_i2c is enabled */ 174 if (rec->mm_i2c && (amdgpu_hw_i2c == 0)) 175 return NULL; 176 177 i2c = kzalloc(sizeof(struct amdgpu_i2c_chan), GFP_KERNEL); 178 if (i2c == NULL) 179 return NULL; 180 181 i2c->rec = *rec; 182 i2c->adapter.owner = THIS_MODULE; 183 i2c->adapter.class = I2C_CLASS_DDC; 184 i2c->adapter.dev.parent = dev->dev; 185 i2c->dev = dev; 186 i2c_set_adapdata(&i2c->adapter, i2c); 187 #ifdef __NetBSD__ 188 linux_mutex_init(&i2c->mutex); 189 #else 190 mutex_init(&i2c->mutex); 191 #endif 192 if (rec->hw_capable && 193 amdgpu_hw_i2c) { 194 /* hw i2c using atom */ 195 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), 196 "AMDGPU i2c hw bus %s", name); 197 i2c->adapter.algo = &amdgpu_atombios_i2c_algo; 198 ret = i2c_add_adapter(&i2c->adapter); 199 if (ret) { 200 DRM_ERROR("Failed to register hw i2c %s\n", name); 201 goto out_free; 202 } 203 } else { 204 /* set the amdgpu bit adapter */ 205 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), 206 "AMDGPU i2c bit bus %s", name); 207 i2c->adapter.algo_data = &i2c->bit; 208 i2c->bit.pre_xfer = amdgpu_i2c_pre_xfer; 209 i2c->bit.post_xfer = amdgpu_i2c_post_xfer; 210 i2c->bit.setsda = amdgpu_i2c_set_data; 211 i2c->bit.setscl = amdgpu_i2c_set_clock; 212 i2c->bit.getsda = amdgpu_i2c_get_data; 213 i2c->bit.getscl = amdgpu_i2c_get_clock; 214 i2c->bit.udelay = 10; 215 i2c->bit.timeout = usecs_to_jiffies(2200); /* from VESA */ 216 i2c->bit.data = i2c; 217 ret = i2c_bit_add_bus(&i2c->adapter); 218 if (ret) { 219 DRM_ERROR("Failed to register bit i2c %s\n", name); 220 goto out_free; 221 } 222 } 223 224 return i2c; 225 out_free: 226 #ifdef __NetBSD__ 227 linux_mutex_destroy(&i2c->mutex); 228 #else 229 mutex_destroy(&i2c->mutex); 230 #endif 231 kfree(i2c); 232 return NULL; 233 234 } 235 236 void amdgpu_i2c_destroy(struct amdgpu_i2c_chan *i2c) 237 { 238 if (!i2c) 239 return; 240 i2c_del_adapter(&i2c->adapter); 241 #ifdef __NetBSD__ 242 linux_mutex_destroy(&i2c->mutex); 243 #else 244 mutex_destroy(&i2c->mutex); 245 #endif 246 kfree(i2c); 247 } 248 249 /* Add the default buses */ 250 void amdgpu_i2c_init(struct amdgpu_device *adev) 251 { 252 if (amdgpu_hw_i2c) 253 DRM_INFO("hw_i2c forced on, you may experience display detection problems!\n"); 254 255 if (adev->is_atom_bios) 256 amdgpu_atombios_i2c_init(adev); 257 } 258 259 /* remove all the buses */ 260 void amdgpu_i2c_fini(struct amdgpu_device *adev) 261 { 262 int i; 263 264 for (i = 0; i < AMDGPU_MAX_I2C_BUS; i++) { 265 if (adev->i2c_bus[i]) { 266 amdgpu_i2c_destroy(adev->i2c_bus[i]); 267 adev->i2c_bus[i] = NULL; 268 } 269 } 270 } 271 272 /* Add additional buses */ 273 void amdgpu_i2c_add(struct amdgpu_device *adev, 274 struct amdgpu_i2c_bus_rec *rec, 275 const char *name) 276 { 277 struct drm_device *dev = adev->ddev; 278 int i; 279 280 for (i = 0; i < AMDGPU_MAX_I2C_BUS; i++) { 281 if (!adev->i2c_bus[i]) { 282 adev->i2c_bus[i] = amdgpu_i2c_create(dev, rec, name); 283 return; 284 } 285 } 286 } 287 288 /* looks up bus based on id */ 289 struct amdgpu_i2c_chan * 290 amdgpu_i2c_lookup(struct amdgpu_device *adev, 291 struct amdgpu_i2c_bus_rec *i2c_bus) 292 { 293 int i; 294 295 for (i = 0; i < AMDGPU_MAX_I2C_BUS; i++) { 296 if (adev->i2c_bus[i] && 297 (adev->i2c_bus[i]->rec.i2c_id == i2c_bus->i2c_id)) { 298 return adev->i2c_bus[i]; 299 } 300 } 301 return NULL; 302 } 303 304 static void amdgpu_i2c_get_byte(struct amdgpu_i2c_chan *i2c_bus, 305 u8 slave_addr, 306 u8 addr, 307 u8 *val) 308 { 309 u8 out_buf[2]; 310 u8 in_buf[2]; 311 struct i2c_msg msgs[] = { 312 { 313 .addr = slave_addr, 314 .flags = 0, 315 .len = 1, 316 .buf = out_buf, 317 }, 318 { 319 .addr = slave_addr, 320 .flags = I2C_M_RD, 321 .len = 1, 322 .buf = in_buf, 323 } 324 }; 325 326 out_buf[0] = addr; 327 out_buf[1] = 0; 328 329 if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) { 330 *val = in_buf[0]; 331 DRM_DEBUG("val = 0x%02x\n", *val); 332 } else { 333 DRM_DEBUG("i2c 0x%02x 0x%02x read failed\n", 334 addr, *val); 335 } 336 } 337 338 static void amdgpu_i2c_put_byte(struct amdgpu_i2c_chan *i2c_bus, 339 u8 slave_addr, 340 u8 addr, 341 u8 val) 342 { 343 uint8_t out_buf[2]; 344 struct i2c_msg msg = { 345 .addr = slave_addr, 346 .flags = 0, 347 .len = 2, 348 .buf = out_buf, 349 }; 350 351 out_buf[0] = addr; 352 out_buf[1] = val; 353 354 if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1) 355 DRM_DEBUG("i2c 0x%02x 0x%02x write failed\n", 356 addr, val); 357 } 358 359 /* ddc router switching */ 360 void 361 amdgpu_i2c_router_select_ddc_port(struct amdgpu_connector *amdgpu_connector) 362 { 363 u8 val; 364 365 if (!amdgpu_connector->router.ddc_valid) 366 return; 367 368 if (!amdgpu_connector->router_bus) 369 return; 370 371 amdgpu_i2c_get_byte(amdgpu_connector->router_bus, 372 amdgpu_connector->router.i2c_addr, 373 0x3, &val); 374 val &= ~amdgpu_connector->router.ddc_mux_control_pin; 375 amdgpu_i2c_put_byte(amdgpu_connector->router_bus, 376 amdgpu_connector->router.i2c_addr, 377 0x3, val); 378 amdgpu_i2c_get_byte(amdgpu_connector->router_bus, 379 amdgpu_connector->router.i2c_addr, 380 0x1, &val); 381 val &= ~amdgpu_connector->router.ddc_mux_control_pin; 382 val |= amdgpu_connector->router.ddc_mux_state; 383 amdgpu_i2c_put_byte(amdgpu_connector->router_bus, 384 amdgpu_connector->router.i2c_addr, 385 0x1, val); 386 } 387 388 /* clock/data router switching */ 389 void 390 amdgpu_i2c_router_select_cd_port(struct amdgpu_connector *amdgpu_connector) 391 { 392 u8 val; 393 394 if (!amdgpu_connector->router.cd_valid) 395 return; 396 397 if (!amdgpu_connector->router_bus) 398 return; 399 400 amdgpu_i2c_get_byte(amdgpu_connector->router_bus, 401 amdgpu_connector->router.i2c_addr, 402 0x3, &val); 403 val &= ~amdgpu_connector->router.cd_mux_control_pin; 404 amdgpu_i2c_put_byte(amdgpu_connector->router_bus, 405 amdgpu_connector->router.i2c_addr, 406 0x3, val); 407 amdgpu_i2c_get_byte(amdgpu_connector->router_bus, 408 amdgpu_connector->router.i2c_addr, 409 0x1, &val); 410 val &= ~amdgpu_connector->router.cd_mux_control_pin; 411 val |= amdgpu_connector->router.cd_mux_state; 412 amdgpu_i2c_put_byte(amdgpu_connector->router_bus, 413 amdgpu_connector->router.i2c_addr, 414 0x1, val); 415 } 416