mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
platform: dce: Add suspend resume hooks
Add suspend resume hooks function and handling of sc7 events. Bug 3583331 Bug 3826630 Signed-off-by: Mahesh Kumar <mahkumar@nvidia.com> Change-Id: I920b02ad46a76330febe666fe17e8d328f744b1d Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2834856 Reviewed-by: Arun Swain <arswain@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2824218 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com>
This commit is contained in:
committed by
Laxman Dewangan
parent
31b6d913ab
commit
75bfcf326d
@@ -1,5 +1,5 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
# Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
#
|
#
|
||||||
# Display Controller Engine code.
|
# Display Controller Engine code.
|
||||||
#
|
#
|
||||||
@@ -34,6 +34,7 @@ tegra-dce-$(CONFIG_TEGRA_DCE) += \
|
|||||||
dce-ipc-signal.o \
|
dce-ipc-signal.o \
|
||||||
dce-client-ipc.o \
|
dce-client-ipc.o \
|
||||||
dce-module.o \
|
dce-module.o \
|
||||||
|
dce-pm.o \
|
||||||
dce-util-common.o
|
dce-util-common.o
|
||||||
|
|
||||||
ifeq ($(CONFIG_DEBUG_FS),y)
|
ifeq ($(CONFIG_DEBUG_FS),y)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2019-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -471,6 +471,79 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dce_admin_send_prepare_sc7 - Sends DCE_ADMIN_CMD_PREPARE_SC7 cmd.
|
||||||
|
*
|
||||||
|
* @d - Pointer to tegra_dce struct.
|
||||||
|
* @msg - Pointer to dce_ipc_msg struct.
|
||||||
|
*
|
||||||
|
* Return - 0 if successful
|
||||||
|
*/
|
||||||
|
int dce_admin_send_prepare_sc7(struct tegra_dce *d,
|
||||||
|
struct dce_ipc_message *msg)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
struct dce_admin_ipc_cmd *req_msg;
|
||||||
|
struct dce_admin_ipc_resp *resp_msg;
|
||||||
|
|
||||||
|
if (!msg || !msg->tx.data || !msg->rx.data)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
req_msg = (struct dce_admin_ipc_cmd *)(msg->tx.data);
|
||||||
|
resp_msg = (struct dce_admin_ipc_resp *) (msg->rx.data);
|
||||||
|
|
||||||
|
req_msg->cmd = (uint32_t)DCE_ADMIN_CMD_PREPARE_SC7;
|
||||||
|
|
||||||
|
ret = dce_admin_send_msg(d, msg);
|
||||||
|
if (ret) {
|
||||||
|
dce_err(d, "Error sending prepare sc7 command [%d]", ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dce_admin_send_enter_sc7 - Sends DCE_ADMIN_CMD_ENTER_SC7 cmd.
|
||||||
|
*
|
||||||
|
* @d - Pointer to tegra_dce struct.
|
||||||
|
* @msg - Pointer to dce_ipc_msg struct.
|
||||||
|
*
|
||||||
|
* Return - 0 if successful
|
||||||
|
*/
|
||||||
|
int dce_admin_send_enter_sc7(struct tegra_dce *d,
|
||||||
|
struct dce_ipc_message *msg)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
struct dce_admin_ipc_cmd *req_msg;
|
||||||
|
struct dce_admin_ipc_resp *resp_msg;
|
||||||
|
|
||||||
|
if (!msg || !msg->tx.data || !msg->rx.data)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
req_msg = (struct dce_admin_ipc_cmd *)(msg->tx.data);
|
||||||
|
resp_msg = (struct dce_admin_ipc_resp *) (msg->rx.data);
|
||||||
|
|
||||||
|
req_msg->cmd = (uint32_t)DCE_ADMIN_CMD_ENTER_SC7;
|
||||||
|
|
||||||
|
ret = dce_ipc_send_message(d, DCE_IPC_CHANNEL_TYPE_ADMIN, msg->tx.data, msg->tx.size);
|
||||||
|
if (ret) {
|
||||||
|
dce_err(d, "Error sending enter sc7 command [%d]", ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for SC7 Enter done */
|
||||||
|
ret = dce_wait_interruptible(d, DCE_WAIT_SC7_ENTER);
|
||||||
|
if (ret) {
|
||||||
|
dce_err(d, "SC7 Enter wait was interrupted with err:%d", ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int dce_admin_setup_clients_ipc(struct tegra_dce *d,
|
static int dce_admin_setup_clients_ipc(struct tegra_dce *d,
|
||||||
struct dce_ipc_message *msg)
|
struct dce_ipc_message *msg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2019-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -151,7 +151,7 @@ int dce_handle_boot_complete_received_event(struct tegra_dce *d, void *params)
|
|||||||
*
|
*
|
||||||
* Return : 0 if successful else error code
|
* Return : 0 if successful else error code
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
dce_start_boot_flow(struct tegra_dce *d)
|
dce_start_boot_flow(struct tegra_dce *d)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -241,8 +241,12 @@ void dce_handle_irq_status(struct tegra_dce *d, u32 status)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & DCE_IRQ_SC7_ENTERED)
|
if (status & DCE_IRQ_SC7_ENTERED) {
|
||||||
dce_info(d, "DCE can be safely powered-off now");
|
dce_info(d, "DCE can be safely powered-off now");
|
||||||
|
(void)dce_fsm_post_event(d,
|
||||||
|
EVENT_ID_DCE_SC7_ENTERED_RECEIVED,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (status & DCE_IRQ_LOG_READY) {
|
if (status & DCE_IRQ_LOG_READY) {
|
||||||
dce_info(d, "DCE trace log buffers available");
|
dce_info(d, "DCE trace log buffers available");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -53,11 +53,15 @@ static struct dce_event_process_struct event_process_table[] = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.event = EVENT_ID_DCE_SC7_ENTER_REQUESTED,
|
.event = EVENT_ID_DCE_SC7_ENTER_REQUESTED,
|
||||||
.fsm_event_handle = dce_handle_event_stub,
|
.fsm_event_handle = dce_pm_handle_sc7_enter_requested_event,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.event = EVENT_ID_DCE_SC7_ENTERED_RECEIVED,
|
.event = EVENT_ID_DCE_SC7_ENTERED_RECEIVED,
|
||||||
.fsm_event_handle = dce_handle_event_stub,
|
.fsm_event_handle = dce_pm_handle_sc7_enter_received_event,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.event = EVENT_ID_DCE_SC7_EXIT_RECEIVED,
|
||||||
|
.fsm_event_handle = dce_pm_handle_sc7_exit_received_event,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.event = EVENT_ID_DCE_LOG_REQUESTED,
|
.event = EVENT_ID_DCE_LOG_REQUESTED,
|
||||||
@@ -178,6 +182,11 @@ dce_fsm_set_state(struct tegra_dce *d,
|
|||||||
fsm->requested_ipcs &= ~DCE_BIT(DCE_WAIT_SC7_ENTER);
|
fsm->requested_ipcs &= ~DCE_BIT(DCE_WAIT_SC7_ENTER);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EVENT_ID_DCE_SC7_EXIT_RECEIVED:
|
||||||
|
fsm->c_state = STATE_DCE_FSM_IDLE;
|
||||||
|
fsm->requested_ipcs = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case EVENT_ID_DCE_LOG_REQUESTED:
|
case EVENT_ID_DCE_LOG_REQUESTED:
|
||||||
fsm->c_state = STATE_DCE_LOG_READY_WFI;
|
fsm->c_state = STATE_DCE_LOG_READY_WFI;
|
||||||
fsm->requested_ipcs |= DCE_BIT(DCE_WAIT_LOG);
|
fsm->requested_ipcs |= DCE_BIT(DCE_WAIT_LOG);
|
||||||
@@ -355,11 +364,16 @@ dce_fsm_validate_event(struct tegra_dce *d,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_DCE_SC7_ENTERED:
|
case STATE_DCE_SC7_ENTERED:
|
||||||
//
|
switch (event) {
|
||||||
// STATE_DCE_SC7_ENTERED is short lived state for now
|
case EVENT_ID_DCE_SC7_EXIT_RECEIVED:
|
||||||
// FSM can expect only EVENT_ID_DCE_FSM_START event here
|
ret = 0;
|
||||||
//
|
break;
|
||||||
dce_err(d, "Event received while in STATE_DCE_SC7_ENTERED state");
|
default:
|
||||||
|
dce_err(d, "Invalid event received [%d] state:[%d]\n",
|
||||||
|
event, curr_state);
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dce_err(d, "Invalid state:[%d] event received [%d]\n", curr_state,
|
dce_err(d, "Invalid state:[%d] event received [%d]\n", curr_state,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2023, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2019-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -59,6 +59,19 @@ static inline struct tegra_dce *dce_get_pdata_dce(struct platform_device *pdev)
|
|||||||
return (&((struct dce_device *)dev_get_drvdata(&pdev->dev))->d);
|
return (&((struct dce_device *)dev_get_drvdata(&pdev->dev))->d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dce_get_tegra_dce_from_dev - inline function to get the tegra_dce pointer
|
||||||
|
* from devicve struct.
|
||||||
|
*
|
||||||
|
* @pdev : Pointer to the device data structure.
|
||||||
|
*
|
||||||
|
* Return : Pointer pointing to tegra_dce data structure.
|
||||||
|
*/
|
||||||
|
static inline struct tegra_dce *dce_get_tegra_dce_from_dev(struct device *dev)
|
||||||
|
{
|
||||||
|
return (&((struct dce_device *)dev_get_drvdata(dev))->d);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dce_init_dev_data - Function to initialize the dce device data structure.
|
* dce_init_dev_data - Function to initialize the dce device data structure.
|
||||||
*
|
*
|
||||||
@@ -273,11 +286,35 @@ static int tegra_dce_remove(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int dce_pm_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct tegra_dce *d = dce_get_tegra_dce_from_dev(dev);
|
||||||
|
|
||||||
|
return dce_pm_enter_sc7(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dce_pm_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct tegra_dce *d = dce_get_tegra_dce_from_dev(dev);
|
||||||
|
|
||||||
|
return dce_pm_exit_sc7(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct dev_pm_ops dce_pm_ops = {
|
||||||
|
.suspend = dce_pm_suspend,
|
||||||
|
.resume = dce_pm_resume,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct platform_driver tegra_dce_driver = {
|
static struct platform_driver tegra_dce_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "tegra-dce",
|
.name = "tegra-dce",
|
||||||
.of_match_table =
|
.of_match_table =
|
||||||
of_match_ptr(tegra_dce_of_match),
|
of_match_ptr(tegra_dce_of_match),
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.pm = &dce_pm_ops,
|
||||||
|
#endif
|
||||||
},
|
},
|
||||||
.probe = tegra_dce_probe,
|
.probe = tegra_dce_probe,
|
||||||
.remove = tegra_dce_remove,
|
.remove = tegra_dce_remove,
|
||||||
|
|||||||
175
drivers/platform/tegra/dce/dce-pm.c
Normal file
175
drivers/platform/tegra/dce/dce-pm.c
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dce.h>
|
||||||
|
|
||||||
|
#define CCPLEX_HSP_IE 1U /* TODO : Have an api to read from platform data */
|
||||||
|
|
||||||
|
static void dce_pm_save_state(struct tegra_dce *d)
|
||||||
|
{
|
||||||
|
d->sc7_state.hsp_ie = dce_hsp_ie_read(d, CCPLEX_HSP_IE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dce_pm_restore_state(struct tegra_dce *d)
|
||||||
|
{
|
||||||
|
uint32_t val = d->sc7_state.hsp_ie;
|
||||||
|
|
||||||
|
dce_hsp_ie_write(d, val, CCPLEX_HSP_IE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dce_resume_work_fn : execute resume and bootstrap flow
|
||||||
|
*
|
||||||
|
* @d : Pointer to tegra_dce struct.
|
||||||
|
*
|
||||||
|
* Return : void
|
||||||
|
*/
|
||||||
|
void dce_resume_work_fn(struct tegra_dce *d)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (d == NULL) {
|
||||||
|
dce_err(d, "tegra_dce struct is NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dce_fsm_post_event(d, EVENT_ID_DCE_BOOT_COMPLETE_REQUESTED, NULL);
|
||||||
|
if (ret) {
|
||||||
|
dce_err(d, "Error while posting DCE_BOOT_COMPLETE_REQUESTED event");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dce_start_boot_flow(d);
|
||||||
|
if (ret) {
|
||||||
|
dce_err(d, "DCE bootstrapping failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dce_handle_sc7_enter_requested_event - callback handler function for event
|
||||||
|
* EVENT_ID_DCE_SC7_ENTER_REQUESTED
|
||||||
|
*
|
||||||
|
* @d : Pointer to tegra_dce struct.
|
||||||
|
* @params : callback params
|
||||||
|
*
|
||||||
|
* Return : 0 if successful else error code
|
||||||
|
*/
|
||||||
|
int dce_pm_handle_sc7_enter_requested_event(struct tegra_dce *d, void *params)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
struct dce_ipc_message *msg = NULL;
|
||||||
|
|
||||||
|
msg = dce_admin_allocate_message(d);
|
||||||
|
if (!msg) {
|
||||||
|
dce_err(d, "IPC msg allocation failed");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dce_admin_send_enter_sc7(d, msg);
|
||||||
|
if (ret) {
|
||||||
|
dce_err(d, "Enter SC7 failed [%d]", ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
dce_admin_free_message(d, msg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dce_handle_sc7_enter_received_event - callback handler function for event
|
||||||
|
* EVENT_ID_DCE_SC7_ENTER_RECEIVED
|
||||||
|
*
|
||||||
|
* @d : Pointer to tegra_dce struct.
|
||||||
|
* @params : callback params
|
||||||
|
*
|
||||||
|
* Return : 0 if successful else error code
|
||||||
|
*/
|
||||||
|
int dce_pm_handle_sc7_enter_received_event(struct tegra_dce *d, void *params)
|
||||||
|
{
|
||||||
|
dce_wakeup_interruptible(d, DCE_WAIT_SC7_ENTER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dce_handle_sc7_exit_received_event - callback handler function for event
|
||||||
|
* EVENT_ID_DCE_SC7_EXIT_RECEIVED
|
||||||
|
*
|
||||||
|
* @d : Pointer to tegra_dce struct.
|
||||||
|
* @params : callback params
|
||||||
|
*
|
||||||
|
* Return : 0 if successful else error code
|
||||||
|
*/
|
||||||
|
int dce_pm_handle_sc7_exit_received_event(struct tegra_dce *d, void *params)
|
||||||
|
{
|
||||||
|
dce_schedule_work(&d->dce_resume_work);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dce_pm_enter_sc7(struct tegra_dce *d)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
struct dce_ipc_message *msg = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If Bootstrap is not yet done. Nothing to do during SC7 Enter
|
||||||
|
* Return success immediately.
|
||||||
|
*/
|
||||||
|
if (!dce_is_bootstrap_done(d)) {
|
||||||
|
dce_debug(d, "Bootstrap not done, Succeed SC7 enter\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = dce_admin_allocate_message(d);
|
||||||
|
if (!msg) {
|
||||||
|
dce_err(d, "IPC msg allocation failed");
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dce_pm_save_state(d);
|
||||||
|
|
||||||
|
ret = dce_admin_send_prepare_sc7(d, msg);
|
||||||
|
if (ret) {
|
||||||
|
dce_err(d, "Prepare SC7 failed [%d]", ret);
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dce_fsm_post_event(d, EVENT_ID_DCE_SC7_ENTER_REQUESTED, NULL);
|
||||||
|
if (ret) {
|
||||||
|
dce_err(d, "Error while posting SC7_ENTER event [%d]", ret);
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
dce_admin_free_message(d, msg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dce_pm_exit_sc7(struct tegra_dce *d)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
dce_pm_restore_state(d);
|
||||||
|
|
||||||
|
ret = dce_fsm_post_event(d, EVENT_ID_DCE_SC7_EXIT_RECEIVED, NULL);
|
||||||
|
if (ret) {
|
||||||
|
dce_err(d, "Error while posting SC7_EXIT event [%d]", ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
* Copyright (c) 2019-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -85,7 +85,13 @@ int dce_work_cond_sw_resource_init(struct tegra_dce *d)
|
|||||||
|
|
||||||
ret = dce_init_work(d, &d->dce_bootstrap_work, dce_bootstrap_work_fn);
|
ret = dce_init_work(d, &d->dce_bootstrap_work, dce_bootstrap_work_fn);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dce_err(d, "fsm_start work init failed");
|
dce_err(d, "Bootstrap work init failed");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dce_init_work(d, &d->dce_resume_work, dce_resume_work_fn);
|
||||||
|
if (ret) {
|
||||||
|
dce_err(d, "resume work init failed");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -32,6 +32,7 @@ enum dce_fsm_event_id_type {
|
|||||||
EVENT_ID_DCE_ADMIN_IPC_MSG_RECEIVED,
|
EVENT_ID_DCE_ADMIN_IPC_MSG_RECEIVED,
|
||||||
EVENT_ID_DCE_SC7_ENTER_REQUESTED,
|
EVENT_ID_DCE_SC7_ENTER_REQUESTED,
|
||||||
EVENT_ID_DCE_SC7_ENTERED_RECEIVED,
|
EVENT_ID_DCE_SC7_ENTERED_RECEIVED,
|
||||||
|
EVENT_ID_DCE_SC7_EXIT_RECEIVED,
|
||||||
EVENT_ID_DCE_LOG_REQUESTED,
|
EVENT_ID_DCE_LOG_REQUESTED,
|
||||||
EVENT_ID_DCE_LOG_READY_RECEIVED,
|
EVENT_ID_DCE_LOG_READY_RECEIVED,
|
||||||
EVENT_ID_DCE_ABORT_RECEIVED,
|
EVENT_ID_DCE_ABORT_RECEIVED,
|
||||||
|
|||||||
30
drivers/platform/tegra/dce/include/dce-pm.h
Normal file
30
drivers/platform/tegra/dce/include/dce-pm.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DCE_PM_H
|
||||||
|
#define DCE_PM_H
|
||||||
|
|
||||||
|
#include <dce.h>
|
||||||
|
|
||||||
|
struct dce_sc7_state {
|
||||||
|
uint32_t hsp_ie;
|
||||||
|
};
|
||||||
|
|
||||||
|
int dce_pm_enter_sc7(struct tegra_dce *d);
|
||||||
|
int dce_pm_exit_sc7(struct tegra_dce *d);
|
||||||
|
void dce_resume_work_fn(struct tegra_dce *d);
|
||||||
|
int dce_pm_handle_sc7_enter_requested_event(struct tegra_dce *d, void *params);
|
||||||
|
int dce_pm_handle_sc7_enter_received_event(struct tegra_dce *d, void *params);
|
||||||
|
int dce_pm_handle_sc7_exit_received_event(struct tegra_dce *d, void *params);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2019-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <dce-thread.h>
|
#include <dce-thread.h>
|
||||||
#include <dce-worker.h>
|
#include <dce-worker.h>
|
||||||
#include <dce-fsm.h>
|
#include <dce-fsm.h>
|
||||||
|
#include <dce-pm.h>
|
||||||
#include <dce-mailbox.h>
|
#include <dce-mailbox.h>
|
||||||
#include <dce-client-ipc-internal.h>
|
#include <dce-client-ipc-internal.h>
|
||||||
#include <dce-workqueue.h>
|
#include <dce-workqueue.h>
|
||||||
@@ -148,6 +149,14 @@ struct tegra_dce {
|
|||||||
* dce_bootstrap_work : dce work to be executed to start FSM flow
|
* dce_bootstrap_work : dce work to be executed to start FSM flow
|
||||||
*/
|
*/
|
||||||
struct dce_work_struct dce_bootstrap_work;
|
struct dce_work_struct dce_bootstrap_work;
|
||||||
|
/**
|
||||||
|
* dce_resume_work : dce work to executed dce resume flow
|
||||||
|
*/
|
||||||
|
struct dce_work_struct dce_resume_work;
|
||||||
|
/**
|
||||||
|
* dce_sc7_state : structure to save/restore state during sc7 enter/exit
|
||||||
|
*/
|
||||||
|
struct dce_sc7_state sc7_state;
|
||||||
/**
|
/**
|
||||||
* dce_wait_info - Data structure to manage wait for different event types
|
* dce_wait_info - Data structure to manage wait for different event types
|
||||||
*/
|
*/
|
||||||
@@ -377,6 +386,7 @@ const char *dce_get_fw_name(struct tegra_dce *d);
|
|||||||
int dce_driver_init(struct tegra_dce *d);
|
int dce_driver_init(struct tegra_dce *d);
|
||||||
void dce_driver_deinit(struct tegra_dce *d);
|
void dce_driver_deinit(struct tegra_dce *d);
|
||||||
|
|
||||||
|
int dce_start_boot_flow(struct tegra_dce *d);
|
||||||
void dce_bootstrap_work_fn(struct tegra_dce *d);
|
void dce_bootstrap_work_fn(struct tegra_dce *d);
|
||||||
int dce_start_bootstrap_flow(struct tegra_dce *d);
|
int dce_start_bootstrap_flow(struct tegra_dce *d);
|
||||||
int dce_boot_interface_init(struct tegra_dce *d);
|
int dce_boot_interface_init(struct tegra_dce *d);
|
||||||
@@ -402,6 +412,10 @@ int dce_admin_send_cmd_echo(struct tegra_dce *d,
|
|||||||
struct dce_ipc_message *msg);
|
struct dce_ipc_message *msg);
|
||||||
int dce_admin_send_cmd_ext_test(struct tegra_dce *d,
|
int dce_admin_send_cmd_ext_test(struct tegra_dce *d,
|
||||||
struct dce_ipc_message *msg);
|
struct dce_ipc_message *msg);
|
||||||
|
int dce_admin_send_prepare_sc7(struct tegra_dce *d,
|
||||||
|
struct dce_ipc_message *msg);
|
||||||
|
int dce_admin_send_enter_sc7(struct tegra_dce *d,
|
||||||
|
struct dce_ipc_message *msg);
|
||||||
int dce_admin_handle_ipc_requested_event(struct tegra_dce *d, void *params);
|
int dce_admin_handle_ipc_requested_event(struct tegra_dce *d, void *params);
|
||||||
int dce_admin_handle_ipc_received_event(struct tegra_dce *d, void *params);
|
int dce_admin_handle_ipc_received_event(struct tegra_dce *d, void *params);
|
||||||
int dce_admin_ipc_wait(struct tegra_dce *d, u32 w_type);
|
int dce_admin_ipc_wait(struct tegra_dce *d, u32 w_type);
|
||||||
|
|||||||
Reference in New Issue
Block a user