Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -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

+5 −3
Original line number Diff line number Diff line
@@ -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);

+345 −81

File changed.

Preview size limit exceeded, changes collapsed.

+36 −14
Original line number Diff line number Diff line
@@ -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;
+230 −47

File changed.

Preview size limit exceeded, changes collapsed.

Loading