Exemple #1
0
static int stm32_qspi_exec_op(struct spi_slave *slave,
			      const struct spi_mem_op *op)
{
	struct stm32_qspi_priv *priv = dev_get_priv(slave->dev->parent);
	u32 cr, ccr, addr_max;
	u8 mode = STM32_QSPI_CCR_IND_WRITE;
	int timeout, ret;

	debug("%s: cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
	      __func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
	      op->dummy.buswidth, op->data.buswidth,
	      op->addr.val, op->data.nbytes);

	ret = _stm32_qspi_wait_for_not_busy(priv);
	if (ret)
		return ret;

	addr_max = op->addr.val + op->data.nbytes + 1;

	if (op->data.dir == SPI_MEM_DATA_IN && op->data.nbytes) {
		if (addr_max < priv->mm_size && op->addr.buswidth)
			mode = STM32_QSPI_CCR_MEM_MAP;
		else
			mode = STM32_QSPI_CCR_IND_READ;
	}

	if (op->data.nbytes)
		writel(op->data.nbytes - 1, &priv->regs->dlr);

	ccr = (mode << STM32_QSPI_CCR_FMODE_SHIFT);
	ccr |= op->cmd.opcode;
	ccr |= (_stm32_qspi_get_mode(op->cmd.buswidth)
		<< STM32_QSPI_CCR_IMODE_SHIFT);

	if (op->addr.nbytes) {
		ccr |= ((op->addr.nbytes - 1) << STM32_QSPI_CCR_ADSIZE_SHIFT);
		ccr |= (_stm32_qspi_get_mode(op->addr.buswidth)
			<< STM32_QSPI_CCR_ADMODE_SHIFT);
	}

	if (op->dummy.buswidth && op->dummy.nbytes)
		ccr |= (op->dummy.nbytes * 8 / op->dummy.buswidth
			<< STM32_QSPI_CCR_DCYC_SHIFT);

	if (op->data.nbytes)
		ccr |= (_stm32_qspi_get_mode(op->data.buswidth)
			<< STM32_QSPI_CCR_DMODE_SHIFT);

	writel(ccr, &priv->regs->ccr);

	if (op->addr.nbytes && mode != STM32_QSPI_CCR_MEM_MAP)
		writel(op->addr.val, &priv->regs->ar);

	ret = _stm32_qspi_tx(priv, op, mode);
	/*
	 * Abort in:
	 * -error case
	 * -read memory map: prefetching must be stopped if we read the last
	 *  byte of device (device size - fifo size). like device size is not
	 *  knows, the prefetching is always stop.
	 */
	if (ret || mode == STM32_QSPI_CCR_MEM_MAP)
		goto abort;

	/* Wait end of tx in indirect mode */
	ret = _stm32_qspi_wait_cmd(priv, op);
	if (ret)
		goto abort;

	return 0;

abort:
	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_ABORT);

	/* Wait clear of abort bit by hw */
	timeout = readl_poll_timeout(&priv->regs->cr, cr,
				     !(cr & STM32_QSPI_CR_ABORT),
				     STM32_ABT_TIMEOUT_US);

	writel(STM32_QSPI_FCR_CTCF, &priv->regs->fcr);

	if (ret || timeout)
		pr_err("%s ret:%d abort timeout:%d\n", __func__, ret, timeout);

	return ret;
}
static void atmel_hlcdc_init(struct udevice *dev)
{
	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
	struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
	struct atmel_hlcd_regs *regs = priv->regs;
	struct display_timing *timing = &priv->timing;
	struct lcd_dma_desc *desc;
	unsigned long value, vl_clk_pol;
	int ret;

	/* Disable DISP signal */
	writel(LCDC_LCDDIS_DISPDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	/* Disable synchronization */
	writel(LCDC_LCDDIS_SYNCDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	/* Disable pixel clock */
	writel(LCDC_LCDDIS_CLKDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	/* Disable PWM */
	writel(LCDC_LCDDIS_PWMDIS, &regs->lcdc_lcddis);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
			   false, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);

	/* Set pixel clock */
	value = priv->clk_rate / timing->pixelclock.typ;
	if (priv->clk_rate % timing->pixelclock.typ)
		value++;

	vl_clk_pol = 0;
	if (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
		vl_clk_pol = LCDC_LCDCFG0_CLKPOL;

	if (value < 1) {
		/* Using system clock as pixel clock */
		writel(LCDC_LCDCFG0_CLKDIV(0)
			| LCDC_LCDCFG0_CGDISHCR
			| LCDC_LCDCFG0_CGDISHEO
			| LCDC_LCDCFG0_CGDISOVR1
			| LCDC_LCDCFG0_CGDISBASE
			| vl_clk_pol
			| LCDC_LCDCFG0_CLKSEL,
			&regs->lcdc_lcdcfg0);

	} else {
		writel(LCDC_LCDCFG0_CLKDIV(value - 2)
			| LCDC_LCDCFG0_CGDISHCR
			| LCDC_LCDCFG0_CGDISHEO
			| LCDC_LCDCFG0_CGDISOVR1
			| LCDC_LCDCFG0_CGDISBASE
			| vl_clk_pol,
			&regs->lcdc_lcdcfg0);
	}

	/* Initialize control register 5 */
	value = 0;

	if (!(timing->flags & DISPLAY_FLAGS_HSYNC_HIGH))
		value |= LCDC_LCDCFG5_HSPOL;
	if (!(timing->flags & DISPLAY_FLAGS_VSYNC_HIGH))
		value |= LCDC_LCDCFG5_VSPOL;

	switch (priv->output_mode) {
	case 12:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP;
		break;
	case 16:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP;
		break;
	case 18:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP;
		break;
	case 24:
		value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP;
		break;
	default:
		BUG();
		break;
	}

	value |= LCDC_LCDCFG5_GUARDTIME(priv->guard_time);
	value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS);
	writel(value, &regs->lcdc_lcdcfg5);

	/* Vertical & Horizontal Timing */
	value = LCDC_LCDCFG1_VSPW(timing->vsync_len.typ - 1);
	value |= LCDC_LCDCFG1_HSPW(timing->hsync_len.typ - 1);
	writel(value, &regs->lcdc_lcdcfg1);

	value = LCDC_LCDCFG2_VBPW(timing->vback_porch.typ);
	value |= LCDC_LCDCFG2_VFPW(timing->vfront_porch.typ - 1);
	writel(value, &regs->lcdc_lcdcfg2);

	value = LCDC_LCDCFG3_HBPW(timing->hback_porch.typ - 1);
	value |= LCDC_LCDCFG3_HFPW(timing->hfront_porch.typ - 1);
	writel(value, &regs->lcdc_lcdcfg3);

	/* Display size */
	value = LCDC_LCDCFG4_RPF(timing->vactive.typ - 1);
	value |= LCDC_LCDCFG4_PPL(timing->hactive.typ - 1);
	writel(value, &regs->lcdc_lcdcfg4);

	writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO,
	       &regs->lcdc_basecfg0);

	switch (VNBITS(priv->vl_bpix)) {
	case 16:
		writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565,
		       &regs->lcdc_basecfg1);
		break;
	case 32:
		writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888,
		       &regs->lcdc_basecfg1);
		break;
	default:
		BUG();
		break;
	}

	writel(LCDC_BASECFG2_XSTRIDE(0), &regs->lcdc_basecfg2);
	writel(0, &regs->lcdc_basecfg3);
	writel(LCDC_BASECFG4_DMA, &regs->lcdc_basecfg4);

	/* Disable all interrupts */
	writel(~0UL, &regs->lcdc_lcdidr);
	writel(~0UL, &regs->lcdc_baseidr);

	/* Setup the DMA descriptor, this descriptor will loop to itself */
	desc = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*desc));
	if (!desc)
		return;

	desc->address = (u32)uc_plat->base;

	/* Disable DMA transfer interrupt & descriptor loaded interrupt. */
	desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN
			| LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
	desc->next = (u32)desc;

	/* Flush the DMA descriptor if we enabled dcache */
	flush_dcache_range((u32)desc,
			   ALIGN(((u32)desc + sizeof(*desc)),
			   CONFIG_SYS_CACHELINE_SIZE));

	writel(desc->address, &regs->lcdc_baseaddr);
	writel(desc->control, &regs->lcdc_basectrl);
	writel(desc->next, &regs->lcdc_basenext);
	writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN,
	       &regs->lcdc_basecher);

	/* Enable LCD */
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_CLKEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_CLKSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_SYNCEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_LCDSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_DISPEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_DISPSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
	value = readl(&regs->lcdc_lcden);
	writel(value | LCDC_LCDEN_PWMEN, &regs->lcdc_lcden);
	ret = wait_for_bit(__func__, &regs->lcdc_lcdsr, LCDC_LCDSR_PWMSTS,
			   true, 1000, false);
	if (ret)
		printf("%s: %d: Timeout!\n", __func__, __LINE__);
}
Exemple #3
0
static int altera_spi_xfer(struct udevice *dev, unsigned int bitlen,
			    const void *dout, void *din, unsigned long flags)
{
	struct udevice *bus = dev->parent;
	struct altera_spi_priv *priv = dev_get_priv(bus);
	struct altera_spi_regs *const regs = priv->regs;
	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);

	/* assume spi core configured to do 8 bit transfers */
	unsigned int bytes = bitlen / 8;
	const unsigned char *txp = dout;
	unsigned char *rxp = din;
	uint32_t reg, data, start;

	debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
	      bus->seq, slave_plat->cs, bitlen, bytes, flags);

	if (bitlen == 0)
		goto done;

	if (bitlen % 8) {
		flags |= SPI_XFER_END;
		goto done;
	}

	/* empty read buffer */
	if (readl(&regs->status) & ALTERA_SPI_STATUS_RRDY_MSK)
		readl(&regs->rxdata);

	if (flags & SPI_XFER_BEGIN)
		spi_cs_activate(dev, slave_plat->cs);

	while (bytes--) {
		if (txp)
			data = *txp++;
		else
			data = CONFIG_ALTERA_SPI_IDLE_VAL;

		debug("%s: tx:%x ", __func__, data);
		writel(data, &regs->txdata);

		start = get_timer(0);
		while (1) {
			reg = readl(&regs->status);
			if (reg & ALTERA_SPI_STATUS_RRDY_MSK)
				break;
			if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
				debug("%s: Transmission timed out!\n", __func__);
				return -1;
			}
		}

		data = readl(&regs->rxdata);
		if (rxp)
			*rxp++ = data & 0xff;

		debug("rx:%x\n", data);
	}

