Home | History | Annotate | Line # | Download | only in ast
ast_main.c revision 1.1.1.2.28.1
      1 /*	$NetBSD: ast_main.c,v 1.1.1.2.28.1 2018/09/06 06:56:16 pgoyette Exp $	*/
      2 
      3 /*
      4  * Copyright 2012 Red Hat Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     17  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
     18  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     19  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     21  *
     22  * The above copyright notice and this permission notice (including the
     23  * next paragraph) shall be included in all copies or substantial portions
     24  * of the Software.
     25  *
     26  */
     27 /*
     28  * Authors: Dave Airlie <airlied (at) redhat.com>
     29  */
     30 #include <sys/cdefs.h>
     31 __KERNEL_RCSID(0, "$NetBSD: ast_main.c,v 1.1.1.2.28.1 2018/09/06 06:56:16 pgoyette Exp $");
     32 
     33 #include <drm/drmP.h>
     34 #include "ast_drv.h"
     35 
     36 
     37 #include <drm/drm_fb_helper.h>
     38 #include <drm/drm_crtc_helper.h>
     39 
     40 #include "ast_dram_tables.h"
     41 
     42 void ast_set_index_reg_mask(struct ast_private *ast,
     43 			    uint32_t base, uint8_t index,
     44 			    uint8_t mask, uint8_t val)
     45 {
     46 	u8 tmp;
     47 	ast_io_write8(ast, base, index);
     48 	tmp = (ast_io_read8(ast, base + 1) & mask) | val;
     49 	ast_set_index_reg(ast, base, index, tmp);
     50 }
     51 
     52 uint8_t ast_get_index_reg(struct ast_private *ast,
     53 			  uint32_t base, uint8_t index)
     54 {
     55 	uint8_t ret;
     56 	ast_io_write8(ast, base, index);
     57 	ret = ast_io_read8(ast, base + 1);
     58 	return ret;
     59 }
     60 
     61 uint8_t ast_get_index_reg_mask(struct ast_private *ast,
     62 			       uint32_t base, uint8_t index, uint8_t mask)
     63 {
     64 	uint8_t ret;
     65 	ast_io_write8(ast, base, index);
     66 	ret = ast_io_read8(ast, base + 1) & mask;
     67 	return ret;
     68 }
     69 
     70 static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
     71 {
     72 	struct device_node *np = dev->pdev->dev.of_node;
     73 	struct ast_private *ast = dev->dev_private;
     74 	uint32_t data, jregd0, jregd1;
     75 
     76 	/* Defaults */
     77 	ast->config_mode = ast_use_defaults;
     78 	*scu_rev = 0xffffffff;
     79 
     80 	/* Check if we have device-tree properties */
     81 	if (np && !of_property_read_u32(np, "aspeed,scu-revision-id",
     82 					scu_rev)) {
     83 		/* We do, disable P2A access */
     84 		ast->config_mode = ast_use_dt;
     85 		DRM_INFO("Using device-tree for configuration\n");
     86 		return;
     87 	}
     88 
     89 	/* Not all families have a P2A bridge */
     90 	if (dev->pdev->device != PCI_CHIP_AST2000)
     91 		return;
     92 
     93 	/*
     94 	 * The BMC will set SCU 0x40 D[12] to 1 if the P2 bridge
     95 	 * is disabled. We force using P2A if VGA only mode bit
     96 	 * is set D[7]
     97 	 */
     98 	jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
     99 	jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
    100 	if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
    101 		/* Double check it's actually working */
    102 		data = ast_read32(ast, 0xf004);
    103 		if (data != 0xFFFFFFFF) {
    104 			/* P2A works, grab silicon revision */
    105 			ast->config_mode = ast_use_p2a;
    106 
    107 			DRM_INFO("Using P2A bridge for configuration\n");
    108 
    109 			/* Read SCU7c (silicon revision register) */
    110 			ast_write32(ast, 0xf004, 0x1e6e0000);
    111 			ast_write32(ast, 0xf000, 0x1);
    112 			*scu_rev = ast_read32(ast, 0x1207c);
    113 			return;
    114 		}
    115 	}
    116 
    117 	/* We have a P2A bridge but it's disabled */
    118 	DRM_INFO("P2A bridge disabled, using default configuration\n");
    119 }
    120 
    121 static int ast_detect_chip(struct drm_device *dev, bool *need_post)
    122 {
    123 	struct ast_private *ast = dev->dev_private;
    124 	uint32_t jreg, scu_rev;
    125 
    126 	/*
    127 	 * If VGA isn't enabled, we need to enable now or subsequent
    128 	 * access to the scratch registers will fail. We also inform
    129 	 * our caller that it needs to POST the chip
    130 	 * (Assumption: VGA not enabled -> need to POST)
    131 	 */
    132 	if (!ast_is_vga_enabled(dev)) {
    133 		ast_enable_vga(dev);
    134 		DRM_INFO("VGA not enabled on entry, requesting chip POST\n");
    135 		*need_post = true;
    136 	} else
    137 		*need_post = false;
    138 
    139 
    140 	/* Enable extended register access */
    141 	ast_enable_mmio(dev);
    142 	ast_open_key(ast);
    143 
    144 	/* Find out whether P2A works or whether to use device-tree */
    145 	ast_detect_config_mode(dev, &scu_rev);
    146 
    147 	/* Identify chipset */
    148 	if (dev->pdev->device == PCI_CHIP_AST1180) {
    149 		ast->chip = AST1100;
    150 		DRM_INFO("AST 1180 detected\n");
    151 	} else {
    152 		if (dev->pdev->revision >= 0x30) {
    153 			ast->chip = AST2400;
    154 			DRM_INFO("AST 2400 detected\n");
    155 		} else if (dev->pdev->revision >= 0x20) {
    156 			ast->chip = AST2300;
    157 			DRM_INFO("AST 2300 detected\n");
    158 		} else if (dev->pdev->revision >= 0x10) {
    159 			switch (scu_rev & 0x0300) {
    160 			case 0x0200:
    161 				ast->chip = AST1100;
    162 				DRM_INFO("AST 1100 detected\n");
    163 				break;
    164 			case 0x0100:
    165 				ast->chip = AST2200;
    166 				DRM_INFO("AST 2200 detected\n");
    167 				break;
    168 			case 0x0000:
    169 				ast->chip = AST2150;
    170 				DRM_INFO("AST 2150 detected\n");
    171 				break;
    172 			default:
    173 				ast->chip = AST2100;
    174 				DRM_INFO("AST 2100 detected\n");
    175 				break;
    176 			}
    177 			ast->vga2_clone = false;
    178 		} else {
    179 			ast->chip = AST2000;
    180 			DRM_INFO("AST 2000 detected\n");
    181 		}
    182 	}
    183 
    184 	/* Check if we support wide screen */
    185 	switch (ast->chip) {
    186 	case AST1180:
    187 		ast->support_wide_screen = true;
    188 		break;
    189 	case AST2000:
    190 		ast->support_wide_screen = false;
    191 		break;
    192 	default:
    193 		jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
    194 		if (!(jreg & 0x80))
    195 			ast->support_wide_screen = true;
    196 		else if (jreg & 0x01)
    197 			ast->support_wide_screen = true;
    198 		else {
    199 			ast->support_wide_screen = false;
    200 			if (ast->chip == AST2300 &&
    201 			    (scu_rev & 0x300) == 0x0) /* ast1300 */
    202 				ast->support_wide_screen = true;
    203 			if (ast->chip == AST2400 &&
    204 			    (scu_rev & 0x300) == 0x100) /* ast1400 */
    205 				ast->support_wide_screen = true;
    206 		}
    207 		break;
    208 	}
    209 
    210 	/* Check 3rd Tx option (digital output afaik) */
    211 	ast->tx_chip_type = AST_TX_NONE;
    212 
    213 	/*
    214 	 * VGACRA3 Enhanced Color Mode Register, check if DVO is already
    215 	 * enabled, in that case, assume we have a SIL164 TMDS transmitter
    216 	 *
    217 	 * Don't make that assumption if we the chip wasn't enabled and
    218 	 * is at power-on reset, otherwise we'll incorrectly "detect" a
    219 	 * SIL164 when there is none.
    220 	 */
    221 	if (!*need_post) {
    222 		jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff);
    223 		if (jreg & 0x80)
    224 			ast->tx_chip_type = AST_TX_SIL164;
    225 	}
    226 
    227 	if ((ast->chip == AST2300) || (ast->chip == AST2400)) {
    228 		/*
    229 		 * On AST2300 and 2400, look the configuration set by the SoC in
    230 		 * the SOC scratch register #1 bits 11:8 (interestingly marked
    231 		 * as "reserved" in the spec)
    232 		 */
    233 		jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
    234 		switch (jreg) {
    235 		case 0x04:
    236 			ast->tx_chip_type = AST_TX_SIL164;
    237 			break;
    238 		case 0x08:
    239 			ast->dp501_fw_addr = kzalloc(32*1024, GFP_KERNEL);
    240 			if (ast->dp501_fw_addr) {
    241 				/* backup firmware */
    242 				if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) {
    243 					kfree(ast->dp501_fw_addr);
    244 					ast->dp501_fw_addr = NULL;
    245 				}
    246 			}
    247 			/* fallthrough */
    248 		case 0x0c:
    249 			ast->tx_chip_type = AST_TX_DP501;
    250 		}
    251 	}
    252 
    253 	/* Print stuff for diagnostic purposes */
    254 	switch(ast->tx_chip_type) {
    255 	case AST_TX_SIL164:
    256 		DRM_INFO("Using Sil164 TMDS transmitter\n");
    257 		break;
    258 	case AST_TX_DP501:
    259 		DRM_INFO("Using DP501 DisplayPort transmitter\n");
    260 		break;
    261 	default:
    262 		DRM_INFO("Analog VGA only\n");
    263 	}
    264 	return 0;
    265 }
    266 
    267 static int ast_get_dram_info(struct drm_device *dev)
    268 {
    269 	struct device_node *np = dev->pdev->dev.of_node;
    270 	struct ast_private *ast = dev->dev_private;
    271 	uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap;
    272 	uint32_t denum, num, div, ref_pll, dsel;
    273 
    274 	switch (ast->config_mode) {
    275 	case ast_use_dt:
    276 		/*
    277 		 * If some properties are missing, use reasonable
    278 		 * defaults for AST2400
    279 		 */
    280 		if (of_property_read_u32(np, "aspeed,mcr-configuration",
    281 					 &mcr_cfg))
    282 			mcr_cfg = 0x00000577;
    283 		if (of_property_read_u32(np, "aspeed,mcr-scu-mpll",
    284 					 &mcr_scu_mpll))
    285 			mcr_scu_mpll = 0x000050C0;
    286 		if (of_property_read_u32(np, "aspeed,mcr-scu-strap",
    287 					 &mcr_scu_strap))
    288 			mcr_scu_strap = 0;
    289 		break;
    290 	case ast_use_p2a:
    291 		ast_write32(ast, 0xf004, 0x1e6e0000);
    292 		ast_write32(ast, 0xf000, 0x1);
    293 		mcr_cfg = ast_read32(ast, 0x10004);
    294 		mcr_scu_mpll = ast_read32(ast, 0x10120);
    295 		mcr_scu_strap = ast_read32(ast, 0x10170);
    296 		break;
    297 	case ast_use_defaults:
    298 	default:
    299 		ast->dram_bus_width = 16;
    300 		ast->dram_type = AST_DRAM_1Gx16;
    301 		ast->mclk = 396;
    302 		return 0;
    303 	}
    304 
    305 	if (mcr_cfg & 0x40)
    306 		ast->dram_bus_width = 16;
    307 	else
    308 		ast->dram_bus_width = 32;
    309 
    310 	if (ast->chip == AST2300 || ast->chip == AST2400) {
    311 		switch (mcr_cfg & 0x03) {
    312 		case 0:
    313 			ast->dram_type = AST_DRAM_512Mx16;
    314 			break;
    315 		default:
    316 		case 1:
    317 			ast->dram_type = AST_DRAM_1Gx16;
    318 			break;
    319 		case 2:
    320 			ast->dram_type = AST_DRAM_2Gx16;
    321 			break;
    322 		case 3:
    323 			ast->dram_type = AST_DRAM_4Gx16;
    324 			break;
    325 		}
    326 	} else {
    327 		switch (mcr_cfg & 0x0c) {
    328 		case 0:
    329 		case 4:
    330 			ast->dram_type = AST_DRAM_512Mx16;
    331 			break;
    332 		case 8:
    333 			if (mcr_cfg & 0x40)
    334 				ast->dram_type = AST_DRAM_1Gx16;
    335 			else
    336 				ast->dram_type = AST_DRAM_512Mx32;
    337 			break;
    338 		case 0xc:
    339 			ast->dram_type = AST_DRAM_1Gx32;
    340 			break;
    341 		}
    342 	}
    343 
    344 	if (mcr_scu_strap & 0x2000)
    345 		ref_pll = 14318;
    346 	else
    347 		ref_pll = 12000;
    348 
    349 	denum = mcr_scu_mpll & 0x1f;
    350 	num = (mcr_scu_mpll & 0x3fe0) >> 5;
    351 	dsel = (mcr_scu_mpll & 0xc000) >> 14;
    352 	switch (dsel) {
    353 	case 3:
    354 		div = 0x4;
    355 		break;
    356 	case 2:
    357 	case 1:
    358 		div = 0x2;
    359 		break;
    360 	default:
    361 		div = 0x1;
    362 		break;
    363 	}
    364 	ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000);
    365 	return 0;
    366 }
    367 
    368 static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb)
    369 {
    370 	struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb);
    371 	if (ast_fb->obj)
    372 		drm_gem_object_unreference_unlocked(ast_fb->obj);
    373 
    374 	drm_framebuffer_cleanup(fb);
    375 	kfree(fb);
    376 }
    377 
    378 static const struct drm_framebuffer_funcs ast_fb_funcs = {
    379 	.destroy = ast_user_framebuffer_destroy,
    380 };
    381 
    382 
    383 int ast_framebuffer_init(struct drm_device *dev,
    384 			 struct ast_framebuffer *ast_fb,
    385 			 struct drm_mode_fb_cmd2 *mode_cmd,
    386 			 struct drm_gem_object *obj)
    387 {
    388 	int ret;
    389 
    390 	drm_helper_mode_fill_fb_struct(&ast_fb->base, mode_cmd);
    391 	ast_fb->obj = obj;
    392 	ret = drm_framebuffer_init(dev, &ast_fb->base, &ast_fb_funcs);
    393 	if (ret) {
    394 		DRM_ERROR("framebuffer init failed %d\n", ret);
    395 		return ret;
    396 	}
    397 	return 0;
    398 }
    399 
    400 static struct drm_framebuffer *
    401 ast_user_framebuffer_create(struct drm_device *dev,
    402 	       struct drm_file *filp,
    403 	       struct drm_mode_fb_cmd2 *mode_cmd)
    404 {
    405 	struct drm_gem_object *obj;
    406 	struct ast_framebuffer *ast_fb;
    407 	int ret;
    408 
    409 	obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]);
    410 	if (obj == NULL)
    411 		return ERR_PTR(-ENOENT);
    412 
    413 	ast_fb = kzalloc(sizeof(*ast_fb), GFP_KERNEL);
    414 	if (!ast_fb) {
    415 		drm_gem_object_unreference_unlocked(obj);
    416 		return ERR_PTR(-ENOMEM);
    417 	}
    418 
    419 	ret = ast_framebuffer_init(dev, ast_fb, mode_cmd, obj);
    420 	if (ret) {
    421 		drm_gem_object_unreference_unlocked(obj);
    422 		kfree(ast_fb);
    423 		return ERR_PTR(ret);
    424 	}
    425 	return &ast_fb->base;
    426 }
    427 
    428 static const struct drm_mode_config_funcs ast_mode_funcs = {
    429 	.fb_create = ast_user_framebuffer_create,
    430 };
    431 
    432 static u32 ast_get_vram_info(struct drm_device *dev)
    433 {
    434 	struct ast_private *ast = dev->dev_private;
    435 	u8 jreg;
    436 	u32 vram_size;
    437 	ast_open_key(ast);
    438 
    439 	vram_size = AST_VIDMEM_DEFAULT_SIZE;
    440 	jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff);
    441 	switch (jreg & 3) {
    442 	case 0: vram_size = AST_VIDMEM_SIZE_8M; break;
    443 	case 1: vram_size = AST_VIDMEM_SIZE_16M; break;
    444 	case 2: vram_size = AST_VIDMEM_SIZE_32M; break;
    445 	case 3: vram_size = AST_VIDMEM_SIZE_64M; break;
    446 	}
    447 
    448 	jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff);
    449 	switch (jreg & 0x03) {
    450 	case 1:
    451 		vram_size -= 0x100000;
    452 		break;
    453 	case 2:
    454 		vram_size -= 0x200000;
    455 		break;
    456 	case 3:
    457 		vram_size -= 0x400000;
    458 		break;
    459 	}
    460 
    461 	return vram_size;
    462 }
    463 
    464 int ast_driver_load(struct drm_device *dev, unsigned long flags)
    465 {
    466 	struct ast_private *ast;
    467 	bool need_post;
    468 	int ret = 0;
    469 
    470 	ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL);
    471 	if (!ast)
    472 		return -ENOMEM;
    473 
    474 	dev->dev_private = ast;
    475 	ast->dev = dev;
    476 
    477 	ast->regs = pci_iomap(dev->pdev, 1, 0);
    478 	if (!ast->regs) {
    479 		ret = -EIO;
    480 		goto out_free;
    481 	}
    482 
    483 	/*
    484 	 * If we don't have IO space at all, use MMIO now and
    485 	 * assume the chip has MMIO enabled by default (rev 0x20
    486 	 * and higher).
    487 	 */
    488 	if (!(pci_resource_flags(dev->pdev, 2) & IORESOURCE_IO)) {
    489 		DRM_INFO("platform has no IO space, trying MMIO\n");
    490 		ast->ioregs = ast->regs + AST_IO_MM_OFFSET;
    491 	}
    492 
    493 	/* "map" IO regs if the above hasn't done so already */
    494 	if (!ast->ioregs) {
    495 		ast->ioregs = pci_iomap(dev->pdev, 2, 0);
    496 		if (!ast->ioregs) {
    497 			ret = -EIO;
    498 			goto out_free;
    499 		}
    500 	}
    501 
    502 	ast_detect_chip(dev, &need_post);
    503 
    504 	if (ast->chip != AST1180) {
    505 		ret = ast_get_dram_info(dev);
    506 		if (ret)
    507 			goto out_free;
    508 		ast->vram_size = ast_get_vram_info(dev);
    509 		DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size);
    510 	}
    511 
    512 	if (need_post)
    513 		ast_post_gpu(dev);
    514 
    515 	ret = ast_mm_init(ast);
    516 	if (ret)
    517 		goto out_free;
    518 
    519 	drm_mode_config_init(dev);
    520 
    521 	dev->mode_config.funcs = (void *)&ast_mode_funcs;
    522 	dev->mode_config.min_width = 0;
    523 	dev->mode_config.min_height = 0;
    524 	dev->mode_config.preferred_depth = 24;
    525 	dev->mode_config.prefer_shadow = 1;
    526 	dev->mode_config.fb_base = pci_resource_start(ast->dev->pdev, 0);
    527 
    528 	if (ast->chip == AST2100 ||
    529 	    ast->chip == AST2200 ||
    530 	    ast->chip == AST2300 ||
    531 	    ast->chip == AST2400 ||
    532 	    ast->chip == AST1180) {
    533 		dev->mode_config.max_width = 1920;
    534 		dev->mode_config.max_height = 2048;
    535 	} else {
    536 		dev->mode_config.max_width = 1600;
    537 		dev->mode_config.max_height = 1200;
    538 	}
    539 
    540 	ret = ast_mode_init(dev);
    541 	if (ret)
    542 		goto out_free;
    543 
    544 	ret = ast_fbdev_init(dev);
    545 	if (ret)
    546 		goto out_free;
    547 
    548 	return 0;
    549 out_free:
    550 	kfree(ast);
    551 	dev->dev_private = NULL;
    552 	return ret;
    553 }
    554 
    555 int ast_driver_unload(struct drm_device *dev)
    556 {
    557 	struct ast_private *ast = dev->dev_private;
    558 
    559 	kfree(ast->dp501_fw_addr);
    560 	ast_mode_fini(dev);
    561 	ast_fbdev_fini(dev);
    562 	drm_mode_config_cleanup(dev);
    563 
    564 	ast_mm_fini(ast);
    565 	pci_iounmap(dev->pdev, ast->ioregs);
    566 	pci_iounmap(dev->pdev, ast->regs);
    567 	kfree(ast);
    568 	return 0;
    569 }
    570 
    571 int ast_gem_create(struct drm_device *dev,
    572 		   u32 size, bool iskernel,
    573 		   struct drm_gem_object **obj)
    574 {
    575 	struct ast_bo *astbo;
    576 	int ret;
    577 
    578 	*obj = NULL;
    579 
    580 	size = roundup(size, PAGE_SIZE);
    581 	if (size == 0)
    582 		return -EINVAL;
    583 
    584 	ret = ast_bo_create(dev, size, 0, 0, &astbo);
    585 	if (ret) {
    586 		if (ret != -ERESTARTSYS)
    587 			DRM_ERROR("failed to allocate GEM object\n");
    588 		return ret;
    589 	}
    590 	*obj = &astbo->gem;
    591 	return 0;
    592 }
    593 
    594 int ast_dumb_create(struct drm_file *file,
    595 		    struct drm_device *dev,
    596 		    struct drm_mode_create_dumb *args)
    597 {
    598 	int ret;
    599 	struct drm_gem_object *gobj;
    600 	u32 handle;
    601 
    602 	args->pitch = args->width * ((args->bpp + 7) / 8);
    603 	args->size = args->pitch * args->height;
    604 
    605 	ret = ast_gem_create(dev, args->size, false,
    606 			     &gobj);
    607 	if (ret)
    608 		return ret;
    609 
    610 	ret = drm_gem_handle_create(file, gobj, &handle);
    611 	drm_gem_object_unreference_unlocked(gobj);
    612 	if (ret)
    613 		return ret;
    614 
    615 	args->handle = handle;
    616 	return 0;
    617 }
    618 
    619 static void ast_bo_unref(struct ast_bo **bo)
    620 {
    621 	struct ttm_buffer_object *tbo;
    622 
    623 	if ((*bo) == NULL)
    624 		return;
    625 
    626 	tbo = &((*bo)->bo);
    627 	ttm_bo_unref(&tbo);
    628 	*bo = NULL;
    629 }
    630 
    631 void ast_gem_free_object(struct drm_gem_object *obj)
    632 {
    633 	struct ast_bo *ast_bo = gem_to_ast_bo(obj);
    634 
    635 	ast_bo_unref(&ast_bo);
    636 }
    637 
    638 
    639 static inline u64 ast_bo_mmap_offset(struct ast_bo *bo)
    640 {
    641 	return drm_vma_node_offset_addr(&bo->bo.vma_node);
    642 }
    643 int
    644 ast_dumb_mmap_offset(struct drm_file *file,
    645 		     struct drm_device *dev,
    646 		     uint32_t handle,
    647 		     uint64_t *offset)
    648 {
    649 	struct drm_gem_object *obj;
    650 	struct ast_bo *bo;
    651 
    652 	obj = drm_gem_object_lookup(dev, file, handle);
    653 	if (obj == NULL)
    654 		return -ENOENT;
    655 
    656 	bo = gem_to_ast_bo(obj);
    657 	*offset = ast_bo_mmap_offset(bo);
    658 
    659 	drm_gem_object_unreference_unlocked(obj);
    660 
    661 	return 0;
    662 
    663 }
    664 
    665