From 5166c3ab71dc76923a60f74f935f9de5df3e7e91 Mon Sep 17 00:00:00 2001 From: Vedashree Vidwans Date: Mon, 10 Oct 2022 14:50:33 -0700 Subject: [PATCH] tegra: hwpm: add clk-rst HALs, update HAL validation - Make clock reset functions into HALs. This way we can control clock-reset logic for any chip. Set clock-reset HAL pointers to appropriate functions. - Remove clock-reset function wrappers as these will not be required and corresponding HAL pointers will be used. - As clock reset init is defined as a HAL, modify probe logic to initialize chip info before invoking any HALs. - Move common/primary HAL validation logic to common code and implement new HAL to validate chip specific HALs. This way we can ensure that HAL pointers are set as expected. - Keep only one definition for t234_hwpm_init_chip_info as t234 should always be initialized and hence only single definition should be available. - Expected return value of 0 indicates success and any other value (mostly negative in current logic) indicates error, compare function returns with 0 to print error in tegra_hwpm_release(). - Since a build can support both ACPI and device tree, update init_chip_info() to retrieve chip information from ACPI and device tree in case of failure. Jira THWPM-41 Bug 3583624 Change-Id: I03fefae0b3b0c8ce46d175d39e4fdbb45e2bb22f Signed-off-by: Vedashree Vidwans Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2789668 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: Vasuki Shankar Reviewed-by: Seema Khowala GVS: Gerrit_Virtual_Submit Reviewed-on: https://git-master.nvidia.com/r/c/linux-hwpm/+/2797445 --- drivers/tegra/hwpm/common/init.c | 169 ++++++++++++++++++ drivers/tegra/hwpm/hal/t234/t234_init.h | 7 - drivers/tegra/hwpm/hal/t234/t234_interface.c | 166 +++-------------- drivers/tegra/hwpm/hal/t234/t234_internal.h | 1 + drivers/tegra/hwpm/include/tegra_hwpm.h | 8 + .../tegra/hwpm/include/tegra_hwpm_clk_rst.h | 21 +-- .../tegra/hwpm/include/tegra_hwpm_common.h | 1 + drivers/tegra/hwpm/os/linux/clk_rst_utils.c | 40 +---- drivers/tegra/hwpm/os/linux/clk_rst_utils.h | 9 +- drivers/tegra/hwpm/os/linux/driver.c | 27 +-- drivers/tegra/hwpm/os/linux/ioctl.c | 28 +-- drivers/tegra/hwpm/os/linux/soc_utils.c | 26 ++- 12 files changed, 255 insertions(+), 248 deletions(-) diff --git a/drivers/tegra/hwpm/common/init.c b/drivers/tegra/hwpm/common/init.c index 9f99825..13e40ec 100644 --- a/drivers/tegra/hwpm/common/init.c +++ b/drivers/tegra/hwpm/common/init.c @@ -222,3 +222,172 @@ void tegra_hwpm_release_sw_setup(struct tegra_soc_hwpm *hwpm) return; } + +/* Validate HALs that are expected to be populated for each chip */ +bool tegra_hwpm_validate_primary_hals(struct tegra_soc_hwpm *hwpm) +{ + tegra_hwpm_fn(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_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->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->validate_current_config == NULL) { + tegra_hwpm_err(hwpm, "validate_current_config 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->get_resource_info == NULL) { + tegra_hwpm_err(hwpm, "get_resource_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_cg == NULL) { + tegra_hwpm_err(hwpm, "disable_cg uninitialized"); + return false; + } + + if (hwpm->active_chip->enable_cg == NULL) { + tegra_hwpm_err(hwpm, "enable_cg uninitialized"); + return false; + } + + if (hwpm->active_chip->reserve_rtr == NULL) { + tegra_hwpm_err(hwpm, "reserve_rtr 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->check_status == NULL) { + tegra_hwpm_err(hwpm, "check_status 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->validate_secondary_hals == NULL) { + tegra_hwpm_err(hwpm, + "validate_secondary_hals HAL uninitialized"); + return false; + } + + return hwpm->active_chip->validate_secondary_hals(hwpm); +} diff --git a/drivers/tegra/hwpm/hal/t234/t234_init.h b/drivers/tegra/hwpm/hal/t234/t234_init.h index b86dd33..112ef2f 100644 --- a/drivers/tegra/hwpm/hal/t234/t234_init.h +++ b/drivers/tegra/hwpm/hal/t234/t234_init.h @@ -16,13 +16,6 @@ struct tegra_soc_hwpm; -#ifdef CONFIG_TEGRA_T234_HWPM int t234_hwpm_init_chip_info(struct tegra_soc_hwpm *hwpm); -#else -int t234_hwpm_init_chip_info(struct tegra_soc_hwpm *hwpm) -{ - return -EINVAL; -} -#endif #endif /* T234_HWPM_INIT_H */ diff --git a/drivers/tegra/hwpm/hal/t234/t234_interface.c b/drivers/tegra/hwpm/hal/t234/t234_interface.c index f200319..aa3f8c5 100644 --- a/drivers/tegra/hwpm/hal/t234/t234_interface.c +++ b/drivers/tegra/hwpm/hal/t234/t234_interface.c @@ -11,6 +11,7 @@ * more details. */ +#include #include #include #include @@ -23,6 +24,13 @@ static struct tegra_soc_hwpm_chip t234_chip_info = { .chip_ips = NULL, /* HALs */ + .validate_secondary_hals = t234_hwpm_validate_secondary_hals, + + .clk_rst_prepare = tegra_hwpm_clk_rst_prepare, + .clk_rst_set_rate_enable = tegra_hwpm_clk_rst_set_rate_enable, + .clk_rst_disable = tegra_hwpm_clk_rst_disable, + .clk_rst_release = tegra_hwpm_clk_rst_release, + .is_ip_active = t234_hwpm_is_ip_active, .is_resource_active = t234_hwpm_is_resource_active, @@ -63,160 +71,28 @@ static struct tegra_soc_hwpm_chip t234_chip_info = { .check_alist = tegra_hwpm_check_alist, }; -static bool t234_hwpm_validate_hals(struct tegra_soc_hwpm *hwpm) +bool t234_hwpm_validate_secondary_hals(struct tegra_soc_hwpm *hwpm) { - if (hwpm->active_chip->is_ip_active == NULL) { - tegra_hwpm_err(hwpm, "is_ip_active HAL uninitialized"); + tegra_hwpm_fn(hwpm, " "); + + if (hwpm->active_chip->clk_rst_prepare == NULL) { + tegra_hwpm_err(hwpm, "clk_rst_prepare HAL uninitialized"); return false; } - if (hwpm->active_chip->is_resource_active == NULL) { - tegra_hwpm_err(hwpm, "is_resource_active HAL uninitialized"); + if (hwpm->active_chip->clk_rst_set_rate_enable == NULL) { + tegra_hwpm_err(hwpm, + "clk_rst_set_rate_enable HAL uninitialized"); return false; } - if (hwpm->active_chip->get_rtr_int_idx == NULL) { - tegra_hwpm_err(hwpm, "get_rtr_int_idx HAL uninitialized"); + if (hwpm->active_chip->clk_rst_disable == NULL) { + tegra_hwpm_err(hwpm, "clk_rst_disable 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->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->validate_current_config == NULL) { - tegra_hwpm_err(hwpm, "validate_current_config 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->get_resource_info == NULL) { - tegra_hwpm_err(hwpm, "get_resource_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_cg == NULL) { - tegra_hwpm_err(hwpm, "disable_cg uninitialized"); - return false; - } - - if (hwpm->active_chip->enable_cg == NULL) { - tegra_hwpm_err(hwpm, "enable_cg uninitialized"); - return false; - } - - if (hwpm->active_chip->reserve_rtr == NULL) { - tegra_hwpm_err(hwpm, "reserve_rtr 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->check_status == NULL) { - tegra_hwpm_err(hwpm, "check_status 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"); + if (hwpm->active_chip->clk_rst_release == NULL) { + tegra_hwpm_err(hwpm, "clk_rst_release HAL uninitialized"); return false; } @@ -500,7 +376,7 @@ 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)) { + if (!tegra_hwpm_validate_primary_hals(hwpm)) { return -EINVAL; } return 0; diff --git a/drivers/tegra/hwpm/hal/t234/t234_internal.h b/drivers/tegra/hwpm/hal/t234/t234_internal.h index 62cd5be..6cc17e9 100644 --- a/drivers/tegra/hwpm/hal/t234/t234_internal.h +++ b/drivers/tegra/hwpm/hal/t234/t234_internal.h @@ -68,6 +68,7 @@ enum tegra_soc_hwpm_resource; struct tegra_soc_hwpm; struct hwpm_ip_aperture; +bool t234_hwpm_validate_secondary_hals(struct tegra_soc_hwpm *hwpm); bool t234_hwpm_is_ip_active(struct tegra_soc_hwpm *hwpm, u32 ip_enum, u32 *config_ip_index); bool t234_hwpm_is_resource_active(struct tegra_soc_hwpm *hwpm, diff --git a/drivers/tegra/hwpm/include/tegra_hwpm.h b/drivers/tegra/hwpm/include/tegra_hwpm.h index 59415b7..b8ba2e9 100644 --- a/drivers/tegra/hwpm/include/tegra_hwpm.h +++ b/drivers/tegra/hwpm/include/tegra_hwpm.h @@ -30,6 +30,7 @@ #define TEGRA_HWPM_FUSE_SECURITY_MODE_MASK BIT(1) #define TEGRA_HWPM_FUSE_HWPM_GLOBAL_DISABLE_MASK BIT(2) +struct tegra_hwpm_os_linux; struct tegra_hwpm_mem_mgmt; struct tegra_hwpm_allowlist_map; enum tegra_soc_hwpm_ip_reg_op; @@ -372,6 +373,13 @@ struct tegra_soc_hwpm_chip { struct hwpm_ip **chip_ips; /* Chip HALs */ + bool (*validate_secondary_hals)(struct tegra_soc_hwpm *hwpm); + + int (*clk_rst_prepare)(struct tegra_hwpm_os_linux *hwpm_linux); + int (*clk_rst_set_rate_enable)(struct tegra_hwpm_os_linux *hwpm_linux); + int (*clk_rst_disable)(struct tegra_hwpm_os_linux *hwpm_linux); + void (*clk_rst_release)(struct tegra_hwpm_os_linux *hwpm_linux); + bool (*is_ip_active)(struct tegra_soc_hwpm *hwpm, u32 ip_enum, u32 *config_ip_index); bool (*is_resource_active)(struct tegra_soc_hwpm *hwpm, diff --git a/drivers/tegra/hwpm/include/tegra_hwpm_clk_rst.h b/drivers/tegra/hwpm/include/tegra_hwpm_clk_rst.h index 0b83060..bb23e85 100644 --- a/drivers/tegra/hwpm/include/tegra_hwpm_clk_rst.h +++ b/drivers/tegra/hwpm/include/tegra_hwpm_clk_rst.h @@ -23,36 +23,23 @@ #else struct tegra_hwpm_os_linux; -int tegra_hwpm_clk_rst_prepare_impl(struct tegra_hwpm_os_linux *hwpm_linux) +int tegra_hwpm_clk_rst_prepare(struct tegra_hwpm_os_linux *hwpm_linux) { return -EINVAL; } -int tegra_hwpm_clk_rst_set_rate_enable_impl( - struct tegra_hwpm_os_linux *hwpm_linux) +int tegra_hwpm_clk_rst_set_rate_enable(struct tegra_hwpm_os_linux *hwpm_linux) { return -EINVAL; } -int tegra_hwpm_clk_rst_disable_impl(struct tegra_hwpm_os_linux *hwpm_linux) +int tegra_hwpm_clk_rst_disable(struct tegra_hwpm_os_linux *hwpm_linux) { } -void tegra_hwpm_clk_rst_release_impl(struct tegra_hwpm_os_linux *hwpm_linux) +void tegra_hwpm_clk_rst_release(struct tegra_hwpm_os_linux *hwpm_linux) { } #endif -#define tegra_hwpm_clk_rst_prepare(hwpm_linux) \ - tegra_hwpm_clk_rst_prepare_impl(hwpm_linux) - -#define tegra_hwpm_clk_rst_set_rate_enable(hwpm_linux) \ - tegra_hwpm_clk_rst_set_rate_enable_impl(hwpm_linux) - -#define tegra_hwpm_clk_rst_disable(hwpm_linux) \ - tegra_hwpm_clk_rst_disable_impl(hwpm_linux) - -#define tegra_hwpm_clk_rst_release(hwpm_linux) \ - tegra_hwpm_clk_rst_release_impl(hwpm_linux) - #endif /* TEGRA_HWPM_CLK_RST_H */ diff --git a/drivers/tegra/hwpm/include/tegra_hwpm_common.h b/drivers/tegra/hwpm/include/tegra_hwpm_common.h index 87ea2d5..5acbc31 100644 --- a/drivers/tegra/hwpm/include/tegra_hwpm_common.h +++ b/drivers/tegra/hwpm/include/tegra_hwpm_common.h @@ -77,6 +77,7 @@ int tegra_hwpm_copy_alist(struct tegra_soc_hwpm *hwpm, bool tegra_hwpm_check_alist(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_aperture *aperture, u64 phys_addr); +bool tegra_hwpm_validate_primary_hals(struct tegra_soc_hwpm *hwpm); int tegra_hwpm_setup_hw(struct tegra_soc_hwpm *hwpm); int tegra_hwpm_setup_sw(struct tegra_soc_hwpm *hwpm); int tegra_hwpm_disable_triggers(struct tegra_soc_hwpm *hwpm); diff --git a/drivers/tegra/hwpm/os/linux/clk_rst_utils.c b/drivers/tegra/hwpm/os/linux/clk_rst_utils.c index b681213..a0f22fa 100644 --- a/drivers/tegra/hwpm/os/linux/clk_rst_utils.c +++ b/drivers/tegra/hwpm/os/linux/clk_rst_utils.c @@ -26,15 +26,8 @@ #define LA_CLK_RATE 625000000UL -int tegra_hwpm_clk_rst_prepare_impl(struct tegra_hwpm_os_linux *hwpm_linux) +int tegra_hwpm_clk_rst_prepare(struct tegra_hwpm_os_linux *hwpm_linux) { -#if defined(CONFIG_TEGRA_HWPM_OOT) - /* - * Starting OOT config, clocks and resets are handled by UEFI layer - * Hence, do nothing. - */ - return 0; -#else int ret = 0; struct tegra_soc_hwpm *hwpm = &hwpm_linux->hwpm; @@ -73,19 +66,10 @@ int tegra_hwpm_clk_rst_prepare_impl(struct tegra_hwpm_os_linux *hwpm_linux) fail: return ret; -#endif } -int tegra_hwpm_clk_rst_set_rate_enable_impl( - struct tegra_hwpm_os_linux *hwpm_linux) +int tegra_hwpm_clk_rst_set_rate_enable(struct tegra_hwpm_os_linux *hwpm_linux) { -#if defined(CONFIG_TEGRA_HWPM_OOT) - /* - * Starting OOT config, clocks and resets are handled by UEFI layer - * Hence, do nothing. - */ - return 0; -#else int ret = 0; struct tegra_soc_hwpm *hwpm = &hwpm_linux->hwpm; @@ -135,18 +119,10 @@ int tegra_hwpm_clk_rst_set_rate_enable_impl( fail: return ret; -#endif } -int tegra_hwpm_clk_rst_disable_impl(struct tegra_hwpm_os_linux *hwpm_linux) +int tegra_hwpm_clk_rst_disable(struct tegra_hwpm_os_linux *hwpm_linux) { -#if defined(CONFIG_TEGRA_HWPM_OOT) - /* - * Starting OOT config, clocks and resets are handled by UEFI layer - * Hence, do nothing. - */ - return 0; -#else int ret = 0; struct tegra_soc_hwpm *hwpm = &hwpm_linux->hwpm; @@ -165,17 +141,10 @@ int tegra_hwpm_clk_rst_disable_impl(struct tegra_hwpm_os_linux *hwpm_linux) } fail: return ret; -#endif } -void tegra_hwpm_clk_rst_release_impl(struct tegra_hwpm_os_linux *hwpm_linux) +void tegra_hwpm_clk_rst_release(struct tegra_hwpm_os_linux *hwpm_linux) { -#if defined(CONFIG_TEGRA_HWPM_OOT) - /* - * Starting OOT config, clocks and resets are handled by UEFI layer - * Hence, do nothing. - */ -#else if (tegra_hwpm_is_platform_silicon()) { if (hwpm_linux->la_clk) { devm_clk_put(hwpm_linux->dev, hwpm_linux->la_clk); @@ -191,5 +160,4 @@ void tegra_hwpm_clk_rst_release_impl(struct tegra_hwpm_os_linux *hwpm_linux) reset_control_assert(hwpm_linux->hwpm_rst); } } -#endif } diff --git a/drivers/tegra/hwpm/os/linux/clk_rst_utils.h b/drivers/tegra/hwpm/os/linux/clk_rst_utils.h index 6ade752..3d0d050 100644 --- a/drivers/tegra/hwpm/os/linux/clk_rst_utils.h +++ b/drivers/tegra/hwpm/os/linux/clk_rst_utils.h @@ -20,10 +20,9 @@ struct tegra_hwpm_os_linux; -int tegra_hwpm_clk_rst_prepare_impl(struct tegra_hwpm_os_linux *hwpm_linux); -int tegra_hwpm_clk_rst_set_rate_enable_impl( - struct tegra_hwpm_os_linux *hwpm_linux); -int tegra_hwpm_clk_rst_disable_impl(struct tegra_hwpm_os_linux *hwpm_linux); -void tegra_hwpm_clk_rst_release_impl(struct tegra_hwpm_os_linux *hwpm_linux); +int tegra_hwpm_clk_rst_prepare(struct tegra_hwpm_os_linux *hwpm_linux); +int tegra_hwpm_clk_rst_set_rate_enable(struct tegra_hwpm_os_linux *hwpm_linux); +int tegra_hwpm_clk_rst_disable(struct tegra_hwpm_os_linux *hwpm_linux); +void tegra_hwpm_clk_rst_release(struct tegra_hwpm_os_linux *hwpm_linux); #endif /* TEGRA_HWPM_OS_LINUX_CLK_RST_UTILS_H */ diff --git a/drivers/tegra/hwpm/os/linux/driver.c b/drivers/tegra/hwpm/os/linux/driver.c index b371de2..bce32a2 100644 --- a/drivers/tegra/hwpm/os/linux/driver.c +++ b/drivers/tegra/hwpm/os/linux/driver.c @@ -166,13 +166,6 @@ static int tegra_hwpm_probe(struct platform_device *pdev) (void) dma_set_mask_and_coherent(hwpm_linux->dev, DMA_BIT_MASK(39)); - ret = tegra_hwpm_clk_rst_prepare(hwpm_linux); - if (ret != 0) { - goto clock_reset_fail; - } - - tegra_hwpm_debugfs_init(hwpm_linux); - ret = tegra_hwpm_get_chip_info(hwpm_linux); if (ret != 0) { tegra_hwpm_err(hwpm, "Failed to get current chip info"); @@ -186,6 +179,15 @@ static int tegra_hwpm_probe(struct platform_device *pdev) goto init_sw_components_fail; } + if (hwpm->active_chip->clk_rst_prepare) { + ret = hwpm->active_chip->clk_rst_prepare(hwpm_linux); + if (ret != 0) { + goto clock_reset_fail; + } + } + + tegra_hwpm_debugfs_init(hwpm_linux); + /* * Currently VDK doesn't have a fmodel for SOC HWPM. Therefore, we * enable fake registers on VDK for minimal testing. @@ -202,10 +204,11 @@ static int tegra_hwpm_probe(struct platform_device *pdev) tegra_hwpm_dbg(hwpm, hwpm_info, "Probe successful!"); goto success; -chip_info_fail: -init_sw_components_fail: - tegra_hwpm_clk_rst_release(hwpm_linux); clock_reset_fail: + tegra_hwpm_release_ip_register_node(hwpm); + tegra_hwpm_release_sw_setup(hwpm); +init_sw_components_fail: +chip_info_fail: device_destroy(&hwpm_linux->class, hwpm_linux->dev_t); device_create: cdev_del(&hwpm_linux->cdev); @@ -243,7 +246,9 @@ static int tegra_hwpm_remove(struct platform_device *pdev) return -ENODEV; } - tegra_hwpm_clk_rst_release(hwpm_linux); + if (hwpm->active_chip->clk_rst_release) { + hwpm->active_chip->clk_rst_release(hwpm_linux); + } tegra_hwpm_release_ip_register_node(hwpm); tegra_hwpm_release_sw_setup(hwpm); diff --git a/drivers/tegra/hwpm/os/linux/ioctl.c b/drivers/tegra/hwpm/os/linux/ioctl.c index f724264..29c857b 100644 --- a/drivers/tegra/hwpm/os/linux/ioctl.c +++ b/drivers/tegra/hwpm/os/linux/ioctl.c @@ -401,9 +401,11 @@ static int tegra_hwpm_open(struct inode *inode, struct file *filp) return -EAGAIN; } - ret = tegra_hwpm_clk_rst_set_rate_enable(hwpm_linux); - if (ret != 0) { - goto fail; + if (hwpm->active_chip->clk_rst_set_rate_enable) { + ret = tegra_hwpm_clk_rst_set_rate_enable(hwpm_linux); + if (ret != 0) { + goto fail; + } } ret = tegra_hwpm_setup_hw(hwpm); @@ -477,14 +479,14 @@ static int tegra_hwpm_release(struct inode *inode, struct file *filp) } ret = tegra_hwpm_disable_triggers(hwpm); - if (ret < 0) { + if (ret != 0) { tegra_hwpm_err(hwpm, "Failed to disable PMA triggers"); err = ret; } /* Disable and release reserved IPs */ ret = tegra_hwpm_release_resources(hwpm); - if (ret < 0) { + if (ret != 0) { tegra_hwpm_err(hwpm, "Failed to release IP apertures"); err = ret; goto fail; @@ -492,7 +494,7 @@ static int tegra_hwpm_release(struct inode *inode, struct file *filp) /* Clear MEM_BYTES pipeline */ ret = tegra_hwpm_clear_mem_pipeline(hwpm); - if (ret < 0) { + if (ret != 0) { tegra_hwpm_err(hwpm, "Failed to clear MEM_BYTES pipeline"); err = ret; goto fail; @@ -502,17 +504,19 @@ static int tegra_hwpm_release(struct inode *inode, struct file *filp) tegra_hwpm_release_mem_mgmt(hwpm); ret = tegra_hwpm_release_hw(hwpm); - if (ret < 0) { + if (ret != 0) { tegra_hwpm_err(hwpm, "Failed to release hw"); err = ret; goto fail; } - ret = tegra_hwpm_clk_rst_disable(hwpm_linux); - if (ret < 0) { - tegra_hwpm_err(hwpm, "Failed to release clock"); - err = ret; - goto fail; + if (hwpm->active_chip->clk_rst_disable) { + ret = tegra_hwpm_clk_rst_disable(hwpm_linux); + if (ret != 0) { + tegra_hwpm_err(hwpm, "Failed to release clock"); + err = ret; + goto fail; + } } /* De-init driver on last close call only */ diff --git a/drivers/tegra/hwpm/os/linux/soc_utils.c b/drivers/tegra/hwpm/os/linux/soc_utils.c index 5d67e5f..39d07f4 100644 --- a/drivers/tegra/hwpm/os/linux/soc_utils.c +++ b/drivers/tegra/hwpm/os/linux/soc_utils.c @@ -36,19 +36,16 @@ static struct hwpm_soc_chip_info chip_info = { }; static bool chip_info_initialized; -#if (!defined(CONFIG_ACPI)) const struct hwpm_soc_chip_info t234_chip_info = { .chip_id = 0x23, .chip_id_rev = 0x4, .platform = PLAT_SI, }; -#endif /* This function should be invoked only once before retrieving soc chip info */ int tegra_hwpm_init_chip_info(struct tegra_hwpm_os_linux *hwpm_linux) { struct device *dev = hwpm_linux->dev; - struct tegra_soc_hwpm *hwpm = &hwpm_linux->hwpm; #if defined(CONFIG_ACPI) const struct acpi_device_id *id; #endif @@ -56,19 +53,19 @@ int tegra_hwpm_init_chip_info(struct tegra_hwpm_os_linux *hwpm_linux) if (chip_info_initialized) { return 0; } + #if defined(CONFIG_ACPI) + /* Get device node info from ACPI table */ id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!id) { - tegra_hwpm_err(hwpm, "Couldn't find matching ACPI device"); - return -ENODEV; + if (id) { + chip_info.chip_id = (id->driver_data >> 8) & 0xff; + chip_info.chip_id_rev = (id->driver_data >> 4) & 0xf; + chip_info.platform = (id->driver_data >> 20) & 0xf; + + goto complete; } - - chip_info.chip_id = (id->driver_data >> 8) & 0xff; - chip_info.chip_id_rev = (id->driver_data >> 4) & 0xf; - chip_info.platform = (id->driver_data >> 20) & 0xf; - - goto complete; -#else /* !CONFIG_ACPI */ +#endif + /* Get device node info from device tree */ if (of_machine_is_compatible("nvidia,tegra234")) { chip_info.chip_id = t234_chip_info.chip_id; chip_info.chip_id_rev = t234_chip_info.chip_id_rev; @@ -87,8 +84,7 @@ int tegra_hwpm_init_chip_info(struct tegra_hwpm_os_linux *hwpm_linux) } #endif -#endif /* CONFIG_ACPI */ - return -EINVAL; + return -ENODEV; complete: chip_info_initialized = true; return 0;