Merge tag 'drm-misc-fixes-2023-06-08' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

drm-misc-fixes for v6.4-rc6:
- resume and modeset fixes for ast.
- Fill in fb-helper vars more correctly.
- Assorted ivpu fixes.
- lima context destroy fix.

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ea6b88ec-b653-3781-0b68-cd0275c27923@linux.intel.com
This commit is contained in:
Dave Airlie 2023-06-09 11:10:09 +10:00
commit bcd84301a3
13 changed files with 91 additions and 85 deletions

View File

@ -7,6 +7,7 @@ config DRM_ACCEL_IVPU
depends on PCI && PCI_MSI depends on PCI && PCI_MSI
select FW_LOADER select FW_LOADER
select SHMEM select SHMEM
select GENERIC_ALLOCATOR
help help
Choose this option if you have a system that has an 14th generation Intel CPU Choose this option if you have a system that has an 14th generation Intel CPU
or newer. VPU stands for Versatile Processing Unit and it's a CPU-integrated or newer. VPU stands for Versatile Processing Unit and it's a CPU-integrated

View File

@ -197,6 +197,11 @@ static void ivpu_pll_init_frequency_ratios(struct ivpu_device *vdev)
hw->pll.pn_ratio = clamp_t(u8, fuse_pn_ratio, hw->pll.min_ratio, hw->pll.max_ratio); hw->pll.pn_ratio = clamp_t(u8, fuse_pn_ratio, hw->pll.min_ratio, hw->pll.max_ratio);
} }
static int ivpu_hw_mtl_wait_for_vpuip_bar(struct ivpu_device *vdev)
{
return REGV_POLL_FLD(MTL_VPU_HOST_SS_CPR_RST_CLR, AON, 0, 100);
}
static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable) static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable)
{ {
struct ivpu_hw_info *hw = vdev->hw; struct ivpu_hw_info *hw = vdev->hw;
@ -239,6 +244,12 @@ static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable)
ivpu_err(vdev, "Timed out waiting for PLL ready status\n"); ivpu_err(vdev, "Timed out waiting for PLL ready status\n");
return ret; return ret;
} }
ret = ivpu_hw_mtl_wait_for_vpuip_bar(vdev);
if (ret) {
ivpu_err(vdev, "Timed out waiting for VPUIP bar\n");
return ret;
}
} }
return 0; return 0;
@ -256,7 +267,7 @@ static int ivpu_pll_disable(struct ivpu_device *vdev)
static void ivpu_boot_host_ss_rst_clr_assert(struct ivpu_device *vdev) static void ivpu_boot_host_ss_rst_clr_assert(struct ivpu_device *vdev)
{ {
u32 val = REGV_RD32(MTL_VPU_HOST_SS_CPR_RST_CLR); u32 val = 0;
val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_CLR, TOP_NOC, val); val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_CLR, TOP_NOC, val);
val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_CLR, DSS_MAS, val); val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_CLR, DSS_MAS, val);
@ -754,9 +765,8 @@ static int ivpu_hw_mtl_power_down(struct ivpu_device *vdev)
{ {
int ret = 0; int ret = 0;
if (ivpu_hw_mtl_reset(vdev)) { if (!ivpu_hw_mtl_is_idle(vdev) && ivpu_hw_mtl_reset(vdev)) {
ivpu_err(vdev, "Failed to reset the VPU\n"); ivpu_err(vdev, "Failed to reset the VPU\n");
ret = -EIO;
} }
if (ivpu_pll_disable(vdev)) { if (ivpu_pll_disable(vdev)) {
@ -764,8 +774,10 @@ static int ivpu_hw_mtl_power_down(struct ivpu_device *vdev)
ret = -EIO; ret = -EIO;
} }
if (ivpu_hw_mtl_d0i3_enable(vdev)) if (ivpu_hw_mtl_d0i3_enable(vdev)) {
ivpu_warn(vdev, "Failed to enable D0I3\n"); ivpu_err(vdev, "Failed to enter D0I3\n");
ret = -EIO;
}
return ret; return ret;
} }

View File

@ -91,6 +91,7 @@
#define MTL_VPU_HOST_SS_CPR_RST_SET_MSS_MAS_MASK BIT_MASK(11) #define MTL_VPU_HOST_SS_CPR_RST_SET_MSS_MAS_MASK BIT_MASK(11)
#define MTL_VPU_HOST_SS_CPR_RST_CLR 0x00000098u #define MTL_VPU_HOST_SS_CPR_RST_CLR 0x00000098u
#define MTL_VPU_HOST_SS_CPR_RST_CLR_AON_MASK BIT_MASK(0)
#define MTL_VPU_HOST_SS_CPR_RST_CLR_TOP_NOC_MASK BIT_MASK(1) #define MTL_VPU_HOST_SS_CPR_RST_CLR_TOP_NOC_MASK BIT_MASK(1)
#define MTL_VPU_HOST_SS_CPR_RST_CLR_DSS_MAS_MASK BIT_MASK(10) #define MTL_VPU_HOST_SS_CPR_RST_CLR_DSS_MAS_MASK BIT_MASK(10)
#define MTL_VPU_HOST_SS_CPR_RST_CLR_MSS_MAS_MASK BIT_MASK(11) #define MTL_VPU_HOST_SS_CPR_RST_CLR_MSS_MAS_MASK BIT_MASK(11)

