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, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, false, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Disable synchronization */ writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, false, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Disable pixel clock */ writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, false, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Disable PWM */ writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->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, ®s->lcdc_lcdcfg0); } else { writel(LCDC_LCDCFG0_CLKDIV(value - 2) | LCDC_LCDCFG0_CGDISHCR | LCDC_LCDCFG0_CGDISHEO | LCDC_LCDCFG0_CGDISOVR1 | LCDC_LCDCFG0_CGDISBASE | vl_clk_pol, ®s->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, ®s->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, ®s->lcdc_lcdcfg1); value = LCDC_LCDCFG2_VBPW(timing->vback_porch.typ); value |= LCDC_LCDCFG2_VFPW(timing->vfront_porch.typ - 1); writel(value, ®s->lcdc_lcdcfg2); value = LCDC_LCDCFG3_HBPW(timing->hback_porch.typ - 1); value |= LCDC_LCDCFG3_HFPW(timing->hfront_porch.typ - 1); writel(value, ®s->lcdc_lcdcfg3); /* Display size */ value = LCDC_LCDCFG4_RPF(timing->vactive.typ - 1); value |= LCDC_LCDCFG4_PPL(timing->hactive.typ - 1); writel(value, ®s->lcdc_lcdcfg4); writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO, ®s->lcdc_basecfg0); switch (VNBITS(priv->vl_bpix)) { case 16: writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565, ®s->lcdc_basecfg1); break; case 32: writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888, ®s->lcdc_basecfg1); break; default: BUG(); break; } writel(LCDC_BASECFG2_XSTRIDE(0), ®s->lcdc_basecfg2); writel(0, ®s->lcdc_basecfg3); writel(LCDC_BASECFG4_DMA, ®s->lcdc_basecfg4); /* Disable all interrupts */ writel(~0UL, ®s->lcdc_lcdidr); writel(~0UL, ®s->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, ®s->lcdc_baseaddr); writel(desc->control, ®s->lcdc_basectrl); writel(desc->next, ®s->lcdc_basenext); writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN, ®s->lcdc_basecher); /* Enable LCD */ value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); }
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(®s->status) & ALTERA_SPI_STATUS_RRDY_MSK) readl(®s->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, ®s->txdata); start = get_timer(0); while (1) { reg = readl(®s->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(®s->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; }
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; }
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, ®s->ctrlr0); return 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); }
/** * 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; }
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; }
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, ®s->idr); /* Disable the receiver & transmitter */ writel(0, ®s->nwctrl); writel(0, ®s->txsr); writel(0, ®s->rxsr); writel(0, ®s->phymntnc); /* Clear the Hash registers for the mac address * pointed by AddressPtr */ writel(0x0, ®s->hashl); /* Write bits [63:32] in TOP */ writel(0x0, ®s->hashh); /* Clear all counters */ for (i = 0; i < STAT_SIZE; i++) readl(®s->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, ®s->rxqbase); /* Setup for DMA Configuration register */ writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); /* Setup for Network Control register, MDIO, Rx and Tx enable */ setbits_le32(®s->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, ®s->transmit_q1_ptr); writel((ulong)dummy_rx_bd, ®s->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(®s->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL, ®s->pcscntrl); #endif } switch (priv->phydev->speed) { case SPEED_1000: writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED1000, ®s->nwcfg); clk_rate = ZYNQ_GEM_FREQUENCY_1000; break; case SPEED_100: writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED100, ®s->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(®s->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(®s->status); writel(reg, ®s->status); /* Clear all SPI events via R/W */ debug("spi_xfer entry: STATUS = %08x\n", reg); reg = readl(®s->command); reg |= SPI_CMD_TXEN | SPI_CMD_RXEN; writel(reg, ®s->command); debug("spi_xfer: COMMAND = %08x\n", readl(®s->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(®s->command, SPI_CMD_BIT_LENGTH_MASK, bytes * 8 - 1); writel(tmpdout, ®s->tx_fifo); setbits_le32(®s->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(®s->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(®s->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(®s->status), ®s->status); }
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; }
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); }
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; };
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; }
/* * 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); }
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; }
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; }
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; }
/** * 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; }