0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <linux/export.h>
0032 #include <linux/pci.h>
0033
0034 #include <drm/drm_atomic.h>
0035 #include <drm/drm_atomic_helper.h>
0036 #include <drm/drm_atomic_state_helper.h>
0037 #include <drm/drm_crtc.h>
0038 #include <drm/drm_crtc_helper.h>
0039 #include <drm/drm_edid.h>
0040 #include <drm/drm_fourcc.h>
0041 #include <drm/drm_gem_atomic_helper.h>
0042 #include <drm/drm_gem_framebuffer_helper.h>
0043 #include <drm/drm_gem_vram_helper.h>
0044 #include <drm/drm_managed.h>
0045 #include <drm/drm_plane_helper.h>
0046 #include <drm/drm_probe_helper.h>
0047 #include <drm/drm_simple_kms_helper.h>
0048
0049 #include "ast_drv.h"
0050 #include "ast_tables.h"
0051
0052 static inline void ast_load_palette_index(struct ast_private *ast,
0053 u8 index, u8 red, u8 green,
0054 u8 blue)
0055 {
0056 ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index);
0057 ast_io_read8(ast, AST_IO_SEQ_PORT);
0058 ast_io_write8(ast, AST_IO_DAC_DATA, red);
0059 ast_io_read8(ast, AST_IO_SEQ_PORT);
0060 ast_io_write8(ast, AST_IO_DAC_DATA, green);
0061 ast_io_read8(ast, AST_IO_SEQ_PORT);
0062 ast_io_write8(ast, AST_IO_DAC_DATA, blue);
0063 ast_io_read8(ast, AST_IO_SEQ_PORT);
0064 }
0065
0066 static void ast_crtc_load_lut(struct ast_private *ast, struct drm_crtc *crtc)
0067 {
0068 u16 *r, *g, *b;
0069 int i;
0070
0071 if (!crtc->enabled)
0072 return;
0073
0074 r = crtc->gamma_store;
0075 g = r + crtc->gamma_size;
0076 b = g + crtc->gamma_size;
0077
0078 for (i = 0; i < 256; i++)
0079 ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
0080 }
0081
0082 static bool ast_get_vbios_mode_info(const struct drm_format_info *format,
0083 const struct drm_display_mode *mode,
0084 struct drm_display_mode *adjusted_mode,
0085 struct ast_vbios_mode_info *vbios_mode)
0086 {
0087 u32 refresh_rate_index = 0, refresh_rate;
0088 const struct ast_vbios_enhtable *best = NULL;
0089 u32 hborder, vborder;
0090 bool check_sync;
0091
0092 switch (format->cpp[0] * 8) {
0093 case 8:
0094 vbios_mode->std_table = &vbios_stdtable[VGAModeIndex];
0095 break;
0096 case 16:
0097 vbios_mode->std_table = &vbios_stdtable[HiCModeIndex];
0098 break;
0099 case 24:
0100 case 32:
0101 vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex];
0102 break;
0103 default:
0104 return false;
0105 }
0106
0107 switch (mode->crtc_hdisplay) {
0108 case 640:
0109 vbios_mode->enh_table = &res_640x480[refresh_rate_index];
0110 break;
0111 case 800:
0112 vbios_mode->enh_table = &res_800x600[refresh_rate_index];
0113 break;
0114 case 1024:
0115 vbios_mode->enh_table = &res_1024x768[refresh_rate_index];
0116 break;
0117 case 1280:
0118 if (mode->crtc_vdisplay == 800)
0119 vbios_mode->enh_table = &res_1280x800[refresh_rate_index];
0120 else
0121 vbios_mode->enh_table = &res_1280x1024[refresh_rate_index];
0122 break;
0123 case 1360:
0124 vbios_mode->enh_table = &res_1360x768[refresh_rate_index];
0125 break;
0126 case 1440:
0127 vbios_mode->enh_table = &res_1440x900[refresh_rate_index];
0128 break;
0129 case 1600:
0130 if (mode->crtc_vdisplay == 900)
0131 vbios_mode->enh_table = &res_1600x900[refresh_rate_index];
0132 else
0133 vbios_mode->enh_table = &res_1600x1200[refresh_rate_index];
0134 break;
0135 case 1680:
0136 vbios_mode->enh_table = &res_1680x1050[refresh_rate_index];
0137 break;
0138 case 1920:
0139 if (mode->crtc_vdisplay == 1080)
0140 vbios_mode->enh_table = &res_1920x1080[refresh_rate_index];
0141 else
0142 vbios_mode->enh_table = &res_1920x1200[refresh_rate_index];
0143 break;
0144 default:
0145 return false;
0146 }
0147
0148 refresh_rate = drm_mode_vrefresh(mode);
0149 check_sync = vbios_mode->enh_table->flags & WideScreenMode;
0150
0151 while (1) {
0152 const struct ast_vbios_enhtable *loop = vbios_mode->enh_table;
0153
0154 while (loop->refresh_rate != 0xff) {
0155 if ((check_sync) &&
0156 (((mode->flags & DRM_MODE_FLAG_NVSYNC) &&
0157 (loop->flags & PVSync)) ||
0158 ((mode->flags & DRM_MODE_FLAG_PVSYNC) &&
0159 (loop->flags & NVSync)) ||
0160 ((mode->flags & DRM_MODE_FLAG_NHSYNC) &&
0161 (loop->flags & PHSync)) ||
0162 ((mode->flags & DRM_MODE_FLAG_PHSYNC) &&
0163 (loop->flags & NHSync)))) {
0164 loop++;
0165 continue;
0166 }
0167 if (loop->refresh_rate <= refresh_rate
0168 && (!best || loop->refresh_rate > best->refresh_rate))
0169 best = loop;
0170 loop++;
0171 }
0172 if (best || !check_sync)
0173 break;
0174 check_sync = 0;
0175 }
0176
0177 if (best)
0178 vbios_mode->enh_table = best;
0179
0180 hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0;
0181 vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0;
0182
0183 adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht;
0184 adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder;
0185 adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder;
0186 adjusted_mode->crtc_hsync_start = vbios_mode->enh_table->hde + hborder +
0187 vbios_mode->enh_table->hfp;
0188 adjusted_mode->crtc_hsync_end = (vbios_mode->enh_table->hde + hborder +
0189 vbios_mode->enh_table->hfp +
0190 vbios_mode->enh_table->hsync);
0191
0192 adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt;
0193 adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder;
0194 adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder;
0195 adjusted_mode->crtc_vsync_start = vbios_mode->enh_table->vde + vborder +
0196 vbios_mode->enh_table->vfp;
0197 adjusted_mode->crtc_vsync_end = (vbios_mode->enh_table->vde + vborder +
0198 vbios_mode->enh_table->vfp +
0199 vbios_mode->enh_table->vsync);
0200
0201 return true;
0202 }
0203
0204 static void ast_set_vbios_color_reg(struct ast_private *ast,
0205 const struct drm_format_info *format,
0206 const struct ast_vbios_mode_info *vbios_mode)
0207 {
0208 u32 color_index;
0209
0210 switch (format->cpp[0]) {
0211 case 1:
0212 color_index = VGAModeIndex - 1;
0213 break;
0214 case 2:
0215 color_index = HiCModeIndex;
0216 break;
0217 case 3:
0218 case 4:
0219 color_index = TrueCModeIndex;
0220 break;
0221 default:
0222 return;
0223 }
0224
0225 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4));
0226
0227 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
0228
0229 if (vbios_mode->enh_table->flags & NewModeInfo) {
0230 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
0231 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, format->cpp[0] * 8);
0232 }
0233 }
0234
0235 static void ast_set_vbios_mode_reg(struct ast_private *ast,
0236 const struct drm_display_mode *adjusted_mode,
0237 const struct ast_vbios_mode_info *vbios_mode)
0238 {
0239 u32 refresh_rate_index, mode_id;
0240
0241 refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
0242 mode_id = vbios_mode->enh_table->mode_id;
0243
0244 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
0245 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
0246
0247 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
0248
0249 if (vbios_mode->enh_table->flags & NewModeInfo) {
0250 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
0251 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
0252 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
0253 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
0254 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
0255 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
0256 }
0257 }
0258
0259 static void ast_set_std_reg(struct ast_private *ast,
0260 struct drm_display_mode *mode,
0261 struct ast_vbios_mode_info *vbios_mode)
0262 {
0263 const struct ast_vbios_stdtable *stdtable;
0264 u32 i;
0265 u8 jreg;
0266
0267 stdtable = vbios_mode->std_table;
0268
0269 jreg = stdtable->misc;
0270 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
0271
0272
0273 ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03);
0274 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]);
0275 for (i = 1; i < 4; i++) {
0276 jreg = stdtable->seq[i];
0277 ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1), jreg);
0278 }
0279
0280
0281 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
0282 for (i = 0; i < 12; i++)
0283 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
0284 for (i = 14; i < 19; i++)
0285 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
0286 for (i = 20; i < 25; i++)
0287 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
0288
0289
0290 jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
0291 for (i = 0; i < 20; i++) {
0292 jreg = stdtable->ar[i];
0293 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i);
0294 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg);
0295 }
0296 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14);
0297 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00);
0298
0299 jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
0300 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20);
0301
0302
0303 for (i = 0; i < 9; i++)
0304 ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]);
0305 }
0306
0307 static void ast_set_crtc_reg(struct ast_private *ast,
0308 struct drm_display_mode *mode,
0309 struct ast_vbios_mode_info *vbios_mode)
0310 {
0311 u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0;
0312 u16 temp, precache = 0;
0313
0314 if ((ast->chip == AST2500) &&
0315 (vbios_mode->enh_table->flags & AST2500PreCatchCRT))
0316 precache = 40;
0317
0318 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
0319
0320 temp = (mode->crtc_htotal >> 3) - 5;
0321 if (temp & 0x100)
0322 jregAC |= 0x01;
0323 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp);
0324
0325 temp = (mode->crtc_hdisplay >> 3) - 1;
0326 if (temp & 0x100)
0327 jregAC |= 0x04;
0328 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp);
0329
0330 temp = (mode->crtc_hblank_start >> 3) - 1;
0331 if (temp & 0x100)
0332 jregAC |= 0x10;
0333 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp);
0334
0335 temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f;
0336 if (temp & 0x20)
0337 jreg05 |= 0x80;
0338 if (temp & 0x40)
0339 jregAD |= 0x01;
0340 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f));
0341
0342 temp = ((mode->crtc_hsync_start-precache) >> 3) - 1;
0343 if (temp & 0x100)
0344 jregAC |= 0x40;
0345 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp);
0346
0347 temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f;
0348 if (temp & 0x20)
0349 jregAD |= 0x04;
0350 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05));
0351
0352 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC);
0353 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD);
0354
0355
0356 temp = (mode->crtc_vtotal) - 2;
0357 if (temp & 0x100)
0358 jreg07 |= 0x01;
0359 if (temp & 0x200)
0360 jreg07 |= 0x20;
0361 if (temp & 0x400)
0362 jregAE |= 0x01;
0363 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp);
0364
0365 temp = (mode->crtc_vsync_start) - 1;
0366 if (temp & 0x100)
0367 jreg07 |= 0x04;
0368 if (temp & 0x200)
0369 jreg07 |= 0x80;
0370 if (temp & 0x400)
0371 jregAE |= 0x08;
0372 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp);
0373
0374 temp = (mode->crtc_vsync_end - 1) & 0x3f;
0375 if (temp & 0x10)
0376 jregAE |= 0x20;
0377 if (temp & 0x20)
0378 jregAE |= 0x40;
0379 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf);
0380
0381 temp = mode->crtc_vdisplay - 1;
0382 if (temp & 0x100)
0383 jreg07 |= 0x02;
0384 if (temp & 0x200)
0385 jreg07 |= 0x40;
0386 if (temp & 0x400)
0387 jregAE |= 0x02;
0388 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp);
0389
0390 temp = mode->crtc_vblank_start - 1;
0391 if (temp & 0x100)
0392 jreg07 |= 0x08;
0393 if (temp & 0x200)
0394 jreg09 |= 0x20;
0395 if (temp & 0x400)
0396 jregAE |= 0x04;
0397 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp);
0398
0399 temp = mode->crtc_vblank_end - 1;
0400 if (temp & 0x100)
0401 jregAE |= 0x10;
0402 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp);
0403
0404 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07);
0405 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09);
0406 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80));
0407
0408 if (precache)
0409 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80);
0410 else
0411 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00);
0412
0413 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80);
0414 }
0415
0416 static void ast_set_offset_reg(struct ast_private *ast,
0417 struct drm_framebuffer *fb)
0418 {
0419 u16 offset;
0420
0421 offset = fb->pitches[0] >> 3;
0422 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff));
0423 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f);
0424 }
0425
0426 static void ast_set_dclk_reg(struct ast_private *ast,
0427 struct drm_display_mode *mode,
0428 struct ast_vbios_mode_info *vbios_mode)
0429 {
0430 const struct ast_vbios_dclk_info *clk_info;
0431
0432 if (ast->chip == AST2500)
0433 clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index];
0434 else
0435 clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
0436
0437 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1);
0438 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2);
0439 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f,
0440 (clk_info->param3 & 0xc0) |
0441 ((clk_info->param3 & 0x3) << 4));
0442 }
0443
0444 static void ast_set_color_reg(struct ast_private *ast,
0445 const struct drm_format_info *format)
0446 {
0447 u8 jregA0 = 0, jregA3 = 0, jregA8 = 0;
0448
0449 switch (format->cpp[0] * 8) {
0450 case 8:
0451 jregA0 = 0x70;
0452 jregA3 = 0x01;
0453 jregA8 = 0x00;
0454 break;
0455 case 15:
0456 case 16:
0457 jregA0 = 0x70;
0458 jregA3 = 0x04;
0459 jregA8 = 0x02;
0460 break;
0461 case 32:
0462 jregA0 = 0x70;
0463 jregA3 = 0x08;
0464 jregA8 = 0x02;
0465 break;
0466 }
0467
0468 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0);
0469 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3);
0470 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8);
0471 }
0472
0473 static void ast_set_crtthd_reg(struct ast_private *ast)
0474 {
0475
0476 if (ast->chip == AST2600) {
0477 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0xe0);
0478 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0xa0);
0479 } else if (ast->chip == AST2300 || ast->chip == AST2400 ||
0480 ast->chip == AST2500) {
0481 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78);
0482 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60);
0483 } else if (ast->chip == AST2100 ||
0484 ast->chip == AST1100 ||
0485 ast->chip == AST2200 ||
0486 ast->chip == AST2150) {
0487 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f);
0488 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f);
0489 } else {
0490 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f);
0491 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f);
0492 }
0493 }
0494
0495 static void ast_set_sync_reg(struct ast_private *ast,
0496 struct drm_display_mode *mode,
0497 struct ast_vbios_mode_info *vbios_mode)
0498 {
0499 u8 jreg;
0500
0501 jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ);
0502 jreg &= ~0xC0;
0503 if (vbios_mode->enh_table->flags & NVSync)
0504 jreg |= 0x80;
0505 if (vbios_mode->enh_table->flags & NHSync)
0506 jreg |= 0x40;
0507 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
0508 }
0509
0510 static void ast_set_start_address_crt1(struct ast_private *ast,
0511 unsigned int offset)
0512 {
0513 u32 addr;
0514
0515 addr = offset >> 2;
0516 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff));
0517 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff));
0518 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff));
0519
0520 }
0521
0522 static void ast_wait_for_vretrace(struct ast_private *ast)
0523 {
0524 unsigned long timeout = jiffies + HZ;
0525 u8 vgair1;
0526
0527 do {
0528 vgair1 = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
0529 } while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout));
0530 }
0531
0532
0533
0534
0535
0536 static const uint32_t ast_primary_plane_formats[] = {
0537 DRM_FORMAT_XRGB8888,
0538 DRM_FORMAT_RGB565,
0539 DRM_FORMAT_C8,
0540 };
0541
0542 static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane,
0543 struct drm_atomic_state *state)
0544 {
0545 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
0546 plane);
0547 struct drm_crtc_state *crtc_state;
0548 struct ast_crtc_state *ast_crtc_state;
0549 int ret;
0550
0551 if (!new_plane_state->crtc)
0552 return 0;
0553
0554 crtc_state = drm_atomic_get_new_crtc_state(state,
0555 new_plane_state->crtc);
0556
0557 ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
0558 DRM_PLANE_HELPER_NO_SCALING,
0559 DRM_PLANE_HELPER_NO_SCALING,
0560 false, true);
0561 if (ret)
0562 return ret;
0563
0564 if (!new_plane_state->visible)
0565 return 0;
0566
0567 ast_crtc_state = to_ast_crtc_state(crtc_state);
0568
0569 ast_crtc_state->format = new_plane_state->fb->format;
0570
0571 return 0;
0572 }
0573
0574 static void
0575 ast_primary_plane_helper_atomic_update(struct drm_plane *plane,
0576 struct drm_atomic_state *state)
0577 {
0578 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
0579 plane);
0580 struct drm_device *dev = plane->dev;
0581 struct ast_private *ast = to_ast_private(dev);
0582 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
0583 plane);
0584 struct drm_gem_vram_object *gbo;
0585 s64 gpu_addr;
0586 struct drm_framebuffer *fb = new_state->fb;
0587 struct drm_framebuffer *old_fb = old_state->fb;
0588
0589 if (!old_fb || (fb->format != old_fb->format)) {
0590 struct drm_crtc_state *crtc_state = new_state->crtc->state;
0591 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
0592 struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
0593
0594 ast_set_color_reg(ast, fb->format);
0595 ast_set_vbios_color_reg(ast, fb->format, vbios_mode_info);
0596 }
0597
0598 gbo = drm_gem_vram_of_gem(fb->obj[0]);
0599 gpu_addr = drm_gem_vram_offset(gbo);
0600 if (drm_WARN_ON_ONCE(dev, gpu_addr < 0))
0601 return;
0602
0603 ast_set_offset_reg(ast, fb);
0604 ast_set_start_address_crt1(ast, (u32)gpu_addr);
0605
0606 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00);
0607 }
0608
0609 static void
0610 ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
0611 struct drm_atomic_state *state)
0612 {
0613 struct ast_private *ast = to_ast_private(plane->dev);
0614
0615 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);
0616 }
0617
0618 static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = {
0619 DRM_GEM_VRAM_PLANE_HELPER_FUNCS,
0620 .atomic_check = ast_primary_plane_helper_atomic_check,
0621 .atomic_update = ast_primary_plane_helper_atomic_update,
0622 .atomic_disable = ast_primary_plane_helper_atomic_disable,
0623 };
0624
0625 static const struct drm_plane_funcs ast_primary_plane_funcs = {
0626 .update_plane = drm_atomic_helper_update_plane,
0627 .disable_plane = drm_atomic_helper_disable_plane,
0628 .destroy = drm_plane_cleanup,
0629 .reset = drm_atomic_helper_plane_reset,
0630 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
0631 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
0632 };
0633
0634 static int ast_primary_plane_init(struct ast_private *ast)
0635 {
0636 struct drm_device *dev = &ast->base;
0637 struct drm_plane *primary_plane = &ast->primary_plane;
0638 int ret;
0639
0640 ret = drm_universal_plane_init(dev, primary_plane, 0x01,
0641 &ast_primary_plane_funcs,
0642 ast_primary_plane_formats,
0643 ARRAY_SIZE(ast_primary_plane_formats),
0644 NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
0645 if (ret) {
0646 drm_err(dev, "drm_universal_plane_init() failed: %d\n", ret);
0647 return ret;
0648 }
0649 drm_plane_helper_add(primary_plane, &ast_primary_plane_helper_funcs);
0650
0651 return 0;
0652 }
0653
0654
0655
0656
0657
0658 static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, int width, int height)
0659 {
0660 union {
0661 u32 ul;
0662 u8 b[4];
0663 } srcdata32[2], data32;
0664 union {
0665 u16 us;
0666 u8 b[2];
0667 } data16;
0668 u32 csum = 0;
0669 s32 alpha_dst_delta, last_alpha_dst_delta;
0670 u8 __iomem *dstxor;
0671 const u8 *srcxor;
0672 int i, j;
0673 u32 per_pixel_copy, two_pixel_copy;
0674
0675 alpha_dst_delta = AST_MAX_HWC_WIDTH << 1;
0676 last_alpha_dst_delta = alpha_dst_delta - (width << 1);
0677
0678 srcxor = src;
0679 dstxor = (u8 *)dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta;
0680 per_pixel_copy = width & 1;
0681 two_pixel_copy = width >> 1;
0682
0683 for (j = 0; j < height; j++) {
0684 for (i = 0; i < two_pixel_copy; i++) {
0685 srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
0686 srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0;
0687 data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
0688 data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
0689 data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4);
0690 data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4);
0691
0692 writel(data32.ul, dstxor);
0693 csum += data32.ul;
0694
0695 dstxor += 4;
0696 srcxor += 8;
0697
0698 }
0699
0700 for (i = 0; i < per_pixel_copy; i++) {
0701 srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
0702 data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
0703 data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
0704 writew(data16.us, dstxor);
0705 csum += (u32)data16.us;
0706
0707 dstxor += 2;
0708 srcxor += 4;
0709 }
0710 dstxor += last_alpha_dst_delta;
0711 }
0712
0713
0714 dst += AST_HWC_SIZE;
0715 writel(csum, dst);
0716 writel(width, dst + AST_HWC_SIGNATURE_SizeX);
0717 writel(height, dst + AST_HWC_SIGNATURE_SizeY);
0718 writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX);
0719 writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY);
0720 }
0721
0722 static void ast_set_cursor_base(struct ast_private *ast, u64 address)
0723 {
0724 u8 addr0 = (address >> 3) & 0xff;
0725 u8 addr1 = (address >> 11) & 0xff;
0726 u8 addr2 = (address >> 19) & 0xff;
0727
0728 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0);
0729 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1);
0730 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2);
0731 }
0732
0733 static void ast_set_cursor_location(struct ast_private *ast, u16 x, u16 y,
0734 u8 x_offset, u8 y_offset)
0735 {
0736 u8 x0 = (x & 0x00ff);
0737 u8 x1 = (x & 0x0f00) >> 8;
0738 u8 y0 = (y & 0x00ff);
0739 u8 y1 = (y & 0x0700) >> 8;
0740
0741 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset);
0742 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset);
0743 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0);
0744 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1);
0745 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0);
0746 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1);
0747 }
0748
0749 static void ast_set_cursor_enabled(struct ast_private *ast, bool enabled)
0750 {
0751 static const u8 mask = (u8)~(AST_IO_VGACRCB_HWC_16BPP |
0752 AST_IO_VGACRCB_HWC_ENABLED);
0753
0754 u8 vgacrcb = AST_IO_VGACRCB_HWC_16BPP;
0755
0756 if (enabled)
0757 vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED;
0758
0759 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, mask, vgacrcb);
0760 }
0761
0762 static const uint32_t ast_cursor_plane_formats[] = {
0763 DRM_FORMAT_ARGB8888,
0764 };
0765
0766 static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane,
0767 struct drm_atomic_state *state)
0768 {
0769 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
0770 plane);
0771 struct drm_framebuffer *fb = new_plane_state->fb;
0772 struct drm_crtc_state *crtc_state;
0773 int ret;
0774
0775 if (!new_plane_state->crtc)
0776 return 0;
0777
0778 crtc_state = drm_atomic_get_new_crtc_state(state,
0779 new_plane_state->crtc);
0780
0781 ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
0782 DRM_PLANE_HELPER_NO_SCALING,
0783 DRM_PLANE_HELPER_NO_SCALING,
0784 true, true);
0785 if (ret)
0786 return ret;
0787
0788 if (!new_plane_state->visible)
0789 return 0;
0790
0791 if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT)
0792 return -EINVAL;
0793
0794 return 0;
0795 }
0796
0797 static void
0798 ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
0799 struct drm_atomic_state *state)
0800 {
0801 struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
0802 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
0803 plane);
0804 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
0805 plane);
0806 struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(new_state);
0807 struct drm_framebuffer *fb = new_state->fb;
0808 struct ast_private *ast = to_ast_private(plane->dev);
0809 struct iosys_map dst_map =
0810 ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
0811 u64 dst_off =
0812 ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].off;
0813 struct iosys_map src_map = shadow_plane_state->data[0];
0814 unsigned int offset_x, offset_y;
0815 u16 x, y;
0816 u8 x_offset, y_offset;
0817 u8 __iomem *dst;
0818 u8 __iomem *sig;
0819 const u8 *src;
0820
0821 src = src_map.vaddr;
0822 dst = dst_map.vaddr_iomem;
0823 sig = dst + AST_HWC_SIZE;
0824
0825
0826
0827
0828
0829
0830 ast_update_cursor_image(dst, src, fb->width, fb->height);
0831
0832 if (new_state->fb != old_state->fb) {
0833 ast_set_cursor_base(ast, dst_off);
0834
0835 ++ast_cursor_plane->next_hwc_index;
0836 ast_cursor_plane->next_hwc_index %= ARRAY_SIZE(ast_cursor_plane->hwc);
0837 }
0838
0839
0840
0841
0842
0843 writel(new_state->crtc_x, sig + AST_HWC_SIGNATURE_X);
0844 writel(new_state->crtc_y, sig + AST_HWC_SIGNATURE_Y);
0845
0846 offset_x = AST_MAX_HWC_WIDTH - fb->width;
0847 offset_y = AST_MAX_HWC_HEIGHT - fb->height;
0848
0849 if (new_state->crtc_x < 0) {
0850 x_offset = (-new_state->crtc_x) + offset_x;
0851 x = 0;
0852 } else {
0853 x_offset = offset_x;
0854 x = new_state->crtc_x;
0855 }
0856 if (new_state->crtc_y < 0) {
0857 y_offset = (-new_state->crtc_y) + offset_y;
0858 y = 0;
0859 } else {
0860 y_offset = offset_y;
0861 y = new_state->crtc_y;
0862 }
0863
0864 ast_set_cursor_location(ast, x, y, x_offset, y_offset);
0865
0866
0867 ast_set_cursor_enabled(ast, true);
0868 }
0869
0870 static void
0871 ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,
0872 struct drm_atomic_state *state)
0873 {
0874 struct ast_private *ast = to_ast_private(plane->dev);
0875
0876 ast_set_cursor_enabled(ast, false);
0877 }
0878
0879 static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = {
0880 DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
0881 .atomic_check = ast_cursor_plane_helper_atomic_check,
0882 .atomic_update = ast_cursor_plane_helper_atomic_update,
0883 .atomic_disable = ast_cursor_plane_helper_atomic_disable,
0884 };
0885
0886 static void ast_cursor_plane_destroy(struct drm_plane *plane)
0887 {
0888 struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
0889 size_t i;
0890 struct drm_gem_vram_object *gbo;
0891 struct iosys_map map;
0892
0893 for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
0894 gbo = ast_cursor_plane->hwc[i].gbo;
0895 map = ast_cursor_plane->hwc[i].map;
0896 drm_gem_vram_vunmap(gbo, &map);
0897 drm_gem_vram_unpin(gbo);
0898 drm_gem_vram_put(gbo);
0899 }
0900
0901 drm_plane_cleanup(plane);
0902 }
0903
0904 static const struct drm_plane_funcs ast_cursor_plane_funcs = {
0905 .update_plane = drm_atomic_helper_update_plane,
0906 .disable_plane = drm_atomic_helper_disable_plane,
0907 .destroy = ast_cursor_plane_destroy,
0908 DRM_GEM_SHADOW_PLANE_FUNCS,
0909 };
0910
0911 static int ast_cursor_plane_init(struct ast_private *ast)
0912 {
0913 struct drm_device *dev = &ast->base;
0914 struct ast_cursor_plane *ast_cursor_plane = &ast->cursor_plane;
0915 struct drm_plane *cursor_plane = &ast_cursor_plane->base;
0916 size_t size, i;
0917 struct drm_gem_vram_object *gbo;
0918 struct iosys_map map;
0919 int ret;
0920 s64 off;
0921
0922
0923
0924
0925
0926
0927 size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE);
0928
0929 for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
0930 gbo = drm_gem_vram_create(dev, size, 0);
0931 if (IS_ERR(gbo)) {
0932 ret = PTR_ERR(gbo);
0933 goto err_hwc;
0934 }
0935 ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM |
0936 DRM_GEM_VRAM_PL_FLAG_TOPDOWN);
0937 if (ret)
0938 goto err_drm_gem_vram_put;
0939 ret = drm_gem_vram_vmap(gbo, &map);
0940 if (ret)
0941 goto err_drm_gem_vram_unpin;
0942 off = drm_gem_vram_offset(gbo);
0943 if (off < 0) {
0944 ret = off;
0945 goto err_drm_gem_vram_vunmap;
0946 }
0947 ast_cursor_plane->hwc[i].gbo = gbo;
0948 ast_cursor_plane->hwc[i].map = map;
0949 ast_cursor_plane->hwc[i].off = off;
0950 }
0951
0952
0953
0954
0955
0956
0957 ret = drm_universal_plane_init(dev, cursor_plane, 0x01,
0958 &ast_cursor_plane_funcs,
0959 ast_cursor_plane_formats,
0960 ARRAY_SIZE(ast_cursor_plane_formats),
0961 NULL, DRM_PLANE_TYPE_CURSOR, NULL);
0962 if (ret) {
0963 drm_err(dev, "drm_universal_plane failed(): %d\n", ret);
0964 goto err_hwc;
0965 }
0966 drm_plane_helper_add(cursor_plane, &ast_cursor_plane_helper_funcs);
0967
0968 return 0;
0969
0970 err_hwc:
0971 while (i) {
0972 --i;
0973 gbo = ast_cursor_plane->hwc[i].gbo;
0974 map = ast_cursor_plane->hwc[i].map;
0975 err_drm_gem_vram_vunmap:
0976 drm_gem_vram_vunmap(gbo, &map);
0977 err_drm_gem_vram_unpin:
0978 drm_gem_vram_unpin(gbo);
0979 err_drm_gem_vram_put:
0980 drm_gem_vram_put(gbo);
0981 }
0982 return ret;
0983 }
0984
0985
0986
0987
0988
0989 static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
0990 {
0991 struct ast_private *ast = to_ast_private(crtc->dev);
0992 u8 ch = AST_DPMS_VSYNC_OFF | AST_DPMS_HSYNC_OFF;
0993 struct ast_crtc_state *ast_state;
0994 const struct drm_format_info *format;
0995 struct ast_vbios_mode_info *vbios_mode_info;
0996
0997
0998
0999
1000 switch (mode) {
1001 case DRM_MODE_DPMS_ON:
1002 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0);
1003 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0);
1004 if (ast->tx_chip_types & AST_TX_DP501_BIT)
1005 ast_set_dp501_video_output(crtc->dev, 1);
1006
1007 if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
1008 ast_dp_power_on_off(crtc->dev, AST_DP_POWER_ON);
1009 ast_wait_for_vretrace(ast);
1010 ast_dp_set_on_off(crtc->dev, 1);
1011 }
1012
1013 ast_state = to_ast_crtc_state(crtc->state);
1014 format = ast_state->format;
1015
1016 if (format) {
1017 vbios_mode_info = &ast_state->vbios_mode_info;
1018
1019 ast_set_color_reg(ast, format);
1020 ast_set_vbios_color_reg(ast, format, vbios_mode_info);
1021 }
1022
1023 ast_crtc_load_lut(ast, crtc);
1024 break;
1025 case DRM_MODE_DPMS_STANDBY:
1026 case DRM_MODE_DPMS_SUSPEND:
1027 case DRM_MODE_DPMS_OFF:
1028 ch = mode;
1029 if (ast->tx_chip_types & AST_TX_DP501_BIT)
1030 ast_set_dp501_video_output(crtc->dev, 0);
1031
1032 if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
1033 ast_dp_set_on_off(crtc->dev, 0);
1034 ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF);
1035 }
1036
1037 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0x20);
1038 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch);
1039 break;
1040 }
1041 }
1042
1043 static enum drm_mode_status
1044 ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
1045 {
1046 struct ast_private *ast = to_ast_private(crtc->dev);
1047 enum drm_mode_status status;
1048 uint32_t jtemp;
1049
1050 if (ast->support_wide_screen) {
1051 if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050))
1052 return MODE_OK;
1053 if ((mode->hdisplay == 1280) && (mode->vdisplay == 800))
1054 return MODE_OK;
1055 if ((mode->hdisplay == 1440) && (mode->vdisplay == 900))
1056 return MODE_OK;
1057 if ((mode->hdisplay == 1360) && (mode->vdisplay == 768))
1058 return MODE_OK;
1059 if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
1060 return MODE_OK;
1061
1062 if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
1063 (ast->chip == AST2300) || (ast->chip == AST2400) ||
1064 (ast->chip == AST2500) || (ast->chip == AST2600)) {
1065 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))
1066 return MODE_OK;
1067
1068 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) {
1069 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
1070 if (jtemp & 0x01)
1071 return MODE_NOMODE;
1072 else
1073 return MODE_OK;
1074 }
1075 }
1076 }
1077
1078 status = MODE_NOMODE;
1079
1080 switch (mode->hdisplay) {
1081 case 640:
1082 if (mode->vdisplay == 480)
1083 status = MODE_OK;
1084 break;
1085 case 800:
1086 if (mode->vdisplay == 600)
1087 status = MODE_OK;
1088 break;
1089 case 1024:
1090 if (mode->vdisplay == 768)
1091 status = MODE_OK;
1092 break;
1093 case 1280:
1094 if (mode->vdisplay == 1024)
1095 status = MODE_OK;
1096 break;
1097 case 1600:
1098 if (mode->vdisplay == 1200)
1099 status = MODE_OK;
1100 break;
1101 default:
1102 break;
1103 }
1104
1105 return status;
1106 }
1107
1108 static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
1109 struct drm_atomic_state *state)
1110 {
1111 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1112 struct drm_device *dev = crtc->dev;
1113 struct ast_crtc_state *ast_state;
1114 const struct drm_format_info *format;
1115 bool succ;
1116 int ret;
1117
1118 ret = drm_atomic_helper_check_crtc_state(crtc_state, false);
1119 if (ret)
1120 return ret;
1121
1122 if (!crtc_state->enable)
1123 goto out;
1124
1125 ast_state = to_ast_crtc_state(crtc_state);
1126
1127 format = ast_state->format;
1128 if (drm_WARN_ON_ONCE(dev, !format))
1129 return -EINVAL;
1130
1131 succ = ast_get_vbios_mode_info(format, &crtc_state->mode,
1132 &crtc_state->adjusted_mode,
1133 &ast_state->vbios_mode_info);
1134 if (!succ)
1135 return -EINVAL;
1136
1137 out:
1138 return drm_atomic_add_affected_planes(state, crtc);
1139 }
1140
1141 static void ast_crtc_helper_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
1142 {
1143 struct drm_device *dev = crtc->dev;
1144 struct ast_private *ast = to_ast_private(dev);
1145
1146
1147
1148
1149
1150
1151
1152 mutex_lock(&ast->ioregs_lock);
1153 }
1154
1155 static void
1156 ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
1157 struct drm_atomic_state *state)
1158 {
1159 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
1160 crtc);
1161 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
1162 crtc);
1163 struct drm_device *dev = crtc->dev;
1164 struct ast_private *ast = to_ast_private(dev);
1165 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
1166 struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state);
1167 struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
1168
1169
1170
1171
1172
1173 if (old_ast_crtc_state->format != ast_crtc_state->format)
1174 ast_crtc_load_lut(ast, crtc);
1175
1176
1177 if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
1178 ast_dp_set_mode(crtc, vbios_mode_info);
1179
1180 mutex_unlock(&ast->ioregs_lock);
1181 }
1182
1183 static void
1184 ast_crtc_helper_atomic_enable(struct drm_crtc *crtc,
1185 struct drm_atomic_state *state)
1186 {
1187 struct drm_device *dev = crtc->dev;
1188 struct ast_private *ast = to_ast_private(dev);
1189 struct drm_crtc_state *crtc_state = crtc->state;
1190 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
1191 struct ast_vbios_mode_info *vbios_mode_info =
1192 &ast_crtc_state->vbios_mode_info;
1193 struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
1194
1195 ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
1196 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
1197 ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
1198 ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
1199 ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
1200 ast_set_crtthd_reg(ast);
1201 ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
1202
1203 ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
1204 }
1205
1206 static void
1207 ast_crtc_helper_atomic_disable(struct drm_crtc *crtc,
1208 struct drm_atomic_state *state)
1209 {
1210 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
1211 crtc);
1212 struct drm_device *dev = crtc->dev;
1213 struct ast_private *ast = to_ast_private(dev);
1214
1215 ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227 drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
1228
1229
1230
1231
1232
1233 ast_wait_for_vretrace(ast);
1234 }
1235
1236 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
1237 .mode_valid = ast_crtc_helper_mode_valid,
1238 .atomic_check = ast_crtc_helper_atomic_check,
1239 .atomic_begin = ast_crtc_helper_atomic_begin,
1240 .atomic_flush = ast_crtc_helper_atomic_flush,
1241 .atomic_enable = ast_crtc_helper_atomic_enable,
1242 .atomic_disable = ast_crtc_helper_atomic_disable,
1243 };
1244
1245 static void ast_crtc_reset(struct drm_crtc *crtc)
1246 {
1247 struct ast_crtc_state *ast_state =
1248 kzalloc(sizeof(*ast_state), GFP_KERNEL);
1249
1250 if (crtc->state)
1251 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
1252
1253 if (ast_state)
1254 __drm_atomic_helper_crtc_reset(crtc, &ast_state->base);
1255 else
1256 __drm_atomic_helper_crtc_reset(crtc, NULL);
1257 }
1258
1259 static struct drm_crtc_state *
1260 ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
1261 {
1262 struct ast_crtc_state *new_ast_state, *ast_state;
1263 struct drm_device *dev = crtc->dev;
1264
1265 if (drm_WARN_ON(dev, !crtc->state))
1266 return NULL;
1267
1268 new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL);
1269 if (!new_ast_state)
1270 return NULL;
1271 __drm_atomic_helper_crtc_duplicate_state(crtc, &new_ast_state->base);
1272
1273 ast_state = to_ast_crtc_state(crtc->state);
1274
1275 new_ast_state->format = ast_state->format;
1276 memcpy(&new_ast_state->vbios_mode_info, &ast_state->vbios_mode_info,
1277 sizeof(new_ast_state->vbios_mode_info));
1278
1279 return &new_ast_state->base;
1280 }
1281
1282 static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc,
1283 struct drm_crtc_state *state)
1284 {
1285 struct ast_crtc_state *ast_state = to_ast_crtc_state(state);
1286
1287 __drm_atomic_helper_crtc_destroy_state(&ast_state->base);
1288 kfree(ast_state);
1289 }
1290
1291 static const struct drm_crtc_funcs ast_crtc_funcs = {
1292 .reset = ast_crtc_reset,
1293 .destroy = drm_crtc_cleanup,
1294 .set_config = drm_atomic_helper_set_config,
1295 .page_flip = drm_atomic_helper_page_flip,
1296 .atomic_duplicate_state = ast_crtc_atomic_duplicate_state,
1297 .atomic_destroy_state = ast_crtc_atomic_destroy_state,
1298 };
1299
1300 static int ast_crtc_init(struct drm_device *dev)
1301 {
1302 struct ast_private *ast = to_ast_private(dev);
1303 struct drm_crtc *crtc = &ast->crtc;
1304 int ret;
1305
1306 ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane,
1307 &ast->cursor_plane.base, &ast_crtc_funcs,
1308 NULL);
1309 if (ret)
1310 return ret;
1311
1312 drm_mode_crtc_set_gamma_size(crtc, 256);
1313 drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs);
1314
1315 return 0;
1316 }
1317
1318
1319
1320
1321
1322 static int ast_vga_connector_helper_get_modes(struct drm_connector *connector)
1323 {
1324 struct ast_vga_connector *ast_vga_connector = to_ast_vga_connector(connector);
1325 struct drm_device *dev = connector->dev;
1326 struct ast_private *ast = to_ast_private(dev);
1327 struct edid *edid;
1328 int count;
1329
1330 if (!ast_vga_connector->i2c)
1331 goto err_drm_connector_update_edid_property;
1332
1333
1334
1335
1336
1337 mutex_lock(&ast->ioregs_lock);
1338
1339 edid = drm_get_edid(connector, &ast_vga_connector->i2c->adapter);
1340 if (!edid)
1341 goto err_mutex_unlock;
1342
1343 mutex_unlock(&ast->ioregs_lock);
1344
1345 count = drm_add_edid_modes(connector, edid);
1346 kfree(edid);
1347
1348 return count;
1349
1350 err_mutex_unlock:
1351 mutex_unlock(&ast->ioregs_lock);
1352 err_drm_connector_update_edid_property:
1353 drm_connector_update_edid_property(connector, NULL);
1354 return 0;
1355 }
1356
1357 static const struct drm_connector_helper_funcs ast_vga_connector_helper_funcs = {
1358 .get_modes = ast_vga_connector_helper_get_modes,
1359 };
1360
1361 static const struct drm_connector_funcs ast_vga_connector_funcs = {
1362 .reset = drm_atomic_helper_connector_reset,
1363 .fill_modes = drm_helper_probe_single_connector_modes,
1364 .destroy = drm_connector_cleanup,
1365 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1366 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1367 };
1368
1369 static int ast_vga_connector_init(struct drm_device *dev,
1370 struct ast_vga_connector *ast_vga_connector)
1371 {
1372 struct drm_connector *connector = &ast_vga_connector->base;
1373 int ret;
1374
1375 ast_vga_connector->i2c = ast_i2c_create(dev);
1376 if (!ast_vga_connector->i2c)
1377 drm_err(dev, "failed to add ddc bus for connector\n");
1378
1379 if (ast_vga_connector->i2c)
1380 ret = drm_connector_init_with_ddc(dev, connector, &ast_vga_connector_funcs,
1381 DRM_MODE_CONNECTOR_VGA,
1382 &ast_vga_connector->i2c->adapter);
1383 else
1384 ret = drm_connector_init(dev, connector, &ast_vga_connector_funcs,
1385 DRM_MODE_CONNECTOR_VGA);
1386 if (ret)
1387 return ret;
1388
1389 drm_connector_helper_add(connector, &ast_vga_connector_helper_funcs);
1390
1391 connector->interlace_allowed = 0;
1392 connector->doublescan_allowed = 0;
1393
1394 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1395
1396 return 0;
1397 }
1398
1399 static int ast_vga_output_init(struct ast_private *ast)
1400 {
1401 struct drm_device *dev = &ast->base;
1402 struct drm_crtc *crtc = &ast->crtc;
1403 struct drm_encoder *encoder = &ast->output.vga.encoder;
1404 struct ast_vga_connector *ast_vga_connector = &ast->output.vga.vga_connector;
1405 struct drm_connector *connector = &ast_vga_connector->base;
1406 int ret;
1407
1408 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC);
1409 if (ret)
1410 return ret;
1411 encoder->possible_crtcs = drm_crtc_mask(crtc);
1412
1413 ret = ast_vga_connector_init(dev, ast_vga_connector);
1414 if (ret)
1415 return ret;
1416
1417 ret = drm_connector_attach_encoder(connector, encoder);
1418 if (ret)
1419 return ret;
1420
1421 return 0;
1422 }
1423
1424
1425
1426
1427
1428 static int ast_sil164_connector_helper_get_modes(struct drm_connector *connector)
1429 {
1430 struct ast_sil164_connector *ast_sil164_connector = to_ast_sil164_connector(connector);
1431 struct drm_device *dev = connector->dev;
1432 struct ast_private *ast = to_ast_private(dev);
1433 struct edid *edid;
1434 int count;
1435
1436 if (!ast_sil164_connector->i2c)
1437 goto err_drm_connector_update_edid_property;
1438
1439
1440
1441
1442
1443 mutex_lock(&ast->ioregs_lock);
1444
1445 edid = drm_get_edid(connector, &ast_sil164_connector->i2c->adapter);
1446 if (!edid)
1447 goto err_mutex_unlock;
1448
1449 mutex_unlock(&ast->ioregs_lock);
1450
1451 count = drm_add_edid_modes(connector, edid);
1452 kfree(edid);
1453
1454 return count;
1455
1456 err_mutex_unlock:
1457 mutex_unlock(&ast->ioregs_lock);
1458 err_drm_connector_update_edid_property:
1459 drm_connector_update_edid_property(connector, NULL);
1460 return 0;
1461 }
1462
1463 static const struct drm_connector_helper_funcs ast_sil164_connector_helper_funcs = {
1464 .get_modes = ast_sil164_connector_helper_get_modes,
1465 };
1466
1467 static const struct drm_connector_funcs ast_sil164_connector_funcs = {
1468 .reset = drm_atomic_helper_connector_reset,
1469 .fill_modes = drm_helper_probe_single_connector_modes,
1470 .destroy = drm_connector_cleanup,
1471 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1472 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1473 };
1474
1475 static int ast_sil164_connector_init(struct drm_device *dev,
1476 struct ast_sil164_connector *ast_sil164_connector)
1477 {
1478 struct drm_connector *connector = &ast_sil164_connector->base;
1479 int ret;
1480
1481 ast_sil164_connector->i2c = ast_i2c_create(dev);
1482 if (!ast_sil164_connector->i2c)
1483 drm_err(dev, "failed to add ddc bus for connector\n");
1484
1485 if (ast_sil164_connector->i2c)
1486 ret = drm_connector_init_with_ddc(dev, connector, &ast_sil164_connector_funcs,
1487 DRM_MODE_CONNECTOR_DVII,
1488 &ast_sil164_connector->i2c->adapter);
1489 else
1490 ret = drm_connector_init(dev, connector, &ast_sil164_connector_funcs,
1491 DRM_MODE_CONNECTOR_DVII);
1492 if (ret)
1493 return ret;
1494
1495 drm_connector_helper_add(connector, &ast_sil164_connector_helper_funcs);
1496
1497 connector->interlace_allowed = 0;
1498 connector->doublescan_allowed = 0;
1499
1500 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1501
1502 return 0;
1503 }
1504
1505 static int ast_sil164_output_init(struct ast_private *ast)
1506 {
1507 struct drm_device *dev = &ast->base;
1508 struct drm_crtc *crtc = &ast->crtc;
1509 struct drm_encoder *encoder = &ast->output.sil164.encoder;
1510 struct ast_sil164_connector *ast_sil164_connector = &ast->output.sil164.sil164_connector;
1511 struct drm_connector *connector = &ast_sil164_connector->base;
1512 int ret;
1513
1514 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
1515 if (ret)
1516 return ret;
1517 encoder->possible_crtcs = drm_crtc_mask(crtc);
1518
1519 ret = ast_sil164_connector_init(dev, ast_sil164_connector);
1520 if (ret)
1521 return ret;
1522
1523 ret = drm_connector_attach_encoder(connector, encoder);
1524 if (ret)
1525 return ret;
1526
1527 return 0;
1528 }
1529
1530
1531
1532
1533
1534 static int ast_dp501_connector_helper_get_modes(struct drm_connector *connector)
1535 {
1536 void *edid;
1537 bool succ;
1538 int count;
1539
1540 edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
1541 if (!edid)
1542 goto err_drm_connector_update_edid_property;
1543
1544 succ = ast_dp501_read_edid(connector->dev, edid);
1545 if (!succ)
1546 goto err_kfree;
1547
1548 drm_connector_update_edid_property(connector, edid);
1549 count = drm_add_edid_modes(connector, edid);
1550 kfree(edid);
1551
1552 return count;
1553
1554 err_kfree:
1555 kfree(edid);
1556 err_drm_connector_update_edid_property:
1557 drm_connector_update_edid_property(connector, NULL);
1558 return 0;
1559 }
1560
1561 static const struct drm_connector_helper_funcs ast_dp501_connector_helper_funcs = {
1562 .get_modes = ast_dp501_connector_helper_get_modes,
1563 };
1564
1565 static const struct drm_connector_funcs ast_dp501_connector_funcs = {
1566 .reset = drm_atomic_helper_connector_reset,
1567 .fill_modes = drm_helper_probe_single_connector_modes,
1568 .destroy = drm_connector_cleanup,
1569 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1570 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1571 };
1572
1573 static int ast_dp501_connector_init(struct drm_device *dev, struct drm_connector *connector)
1574 {
1575 int ret;
1576
1577 ret = drm_connector_init(dev, connector, &ast_dp501_connector_funcs,
1578 DRM_MODE_CONNECTOR_DisplayPort);
1579 if (ret)
1580 return ret;
1581
1582 drm_connector_helper_add(connector, &ast_dp501_connector_helper_funcs);
1583
1584 connector->interlace_allowed = 0;
1585 connector->doublescan_allowed = 0;
1586
1587 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1588
1589 return 0;
1590 }
1591
1592 static int ast_dp501_output_init(struct ast_private *ast)
1593 {
1594 struct drm_device *dev = &ast->base;
1595 struct drm_crtc *crtc = &ast->crtc;
1596 struct drm_encoder *encoder = &ast->output.dp501.encoder;
1597 struct drm_connector *connector = &ast->output.dp501.connector;
1598 int ret;
1599
1600 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
1601 if (ret)
1602 return ret;
1603 encoder->possible_crtcs = drm_crtc_mask(crtc);
1604
1605 ret = ast_dp501_connector_init(dev, connector);
1606 if (ret)
1607 return ret;
1608
1609 ret = drm_connector_attach_encoder(connector, encoder);
1610 if (ret)
1611 return ret;
1612
1613 return 0;
1614 }
1615
1616
1617
1618
1619
1620 static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
1621 {
1622 void *edid;
1623
1624 int succ;
1625 int count;
1626
1627 edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
1628 if (!edid)
1629 goto err_drm_connector_update_edid_property;
1630
1631 succ = ast_astdp_read_edid(connector->dev, edid);
1632 if (succ < 0)
1633 goto err_kfree;
1634
1635 drm_connector_update_edid_property(connector, edid);
1636 count = drm_add_edid_modes(connector, edid);
1637 kfree(edid);
1638
1639 return count;
1640
1641 err_kfree:
1642 kfree(edid);
1643 err_drm_connector_update_edid_property:
1644 drm_connector_update_edid_property(connector, NULL);
1645 return 0;
1646 }
1647
1648 static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs = {
1649 .get_modes = ast_astdp_connector_helper_get_modes,
1650 };
1651
1652 static const struct drm_connector_funcs ast_astdp_connector_funcs = {
1653 .reset = drm_atomic_helper_connector_reset,
1654 .fill_modes = drm_helper_probe_single_connector_modes,
1655 .destroy = drm_connector_cleanup,
1656 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1657 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1658 };
1659
1660 static int ast_astdp_connector_init(struct drm_device *dev, struct drm_connector *connector)
1661 {
1662 int ret;
1663
1664 ret = drm_connector_init(dev, connector, &ast_astdp_connector_funcs,
1665 DRM_MODE_CONNECTOR_DisplayPort);
1666 if (ret)
1667 return ret;
1668
1669 drm_connector_helper_add(connector, &ast_astdp_connector_helper_funcs);
1670
1671 connector->interlace_allowed = 0;
1672 connector->doublescan_allowed = 0;
1673
1674 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1675
1676 return 0;
1677 }
1678
1679 static int ast_astdp_output_init(struct ast_private *ast)
1680 {
1681 struct drm_device *dev = &ast->base;
1682 struct drm_crtc *crtc = &ast->crtc;
1683 struct drm_encoder *encoder = &ast->output.astdp.encoder;
1684 struct drm_connector *connector = &ast->output.astdp.connector;
1685 int ret;
1686
1687 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
1688 if (ret)
1689 return ret;
1690 encoder->possible_crtcs = drm_crtc_mask(crtc);
1691
1692 ret = ast_astdp_connector_init(dev, connector);
1693 if (ret)
1694 return ret;
1695
1696 ret = drm_connector_attach_encoder(connector, encoder);
1697 if (ret)
1698 return ret;
1699
1700 return 0;
1701 }
1702
1703
1704
1705
1706
1707 static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs = {
1708 .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
1709 };
1710
1711 static const struct drm_mode_config_funcs ast_mode_config_funcs = {
1712 .fb_create = drm_gem_fb_create,
1713 .mode_valid = drm_vram_helper_mode_valid,
1714 .atomic_check = drm_atomic_helper_check,
1715 .atomic_commit = drm_atomic_helper_commit,
1716 };
1717
1718 int ast_mode_config_init(struct ast_private *ast)
1719 {
1720 struct drm_device *dev = &ast->base;
1721 struct pci_dev *pdev = to_pci_dev(dev->dev);
1722 int ret;
1723
1724 ret = drmm_mode_config_init(dev);
1725 if (ret)
1726 return ret;
1727
1728 dev->mode_config.funcs = &ast_mode_config_funcs;
1729 dev->mode_config.min_width = 0;
1730 dev->mode_config.min_height = 0;
1731 dev->mode_config.preferred_depth = 24;
1732 dev->mode_config.prefer_shadow = 1;
1733 dev->mode_config.fb_base = pci_resource_start(pdev, 0);
1734
1735 if (ast->chip == AST2100 ||
1736 ast->chip == AST2200 ||
1737 ast->chip == AST2300 ||
1738 ast->chip == AST2400 ||
1739 ast->chip == AST2500 ||
1740 ast->chip == AST2600) {
1741 dev->mode_config.max_width = 1920;
1742 dev->mode_config.max_height = 2048;
1743 } else {
1744 dev->mode_config.max_width = 1600;
1745 dev->mode_config.max_height = 1200;
1746 }
1747
1748 dev->mode_config.helper_private = &ast_mode_config_helper_funcs;
1749
1750
1751 ret = ast_primary_plane_init(ast);
1752 if (ret)
1753 return ret;
1754
1755 ret = ast_cursor_plane_init(ast);
1756 if (ret)
1757 return ret;
1758
1759 ast_crtc_init(dev);
1760
1761 if (ast->tx_chip_types & AST_TX_NONE_BIT) {
1762 ret = ast_vga_output_init(ast);
1763 if (ret)
1764 return ret;
1765 }
1766 if (ast->tx_chip_types & AST_TX_SIL164_BIT) {
1767 ret = ast_sil164_output_init(ast);
1768 if (ret)
1769 return ret;
1770 }
1771 if (ast->tx_chip_types & AST_TX_DP501_BIT) {
1772 ret = ast_dp501_output_init(ast);
1773 if (ret)
1774 return ret;
1775 }
1776 if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
1777 ret = ast_astdp_output_init(ast);
1778 if (ret)
1779 return ret;
1780 }
1781
1782 drm_mode_config_reset(dev);
1783
1784 return 0;
1785 }