View File

@ -183,9 +183,7 @@ ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct v
struct ivpu_ipc_info *ipc = vdev->ipc; struct ivpu_ipc_info *ipc = vdev->ipc;
int ret; int ret;
ret = mutex_lock_interruptible(&ipc->lock); mutex_lock(&ipc->lock);
if (ret)
return ret;
if (!ipc->on) { if (!ipc->on) {
ret = -EAGAIN; ret = -EAGAIN;

View File

@ -431,6 +431,7 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32
struct ivpu_file_priv *file_priv = file->driver_priv; struct ivpu_file_priv *file_priv = file->driver_priv;
struct ivpu_device *vdev = file_priv->vdev; struct ivpu_device *vdev = file_priv->vdev;
struct ww_acquire_ctx acquire_ctx; struct ww_acquire_ctx acquire_ctx;
enum dma_resv_usage usage;
struct ivpu_bo *bo; struct ivpu_bo *bo;
int ret; int ret;
u32 i; u32 i;
@ -461,22 +462,28 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32
job->cmd_buf_vpu_addr = bo->vpu_addr + commands_offset; job->cmd_buf_vpu_addr = bo->vpu_addr + commands_offset;
ret = drm_gem_lock_reservations((struct drm_gem_object **)job->bos, 1, &acquire_ctx); ret = drm_gem_lock_reservations((struct drm_gem_object **)job->bos, buf_count,
&acquire_ctx);
if (ret) { if (ret) {
ivpu_warn(vdev, "Failed to lock reservations: %d\n", ret); ivpu_warn(vdev, "Failed to lock reservations: %d\n", ret);
return ret; return ret;
} }
ret = dma_resv_reserve_fences(bo->base.resv, 1); for (i = 0; i < buf_count; i++) {
ret = dma_resv_reserve_fences(job->bos[i]->base.resv, 1);
if (ret) { if (ret) {
ivpu_warn(vdev, "Failed to reserve fences: %d\n", ret); ivpu_warn(vdev, "Failed to reserve fences: %d\n", ret);
goto unlock_reservations; goto unlock_reservations;
} }
}
dma_resv_add_fence(bo->base.resv, job->done_fence, DMA_RESV_USAGE_WRITE); for (i = 0; i < buf_count; i++) {
usage = (i == CMD_BUF_IDX) ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_BOOKKEEP;
dma_resv_add_fence(job->bos[i]->base.resv, job->done_fence, usage);
}
unlock_reservations: unlock_reservations:
drm_gem_unlock_reservations((struct drm_gem_object **)job->bos, 1, &acquire_ctx); drm_gem_unlock_reservations((struct drm_gem_object **)job->bos, buf_count, &acquire_ctx);
wmb(); /* Flush write combining buffers */ wmb(); /* Flush write combining buffers */

View File

@ -587,16 +587,11 @@ static int ivpu_mmu_strtab_init(struct ivpu_device *vdev)
int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid) int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid)
{ {
struct ivpu_mmu_info *mmu = vdev->mmu; struct ivpu_mmu_info *mmu = vdev->mmu;
int ret; int ret = 0;
ret = mutex_lock_interruptible(&mmu->lock); mutex_lock(&mmu->lock);
if (ret) if (!mmu->on)
return ret;
if (!mmu->on) {
ret = 0;
goto unlock; goto unlock;
}
ret = ivpu_mmu_cmdq_write_tlbi_nh_asid(vdev, ssid); ret = ivpu_mmu_cmdq_write_tlbi_nh_asid(vdev, ssid);
if (ret) if (ret)
@ -614,7 +609,7 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma)
struct ivpu_mmu_cdtab *cdtab = &mmu->cdtab; struct ivpu_mmu_cdtab *cdtab = &mmu->cdtab;
u64 *entry; u64 *entry;
u64 cd[4]; u64 cd[4];
int ret; int ret = 0;
if (ssid > IVPU_MMU_CDTAB_ENT_COUNT) if (ssid > IVPU_MMU_CDTAB_ENT_COUNT)
return -EINVAL; return -EINVAL;
@ -655,14 +650,9 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma)
ivpu_dbg(vdev, MMU, "CDTAB %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", ivpu_dbg(vdev, MMU, "CDTAB %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n",
cd_dma ? "write" : "clear", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]); cd_dma ? "write" : "clear", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]);
ret = mutex_lock_interruptible(&mmu->lock); mutex_lock(&mmu->lock);
if (ret) if (!mmu->on)
return ret;
if (!mmu->on) {
ret = 0;
goto unlock; goto unlock;
}
ret = ivpu_mmu_cmdq_write_cfgi_all(vdev); ret = ivpu_mmu_cmdq_write_cfgi_all(vdev);
if (ret) if (ret)

