diff options
Diffstat (limited to 'drivers/gpu/drm/ast/ast_main.c')
| -rw-r--r-- | drivers/gpu/drm/ast/ast_main.c | 519 |
1 files changed, 0 insertions, 519 deletions
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c deleted file mode 100644 index f60fd7bd1183..000000000000 --- a/drivers/gpu/drm/ast/ast_main.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright 2012 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - */ -/* - * Authors: Dave Airlie <airlied@redhat.com> - */ -#include <drm/drmP.h> -#include "ast_drv.h" - - -#include <drm/drm_fb_helper.h> -#include <drm/drm_crtc_helper.h> - -#include "ast_dram_tables.h" - -void ast_set_index_reg_mask(struct ast_private *ast, - uint32_t base, uint8_t index, - uint8_t mask, uint8_t val) -{ - u8 tmp; - ast_io_write8(ast, base, index); - tmp = (ast_io_read8(ast, base + 1) & mask) | val; - ast_set_index_reg(ast, base, index, tmp); -} - -uint8_t ast_get_index_reg(struct ast_private *ast, - uint32_t base, uint8_t index) -{ - uint8_t ret; - ast_io_write8(ast, base, index); - ret = ast_io_read8(ast, base + 1); - return ret; -} - -uint8_t ast_get_index_reg_mask(struct ast_private *ast, - uint32_t base, uint8_t index, uint8_t mask) -{ - uint8_t ret; - ast_io_write8(ast, base, index); - ret = ast_io_read8(ast, base + 1) & mask; - return ret; -} - - -static int ast_detect_chip(struct drm_device *dev) -{ - struct ast_private *ast = dev->dev_private; - - if (dev->pdev->device == PCI_CHIP_AST1180) { - ast->chip = AST1100; - DRM_INFO("AST 1180 detected\n"); - } else { - if (dev->pdev->revision >= 0x20) { - ast->chip = AST2300; - DRM_INFO("AST 2300 detected\n"); - } else if (dev->pdev->revision >= 0x10) { - uint32_t data; - ast_write32(ast, 0xf004, 0x1e6e0000); - ast_write32(ast, 0xf000, 0x1); - - data = ast_read32(ast, 0x1207c); - switch (data & 0x0300) { - case 0x0200: - ast->chip = AST1100; - DRM_INFO("AST 1100 detected\n"); - break; - case 0x0100: - ast->chip = AST2200; - DRM_INFO("AST 2200 detected\n"); - break; - case 0x0000: - ast->chip = AST2150; - DRM_INFO("AST 2150 detected\n"); - break; - default: - ast->chip = AST2100; - DRM_INFO("AST 2100 detected\n"); - break; - } - ast->vga2_clone = false; - } else { - ast->chip = 2000; - DRM_INFO("AST 2000 detected\n"); - } - } - return 0; -} - -static int ast_get_dram_info(struct drm_device *dev) -{ - struct ast_private *ast = dev->dev_private; - uint32_t data, data2; - uint32_t denum, num, div, ref_pll; - - ast_write32(ast, 0xf004, 0x1e6e0000); - ast_write32(ast, 0xf000, 0x1); - - - ast_write32(ast, 0x10000, 0xfc600309); - - do { - ; - } while (ast_read32(ast, 0x10000) != 0x01); - data = ast_read32(ast, 0x10004); - - if (data & 0x400) - ast->dram_bus_width = 16; - else - ast->dram_bus_width = 32; - - if (ast->chip == AST2300) { - switch (data & 0x03) { - case 0: - ast->dram_type = AST_DRAM_512Mx16; - break; - default: - case 1: - ast->dram_type = AST_DRAM_1Gx16; - break; - case 2: - ast->dram_type = AST_DRAM_2Gx16; - break; - case 3: - ast->dram_type = AST_DRAM_4Gx16; - break; - } - } else { - switch (data & 0x0c) { - case 0: - case 4: - ast->dram_type = AST_DRAM_512Mx16; - break; - case 8: - if (data & 0x40) - ast->dram_type = AST_DRAM_1Gx16; - else - ast->dram_type = AST_DRAM_512Mx32; - break; - case 0xc: - ast->dram_type = AST_DRAM_1Gx32; - break; - } - } - - data = ast_read32(ast, 0x10120); - data2 = ast_read32(ast, 0x10170); - if (data2 & 0x2000) - ref_pll = 14318; - else - ref_pll = 12000; - - denum = data & 0x1f; - num = (data & 0x3fe0) >> 5; - data = (data & 0xc000) >> 14; - switch (data) { - case 3: - div = 0x4; - break; - case 2: - case 1: - div = 0x2; - break; - default: - div = 0x1; - break; - } - ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000); - return 0; -} - -uint32_t ast_get_max_dclk(struct drm_device *dev, int bpp) -{ - struct ast_private *ast = dev->dev_private; - uint32_t dclk, jreg; - uint32_t dram_bus_width, mclk, dram_bandwidth, actual_dram_bandwidth, dram_efficency = 500; - - dram_bus_width = ast->dram_bus_width; - mclk = ast->mclk; - - if (ast->chip == AST2100 || - ast->chip == AST1100 || - ast->chip == AST2200 || - ast->chip == AST2150 || - ast->dram_bus_width == 16) - dram_efficency = 600; - else if (ast->chip == AST2300) - dram_efficency = 400; - - dram_bandwidth = mclk * dram_bus_width * 2 / 8; - actual_dram_bandwidth = dram_bandwidth * dram_efficency / 1000; - - if (ast->chip == AST1180) - dclk = actual_dram_bandwidth / ((bpp + 1) / 8); - else { - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); - if ((jreg & 0x08) && (ast->chip == AST2000)) - dclk = actual_dram_bandwidth / ((bpp + 1 + 16) / 8); - else if ((jreg & 0x08) && (bpp == 8)) - dclk = actual_dram_bandwidth / ((bpp + 1 + 24) / 8); - else - dclk = actual_dram_bandwidth / ((bpp + 1) / 8); - } - - if (ast->chip == AST2100 || - ast->chip == AST2200 || - ast->chip == AST2300 || - ast->chip == AST1180) { - if (dclk > 200) - dclk = 200; - } else { - if (dclk > 165) - dclk = 165; - } - - return dclk; -} - -static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb) -{ - struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb); - if (ast_fb->obj) - drm_gem_object_unreference_unlocked(ast_fb->obj); - - drm_framebuffer_cleanup(fb); - kfree(fb); -} - -static const struct drm_framebuffer_funcs ast_fb_funcs = { - .destroy = ast_user_framebuffer_destroy, -}; - - -int ast_framebuffer_init(struct drm_device *dev, - struct ast_framebuffer *ast_fb, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj) -{ - int ret; - - drm_helper_mode_fill_fb_struct(&ast_fb->base, mode_cmd); - ast_fb->obj = obj; - ret = drm_framebuffer_init(dev, &ast_fb->base, &ast_fb_funcs); - if (ret) { - DRM_ERROR("framebuffer init failed %d\n", ret); - return ret; - } - return 0; -} - -static struct drm_framebuffer * -ast_user_framebuffer_create(struct drm_device *dev, - struct drm_file *filp, - struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct drm_gem_object *obj; - struct ast_framebuffer *ast_fb; - int ret; - - obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]); - if (obj == NULL) - return ERR_PTR(-ENOENT); - - ast_fb = kzalloc(sizeof(*ast_fb), GFP_KERNEL); - if (!ast_fb) { - drm_gem_object_unreference_unlocked(obj); - return ERR_PTR(-ENOMEM); - } - - ret = ast_framebuffer_init(dev, ast_fb, mode_cmd, obj); - if (ret) { - drm_gem_object_unreference_unlocked(obj); - kfree(ast_fb); - return ERR_PTR(ret); - } - return &ast_fb->base; -} - -static const struct drm_mode_config_funcs ast_mode_funcs = { - .fb_create = ast_user_framebuffer_create, -}; - -static u32 ast_get_vram_info(struct drm_device *dev) -{ - struct ast_private *ast = dev->dev_private; - u8 jreg; - - ast_open_key(ast); - - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); - switch (jreg & 3) { - case 0: return AST_VIDMEM_SIZE_8M; - case 1: return AST_VIDMEM_SIZE_16M; - case 2: return AST_VIDMEM_SIZE_32M; - case 3: return AST_VIDMEM_SIZE_64M; - } - return AST_VIDMEM_DEFAULT_SIZE; -} - -int ast_driver_load(struct drm_device *dev, unsigned long flags) -{ - struct ast_private *ast; - int ret = 0; - - ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL); - if (!ast) - return -ENOMEM; - - dev->dev_private = ast; - ast->dev = dev; - - ast->regs = pci_iomap(dev->pdev, 1, 0); - if (!ast->regs) { - ret = -EIO; - goto out_free; - } - ast->ioregs = pci_iomap(dev->pdev, 2, 0); - if (!ast->ioregs) { - ret = -EIO; - goto out_free; - } - - ast_detect_chip(dev); - - if (ast->chip != AST1180) { - ast_get_dram_info(dev); - ast->vram_size = ast_get_vram_info(dev); - DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size); - } - - ret = ast_mm_init(ast); - if (ret) - goto out_free; - - drm_mode_config_init(dev); - - dev->mode_config.funcs = (void *)&ast_mode_funcs; - dev->mode_config.min_width = 0; - dev->mode_config.min_height = 0; - dev->mode_config.preferred_depth = 24; - dev->mode_config.prefer_shadow = 1; - - if (ast->chip == AST2100 || - ast->chip == AST2200 || - ast->chip == AST2300 || - ast->chip == AST1180) { - dev->mode_config.max_width = 1920; - dev->mode_config.max_height = 2048; - } else { - dev->mode_config.max_width = 1600; - dev->mode_config.max_height = 1200; - } - - ret = ast_mode_init(dev); - if (ret) - goto out_free; - - ret = ast_fbdev_init(dev); - if (ret) - goto out_free; - - return 0; -out_free: - kfree(ast); - dev->dev_private = NULL; - return ret; -} - -int ast_driver_unload(struct drm_device *dev) -{ - struct ast_private *ast = dev->dev_private; - - ast_mode_fini(dev); - ast_fbdev_fini(dev); - drm_mode_config_cleanup(dev); - - ast_mm_fini(ast); - pci_iounmap(dev->pdev, ast->ioregs); - pci_iounmap(dev->pdev, ast->regs); - kfree(ast); - return 0; -} - -int ast_gem_create(struct drm_device *dev, - u32 size, bool iskernel, - struct drm_gem_object **obj) -{ - struct ast_bo *astbo; - int ret; - - *obj = NULL; - - size = roundup(size, PAGE_SIZE); - if (size == 0) - return -EINVAL; - - ret = ast_bo_create(dev, size, 0, 0, &astbo); - if (ret) { - if (ret != -ERESTARTSYS) - DRM_ERROR("failed to allocate GEM object\n"); - return ret; - } - *obj = &astbo->gem; - return 0; -} - -int ast_dumb_create(struct drm_file *file, - struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - int ret; - struct drm_gem_object *gobj; - u32 handle; - - args->pitch = args->width * ((args->bpp + 7) / 8); - args->size = args->pitch * args->height; - - ret = ast_gem_create(dev, args->size, false, - &gobj); - if (ret) - return ret; - - ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_unreference_unlocked(gobj); - if (ret) - return ret; - - args->handle = handle; - return 0; -} - -int ast_dumb_destroy(struct drm_file *file, - struct drm_device *dev, - uint32_t handle) -{ - return drm_gem_handle_delete(file, handle); -} - -int ast_gem_init_object(struct drm_gem_object *obj) -{ - BUG(); - return 0; -} - -void ast_bo_unref(struct ast_bo **bo) -{ - struct ttm_buffer_object *tbo; - - if ((*bo) == NULL) - return; - - tbo = &((*bo)->bo); - ttm_bo_unref(&tbo); - if (tbo == NULL) - *bo = NULL; - -} -void ast_gem_free_object(struct drm_gem_object *obj) -{ - struct ast_bo *ast_bo = gem_to_ast_bo(obj); - - if (!ast_bo) - return; - ast_bo_unref(&ast_bo); -} - - -static inline u64 ast_bo_mmap_offset(struct ast_bo *bo) -{ - return bo->bo.addr_space_offset; -} -int -ast_dumb_mmap_offset(struct drm_file *file, - struct drm_device *dev, - uint32_t handle, - uint64_t *offset) -{ - struct drm_gem_object *obj; - int ret; - struct ast_bo *bo; - - mutex_lock(&dev->struct_mutex); - obj = drm_gem_object_lookup(dev, file, handle); - if (obj == NULL) { - ret = -ENOENT; - goto out_unlock; - } - - bo = gem_to_ast_bo(obj); - *offset = ast_bo_mmap_offset(bo); - - drm_gem_object_unreference(obj); - ret = 0; -out_unlock: - mutex_unlock(&dev->struct_mutex); - return ret; - -} - |
