1 /* 2 * Copyright 2012 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sub license, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 15 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 17 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 18 * USE OR OTHER DEALINGS IN THE SOFTWARE. 19 * 20 * The above copyright notice and this permission notice (including the 21 * next paragraph) shall be included in all copies or substantial portions 22 * of the Software. 23 * 24 */ 25 /* 26 * Authors: Dave Airlie <airlied@redhat.com> 27 */ 28 #include <drm/drmP.h> 29 #include "ast_drv.h" 30 31 32 #include <drm/drm_fb_helper.h> 33 #include <drm/drm_crtc_helper.h> 34 35 #include "ast_dram_tables.h" 36 37 void ast_set_index_reg_mask(struct ast_private *ast, 38 uint32_t base, uint8_t index, 39 uint8_t mask, uint8_t val) 40 { 41 u8 tmp; 42 ast_io_write8(ast, base, index); 43 tmp = (ast_io_read8(ast, base + 1) & mask) | val; 44 ast_set_index_reg(ast, base, index, tmp); 45 } 46 47 uint8_t ast_get_index_reg(struct ast_private *ast, 48 uint32_t base, uint8_t index) 49 { 50 uint8_t ret; 51 ast_io_write8(ast, base, index); 52 ret = ast_io_read8(ast, base + 1); 53 return ret; 54 } 55 56 uint8_t ast_get_index_reg_mask(struct ast_private *ast, 57 uint32_t base, uint8_t index, uint8_t mask) 58 { 59 uint8_t ret; 60 ast_io_write8(ast, base, index); 61 ret = ast_io_read8(ast, base + 1) & mask; 62 return ret; 63 } 64 65 66 static int ast_detect_chip(struct drm_device *dev) 67 { 68 struct ast_private *ast = dev->dev_private; 69 uint32_t data, jreg; 70 ast_open_key(ast); 71 72 if (dev->pdev->device == PCI_CHIP_AST1180) { 73 ast->chip = AST1100; 74 DRM_INFO("AST 1180 detected\n"); 75 } else { 76 if (dev->pdev->revision >= 0x30) { 77 ast->chip = AST2400; 78 DRM_INFO("AST 2400 detected\n"); 79 } else if (dev->pdev->revision >= 0x20) { 80 ast->chip = AST2300; 81 DRM_INFO("AST 2300 detected\n"); 82 } else if (dev->pdev->revision >= 0x10) { 83 uint32_t data; 84 ast_write32(ast, 0xf004, 0x1e6e0000); 85 ast_write32(ast, 0xf000, 0x1); 86 87 data = ast_read32(ast, 0x1207c); 88 switch (data & 0x0300) { 89 case 0x0200: 90 ast->chip = AST1100; 91 DRM_INFO("AST 1100 detected\n"); 92 break; 93 case 0x0100: 94 ast->chip = AST2200; 95 DRM_INFO("AST 2200 detected\n"); 96 break; 97 case 0x0000: 98 ast->chip = AST2150; 99 DRM_INFO("AST 2150 detected\n"); 100 break; 101 default: 102 ast->chip = AST2100; 103 DRM_INFO("AST 2100 detected\n"); 104 break; 105 } 106 ast->vga2_clone = false; 107 } else { 108 ast->chip = AST2000; 109 DRM_INFO("AST 2000 detected\n"); 110 } 111 } 112 113 switch (ast->chip) { 114 case AST1180: 115 ast->support_wide_screen = true; 116 break; 117 case AST2000: 118 ast->support_wide_screen = false; 119 break; 120 default: 121 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); 122 if (!(jreg & 0x80)) 123 ast->support_wide_screen = true; 124 else if (jreg & 0x01) 125 ast->support_wide_screen = true; 126 else { 127 ast->support_wide_screen = false; 128 ast_write32(ast, 0xf004, 0x1e6e0000); 129 ast_write32(ast, 0xf000, 0x1); 130 data = ast_read32(ast, 0x1207c); 131 data &= 0x300; 132 if (ast->chip == AST2300 && data == 0x0) /* ast1300 */ 133 ast->support_wide_screen = true; 134 if (ast->chip == AST2400 && data == 0x100) /* ast1400 */ 135 ast->support_wide_screen = true; 136 } 137 break; 138 } 139 140 ast->tx_chip_type = AST_TX_NONE; 141 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff); 142 if (jreg & 0x80) 143 ast->tx_chip_type = AST_TX_SIL164; 144 if ((ast->chip == AST2300) || (ast->chip == AST2400)) { 145 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); 146 switch (jreg) { 147 case 0x04: 148 ast->tx_chip_type = AST_TX_SIL164; 149 break; 150 case 0x08: 151 ast->dp501_fw_addr = kzalloc(32*1024, GFP_KERNEL); 152 if (ast->dp501_fw_addr) { 153 /* backup firmware */ 154 if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) { 155 kfree(ast->dp501_fw_addr); 156 ast->dp501_fw_addr = NULL; 157 } 158 } 159 /* fallthrough */ 160 case 0x0c: 161 ast->tx_chip_type = AST_TX_DP501; 162 } 163 } 164 165 return 0; 166 } 167 168 static int ast_get_dram_info(struct drm_device *dev) 169 { 170 struct ast_private *ast = dev->dev_private; 171 uint32_t data, data2; 172 uint32_t denum, num, div, ref_pll; 173 174 ast_write32(ast, 0xf004, 0x1e6e0000); 175 ast_write32(ast, 0xf000, 0x1); 176 177 178 ast_write32(ast, 0x10000, 0xfc600309); 179 180 do { 181 ; 182 } while (ast_read32(ast, 0x10000) != 0x01); 183 data = ast_read32(ast, 0x10004); 184 185 if (data & 0x400) 186 ast->dram_bus_width = 16; 187 else 188 ast->dram_bus_width = 32; 189 190 if (ast->chip == AST2300 || ast->chip == AST2400) { 191 switch (data & 0x03) { 192 case 0: 193 ast->dram_type = AST_DRAM_512Mx16; 194 break; 195 default: 196 case 1: 197 ast->dram_type = AST_DRAM_1Gx16; 198 break; 199 case 2: 200 ast->dram_type = AST_DRAM_2Gx16; 201 break; 202 case 3: 203 ast->dram_type = AST_DRAM_4Gx16; 204 break; 205 } 206 } else { 207 switch (data & 0x0c) { 208 case 0: 209 case 4: 210 ast->dram_type = AST_DRAM_512Mx16; 211 break; 212 case 8: 213 if (data & 0x40) 214 ast->dram_type = AST_DRAM_1Gx16; 215 else 216 ast->dram_type = AST_DRAM_512Mx32; 217 break; 218 case 0xc: 219 ast->dram_type = AST_DRAM_1Gx32; 220 break; 221 } 222 } 223 224 data = ast_read32(ast, 0x10120); 225 data2 = ast_read32(ast, 0x10170); 226 if (data2 & 0x2000) 227 ref_pll = 14318; 228 else 229 ref_pll = 12000; 230 231 denum = data & 0x1f; 232 num = (data & 0x3fe0) >> 5; 233 data = (data & 0xc000) >> 14; 234 switch (data) { 235 case 3: 236 div = 0x4; 237 break; 238 case 2: 239 case 1: 240 div = 0x2; 241 break; 242 default: 243 div = 0x1; 244 break; 245 } 246 ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000); 247 return 0; 248 } 249 250 static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb) 251 { 252 struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb); 253 if (ast_fb->obj) 254 drm_gem_object_unreference_unlocked(ast_fb->obj); 255 256 drm_framebuffer_cleanup(fb); 257 kfree(fb); 258 } 259 260 static const struct drm_framebuffer_funcs ast_fb_funcs = { 261 .destroy = ast_user_framebuffer_destroy, 262 }; 263 264 265 int ast_framebuffer_init(struct drm_device *dev, 266 struct ast_framebuffer *ast_fb, 267 struct drm_mode_fb_cmd2 *mode_cmd, 268 struct drm_gem_object *obj) 269 { 270 int ret; 271 272 drm_helper_mode_fill_fb_struct(&ast_fb->base, mode_cmd); 273 ast_fb->obj = obj; 274 ret = drm_framebuffer_init(dev, &ast_fb->base, &ast_fb_funcs); 275 if (ret) { 276 DRM_ERROR("framebuffer init failed %d\n", ret); 277 return ret; 278 } 279 return 0; 280 } 281 282 static struct drm_framebuffer * 283 ast_user_framebuffer_create(struct drm_device *dev, 284 struct drm_file *filp, 285 struct drm_mode_fb_cmd2 *mode_cmd) 286 { 287 struct drm_gem_object *obj; 288 struct ast_framebuffer *ast_fb; 289 int ret; 290 291 obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]); 292 if (obj == NULL) 293 return ERR_PTR(-ENOENT); 294 295 ast_fb = kzalloc(sizeof(*ast_fb), GFP_KERNEL); 296 if (!ast_fb) { 297 drm_gem_object_unreference_unlocked(obj); 298 return ERR_PTR(-ENOMEM); 299 } 300 301 ret = ast_framebuffer_init(dev, ast_fb, mode_cmd, obj); 302 if (ret) { 303 drm_gem_object_unreference_unlocked(obj); 304 kfree(ast_fb); 305 return ERR_PTR(ret); 306 } 307 return &ast_fb->base; 308 } 309 310 static const struct drm_mode_config_funcs ast_mode_funcs = { 311 .fb_create = ast_user_framebuffer_create, 312 }; 313 314 static u32 ast_get_vram_info(struct drm_device *dev) 315 { 316 struct ast_private *ast = dev->dev_private; 317 u8 jreg; 318 u32 vram_size; 319 ast_open_key(ast); 320 321 vram_size = AST_VIDMEM_DEFAULT_SIZE; 322 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); 323 switch (jreg & 3) { 324 case 0: vram_size = AST_VIDMEM_SIZE_8M; break; 325 case 1: vram_size = AST_VIDMEM_SIZE_16M; break; 326 case 2: vram_size = AST_VIDMEM_SIZE_32M; break; 327 case 3: vram_size = AST_VIDMEM_SIZE_64M; break; 328 } 329 330 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff); 331 switch (jreg & 0x03) { 332 case 1: 333 vram_size -= 0x100000; 334 break; 335 case 2: 336 vram_size -= 0x200000; 337 break; 338 case 3: 339 vram_size -= 0x400000; 340 break; 341 } 342 343 return vram_size; 344 } 345 346 int ast_driver_load(struct drm_device *dev, unsigned long flags) 347 { 348 struct ast_private *ast; 349 int ret = 0; 350 351 ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL); 352 if (!ast) 353 return -ENOMEM; 354 355 dev->dev_private = ast; 356 ast->dev = dev; 357 358 ast->regs = pci_iomap(dev->pdev, 1, 0); 359 if (!ast->regs) { 360 ret = -EIO; 361 goto out_free; 362 } 363 ast->ioregs = pci_iomap(dev->pdev, 2, 0); 364 if (!ast->ioregs) { 365 ret = -EIO; 366 goto out_free; 367 } 368 369 ast_detect_chip(dev); 370 371 if (ast->chip != AST1180) { 372 ast_get_dram_info(dev); 373 ast->vram_size = ast_get_vram_info(dev); 374 DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size); 375 } 376 377 ret = ast_mm_init(ast); 378 if (ret) 379 goto out_free; 380 381 drm_mode_config_init(dev); 382 383 dev->mode_config.funcs = (void *)&ast_mode_funcs; 384 dev->mode_config.min_width = 0; 385 dev->mode_config.min_height = 0; 386 dev->mode_config.preferred_depth = 24; 387 dev->mode_config.prefer_shadow = 1; 388 389 if (ast->chip == AST2100 || 390 ast->chip == AST2200 || 391 ast->chip == AST2300 || 392 ast->chip == AST2400 || 393 ast->chip == AST1180) { 394 dev->mode_config.max_width = 1920; 395 dev->mode_config.max_height = 2048; 396 } else { 397 dev->mode_config.max_width = 1600; 398 dev->mode_config.max_height = 1200; 399 } 400 401 ret = ast_mode_init(dev); 402 if (ret) 403 goto out_free; 404 405 ret = ast_fbdev_init(dev); 406 if (ret) 407 goto out_free; 408 409 return 0; 410 out_free: 411 kfree(ast); 412 dev->dev_private = NULL; 413 return ret; 414 } 415 416 int ast_driver_unload(struct drm_device *dev) 417 { 418 struct ast_private *ast = dev->dev_private; 419 420 kfree(ast->dp501_fw_addr); 421 ast_mode_fini(dev); 422 ast_fbdev_fini(dev); 423 drm_mode_config_cleanup(dev); 424 425 ast_mm_fini(ast); 426 pci_iounmap(dev->pdev, ast->ioregs); 427 pci_iounmap(dev->pdev, ast->regs); 428 kfree(ast); 429 return 0; 430 } 431 432 int ast_gem_create(struct drm_device *dev, 433 u32 size, bool iskernel, 434 struct drm_gem_object **obj) 435 { 436 struct ast_bo *astbo; 437 int ret; 438 439 *obj = NULL; 440 441 size = roundup(size, PAGE_SIZE); 442 if (size == 0) 443 return -EINVAL; 444 445 ret = ast_bo_create(dev, size, 0, 0, &astbo); 446 if (ret) { 447 if (ret != -ERESTARTSYS) 448 DRM_ERROR("failed to allocate GEM object\n"); 449 return ret; 450 } 451 *obj = &astbo->gem; 452 return 0; 453 } 454 455 int ast_dumb_create(struct drm_file *file, 456 struct drm_device *dev, 457 struct drm_mode_create_dumb *args) 458 { 459 int ret; 460 struct drm_gem_object *gobj; 461 u32 handle; 462 463 args->pitch = args->width * ((args->bpp + 7) / 8); 464 args->size = args->pitch * args->height; 465 466 ret = ast_gem_create(dev, args->size, false, 467 &gobj); 468 if (ret) 469 return ret; 470 471 ret = drm_gem_handle_create(file, gobj, &handle); 472 drm_gem_object_unreference_unlocked(gobj); 473 if (ret) 474 return ret; 475 476 args->handle = handle; 477 return 0; 478 } 479 480 static void ast_bo_unref(struct ast_bo **bo) 481 { 482 struct ttm_buffer_object *tbo; 483 484 if ((*bo) == NULL) 485 return; 486 487 tbo = &((*bo)->bo); 488 ttm_bo_unref(&tbo); 489 *bo = NULL; 490 } 491 492 void ast_gem_free_object(struct drm_gem_object *obj) 493 { 494 struct ast_bo *ast_bo = gem_to_ast_bo(obj); 495 496 ast_bo_unref(&ast_bo); 497 } 498 499 500 static inline u64 ast_bo_mmap_offset(struct ast_bo *bo) 501 { 502 return drm_vma_node_offset_addr(&bo->bo.vma_node); 503 } 504 int 505 ast_dumb_mmap_offset(struct drm_file *file, 506 struct drm_device *dev, 507 uint32_t handle, 508 uint64_t *offset) 509 { 510 struct drm_gem_object *obj; 511 int ret; 512 struct ast_bo *bo; 513 514 mutex_lock(&dev->struct_mutex); 515 obj = drm_gem_object_lookup(dev, file, handle); 516 if (obj == NULL) { 517 ret = -ENOENT; 518 goto out_unlock; 519 } 520 521 bo = gem_to_ast_bo(obj); 522 *offset = ast_bo_mmap_offset(bo); 523 524 drm_gem_object_unreference(obj); 525 ret = 0; 526 out_unlock: 527 mutex_unlock(&dev->struct_mutex); 528 return ret; 529 530 } 531 532