View File

@ -119,35 +119,15 @@ err_astdp_edid_not_ready:
/* /*
* Launch Aspeed DP * Launch Aspeed DP
*/ */
void ast_dp_launch(struct drm_device *dev, u8 bPower) void ast_dp_launch(struct drm_device *dev)
{ {
u32 i = 0, j = 0, WaitCount = 1; u32 i = 0;
u8 bDPTX = 0;
u8 bDPExecute = 1; u8 bDPExecute = 1;
struct ast_device *ast = to_ast_device(dev); struct ast_device *ast = to_ast_device(dev);
// S3 come back, need more time to wait BMC ready.
if (bPower)
WaitCount = 300;
// Wait total count by different condition.
for (j = 0; j < WaitCount; j++) {
bDPTX = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK);
if (bDPTX)
break;
msleep(100);
}
// 0xE : ASTDP with DPMCU FW handling
if (bDPTX == ASTDP_DPMCU_TX) {
// Wait one second then timeout. // Wait one second then timeout.
i = 0; while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) !=
ASTDP_MCU_FW_EXECUTING) {
while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, COPROCESSOR_LAUNCH) !=
COPROCESSOR_LAUNCH) {
i++; i++;
// wait 100 ms // wait 100 ms
msleep(100); msleep(100);
@ -159,14 +139,13 @@ void ast_dp_launch(struct drm_device *dev, u8 bPower)
} }
} }
if (bDPExecute) if (!bDPExecute)
ast->tx_chip_types |= BIT(AST_TX_ASTDP); drm_err(dev, "Wait DPMCU executing timeout\n");
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
(u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
ASTDP_HOST_EDID_READ_DONE); ASTDP_HOST_EDID_READ_DONE);
} }
}

View File

@ -350,9 +350,6 @@ int ast_mode_config_init(struct ast_device *ast);
#define AST_DP501_LINKRATE 0xf014 #define AST_DP501_LINKRATE 0xf014
#define AST_DP501_EDID_DATA 0xf020 #define AST_DP501_EDID_DATA 0xf020
/* Define for Soc scratched reg */
#define COPROCESSOR_LAUNCH BIT(5)
/* /*
* Display Transmitter Type: * Display Transmitter Type:
*/ */
@ -480,7 +477,7 @@ struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev);
/* aspeed DP */ /* aspeed DP */
int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata); int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata);
void ast_dp_launch(struct drm_device *dev, u8 bPower); void ast_dp_launch(struct drm_device *dev);
void ast_dp_power_on_off(struct drm_device *dev, bool no); void ast_dp_power_on_off(struct drm_device *dev, bool no);
void ast_dp_set_on_off(struct drm_device *dev, bool no); void ast_dp_set_on_off(struct drm_device *dev, bool no);
void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode); void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode);

View File

@ -254,8 +254,13 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
case 0x0c: case 0x0c:
ast->tx_chip_types = AST_TX_DP501_BIT; ast->tx_chip_types = AST_TX_DP501_BIT;
} }
} else if (ast->chip == AST2600) } else if (ast->chip == AST2600) {
ast_dp_launch(&ast->base, 0); if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK) ==
ASTDP_DPMCU_TX) {
ast->tx_chip_types = AST_TX_ASTDP_BIT;
ast_dp_launch(&ast->base);
}
}
/* Print stuff for diagnostic purposes */ /* Print stuff for diagnostic purposes */
if (ast->tx_chip_types & AST_TX_NONE_BIT) if (ast->tx_chip_types & AST_TX_NONE_BIT)
@ -264,6 +269,8 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
drm_info(dev, "Using Sil164 TMDS transmitter\n"); drm_info(dev, "Using Sil164 TMDS transmitter\n");
if (ast->tx_chip_types & AST_TX_DP501_BIT) if (ast->tx_chip_types & AST_TX_DP501_BIT)
drm_info(dev, "Using DP501 DisplayPort transmitter\n"); drm_info(dev, "Using DP501 DisplayPort transmitter\n");
if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
drm_info(dev, "Using ASPEED DisplayPort transmitter\n");
return 0; return 0;
} }

View File

