Пример #1
0
static int get_dprc_icid(struct fsl_mc_io *mc_io,
			 int container_id, u16 *icid)
{
	u16 dprc_handle;
	struct dprc_attributes attr;
	int error;

	error = dprc_open(mc_io, 0, container_id, &dprc_handle);
	if (error < 0) {
		dev_err(mc_io->dev, "dprc_open() failed: %d\n", error);
		return error;
	}

	memset(&attr, 0, sizeof(attr));
	error = dprc_get_attributes(mc_io, 0, dprc_handle, &attr);
	if (error < 0) {
		dev_err(mc_io->dev, "dprc_get_attributes() failed: %d\n",
			error);
		goto common_cleanup;
	}

	*icid = attr.icid;
	error = 0;

common_cleanup:
	(void)dprc_close(mc_io, 0, dprc_handle);
	return error;
}
Пример #2
0
int fsl_mc_ldpaa_init(bd_t *bis)
{
	int i, error = 0;
	int dprc_opened = 0, container_id;
	int num_child_objects = 0;

	error = mc_init();
	if (error < 0)
		goto error;

	error = dprc_get_container_id(dflt_mc_io, MC_CMD_NO_FLAGS,
				      &container_id);
	if (error < 0) {
		printf("dprc_get_container_id() failed: %d\n", error);
		goto error;
	}

	debug("fsl-mc: Container id=0x%x\n", container_id);

	error = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, container_id,
			  &dflt_dprc_handle);
	if (error < 0) {
		printf("dprc_open() failed: %d\n", error);
		goto error;
	}
	dprc_opened = true;

	error = dprc_get_obj_count(dflt_mc_io,
				   MC_CMD_NO_FLAGS, dflt_dprc_handle,
				   &num_child_objects);
	if (error < 0) {
		printf("dprc_get_obj_count() failed: %d\n", error);
		goto error;
	}
	debug("Total child in container %d = %d\n", container_id,
	      num_child_objects);

	if (num_child_objects != 0) {
		/*
		 * Discover objects currently in the DPRC container in the MC:
		 */
		for (i = 0; i < num_child_objects; i++)
			error = dprc_scan_container_obj(dflt_dprc_handle,
							"dpbp", i);

		for (i = 0; i < num_child_objects; i++)
			error = dprc_scan_container_obj(dflt_dprc_handle,
							"dpio", i);

		for (i = 0; i < num_child_objects; i++)
			error = dprc_scan_container_obj(dflt_dprc_handle,
							"dpni", i);
	}
error:
	if (dprc_opened)
		dprc_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle);

	return error;
}
Пример #3
0
static int dprc_init(void)
{
	int err, child_portal_id, container_id;
	struct dprc_cfg cfg;
	uint64_t mc_portal_offset;

	/* Open root container */
	err = dprc_get_container_id(root_mc_io, MC_CMD_NO_FLAGS, &container_id);
	if (err < 0) {
		printf("dprc_get_container_id(): Root failed: %d\n", err);
		goto err_root_container_id;
	}

#ifdef DEBUG
	printf("Root container id = %d\n", container_id);
#endif
	err = dprc_open(root_mc_io, MC_CMD_NO_FLAGS, container_id,
			&root_dprc_handle);
	if (err < 0) {
		printf("dprc_open(): Root Container failed: %d\n", err);
		goto err_root_open;
	}

	if (!root_dprc_handle) {
		printf("dprc_open(): Root Container Handle is not valid\n");
		goto err_root_open;
	}

	cfg.options = DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED |
		      DPRC_CFG_OPT_OBJ_CREATE_ALLOWED |
		      DPRC_CFG_OPT_ALLOC_ALLOWED;
	cfg.icid = DPRC_GET_ICID_FROM_POOL;
	cfg.portal_id = 250;
	err = dprc_create_container(root_mc_io, MC_CMD_NO_FLAGS,
			root_dprc_handle,
			&cfg,
			&child_dprc_id,
			&mc_portal_offset);
	if (err < 0) {
		printf("dprc_create_container() failed: %d\n", err);
		goto err_create;
	}

	dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io));
	if (!dflt_mc_io) {
		err  = -ENOMEM;
		printf(" No memory: malloc() failed\n");
		goto err_malloc;
	}

	child_portal_id = MC_PORTAL_OFFSET_TO_PORTAL_ID(mc_portal_offset);
	dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(child_portal_id);
#ifdef DEBUG
	printf("MC portal of child DPRC container: %d, physical addr %p)\n",
	       child_dprc_id, dflt_mc_io->mmio_regs);
