Home | History | Annotate | Line # | Download | only in ast
ast_main.c revision 1.1.1.1.4.2
      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 (at) 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 
     70 	if (dev->pdev->device == PCI_CHIP_AST1180) {
     71 		ast->chip = AST1100;
     72 		DRM_INFO("AST 1180 detected\n");
     73 	} else {
     74 		if (dev->pdev->revision >= 0x20) {
     75 			ast->chip = AST2300;
     76 			DRM_INFO("AST 2300 detected\n");
     77 		} else if (dev->pdev->revision >= 0x10) {
     78 			uint32_t data;
     79 			ast_write32(ast, 0xf004, 0x1e6e0000);
     80 			ast_write32(ast, 0xf000, 0x1);
     81 
     82 			data = ast_read32(ast, 0x1207c);
     83 			switch (data & 0x0300) {
     84 			case 0x0200:
     85 				ast->chip = AST1100;
     86 				DRM_INFO("AST 1100 detected\n");
     87 				break;
     88 			case 0x0100:
     89 				ast->chip = AST2200;
     90 				DRM_INFO("AST 2200 detected\n");
     91 				break;
     92 			case 0x0000:
     93 				ast->chip = AST2150;
     94 				DRM_INFO("AST 2150 detected\n");
     95 				break;
     96 			default:
     97 				ast->chip = AST2100;
     98 				DRM_INFO("AST 2100 detected\n");
     99 				break;
    100 			}
    101 			ast->vga2_clone = false;
    102 		} else {
    103 			ast->chip = 2000;
    104 			DRM_INFO("AST 2000 detected\n");
    105 		}
    106 	}
    107 	return 0;
    108 }
    109 
    110 static int ast_get_dram_info(struct drm_device *dev)
    111 {
    112 	struct ast_private *ast = dev->dev_private;
    113 	uint32_t data, data2;
    114 	uint32_t denum, num, div, ref_pll;
    115 
    116 	ast_write32(ast, 0xf004, 0x1e6e0000);
    117 	ast_write32(ast, 0xf000, 0x1);
    118 
    119 
    120 	ast_write32(ast, 0x10000, 0xfc600309);
    121 
    122 	do {
    123 		;
    124 	} while (ast_read32(ast, 0x10000) != 0x01);
    125 	data = ast_read32(ast, 0x10004);
    126 
    127 	if (data & 0x400)
    128 		ast->dram_bus_width = 16;
    129 	else
    130 		ast->dram_bus_width = 32;
    131 
    132 	if (ast->chip == AST2300) {
    133 		switch (data & 0x03) {
    134 		case 0:
    135 			ast->dram_type = AST_DRAM_512Mx16;
    136 			break;
    137 		default:
    138 		case 1:
    139 			ast->dram_type = AST_DRAM_1Gx16;
    140 			break;
    141 		case 2:
    142 			ast->dram_type = AST_DRAM_2Gx16;
    143 			break;
    144 		case 3:
    145 			ast->dram_type = AST_DRAM_4Gx16;
    146 			break;
    147 		}
    148 	} else {
    149 		switch (data & 0x0c) {
    150 		case 0:
    151 		case 4:
    152 			ast->dram_type = AST_DRAM_512Mx16;
    153 			break;
    154 		case 8:
    155 			if (data & 0x40)
    156 				ast->dram_type = AST_DRAM_1Gx16;
    157 			else
    158 				ast->dram_type = AST_DRAM_512Mx32;
    159 			break;
    160 		case 0xc:
    161 			ast->dram_type = AST_DRAM_1Gx32;
    162 			break;
    163 		}
    164 	}
    165 
    166 	data = ast_read32(ast, 0x10120);
    167 	data2 = ast_read32(ast, 0x10170);
    168 	if (data2 & 0x2000)
    169 		ref_pll = 14318;
    170 	else
    171 		ref_pll = 12000;
    172 
    173 	denum = data & 0x1f;
    174 	num = (data & 0x3fe0) >> 5;
    175 	data = (data & 0xc000) >> 14;
    176 	switch (data) {
    177 	case 3:
    178 		div = 0x4;
    179 		break;
    180 	case 2:
    181 	case 1:
    182 		div = 0x2;
    183 		break;
    184 	default:
    185 		div = 0x1;
    186 		break;
    187 	}
    188 	ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000);
    189 	return 0;
    190 }
    191 
    192 uint32_t ast_get_max_dclk(struct drm_device *dev, int bpp)
    193 {
    194 	struct ast_private *ast = dev->dev_private;
    195 	uint32_t dclk, jreg;
    196 	uint32_t dram_bus_width, mclk, dram_bandwidth, actual_dram_bandwidth, dram_efficency = 500;
    197 
    198 	dram_bus_width = ast->dram_bus_width;
    199 	mclk = ast->mclk;
    200 
    201 	if (ast->chip == AST2100 ||
    202 	    ast->chip == AST1100 ||
    203 	    ast->chip == AST2200 ||
    204 	    ast->chip == AST2150 ||
    205 	    ast->dram_bus_width == 16)
    206 		dram_efficency = 600;
    207 	else if (ast->chip == AST2300)
    208 		dram_efficency = 400;
    209 
    210 	dram_bandwidth = mclk * dram_bus_width * 2 / 8;
    211 	actual_dram_bandwidth = dram_bandwidth * dram_efficency / 1000;
    212 
    213 	if (ast->chip == AST1180)
    214 		dclk = actual_dram_bandwidth / ((bpp + 1) / 8);
    215 	else {
    216 		jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
    217 		if ((jreg & 0x08) && (ast->chip == AST2000))
    218 			dclk = actual_dram_bandwidth / ((bpp + 1 + 16) / 8);
    219 		else if ((jreg & 0x08) && (bpp == 8))
    220 			dclk = actual_dram_bandwidth / ((bpp + 1 + 24) / 8);
    221 		else
    222 			dclk = actual_dram_bandwidth / ((bpp + 1) / 8);
    223 	}
    224 
    225 	if (ast->chip == AST2100 ||
    226 	    ast->chip == AST2200 ||
    227 	    ast->chip == AST2300 ||
    228 	    ast->chip == AST1180) {
    229 		if (dclk > 200)
    230 			dclk = 200;
    231 	} else {
    232 		if (dclk > 165)
    233 			dclk = 165;
    234 	}
    235 
    236 	return dclk;
    237 }
    238 
    239 static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb)
    240 {
    241 	struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb);
    242 	if (ast_fb->obj)
    243 		drm_gem_object_unreference_unlocked(ast_fb->obj);
    244 
    245 	drm_framebuffer_cleanup(fb);
    246 	kfree(fb);
    247 }
    248 
    249 static int ast_user_framebuffer_create_handle(struct drm_framebuffer *fb,
    250 					      struct drm_file *file,
    251 					      unsigned int *handle)
    252 {
    253 	return -EINVAL;
    254 }
    255 
    256 static const struct drm_framebuffer_funcs ast_fb_funcs = {
    257 	.destroy = ast_user_framebuffer_destroy,
    258 	.create_handle = ast_user_framebuffer_create_handle,
    259 };
    260 
    261 
    262 int ast_framebuffer_init(struct drm_device *dev,
    263 			 struct ast_framebuffer *ast_fb,
    264 			 struct drm_mode_fb_cmd2 *mode_cmd,
    265 			 struct drm_gem_object *obj)
    266 {
    267 	int ret;
    268 
    269 	ret = drm_framebuffer_init(dev, &ast_fb->base, &ast_fb_funcs);
    270 	if (ret) {
    271 		DRM_ERROR("framebuffer init failed %d\n", ret);
    272 		return ret;
    273 	}
    274 	drm_helper_mode_fill_fb_struct(&ast_fb->base, mode_cmd);
    275 	ast_fb->obj = obj;
    276 	return 0;
    277 }
    278 
    279 static struct drm_framebuffer *
    280 ast_user_framebuffer_create(struct drm_device *dev,
    281 	       struct drm_file *filp,
    282 	       struct drm_mode_fb_cmd2 *mode_cmd)
    283 {
    284 	struct drm_gem_object *obj;
    285 	struct ast_framebuffer *ast_fb;
    286 	int ret;
    287 
    288 	obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]);
    289 	if (obj == NULL)
    290 		return ERR_PTR(-ENOENT);
    291 
    292 	ast_fb = kzalloc(sizeof(*ast_fb), GFP_KERNEL);
    293 	if (!ast_fb) {
    294 		drm_gem_object_unreference_unlocked(obj);
    295 		return ERR_PTR(-ENOMEM);
    296 	}
    297 
    298 	ret = ast_framebuffer_init(dev, ast_fb, mode_cmd, obj);
    299 	if (ret) {
    300 		drm_gem_object_unreference_unlocked(obj);
    301 		kfree(ast_fb);
    302 		return ERR_PTR(ret);
    303 	}
    304 	return &ast_fb->base;
    305 }
    306 
    307 static const struct drm_mode_config_funcs ast_mode_funcs = {
    308 	.fb_create = ast_user_framebuffer_create,
    309 };
    310 
    311 static u32 ast_get_vram_info(struct drm_device *dev)
    312 {
    313 	struct ast_private *ast = dev->dev_private;
    314 	u8 jreg;
    315 
    316 	ast_open_key(ast);
    317 
    318 	jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff);
    319 	switch (jreg & 3) {
    320 	case 0: return AST_VIDMEM_SIZE_8M;
    321 	case 1: return AST_VIDMEM_SIZE_16M;
    322 	case 2: return AST_VIDMEM_SIZE_32M;
    323 	case 3: return AST_VIDMEM_SIZE_64M;
    324 	}
    325 	return AST_VIDMEM_DEFAULT_SIZE;
    326 }
    327 
    328 int ast_driver_load(struct drm_device *dev, unsigned long flags)
    329 {
    330 	struct ast_private *ast;
    331 	int ret = 0;
    332 
    333 	ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL);
    334 	if (!ast)
    335 		return -ENOMEM;
    336 
    337 	dev->dev_private = ast;
    338 	ast->dev = dev;
    339 
    340 	ast->regs = pci_iomap(dev->pdev, 1, 0);
    341 	if (!ast->regs) {
    342 		ret = -EIO;
    343 		goto out_free;
    344 	}
    345 	ast->ioregs = pci_iomap(dev->pdev, 2, 0);
    346 	if (!ast->ioregs) {
    347 		ret = -EIO;
    348 		goto out_free;
    349 	}
    350 
    351 	ast_detect_chip(dev);
    352 
    353 	if (ast->chip != AST1180) {
    354 		ast_get_dram_info(dev);
    355 		ast->vram_size = ast_get_vram_info(dev);
    356 		DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size);
    357 	}
    358 
    359 	ret = ast_mm_init(ast);
    360 	if (ret)
    361 		goto out_free;
    362 
    363 	drm_mode_config_init(dev);
    364 
    365 	dev->mode_config.funcs = (void *)&ast_mode_funcs;
    366 	dev->mode_config.min_width = 0;
    367 	dev->mode_config.min_height = 0;
    368 	dev->mode_config.preferred_depth = 24;
    369 	dev->mode_config.prefer_shadow = 1;
    370 
    371 	if (ast->chip == AST2100 ||
    372 	    ast->chip == AST2200 ||
    373 	    ast->chip == AST2300 ||
    374 	    ast->chip == AST1180) {
    375 		dev->mode_config.max_width = 1920;
    376 		dev->mode_config.max_height = 2048;
    377 	} else {
    378 		dev->mode_config.max_width = 1600;
    379 		dev->mode_config.max_height = 1200;
    380 	}
    381 
    382 	ret = ast_mode_init(dev);
    383 	if (ret)
    384 		goto out_free;
    385 
    386 	ret = ast_fbdev_init(dev);
    387 	if (ret)
    388 		goto out_free;
    389 
    390 	return 0;
    391 out_free:
    392 	kfree(ast);
    393 	dev->dev_private = NULL;
    394 	return ret;
    395 }
    396 
    397 int ast_driver_unload(struct drm_device *dev)
    398 {
    399 	struct ast_private *ast = dev->dev_private;
    400 
    401 	ast_mode_fini(dev);
    402 	ast_fbdev_fini(dev);
    403 	drm_mode_config_cleanup(dev);
    404 
    405 	ast_mm_fini(ast);
    406 	pci_iounmap(dev->pdev, ast->ioregs);
    407 	pci_iounmap(dev->pdev, ast->regs);
    408 	kfree(ast);
    409 	return 0;
    410 }
    411 
    412 int ast_gem_create(struct drm_device *dev,
    413 		   u32 size, bool iskernel,
    414 		   struct drm_gem_object **obj)
    415 {
    416 	struct ast_bo *astbo;
    417 	int ret;
    418 
    419 	*obj = NULL;
    420 
    421 	size = roundup(size, PAGE_SIZE);
    422 	if (size == 0)
    423 		return -EINVAL;
    424 
    425 	ret = ast_bo_create(dev, size, 0, 0, &astbo);
    426 	if (ret) {
    427 		if (ret != -ERESTARTSYS)
    428 			DRM_ERROR("failed to allocate GEM object\n");
    429 		return ret;
    430 	}
    431 	*obj = &astbo->gem;
    432 	return 0;
    433 }
    434 
    435 int ast_dumb_create(struct drm_file *file,
    436 		    struct drm_device *dev,
    437 		    struct drm_mode_create_dumb *args)
    438 {
    439 	int ret;
    440 	struct drm_gem_object *gobj;
    441 	u32 handle;
    442 
    443 	args->pitch = args->width * ((args->bpp + 7) / 8);
    444 	args->size = args->pitch * args->height;
    445 
    446 	ret = ast_gem_create(dev, args->size, false,
    447 			     &gobj);
    448 	if (ret)
    449 		return ret;
    450 
    451 	ret = drm_gem_handle_create(file, gobj, &handle);
    452 	drm_gem_object_unreference_unlocked(gobj);
    453 	if (ret)
    454 		return ret;
    455 
    456 	args->handle = handle;
    457 	return 0;
    458 }
    459 
    460 int ast_dumb_destroy(struct drm_file *file,
    461 		     struct drm_device *dev,
    462 		     uint32_t handle)
    463 {
    464 	return drm_gem_handle_delete(file, handle);
    465 }
    466 
    467 int ast_gem_init_object(struct drm_gem_object *obj)
    468 {
    469 	BUG();
    470 	return 0;
    471 }
    472 
    473 void ast_bo_unref(struct ast_bo **bo)
    474 {
    475 	struct ttm_buffer_object *tbo;
    476 
    477 	if ((*bo) == NULL)
    478 		return;
    479 
    480 	tbo = &((*bo)->bo);
    481 	ttm_bo_unref(&tbo);
    482 	if (tbo == NULL)
    483 		*bo = NULL;
    484 
    485 }
    486 void ast_gem_free_object(struct drm_gem_object *obj)
    487 {
    488 	struct ast_bo *ast_bo = gem_to_ast_bo(obj);
    489 
    490 	if (!ast_bo)
    491 		return;
    492 	ast_bo_unref(&ast_bo);
    493 }
    494 
    495 
    496 static inline u64 ast_bo_mmap_offset(struct ast_bo *bo)
    497 {
    498 	return bo->bo.addr_space_offset;
    499 }
    500 int
    501 ast_dumb_mmap_offset(struct drm_file *file,
    502 		     struct drm_device *dev,
    503 		     uint32_t handle,
    504 		     uint64_t *offset)
    505 {
    506 	struct drm_gem_object *obj;
    507 	int ret;
    508 	struct ast_bo *bo;
    509 
    510 	mutex_lock(&dev->struct_mutex);
    511 	obj = drm_gem_object_lookup(dev, file, handle);
    512 	if (obj == NULL) {
    513 		ret = -ENOENT;
    514 		goto out_unlock;
    515 	}
    516 
    517 	bo = gem_to_ast_bo(obj);
    518 	*offset = ast_bo_mmap_offset(bo);
    519 
    520 	drm_gem_object_unreference(obj);
    521 	ret = 0;
    522 out_unlock:
    523 	mutex_unlock(&dev->struct_mutex);
    524 	return ret;
    525 
    526 }
    527 
    528