You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
memory: rockchip: dsmc: fix io width config error
The io_width in diff cs should set the same value at the same time. Change-Id: I2a872ba487bde9aa56f0a3490acbb526a1521475 Signed-off-by: Zhihuan He <huan.he@rock-chips.com>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
#include <linux/cacheflush.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
@@ -110,19 +111,21 @@ static uint32_t cap_2_dev_size(uint32_t cap)
|
||||
|
||||
static int dsmc_psram_id_detect(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
{
|
||||
uint32_t tmp, i;
|
||||
uint32_t tmp[DSMC_MAX_SLAVE_NUM], i;
|
||||
int ret = -1;
|
||||
struct dsmc_map *region_map = &dsmc->cs_map[cs].region_map[0];
|
||||
struct dsmc_config_cs *cfg = &dsmc->cfg.cs_cfg[cs];
|
||||
|
||||
tmp = readl(dsmc->regs + DSMC_MCR(cs));
|
||||
for (i = 0; i < DSMC_MAX_SLAVE_NUM; i++) {
|
||||
tmp[i] = readl(dsmc->regs + DSMC_MCR(i));
|
||||
|
||||
/* config to CR space */
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(cs),
|
||||
(MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_MASK << MCR_CRT_SHIFT),
|
||||
(MCR_IOWIDTH_X8 << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_CR_SPACE << MCR_CRT_SHIFT));
|
||||
/* config to CR space */
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(i),
|
||||
(MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_MASK << MCR_CRT_SHIFT),
|
||||
(MCR_IOWIDTH_X8 << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_CR_SPACE << MCR_CRT_SHIFT));
|
||||
}
|
||||
|
||||
if (cfg->protcl == OPI_XCCELA_PSRAM) {
|
||||
uint8_t mid;
|
||||
@@ -157,15 +160,17 @@ static int dsmc_psram_id_detect(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
}
|
||||
}
|
||||
|
||||
/* config to memory space */
|
||||
writel(tmp, dsmc->regs + DSMC_MCR(cs));
|
||||
for (i = 0; i < DSMC_MAX_SLAVE_NUM; i++)
|
||||
/* config to memory space */
|
||||
writel(tmp[i], dsmc->regs + DSMC_MCR(i));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dsmc_psram_bw_detect(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
{
|
||||
uint32_t tmp, col;
|
||||
uint32_t i;
|
||||
uint32_t tmp[DSMC_MAX_SLAVE_NUM], col;
|
||||
uint16_t ir0_ir1;
|
||||
struct dsmc_map *region_map = &dsmc->cs_map[cs].region_map[0];
|
||||
struct dsmc_config_cs *cfg = &dsmc->cfg.cs_cfg[cs];
|
||||
@@ -177,13 +182,15 @@ static void dsmc_psram_bw_detect(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
else
|
||||
cfg->io_width = MCR_IOWIDTH_X8;
|
||||
} else {
|
||||
tmp = readl(dsmc->regs + DSMC_MCR(cs));
|
||||
/* config to CR space */
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(cs),
|
||||
(MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_MASK << MCR_CRT_SHIFT),
|
||||
(MCR_IOWIDTH_X8 << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_CR_SPACE << MCR_CRT_SHIFT));
|
||||
for (i = 0; i < DSMC_MAX_SLAVE_NUM; i++) {
|
||||
tmp[i] = readl(dsmc->regs + DSMC_MCR(i));
|
||||
/* config to CR space */
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(i),
|
||||
(MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_MASK << MCR_CRT_SHIFT),
|
||||
(MCR_IOWIDTH_X8 << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_CR_SPACE << MCR_CRT_SHIFT));
|
||||
}
|
||||
|
||||
/* hyper psram get IR0 */
|
||||
ir0_ir1 = hyper_read_mr(region_map, HYPER_PSRAM_IR0);
|
||||
@@ -195,8 +202,9 @@ static void dsmc_psram_bw_detect(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
else
|
||||
cfg->io_width = MCR_IOWIDTH_X8;
|
||||
|
||||
/* config to memory space */
|
||||
writel(tmp, dsmc->regs + DSMC_MCR(cs));
|
||||
for (i = 0; i < DSMC_MAX_SLAVE_NUM; i++)
|
||||
/* config to memory space */
|
||||
writel(tmp[i], dsmc->regs + DSMC_MCR(i));
|
||||
|
||||
}
|
||||
cfg->col = col;
|
||||
@@ -206,6 +214,7 @@ static int dsmc_psram_dectect(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
int ret = -1;
|
||||
struct device *dev = dsmc->dev;
|
||||
struct dsmc_config_cs *cfg = &dsmc->cfg.cs_cfg[cs];
|
||||
|
||||
/* axi read do not response error */
|
||||
@@ -229,7 +238,7 @@ static int dsmc_psram_dectect(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
cfg->protcl = psram_info[i].protcl;
|
||||
cfg->mtr_timing = psram_info[i].mtr_timing;
|
||||
if (!dsmc_psram_id_detect(dsmc, cs)) {
|
||||
pr_info("DSMC: The cs%d %s PSRAM ID: 0x%x\n", cs,
|
||||
dev_info(dev, "The cs%d %s PSRAM ID: 0x%x\n", cs,
|
||||
(cfg->protcl == OPI_XCCELA_PSRAM) ? "XCCELA" : "HYPER",
|
||||
psram_info[i].id);
|
||||
ret = 0;
|
||||
@@ -237,7 +246,7 @@ static int dsmc_psram_dectect(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
}
|
||||
}
|
||||
if (i == ARRAY_SIZE(psram_info)) {
|
||||
pr_err("DSMC: Unknown PSRAM device\n");
|
||||
dev_err(dev, "Unknown PSRAM device\n");
|
||||
ret = -1;
|
||||
} else {
|
||||
dsmc_psram_bw_detect(dsmc, cs);
|
||||
@@ -315,6 +324,7 @@ static int dsmc_slv_cmn_rgn_config(struct rockchip_dsmc *dsmc,
|
||||
uint32_t rgn, uint32_t cs)
|
||||
{
|
||||
uint32_t tmp;
|
||||
struct device *dev = dsmc->dev;
|
||||
struct dsmc_map *region_map = &dsmc->cs_map[cs].region_map[0];
|
||||
struct dsmc_config_cs *cfg = &dsmc->cfg.cs_cfg[cs];
|
||||
|
||||
@@ -324,21 +334,21 @@ static int dsmc_slv_cmn_rgn_config(struct rockchip_dsmc *dsmc,
|
||||
} else if (slv_rgn->dummy_clk_num == 1) {
|
||||
tmp |= slv_rgn->dummy_clk_num << WR_DATA_CYC_EXTENDED_SHIFT;
|
||||
} else {
|
||||
pr_err("DSMC: lb slave: dummy clk too large\n");
|
||||
dev_err(dev, "lb slave: dummy clk too large\n");
|
||||
return -1;
|
||||
}
|
||||
tmp &= ~(RD_LATENCY_CYC_MASK << RD_LATENCY_CYC_SHIFT);
|
||||
if ((cfg->rd_latency == 1) || (cfg->rd_latency == 2)) {
|
||||
tmp |= cfg->rd_latency << RD_LATENCY_CYC_SHIFT;
|
||||
} else {
|
||||
pr_err("DSMC: lb slave: read latency value error\n");
|
||||
dev_err(dev, "lb slave: read latency value error\n");
|
||||
return -1;
|
||||
}
|
||||
tmp &= ~(WR_LATENCY_CYC_MASK << WR_LATENCY_CYC_SHIFT);
|
||||
if ((cfg->wr_latency == 1) || (cfg->wr_latency == 2)) {
|
||||
tmp |= cfg->wr_latency << WR_LATENCY_CYC_SHIFT;
|
||||
} else {
|
||||
pr_err("DSMC: lb slave: write latency value error\n");
|
||||
dev_err(dev, "lb slave: write latency value error\n");
|
||||
return -1;
|
||||
}
|
||||
tmp &= ~(CA_CYC_MASK << CA_CYC_SHIFT);
|
||||
@@ -356,6 +366,7 @@ static int dsmc_slv_cmn_config(struct rockchip_dsmc *dsmc,
|
||||
struct regions_config *slv_rgn, uint32_t cs)
|
||||
{
|
||||
uint32_t tmp;
|
||||
struct device *dev = dsmc->dev;
|
||||
struct dsmc_map *region_map = &dsmc->cs_map[cs].region_map[0];
|
||||
struct dsmc_config_cs *cfg = &dsmc->cfg.cs_cfg[cs];
|
||||
|
||||
@@ -371,7 +382,7 @@ static int dsmc_slv_cmn_config(struct rockchip_dsmc *dsmc,
|
||||
} else if (slv_rgn->dummy_clk_num == 1) {
|
||||
tmp |= slv_rgn->dummy_clk_num << WR_DATA_CYC_EXTENDED_SHIFT;
|
||||
} else {
|
||||
pr_err("DSMC: lb slave: dummy clk too large\n");
|
||||
dev_err(dev, "lb slave: dummy clk too large\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -388,18 +399,20 @@ static int dsmc_slv_cmn_config(struct rockchip_dsmc *dsmc,
|
||||
|
||||
static int dsmc_lb_cmn_config(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
{
|
||||
uint32_t tmp, i;
|
||||
uint32_t tmp[DSMC_MAX_SLAVE_NUM], i;
|
||||
struct dsmc_config_cs *cfg = &dsmc->cfg.cs_cfg[cs];
|
||||
struct regions_config *slv_rgn;
|
||||
int ret = 0;
|
||||
|
||||
tmp = readl(dsmc->regs + DSMC_MCR(cs));
|
||||
/* config to CR space */
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(cs),
|
||||
(MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_MASK << MCR_CRT_SHIFT),
|
||||
(MCR_IOWIDTH_X8 << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_CR_SPACE << MCR_CRT_SHIFT));
|
||||
for (i = 0; i < DSMC_MAX_SLAVE_NUM; i++) {
|
||||
tmp[i] = readl(dsmc->regs + DSMC_MCR(i));
|
||||
/* config to CR space */
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(i),
|
||||
(MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_MASK << MCR_CRT_SHIFT),
|
||||
(MCR_IOWIDTH_X8 << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_CR_SPACE << MCR_CRT_SHIFT));
|
||||
}
|
||||
|
||||
for (i = 0; i < DSMC_LB_MAX_RGN; i++) {
|
||||
slv_rgn = &cfg->slv_rgn[i];
|
||||
@@ -413,8 +426,9 @@ static int dsmc_lb_cmn_config(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
slv_rgn = &cfg->slv_rgn[0];
|
||||
ret = dsmc_slv_cmn_config(dsmc, slv_rgn, cs);
|
||||
|
||||
/* config to memory space */
|
||||
writel(tmp, dsmc->regs + DSMC_MCR(cs));
|
||||
for (i = 0; i < DSMC_MAX_SLAVE_NUM; i++)
|
||||
/* config to memory space */
|
||||
writel(tmp[i], dsmc->regs + DSMC_MCR(i));
|
||||
|
||||
for (i = 0; i < DSMC_LB_MAX_RGN; i++) {
|
||||
slv_rgn = &cfg->slv_rgn[i];
|
||||
@@ -472,17 +486,20 @@ static void dsmc_cfg_latency(uint32_t rd_ltcy, uint32_t wr_ltcy,
|
||||
|
||||
static int dsmc_psram_cfg(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
{
|
||||
uint32_t latency, mcr, tmp;
|
||||
uint32_t i;
|
||||
uint32_t latency, mcr[DSMC_MAX_SLAVE_NUM], tmp;
|
||||
struct dsmc_map *region_map = &dsmc->cs_map[cs].region_map[0];
|
||||
struct dsmc_config_cs *cs_cfg = &dsmc->cfg.cs_cfg[cs];
|
||||
|
||||
mcr = readl(dsmc->regs + DSMC_MCR(cs));
|
||||
/* config to CR space */
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(cs),
|
||||
(MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_MASK << MCR_CRT_SHIFT),
|
||||
(MCR_IOWIDTH_X8 << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_CR_SPACE << MCR_CRT_SHIFT));
|
||||
for (i = 0; i < DSMC_MAX_SLAVE_NUM; i++) {
|
||||
mcr[i] = readl(dsmc->regs + DSMC_MCR(i));
|
||||
/* config to CR space */
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(i),
|
||||
(MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_MASK << MCR_CRT_SHIFT),
|
||||
(MCR_IOWIDTH_X8 << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_CRT_CR_SPACE << MCR_CRT_SHIFT));
|
||||
}
|
||||
if (cs_cfg->protcl == OPI_XCCELA_PSRAM) {
|
||||
/* Xccela psram init */
|
||||
uint8_t mr_tmp, rbxen;
|
||||
@@ -586,8 +603,9 @@ static int dsmc_psram_cfg(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
(CR1_CLOCK_TYPE_DIFF_CLK << CR1_CLOCK_TYPE_SHIFT);
|
||||
hyper_write_mr(region_map, HYPER_PSRAM_CR1, cr_tmp);
|
||||
}
|
||||
/* config to memory space */
|
||||
writel(mcr, dsmc->regs + DSMC_MCR(cs));
|
||||
for (i = 0; i < DSMC_MAX_SLAVE_NUM; i++)
|
||||
/* config to memory space */
|
||||
writel(mcr[i], dsmc->regs + DSMC_MCR(i));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -596,6 +614,7 @@ static int dsmc_psram_cfg(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
static int dsmc_psram_init(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
{
|
||||
uint32_t latency;
|
||||
struct device *dev = dsmc->dev;
|
||||
struct dsmc_config_cs *cs_cfg = &dsmc->cfg.cs_cfg[cs];
|
||||
uint32_t mhz = dsmc->cfg.freq_hz / MHZ;
|
||||
|
||||
@@ -610,7 +629,7 @@ static int dsmc_psram_init(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
} else if (mhz <= 200) {
|
||||
latency = 7;
|
||||
} else {
|
||||
pr_err("DSMC: PSRAM frequency do not support!\n");
|
||||
dev_err(dev, "PSRAM frequency do not support!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -649,6 +668,7 @@ static int dsmc_ctrller_cfg_for_psram(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
|
||||
static void dsmc_psram_remodify_timing(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t max_length = 511, tcmd = 3;
|
||||
uint32_t tcsm, tmp;
|
||||
uint32_t mhz = dsmc->cfg.freq_hz / MHZ;
|
||||
@@ -673,13 +693,16 @@ static void dsmc_psram_remodify_timing(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
if (tmp > max_length)
|
||||
tmp = max_length;
|
||||
|
||||
for (i = 0; i < DSMC_MAX_SLAVE_NUM; i++)
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(i),
|
||||
MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT,
|
||||
cs_cfg->io_width << MCR_IOWIDTH_SHIFT);
|
||||
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(cs),
|
||||
(MCR_MAXEN_MASK << MCR_MAXEN_SHIFT) |
|
||||
(MCR_MAXLEN_MASK << MCR_MAXLEN_SHIFT) |
|
||||
(MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT),
|
||||
(MCR_MAXLEN_MASK << MCR_MAXLEN_SHIFT),
|
||||
(MCR_MAX_LENGTH_EN << MCR_MAXEN_SHIFT) |
|
||||
(tmp << MCR_MAXLEN_SHIFT) |
|
||||
(cs_cfg->io_width << MCR_IOWIDTH_SHIFT));
|
||||
(tmp << MCR_MAXLEN_SHIFT));
|
||||
|
||||
if (cs_cfg->io_width == MCR_IOWIDTH_X16)
|
||||
tmp = cs_cfg->col - 2;
|
||||
@@ -797,6 +820,7 @@ int rockchip_dsmc_dll_training(struct rockchip_dsmc_device *priv)
|
||||
int dll, dll_step = 10;
|
||||
struct dsmc_config_cs *cfg;
|
||||
struct rockchip_dsmc *dsmc = &priv->dsmc;
|
||||
struct device *dev = dsmc->dev;
|
||||
int ret;
|
||||
|
||||
for (cs = 0; cs < DSMC_MAX_SLAVE_NUM; cs++) {
|
||||
@@ -832,11 +856,11 @@ int rockchip_dsmc_dll_training(struct rockchip_dsmc_device *priv)
|
||||
}
|
||||
dll = (dll_max + dll_min) / 2;
|
||||
if ((dll >= 0xff) || (dll <= 0)) {
|
||||
pr_err("DSMC: cs%d byte%d dll training error(0x%x)\n",
|
||||
dev_err(dev, "DSMC: cs%d byte%d dll training error(0x%x)\n",
|
||||
cs, byte, dll);
|
||||
return -1;
|
||||
}
|
||||
pr_info("DSMC: cs%d byte%d dll delay line result 0x%x\n", cs, byte, dll);
|
||||
dev_info(dev, "cs%d byte%d dll delay line result 0x%x\n", cs, byte, dll);
|
||||
REG_CLRSETBITS(dsmc, DSMC_RDS_DLL_CTL(cs, byte),
|
||||
RDS_DLL0_CTL_RDS_0_CLK_DELAY_NUM_MASK,
|
||||
dll << RDS_DLL0_CTL_RDS_0_CLK_DELAY_NUM_SHIFT);
|
||||
@@ -945,6 +969,7 @@ EXPORT_SYMBOL(rockchip_dsmc_psram_reinit);
|
||||
|
||||
int rockchip_dsmc_ctrller_init(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
{
|
||||
uint32_t i;
|
||||
struct dsmc_config_cs *cfg = &dsmc->cfg.cs_cfg[cs];
|
||||
|
||||
writel(MRGTCR_READ_WRITE_MERGE_EN,
|
||||
@@ -956,17 +981,21 @@ int rockchip_dsmc_ctrller_init(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
(cfg->dll_num[1] << RDS_DLL1_CTL_RDS_1_CLK_DELAY_NUM_SHIFT),
|
||||
dsmc->regs + DSMC_RDS_DLL1_CTL(cs));
|
||||
|
||||
/* all io_width should set the same value in diff cs */
|
||||
for (i = 0; i < DSMC_MAX_SLAVE_NUM; i++)
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(cs),
|
||||
MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT,
|
||||
cfg->io_width << MCR_IOWIDTH_SHIFT);
|
||||
|
||||
REG_CLRSETBITS(dsmc, DSMC_MCR(cs),
|
||||
(MCR_ACS_MASK << MCR_ACS_SHIFT) |
|
||||
(MCR_DEVTYPE_MASK << MCR_DEVTYPE_SHIFT) |
|
||||
(MCR_IOWIDTH_MASK << MCR_IOWIDTH_SHIFT) |
|
||||
(MCR_EXCLUSIVE_DQS_MASK << MCR_EXCLUSIVE_DQS_SHIFT) |
|
||||
(MCR_WRAPSIZE_MASK << MCR_WRAPSIZE_SHIFT) |
|
||||
(MCR_MAXEN_MASK << MCR_MAXEN_SHIFT) |
|
||||
(MCR_MAXLEN_MASK << MCR_MAXLEN_SHIFT),
|
||||
(cfg->acs << MCR_ACS_SHIFT) |
|
||||
(MCR_DEVTYPE_HYPERRAM << MCR_DEVTYPE_SHIFT) |
|
||||
(cfg->io_width << MCR_IOWIDTH_SHIFT) |
|
||||
(cfg->exclusive_dqs << MCR_EXCLUSIVE_DQS_SHIFT) |
|
||||
(cfg->wrap_size << MCR_WRAPSIZE_SHIFT) |
|
||||
(cfg->max_length_en << MCR_MAXEN_SHIFT) |
|
||||
|
||||
@@ -526,6 +526,7 @@ static int dsmc_write(struct rockchip_dsmc_device *dsmc_dev, uint32_t cs, uint32
|
||||
|
||||
static void dsmc_lb_dma_hw_mode_en(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
{
|
||||
struct device *dev = dsmc->dev;
|
||||
struct dsmc_transfer *xfer = &dsmc->xfer;
|
||||
size_t size = xfer->transfer_size;
|
||||
uint32_t burst_byte = xfer->brst_len * xfer->brst_size;
|
||||
@@ -533,7 +534,7 @@ static void dsmc_lb_dma_hw_mode_en(struct rockchip_dsmc *dsmc, uint32_t cs)
|
||||
|
||||
dma_req_num = size / burst_byte;
|
||||
if (size % burst_byte) {
|
||||
pr_warn("DSMC: DMA size is unaligned\n");
|
||||
dev_warn(dev, "DMA size is unaligned\n");
|
||||
dma_req_num++;
|
||||
}
|
||||
writel(dma_req_num, dsmc->regs + DSMC_DMA_REQ_NUM(cs));
|
||||
@@ -683,7 +684,7 @@ static int dsmc_copy_from(struct rockchip_dsmc_device *dsmc_dev, uint32_t cs, ui
|
||||
struct rockchip_dsmc *dsmc = &dsmc_dev->dsmc;
|
||||
|
||||
if (atomic_read(&dsmc->xfer.state) & (RXDMA | TXDMA)) {
|
||||
pr_warn("DSMC: copy_from: the transfer is busy!\n");
|
||||
dev_warn(dev, "copy_from: the transfer is busy!\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@@ -721,7 +722,7 @@ static int dsmc_copy_to(struct rockchip_dsmc_device *dsmc_dev, uint32_t cs, uint
|
||||
struct rockchip_dsmc *dsmc = &dsmc_dev->dsmc;
|
||||
|
||||
if (atomic_read(&dsmc->xfer.state) & (RXDMA | TXDMA)) {
|
||||
pr_warn("DSMC: copy_to: the transfer is busy!\n");
|
||||
dev_warn(dev, "copy_to: the transfer is busy!\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@@ -785,6 +786,29 @@ static void dsmc_data_init(struct rockchip_dsmc *dsmc)
|
||||
}
|
||||
}
|
||||
|
||||
static int dsmc_check_mult_psram_cap(struct rockchip_dsmc *dsmc)
|
||||
{
|
||||
uint32_t cs;
|
||||
uint32_t io_width = 0xffffffff;
|
||||
struct device *dev = dsmc->dev;
|
||||
struct dsmc_ctrl_config *cfg = &dsmc->cfg;
|
||||
|
||||
for (cs = 0; cs < DSMC_MAX_SLAVE_NUM; cs++) {
|
||||
if (cfg->cs_cfg[cs].device_type == DSMC_UNKNOWN_DEVICE)
|
||||
continue;
|
||||
if (io_width == 0xffffffff) {
|
||||
io_width = dsmc->cfg.cs_cfg[cs].io_width;
|
||||
} else {
|
||||
if (io_width != dsmc->cfg.cs_cfg[cs].io_width) {
|
||||
dev_err(dev, "The io width error for mult rank!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dsmc_reset_ctrl(struct rockchip_dsmc *dsmc)
|
||||
{
|
||||
reset_control_assert(dsmc->areset);
|
||||
@@ -797,6 +821,7 @@ static void dsmc_reset_ctrl(struct rockchip_dsmc *dsmc)
|
||||
static int dsmc_init(struct rockchip_dsmc *dsmc)
|
||||
{
|
||||
uint32_t cs;
|
||||
struct device *dev = dsmc->dev;
|
||||
struct dsmc_ctrl_config *cfg = &dsmc->cfg;
|
||||
struct dsmc_config_cs *cs_cfg;
|
||||
uint32_t ret = 0;
|
||||
@@ -812,13 +837,18 @@ static int dsmc_init(struct rockchip_dsmc *dsmc)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = dsmc_check_mult_psram_cap(dsmc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dsmc_reset_ctrl(dsmc);
|
||||
|
||||
for (cs = 0; cs < DSMC_MAX_SLAVE_NUM; cs++) {
|
||||
if (cfg->cs_cfg[cs].device_type == DSMC_UNKNOWN_DEVICE)
|
||||
continue;
|
||||
cs_cfg = &dsmc->cfg.cs_cfg[cs];
|
||||
pr_info("DSMC: init cs%d %s device\n",
|
||||
dev_info(dev, "init cs%d %s device\n",
|
||||
cs, (cs_cfg->device_type == DSMC_LB_DEVICE) ? "LB" : "PSRAM");
|
||||
rockchip_dsmc_ctrller_init(dsmc, cs);
|
||||
if (cs_cfg->device_type == OPI_XCCELA_PSRAM)
|
||||
|
||||
Reference in New Issue
Block a user