done:
	if (flags & SPI_XFER_END)
		spi_cs_deactivate(dev);

	return 0;
}
static int altera_tse_probe(struct udevice *dev)
{
	struct eth_pdata *pdata = dev_get_platdata(dev);
	struct altera_tse_priv *priv = dev_get_priv(dev);
	void *blob = (void *)gd->fdt_blob;
	int node = dev->of_offset;
	const char *list, *end;
	const fdt32_t *cell;
	void *base, *desc_mem = NULL;
	unsigned long addr, size;
	int parent, addrc, sizec;
	int len, idx;
	int ret;

	priv->dma_type = dev_get_driver_data(dev);
	if (priv->dma_type == ALT_SGDMA)
		priv->ops = &tse_sgdma_ops;
	else
		priv->ops = &tse_msgdma_ops;
	/*
	 * decode regs. there are multiple reg tuples, and they need to
	 * match with reg-names.
	 */
	parent = fdt_parent_offset(blob, node);
	of_bus_default_count_cells(blob, parent, &addrc, &sizec);
	list = fdt_getprop(blob, node, "reg-names", &len);
	if (!list)
		return -ENOENT;
	end = list + len;
	cell = fdt_getprop(blob, node, "reg", &len);
	if (!cell)
		return -ENOENT;
	idx = 0;
	while (list < end) {
		addr = fdt_translate_address((void *)blob,
					     node, cell + idx);
		size = fdt_addr_to_cpu(cell[idx + addrc]);
		base = map_physmem(addr, size, MAP_NOCACHE);
		len = strlen(list);
		if (strcmp(list, "control_port") == 0)
			priv->mac_dev = base;
		else if (strcmp(list, "rx_csr") == 0)
			priv->sgdma_rx = base;
		else if (strcmp(list, "rx_desc") == 0)
			priv->rx_desc = base;
		else if (strcmp(list, "rx_resp") == 0)
			priv->rx_resp = base;
		else if (strcmp(list, "tx_csr") == 0)
			priv->sgdma_tx = base;
		else if (strcmp(list, "tx_desc") == 0)
			priv->tx_desc = base;
		else if (strcmp(list, "s1") == 0)
			desc_mem = base;
		idx += addrc + sizec;
		list += (len + 1);
	}
	/* decode fifo depth */
	priv->rx_fifo_depth = fdtdec_get_int(blob, node,
		"rx-fifo-depth", 0);
	priv->tx_fifo_depth = fdtdec_get_int(blob, node,
		"tx-fifo-depth", 0);
	/* decode phy */
	addr = fdtdec_get_int(blob, node,
			      "phy-handle", 0);
	addr = fdt_node_offset_by_phandle(blob, addr);
	priv->phyaddr = fdtdec_get_int(blob, addr,
		"reg", 0);
	/* init desc */
	if (priv->dma_type == ALT_SGDMA) {
		len = sizeof(struct alt_sgdma_descriptor) * 4;
		if (!desc_mem) {
			desc_mem = dma_alloc_coherent(len, &addr);
			if (!desc_mem)
				return -ENOMEM;
		}
		memset(desc_mem, 0, len);
		priv->tx_desc = desc_mem;
		priv->rx_desc = priv->tx_desc +
			2 * sizeof(struct alt_sgdma_descriptor);
	}
	/* allocate recv packet buffer */
	priv->rx_buf = malloc_cache_aligned(PKTSIZE_ALIGN);
	if (!priv->rx_buf)
		return -ENOMEM;

	/* stop controller */
	debug("Reset TSE & SGDMAs\n");
	altera_tse_stop(dev);

	/* start the phy */
	priv->interface = pdata->phy_interface;
	tse_mdio_init(dev->name, priv);
	priv->bus = miiphy_get_dev_by_name(dev->name);

	ret = tse_phy_init(priv, dev);

	return ret;
}
static int tegra186_bpmp_call(struct udevice *dev, int mrq, void *tx_msg,
			      int tx_size, void *rx_msg, int rx_size)
{
	struct tegra186_bpmp *priv = dev_get_priv(dev);
	int ret, err;
	void *ivc_frame;
	struct mrq_request *req;
	struct mrq_response *resp;
	ulong start_time;

	debug("%s(dev=%p, mrq=%u, tx_msg=%p, tx_size=%d, rx_msg=%p, rx_size=%d) (priv=%p)\n",
	      __func__, dev, mrq, tx_msg, tx_size, rx_msg, rx_size, priv);

	if ((tx_size > BPMP_IVC_FRAME_SIZE) || (rx_size > BPMP_IVC_FRAME_SIZE))
		return -EINVAL;

	ret = tegra_ivc_write_get_next_frame(&priv->ivc, &ivc_frame);
	if (ret) {
		error("tegra_ivc_write_get_next_frame() failed: %d\n", ret);
		return ret;
	}

	req = ivc_frame;
	req->mrq = mrq;
	req->flags = BPMP_FLAG_DO_ACK | BPMP_FLAG_RING_DOORBELL;
	memcpy(req + 1, tx_msg, tx_size);

	ret = tegra_ivc_write_advance(&priv->ivc);
	if (ret) {
		error("tegra_ivc_write_advance() failed: %d\n", ret);
		return ret;
	}

	start_time = timer_get_us();
	for (;;) {
		ret = tegra_ivc_channel_notified(&priv->ivc);
		if (ret) {
			error("tegra_ivc_channel_notified() failed: %d\n", ret);
			return ret;
		}

		ret = tegra_ivc_read_get_next_frame(&priv->ivc, &ivc_frame);
		if (!ret)
			break;

		/* Timeout 20ms; roughly 10x current max observed duration */
		if ((timer_get_us() - start_time) > 20 * 1000) {
			error("tegra_ivc_read_get_next_frame() timed out (%d)\n",
			      ret);
			return -ETIMEDOUT;
		}
	}

	resp = ivc_frame;
	err = resp->err;
	if (!err && rx_msg && rx_size)
		memcpy(rx_msg, resp + 1, rx_size);

	ret = tegra_ivc_read_advance(&priv->ivc);
	if (ret) {
		error("tegra_ivc_write_advance() failed: %d\n", ret);
		return ret;
	}

	if (err) {
		error("BPMP responded with error %d\n", err);
		/* err isn't a U-Boot error code, so don't that */
		return -EIO;
	}

	return rx_size;
}
Exemple #6
0
int pfe_eth_board_init(struct udevice *dev)
{
	static int init_done;
	struct mii_dev *bus;
	static const char *mdio_name;
	struct pfe_mdio_info mac_mdio_info;
	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
	u8 data8;
	struct pfe_eth_dev *priv = dev_get_priv(dev);

	int srds_s1 = in_be32(&gur->rcwsr[4]) &
			FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
	srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;

	ls1012aqds_mux_mdio(EMI1_SLOT1);

	if (!init_done) {
		mac_mdio_info.reg_base = (void *)EMAC1_BASE_ADDR;
		mac_mdio_info.name = DEFAULT_PFE_MDIO_NAME;

		bus = pfe_mdio_init(&mac_mdio_info);
		if (!bus) {
			printf("Failed to register mdio\n");
			return -1;
		}
		init_done = 1;
	}

	if (priv->gemac_port) {
		mac_mdio_info.reg_base = (void *)EMAC2_BASE_ADDR;
		mac_mdio_info.name = DEFAULT_PFE_MDIO1_NAME;

		bus = pfe_mdio_init(&mac_mdio_info);
		if (!bus) {
			printf("Failed to register mdio\n");
			return -1;
		}
	}

	switch (srds_s1) {
	case 0x3508:
		printf("ls1012aqds:supported SerDes PRCTL= %d\n", srds_s1);
#ifdef CONFIG_PFE_RGMII_RESET_WA
		/*
		 * Work around for FPGA registers initialization
		 * This is needed for RGMII to work.
		 */
		printf("Reset RGMII WA....\n");
		data8 = QIXIS_READ(rst_frc[0]);
		data8 |= 0x2;
		QIXIS_WRITE(rst_frc[0], data8);
		data8 = QIXIS_READ(rst_frc[0]);

		data8 = QIXIS_READ(res8[6]);
		data8 |= 0xff;
		QIXIS_WRITE(res8[6], data8);
		data8 = QIXIS_READ(res8[6]);
#endif
	if (priv->gemac_port) {
		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_RGMII);
		if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_RGMII)
		    < 0) {
			printf("Failed to register mdio for %s\n", mdio_name);
		}

		/* MAC2 */
		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_RGMII);
		bus = miiphy_get_dev_by_name(mdio_name);
		pfe_set_mdio(priv->gemac_port, bus);
		pfe_set_phy_address_mode(priv->gemac_port,
					 CONFIG_PFE_EMAC2_PHY_ADDR,
					 PHY_INTERFACE_MODE_RGMII);

	} else {
		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
		if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_SLOT1)
		< 0) {
			printf("Failed to register mdio for %s\n", mdio_name);
		}

		/* MAC1 */
		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
		bus = miiphy_get_dev_by_name(mdio_name);
		pfe_set_mdio(priv->gemac_port, bus);
		pfe_set_phy_address_mode(priv->gemac_port,
					 CONFIG_PFE_EMAC1_PHY_ADDR,
					 PHY_INTERFACE_MODE_SGMII);
	}

		break;

	case 0x2205:
		printf("ls1012aqds:supported SerDes PRCTL= %d\n", srds_s1);
		/*
		 * Work around for FPGA registers initialization
		 * This is needed for RGMII to work.
		 */
		printf("Reset SLOT1 SLOT2....\n");
		data8 = QIXIS_READ(rst_frc[2]);
		data8 |= 0xc0;
		QIXIS_WRITE(rst_frc[2], data8);
		mdelay(100);
		data8 = QIXIS_READ(rst_frc[2]);
		data8 &= 0x3f;
		QIXIS_WRITE(rst_frc[2], data8);

	if (priv->gemac_port) {
		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT2);
		if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_SLOT2)
		< 0) {
			printf("Failed to register mdio for %s\n", mdio_name);
		}
		/* MAC2 */
		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT2);
		bus = miiphy_get_dev_by_name(mdio_name);
		pfe_set_mdio(1, bus);
		pfe_set_phy_address_mode(1, CONFIG_PFE_SGMII_2500_PHY2_ADDR,
					 PHY_INTERFACE_MODE_SGMII_2500);

		data8 = QIXIS_READ(brdcfg[12]);
		data8 |= 0x20;
		QIXIS_WRITE(brdcfg[12], data8);

	} else {
		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
		if (ls1012aqds_mdio_init(DEFAULT_PFE_MDIO_NAME, EMI1_SLOT1)
		    < 0) {
			printf("Failed to register mdio for %s\n", mdio_name);
		}

		/* MAC1 */
		mdio_name = ls1012aqds_mdio_name_for_muxval(EMI1_SLOT1);
		bus = miiphy_get_dev_by_name(mdio_name);
		pfe_set_mdio(0, bus);
		pfe_set_phy_address_mode(0,
					 CONFIG_PFE_SGMII_2500_PHY1_ADDR,
					 PHY_INTERFACE_MODE_SGMII_2500);
	}
		break;

	default:
		printf("ls1012aqds:unsupported SerDes PRCTL= %d\n", srds_s1);
		break;
	}
	return 0;
}
Exemple #7
0
static int gpio_stm32_probe(struct udevice *dev)
{
	struct stm32_gpio_priv *priv = dev_get_priv(dev);
	struct clk clk;
	fdt_addr_t addr;
	int ret;

	addr = dev_read_addr(dev);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	priv->regs = (struct stm32_gpio_regs *)addr;

#ifndef CONFIG_SPL_BUILD
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct ofnode_phandle_args args;
	const char *name;
	int i;

	name = dev_read_string(dev, "st,bank-name");
	if (!name)
		return -EINVAL;
	uc_priv->bank_name = name;

	i = 0;
	ret = dev_read_phandle_with_args(dev, "gpio-ranges",
					 NULL, 3, i, &args);

	if (ret == -ENOENT) {
		uc_priv->gpio_count = STM32_GPIOS_PER_BANK;
		priv->gpio_range = GENMASK(STM32_GPIOS_PER_BANK - 1, 0);
	}

	while (ret != -ENOENT) {
		priv->gpio_range |= GENMASK(args.args[2] + args.args[0] - 1,
				    args.args[0]);

		uc_priv->gpio_count += args.args[2];

		ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3,
						 ++i, &args);
	}

	dev_dbg(dev, "addr = 0x%p bank_name = %s gpio_count = %d gpio_range = 0x%x\n",
		(u32 *)priv->regs, uc_priv->bank_name, uc_priv->gpio_count,
		priv->gpio_range);
