diff options
Diffstat (limited to 'drivers/gpu/drm/ast')
| -rw-r--r-- | drivers/gpu/drm/ast/Makefile | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_cursor.c | 289 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_dp501.c | 24 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_drv.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_drv.h | 28 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_main.c | 182 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_mm.c (renamed from drivers/gpu/drm/ast/ast_ttm.c) | 79 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_mode.c | 371 | ||||
| -rw-r--r-- | drivers/gpu/drm/ast/ast_post.c | 28 | 
9 files changed, 521 insertions, 497 deletions
| diff --git a/drivers/gpu/drm/ast/Makefile b/drivers/gpu/drm/ast/Makefile index 561f7c4199e4..2265a8a624dd 100644 --- a/drivers/gpu/drm/ast/Makefile +++ b/drivers/gpu/drm/ast/Makefile @@ -3,6 +3,7 @@  # Makefile for the drm device driver.  This driver provides support for the  # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. -ast-y := ast_drv.o ast_main.o ast_mode.o ast_ttm.o ast_post.o ast_dp501.o +ast-y := ast_cursor.o ast_drv.o ast_main.o ast_mm.o ast_mode.o ast_post.o \ +	 ast_dp501.o  obj-$(CONFIG_DRM_AST) := ast.o diff --git a/drivers/gpu/drm/ast/ast_cursor.c b/drivers/gpu/drm/ast/ast_cursor.c new file mode 100644 index 000000000000..acf0d23514e8 --- /dev/null +++ b/drivers/gpu/drm/ast/ast_cursor.c @@ -0,0 +1,289 @@ +/* + * Copyright 2012 Red Hat Inc. + * Parts based on xf86-video-ast + * Copyright (c) 2005 ASPEED Technology 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 <[email protected]> + */ + +#include <drm/drm_gem_vram_helper.h> +#include <drm/drm_managed.h> + +#include "ast_drv.h" + +static void ast_cursor_fini(struct ast_private *ast) +{ +	size_t i; +	struct drm_gem_vram_object *gbo; + +	for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) { +		gbo = ast->cursor.gbo[i]; +		drm_gem_vram_vunmap(gbo, ast->cursor.vaddr[i]); +		drm_gem_vram_unpin(gbo); +		drm_gem_vram_put(gbo); +	} +} + +static void ast_cursor_release(struct drm_device *dev, void *ptr) +{ +	struct ast_private *ast = dev->dev_private; + +	ast_cursor_fini(ast); +} + +/* + * Allocate cursor BOs and pins them at the end of VRAM. + */ +int ast_cursor_init(struct ast_private *ast) +{ +	struct drm_device *dev = ast->dev; +	size_t size, i; +	struct drm_gem_vram_object *gbo; +	void __iomem *vaddr; +	int ret; + +	size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE); + +	for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) { +		gbo = drm_gem_vram_create(dev, size, 0); +		if (IS_ERR(gbo)) { +			ret = PTR_ERR(gbo); +			goto err_drm_gem_vram_put; +		} +		ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM | +					    DRM_GEM_VRAM_PL_FLAG_TOPDOWN); +		if (ret) { +			drm_gem_vram_put(gbo); +			goto err_drm_gem_vram_put; +		} +		vaddr = drm_gem_vram_vmap(gbo); +		if (IS_ERR(vaddr)) { +			ret = PTR_ERR(vaddr); +			drm_gem_vram_unpin(gbo); +			drm_gem_vram_put(gbo); +			goto err_drm_gem_vram_put; +		} + +		ast->cursor.gbo[i] = gbo; +		ast->cursor.vaddr[i] = vaddr; +	} + +	return drmm_add_action_or_reset(dev, ast_cursor_release, NULL); + +err_drm_gem_vram_put: +	while (i) { +		--i; +		gbo = ast->cursor.gbo[i]; +		drm_gem_vram_vunmap(gbo, ast->cursor.vaddr[i]); +		drm_gem_vram_unpin(gbo); +		drm_gem_vram_put(gbo); +	} +	return ret; +} + +static void update_cursor_image(u8 __iomem *dst, const u8 *src, int width, int height) +{ +	union { +		u32 ul; +		u8 b[4]; +	} srcdata32[2], data32; +	union { +		u16 us; +		u8 b[2]; +	} data16; +	u32 csum = 0; +	s32 alpha_dst_delta, last_alpha_dst_delta; +	u8 __iomem *dstxor; +	const u8 *srcxor; +	int i, j; +	u32 per_pixel_copy, two_pixel_copy; + +	alpha_dst_delta = AST_MAX_HWC_WIDTH << 1; +	last_alpha_dst_delta = alpha_dst_delta - (width << 1); + +	srcxor = src; +	dstxor = (u8 *)dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta; +	per_pixel_copy = width & 1; +	two_pixel_copy = width >> 1; + +	for (j = 0; j < height; j++) { +		for (i = 0; i < two_pixel_copy; i++) { +			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0; +			srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0; +			data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); +			data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); +			data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4); +			data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4); + +			writel(data32.ul, dstxor); +			csum += data32.ul; + +			dstxor += 4; +			srcxor += 8; + +		} + +		for (i = 0; i < per_pixel_copy; i++) { +			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0; +			data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); +			data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); +			writew(data16.us, dstxor); +			csum += (u32)data16.us; + +			dstxor += 2; +			srcxor += 4; +		} +		dstxor += last_alpha_dst_delta; +	} + +	/* write checksum + signature */ +	dst += AST_HWC_SIZE; +	writel(csum, dst); +	writel(width, dst + AST_HWC_SIGNATURE_SizeX); +	writel(height, dst + AST_HWC_SIGNATURE_SizeY); +	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX); +	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY); +} + +int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb) +{ +	struct drm_device *dev = ast->dev; +	struct drm_gem_vram_object *gbo; +	int ret; +	void *src; +	void __iomem *dst; + +	if (drm_WARN_ON_ONCE(dev, fb->width > AST_MAX_HWC_WIDTH) || +	    drm_WARN_ON_ONCE(dev, fb->height > AST_MAX_HWC_HEIGHT)) +		return -EINVAL; + +	gbo = drm_gem_vram_of_gem(fb->obj[0]); + +	ret = drm_gem_vram_pin(gbo, 0); +	if (ret) +		return ret; +	src = drm_gem_vram_vmap(gbo); +	if (IS_ERR(src)) { +		ret = PTR_ERR(src); +		goto err_drm_gem_vram_unpin; +	} + +	dst = ast->cursor.vaddr[ast->cursor.next_index]; + +	/* do data transfer to cursor BO */ +	update_cursor_image(dst, src, fb->width, fb->height); + +	drm_gem_vram_vunmap(gbo, src); +	drm_gem_vram_unpin(gbo); + +	return 0; + +err_drm_gem_vram_unpin: +	drm_gem_vram_unpin(gbo); +	return ret; +} + +static void ast_cursor_set_base(struct ast_private *ast, u64 address) +{ +	u8 addr0 = (address >> 3) & 0xff; +	u8 addr1 = (address >> 11) & 0xff; +	u8 addr2 = (address >> 19) & 0xff; + +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0); +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1); +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2); +} + +void ast_cursor_page_flip(struct ast_private *ast) +{ +	struct drm_device *dev = ast->dev; +	struct drm_gem_vram_object *gbo; +	s64 off; + +	gbo = ast->cursor.gbo[ast->cursor.next_index]; + +	off = drm_gem_vram_offset(gbo); +	if (drm_WARN_ON_ONCE(dev, off < 0)) +		return; /* Bug: we didn't pin the cursor HW BO to VRAM. */ + +	ast_cursor_set_base(ast, off); + +	++ast->cursor.next_index; +	ast->cursor.next_index %= ARRAY_SIZE(ast->cursor.gbo); +} + +static void ast_cursor_set_location(struct ast_private *ast, u16 x, u16 y, +				    u8 x_offset, u8 y_offset) +{ +	u8 x0 = (x & 0x00ff); +	u8 x1 = (x & 0x0f00) >> 8; +	u8 y0 = (y & 0x00ff); +	u8 y1 = (y & 0x0700) >> 8; + +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset); +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset); +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0); +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1); +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0); +	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1); +} + +void ast_cursor_show(struct ast_private *ast, int x, int y, +		     unsigned int offset_x, unsigned int offset_y) +{ +	u8 x_offset, y_offset; +	u8 __iomem *dst, __iomem *sig; +	u8 jreg; + +	dst = ast->cursor.vaddr[ast->cursor.next_index]; + +	sig = dst + AST_HWC_SIZE; +	writel(x, sig + AST_HWC_SIGNATURE_X); +	writel(y, sig + AST_HWC_SIGNATURE_Y); + +	if (x < 0) { +		x_offset = (-x) + offset_x; +		x = 0; +	} else { +		x_offset = offset_x; +	} +	if (y < 0) { +		y_offset = (-y) + offset_y; +		y = 0; +	} else { +		y_offset = offset_y; +	} + +	ast_cursor_set_location(ast, x, y, x_offset, y_offset); + +	/* dummy write to fire HWC */ +	jreg = 0x02 | +	       0x01; /* enable ARGB4444 cursor */ +	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, jreg); +} + +void ast_cursor_hide(struct ast_private *ast) +{ +	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, 0x00); +} diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index 98cd69269263..4b85a504825a 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -10,7 +10,7 @@ MODULE_FIRMWARE("ast_dp501_fw.bin");  static int ast_load_dp501_microcode(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	return request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev);  } @@ -93,7 +93,7 @@ static bool wait_fw_ready(struct ast_private *ast)  static bool ast_write_cmd(struct drm_device *dev, u8 data)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	int retry = 0;  	if (wait_nack(ast)) {  		send_nack(ast); @@ -115,7 +115,7 @@ static bool ast_write_cmd(struct drm_device *dev, u8 data)  static bool ast_write_data(struct drm_device *dev, u8 data)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	if (wait_nack(ast)) {  		send_nack(ast); @@ -133,7 +133,7 @@ static bool ast_write_data(struct drm_device *dev, u8 data)  #if 0  static bool ast_read_data(struct drm_device *dev, u8 *data)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u8 tmp;  	*data = 0; @@ -172,7 +172,7 @@ static u32 get_fw_base(struct ast_private *ast)  bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u32 i, data;  	u32 boot_address; @@ -188,7 +188,7 @@ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)  static bool ast_launch_m68k(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u32 i, data, len = 0;  	u32 boot_address;  	u8 *fw_addr = NULL; @@ -255,7 +255,7 @@ static bool ast_launch_m68k(struct drm_device *dev)  u8 ast_get_dp501_max_clk(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u32 boot_address, offset, data;  	u8 linkcap[4], linkrate, linklanes, maxclk = 0xff; @@ -283,7 +283,7 @@ u8 ast_get_dp501_max_clk(struct drm_device *dev)  bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u32 i, boot_address, offset, data;  	boot_address = get_fw_base(ast); @@ -312,7 +312,7 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)  static bool ast_init_dvo(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u8 jreg;  	u32 data;  	ast_write32(ast, 0xf004, 0x1e6e0000); @@ -385,7 +385,7 @@ static bool ast_init_dvo(struct drm_device *dev)  static void ast_init_analog(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u32 data;  	/* @@ -412,7 +412,7 @@ static void ast_init_analog(struct drm_device *dev)  void ast_init_3rdtx(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u8 jreg;  	if (ast->chip == AST2300 || ast->chip == AST2400) { @@ -438,7 +438,7 @@ void ast_init_3rdtx(struct drm_device *dev)  void ast_release_firmware(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	release_firmware(ast->dp501_fw);  	ast->dp501_fw = NULL; diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index b7ba22dddcad..0b58f7aee6b0 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -59,7 +59,6 @@ static struct drm_driver driver;  static const struct pci_device_id pciidlist[] = {  	AST_VGA_DEVICE(PCI_CHIP_AST2000, NULL),  	AST_VGA_DEVICE(PCI_CHIP_AST2100, NULL), -	/*	AST_VGA_DEVICE(PCI_CHIP_AST1180, NULL), - don't bind to 1180 for now */  	{0, 0, 0},  }; @@ -91,15 +90,13 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	ast_kick_out_firmware_fb(pdev); -	ret = pci_enable_device(pdev); +	ret = pcim_enable_device(pdev);  	if (ret)  		return ret;  	dev = drm_dev_alloc(&driver, &pdev->dev); -	if (IS_ERR(dev)) { -		ret = PTR_ERR(dev); -		goto err_pci_disable_device; -	} +	if (IS_ERR(dev)) +		return  PTR_ERR(dev);  	dev->pdev = pdev;  	pci_set_drvdata(pdev, dev); @@ -120,8 +117,6 @@ err_ast_driver_unload:  	ast_driver_unload(dev);  err_drm_dev_put:  	drm_dev_put(dev); -err_pci_disable_device: -	pci_disable_device(pdev);  	return ret;  } @@ -193,9 +188,6 @@ static int ast_pm_freeze(struct device *dev)  {  	struct pci_dev *pdev = to_pci_dev(dev);  	struct drm_device *ddev = pci_get_drvdata(pdev); - -	if (!ddev || !ddev->dev_private) -		return -ENODEV;  	return ast_drm_freeze(ddev);  } diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 656d591b154b..e3a264ac7ee2 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -52,7 +52,6 @@  #define PCI_CHIP_AST2000 0x2000  #define PCI_CHIP_AST2100 0x2010 -#define PCI_CHIP_AST1180 0x1180  enum ast_chip { @@ -64,7 +63,6 @@ enum ast_chip {  	AST2300,  	AST2400,  	AST2500, -	AST1180,  };  enum ast_tx_chip { @@ -112,12 +110,12 @@ struct ast_private {  	uint32_t dram_bus_width;  	uint32_t dram_type;  	uint32_t mclk; -	uint32_t vram_size;  	int fb_mtrr;  	struct {  		struct drm_gem_vram_object *gbo[AST_DEFAULT_HWC_NUM]; +		void __iomem *vaddr[AST_DEFAULT_HWC_NUM];  		unsigned int next_index;  	} cursor; @@ -138,6 +136,11 @@ struct ast_private {  	const struct firmware *dp501_fw;	/* dp501 fw */  }; +static inline struct ast_private *to_ast_private(struct drm_device *dev) +{ +	return dev->dev_private; +} +  int ast_driver_load(struct drm_device *dev, unsigned long flags);  void ast_driver_unload(struct drm_device *dev); @@ -234,12 +237,6 @@ struct ast_connector {  	struct ast_i2c_chan *i2c;  }; -struct ast_crtc { -	struct drm_crtc base; -	u8 offset_x, offset_y; -}; - -#define to_ast_crtc(x) container_of(x, struct ast_crtc, base)  #define to_ast_connector(x) container_of(x, struct ast_connector, base)  struct ast_vbios_stdtable { @@ -288,14 +285,12 @@ struct ast_crtc_state {  #define to_ast_crtc_state(state) container_of(state, struct ast_crtc_state, base) -extern int ast_mode_init(struct drm_device *dev); -extern void ast_mode_fini(struct drm_device *dev); +int ast_mode_config_init(struct ast_private *ast);  #define AST_MM_ALIGN_SHIFT 4  #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1)  int ast_mm_init(struct ast_private *ast); -void ast_mm_fini(struct ast_private *ast);  /* ast post */  void ast_enable_vga(struct drm_device *dev); @@ -311,4 +306,13 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata);  u8 ast_get_dp501_max_clk(struct drm_device *dev);  void ast_init_3rdtx(struct drm_device *dev);  void ast_release_firmware(struct drm_device *dev); + +/* ast_cursor.c */ +int ast_cursor_init(struct ast_private *ast); +int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb); +void ast_cursor_page_flip(struct ast_private *ast); +void ast_cursor_show(struct ast_private *ast, int x, int y, +		     unsigned int offset_x, unsigned int offset_y); +void ast_cursor_hide(struct ast_private *ast); +  #endif diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index e5398e3dabe7..dd12b55d57a2 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -31,7 +31,6 @@  #include <drm/drm_atomic_helper.h>  #include <drm/drm_crtc_helper.h>  #include <drm/drm_gem.h> -#include <drm/drm_gem_framebuffer_helper.h>  #include <drm/drm_gem_vram_helper.h>  #include "ast_drv.h" @@ -67,7 +66,7 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast,  static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)  {  	struct device_node *np = dev->pdev->dev.of_node; -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	uint32_t data, jregd0, jregd1;  	/* Defaults */ @@ -79,7 +78,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)  					scu_rev)) {  		/* We do, disable P2A access */  		ast->config_mode = ast_use_dt; -		DRM_INFO("Using device-tree for configuration\n"); +		drm_info(dev, "Using device-tree for configuration\n");  		return;  	} @@ -101,7 +100,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)  			/* P2A works, grab silicon revision */  			ast->config_mode = ast_use_p2a; -			DRM_INFO("Using P2A bridge for configuration\n"); +			drm_info(dev, "Using P2A bridge for configuration\n");  			/* Read SCU7c (silicon revision register) */  			ast_write32(ast, 0xf004, 0x1e6e0000); @@ -112,12 +111,12 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)  	}  	/* We have a P2A bridge but it's disabled */ -	DRM_INFO("P2A bridge disabled, using default configuration\n"); +	drm_info(dev, "P2A bridge disabled, using default configuration\n");  }  static int ast_detect_chip(struct drm_device *dev, bool *need_post)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	uint32_t jreg, scu_rev;  	/* @@ -128,7 +127,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)  	 */  	if (!ast_is_vga_enabled(dev)) {  		ast_enable_vga(dev); -		DRM_INFO("VGA not enabled on entry, requesting chip POST\n"); +		drm_info(dev, "VGA not enabled on entry, requesting chip POST\n");  		*need_post = true;  	} else  		*need_post = false; @@ -142,50 +141,42 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)  	ast_detect_config_mode(dev, &scu_rev);  	/* Identify chipset */ -	if (dev->pdev->device == PCI_CHIP_AST1180) { -		ast->chip = AST1100; -		DRM_INFO("AST 1180 detected\n"); -	} else { -		if (dev->pdev->revision >= 0x40) { -			ast->chip = AST2500; -			DRM_INFO("AST 2500 detected\n"); -		} else if (dev->pdev->revision >= 0x30) { -			ast->chip = AST2400; -			DRM_INFO("AST 2400 detected\n"); -		} else if (dev->pdev->revision >= 0x20) { -			ast->chip = AST2300; -			DRM_INFO("AST 2300 detected\n"); -		} else if (dev->pdev->revision >= 0x10) { -			switch (scu_rev & 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 = AST2000; -			DRM_INFO("AST 2000 detected\n"); +	if (dev->pdev->revision >= 0x40) { +		ast->chip = AST2500; +		drm_info(dev, "AST 2500 detected\n"); +	} else if (dev->pdev->revision >= 0x30) { +		ast->chip = AST2400; +		drm_info(dev, "AST 2400 detected\n"); +	} else if (dev->pdev->revision >= 0x20) { +		ast->chip = AST2300; +		drm_info(dev, "AST 2300 detected\n"); +	} else if (dev->pdev->revision >= 0x10) { +		switch (scu_rev & 0x0300) { +		case 0x0200: +			ast->chip = AST1100; +			drm_info(dev, "AST 1100 detected\n"); +			break; +		case 0x0100: +			ast->chip = AST2200; +			drm_info(dev, "AST 2200 detected\n"); +			break; +		case 0x0000: +			ast->chip = AST2150; +			drm_info(dev, "AST 2150 detected\n"); +			break; +		default: +			ast->chip = AST2100; +			drm_info(dev, "AST 2100 detected\n"); +			break;  		} +		ast->vga2_clone = false; +	} else { +		ast->chip = AST2000; +		drm_info(dev, "AST 2000 detected\n");  	}  	/* Check if we support wide screen */  	switch (ast->chip) { -	case AST1180: -		ast->support_wide_screen = true; -		break;  	case AST2000:  		ast->support_wide_screen = false;  		break; @@ -256,13 +247,13 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)  	/* Print stuff for diagnostic purposes */  	switch(ast->tx_chip_type) {  	case AST_TX_SIL164: -		DRM_INFO("Using Sil164 TMDS transmitter\n"); +		drm_info(dev, "Using Sil164 TMDS transmitter\n");  		break;  	case AST_TX_DP501: -		DRM_INFO("Using DP501 DisplayPort transmitter\n"); +		drm_info(dev, "Using DP501 DisplayPort transmitter\n");  		break;  	default: -		DRM_INFO("Analog VGA only\n"); +		drm_info(dev, "Analog VGA only\n");  	}  	return 0;  } @@ -270,7 +261,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)  static int ast_get_dram_info(struct drm_device *dev)  {  	struct device_node *np = dev->pdev->dev.of_node; -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap;  	uint32_t denum, num, div, ref_pll, dsel; @@ -387,45 +378,6 @@ static int ast_get_dram_info(struct drm_device *dev)  	return 0;  } -static const struct drm_mode_config_funcs ast_mode_funcs = { -	.fb_create = drm_gem_fb_create, -	.mode_valid = drm_vram_helper_mode_valid, -	.atomic_check = drm_atomic_helper_check, -	.atomic_commit = drm_atomic_helper_commit, -}; - -static u32 ast_get_vram_info(struct drm_device *dev) -{ -	struct ast_private *ast = dev->dev_private; -	u8 jreg; -	u32 vram_size; -	ast_open_key(ast); - -	vram_size = AST_VIDMEM_DEFAULT_SIZE; -	jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); -	switch (jreg & 3) { -	case 0: vram_size = AST_VIDMEM_SIZE_8M; break; -	case 1: vram_size = AST_VIDMEM_SIZE_16M; break; -	case 2: vram_size = AST_VIDMEM_SIZE_32M; break; -	case 3: vram_size = AST_VIDMEM_SIZE_64M; break; -	} - -	jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff); -	switch (jreg & 0x03) { -	case 1: -		vram_size -= 0x100000; -		break; -	case 2: -		vram_size -= 0x200000; -		break; -	case 3: -		vram_size -= 0x400000; -		break; -	} - -	return vram_size; -} -  int ast_driver_load(struct drm_device *dev, unsigned long flags)  {  	struct ast_private *ast; @@ -451,7 +403,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)  	 * and higher).  	 */  	if (!(pci_resource_flags(dev->pdev, 2) & IORESOURCE_IO)) { -		DRM_INFO("platform has no IO space, trying MMIO\n"); +		drm_info(dev, "platform has no IO space, trying MMIO\n");  		ast->ioregs = ast->regs + AST_IO_MM_OFFSET;  	} @@ -466,51 +418,23 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)  	ast_detect_chip(dev, &need_post); +	ret = ast_get_dram_info(dev); +	if (ret) +		goto out_free; +	drm_info(dev, "dram MCLK=%u Mhz type=%d bus_width=%d\n", +		 ast->mclk, ast->dram_type, ast->dram_bus_width); +  	if (need_post)  		ast_post_gpu(dev); -	if (ast->chip != AST1180) { -		ret = ast_get_dram_info(dev); -		if (ret) -			goto out_free; -		ast->vram_size = ast_get_vram_info(dev); -		DRM_INFO("dram MCLK=%u Mhz type=%d bus_width=%d size=%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; -	dev->mode_config.fb_base = pci_resource_start(ast->dev->pdev, 0); - -	if (ast->chip == AST2100 || -	    ast->chip == AST2200 || -	    ast->chip == AST2300 || -	    ast->chip == AST2400 || -	    ast->chip == AST2500 || -	    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); +	ret = ast_mode_config_init(ast);  	if (ret)  		goto out_free; -	drm_mode_config_reset(dev); -  	return 0;  out_free:  	kfree(ast); @@ -520,19 +444,13 @@ out_free:  void ast_driver_unload(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	/* enable standard VGA decode */  	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04);  	ast_release_firmware(dev);  	kfree(ast->dp501_fw_addr); -	ast_mode_fini(dev); -	drm_mode_config_cleanup(dev); -	ast_mm_fini(ast); -	if (ast->ioregs != ast->regs + AST_IO_MM_OFFSET) -		pci_iounmap(dev->pdev, ast->ioregs); -	pci_iounmap(dev->pdev, ast->regs);  	kfree(ast);  } diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_mm.c index fad34106083a..9186ec3ebbe0 100644 --- a/drivers/gpu/drm/ast/ast_ttm.c +++ b/drivers/gpu/drm/ast/ast_mm.c @@ -28,23 +28,73 @@  #include <linux/pci.h> -#include <drm/drm_print.h>  #include <drm/drm_gem_vram_helper.h> +#include <drm/drm_managed.h> +#include <drm/drm_print.h>  #include "ast_drv.h" +static u32 ast_get_vram_size(struct ast_private *ast) +{ +	u8 jreg; +	u32 vram_size; + +	ast_open_key(ast); + +	vram_size = AST_VIDMEM_DEFAULT_SIZE; +	jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); +	switch (jreg & 3) { +	case 0: +		vram_size = AST_VIDMEM_SIZE_8M; +		break; +	case 1: +		vram_size = AST_VIDMEM_SIZE_16M; +		break; +	case 2: +		vram_size = AST_VIDMEM_SIZE_32M; +		break; +	case 3: +		vram_size = AST_VIDMEM_SIZE_64M; +		break; +	} + +	jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff); +	switch (jreg & 0x03) { +	case 1: +		vram_size -= 0x100000; +		break; +	case 2: +		vram_size -= 0x200000; +		break; +	case 3: +		vram_size -= 0x400000; +		break; +	} + +	return vram_size; +} + +static void ast_mm_release(struct drm_device *dev, void *ptr) +{ +	struct ast_private *ast = to_ast_private(dev); + +	arch_phys_wc_del(ast->fb_mtrr); +	arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0), +				pci_resource_len(dev->pdev, 0)); +} +  int ast_mm_init(struct ast_private *ast)  { -	struct drm_vram_mm *vmm; +	u32 vram_size;  	int ret;  	struct drm_device *dev = ast->dev; -	vmm = drm_vram_helper_alloc_mm( -		dev, pci_resource_start(dev->pdev, 0), -		ast->vram_size); -	if (IS_ERR(vmm)) { -		ret = PTR_ERR(vmm); -		DRM_ERROR("Error initializing VRAM MM; %d\n", ret); +	vram_size = ast_get_vram_size(ast); + +	ret = drmm_vram_helper_init(dev, pci_resource_start(dev->pdev, 0), +				    vram_size); +	if (ret) { +		drm_err(dev, "Error initializing VRAM MM; %d\n", ret);  		return ret;  	} @@ -53,16 +103,5 @@ int ast_mm_init(struct ast_private *ast)  	ast->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0),  					pci_resource_len(dev->pdev, 0)); -	return 0; -} - -void ast_mm_fini(struct ast_private *ast) -{ -	struct drm_device *dev = ast->dev; - -	drm_vram_helper_release_mm(dev); - -	arch_phys_wc_del(ast->fb_mtrr); -	arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0), -				pci_resource_len(dev->pdev, 0)); +	return drmm_add_action_or_reset(dev, ast_mm_release, NULL);  } diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 3a3a511670c9..154cd877d9d1 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -37,6 +37,7 @@  #include <drm/drm_crtc.h>  #include <drm/drm_crtc_helper.h>  #include <drm/drm_fourcc.h> +#include <drm/drm_gem_framebuffer_helper.h>  #include <drm/drm_gem_vram_helper.h>  #include <drm/drm_plane_helper.h>  #include <drm/drm_probe_helper.h> @@ -47,16 +48,6 @@  static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev);  static void ast_i2c_destroy(struct ast_i2c_chan *i2c); -static int ast_cursor_move(struct drm_crtc *crtc, -			   int x, int y); - - -static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height); -static int ast_cursor_update(void *dst, void *src, unsigned int width, -			     unsigned int height); -static void ast_cursor_set_base(struct ast_private *ast, u64 address); -static int ast_cursor_move(struct drm_crtc *crtc, -			   int x, int y);  static inline void ast_load_palette_index(struct ast_private *ast,  				     u8 index, u8 red, u8 green, @@ -566,14 +557,15 @@ static void  ast_primary_plane_helper_atomic_update(struct drm_plane *plane,  				       struct drm_plane_state *old_state)  { -	struct ast_private *ast = plane->dev->dev_private; +	struct drm_device *dev = plane->dev; +	struct ast_private *ast = to_ast_private(dev);  	struct drm_plane_state *state = plane->state;  	struct drm_gem_vram_object *gbo;  	s64 gpu_addr;  	gbo = drm_gem_vram_of_gem(state->fb->obj[0]);  	gpu_addr = drm_gem_vram_offset(gbo); -	if (WARN_ON_ONCE(gpu_addr < 0)) +	if (drm_WARN_ON_ONCE(dev, gpu_addr < 0))  		return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */  	ast_set_offset_reg(ast, state->fb); @@ -586,7 +578,7 @@ static void  ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,  					struct drm_plane_state *old_state)  { -	struct ast_private *ast = plane->dev->dev_private; +	struct ast_private *ast = to_ast_private(plane->dev);  	ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);  } @@ -622,53 +614,19 @@ ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane,  {  	struct drm_framebuffer *fb = new_state->fb;  	struct drm_crtc *crtc = new_state->crtc; -	struct drm_gem_vram_object *gbo;  	struct ast_private *ast;  	int ret; -	void *src, *dst;  	if (!crtc || !fb)  		return 0; -	if (WARN_ON_ONCE(fb->width > AST_MAX_HWC_WIDTH) || -	    WARN_ON_ONCE(fb->height > AST_MAX_HWC_HEIGHT)) -		return -EINVAL; /* BUG: didn't test in atomic_check() */ - -	ast = crtc->dev->dev_private; +	ast = to_ast_private(plane->dev); -	gbo = drm_gem_vram_of_gem(fb->obj[0]); -	src = drm_gem_vram_vmap(gbo); -	if (IS_ERR(src)) { -		ret = PTR_ERR(src); -		goto err_drm_gem_vram_unpin; -	} - -	dst = drm_gem_vram_vmap(ast->cursor.gbo[ast->cursor.next_index]); -	if (IS_ERR(dst)) { -		ret = PTR_ERR(dst); -		goto err_drm_gem_vram_vunmap_src; -	} - -	ret = ast_cursor_update(dst, src, fb->width, fb->height); +	ret = ast_cursor_blit(ast, fb);  	if (ret) -		goto err_drm_gem_vram_vunmap_dst; - -	/* Always unmap buffers here. Destination buffers are -	 * perma-pinned while the driver is active. We're only -	 * changing ref-counters here. -	 */ -	drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst); -	drm_gem_vram_vunmap(gbo, src); +		return ret;  	return 0; - -err_drm_gem_vram_vunmap_dst: -	drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst); -err_drm_gem_vram_vunmap_src: -	drm_gem_vram_vunmap(gbo, src); -err_drm_gem_vram_unpin: -	drm_gem_vram_unpin(gbo); -	return ret;  }  static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane, @@ -704,44 +662,29 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,  				      struct drm_plane_state *old_state)  {  	struct drm_plane_state *state = plane->state; -	struct drm_crtc *crtc = state->crtc;  	struct drm_framebuffer *fb = state->fb;  	struct ast_private *ast = plane->dev->dev_private; -	struct ast_crtc *ast_crtc = to_ast_crtc(crtc); -	struct drm_gem_vram_object *gbo; -	s64 off; -	u8 jreg; +	unsigned int offset_x, offset_y; -	ast_crtc->offset_x = AST_MAX_HWC_WIDTH - fb->width; -	ast_crtc->offset_y = AST_MAX_HWC_WIDTH - fb->height; +	offset_x = AST_MAX_HWC_WIDTH - fb->width; +	offset_y = AST_MAX_HWC_WIDTH - fb->height;  	if (state->fb != old_state->fb) {  		/* A new cursor image was installed. */ -		gbo = ast->cursor.gbo[ast->cursor.next_index]; -		off = drm_gem_vram_offset(gbo); -		if (WARN_ON_ONCE(off < 0)) -			return; /* Bug: we didn't pin cursor HW BO to VRAM. */ -		ast_cursor_set_base(ast, off); - -		++ast->cursor.next_index; -		ast->cursor.next_index %= ARRAY_SIZE(ast->cursor.gbo); +		ast_cursor_page_flip(ast);  	} -	ast_cursor_move(crtc, state->crtc_x, state->crtc_y); - -	jreg = 0x2; -	/* enable ARGB cursor */ -	jreg |= 1; -	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, jreg); +	ast_cursor_show(ast, state->crtc_x, state->crtc_y, +			offset_x, offset_y);  }  static void  ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,  				       struct drm_plane_state *old_state)  { -	struct ast_private *ast = plane->dev->dev_private; +	struct ast_private *ast = to_ast_private(plane->dev); -	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, 0x00); +	ast_cursor_hide(ast);  }  static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = { @@ -767,10 +710,7 @@ static const struct drm_plane_funcs ast_cursor_plane_funcs = {  static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)  { -	struct ast_private *ast = crtc->dev->dev_private; - -	if (ast->chip == AST1180) -		return; +	struct ast_private *ast = to_ast_private(crtc->dev);  	/* TODO: Maybe control display signal generation with  	 *       Sync Enable (bit CR17.7). @@ -793,16 +733,10 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)  static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,  					struct drm_crtc_state *state)  { -	struct ast_private *ast = crtc->dev->dev_private;  	struct ast_crtc_state *ast_state;  	const struct drm_format_info *format;  	bool succ; -	if (ast->chip == AST1180) { -		DRM_ERROR("AST 1180 modesetting not supported\n"); -		return -EINVAL; -	} -  	if (!state->enable)  		return 0; /* no mode checks if CRTC is being disabled */ @@ -824,7 +758,7 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,  static void ast_crtc_helper_atomic_begin(struct drm_crtc *crtc,  					 struct drm_crtc_state *old_crtc_state)  { -	struct ast_private *ast = crtc->dev->dev_private; +	struct ast_private *ast = to_ast_private(crtc->dev);  	ast_open_key(ast);  } @@ -833,7 +767,7 @@ static void ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,  					 struct drm_crtc_state *old_crtc_state)  {  	struct drm_device *dev = crtc->dev; -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	struct ast_crtc_state *ast_state;  	const struct drm_format_info *format;  	struct ast_vbios_mode_info *vbios_mode_info; @@ -907,8 +841,9 @@ static struct drm_crtc_state *  ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc)  {  	struct ast_crtc_state *new_ast_state, *ast_state; +	struct drm_device *dev = crtc->dev; -	if (WARN_ON(!crtc->state)) +	if (drm_WARN_ON(dev, !crtc->state))  		return NULL;  	new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL); @@ -946,22 +881,23 @@ static const struct drm_crtc_funcs ast_crtc_funcs = {  static int ast_crtc_init(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; -	struct ast_crtc *crtc; +	struct ast_private *ast = to_ast_private(dev); +	struct drm_crtc *crtc;  	int ret; -	crtc = kzalloc(sizeof(struct ast_crtc), GFP_KERNEL); +	crtc = kzalloc(sizeof(*crtc), GFP_KERNEL);  	if (!crtc)  		return -ENOMEM; -	ret = drm_crtc_init_with_planes(dev, &crtc->base, &ast->primary_plane, +	ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane,  					&ast->cursor_plane, &ast_crtc_funcs,  					NULL);  	if (ret)  		goto err_kfree; -	drm_mode_crtc_set_gamma_size(&crtc->base, 256); -	drm_crtc_helper_add(&crtc->base, &ast_crtc_helper_funcs); +	drm_mode_crtc_set_gamma_size(crtc, 256); +	drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs); +  	return 0;  err_kfree: @@ -975,7 +911,7 @@ err_kfree:  static int ast_encoder_init(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	struct drm_encoder *encoder = &ast->encoder;  	int ret; @@ -995,7 +931,7 @@ static int ast_encoder_init(struct drm_device *dev)  static int ast_get_modes(struct drm_connector *connector)  {  	struct ast_connector *ast_connector = to_ast_connector(connector); -	struct ast_private *ast = connector->dev->dev_private; +	struct ast_private *ast = to_ast_private(connector->dev);  	struct edid *edid;  	int ret;  	bool flags = false; @@ -1026,7 +962,7 @@ static int ast_get_modes(struct drm_connector *connector)  static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,  			  struct drm_display_mode *mode)  { -	struct ast_private *ast = connector->dev->dev_private; +	struct ast_private *ast = to_ast_private(connector->dev);  	int flags = MODE_NOMODE;  	uint32_t jtemp; @@ -1044,7 +980,7 @@ static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,  		if ((ast->chip == AST2100) || (ast->chip == AST2200) ||  		    (ast->chip == AST2300) || (ast->chip == AST2400) || -		    (ast->chip == AST2500) || (ast->chip == AST1180)) { +		    (ast->chip == AST2500)) {  			if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080))  				return MODE_OK; @@ -1114,7 +1050,7 @@ static int ast_connector_init(struct drm_device *dev)  	connector = &ast_connector->base;  	ast_connector->i2c = ast_i2c_create(dev);  	if (!ast_connector->i2c) -		DRM_ERROR("failed to add ddc bus for connector\n"); +		drm_err(dev, "failed to add ddc bus for connector\n");  	drm_connector_init_with_ddc(dev, connector,  				    &ast_connector_funcs, @@ -1134,62 +1070,48 @@ static int ast_connector_init(struct drm_device *dev)  	return 0;  } -/* allocate cursor cache and pin at start of VRAM */ -static int ast_cursor_init(struct drm_device *dev) -{ -	struct ast_private *ast = dev->dev_private; -	size_t size, i; -	struct drm_gem_vram_object *gbo; -	int ret; - -	size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE); - -	for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) { -		gbo = drm_gem_vram_create(dev, size, 0); -		if (IS_ERR(gbo)) { -			ret = PTR_ERR(gbo); -			goto err_drm_gem_vram_put; -		} -		ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM | -					    DRM_GEM_VRAM_PL_FLAG_TOPDOWN); -		if (ret) { -			drm_gem_vram_put(gbo); -			goto err_drm_gem_vram_put; -		} +/* + * Mode config + */ -		ast->cursor.gbo[i] = gbo; -	} +static const struct drm_mode_config_funcs ast_mode_config_funcs = { +	.fb_create = drm_gem_fb_create, +	.mode_valid = drm_vram_helper_mode_valid, +	.atomic_check = drm_atomic_helper_check, +	.atomic_commit = drm_atomic_helper_commit, +}; -	return 0; +int ast_mode_config_init(struct ast_private *ast) +{ +	struct drm_device *dev = ast->dev; +	int ret; -err_drm_gem_vram_put: -	while (i) { -		--i; -		gbo = ast->cursor.gbo[i]; -		drm_gem_vram_unpin(gbo); -		drm_gem_vram_put(gbo); -		ast->cursor.gbo[i] = NULL; -	} -	return ret; -} +	ret = ast_cursor_init(ast); +	if (ret) +		return ret; -static void ast_cursor_fini(struct drm_device *dev) -{ -	struct ast_private *ast = dev->dev_private; -	size_t i; -	struct drm_gem_vram_object *gbo; +	ret = drmm_mode_config_init(dev); +	if (ret) +		return ret; -	for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) { -		gbo = ast->cursor.gbo[i]; -		drm_gem_vram_unpin(gbo); -		drm_gem_vram_put(gbo); +	dev->mode_config.funcs = &ast_mode_config_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; +	dev->mode_config.fb_base = pci_resource_start(ast->dev->pdev, 0); + +	if (ast->chip == AST2100 || +	    ast->chip == AST2200 || +	    ast->chip == AST2300 || +	    ast->chip == AST2400 || +	    ast->chip == AST2500) { +		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;  	} -} - -int ast_mode_init(struct drm_device *dev) -{ -	struct ast_private *ast = dev->dev_private; -	int ret;  	memset(&ast->primary_plane, 0, sizeof(ast->primary_plane));  	ret = drm_universal_plane_init(dev, &ast->primary_plane, 0x01, @@ -1198,7 +1120,7 @@ int ast_mode_init(struct drm_device *dev)  				       ARRAY_SIZE(ast_primary_plane_formats),  				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);  	if (ret) { -		DRM_ERROR("ast: drm_universal_plane_init() failed: %d\n", ret); +		drm_err(dev, "ast: drm_universal_plane_init() failed: %d\n", ret);  		return ret;  	}  	drm_plane_helper_add(&ast->primary_plane, @@ -1210,29 +1132,25 @@ int ast_mode_init(struct drm_device *dev)  				       ARRAY_SIZE(ast_cursor_plane_formats),  				       NULL, DRM_PLANE_TYPE_CURSOR, NULL);  	if (ret) { -		DRM_ERROR("drm_universal_plane_failed(): %d\n", ret); +		drm_err(dev, "drm_universal_plane_failed(): %d\n", ret);  		return ret;  	}  	drm_plane_helper_add(&ast->cursor_plane,  			     &ast_cursor_plane_helper_funcs); -	ast_cursor_init(dev);  	ast_crtc_init(dev);  	ast_encoder_init(dev);  	ast_connector_init(dev); -	return 0; -} +	drm_mode_config_reset(dev); -void ast_mode_fini(struct drm_device *dev) -{ -	ast_cursor_fini(dev); +	return 0;  }  static int get_clock(void *i2c_priv)  {  	struct ast_i2c_chan *i2c = i2c_priv; -	struct ast_private *ast = i2c->dev->dev_private; +	struct ast_private *ast = to_ast_private(i2c->dev);  	uint32_t val, val2, count, pass;  	count = 0; @@ -1254,7 +1172,7 @@ static int get_clock(void *i2c_priv)  static int get_data(void *i2c_priv)  {  	struct ast_i2c_chan *i2c = i2c_priv; -	struct ast_private *ast = i2c->dev->dev_private; +	struct ast_private *ast = to_ast_private(i2c->dev);  	uint32_t val, val2, count, pass;  	count = 0; @@ -1276,7 +1194,7 @@ static int get_data(void *i2c_priv)  static void set_clock(void *i2c_priv, int clock)  {  	struct ast_i2c_chan *i2c = i2c_priv; -	struct ast_private *ast = i2c->dev->dev_private; +	struct ast_private *ast = to_ast_private(i2c->dev);  	int i;  	u8 ujcrb7, jtemp; @@ -1292,7 +1210,7 @@ static void set_clock(void *i2c_priv, int clock)  static void set_data(void *i2c_priv, int data)  {  	struct ast_i2c_chan *i2c = i2c_priv; -	struct ast_private *ast = i2c->dev->dev_private; +	struct ast_private *ast = to_ast_private(i2c->dev);  	int i;  	u8 ujcrb7, jtemp; @@ -1332,7 +1250,7 @@ static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev)  	i2c->bit.getscl = get_clock;  	ret = i2c_bit_add_bus(&i2c->adapter);  	if (ret) { -		DRM_ERROR("Failed to register bit i2c\n"); +		drm_err(dev, "Failed to register bit i2c\n");  		goto out_free;  	} @@ -1349,136 +1267,3 @@ static void ast_i2c_destroy(struct ast_i2c_chan *i2c)  	i2c_del_adapter(&i2c->adapter);  	kfree(i2c);  } - -static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height) -{ -	union { -		u32 ul; -		u8 b[4]; -	} srcdata32[2], data32; -	union { -		u16 us; -		u8 b[2]; -	} data16; -	u32 csum = 0; -	s32 alpha_dst_delta, last_alpha_dst_delta; -	u8 *srcxor, *dstxor; -	int i, j; -	u32 per_pixel_copy, two_pixel_copy; - -	alpha_dst_delta = AST_MAX_HWC_WIDTH << 1; -	last_alpha_dst_delta = alpha_dst_delta - (width << 1); - -	srcxor = src; -	dstxor = (u8 *)dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta; -	per_pixel_copy = width & 1; -	two_pixel_copy = width >> 1; - -	for (j = 0; j < height; j++) { -		for (i = 0; i < two_pixel_copy; i++) { -			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0; -			srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0; -			data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); -			data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); -			data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4); -			data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4); - -			writel(data32.ul, dstxor); -			csum += data32.ul; - -			dstxor += 4; -			srcxor += 8; - -		} - -		for (i = 0; i < per_pixel_copy; i++) { -			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0; -			data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); -			data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); -			writew(data16.us, dstxor); -			csum += (u32)data16.us; - -			dstxor += 2; -			srcxor += 4; -		} -		dstxor += last_alpha_dst_delta; -	} -	return csum; -} - -static int ast_cursor_update(void *dst, void *src, unsigned int width, -			     unsigned int height) -{ -	u32 csum; - -	/* do data transfer to cursor cache */ -	csum = copy_cursor_image(src, dst, width, height); - -	/* write checksum + signature */ -	dst += AST_HWC_SIZE; -	writel(csum, dst); -	writel(width, dst + AST_HWC_SIGNATURE_SizeX); -	writel(height, dst + AST_HWC_SIGNATURE_SizeY); -	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX); -	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY); - -	return 0; -} - -static void ast_cursor_set_base(struct ast_private *ast, u64 address) -{ -	u8 addr0 = (address >> 3) & 0xff; -	u8 addr1 = (address >> 11) & 0xff; -	u8 addr2 = (address >> 19) & 0xff; - -	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0); -	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1); -	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2); -} - -static int ast_cursor_move(struct drm_crtc *crtc, -			   int x, int y) -{ -	struct ast_crtc *ast_crtc = to_ast_crtc(crtc); -	struct ast_private *ast = crtc->dev->dev_private; -	struct drm_gem_vram_object *gbo; -	int x_offset, y_offset; -	u8 *dst, *sig; -	u8 jreg; - -	gbo = ast->cursor.gbo[ast->cursor.next_index]; -	dst = drm_gem_vram_vmap(gbo); -	if (IS_ERR(dst)) -		return PTR_ERR(dst); - -	sig = dst + AST_HWC_SIZE; -	writel(x, sig + AST_HWC_SIGNATURE_X); -	writel(y, sig + AST_HWC_SIGNATURE_Y); - -	x_offset = ast_crtc->offset_x; -	y_offset = ast_crtc->offset_y; -	if (x < 0) { -		x_offset = (-x) + ast_crtc->offset_x; -		x = 0; -	} - -	if (y < 0) { -		y_offset = (-y) + ast_crtc->offset_y; -		y = 0; -	} -	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset); -	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset); -	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, (x & 0xff)); -	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, ((x >> 8) & 0x0f)); -	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, (y & 0xff)); -	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, ((y >> 8) & 0x07)); - -	/* dummy write to fire HWC */ -	jreg = 0x02 | -	       0x01; /* enable ARGB4444 cursor */ -	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, jreg); - -	drm_gem_vram_vunmap(gbo, dst); - -	return 0; -} diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 2d1b18619743..c043fe717553 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -39,7 +39,7 @@ static void ast_post_chip_2500(struct drm_device *dev);  void ast_enable_vga(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01);  	ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01); @@ -47,7 +47,7 @@ void ast_enable_vga(struct drm_device *dev)  void ast_enable_mmio(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);  } @@ -55,16 +55,12 @@ void ast_enable_mmio(struct drm_device *dev)  bool ast_is_vga_enabled(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u8 ch; -	if (ast->chip == AST1180) { -		/* TODO 1180 */ -	} else { -		ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT); -		return !!(ch & 0x01); -	} -	return false; +	ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT); + +	return !!(ch & 0x01);  }  static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff }; @@ -74,7 +70,7 @@ static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff };  static void  ast_set_def_ext_reg(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u8 i, index, reg;  	const u8 *ext_reg_info; @@ -276,7 +272,7 @@ cbr_start:  static void ast_init_dram_reg(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u8 j;  	u32 data, temp, i;  	const struct ast_dramstruct *dram_reg_info; @@ -370,7 +366,7 @@ static void ast_init_dram_reg(struct drm_device *dev)  void ast_post_gpu(struct drm_device *dev)  {  	u32 reg; -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	pci_read_config_dword(ast->dev->pdev, 0x04, ®);  	reg |= 0x3; @@ -1600,7 +1596,7 @@ ddr2_init_start:  static void ast_post_chip_2300(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	struct ast2300_dram_param param;  	u32 temp;  	u8 reg; @@ -2032,7 +2028,7 @@ static bool ast_dram_init_2500(struct ast_private *ast)  void ast_post_chip_2500(struct drm_device *dev)  { -	struct ast_private *ast = dev->dev_private; +	struct ast_private *ast = to_ast_private(dev);  	u32 temp;  	u8 reg; @@ -2071,7 +2067,7 @@ void ast_post_chip_2500(struct drm_device *dev)  		}  		if (!ast_dram_init_2500(ast)) -			DRM_ERROR("DRAM init failed !\n"); +			drm_err(dev, "DRAM init failed !\n");  		temp = ast_mindwm(ast, 0x1e6e2040);  		ast_moutdwm(ast, 0x1e6e2040, temp | 0x40); |