#endif

	err = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, child_dprc_id,
			&dflt_dprc_handle);
	if (err < 0) {
		printf("dprc_open(): Child container failed: %d\n", err);
		goto err_child_open;
	}

	if (!dflt_dprc_handle) {
		printf("dprc_open(): Child container Handle is not valid\n");
		goto err_child_open;
	}

	return 0;
err_child_open:
	free(dflt_mc_io);
err_malloc:
	dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS,
			       root_dprc_handle, child_dprc_id);
err_create:
	dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle);
err_root_open:
err_root_container_id:
	return err;
}
Пример #4
0
/**
 * dprc_probe - callback invoked when a DPRC is being bound to this driver
 *
 * @mc_dev: Pointer to fsl-mc device representing a DPRC
 *
 * It opens the physical DPRC in the MC.
 * It scans the DPRC to discover the MC objects contained in it.
 * It creates the interrupt pool for the MC bus associated with the DPRC.
 * It configures the interrupts for the DPRC device itself.
 */
static int dprc_probe(struct fsl_mc_device *mc_dev)
{
	int error;
	size_t region_size;
	struct device *parent_dev = mc_dev->dev.parent;
	struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
	bool mc_io_created = false;
	bool msi_domain_set = false;

	if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
		return -EINVAL;

	if (WARN_ON(dev_get_msi_domain(&mc_dev->dev)))
		return -EINVAL;

	if (!mc_dev->mc_io) {
		/*
		 * This is a child DPRC:
		 */
		if (WARN_ON(!dev_is_fsl_mc(parent_dev)))
			return -EINVAL;

		if (WARN_ON(mc_dev->obj_desc.region_count == 0))
			return -EINVAL;

		region_size = mc_dev->regions[0].end -
			      mc_dev->regions[0].start + 1;

		error = fsl_create_mc_io(&mc_dev->dev,
					 mc_dev->regions[0].start,
					 region_size,
					 NULL,
					 FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
					 &mc_dev->mc_io);
		if (error < 0)
			return error;

		mc_io_created = true;

		/*
		 * Inherit parent MSI domain:
		 */
		dev_set_msi_domain(&mc_dev->dev,
				   dev_get_msi_domain(parent_dev));
		msi_domain_set = true;
	} else {
		/*
		 * This is a root DPRC
		 */
		struct irq_domain *mc_msi_domain;

		if (WARN_ON(dev_is_fsl_mc(parent_dev)))
			return -EINVAL;

		error = fsl_mc_find_msi_domain(parent_dev,
					       &mc_msi_domain);
		if (error < 0) {
			dev_warn(&mc_dev->dev,
				 "WARNING: MC bus without interrupt support\n");
		} else {
			dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
			msi_domain_set = true;
		}
	}

	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);
		goto error_cleanup_msi_domain;
	}

	error = dprc_get_attributes(mc_dev->mc_io, 0, mc_dev->mc_handle,
				    &mc_bus->dprc_attr);
	if (error < 0) {
		dev_err(&mc_dev->dev, "dprc_get_attributes() failed: %d\n",
			error);
		goto error_cleanup_open;
	}

	if (mc_bus->dprc_attr.version.major < DPRC_MIN_VER_MAJOR ||
	   (mc_bus->dprc_attr.version.major == DPRC_MIN_VER_MAJOR &&
	    mc_bus->dprc_attr.version.minor < DPRC_MIN_VER_MINOR)) {
		dev_err(&mc_dev->dev,
			"ERROR: DPRC version %d.%d not supported\n",
			mc_bus->dprc_attr.version.major,
			mc_bus->dprc_attr.version.minor);
		error = -ENOTSUPP;
		goto error_cleanup_open;
	}

	mutex_init(&mc_bus->scan_mutex);

	/*
	 * Discover MC objects in DPRC object:
	 */
	error = dprc_scan_container(mc_dev);
	if (error < 0)
		goto error_cleanup_open;

	/*
	 * Configure interrupt for the DPRC object associated with this MC bus:
	 */
	error = dprc_setup_irq(mc_dev);
	if (error < 0)
		goto error_cleanup_open;

	dev_info(&mc_dev->dev, "DPRC device bound to driver");
	return 0;

error_cleanup_open:
	(void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);

error_cleanup_msi_domain:
	if (msi_domain_set)
		dev_set_msi_domain(&mc_dev->dev, NULL);

	if (mc_io_created) {
		fsl_destroy_mc_io(mc_dev->mc_io);
		mc_dev->mc_io = NULL;
	}

	return error;
}