linux/drivers/staging/gma500/psb_intel_sdvo.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2006-2007 Intel Corporation
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms and conditions of the GNU General Public License,
   6 * version 2, as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope it will be useful, but WITHOUT
   9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  11 * more details.
  12 *
  13 * You should have received a copy of the GNU General Public License along with
  14 * this program; if not, write to the Free Software Foundation, Inc.,
  15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  16 *
  17 * Authors:
  18 *      Eric Anholt <eric@anholt.net>
  19 */
  20
  21#include <linux/i2c.h>
  22#include <linux/delay.h>
  23/* #include <drm/drm_crtc.h> */
  24#include <drm/drmP.h>
  25#include "psb_drv.h"
  26#include "psb_intel_drv.h"
  27#include "psb_intel_reg.h"
  28#include "psb_intel_sdvo_regs.h"
  29
  30struct psb_intel_sdvo_priv {
  31        struct psb_intel_i2c_chan *i2c_bus;
  32        int slaveaddr;
  33        int output_device;
  34
  35        u16 active_outputs;
  36
  37        struct psb_intel_sdvo_caps caps;
  38        int pixel_clock_min, pixel_clock_max;
  39
  40        int save_sdvo_mult;
  41        u16 save_active_outputs;
  42        struct psb_intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
  43        struct psb_intel_sdvo_dtd save_output_dtd[16];
  44        u32 save_SDVOX;
  45        u8 in_out_map[4];
  46
  47        u8 by_input_wiring;
  48        u32 active_device;
  49};
  50
  51/**
  52 * Writes the SDVOB or SDVOC with the given value, but always writes both
  53 * SDVOB and SDVOC to work around apparent hardware issues (according to
  54 * comments in the BIOS).
  55 */
  56void psb_intel_sdvo_write_sdvox(struct psb_intel_output *psb_intel_output,
  57                                u32 val)
  58{
  59        struct drm_device *dev = psb_intel_output->base.dev;
  60        struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
  61        u32 bval = val, cval = val;
  62        int i;
  63
  64        if (sdvo_priv->output_device == SDVOB)
  65                cval = REG_READ(SDVOC);
  66        else
  67                bval = REG_READ(SDVOB);
  68        /*
  69         * Write the registers twice for luck. Sometimes,
  70         * writing them only once doesn't appear to 'stick'.
  71         * The BIOS does this too. Yay, magic
  72         */
  73        for (i = 0; i < 2; i++) {
  74                REG_WRITE(SDVOB, bval);
  75                REG_READ(SDVOB);
  76                REG_WRITE(SDVOC, cval);
  77                REG_READ(SDVOC);
  78        }
  79}
  80
  81static bool psb_intel_sdvo_read_byte(
  82                                struct psb_intel_output *psb_intel_output,
  83                                u8 addr, u8 *ch)
  84{
  85        struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
  86        u8 out_buf[2];
  87        u8 buf[2];
  88        int ret;
  89
  90        struct i2c_msg msgs[] = {
  91                {
  92                 .addr = sdvo_priv->i2c_bus->slave_addr,
  93                 .flags = 0,
  94                 .len = 1,
  95                 .buf = out_buf,
  96                 },
  97                {
  98                 .addr = sdvo_priv->i2c_bus->slave_addr,
  99                 .flags = I2C_M_RD,
 100                 .len = 1,
 101                 .buf = buf,
 102                 }
 103        };
 104
 105        out_buf[0] = addr;
 106        out_buf[1] = 0;
 107
 108        ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2);
 109        if (ret == 2) {
 110                *ch = buf[0];
 111                return true;
 112        }
 113
 114        return false;
 115}
 116
 117static bool psb_intel_sdvo_write_byte(
 118                        struct psb_intel_output *psb_intel_output,
 119                        int addr, u8 ch)
 120{
 121        u8 out_buf[2];
 122        struct i2c_msg msgs[] = {
 123                {
 124                 .addr = psb_intel_output->i2c_bus->slave_addr,
 125                 .flags = 0,
 126                 .len = 2,
 127                 .buf = out_buf,
 128                 }
 129        };
 130
 131        out_buf[0] = addr;
 132        out_buf[1] = ch;
 133
 134        if (i2c_transfer(&psb_intel_output->i2c_bus->adapter, msgs, 1) == 1)
 135                return true;
 136        return false;
 137}
 138
 139#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
 140/** Mapping of command numbers to names, for debug output */
 141static const struct _sdvo_cmd_name {
 142        u8 cmd;
 143        char *name;
 144} sdvo_cmd_names[] = {
 145SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
 146            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
 147            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
 148            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
 149            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
 150            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
 151            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
 152            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
 153            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
 154            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
 155            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
 156            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
 157            SDVO_CMD_NAME_ENTRY
 158            (SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
 159            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
 160            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
 161            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
 162            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
 163            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
 164            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
 165            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
 166            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
 167            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
 168            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
 169            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
 170            SDVO_CMD_NAME_ENTRY
 171            (SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
 172            SDVO_CMD_NAME_ENTRY
 173            (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
 174            SDVO_CMD_NAME_ENTRY
 175            (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
 176            SDVO_CMD_NAME_ENTRY
 177            (SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
 178            SDVO_CMD_NAME_ENTRY
 179            (SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
 180            SDVO_CMD_NAME_ENTRY
 181            (SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
 182            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
 183            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
 184            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
 185            SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
 186            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
 187            SDVO_CMD_NAME_ENTRY
 188            (SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
 189            SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),};
 190
 191#define SDVO_NAME(dev_priv) \
 192                 ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
 193#define SDVO_PRIV(output)   ((struct psb_intel_sdvo_priv *) (output)->dev_priv)
 194
 195static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output,
 196                                     u8 cmd,
 197                                     void *args,
 198                                     int args_len)
 199{
 200        struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
 201        int i;
 202
 203        if (0) {
 204                printk(KERN_DEBUG "%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
 205                for (i = 0; i < args_len; i++)
 206                        printk(KERN_CONT "%02X ", ((u8 *) args)[i]);
 207                for (; i < 8; i++)
 208                        printk(KERN_CONT "   ");
 209                for (i = 0;
 210                     i <
 211                     sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]);
 212                     i++) {
 213                        if (cmd == sdvo_cmd_names[i].cmd) {
 214                                printk(KERN_CONT
 215                                        "(%s)", sdvo_cmd_names[i].name);
 216                                break;
 217                        }
 218                }
 219                if (i ==
 220                    sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]))
 221                        printk(KERN_CONT "(%02X)", cmd);
 222                printk(KERN_CONT "\n");
 223        }
 224
 225        for (i = 0; i < args_len; i++) {
 226                psb_intel_sdvo_write_byte(psb_intel_output,
 227                                        SDVO_I2C_ARG_0 - i,
 228                                        ((u8 *) args)[i]);
 229        }
 230
 231        psb_intel_sdvo_write_byte(psb_intel_output, SDVO_I2C_OPCODE, cmd);
 232}
 233
 234static const char *const cmd_status_names[] = {
 235        "Power on",
 236        "Success",
 237        "Not supported",
 238        "Invalid arg",
 239        "Pending",
 240        "Target not specified",
 241        "Scaling not supported"
 242};
 243
 244static u8 psb_intel_sdvo_read_response(
 245                                struct psb_intel_output *psb_intel_output,
 246                                void *response, int response_len)
 247{
 248        struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
 249        int i;
 250        u8 status;
 251        u8 retry = 50;
 252
 253        while (retry--) {
 254                /* Read the command response */
 255                for (i = 0; i < response_len; i++) {
 256                        psb_intel_sdvo_read_byte(psb_intel_output,
 257                                             SDVO_I2C_RETURN_0 + i,
 258                                             &((u8 *) response)[i]);
 259                }
 260
 261                /* read the return status */
 262                psb_intel_sdvo_read_byte(psb_intel_output,
 263                                         SDVO_I2C_CMD_STATUS,
 264                                         &status);
 265
 266                if (0) {
 267                        pr_debug("%s: R: ", SDVO_NAME(sdvo_priv));
 268                        for (i = 0; i < response_len; i++)
 269                                printk(KERN_CONT "%02X ", ((u8 *) response)[i]);
 270                        for (; i < 8; i++)
 271                                printk("   ");
 272                        if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
 273                                printk(KERN_CONT "(%s)",
 274                                         cmd_status_names[status]);
 275                        else
 276                                printk(KERN_CONT "(??? %d)", status);
 277                        printk(KERN_CONT "\n");
 278                }
 279
 280                if (status != SDVO_CMD_STATUS_PENDING)
 281                        return status;
 282
 283                mdelay(50);
 284        }
 285
 286        return status;
 287}
 288
 289int psb_intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
 290{
 291        if (mode->clock >= 100000)
 292                return 1;
 293        else if (mode->clock >= 50000)
 294                return 2;
 295        else
 296                return 4;
 297}
 298
 299/**
 300 * Don't check status code from this as it switches the bus back to the
 301 * SDVO chips which defeats the purpose of doing a bus switch in the first
 302 * place.
 303 */
 304void psb_intel_sdvo_set_control_bus_switch(
 305                                struct psb_intel_output *psb_intel_output,
 306                                u8 target)
 307{
 308        psb_intel_sdvo_write_cmd(psb_intel_output,
 309                                 SDVO_CMD_SET_CONTROL_BUS_SWITCH,
 310                                 &target,
 311                                 1);
 312}
 313
 314static bool psb_intel_sdvo_set_target_input(
 315                                struct psb_intel_output *psb_intel_output,
 316                                bool target_0, bool target_1)
 317{
 318        struct psb_intel_sdvo_set_target_input_args targets = { 0 };
 319        u8 status;
 320
 321        if (target_0 && target_1)
 322                return SDVO_CMD_STATUS_NOTSUPP;
 323
 324        if (target_1)
 325                targets.target_1 = 1;
 326
 327        psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_INPUT,
 328                             &targets, sizeof(targets));
 329
 330        status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
 331
 332        return status == SDVO_CMD_STATUS_SUCCESS;
 333}
 334
 335/**
 336 * Return whether each input is trained.
 337 *
 338 * This function is making an assumption about the layout of the response,
 339 * which should be checked against the docs.
 340 */
 341static bool psb_intel_sdvo_get_trained_inputs(struct psb_intel_output
 342                                          *psb_intel_output, bool *input_1,
 343                                          bool *input_2)
 344{
 345        struct psb_intel_sdvo_get_trained_inputs_response response;
 346        u8 status;
 347
 348        psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_TRAINED_INPUTS,
 349                             NULL, 0);
 350        status =
 351            psb_intel_sdvo_read_response(psb_intel_output, &response,
 352                                     sizeof(response));
 353        if (status != SDVO_CMD_STATUS_SUCCESS)
 354                return false;
 355
 356        *input_1 = response.input0_trained;
 357        *input_2 = response.input1_trained;
 358        return true;
 359}
 360
 361static bool psb_intel_sdvo_get_active_outputs(struct psb_intel_output
 362                                          *psb_intel_output, u16 *outputs)
 363{
 364        u8 status;
 365
 366        psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS,
 367                             NULL, 0);
 368        status =
 369            psb_intel_sdvo_read_response(psb_intel_output, outputs,
 370                                     sizeof(*outputs));
 371
 372        return status == SDVO_CMD_STATUS_SUCCESS;
 373}
 374
 375static bool psb_intel_sdvo_set_active_outputs(struct psb_intel_output
 376                                          *psb_intel_output, u16 outputs)
 377{
 378        u8 status;
 379
 380        psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS,
 381                             &outputs, sizeof(outputs));
 382        status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
 383        return status == SDVO_CMD_STATUS_SUCCESS;
 384}
 385
 386static bool psb_intel_sdvo_set_encoder_power_state(struct psb_intel_output
 387                                               *psb_intel_output, int mode)
 388{
 389        u8 status, state = SDVO_ENCODER_STATE_ON;
 390
 391        switch (mode) {
 392        case DRM_MODE_DPMS_ON:
 393                state = SDVO_ENCODER_STATE_ON;
 394                break;
 395        case DRM_MODE_DPMS_STANDBY:
 396                state = SDVO_ENCODER_STATE_STANDBY;
 397                break;
 398        case DRM_MODE_DPMS_SUSPEND:
 399                state = SDVO_ENCODER_STATE_SUSPEND;
 400                break;
 401        case DRM_MODE_DPMS_OFF:
 402                state = SDVO_ENCODER_STATE_OFF;
 403                break;
 404        }
 405
 406        psb_intel_sdvo_write_cmd(psb_intel_output,
 407                             SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
 408                             sizeof(state));
 409        status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
 410
 411        return status == SDVO_CMD_STATUS_SUCCESS;
 412}
 413
 414static bool psb_intel_sdvo_get_input_pixel_clock_range(struct psb_intel_output
 415                                                   *psb_intel_output,
 416                                                   int *clock_min,
 417                                                   int *clock_max)
 418{
 419        struct psb_intel_sdvo_pixel_clock_range clocks;
 420        u8 status;
 421
 422        psb_intel_sdvo_write_cmd(psb_intel_output,
 423                             SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, NULL,
 424                             0);
 425
 426        status =
 427            psb_intel_sdvo_read_response(psb_intel_output, &clocks,
 428                                     sizeof(clocks));
 429
 430        if (status != SDVO_CMD_STATUS_SUCCESS)
 431                return false;
 432
 433        /* Convert the values from units of 10 kHz to kHz. */
 434        *clock_min = clocks.min * 10;
 435        *clock_max = clocks.max * 10;
 436
 437        return true;
 438}
 439
 440static bool psb_intel_sdvo_set_target_output(
 441                                struct psb_intel_output *psb_intel_output,
 442                                u16 outputs)
 443{
 444        u8 status;
 445
 446        psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_OUTPUT,
 447                             &outputs, sizeof(outputs));
 448
 449        status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
 450        return status == SDVO_CMD_STATUS_SUCCESS;
 451}
 452
 453static bool psb_intel_sdvo_get_timing(struct psb_intel_output *psb_intel_output,
 454                                  u8 cmd, struct psb_intel_sdvo_dtd *dtd)
 455{
 456        u8 status;
 457
 458        psb_intel_sdvo_write_cmd(psb_intel_output, cmd, NULL, 0);
 459        status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part1,
 460                                          sizeof(dtd->part1));
 461        if (status != SDVO_CMD_STATUS_SUCCESS)
 462                return false;
 463
 464        psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, NULL, 0);
 465        status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part2,
 466                                          sizeof(dtd->part2));
 467        if (status != SDVO_CMD_STATUS_SUCCESS)
 468                return false;
 469
 470        return true;
 471}
 472
 473static bool psb_intel_sdvo_get_input_timing(
 474                                struct psb_intel_output *psb_intel_output,
 475                                struct psb_intel_sdvo_dtd *dtd)
 476{
 477        return psb_intel_sdvo_get_timing(psb_intel_output,
 478                                     SDVO_CMD_GET_INPUT_TIMINGS_PART1,
 479                                     dtd);
 480}
 481
 482static bool psb_intel_sdvo_set_timing(
 483                                struct psb_intel_output *psb_intel_output,
 484                                u8 cmd,
 485                                struct psb_intel_sdvo_dtd *dtd)
 486{
 487        u8 status;
 488
 489        psb_intel_sdvo_write_cmd(psb_intel_output, cmd, &dtd->part1,
 490                             sizeof(dtd->part1));
 491        status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
 492        if (status != SDVO_CMD_STATUS_SUCCESS)
 493                return false;
 494
 495        psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, &dtd->part2,
 496                             sizeof(dtd->part2));
 497        status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
 498        if (status != SDVO_CMD_STATUS_SUCCESS)
 499                return false;
 500
 501        return true;
 502}
 503
 504static bool psb_intel_sdvo_set_input_timing(
 505                                struct psb_intel_output *psb_intel_output,
 506                                struct psb_intel_sdvo_dtd *dtd)
 507{
 508        return psb_intel_sdvo_set_timing(psb_intel_output,
 509                                     SDVO_CMD_SET_INPUT_TIMINGS_PART1,
 510                                     dtd);
 511}
 512
 513static bool psb_intel_sdvo_set_output_timing(
 514                                struct psb_intel_output *psb_intel_output,
 515                                struct psb_intel_sdvo_dtd *dtd)
 516{
 517        return psb_intel_sdvo_set_timing(psb_intel_output,
 518                                     SDVO_CMD_SET_OUTPUT_TIMINGS_PART1,
 519                                     dtd);
 520}
 521
 522static int psb_intel_sdvo_get_clock_rate_mult(struct psb_intel_output
 523                                                *psb_intel_output)
 524{
 525        u8 response, status;
 526
 527        psb_intel_sdvo_write_cmd(psb_intel_output,
 528                                 SDVO_CMD_GET_CLOCK_RATE_MULT,
 529                                 NULL,
 530                                 0);
 531
 532        status = psb_intel_sdvo_read_response(psb_intel_output, &response, 1);
 533
 534        if (status != SDVO_CMD_STATUS_SUCCESS) {
 535                DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
 536                return SDVO_CLOCK_RATE_MULT_1X;
 537        } else {
 538                DRM_DEBUG("Current clock rate multiplier: %d\n", response);
 539        }
 540
 541        return response;
 542}
 543
 544static bool psb_intel_sdvo_set_clock_rate_mult(struct psb_intel_output
 545                                                *psb_intel_output, u8 val)
 546{
 547        u8 status;
 548
 549        psb_intel_sdvo_write_cmd(psb_intel_output,
 550                                SDVO_CMD_SET_CLOCK_RATE_MULT,
 551                                &val,
 552                                1);
 553
 554        status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
 555        if (status != SDVO_CMD_STATUS_SUCCESS)
 556                return false;
 557
 558        return true;
 559}
 560
 561static bool psb_sdvo_set_current_inoutmap(struct psb_intel_output *output,
 562                                          u32 in0outputmask,
 563                                          u32 in1outputmask)
 564{
 565        u8 byArgs[4];
 566        u8 status;
 567        int i;
 568        struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv;
 569
 570        /* Make all fields of the  args/ret to zero */
 571        memset(byArgs, 0, sizeof(byArgs));
 572
 573        /* Fill up the argument values; */
 574        byArgs[0] = (u8) (in0outputmask & 0xFF);
 575        byArgs[1] = (u8) ((in0outputmask >> 8) & 0xFF);
 576        byArgs[2] = (u8) (in1outputmask & 0xFF);
 577        byArgs[3] = (u8) ((in1outputmask >> 8) & 0xFF);
 578
 579
 580        /*save inoutmap arg here*/
 581        for (i = 0; i < 4; i++)
 582                sdvo_priv->in_out_map[i] = byArgs[0];
 583
 584        psb_intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, byArgs, 4);
 585        status = psb_intel_sdvo_read_response(output, NULL, 0);
 586
 587        if (status != SDVO_CMD_STATUS_SUCCESS)
 588                return false;
 589        return true;
 590}
 591
 592
 593static void psb_intel_sdvo_set_iomap(struct psb_intel_output *output)
 594{
 595        u32 dwCurrentSDVOIn0 = 0;
 596        u32 dwCurrentSDVOIn1 = 0;
 597        u32 dwDevMask = 0;
 598
 599
 600        struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv;
 601
 602        /* Please DO NOT change the following code. */
 603        /* SDVOB_IN0 or SDVOB_IN1 ==> sdvo_in0 */
 604        /* SDVOC_IN0 or SDVOC_IN1 ==> sdvo_in1 */
 605        if (sdvo_priv->by_input_wiring & (SDVOB_IN0 | SDVOC_IN0)) {
 606                switch (sdvo_priv->active_device) {
 607                case SDVO_DEVICE_LVDS:
 608                        dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1;
 609                        break;
 610                case SDVO_DEVICE_TMDS:
 611                        dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1;
 612                        break;
 613                case SDVO_DEVICE_TV:
 614                        dwDevMask =
 615                        SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 |
 616                        SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 |
 617                        SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 |
 618                        SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1;
 619                        break;
 620                case SDVO_DEVICE_CRT:
 621                        dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1;
 622                        break;
 623                }
 624                dwCurrentSDVOIn0 = (sdvo_priv->active_outputs & dwDevMask);
 625        } else if (sdvo_priv->by_input_wiring & (SDVOB_IN1 | SDVOC_IN1)) {
 626                switch (sdvo_priv->active_device) {
 627                case SDVO_DEVICE_LVDS:
 628                        dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1;
 629                        break;
 630                case SDVO_DEVICE_TMDS:
 631                        dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1;
 632                        break;
 633                case SDVO_DEVICE_TV:
 634                        dwDevMask =
 635                        SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 |
 636                        SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 |
 637                        SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 |
 638                        SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1;
 639                        break;
 640                case SDVO_DEVICE_CRT:
 641                        dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1;
 642                        break;
 643                }
 644                dwCurrentSDVOIn1 = (sdvo_priv->active_outputs & dwDevMask);
 645        }
 646
 647        psb_sdvo_set_current_inoutmap(output, dwCurrentSDVOIn0,
 648                                          dwCurrentSDVOIn1);
 649}
 650
 651
 652static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder,
 653                                  struct drm_display_mode *mode,
 654                                  struct drm_display_mode *adjusted_mode)
 655{
 656        /* Make the CRTC code factor in the SDVO pixel multiplier.  The SDVO
 657         * device will be told of the multiplier during mode_set.
 658         */
 659        adjusted_mode->clock *= psb_intel_sdvo_get_pixel_multiplier(mode);
 660        return true;
 661}
 662
 663static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
 664                                struct drm_display_mode *mode,
 665                                struct drm_display_mode *adjusted_mode)
 666{
 667        struct drm_device *dev = encoder->dev;
 668        struct drm_crtc *crtc = encoder->crtc;
 669        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 670        struct psb_intel_output *psb_intel_output =
 671                                        enc_to_psb_intel_output(encoder);
 672        struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
 673        u16 width, height;
 674        u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
 675        u16 h_sync_offset, v_sync_offset;
 676        u32 sdvox;
 677        struct psb_intel_sdvo_dtd output_dtd;
 678        int sdvo_pixel_multiply;
 679
 680        if (!mode)
 681                return;
 682
 683        psb_intel_sdvo_set_target_output(psb_intel_output, 0);
 684
 685        width = mode->crtc_hdisplay;
 686        height = mode->crtc_vdisplay;
 687
 688        /* do some mode translations */
 689        h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
 690        h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
 691
 692        v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
 693        v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
 694
 695        h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
 696        v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
 697
 698        output_dtd.part1.clock = mode->clock / 10;
 699        output_dtd.part1.h_active = width & 0xff;
 700        output_dtd.part1.h_blank = h_blank_len & 0xff;
 701        output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
 702            ((h_blank_len >> 8) & 0xf);
 703        output_dtd.part1.v_active = height & 0xff;
 704        output_dtd.part1.v_blank = v_blank_len & 0xff;
 705        output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
 706            ((v_blank_len >> 8) & 0xf);
 707
 708        output_dtd.part2.h_sync_off = h_sync_offset;
 709        output_dtd.part2.h_sync_width = h_sync_len & 0xff;
 710        output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
 711            (v_sync_len & 0xf);
 712        output_dtd.part2.sync_off_width_high =
 713            ((h_sync_offset & 0x300) >> 2) | ((h_sync_len & 0x300) >> 4) |
 714            ((v_sync_offset & 0x30) >> 2) | ((v_sync_len & 0x30) >> 4);
 715
 716        output_dtd.part2.dtd_flags = 0x18;
 717        if (mode->flags & DRM_MODE_FLAG_PHSYNC)
 718                output_dtd.part2.dtd_flags |= 0x2;
 719        if (mode->flags & DRM_MODE_FLAG_PVSYNC)
 720                output_dtd.part2.dtd_flags |= 0x4;
 721
 722        output_dtd.part2.sdvo_flags = 0;
 723        output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
 724        output_dtd.part2.reserved = 0;
 725
 726        /* Set the output timing to the screen */
 727        psb_intel_sdvo_set_target_output(psb_intel_output,
 728                                     sdvo_priv->active_outputs);
 729
 730        /* Set the input timing to the screen. Assume always input 0. */
 731        psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
 732
 733        psb_intel_sdvo_set_output_timing(psb_intel_output, &output_dtd);
 734
 735        /* We would like to use i830_sdvo_create_preferred_input_timing() to
 736         * provide the device with a timing it can support, if it supports that
 737         * feature.  However, presumably we would need to adjust the CRTC to
 738         * output the preferred timing, and we don't support that currently.
 739         */
 740        psb_intel_sdvo_set_input_timing(psb_intel_output, &output_dtd);
 741
 742        switch (psb_intel_sdvo_get_pixel_multiplier(mode)) {
 743        case 1:
 744                psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
 745                                               SDVO_CLOCK_RATE_MULT_1X);
 746                break;
 747        case 2:
 748                psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
 749                                               SDVO_CLOCK_RATE_MULT_2X);
 750                break;
 751        case 4:
 752                psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
 753                                               SDVO_CLOCK_RATE_MULT_4X);
 754                break;
 755        }
 756
 757        /* Set the SDVO control regs. */
 758        sdvox = REG_READ(sdvo_priv->output_device);
 759        switch (sdvo_priv->output_device) {
 760        case SDVOB:
 761                sdvox &= SDVOB_PRESERVE_MASK;
 762                break;
 763        case SDVOC:
 764                sdvox &= SDVOC_PRESERVE_MASK;
 765                break;
 766        }
 767        sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
 768        if (psb_intel_crtc->pipe == 1)
 769                sdvox |= SDVO_PIPE_B_SELECT;
 770
 771        sdvo_pixel_multiply = psb_intel_sdvo_get_pixel_multiplier(mode);
 772
 773        psb_intel_sdvo_write_sdvox(psb_intel_output, sdvox);
 774
 775         psb_intel_sdvo_set_iomap(psb_intel_output);
 776}
 777
 778static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
 779{
 780        struct drm_device *dev = encoder->dev;
 781        struct psb_intel_output *psb_intel_output =
 782                                        enc_to_psb_intel_output(encoder);
 783        struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
 784        u32 temp;
 785
 786        if (mode != DRM_MODE_DPMS_ON) {
 787                psb_intel_sdvo_set_active_outputs(psb_intel_output, 0);
 788                if (0)
 789                        psb_intel_sdvo_set_encoder_power_state(
 790                                                        psb_intel_output,
 791                                                        mode);
 792
 793                if (mode == DRM_MODE_DPMS_OFF) {
 794                        temp = REG_READ(sdvo_priv->output_device);
 795                        if ((temp & SDVO_ENABLE) != 0) {
 796                                psb_intel_sdvo_write_sdvox(psb_intel_output,
 797                                                       temp &
 798                                                       ~SDVO_ENABLE);
 799                        }
 800                }
 801        } else {
 802                bool input1, input2;
 803                int i;
 804                u8 status;
 805
 806                temp = REG_READ(sdvo_priv->output_device);
 807                if ((temp & SDVO_ENABLE) == 0)
 808                        psb_intel_sdvo_write_sdvox(psb_intel_output,
 809                                               temp | SDVO_ENABLE);
 810                for (i = 0; i < 2; i++)
 811                        psb_intel_wait_for_vblank(dev);
 812
 813                status =
 814                    psb_intel_sdvo_get_trained_inputs(psb_intel_output,
 815                                                        &input1,
 816                                                        &input2);
 817
 818
 819                /* Warn if the device reported failure to sync.
 820                 * A lot of SDVO devices fail to notify of sync, but it's
 821                 * a given it the status is a success, we succeeded.
 822                 */
 823                if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
 824                        DRM_DEBUG
 825                            ("First %s output reported failure to sync\n",
 826                             SDVO_NAME(sdvo_priv));
 827                }
 828
 829                if (0)
 830                        psb_intel_sdvo_set_encoder_power_state(
 831                                                        psb_intel_output,
 832                                                        mode);
 833                psb_intel_sdvo_set_active_outputs(psb_intel_output,
 834                                              sdvo_priv->active_outputs);
 835        }
 836        return;
 837}
 838
 839static void psb_intel_sdvo_save(struct drm_connector *connector)
 840{
 841        struct drm_device *dev = connector->dev;
 842        struct psb_intel_output *psb_intel_output =
 843                                        to_psb_intel_output(connector);
 844        struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
 845        /*int o;*/
 846
 847        sdvo_priv->save_sdvo_mult =
 848            psb_intel_sdvo_get_clock_rate_mult(psb_intel_output);
 849        psb_intel_sdvo_get_active_outputs(psb_intel_output,
 850                                      &sdvo_priv->save_active_outputs);
 851
 852        if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
 853                psb_intel_sdvo_set_target_input(psb_intel_output,
 854                                                true,
 855                                                false);
 856                psb_intel_sdvo_get_input_timing(psb_intel_output,
 857                                            &sdvo_priv->save_input_dtd_1);
 858        }
 859
 860        if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
 861                psb_intel_sdvo_set_target_input(psb_intel_output,
 862                                                false,
 863                                                true);
 864                psb_intel_sdvo_get_input_timing(psb_intel_output,
 865                                            &sdvo_priv->save_input_dtd_2);
 866        }
 867        sdvo_priv->save_SDVOX = REG_READ(sdvo_priv->output_device);
 868
 869        /*TODO: save the in_out_map state*/
 870}
 871
 872static void psb_intel_sdvo_restore(struct drm_connector *connector)
 873{
 874        struct drm_device *dev = connector->dev;
 875        struct psb_intel_output *psb_intel_output =
 876                                        to_psb_intel_output(connector);
 877        struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
 878        /*int o;*/
 879        int i;
 880        bool input1, input2;
 881        u8 status;
 882
 883        psb_intel_sdvo_set_active_outputs(psb_intel_output, 0);
 884
 885        if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
 886                psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
 887                psb_intel_sdvo_set_input_timing(psb_intel_output,
 888                                            &sdvo_priv->save_input_dtd_1);
 889        }
 890
 891        if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
 892                psb_intel_sdvo_set_target_input(psb_intel_output, false, true);
 893                psb_intel_sdvo_set_input_timing(psb_intel_output,
 894                                            &sdvo_priv->save_input_dtd_2);
 895        }
 896
 897        psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
 898                                       sdvo_priv->save_sdvo_mult);
 899
 900        REG_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
 901
 902        if (sdvo_priv->save_SDVOX & SDVO_ENABLE) {
 903                for (i = 0; i < 2; i++)
 904                        psb_intel_wait_for_vblank(dev);
 905                status =
 906                    psb_intel_sdvo_get_trained_inputs(psb_intel_output,
 907                                                        &input1,
 908                                                        &input2);
 909                if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
 910                        DRM_DEBUG
 911                            ("First %s output reported failure to sync\n",
 912                             SDVO_NAME(sdvo_priv));
 913        }
 914
 915        psb_intel_sdvo_set_active_outputs(psb_intel_output,
 916                                      sdvo_priv->save_active_outputs);
 917
 918        /*TODO: restore in_out_map*/
 919        psb_intel_sdvo_write_cmd(psb_intel_output,
 920                                 SDVO_CMD_SET_IN_OUT_MAP,
 921                                 sdvo_priv->in_out_map,
 922                                 4);
 923
 924        psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
 925}
 926
 927static int psb_intel_sdvo_mode_valid(struct drm_connector *connector,
 928                                 struct drm_display_mode *mode)
 929{
 930        struct psb_intel_output *psb_intel_output =
 931                                to_psb_intel_output(connector);
 932        struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
 933
 934        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 935                return MODE_NO_DBLESCAN;
 936
 937        if (sdvo_priv->pixel_clock_min > mode->clock)
 938                return MODE_CLOCK_LOW;
 939
 940        if (sdvo_priv->pixel_clock_max < mode->clock)
 941                return MODE_CLOCK_HIGH;
 942
 943        return MODE_OK;
 944}
 945
 946static bool psb_intel_sdvo_get_capabilities(
 947                                struct psb_intel_output *psb_intel_output,
 948                                struct psb_intel_sdvo_caps *caps)
 949{
 950        u8 status;
 951
 952        psb_intel_sdvo_write_cmd(psb_intel_output,
 953                                 SDVO_CMD_GET_DEVICE_CAPS,
 954                                 NULL,
 955                                 0);
 956        status = psb_intel_sdvo_read_response(psb_intel_output,
 957                                                caps,
 958                                                sizeof(*caps));
 959        if (status != SDVO_CMD_STATUS_SUCCESS)
 960                return false;
 961
 962        return true;
 963}
 964
 965struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev, int sdvoB)
 966{
 967        struct drm_connector *connector = NULL;
 968        struct psb_intel_output *iout = NULL;
 969        struct psb_intel_sdvo_priv *sdvo;
 970
 971        /* find the sdvo connector */
 972        list_for_each_entry(connector, &dev->mode_config.connector_list,
 973                            head) {
 974                iout = to_psb_intel_output(connector);
 975
 976                if (iout->type != INTEL_OUTPUT_SDVO)
 977                        continue;
 978
 979                sdvo = iout->dev_priv;
 980
 981                if (sdvo->output_device == SDVOB && sdvoB)
 982                        return connector;
 983
 984                if (sdvo->output_device == SDVOC && !sdvoB)
 985                        return connector;
 986
 987        }
 988
 989        return NULL;
 990}
 991
 992int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector)
 993{
 994        u8 response[2];
 995        u8 status;
 996        struct psb_intel_output *psb_intel_output;
 997
 998        if (!connector)
 999                return 0;
1000
1001        psb_intel_output = to_psb_intel_output(connector);
1002
1003        psb_intel_sdvo_write_cmd(psb_intel_output,
1004                                 SDVO_CMD_GET_HOT_PLUG_SUPPORT,
1005                                 NULL,
1006                                 0);
1007        status = psb_intel_sdvo_read_response(psb_intel_output,
1008                                                &response,
1009                                                2);
1010
1011        if (response[0] != 0)
1012                return 1;
1013
1014        return 0;
1015}
1016
1017void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
1018{
1019        u8 response[2];
1020        u8 status;
1021        struct psb_intel_output *psb_intel_output =
1022                                        to_psb_intel_output(connector);
1023
1024        psb_intel_sdvo_write_cmd(psb_intel_output,
1025                                 SDVO_CMD_GET_ACTIVE_HOT_PLUG,
1026                                 NULL,
1027                                 0);
1028        psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
1029
1030        if (on) {
1031                psb_intel_sdvo_write_cmd(psb_intel_output,
1032                                     SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL,
1033                                     0);
1034                status = psb_intel_sdvo_read_response(psb_intel_output,
1035                                                      &response,
1036                                                      2);
1037
1038                psb_intel_sdvo_write_cmd(psb_intel_output,
1039                                     SDVO_CMD_SET_ACTIVE_HOT_PLUG,
1040                                     &response, 2);
1041        } else {
1042                response[0] = 0;
1043                response[1] = 0;
1044                psb_intel_sdvo_write_cmd(psb_intel_output,
1045                                     SDVO_CMD_SET_ACTIVE_HOT_PLUG,
1046                                     &response, 2);
1047        }
1048
1049        psb_intel_sdvo_write_cmd(psb_intel_output,
1050                                 SDVO_CMD_GET_ACTIVE_HOT_PLUG,
1051                                 NULL,
1052                                 0);
1053        psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
1054}
1055
1056static enum drm_connector_status psb_intel_sdvo_detect(struct drm_connector
1057                                                   *connector, bool force)
1058{
1059        u8 response[2];
1060        u8 status;
1061        struct psb_intel_output *psb_intel_output =
1062                                        to_psb_intel_output(connector);
1063
1064        psb_intel_sdvo_write_cmd(psb_intel_output,
1065                                 SDVO_CMD_GET_ATTACHED_DISPLAYS,
1066                                 NULL,
1067                                 0);
1068        status = psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
1069
1070        DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
1071        if ((response[0] != 0) || (response[1] != 0))
1072                return connector_status_connected;
1073        else
1074                return connector_status_disconnected;
1075}
1076
1077static int psb_intel_sdvo_get_modes(struct drm_connector *connector)
1078{
1079        struct psb_intel_output *psb_intel_output =
1080                                        to_psb_intel_output(connector);
1081
1082        /* set the bus switch and get the modes */
1083        psb_intel_sdvo_set_control_bus_switch(psb_intel_output,
1084                                          SDVO_CONTROL_BUS_DDC2);
1085        psb_intel_ddc_get_modes(psb_intel_output);
1086
1087        if (list_empty(&connector->probed_modes))
1088                return 0;
1089        return 1;
1090}
1091
1092static void psb_intel_sdvo_destroy(struct drm_connector *connector)
1093{
1094        struct psb_intel_output *psb_intel_output =
1095                                to_psb_intel_output(connector);
1096
1097        if (psb_intel_output->i2c_bus)
1098                psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
1099        drm_sysfs_connector_remove(connector);
1100        drm_connector_cleanup(connector);
1101        kfree(psb_intel_output);
1102}
1103
1104static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = {
1105        .dpms = psb_intel_sdvo_dpms,
1106        .mode_fixup = psb_intel_sdvo_mode_fixup,
1107        .prepare = psb_intel_encoder_prepare,
1108        .mode_set = psb_intel_sdvo_mode_set,
1109        .commit = psb_intel_encoder_commit,
1110};
1111
1112static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = {
1113        .dpms = drm_helper_connector_dpms,
1114        .save = psb_intel_sdvo_save,
1115        .restore = psb_intel_sdvo_restore,
1116        .detect = psb_intel_sdvo_detect,
1117        .fill_modes = drm_helper_probe_single_connector_modes,
1118        .destroy = psb_intel_sdvo_destroy,
1119};
1120
1121static const struct drm_connector_helper_funcs
1122                                psb_intel_sdvo_connector_helper_funcs = {
1123        .get_modes = psb_intel_sdvo_get_modes,
1124        .mode_valid = psb_intel_sdvo_mode_valid,
1125        .best_encoder = psb_intel_best_encoder,
1126};
1127
1128void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder)
1129{
1130        drm_encoder_cleanup(encoder);
1131}
1132
1133static const struct drm_encoder_funcs psb_intel_sdvo_enc_funcs = {
1134        .destroy = psb_intel_sdvo_enc_destroy,
1135};
1136
1137
1138void psb_intel_sdvo_init(struct drm_device *dev, int output_device)
1139{
1140        struct drm_connector *connector;
1141        struct psb_intel_output *psb_intel_output;
1142        struct psb_intel_sdvo_priv *sdvo_priv;
1143        struct psb_intel_i2c_chan *i2cbus = NULL;
1144        int connector_type;
1145        u8 ch[0x40];
1146        int i;
1147        int encoder_type, output_id;
1148
1149        psb_intel_output =
1150            kcalloc(sizeof(struct psb_intel_output) +
1151                    sizeof(struct psb_intel_sdvo_priv), 1, GFP_KERNEL);
1152        if (!psb_intel_output)
1153                return;
1154
1155        connector = &psb_intel_output->base;
1156
1157        drm_connector_init(dev, connector, &psb_intel_sdvo_connector_funcs,
1158                           DRM_MODE_CONNECTOR_Unknown);
1159        drm_connector_helper_add(connector,
1160                                 &psb_intel_sdvo_connector_helper_funcs);
1161        sdvo_priv = (struct psb_intel_sdvo_priv *) (psb_intel_output + 1);
1162        psb_intel_output->type = INTEL_OUTPUT_SDVO;
1163
1164        connector->interlace_allowed = 0;
1165        connector->doublescan_allowed = 0;
1166
1167        /* setup the DDC bus. */
1168        if (output_device == SDVOB)
1169                i2cbus =
1170                    psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
1171        else
1172                i2cbus =
1173                    psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
1174
1175        if (!i2cbus)
1176                goto err_connector;
1177
1178        sdvo_priv->i2c_bus = i2cbus;
1179
1180        if (output_device == SDVOB) {
1181                output_id = 1;
1182                sdvo_priv->by_input_wiring = SDVOB_IN0;
1183                sdvo_priv->i2c_bus->slave_addr = 0x38;
1184        } else {
1185                output_id = 2;
1186                sdvo_priv->i2c_bus->slave_addr = 0x39;
1187        }
1188
1189        sdvo_priv->output_device = output_device;
1190        psb_intel_output->i2c_bus = i2cbus;
1191        psb_intel_output->dev_priv = sdvo_priv;
1192
1193
1194        /* Read the regs to test if we can talk to the device */
1195        for (i = 0; i < 0x40; i++) {
1196                if (!psb_intel_sdvo_read_byte(psb_intel_output, i, &ch[i])) {
1197                        dev_dbg(dev->dev, "No SDVO device found on SDVO%c\n",
1198                                  output_device == SDVOB ? 'B' : 'C');
1199                        goto err_i2c;
1200                }
1201        }
1202
1203        psb_intel_sdvo_get_capabilities(psb_intel_output, &sdvo_priv->caps);
1204
1205        memset(&sdvo_priv->active_outputs, 0,
1206               sizeof(sdvo_priv->active_outputs));
1207
1208        /* TODO, CVBS, SVID, YPRPB & SCART outputs. */
1209        if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) {
1210                sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
1211                sdvo_priv->active_device = SDVO_DEVICE_CRT;
1212                connector->display_info.subpixel_order =
1213                    SubPixelHorizontalRGB;
1214                encoder_type = DRM_MODE_ENCODER_DAC;
1215                connector_type = DRM_MODE_CONNECTOR_VGA;
1216        } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) {
1217                sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
1218                sdvo_priv->active_outputs = SDVO_DEVICE_CRT;
1219                connector->display_info.subpixel_order =
1220                    SubPixelHorizontalRGB;
1221                encoder_type = DRM_MODE_ENCODER_DAC;
1222                connector_type = DRM_MODE_CONNECTOR_VGA;
1223        } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) {
1224                sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
1225                sdvo_priv->active_device = SDVO_DEVICE_TMDS;
1226                connector->display_info.subpixel_order =
1227                    SubPixelHorizontalRGB;
1228                encoder_type = DRM_MODE_ENCODER_TMDS;
1229                connector_type = DRM_MODE_CONNECTOR_DVID;
1230        } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1) {
1231                sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
1232                sdvo_priv->active_device = SDVO_DEVICE_TMDS;
1233                connector->display_info.subpixel_order =
1234                    SubPixelHorizontalRGB;
1235                encoder_type = DRM_MODE_ENCODER_TMDS;
1236                connector_type = DRM_MODE_CONNECTOR_DVID;
1237        } else {
1238                unsigned char bytes[2];
1239
1240                memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
1241                dev_dbg(dev->dev, "%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
1242                     SDVO_NAME(sdvo_priv), bytes[0], bytes[1]);
1243                goto err_i2c;
1244        }
1245
1246        drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_sdvo_enc_funcs,
1247                         encoder_type);
1248        drm_encoder_helper_add(&psb_intel_output->enc,
1249                               &psb_intel_sdvo_helper_funcs);
1250        connector->connector_type = connector_type;
1251
1252        drm_mode_connector_attach_encoder(&psb_intel_output->base,
1253                                          &psb_intel_output->enc);
1254        drm_sysfs_connector_add(connector);
1255
1256        /* Set the input timing to the screen. Assume always input 0. */
1257        psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
1258
1259        psb_intel_sdvo_get_input_pixel_clock_range(psb_intel_output,
1260                                               &sdvo_priv->pixel_clock_min,
1261                                               &sdvo_priv->
1262                                               pixel_clock_max);
1263
1264
1265        dev_dbg(dev->dev, "%s device VID/DID: %02X:%02X.%02X, "
1266                  "clock range %dMHz - %dMHz, "
1267                  "input 1: %c, input 2: %c, "
1268                  "output 1: %c, output 2: %c\n",
1269                  SDVO_NAME(sdvo_priv),
1270                  sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
1271                  sdvo_priv->caps.device_rev_id,
1272                  sdvo_priv->pixel_clock_min / 1000,
1273                  sdvo_priv->pixel_clock_max / 1000,
1274                  (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
1275                  (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
1276                  /* check currently supported outputs */
1277                  sdvo_priv->caps.output_flags &
1278                  (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
1279                  sdvo_priv->caps.output_flags &
1280                  (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
1281
1282        psb_intel_output->ddc_bus = i2cbus;
1283
1284        return;
1285
1286err_i2c:
1287        psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
1288err_connector:
1289        drm_connector_cleanup(connector);
1290        kfree(psb_intel_output);
1291
1292        return;
1293}
1294