Commit 968ee436 authored by Jiakun Shuai's avatar Jiakun Shuai
Browse files

drm/ast: Fixed display error for ps23xx when using ast bmc card

phytium inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9NGXP


CVE: NA

-----------------------------------------------------------------

When the ast bmc card is detected on ps23xx SoCs, change the card's
vram to uncache mode to avoid unnecessary trouble.

Signed-off-by: default avatarWangHao <wanghao1851@phytium.com.cn>
Signed-off-by: default avatarJiakun Shuai <shuaijiakun1288@phytium.com.cn>
parent b5620901
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -50,11 +50,31 @@ module_param_named(modeset, ast_modeset, int, 0400);

DEFINE_DRM_GEM_FOPS(ast_fops);

#define DRM_AST_VRAM_TYPE_DEVICE 0x0
#define DRM_IOCTL_AST_VRAM_TYPE_DEVICE	DRM_IO(DRM_COMMAND_BASE\
	+ DRM_AST_VRAM_TYPE_DEVICE)

static int ast_ioctl_check_5c01_device(struct drm_device *dev, void *data,
				struct drm_file *file_priv)
{
	struct ast_private *priv = to_ast_private(dev);

	return priv->is_5c01_device ? 1 : 0;
}

static const struct drm_ioctl_desc ast_ioctls[] = {
	/* for test, none so far */
	DRM_IOCTL_DEF_DRV(AST_VRAM_TYPE_DEVICE, ast_ioctl_check_5c01_device,
						DRM_AUTH|DRM_UNLOCKED),
};

static struct drm_driver ast_driver = {
	.driver_features = DRIVER_ATOMIC |
			   DRIVER_GEM |
			   DRIVER_MODESET,

	.ioctls = ast_ioctls,
	.num_ioctls = ARRAY_SIZE(ast_ioctls),
	.fops = &ast_fops,
	.name = DRIVER_NAME,
	.desc = DRIVER_DESC,
+1 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ struct ast_private {
	struct drm_encoder encoder;
	struct ast_connector connector;

	bool is_5c01_device;
	bool support_wide_screen;
	enum {
		ast_use_p2a,
+54 −0
Original line number Diff line number Diff line
@@ -74,6 +74,52 @@ static u32 ast_get_vram_size(struct ast_private *ast)
	return vram_size;
}

static int ast_driver_io_mem_reserve(struct ttm_bo_device *bdev,
									struct ttm_resource *mem)
{
	struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bdev);
	size_t bus_size = (size_t)mem->num_pages << PAGE_SHIFT;

	switch (mem->mem_type) {
	case TTM_PL_SYSTEM:     /* nothing to do */
			break;
	case TTM_PL_VRAM:
			mem->bus.offset = (mem->start << PAGE_SHIFT) + vmm->vram_base;
			mem->bus.is_iomem = true;

			mem->placement = TTM_PL_FLAG_UNCACHED;
			mem->bus.addr = ioremap(mem->bus.offset, bus_size);

			if (!mem->bus.addr)
				return -ENOMEM;

			break;
	default:
			return -EINVAL;
	}

	return 0;
}

static bool ast_pci_host_is_5c01(struct pci_bus *bus)
{
	struct pci_bus *child = bus;
	struct pci_dev *root = NULL;

	while (child) {
		if (child->parent->parent)
			child = child->parent;
		else
			break;
	}

	root = child->self;

	if ((root->vendor == 0x1db7) && (root->device == 0x5c01))
		return true;
	return false;
}

static void ast_mm_release(struct drm_device *dev, void *ptr)
{
	struct ast_private *ast = to_ast_private(dev);
@@ -86,6 +132,7 @@ static void ast_mm_release(struct drm_device *dev, void *ptr)
int ast_mm_init(struct ast_private *ast)
{
	struct drm_device *dev = &ast->base;
	struct pci_dev *pdev = to_pci_dev(dev->dev);
	u32 vram_size;
	int ret;

@@ -98,6 +145,13 @@ int ast_mm_init(struct ast_private *ast)
		return ret;
	}

	if (ast_pci_host_is_5c01(pdev->bus) && dev->vram_mm->bdev.driver) {
		ast->is_5c01_device = true;
		dev->vram_mm->bdev.driver->io_mem_reserve = ast_driver_io_mem_reserve;
	} else {
		ast->is_5c01_device = false;
	}

	arch_io_reserve_memtype_wc(pci_resource_start(dev->pdev, 0),
				   pci_resource_len(dev->pdev, 0));
	ast->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0),