mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
Bug 4165184 Change-Id: Id5d570cc4e5c3364d696271b1333e47e02e17b9e Signed-off-by: Chris Dragan <kdragan@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2976924 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
137 lines
3.5 KiB
C
137 lines
3.5 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/* SPDX-FileCopyrightText: Copyright (c) 2017-2023, NVIDIA CORPORATION. All rights reserved. */
|
|
|
|
#include "mods_internal.h"
|
|
#include <linux/err.h>
|
|
|
|
#ifdef MODS_ENABLE_BPMP_MRQ_API
|
|
static int tegra_pcie_bpmp_set_ctrl_state(struct mods_smmu_dev *pcie_dev,
|
|
bool enable)
|
|
{
|
|
struct mrq_uphy_response resp;
|
|
struct tegra_bpmp_message msg;
|
|
struct mrq_uphy_request req;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
memset(&resp, 0, sizeof(resp));
|
|
|
|
req.cmd = CMD_UPHY_PCIE_CONTROLLER_STATE;
|
|
req.controller_state.pcie_controller = pcie_dev->cid;
|
|
req.controller_state.enable = enable;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.mrq = MRQ_UPHY;
|
|
msg.tx.data = &req;
|
|
msg.tx.size = sizeof(req);
|
|
msg.rx.data = &resp;
|
|
msg.rx.size = sizeof(resp);
|
|
|
|
return tegra_bpmp_transfer(pcie_dev->bpmp, &msg);
|
|
}
|
|
|
|
static int uphy_bpmp_pcie_controller_state_set(int controller, int enable)
|
|
{
|
|
#define MAX_DEV_NAME_LEN 32
|
|
char dev_name[MAX_DEV_NAME_LEN];
|
|
struct mods_smmu_dev *smmu_pdev = NULL;
|
|
int smmudev_idx, n;
|
|
|
|
memset(dev_name, 0, MAX_DEV_NAME_LEN);
|
|
n = snprintf(dev_name, MAX_DEV_NAME_LEN, "mods_pcie%d", controller);
|
|
if (n < 0 || n >= MAX_DEV_NAME_LEN)
|
|
return -EINVAL;
|
|
smmudev_idx = get_mods_smmu_device_index(dev_name);
|
|
if (smmudev_idx >= 0)
|
|
smmu_pdev = get_mods_smmu_device(smmudev_idx);
|
|
if (!smmu_pdev || smmudev_idx < 0) {
|
|
mods_error_printk("smmu device %s is not found\n", dev_name);
|
|
return -ENODEV;
|
|
}
|
|
smmu_pdev->cid = controller;
|
|
return tegra_pcie_bpmp_set_ctrl_state(smmu_pdev, enable);
|
|
}
|
|
#else
|
|
|
|
static int uphy_bpmp_pcie_controller_state_set(int controller, int enable)
|
|
{
|
|
mods_error_printk("bpmp mrq api is not supported\n");
|
|
return -ENODEV;
|
|
}
|
|
#endif
|
|
|
|
int esc_mods_bpmp_set_pcie_state(
|
|
struct mods_client *client,
|
|
struct MODS_SET_PCIE_STATE *p
|
|
)
|
|
{
|
|
|
|
return uphy_bpmp_pcie_controller_state_set(p->controller, p->enable);
|
|
}
|
|
|
|
#ifdef MODS_ENABLE_BPMP_MRQ_API
|
|
static int tegra_pcie_bpmp_set_pll_state(struct mods_smmu_dev *pcie_dev,
|
|
bool enable)
|
|
{
|
|
struct mrq_uphy_response resp;
|
|
struct tegra_bpmp_message msg;
|
|
struct mrq_uphy_request req;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
memset(&resp, 0, sizeof(resp));
|
|
|
|
if (enable) {
|
|
req.cmd = CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT;
|
|
req.ep_ctrlr_pll_init.ep_controller = pcie_dev->cid;
|
|
} else {
|
|
req.cmd = CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF;
|
|
req.ep_ctrlr_pll_off.ep_controller = pcie_dev->cid;
|
|
}
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.mrq = MRQ_UPHY;
|
|
msg.tx.data = &req;
|
|
msg.tx.size = sizeof(req);
|
|
msg.rx.data = &resp;
|
|
msg.rx.size = sizeof(resp);
|
|
|
|
return tegra_bpmp_transfer(pcie_dev->bpmp, &msg);
|
|
}
|
|
|
|
static int uphy_bpmp_pcie_set_pll_state(int controller, int enable)
|
|
{
|
|
#define MAX_DEV_NAME_LEN 32
|
|
char dev_name[MAX_DEV_NAME_LEN];
|
|
struct mods_smmu_dev *smmu_pdev = NULL;
|
|
int smmudev_idx, n;
|
|
|
|
memset(dev_name, 0, MAX_DEV_NAME_LEN);
|
|
n = snprintf(dev_name, MAX_DEV_NAME_LEN, "mods_pcie%d", controller);
|
|
if (n < 0 || n >= MAX_DEV_NAME_LEN)
|
|
return -EINVAL;
|
|
smmudev_idx = get_mods_smmu_device_index(dev_name);
|
|
if (smmudev_idx >= 0)
|
|
smmu_pdev = get_mods_smmu_device(smmudev_idx);
|
|
if (!smmu_pdev || smmudev_idx < 0) {
|
|
mods_error_printk("smmu device %s is not found\n", dev_name);
|
|
return -ENODEV;
|
|
}
|
|
smmu_pdev->cid = controller;
|
|
return tegra_pcie_bpmp_set_pll_state(smmu_pdev, enable);
|
|
}
|
|
#else
|
|
|
|
static int uphy_bpmp_pcie_set_pll_state(int controller, int enable)
|
|
{
|
|
mods_error_printk("bpmp mrq api is not supported\n");
|
|
return -ENODEV;
|
|
}
|
|
#endif
|
|
|
|
int esc_mods_bpmp_init_pcie_ep_pll(
|
|
struct mods_client *client,
|
|
struct MODS_INIT_PCIE_EP_PLL *p
|
|
)
|
|
{
|
|
return uphy_bpmp_pcie_set_pll_state(p->ep_id, 1);
|
|
}
|