Exemple #1
0
static u_int32_t
xlp_pcib_read_config(device_t dev, u_int b, u_int s, u_int f,
    u_int reg, int width)
{
	uint32_t data = 0;
	uint64_t cfgaddr;
	int	regindex = reg/sizeof(uint32_t);

	cfgaddr = nlm_pcicfg_base(XLP_HDR_OFFSET(0, b, s, f));
	if ((width == 2) && (reg & 1))
		return 0xFFFFFFFF;
	else if ((width == 4) && (reg & 3))
		return 0xFFFFFFFF;

	/* 
	 * The intline and int pin of SoC devices are DOA, except
	 * for bridges (slot %8 == 1).
	 * use the values we stashed in a writable PCI scratch reg.
	 */
	if (b == 0 && regindex == 0xf && s % 8 > 1)
		regindex = XLP_PCI_DEVSCRATCH_REG0;

	data = nlm_read_pci_reg(cfgaddr, regindex);
	if (width == 1)
		return ((data >> ((reg & 3) << 3)) & 0xff);
	else if (width == 2)
Exemple #2
0
static u_int32_t
xlp_pcib_read_config(device_t dev, u_int b, u_int s, u_int f,
    u_int reg, int width)
{
	uint32_t data = 0;
	uint64_t cfgaddr;
	int	regindex = reg/sizeof(uint32_t);

	cfgaddr = nlm_pcicfg_base(XLP_HDR_OFFSET(0, b, s, f));
	if ((width == 2) && (reg & 1))
		return 0xFFFFFFFF;
	else if ((width == 4) && (reg & 3))
		return 0xFFFFFFFF;

	data = nlm_read_pci_reg(cfgaddr, regindex);

	/* 
	 * Fix up read data in some SoC devices 
	 * to emulate complete PCIe header
	 */
	if (b == 0) {
		int dev = s % 8;

		/* Fake intpin on config read for UART/I2C, USB, SD/Flash */
		if (regindex == 0xf && 
		    (dev == 6 || dev == 2 || dev == 7))
			data |= 0x1 << 8;	/* Fake int pin */
	}

	if (width == 1)
		return ((data >> ((reg & 3) << 3)) & 0xff);
	else if (width == 2)
Exemple #3
0
static void
xlp_add_soc_child(device_t pcib, device_t dev, int b, int s, int f)
{
	struct pci_devinfo *dinfo;
	struct xlp_devinfo *xlp_dinfo;
	struct soc_dev_desc *si;
	uint64_t pcibase;
	int domain, node, irt, irq, flags, devoffset, num;
	uint16_t devid;

	domain = pcib_get_domain(dev);
	node = s / 8;
	devoffset = XLP_HDR_OFFSET(node, 0, s % 8, f);
	if (!nlm_dev_exists(devoffset))
		return;

	/* Find if there is a desc for the SoC device */
	devid = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVICE, 2);
	si = xlp_find_soc_desc(devid);

	/* update flags and irq from desc if available */
	irq = 0;
	flags = 0;
	if (si != NULL) {
		if (si->irqbase != 0)
			irq = si->irqbase + si->ndevs;
		flags = si->flags;
		si->ndevs++;
	}

	/* skip internal devices */
	if ((flags & INTERNAL_DEV) != 0)
		return;

	/* PCIe interfaces are special, bug in Ax */
	if (devid == PCI_DEVICE_ID_NLM_PCIE) {
		xlp_add_irq(node, xlp_pcie_link_irt(f), PIC_PCIE_0_IRQ + f);
	} else {
		/* Stash intline and pin in shadow reg for devices */
		pcibase = nlm_pcicfg_base(devoffset);
		irt = nlm_irtstart(pcibase);
		num = nlm_irtnum(pcibase);
		if (irq != 0 && num > 0) {
			xlp_add_irq(node, irt, irq);
			nlm_write_reg(pcibase, XLP_PCI_DEVSCRATCH_REG0,
			    (1 << 8) | irq);
		}
	}
	dinfo = pci_read_device(pcib, domain, b, s, f, sizeof(*xlp_dinfo));
	if (dinfo == NULL)
		return;
	xlp_dinfo = (struct xlp_devinfo *)dinfo;
	xlp_dinfo->irq = irq;
	xlp_dinfo->flags = flags;

	/* memory resource from ecfg space, if MEM_RES_EMUL is set */
	if ((flags & MEM_RES_EMUL) != 0)
		xlp_dinfo->mem_res_start = XLP_DEFAULT_IO_BASE + devoffset +
		    XLP_IO_PCI_HDRSZ;
	pci_add_child(dev, dinfo);
}
Exemple #4
0
int
nlm_board_eeprom_read(int node, int bus, int addr, int offs, uint8_t *buf,
    int sz)
{
	int rd, i;
	char *err = NULL;

	eeprom_i2c_base = nlm_pcicfg_base(XLP_IO_I2C_OFFSET(node, bus)) +
	    XLP_IO_PCI_HDRSZ;

	if (oc_wait_on_status(OC_STATUS_BUSY) < 0) {
		err = "Not idle";
		goto err_exit;
	}

	/* write start */
	if (oc_wr_cmd(addr, OC_COMMAND_START)) {
		err = "I2C write start failed.";
		goto err_exit;
	}

	if (oc_read_reg(OC_I2C_STATUS_REG) & OC_STATUS_NACK) {
		err = "No ack after start";
		goto err_exit_stop;
	}

	if (oc_read_reg(OC_I2C_STATUS_REG) & OC_STATUS_AL) {
		err = "I2C Bus Arbitration Lost";
		goto err_exit_stop;
	}

	/* Write offset */
	if (oc_wr_cmd(offs, OC_COMMAND_WRITE)) {
		err = "I2C write slave offset failed.";
		goto err_exit_stop;
	}

	if (oc_read_reg(OC_I2C_STATUS_REG) & OC_STATUS_NACK) {
		err = "No ack after write";
		goto err_exit_stop;
	}

	/* read start */
	if (oc_wr_cmd(addr | 1, OC_COMMAND_START)) {
		err = "I2C read start failed.";
		goto err_exit_stop;
	}

	if (oc_read_reg(OC_I2C_STATUS_REG) & OC_STATUS_NACK) {
		err = "No ack after read start";
		goto err_exit_stop;
	}
	
	for (i = 0; i < sz - 1; i++) {
		if ((rd = oc_rd_cmd(OC_COMMAND_READ)) < 0) {
			err = "I2C read data byte failed.";
			goto err_exit_stop;
		}
	buf[i] = rd;
	}

	/* last byte */
	if ((rd = oc_rd_cmd(OC_COMMAND_RDNACK)) < 0) {
		err = "I2C read last data byte failed.";
		goto err_exit_stop;
	}
	buf[sz - 1] = rd;

err_exit_stop:
	oc_write_reg(OC_I2C_CMD_REG, OC_COMMAND_STOP);
	if (oc_wait_on_status(OC_STATUS_BUSY) < 0)
		printf("%s: stop failed", __func__);

err_exit:
	if (err) {
		printf("%s: Failed (%s)\n", __func__, err);
		return (-1);
	}
	return (0);
}