From 9df731a176aab8e03b984b681b1bea01ccff6644 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 06 Nov 2023 07:23:06 +0000 Subject: [PATCH] rk3568 rt uboot init --- u-boot/drivers/mmc/dw_mmc.c | 78 ++++++++++++++++++++++++++++++++------- 1 files changed, 64 insertions(+), 14 deletions(-) diff --git a/u-boot/drivers/mmc/dw_mmc.c b/u-boot/drivers/mmc/dw_mmc.c index ae4a04d..aa31971 100644 --- a/u-boot/drivers/mmc/dw_mmc.c +++ b/u-boot/drivers/mmc/dw_mmc.c @@ -8,6 +8,7 @@ #include <common.h> #include <bouncebuf.h> +#include <div64.h> #include <errno.h> #include <malloc.h> #include <memalign.h> @@ -19,6 +20,7 @@ #endif #define PAGE_SIZE 4096 +#define MSEC_PER_SEC 1000ULL /* * Currently it supports read/write up to 8*8*4 Bytes per @@ -159,18 +161,62 @@ dwmci_writel(host, DWMCI_BYTCNT, data->blocksize * data->blocks); } -static unsigned int dwmci_get_timeout(struct mmc *mmc, const unsigned int size) +#ifdef CONFIG_SPL_BUILD +static unsigned int dwmci_get_drto(struct dwmci_host *host, + const unsigned int size) +{ + unsigned int drto_clks; + unsigned int drto_div; + unsigned int drto_ms; + + drto_clks = dwmci_readl(host, DWMCI_TMOUT) >> 8; + drto_div = (dwmci_readl(host, DWMCI_CLKDIV) & 0xff) * 2; + if (drto_div == 0) + drto_div = 1; + + drto_ms = DIV_ROUND_UP_ULL((u64)MSEC_PER_SEC * drto_clks * drto_div, + host->mmc->clock); + + /* add a bit spare time */ + drto_ms += 10; + + return drto_ms; +} +#else +static unsigned int dwmci_get_drto(struct dwmci_host *host, + const unsigned int size) { unsigned int timeout; timeout = size * 8; /* counting in bits */ timeout *= 10; /* wait 10 times as long */ - timeout /= mmc->clock; - timeout /= mmc->bus_width; + timeout /= host->mmc->clock; + timeout /= host->mmc->bus_width; timeout *= 1000; /* counting in msec */ timeout = (timeout < 10000) ? 10000 : timeout; return timeout; +} +#endif + +static unsigned int dwmci_get_cto(struct dwmci_host *host) +{ + unsigned int cto_clks; + unsigned int cto_div; + unsigned int cto_ms; + + cto_clks = dwmci_readl(host, DWMCI_TMOUT) & 0xff; + cto_div = (dwmci_readl(host, DWMCI_CLKDIV) & 0xff) * 2; + if (cto_div == 0) + cto_div = 1; + + cto_ms = DIV_ROUND_UP_ULL((u64)MSEC_PER_SEC * cto_clks * cto_div, + host->mmc->clock); + + /* add a bit spare time */ + cto_ms += 10; + + return cto_ms; } static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) @@ -192,7 +238,7 @@ else buf = (unsigned int *)data->src; - timeout = dwmci_get_timeout(host->mmc, size); + timeout = dwmci_get_drto(host, size); size /= 4; for (;;) { @@ -252,6 +298,7 @@ } dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_RXDR); + start = get_timer(0); } else if (data->flags == MMC_DATA_WRITE && (mask & DWMCI_INTMSK_TXDR)) { while (size) { @@ -281,6 +328,7 @@ } dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_TXDR); + start = get_timer(0); } } @@ -329,9 +377,8 @@ struct dwmci_host *host = mmc->priv; ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, data ? DIV_ROUND_UP(data->blocks, 8) : 0); - int ret = 0, flags = 0, i; + int ret = 0, flags = 0; unsigned int timeout = 500; - u32 retry = 100000; u32 mask, ctrl; ulong start = get_timer(0); struct bounce_buffer bbstate; @@ -400,16 +447,18 @@ dwmci_writel(host, DWMCI_CMD, flags); - for (i = 0; i < retry; i++) { + timeout = dwmci_get_cto(host); + start = get_timer(0); + do { mask = dwmci_readl(host, DWMCI_RINTSTS); if (mask & DWMCI_INTMSK_CDONE) { if (!data) dwmci_writel(host, DWMCI_RINTSTS, mask); break; } - } + } while (!(get_timer(start) > timeout)); - if (i == retry) { + if (get_timer(start) > timeout) { debug("%s: Timeout.\n", __func__); return -ETIMEDOUT; } @@ -470,9 +519,8 @@ #endif struct dwmci_host *host = mmc->priv; struct dwmci_idmac *cur_idmac; - int ret = 0, flags = 0, i; + int ret = 0, flags = 0; unsigned int timeout = 500; - u32 retry = 100000; u32 mask; ulong start = get_timer(0); struct bounce_buffer bbstate; @@ -541,16 +589,18 @@ dwmci_writel(host, DWMCI_CMD, flags); - for (i = 0; i < retry; i++) { + timeout = dwmci_get_cto(host); + start = get_timer(0); + do { mask = dwmci_readl(host, DWMCI_RINTSTS); if (mask & DWMCI_INTMSK_CDONE) { if (!data) dwmci_writel(host, DWMCI_RINTSTS, mask); break; } - } + } while (!(get_timer(start) > timeout)); - if (i == retry) { + if (get_timer(start) > timeout) { debug("%s: Timeout.\n", __func__); return -ETIMEDOUT; } -- Gitblit v1.6.2