diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/clk/rockchip/clk_px30.c | 3 | ||||
| -rw-r--r-- | drivers/clk/rockchip/clk_rk3568.c | 11 | ||||
| -rw-r--r-- | drivers/mmc/rockchip_sdhci.c | 3 | ||||
| -rw-r--r-- | drivers/spi/rockchip_sfc.c | 149 | 
4 files changed, 89 insertions, 77 deletions
| diff --git a/drivers/clk/rockchip/clk_px30.c b/drivers/clk/rockchip/clk_px30.c index 617ce0dce5a..ea874e3f4b9 100644 --- a/drivers/clk/rockchip/clk_px30.c +++ b/drivers/clk/rockchip/clk_px30.c @@ -1291,6 +1291,9 @@ static ulong px30_clk_set_rate(struct clk *clk, ulong rate)  	case PLL_NPLL:  		ret = px30_clk_set_pll_rate(priv, NPLL, rate);  		break; +	case PLL_CPLL: +		ret = px30_clk_set_pll_rate(priv, CPLL, rate); +		break;  	case ARMCLK:  		ret = px30_armclk_set_clk(priv, rate);  		break; diff --git a/drivers/clk/rockchip/clk_rk3568.c b/drivers/clk/rockchip/clk_rk3568.c index 553c6c0dafb..d5e45e7602c 100644 --- a/drivers/clk/rockchip/clk_rk3568.c +++ b/drivers/clk/rockchip/clk_rk3568.c @@ -1441,6 +1441,7 @@ static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv,  	switch (rate) {  	case OSC_HZ: +	case 26 * MHz:  		src_clk = CLK_SDMMC_SEL_24M;  		break;  	case 400 * MHz: @@ -1507,7 +1508,7 @@ static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv)  	case SCLK_SFC_SEL_125M:  		return 125 * MHz;  	case SCLK_SFC_SEL_150M: -		return 150 * KHz; +		return 150 * MHz;  	default:  		return -ENOENT;  	} @@ -1534,7 +1535,7 @@ static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate)  	case 125 * MHz:  		src_clk = SCLK_SFC_SEL_125M;  		break; -	case 150 * KHz: +	case 150 * MHz:  		src_clk = SCLK_SFC_SEL_150M;  		break;  	default: @@ -2406,6 +2407,9 @@ static ulong rk3568_clk_get_rate(struct clk *clk)  	case BCLK_EMMC:  		rate = rk3568_emmc_get_bclk(priv);  		break; +	case TCLK_EMMC: +		rate = OSC_HZ; +		break;  #ifndef CONFIG_SPL_BUILD  	case ACLK_VOP:  		rate = rk3568_aclk_vop_get_clk(priv); @@ -2582,6 +2586,9 @@ static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate)  	case BCLK_EMMC:  		ret = rk3568_emmc_set_bclk(priv, rate);  		break; +	case TCLK_EMMC: +		ret = OSC_HZ; +		break;  #ifndef CONFIG_SPL_BUILD  	case ACLK_VOP:  		ret = rk3568_aclk_vop_set_clk(priv, rate); diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c index 1ac00587d44..278473899c7 100644 --- a/drivers/mmc/rockchip_sdhci.c +++ b/drivers/mmc/rockchip_sdhci.c @@ -143,6 +143,9 @@ static void rk3399_emmc_phy_power_on(struct rockchip_emmc_phy *phy, u32 clock)  	writel(RK_CLRSETBITS(3 << 12, freqsel << 12), &phy->emmcphy_con[0]);  	writel(RK_CLRSETBITS(1 << 1, 1 << 1), &phy->emmcphy_con[6]); +	/* REN Enable on STRB Line for HS400 */ +	writel(RK_CLRSETBITS(0, 1 << 9), &phy->emmcphy_con[2]); +  	read_poll_timeout(readl, &phy->emmcphy_status, dllrdy,  			  PHYCTRL_DLL_LOCK_WO_TMOUT(dllrdy), 1, 5000);  } diff --git a/drivers/spi/rockchip_sfc.c b/drivers/spi/rockchip_sfc.c index 4e2b861f224..e098addddca 100644 --- a/drivers/spi/rockchip_sfc.c +++ b/drivers/spi/rockchip_sfc.c @@ -116,6 +116,7 @@  /* Master trigger */  #define SFC_DMA_TRIGGER			0x80 +#define SFC_DMA_TRIGGER_START		1  /* Src or Dst addr for master */  #define SFC_DMA_ADDR			0x84 @@ -163,14 +164,12 @@  #define SFC_DMA_TRANS_THRETHOLD		(0x40)  /* Maximum clock values from datasheet suggest keeping clock value under - * 150MHz. No minimum or average value is suggested, but the U-boot BSP driver - * has a minimum of 10MHz and a default of 80MHz which seems reasonable. + * 150MHz. No minimum or average value is suggested.   */ -#define SFC_MIN_SPEED_HZ		(10 * 1000 * 1000) -#define SFC_DEFAULT_SPEED_HZ		(80 * 1000 * 1000) -#define SFC_MAX_SPEED_HZ		(150 * 1000 * 1000) +#define SFC_MAX_SPEED		(150 * 1000 * 1000)  struct rockchip_sfc { +	struct udevice *dev;  	void __iomem *regbase;  	struct clk hclk;  	struct clk clk; @@ -197,8 +196,6 @@ static int rockchip_sfc_reset(struct rockchip_sfc *sfc)  	/* Still need to clear the masked interrupt from RISR */  	writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR); -	debug("reset\n"); -  	return err;  } @@ -261,15 +258,11 @@ static int rockchip_sfc_probe(struct udevice *bus)  #if CONFIG_IS_ENABLED(CLK)  	ret = clk_enable(&sfc->hclk);  	if (ret) -		debug("Enable ahb clock fail %s: %d\n", bus->name, ret); +		dev_dbg(sfc->dev, "sfc Enable ahb clock fail %s: %d\n", bus->name, ret);  	ret = clk_enable(&sfc->clk);  	if (ret) -		debug("Enable clock fail for %s: %d\n", bus->name, ret); - -	ret = clk_set_rate(&sfc->clk, SFC_DEFAULT_SPEED_HZ); -	if (ret) -		debug("Could not set sfc clock for %s: %d\n", bus->name, ret); +		dev_dbg(sfc->dev, "sfc Enable clock fail for %s: %d\n", bus->name, ret);  #endif  	ret = rockchip_sfc_init(sfc); @@ -278,7 +271,8 @@ static int rockchip_sfc_probe(struct udevice *bus)  	sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);  	sfc->version = rockchip_sfc_get_version(sfc); -	sfc->speed = SFC_DEFAULT_SPEED_HZ; +	sfc->max_freq = SFC_MAX_SPEED; +	sfc->dev = bus;  	return 0; @@ -291,33 +285,38 @@ err_init:  	return ret;  } -static inline int rockchip_sfc_get_fifo_level(struct rockchip_sfc *sfc, int wr) +static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)  { -	u32 fsr = readl(sfc->regbase + SFC_FSR); -	int level; +	int ret = 0; +	u32 status; -	if (wr) -		level = (fsr & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT; -	else -		level = (fsr & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT; +	ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status, +				 status & SFC_FSR_TXLV_MASK, +				 timeout_us); +	if (ret) { +		dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n"); + +		return -ETIMEDOUT; +	} -	return level; +	return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;  } -static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int wr, u32 timeout) +static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)  { -	unsigned long tbase = get_timer(0); -	int level; +	int ret = 0; +	u32 status; -	while (!(level = rockchip_sfc_get_fifo_level(sfc, wr))) { -		if (get_timer(tbase) > timeout) { -			debug("%s fifo timeout\n", wr ? "write" : "read"); -			return -ETIMEDOUT; -		} -		udelay(1); +	ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status, +				 status & SFC_FSR_RXLV_MASK, +				 timeout_us); +	if (ret) { +		dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n"); + +		return -ETIMEDOUT;  	} -	return level; +	return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;  }  static void rockchip_sfc_adjust_op_work(struct spi_mem_op *op) @@ -411,11 +410,11 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,  	ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE;  	cmd |= plat->cs << SFC_CMD_CS_SHIFT; -	debug("addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n", -	      op->addr.nbytes, op->addr.buswidth, -	      op->dummy.nbytes, op->dummy.buswidth); -	debug("ctrl=%x cmd=%x addr=%llx len=%x\n", -	      ctrl, cmd, op->addr.val, len); +	dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n", +		op->addr.nbytes, op->addr.buswidth, +		op->dummy.nbytes, op->dummy.buswidth); +	dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n", +		ctrl, cmd, op->addr.val, len);  	writel(ctrl, sfc->regbase + SFC_CTRL);  	writel(cmd, sfc->regbase + SFC_CMD); @@ -435,7 +434,7 @@ static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int  	dwords = len >> 2;  	while (dwords) { -		tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000); +		tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);  		if (tx_level < 0)  			return tx_level;  		write_words = min_t(u32, tx_level, dwords); @@ -446,7 +445,7 @@ static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int  	/* write the rest non word aligned bytes */  	if (bytes) { -		tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000); +		tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);  		if (tx_level < 0)  			return tx_level;  		memcpy(&tmp, buf, bytes); @@ -467,7 +466,7 @@ static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)  	/* word aligned access only */  	dwords = len >> 2;  	while (dwords) { -		rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000); +		rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);  		if (rx_level < 0)  			return rx_level;  		read_words = min_t(u32, rx_level, dwords); @@ -478,7 +477,7 @@ static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)  	/* read the rest non word aligned bytes */  	if (bytes) { -		rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000); +		rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);  		if (rx_level < 0)  			return rx_level;  		tmp = readl(sfc->regbase + SFC_DATA); @@ -492,7 +491,7 @@ static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t d  {  	writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);  	writel((u32)dma_buf, sfc->regbase + SFC_DMA_ADDR); -	writel(0x1, sfc->regbase + SFC_DMA_TRIGGER); +	writel(SFC_DMA_TRIGGER_START, sfc->regbase + SFC_DMA_TRIGGER);  	return len;  } @@ -500,7 +499,7 @@ static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t d  static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc,  				       const struct spi_mem_op *op, u32 len)  { -	debug("xfer_poll len=%x\n", len); +	dev_dbg(sfc->dev, "sfc xfer_poll len=%x\n", len);  	if (op->data.dir == SPI_MEM_DATA_OUT)  		return rockchip_sfc_write_fifo(sfc, op->data.buf.out, len); @@ -516,7 +515,7 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,  	void *dma_buf;  	int ret; -	debug("xfer_dma len=%x\n", len); +	dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len);  	if (op->data.dir == SPI_MEM_DATA_OUT) {  		dma_buf = (void *)op->data.buf.out; @@ -539,19 +538,17 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,  static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us)  { -	unsigned long tbase = get_timer(0);  	int ret = 0; -	u32 timeout = timeout_us; - -	while (readl(sfc->regbase + SFC_SR) & SFC_SR_IS_BUSY) { -		if (get_timer(tbase) > timeout) { -			printf("wait sfc idle timeout\n"); -			rockchip_sfc_reset(sfc); +	u32 status; -			return -ETIMEDOUT; -		} +	ret = readl_poll_timeout(sfc->regbase + SFC_SR, status, +				 !(status & SFC_SR_IS_BUSY), +				 timeout_us); +	if (ret) { +		dev_err(sfc->dev, "wait sfc idle timeout\n"); +		rockchip_sfc_reset(sfc); -		udelay(1); +		ret = -EIO;  	}  	return ret; @@ -564,33 +561,16 @@ static int rockchip_sfc_exec_op(struct spi_slave *mem,  	u32 len = min_t(u32, op->data.nbytes, sfc->max_iosize);  	int ret; -#if CONFIG_IS_ENABLED(CLK) -	if (unlikely(mem->max_hz != sfc->speed)) { -		ret = clk_set_rate(&sfc->clk, clamp(mem->max_hz, (uint)SFC_MIN_SPEED_HZ, -						    (uint)SFC_MAX_SPEED_HZ)); -		if (ret < 0) { -			printf("set_freq=%dHz fail, check if it's the cru support level\n", -			       mem->max_hz); -			return ret; -		} - -		sfc->max_freq = mem->max_hz; -		sfc->speed = mem->max_hz; -		debug("set_freq=%dHz real_freq=%dHz\n", sfc->max_freq, sfc->speed); -	} -#endif -  	rockchip_sfc_adjust_op_work((struct spi_mem_op *)op); -  	rockchip_sfc_xfer_setup(sfc, mem, op, len);  	if (len) { -		if (likely(sfc->use_dma) && !(len & 0x3) && len >= SFC_DMA_TRANS_THRETHOLD) +		if (likely(sfc->use_dma) && len >= SFC_DMA_TRANS_THRETHOLD)  			ret = rockchip_sfc_xfer_data_dma(sfc, op, len);  		else  			ret = rockchip_sfc_xfer_data_poll(sfc, op, len);  		if (ret != len) { -			printf("xfer data failed ret %d dir %d\n", ret, op->data.dir); +			dev_err(sfc->dev, "xfer data failed ret %d dir %d\n", ret, op->data.dir);  			return -EIO;  		} @@ -604,13 +584,32 @@ static int rockchip_sfc_adjust_op_size(struct spi_slave *mem, struct spi_mem_op  	struct rockchip_sfc *sfc = dev_get_plat(mem->dev->parent);  	op->data.nbytes = min(op->data.nbytes, sfc->max_iosize); +  	return 0;  }  static int rockchip_sfc_set_speed(struct udevice *bus, uint speed)  { -	/* We set up speed later for each transmission. -	 */ +	struct rockchip_sfc *sfc = dev_get_plat(bus); + +	if (speed > sfc->max_freq) +		speed = sfc->max_freq; + +	if (speed == sfc->speed) +		return 0; + +#if CONFIG_IS_ENABLED(CLK) +	int ret = clk_set_rate(&sfc->clk, speed); + +	if (ret < 0) { +		dev_err(sfc->dev, "set_freq=%dHz fail, check if it's the cru support level\n", +			speed); +		return ret; +	} +	sfc->speed = speed; +#else +	dev_dbg(sfc->dev, "sfc failed, CLK not support\n"); +#endif  	return 0;  } | 
