Home | History | Annotate | Line # | Download | only in ast
ast_main.c revision 1.1.1.2.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 static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb)
    193 {
    194 	struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb);
    195 	if (ast_fb->obj)
    196 		drm_gem_object_unreference_unlocked(ast_fb->obj);
    197 
    198 	drm_framebuffer_cleanup(fb);
    199 	kfree(fb);
    200 }
    201 
    202 static const struct drm_framebuffer_funcs ast_fb_funcs = {
    203 	.destroy = ast_user_framebuffer_destroy,
    204 };
    205 
    206 
    207 int ast_framebuffer_init(struct drm_device *dev,
    208 			 struct ast_framebuffer *ast_fb,
    209 			 struct drm_mode_fb_cmd2 *mode_cmd,
    210 			 struct drm_gem_object *obj)
    211 {
    212 	int ret;
    213 
    214 	drm_helper_mode_fill_fb_struct(&ast_fb->base, mode_cmd);
    215 	ast_fb->obj = obj;
    216 	ret = drm_framebuffer_init(dev, &ast_fb->base, &ast_fb_funcs);
    217 	if (ret) {
    218 		DRM_ERROR("framebuffer init failed %d\n", ret);
    219 		return ret;
    220 	}
    221 	return 0;
    222 }
    223 
    224 static struct drm_framebuffer *
    225 ast_user_framebuffer_create(struct drm_device *dev,
    226 	       struct drm_file *filp,
    227 	       struct drm_mode_fb_cmd2 *mode_cmd)
    228 {
    229 	struct drm_gem_object *obj;
    230 	struct ast_framebuffer *ast_fb;
    231 	int ret;
    232 
    233 	obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]);
    234 	if (obj == NULL)
    235 		return ERR_PTR(-ENOENT);
    236 
    237 	ast_fb = kzalloc(sizeof(*ast_fb), GFP_KERNEL);
    238 	if (!ast_fb) {
    239 		drm_gem_object_unreference_unlocked(obj);
    240 		return ERR_PTR(-ENOMEM);
    241 	}
    242 
    243 	ret = ast_framebuffer_init(dev, ast_fb, mode_cmd, obj);
    244 	if (ret) {
    245 		drm_gem_object_unreference_unlocked(obj);
    246 		kfree(ast_fb);
    247 		return ERR_PTR(ret);
    248 	}
    249 	return &ast_fb->base;
    250 }
    251 
    252 static const struct drm_mode_config_funcs ast_mode_funcs = {
    253 	.fb_create = ast_user_framebuffer_create,
    254 };
    255 
    256 static u32 ast_get_vram_info(struct drm_device *dev)
    257 {
    258 	struct ast_private *ast = dev->dev_private;
    259 	u8 jreg;
    260 
    261 	ast_open_key(ast);
    262 
    263 	jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff);
    264 	switch (jreg & 3) {
    265 	case 0: return AST_VIDMEM_SIZE_8M;
    266 	case 1: return AST_VIDMEM_SIZE_16M;
    267 	case 2: return AST_VIDMEM_SIZE_32M;
    268 	case 3: return AST_VIDMEM_SIZE_64M;
    269 	}
    270 	return AST_VIDMEM_DEFAULT_SIZE;
    271 }
    272 
    273 int ast_driver_load(struct drm_device *dev, unsigned long flags)
    274 {
    275 	struct ast_private *ast;
    276 	int ret = 0;
    277 
    278 	ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL);
    279 	if (!ast)
    280 		return -ENOMEM;
    281 
    282 	dev->dev_private = ast;
    283 	ast->dev = dev;
    284 
    285 	ast->regs = pci_iomap(dev->pdev, 1, 0);
    286 	if (!ast->regs) {
    287 		ret = -EIO;
    288 		goto out_free;
    289 	}
    290 	ast->ioregs = pci_iomap(dev->pdev, 2, 0);
    291 	if (!ast->ioregs) {
    292 		ret = -EIO;
    293 		goto out_free;
    294 	}
    295 
    296 	ast_detect_chip(dev);
    297 
    298 	if (ast->chip != AST1180) {
    299 		ast_get_dram_info(dev);
    300 		ast->vram_size = ast_get_vram_info(dev);
    301 		DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size);
    302 	}
    303 
    304 	ret = ast_mm_init(ast);
    305 	if (ret)
    306 		goto out_free;
    307 
    308 	drm_mode_config_init(dev);
    309 
    310 	dev->mode_config.funcs = (void *)&ast_mode_funcs;
    311 	dev->mode_config.min_width = 0;
    312 	dev->mode_config.min_height = 0;
    313 	dev->mode_config.preferred_depth = 24;
    314 	dev->mode_config.prefer_shadow = 1;
    315 
    316 	if (ast->chip == AST2100 ||
    317 	    ast->chip == AST2200 ||
    318 	    ast->chip == AST2300 ||
    319 	    ast->chip == AST1180) {
    320 		dev->mode_config.max_width = 1920;
    321 		dev->mode_config.max_height = 2048;
    322 	} else {
    323 		dev->mode_config.max_width = 1600;
    324 		dev->mode_config.max_height = 1200;
    325 	}
    326 
    327 	ret = ast_mode_init(dev);
    328 	if (ret)
    329 		goto out_free;
    330 
    331 	ret = ast_fbdev_init(dev);
    332 	if (ret)
    333 		goto out_free;
    334 
    335 	return 0;
    336 out_free:
    337 	kfree(ast);
    338 	dev->dev_private = NULL;
    339 	return ret;
    340 }
    341 
    342 int ast_driver_unload(struct drm_device *dev)
    343 {
    344 	struct ast_private *ast = dev->dev_private;
    345 
    346 	ast_mode_fini(dev);
    347 	ast_fbdev_fini(dev);
    348 	drm_mode_config_cleanup(dev);
    349 
    350 	ast_mm_fini(ast);
    351 	pci_iounmap(dev->pdev, ast->ioregs);
    352 	pci_iounmap(dev->pdev, ast->regs);
    353 	kfree(ast);
    354 	return 0;
    355 }
    356 
    357 int ast_gem_create(struct drm_device *dev,
    358 		   u32 size, bool iskernel,
    359 		   struct drm_gem_object **obj)
    360 {
    361 	struct ast_bo *astbo;
    362 	int ret;
    363 
    364 	*obj = NULL;
    365 
    366 	size = roundup(size, PAGE_SIZE);
    367 	if (size == 0)
    368 		return -EINVAL;
    369 
    370 	ret = ast_bo_create(dev, size, 0, 0, &astbo);
    371 	if (ret) {
    372 		if (ret != -ERESTARTSYS)
    373 			DRM_ERROR("failed to allocate GEM object\n");
    374 		return ret;
    375 	}
    376 	*obj = &astbo->gem;
    377 	return 0;
    378 }
    379 
    380 int ast_dumb_create(struct drm_file *file,
    381 		    struct drm_device *dev,
    382 		    struct drm_mode_create_dumb *args)
    383 {
    384 	int ret;
    385 	struct drm_gem_object *gobj;
    386 	u32 handle;
    387 
    388 	args->pitch = args->width * ((args->bpp + 7) / 8);
    389 	args->size = args->pitch * args->height;
    390 
    391 	ret = ast_gem_create(dev, args->size, false,
    392 			     &gobj);
    393 	if (ret)
    394 		return ret;
    395 
    396 	ret = drm_gem_handle_create(file, gobj, &handle);
    397 	drm_gem_object_unreference_unlocked(gobj);
    398 	if (ret)
    399 		return ret;
    400 
    401 	args->handle = handle;
    402 	return 0;
    403 }
    404 
    405 static void ast_bo_unref(struct ast_bo **bo)
    406 {
    407 	struct ttm_buffer_object *tbo;
    408 
    409 	if ((*bo) == NULL)
    410 		return;
    411 
    412 	tbo = &((*bo)->bo);
    413 	ttm_bo_unref(&tbo);
    414 	if (tbo == NULL)
    415 		*bo = NULL;
    416 
    417 }
    418 void ast_gem_free_object(struct drm_gem_object *obj)
    419 {
    420 	struct ast_bo *ast_bo = gem_to_ast_bo(obj);
    421 
    422 	if (!ast_bo)
    423 		return;
    424 	ast_bo_unref(&ast_bo);
    425 }
    426 
    427 
    428 static inline u64 ast_bo_mmap_offset(struct ast_bo *bo)
    429 {
    430 	return drm_vma_node_offset_addr(&bo->bo.vma_node);
    431 }
    432 int
    433 ast_dumb_mmap_offset(struct drm_file *file,
    434 		     struct drm_device *dev,
    435 		     uint32_t handle,
    436 		     uint64_t *offset)
    437 {
    438 	struct drm_gem_object *obj;
    439 	int ret;
    440 	struct ast_bo *bo;
    441 
    442 	mutex_lock(&dev->struct_mutex);
    443 	obj = drm_gem_object_lookup(dev, file, handle);
    444 	if (obj == NULL) {
    445 		ret = -ENOENT;
    446 		goto out_unlock;
    447 	}
    448 
    449 	bo = gem_to_ast_bo(obj);
    450 	*offset = ast_bo_mmap_offset(bo);
    451 
    452 	drm_gem_object_unreference(obj);
    453 	ret = 0;
    454 out_unlock:
    455 	mutex_unlock(&dev->struct_mutex);
    456 	return ret;
    457 
    458 }
    459 
    460