drm/phytium: Bugfix Xorg startup for ps23xx when using pe2201

bmc card

When the pe2201 bmc card is detected on ps23xx SoCs, map the card's
graphics memory to device attributes to avoid unnecessary trouble.

Reviewed-by: Jiakun Shuai<shuaijiakun1288@phytium.com.cn>
Signed-off-by: Xu Yan <xuyan1481@phytium.com.cn>
Signed-off-by: WangHao <wanghao1851@phytium.com.cn>
This commit is contained in:
xuyan 2024-06-26 14:21:46 +08:00
parent 9debb2ab33
commit 4c42a59bb6
4 changed files with 67 additions and 15 deletions

View File

@ -250,7 +250,7 @@ static int phytium_display_load(struct drm_device *dev, unsigned long flags)
goto failed_modeset_init;
}
if (priv->support_memory_type & MEMORY_TYPE_VRAM)
if (priv->support_memory_type & (MEMORY_TYPE_VRAM_WC | MEMORY_TYPE_VRAM_DEVICE))
priv->vram_hw_init(priv);
ret = drm_irq_install(dev, priv->irq);
@ -281,8 +281,25 @@ static void phytium_display_unload(struct drm_device *dev)
drm_mode_config_cleanup(dev);
}
/* phytium display specific ioctls
* The device specific ioctl range is 0x40 to 0x79.
*/
#define DRM_PHYTIUM_VRAM_TYPE_DEVICE 0x0
#define DRM_IOCTL_PHYTIUM_VRAM_TYPE_DEVICE DRM_IO(DRM_COMMAND_BASE\
+ DRM_PHYTIUM_VRAM_TYPE_DEVICE)
static int phytium_ioctl_check_vram_device(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct phytium_display_private *priv = dev->dev_private;
return ((priv->support_memory_type == MEMORY_TYPE_VRAM_DEVICE) ? 1 : 0);
}
static const struct drm_ioctl_desc phytium_ioctls[] = {
/* for test, none so far */
DRM_IOCTL_DEF_DRV(PHYTIUM_VRAM_TYPE_DEVICE, phytium_ioctl_check_vram_device,
DRM_AUTH|DRM_UNLOCKED),
};
static const struct file_operations phytium_drm_driver_fops = {
@ -382,7 +399,7 @@ static int phytium_display_pm_resume(struct drm_device *dev)
phytium_crtc_resume(dev);
phytium_gem_resume(dev);
if (priv->support_memory_type & MEMORY_TYPE_VRAM)
if (priv->support_memory_type & (MEMORY_TYPE_VRAM_WC | MEMORY_TYPE_VRAM_DEVICE))
priv->vram_hw_init(priv);
ret = drm_atomic_helper_resume(dev, dev->mode_config.suspend_state);

View File

@ -49,9 +49,10 @@ enum phytium_mem_state_type {
PHYTIUM_MEM_STATE_TYPE_COUNT,
};
#define MEMORY_TYPE_VRAM 0x1
#define MEMORY_TYPE_VRAM_WC 0x1
#define MEMORY_TYPE_SYSTEM_CARVEOUT 0x2
#define MEMORY_TYPE_SYSTEM_UNIFIED 0x4
#define MEMORY_TYPE_VRAM_DEVICE 0x8
#define IS_PLATFORM(priv, p) ((priv)->info.platform_mask & BIT(p))

View File

@ -86,7 +86,8 @@ phytium_gem_prime_get_sg_table(struct drm_gem_object *obj)
return ERR_PTR(-ENOMEM);
}
if ((phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM) ||
if ((phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_WC) ||
(phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_DEVICE) ||
(phytium_gem_obj->memory_type == MEMORY_TYPE_SYSTEM_CARVEOUT)) {
ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
if (ret) {
@ -280,7 +281,8 @@ int phytium_gem_suspend(struct drm_device *drm_dev)
int ret = 0;
list_for_each_entry(phytium_gem_obj, &priv->gem_list_head, list) {
if (phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM)
if ((phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_WC) &&
(phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_DEVICE))
continue;
phytium_gem_obj->vaddr_save = vmalloc(phytium_gem_obj->size);
@ -299,7 +301,8 @@ int phytium_gem_suspend(struct drm_device *drm_dev)
return 0;
malloc_failed:
list_for_each_entry(phytium_gem_obj, &priv->gem_list_head, list) {
if (phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM)
if ((phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_WC) &&
(phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_DEVICE))
continue;
if (phytium_gem_obj->vaddr_save) {
@ -316,7 +319,8 @@ void phytium_gem_resume(struct drm_device *drm_dev)
struct phytium_gem_object *phytium_gem_obj = NULL;
list_for_each_entry(phytium_gem_obj, &priv->gem_list_head, list) {
if (phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM)
if ((phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_WC) &&
(phytium_gem_obj->memory_type != MEMORY_TYPE_VRAM_DEVICE))
continue;
memcpy(phytium_gem_obj->vaddr, phytium_gem_obj->vaddr_save, phytium_gem_obj->size);
@ -335,7 +339,8 @@ void phytium_gem_free_object(struct drm_gem_object *obj)
DRM_DEBUG_KMS("free phytium_gem_obj iova:0x%pa size:0x%lx\n",
&phytium_gem_obj->iova, phytium_gem_obj->size);
if (phytium_gem_obj->vaddr) {
if (phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM) {
if ((phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_WC) ||
(phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_DEVICE)) {
phytium_memory_pool_free(priv, phytium_gem_obj->vaddr, size);
priv->mem_state[PHYTIUM_MEM_VRAM_ALLOC] -= size;
} else if (phytium_gem_obj->memory_type == MEMORY_TYPE_SYSTEM_CARVEOUT) {
@ -368,10 +373,14 @@ int phytium_gem_mmap_obj(struct drm_gem_object *obj, struct vm_area_struct *vma)
vma->vm_pgoff = 0;
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
if (phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM) {
if (phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_WC) {
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
ret = remap_pfn_range(vma, vma->vm_start, pfn,
vma->vm_end - vma->vm_start, vma->vm_page_prot);
} else if (phytium_gem_obj->memory_type == MEMORY_TYPE_VRAM_DEVICE) {
vma->vm_page_prot = pgprot_device(vma->vm_page_prot);
ret = remap_pfn_range(vma, vma->vm_start, pfn,
vma->vm_end - vma->vm_start, vma->vm_page_prot);
} else if (phytium_gem_obj->memory_type == MEMORY_TYPE_SYSTEM_CARVEOUT) {
ret = remap_pfn_range(vma, vma->vm_start, pfn,
vma->vm_end - vma->vm_start, vma->vm_page_prot);
@ -434,7 +443,7 @@ struct phytium_gem_object *phytium_gem_create_object(struct drm_device *dev, uns
goto failed_object_init;
}
if (priv->support_memory_type & MEMORY_TYPE_VRAM) {
if (priv->support_memory_type & (MEMORY_TYPE_VRAM_WC | MEMORY_TYPE_VRAM_DEVICE)) {
ret = phytium_memory_pool_alloc(priv, &phytium_gem_obj->vaddr,
&phytium_gem_obj->phys_addr, size);
if (ret) {
@ -442,7 +451,7 @@ struct phytium_gem_object *phytium_gem_create_object(struct drm_device *dev, uns
goto failed_dma_alloc;
}
phytium_gem_obj->iova = phytium_gem_obj->phys_addr;
phytium_gem_obj->memory_type = MEMORY_TYPE_VRAM;
phytium_gem_obj->memory_type = priv->support_memory_type;
priv->mem_state[PHYTIUM_MEM_VRAM_ALLOC] += size;
} else if (priv->support_memory_type & MEMORY_TYPE_SYSTEM_CARVEOUT) {
ret = phytium_memory_pool_alloc(priv, &phytium_gem_obj->vaddr,

View File

@ -27,6 +27,24 @@ void phytium_pci_vram_hw_init(struct phytium_display_private *priv)
pci_priv->dc_hw_vram_init(priv, priv->pool_phys_addr, priv->pool_size);
}
static bool phytium_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;
}
int phytium_pci_vram_init(struct pci_dev *pdev, struct phytium_display_private *priv)
{
int ret = 0;
@ -34,8 +52,15 @@ int phytium_pci_vram_init(struct pci_dev *pdev, struct phytium_display_private *
priv->pool_phys_addr = pci_resource_start(pdev, 2);
priv->pool_size = pci_resource_len(pdev, 2);
if ((priv->pool_phys_addr != 0) && (priv->pool_size != 0)) {
priv->pool_virt_addr = devm_ioremap_wc(&pdev->dev, priv->pool_phys_addr,
priv->pool_size);
if ((pdev->device == 0xdc3e) && phytium_pci_host_is_5c01(pdev->bus)) {
priv->pool_virt_addr = devm_ioremap(&pdev->dev, priv->pool_phys_addr,
priv->pool_size);
priv->support_memory_type = MEMORY_TYPE_VRAM_DEVICE;
} else {
priv->pool_virt_addr = devm_ioremap_wc(&pdev->dev, priv->pool_phys_addr,
priv->pool_size);
priv->support_memory_type = MEMORY_TYPE_VRAM_WC;
}
if (priv->pool_virt_addr == NULL) {
DRM_ERROR("pci vram ioremap fail, addr:0x%llx, size:0x%llx\n",
priv->pool_phys_addr, priv->pool_size);
@ -47,7 +72,6 @@ int phytium_pci_vram_init(struct pci_dev *pdev, struct phytium_display_private *
goto failed_init_memory_pool;
priv->mem_state[PHYTIUM_MEM_VRAM_TOTAL] = priv->pool_size;
priv->support_memory_type = MEMORY_TYPE_VRAM;
priv->vram_hw_init = phytium_pci_vram_hw_init;
} else {
DRM_DEBUG_KMS("not support vram\n");
@ -67,7 +91,8 @@ failed_ioremap:
void phytium_pci_vram_fini(struct pci_dev *pdev, struct phytium_display_private *priv)
{
if (priv->support_memory_type == MEMORY_TYPE_VRAM) {
if ((priv->support_memory_type == MEMORY_TYPE_VRAM_WC) ||
(priv->support_memory_type == MEMORY_TYPE_VRAM_DEVICE)) {
phytium_memory_pool_fini(&pdev->dev, priv);
devm_iounmap(&pdev->dev, priv->pool_virt_addr);
}