#endif
	ret = clk_get_by_index(dev, 0, &clk);
	if (ret < 0)
		return ret;

	ret = clk_enable(&clk);

	if (ret) {
		dev_err(dev, "failed to enable clock\n");
		return ret;
	}
	debug("clock enabled for device %s\n", dev->name);

	return 0;
}
static int rockchip_spi_claim_bus(struct udevice *dev)
{
    struct udevice *bus = dev->parent;
    struct rockchip_spi_priv *priv = dev_get_priv(bus);
    struct rockchip_spi *regs = priv->regs;
    u8 spi_dfs, spi_tf;
    uint ctrlr0;

    /* Disable the SPI hardware */
    rkspi_enable_chip(regs, 0);

    switch (priv->bits_per_word) {
    case 8:
        priv->n_bytes = 1;
        spi_dfs = DFS_8BIT;
        spi_tf = HALF_WORD_OFF;
        break;
    case 16:
        priv->n_bytes = 2;
        spi_dfs = DFS_16BIT;
        spi_tf = HALF_WORD_ON;
        break;
    default:
        debug("%s: unsupported bits: %dbits\n", __func__,
              priv->bits_per_word);
        return -EPROTONOSUPPORT;
    }

    if (priv->speed_hz != priv->last_speed_hz)
        rkspi_set_clk(priv, priv->speed_hz);

    /* Operation Mode */
    ctrlr0 = OMOD_MASTER << OMOD_SHIFT;

    /* Data Frame Size */
    ctrlr0 |= spi_dfs << DFS_SHIFT;

    /* set SPI mode 0..3 */
    if (priv->mode & SPI_CPOL)
        ctrlr0 |= SCOL_HIGH << SCOL_SHIFT;
    if (priv->mode & SPI_CPHA)
        ctrlr0 |= SCPH_TOGSTA << SCPH_SHIFT;

    /* Chip Select Mode */
    ctrlr0 |= CSM_KEEP << CSM_SHIFT;

    /* SSN to Sclk_out delay */
    ctrlr0 |= SSN_DELAY_ONE << SSN_DELAY_SHIFT;

    /* Serial Endian Mode */
    ctrlr0 |= SEM_LITTLE << SEM_SHIFT;

    /* First Bit Mode */
    ctrlr0 |= FBM_MSB << FBM_SHIFT;

    /* Byte and Halfword Transform */
    ctrlr0 |= spi_tf << HALF_WORD_TX_SHIFT;

    /* Rxd Sample Delay */
    ctrlr0 |= 0 << RXDSD_SHIFT;

    /* Frame Format */
    ctrlr0 |= FRF_SPI << FRF_SHIFT;

    /* Tx and Rx mode */
    ctrlr0 |= (priv->tmode & TMOD_MASK) << TMOD_SHIFT;

    writel(ctrlr0, &regs->ctrlr0);

    return 0;
}
Exemple #9
0
static int musb_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
				unsigned long pipe, void *buffer, int length)
{
	struct musb_host_data *host = dev_get_priv(dev);
	return _musb_submit_bulk_msg(host, udev, pipe, buffer, length);
}
Exemple #10
0
/**
 * This is a very strange probe function. If it has platform data (which may
 * have come from the device tree) then this function gets the filename and
 * device type from there. Failing that it looks at the command line
 * parameter.
 */
