diff --git a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c index 90a0c7ffb3c8..bcef8df546e0 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c @@ -1833,6 +1833,90 @@ static const struct adreno_reglist_pipe x285_dyn_pwrup_reglist_regs[] = { }; DECLARE_ADRENO_REGLIST_PIPE_LIST(x285_dyn_pwrup_reglist); +static const struct a6xx_hfi_clx_table_v2_cmd x285_clx_tbl = { + .version = (2 << 16) | 1, + .domain = { + /* GX DOMAIN */ + { + .data = CLX_DATA(60, 11, 0, 1), + .clxt = 0, + .clxh = 0, + .urg_mode = 1, + .lkg_en = 0, + .curr_budget = 100, + }, + /* MXG DOMAIN */ + { + .data = CLX_DATA(60, 3, 1, 1), + .clxt = 0, + .clxh = 0, + .urg_mode = 1, + .lkg_en = 0, + .curr_budget = 100, + }, + }, +}; + +struct a6xx_hfi_limits_tbl x285_limits_tbl[] = { + { + .feature_id = GMU_MIT_IFF, + .domain = GMU_GX_DOMAIN, + .feature_rev = 0, + .cfg = { + .enable = 1, + .msg_path = 0, + .lkg_en = 0, + .mode = 0, + .sid = 12, + .mit_time = 5, + .curr_limit = 18000, + }, + }, + { + .feature_id = GMU_MIT_IFF, + .domain = GMU_MX_DOMAIN, + .feature_rev = 0, + .cfg = { + .enable = 1, + .msg_path = 0, + .lkg_en = 0, + .mode = 0, + .sid = 18, + .mit_time = 2000, + .curr_limit = 6000, + }, + }, + { + .feature_id = GMU_MIT_PCLX, + .domain = GMU_GX_DOMAIN, + .feature_rev = 0, + .cfg = { + .enable = 1, + .msg_path = 0, + .lkg_en = 0, + .mode = 0, + .sid = 6, + .mit_time = 3, + .curr_limit = 66000, + }, + }, + { + .feature_id = GMU_MIT_PCLX, + .domain = GMU_MX_DOMAIN, + .feature_rev = 0, + .cfg = { + .enable = 0, + .msg_path = 0, + .lkg_en = 0, + .mode = 0, + .sid = 6, + .mit_time = 3, + .curr_limit = 18000, + }, + }, +}; +DECLARE_ADRENO_LIMITS_TABLE(x285_limits); + static const struct adreno_reglist_pipe a810_nonctxt_regs[] = { { REG_A8XX_CP_SMMU_STREAM_ID_LPAC, 0x00000101, BIT(PIPE_NONE) }, { REG_A8XX_GRAS_DBG_ECO_CNTL, 0x00f80800, BIT(PIPE_BV) | BIT(PIPE_BR) }, @@ -2397,6 +2481,90 @@ static const struct adreno_reglist_pipe a840_dyn_pwrup_reglist_regs[] = { }; DECLARE_ADRENO_REGLIST_PIPE_LIST(a840_dyn_pwrup_reglist); +static const struct a6xx_hfi_clx_table_v2_cmd a840_clx_tbl = { + .version = (2 << 16) | 1, + .domain = { + /* GX DOMAIN */ + { + .data = CLX_DATA(60, 5, 1, 1), + .clxt = 0, + .clxh = 0, + .urg_mode = 1, + .lkg_en = 0, + .curr_budget = 100, + }, + /* MXG DOMAIN */ + { + .data = CLX_DATA(60, 1, 1, 1), + .clxt = 0, + .clxh = 0, + .urg_mode = 1, + .lkg_en = 0, + .curr_budget = 50, + }, + }, +}; + +struct a6xx_hfi_limits_tbl a840_limits_tbl[] = { + { + .feature_id = GMU_MIT_IFF, + .domain = GMU_GX_DOMAIN, + .feature_rev = 0, + .cfg = { + .enable = 1, + .msg_path = 0, + .lkg_en = 0, + .mode = 0, + .sid = 12, + .mit_time = 5, + .curr_limit = 6000, + }, + }, + { + .feature_id = GMU_MIT_IFF, + .domain = GMU_MX_DOMAIN, + .feature_rev = 0, + .cfg = { + .enable = 1, + .msg_path = 0, + .lkg_en = 0, + .mode = 0, + .sid = 9, + .mit_time = 2000, + .curr_limit = 6000, + }, + }, + { + .feature_id = GMU_MIT_PCLX, + .domain = GMU_GX_DOMAIN, + .feature_rev = 0, + .cfg = { + .enable = 1, + .msg_path = 0, + .lkg_en = 0, + .mode = 0, + .sid = 7, + .mit_time = 3, + .curr_limit = 30000, + }, + }, + { + .feature_id = GMU_MIT_PCLX, + .domain = GMU_MX_DOMAIN, + .feature_rev = 0, + .cfg = { + .enable = 0, + .msg_path = 0, + .lkg_en = 0, + .mode = 0, + .sid = 7, + .mit_time = 3, + .curr_limit = 6000, + }, + }, +}; +DECLARE_ADRENO_LIMITS_TABLE(a840_limits); + static const struct adreno_info a8xx_gpus[] = { { .chip_ids = ADRENO_CHIP_IDS(0x44070001), @@ -2432,6 +2600,8 @@ static const struct adreno_info a8xx_gpus[] = { }, { /* sentinel */ }, }, + .clx_tbl = &x285_clx_tbl, + .limits_tbl = &x285_limits, }, .speedbins = ADRENO_SPEEDBINS( { 0, 0 }, @@ -2474,6 +2644,8 @@ static const struct adreno_info a8xx_gpus[] = { }, { /* sentinel */ }, }, + .clx_tbl = &a840_clx_tbl, + .limits_tbl = &a840_limits, }, .preempt_record_size = 19708 * SZ_1K, .speedbins = ADRENO_SPEEDBINS( diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index b50c57f427b4..a4b197be7e1a 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -36,6 +36,19 @@ struct cpu_gpu_lock { uint64_t regs[]; }; +struct a6xx_limits_tbl { + /** @tbl: List of limits table **/ + struct a6xx_hfi_limits_tbl *tbl; + /** @count: Number of entries in the list **/ + u32 count; +}; + +#define DECLARE_ADRENO_LIMITS_TABLE(name) \ +static const struct a6xx_limits_tbl name = { \ + .tbl = name ## _tbl, \ + .count = ARRAY_SIZE(name ## _tbl), \ +} + /** * struct a6xx_info - a6xx specific information from device table * @@ -56,6 +69,8 @@ struct a6xx_info { u32 gmu_cgc_mode; u32 prim_fifo_threshold; const struct a6xx_bcm *bcms; + const struct a6xx_hfi_clx_table_v2_cmd *clx_tbl; + const struct a6xx_limits_tbl *limits_tbl; }; struct a6xx_gpu { diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c index 186a73c0b99c..16a94d210844 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c @@ -888,6 +888,73 @@ static int a6xx_hfi_enable_acd(struct a6xx_gmu *gmu) return 0; } +static int a6xx_hfi_enable_iff_pclx(struct a6xx_gmu *gmu, const struct a6xx_limits_tbl *limits) +{ + struct a6xx_hfi_table_entry *entry; + struct a6xx_hfi_table *tbl; + size_t entry_size; + size_t size; + int ret; + + if (!limits) + return 0; + + ret = a6xx_hfi_feature_ctrl_msg(gmu, HFI_FEATURE_IFF_PCLX, 1, 0); + if (ret) { + DRM_DEV_ERROR(gmu->dev, "Unable to enable IFF PCLX (%d)\n", ret); + return ret; + } + + entry_size = limits->count * sizeof(struct a6xx_hfi_limits_tbl); + size = sizeof(*tbl) + sizeof(*entry) + entry_size; + + tbl = kzalloc(size, GFP_KERNEL); + if (!tbl) + return -ENOMEM; + + tbl->type = HFI_TABLE_LIMITS_MIT; + entry = &tbl->entry[0]; + entry->count = limits->count; + entry->stride = sizeof(struct a6xx_hfi_limits_tbl) >> 2; + + memcpy(entry->data, limits->tbl, entry_size); + + ret = a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_TABLE, tbl, size, NULL, 0); + if (ret) + DRM_DEV_ERROR(gmu->dev, "Unable to send PCLX table (%d)\n", ret); + + kfree(tbl); + return ret; +} + +static int a6xx_hfi_enable_clx(struct a6xx_gmu *gmu) +{ + struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu); + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; + const struct a6xx_info *info = adreno_gpu->info->a6xx; + struct a6xx_hfi_clx_table_v2_cmd cmd = { 0 }; + int ret; + + if (!info->clx_tbl) + return 0; + + ret = a6xx_hfi_feature_ctrl_msg(gmu, HFI_FEATURE_CLX, 1, 0); + if (ret) { + DRM_DEV_ERROR(gmu->dev, "Unable to enable CLX (%d)\n", ret); + return ret; + } + + memcpy(&cmd, info->clx_tbl, sizeof(cmd)); + + ret = a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_CLX_TBL, &cmd, sizeof(cmd), NULL, 0); + if (ret) { + DRM_DEV_ERROR(gmu->dev, "Unable to send CLX table (%d)\n", ret); + return ret; + } + + return a6xx_hfi_enable_iff_pclx(gmu, info->limits_tbl); +} + static int a6xx_hfi_send_test(struct a6xx_gmu *gmu) { struct a6xx_hfi_msg_test msg = { 0 }; @@ -989,6 +1056,10 @@ int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state) if (ret) return ret; + ret = a6xx_hfi_enable_clx(gmu); + if (ret) + return ret; + ret = a6xx_hfi_enable_ifpc(gmu); if (ret) return ret;