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 <vvidwans@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2789668
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Vasuki Shankar <vasukis@nvidia.com>
Reviewed-by: Seema Khowala <seemaj@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-hwpm/+/2797445
This commit is contained in:
Vedashree Vidwans
2022-10-10 14:50:33 -07:00
committed by mobile promotions
parent 913f1b0697
commit 5166c3ab71
12 changed files with 255 additions and 248 deletions

View File

@@ -222,3 +222,172 @@ void tegra_hwpm_release_sw_setup(struct tegra_soc_hwpm *hwpm)
return; 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);
}

View File

@@ -16,13 +16,6 @@
struct tegra_soc_hwpm; struct tegra_soc_hwpm;
#ifdef CONFIG_TEGRA_T234_HWPM
int t234_hwpm_init_chip_info(struct tegra_soc_hwpm *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 */ #endif /* T234_HWPM_INIT_H */

View File

@@ -11,6 +11,7 @@
* more details. * more details.
*/ */
#include <tegra_hwpm_clk_rst.h>
#include <tegra_hwpm_common.h> #include <tegra_hwpm_common.h>
#include <tegra_hwpm_kmem.h> #include <tegra_hwpm_kmem.h>
#include <tegra_hwpm_log.h> #include <tegra_hwpm_log.h>
@@ -23,6 +24,13 @@ static struct tegra_soc_hwpm_chip t234_chip_info = {
.chip_ips = NULL, .chip_ips = NULL,
/* HALs */ /* 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_ip_active = t234_hwpm_is_ip_active,
.is_resource_active = t234_hwpm_is_resource_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, .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_fn(hwpm, " ");
tegra_hwpm_err(hwpm, "is_ip_active HAL uninitialized");
if (hwpm->active_chip->clk_rst_prepare == NULL) {
tegra_hwpm_err(hwpm, "clk_rst_prepare HAL uninitialized");
return false; return false;
} }
if (hwpm->active_chip->is_resource_active == NULL) { if (hwpm->active_chip->clk_rst_set_rate_enable == NULL) {
tegra_hwpm_err(hwpm, "is_resource_active HAL uninitialized"); tegra_hwpm_err(hwpm,
"clk_rst_set_rate_enable HAL uninitialized");
return false; return false;
} }
if (hwpm->active_chip->get_rtr_int_idx == NULL) { if (hwpm->active_chip->clk_rst_disable == NULL) {
tegra_hwpm_err(hwpm, "get_rtr_int_idx HAL uninitialized"); tegra_hwpm_err(hwpm, "clk_rst_disable HAL uninitialized");
return false; return false;
} }
if (hwpm->active_chip->get_ip_max_idx == NULL) { if (hwpm->active_chip->clk_rst_release == NULL) {
tegra_hwpm_err(hwpm, "get_ip_max_idx HAL uninitialized"); tegra_hwpm_err(hwpm, "clk_rst_release 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; 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; t234_active_ip_info[T234_HWPM_IP_VIC] = &t234_hwpm_ip_vic;
#endif #endif
if (!t234_hwpm_validate_hals(hwpm)) { if (!tegra_hwpm_validate_primary_hals(hwpm)) {
return -EINVAL; return -EINVAL;
} }
return 0; return 0;

View File

@@ -68,6 +68,7 @@ enum tegra_soc_hwpm_resource;
struct tegra_soc_hwpm; struct tegra_soc_hwpm;
struct hwpm_ip_aperture; 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, bool t234_hwpm_is_ip_active(struct tegra_soc_hwpm *hwpm,
u32 ip_enum, u32 *config_ip_index); u32 ip_enum, u32 *config_ip_index);
bool t234_hwpm_is_resource_active(struct tegra_soc_hwpm *hwpm, bool t234_hwpm_is_resource_active(struct tegra_soc_hwpm *hwpm,

View File

@@ -30,6 +30,7 @@
#define TEGRA_HWPM_FUSE_SECURITY_MODE_MASK BIT(1) #define TEGRA_HWPM_FUSE_SECURITY_MODE_MASK BIT(1)
#define TEGRA_HWPM_FUSE_HWPM_GLOBAL_DISABLE_MASK BIT(2) #define TEGRA_HWPM_FUSE_HWPM_GLOBAL_DISABLE_MASK BIT(2)
struct tegra_hwpm_os_linux;
struct tegra_hwpm_mem_mgmt; struct tegra_hwpm_mem_mgmt;
struct tegra_hwpm_allowlist_map; struct tegra_hwpm_allowlist_map;
enum tegra_soc_hwpm_ip_reg_op; enum tegra_soc_hwpm_ip_reg_op;
@@ -372,6 +373,13 @@ struct tegra_soc_hwpm_chip {
struct hwpm_ip **chip_ips; struct hwpm_ip **chip_ips;
/* Chip HALs */ /* 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, bool (*is_ip_active)(struct tegra_soc_hwpm *hwpm,
u32 ip_enum, u32 *config_ip_index); u32 ip_enum, u32 *config_ip_index);
bool (*is_resource_active)(struct tegra_soc_hwpm *hwpm, bool (*is_resource_active)(struct tegra_soc_hwpm *hwpm,

View File

@@ -23,36 +23,23 @@
#else #else
struct tegra_hwpm_os_linux; 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; return -EINVAL;
} }
int tegra_hwpm_clk_rst_set_rate_enable_impl( int tegra_hwpm_clk_rst_set_rate_enable(struct tegra_hwpm_os_linux *hwpm_linux)
struct tegra_hwpm_os_linux *hwpm_linux)
{ {
return -EINVAL; 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 #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 */ #endif /* TEGRA_HWPM_CLK_RST_H */

View File

@@ -77,6 +77,7 @@ int tegra_hwpm_copy_alist(struct tegra_soc_hwpm *hwpm,
bool tegra_hwpm_check_alist(struct tegra_soc_hwpm *hwpm, bool tegra_hwpm_check_alist(struct tegra_soc_hwpm *hwpm,
struct hwpm_ip_aperture *aperture, u64 phys_addr); 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_hw(struct tegra_soc_hwpm *hwpm);
int tegra_hwpm_setup_sw(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); int tegra_hwpm_disable_triggers(struct tegra_soc_hwpm *hwpm);

View File

@@ -26,15 +26,8 @@
#define LA_CLK_RATE 625000000UL #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; int ret = 0;
struct tegra_soc_hwpm *hwpm = &hwpm_linux->hwpm; 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: fail:
return ret; return ret;
#endif
} }
int tegra_hwpm_clk_rst_set_rate_enable_impl( int tegra_hwpm_clk_rst_set_rate_enable(struct tegra_hwpm_os_linux *hwpm_linux)
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; int ret = 0;
struct tegra_soc_hwpm *hwpm = &hwpm_linux->hwpm; struct tegra_soc_hwpm *hwpm = &hwpm_linux->hwpm;
@@ -135,18 +119,10 @@ int tegra_hwpm_clk_rst_set_rate_enable_impl(
fail: fail:
return ret; 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; int ret = 0;
struct tegra_soc_hwpm *hwpm = &hwpm_linux->hwpm; 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: fail:
return ret; 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 (tegra_hwpm_is_platform_silicon()) {
if (hwpm_linux->la_clk) { if (hwpm_linux->la_clk) {
devm_clk_put(hwpm_linux->dev, 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); reset_control_assert(hwpm_linux->hwpm_rst);
} }
} }
#endif
} }

View File

@@ -20,10 +20,9 @@
struct tegra_hwpm_os_linux; 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);
int tegra_hwpm_clk_rst_set_rate_enable_impl( int tegra_hwpm_clk_rst_set_rate_enable(struct tegra_hwpm_os_linux *hwpm_linux);
struct tegra_hwpm_os_linux *hwpm_linux); int tegra_hwpm_clk_rst_disable(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(struct tegra_hwpm_os_linux *hwpm_linux);
void tegra_hwpm_clk_rst_release_impl(struct tegra_hwpm_os_linux *hwpm_linux);
#endif /* TEGRA_HWPM_OS_LINUX_CLK_RST_UTILS_H */ #endif /* TEGRA_HWPM_OS_LINUX_CLK_RST_UTILS_H */

View File

@@ -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)); (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); ret = tegra_hwpm_get_chip_info(hwpm_linux);
if (ret != 0) { if (ret != 0) {
tegra_hwpm_err(hwpm, "Failed to get current chip info"); 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; 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 * Currently VDK doesn't have a fmodel for SOC HWPM. Therefore, we
* enable fake registers on VDK for minimal testing. * 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!"); tegra_hwpm_dbg(hwpm, hwpm_info, "Probe successful!");
goto success; goto success;
chip_info_fail:
init_sw_components_fail:
tegra_hwpm_clk_rst_release(hwpm_linux);
clock_reset_fail: 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_destroy(&hwpm_linux->class, hwpm_linux->dev_t);
device_create: device_create:
cdev_del(&hwpm_linux->cdev); cdev_del(&hwpm_linux->cdev);
@@ -243,7 +246,9 @@ static int tegra_hwpm_remove(struct platform_device *pdev)
return -ENODEV; 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_ip_register_node(hwpm);
tegra_hwpm_release_sw_setup(hwpm); tegra_hwpm_release_sw_setup(hwpm);

View File

@@ -401,10 +401,12 @@ static int tegra_hwpm_open(struct inode *inode, struct file *filp)
return -EAGAIN; return -EAGAIN;
} }
if (hwpm->active_chip->clk_rst_set_rate_enable) {
ret = tegra_hwpm_clk_rst_set_rate_enable(hwpm_linux); ret = tegra_hwpm_clk_rst_set_rate_enable(hwpm_linux);
if (ret != 0) { if (ret != 0) {
goto fail; goto fail;
} }
}
ret = tegra_hwpm_setup_hw(hwpm); ret = tegra_hwpm_setup_hw(hwpm);
if (ret < 0) { if (ret < 0) {
@@ -477,14 +479,14 @@ static int tegra_hwpm_release(struct inode *inode, struct file *filp)
} }
ret = tegra_hwpm_disable_triggers(hwpm); ret = tegra_hwpm_disable_triggers(hwpm);
if (ret < 0) { if (ret != 0) {
tegra_hwpm_err(hwpm, "Failed to disable PMA triggers"); tegra_hwpm_err(hwpm, "Failed to disable PMA triggers");
err = ret; err = ret;
} }
/* Disable and release reserved IPs */ /* Disable and release reserved IPs */
ret = tegra_hwpm_release_resources(hwpm); ret = tegra_hwpm_release_resources(hwpm);
if (ret < 0) { if (ret != 0) {
tegra_hwpm_err(hwpm, "Failed to release IP apertures"); tegra_hwpm_err(hwpm, "Failed to release IP apertures");
err = ret; err = ret;
goto fail; goto fail;
@@ -492,7 +494,7 @@ static int tegra_hwpm_release(struct inode *inode, struct file *filp)
/* Clear MEM_BYTES pipeline */ /* Clear MEM_BYTES pipeline */
ret = tegra_hwpm_clear_mem_pipeline(hwpm); ret = tegra_hwpm_clear_mem_pipeline(hwpm);
if (ret < 0) { if (ret != 0) {
tegra_hwpm_err(hwpm, "Failed to clear MEM_BYTES pipeline"); tegra_hwpm_err(hwpm, "Failed to clear MEM_BYTES pipeline");
err = ret; err = ret;
goto fail; goto fail;
@@ -502,18 +504,20 @@ static int tegra_hwpm_release(struct inode *inode, struct file *filp)
tegra_hwpm_release_mem_mgmt(hwpm); tegra_hwpm_release_mem_mgmt(hwpm);
ret = tegra_hwpm_release_hw(hwpm); ret = tegra_hwpm_release_hw(hwpm);
if (ret < 0) { if (ret != 0) {
tegra_hwpm_err(hwpm, "Failed to release hw"); tegra_hwpm_err(hwpm, "Failed to release hw");
err = ret; err = ret;
goto fail; goto fail;
} }
if (hwpm->active_chip->clk_rst_disable) {
ret = tegra_hwpm_clk_rst_disable(hwpm_linux); ret = tegra_hwpm_clk_rst_disable(hwpm_linux);
if (ret < 0) { if (ret != 0) {
tegra_hwpm_err(hwpm, "Failed to release clock"); tegra_hwpm_err(hwpm, "Failed to release clock");
err = ret; err = ret;
goto fail; goto fail;
} }
}
/* De-init driver on last close call only */ /* De-init driver on last close call only */
if (!atomic_dec_and_test(&hwpm_linux->usage_count.var)) { if (!atomic_dec_and_test(&hwpm_linux->usage_count.var)) {

View File

@@ -36,19 +36,16 @@ static struct hwpm_soc_chip_info chip_info = {
}; };
static bool chip_info_initialized; static bool chip_info_initialized;
#if (!defined(CONFIG_ACPI))
const struct hwpm_soc_chip_info t234_chip_info = { const struct hwpm_soc_chip_info t234_chip_info = {
.chip_id = 0x23, .chip_id = 0x23,
.chip_id_rev = 0x4, .chip_id_rev = 0x4,
.platform = PLAT_SI, .platform = PLAT_SI,
}; };
#endif
/* This function should be invoked only once before retrieving soc chip info */ /* 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) int tegra_hwpm_init_chip_info(struct tegra_hwpm_os_linux *hwpm_linux)
{ {
struct device *dev = hwpm_linux->dev; struct device *dev = hwpm_linux->dev;
struct tegra_soc_hwpm *hwpm = &hwpm_linux->hwpm;
#if defined(CONFIG_ACPI) #if defined(CONFIG_ACPI)
const struct acpi_device_id *id; const struct acpi_device_id *id;
#endif #endif
@@ -56,19 +53,19 @@ int tegra_hwpm_init_chip_info(struct tegra_hwpm_os_linux *hwpm_linux)
if (chip_info_initialized) { if (chip_info_initialized) {
return 0; return 0;
} }
#if defined(CONFIG_ACPI)
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 defined(CONFIG_ACPI)
/* Get device node info from ACPI table */
id = acpi_match_device(dev->driver->acpi_match_table, dev);
if (id) {
chip_info.chip_id = (id->driver_data >> 8) & 0xff; chip_info.chip_id = (id->driver_data >> 8) & 0xff;
chip_info.chip_id_rev = (id->driver_data >> 4) & 0xf; chip_info.chip_id_rev = (id->driver_data >> 4) & 0xf;
chip_info.platform = (id->driver_data >> 20) & 0xf; chip_info.platform = (id->driver_data >> 20) & 0xf;
goto complete; goto complete;
#else /* !CONFIG_ACPI */ }
#endif
/* Get device node info from device tree */
if (of_machine_is_compatible("nvidia,tegra234")) { if (of_machine_is_compatible("nvidia,tegra234")) {
chip_info.chip_id = t234_chip_info.chip_id; chip_info.chip_id = t234_chip_info.chip_id;
chip_info.chip_id_rev = t234_chip_info.chip_id_rev; 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
#endif /* CONFIG_ACPI */ return -ENODEV;
return -EINVAL;
complete: complete:
chip_info_initialized = true; chip_info_initialized = true;
return 0; return 0;