static int sandbox_sf_probe(struct udevice *dev)
{
	/* spec = idcode:file */
	struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
	const char *file;
	size_t len, idname_len;
	const struct spi_flash_params *data;
	struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev);
	struct sandbox_state *state = state_get_current();
	struct udevice *bus = dev->parent;
	const char *spec = NULL;
	int ret = 0;
	int cs = -1;
	int i;

	debug("%s: bus %d, looking for emul=%p: ", __func__, bus->seq, dev);
	if (bus->seq >= 0 && bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS) {
		for (i = 0; i < CONFIG_SANDBOX_SPI_MAX_CS; i++) {
			if (state->spi[bus->seq][i].emul == dev)
				cs = i;
		}
	}
	if (cs == -1) {
		printf("Error: Unknown chip select for device '%s'",
		       dev->name);
		return -EINVAL;
	}
	debug("found at cs %d\n", cs);

	if (!pdata->filename) {
		struct sandbox_state *state = state_get_current();

		assert(bus->seq != -1);
		if (bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS)
			spec = state->spi[bus->seq][cs].spec;
		if (!spec)
			return -ENOENT;

		file = strchr(spec, ':');
		if (!file) {
			printf("sandbox_sf: unable to parse file\n");
			ret = -EINVAL;
			goto error;
		}
		idname_len = file - spec;
		pdata->filename = file + 1;
		pdata->device_name = spec;
		++file;
	} else {
		spec = strchr(pdata->device_name, ',');
		if (spec)
			spec++;
		else
			spec = pdata->device_name;
		idname_len = strlen(spec);
	}
	debug("%s: device='%s'\n", __func__, spec);

	for (data = spi_flash_params_table; data->name; data++) {
		len = strlen(data->name);
		if (idname_len != len)
			continue;
		if (!strncasecmp(spec, data->name, len))
			break;
	}
	if (!data->name) {
		printf("sandbox_sf: unknown flash '%*s'\n", (int)idname_len,
		       spec);
		ret = -EINVAL;
		goto error;
	}

	if (sandbox_sf_0xff[0] == 0x00)
		memset(sandbox_sf_0xff, 0xff, sizeof(sandbox_sf_0xff));

	sbsf->fd = os_open(pdata->filename, 02);
	if (sbsf->fd == -1) {
		free(sbsf);
		printf("sandbox_sf: unable to open file '%s'\n",
		       pdata->filename);
		ret = -EIO;
		goto error;
	}

	sbsf->data = data;
	sbsf->cs = cs;

	return 0;

 error:
	return ret;
}
Exemple #11
0
static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen,
			   const void *rxp, void *txp, unsigned long flags)
{
	struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
	const uint8_t *rx = rxp;
	uint8_t *tx = txp;
	uint cnt, pos = 0;
	int bytes = bitlen / 8;
	int ret;

	debug("sandbox_sf: state:%x(%s) bytes:%u\n", sbsf->state,
	      sandbox_sf_state_name(sbsf->state), bytes);

	if ((flags & SPI_XFER_BEGIN))
		sandbox_sf_cs_activate(dev);

	if (sbsf->state == SF_CMD) {
		/* Figure out the initial state */
		ret = sandbox_sf_process_cmd(sbsf, rx, tx);
		if (ret)
			return ret;
		++pos;
	}

	/* Process the remaining data */
	while (pos < bytes) {
		switch (sbsf->state) {
		case SF_ID: {
			u8 id;

			debug(" id: off:%u tx:", sbsf->off);
			if (sbsf->off < IDCODE_LEN) {
				/* Extract correct byte from ID 0x00aabbcc */
				id = sbsf->data->jedec >>
					(8 * (IDCODE_LEN - 1 - sbsf->off));
			} else {
				id = 0;
			}
			debug("%d %02x\n", sbsf->off, id);
			tx[pos++] = id;
			++sbsf->off;
			break;
		}
		case SF_ADDR:
			debug(" addr: bytes:%u rx:%02x ", sbsf->addr_bytes,
			      rx[pos]);

			if (sbsf->addr_bytes++ < SF_ADDR_LEN)
				sbsf->off = (sbsf->off << 8) | rx[pos];
			debug("addr:%06x\n", sbsf->off);

			if (tx)
				sandbox_spi_tristate(&tx[pos], 1);
			pos++;

			/* See if we're done processing */
			if (sbsf->addr_bytes <
					SF_ADDR_LEN + sbsf->pad_addr_bytes)
				break;

			/* Next state! */
			if (os_lseek(sbsf->fd, sbsf->off, OS_SEEK_SET) < 0) {
				puts("sandbox_sf: os_lseek() failed");
				return -EIO;
			}
			switch (sbsf->cmd) {
			case CMD_READ_ARRAY_FAST:
			case CMD_READ_ARRAY_SLOW:
				sbsf->state = SF_READ;
				break;
			case CMD_PAGE_PROGRAM:
				sbsf->state = SF_WRITE;
				break;
			default:
				/* assume erase state ... */
				sbsf->state = SF_ERASE;
				goto case_sf_erase;
			}
			debug(" cmd: transition to %s state\n",
			      sandbox_sf_state_name(sbsf->state));
			break;
		case SF_READ:
			/*
			 * XXX: need to handle exotic behavior:
			 *      - reading past end of device
			 */

			cnt = bytes - pos;
			debug(" tx: read(%u)\n", cnt);
			assert(tx);
			ret = os_read(sbsf->fd, tx + pos, cnt);
			if (ret < 0) {
				puts("sandbox_sf: os_read() failed\n");
				return -EIO;
			}
			pos += ret;
			break;
		case SF_READ_STATUS:
			debug(" read status: %#x\n", sbsf->status);
			cnt = bytes - pos;
			memset(tx + pos, sbsf->status, cnt);
			pos += cnt;
			break;
		case SF_READ_STATUS1:
			debug(" read status: %#x\n", sbsf->status);
			cnt = bytes - pos;
			memset(tx + pos, sbsf->status >> 8, cnt);
			pos += cnt;
			break;
		case SF_WRITE_STATUS:
			debug(" write status: %#x (ignored)\n", rx[pos]);
			pos = bytes;
			break;
		case SF_WRITE:
			/*
			 * XXX: need to handle exotic behavior:
			 *      - unaligned addresses
			 *      - more than a page (256) worth of data
			 *      - reading past end of device
			 */
			if (!(sbsf->status & STAT_WEL)) {
				puts("sandbox_sf: write enable not set before write\n");
				goto done;
			}

			cnt = bytes - pos;
			debug(" rx: write(%u)\n", cnt);
			if (tx)
				sandbox_spi_tristate(&tx[pos], cnt);
			ret = os_write(sbsf->fd, rx + pos, cnt);
			if (ret < 0) {
				puts("sandbox_spi: os_write() failed\n");
				return -EIO;
			}
			pos += ret;
			sbsf->status &= ~STAT_WEL;
			break;
		case SF_ERASE:
 case_sf_erase: {
			if (!(sbsf->status & STAT_WEL)) {
				puts("sandbox_sf: write enable not set before erase\n");
				goto done;
			}

			/* verify address is aligned */
			if (sbsf->off & (sbsf->erase_size - 1)) {
				debug(" sector erase: cmd:%#x needs align:%#x, but we got %#x\n",
				      sbsf->cmd, sbsf->erase_size,
				      sbsf->off);
				sbsf->status &= ~STAT_WEL;
				goto done;
			}

			debug(" sector erase addr: %u, size: %u\n", sbsf->off,
			      sbsf->erase_size);

			cnt = bytes - pos;
			if (tx)
				sandbox_spi_tristate(&tx[pos], cnt);
			pos += cnt;

			/*
			 * TODO([email protected]): latch WIP in status, and
			 * delay before clearing it ?
			 */
			ret = sandbox_erase_part(sbsf, sbsf->erase_size);
			sbsf->status &= ~STAT_WEL;
			if (ret) {
				debug("sandbox_sf: Erase failed\n");
				goto done;
			}
			goto done;
		}
		default:
			debug(" ??? no idea what to do ???\n");
			goto done;
		}
Exemple #12
0
int host_dev_bind(int devnum, char *filename)
{
	struct host_block_dev *host_dev;
	struct udevice *dev;
	char dev_name[20], *str, *fname;
	int ret, fd;

	/* Remove and unbind the old device, if any */
	ret = blk_get_device(IF_TYPE_HOST, devnum, &dev);
	if (ret == 0) {
		ret = device_remove(dev);
		if (ret)
			return ret;
		ret = device_unbind(dev);
		if (ret)
			return ret;
	} else if (ret != -ENODEV) {
		return ret;
	}

	if (!filename)
		return 0;

	snprintf(dev_name, sizeof(dev_name), "host%d", devnum);
	str = strdup(dev_name);
	if (!str)
		return -ENOMEM;
	fname = strdup(filename);
	if (!fname) {
		free(str);
		return -ENOMEM;
	}

	fd = os_open(filename, OS_O_RDWR);
	if (fd == -1) {
		printf("Failed to access host backing file '%s'\n", filename);
		ret = -ENOENT;
		goto err;
	}
	ret = blk_create_device(gd->dm_root, "sandbox_host_blk", str,
				IF_TYPE_HOST, devnum, 512,
				os_lseek(fd, 0, OS_SEEK_END), &dev);
	if (ret)
		goto err_file;
	ret = device_probe(dev);
	if (ret) {
		device_unbind(dev);
		goto err_file;
	}

	host_dev = dev_get_priv(dev);
	host_dev->fd = fd;
	host_dev->filename = fname;

	return blk_prepare_device(dev);
err_file:
	os_close(fd);
err:
	free(fname);
	free(str);
	return ret;
}
static int zynq_gem_init(struct udevice *dev)
{
	u32 i, nwconfig;
	int ret;
	unsigned long clk_rate = 0;
	struct zynq_gem_priv *priv = dev_get_priv(dev);
	struct zynq_gem_regs *regs = priv->iobase;
	struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC];
	struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2];

	if (!priv->init) {
		/* Disable all interrupts */
		writel(0xFFFFFFFF, &regs->idr);

		/* Disable the receiver & transmitter */
		writel(0, &regs->nwctrl);
		writel(0, &regs->txsr);
		writel(0, &regs->rxsr);
		writel(0, &regs->phymntnc);

		/* Clear the Hash registers for the mac address
		 * pointed by AddressPtr
		 */
		writel(0x0, &regs->hashl);
		/* Write bits [63:32] in TOP */
		writel(0x0, &regs->hashh);

		/* Clear all counters */
		for (i = 0; i < STAT_SIZE; i++)
			readl(&regs->stat[i]);

		/* Setup RxBD space */
		memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));

		for (i = 0; i < RX_BUF; i++) {
			priv->rx_bd[i].status = 0xF0000000;
			priv->rx_bd[i].addr =
					((ulong)(priv->rxbuffers) +
							(i * PKTSIZE_ALIGN));
		}
		/* WRAP bit to last BD */
		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
		/* Write RxBDs to IP */
		writel((ulong)priv->rx_bd, &regs->rxqbase);

		/* Setup for DMA Configuration register */
		writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);

		/* Setup for Network Control register, MDIO, Rx and Tx enable */
		setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK);

		/* Disable the second priority queue */
		dummy_tx_bd->addr = 0;
		dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
				ZYNQ_GEM_TXBUF_LAST_MASK|
				ZYNQ_GEM_TXBUF_USED_MASK;

		dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
				ZYNQ_GEM_RXBUF_NEW_MASK;
		dummy_rx_bd->status = 0;

		writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
		writel((ulong)dummy_rx_bd, &regs->receive_q1_ptr);

		priv->init++;
	}

	ret = phy_startup(priv->phydev);
	if (ret)
		return ret;

	if (!priv->phydev->link) {
		printf("%s: No link.\n", priv->phydev->dev->name);
		return -1;
	}

	nwconfig = ZYNQ_GEM_NWCFG_INIT;

	/*
	 * Set SGMII enable PCS selection only if internal PCS/PMA
	 * core is used and interface is SGMII.
	 */
	if (priv->interface == PHY_INTERFACE_MODE_SGMII &&
	    priv->int_pcs) {
		nwconfig |= ZYNQ_GEM_NWCFG_SGMII_ENBL |
			    ZYNQ_GEM_NWCFG_PCS_SEL;
#ifdef CONFIG_ARM64
		writel(readl(&regs->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL,
		       &regs->pcscntrl);
#endif
	}

	switch (priv->phydev->speed) {
	case SPEED_1000:
		writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED1000,
		       &regs->nwcfg);
		clk_rate = ZYNQ_GEM_FREQUENCY_1000;
		break;
	case SPEED_100:
		writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED100,
		       &regs->nwcfg);
		clk_rate = ZYNQ_GEM_FREQUENCY_100;
		break;
	case SPEED_10:
		clk_rate = ZYNQ_GEM_FREQUENCY_10;
		break;
	}

	ret = clk_set_rate(&priv->clk, clk_rate);
	if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) {
		dev_err(dev, "failed to set tx clock rate\n");
		return ret;
	}

	ret = clk_enable(&priv->clk);
	if (ret && ret != -ENOSYS) {
		dev_err(dev, "failed to enable tx clock\n");
		return ret;
	}

	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
					ZYNQ_GEM_NWCTRL_TXEN_MASK);

	return 0;
}
static int tegra20_sflash_xfer(struct udevice *dev, unsigned int bitlen,
			     const void *data_out, void *data_in,
			     unsigned long flags)
{
	struct udevice *bus = dev->parent;
	struct tegra20_sflash_priv *priv = dev_get_priv(bus);
	struct spi_regs *regs = priv->regs;
	u32 reg, tmpdout, tmpdin = 0;
	const u8 *dout = data_out;
	u8 *din = data_in;
	int num_bytes;
	int ret;

	debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
	      __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
	if (bitlen % 8)
		return -1;
	num_bytes = bitlen / 8;

	ret = 0;

	reg = readl(&regs->status);
	writel(reg, &regs->status);	/* Clear all SPI events via R/W */
	debug("spi_xfer entry: STATUS = %08x\n", reg);

	reg = readl(&regs->command);
	reg |= SPI_CMD_TXEN | SPI_CMD_RXEN;
	writel(reg, &regs->command);
	debug("spi_xfer: COMMAND = %08x\n", readl(&regs->command));

	if (flags & SPI_XFER_BEGIN)
		spi_cs_activate(dev);

	/* handle data in 32-bit chunks */
	while (num_bytes > 0) {
		int bytes;
		int is_read = 0;
		int tm, i;

		tmpdout = 0;
		bytes = (num_bytes > 4) ?  4 : num_bytes;

		if (dout != NULL) {
			for (i = 0; i < bytes; ++i)
				tmpdout = (tmpdout << 8) | dout[i];
		}

		num_bytes -= bytes;
		if (dout)
			dout += bytes;

		clrsetbits_le32(&regs->command, SPI_CMD_BIT_LENGTH_MASK,
				bytes * 8 - 1);
		writel(tmpdout, &regs->tx_fifo);
		setbits_le32(&regs->command, SPI_CMD_GO);

		/*
		 * Wait for SPI transmit FIFO to empty, or to time out.
		 * The RX FIFO status will be read and cleared last
		 */
		for (tm = 0, is_read = 0; tm < SPI_TIMEOUT; ++tm) {
			u32 status;

			status = readl(&regs->status);

			/* We can exit when we've had both RX and TX activity */
			if (is_read && (status & SPI_STAT_TXF_EMPTY))
				break;

			if ((status & (SPI_STAT_BSY | SPI_STAT_RDY)) !=
					SPI_STAT_RDY)
				tm++;

			else if (!(status & SPI_STAT_RXF_EMPTY)) {
				tmpdin = readl(&regs->rx_fifo);
				is_read = 1;

				/* swap bytes read in */
				if (din != NULL) {
					for (i = bytes - 1; i >= 0; --i) {
						din[i] = tmpdin & 0xff;
						tmpdin >>= 8;
					}
					din += bytes;
				}
			}
		}

		if (tm >= SPI_TIMEOUT)
			ret = tm;

		/* clear ACK RDY, etc. bits */
		writel(readl(&regs->status), &regs->status);
	}
Exemple #15
0
static int stm32_qspi_probe(struct udevice *bus)
{
	struct stm32_qspi_priv *priv = dev_get_priv(bus);
	struct resource res;
	struct clk clk;
	struct reset_ctl reset_ctl;
	int ret;

	ret = dev_read_resource_byname(bus, "qspi", &res);
	if (ret) {
		dev_err(bus, "can't get regs base addresses(ret = %d)!\n", ret);
		return ret;
	}

	priv->regs = (struct stm32_qspi_regs *)res.start;

	ret = dev_read_resource_byname(bus, "qspi_mm", &res);
	if (ret) {
		dev_err(bus, "can't get mmap base address(ret = %d)!\n", ret);
		return ret;
	}

	priv->mm_base = (void __iomem *)res.start;

	priv->mm_size = resource_size(&res);
	if (priv->mm_size > STM32_QSPI_MAX_MMAP_SZ)
		return -EINVAL;

	debug("%s: regs=<0x%p> mapped=<0x%p> mapped_size=<0x%lx>\n",
	      __func__, priv->regs, priv->mm_base, priv->mm_size);

	ret = clk_get_by_index(bus, 0, &clk);
	if (ret < 0)
		return ret;

	ret = clk_enable(&clk);
	if (ret) {
		dev_err(bus, "failed to enable clock\n");
		return ret;
	}

	priv->clock_rate = clk_get_rate(&clk);
	if (priv->clock_rate < 0) {
		clk_disable(&clk);
		return priv->clock_rate;
	}

	ret = reset_get_by_index(bus, 0, &reset_ctl);
	if (ret) {
		if (ret != -ENOENT) {
			dev_err(bus, "failed to get reset\n");
			clk_disable(&clk);
			return ret;
		}
	} else {
		/* Reset QSPI controller */
		reset_assert(&reset_ctl);
		udelay(2);
		reset_deassert(&reset_ctl);
	}

	priv->cs_used = -1;

	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT);

	/* Set dcr fsize to max address */
	setbits_le32(&priv->regs->dcr,
		     STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT);

	return 0;
}
Exemple #16
0
static int musb_destroy_int_queue(struct udevice *dev, struct usb_device *udev,
				  struct int_queue *queue)
{
	struct musb_host_data *host = dev_get_priv(dev);
	return _musb_destroy_int_queue(host, udev, queue);
}
Exemple #17
0
static int haswell_early_init(struct udevice *dev)
{
	struct broadwell_igd_priv *priv = dev_get_priv(dev);
	u8 *regs = priv->regs;
	int ret;

	/* Enable Force Wake */
	writel(0x00000020, regs + 0xa180);
	writel(0x00010001, regs + 0xa188);
	ret = poll32(regs + 0x130044, 1, 1);
	if (ret)
		goto err;

	/* Enable Counters */
	setbits_le32(regs + 0xa248, 0x00000016);

	/* GFXPAUSE settings */
	writel(0x00070020, regs + 0xa000);

	/* ECO Settings */
	clrsetbits_le32(regs + 0xa180, ~0xff3fffff, 0x15000000);

	/* Enable DOP Clock Gating */
	writel(0x000003fd, regs + 0x9424);

	/* Enable Unit Level Clock Gating */
	writel(0x00000080, regs + 0x9400);
	writel(0x40401000, regs + 0x9404);
	writel(0x00000000, regs + 0x9408);
	writel(0x02000001, regs + 0x940c);

	/*
	 * RC6 Settings
	 */

	/* Wake Rate Limits */
	setbits_le32(regs + 0xa090, 0x00000000);
	setbits_le32(regs + 0xa098, 0x03e80000);
	setbits_le32(regs + 0xa09c, 0x00280000);
	setbits_le32(regs + 0xa0a8, 0x0001e848);
	setbits_le32(regs + 0xa0ac, 0x00000019);

	/* Render/Video/Blitter Idle Max Count */
	writel(0x0000000a, regs + 0x02054);
	writel(0x0000000a, regs + 0x12054);
	writel(0x0000000a, regs + 0x22054);
	writel(0x0000000a, regs + 0x1a054);

	/* RC Sleep / RCx Thresholds */
	setbits_le32(regs + 0xa0b0, 0x00000000);
	setbits_le32(regs + 0xa0b4, 0x000003e8);
	setbits_le32(regs + 0xa0b8, 0x0000c350);

	/* RP Settings */
	setbits_le32(regs + 0xa010, 0x000f4240);
	setbits_le32(regs + 0xa014, 0x12060000);
	setbits_le32(regs + 0xa02c, 0x0000e808);
	setbits_le32(regs + 0xa030, 0x0003bd08);
	setbits_le32(regs + 0xa068, 0x000101d0);
	setbits_le32(regs + 0xa06c, 0x00055730);
	setbits_le32(regs + 0xa070, 0x0000000a);

	/* RP Control */
	writel(0x00000b92, regs + 0xa024);

	/* HW RC6 Control */
	writel(0x88040000, regs + 0xa090);

	/* Video Frequency Request */
	writel(0x08000000, regs + 0xa00c);

	/* Set RC6 VIDs */
	ret = poll32(regs + 0x138124, (1 << 31), 0);
	if (ret)
		goto err;
	writel(0, regs + 0x138128);
	writel(0x80000004, regs + 0x138124);
	ret = poll32(regs + 0x138124, (1 << 31), 0);
	if (ret)
		goto err;

	/* Enable PM Interrupts */
	writel(0x03000076, regs + 0x4402c);

	/* Enable RC6 in idle */
	writel(0x00040000, regs + 0xa094);

	return 0;
err:
	debug("%s: ret=%d\n", __func__, ret);
	return ret;
};
Exemple #18
0
static int musb_reset_root_port(struct udevice *dev, struct usb_device *udev)
{
	struct musb_host_data *host = dev_get_priv(dev);
	return _musb_reset_root_port(host, udev);
}
static int tpm_tis_i2c_send(struct udevice *dev, const u8 *buf, size_t len)
{
	struct tpm_chip *chip = dev_get_priv(dev);
	int rc, status;
	size_t burstcnt;
	size_t count = 0;
	int retry = 0;
	u8 sts = TPM_STS_GO;

	debug("%s: len=%d\n", __func__, len);
	if (len > TPM_DEV_BUFSIZE)
		return -E2BIG;  /* Command is too long for our tpm, sorry */

	if (tpm_tis_i2c_request_locality(dev, 0) < 0)
		return -EBUSY;

	status = tpm_tis_i2c_status(dev);
	if ((status & TPM_STS_COMMAND_READY) == 0) {
		rc = tpm_tis_i2c_ready(dev);
		if (rc)
			return rc;
		rc = tpm_tis_i2c_wait_for_stat(dev, TPM_STS_COMMAND_READY,
					       chip->timeout_b, &status);
		if (rc)
			return rc;
	}

	burstcnt = tpm_tis_i2c_get_burstcount(dev);

	/* burstcount < 0 -> tpm is busy */
	if (burstcnt < 0)
		return burstcnt;

	while (count < len) {
		udelay(300);
		if (burstcnt > len - count)
			burstcnt = len - count;

#ifdef CONFIG_TPM_TIS_I2C_BURST_LIMITATION
		if (retry && burstcnt > CONFIG_TPM_TIS_I2C_BURST_LIMITATION_LEN)
			burstcnt = CONFIG_TPM_TIS_I2C_BURST_LIMITATION_LEN;
#endif /* CONFIG_TPM_TIS_I2C_BURST_LIMITATION */

		rc = tpm_tis_i2c_write(dev, TPM_DATA_FIFO(chip->locality),
				       &(buf[count]), burstcnt);
		if (rc == 0)
			count += burstcnt;
		else {
			debug("%s: error\n", __func__);
			if (retry++ > 10)
				return -EIO;
			rc = tpm_tis_i2c_wait_for_stat(dev, TPM_STS_VALID,
						       chip->timeout_c,
						       &status);
			if (rc)
				return rc;

			if ((status & TPM_STS_DATA_EXPECT) == 0)
				return -EIO;
		}
	}

	/* Go and do it */
	rc = tpm_tis_i2c_write(dev, TPM_STS(chip->locality), &sts, 1);
	if (rc < 0)
		return rc;
	debug("%s: done, rc=%d\n", __func__, rc);

	return len;
}
Exemple #20
0
/*
 * The SOR power sequencer does not work for t124 so SW has to
 *  go through the power sequence manually
 * Power up steps from spec:
 * STEP	PDPORT	PDPLL	PDBG	PLLVCOD	PLLCAPD	E_DPD	PDCAL
 * 1	1	1	1	1	1	1	1
 * 2	1	1	1	1	1	0	1
 * 3	1	1	0	1	1	0	1
 * 4	1	0	0	0	0	0	1
 * 5	0	0	0	0	0	0	1
 */
