linux/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
<<
>>
Prefs
   1/*
   2 * Copyright 2013 Red Hat Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * Authors: Ben Skeggs
  23 */
  24
  25#include <core/option.h>
  26#include <core/event.h>
  27
  28#include <subdev/bios.h>
  29#include <subdev/bios/dcb.h>
  30#include <subdev/bios/i2c.h>
  31#include <subdev/vga.h>
  32
  33#include "priv.h"
  34#include "pad.h"
  35
  36/******************************************************************************
  37 * interface to linux i2c bit-banging algorithm
  38 *****************************************************************************/
  39
  40#ifdef CONFIG_NOUVEAU_I2C_INTERNAL_DEFAULT
  41#define CSTMSEL true
  42#else
  43#define CSTMSEL false
  44#endif
  45
  46static int
  47nouveau_i2c_pre_xfer(struct i2c_adapter *adap)
  48{
  49        struct i2c_algo_bit_data *bit = adap->algo_data;
  50        struct nouveau_i2c_port *port = bit->data;
  51        return nouveau_i2c(port)->acquire(port, bit->timeout);
  52}
  53
  54static void
  55nouveau_i2c_post_xfer(struct i2c_adapter *adap)
  56{
  57        struct i2c_algo_bit_data *bit = adap->algo_data;
  58        struct nouveau_i2c_port *port = bit->data;
  59        return nouveau_i2c(port)->release(port);
  60}
  61
  62static void
  63nouveau_i2c_setscl(void *data, int state)
  64{
  65        struct nouveau_i2c_port *port = data;
  66        port->func->drive_scl(port, state);
  67}
  68
  69static void
  70nouveau_i2c_setsda(void *data, int state)
  71{
  72        struct nouveau_i2c_port *port = data;
  73        port->func->drive_sda(port, state);
  74}
  75
  76static int
  77nouveau_i2c_getscl(void *data)
  78{
  79        struct nouveau_i2c_port *port = data;
  80        return port->func->sense_scl(port);
  81}
  82
  83static int
  84nouveau_i2c_getsda(void *data)
  85{
  86        struct nouveau_i2c_port *port = data;
  87        return port->func->sense_sda(port);
  88}
  89
  90/******************************************************************************
  91 * base i2c "port" class implementation
  92 *****************************************************************************/
  93
  94int
  95_nouveau_i2c_port_fini(struct nouveau_object *object, bool suspend)
  96{
  97        struct nouveau_i2c_port *port = (void *)object;
  98        struct nvkm_i2c_pad *pad = nvkm_i2c_pad(port);
  99        nv_ofuncs(pad)->fini(nv_object(pad), suspend);
 100        return nouveau_object_fini(&port->base, suspend);
 101}
 102
 103void
 104_nouveau_i2c_port_dtor(struct nouveau_object *object)
 105{
 106        struct nouveau_i2c_port *port = (void *)object;
 107        i2c_del_adapter(&port->adapter);
 108        nouveau_object_destroy(&port->base);
 109}
 110
 111int
 112nouveau_i2c_port_create_(struct nouveau_object *parent,
 113                         struct nouveau_object *engine,
 114                         struct nouveau_oclass *oclass, u8 index,
 115                         const struct i2c_algorithm *algo,
 116                         const struct nouveau_i2c_func *func,
 117                         int size, void **pobject)
 118{
 119        struct nouveau_device *device = nv_device(engine);
 120        struct nouveau_i2c *i2c = (void *)engine;
 121        struct nouveau_i2c_port *port;
 122        int ret;
 123
 124        ret = nouveau_object_create_(parent, engine, oclass, 0, size, pobject);
 125        port = *pobject;
 126        if (ret)
 127                return ret;
 128
 129        snprintf(port->adapter.name, sizeof(port->adapter.name),
 130                 "nouveau-%s-%d", device->name, index);
 131        port->adapter.owner = THIS_MODULE;
 132        port->adapter.dev.parent = nv_device_base(device);
 133        port->index = index;
 134        port->aux = -1;
 135        port->func = func;
 136        mutex_init(&port->mutex);
 137
 138        if ( algo == &nouveau_i2c_bit_algo &&
 139            !nouveau_boolopt(device->cfgopt, "NvI2C", CSTMSEL)) {
 140                struct i2c_algo_bit_data *bit;
 141
 142                bit = kzalloc(sizeof(*bit), GFP_KERNEL);
 143                if (!bit)
 144                        return -ENOMEM;
 145
 146                bit->udelay = 10;
 147                bit->timeout = usecs_to_jiffies(2200);
 148                bit->data = port;
 149                bit->pre_xfer = nouveau_i2c_pre_xfer;
 150                bit->post_xfer = nouveau_i2c_post_xfer;
 151                bit->setsda = nouveau_i2c_setsda;
 152                bit->setscl = nouveau_i2c_setscl;
 153                bit->getsda = nouveau_i2c_getsda;
 154                bit->getscl = nouveau_i2c_getscl;
 155
 156                port->adapter.algo_data = bit;
 157                ret = i2c_bit_add_bus(&port->adapter);
 158        } else {
 159                port->adapter.algo_data = port;
 160                port->adapter.algo = algo;
 161                ret = i2c_add_adapter(&port->adapter);
 162        }
 163
 164        if (ret == 0)
 165                list_add_tail(&port->head, &i2c->ports);
 166        return ret;
 167}
 168
 169/******************************************************************************
 170 * base i2c subdev class implementation
 171 *****************************************************************************/
 172
 173static struct nouveau_i2c_port *
 174nouveau_i2c_find(struct nouveau_i2c *i2c, u8 index)
 175{
 176        struct nouveau_bios *bios = nouveau_bios(i2c);
 177        struct nouveau_i2c_port *port;
 178
 179        if (index == NV_I2C_DEFAULT(0) ||
 180            index == NV_I2C_DEFAULT(1)) {
 181                u8  ver, hdr, cnt, len;
 182                u16 i2c = dcb_i2c_table(bios, &ver, &hdr, &cnt, &len);
 183                if (i2c && ver >= 0x30) {
 184                        u8 auxidx = nv_ro08(bios, i2c + 4);
 185                        if (index == NV_I2C_DEFAULT(0))
 186                                index = (auxidx & 0x0f) >> 0;
 187                        else
 188                                index = (auxidx & 0xf0) >> 4;
 189                } else {
 190                        index = 2;
 191                }
 192        }
 193
 194        list_for_each_entry(port, &i2c->ports, head) {
 195                if (port->index == index)
 196                        return port;
 197        }
 198
 199        return NULL;
 200}
 201
 202static struct nouveau_i2c_port *
 203nouveau_i2c_find_type(struct nouveau_i2c *i2c, u16 type)
 204{
 205        struct nouveau_i2c_port *port;
 206
 207        list_for_each_entry(port, &i2c->ports, head) {
 208                if (nv_hclass(port) == type)
 209                        return port;
 210        }
 211
 212        return NULL;
 213}
 214
 215static void
 216nouveau_i2c_release_pad(struct nouveau_i2c_port *port)
 217{
 218        struct nvkm_i2c_pad *pad = nvkm_i2c_pad(port);
 219        struct nouveau_i2c *i2c = nouveau_i2c(port);
 220
 221        if (atomic_dec_and_test(&nv_object(pad)->usecount)) {
 222                nv_ofuncs(pad)->fini(nv_object(pad), false);
 223                wake_up_all(&i2c->wait);
 224        }
 225}
 226
 227static int
 228nouveau_i2c_try_acquire_pad(struct nouveau_i2c_port *port)
 229{
 230        struct nvkm_i2c_pad *pad = nvkm_i2c_pad(port);
 231
 232        if (atomic_add_return(1, &nv_object(pad)->usecount) != 1) {
 233                struct nouveau_object *owner = (void *)pad->port;
 234                do {
 235                        if (owner == (void *)port)
 236                                return 0;
 237                        owner = owner->parent;
 238                } while(owner);
 239                nouveau_i2c_release_pad(port);
 240                return -EBUSY;
 241        }
 242
 243        pad->next = port;
 244        nv_ofuncs(pad)->init(nv_object(pad));
 245        return 0;
 246}
 247
 248static int
 249nouveau_i2c_acquire_pad(struct nouveau_i2c_port *port, unsigned long timeout)
 250{
 251        struct nouveau_i2c *i2c = nouveau_i2c(port);
 252
 253        if (timeout) {
 254                if (wait_event_timeout(i2c->wait,
 255                                       nouveau_i2c_try_acquire_pad(port) == 0,
 256                                       timeout) == 0)
 257                        return -EBUSY;
 258        } else {
 259                wait_event(i2c->wait, nouveau_i2c_try_acquire_pad(port) == 0);
 260        }
 261
 262        return 0;
 263}
 264
 265static void
 266nouveau_i2c_release(struct nouveau_i2c_port *port)
 267__releases(pad->mutex)
 268{
 269        nouveau_i2c(port)->release_pad(port);
 270        mutex_unlock(&port->mutex);
 271}
 272
 273static int
 274nouveau_i2c_acquire(struct nouveau_i2c_port *port, unsigned long timeout)
 275__acquires(pad->mutex)
 276{
 277        int ret;
 278        mutex_lock(&port->mutex);
 279        if ((ret = nouveau_i2c(port)->acquire_pad(port, timeout)))
 280                mutex_unlock(&port->mutex);
 281        return ret;
 282}
 283
 284static int
 285nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what,
 286                     struct nouveau_i2c_board_info *info,
 287                     bool (*match)(struct nouveau_i2c_port *,
 288                                   struct i2c_board_info *, void *), void *data)
 289{
 290        struct nouveau_i2c_port *port = nouveau_i2c_find(i2c, index);
 291        int i;
 292
 293        if (!port) {
 294                nv_debug(i2c, "no bus when probing %s on %d\n", what, index);
 295                return -ENODEV;
 296        }
 297
 298        nv_debug(i2c, "probing %ss on bus: %d\n", what, port->index);
 299        for (i = 0; info[i].dev.addr; i++) {
 300                u8 orig_udelay = 0;
 301
 302                if ((port->adapter.algo == &i2c_bit_algo) &&
 303                    (info[i].udelay != 0)) {
 304                        struct i2c_algo_bit_data *algo = port->adapter.algo_data;
 305                        nv_debug(i2c, "using custom udelay %d instead of %d\n",
 306                                 info[i].udelay, algo->udelay);
 307                        orig_udelay = algo->udelay;
 308                        algo->udelay = info[i].udelay;
 309                }
 310
 311                if (nv_probe_i2c(port, info[i].dev.addr) &&
 312                    (!match || match(port, &info[i].dev, data))) {
 313                        nv_info(i2c, "detected %s: %s\n", what,
 314                                info[i].dev.type);
 315                        return i;
 316                }
 317
 318                if (orig_udelay) {
 319                        struct i2c_algo_bit_data *algo = port->adapter.algo_data;
 320                        algo->udelay = orig_udelay;
 321                }
 322        }
 323
 324        nv_debug(i2c, "no devices found.\n");
 325        return -ENODEV;
 326}
 327
 328static void
 329nouveau_i2c_intr_fini(struct nvkm_event *event, int type, int index)
 330{
 331        struct nouveau_i2c *i2c = container_of(event, typeof(*i2c), event);
 332        struct nouveau_i2c_port *port = i2c->find(i2c, index);
 333        const struct nouveau_i2c_impl *impl = (void *)nv_object(i2c)->oclass;
 334        if (port && port->aux >= 0)
 335                impl->aux_mask(i2c, type, 1 << port->aux, 0);
 336}
 337
 338static void
 339nouveau_i2c_intr_init(struct nvkm_event *event, int type, int index)
 340{
 341        struct nouveau_i2c *i2c = container_of(event, typeof(*i2c), event);
 342        struct nouveau_i2c_port *port = i2c->find(i2c, index);
 343        const struct nouveau_i2c_impl *impl = (void *)nv_object(i2c)->oclass;
 344        if (port && port->aux >= 0)
 345                impl->aux_mask(i2c, type, 1 << port->aux, 1 << port->aux);
 346}
 347
 348static int
 349nouveau_i2c_intr_ctor(void *data, u32 size, struct nvkm_notify *notify)
 350{
 351        struct nvkm_i2c_ntfy_req *req = data;
 352        if (!WARN_ON(size != sizeof(*req))) {
 353                notify->size  = sizeof(struct nvkm_i2c_ntfy_rep);
 354                notify->types = req->mask;
 355                notify->index = req->port;
 356                return 0;
 357        }
 358        return -EINVAL;
 359}
 360
 361static void
 362nouveau_i2c_intr(struct nouveau_subdev *subdev)
 363{
 364        struct nouveau_i2c_impl *impl = (void *)nv_oclass(subdev);
 365        struct nouveau_i2c *i2c = nouveau_i2c(subdev);
 366        struct nouveau_i2c_port *port;
 367        u32 hi, lo, rq, tx, e;
 368
 369        if (impl->aux_stat) {
 370                impl->aux_stat(i2c, &hi, &lo, &rq, &tx);
 371                if (hi || lo || rq || tx) {
 372                        list_for_each_entry(port, &i2c->ports, head) {
 373                                if (e = 0, port->aux < 0)
 374                                        continue;
 375
 376                                if (hi & (1 << port->aux)) e |= NVKM_I2C_PLUG;
 377                                if (lo & (1 << port->aux)) e |= NVKM_I2C_UNPLUG;
 378                                if (rq & (1 << port->aux)) e |= NVKM_I2C_IRQ;
 379                                if (tx & (1 << port->aux)) e |= NVKM_I2C_DONE;
 380                                if (e) {
 381                                        struct nvkm_i2c_ntfy_rep rep = {
 382                                                .mask = e,
 383                                        };
 384                                        nvkm_event_send(&i2c->event, rep.mask,
 385                                                        port->index, &rep,
 386                                                        sizeof(rep));
 387                                }
 388                        }
 389                }
 390        }
 391}
 392
 393static const struct nvkm_event_func
 394nouveau_i2c_intr_func = {
 395        .ctor = nouveau_i2c_intr_ctor,
 396        .init = nouveau_i2c_intr_init,
 397        .fini = nouveau_i2c_intr_fini,
 398};
 399
 400int
 401_nouveau_i2c_fini(struct nouveau_object *object, bool suspend)
 402{
 403        struct nouveau_i2c_impl *impl = (void *)nv_oclass(object);
 404        struct nouveau_i2c *i2c = (void *)object;
 405        struct nouveau_i2c_port *port;
 406        u32 mask;
 407        int ret;
 408
 409        list_for_each_entry(port, &i2c->ports, head) {
 410                ret = nv_ofuncs(port)->fini(nv_object(port), suspend);
 411                if (ret && suspend)
 412                        goto fail;
 413        }
 414
 415        if ((mask = (1 << impl->aux) - 1), impl->aux_stat) {
 416                impl->aux_mask(i2c, NVKM_I2C_ANY, mask, 0);
 417                impl->aux_stat(i2c, &mask, &mask, &mask, &mask);
 418        }
 419
 420        return nouveau_subdev_fini(&i2c->base, suspend);
 421fail:
 422        list_for_each_entry_continue_reverse(port, &i2c->ports, head) {
 423                nv_ofuncs(port)->init(nv_object(port));
 424        }
 425
 426        return ret;
 427}
 428
 429int
 430_nouveau_i2c_init(struct nouveau_object *object)
 431{
 432        struct nouveau_i2c *i2c = (void *)object;
 433        struct nouveau_i2c_port *port;
 434        int ret;
 435
 436        ret = nouveau_subdev_init(&i2c->base);
 437        if (ret == 0) {
 438                list_for_each_entry(port, &i2c->ports, head) {
 439                        ret = nv_ofuncs(port)->init(nv_object(port));
 440                        if (ret)
 441                                goto fail;
 442                }
 443        }
 444
 445        return ret;
 446fail:
 447        list_for_each_entry_continue_reverse(port, &i2c->ports, head) {
 448                nv_ofuncs(port)->fini(nv_object(port), false);
 449        }
 450
 451        return ret;
 452}
 453
 454void
 455_nouveau_i2c_dtor(struct nouveau_object *object)
 456{
 457        struct nouveau_i2c *i2c = (void *)object;
 458        struct nouveau_i2c_port *port, *temp;
 459
 460        nvkm_event_fini(&i2c->event);
 461
 462        list_for_each_entry_safe(port, temp, &i2c->ports, head) {
 463                nouveau_object_ref(NULL, (struct nouveau_object **)&port);
 464        }
 465
 466        nouveau_subdev_destroy(&i2c->base);
 467}
 468
 469static struct nouveau_oclass *
 470nouveau_i2c_extdev_sclass[] = {
 471        nouveau_anx9805_sclass,
 472};
 473
 474int
 475nouveau_i2c_create_(struct nouveau_object *parent,
 476                    struct nouveau_object *engine,
 477                    struct nouveau_oclass *oclass,
 478                    int length, void **pobject)
 479{
 480        const struct nouveau_i2c_impl *impl = (void *)oclass;
 481        struct nouveau_bios *bios = nouveau_bios(parent);
 482        struct nouveau_i2c *i2c;
 483        struct nouveau_object *object;
 484        struct dcb_i2c_entry info;
 485        int ret, i, j, index = -1, pad;
 486        struct dcb_output outp;
 487        u8  ver, hdr;
 488        u32 data;
 489
 490        ret = nouveau_subdev_create(parent, engine, oclass, 0,
 491                                    "I2C", "i2c", &i2c);
 492        *pobject = nv_object(i2c);
 493        if (ret)
 494                return ret;
 495
 496        nv_subdev(i2c)->intr = nouveau_i2c_intr;
 497        i2c->find = nouveau_i2c_find;
 498        i2c->find_type = nouveau_i2c_find_type;
 499        i2c->acquire_pad = nouveau_i2c_acquire_pad;
 500        i2c->release_pad = nouveau_i2c_release_pad;
 501        i2c->acquire = nouveau_i2c_acquire;
 502        i2c->release = nouveau_i2c_release;
 503        i2c->identify = nouveau_i2c_identify;
 504        init_waitqueue_head(&i2c->wait);
 505        INIT_LIST_HEAD(&i2c->ports);
 506
 507        while (!dcb_i2c_parse(bios, ++index, &info)) {
 508                if (info.type == DCB_I2C_UNUSED)
 509                        continue;
 510
 511                if (info.share != DCB_I2C_UNUSED) {
 512                        if (info.type == DCB_I2C_NVIO_AUX)
 513                                pad = info.drive;
 514                        else
 515                                pad = info.share;
 516                        oclass = impl->pad_s;
 517                } else {
 518                        pad = 0x100 + info.drive;
 519                        oclass = impl->pad_x;
 520                }
 521
 522                ret = nouveau_object_ctor(NULL, *pobject, oclass,
 523                                          NULL, pad, &parent);
 524                if (ret < 0)
 525                        continue;
 526
 527                oclass = impl->sclass;
 528                do {
 529                        ret = -EINVAL;
 530                        if (oclass->handle == info.type) {
 531                                ret = nouveau_object_ctor(parent, *pobject,
 532                                                          oclass, &info,
 533                                                          index, &object);
 534                        }
 535                } while (ret && (++oclass)->handle);
 536
 537                nouveau_object_ref(NULL, &parent);
 538        }
 539
 540        /* in addition to the busses specified in the i2c table, there
 541         * may be ddc/aux channels hiding behind external tmds/dp/etc
 542         * transmitters.
 543         */
 544        index = ((index + 0x0f) / 0x10) * 0x10;
 545        i = -1;
 546        while ((data = dcb_outp_parse(bios, ++i, &ver, &hdr, &outp))) {
 547                if (!outp.location || !outp.extdev)
 548                        continue;
 549
 550                switch (outp.type) {
 551                case DCB_OUTPUT_TMDS:
 552                        info.type = NV_I2C_TYPE_EXTDDC(outp.extdev);
 553                        break;
 554                case DCB_OUTPUT_DP:
 555                        info.type = NV_I2C_TYPE_EXTAUX(outp.extdev);
 556                        break;
 557                default:
 558                        continue;
 559                }
 560
 561                ret = -ENODEV;
 562                j = -1;
 563                while (ret && ++j < ARRAY_SIZE(nouveau_i2c_extdev_sclass)) {
 564                        parent = nv_object(i2c->find(i2c, outp.i2c_index));
 565                        oclass = nouveau_i2c_extdev_sclass[j];
 566                        do {
 567                                if (oclass->handle != info.type)
 568                                        continue;
 569                                ret = nouveau_object_ctor(parent, *pobject,
 570                                                          oclass, NULL,
 571                                                          index++, &object);
 572                        } while (ret && (++oclass)->handle);
 573                }
 574        }
 575
 576        ret = nvkm_event_init(&nouveau_i2c_intr_func, 4, index, &i2c->event);
 577        if (ret)
 578                return ret;
 579
 580        return 0;
 581}
 582
 583int
 584_nouveau_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 585                  struct nouveau_oclass *oclass, void *data, u32 size,
 586                  struct nouveau_object **pobject)
 587{
 588        struct nouveau_i2c *i2c;
 589        int ret;
 590
 591        ret = nouveau_i2c_create(parent, engine, oclass, &i2c);
 592        *pobject = nv_object(i2c);
 593        if (ret)
 594                return ret;
 595
 596        return 0;
 597}
 598