linux/drivers/gpu/drm/ast/ast_mode.c
<<
>>
Prefs
   1/*
   2 * Copyright 2012 Red Hat Inc.
   3 * Parts based on xf86-video-ast
   4 * Copyright (c) 2005 ASPEED Technology Inc.
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a
   7 * copy of this software and associated documentation files (the
   8 * "Software"), to deal in the Software without restriction, including
   9 * without limitation the rights to use, copy, modify, merge, publish,
  10 * distribute, sub license, and/or sell copies of the Software, and to
  11 * permit persons to whom the Software is furnished to do so, subject to
  12 * the following conditions:
  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 NON-INFRINGEMENT. IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * The above copyright notice and this permission notice (including the
  23 * next paragraph) shall be included in all copies or substantial portions
  24 * of the Software.
  25 *
  26 */
  27/*
  28 * Authors: Dave Airlie <airlied@redhat.com>
  29 */
  30
  31#include <linux/export.h>
  32#include <linux/pci.h>
  33
  34#include <drm/drm_atomic.h>
  35#include <drm/drm_atomic_helper.h>
  36#include <drm/drm_atomic_state_helper.h>
  37#include <drm/drm_crtc.h>
  38#include <drm/drm_crtc_helper.h>
  39#include <drm/drm_fourcc.h>
  40#include <drm/drm_gem_framebuffer_helper.h>
  41#include <drm/drm_gem_vram_helper.h>
  42#include <drm/drm_plane_helper.h>
  43#include <drm/drm_probe_helper.h>
  44#include <drm/drm_simple_kms_helper.h>
  45
  46#include "ast_drv.h"
  47#include "ast_tables.h"
  48
  49static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev);
  50static void ast_i2c_destroy(struct ast_i2c_chan *i2c);
  51
  52static inline void ast_load_palette_index(struct ast_private *ast,
  53                                     u8 index, u8 red, u8 green,
  54                                     u8 blue)
  55{
  56        ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index);
  57        ast_io_read8(ast, AST_IO_SEQ_PORT);
  58        ast_io_write8(ast, AST_IO_DAC_DATA, red);
  59        ast_io_read8(ast, AST_IO_SEQ_PORT);
  60        ast_io_write8(ast, AST_IO_DAC_DATA, green);
  61        ast_io_read8(ast, AST_IO_SEQ_PORT);
  62        ast_io_write8(ast, AST_IO_DAC_DATA, blue);
  63        ast_io_read8(ast, AST_IO_SEQ_PORT);
  64}
  65
  66static void ast_crtc_load_lut(struct ast_private *ast, struct drm_crtc *crtc)
  67{
  68        u16 *r, *g, *b;
  69        int i;
  70
  71        if (!crtc->enabled)
  72                return;
  73
  74        r = crtc->gamma_store;
  75        g = r + crtc->gamma_size;
  76        b = g + crtc->gamma_size;
  77
  78        for (i = 0; i < 256; i++)
  79                ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
  80}
  81
  82static bool ast_get_vbios_mode_info(const struct drm_format_info *format,
  83                                    const struct drm_display_mode *mode,
  84                                    struct drm_display_mode *adjusted_mode,
  85                                    struct ast_vbios_mode_info *vbios_mode)
  86{
  87        u32 refresh_rate_index = 0, refresh_rate;
  88        const struct ast_vbios_enhtable *best = NULL;
  89        u32 hborder, vborder;
  90        bool check_sync;
  91
  92        switch (format->cpp[0] * 8) {
  93        case 8:
  94                vbios_mode->std_table = &vbios_stdtable[VGAModeIndex];
  95                break;
  96        case 16:
  97                vbios_mode->std_table = &vbios_stdtable[HiCModeIndex];
  98                break;
  99        case 24:
 100        case 32:
 101                vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex];
 102                break;
 103        default:
 104                return false;
 105        }
 106
 107        switch (mode->crtc_hdisplay) {
 108        case 640:
 109                vbios_mode->enh_table = &res_640x480[refresh_rate_index];
 110                break;
 111        case 800:
 112                vbios_mode->enh_table = &res_800x600[refresh_rate_index];
 113                break;
 114        case 1024:
 115                vbios_mode->enh_table = &res_1024x768[refresh_rate_index];
 116                break;
 117        case 1280:
 118                if (mode->crtc_vdisplay == 800)
 119                        vbios_mode->enh_table = &res_1280x800[refresh_rate_index];
 120                else
 121                        vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
 122                break;
 123        case 1360:
 124                vbios_mode->enh_table = &res_1360x768[refresh_rate_index];
 125                break;
 126        case 1440:
 127                vbios_mode->enh_table = &res_1440x900[refresh_rate_index];
 128                break;
 129        case 1600:
 130                if (mode->crtc_vdisplay == 900)
 131                        vbios_mode->enh_table = &res_1600x900[refresh_rate_index];
 132                else
 133                        vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
 134                break;
 135        case 1680:
 136                vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];
 137                break;
 138        case 1920:
 139                if (mode->crtc_vdisplay == 1080)
 140                        vbios_mode->enh_table = &res_1920x1080[refresh_rate_index];
 141                else
 142                        vbios_mode->enh_table = &res_1920x1200[refresh_rate_index];
 143                break;
 144        default:
 145                return false;
 146        }
 147
 148        refresh_rate = drm_mode_vrefresh(mode);
 149        check_sync = vbios_mode->enh_table->flags & WideScreenMode;
 150
 151        while (1) {
 152                const struct ast_vbios_enhtable *loop = vbios_mode->enh_table;
 153
 154                while (loop->refresh_rate != 0xff) {
 155                        if ((check_sync) &&
 156                            (((mode->flags & DRM_MODE_FLAG_NVSYNC)  &&
 157                              (loop->flags & PVSync))  ||
 158                             ((mode->flags & DRM_MODE_FLAG_PVSYNC)  &&
 159                              (loop->flags & NVSync))  ||
 160                             ((mode->flags & DRM_MODE_FLAG_NHSYNC)  &&
 161                              (loop->flags & PHSync))  ||
 162                             ((mode->flags & DRM_MODE_FLAG_PHSYNC)  &&
 163                              (loop->flags & NHSync)))) {
 164                                loop++;
 165                                continue;
 166                        }
 167                        if (loop->refresh_rate <= refresh_rate
 168                            && (!best || loop->refresh_rate > best->refresh_rate))
 169                                best = loop;
 170                        loop++;
 171                }
 172                if (best || !check_sync)
 173                        break;
 174                check_sync = 0;
 175        }
 176
 177        if (best)
 178                vbios_mode->enh_table = best;
 179
 180        hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0;
 181        vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0;
 182
 183        adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht;
 184        adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder;
 185        adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder;
 186        adjusted_mode->crtc_hsync_start = vbios_mode->enh_table->hde + hborder +
 187                vbios_mode->enh_table->hfp;
 188        adjusted_mode->crtc_hsync_end = (vbios_mode->enh_table->hde + hborder +
 189                                         vbios_mode->enh_table->hfp +
 190                                         vbios_mode->enh_table->hsync);
 191
 192        adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt;
 193        adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder;
 194        adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder;
 195        adjusted_mode->crtc_vsync_start = vbios_mode->enh_table->vde + vborder +
 196                vbios_mode->enh_table->vfp;
 197        adjusted_mode->crtc_vsync_end = (vbios_mode->enh_table->vde + vborder +
 198                                         vbios_mode->enh_table->vfp +
 199                                         vbios_mode->enh_table->vsync);
 200
 201        return true;
 202}
 203
 204static void ast_set_vbios_color_reg(struct ast_private *ast,
 205                                    const struct drm_format_info *format,
 206                                    const struct ast_vbios_mode_info *vbios_mode)
 207{
 208        u32 color_index;
 209
 210        switch (format->cpp[0]) {
 211        case 1:
 212                color_index = VGAModeIndex - 1;
 213                break;
 214        case 2:
 215                color_index = HiCModeIndex;
 216                break;
 217        case 3:
 218        case 4:
 219                color_index = TrueCModeIndex;
 220                break;
 221        default:
 222                return;
 223        }
 224
 225        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4));
 226
 227        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
 228
 229        if (vbios_mode->enh_table->flags & NewModeInfo) {
 230                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
 231                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, format->cpp[0] * 8);
 232        }
 233}
 234
 235static void ast_set_vbios_mode_reg(struct ast_private *ast,
 236                                   const struct drm_display_mode *adjusted_mode,
 237                                   const struct ast_vbios_mode_info *vbios_mode)
 238{
 239        u32 refresh_rate_index, mode_id;
 240
 241        refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
 242        mode_id = vbios_mode->enh_table->mode_id;
 243
 244        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
 245        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
 246
 247        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
 248
 249        if (vbios_mode->enh_table->flags & NewModeInfo) {
 250                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
 251                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
 252                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
 253                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
 254                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
 255                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
 256        }
 257}
 258
 259static void ast_set_std_reg(struct ast_private *ast,
 260                            struct drm_display_mode *mode,
 261                            struct ast_vbios_mode_info *vbios_mode)
 262{
 263        const struct ast_vbios_stdtable *stdtable;
 264        u32 i;
 265        u8 jreg;
 266
 267        stdtable = vbios_mode->std_table;
 268
 269        jreg = stdtable->misc;
 270        ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
 271
 272        /* Set SEQ; except Screen Disable field */
 273        ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03);
 274        ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]);
 275        for (i = 1; i < 4; i++) {
 276                jreg = stdtable->seq[i];
 277                ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1) , jreg);
 278        }
 279
 280        /* Set CRTC; except base address and offset */
 281        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
 282        for (i = 0; i < 12; i++)
 283                ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
 284        for (i = 14; i < 19; i++)
 285                ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
 286        for (i = 20; i < 25; i++)
 287                ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
 288
 289        /* set AR */
 290        jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
 291        for (i = 0; i < 20; i++) {
 292                jreg = stdtable->ar[i];
 293                ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i);
 294                ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg);
 295        }
 296        ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14);
 297        ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00);
 298
 299        jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
 300        ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20);
 301
 302        /* Set GR */
 303        for (i = 0; i < 9; i++)
 304                ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]);
 305}
 306
 307static void ast_set_crtc_reg(struct ast_private *ast,
 308                             struct drm_display_mode *mode,
 309                             struct ast_vbios_mode_info *vbios_mode)
 310{
 311        u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0;
 312        u16 temp, precache = 0;
 313
 314        if ((ast->chip == AST2500) &&
 315            (vbios_mode->enh_table->flags & AST2500PreCatchCRT))
 316                precache = 40;
 317
 318        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
 319
 320        temp = (mode->crtc_htotal >> 3) - 5;
 321        if (temp & 0x100)
 322                jregAC |= 0x01; /* HT D[8] */
 323        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp);
 324
 325        temp = (mode->crtc_hdisplay >> 3) - 1;
 326        if (temp & 0x100)
 327                jregAC |= 0x04; /* HDE D[8] */
 328        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp);
 329
 330        temp = (mode->crtc_hblank_start >> 3) - 1;
 331        if (temp & 0x100)
 332                jregAC |= 0x10; /* HBS D[8] */
 333        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp);
 334
 335        temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f;
 336        if (temp & 0x20)
 337                jreg05 |= 0x80;  /* HBE D[5] */
 338        if (temp & 0x40)
 339                jregAD |= 0x01;  /* HBE D[5] */
 340        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f));
 341
 342        temp = ((mode->crtc_hsync_start-precache) >> 3) - 1;
 343        if (temp & 0x100)
 344                jregAC |= 0x40; /* HRS D[5] */
 345        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp);
 346
 347        temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f;
 348        if (temp & 0x20)
 349                jregAD |= 0x04; /* HRE D[5] */
 350        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05));
 351
 352        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC);
 353        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD);
 354
 355        /* vert timings */
 356        temp = (mode->crtc_vtotal) - 2;
 357        if (temp & 0x100)
 358                jreg07 |= 0x01;
 359        if (temp & 0x200)
 360                jreg07 |= 0x20;
 361        if (temp & 0x400)
 362                jregAE |= 0x01;
 363        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp);
 364
 365        temp = (mode->crtc_vsync_start) - 1;
 366        if (temp & 0x100)
 367                jreg07 |= 0x04;
 368        if (temp & 0x200)
 369                jreg07 |= 0x80;
 370        if (temp & 0x400)
 371                jregAE |= 0x08;
 372        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp);
 373
 374        temp = (mode->crtc_vsync_end - 1) & 0x3f;
 375        if (temp & 0x10)
 376                jregAE |= 0x20;
 377        if (temp & 0x20)
 378                jregAE |= 0x40;
 379        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf);
 380
 381        temp = mode->crtc_vdisplay - 1;
 382        if (temp & 0x100)
 383                jreg07 |= 0x02;
 384        if (temp & 0x200)
 385                jreg07 |= 0x40;
 386        if (temp & 0x400)
 387                jregAE |= 0x02;
 388        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp);
 389
 390        temp = mode->crtc_vblank_start - 1;
 391        if (temp & 0x100)
 392                jreg07 |= 0x08;
 393        if (temp & 0x200)
 394                jreg09 |= 0x20;
 395        if (temp & 0x400)
 396                jregAE |= 0x04;
 397        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp);
 398
 399        temp = mode->crtc_vblank_end - 1;
 400        if (temp & 0x100)
 401                jregAE |= 0x10;
 402        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp);
 403
 404        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07);
 405        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09);
 406        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80));
 407
 408        if (precache)
 409                ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80);
 410        else
 411                ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00);
 412
 413        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80);
 414}
 415
 416static void ast_set_offset_reg(struct ast_private *ast,
 417                               struct drm_framebuffer *fb)
 418{
 419        u16 offset;
 420
 421        offset = fb->pitches[0] >> 3;
 422        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff));
 423        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f);
 424}
 425
 426static void ast_set_dclk_reg(struct ast_private *ast,
 427                             struct drm_display_mode *mode,
 428                             struct ast_vbios_mode_info *vbios_mode)
 429{
 430        const struct ast_vbios_dclk_info *clk_info;
 431
 432        if (ast->chip == AST2500)
 433                clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index];
 434        else
 435                clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
 436
 437        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1);
 438        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2);
 439        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f,
 440                               (clk_info->param3 & 0xc0) |
 441                               ((clk_info->param3 & 0x3) << 4));
 442}
 443
 444static void ast_set_color_reg(struct ast_private *ast,
 445                              const struct drm_format_info *format)
 446{
 447        u8 jregA0 = 0, jregA3 = 0, jregA8 = 0;
 448
 449        switch (format->cpp[0] * 8) {
 450        case 8:
 451                jregA0 = 0x70;
 452                jregA3 = 0x01;
 453                jregA8 = 0x00;
 454                break;
 455        case 15:
 456        case 16:
 457                jregA0 = 0x70;
 458                jregA3 = 0x04;
 459                jregA8 = 0x02;
 460                break;
 461        case 32:
 462                jregA0 = 0x70;
 463                jregA3 = 0x08;
 464                jregA8 = 0x02;
 465                break;
 466        }
 467
 468        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0);
 469        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3);
 470        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8);
 471}
 472
 473static void ast_set_crtthd_reg(struct ast_private *ast)
 474{
 475        /* Set Threshold */
 476        if (ast->chip == AST2300 || ast->chip == AST2400 ||
 477            ast->chip == AST2500) {
 478                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78);
 479                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60);
 480        } else if (ast->chip == AST2100 ||
 481                   ast->chip == AST1100 ||
 482                   ast->chip == AST2200 ||
 483                   ast->chip == AST2150) {
 484                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f);
 485                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f);
 486        } else {
 487                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f);
 488                ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f);
 489        }
 490}
 491
 492static void ast_set_sync_reg(struct ast_private *ast,
 493                             struct drm_display_mode *mode,
 494                             struct ast_vbios_mode_info *vbios_mode)
 495{
 496        u8 jreg;
 497
 498        jreg  = ast_io_read8(ast, AST_IO_MISC_PORT_READ);
 499        jreg &= ~0xC0;
 500        if (vbios_mode->enh_table->flags & NVSync) jreg |= 0x80;
 501        if (vbios_mode->enh_table->flags & NHSync) jreg |= 0x40;
 502        ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
 503}
 504
 505static void ast_set_start_address_crt1(struct ast_private *ast,
 506                                       unsigned offset)
 507{
 508        u32 addr;
 509
 510        addr = offset >> 2;
 511        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff));
 512        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff));
 513        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff));
 514
 515}
 516
 517/*
 518 * Primary plane
 519 */
 520
 521static const uint32_t ast_primary_plane_formats[] = {
 522        DRM_FORMAT_XRGB8888,
 523        DRM_FORMAT_RGB565,
 524        DRM_FORMAT_C8,
 525};
 526
 527static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane,
 528                                                 struct drm_plane_state *state)
 529{
 530        struct drm_crtc_state *crtc_state;
 531        struct ast_crtc_state *ast_crtc_state;
 532        int ret;
 533
 534        if (!state->crtc)
 535                return 0;
 536
 537        crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc);
 538
 539        ret = drm_atomic_helper_check_plane_state(state, crtc_state,
 540                                                  DRM_PLANE_HELPER_NO_SCALING,
 541                                                  DRM_PLANE_HELPER_NO_SCALING,
 542                                                  false, true);
 543        if (ret)
 544                return ret;
 545
 546        if (!state->visible)
 547                return 0;
 548
 549        ast_crtc_state = to_ast_crtc_state(crtc_state);
 550
 551        ast_crtc_state->format = state->fb->format;
 552
 553        return 0;
 554}
 555
 556static void
 557ast_primary_plane_helper_atomic_update(struct drm_plane *plane,
 558                                       struct drm_plane_state *old_state)
 559{
 560        struct drm_device *dev = plane->dev;
 561        struct ast_private *ast = to_ast_private(dev);
 562        struct drm_plane_state *state = plane->state;
 563        struct drm_gem_vram_object *gbo;
 564        s64 gpu_addr;
 565
 566        gbo = drm_gem_vram_of_gem(state->fb->obj[0]);
 567        gpu_addr = drm_gem_vram_offset(gbo);
 568        if (drm_WARN_ON_ONCE(dev, gpu_addr < 0))
 569                return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
 570
 571        ast_set_offset_reg(ast, state->fb);
 572        ast_set_start_address_crt1(ast, (u32)gpu_addr);
 573
 574        ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00);
 575}
 576
 577static void
 578ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
 579                                        struct drm_plane_state *old_state)
 580{
 581        struct ast_private *ast = to_ast_private(plane->dev);
 582
 583        ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);
 584}
 585
 586static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = {
 587        .prepare_fb = drm_gem_vram_plane_helper_prepare_fb,
 588        .cleanup_fb = drm_gem_vram_plane_helper_cleanup_fb,
 589        .atomic_check = ast_primary_plane_helper_atomic_check,
 590        .atomic_update = ast_primary_plane_helper_atomic_update,
 591        .atomic_disable = ast_primary_plane_helper_atomic_disable,
 592};
 593
 594static const struct drm_plane_funcs ast_primary_plane_funcs = {
 595        .update_plane = drm_atomic_helper_update_plane,
 596        .disable_plane = drm_atomic_helper_disable_plane,
 597        .destroy = drm_plane_cleanup,
 598        .reset = drm_atomic_helper_plane_reset,
 599        .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 600        .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 601};
 602
 603/*
 604 * Cursor plane
 605 */
 606
 607static const uint32_t ast_cursor_plane_formats[] = {
 608        DRM_FORMAT_ARGB8888,
 609};
 610
 611static int
 612ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane,
 613                                   struct drm_plane_state *new_state)
 614{
 615        struct drm_framebuffer *fb = new_state->fb;
 616        struct drm_crtc *crtc = new_state->crtc;
 617        struct ast_private *ast;
 618        int ret;
 619
 620        if (!crtc || !fb)
 621                return 0;
 622
 623        ast = to_ast_private(plane->dev);
 624
 625        ret = ast_cursor_blit(ast, fb);
 626        if (ret)
 627                return ret;
 628
 629        return 0;
 630}
 631
 632static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane,
 633                                                struct drm_plane_state *state)
 634{
 635        struct drm_framebuffer *fb = state->fb;
 636        struct drm_crtc_state *crtc_state;
 637        int ret;
 638
 639        if (!state->crtc)
 640                return 0;
 641
 642        crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc);
 643
 644        ret = drm_atomic_helper_check_plane_state(state, crtc_state,
 645                                                  DRM_PLANE_HELPER_NO_SCALING,
 646                                                  DRM_PLANE_HELPER_NO_SCALING,
 647                                                  true, true);
 648        if (ret)
 649                return ret;
 650
 651        if (!state->visible)
 652                return 0;
 653
 654        if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT)
 655                return -EINVAL;
 656
 657        return 0;
 658}
 659
 660static void
 661ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 662                                      struct drm_plane_state *old_state)
 663{
 664        struct drm_plane_state *state = plane->state;
 665        struct drm_framebuffer *fb = state->fb;
 666        struct ast_private *ast = plane->dev->dev_private;
 667        unsigned int offset_x, offset_y;
 668
 669        offset_x = AST_MAX_HWC_WIDTH - fb->width;
 670        offset_y = AST_MAX_HWC_WIDTH - fb->height;
 671
 672        if (state->fb != old_state->fb) {
 673                /* A new cursor image was installed. */
 674                ast_cursor_page_flip(ast);
 675        }
 676
 677        ast_cursor_show(ast, state->crtc_x, state->crtc_y,
 678                        offset_x, offset_y);
 679}
 680
 681static void
 682ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,
 683                                       struct drm_plane_state *old_state)
 684{
 685        struct ast_private *ast = to_ast_private(plane->dev);
 686
 687        ast_cursor_hide(ast);
 688}
 689
 690static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = {
 691        .prepare_fb = ast_cursor_plane_helper_prepare_fb,
 692        .cleanup_fb = NULL, /* not required for cursor plane */
 693        .atomic_check = ast_cursor_plane_helper_atomic_check,
 694        .atomic_update = ast_cursor_plane_helper_atomic_update,
 695        .atomic_disable = ast_cursor_plane_helper_atomic_disable,
 696};
 697
 698static const struct drm_plane_funcs ast_cursor_plane_funcs = {
 699        .update_plane = drm_atomic_helper_update_plane,
 700        .disable_plane = drm_atomic_helper_disable_plane,
 701        .destroy = drm_plane_cleanup,
 702        .reset = drm_atomic_helper_plane_reset,
 703        .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 704        .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 705};
 706
 707/*
 708 * CRTC
 709 */
 710
 711static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
 712{
 713        struct ast_private *ast = to_ast_private(crtc->dev);
 714
 715        /* TODO: Maybe control display signal generation with
 716         *       Sync Enable (bit CR17.7).
 717         */
 718        switch (mode) {
 719        case DRM_MODE_DPMS_ON:
 720        case DRM_MODE_DPMS_STANDBY:
 721        case DRM_MODE_DPMS_SUSPEND:
 722                if (ast->tx_chip_type == AST_TX_DP501)
 723                        ast_set_dp501_video_output(crtc->dev, 1);
 724                ast_crtc_load_lut(ast, crtc);
 725                break;
 726        case DRM_MODE_DPMS_OFF:
 727                if (ast->tx_chip_type == AST_TX_DP501)
 728                        ast_set_dp501_video_output(crtc->dev, 0);
 729                break;
 730        }
 731}
 732
 733static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
 734                                        struct drm_crtc_state *state)
 735{
 736        struct ast_crtc_state *ast_state;
 737        const struct drm_format_info *format;
 738        bool succ;
 739
 740        if (!state->enable)
 741                return 0; /* no mode checks if CRTC is being disabled */
 742
 743        ast_state = to_ast_crtc_state(state);
 744
 745        format = ast_state->format;
 746        if (!format)
 747                return 0;
 748
 749        succ = ast_get_vbios_mode_info(format, &state->mode,
 750                                       &state->adjusted_mode,
 751                                       &ast_state->vbios_mode_info);
 752        if (!succ)
 753                return -EINVAL;
 754
 755        return 0;
 756}
 757
 758static void ast_crtc_helper_atomic_begin(struct drm_crtc *crtc,
 759                                         struct drm_crtc_state *old_crtc_state)
 760{
 761        struct ast_private *ast = to_ast_private(crtc->dev);
 762
 763        ast_open_key(ast);
 764}
 765
 766static void ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
 767                                         struct drm_crtc_state *old_crtc_state)
 768{
 769        struct drm_device *dev = crtc->dev;
 770        struct ast_private *ast = to_ast_private(dev);
 771        struct ast_crtc_state *ast_state;
 772        const struct drm_format_info *format;
 773        struct ast_vbios_mode_info *vbios_mode_info;
 774        struct drm_display_mode *adjusted_mode;
 775
 776        ast_state = to_ast_crtc_state(crtc->state);
 777
 778        format = ast_state->format;
 779        if (!format)
 780                return;
 781
 782        vbios_mode_info = &ast_state->vbios_mode_info;
 783
 784        ast_set_color_reg(ast, format);
 785        ast_set_vbios_color_reg(ast, format, vbios_mode_info);
 786
 787        if (!crtc->state->mode_changed)
 788                return;
 789
 790        adjusted_mode = &crtc->state->adjusted_mode;
 791
 792        ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
 793        ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
 794        ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
 795        ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
 796        ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
 797        ast_set_crtthd_reg(ast);
 798        ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
 799}
 800
 801static void
 802ast_crtc_helper_atomic_enable(struct drm_crtc *crtc,
 803                              struct drm_crtc_state *old_crtc_state)
 804{
 805        ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
 806}
 807
 808static void
 809ast_crtc_helper_atomic_disable(struct drm_crtc *crtc,
 810                               struct drm_crtc_state *old_crtc_state)
 811{
 812        ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 813}
 814
 815static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
 816        .atomic_check = ast_crtc_helper_atomic_check,
 817        .atomic_begin = ast_crtc_helper_atomic_begin,
 818        .atomic_flush = ast_crtc_helper_atomic_flush,
 819        .atomic_enable = ast_crtc_helper_atomic_enable,
 820        .atomic_disable = ast_crtc_helper_atomic_disable,
 821};
 822
 823static void ast_crtc_reset(struct drm_crtc *crtc)
 824{
 825        struct ast_crtc_state *ast_state =
 826                kzalloc(sizeof(*ast_state), GFP_KERNEL);
 827
 828        if (crtc->state)
 829                crtc->funcs->atomic_destroy_state(crtc, crtc->state);
 830
 831        __drm_atomic_helper_crtc_reset(crtc, &ast_state->base);
 832}
 833
 834static void ast_crtc_destroy(struct drm_crtc *crtc)
 835{
 836        drm_crtc_cleanup(crtc);
 837        kfree(crtc);
 838}
 839
 840static struct drm_crtc_state *
 841ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
 842{
 843        struct ast_crtc_state *new_ast_state, *ast_state;
 844        struct drm_device *dev = crtc->dev;
 845
 846        if (drm_WARN_ON(dev, !crtc->state))
 847                return NULL;
 848
 849        new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL);
 850        if (!new_ast_state)
 851                return NULL;
 852        __drm_atomic_helper_crtc_duplicate_state(crtc, &new_ast_state->base);
 853
 854        ast_state = to_ast_crtc_state(crtc->state);
 855
 856        new_ast_state->format = ast_state->format;
 857        memcpy(&new_ast_state->vbios_mode_info, &ast_state->vbios_mode_info,
 858               sizeof(new_ast_state->vbios_mode_info));
 859
 860        return &new_ast_state->base;
 861}
 862
 863static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc,
 864                                          struct drm_crtc_state *state)
 865{
 866        struct ast_crtc_state *ast_state = to_ast_crtc_state(state);
 867
 868        __drm_atomic_helper_crtc_destroy_state(&ast_state->base);
 869        kfree(ast_state);
 870}
 871
 872static const struct drm_crtc_funcs ast_crtc_funcs = {
 873        .reset = ast_crtc_reset,
 874        .gamma_set = drm_atomic_helper_legacy_gamma_set,
 875        .destroy = ast_crtc_destroy,
 876        .set_config = drm_atomic_helper_set_config,
 877        .page_flip = drm_atomic_helper_page_flip,
 878        .atomic_duplicate_state = ast_crtc_atomic_duplicate_state,
 879        .atomic_destroy_state = ast_crtc_atomic_destroy_state,
 880};
 881
 882static int ast_crtc_init(struct drm_device *dev)
 883{
 884        struct ast_private *ast = to_ast_private(dev);
 885        struct drm_crtc *crtc;
 886        int ret;
 887
 888        crtc = kzalloc(sizeof(*crtc), GFP_KERNEL);
 889        if (!crtc)
 890                return -ENOMEM;
 891
 892        ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane,
 893                                        &ast->cursor_plane, &ast_crtc_funcs,
 894                                        NULL);
 895        if (ret)
 896                goto err_kfree;
 897
 898        drm_mode_crtc_set_gamma_size(crtc, 256);
 899        drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs);
 900
 901        return 0;
 902
 903err_kfree:
 904        kfree(crtc);
 905        return ret;
 906}
 907
 908/*
 909 * Encoder
 910 */
 911
 912static int ast_encoder_init(struct drm_device *dev)
 913{
 914        struct ast_private *ast = to_ast_private(dev);
 915        struct drm_encoder *encoder = &ast->encoder;
 916        int ret;
 917
 918        ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC);
 919        if (ret)
 920                return ret;
 921
 922        encoder->possible_crtcs = 1;
 923
 924        return 0;
 925}
 926
 927/*
 928 * Connector
 929 */
 930
 931static int ast_get_modes(struct drm_connector *connector)
 932{
 933        struct ast_connector *ast_connector = to_ast_connector(connector);
 934        struct ast_private *ast = to_ast_private(connector->dev);
 935        struct edid *edid;
 936        int ret;
 937        bool flags = false;
 938        if (ast->tx_chip_type == AST_TX_DP501) {
 939                ast->dp501_maxclk = 0xff;
 940                edid = kmalloc(128, GFP_KERNEL);
 941                if (!edid)
 942                        return -ENOMEM;
 943
 944                flags = ast_dp501_read_edid(connector->dev, (u8 *)edid);
 945                if (flags)
 946                        ast->dp501_maxclk = ast_get_dp501_max_clk(connector->dev);
 947                else
 948                        kfree(edid);
 949        }
 950        if (!flags)
 951                edid = drm_get_edid(connector, &ast_connector->i2c->adapter);
 952        if (edid) {
 953                drm_connector_update_edid_property(&ast_connector->base, edid);
 954                ret = drm_add_edid_modes(connector, edid);
 955                kfree(edid);
 956                return ret;
 957        } else
 958                drm_connector_update_edid_property(&ast_connector->base, NULL);
 959        return 0;
 960}
 961
 962static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,
 963                          struct drm_display_mode *mode)
 964{
 965        struct ast_private *ast = to_ast_private(connector->dev);
 966        int flags = MODE_NOMODE;
 967        uint32_t jtemp;
 968
 969        if (ast->support_wide_screen) {
 970                if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050))
 971                        return MODE_OK;
 972                if ((mode->hdisplay == 1280) && (mode->vdisplay == 800))
 973                        return MODE_OK;
 974                if ((mode->hdisplay == 1440) && (mode->vdisplay == 900))
 975                        return MODE_OK;
 976                if ((mode->hdisplay == 1360) && (mode->vdisplay == 768))
 977                        return MODE_OK;
 978                if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
 979                        return MODE_OK;
 980
 981                if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
 982                    (ast->chip == AST2300) || (ast->chip == AST2400) ||
 983                    (ast->chip == AST2500)) {
 984                        if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
 985                                return MODE_OK;
 986
 987                        if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) {
 988                                jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
 989                                if (jtemp & 0x01)
 990                                        return MODE_NOMODE;
 991                                else
 992                                        return MODE_OK;
 993                        }
 994                }
 995        }
 996        switch (mode->hdisplay) {
 997        case 640:
 998                if (mode->vdisplay == 480) flags = MODE_OK;
 999                break;
1000        case 800:
1001                if (mode->vdisplay == 600) flags = MODE_OK;
1002                break;
1003        case 1024:
1004                if (mode->vdisplay == 768) flags = MODE_OK;
1005                break;
1006        case 1280:
1007                if (mode->vdisplay == 1024) flags = MODE_OK;
1008                break;
1009        case 1600:
1010                if (mode->vdisplay == 1200) flags = MODE_OK;
1011                break;
1012        default:
1013                return flags;
1014        }
1015
1016        return flags;
1017}
1018
1019static void ast_connector_destroy(struct drm_connector *connector)
1020{
1021        struct ast_connector *ast_connector = to_ast_connector(connector);
1022        ast_i2c_destroy(ast_connector->i2c);
1023        drm_connector_cleanup(connector);
1024        kfree(connector);
1025}
1026
1027static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
1028        .get_modes = ast_get_modes,
1029        .mode_valid = ast_mode_valid,
1030};
1031
1032static const struct drm_connector_funcs ast_connector_funcs = {
1033        .reset = drm_atomic_helper_connector_reset,
1034        .fill_modes = drm_helper_probe_single_connector_modes,
1035        .destroy = ast_connector_destroy,
1036        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1037        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1038};
1039
1040static int ast_connector_init(struct drm_device *dev)
1041{
1042        struct ast_connector *ast_connector;
1043        struct drm_connector *connector;
1044        struct drm_encoder *encoder;
1045
1046        ast_connector = kzalloc(sizeof(struct ast_connector), GFP_KERNEL);
1047        if (!ast_connector)
1048                return -ENOMEM;
1049
1050        connector = &ast_connector->base;
1051        ast_connector->i2c = ast_i2c_create(dev);
1052        if (!ast_connector->i2c)
1053                drm_err(dev, "failed to add ddc bus for connector\n");
1054
1055        drm_connector_init_with_ddc(dev, connector,
1056                                    &ast_connector_funcs,
1057                                    DRM_MODE_CONNECTOR_VGA,
1058                                    &ast_connector->i2c->adapter);
1059
1060        drm_connector_helper_add(connector, &ast_connector_helper_funcs);
1061
1062        connector->interlace_allowed = 0;
1063        connector->doublescan_allowed = 0;
1064
1065        connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1066
1067        encoder = list_first_entry(&dev->mode_config.encoder_list, struct drm_encoder, head);
1068        drm_connector_attach_encoder(connector, encoder);
1069
1070        return 0;
1071}
1072
1073/*
1074 * Mode config
1075 */
1076
1077static const struct drm_mode_config_funcs ast_mode_config_funcs = {
1078        .fb_create = drm_gem_fb_create,
1079        .mode_valid = drm_vram_helper_mode_valid,
1080        .atomic_check = drm_atomic_helper_check,
1081        .atomic_commit = drm_atomic_helper_commit,
1082};
1083
1084int ast_mode_config_init(struct ast_private *ast)
1085{
1086        struct drm_device *dev = ast->dev;
1087        int ret;
1088
1089        ret = ast_cursor_init(ast);
1090        if (ret)
1091                return ret;
1092
1093        ret = drmm_mode_config_init(dev);
1094        if (ret)
1095                return ret;
1096
1097        dev->mode_config.funcs = &ast_mode_config_funcs;
1098        dev->mode_config.min_width = 0;
1099        dev->mode_config.min_height = 0;
1100        dev->mode_config.preferred_depth = 24;
1101        dev->mode_config.prefer_shadow = 1;
1102        dev->mode_config.fb_base = pci_resource_start(ast->dev->pdev, 0);
1103
1104        if (ast->chip == AST2100 ||
1105            ast->chip == AST2200 ||
1106            ast->chip == AST2300 ||
1107            ast->chip == AST2400 ||
1108            ast->chip == AST2500) {
1109                dev->mode_config.max_width = 1920;
1110                dev->mode_config.max_height = 2048;
1111        } else {
1112                dev->mode_config.max_width = 1600;
1113                dev->mode_config.max_height = 1200;
1114        }
1115
1116        memset(&ast->primary_plane, 0, sizeof(ast->primary_plane));
1117        ret = drm_universal_plane_init(dev, &ast->primary_plane, 0x01,
1118                                       &ast_primary_plane_funcs,
1119                                       ast_primary_plane_formats,
1120                                       ARRAY_SIZE(ast_primary_plane_formats),
1121                                       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
1122        if (ret) {
1123                drm_err(dev, "ast: drm_universal_plane_init() failed: %d\n", ret);
1124                return ret;
1125        }
1126        drm_plane_helper_add(&ast->primary_plane,
1127                             &ast_primary_plane_helper_funcs);
1128
1129        ret = drm_universal_plane_init(dev, &ast->cursor_plane, 0x01,
1130                                       &ast_cursor_plane_funcs,
1131                                       ast_cursor_plane_formats,
1132                                       ARRAY_SIZE(ast_cursor_plane_formats),
1133                                       NULL, DRM_PLANE_TYPE_CURSOR, NULL);
1134        if (ret) {
1135                drm_err(dev, "drm_universal_plane_failed(): %d\n", ret);
1136                return ret;
1137        }
1138        drm_plane_helper_add(&ast->cursor_plane,
1139                             &ast_cursor_plane_helper_funcs);
1140
1141        ast_crtc_init(dev);
1142        ast_encoder_init(dev);
1143        ast_connector_init(dev);
1144
1145        drm_mode_config_reset(dev);
1146
1147        return 0;
1148}
1149
1150static int get_clock(void *i2c_priv)
1151{
1152        struct ast_i2c_chan *i2c = i2c_priv;
1153        struct ast_private *ast = to_ast_private(i2c->dev);
1154        uint32_t val, val2, count, pass;
1155
1156        count = 0;
1157        pass = 0;
1158        val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
1159        do {
1160                val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
1161                if (val == val2) {
1162                        pass++;
1163                } else {
1164                        pass = 0;
1165                        val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
1166                }
1167        } while ((pass < 5) && (count++ < 0x10000));
1168
1169        return val & 1 ? 1 : 0;
1170}
1171
1172static int get_data(void *i2c_priv)
1173{
1174        struct ast_i2c_chan *i2c = i2c_priv;
1175        struct ast_private *ast = to_ast_private(i2c->dev);
1176        uint32_t val, val2, count, pass;
1177
1178        count = 0;
1179        pass = 0;
1180        val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1181        do {
1182                val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1183                if (val == val2) {
1184                        pass++;
1185                } else {
1186                        pass = 0;
1187                        val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
1188                }
1189        } while ((pass < 5) && (count++ < 0x10000));
1190
1191        return val & 1 ? 1 : 0;
1192}
1193
1194static void set_clock(void *i2c_priv, int clock)
1195{
1196        struct ast_i2c_chan *i2c = i2c_priv;
1197        struct ast_private *ast = to_ast_private(i2c->dev);
1198        int i;
1199        u8 ujcrb7, jtemp;
1200
1201        for (i = 0; i < 0x10000; i++) {
1202                ujcrb7 = ((clock & 0x01) ? 0 : 1);
1203                ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
1204                jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
1205                if (ujcrb7 == jtemp)
1206                        break;
1207        }
1208}
1209
1210static void set_data(void *i2c_priv, int data)
1211{
1212        struct ast_i2c_chan *i2c = i2c_priv;
1213        struct ast_private *ast = to_ast_private(i2c->dev);
1214        int i;
1215        u8 ujcrb7, jtemp;
1216
1217        for (i = 0; i < 0x10000; i++) {
1218                ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
1219                ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
1220                jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
1221                if (ujcrb7 == jtemp)
1222                        break;
1223        }
1224}
1225
1226static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev)
1227{
1228        struct ast_i2c_chan *i2c;
1229        int ret;
1230
1231        i2c = kzalloc(sizeof(struct ast_i2c_chan), GFP_KERNEL);
1232        if (!i2c)
1233                return NULL;
1234
1235        i2c->adapter.owner = THIS_MODULE;
1236        i2c->adapter.class = I2C_CLASS_DDC;
1237        i2c->adapter.dev.parent = &dev->pdev->dev;
1238        i2c->dev = dev;
1239        i2c_set_adapdata(&i2c->adapter, i2c);
1240        snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
1241                 "AST i2c bit bus");
1242        i2c->adapter.algo_data = &i2c->bit;
1243
1244        i2c->bit.udelay = 20;
1245        i2c->bit.timeout = 2;
1246        i2c->bit.data = i2c;
1247        i2c->bit.setsda = set_data;
1248        i2c->bit.setscl = set_clock;
1249        i2c->bit.getsda = get_data;
1250        i2c->bit.getscl = get_clock;
1251        ret = i2c_bit_add_bus(&i2c->adapter);
1252        if (ret) {
1253                drm_err(dev, "Failed to register bit i2c\n");
1254                goto out_free;
1255        }
1256
1257        return i2c;
1258out_free:
1259        kfree(i2c);
1260        return NULL;
1261}
1262
1263static void ast_i2c_destroy(struct ast_i2c_chan *i2c)
1264{
1265        if (!i2c)
1266                return;
1267        i2c_del_adapter(&i2c->adapter);
1268        kfree(i2c);
1269}
1270