static int tegra_dc_sor_power_up(struct udevice *dev, int is_lvds)
{
	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
	u32 reg;
	int ret;

	if (sor->power_is_up)
		return 0;

	/*
	 * If for some reason it is already powered up, don't do it again.
	 * This can happen if U-Boot is the secondary boot loader.
	 */
	reg = tegra_sor_readl(sor, DP_PADCTL(sor->portnum));
	if (reg & DP_PADCTL_PD_TXD_0_NO)
		return 0;

	/* Set link bw */
	tegra_dc_sor_set_link_bandwidth(dev, is_lvds ?
					CLK_CNTRL_DP_LINK_SPEED_LVDS :
					CLK_CNTRL_DP_LINK_SPEED_G1_62);

	/* step 1 */
	tegra_sor_write_field(sor, PLL2,
			      PLL2_AUX7_PORT_POWERDOWN_MASK | /* PDPORT */
			      PLL2_AUX6_BANDGAP_POWERDOWN_MASK | /* PDBG */
			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK, /* PLLCAPD */
			      PLL2_AUX7_PORT_POWERDOWN_ENABLE |
			      PLL2_AUX6_BANDGAP_POWERDOWN_ENABLE |
			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_ENABLE);
	tegra_sor_write_field(sor, PLL0, PLL0_PWR_MASK | /* PDPLL */
			      PLL0_VCOPD_MASK, /* PLLVCOPD */
			      PLL0_PWR_OFF | PLL0_VCOPD_ASSERT);
	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum),
			      DP_PADCTL_PAD_CAL_PD_POWERDOWN, /* PDCAL */
			      DP_PADCTL_PAD_CAL_PD_POWERDOWN);

	/* step 2 */
	ret = tegra_dc_sor_io_set_dpd(sor, 1);
	if (ret)
		return ret;
	udelay(15);

	/* step 3 */
	tegra_sor_write_field(sor, PLL2,
			      PLL2_AUX6_BANDGAP_POWERDOWN_MASK,
			      PLL2_AUX6_BANDGAP_POWERDOWN_DISABLE);
	udelay(25);

	/* step 4 */
	tegra_sor_write_field(sor, PLL0,
			      PLL0_PWR_MASK | /* PDPLL */
			      PLL0_VCOPD_MASK, /* PLLVCOPD */
			      PLL0_PWR_ON | PLL0_VCOPD_RESCIND);
	/* PLLCAPD */
	tegra_sor_write_field(sor, PLL2,
			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE);
	udelay(225);

	/* step 5 PDPORT */
	tegra_sor_write_field(sor, PLL2,
			      PLL2_AUX7_PORT_POWERDOWN_MASK,
			      PLL2_AUX7_PORT_POWERDOWN_DISABLE);

	sor->power_is_up = 1;

	return 0;
}
static int altera_tse_recv(struct udevice *dev, int flags, uchar **packetp)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);

	return priv->ops->recv(dev, flags, packetp);
}
Exemple #22
0
int tegra_dc_sor_enable_dp(struct udevice *dev,
			   const struct tegra_dp_link_config *link_cfg)
{
	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
	int ret;

	tegra_sor_write_field(sor, CLK_CNTRL,
			      CLK_CNTRL_DP_CLK_SEL_MASK,
			      CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK);

	tegra_sor_write_field(sor, PLL2,
			      PLL2_AUX6_BANDGAP_POWERDOWN_MASK,
			      PLL2_AUX6_BANDGAP_POWERDOWN_DISABLE);
	udelay(25);

	tegra_sor_write_field(sor, PLL3,
			      PLL3_PLLVDD_MODE_MASK,
			      PLL3_PLLVDD_MODE_V3_3);
	tegra_sor_writel(sor, PLL0,
			 0xf << PLL0_ICHPMP_SHFIT |
			 0x3 << PLL0_VCOCAP_SHIFT |
			 PLL0_PLLREG_LEVEL_V45 |
			 PLL0_RESISTORSEL_EXT |
			 PLL0_PWR_ON | PLL0_VCOPD_RESCIND);
	tegra_sor_write_field(sor, PLL2,
			      PLL2_AUX1_SEQ_MASK |
			      PLL2_AUX9_LVDSEN_OVERRIDE |
			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
			      PLL2_AUX1_SEQ_PLLCAPPD_OVERRIDE |
			      PLL2_AUX9_LVDSEN_OVERRIDE |
			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE);
	tegra_sor_writel(sor, PLL1, PLL1_TERM_COMPOUT_HIGH |
			 PLL1_TMDS_TERM_ENABLE);

	if (tegra_dc_sor_poll_register(sor, PLL2,
				       PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
				       PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE,
				       100, TEGRA_SOR_TIMEOUT_MS)) {
		printf("DP failed to lock PLL\n");
		return -EIO;
	}

	tegra_sor_write_field(sor, PLL2, PLL2_AUX2_MASK |
			      PLL2_AUX7_PORT_POWERDOWN_MASK,
			      PLL2_AUX2_OVERRIDE_POWERDOWN |
			      PLL2_AUX7_PORT_POWERDOWN_DISABLE);

	ret = tegra_dc_sor_power_up(dev, 0);
	if (ret) {
		debug("DP failed to power up\n");
		return ret;
	}

	/* re-enable SOR clock */
	clock_sor_enable_edp_clock();

	/* Power up lanes */
	tegra_dc_sor_power_dplanes(dev, link_cfg->lane_count, 1);

	tegra_dc_sor_set_dp_mode(dev, link_cfg);
	debug("%s ret\n", __func__);

	return 0;
}
int uniphier_sd_probe(struct udevice *dev)
{
	struct uniphier_sd_priv *priv = dev_get_priv(dev);
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	fdt_addr_t base;
	struct udevice *clk_dev;
	int clk_id;
	int ret;

	priv->dev = dev;

	base = dev_get_addr(dev);
	if (base == FDT_ADDR_T_NONE)
		return -EINVAL;

	priv->regbase = map_sysmem(base, SZ_2K);
	if (!priv->regbase)
		return -ENOMEM;

	clk_id = clk_get_by_index(dev, 0, &clk_dev);
	if (clk_id < 0) {
		dev_err(dev, "failed to get host clock\n");
		return clk_id;
	}

	/* set to max rate */
	priv->mclk = clk_set_periph_rate(clk_dev, clk_id, ULONG_MAX);
	if (IS_ERR_VALUE(priv->mclk)) {
		dev_err(dev, "failed to set rate for host clock\n");
		return priv->mclk;
	}

	ret = clk_enable(clk_dev, clk_id);
	if (ret) {
		dev_err(dev, "failed to enable host clock\n");
		return ret;
	}

	priv->cfg.name = dev->name;
	priv->cfg.ops = &uniphier_sd_ops;
	priv->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;

	switch (fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width", 1)) {
	case 8:
		priv->cfg.host_caps |= MMC_MODE_8BIT;
		break;
	case 4:
		priv->cfg.host_caps |= MMC_MODE_4BIT;
		break;
	case 1:
		break;
	default:
		dev_err(dev, "Invalid \"bus-width\" value\n");
		return -EINVAL;
	}

	if (fdt_get_property(gd->fdt_blob, dev->of_offset, "non-removable",
			     NULL))
		priv->caps |= UNIPHIER_SD_CAP_NONREMOVABLE;

	priv->version = readl(priv->regbase + UNIPHIER_SD_VERSION) &
							UNIPHIER_SD_VERSION_IP;
	dev_dbg(dev, "version %x\n", priv->version);
	if (priv->version >= 0x10) {
		priv->caps |= UNIPHIER_SD_CAP_DMA_INTERNAL;
		priv->caps |= UNIPHIER_SD_CAP_DIV1024;
	}

	priv->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
	priv->cfg.f_min = priv->mclk /
			(priv->caps & UNIPHIER_SD_CAP_DIV1024 ? 1024 : 512);
	priv->cfg.f_max = priv->mclk;
	priv->cfg.b_max = U32_MAX; /* max value of UNIPHIER_SD_SECCNT */

	priv->mmc = mmc_create(&priv->cfg, priv);
	if (!priv->mmc)
		return -EIO;

	upriv->mmc = priv->mmc;

	return 0;
}
Exemple #24
0
int tegra_dc_sor_attach(struct udevice *dc_dev, struct udevice *dev,
			const struct tegra_dp_link_config *link_cfg,
			const struct display_timing *timing)
{
	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
	struct dc_ctlr *disp_ctrl;
	u32 reg_val;

	/* Use the first display controller */
	debug("%s\n", __func__);
	disp_ctrl = (struct dc_ctlr *)dev_read_addr(dc_dev);

	tegra_dc_sor_enable_dc(disp_ctrl);
	tegra_dc_sor_config_panel(sor, 0, link_cfg, timing);

	writel(0x9f00, &disp_ctrl->cmd.state_ctrl);
	writel(0x9f, &disp_ctrl->cmd.state_ctrl);

	writel(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
	       PW4_ENABLE | PM0_ENABLE | PM1_ENABLE,
	       &disp_ctrl->cmd.disp_pow_ctrl);

	reg_val = tegra_sor_readl(sor, TEST);
	if (reg_val & TEST_ATTACHED_TRUE)
		return -EEXIST;

	tegra_sor_writel(sor, SUPER_STATE1,
			 SUPER_STATE1_ATTACHED_NO);

	/*
	 * Enable display2sor clock at least 2 cycles before DC start,
	 * to clear sor internal valid signal.
	 */
	writel(SOR_ENABLE, &disp_ctrl->disp.disp_win_opt);
	writel(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
	writel(0, &disp_ctrl->disp.disp_win_opt);
	writel(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);

	/* Attach head */
	tegra_dc_sor_update(sor);
	tegra_sor_writel(sor, SUPER_STATE1,
			 SUPER_STATE1_ATTACHED_YES);
	tegra_sor_writel(sor, SUPER_STATE1,
			 SUPER_STATE1_ATTACHED_YES |
			 SUPER_STATE1_ASY_HEAD_OP_AWAKE |
			 SUPER_STATE1_ASY_ORMODE_NORMAL);
	tegra_dc_sor_super_update(sor);

	/* Enable dc */
	reg_val = readl(&disp_ctrl->cmd.state_access);
	writel(reg_val | WRITE_MUX_ACTIVE, &disp_ctrl->cmd.state_access);
	writel(CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT,
	       &disp_ctrl->cmd.disp_cmd);
	writel(SOR_ENABLE, &disp_ctrl->disp.disp_win_opt);
	writel(reg_val, &disp_ctrl->cmd.state_access);

	if (tegra_dc_sor_poll_register(sor, TEST,
				       TEST_ACT_HEAD_OPMODE_DEFAULT_MASK,
				       TEST_ACT_HEAD_OPMODE_AWAKE,
				       100,
				       TEGRA_SOR_ATTACH_TIMEOUT_MS)) {
		printf("dc timeout waiting for OPMOD = AWAKE\n");
		return -ETIMEDOUT;
	} else {
		debug("%s: sor is attached\n", __func__);
	}

#if DEBUG_SOR
	dump_sor_reg(sor);
#endif
	debug("%s: ret=%d\n", __func__, 0);

	return 0;
}
Exemple #25
0
static int uniphier_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
				struct mmc_data *data)
{
	struct uniphier_sd_priv *priv = dev_get_priv(dev);
	int ret;
	u32 tmp;

