root/drivers/gpu/drm/ast/ast_mode.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ast_load_palette_index
  2. ast_crtc_load_lut
  3. ast_get_vbios_mode_info
  4. ast_set_std_reg
  5. ast_set_crtc_reg
  6. ast_set_offset_reg
  7. ast_set_dclk_reg
  8. ast_set_ext_reg
  9. ast_set_sync_reg
  10. ast_set_dac_reg
  11. ast_set_start_address_crt1
  12. ast_crtc_dpms
  13. ast_crtc_do_set_base
  14. ast_crtc_mode_set_base
  15. ast_crtc_mode_set
  16. ast_crtc_disable
  17. ast_crtc_prepare
  18. ast_crtc_commit
  19. ast_crtc_reset
  20. ast_crtc_gamma_set
  21. ast_crtc_destroy
  22. ast_crtc_init
  23. ast_encoder_destroy
  24. ast_best_single_encoder
  25. ast_encoder_dpms
  26. ast_encoder_mode_set
  27. ast_encoder_prepare
  28. ast_encoder_commit
  29. ast_encoder_init
  30. ast_get_modes
  31. ast_mode_valid
  32. ast_connector_destroy
  33. ast_connector_init
  34. ast_cursor_init
  35. ast_cursor_fini
  36. ast_mode_init
  37. ast_mode_fini
  38. get_clock
  39. get_data
  40. set_clock
  41. set_data
  42. ast_i2c_create
  43. ast_i2c_destroy
  44. ast_show_cursor
  45. ast_hide_cursor
  46. copy_cursor_image
  47. ast_cursor_set
  48. ast_cursor_move

   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_crtc.h>
  35 #include <drm/drm_crtc_helper.h>
  36 #include <drm/drm_fourcc.h>
  37 #include <drm/drm_gem_vram_helper.h>
  38 #include <drm/drm_plane_helper.h>
  39 #include <drm/drm_probe_helper.h>
  40 
  41 #include "ast_drv.h"
  42 #include "ast_tables.h"
  43 
  44 static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev);
  45 static void ast_i2c_destroy(struct ast_i2c_chan *i2c);
  46 static int ast_cursor_set(struct drm_crtc *crtc,
  47                           struct drm_file *file_priv,
  48                           uint32_t handle,
  49                           uint32_t width,
  50                           uint32_t height);
  51 static int ast_cursor_move(struct drm_crtc *crtc,
  52                            int x, int y);
  53 
  54 static inline void ast_load_palette_index(struct ast_private *ast,
  55                                      u8 index, u8 red, u8 green,
  56                                      u8 blue)
  57 {
  58         ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index);
  59         ast_io_read8(ast, AST_IO_SEQ_PORT);
  60         ast_io_write8(ast, AST_IO_DAC_DATA, red);
  61         ast_io_read8(ast, AST_IO_SEQ_PORT);
  62         ast_io_write8(ast, AST_IO_DAC_DATA, green);
  63         ast_io_read8(ast, AST_IO_SEQ_PORT);
  64         ast_io_write8(ast, AST_IO_DAC_DATA, blue);
  65         ast_io_read8(ast, AST_IO_SEQ_PORT);
  66 }
  67 
  68 static void ast_crtc_load_lut(struct drm_crtc *crtc)
  69 {
  70         struct ast_private *ast = crtc->dev->dev_private;
  71         u16 *r, *g, *b;
  72         int i;
  73 
  74         if (!crtc->enabled)
  75                 return;
  76 
  77         r = crtc->gamma_store;
  78         g = r + crtc->gamma_size;
  79         b = g + crtc->gamma_size;
  80 
  81         for (i = 0; i < 256; i++)
  82                 ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
  83 }
  84 
  85 static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mode *mode,
  86                                     struct drm_display_mode *adjusted_mode,
  87                                     struct ast_vbios_mode_info *vbios_mode)
  88 {
  89         struct ast_private *ast = crtc->dev->dev_private;
  90         const struct drm_framebuffer *fb = crtc->primary->fb;
  91         u32 refresh_rate_index = 0, mode_id, color_index, refresh_rate;
  92         const struct ast_vbios_enhtable *best = NULL;
  93         u32 hborder, vborder;
  94         bool check_sync;
  95 
  96         switch (fb->format->cpp[0] * 8) {
  97         case 8:
  98                 vbios_mode->std_table = &vbios_stdtable[VGAModeIndex];
  99                 color_index = VGAModeIndex - 1;
 100                 break;
 101         case 16:
 102                 vbios_mode->std_table = &vbios_stdtable[HiCModeIndex];
 103                 color_index = HiCModeIndex;
 104                 break;
 105         case 24:
 106         case 32:
 107                 vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex];
 108                 color_index = TrueCModeIndex;
 109                 break;
 110         default:
 111                 return false;
 112         }
 113 
 114         switch (crtc->mode.crtc_hdisplay) {
 115         case 640:
 116                 vbios_mode->enh_table = &res_640x480[refresh_rate_index];
 117                 break;
 118         case 800:
 119                 vbios_mode->enh_table = &res_800x600[refresh_rate_index];
 120                 break;
 121         case 1024:
 122                 vbios_mode->enh_table = &res_1024x768[refresh_rate_index];
 123                 break;
 124         case 1280:
 125                 if (crtc->mode.crtc_vdisplay == 800)
 126                         vbios_mode->enh_table = &res_1280x800[refresh_rate_index];
 127                 else
 128                         vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
 129                 break;
 130         case 1360:
 131                 vbios_mode->enh_table = &res_1360x768[refresh_rate_index];
 132                 break;
 133         case 1440:
 134                 vbios_mode->enh_table = &res_1440x900[refresh_rate_index];
 135                 break;
 136         case 1600:
 137                 if (crtc->mode.crtc_vdisplay == 900)
 138                         vbios_mode->enh_table = &res_1600x900[refresh_rate_index];
 139                 else
 140                         vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
 141                 break;
 142         case 1680:
 143                 vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];
 144                 break;
 145         case 1920:
 146                 if (crtc->mode.crtc_vdisplay == 1080)
 147                         vbios_mode->enh_table = &res_1920x1080[refresh_rate_index];
 148                 else
 149                         vbios_mode->enh_table = &res_1920x1200[refresh_rate_index];
 150                 break;
 151         default:
 152                 return false;
 153         }
 154 
 155         refresh_rate = drm_mode_vrefresh(mode);
 156         check_sync = vbios_mode->enh_table->flags & WideScreenMode;
 157         do {
 158                 const struct ast_vbios_enhtable *loop = vbios_mode->enh_table;
 159 
 160                 while (loop->refresh_rate != 0xff) {
 161                         if ((check_sync) &&
 162                             (((mode->flags & DRM_MODE_FLAG_NVSYNC)  &&
 163                               (loop->flags & PVSync))  ||
 164                              ((mode->flags & DRM_MODE_FLAG_PVSYNC)  &&
 165                               (loop->flags & NVSync))  ||
 166                              ((mode->flags & DRM_MODE_FLAG_NHSYNC)  &&
 167                               (loop->flags & PHSync))  ||
 168                              ((mode->flags & DRM_MODE_FLAG_PHSYNC)  &&
 169                               (loop->flags & NHSync)))) {
 170                                 loop++;
 171                                 continue;
 172                         }
 173                         if (loop->refresh_rate <= refresh_rate
 174                             && (!best || loop->refresh_rate > best->refresh_rate))
 175                                 best = loop;
 176                         loop++;
 177                 }
 178                 if (best || !check_sync)
 179                         break;
 180                 check_sync = 0;
 181         } while (1);
 182         if (best)
 183                 vbios_mode->enh_table = best;
 184 
 185         hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0;
 186         vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0;
 187 
 188         adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht;
 189         adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder;
 190         adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder;
 191         adjusted_mode->crtc_hsync_start = vbios_mode->enh_table->hde + hborder +
 192                 vbios_mode->enh_table->hfp;
 193         adjusted_mode->crtc_hsync_end = (vbios_mode->enh_table->hde + hborder +
 194                                          vbios_mode->enh_table->hfp +
 195                                          vbios_mode->enh_table->hsync);
 196 
 197         adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt;
 198         adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder;
 199         adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder;
 200         adjusted_mode->crtc_vsync_start = vbios_mode->enh_table->vde + vborder +
 201                 vbios_mode->enh_table->vfp;
 202         adjusted_mode->crtc_vsync_end = (vbios_mode->enh_table->vde + vborder +
 203                                          vbios_mode->enh_table->vfp +
 204                                          vbios_mode->enh_table->vsync);
 205 
 206         refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
 207         mode_id = vbios_mode->enh_table->mode_id;
 208 
 209         if (ast->chip == AST1180) {
 210                 /* TODO 1180 */
 211         } else {
 212                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0xf) << 4));
 213                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
 214                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
 215 
 216                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
 217                 if (vbios_mode->enh_table->flags & NewModeInfo) {
 218                         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
 219                         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92,
 220                                           fb->format->cpp[0] * 8);
 221                         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
 222                         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
 223                         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
 224 
 225                         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
 226                         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
 227                 }
 228         }
 229 
 230         return true;
 231 
 232 
 233 }
 234 static void ast_set_std_reg(struct drm_crtc *crtc, struct drm_display_mode *mode,
 235                             struct ast_vbios_mode_info *vbios_mode)
 236 {
 237         struct ast_private *ast = crtc->dev->dev_private;
 238         const struct ast_vbios_stdtable *stdtable;
 239         u32 i;
 240         u8 jreg;
 241 
 242         stdtable = vbios_mode->std_table;
 243 
 244         jreg = stdtable->misc;
 245         ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
 246 
 247         /* Set SEQ */
 248         ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03);
 249         for (i = 0; i < 4; i++) {
 250                 jreg = stdtable->seq[i];
 251                 if (!i)
 252                         jreg |= 0x20;
 253                 ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1) , jreg);
 254         }
 255 
 256         /* Set CRTC */
 257         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
 258         for (i = 0; i < 25; i++)
 259                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
 260 
 261         /* set AR */
 262         jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
 263         for (i = 0; i < 20; i++) {
 264                 jreg = stdtable->ar[i];
 265                 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i);
 266                 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg);
 267         }
 268         ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14);
 269         ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00);
 270 
 271         jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
 272         ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20);
 273 
 274         /* Set GR */
 275         for (i = 0; i < 9; i++)
 276                 ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]);
 277 }
 278 
 279 static void ast_set_crtc_reg(struct drm_crtc *crtc, struct drm_display_mode *mode,
 280                              struct ast_vbios_mode_info *vbios_mode)
 281 {
 282         struct ast_private *ast = crtc->dev->dev_private;
 283         u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0;
 284         u16 temp, precache = 0;
 285 
 286         if ((ast->chip == AST2500) &&
 287             (vbios_mode->enh_table->flags & AST2500PreCatchCRT))
 288                 precache = 40;
 289 
 290         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
 291 
 292         temp = (mode->crtc_htotal >> 3) - 5;
 293         if (temp & 0x100)
 294                 jregAC |= 0x01; /* HT D[8] */
 295         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp);
 296 
 297         temp = (mode->crtc_hdisplay >> 3) - 1;
 298         if (temp & 0x100)
 299                 jregAC |= 0x04; /* HDE D[8] */
 300         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp);
 301 
 302         temp = (mode->crtc_hblank_start >> 3) - 1;
 303         if (temp & 0x100)
 304                 jregAC |= 0x10; /* HBS D[8] */
 305         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp);
 306 
 307         temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f;
 308         if (temp & 0x20)
 309                 jreg05 |= 0x80;  /* HBE D[5] */
 310         if (temp & 0x40)
 311                 jregAD |= 0x01;  /* HBE D[5] */
 312         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f));
 313 
 314         temp = ((mode->crtc_hsync_start-precache) >> 3) - 1;
 315         if (temp & 0x100)
 316                 jregAC |= 0x40; /* HRS D[5] */
 317         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp);
 318 
 319         temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f;
 320         if (temp & 0x20)
 321                 jregAD |= 0x04; /* HRE D[5] */
 322         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05));
 323 
 324         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC);
 325         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD);
 326 
 327         /* vert timings */
 328         temp = (mode->crtc_vtotal) - 2;
 329         if (temp & 0x100)
 330                 jreg07 |= 0x01;
 331         if (temp & 0x200)
 332                 jreg07 |= 0x20;
 333         if (temp & 0x400)
 334                 jregAE |= 0x01;
 335         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp);
 336 
 337         temp = (mode->crtc_vsync_start) - 1;
 338         if (temp & 0x100)
 339                 jreg07 |= 0x04;
 340         if (temp & 0x200)
 341                 jreg07 |= 0x80;
 342         if (temp & 0x400)
 343                 jregAE |= 0x08;
 344         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp);
 345 
 346         temp = (mode->crtc_vsync_end - 1) & 0x3f;
 347         if (temp & 0x10)
 348                 jregAE |= 0x20;
 349         if (temp & 0x20)
 350                 jregAE |= 0x40;
 351         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf);
 352 
 353         temp = mode->crtc_vdisplay - 1;
 354         if (temp & 0x100)
 355                 jreg07 |= 0x02;
 356         if (temp & 0x200)
 357                 jreg07 |= 0x40;
 358         if (temp & 0x400)
 359                 jregAE |= 0x02;
 360         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp);
 361 
 362         temp = mode->crtc_vblank_start - 1;
 363         if (temp & 0x100)
 364                 jreg07 |= 0x08;
 365         if (temp & 0x200)
 366                 jreg09 |= 0x20;
 367         if (temp & 0x400)
 368                 jregAE |= 0x04;
 369         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp);
 370 
 371         temp = mode->crtc_vblank_end - 1;
 372         if (temp & 0x100)
 373                 jregAE |= 0x10;
 374         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp);
 375 
 376         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07);
 377         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09);
 378         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80));
 379 
 380         if (precache)
 381                 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80);
 382         else
 383                 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00);
 384 
 385         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80);
 386 }
 387 
 388 static void ast_set_offset_reg(struct drm_crtc *crtc)
 389 {
 390         struct ast_private *ast = crtc->dev->dev_private;
 391         const struct drm_framebuffer *fb = crtc->primary->fb;
 392 
 393         u16 offset;
 394 
 395         offset = fb->pitches[0] >> 3;
 396         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff));
 397         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f);
 398 }
 399 
 400 static void ast_set_dclk_reg(struct drm_device *dev, struct drm_display_mode *mode,
 401                              struct ast_vbios_mode_info *vbios_mode)
 402 {
 403         struct ast_private *ast = dev->dev_private;
 404         const struct ast_vbios_dclk_info *clk_info;
 405 
 406         if (ast->chip == AST2500)
 407                 clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index];
 408         else
 409                 clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
 410 
 411         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1);
 412         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2);
 413         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f,
 414                                (clk_info->param3 & 0xc0) |
 415                                ((clk_info->param3 & 0x3) << 4));
 416 }
 417 
 418 static void ast_set_ext_reg(struct drm_crtc *crtc, struct drm_display_mode *mode,
 419                              struct ast_vbios_mode_info *vbios_mode)
 420 {
 421         struct ast_private *ast = crtc->dev->dev_private;
 422         const struct drm_framebuffer *fb = crtc->primary->fb;
 423         u8 jregA0 = 0, jregA3 = 0, jregA8 = 0;
 424 
 425         switch (fb->format->cpp[0] * 8) {
 426         case 8:
 427                 jregA0 = 0x70;
 428                 jregA3 = 0x01;
 429                 jregA8 = 0x00;
 430                 break;
 431         case 15:
 432         case 16:
 433                 jregA0 = 0x70;
 434                 jregA3 = 0x04;
 435                 jregA8 = 0x02;
 436                 break;
 437         case 32:
 438                 jregA0 = 0x70;
 439                 jregA3 = 0x08;
 440                 jregA8 = 0x02;
 441                 break;
 442         }
 443 
 444         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0);
 445         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3);
 446         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8);
 447 
 448         /* Set Threshold */
 449         if (ast->chip == AST2300 || ast->chip == AST2400 ||
 450             ast->chip == AST2500) {
 451                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78);
 452                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60);
 453         } else if (ast->chip == AST2100 ||
 454                    ast->chip == AST1100 ||
 455                    ast->chip == AST2200 ||
 456                    ast->chip == AST2150) {
 457                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f);
 458                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f);
 459         } else {
 460                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f);
 461                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f);
 462         }
 463 }
 464 
 465 static void ast_set_sync_reg(struct drm_device *dev, struct drm_display_mode *mode,
 466                       struct ast_vbios_mode_info *vbios_mode)
 467 {
 468         struct ast_private *ast = dev->dev_private;
 469         u8 jreg;
 470 
 471         jreg  = ast_io_read8(ast, AST_IO_MISC_PORT_READ);
 472         jreg &= ~0xC0;
 473         if (vbios_mode->enh_table->flags & NVSync) jreg |= 0x80;
 474         if (vbios_mode->enh_table->flags & NHSync) jreg |= 0x40;
 475         ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
 476 }
 477 
 478 static bool ast_set_dac_reg(struct drm_crtc *crtc, struct drm_display_mode *mode,
 479                      struct ast_vbios_mode_info *vbios_mode)
 480 {
 481         const struct drm_framebuffer *fb = crtc->primary->fb;
 482 
 483         switch (fb->format->cpp[0] * 8) {
 484         case 8:
 485                 break;
 486         default:
 487                 return false;
 488         }
 489         return true;
 490 }
 491 
 492 static void ast_set_start_address_crt1(struct drm_crtc *crtc, unsigned offset)
 493 {
 494         struct ast_private *ast = crtc->dev->dev_private;
 495         u32 addr;
 496 
 497         addr = offset >> 2;
 498         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff));
 499         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff));
 500         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff));
 501 
 502 }
 503 
 504 static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
 505 {
 506         struct ast_private *ast = crtc->dev->dev_private;
 507 
 508         if (ast->chip == AST1180)
 509                 return;
 510 
 511         switch (mode) {
 512         case DRM_MODE_DPMS_ON:
 513         case DRM_MODE_DPMS_STANDBY:
 514         case DRM_MODE_DPMS_SUSPEND:
 515                 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0);
 516                 if (ast->tx_chip_type == AST_TX_DP501)
 517                         ast_set_dp501_video_output(crtc->dev, 1);
 518                 ast_crtc_load_lut(crtc);
 519                 break;
 520         case DRM_MODE_DPMS_OFF:
 521                 if (ast->tx_chip_type == AST_TX_DP501)
 522                         ast_set_dp501_video_output(crtc->dev, 0);
 523                 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);
 524                 break;
 525         }
 526 }
 527 
 528 static int ast_crtc_do_set_base(struct drm_crtc *crtc,
 529                                 struct drm_framebuffer *fb,
 530                                 int x, int y, int atomic)
 531 {
 532         struct drm_gem_vram_object *gbo;
 533         int ret;
 534         s64 gpu_addr;
 535 
 536         if (!atomic && fb) {
 537                 gbo = drm_gem_vram_of_gem(fb->obj[0]);
 538                 drm_gem_vram_unpin(gbo);
 539         }
 540 
 541         gbo = drm_gem_vram_of_gem(crtc->primary->fb->obj[0]);
 542 
 543         ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
 544         if (ret)
 545                 return ret;
 546         gpu_addr = drm_gem_vram_offset(gbo);
 547         if (gpu_addr < 0) {
 548                 ret = (int)gpu_addr;
 549                 goto err_drm_gem_vram_unpin;
 550         }
 551 
 552         ast_set_offset_reg(crtc);
 553         ast_set_start_address_crt1(crtc, (u32)gpu_addr);
 554 
 555         return 0;
 556 
 557 err_drm_gem_vram_unpin:
 558         drm_gem_vram_unpin(gbo);
 559         return ret;
 560 }
 561 
 562 static int ast_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 563                              struct drm_framebuffer *old_fb)
 564 {
 565         return ast_crtc_do_set_base(crtc, old_fb, x, y, 0);
 566 }
 567 
 568 static int ast_crtc_mode_set(struct drm_crtc *crtc,
 569                              struct drm_display_mode *mode,
 570                              struct drm_display_mode *adjusted_mode,
 571                              int x, int y,
 572                              struct drm_framebuffer *old_fb)
 573 {
 574         struct drm_device *dev = crtc->dev;
 575         struct ast_private *ast = crtc->dev->dev_private;
 576         struct ast_vbios_mode_info vbios_mode;
 577         bool ret;
 578         if (ast->chip == AST1180) {
 579                 DRM_ERROR("AST 1180 modesetting not supported\n");
 580                 return -EINVAL;
 581         }
 582 
 583         ret = ast_get_vbios_mode_info(crtc, mode, adjusted_mode, &vbios_mode);
 584         if (ret == false)
 585                 return -EINVAL;
 586         ast_open_key(ast);
 587 
 588         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
 589 
 590         ast_set_std_reg(crtc, adjusted_mode, &vbios_mode);
 591         ast_set_crtc_reg(crtc, adjusted_mode, &vbios_mode);
 592         ast_set_offset_reg(crtc);
 593         ast_set_dclk_reg(dev, adjusted_mode, &vbios_mode);
 594         ast_set_ext_reg(crtc, adjusted_mode, &vbios_mode);
 595         ast_set_sync_reg(dev, adjusted_mode, &vbios_mode);
 596         ast_set_dac_reg(crtc, adjusted_mode, &vbios_mode);
 597 
 598         ast_crtc_mode_set_base(crtc, x, y, old_fb);
 599 
 600         return 0;
 601 }
 602 
 603 static void ast_crtc_disable(struct drm_crtc *crtc)
 604 {
 605         DRM_DEBUG_KMS("\n");
 606         ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 607         if (crtc->primary->fb) {
 608                 struct drm_framebuffer *fb = crtc->primary->fb;
 609                 struct drm_gem_vram_object *gbo =
 610                         drm_gem_vram_of_gem(fb->obj[0]);
 611 
 612                 drm_gem_vram_unpin(gbo);
 613         }
 614         crtc->primary->fb = NULL;
 615 }
 616 
 617 static void ast_crtc_prepare(struct drm_crtc *crtc)
 618 {
 619 
 620 }
 621 
 622 static void ast_crtc_commit(struct drm_crtc *crtc)
 623 {
 624         struct ast_private *ast = crtc->dev->dev_private;
 625         ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0);
 626         ast_crtc_load_lut(crtc);
 627 }
 628 
 629 
 630 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
 631         .dpms = ast_crtc_dpms,
 632         .mode_set = ast_crtc_mode_set,
 633         .mode_set_base = ast_crtc_mode_set_base,
 634         .disable = ast_crtc_disable,
 635         .prepare = ast_crtc_prepare,
 636         .commit = ast_crtc_commit,
 637 
 638 };
 639 
 640 static void ast_crtc_reset(struct drm_crtc *crtc)
 641 {
 642 
 643 }
 644 
 645 static int ast_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
 646                               u16 *blue, uint32_t size,
 647                               struct drm_modeset_acquire_ctx *ctx)
 648 {
 649         ast_crtc_load_lut(crtc);
 650 
 651         return 0;
 652 }
 653 
 654 
 655 static void ast_crtc_destroy(struct drm_crtc *crtc)
 656 {
 657         drm_crtc_cleanup(crtc);
 658         kfree(crtc);
 659 }
 660 
 661 static const struct drm_crtc_funcs ast_crtc_funcs = {
 662         .cursor_set = ast_cursor_set,
 663         .cursor_move = ast_cursor_move,
 664         .reset = ast_crtc_reset,
 665         .set_config = drm_crtc_helper_set_config,
 666         .gamma_set = ast_crtc_gamma_set,
 667         .destroy = ast_crtc_destroy,
 668 };
 669 
 670 static int ast_crtc_init(struct drm_device *dev)
 671 {
 672         struct ast_crtc *crtc;
 673 
 674         crtc = kzalloc(sizeof(struct ast_crtc), GFP_KERNEL);
 675         if (!crtc)
 676                 return -ENOMEM;
 677 
 678         drm_crtc_init(dev, &crtc->base, &ast_crtc_funcs);
 679         drm_mode_crtc_set_gamma_size(&crtc->base, 256);
 680         drm_crtc_helper_add(&crtc->base, &ast_crtc_helper_funcs);
 681         return 0;
 682 }
 683 
 684 static void ast_encoder_destroy(struct drm_encoder *encoder)
 685 {
 686         drm_encoder_cleanup(encoder);
 687         kfree(encoder);
 688 }
 689 
 690 
 691 static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connector)
 692 {
 693         int enc_id = connector->encoder_ids[0];
 694         /* pick the encoder ids */
 695         if (enc_id)
 696                 return drm_encoder_find(connector->dev, NULL, enc_id);
 697         return NULL;
 698 }
 699 
 700 
 701 static const struct drm_encoder_funcs ast_enc_funcs = {
 702         .destroy = ast_encoder_destroy,
 703 };
 704 
 705 static void ast_encoder_dpms(struct drm_encoder *encoder, int mode)
 706 {
 707 
 708 }
 709 
 710 static void ast_encoder_mode_set(struct drm_encoder *encoder,
 711                                struct drm_display_mode *mode,
 712                                struct drm_display_mode *adjusted_mode)
 713 {
 714 }
 715 
 716 static void ast_encoder_prepare(struct drm_encoder *encoder)
 717 {
 718 
 719 }
 720 
 721 static void ast_encoder_commit(struct drm_encoder *encoder)
 722 {
 723 
 724 }
 725 
 726 
 727 static const struct drm_encoder_helper_funcs ast_enc_helper_funcs = {
 728         .dpms = ast_encoder_dpms,
 729         .prepare = ast_encoder_prepare,
 730         .commit = ast_encoder_commit,
 731         .mode_set = ast_encoder_mode_set,
 732 };
 733 
 734 static int ast_encoder_init(struct drm_device *dev)
 735 {
 736         struct ast_encoder *ast_encoder;
 737 
 738         ast_encoder = kzalloc(sizeof(struct ast_encoder), GFP_KERNEL);
 739         if (!ast_encoder)
 740                 return -ENOMEM;
 741 
 742         drm_encoder_init(dev, &ast_encoder->base, &ast_enc_funcs,
 743                          DRM_MODE_ENCODER_DAC, NULL);
 744         drm_encoder_helper_add(&ast_encoder->base, &ast_enc_helper_funcs);
 745 
 746         ast_encoder->base.possible_crtcs = 1;
 747         return 0;
 748 }
 749 
 750 static int ast_get_modes(struct drm_connector *connector)
 751 {
 752         struct ast_connector *ast_connector = to_ast_connector(connector);
 753         struct ast_private *ast = connector->dev->dev_private;
 754         struct edid *edid;
 755         int ret;
 756         bool flags = false;
 757         if (ast->tx_chip_type == AST_TX_DP501) {
 758                 ast->dp501_maxclk = 0xff;
 759                 edid = kmalloc(128, GFP_KERNEL);
 760                 if (!edid)
 761                         return -ENOMEM;
 762 
 763                 flags = ast_dp501_read_edid(connector->dev, (u8 *)edid);
 764                 if (flags)
 765                         ast->dp501_maxclk = ast_get_dp501_max_clk(connector->dev);
 766                 else
 767                         kfree(edid);
 768         }
 769         if (!flags)
 770                 edid = drm_get_edid(connector, &ast_connector->i2c->adapter);
 771         if (edid) {
 772                 drm_connector_update_edid_property(&ast_connector->base, edid);
 773                 ret = drm_add_edid_modes(connector, edid);
 774                 kfree(edid);
 775                 return ret;
 776         } else
 777                 drm_connector_update_edid_property(&ast_connector->base, NULL);
 778         return 0;
 779 }
 780 
 781 static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,
 782                           struct drm_display_mode *mode)
 783 {
 784         struct ast_private *ast = connector->dev->dev_private;
 785         int flags = MODE_NOMODE;
 786         uint32_t jtemp;
 787 
 788         if (ast->support_wide_screen) {
 789                 if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050))
 790                         return MODE_OK;
 791                 if ((mode->hdisplay == 1280) && (mode->vdisplay == 800))
 792                         return MODE_OK;
 793                 if ((mode->hdisplay == 1440) && (mode->vdisplay == 900))
 794                         return MODE_OK;
 795                 if ((mode->hdisplay == 1360) && (mode->vdisplay == 768))
 796                         return MODE_OK;
 797                 if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
 798                         return MODE_OK;
 799 
 800                 if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
 801                     (ast->chip == AST2300) || (ast->chip == AST2400) ||
 802                     (ast->chip == AST2500) || (ast->chip == AST1180)) {
 803                         if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
 804                                 return MODE_OK;
 805 
 806                         if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) {
 807                                 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
 808                                 if (jtemp & 0x01)
 809                                         return MODE_NOMODE;
 810                                 else
 811                                         return MODE_OK;
 812                         }
 813                 }
 814         }
 815         switch (mode->hdisplay) {
 816         case 640:
 817                 if (mode->vdisplay == 480) flags = MODE_OK;
 818                 break;
 819         case 800:
 820                 if (mode->vdisplay == 600) flags = MODE_OK;
 821                 break;
 822         case 1024:
 823                 if (mode->vdisplay == 768) flags = MODE_OK;
 824                 break;
 825         case 1280:
 826                 if (mode->vdisplay == 1024) flags = MODE_OK;
 827                 break;
 828         case 1600:
 829                 if (mode->vdisplay == 1200) flags = MODE_OK;
 830                 break;
 831         default:
 832                 return flags;
 833         }
 834 
 835         return flags;
 836 }
 837 
 838 static void ast_connector_destroy(struct drm_connector *connector)
 839 {
 840         struct ast_connector *ast_connector = to_ast_connector(connector);
 841         ast_i2c_destroy(ast_connector->i2c);
 842         drm_connector_unregister(connector);
 843         drm_connector_cleanup(connector);
 844         kfree(connector);
 845 }
 846 
 847 static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
 848         .mode_valid = ast_mode_valid,
 849         .get_modes = ast_get_modes,
 850         .best_encoder = ast_best_single_encoder,
 851 };
 852 
 853 static const struct drm_connector_funcs ast_connector_funcs = {
 854         .dpms = drm_helper_connector_dpms,
 855         .fill_modes = drm_helper_probe_single_connector_modes,
 856         .destroy = ast_connector_destroy,
 857 };
 858 
 859 static int ast_connector_init(struct drm_device *dev)
 860 {
 861         struct ast_connector *ast_connector;
 862         struct drm_connector *connector;
 863         struct drm_encoder *encoder;
 864 
 865         ast_connector = kzalloc(sizeof(struct ast_connector), GFP_KERNEL);
 866         if (!ast_connector)
 867                 return -ENOMEM;
 868 
 869         connector = &ast_connector->base;
 870         ast_connector->i2c = ast_i2c_create(dev);
 871         if (!ast_connector->i2c)
 872                 DRM_ERROR("failed to add ddc bus for connector\n");
 873 
 874         drm_connector_init_with_ddc(dev, connector,
 875                                     &ast_connector_funcs,
 876                                     DRM_MODE_CONNECTOR_VGA,
 877                                     &ast_connector->i2c->adapter);
 878 
 879         drm_connector_helper_add(connector, &ast_connector_helper_funcs);
 880 
 881         connector->interlace_allowed = 0;
 882         connector->doublescan_allowed = 0;
 883 
 884         drm_connector_register(connector);
 885 
 886         connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 887 
 888         encoder = list_first_entry(&dev->mode_config.encoder_list, struct drm_encoder, head);
 889         drm_connector_attach_encoder(connector, encoder);
 890 
 891         return 0;
 892 }
 893 
 894 /* allocate cursor cache and pin at start of VRAM */
 895 static int ast_cursor_init(struct drm_device *dev)
 896 {
 897         struct ast_private *ast = dev->dev_private;
 898         int size;
 899         int ret;
 900         struct drm_gem_object *obj;
 901         struct drm_gem_vram_object *gbo;
 902         s64 gpu_addr;
 903         void *base;
 904 
 905         size = (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE) * AST_DEFAULT_HWC_NUM;
 906 
 907         ret = ast_gem_create(dev, size, true, &obj);
 908         if (ret)
 909                 return ret;
 910         gbo = drm_gem_vram_of_gem(obj);
 911         ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
 912         if (ret)
 913                 goto fail;
 914         gpu_addr = drm_gem_vram_offset(gbo);
 915         if (gpu_addr < 0) {
 916                 drm_gem_vram_unpin(gbo);
 917                 ret = (int)gpu_addr;
 918                 goto fail;
 919         }
 920 
 921         /* kmap the object */
 922         base = drm_gem_vram_kmap(gbo, true, NULL);
 923         if (IS_ERR(base)) {
 924                 ret = PTR_ERR(base);
 925                 goto fail;
 926         }
 927 
 928         ast->cursor_cache = obj;
 929         return 0;
 930 fail:
 931         return ret;
 932 }
 933 
 934 static void ast_cursor_fini(struct drm_device *dev)
 935 {
 936         struct ast_private *ast = dev->dev_private;
 937         struct drm_gem_vram_object *gbo =
 938                 drm_gem_vram_of_gem(ast->cursor_cache);
 939         drm_gem_vram_kunmap(gbo);
 940         drm_gem_vram_unpin(gbo);
 941         drm_gem_object_put_unlocked(ast->cursor_cache);
 942 }
 943 
 944 int ast_mode_init(struct drm_device *dev)
 945 {
 946         ast_cursor_init(dev);
 947         ast_crtc_init(dev);
 948         ast_encoder_init(dev);
 949         ast_connector_init(dev);
 950         return 0;
 951 }
 952 
 953 void ast_mode_fini(struct drm_device *dev)
 954 {
 955         ast_cursor_fini(dev);
 956 }
 957 
 958 static int get_clock(void *i2c_priv)
 959 {
 960         struct ast_i2c_chan *i2c = i2c_priv;
 961         struct ast_private *ast = i2c->dev->dev_private;
 962         uint32_t val, val2, count, pass;
 963 
 964         count = 0;
 965         pass = 0;
 966         val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
 967         do {
 968                 val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
 969                 if (val == val2) {
 970                         pass++;
 971                 } else {
 972                         pass = 0;
 973                         val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
 974                 }
 975         } while ((pass < 5) && (count++ < 0x10000));
 976 
 977         return val & 1 ? 1 : 0;
 978 }
 979 
 980 static int get_data(void *i2c_priv)
 981 {
 982         struct ast_i2c_chan *i2c = i2c_priv;
 983         struct ast_private *ast = i2c->dev->dev_private;
 984         uint32_t val, val2, count, pass;
 985 
 986         count = 0;
 987         pass = 0;
 988         val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
 989         do {
 990                 val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
 991                 if (val == val2) {
 992                         pass++;
 993                 } else {
 994                         pass = 0;
 995                         val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
 996                 }
 997         } while ((pass < 5) && (count++ < 0x10000));
 998 
 999         return val & 1 ? 1 : 0;
1000 }
1001 
1002 static void set_clock(void *i2c_priv, int clock)
1003 {
1004         struct ast_i2c_chan *i2c = i2c_priv;
1005         struct ast_private *ast = i2c->dev->dev_private;
1006         int i;
1007         u8 ujcrb7, jtemp;
1008 
1009         for (i = 0; i < 0x10000; i++) {
1010                 ujcrb7 = ((clock & 0x01) ? 0 : 1);
1011                 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
1012                 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
1013                 if (ujcrb7 == jtemp)
1014                         break;
1015         }
1016 }
1017 
1018 static void set_data(void *i2c_priv, int data)
1019 {
1020         struct ast_i2c_chan *i2c = i2c_priv;
1021         struct ast_private *ast = i2c->dev->dev_private;
1022         int i;
1023         u8 ujcrb7, jtemp;
1024 
1025         for (i = 0; i < 0x10000; i++) {
1026                 ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
1027                 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
1028                 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
1029                 if (ujcrb7 == jtemp)
1030                         break;
1031         }
1032 }
1033 
1034 static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev)
1035 {
1036         struct ast_i2c_chan *i2c;
1037         int ret;
1038 
1039         i2c = kzalloc(sizeof(struct ast_i2c_chan), GFP_KERNEL);
1040         if (!i2c)
1041                 return NULL;
1042 
1043         i2c->adapter.owner = THIS_MODULE;
1044         i2c->adapter.class = I2C_CLASS_DDC;
1045         i2c->adapter.dev.parent = &dev->pdev->dev;
1046         i2c->dev = dev;
1047         i2c_set_adapdata(&i2c->adapter, i2c);
1048         snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
1049                  "AST i2c bit bus");
1050         i2c->adapter.algo_data = &i2c->bit;
1051 
1052         i2c->bit.udelay = 20;
1053         i2c->bit.timeout = 2;
1054         i2c->bit.data = i2c;
1055         i2c->bit.setsda = set_data;
1056         i2c->bit.setscl = set_clock;
1057         i2c->bit.getsda = get_data;
1058         i2c->bit.getscl = get_clock;
1059         ret = i2c_bit_add_bus(&i2c->adapter);
1060         if (ret) {
1061                 DRM_ERROR("Failed to register bit i2c\n");
1062                 goto out_free;
1063         }
1064 
1065         return i2c;
1066 out_free:
1067         kfree(i2c);
1068         return NULL;
1069 }
1070 
1071 static void ast_i2c_destroy(struct ast_i2c_chan *i2c)
1072 {
1073         if (!i2c)
1074                 return;
1075         i2c_del_adapter(&i2c->adapter);
1076         kfree(i2c);
1077 }
1078 
1079 static void ast_show_cursor(struct drm_crtc *crtc)
1080 {
1081         struct ast_private *ast = crtc->dev->dev_private;
1082         u8 jreg;
1083 
1084         jreg = 0x2;
1085         /* enable ARGB cursor */
1086         jreg |= 1;
1087         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, jreg);
1088 }
1089 
1090 static void ast_hide_cursor(struct drm_crtc *crtc)
1091 {
1092         struct ast_private *ast = crtc->dev->dev_private;
1093         ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, 0x00);
1094 }
1095 
1096 static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height)
1097 {
1098         union {
1099                 u32 ul;
1100                 u8 b[4];
1101         } srcdata32[2], data32;
1102         union {
1103                 u16 us;
1104                 u8 b[2];
1105         } data16;
1106         u32 csum = 0;
1107         s32 alpha_dst_delta, last_alpha_dst_delta;
1108         u8 *srcxor, *dstxor;
1109         int i, j;
1110         u32 per_pixel_copy, two_pixel_copy;
1111 
1112         alpha_dst_delta = AST_MAX_HWC_WIDTH << 1;
1113         last_alpha_dst_delta = alpha_dst_delta - (width << 1);
1114 
1115         srcxor = src;
1116         dstxor = (u8 *)dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta;
1117         per_pixel_copy = width & 1;
1118         two_pixel_copy = width >> 1;
1119 
1120         for (j = 0; j < height; j++) {
1121                 for (i = 0; i < two_pixel_copy; i++) {
1122                         srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
1123                         srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0;
1124                         data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
1125                         data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
1126                         data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4);
1127                         data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4);
1128 
1129                         writel(data32.ul, dstxor);
1130                         csum += data32.ul;
1131 
1132                         dstxor += 4;
1133                         srcxor += 8;
1134 
1135                 }
1136 
1137                 for (i = 0; i < per_pixel_copy; i++) {
1138                         srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
1139                         data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
1140                         data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
1141                         writew(data16.us, dstxor);
1142                         csum += (u32)data16.us;
1143 
1144                         dstxor += 2;
1145                         srcxor += 4;
1146                 }
1147                 dstxor += last_alpha_dst_delta;
1148         }
1149         return csum;
1150 }
1151 
1152 static int ast_cursor_set(struct drm_crtc *crtc,
1153                           struct drm_file *file_priv,
1154                           uint32_t handle,
1155                           uint32_t width,
1156                           uint32_t height)
1157 {
1158         struct ast_private *ast = crtc->dev->dev_private;
1159         struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
1160         struct drm_gem_object *obj;
1161         struct drm_gem_vram_object *gbo;
1162         s64 dst_gpu;
1163         u64 gpu_addr;
1164         u32 csum;
1165         int ret;
1166         u8 *src, *dst;
1167 
1168         if (!handle) {
1169                 ast_hide_cursor(crtc);
1170                 return 0;
1171         }
1172 
1173         if (width > AST_MAX_HWC_WIDTH || height > AST_MAX_HWC_HEIGHT)
1174                 return -EINVAL;
1175 
1176         obj = drm_gem_object_lookup(file_priv, handle);
1177         if (!obj) {
1178                 DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
1179                 return -ENOENT;
1180         }
1181         gbo = drm_gem_vram_of_gem(obj);
1182 
1183         ret = drm_gem_vram_pin(gbo, 0);
1184         if (ret)
1185                 goto err_drm_gem_object_put_unlocked;
1186         src = drm_gem_vram_kmap(gbo, true, NULL);
1187         if (IS_ERR(src)) {
1188                 ret = PTR_ERR(src);
1189                 goto err_drm_gem_vram_unpin;
1190         }
1191 
1192         dst = drm_gem_vram_kmap(drm_gem_vram_of_gem(ast->cursor_cache),
1193                                 false, NULL);
1194         if (IS_ERR(dst)) {
1195                 ret = PTR_ERR(dst);
1196                 goto err_drm_gem_vram_kunmap;
1197         }
1198         dst_gpu = drm_gem_vram_offset(drm_gem_vram_of_gem(ast->cursor_cache));
1199         if (dst_gpu < 0) {
1200                 ret = (int)dst_gpu;
1201                 goto err_drm_gem_vram_kunmap;
1202         }
1203 
1204         dst += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor;
1205 
1206         /* do data transfer to cursor cache */
1207         csum = copy_cursor_image(src, dst, width, height);
1208 
1209         /* write checksum + signature */
1210         {
1211                 struct drm_gem_vram_object *dst_gbo =
1212                         drm_gem_vram_of_gem(ast->cursor_cache);
1213                 u8 *dst = drm_gem_vram_kmap(dst_gbo, false, NULL);
1214                 dst += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE;
1215                 writel(csum, dst);
1216                 writel(width, dst + AST_HWC_SIGNATURE_SizeX);
1217                 writel(height, dst + AST_HWC_SIGNATURE_SizeY);
1218                 writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX);
1219                 writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY);
1220 
1221                 /* set pattern offset */
1222                 gpu_addr = (u64)dst_gpu;
1223                 gpu_addr += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor;
1224                 gpu_addr >>= 3;
1225                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, gpu_addr & 0xff);
1226                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, (gpu_addr >> 8) & 0xff);
1227                 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, (gpu_addr >> 16) & 0xff);
1228         }
1229         ast_crtc->offset_x = AST_MAX_HWC_WIDTH - width;
1230         ast_crtc->offset_y = AST_MAX_HWC_WIDTH - height;
1231 
1232         ast->next_cursor = (ast->next_cursor + 1) % AST_DEFAULT_HWC_NUM;
1233 
1234         ast_show_cursor(crtc);
1235 
1236         drm_gem_vram_kunmap(gbo);
1237         drm_gem_vram_unpin(gbo);
1238         drm_gem_object_put_unlocked(obj);
1239 
1240         return 0;
1241 
1242 err_drm_gem_vram_kunmap:
1243         drm_gem_vram_kunmap(gbo);
1244 err_drm_gem_vram_unpin:
1245         drm_gem_vram_unpin(gbo);
1246 err_drm_gem_object_put_unlocked:
1247         drm_gem_object_put_unlocked(obj);
1248         return ret;
1249 }
1250 
1251 static int ast_cursor_move(struct drm_crtc *crtc,
1252                            int x, int y)
1253 {
1254         struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
1255         struct ast_private *ast = crtc->dev->dev_private;
1256         int x_offset, y_offset;
1257         u8 *sig;
1258 
1259         sig = drm_gem_vram_kmap(drm_gem_vram_of_gem(ast->cursor_cache),
1260                                 false, NULL);
1261         sig += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE;
1262         writel(x, sig + AST_HWC_SIGNATURE_X);
1263         writel(y, sig + AST_HWC_SIGNATURE_Y);
1264 
1265         x_offset = ast_crtc->offset_x;
1266         y_offset = ast_crtc->offset_y;
1267         if (x < 0) {
1268                 x_offset = (-x) + ast_crtc->offset_x;
1269                 x = 0;
1270         }
1271 
1272         if (y < 0) {
1273                 y_offset = (-y) + ast_crtc->offset_y;
1274                 y = 0;
1275         }
1276         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset);
1277         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset);
1278         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, (x & 0xff));
1279         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, ((x >> 8) & 0x0f));
1280         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, (y & 0xff));
1281         ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, ((y >> 8) & 0x07));
1282 
1283         /* dummy write to fire HWC */
1284         ast_show_cursor(crtc);
1285 
1286         return 0;
1287 }

/* [<][>][^][v][top][bottom][index][help] */