@ -1647,6 +1647,8 @@ static int ast_dp501_output_init(struct ast_device *ast)
static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector) static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
{ {
void *edid; void *edid;
struct drm_device *dev = connector->dev;
struct ast_device *ast = to_ast_device(dev);
int succ; int succ;
int count; int count;
@ -1655,9 +1657,17 @@ static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
if (!edid) if (!edid)
goto err_drm_connector_update_edid_property; goto err_drm_connector_update_edid_property;
/*
* Protect access to I/O registers from concurrent modesetting
* by acquiring the I/O-register lock.
*/
mutex_lock(&ast->ioregs_lock);
succ = ast_astdp_read_edid(connector->dev, edid); succ = ast_astdp_read_edid(connector->dev, edid);
if (succ < 0) if (succ < 0)
goto err_kfree; goto err_mutex_unlock;
mutex_unlock(&ast->ioregs_lock);
drm_connector_update_edid_property(connector, edid); drm_connector_update_edid_property(connector, edid);
count = drm_add_edid_modes(connector, edid); count = drm_add_edid_modes(connector, edid);
@ -1665,7 +1675,8 @@ static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
return count; return count;
err_kfree: err_mutex_unlock:
mutex_unlock(&ast->ioregs_lock);
kfree(edid); kfree(edid);
err_drm_connector_update_edid_property: err_drm_connector_update_edid_property:
drm_connector_update_edid_property(connector, NULL); drm_connector_update_edid_property(connector, NULL);

View File

@ -380,7 +380,8 @@ void ast_post_gpu(struct drm_device *dev)
ast_set_def_ext_reg(dev); ast_set_def_ext_reg(dev);
if (ast->chip == AST2600) { if (ast->chip == AST2600) {
ast_dp_launch(dev, 1); if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
ast_dp_launch(dev);
} else if (ast->config_mode == ast_use_p2a) { } else if (ast->config_mode == ast_use_p2a) {
if (ast->chip == AST2500) if (ast->chip == AST2500)
ast_post_chip_2500(dev); ast_post_chip_2500(dev);

View File

@ -1545,17 +1545,19 @@ static void drm_fb_helper_fill_pixel_fmt(struct fb_var_screeninfo *var,
} }
} }
static void __fill_var(struct fb_var_screeninfo *var, static void __fill_var(struct fb_var_screeninfo *var, struct fb_info *info,
struct drm_framebuffer *fb) struct drm_framebuffer *fb)
{ {
int i; int i;
var->xres_virtual = fb->width; var->xres_virtual = fb->width;
var->yres_virtual = fb->height; var->yres_virtual = fb->height;
var->accel_flags = FB_ACCELF_TEXT; var->accel_flags = 0;
var->bits_per_pixel = drm_format_info_bpp(fb->format, 0); var->bits_per_pixel = drm_format_info_bpp(fb->format, 0);
var->height = var->width = 0; var->height = info->var.height;
var->width = info->var.width;
var->left_margin = var->right_margin = 0; var->left_margin = var->right_margin = 0;
var->upper_margin = var->lower_margin = 0; var->upper_margin = var->lower_margin = 0;
var->hsync_len = var->vsync_len = 0; var->hsync_len = var->vsync_len = 0;
@ -1618,7 +1620,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
return -EINVAL; return -EINVAL;
} }
__fill_var(var, fb); __fill_var(var, info, fb);
/* /*
* fb_pan_display() validates this, but fb_set_par() doesn't and just * fb_pan_display() validates this, but fb_set_par() doesn't and just
@ -2074,7 +2076,7 @@ static void drm_fb_helper_fill_var(struct fb_info *info,
info->pseudo_palette = fb_helper->pseudo_palette; info->pseudo_palette = fb_helper->pseudo_palette;
info->var.xoffset = 0; info->var.xoffset = 0;
info->var.yoffset = 0; info->var.yoffset = 0;
__fill_var(&info->var, fb); __fill_var(&info->var, info, fb);
info->var.activate = FB_ACTIVATE_NOW; info->var.activate = FB_ACTIVATE_NOW;
drm_fb_helper_fill_pixel_fmt(&info->var, format); drm_fb_helper_fill_pixel_fmt(&info->var, format);

View File

@ -165,7 +165,7 @@ int lima_sched_context_init(struct lima_sched_pipe *pipe,
void lima_sched_context_fini(struct lima_sched_pipe *pipe, void lima_sched_context_fini(struct lima_sched_pipe *pipe,
struct lima_sched_context *context) struct lima_sched_context *context)
{ {
drm_sched_entity_fini(&context->base); drm_sched_entity_destroy(&context->base);
} }
struct dma_fence *lima_sched_context_queue_task(struct lima_sched_task *task) struct dma_fence *lima_sched_context_queue_task(struct lima_sched_task *task)