	if (readl(priv->regbase + UNIPHIER_SD_INFO2) & UNIPHIER_SD_INFO2_CBSY) {
		dev_err(dev, "command busy\n");
		return -EBUSY;
	}

	/* clear all status flags */
	writel(0, priv->regbase + UNIPHIER_SD_INFO1);
	writel(0, priv->regbase + UNIPHIER_SD_INFO2);

	/* disable DMA once */
	tmp = readl(priv->regbase + UNIPHIER_SD_EXTMODE);
	tmp &= ~UNIPHIER_SD_EXTMODE_DMA_EN;
	writel(tmp, priv->regbase + UNIPHIER_SD_EXTMODE);

	writel(cmd->cmdarg, priv->regbase + UNIPHIER_SD_ARG);

	tmp = cmd->cmdidx;

	if (data) {
		writel(data->blocksize, priv->regbase + UNIPHIER_SD_SIZE);
		writel(data->blocks, priv->regbase + UNIPHIER_SD_SECCNT);

		/* Do not send CMD12 automatically */
		tmp |= UNIPHIER_SD_CMD_NOSTOP | UNIPHIER_SD_CMD_DATA;

		if (data->blocks > 1)
			tmp |= UNIPHIER_SD_CMD_MULTI;

		if (data->flags & MMC_DATA_READ)
			tmp |= UNIPHIER_SD_CMD_RD;
	}

