Commit 1ee695fa authored by J. German Rivera's avatar J. German Rivera Committed by Greg Kroah-Hartman

staging: fsl-mc: up-rev dprc binary interface to v4.0

Add cmd_flags parameter to all dprc APIs to comply
with the dprc 4.0 MC interface. Updated MC version
major number.  Pass irq args in struct instead of
separate args.

dprc 4.0 uses MC-relative offsets to specify object regions,
instead of physical addresses. So, translate_mc_addr() and
struct fsl_mc_addr_translation_range need to be updated
accordingly.

Update commands for 4.0: add new commands 'set/get
obj irq', 'set obj label', 'get obj descriptor'.
Remove 'get portal paddr'.
Signed-off-by: default avatarJ. German Rivera <German.Rivera@freescale.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e1135cb6
......@@ -41,7 +41,7 @@
#define _FSL_DPRC_CMD_H
/* DPRC Version */
#define DPRC_VER_MAJOR 3
#define DPRC_VER_MAJOR 4
#define DPRC_VER_MINOR 0
/* Command IDs */
......@@ -72,12 +72,15 @@
#define DPRC_CMDID_GET_RES_COUNT 0x15B
#define DPRC_CMDID_GET_RES_IDS 0x15C
#define DPRC_CMDID_GET_OBJ_REG 0x15E
#define DPRC_CMDID_SET_OBJ_IRQ 0x15F
#define DPRC_CMDID_GET_OBJ_IRQ 0x160
#define DPRC_CMDID_SET_OBJ_LABEL 0x161
#define DPRC_CMDID_GET_OBJ_DESC 0x162
#define DPRC_CMDID_CONNECT 0x167
#define DPRC_CMDID_DISCONNECT 0x168
#define DPRC_CMDID_GET_POOL 0x169
#define DPRC_CMDID_GET_POOL_COUNT 0x16A
#define DPRC_CMDID_GET_PORTAL_PADDR 0x16B
#define DPRC_CMDID_GET_CONNECTION 0x16C
......
......@@ -262,6 +262,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
struct dprc_obj_desc *child_obj_desc_array = NULL;
error = dprc_get_obj_count(mc_bus_dev->mc_io,
0,
mc_bus_dev->mc_handle,
&num_child_objects);
if (error < 0) {
......@@ -289,6 +290,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
&child_obj_desc_array[i];
error = dprc_get_obj(mc_bus_dev->mc_io,
0,
mc_bus_dev->mc_handle,
i, obj_desc);
if (error < 0) {
......@@ -399,7 +401,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
return error;
}
error = dprc_open(mc_dev->mc_io, mc_dev->obj_desc.id,
error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
&mc_dev->mc_handle);
if (error < 0) {
dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error);
......@@ -419,7 +421,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
return 0;
error_cleanup_open:
(void)dprc_close(mc_dev->mc_io, mc_dev->mc_handle);
(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
error_cleanup_mc_io:
fsl_destroy_mc_io(mc_dev->mc_io);
......@@ -447,7 +449,7 @@ static int dprc_remove(struct fsl_mc_device *mc_dev)
device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
dprc_cleanup_all_resource_pools(mc_dev);
error = dprc_close(mc_dev->mc_io, mc_dev->mc_handle);
error = dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
if (error < 0)
dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);
......
This diff is collapsed.
......@@ -213,14 +213,14 @@ static int get_dprc_icid(struct fsl_mc_io *mc_io,
struct dprc_attributes attr;
int error;
error = dprc_open(mc_io, container_id, &dprc_handle);
error = dprc_open(mc_io, 0, container_id, &dprc_handle);
if (error < 0) {
pr_err("dprc_open() failed: %d\n", error);
return error;
}
memset(&attr, 0, sizeof(attr));
error = dprc_get_attributes(mc_io, dprc_handle, &attr);
error = dprc_get_attributes(mc_io, 0, dprc_handle, &attr);
if (error < 0) {
pr_err("dprc_get_attributes() failed: %d\n", error);
goto common_cleanup;
......@@ -230,11 +230,12 @@ static int get_dprc_icid(struct fsl_mc_io *mc_io,
error = 0;
common_cleanup:
(void)dprc_close(mc_io, dprc_handle);
(void)dprc_close(mc_io, 0, dprc_handle);
return error;
}
static int translate_mc_addr(u64 mc_addr, phys_addr_t *phys_addr)
static int translate_mc_addr(enum dprc_region_type mc_region_type,
u64 mc_offset, phys_addr_t *phys_addr)
{
int i;
struct fsl_mc *mc = dev_get_drvdata(fsl_mc_bus_type.dev_root->parent);
......@@ -243,7 +244,7 @@ static int translate_mc_addr(u64 mc_addr, phys_addr_t *phys_addr)
/*
* Do identity mapping:
*/
*phys_addr = mc_addr;
*phys_addr = mc_offset;
return 0;
}
......@@ -251,10 +252,11 @@ static int translate_mc_addr(u64 mc_addr, phys_addr_t *phys_addr)
struct fsl_mc_addr_translation_range *range =
&mc->translation_ranges[i];
if (mc_addr >= range->start_mc_addr &&
mc_addr < range->end_mc_addr) {
if (mc_region_type == range->mc_region_type &&
mc_offset >= range->start_mc_offset &&
mc_offset < range->end_mc_offset) {
*phys_addr = range->start_phys_addr +
(mc_addr - range->start_mc_addr);
(mc_offset - range->start_mc_offset);
return 0;
}
}
......@@ -270,6 +272,22 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev,
struct resource *regions;
struct dprc_obj_desc *obj_desc = &mc_dev->obj_desc;
struct device *parent_dev = mc_dev->dev.parent;
enum dprc_region_type mc_region_type;
if (strcmp(obj_desc->type, "dprc") == 0 ||
strcmp(obj_desc->type, "dpmcp") == 0) {
mc_region_type = DPRC_REGION_TYPE_MC_PORTAL;
} else if (strcmp(obj_desc->type, "dpio") == 0) {
mc_region_type = DPRC_REGION_TYPE_QBMAN_PORTAL;
} else {
/*
* This function should not have been called for this MC object
* type, as this object type is not supposed to have MMIO
* regions
*/
WARN_ON(true);
return -EINVAL;
}
regions = kmalloc_array(obj_desc->region_count,
sizeof(regions[0]), GFP_KERNEL);
......@@ -280,6 +298,7 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev,
struct dprc_region_desc region_desc;
error = dprc_get_obj_region(mc_bus_dev->mc_io,
0,
mc_bus_dev->mc_handle,
obj_desc->type,
obj_desc->id, i, &region_desc);
......@@ -289,14 +308,15 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev,
goto error_cleanup_regions;
}
WARN_ON(region_desc.base_paddr == 0x0);
WARN_ON(region_desc.size == 0);
error = translate_mc_addr(region_desc.base_paddr,
error = translate_mc_addr(mc_region_type,
region_desc.base_offset,
&regions[i].start);
if (error < 0) {
dev_err(parent_dev,
"Invalid MC address: %#llx\n",
region_desc.base_paddr);
"Invalid MC offset: %#x (for %s.%d\'s region %d)\n",
region_desc.base_offset,
obj_desc->type, obj_desc->id, i);
goto error_cleanup_regions;
}
......@@ -574,11 +594,13 @@ static int get_mc_addr_translation_ranges(struct device *dev,
for (i = 0; i < *num_ranges; ++i) {
struct fsl_mc_addr_translation_range *range = &(*ranges)[i];
range->start_mc_addr = of_read_number(cell, mc_addr_cells);
range->mc_region_type = of_read_number(cell, 1);
range->start_mc_offset = of_read_number(cell + 1,
mc_addr_cells - 1);
cell += mc_addr_cells;
range->start_phys_addr = of_read_number(cell, paddr_cells);
cell += paddr_cells;
range->end_mc_addr = range->start_mc_addr +
range->end_mc_offset = range->start_mc_offset +
of_read_number(cell, mc_size_cells);
cell += mc_size_cells;
......
This diff is collapsed.
......@@ -29,7 +29,8 @@
/**
* struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
* @root_mc_bus_dev: MC object device representing the root DPRC
* @addr_translation_ranges: array of bus to system address translation ranges
* @num_translation_ranges: number of entries in addr_translation_ranges
* @translation_ranges: array of bus to system address translation ranges
*/
struct fsl_mc {
struct fsl_mc_device *root_mc_bus_dev;
......@@ -40,14 +41,16 @@ struct fsl_mc {
/**
* struct fsl_mc_addr_translation_range - bus to system address translation
* range
* @start_mc_addr: Start MC address of the range being translated
* @end_mc_addr: MC address of the first byte after the range (last MC
* address of the range is end_mc_addr - 1)
* @mc_region_type: Type of MC region for the range being translated
* @start_mc_offset: Start MC offset of the range being translated
* @end_mc_offset: MC offset of the first byte after the range (last MC
* offset of the range is end_mc_offset - 1)
* @start_phys_addr: system physical address corresponding to start_mc_addr
*/
struct fsl_mc_addr_translation_range {
uint64_t start_mc_addr;
uint64_t end_mc_addr;
enum dprc_region_type mc_region_type;
uint64_t start_mc_offset;
uint64_t end_mc_offset;
phys_addr_t start_phys_addr;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment