1254885Sdumbbell/* 2254885Sdumbbell * Copyright 2007-8 Advanced Micro Devices, Inc. 3254885Sdumbbell * Copyright 2008 Red Hat Inc. 4254885Sdumbbell * 5254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a 6254885Sdumbbell * copy of this software and associated documentation files (the "Software"), 7254885Sdumbbell * to deal in the Software without restriction, including without limitation 8254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the 10254885Sdumbbell * Software is furnished to do so, subject to the following conditions: 11254885Sdumbbell * 12254885Sdumbbell * The above copyright notice and this permission notice shall be included in 13254885Sdumbbell * all copies or substantial portions of the Software. 14254885Sdumbbell * 15254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18254885Sdumbbell * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19254885Sdumbbell * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20254885Sdumbbell * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21254885Sdumbbell * OTHER DEALINGS IN THE SOFTWARE. 22254885Sdumbbell * 23254885Sdumbbell * Authors: Dave Airlie 24254885Sdumbbell * Alex Deucher 25254885Sdumbbell */ 26254885Sdumbbell 27254885Sdumbbell#include <sys/cdefs.h> 28254885Sdumbbell__FBSDID("$FreeBSD$"); 29254885Sdumbbell 30254885Sdumbbell#include <dev/drm2/drmP.h> 31254885Sdumbbell#include <dev/drm2/drm_edid.h> 32254885Sdumbbell#include <dev/drm2/radeon/radeon_drm.h> 33254885Sdumbbell#include <dev/iicbus/iic.h> 34254885Sdumbbell#include <dev/iicbus/iiconf.h> 35254885Sdumbbell#include <dev/iicbus/iicbus.h> 36254885Sdumbbell#include "radeon.h" 37254885Sdumbbell#include "atom.h" 38254885Sdumbbell#include "iicbus_if.h" 39254885Sdumbbell#include "iicbb_if.h" 40254885Sdumbbell 41254885Sdumbbell/** 42254885Sdumbbell * radeon_ddc_probe 43254885Sdumbbell * 44254885Sdumbbell */ 45254885Sdumbbellbool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux) 46254885Sdumbbell{ 47254885Sdumbbell u8 out = 0x0; 48254885Sdumbbell u8 buf[8]; 49254885Sdumbbell int ret; 50254885Sdumbbell struct iic_msg msgs[] = { 51254885Sdumbbell { 52254885Sdumbbell .slave = DDC_ADDR << 1, 53254885Sdumbbell .flags = 0, 54254885Sdumbbell .len = 1, 55254885Sdumbbell .buf = &out, 56254885Sdumbbell }, 57254885Sdumbbell { 58254885Sdumbbell .slave = DDC_ADDR << 1, 59254885Sdumbbell .flags = IIC_M_RD, 60254885Sdumbbell .len = 8, 61254885Sdumbbell .buf = buf, 62254885Sdumbbell } 63254885Sdumbbell }; 64254885Sdumbbell 65254885Sdumbbell /* on hw with routers, select right port */ 66254885Sdumbbell if (radeon_connector->router.ddc_valid) 67254885Sdumbbell radeon_router_select_ddc_port(radeon_connector); 68254885Sdumbbell 69254885Sdumbbell if (use_aux) { 70254885Sdumbbell struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; 71254885Sdumbbell ret = iicbus_transfer(dig->dp_i2c_bus->adapter, msgs, 2); 72254885Sdumbbell } else { 73254885Sdumbbell ret = iicbus_transfer(radeon_connector->ddc_bus->adapter, msgs, 2); 74254885Sdumbbell } 75254885Sdumbbell 76254885Sdumbbell if (ret != 0) 77254885Sdumbbell /* Couldn't find an accessible DDC on this connector */ 78254885Sdumbbell return false; 79254885Sdumbbell /* Probe also for valid EDID header 80254885Sdumbbell * EDID header starts with: 81254885Sdumbbell * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. 82254885Sdumbbell * Only the first 6 bytes must be valid as 83254885Sdumbbell * drm_edid_block_valid() can fix the last 2 bytes */ 84254885Sdumbbell if (drm_edid_header_is_valid(buf) < 6) { 85254885Sdumbbell /* Couldn't find an accessible EDID on this 86254885Sdumbbell * connector */ 87254885Sdumbbell return false; 88254885Sdumbbell } 89254885Sdumbbell return true; 90254885Sdumbbell} 91254885Sdumbbell 92254885Sdumbbell/* bit banging i2c */ 93254885Sdumbbell 94254885Sdumbbellstatic int radeon_iicbb_pre_xfer(device_t dev) 95254885Sdumbbell{ 96254885Sdumbbell struct radeon_i2c_chan *i2c = device_get_softc(dev); 97254885Sdumbbell struct radeon_device *rdev = i2c->dev->dev_private; 98254885Sdumbbell struct radeon_i2c_bus_rec *rec = &i2c->rec; 99254885Sdumbbell uint32_t temp; 100254885Sdumbbell 101254885Sdumbbell /* RV410 appears to have a bug where the hw i2c in reset 102254885Sdumbbell * holds the i2c port in a bad state - switch hw i2c away before 103254885Sdumbbell * doing DDC - do this for all r200s/r300s/r400s for safety sake 104254885Sdumbbell */ 105254885Sdumbbell if (rec->hw_capable) { 106254885Sdumbbell if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { 107254885Sdumbbell u32 reg; 108254885Sdumbbell 109254885Sdumbbell if (rdev->family >= CHIP_RV350) 110254885Sdumbbell reg = RADEON_GPIO_MONID; 111254885Sdumbbell else if ((rdev->family == CHIP_R300) || 112254885Sdumbbell (rdev->family == CHIP_R350)) 113254885Sdumbbell reg = RADEON_GPIO_DVI_DDC; 114254885Sdumbbell else 115254885Sdumbbell reg = RADEON_GPIO_CRT2_DDC; 116254885Sdumbbell 117254885Sdumbbell sx_xlock(&rdev->dc_hw_i2c_mutex); 118254885Sdumbbell if (rec->a_clk_reg == reg) { 119254885Sdumbbell WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | 120254885Sdumbbell R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); 121254885Sdumbbell } else { 122254885Sdumbbell WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | 123254885Sdumbbell R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); 124254885Sdumbbell } 125254885Sdumbbell sx_xunlock(&rdev->dc_hw_i2c_mutex); 126254885Sdumbbell } 127254885Sdumbbell } 128254885Sdumbbell 129254885Sdumbbell /* switch the pads to ddc mode */ 130254885Sdumbbell if (ASIC_IS_DCE3(rdev) && rec->hw_capable) { 131254885Sdumbbell temp = RREG32(rec->mask_clk_reg); 132254885Sdumbbell temp &= ~(1 << 16); 133254885Sdumbbell WREG32(rec->mask_clk_reg, temp); 134254885Sdumbbell } 135254885Sdumbbell 136254885Sdumbbell /* clear the output pin values */ 137254885Sdumbbell temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; 138254885Sdumbbell WREG32(rec->a_clk_reg, temp); 139254885Sdumbbell 140254885Sdumbbell temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask; 141254885Sdumbbell WREG32(rec->a_data_reg, temp); 142254885Sdumbbell 143254885Sdumbbell /* set the pins to input */ 144254885Sdumbbell temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; 145254885Sdumbbell WREG32(rec->en_clk_reg, temp); 146254885Sdumbbell 147254885Sdumbbell temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask; 148254885Sdumbbell WREG32(rec->en_data_reg, temp); 149254885Sdumbbell 150254885Sdumbbell /* mask the gpio pins for software use */ 151254885Sdumbbell temp = RREG32(rec->mask_clk_reg) | rec->mask_clk_mask; 152254885Sdumbbell WREG32(rec->mask_clk_reg, temp); 153254885Sdumbbell temp = RREG32(rec->mask_clk_reg); 154254885Sdumbbell 155254885Sdumbbell temp = RREG32(rec->mask_data_reg) | rec->mask_data_mask; 156254885Sdumbbell WREG32(rec->mask_data_reg, temp); 157254885Sdumbbell temp = RREG32(rec->mask_data_reg); 158254885Sdumbbell 159254885Sdumbbell return 0; 160254885Sdumbbell} 161254885Sdumbbell 162254885Sdumbbellstatic void radeon_iicbb_post_xfer(device_t dev) 163254885Sdumbbell{ 164254885Sdumbbell struct radeon_i2c_chan *i2c = device_get_softc(dev); 165254885Sdumbbell struct radeon_device *rdev = i2c->dev->dev_private; 166254885Sdumbbell struct radeon_i2c_bus_rec *rec = &i2c->rec; 167254885Sdumbbell uint32_t temp; 168254885Sdumbbell 169254885Sdumbbell /* unmask the gpio pins for software use */ 170254885Sdumbbell temp = RREG32(rec->mask_clk_reg) & ~rec->mask_clk_mask; 171254885Sdumbbell WREG32(rec->mask_clk_reg, temp); 172254885Sdumbbell temp = RREG32(rec->mask_clk_reg); 173254885Sdumbbell 174254885Sdumbbell temp = RREG32(rec->mask_data_reg) & ~rec->mask_data_mask; 175254885Sdumbbell WREG32(rec->mask_data_reg, temp); 176254885Sdumbbell temp = RREG32(rec->mask_data_reg); 177254885Sdumbbell} 178254885Sdumbbell 179254885Sdumbbellstatic int radeon_iicbb_get_clock(device_t dev) 180254885Sdumbbell{ 181254885Sdumbbell struct radeon_i2c_chan *i2c = device_get_softc(dev); 182254885Sdumbbell struct radeon_device *rdev = i2c->dev->dev_private; 183254885Sdumbbell struct radeon_i2c_bus_rec *rec = &i2c->rec; 184254885Sdumbbell uint32_t val; 185254885Sdumbbell 186254885Sdumbbell /* read the value off the pin */ 187254885Sdumbbell val = RREG32(rec->y_clk_reg); 188254885Sdumbbell val &= rec->y_clk_mask; 189254885Sdumbbell 190254885Sdumbbell return (val != 0); 191254885Sdumbbell} 192254885Sdumbbell 193254885Sdumbbell 194254885Sdumbbellstatic int radeon_iicbb_get_data(device_t dev) 195254885Sdumbbell{ 196254885Sdumbbell struct radeon_i2c_chan *i2c = device_get_softc(dev); 197254885Sdumbbell struct radeon_device *rdev = i2c->dev->dev_private; 198254885Sdumbbell struct radeon_i2c_bus_rec *rec = &i2c->rec; 199254885Sdumbbell uint32_t val; 200254885Sdumbbell 201254885Sdumbbell /* read the value off the pin */ 202254885Sdumbbell val = RREG32(rec->y_data_reg); 203254885Sdumbbell val &= rec->y_data_mask; 204254885Sdumbbell 205254885Sdumbbell return (val != 0); 206254885Sdumbbell} 207254885Sdumbbell 208254885Sdumbbellstatic void radeon_iicbb_set_clock(device_t dev, int clock) 209254885Sdumbbell{ 210254885Sdumbbell struct radeon_i2c_chan *i2c = device_get_softc(dev); 211254885Sdumbbell struct radeon_device *rdev = i2c->dev->dev_private; 212254885Sdumbbell struct radeon_i2c_bus_rec *rec = &i2c->rec; 213254885Sdumbbell uint32_t val; 214254885Sdumbbell 215254885Sdumbbell /* set pin direction */ 216254885Sdumbbell val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; 217254885Sdumbbell val |= clock ? 0 : rec->en_clk_mask; 218254885Sdumbbell WREG32(rec->en_clk_reg, val); 219254885Sdumbbell} 220254885Sdumbbell 221254885Sdumbbellstatic void radeon_iicbb_set_data(device_t dev, int data) 222254885Sdumbbell{ 223254885Sdumbbell struct radeon_i2c_chan *i2c = device_get_softc(dev); 224254885Sdumbbell struct radeon_device *rdev = i2c->dev->dev_private; 225254885Sdumbbell struct radeon_i2c_bus_rec *rec = &i2c->rec; 226254885Sdumbbell uint32_t val; 227254885Sdumbbell 228254885Sdumbbell /* set pin direction */ 229254885Sdumbbell val = RREG32(rec->en_data_reg) & ~rec->en_data_mask; 230254885Sdumbbell val |= data ? 0 : rec->en_data_mask; 231254885Sdumbbell WREG32(rec->en_data_reg, val); 232254885Sdumbbell} 233254885Sdumbbell 234254885Sdumbbellstatic int 235254885Sdumbbellradeon_iicbb_probe(device_t dev) 236254885Sdumbbell{ 237254885Sdumbbell 238254885Sdumbbell return (BUS_PROBE_DEFAULT); 239254885Sdumbbell} 240254885Sdumbbell 241254885Sdumbbellstatic int 242254885Sdumbbellradeon_iicbb_attach(device_t dev) 243254885Sdumbbell{ 244254885Sdumbbell struct radeon_i2c_chan *i2c; 245254885Sdumbbell device_t iic_dev; 246254885Sdumbbell 247254885Sdumbbell i2c = device_get_softc(dev); 248254885Sdumbbell device_set_desc(dev, i2c->name); 249254885Sdumbbell 250254885Sdumbbell /* add generic bit-banging code */ 251254885Sdumbbell iic_dev = device_add_child(dev, "iicbb", -1); 252254885Sdumbbell if (iic_dev == NULL) 253254885Sdumbbell return (ENXIO); 254254885Sdumbbell device_quiet(iic_dev); 255254885Sdumbbell 256254885Sdumbbell /* attach and probe added child */ 257254885Sdumbbell bus_generic_attach(dev); 258254885Sdumbbell 259254885Sdumbbell return (0); 260254885Sdumbbell} 261254885Sdumbbell 262254885Sdumbbellstatic int 263254885Sdumbbellradeon_iicbb_detach(device_t dev) 264254885Sdumbbell{ 265254885Sdumbbell 266254885Sdumbbell /* detach bit-banding code. */ 267254885Sdumbbell bus_generic_detach(dev); 268254885Sdumbbell 269254885Sdumbbell /* delete bit-banding code. */ 270254885Sdumbbell device_delete_children(dev); 271254885Sdumbbell return (0); 272254885Sdumbbell} 273254885Sdumbbell 274254885Sdumbbellstatic int 275254885Sdumbbellradeon_iicbb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) 276254885Sdumbbell{ 277254885Sdumbbell 278254885Sdumbbell /* Not sure what to do here. */ 279254885Sdumbbell return 0; 280254885Sdumbbell} 281254885Sdumbbell 282254885Sdumbbellstatic device_method_t radeon_iicbb_methods[] = { 283254885Sdumbbell DEVMETHOD(device_probe, radeon_iicbb_probe), 284254885Sdumbbell DEVMETHOD(device_attach, radeon_iicbb_attach), 285254885Sdumbbell DEVMETHOD(device_detach, radeon_iicbb_detach), 286254885Sdumbbell 287254885Sdumbbell DEVMETHOD(bus_add_child, bus_generic_add_child), 288254885Sdumbbell DEVMETHOD(bus_print_child, bus_generic_print_child), 289254885Sdumbbell 290254885Sdumbbell DEVMETHOD(iicbb_reset, radeon_iicbb_reset), 291254885Sdumbbell DEVMETHOD(iicbb_pre_xfer, radeon_iicbb_pre_xfer), 292254885Sdumbbell DEVMETHOD(iicbb_post_xfer, radeon_iicbb_post_xfer), 293254885Sdumbbell DEVMETHOD(iicbb_setsda, radeon_iicbb_set_data), 294254885Sdumbbell DEVMETHOD(iicbb_setscl, radeon_iicbb_set_clock), 295254885Sdumbbell DEVMETHOD(iicbb_getsda, radeon_iicbb_get_data), 296254885Sdumbbell DEVMETHOD(iicbb_getscl, radeon_iicbb_get_clock), 297254885Sdumbbell DEVMETHOD_END 298254885Sdumbbell}; 299254885Sdumbbell 300254885Sdumbbellstatic driver_t radeon_iicbb_driver = { 301254885Sdumbbell "radeon_iicbb", 302254885Sdumbbell radeon_iicbb_methods, 303254885Sdumbbell 0 /* softc will be allocated by parent */ 304254885Sdumbbell}; 305254885Sdumbbellstatic devclass_t radeon_iicbb_devclass; 306254885SdumbbellDRIVER_MODULE_ORDERED(radeon_iicbb, drmn, radeon_iicbb_driver, 307254885Sdumbbell radeon_iicbb_devclass, 0, 0, SI_ORDER_FIRST); 308254885SdumbbellDRIVER_MODULE(iicbb, radeon_iicbb, iicbb_driver, iicbb_devclass, 0, 0); 309254885Sdumbbell 310254885Sdumbbell/* hw i2c */ 311254885Sdumbbell 312254885Sdumbbellstatic u32 radeon_get_i2c_prescale(struct radeon_device *rdev) 313254885Sdumbbell{ 314254885Sdumbbell u32 sclk = rdev->pm.current_sclk; 315254885Sdumbbell u32 prescale = 0; 316254885Sdumbbell u32 nm; 317254885Sdumbbell u8 n, m, loop; 318254885Sdumbbell int i2c_clock; 319254885Sdumbbell 320254885Sdumbbell switch (rdev->family) { 321254885Sdumbbell case CHIP_R100: 322254885Sdumbbell case CHIP_RV100: 323254885Sdumbbell case CHIP_RS100: 324254885Sdumbbell case CHIP_RV200: 325254885Sdumbbell case CHIP_RS200: 326254885Sdumbbell case CHIP_R200: 327254885Sdumbbell case CHIP_RV250: 328254885Sdumbbell case CHIP_RS300: 329254885Sdumbbell case CHIP_RV280: 330254885Sdumbbell case CHIP_R300: 331254885Sdumbbell case CHIP_R350: 332254885Sdumbbell case CHIP_RV350: 333254885Sdumbbell i2c_clock = 60; 334254885Sdumbbell nm = (sclk * 10) / (i2c_clock * 4); 335254885Sdumbbell for (loop = 1; loop < 255; loop++) { 336254885Sdumbbell if ((nm / loop) < loop) 337254885Sdumbbell break; 338254885Sdumbbell } 339254885Sdumbbell n = loop - 1; 340254885Sdumbbell m = loop - 2; 341254885Sdumbbell prescale = m | (n << 8); 342254885Sdumbbell break; 343254885Sdumbbell case CHIP_RV380: 344254885Sdumbbell case CHIP_RS400: 345254885Sdumbbell case CHIP_RS480: 346254885Sdumbbell case CHIP_R420: 347254885Sdumbbell case CHIP_R423: 348254885Sdumbbell case CHIP_RV410: 349254885Sdumbbell prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; 350254885Sdumbbell break; 351254885Sdumbbell case CHIP_RS600: 352254885Sdumbbell case CHIP_RS690: 353254885Sdumbbell case CHIP_RS740: 354254885Sdumbbell /* todo */ 355254885Sdumbbell break; 356254885Sdumbbell case CHIP_RV515: 357254885Sdumbbell case CHIP_R520: 358254885Sdumbbell case CHIP_RV530: 359254885Sdumbbell case CHIP_RV560: 360254885Sdumbbell case CHIP_RV570: 361254885Sdumbbell case CHIP_R580: 362254885Sdumbbell i2c_clock = 50; 363254885Sdumbbell if (rdev->family == CHIP_R520) 364254885Sdumbbell prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock)); 365254885Sdumbbell else 366254885Sdumbbell prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; 367254885Sdumbbell break; 368254885Sdumbbell case CHIP_R600: 369254885Sdumbbell case CHIP_RV610: 370254885Sdumbbell case CHIP_RV630: 371254885Sdumbbell case CHIP_RV670: 372254885Sdumbbell /* todo */ 373254885Sdumbbell break; 374254885Sdumbbell case CHIP_RV620: 375254885Sdumbbell case CHIP_RV635: 376254885Sdumbbell case CHIP_RS780: 377254885Sdumbbell case CHIP_RS880: 378254885Sdumbbell case CHIP_RV770: 379254885Sdumbbell case CHIP_RV730: 380254885Sdumbbell case CHIP_RV710: 381254885Sdumbbell case CHIP_RV740: 382254885Sdumbbell /* todo */ 383254885Sdumbbell break; 384254885Sdumbbell case CHIP_CEDAR: 385254885Sdumbbell case CHIP_REDWOOD: 386254885Sdumbbell case CHIP_JUNIPER: 387254885Sdumbbell case CHIP_CYPRESS: 388254885Sdumbbell case CHIP_HEMLOCK: 389254885Sdumbbell /* todo */ 390254885Sdumbbell break; 391254885Sdumbbell default: 392254885Sdumbbell DRM_ERROR("i2c: unhandled radeon chip\n"); 393254885Sdumbbell break; 394254885Sdumbbell } 395254885Sdumbbell return prescale; 396254885Sdumbbell} 397254885Sdumbbell 398254885Sdumbbell 399254885Sdumbbell/* hw i2c engine for r1xx-4xx hardware 400254885Sdumbbell * hw can buffer up to 15 bytes 401254885Sdumbbell */ 402254885Sdumbbellstatic int r100_hw_i2c_xfer(struct radeon_i2c_chan *i2c, 403254885Sdumbbell struct iic_msg *msgs, int num) 404254885Sdumbbell{ 405254885Sdumbbell struct radeon_device *rdev = i2c->dev->dev_private; 406254885Sdumbbell struct radeon_i2c_bus_rec *rec = &i2c->rec; 407254885Sdumbbell struct iic_msg *p; 408254885Sdumbbell int i, j, k, ret = 0; 409254885Sdumbbell u32 prescale; 410254885Sdumbbell u32 i2c_cntl_0, i2c_cntl_1, i2c_data; 411254885Sdumbbell u32 tmp, reg; 412254885Sdumbbell 413254885Sdumbbell sx_xlock(&rdev->dc_hw_i2c_mutex); 414254885Sdumbbell /* take the pm lock since we need a constant sclk */ 415254885Sdumbbell sx_xlock(&rdev->pm.mutex); 416254885Sdumbbell 417254885Sdumbbell prescale = radeon_get_i2c_prescale(rdev); 418254885Sdumbbell 419254885Sdumbbell reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) | 420254885Sdumbbell RADEON_I2C_DRIVE_EN | 421254885Sdumbbell RADEON_I2C_START | 422254885Sdumbbell RADEON_I2C_STOP | 423254885Sdumbbell RADEON_I2C_GO); 424254885Sdumbbell 425254885Sdumbbell if (rdev->is_atom_bios) { 426254885Sdumbbell tmp = RREG32(RADEON_BIOS_6_SCRATCH); 427254885Sdumbbell WREG32(RADEON_BIOS_6_SCRATCH, tmp | ATOM_S6_HW_I2C_BUSY_STATE); 428254885Sdumbbell } 429254885Sdumbbell 430254885Sdumbbell if (rec->mm_i2c) { 431254885Sdumbbell i2c_cntl_0 = RADEON_I2C_CNTL_0; 432254885Sdumbbell i2c_cntl_1 = RADEON_I2C_CNTL_1; 433254885Sdumbbell i2c_data = RADEON_I2C_DATA; 434254885Sdumbbell } else { 435254885Sdumbbell i2c_cntl_0 = RADEON_DVI_I2C_CNTL_0; 436254885Sdumbbell i2c_cntl_1 = RADEON_DVI_I2C_CNTL_1; 437254885Sdumbbell i2c_data = RADEON_DVI_I2C_DATA; 438254885Sdumbbell 439254885Sdumbbell switch (rdev->family) { 440254885Sdumbbell case CHIP_R100: 441254885Sdumbbell case CHIP_RV100: 442254885Sdumbbell case CHIP_RS100: 443254885Sdumbbell case CHIP_RV200: 444254885Sdumbbell case CHIP_RS200: 445254885Sdumbbell case CHIP_RS300: 446254885Sdumbbell switch (rec->mask_clk_reg) { 447254885Sdumbbell case RADEON_GPIO_DVI_DDC: 448254885Sdumbbell /* no gpio select bit */ 449254885Sdumbbell break; 450254885Sdumbbell default: 451254885Sdumbbell DRM_ERROR("gpio not supported with hw i2c\n"); 452282199Sdumbbell ret = -EINVAL; 453254885Sdumbbell goto done; 454254885Sdumbbell } 455254885Sdumbbell break; 456254885Sdumbbell case CHIP_R200: 457254885Sdumbbell /* only bit 4 on r200 */ 458254885Sdumbbell switch (rec->mask_clk_reg) { 459254885Sdumbbell case RADEON_GPIO_DVI_DDC: 460254885Sdumbbell reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); 461254885Sdumbbell break; 462254885Sdumbbell case RADEON_GPIO_MONID: 463254885Sdumbbell reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); 464254885Sdumbbell break; 465254885Sdumbbell default: 466254885Sdumbbell DRM_ERROR("gpio not supported with hw i2c\n"); 467282199Sdumbbell ret = -EINVAL; 468254885Sdumbbell goto done; 469254885Sdumbbell } 470254885Sdumbbell break; 471254885Sdumbbell case CHIP_RV250: 472254885Sdumbbell case CHIP_RV280: 473254885Sdumbbell /* bits 3 and 4 */ 474254885Sdumbbell switch (rec->mask_clk_reg) { 475254885Sdumbbell case RADEON_GPIO_DVI_DDC: 476254885Sdumbbell reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); 477254885Sdumbbell break; 478254885Sdumbbell case RADEON_GPIO_VGA_DDC: 479254885Sdumbbell reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC2); 480254885Sdumbbell break; 481254885Sdumbbell case RADEON_GPIO_CRT2_DDC: 482254885Sdumbbell reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); 483254885Sdumbbell break; 484254885Sdumbbell default: 485254885Sdumbbell DRM_ERROR("gpio not supported with hw i2c\n"); 486282199Sdumbbell ret = -EINVAL; 487254885Sdumbbell goto done; 488254885Sdumbbell } 489254885Sdumbbell break; 490254885Sdumbbell case CHIP_R300: 491254885Sdumbbell case CHIP_R350: 492254885Sdumbbell /* only bit 4 on r300/r350 */ 493254885Sdumbbell switch (rec->mask_clk_reg) { 494254885Sdumbbell case RADEON_GPIO_VGA_DDC: 495254885Sdumbbell reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); 496254885Sdumbbell break; 497254885Sdumbbell case RADEON_GPIO_DVI_DDC: 498254885Sdumbbell reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); 499254885Sdumbbell break; 500254885Sdumbbell default: 501254885Sdumbbell DRM_ERROR("gpio not supported with hw i2c\n"); 502282199Sdumbbell ret = -EINVAL; 503254885Sdumbbell goto done; 504254885Sdumbbell } 505254885Sdumbbell break; 506254885Sdumbbell case CHIP_RV350: 507254885Sdumbbell case CHIP_RV380: 508254885Sdumbbell case CHIP_R420: 509254885Sdumbbell case CHIP_R423: 510254885Sdumbbell case CHIP_RV410: 511254885Sdumbbell case CHIP_RS400: 512254885Sdumbbell case CHIP_RS480: 513254885Sdumbbell /* bits 3 and 4 */ 514254885Sdumbbell switch (rec->mask_clk_reg) { 515254885Sdumbbell case RADEON_GPIO_VGA_DDC: 516254885Sdumbbell reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); 517254885Sdumbbell break; 518254885Sdumbbell case RADEON_GPIO_DVI_DDC: 519254885Sdumbbell reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC2); 520254885Sdumbbell break; 521254885Sdumbbell case RADEON_GPIO_MONID: 522254885Sdumbbell reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); 523254885Sdumbbell break; 524254885Sdumbbell default: 525254885Sdumbbell DRM_ERROR("gpio not supported with hw i2c\n"); 526282199Sdumbbell ret = -EINVAL; 527254885Sdumbbell goto done; 528254885Sdumbbell } 529254885Sdumbbell break; 530254885Sdumbbell default: 531254885Sdumbbell DRM_ERROR("unsupported asic\n"); 532282199Sdumbbell ret = -EINVAL; 533254885Sdumbbell goto done; 534254885Sdumbbell break; 535254885Sdumbbell } 536254885Sdumbbell } 537254885Sdumbbell 538254885Sdumbbell /* check for bus probe */ 539254885Sdumbbell p = &msgs[0]; 540254885Sdumbbell if ((num == 1) && (p->len == 0)) { 541254885Sdumbbell WREG32(i2c_cntl_0, (RADEON_I2C_DONE | 542254885Sdumbbell RADEON_I2C_NACK | 543254885Sdumbbell RADEON_I2C_HALT | 544254885Sdumbbell RADEON_I2C_SOFT_RST)); 545254885Sdumbbell WREG32(i2c_data, (p->slave << 1) & 0xff); 546254885Sdumbbell WREG32(i2c_data, 0); 547254885Sdumbbell WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | 548254885Sdumbbell (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | 549254885Sdumbbell RADEON_I2C_EN | 550254885Sdumbbell (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); 551254885Sdumbbell WREG32(i2c_cntl_0, reg); 552254885Sdumbbell for (k = 0; k < 32; k++) { 553282199Sdumbbell udelay(10); 554254885Sdumbbell tmp = RREG32(i2c_cntl_0); 555254885Sdumbbell if (tmp & RADEON_I2C_GO) 556254885Sdumbbell continue; 557254885Sdumbbell tmp = RREG32(i2c_cntl_0); 558254885Sdumbbell if (tmp & RADEON_I2C_DONE) 559254885Sdumbbell break; 560254885Sdumbbell else { 561254885Sdumbbell DRM_DEBUG("i2c write error 0x%08x\n", tmp); 562254885Sdumbbell WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); 563282199Sdumbbell ret = -EIO; 564254885Sdumbbell goto done; 565254885Sdumbbell } 566254885Sdumbbell } 567254885Sdumbbell goto done; 568254885Sdumbbell } 569254885Sdumbbell 570254885Sdumbbell for (i = 0; i < num; i++) { 571254885Sdumbbell p = &msgs[i]; 572254885Sdumbbell for (j = 0; j < p->len; j++) { 573254885Sdumbbell if (p->flags & IIC_M_RD) { 574254885Sdumbbell WREG32(i2c_cntl_0, (RADEON_I2C_DONE | 575254885Sdumbbell RADEON_I2C_NACK | 576254885Sdumbbell RADEON_I2C_HALT | 577254885Sdumbbell RADEON_I2C_SOFT_RST)); 578254885Sdumbbell WREG32(i2c_data, ((p->slave << 1) & 0xff) | 0x1); 579254885Sdumbbell WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | 580254885Sdumbbell (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | 581254885Sdumbbell RADEON_I2C_EN | 582254885Sdumbbell (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); 583254885Sdumbbell WREG32(i2c_cntl_0, reg | RADEON_I2C_RECEIVE); 584254885Sdumbbell for (k = 0; k < 32; k++) { 585282199Sdumbbell udelay(10); 586254885Sdumbbell tmp = RREG32(i2c_cntl_0); 587254885Sdumbbell if (tmp & RADEON_I2C_GO) 588254885Sdumbbell continue; 589254885Sdumbbell tmp = RREG32(i2c_cntl_0); 590254885Sdumbbell if (tmp & RADEON_I2C_DONE) 591254885Sdumbbell break; 592254885Sdumbbell else { 593254885Sdumbbell DRM_DEBUG("i2c read error 0x%08x\n", tmp); 594254885Sdumbbell WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); 595282199Sdumbbell ret = -EIO; 596254885Sdumbbell goto done; 597254885Sdumbbell } 598254885Sdumbbell } 599254885Sdumbbell p->buf[j] = RREG32(i2c_data) & 0xff; 600254885Sdumbbell } else { 601254885Sdumbbell WREG32(i2c_cntl_0, (RADEON_I2C_DONE | 602254885Sdumbbell RADEON_I2C_NACK | 603254885Sdumbbell RADEON_I2C_HALT | 604254885Sdumbbell RADEON_I2C_SOFT_RST)); 605254885Sdumbbell WREG32(i2c_data, (p->slave << 1) & 0xff); 606254885Sdumbbell WREG32(i2c_data, p->buf[j]); 607254885Sdumbbell WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | 608254885Sdumbbell (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | 609254885Sdumbbell RADEON_I2C_EN | 610254885Sdumbbell (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); 611254885Sdumbbell WREG32(i2c_cntl_0, reg); 612254885Sdumbbell for (k = 0; k < 32; k++) { 613282199Sdumbbell udelay(10); 614254885Sdumbbell tmp = RREG32(i2c_cntl_0); 615254885Sdumbbell if (tmp & RADEON_I2C_GO) 616254885Sdumbbell continue; 617254885Sdumbbell tmp = RREG32(i2c_cntl_0); 618254885Sdumbbell if (tmp & RADEON_I2C_DONE) 619254885Sdumbbell break; 620254885Sdumbbell else { 621254885Sdumbbell DRM_DEBUG("i2c write error 0x%08x\n", tmp); 622254885Sdumbbell WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); 623282199Sdumbbell ret = -EIO; 624254885Sdumbbell goto done; 625254885Sdumbbell } 626254885Sdumbbell } 627254885Sdumbbell } 628254885Sdumbbell } 629254885Sdumbbell } 630254885Sdumbbell 631254885Sdumbbelldone: 632254885Sdumbbell WREG32(i2c_cntl_0, 0); 633254885Sdumbbell WREG32(i2c_cntl_1, 0); 634254885Sdumbbell WREG32(i2c_cntl_0, (RADEON_I2C_DONE | 635254885Sdumbbell RADEON_I2C_NACK | 636254885Sdumbbell RADEON_I2C_HALT | 637254885Sdumbbell RADEON_I2C_SOFT_RST)); 638254885Sdumbbell 639254885Sdumbbell if (rdev->is_atom_bios) { 640254885Sdumbbell tmp = RREG32(RADEON_BIOS_6_SCRATCH); 641254885Sdumbbell tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE; 642254885Sdumbbell WREG32(RADEON_BIOS_6_SCRATCH, tmp); 643254885Sdumbbell } 644254885Sdumbbell 645254885Sdumbbell sx_xunlock(&rdev->pm.mutex); 646254885Sdumbbell sx_xunlock(&rdev->dc_hw_i2c_mutex); 647254885Sdumbbell 648254885Sdumbbell return ret; 649254885Sdumbbell} 650254885Sdumbbell 651254885Sdumbbell/* hw i2c engine for r5xx hardware 652254885Sdumbbell * hw can buffer up to 15 bytes 653254885Sdumbbell */ 654254885Sdumbbellstatic int r500_hw_i2c_xfer(struct radeon_i2c_chan *i2c, 655254885Sdumbbell struct iic_msg *msgs, int num) 656254885Sdumbbell{ 657254885Sdumbbell struct radeon_device *rdev = i2c->dev->dev_private; 658254885Sdumbbell struct radeon_i2c_bus_rec *rec = &i2c->rec; 659254885Sdumbbell struct iic_msg *p; 660254885Sdumbbell int i, j, remaining, current_count, buffer_offset, ret = 0; 661254885Sdumbbell u32 prescale; 662254885Sdumbbell u32 tmp, reg; 663254885Sdumbbell u32 saved1, saved2; 664254885Sdumbbell 665254885Sdumbbell sx_xlock(&rdev->dc_hw_i2c_mutex); 666254885Sdumbbell /* take the pm lock since we need a constant sclk */ 667254885Sdumbbell sx_xlock(&rdev->pm.mutex); 668254885Sdumbbell 669254885Sdumbbell prescale = radeon_get_i2c_prescale(rdev); 670254885Sdumbbell 671254885Sdumbbell /* clear gpio mask bits */ 672254885Sdumbbell tmp = RREG32(rec->mask_clk_reg); 673254885Sdumbbell tmp &= ~rec->mask_clk_mask; 674254885Sdumbbell WREG32(rec->mask_clk_reg, tmp); 675254885Sdumbbell tmp = RREG32(rec->mask_clk_reg); 676254885Sdumbbell 677254885Sdumbbell tmp = RREG32(rec->mask_data_reg); 678254885Sdumbbell tmp &= ~rec->mask_data_mask; 679254885Sdumbbell WREG32(rec->mask_data_reg, tmp); 680254885Sdumbbell tmp = RREG32(rec->mask_data_reg); 681254885Sdumbbell 682254885Sdumbbell /* clear pin values */ 683254885Sdumbbell tmp = RREG32(rec->a_clk_reg); 684254885Sdumbbell tmp &= ~rec->a_clk_mask; 685254885Sdumbbell WREG32(rec->a_clk_reg, tmp); 686254885Sdumbbell tmp = RREG32(rec->a_clk_reg); 687254885Sdumbbell 688254885Sdumbbell tmp = RREG32(rec->a_data_reg); 689254885Sdumbbell tmp &= ~rec->a_data_mask; 690254885Sdumbbell WREG32(rec->a_data_reg, tmp); 691254885Sdumbbell tmp = RREG32(rec->a_data_reg); 692254885Sdumbbell 693254885Sdumbbell /* set the pins to input */ 694254885Sdumbbell tmp = RREG32(rec->en_clk_reg); 695254885Sdumbbell tmp &= ~rec->en_clk_mask; 696254885Sdumbbell WREG32(rec->en_clk_reg, tmp); 697254885Sdumbbell tmp = RREG32(rec->en_clk_reg); 698254885Sdumbbell 699254885Sdumbbell tmp = RREG32(rec->en_data_reg); 700254885Sdumbbell tmp &= ~rec->en_data_mask; 701254885Sdumbbell WREG32(rec->en_data_reg, tmp); 702254885Sdumbbell tmp = RREG32(rec->en_data_reg); 703254885Sdumbbell 704254885Sdumbbell /* */ 705254885Sdumbbell tmp = RREG32(RADEON_BIOS_6_SCRATCH); 706254885Sdumbbell WREG32(RADEON_BIOS_6_SCRATCH, tmp | ATOM_S6_HW_I2C_BUSY_STATE); 707254885Sdumbbell saved1 = RREG32(AVIVO_DC_I2C_CONTROL1); 708254885Sdumbbell saved2 = RREG32(0x494); 709254885Sdumbbell WREG32(0x494, saved2 | 0x1); 710254885Sdumbbell 711254885Sdumbbell WREG32(AVIVO_DC_I2C_ARBITRATION, AVIVO_DC_I2C_SW_WANTS_TO_USE_I2C); 712254885Sdumbbell for (i = 0; i < 50; i++) { 713282199Sdumbbell udelay(1); 714254885Sdumbbell if (RREG32(AVIVO_DC_I2C_ARBITRATION) & AVIVO_DC_I2C_SW_CAN_USE_I2C) 715254885Sdumbbell break; 716254885Sdumbbell } 717254885Sdumbbell if (i == 50) { 718254885Sdumbbell DRM_ERROR("failed to get i2c bus\n"); 719282199Sdumbbell ret = -EBUSY; 720254885Sdumbbell goto done; 721254885Sdumbbell } 722254885Sdumbbell 723254885Sdumbbell reg = AVIVO_DC_I2C_START | AVIVO_DC_I2C_STOP | AVIVO_DC_I2C_EN; 724254885Sdumbbell switch (rec->mask_clk_reg) { 725254885Sdumbbell case AVIVO_DC_GPIO_DDC1_MASK: 726254885Sdumbbell reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC1); 727254885Sdumbbell break; 728254885Sdumbbell case AVIVO_DC_GPIO_DDC2_MASK: 729254885Sdumbbell reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC2); 730254885Sdumbbell break; 731254885Sdumbbell case AVIVO_DC_GPIO_DDC3_MASK: 732254885Sdumbbell reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC3); 733254885Sdumbbell break; 734254885Sdumbbell default: 735254885Sdumbbell DRM_ERROR("gpio not supported with hw i2c\n"); 736282199Sdumbbell ret = -EINVAL; 737254885Sdumbbell goto done; 738254885Sdumbbell } 739254885Sdumbbell 740254885Sdumbbell /* check for bus probe */ 741254885Sdumbbell p = &msgs[0]; 742254885Sdumbbell if ((num == 1) && (p->len == 0)) { 743254885Sdumbbell WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | 744254885Sdumbbell AVIVO_DC_I2C_NACK | 745254885Sdumbbell AVIVO_DC_I2C_HALT)); 746254885Sdumbbell WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); 747282199Sdumbbell udelay(1); 748254885Sdumbbell WREG32(AVIVO_DC_I2C_RESET, 0); 749254885Sdumbbell 750254885Sdumbbell WREG32(AVIVO_DC_I2C_DATA, (p->slave << 1) & 0xff); 751254885Sdumbbell WREG32(AVIVO_DC_I2C_DATA, 0); 752254885Sdumbbell 753254885Sdumbbell WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); 754254885Sdumbbell WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | 755254885Sdumbbell AVIVO_DC_I2C_DATA_COUNT(1) | 756254885Sdumbbell (prescale << 16))); 757254885Sdumbbell WREG32(AVIVO_DC_I2C_CONTROL1, reg); 758254885Sdumbbell WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); 759254885Sdumbbell for (j = 0; j < 200; j++) { 760282199Sdumbbell udelay(50); 761254885Sdumbbell tmp = RREG32(AVIVO_DC_I2C_STATUS1); 762254885Sdumbbell if (tmp & AVIVO_DC_I2C_GO) 763254885Sdumbbell continue; 764254885Sdumbbell tmp = RREG32(AVIVO_DC_I2C_STATUS1); 765254885Sdumbbell if (tmp & AVIVO_DC_I2C_DONE) 766254885Sdumbbell break; 767254885Sdumbbell else { 768254885Sdumbbell DRM_DEBUG("i2c write error 0x%08x\n", tmp); 769254885Sdumbbell WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); 770282199Sdumbbell ret = -EIO; 771254885Sdumbbell goto done; 772254885Sdumbbell } 773254885Sdumbbell } 774254885Sdumbbell goto done; 775254885Sdumbbell } 776254885Sdumbbell 777254885Sdumbbell for (i = 0; i < num; i++) { 778254885Sdumbbell p = &msgs[i]; 779254885Sdumbbell remaining = p->len; 780254885Sdumbbell buffer_offset = 0; 781254885Sdumbbell if (p->flags & IIC_M_RD) { 782254885Sdumbbell while (remaining) { 783254885Sdumbbell if (remaining > 15) 784254885Sdumbbell current_count = 15; 785254885Sdumbbell else 786254885Sdumbbell current_count = remaining; 787254885Sdumbbell WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | 788254885Sdumbbell AVIVO_DC_I2C_NACK | 789254885Sdumbbell AVIVO_DC_I2C_HALT)); 790254885Sdumbbell WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); 791282199Sdumbbell udelay(1); 792254885Sdumbbell WREG32(AVIVO_DC_I2C_RESET, 0); 793254885Sdumbbell 794254885Sdumbbell WREG32(AVIVO_DC_I2C_DATA, ((p->slave << 1) & 0xff) | 0x1); 795254885Sdumbbell WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); 796254885Sdumbbell WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | 797254885Sdumbbell AVIVO_DC_I2C_DATA_COUNT(current_count) | 798254885Sdumbbell (prescale << 16))); 799254885Sdumbbell WREG32(AVIVO_DC_I2C_CONTROL1, reg | AVIVO_DC_I2C_RECEIVE); 800254885Sdumbbell WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); 801254885Sdumbbell for (j = 0; j < 200; j++) { 802282199Sdumbbell udelay(50); 803254885Sdumbbell tmp = RREG32(AVIVO_DC_I2C_STATUS1); 804254885Sdumbbell if (tmp & AVIVO_DC_I2C_GO) 805254885Sdumbbell continue; 806254885Sdumbbell tmp = RREG32(AVIVO_DC_I2C_STATUS1); 807254885Sdumbbell if (tmp & AVIVO_DC_I2C_DONE) 808254885Sdumbbell break; 809254885Sdumbbell else { 810254885Sdumbbell DRM_DEBUG("i2c read error 0x%08x\n", tmp); 811254885Sdumbbell WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); 812282199Sdumbbell ret = -EIO; 813254885Sdumbbell goto done; 814254885Sdumbbell } 815254885Sdumbbell } 816254885Sdumbbell for (j = 0; j < current_count; j++) 817254885Sdumbbell p->buf[buffer_offset + j] = RREG32(AVIVO_DC_I2C_DATA) & 0xff; 818254885Sdumbbell remaining -= current_count; 819254885Sdumbbell buffer_offset += current_count; 820254885Sdumbbell } 821254885Sdumbbell } else { 822254885Sdumbbell while (remaining) { 823254885Sdumbbell if (remaining > 15) 824254885Sdumbbell current_count = 15; 825254885Sdumbbell else 826254885Sdumbbell current_count = remaining; 827254885Sdumbbell WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | 828254885Sdumbbell AVIVO_DC_I2C_NACK | 829254885Sdumbbell AVIVO_DC_I2C_HALT)); 830254885Sdumbbell WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); 831282199Sdumbbell udelay(1); 832254885Sdumbbell WREG32(AVIVO_DC_I2C_RESET, 0); 833254885Sdumbbell 834254885Sdumbbell WREG32(AVIVO_DC_I2C_DATA, (p->slave << 1) & 0xff); 835254885Sdumbbell for (j = 0; j < current_count; j++) 836254885Sdumbbell WREG32(AVIVO_DC_I2C_DATA, p->buf[buffer_offset + j]); 837254885Sdumbbell 838254885Sdumbbell WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); 839254885Sdumbbell WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | 840254885Sdumbbell AVIVO_DC_I2C_DATA_COUNT(current_count) | 841254885Sdumbbell (prescale << 16))); 842254885Sdumbbell WREG32(AVIVO_DC_I2C_CONTROL1, reg); 843254885Sdumbbell WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); 844254885Sdumbbell for (j = 0; j < 200; j++) { 845282199Sdumbbell udelay(50); 846254885Sdumbbell tmp = RREG32(AVIVO_DC_I2C_STATUS1); 847254885Sdumbbell if (tmp & AVIVO_DC_I2C_GO) 848254885Sdumbbell continue; 849254885Sdumbbell tmp = RREG32(AVIVO_DC_I2C_STATUS1); 850254885Sdumbbell if (tmp & AVIVO_DC_I2C_DONE) 851254885Sdumbbell break; 852254885Sdumbbell else { 853254885Sdumbbell DRM_DEBUG("i2c write error 0x%08x\n", tmp); 854254885Sdumbbell WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); 855282199Sdumbbell ret = -EIO; 856254885Sdumbbell goto done; 857254885Sdumbbell } 858254885Sdumbbell } 859254885Sdumbbell remaining -= current_count; 860254885Sdumbbell buffer_offset += current_count; 861254885Sdumbbell } 862254885Sdumbbell } 863254885Sdumbbell } 864254885Sdumbbell 865254885Sdumbbelldone: 866254885Sdumbbell WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | 867254885Sdumbbell AVIVO_DC_I2C_NACK | 868254885Sdumbbell AVIVO_DC_I2C_HALT)); 869254885Sdumbbell WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); 870282199Sdumbbell udelay(1); 871254885Sdumbbell WREG32(AVIVO_DC_I2C_RESET, 0); 872254885Sdumbbell 873254885Sdumbbell WREG32(AVIVO_DC_I2C_ARBITRATION, AVIVO_DC_I2C_SW_DONE_USING_I2C); 874254885Sdumbbell WREG32(AVIVO_DC_I2C_CONTROL1, saved1); 875254885Sdumbbell WREG32(0x494, saved2); 876254885Sdumbbell tmp = RREG32(RADEON_BIOS_6_SCRATCH); 877254885Sdumbbell tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE; 878254885Sdumbbell WREG32(RADEON_BIOS_6_SCRATCH, tmp); 879254885Sdumbbell 880254885Sdumbbell sx_xunlock(&rdev->pm.mutex); 881254885Sdumbbell sx_xunlock(&rdev->dc_hw_i2c_mutex); 882254885Sdumbbell 883254885Sdumbbell return ret; 884254885Sdumbbell} 885254885Sdumbbell 886254885Sdumbbellstatic int radeon_hw_i2c_xfer(device_t dev, 887254885Sdumbbell struct iic_msg *msgs, uint32_t num) 888254885Sdumbbell{ 889254885Sdumbbell struct radeon_i2c_chan *i2c = device_get_softc(dev); 890254885Sdumbbell struct radeon_device *rdev = i2c->dev->dev_private; 891254885Sdumbbell struct radeon_i2c_bus_rec *rec = &i2c->rec; 892254885Sdumbbell int ret = 0; 893254885Sdumbbell 894254885Sdumbbell switch (rdev->family) { 895254885Sdumbbell case CHIP_R100: 896254885Sdumbbell case CHIP_RV100: 897254885Sdumbbell case CHIP_RS100: 898254885Sdumbbell case CHIP_RV200: 899254885Sdumbbell case CHIP_RS200: 900254885Sdumbbell case CHIP_R200: 901254885Sdumbbell case CHIP_RV250: 902254885Sdumbbell case CHIP_RS300: 903254885Sdumbbell case CHIP_RV280: 904254885Sdumbbell case CHIP_R300: 905254885Sdumbbell case CHIP_R350: 906254885Sdumbbell case CHIP_RV350: 907254885Sdumbbell case CHIP_RV380: 908254885Sdumbbell case CHIP_R420: 909254885Sdumbbell case CHIP_R423: 910254885Sdumbbell case CHIP_RV410: 911254885Sdumbbell case CHIP_RS400: 912254885Sdumbbell case CHIP_RS480: 913254885Sdumbbell ret = r100_hw_i2c_xfer(i2c, msgs, num); 914254885Sdumbbell break; 915254885Sdumbbell case CHIP_RS600: 916254885Sdumbbell case CHIP_RS690: 917254885Sdumbbell case CHIP_RS740: 918254885Sdumbbell /* XXX fill in hw i2c implementation */ 919254885Sdumbbell break; 920254885Sdumbbell case CHIP_RV515: 921254885Sdumbbell case CHIP_R520: 922254885Sdumbbell case CHIP_RV530: 923254885Sdumbbell case CHIP_RV560: 924254885Sdumbbell case CHIP_RV570: 925254885Sdumbbell case CHIP_R580: 926254885Sdumbbell if (rec->mm_i2c) 927254885Sdumbbell ret = r100_hw_i2c_xfer(i2c, msgs, num); 928254885Sdumbbell else 929254885Sdumbbell ret = r500_hw_i2c_xfer(i2c, msgs, num); 930254885Sdumbbell break; 931254885Sdumbbell case CHIP_R600: 932254885Sdumbbell case CHIP_RV610: 933254885Sdumbbell case CHIP_RV630: 934254885Sdumbbell case CHIP_RV670: 935254885Sdumbbell /* XXX fill in hw i2c implementation */ 936254885Sdumbbell break; 937254885Sdumbbell case CHIP_RV620: 938254885Sdumbbell case CHIP_RV635: 939254885Sdumbbell case CHIP_RS780: 940254885Sdumbbell case CHIP_RS880: 941254885Sdumbbell case CHIP_RV770: 942254885Sdumbbell case CHIP_RV730: 943254885Sdumbbell case CHIP_RV710: 944254885Sdumbbell case CHIP_RV740: 945254885Sdumbbell /* XXX fill in hw i2c implementation */ 946254885Sdumbbell break; 947254885Sdumbbell case CHIP_CEDAR: 948254885Sdumbbell case CHIP_REDWOOD: 949254885Sdumbbell case CHIP_JUNIPER: 950254885Sdumbbell case CHIP_CYPRESS: 951254885Sdumbbell case CHIP_HEMLOCK: 952254885Sdumbbell /* XXX fill in hw i2c implementation */ 953254885Sdumbbell break; 954254885Sdumbbell default: 955254885Sdumbbell DRM_ERROR("i2c: unhandled radeon chip\n"); 956282199Sdumbbell ret = -EIO; 957254885Sdumbbell break; 958254885Sdumbbell } 959254885Sdumbbell 960282199Sdumbbell return -ret; 961254885Sdumbbell} 962254885Sdumbbell 963254885Sdumbbellstatic int 964254885Sdumbbellradeon_hw_i2c_probe(device_t dev) 965254885Sdumbbell{ 966254885Sdumbbell 967254885Sdumbbell return (BUS_PROBE_SPECIFIC); 968254885Sdumbbell} 969254885Sdumbbell 970254885Sdumbbellstatic int 971254885Sdumbbellradeon_hw_i2c_attach(device_t dev) 972254885Sdumbbell{ 973254885Sdumbbell struct radeon_i2c_chan *i2c; 974254885Sdumbbell device_t iic_dev; 975254885Sdumbbell 976254885Sdumbbell i2c = device_get_softc(dev); 977254885Sdumbbell device_set_desc(dev, i2c->name); 978254885Sdumbbell 979254885Sdumbbell /* add generic bit-banging code */ 980254885Sdumbbell iic_dev = device_add_child(dev, "iicbus", -1); 981254885Sdumbbell if (iic_dev == NULL) 982254885Sdumbbell return (ENXIO); 983254885Sdumbbell device_quiet(iic_dev); 984254885Sdumbbell 985254885Sdumbbell /* attach and probe added child */ 986254885Sdumbbell bus_generic_attach(dev); 987254885Sdumbbell 988254885Sdumbbell return (0); 989254885Sdumbbell} 990254885Sdumbbell 991254885Sdumbbellstatic int 992254885Sdumbbellradeon_hw_i2c_detach(device_t dev) 993254885Sdumbbell{ 994254885Sdumbbell 995254885Sdumbbell /* detach bit-banding code. */ 996254885Sdumbbell bus_generic_detach(dev); 997254885Sdumbbell 998254885Sdumbbell /* delete bit-banding code. */ 999254885Sdumbbell device_delete_children(dev); 1000254885Sdumbbell return (0); 1001254885Sdumbbell} 1002254885Sdumbbell 1003254885Sdumbbellstatic int 1004254885Sdumbbellradeon_hw_i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) 1005254885Sdumbbell{ 1006254885Sdumbbell 1007254885Sdumbbell /* Not sure what to do here. */ 1008254885Sdumbbell return 0; 1009254885Sdumbbell} 1010254885Sdumbbell 1011254885Sdumbbell 1012254885Sdumbbellstatic device_method_t radeon_hw_i2c_methods[] = { 1013254885Sdumbbell DEVMETHOD(device_probe, radeon_hw_i2c_probe), 1014254885Sdumbbell DEVMETHOD(device_attach, radeon_hw_i2c_attach), 1015254885Sdumbbell DEVMETHOD(device_detach, radeon_hw_i2c_detach), 1016254885Sdumbbell DEVMETHOD(iicbus_reset, radeon_hw_i2c_reset), 1017254885Sdumbbell DEVMETHOD(iicbus_transfer, radeon_hw_i2c_xfer), 1018254885Sdumbbell DEVMETHOD_END 1019254885Sdumbbell}; 1020254885Sdumbbell 1021254885Sdumbbellstatic driver_t radeon_hw_i2c_driver = { 1022254885Sdumbbell "radeon_hw_i2c", 1023254885Sdumbbell radeon_hw_i2c_methods, 1024254885Sdumbbell 0 /* softc will be allocated by parent */ 1025254885Sdumbbell}; 1026254885Sdumbbell 1027254885Sdumbbellstatic devclass_t radeon_hw_i2c_devclass; 1028254885SdumbbellDRIVER_MODULE_ORDERED(radeon_hw_i2c, drm, radeon_hw_i2c_driver, 1029254885Sdumbbell radeon_hw_i2c_devclass, 0, 0, SI_ORDER_FIRST); 1030254885SdumbbellDRIVER_MODULE(iicbus, radeon_hw_i2c, iicbus_driver, iicbus_devclass, 0, 0); 1031254885Sdumbbell 1032254885Sdumbbellstruct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, 1033254885Sdumbbell struct radeon_i2c_bus_rec *rec, 1034254885Sdumbbell const char *name) 1035254885Sdumbbell{ 1036254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1037254885Sdumbbell struct radeon_i2c_chan *i2c; 1038254885Sdumbbell device_t iicbus_dev; 1039254885Sdumbbell int ret; 1040254885Sdumbbell 1041254885Sdumbbell /* don't add the mm_i2c bus unless hw_i2c is enabled */ 1042254885Sdumbbell if (rec->mm_i2c && (radeon_hw_i2c == 0)) 1043254885Sdumbbell return NULL; 1044254885Sdumbbell 1045254885Sdumbbell i2c = malloc(sizeof(struct radeon_i2c_chan), 1046282199Sdumbbell DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 1047254885Sdumbbell if (i2c == NULL) 1048254885Sdumbbell return NULL; 1049254885Sdumbbell 1050254885Sdumbbell /* 1051254885Sdumbbell * Grab Giant before messing with newbus devices, just in case 1052254885Sdumbbell * we do not hold it already. 1053254885Sdumbbell */ 1054254885Sdumbbell mtx_lock(&Giant); 1055254885Sdumbbell 1056254885Sdumbbell i2c->rec = *rec; 1057254885Sdumbbell i2c->dev = dev; 1058254885Sdumbbell if (rec->mm_i2c || 1059254885Sdumbbell (rec->hw_capable && 1060254885Sdumbbell radeon_hw_i2c && 1061254885Sdumbbell ((rdev->family <= CHIP_RS480) || 1062254885Sdumbbell ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) { 1063254885Sdumbbell /* set the radeon hw i2c adapter */ 1064254885Sdumbbell snprintf(i2c->name, sizeof(i2c->name), 1065254885Sdumbbell "Radeon i2c hw bus %s", name); 1066282199Sdumbbell iicbus_dev = device_add_child(dev->dev, "radeon_hw_i2c", -1); 1067254885Sdumbbell if (iicbus_dev == NULL) { 1068254885Sdumbbell DRM_ERROR("Failed to create bridge for hw i2c %s\n", 1069254885Sdumbbell name); 1070254885Sdumbbell goto out_free; 1071254885Sdumbbell } 1072254885Sdumbbell device_quiet(iicbus_dev); 1073254885Sdumbbell device_set_softc(iicbus_dev, i2c); 1074254885Sdumbbell 1075254885Sdumbbell ret = device_probe_and_attach(iicbus_dev); 1076254885Sdumbbell if (ret != 0) { 1077254885Sdumbbell DRM_ERROR("Attach failed for bridge for hw i2c %s\n", 1078254885Sdumbbell name); 1079282199Sdumbbell device_delete_child(dev->dev, iicbus_dev); 1080254885Sdumbbell goto out_free; 1081254885Sdumbbell } 1082254885Sdumbbell 1083254885Sdumbbell i2c->adapter = device_find_child(iicbus_dev, "iicbus", -1); 1084254885Sdumbbell if (i2c->adapter == NULL) { 1085254885Sdumbbell DRM_ERROR("hw i2c bridge doesn't have iicbus child\n"); 1086282199Sdumbbell device_delete_child(dev->dev, iicbus_dev); 1087254885Sdumbbell goto out_free; 1088254885Sdumbbell } 1089254885Sdumbbell } else if (rec->hw_capable && 1090254885Sdumbbell radeon_hw_i2c && 1091254885Sdumbbell ASIC_IS_DCE3(rdev)) { 1092254885Sdumbbell /* hw i2c using atom */ 1093254885Sdumbbell snprintf(i2c->name, sizeof(i2c->name), 1094254885Sdumbbell "Radeon i2c hw bus %s", name); 1095282199Sdumbbell iicbus_dev = device_add_child(dev->dev, "radeon_atom_hw_i2c", -1); 1096254885Sdumbbell if (iicbus_dev == NULL) { 1097254885Sdumbbell DRM_ERROR("Failed to create bridge for hw i2c %s\n", 1098254885Sdumbbell name); 1099254885Sdumbbell goto out_free; 1100254885Sdumbbell } 1101254885Sdumbbell device_quiet(iicbus_dev); 1102254885Sdumbbell device_set_softc(iicbus_dev, i2c); 1103254885Sdumbbell 1104254885Sdumbbell ret = device_probe_and_attach(iicbus_dev); 1105254885Sdumbbell if (ret != 0) { 1106254885Sdumbbell DRM_ERROR("Attach failed for bridge for hw i2c %s\n", 1107254885Sdumbbell name); 1108282199Sdumbbell device_delete_child(dev->dev, iicbus_dev); 1109254885Sdumbbell goto out_free; 1110254885Sdumbbell } 1111254885Sdumbbell 1112254885Sdumbbell i2c->adapter = device_find_child(iicbus_dev, "iicbus", -1); 1113254885Sdumbbell if (i2c->adapter == NULL) { 1114254885Sdumbbell DRM_ERROR("hw i2c bridge doesn't have iicbus child\n"); 1115282199Sdumbbell device_delete_child(dev->dev, iicbus_dev); 1116254885Sdumbbell goto out_free; 1117254885Sdumbbell } 1118254885Sdumbbell } else { 1119254885Sdumbbell device_t iicbb_dev; 1120254885Sdumbbell 1121254885Sdumbbell /* set the radeon bit adapter */ 1122254885Sdumbbell snprintf(i2c->name, sizeof(i2c->name), 1123254885Sdumbbell "Radeon i2c bit bus %s", name); 1124282199Sdumbbell iicbus_dev = device_add_child(dev->dev, "radeon_iicbb", -1); 1125254885Sdumbbell if (iicbus_dev == NULL) { 1126254885Sdumbbell DRM_ERROR("Failed to create bridge for bb i2c %s\n", 1127254885Sdumbbell name); 1128254885Sdumbbell goto out_free; 1129254885Sdumbbell } 1130254885Sdumbbell device_quiet(iicbus_dev); 1131254885Sdumbbell device_set_softc(iicbus_dev, i2c); 1132254885Sdumbbell 1133254885Sdumbbell ret = device_probe_and_attach(iicbus_dev); 1134254885Sdumbbell if (ret != 0) { 1135254885Sdumbbell DRM_ERROR("Attach failed for bridge for bb i2c %s\n", 1136254885Sdumbbell name); 1137282199Sdumbbell device_delete_child(dev->dev, iicbus_dev); 1138254885Sdumbbell goto out_free; 1139254885Sdumbbell } 1140254885Sdumbbell 1141254885Sdumbbell iicbb_dev = device_find_child(iicbus_dev, "iicbb", -1); 1142254885Sdumbbell if (iicbb_dev == NULL) { 1143254885Sdumbbell DRM_ERROR("bb i2c bridge doesn't have iicbb child\n"); 1144282199Sdumbbell device_delete_child(dev->dev, iicbus_dev); 1145254885Sdumbbell goto out_free; 1146254885Sdumbbell } 1147254885Sdumbbell 1148254885Sdumbbell i2c->adapter = device_find_child(iicbb_dev, "iicbus", -1); 1149254885Sdumbbell if (i2c->adapter == NULL) { 1150254885Sdumbbell DRM_ERROR( 1151254885Sdumbbell "bbbus bridge doesn't have iicbus grandchild\n"); 1152282199Sdumbbell device_delete_child(dev->dev, iicbus_dev); 1153254885Sdumbbell goto out_free; 1154254885Sdumbbell } 1155254885Sdumbbell } 1156254885Sdumbbell 1157254885Sdumbbell i2c->iic_bus = iicbus_dev; 1158254885Sdumbbell 1159254885Sdumbbell mtx_unlock(&Giant); 1160254885Sdumbbell 1161254885Sdumbbell return i2c; 1162254885Sdumbbellout_free: 1163254885Sdumbbell mtx_unlock(&Giant); 1164254885Sdumbbell free(i2c, DRM_MEM_DRIVER); 1165254885Sdumbbell return NULL; 1166254885Sdumbbell 1167254885Sdumbbell} 1168254885Sdumbbell 1169254885Sdumbbellstruct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, 1170254885Sdumbbell struct radeon_i2c_bus_rec *rec, 1171254885Sdumbbell const char *name) 1172254885Sdumbbell{ 1173254885Sdumbbell struct radeon_i2c_chan *i2c; 1174254885Sdumbbell int ret; 1175254885Sdumbbell 1176254885Sdumbbell i2c = malloc(sizeof(struct radeon_i2c_chan), 1177282199Sdumbbell DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 1178254885Sdumbbell if (i2c == NULL) 1179254885Sdumbbell return NULL; 1180254885Sdumbbell 1181254885Sdumbbell i2c->rec = *rec; 1182254885Sdumbbell i2c->dev = dev; 1183254885Sdumbbell snprintf(i2c->name, sizeof(i2c->name), 1184254885Sdumbbell "Radeon aux bus %s", name); 1185282199Sdumbbell ret = iic_dp_aux_add_bus(dev->dev, i2c->name, 1186254885Sdumbbell radeon_dp_i2c_aux_ch, i2c, &i2c->iic_bus, 1187254885Sdumbbell &i2c->adapter); 1188254885Sdumbbell if (ret) { 1189254885Sdumbbell DRM_INFO("Failed to register i2c %s\n", name); 1190254885Sdumbbell goto out_free; 1191254885Sdumbbell } 1192254885Sdumbbell 1193254885Sdumbbell return i2c; 1194254885Sdumbbellout_free: 1195254885Sdumbbell free(i2c, DRM_MEM_DRIVER); 1196254885Sdumbbell return NULL; 1197254885Sdumbbell 1198254885Sdumbbell} 1199254885Sdumbbell 1200254885Sdumbbellvoid radeon_i2c_destroy(struct radeon_i2c_chan *i2c) 1201254885Sdumbbell{ 1202254885Sdumbbell if (!i2c) 1203254885Sdumbbell return; 1204254885Sdumbbell if (i2c->iic_bus != NULL) { 1205254885Sdumbbell int ret; 1206254885Sdumbbell 1207254885Sdumbbell mtx_lock(&Giant); 1208282199Sdumbbell ret = device_delete_child(i2c->dev->dev, i2c->iic_bus); 1209254885Sdumbbell mtx_unlock(&Giant); 1210254885Sdumbbell KASSERT(ret == 0, ("unable to detach iic bus %s: %d", 1211254885Sdumbbell i2c->name, ret)); 1212254885Sdumbbell } 1213254885Sdumbbell free(i2c, DRM_MEM_DRIVER); 1214254885Sdumbbell} 1215254885Sdumbbell 1216254885Sdumbbell/* Add the default buses */ 1217254885Sdumbbellvoid radeon_i2c_init(struct radeon_device *rdev) 1218254885Sdumbbell{ 1219254885Sdumbbell if (rdev->is_atom_bios) 1220254885Sdumbbell radeon_atombios_i2c_init(rdev); 1221254885Sdumbbell else 1222254885Sdumbbell radeon_combios_i2c_init(rdev); 1223254885Sdumbbell} 1224254885Sdumbbell 1225254885Sdumbbell/* remove all the buses */ 1226254885Sdumbbellvoid radeon_i2c_fini(struct radeon_device *rdev) 1227254885Sdumbbell{ 1228254885Sdumbbell int i; 1229254885Sdumbbell 1230254885Sdumbbell for (i = 0; i < RADEON_MAX_I2C_BUS; i++) { 1231254885Sdumbbell if (rdev->i2c_bus[i]) { 1232254885Sdumbbell radeon_i2c_destroy(rdev->i2c_bus[i]); 1233254885Sdumbbell rdev->i2c_bus[i] = NULL; 1234254885Sdumbbell } 1235254885Sdumbbell } 1236254885Sdumbbell} 1237254885Sdumbbell 1238254885Sdumbbell/* Add additional buses */ 1239254885Sdumbbellvoid radeon_i2c_add(struct radeon_device *rdev, 1240254885Sdumbbell struct radeon_i2c_bus_rec *rec, 1241254885Sdumbbell const char *name) 1242254885Sdumbbell{ 1243254885Sdumbbell struct drm_device *dev = rdev->ddev; 1244254885Sdumbbell int i; 1245254885Sdumbbell 1246254885Sdumbbell for (i = 0; i < RADEON_MAX_I2C_BUS; i++) { 1247254885Sdumbbell if (!rdev->i2c_bus[i]) { 1248254885Sdumbbell rdev->i2c_bus[i] = radeon_i2c_create(dev, rec, name); 1249254885Sdumbbell return; 1250254885Sdumbbell } 1251254885Sdumbbell } 1252254885Sdumbbell} 1253254885Sdumbbell 1254254885Sdumbbell/* looks up bus based on id */ 1255254885Sdumbbellstruct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev, 1256254885Sdumbbell struct radeon_i2c_bus_rec *i2c_bus) 1257254885Sdumbbell{ 1258254885Sdumbbell int i; 1259254885Sdumbbell 1260254885Sdumbbell for (i = 0; i < RADEON_MAX_I2C_BUS; i++) { 1261254885Sdumbbell if (rdev->i2c_bus[i] && 1262254885Sdumbbell (rdev->i2c_bus[i]->rec.i2c_id == i2c_bus->i2c_id)) { 1263254885Sdumbbell return rdev->i2c_bus[i]; 1264254885Sdumbbell } 1265254885Sdumbbell } 1266254885Sdumbbell return NULL; 1267254885Sdumbbell} 1268254885Sdumbbell 1269254885Sdumbbellstruct drm_encoder *radeon_best_encoder(struct drm_connector *connector) 1270254885Sdumbbell{ 1271254885Sdumbbell return NULL; 1272254885Sdumbbell} 1273254885Sdumbbell 1274254885Sdumbbellvoid radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, 1275254885Sdumbbell u8 slave_addr, 1276254885Sdumbbell u8 addr, 1277254885Sdumbbell u8 *val) 1278254885Sdumbbell{ 1279254885Sdumbbell u8 out_buf[2]; 1280254885Sdumbbell u8 in_buf[2]; 1281254885Sdumbbell struct iic_msg msgs[] = { 1282254885Sdumbbell { 1283254885Sdumbbell .slave = slave_addr << 1, 1284254885Sdumbbell .flags = 0, 1285254885Sdumbbell .len = 1, 1286254885Sdumbbell .buf = out_buf, 1287254885Sdumbbell }, 1288254885Sdumbbell { 1289254885Sdumbbell .slave = slave_addr << 1, 1290254885Sdumbbell .flags = IIC_M_RD, 1291254885Sdumbbell .len = 1, 1292254885Sdumbbell .buf = in_buf, 1293254885Sdumbbell } 1294254885Sdumbbell }; 1295254885Sdumbbell 1296254885Sdumbbell out_buf[0] = addr; 1297254885Sdumbbell out_buf[1] = 0; 1298254885Sdumbbell 1299254885Sdumbbell if (iicbus_transfer(i2c_bus->adapter, msgs, 2) == 0) { 1300254885Sdumbbell *val = in_buf[0]; 1301254885Sdumbbell DRM_DEBUG("val = 0x%02x\n", *val); 1302254885Sdumbbell } else { 1303254885Sdumbbell DRM_DEBUG("i2c 0x%02x 0x%02x read failed\n", 1304254885Sdumbbell addr, *val); 1305254885Sdumbbell } 1306254885Sdumbbell} 1307254885Sdumbbell 1308254885Sdumbbellvoid radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus, 1309254885Sdumbbell u8 slave_addr, 1310254885Sdumbbell u8 addr, 1311254885Sdumbbell u8 val) 1312254885Sdumbbell{ 1313254885Sdumbbell uint8_t out_buf[2]; 1314254885Sdumbbell struct iic_msg msg = { 1315254885Sdumbbell .slave = slave_addr << 1, 1316254885Sdumbbell .flags = 0, 1317254885Sdumbbell .len = 2, 1318254885Sdumbbell .buf = out_buf, 1319254885Sdumbbell }; 1320254885Sdumbbell 1321254885Sdumbbell out_buf[0] = addr; 1322254885Sdumbbell out_buf[1] = val; 1323254885Sdumbbell 1324254885Sdumbbell if (iicbus_transfer(i2c_bus->adapter, &msg, 1) != 0) 1325254885Sdumbbell DRM_DEBUG("i2c 0x%02x 0x%02x write failed\n", 1326254885Sdumbbell addr, val); 1327254885Sdumbbell} 1328254885Sdumbbell 1329254885Sdumbbell/* ddc router switching */ 1330254885Sdumbbellvoid radeon_router_select_ddc_port(struct radeon_connector *radeon_connector) 1331254885Sdumbbell{ 1332254885Sdumbbell u8 val; 1333254885Sdumbbell 1334254885Sdumbbell if (!radeon_connector->router.ddc_valid) 1335254885Sdumbbell return; 1336254885Sdumbbell 1337254885Sdumbbell if (!radeon_connector->router_bus) 1338254885Sdumbbell return; 1339254885Sdumbbell 1340254885Sdumbbell radeon_i2c_get_byte(radeon_connector->router_bus, 1341254885Sdumbbell radeon_connector->router.i2c_addr, 1342254885Sdumbbell 0x3, &val); 1343254885Sdumbbell val &= ~radeon_connector->router.ddc_mux_control_pin; 1344254885Sdumbbell radeon_i2c_put_byte(radeon_connector->router_bus, 1345254885Sdumbbell radeon_connector->router.i2c_addr, 1346254885Sdumbbell 0x3, val); 1347254885Sdumbbell radeon_i2c_get_byte(radeon_connector->router_bus, 1348254885Sdumbbell radeon_connector->router.i2c_addr, 1349254885Sdumbbell 0x1, &val); 1350254885Sdumbbell val &= ~radeon_connector->router.ddc_mux_control_pin; 1351254885Sdumbbell val |= radeon_connector->router.ddc_mux_state; 1352254885Sdumbbell radeon_i2c_put_byte(radeon_connector->router_bus, 1353254885Sdumbbell radeon_connector->router.i2c_addr, 1354254885Sdumbbell 0x1, val); 1355254885Sdumbbell} 1356254885Sdumbbell 1357254885Sdumbbell/* clock/data router switching */ 1358254885Sdumbbellvoid radeon_router_select_cd_port(struct radeon_connector *radeon_connector) 1359254885Sdumbbell{ 1360254885Sdumbbell u8 val; 1361254885Sdumbbell 1362254885Sdumbbell if (!radeon_connector->router.cd_valid) 1363254885Sdumbbell return; 1364254885Sdumbbell 1365254885Sdumbbell if (!radeon_connector->router_bus) 1366254885Sdumbbell return; 1367254885Sdumbbell 1368254885Sdumbbell radeon_i2c_get_byte(radeon_connector->router_bus, 1369254885Sdumbbell radeon_connector->router.i2c_addr, 1370254885Sdumbbell 0x3, &val); 1371254885Sdumbbell val &= ~radeon_connector->router.cd_mux_control_pin; 1372254885Sdumbbell radeon_i2c_put_byte(radeon_connector->router_bus, 1373254885Sdumbbell radeon_connector->router.i2c_addr, 1374254885Sdumbbell 0x3, val); 1375254885Sdumbbell radeon_i2c_get_byte(radeon_connector->router_bus, 1376254885Sdumbbell radeon_connector->router.i2c_addr, 1377254885Sdumbbell 0x1, &val); 1378254885Sdumbbell val &= ~radeon_connector->router.cd_mux_control_pin; 1379254885Sdumbbell val |= radeon_connector->router.cd_mux_state; 1380254885Sdumbbell radeon_i2c_put_byte(radeon_connector->router_bus, 1381254885Sdumbbell radeon_connector->router.i2c_addr, 1382254885Sdumbbell 0x1, val); 1383254885Sdumbbell} 1384254885Sdumbbell 1385