	/*
	 * Do not use the response type auto-detection on this hardware.
	 * CMD8, for example, has different response types on SD and eMMC,
	 * while this controller always assumes the response type for SD.
	 * Set the response type manually.
	 */
	switch (cmd->resp_type) {
	case MMC_RSP_NONE:
		tmp |= UNIPHIER_SD_CMD_RSP_NONE;
		break;
	case MMC_RSP_R1:
		tmp |= UNIPHIER_SD_CMD_RSP_R1;
		break;
	case MMC_RSP_R1b:
		tmp |= UNIPHIER_SD_CMD_RSP_R1B;
		break;
	case MMC_RSP_R2:
		tmp |= UNIPHIER_SD_CMD_RSP_R2;
		break;
	case MMC_RSP_R3:
		tmp |= UNIPHIER_SD_CMD_RSP_R3;
		break;
	default:
		dev_err(dev, "unknown response type\n");
		return -EINVAL;
	}

	dev_dbg(dev, "sending CMD%d (SD_CMD=%08x, SD_ARG=%08x)\n",
		cmd->cmdidx, tmp, cmd->cmdarg);
	writel(tmp, priv->regbase + UNIPHIER_SD_CMD);

	ret = uniphier_sd_wait_for_irq(dev, UNIPHIER_SD_INFO1,
				       UNIPHIER_SD_INFO1_RSP);
	if (ret)
		return ret;

