mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
misc: mods: cleanup tegra prod module
Bug 4051795 Change-Id: Ia545cdb456bb6876aa1f48b4efcd111387999167 Signed-off-by: Kuan Luo <kluo@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2891512 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
48e336f384
commit
ec7162fc4d
@@ -29,11 +29,7 @@ mods-$(CONFIG_PCI) += mods_pci.o
|
||||
mods-$(CONFIG_ARCH_TEGRA_19x_SOC) += mods_ras.o
|
||||
mods-$(CONFIG_ARCH_TEGRA) += mods_smmu_drv.o
|
||||
mods-$(CONFIG_TEGRA_DC) += mods_tegradc.o
|
||||
mods-$(CONFIG_ARCH_TEGRA) += mods_tegraprod.o
|
||||
mods-$(CONFIG_TRUSTY) += mods_tz.o
|
||||
|
||||
mods-objs := mods.dtb.o
|
||||
|
||||
ifneq ($(CONFIG_TEGRA_OOT_MODULE),m)
|
||||
ccflags-y += -DMODS_HAS_PROD
|
||||
mods-$(CONFIG_ARCH_TEGRA) += mods_tegraprod.o
|
||||
endif
|
||||
|
||||
@@ -593,15 +593,12 @@ int esc_mods_register_irq_4(struct mods_client *client,
|
||||
int esc_mods_query_irq_3(struct mods_client *client,
|
||||
struct MODS_QUERY_IRQ_3 *p);
|
||||
|
||||
#ifdef MODS_HAS_PROD
|
||||
#ifdef MODS_HAS_TEGRA
|
||||
/* bpmp uphy */
|
||||
int esc_mods_bpmp_set_pcie_state(struct mods_client *client,
|
||||
struct MODS_SET_PCIE_STATE *p);
|
||||
int esc_mods_bpmp_init_pcie_ep_pll(struct mods_client *client,
|
||||
struct MODS_INIT_PCIE_EP_PLL *p);
|
||||
#endif
|
||||
|
||||
#ifdef MODS_HAS_TEGRA
|
||||
|
||||
/* clock */
|
||||
int esc_mods_get_clock_handle(struct mods_client *client,
|
||||
@@ -688,23 +685,6 @@ int esc_mods_adsp_run_app(struct mods_client *client,
|
||||
struct MODS_ADSP_RUN_APP_INFO *p);
|
||||
#endif
|
||||
|
||||
#ifdef MODS_HAS_PROD
|
||||
/* prod */
|
||||
int mods_tegra_prod_init(const struct miscdevice *misc_dev);
|
||||
int esc_mods_tegra_prod_iterate_dt(struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_ITERATOR *iterator);
|
||||
int esc_mods_tegra_prod_is_supported(struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_IS_SUPPORTED *tuple);
|
||||
int esc_mods_tegra_prod_set_prod_all(struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_SET_TUPLE *tuple);
|
||||
int esc_mods_tegra_prod_set_prod_boot(struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_SET_TUPLE *tuple);
|
||||
int esc_mods_tegra_prod_set_prod_by_name(struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_SET_TUPLE *tuple);
|
||||
int esc_mods_tegra_prod_set_prod_exact(struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_SET_TUPLE *tuple);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TRUSTY
|
||||
/* trustzone app call */
|
||||
int esc_mods_send_trustzone_msg(struct mods_client *client,
|
||||
|
||||
@@ -558,11 +558,6 @@ static int __init mods_init_module(void)
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
#if defined(MODS_HAS_PROD)
|
||||
/* tegra prod */
|
||||
mods_tegra_prod_init(&mods_dev);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DMA_ENGINE)
|
||||
rc = mods_init_dma();
|
||||
if (rc < 0)
|
||||
@@ -2552,7 +2547,7 @@ static long mods_krnl_ioctl(struct file *fp,
|
||||
MODS_GET_RESET_HANDLE);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MODS_HAS_PROD)
|
||||
#if defined(MODS_HAS_TEGRA)
|
||||
case MODS_ESC_BPMP_SET_PCIE_STATE:
|
||||
MODS_IOCTL(MODS_ESC_BPMP_SET_PCIE_STATE,
|
||||
esc_mods_bpmp_set_pcie_state,
|
||||
@@ -2564,8 +2559,7 @@ static long mods_krnl_ioctl(struct file *fp,
|
||||
esc_mods_bpmp_init_pcie_ep_pll,
|
||||
MODS_INIT_PCIE_EP_PLL);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MODS_HAS_TEGRA)
|
||||
|
||||
case MODS_ESC_DMA_ALLOC_COHERENT:
|
||||
MODS_IOCTL(MODS_ESC_DMA_ALLOC_COHERENT,
|
||||
esc_mods_dma_alloc_coherent,
|
||||
@@ -2716,44 +2710,6 @@ static long mods_krnl_ioctl(struct file *fp,
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(MODS_HAS_PROD)
|
||||
case MODS_ESC_TEGRA_PROD_IS_SUPPORTED:
|
||||
MODS_IOCTL(MODS_ESC_TEGRA_PROD_IS_SUPPORTED,
|
||||
esc_mods_tegra_prod_is_supported,
|
||||
MODS_TEGRA_PROD_IS_SUPPORTED);
|
||||
break;
|
||||
|
||||
case MODS_ESC_TEGRA_PROD_SET_PROD_ALL:
|
||||
MODS_IOCTL_NORETVAL(MODS_ESC_TEGRA_PROD_SET_PROD_ALL,
|
||||
esc_mods_tegra_prod_set_prod_all,
|
||||
MODS_TEGRA_PROD_SET_TUPLE);
|
||||
break;
|
||||
|
||||
case MODS_ESC_TEGRA_PROD_SET_PROD_BOOT:
|
||||
MODS_IOCTL_NORETVAL(MODS_ESC_TEGRA_PROD_SET_PROD_BOOT,
|
||||
esc_mods_tegra_prod_set_prod_boot,
|
||||
MODS_TEGRA_PROD_SET_TUPLE);
|
||||
break;
|
||||
|
||||
case MODS_ESC_TEGRA_PROD_SET_PROD_BY_NAME:
|
||||
MODS_IOCTL_NORETVAL(MODS_ESC_TEGRA_PROD_SET_PROD_BY_NAME,
|
||||
esc_mods_tegra_prod_set_prod_by_name,
|
||||
MODS_TEGRA_PROD_SET_TUPLE);
|
||||
break;
|
||||
|
||||
case MODS_ESC_TEGRA_PROD_SET_PROD_EXACT:
|
||||
MODS_IOCTL_NORETVAL(MODS_ESC_TEGRA_PROD_SET_PROD_EXACT,
|
||||
esc_mods_tegra_prod_set_prod_exact,
|
||||
MODS_TEGRA_PROD_SET_TUPLE);
|
||||
break;
|
||||
|
||||
case MODS_ESC_TEGRA_PROD_ITERATE_DT:
|
||||
MODS_IOCTL(MODS_ESC_TEGRA_PROD_ITERATE_DT,
|
||||
esc_mods_tegra_prod_iterate_dt,
|
||||
MODS_TEGRA_PROD_ITERATOR);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(MODS_HAS_TEGRA)
|
||||
|
||||
#ifdef CONFIG_TRUSTY
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* This file is part of NVIDIA MODS kernel driver.
|
||||
*
|
||||
* Copyright (c) 2017-2022, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2017-2023, 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,
|
||||
@@ -20,623 +20,6 @@
|
||||
|
||||
#include "mods_internal.h"
|
||||
#include <linux/err.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/tegra_prod.h>
|
||||
|
||||
|
||||
#define MAX_REG_INFO_ENTRY 400
|
||||
#define MAX_IO_MAP_ENTRY 200
|
||||
|
||||
static struct device *mods_tegra_prod_dev;
|
||||
|
||||
/**
|
||||
* mods_tegra_prod_init - Initialize tegra prod module.
|
||||
* @misc_dev: pointer to mods device
|
||||
*
|
||||
* Returns 0 on success, others for error.
|
||||
*/
|
||||
int mods_tegra_prod_init(const struct miscdevice *misc_dev)
|
||||
{
|
||||
if (!misc_dev) {
|
||||
mods_error_printk("mods device pointer is NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mods_tegra_prod_dev = misc_dev->this_device;
|
||||
if (!mods_tegra_prod_dev) {
|
||||
mods_error_printk("this_device in mods device is NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* esc_mods_tegra_prod_iterate_dt - Find device_node by device name.
|
||||
* @MODS_TEGRA_PROD_ITERATOR: Input information, only the following
|
||||
* members are used.
|
||||
* +device_handle: Last node pointer for current iteration
|
||||
* +name: Current node name
|
||||
* +next_name: Next node name
|
||||
* +index: Index of the device nodes shared the same name
|
||||
* (NOTE: index starts from 0)
|
||||
* +is_leaf: Is the node with current name a leaf node
|
||||
* +next_device_handle: Result node pointer for next iteration
|
||||
* Returns 0 on success, others for error or no matching node found.
|
||||
*/
|
||||
int esc_mods_tegra_prod_iterate_dt(
|
||||
struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_ITERATOR *iterator
|
||||
)
|
||||
{
|
||||
struct device_node *dev_node;
|
||||
struct device_node *child_node = NULL;
|
||||
struct resource res;
|
||||
int ret_resource = -1;
|
||||
int i;
|
||||
|
||||
dev_node = (struct device_node *)iterator->device_handle;
|
||||
|
||||
if (!iterator->name[0]) {
|
||||
cl_error("node name is missing for tegra prod value\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!iterator->next_name[0] && !iterator->is_leaf) {
|
||||
cl_error("inner node with empty next_name\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Need to search several times since some nodes may share same name */
|
||||
for (i = 0; i <= iterator->index; ++i) {
|
||||
/* Search from Left to Right in DT */
|
||||
dev_node = of_find_node_by_name(dev_node, iterator->name);
|
||||
if (!dev_node) {
|
||||
cl_error("node %s not found in device tree\n",
|
||||
iterator->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search from Top to Bottom in DT
|
||||
* Check: does this node need to be filtered out
|
||||
*/
|
||||
if (iterator->is_leaf) {
|
||||
/* Leaf node : search for "prod-settings" node */
|
||||
child_node = of_get_child_by_name(dev_node,
|
||||
"prod-settings");
|
||||
ret_resource = of_address_to_resource(
|
||||
dev_node, 0, &res);
|
||||
} else {
|
||||
/* Inner node : search for next device node */
|
||||
child_node = of_get_child_by_name(dev_node,
|
||||
iterator->next_name);
|
||||
ret_resource = -1;
|
||||
}
|
||||
if (!child_node && ret_resource < 0)
|
||||
--i; /* Not a valid device node */
|
||||
}
|
||||
|
||||
/* Return next_device_handler to ioctl caller */
|
||||
iterator->next_device_handle = (__u64)dev_node;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* mods_read_reg_info - Read register information (address and size)
|
||||
* @dev_node: Device node pointer
|
||||
* @reg_info: Register information array
|
||||
* @count_reg_cells: (OUT) Pointer to count of cells in "reg"
|
||||
* @count_addrsize_pair: (OUT) Pointer to count of each pair in "reg"
|
||||
* @count_address_cells: (OUT) Pointer to count of "address" cell in "reg"
|
||||
* @count_size_cells: (OUT) Pointer to count of "size" cell in "reg"
|
||||
*
|
||||
* Return Value :
|
||||
* 0 - OK
|
||||
* Others - ERROR
|
||||
*
|
||||
*/
|
||||
static int mods_read_reg_info(struct mods_client *client,
|
||||
const struct device_node *dev_node,
|
||||
__u32 *reg_info,
|
||||
__u32 *count_reg_cells,
|
||||
__u32 *count_addrsize_pair,
|
||||
__u32 *count_address_cells,
|
||||
__u32 *count_size_cells)
|
||||
{
|
||||
struct device_node *parent_node;
|
||||
int ret;
|
||||
|
||||
/* Get parent node to read the format of "reg" property */
|
||||
parent_node = dev_node->parent;
|
||||
ret = of_property_read_u32(parent_node, "#address-cells",
|
||||
count_address_cells);
|
||||
if (ret < 0) {
|
||||
cl_error("read #address-cells failed\n");
|
||||
return ret;
|
||||
|
||||
} else if (*count_address_cells == 0) {
|
||||
cl_error("#address-cells cannot be 0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(parent_node, "#size-cells",
|
||||
count_size_cells);
|
||||
if (ret < 0) {
|
||||
cl_error("read #size-cells failed\n");
|
||||
return ret;
|
||||
|
||||
} else if (*count_size_cells == 0) {
|
||||
cl_error("#size-cells cannot be 0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
*count_addrsize_pair = *count_address_cells + *count_size_cells;
|
||||
|
||||
/* Read count of cells in "reg" property */
|
||||
ret = of_property_count_u32_elems(dev_node, "reg");
|
||||
if (ret < 0) {
|
||||
cl_error(
|
||||
"unable to get count of cells in \"reg\" of node %s\n",
|
||||
dev_node->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*count_reg_cells = (__u32)ret;
|
||||
if (*count_reg_cells == 0) {
|
||||
cl_error("no \"reg\" info is available\n");
|
||||
return -EINVAL;
|
||||
|
||||
} else if (*count_reg_cells % *count_addrsize_pair != 0) {
|
||||
/*
|
||||
* "reg" property may have more than 1 pairs of address
|
||||
* and size. The length of each pair is represented by
|
||||
* "count_addrsize_pair"; the total length of "reg"
|
||||
* property is represented by "count_reg_cells". If
|
||||
* "count_reg_cells" is not an integral multiple of
|
||||
* "count_addrsize_pair", the read "reg" information is
|
||||
* incomplete or incorrect.
|
||||
*/
|
||||
cl_error("\"reg\" property has invalid length : %d\n",
|
||||
*count_reg_cells);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Read register information from "reg" property */
|
||||
ret = of_property_read_u32_array(dev_node, "reg", reg_info,
|
||||
(size_t)(*count_reg_cells));
|
||||
if (ret < 0) {
|
||||
cl_error("Unable to read \"reg\" property of node %s\n",
|
||||
dev_node->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* mods_batch_iounmap - Unmap all virtual memory mapped by IO address.
|
||||
* @io_base: IO address array
|
||||
* @count_io_base: Count of IO addresses are mapped
|
||||
*
|
||||
*/
|
||||
static void mods_batch_iounmap(struct mods_client *client,
|
||||
void __iomem **io_base,
|
||||
__u32 count_io_base)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!io_base) {
|
||||
cl_error("IO base address array is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count_io_base; ++i)
|
||||
iounmap(io_base[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* mods_batch_iomap - Get all segments of IO address from a device node,
|
||||
* and create a virtual memory mapping.
|
||||
* @dev_node: Device node pointer
|
||||
* @io_base: (OUT) IO address array
|
||||
* @count_io_base: (OUT) Pointer to the count of IO addresses are mapped
|
||||
*
|
||||
* Return Value :
|
||||
* 0 - OK
|
||||
* Others - ERROR (NOTE: partially mapped IO memory will be unmapped on error)
|
||||
*
|
||||
*/
|
||||
static int mods_batch_iomap(struct mods_client *client,
|
||||
const struct device_node *dev_node,
|
||||
void __iomem **io_base,
|
||||
__u32 *count_io_base)
|
||||
{
|
||||
__u32 reg_info[MAX_REG_INFO_ENTRY];
|
||||
__u32 count_reg_cells = 0;
|
||||
__u32 count_addrsize_pair, count_address_cells, count_size_cells;
|
||||
__u64 io_addr_base, io_addr_length;
|
||||
void __iomem *io_addr_mapped;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Check arguments */
|
||||
if (!dev_node) {
|
||||
cl_error("controller device handle is NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!io_base) {
|
||||
cl_error("IO base address array is NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!count_io_base) {
|
||||
cl_error("count of IO base address array is NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get registers information */
|
||||
ret = mods_read_reg_info(client,
|
||||
dev_node,
|
||||
reg_info,
|
||||
&count_reg_cells,
|
||||
&count_addrsize_pair,
|
||||
&count_address_cells,
|
||||
&count_size_cells);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* IO mapping - using 64-bit physical address */
|
||||
*count_io_base = 0;
|
||||
for (i = 0; i < count_reg_cells;
|
||||
i += count_addrsize_pair, *count_io_base += 1) {
|
||||
|
||||
/* Compute IO physical address */
|
||||
/* Lower 32-bit IO physical address in DTB */
|
||||
io_addr_base = reg_info[i + count_address_cells - 1];
|
||||
if (count_address_cells > 1) {
|
||||
/* Higher 32-bit IO physical address in DTB */
|
||||
io_addr_base += ((__u64)reg_info
|
||||
[i + count_address_cells - 2]) << 32;
|
||||
}
|
||||
|
||||
/* Compute IO address space length */
|
||||
/* Lower 32-bit IO address space length in DTB */
|
||||
io_addr_length = reg_info[i + count_addrsize_pair - 1];
|
||||
if (count_size_cells > 1) {
|
||||
/* Higher 32-bit IO address space length in DTB */
|
||||
io_addr_length += ((__u64)reg_info
|
||||
[i + count_addrsize_pair - 2]) << 32;
|
||||
}
|
||||
|
||||
/* Map physical address to virtual address space */
|
||||
io_addr_mapped = ioremap((resource_size_t)io_addr_base,
|
||||
(resource_size_t)io_addr_length);
|
||||
if (io_addr_mapped == NULL) {
|
||||
cl_error(
|
||||
"Unable to map io address 0x%llx, length 0x%llx\n",
|
||||
io_addr_base,
|
||||
io_addr_length);
|
||||
/* Clean :
|
||||
* Unmap the IO memory that have already been mapped
|
||||
*/
|
||||
mods_batch_iounmap(client, io_base, *count_io_base);
|
||||
return -ENXIO;
|
||||
}
|
||||
io_base[*count_io_base] = io_addr_mapped;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* mods_tegra_get_prod_list - Get tegra_prod list by valid device node.
|
||||
* @dev_node: Device node.
|
||||
*
|
||||
* Returns non-NULL on success, NULL on error.
|
||||
*/
|
||||
static struct tegra_prod *mods_tegra_get_prod_list(struct mods_client *client,
|
||||
struct device_node *dev_node)
|
||||
{
|
||||
struct tegra_prod *prod_list;
|
||||
|
||||
if (!mods_tegra_prod_dev) {
|
||||
cl_error("tegra prod is not initialized\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dev_node) {
|
||||
cl_error("device node is NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prod_list = devm_tegra_prod_get_from_node(mods_tegra_prod_dev,
|
||||
dev_node);
|
||||
if (IS_ERR(prod_list)) {
|
||||
cl_error("failed to get prod_list : %s\n",
|
||||
dev_node->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return prod_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* mods_tegra_get_prod_info - Get tegra_prod_list & mapped IO addresses
|
||||
* @MODS_TEGRA_PROD_SET_TUPLE: Input information, only the following
|
||||
* members are used.
|
||||
* +prod_node_handle: Handle of device node contained prod values.
|
||||
* +ctrl_node_handle: Handle of controller device node.
|
||||
* @tegra_prod_list: (OUT) Pointer to tegra_prod_list.
|
||||
* @ctrl_base: (OUT) Array of mapped IO address.
|
||||
* @count_ctrl_base: (OUT) Pointer to count of mapped IO address.
|
||||
*
|
||||
* Return Value :
|
||||
* 0 - OK
|
||||
* Others - ERROR
|
||||
*
|
||||
*/
|
||||
static int mods_tegra_get_prod_info(
|
||||
struct mods_client *client,
|
||||
const struct MODS_TEGRA_PROD_SET_TUPLE *tuple,
|
||||
struct tegra_prod **tegra_prod_list,
|
||||
void __iomem **ctrl_base,
|
||||
__u32 *count_ctrl_base)
|
||||
{
|
||||
struct device_node *prod_node, *ctrl_node;
|
||||
|
||||
if (!tegra_prod_list || !ctrl_base || !count_ctrl_base) {
|
||||
cl_error("detected NULL pointer for out value.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
prod_node = (struct device_node *)tuple->prod_dev_handle;
|
||||
if (!prod_node) {
|
||||
cl_error("prod device handle is NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*tegra_prod_list = mods_tegra_get_prod_list(client, prod_node);
|
||||
if (!(*tegra_prod_list)) {
|
||||
cl_error("failed to get prod_list with prod handle 0x%llx\n",
|
||||
tuple->prod_dev_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctrl_node = (struct device_node *)tuple->ctrl_dev_handle;
|
||||
if (!ctrl_node) {
|
||||
cl_error("controller device handle is NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return mods_batch_iomap(client, ctrl_node, ctrl_base, count_ctrl_base);
|
||||
}
|
||||
|
||||
/**
|
||||
* esc_mods_tegra_prod_is_supported - Test the prod is supported by
|
||||
* given prod name.
|
||||
* @MODS_TEGRA_PROD_IS_SUPPORTED: Input information, only the following
|
||||
members are used.
|
||||
* +prod_node_handle: Handle of device node contained prod values.
|
||||
* +prod_name: Prod name.
|
||||
* +is_supported: Result of supporting given prod configuration.
|
||||
*
|
||||
* Return Value :
|
||||
* 0 - OK
|
||||
* Others - ERROR
|
||||
*
|
||||
*/
|
||||
int esc_mods_tegra_prod_is_supported(
|
||||
struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_IS_SUPPORTED *tuple
|
||||
)
|
||||
{
|
||||
struct device_node *prod_node;
|
||||
struct tegra_prod *tegra_prod;
|
||||
bool is_supported;
|
||||
|
||||
prod_node = (struct device_node *)tuple->prod_dev_handle;
|
||||
if (!prod_node) {
|
||||
cl_error("prod device handle is NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tegra_prod = mods_tegra_get_prod_list(client, prod_node);
|
||||
if (!tegra_prod) {
|
||||
cl_error("failed to get prod_list with prod handle 0x%llx\n",
|
||||
tuple->prod_dev_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
is_supported = tegra_prod_by_name_supported(tegra_prod,
|
||||
tuple->prod_name);
|
||||
tuple->is_supported = is_supported ? 1 : 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* esc_mods_tegra_prod_set_prod_all - Read prod values from prod device node,
|
||||
* and set prod values to controller device
|
||||
* node.
|
||||
* @MODS_TEGRA_PROD_SET_TUPLE: Input information, only the following
|
||||
* members are used.
|
||||
* +prod_node_handle: Handle of device node contained prod values.
|
||||
* +ctrl_node_handle: Handle of controller device node.
|
||||
*
|
||||
* Return Value :
|
||||
* 0 - OK
|
||||
* Others - ERROR
|
||||
*
|
||||
*/
|
||||
int esc_mods_tegra_prod_set_prod_all(
|
||||
struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_SET_TUPLE *tuple
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
struct tegra_prod *tegra_prod_list;
|
||||
void __iomem *ctrl_base[MAX_IO_MAP_ENTRY];
|
||||
__u32 count_ctrl_base;
|
||||
|
||||
ret = mods_tegra_get_prod_info(client,
|
||||
tuple,
|
||||
&tegra_prod_list,
|
||||
ctrl_base,
|
||||
&count_ctrl_base);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = tegra_prod_set_list(ctrl_base, tegra_prod_list);
|
||||
if (ret < 0)
|
||||
cl_error("set prod failed\n");
|
||||
|
||||
mods_batch_iounmap(client, ctrl_base, count_ctrl_base);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* esc_mods_tegra_prod_set_prod_boot - Read prod values from prod device
|
||||
* node, and set prod values to
|
||||
* controller device node, which are
|
||||
* required for boot initialization.
|
||||
* @MODS_TEGRA_PROD_SET_TUPLE: Input information, only the following
|
||||
* members are used.
|
||||
* +prod_node_handle: Handle of device node contained prod values.
|
||||
* +ctrl_node_handle: Handle of controller device node.
|
||||
*
|
||||
* Return Value :
|
||||
* 0 - OK
|
||||
* Others - ERROR
|
||||
*
|
||||
*/
|
||||
int esc_mods_tegra_prod_set_prod_boot(
|
||||
struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_SET_TUPLE *tuple
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
struct tegra_prod *tegra_prod_list;
|
||||
void __iomem *ctrl_base[MAX_IO_MAP_ENTRY];
|
||||
__u32 count_ctrl_base;
|
||||
|
||||
ret = mods_tegra_get_prod_info(client,
|
||||
tuple,
|
||||
&tegra_prod_list,
|
||||
ctrl_base,
|
||||
&count_ctrl_base);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = tegra_prod_set_boot_init(ctrl_base, tegra_prod_list);
|
||||
if (ret < 0)
|
||||
cl_error("set boot init prod failed\n");
|
||||
|
||||
mods_batch_iounmap(client, ctrl_base, count_ctrl_base);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* esc_mods_tegra_prod_set_prod_by_name - Read prod values from prod
|
||||
* device node, and set prod values
|
||||
* to controller device node based
|
||||
* on prod name.
|
||||
* @MODS_TEGRA_PROD_SET_TUPLE: Input information, only the following
|
||||
* members are used.
|
||||
* +prod_node_handle: Handle of device node contained prod values.
|
||||
* +ctrl_node_handle: Handle of controller device node.
|
||||
* +prod_name: Prod name.
|
||||
*
|
||||
* Return Value :
|
||||
* 0 - OK
|
||||
* Others - ERROR
|
||||
*
|
||||
*/
|
||||
int esc_mods_tegra_prod_set_prod_by_name(
|
||||
struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_SET_TUPLE *tuple
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
struct tegra_prod *tegra_prod_list;
|
||||
void __iomem *ctrl_base[MAX_IO_MAP_ENTRY];
|
||||
__u32 count_ctrl_base;
|
||||
|
||||
ret = mods_tegra_get_prod_info(client,
|
||||
tuple,
|
||||
&tegra_prod_list,
|
||||
ctrl_base,
|
||||
&count_ctrl_base);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = tegra_prod_set_by_name(ctrl_base, tuple->prod_name,
|
||||
tegra_prod_list);
|
||||
if (ret < 0) {
|
||||
cl_error("set prod by name \"%s\" failed\n",
|
||||
tuple->prod_name);
|
||||
}
|
||||
|
||||
mods_batch_iounmap(client, ctrl_base, count_ctrl_base);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* esc_mods_tegra_prod_set_prod_exact - Read prod values from prod device
|
||||
* node, and set prod values to
|
||||
* controller device node based
|
||||
* on prod name, index, offset, and mask.
|
||||
* @MODS_TEGRA_PROD_SET_TUPLE: Input information, only the following
|
||||
members are used.
|
||||
* +prod_node_handle: Handle of device node contained prod values.
|
||||
* +ctrl_node_handle: Handle of controller device node.
|
||||
* +prod_name: Prod name.
|
||||
* +index: Index of base address.
|
||||
* +offset: Offset of the register.
|
||||
* +mask: Mask field on given register.
|
||||
*
|
||||
* Return Value :
|
||||
* 0 - OK
|
||||
* Others - ERROR
|
||||
*
|
||||
*/
|
||||
int esc_mods_tegra_prod_set_prod_exact(
|
||||
struct mods_client *client,
|
||||
struct MODS_TEGRA_PROD_SET_TUPLE *tuple
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
struct tegra_prod *tegra_prod_list;
|
||||
void __iomem *ctrl_base[MAX_IO_MAP_ENTRY];
|
||||
__u32 count_ctrl_base;
|
||||
|
||||
ret = mods_tegra_get_prod_info(client,
|
||||
tuple,
|
||||
&tegra_prod_list,
|
||||
ctrl_base,
|
||||
&count_ctrl_base);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = tegra_prod_set_by_name_partially(ctrl_base, tuple->prod_name,
|
||||
tegra_prod_list, tuple->index, tuple->offset,
|
||||
tuple->mask);
|
||||
if (ret < 0) {
|
||||
cl_error("set prod exact by name \"%s\" failed\n",
|
||||
tuple->prod_name);
|
||||
cl_error("index [%x]; offset [%x]; mask [%x]\n",
|
||||
tuple->index, tuple->offset, tuple->mask);
|
||||
}
|
||||
|
||||
mods_batch_iounmap(client, ctrl_base, count_ctrl_base);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MODS_ENABLE_BPMP_MRQ_API
|
||||
static int tegra_pcie_bpmp_set_ctrl_state(struct mods_smmu_dev *pcie_dev,
|
||||
|
||||
@@ -2093,16 +2093,22 @@ struct MODS_BPMP_UPHY_LANE_EOM_SCAN_PARAMS {
|
||||
#define MODS_ESC_LOCK_CONSOLE _IO(MODS_IOC_MAGIC, 93)
|
||||
/* Unlocks system console */
|
||||
#define MODS_ESC_UNLOCK_CONSOLE _IO(MODS_IOC_MAGIC, 94)
|
||||
/* Deprecated */
|
||||
#define MODS_ESC_TEGRA_PROD_IS_SUPPORTED MODSIO(WR, 95, \
|
||||
MODS_TEGRA_PROD_IS_SUPPORTED)
|
||||
/* Deprecated */
|
||||
#define MODS_ESC_TEGRA_PROD_SET_PROD_ALL MODSIO(W, 96, \
|
||||
MODS_TEGRA_PROD_SET_TUPLE)
|
||||
/* Deprecated */
|
||||
#define MODS_ESC_TEGRA_PROD_SET_PROD_BOOT MODSIO(W, 97, \
|
||||
MODS_TEGRA_PROD_SET_TUPLE)
|
||||
/* Deprecated */
|
||||
#define MODS_ESC_TEGRA_PROD_SET_PROD_BY_NAME MODSIO(W, 98, \
|
||||
MODS_TEGRA_PROD_SET_TUPLE)
|
||||
/* Deprecated */
|
||||
#define MODS_ESC_TEGRA_PROD_SET_PROD_EXACT MODSIO(W, 99, \
|
||||
MODS_TEGRA_PROD_SET_TUPLE)
|
||||
/* Deprecated */
|
||||
#define MODS_ESC_TEGRA_PROD_ITERATE_DT MODSIO(WR, 100, MODS_TEGRA_PROD_ITERATOR)
|
||||
#define MODS_ESC_GET_ATS_ADDRESS_RANGE MODSIO(WR, 101, \
|
||||
MODS_GET_ATS_ADDRESS_RANGE)
|
||||
|
||||
Reference in New Issue
Block a user