diff --git a/common/tegra_hwpm_alist_utils.c b/common/tegra_hwpm_alist_utils.c index d0a82c8..dd7a974 100644 --- a/common/tegra_hwpm_alist_utils.c +++ b/common/tegra_hwpm_alist_utils.c @@ -28,92 +28,6 @@ #include #include -static int tegra_hwpm_get_alist_size(struct tegra_soc_hwpm *hwpm) -{ - struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; - u32 ip_idx; - u32 perfmux_idx, perfmon_idx; - unsigned long inst_idx = 0UL; - unsigned long floorsweep_info = 0UL; - struct hwpm_ip *chip_ip = NULL; - hwpm_ip_perfmux *perfmux = NULL; - hwpm_ip_perfmon *perfmon = NULL; - - tegra_hwpm_fn(hwpm, " "); - - for (ip_idx = 0U; ip_idx < active_chip->get_ip_max_idx(hwpm); - ip_idx++) { - chip_ip = active_chip->chip_ips[ip_idx]; - - /* Skip unavailable IPs */ - if (!chip_ip->reserved) { - continue; - } - - if (chip_ip->fs_mask == 0U) { - /* No IP instance is available */ - continue; - } - - floorsweep_info = (unsigned long)chip_ip->fs_mask; - - for_each_set_bit(inst_idx, &floorsweep_info, 32U) { - /* Add perfmux alist size to full alist size */ - for (perfmux_idx = 0U; - perfmux_idx < chip_ip->num_perfmux_slots; - perfmux_idx++) { - perfmux = chip_ip->ip_perfmux[perfmux_idx]; - - if (perfmux == NULL) { - continue; - } - - if (perfmux->hw_inst_mask != BIT(inst_idx)) { - continue; - } - - if (perfmux->alist) { - hwpm->full_alist_size = - tegra_hwpm_safe_add_u64( - hwpm->full_alist_size, - perfmux->alist_size); - } else { - tegra_hwpm_err(hwpm, "IP %d" - " perfmux %d NULL alist", - ip_idx, perfmux_idx); - } - } - - /* Add perfmon alist size to full alist size */ - for (perfmon_idx = 0U; - perfmon_idx < chip_ip->num_perfmon_slots; - perfmon_idx++) { - perfmon = chip_ip->ip_perfmon[perfmon_idx]; - - if (perfmon == NULL) { - continue; - } - - if (perfmon->hw_inst_mask != BIT(inst_idx)) { - continue; - } - - if (perfmon->alist) { - hwpm->full_alist_size = - tegra_hwpm_safe_add_u64( - hwpm->full_alist_size, - perfmon->alist_size); - } else { - tegra_hwpm_err(hwpm, "IP %d" - " perfmon %d NULL alist", - ip_idx, perfmon_idx); - } - } - } - } - - return 0; -} int tegra_hwpm_get_allowlist_size(struct tegra_soc_hwpm *hwpm) { @@ -123,7 +37,7 @@ int tegra_hwpm_get_allowlist_size(struct tegra_soc_hwpm *hwpm) tegra_hwpm_fn(hwpm, " "); - ret = tegra_hwpm_get_alist_size(hwpm); + ret = tegra_hwpm_func_all_ip(hwpm, NULL, TEGRA_HWPM_GET_ALIST_SIZE); if (ret != 0) { tegra_hwpm_err(hwpm, "get_alist_size failed"); return ret; @@ -134,100 +48,29 @@ int tegra_hwpm_get_allowlist_size(struct tegra_soc_hwpm *hwpm) static int tegra_hwpm_combine_alist(struct tegra_soc_hwpm *hwpm, u64 *alist) { - struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; - u32 ip_idx; - u32 perfmux_idx, perfmon_idx; - unsigned long inst_idx = 0UL; - unsigned long floorsweep_info = 0UL; - struct hwpm_ip *chip_ip = NULL; - hwpm_ip_perfmux *perfmux = NULL; - hwpm_ip_perfmon *perfmon = NULL; - u64 full_alist_idx = 0; + struct tegra_hwpm_func_args func_args; int err = 0; tegra_hwpm_fn(hwpm, " "); - for (ip_idx = 0U; ip_idx < active_chip->get_ip_max_idx(hwpm); - ip_idx++) { - chip_ip = active_chip->chip_ips[ip_idx]; + func_args.alist = alist; + func_args.full_alist_idx = 0ULL; - /* Skip unavailable IPs */ - if (!chip_ip->reserved) { - continue; - } - - if (chip_ip->fs_mask == 0U) { - /* No IP instance is available */ - continue; - } - - if (hwpm->active_chip->copy_alist == NULL) { - tegra_hwpm_err(hwpm, "copy_alist uninitialized"); - return -ENODEV; - } - - floorsweep_info = (unsigned long)chip_ip->fs_mask; - - for_each_set_bit(inst_idx, &floorsweep_info, 32U) { - /* Copy perfmux alist to full alist array */ - for (perfmux_idx = 0U; - perfmux_idx < chip_ip->num_perfmux_slots; - perfmux_idx++) { - perfmux = chip_ip->ip_perfmux[perfmux_idx]; - - if (perfmux == NULL) { - continue; - } - - if (perfmux->hw_inst_mask != BIT(inst_idx)) { - continue; - } - - err = hwpm->active_chip->copy_alist(hwpm, - perfmux, alist, &full_alist_idx); - if (err != 0) { - tegra_hwpm_err(hwpm, "IP %d" - " perfmux %d alist copy failed", - ip_idx, perfmux_idx); - goto fail; - } - } - - /* Copy perfmon alist to full alist array */ - for (perfmon_idx = 0U; - perfmon_idx < chip_ip->num_perfmon_slots; - perfmon_idx++) { - perfmon = chip_ip->ip_perfmon[perfmon_idx]; - - if (perfmon == NULL) { - continue; - } - - if (perfmon->hw_inst_mask != BIT(inst_idx)) { - continue; - } - - err = hwpm->active_chip->copy_alist(hwpm, - perfmon, alist, &full_alist_idx); - if (err != 0) { - tegra_hwpm_err(hwpm, "IP %d" - " perfmon %d alist copy failed", - ip_idx, perfmon_idx); - goto fail; - } - } - } + err = tegra_hwpm_func_all_ip(hwpm, &func_args, + TEGRA_HWPM_COMBINE_ALIST); + if (err != 0) { + tegra_hwpm_err(hwpm, "combine alist failed"); + return err; } /* Check size of full alist with hwpm->full_alist_size*/ - if (full_alist_idx != hwpm->full_alist_size) { + if (func_args.full_alist_idx != hwpm->full_alist_size) { tegra_hwpm_err(hwpm, "full_alist_size 0x%llx doesn't match " "max full_alist_idx 0x%llx", - hwpm->full_alist_size, full_alist_idx); + hwpm->full_alist_size, func_args.full_alist_idx); err = -EINVAL; } -fail: return err; } @@ -253,10 +96,7 @@ int tegra_hwpm_update_allowlist(struct tegra_soc_hwpm *hwpm, tegra_hwpm_err(hwpm, "Invalid allowlist size"); return -EINVAL; } - if (hwpm->active_chip->get_alist_buf_size == NULL) { - tegra_hwpm_err(hwpm, "alist_buf_size uninitialized"); - return -ENODEV; - } + alist_buf_size = tegra_hwpm_safe_mult_u64(hwpm->full_alist_size, hwpm->active_chip->get_alist_buf_size(hwpm)); diff --git a/common/tegra_hwpm_init.c b/common/tegra_hwpm_init.c index 4dca24b..6b07315 100644 --- a/common/tegra_hwpm_init.c +++ b/common/tegra_hwpm_init.c @@ -81,10 +81,6 @@ int tegra_hwpm_init_sw_components(struct tegra_soc_hwpm *hwpm) return err; } - if (hwpm->active_chip->init_chip_ip_structures == NULL) { - tegra_hwpm_err(hwpm, "init_chip_ip_structures uninitialized"); - } - err = hwpm->active_chip->init_chip_ip_structures(hwpm); if (err != 0) { tegra_hwpm_err(hwpm, "IP structure init failed"); @@ -101,11 +97,7 @@ void tegra_hwpm_release_sw_components(struct tegra_soc_hwpm *hwpm) tegra_hwpm_fn(hwpm, " "); - if (hwpm->active_chip->release_sw_setup == NULL) { - tegra_hwpm_err(hwpm, "release_sw_setup uninitialized"); - } else { - hwpm->active_chip->release_sw_setup(hwpm); - } + hwpm->active_chip->release_sw_setup(hwpm); while (node != NULL) { tmp_node = node; @@ -152,20 +144,12 @@ int tegra_hwpm_setup_hw(struct tegra_soc_hwpm *hwpm) * Map/reserve these apertures to get MMIO address required for hwpm * configuration (following steps). */ - if (hwpm->active_chip->reserve_pma == NULL) { - tegra_hwpm_err(hwpm, "reserve_pma uninitialized"); - goto enodev; - } ret = hwpm->active_chip->reserve_pma(hwpm); if (ret < 0) { tegra_hwpm_err(hwpm, "Unable to reserve PMA aperture"); goto fail; } - if (hwpm->active_chip->reserve_rtr == NULL) { - tegra_hwpm_err(hwpm, "reserve_rtr uninitialized"); - goto enodev; - } ret = hwpm->active_chip->reserve_rtr(hwpm); if (ret < 0) { tegra_hwpm_err(hwpm, "Unable to reserve RTR aperture"); @@ -173,10 +157,6 @@ int tegra_hwpm_setup_hw(struct tegra_soc_hwpm *hwpm) } /* Disable SLCG */ - if (hwpm->active_chip->disable_slcg == NULL) { - tegra_hwpm_err(hwpm, "disable_slcg uninitialized"); - goto enodev; - } ret = hwpm->active_chip->disable_slcg(hwpm); if (ret < 0) { tegra_hwpm_err(hwpm, "Unable to disable SLCG"); @@ -184,10 +164,6 @@ int tegra_hwpm_setup_hw(struct tegra_soc_hwpm *hwpm) } /* Program PROD values */ - if (hwpm->active_chip->init_prod_values == NULL) { - tegra_hwpm_err(hwpm, "init_prod_values uninitialized"); - goto enodev; - } ret = hwpm->active_chip->init_prod_values(hwpm); if (ret < 0) { tegra_hwpm_err(hwpm, "Unable to set PROD values"); @@ -195,8 +171,6 @@ int tegra_hwpm_setup_hw(struct tegra_soc_hwpm *hwpm) } return 0; -enodev: - ret = -ENODEV; fail: return ret; } @@ -205,10 +179,6 @@ int tegra_hwpm_disable_triggers(struct tegra_soc_hwpm *hwpm) { tegra_hwpm_fn(hwpm, " "); - if (hwpm->active_chip->disable_triggers == NULL) { - tegra_hwpm_err(hwpm, "disable_triggers uninitialized"); - return -ENODEV; - } return hwpm->active_chip->disable_triggers(hwpm); } @@ -219,10 +189,6 @@ int tegra_hwpm_release_hw(struct tegra_soc_hwpm *hwpm) tegra_hwpm_fn(hwpm, " "); /* Enable SLCG */ - if (hwpm->active_chip->enable_slcg == NULL) { - tegra_hwpm_err(hwpm, "enable_slcg uninitialized"); - goto enodev; - } ret = hwpm->active_chip->enable_slcg(hwpm); if (ret < 0) { tegra_hwpm_err(hwpm, "Unable to enable SLCG"); @@ -235,20 +201,12 @@ int tegra_hwpm_release_hw(struct tegra_soc_hwpm *hwpm) * these aperture mappings are required to reset hwpm config. * Hence, explicitly unmap/release these apertures as a last step. */ - if (hwpm->active_chip->release_rtr == NULL) { - tegra_hwpm_err(hwpm, "release_rtr uninitialized"); - goto enodev; - } ret = hwpm->active_chip->release_rtr(hwpm); if (ret < 0) { tegra_hwpm_err(hwpm, "Unable to release RTR aperture"); goto fail; } - if (hwpm->active_chip->release_pma == NULL) { - tegra_hwpm_err(hwpm, "release_pma uninitialized"); - goto enodev; - } ret = hwpm->active_chip->release_pma(hwpm); if (ret < 0) { tegra_hwpm_err(hwpm, "Unable to release PMA aperture"); @@ -256,8 +214,6 @@ int tegra_hwpm_release_hw(struct tegra_soc_hwpm *hwpm) } return 0; -enodev: - ret = -ENODEV; fail: return ret; } diff --git a/common/tegra_hwpm_ip_utils.c b/common/tegra_hwpm_ip_utils.c index 968208a..2e114bb 100644 --- a/common/tegra_hwpm_ip_utils.c +++ b/common/tegra_hwpm_ip_utils.c @@ -464,11 +464,6 @@ static int tegra_hwpm_complete_ip_register(struct tegra_soc_hwpm *hwpm) tegra_hwpm_fn(hwpm, " "); - if (hwpm->active_chip->extract_ip_ops == NULL) { - tegra_hwpm_err(hwpm, "extract_ip_ops uninitialized"); - return -ENODEV; - } - while (node != NULL) { tegra_hwpm_dbg(hwpm, hwpm_info, "IP ext idx %d info", node->ip_ops.ip_index); @@ -507,10 +502,6 @@ int tegra_hwpm_finalize_chip_info(struct tegra_soc_hwpm *hwpm) return ret; } - if (hwpm->active_chip->force_enable_ips == NULL) { - tegra_hwpm_err(hwpm, "force_enable_ips uninitialized"); - return -ENODEV; - } ret = hwpm->active_chip->force_enable_ips(hwpm); if (ret != 0) { tegra_hwpm_err(hwpm, "Failed to force enable IPs"); diff --git a/common/tegra_hwpm_mem_buf_utils.c b/common/tegra_hwpm_mem_buf_utils.c index c824d8c..90f5d45 100644 --- a/common/tegra_hwpm_mem_buf_utils.c +++ b/common/tegra_hwpm_mem_buf_utils.c @@ -169,10 +169,6 @@ int tegra_hwpm_map_stream_buffer(struct tegra_soc_hwpm *hwpm, } /* Configure memory management */ - if (hwpm->active_chip->enable_mem_mgmt == NULL) { - tegra_hwpm_err(hwpm, "enable memory mgmt HAL uninitialized"); - return -ENODEV; - } ret = hwpm->active_chip->enable_mem_mgmt(hwpm, alloc_pma_stream); if (ret != 0) { tegra_hwpm_err(hwpm, "Failed to configure stream memory"); @@ -183,20 +179,12 @@ int tegra_hwpm_map_stream_buffer(struct tegra_soc_hwpm *hwpm, fail: /* Invalidate memory config */ - if (hwpm->active_chip->invalidate_mem_config == NULL) { - tegra_hwpm_err(hwpm, "invalidate_mem_config HAL uninitialized"); - return -ENODEV; - } err = hwpm->active_chip->invalidate_mem_config(hwpm); if (err != 0) { tegra_hwpm_err(hwpm, "Failed to invalidate memory config"); } /* Disable memory management */ - if (hwpm->active_chip->disable_mem_mgmt == NULL) { - tegra_hwpm_err(hwpm, "disable_mem_mgmt HAL uninitialized"); - return -ENODEV; - } err = hwpm->active_chip->disable_mem_mgmt(hwpm); if (err != 0) { tegra_hwpm_err(hwpm, "Failed to disable memory management"); @@ -224,10 +212,6 @@ int tegra_hwpm_clear_mem_pipeline(struct tegra_soc_hwpm *hwpm) bool timeout = false; u32 *mem_bytes_kernel_u32 = (u32 *)(hwpm->mem_bytes_kernel); - if (hwpm->active_chip->stream_mem_bytes == NULL) { - tegra_hwpm_err(hwpm, "stream_mem_bytes uninitialized"); - return -ENODEV; - } ret = hwpm->active_chip->stream_mem_bytes(hwpm); if (ret != 0) { tegra_hwpm_err(hwpm, @@ -243,10 +227,6 @@ int tegra_hwpm_clear_mem_pipeline(struct tegra_soc_hwpm *hwpm) } } - if (hwpm->active_chip->disable_pma_streaming == NULL) { - tegra_hwpm_err(hwpm, "disable_pma_streaming uninitialized"); - return -ENODEV; - } ret = hwpm->active_chip->disable_pma_streaming(hwpm); if (ret != 0) { tegra_hwpm_err(hwpm, "Failed to disable pma streaming"); @@ -254,10 +234,6 @@ int tegra_hwpm_clear_mem_pipeline(struct tegra_soc_hwpm *hwpm) } /* Disable memory management */ - if (hwpm->active_chip->disable_mem_mgmt == NULL) { - tegra_hwpm_err(hwpm, "disable_mem_mgmt HAL uninitialized"); - return -ENODEV; - } ret = hwpm->active_chip->disable_mem_mgmt(hwpm); if (ret != 0) { tegra_hwpm_err(hwpm, "Failed to disable memory management"); @@ -282,10 +258,6 @@ int tegra_hwpm_update_mem_bytes(struct tegra_soc_hwpm *hwpm, tegra_hwpm_fn(hwpm, " "); /* Update SW get pointer */ - if (hwpm->active_chip->update_mem_bytes_get_ptr == NULL) { - tegra_hwpm_err(hwpm, "update_mem_bytes_get_ptr uninitialized"); - return -ENODEV; - } ret = hwpm->active_chip->update_mem_bytes_get_ptr(hwpm, update_get_put->mem_bump); if (ret != 0) { @@ -295,10 +267,6 @@ int tegra_hwpm_update_mem_bytes(struct tegra_soc_hwpm *hwpm, /* Stream MEM_BYTES value to MEM_BYTES buffer */ if (update_get_put->b_stream_mem_bytes) { - if (hwpm->active_chip->stream_mem_bytes == NULL) { - tegra_hwpm_err(hwpm, "stream_mem_bytes uninitialized"); - return -ENODEV; - } ret = hwpm->active_chip->stream_mem_bytes(hwpm); if (ret != 0) { tegra_hwpm_err(hwpm, @@ -308,11 +276,6 @@ int tegra_hwpm_update_mem_bytes(struct tegra_soc_hwpm *hwpm, /* Read HW put pointer */ if (update_get_put->b_read_mem_head) { - if (hwpm->active_chip->get_mem_bytes_put_ptr == NULL) { - tegra_hwpm_err(hwpm, - "get_mem_bytes_put_ptr uninitialized"); - return -ENODEV; - } update_get_put->mem_head = hwpm->active_chip->get_mem_bytes_put_ptr(hwpm); tegra_hwpm_dbg(hwpm, hwpm_verbose, @@ -321,11 +284,6 @@ int tegra_hwpm_update_mem_bytes(struct tegra_soc_hwpm *hwpm, /* Check overflow error status */ if (update_get_put->b_check_overflow) { - if (hwpm->active_chip->membuf_overflow_status == NULL) { - tegra_hwpm_err(hwpm, - "membuf_overflow_status uninitialized"); - return -ENODEV; - } update_get_put->b_overflowed = (u8) hwpm->active_chip->membuf_overflow_status(hwpm); tegra_hwpm_dbg(hwpm, hwpm_verbose, "OVERFLOWED = %u", diff --git a/common/tegra_hwpm_resource_utils.c b/common/tegra_hwpm_resource_utils.c index 07238e0..44c51e4 100644 --- a/common/tegra_hwpm_resource_utils.c +++ b/common/tegra_hwpm_resource_utils.c @@ -19,160 +19,418 @@ #include #include -/* ip_idx indicates internal active ip index */ -static int tegra_hwpm_reserve_given_resource(struct tegra_soc_hwpm *hwpm, - u32 ip_idx) +int tegra_hwpm_func_single_aperture(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func, u32 ip_idx, struct hwpm_ip *chip_ip, + u32 inst_idx, u32 aperture_idx, enum hwpm_aperture_type a_type) { + struct hwpm_ip_aperture *aperture = NULL; int err = 0, ret = 0; - u32 perfmux_idx, perfmon_idx; - unsigned long inst_idx = 0UL; - unsigned long floorsweep_info = 0UL, reserved_insts = 0UL; - struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; - struct hwpm_ip *chip_ip = active_chip->chip_ips[ip_idx]; - hwpm_ip_perfmon *perfmon = NULL; - hwpm_ip_perfmux *perfmux = NULL; - floorsweep_info = (unsigned long)chip_ip->fs_mask; + if (a_type == HWPM_APERTURE_PERFMUX) { + aperture = chip_ip->ip_perfmux[aperture_idx]; + } else if (a_type == HWPM_APERTURE_PERFMON) { + aperture = chip_ip->ip_perfmon[aperture_idx]; + } else { + tegra_hwpm_err(hwpm, "INVALID a_type %d", a_type); + return -EINVAL; + } - tegra_hwpm_fn(hwpm, " "); - - tegra_hwpm_dbg(hwpm, hwpm_info, "Reserve IP %d, fs_mask 0x%x", - ip_idx, chip_ip->fs_mask); - - /* PMA and RTR are already reserved */ - if ((ip_idx == active_chip->get_pma_int_idx(hwpm)) || - (ip_idx == active_chip->get_rtr_int_idx(hwpm))) { + if (aperture == NULL) { return 0; } - for_each_set_bit(inst_idx, &floorsweep_info, 32U) { - /* Reserve all perfmon belonging to this instance */ - for (perfmon_idx = 0U; perfmon_idx < chip_ip->num_perfmon_slots; - perfmon_idx++) { - perfmon = chip_ip->ip_perfmon[perfmon_idx]; - - if (perfmon == NULL) { - continue; - } - - if (perfmon->hw_inst_mask != BIT(inst_idx)) { - continue; - } - - err = tegra_hwpm_perfmon_reserve(hwpm, perfmon); - if (err != 0) { - tegra_hwpm_err(hwpm, - "IP %d perfmon %d reserve failed", - ip_idx, perfmon_idx); - goto fail; - } - } - - /* Reserve all perfmux belonging to this instance */ - for (perfmux_idx = 0U; perfmux_idx < chip_ip->num_perfmux_slots; - perfmux_idx++) { - perfmux = chip_ip->ip_perfmux[perfmux_idx]; - - if (perfmux == NULL) { - continue; - } - - if (perfmux->hw_inst_mask != BIT(inst_idx)) { - continue; - } - - err = tegra_hwpm_perfmux_reserve(hwpm, perfmux); - if (err != 0) { - tegra_hwpm_err(hwpm, - "IP %d perfmux %d reserve failed", - ip_idx, perfmux_idx); - goto fail; - } - } - - reserved_insts |= BIT(inst_idx); + if (aperture->hw_inst_mask != BIT(inst_idx)) { + return 0; + } + + switch (iia_func) { + case TEGRA_HWPM_GET_ALIST_SIZE: + if (aperture->alist) { + hwpm->full_alist_size = + tegra_hwpm_safe_add_u64( + hwpm->full_alist_size, + aperture->alist_size); + } else { + tegra_hwpm_err(hwpm, "IP %d" + " aperture type %d idx %d NULL alist", + ip_idx, a_type, aperture_idx); + } + break; + case TEGRA_HWPM_COMBINE_ALIST: + err = hwpm->active_chip->copy_alist(hwpm, + aperture, func_args->alist, &func_args->full_alist_idx); + if (err != 0) { + tegra_hwpm_err(hwpm, "IP %d" + " aperture type %d idx %d alist copy failed", + ip_idx, a_type, aperture_idx); + return err; + } + break; + case TEGRA_HWPM_RESERVE_GIVEN_RESOURCE: + if (a_type == HWPM_APERTURE_PERFMUX) { + err = tegra_hwpm_perfmux_reserve(hwpm, aperture); + if (err != 0) { + tegra_hwpm_err(hwpm, "IP %d aperture" + " type %d idx %d reserve failed", + ip_idx, aperture_idx); + goto fail; + } + } else if (a_type == HWPM_APERTURE_PERFMON) { + err = tegra_hwpm_perfmon_reserve(hwpm, aperture); + if (err != 0) { + tegra_hwpm_err(hwpm, "IP %d aperture" + " type %d idx %d reserve failed", + ip_idx, aperture_idx); + goto fail; + } + } + break; + case TEGRA_HWPM_RELEASE_RESOURCES: + if (a_type == HWPM_APERTURE_PERFMUX) { + ret = hwpm->active_chip->perfmux_disable(hwpm, aperture); + if (ret != 0) { + tegra_hwpm_err(hwpm, "IP %d aperture" + " type %d idx %d disable failed", + ip_idx, aperture_idx); + } + + ret = tegra_hwpm_perfmux_release(hwpm, aperture); + if (ret != 0) { + tegra_hwpm_err(hwpm, "IP %d aperture" + " type %d idx %d release failed", + ip_idx, aperture_idx); + } + } else if (a_type == HWPM_APERTURE_PERFMON) { + ret = hwpm->active_chip->perfmon_disable(hwpm, aperture); + if (ret != 0) { + tegra_hwpm_err(hwpm, "IP %d aperture" + " type %d idx %d disable failed", + ip_idx, aperture_idx); + } + + ret = tegra_hwpm_perfmon_release(hwpm, aperture); + if (ret != 0) { + tegra_hwpm_err(hwpm, "IP %d aperture" + " type %d idx %d release failed", + ip_idx, aperture_idx); + } + } + break; + case TEGRA_HWPM_BIND_RESOURCES: + err = hwpm->active_chip->zero_alist_regs(hwpm, aperture); + if (err != 0) { + tegra_hwpm_err(hwpm, "IP %d aperture" + " type %d idx %d zero regs failed", + ip_idx, aperture_idx); + goto fail; + } + if (a_type == HWPM_APERTURE_PERFMON) { + err = hwpm->active_chip->perfmon_enable(hwpm, aperture); + if (err != 0) { + tegra_hwpm_err(hwpm, "IP %d aperture" + " type %d idx %d enable failed", + ip_idx, aperture_idx); + goto fail; + } + } + break; + default: + tegra_hwpm_err(hwpm, "func 0x%x unknown", iia_func); + return -EINVAL; + break; } - chip_ip->reserved = true; return 0; fail: - if (hwpm->active_chip->perfmon_disable == NULL) { - tegra_hwpm_err(hwpm, "perfmon_disable HAL uninitialized"); - return -ENODEV; + return err; +} + +int tegra_hwpm_func_all_perfmons(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func, u32 ip_idx, struct hwpm_ip *chip_ip, + u32 inst_idx) +{ + u32 perfmon_idx; + int err = 0; + + for (perfmon_idx = 0U; perfmon_idx < chip_ip->num_perfmon_slots; + perfmon_idx++) { + err = tegra_hwpm_func_single_aperture( + hwpm, func_args, iia_func, ip_idx, + chip_ip, inst_idx, perfmon_idx, HWPM_APERTURE_PERFMON); + if (err < 0) { + tegra_hwpm_err(hwpm, + "IP %d inst %d perfmon %d func 0x%x failed", + ip_idx, inst_idx, perfmon_idx, iia_func); + goto fail; + } } - if (hwpm->active_chip->perfmux_disable == NULL) { - tegra_hwpm_err(hwpm, "perfmux_disable HAL uninitialized"); - return -ENODEV; + return 0; +fail: + return err; +} + +int tegra_hwpm_func_all_perfmuxes(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func, u32 ip_idx, struct hwpm_ip *chip_ip, + u32 inst_idx) +{ + u32 perfmux_idx; + int err = 0; + + for (perfmux_idx = 0U; perfmux_idx < chip_ip->num_perfmux_slots; + perfmux_idx++) { + err = tegra_hwpm_func_single_aperture( + hwpm, func_args, iia_func, ip_idx, + chip_ip, inst_idx, perfmux_idx, HWPM_APERTURE_PERFMUX); + if (err < 0) { + tegra_hwpm_err(hwpm, + "IP %d inst %d perfmux %d func 0x%x failed", + ip_idx, inst_idx, perfmux_idx, iia_func); + goto fail; + } } - /* release reserved instances */ - for_each_set_bit(inst_idx, &reserved_insts, 32U) { - /* Release all perfmon belonging to this instance */ - for (perfmon_idx = 0U; perfmon_idx < chip_ip->num_perfmon_slots; - perfmon_idx++) { - perfmon = chip_ip->ip_perfmon[perfmon_idx]; + return 0; +fail: + return err; +} - if (perfmon == NULL) { - continue; - } +int tegra_hwpm_func_all_inst(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func, u32 ip_idx, struct hwpm_ip *chip_ip) +{ + unsigned long inst_idx = 0UL; + unsigned long floorsweep_info = 0UL; + unsigned long reserved_insts = 0UL; + int err = 0; - if (perfmon->hw_inst_mask != BIT(inst_idx)) { - continue; - } + /* Execute tasks for all instances if any */ + floorsweep_info = (unsigned long)chip_ip->fs_mask; - ret = hwpm->active_chip->perfmon_disable(hwpm, perfmon); - if (ret != 0) { - tegra_hwpm_err(hwpm, - "IP %d perfmon %d disable failed", - ip_idx, perfmon_idx); - } - - ret = tegra_hwpm_perfmon_release(hwpm, perfmon); - if (ret != 0) { - tegra_hwpm_err(hwpm, - "IP %d perfmon %d release failed", - ip_idx, perfmon_idx); - } + for_each_set_bit(inst_idx, &floorsweep_info, 32U) { + switch (iia_func) { + case TEGRA_HWPM_GET_ALIST_SIZE: + /* do nothing, continue to apertures */ + break; + case TEGRA_HWPM_COMBINE_ALIST: + func_args->full_alist_idx = 0ULL; + break; + case TEGRA_HWPM_RESERVE_GIVEN_RESOURCE: + /* do nothing, continue to apertures */ + break; + case TEGRA_HWPM_BIND_RESOURCES: + /* do nothing, continue to instances */ + break; + case TEGRA_HWPM_RELEASE_RESOURCES: + /* do nothing, continue to instances */ + break; + default: + tegra_hwpm_err(hwpm, "func 0x%x unknown", iia_func); + goto fail; + break; } - /* Release all perfmux belonging to this instance */ - for (perfmux_idx = 0U; perfmux_idx < chip_ip->num_perfmux_slots; - perfmux_idx++) { - perfmux = chip_ip->ip_perfmux[perfmux_idx]; + /* Continue functionality for all apertures */ + err = tegra_hwpm_func_all_perfmuxes( + hwpm, func_args, iia_func, ip_idx, chip_ip, inst_idx); + if (err < 0) { + tegra_hwpm_err(hwpm, "IP %d inst %d func 0x%x failed", + ip_idx, inst_idx, iia_func); + goto fail; + } - if (perfmux == NULL) { - continue; - } + err = tegra_hwpm_func_all_perfmons( + hwpm, func_args, iia_func, ip_idx, chip_ip, inst_idx); + if (err < 0) { + tegra_hwpm_err(hwpm, "IP %d inst %d func 0x%x failed", + ip_idx, inst_idx, iia_func); + goto fail; + } - if (perfmux->hw_inst_mask != BIT(inst_idx)) { - continue; - } + /* Post execute functionality */ + switch (iia_func) { + case TEGRA_HWPM_GET_ALIST_SIZE: + /* do nothing, continue to apertures */ + break; + case TEGRA_HWPM_COMBINE_ALIST: + /* do nothing, continue to apertures */ + break; + case TEGRA_HWPM_RESERVE_GIVEN_RESOURCE: + reserved_insts |= BIT(inst_idx); + break; + case TEGRA_HWPM_BIND_RESOURCES: + /* do nothing, continue to instances */ + break; + case TEGRA_HWPM_RELEASE_RESOURCES: + /* do nothing, continue to instances */ + break; + default: + tegra_hwpm_err(hwpm, "func 0x%x unknown", iia_func); + goto fail; + break; + } + } - ret = hwpm->active_chip->perfmux_disable(hwpm, perfmux); - if (ret != 0) { + return 0; + +fail: + if (iia_func == TEGRA_HWPM_RESERVE_GIVEN_RESOURCE) { + /* Revert previously reserved instances of this IP */ + for_each_set_bit(inst_idx, &reserved_insts, 32U) { + /* Release all apertures belonging to this instance */ + err = tegra_hwpm_func_all_perfmuxes(hwpm, func_args, + TEGRA_HWPM_RELEASE_RESOURCES, ip_idx, + chip_ip, inst_idx); + if (err < 0) { tegra_hwpm_err(hwpm, - "IP %d perfmux %d disable failed", - ip_idx, perfmux_idx); + "IP %d inst %d func 0x%x failed", + ip_idx, inst_idx, iia_func); + return err; } - ret = tegra_hwpm_perfmux_release(hwpm, perfmux); - if (ret != 0) { + err = tegra_hwpm_func_all_perfmons(hwpm, func_args, + TEGRA_HWPM_RELEASE_RESOURCES, ip_idx, + chip_ip, inst_idx); + if (err < 0) { tegra_hwpm_err(hwpm, - "IP %d perfmux %d release failed", - ip_idx, perfmux_idx); + "IP %d inst %d func 0x%x failed", + ip_idx, inst_idx, iia_func); + return err; } } } + + return err; +} + +int tegra_hwpm_func_single_ip(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func, u32 ip_idx) +{ + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ip_idx]; + int err = 0; + + tegra_hwpm_fn(hwpm, " "); + + if (chip_ip == NULL) { + tegra_hwpm_err(hwpm, "IP %d not populated", ip_idx); + return -ENODEV; + } + + switch (iia_func) { + case TEGRA_HWPM_GET_ALIST_SIZE: + case TEGRA_HWPM_COMBINE_ALIST: + case TEGRA_HWPM_BIND_RESOURCES: + /* Skip unavailable IPs */ + if (!chip_ip->reserved) { + return 0; + } + + if (chip_ip->fs_mask == 0U) { + /* No IP instance is available */ + return 0; + } + break; + case TEGRA_HWPM_RESERVE_GIVEN_RESOURCE: + /* PMA and RTR are already reserved */ + if ((ip_idx == active_chip->get_pma_int_idx(hwpm)) || + (ip_idx == active_chip->get_rtr_int_idx(hwpm))) { + return 0; + } + /* Skip IPs which are already reserved */ + if (chip_ip->reserved) { + tegra_hwpm_dbg(hwpm, hwpm_info, + "Chip IP %d already reserved", ip_idx); + return 0; + } + + /* Make sure IP override is not enabled */ + if (chip_ip->override_enable) { + tegra_hwpm_dbg(hwpm, hwpm_info, + "Chip IP %d not available", ip_idx); + return 0; + } + break; + case TEGRA_HWPM_RELEASE_RESOURCES: + /* PMA and RTR will be released later */ + if ((ip_idx == active_chip->get_pma_int_idx(hwpm)) || + (ip_idx == active_chip->get_rtr_int_idx(hwpm))) { + return 0; + } + /* Skip unavailable IPs */ + if (!chip_ip->reserved) { + return 0; + } + + if (chip_ip->fs_mask == 0U) { + /* No IP instance is available */ + return 0; + } + break; + default: + tegra_hwpm_err(hwpm, "func 0x%x unknown", iia_func); + goto fail; + break; + } + + /* Continue functionality for all instances in this IP */ + err = tegra_hwpm_func_all_inst(hwpm, func_args, iia_func, + ip_idx, chip_ip); + if (err < 0) { + tegra_hwpm_err(hwpm, "IP %d func 0x%x failed", + ip_idx, iia_func); + goto fail; + } + + /* Post execute functionality */ + if (iia_func == TEGRA_HWPM_RESERVE_GIVEN_RESOURCE) { + chip_ip->reserved = true; + } + if (iia_func == TEGRA_HWPM_RELEASE_RESOURCES) { + chip_ip->reserved = false; + } + + return 0; +fail: + return err; +} + +int tegra_hwpm_func_all_ip(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func) +{ + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + u32 ip_idx; + int err = 0; + + tegra_hwpm_fn(hwpm, " "); + + for (ip_idx = 0U; ip_idx < active_chip->get_ip_max_idx(hwpm); + ip_idx++) { + + err = tegra_hwpm_func_single_ip( + hwpm, func_args, iia_func, ip_idx); + if (err < 0) { + tegra_hwpm_err(hwpm, "IP %d func 0x%x failed", + ip_idx, iia_func); + goto fail; + } + } + + return 0; +fail: return err; } int tegra_hwpm_reserve_resource(struct tegra_soc_hwpm *hwpm, u32 resource) { struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; - struct hwpm_ip *chip_ip = NULL; u32 ip_idx = TEGRA_SOC_HWPM_IP_INACTIVE; - int ret = 0; + int err = 0; tegra_hwpm_fn(hwpm, " "); @@ -192,266 +450,28 @@ int tegra_hwpm_reserve_resource(struct tegra_soc_hwpm *hwpm, u32 resource) return -EINVAL; } - /* Get IP structure from ip_idx */ - chip_ip = active_chip->chip_ips[ip_idx]; - - /* Skip IPs which are already reserved (covers PMA and RTR case) */ - if (chip_ip->reserved) { - tegra_hwpm_dbg(hwpm, hwpm_info, - "Chip IP %d already reserved", ip_idx); - return 0; - } - - /* Make sure IP override is not enabled */ - if (chip_ip->override_enable) { - tegra_hwpm_dbg(hwpm, hwpm_info, - "Chip IP %d not available", ip_idx); - return 0; - } - - ret = tegra_hwpm_reserve_given_resource(hwpm, ip_idx); - if (ret != 0) { - tegra_hwpm_err(hwpm, "Failed to reserve resource %d", resource); - return ret; + err = tegra_hwpm_func_single_ip(hwpm, NULL, + TEGRA_HWPM_RESERVE_GIVEN_RESOURCE, ip_idx); + if (err != 0) { + tegra_hwpm_err(hwpm, "failed to reserve IP %d", ip_idx); + return err; } return 0; } -static int tegra_hwpm_bind_reserved_resources(struct tegra_soc_hwpm *hwpm) -{ - struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; - struct hwpm_ip *chip_ip = NULL; - u32 ip_idx; - u32 perfmux_idx, perfmon_idx; - unsigned long inst_idx = 0UL; - unsigned long floorsweep_info = 0UL; - int err = 0; - hwpm_ip_perfmon *perfmon = NULL; - hwpm_ip_perfmux *perfmux = NULL; - - tegra_hwpm_fn(hwpm, " "); - - if (hwpm->active_chip->zero_alist_regs == NULL) { - tegra_hwpm_err(hwpm, - "zero_alist_regs HAL uninitialized"); - return -ENODEV; - } - - if (hwpm->active_chip->perfmon_enable == NULL) { - tegra_hwpm_err(hwpm, - "perfmon_enable HAL uninitialized"); - return -ENODEV; - } - - for (ip_idx = 0U; ip_idx < active_chip->get_ip_max_idx(hwpm); - ip_idx++) { - chip_ip = active_chip->chip_ips[ip_idx]; - - /* Skip unavailable IPs */ - if (!chip_ip->reserved) { - continue; - } - - if (chip_ip->fs_mask == 0U) { - /* No IP instance is available */ - continue; - } - - floorsweep_info = (unsigned long)chip_ip->fs_mask; - - for_each_set_bit(inst_idx, &floorsweep_info, 32U) { - /* Zero out necessary perfmux registers */ - for (perfmux_idx = 0U; - perfmux_idx < chip_ip->num_perfmux_slots; - perfmux_idx++) { - perfmux = chip_ip->ip_perfmux[perfmux_idx]; - - if (perfmux == NULL) { - continue; - } - - if (perfmux->hw_inst_mask != BIT(inst_idx)) { - continue; - } - - err = hwpm->active_chip->zero_alist_regs( - hwpm, perfmux); - if (err != 0) { - tegra_hwpm_err(hwpm, "IP %d" - " perfmux %d zero regs failed", - ip_idx, perfmux_idx); - } - } - - /* Zero out necessary perfmon registers */ - /* And enable reporting of PERFMON status */ - for (perfmon_idx = 0U; - perfmon_idx < chip_ip->num_perfmon_slots; - perfmon_idx++) { - perfmon = chip_ip->ip_perfmon[perfmon_idx]; - - if (perfmon == NULL) { - continue; - } - - if (perfmon->hw_inst_mask != BIT(inst_idx)) { - continue; - } - - err = hwpm->active_chip->zero_alist_regs( - hwpm, perfmon); - if (err != 0) { - tegra_hwpm_err(hwpm, "IP %d" - " perfmon %d zero regs failed", - ip_idx, perfmon_idx); - } - - err = hwpm->active_chip->perfmon_enable( - hwpm, perfmon); - if (err != 0) { - tegra_hwpm_err(hwpm, "IP %d" - " perfmon %d enable failed", - ip_idx, perfmon_idx); - } - } - } - } - return err; -} - int tegra_hwpm_bind_resources(struct tegra_soc_hwpm *hwpm) { - int ret = 0; - - tegra_hwpm_fn(hwpm, " "); - - ret = tegra_hwpm_bind_reserved_resources(hwpm); - if (ret != 0) { - tegra_hwpm_err(hwpm, "failed to bind resources"); - return ret; - } - - return 0; -} - -int tegra_hwpm_release_all_resources(struct tegra_soc_hwpm *hwpm) -{ - struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; - struct hwpm_ip *chip_ip = NULL; - hwpm_ip_perfmon *perfmon = NULL; - hwpm_ip_perfmux *perfmux = NULL; - u32 ip_idx; - u32 perfmux_idx, perfmon_idx; - unsigned long floorsweep_info = 0UL; - unsigned long inst_idx = 0UL; int err = 0; tegra_hwpm_fn(hwpm, " "); - for (ip_idx = 0U; ip_idx < active_chip->get_ip_max_idx(hwpm); - ip_idx++) { - chip_ip = active_chip->chip_ips[ip_idx]; - - /* PMA and RTR will be released later */ - if ((ip_idx == active_chip->get_pma_int_idx(hwpm)) || - (ip_idx == active_chip->get_rtr_int_idx(hwpm))) { - continue; - } - - /* Disable only available IPs */ - if (chip_ip->override_enable) { - /* IP not available */ - continue; - } - - /* Disable and release only reserved IPs */ - if (!chip_ip->reserved) { - continue; - } - - if (chip_ip->fs_mask == 0U) { - /* No IP instance is available */ - continue; - } - - if (hwpm->active_chip->perfmon_disable == NULL) { - tegra_hwpm_err(hwpm, - "perfmon_disable HAL uninitialized"); - return -ENODEV; - } - - if (hwpm->active_chip->perfmux_disable == NULL) { - tegra_hwpm_err(hwpm, - "perfmux_disable HAL uninitialized"); - return -ENODEV; - } - - floorsweep_info = (unsigned long)chip_ip->fs_mask; - - for_each_set_bit(inst_idx, &floorsweep_info, 32U) { - /* Release all perfmon associated with inst_idx */ - for (perfmon_idx = 0U; - perfmon_idx < chip_ip->num_perfmon_slots; - perfmon_idx++) { - perfmon = chip_ip->ip_perfmon[perfmon_idx]; - - if (perfmon == NULL) { - continue; - } - - if (perfmon->hw_inst_mask != BIT(inst_idx)) { - continue; - } - - err = hwpm->active_chip->perfmon_disable( - hwpm, perfmon); - if (err != 0) { - tegra_hwpm_err(hwpm, "IP %d" - " perfmon %d disable failed", - ip_idx, perfmon_idx); - } - - err = tegra_hwpm_perfmon_release(hwpm, perfmon); - if (err != 0) { - tegra_hwpm_err(hwpm, "IP %d" - " perfmon %d release failed", - ip_idx, perfmon_idx); - } - } - - /* Release all perfmux associated with inst_idx */ - for (perfmux_idx = 0U; - perfmux_idx < chip_ip->num_perfmux_slots; - perfmux_idx++) { - perfmux = chip_ip->ip_perfmux[perfmux_idx]; - - if (perfmux == NULL) { - continue; - } - - if (perfmux->hw_inst_mask != BIT(inst_idx)) { - continue; - } - - err = hwpm->active_chip->perfmux_disable( - hwpm, perfmux); - if (err != 0) { - tegra_hwpm_err(hwpm, "IP %d" - " perfmux %d disable failed", - ip_idx, perfmux_idx); - } - - err = tegra_hwpm_perfmux_release(hwpm, perfmux); - if (err != 0) { - tegra_hwpm_err(hwpm, "IP %d" - " perfmux %d release failed", - ip_idx, perfmux_idx); - } - } - } - chip_ip->reserved = false; + err = tegra_hwpm_func_all_ip(hwpm, NULL, TEGRA_HWPM_BIND_RESOURCES); + if (err != 0) { + tegra_hwpm_err(hwpm, "failed to bind resources"); + return err; } + return 0; } @@ -461,7 +481,7 @@ int tegra_hwpm_release_resources(struct tegra_soc_hwpm *hwpm) tegra_hwpm_fn(hwpm, " "); - ret = tegra_hwpm_release_all_resources(hwpm); + ret = tegra_hwpm_func_all_ip(hwpm, NULL, TEGRA_HWPM_RELEASE_RESOURCES); if (ret != 0) { tegra_hwpm_err(hwpm, "failed to release resources"); return ret; diff --git a/hal/t234/t234_hwpm_interface_utils.c b/hal/t234/t234_hwpm_interface_utils.c index 933773e..b8f4eb0 100644 --- a/hal/t234/t234_hwpm_interface_utils.c +++ b/hal/t234/t234_hwpm_interface_utils.c @@ -71,6 +71,181 @@ struct tegra_soc_hwpm_chip t234_chip_info = { .release_sw_setup = tegra_hwpm_release_sw_setup, }; +static bool t234_hwpm_validate_hals(struct tegra_soc_hwpm *hwpm) +{ + if (hwpm->active_chip->is_ip_active == NULL) { + tegra_hwpm_err(hwpm, "is_ip_active HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->is_resource_active == NULL) { + tegra_hwpm_err(hwpm, "is_resource_active HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->get_pma_int_idx == NULL) { + tegra_hwpm_err(hwpm, "get_pma_int_idx HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->get_rtr_int_idx == NULL) { + tegra_hwpm_err(hwpm, "get_rtr_int_idx HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->get_ip_max_idx == NULL) { + tegra_hwpm_err(hwpm, "get_ip_max_idx HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->init_chip_ip_structures == NULL) { + tegra_hwpm_err(hwpm, "init_chip_ip_structures uninitialized"); + return false; + } + + if (hwpm->active_chip->extract_ip_ops == NULL) { + tegra_hwpm_err(hwpm, "extract_ip_ops uninitialized"); + return false; + } + + if (hwpm->active_chip->force_enable_ips == NULL) { + tegra_hwpm_err(hwpm, "force_enable_ips uninitialized"); + return false; + } + + if (hwpm->active_chip->get_fs_info == NULL) { + tegra_hwpm_err(hwpm, "get_fs_info uninitialized"); + return false; + } + + if (hwpm->active_chip->init_prod_values == NULL) { + tegra_hwpm_err(hwpm, "init_prod_values uninitialized"); + return false; + } + + if (hwpm->active_chip->disable_slcg == NULL) { + tegra_hwpm_err(hwpm, "disable_slcg uninitialized"); + return false; + } + + if (hwpm->active_chip->enable_slcg == NULL) { + tegra_hwpm_err(hwpm, "enable_slcg uninitialized"); + return false; + } + + if (hwpm->active_chip->reserve_pma == NULL) { + tegra_hwpm_err(hwpm, "reserve_pma uninitialized"); + return false; + } + + if (hwpm->active_chip->reserve_rtr == NULL) { + tegra_hwpm_err(hwpm, "reserve_rtr uninitialized"); + return false; + } + + if (hwpm->active_chip->release_pma == NULL) { + tegra_hwpm_err(hwpm, "release_pma uninitialized"); + return false; + } + + if (hwpm->active_chip->release_rtr == NULL) { + tegra_hwpm_err(hwpm, "release_rtr uninitialized"); + return false; + } + + if (hwpm->active_chip->perfmon_enable == NULL) { + tegra_hwpm_err(hwpm, "perfmon_enable HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->perfmon_disable == NULL) { + tegra_hwpm_err(hwpm, "perfmon_disable HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->perfmux_disable == NULL) { + tegra_hwpm_err(hwpm, "perfmux_disable HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->disable_triggers == NULL) { + tegra_hwpm_err(hwpm, "disable_triggers uninitialized"); + return false; + } + + if (hwpm->active_chip->disable_mem_mgmt == NULL) { + tegra_hwpm_err(hwpm, "disable_mem_mgmt HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->enable_mem_mgmt == NULL) { + tegra_hwpm_err(hwpm, "enable_mem_mgmt HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->invalidate_mem_config == NULL) { + tegra_hwpm_err(hwpm, "invalidate_mem_config HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->stream_mem_bytes == NULL) { + tegra_hwpm_err(hwpm, "stream_mem_bytes uninitialized"); + return false; + } + + if (hwpm->active_chip->disable_pma_streaming == NULL) { + tegra_hwpm_err(hwpm, "disable_pma_streaming uninitialized"); + return false; + } + + if (hwpm->active_chip->update_mem_bytes_get_ptr == NULL) { + tegra_hwpm_err(hwpm, "update_mem_bytes_get_ptr uninitialized"); + return false; + } + + if (hwpm->active_chip->get_mem_bytes_put_ptr == NULL) { + tegra_hwpm_err(hwpm, "get_mem_bytes_put_ptr uninitialized"); + return false; + } + + if (hwpm->active_chip->membuf_overflow_status == NULL) { + tegra_hwpm_err(hwpm, "membuf_overflow_status uninitialized"); + return false; + } + + if (hwpm->active_chip->get_alist_buf_size == NULL) { + tegra_hwpm_err(hwpm, "alist_buf_size uninitialized"); + return false; + } + + if (hwpm->active_chip->zero_alist_regs == NULL) { + tegra_hwpm_err(hwpm, "zero_alist_regs HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->copy_alist == NULL) { + tegra_hwpm_err(hwpm, "copy_alist HAL uninitialized"); + return false; + } + + if (hwpm->active_chip->check_alist == NULL) { + tegra_hwpm_err(hwpm, "check_alist uninitialized"); + return false; + } + + if (hwpm->active_chip->exec_reg_ops == NULL) { + tegra_hwpm_err(hwpm, "exec_reg_ops uninitialized"); + return false; + } + + if (hwpm->active_chip->release_sw_setup == NULL) { + tegra_hwpm_err(hwpm, "release_sw_setup uninitialized"); + return false; + } + + return true; +} + bool t234_hwpm_is_ip_active(struct tegra_soc_hwpm *hwpm, u32 ip_index, u32 *config_ip_index) { @@ -354,5 +529,8 @@ int t234_hwpm_init_chip_info(struct tegra_soc_hwpm *hwpm) t234_active_ip_info[T234_HWPM_IP_VIC] = &t234_hwpm_ip_vic; #endif + if (!t234_hwpm_validate_hals(hwpm)) { + return -EINVAL; + } return 0; } diff --git a/include/tegra_hwpm.h b/include/tegra_hwpm.h index a303e5b..c786d26 100644 --- a/include/tegra_hwpm.h +++ b/include/tegra_hwpm.h @@ -98,6 +98,25 @@ struct tegra_hwpm_ip_ops { __u64 reg_offset, __u32 *reg_data); }; +struct tegra_hwpm_func_args { + u64 *alist; + u64 full_alist_idx; +}; + +enum tegra_hwpm_funcs { + TEGRA_HWPM_GET_ALIST_SIZE, + TEGRA_HWPM_COMBINE_ALIST, + TEGRA_HWPM_RESERVE_GIVEN_RESOURCE, + TEGRA_HWPM_BIND_RESOURCES, + TEGRA_HWPM_RELEASE_RESOURCES, +}; + +enum hwpm_aperture_type { + HWPM_APERTURE_INVALID, + HWPM_APERTURE_PERFMUX, + HWPM_APERTURE_PERFMON, +}; + struct hwpm_ip_aperture { /* * Indicates which domain (HWPM or IP) aperture belongs to, diff --git a/include/tegra_hwpm_common.h b/include/tegra_hwpm_common.h index dad019b..dd07566 100644 --- a/include/tegra_hwpm_common.h +++ b/include/tegra_hwpm_common.h @@ -14,11 +14,15 @@ #ifndef TEGRA_HWPM_COMMON_H #define TEGRA_HWPM_COMMON_H +enum tegra_hwpm_funcs; +enum hwpm_aperture_type; +struct tegra_hwpm_func_args; struct tegra_soc_hwpm; struct tegra_soc_hwpm_exec_reg_ops; struct tegra_soc_hwpm_ip_floorsweep_info; struct tegra_soc_hwpm_alloc_pma_stream; struct tegra_soc_hwpm_update_get_put; +struct hwpm_ip; struct tegra_soc_hwpm_ip_ops; struct hwpm_ip_aperture; typedef struct hwpm_ip_aperture hwpm_ip_perfmon; @@ -27,6 +31,27 @@ typedef struct hwpm_ip_aperture hwpm_ip_perfmux; int tegra_hwpm_init_sw_components(struct tegra_soc_hwpm *hwpm); void tegra_hwpm_release_sw_components(struct tegra_soc_hwpm *hwpm); +int tegra_hwpm_func_single_aperture(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func, u32 ip_idx, struct hwpm_ip *chip_ip, + u32 inst_idx, u32 aperture_idx, enum hwpm_aperture_type a_type); +int tegra_hwpm_func_all_perfmons(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func, u32 ip_idx, struct hwpm_ip *chip_ip, u32 inst_idx); +int tegra_hwpm_func_all_perfmuxes(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func, u32 ip_idx, struct hwpm_ip *chip_ip, u32 inst_idx); +int tegra_hwpm_func_all_inst(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func, u32 ip_idx, struct hwpm_ip *chip_ip); +int tegra_hwpm_func_single_ip(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func, u32 ip_idx); +int tegra_hwpm_func_all_ip(struct tegra_soc_hwpm *hwpm, + struct tegra_hwpm_func_args *func_args, + enum tegra_hwpm_funcs iia_func); + + int tegra_hwpm_reserve_resource(struct tegra_soc_hwpm *hwpm, u32 resource); int tegra_hwpm_release_resources(struct tegra_soc_hwpm *hwpm); int tegra_hwpm_bind_resources(struct tegra_soc_hwpm *hwpm); diff --git a/os/linux/tegra_hwpm_ip.c b/os/linux/tegra_hwpm_ip.c index 28409e1..1395b62 100644 --- a/os/linux/tegra_hwpm_ip.c +++ b/os/linux/tegra_hwpm_ip.c @@ -106,10 +106,6 @@ void tegra_soc_hwpm_ip_register(struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops) tegra_hwpm_dbg(hwpm, hwpm_info, "Register IP 0x%llx", hwpm_ip_ops->ip_base_address); - if (hwpm->active_chip->extract_ip_ops == NULL) { - tegra_hwpm_err(hwpm, "extract_ip_ops uninitialized"); - return; - } ret = hwpm->active_chip->extract_ip_ops(hwpm, hwpm_ip_ops, REGISTER_IP); if (ret < 0) { @@ -141,10 +137,6 @@ void tegra_soc_hwpm_ip_unregister(struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops) tegra_hwpm_dbg(hwpm, hwpm_info, "Unregister IP 0x%llx", hwpm_ip_ops->ip_base_address); - if (hwpm->active_chip->extract_ip_ops == NULL) { - tegra_hwpm_err(hwpm, "extract_ip_ops uninitialized"); - return; - } ret = hwpm->active_chip->extract_ip_ops(hwpm, hwpm_ip_ops, UNREGISTER_IP); if (ret < 0) { @@ -162,11 +154,6 @@ int tegra_hwpm_get_floorsweep_info(struct tegra_soc_hwpm *hwpm, tegra_hwpm_fn(hwpm, " "); - if (hwpm->active_chip->get_fs_info == NULL) { - tegra_hwpm_err(hwpm, "get_fs_info uninitialized"); - return -ENODEV; - } - for (i = 0U; i < fs_info->num_queries; i++) { ret = hwpm->active_chip->get_fs_info( hwpm, (u32)fs_info->ip_fsinfo[i].ip_type,