	if (cmd->resp_type & MMC_RSP_136) {
		u32 rsp_127_104 = readl(priv->regbase + UNIPHIER_SD_RSP76);
		u32 rsp_103_72 = readl(priv->regbase + UNIPHIER_SD_RSP54);
		u32 rsp_71_40 = readl(priv->regbase + UNIPHIER_SD_RSP32);
		u32 rsp_39_8 = readl(priv->regbase + UNIPHIER_SD_RSP10);

		cmd->response[0] = (rsp_127_104 & 0xffffff) << 8 |
							(rsp_103_72 & 0xff);
		cmd->response[1] = (rsp_103_72  & 0xffffff) << 8 |
							(rsp_71_40 & 0xff);
		cmd->response[2] = (rsp_71_40   & 0xffffff) << 8 |
							(rsp_39_8 & 0xff);
		cmd->response[3] = (rsp_39_8    & 0xffffff) << 8;
	} else {
		/* bit 39-8 */
		cmd->response[0] = readl(priv->regbase + UNIPHIER_SD_RSP10);
	}

	if (data) {
		/* use DMA if the HW supports it and the buffer is aligned */
		if (priv->caps & UNIPHIER_SD_CAP_DMA_INTERNAL &&
		    uniphier_sd_addr_is_dmaable((long)data->src))
			ret = uniphier_sd_dma_xfer(dev, data);
		else
			ret = uniphier_sd_pio_xfer(dev, data);

		ret = uniphier_sd_wait_for_irq(dev, UNIPHIER_SD_INFO1,
					       UNIPHIER_SD_INFO1_CMP);
		if (ret)
			return ret;
	}

	return ret;
}
Exemple #26
0
/**
 * This is a very strange probe function. If it has platform data (which may
 * have come from the device tree) then this function gets the filename and
 * device type from there.
 */
static int sandbox_sf_probe(struct udevice *dev)
{
	/* spec = idcode:file */
	struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
	size_t len, idname_len;
	const struct flash_info *data;
	struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev);
	struct sandbox_state *state = state_get_current();
	struct dm_spi_slave_platdata *slave_plat;
	struct udevice *bus = dev->parent;
	const char *spec = NULL;
	struct udevice *emul;
	int ret = 0;
	int cs = -1;

	debug("%s: bus %d, looking for emul=%p: ", __func__, bus->seq, dev);
	ret = sandbox_spi_get_emul(state, bus, dev, &emul);
	if (ret) {
		printf("Error: Unknown chip select for device '%s'\n",
			dev->name);
		return ret;
	}
	slave_plat = dev_get_parent_platdata(dev);
	cs = slave_plat->cs;
	debug("found at cs %d\n", cs);

	if (!pdata->filename) {
		printf("Error: No filename available\n");
		return -EINVAL;
	}
	spec = strchr(pdata->device_name, ',');
	if (spec)
		spec++;
	else
		spec = pdata->device_name;
	idname_len = strlen(spec);
	debug("%s: device='%s'\n", __func__, spec);

	for (data = spi_nor_ids; data->name; data++) {
		len = strlen(data->name);
		if (idname_len != len)
			continue;
		if (!strncasecmp(spec, data->name, len))
			break;
	}
	if (!data->name) {
		printf("%s: unknown flash '%*s'\n", __func__, (int)idname_len,
		       spec);
		ret = -EINVAL;
		goto error;
	}

	if (sandbox_sf_0xff[0] == 0x00)
		memset(sandbox_sf_0xff, 0xff, sizeof(sandbox_sf_0xff));

	sbsf->fd = os_open(pdata->filename, 02);
	if (sbsf->fd == -1) {
		printf("%s: unable to open file '%s'\n", __func__,
		       pdata->filename);
		ret = -EIO;
		goto error;
	}

	sbsf->data = data;
	sbsf->cs = cs;

	return 0;

 error:
	debug("%s: Got error %d\n", __func__, ret);
	return ret;
}