Update for Bpmp MRQ Call

Update Bpmp MRQ Call Api to use bpmp dtb node in mods dtb devices
Used by MODS PCIE Test for bpmp uphy api
JIRA: TM-586

Change-Id: I67b34979151fa57fd1707b2393237828f2c23cef
Signed-off-by: Carl Dong <carld@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2577098
Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com>
Reviewed-by: Danny Li <dali@nvidia.com>
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
dongqiang
2021-08-16 17:09:44 +08:00
committed by Laxman Dewangan
parent 62a67b00a8
commit df0985a449
3 changed files with 120 additions and 46 deletions

View File

@@ -38,6 +38,11 @@
#include <linux/set_memory.h>
#endif
#if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE
#define MODS_ENABLE_BPMP_MRQ_API
#include <soc/tegra/bpmp.h>
#endif
#ifndef true
#define true 1
#define false 0
@@ -205,6 +210,10 @@ struct SYS_MAP_MEMORY {
struct mods_smmu_dev {
struct device *dev;
#ifdef MODS_ENABLE_BPMP_MRQ_API
struct tegra_bpmp *bpmp; //bpmp node for mrq
int cid; //pcie ctrl id
#endif
char dev_name[MAX_DT_SIZE];
};

View File

@@ -1,7 +1,7 @@
/*
* mods_dma_mapping.c - This file is part of NVIDIA MODS kernel driver.
*
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
*
* NVIDIA MODS kernel driver is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License,
@@ -92,6 +92,10 @@ static int mods_smmu_driver_probe(struct platform_device *pdev)
strncpy(mods_smmu_devs[dev_idx].dev_name,
dev_name,
MAX_DT_SIZE - 1);
#ifdef MODS_ENABLE_BPMP_MRQ_API
mods_smmu_devs[dev_idx].bpmp = tegra_bpmp_get(dev);
#endif
LOG_EXT();
return err;

View File

@@ -25,8 +25,7 @@
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/tegra_prod.h>
#include <soc/tegra/bpmp_abi.h>
#include <soc/tegra/tegra_bpmp.h>
#define MAX_REG_INFO_ENTRY 400
#define MAX_IO_MAP_ENTRY 200
@@ -638,68 +637,130 @@ int esc_mods_tegra_prod_set_prod_exact(
return ret;
}
static int bpmp_send_uphy_message_atomic(
struct mrq_uphy_request *req, int size,
struct mrq_uphy_response *reply,
int reply_size
)
#ifdef MODS_ENABLE_BPMP_MRQ_API
static int tegra_pcie_bpmp_set_ctrl_state(struct mods_smmu_dev *pcie_dev,
bool enable)
{
unsigned long flags;
int err;
struct mrq_uphy_response resp;
struct tegra_bpmp_message msg;
struct mrq_uphy_request req;
local_irq_save(flags);
err = tegra_bpmp_send_receive_atomic(MRQ_UPHY, req, size, reply,
reply_size);
local_irq_restore(flags);
memset(&req, 0, sizeof(req));
memset(&resp, 0, sizeof(resp));
return err;
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 bpmp_send_uphy_message(
struct mrq_uphy_request *req, int size,
struct mrq_uphy_response *reply,
int reply_size
)
int uphy_bpmp_pcie_controller_state_set(int controller, int enable)
{
int err;
#define MAX_DEV_NAME_LEN 32
char dev_name[MAX_DEV_NAME_LEN];
struct mods_smmu_dev *smmu_pdev = NULL;
int smmudev_idx;
err = tegra_bpmp_send_receive(MRQ_UPHY, req, size, reply, reply_size);
if (err != -EAGAIN)
return err;
/*
* in case the mail systems worker threads haven't been started yet,
* use the atomic send/receive interface. This happens because the
* clocks are initialized before the IPC mechanism.
*/
return bpmp_send_uphy_message_atomic(req, size, reply, reply_size);
memset(dev_name, 0, MAX_DEV_NAME_LEN);
snprintf(dev_name, MAX_DEV_NAME_LEN, "mods_pcie%d", controller);
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
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
)
{
struct mrq_uphy_request req;
struct mrq_uphy_response resp;
req.cmd = CMD_UPHY_PCIE_CONTROLLER_STATE;
req.controller_state.pcie_controller = p->controller;
req.controller_state.enable = p->enable;
return bpmp_send_uphy_message(&req, sizeof(req), &resp, sizeof(resp));
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);
}
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;
memset(dev_name, 0, MAX_DEV_NAME_LEN);
snprintf(dev_name, MAX_DEV_NAME_LEN, "mods_pcie%d", controller);
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
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
)
{
struct mrq_uphy_request req;
struct mrq_uphy_response resp;
req.cmd = CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT;
req.ep_ctrlr_pll_init.ep_controller = p->ep_id;
return bpmp_send_uphy_message(&req, sizeof(req), &resp, sizeof(resp));
return uphy_bpmp_pcie_set_pll_state(p->ep_id, 1);
}