18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com> 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Original author: 68c2ecf20Sopenharmony_ci * Ben Collins <bcollins@ubuntu.com> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Additional work by: 98c2ecf20Sopenharmony_ci * John Brooks <john.brooks@bluecherry.net> 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/kernel.h> 138c2ecf20Sopenharmony_ci#include <linux/module.h> 148c2ecf20Sopenharmony_ci#include <linux/slab.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include "solo6x10.h" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_cistatic int multi_p2m; 198c2ecf20Sopenharmony_cimodule_param(multi_p2m, uint, 0644); 208c2ecf20Sopenharmony_ciMODULE_PARM_DESC(multi_p2m, 218c2ecf20Sopenharmony_ci "Use multiple P2M DMA channels (default: no, 6010-only)"); 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic int desc_mode; 248c2ecf20Sopenharmony_cimodule_param(desc_mode, uint, 0644); 258c2ecf20Sopenharmony_ciMODULE_PARM_DESC(desc_mode, 268c2ecf20Sopenharmony_ci "Allow use of descriptor mode DMA (default: no, 6010-only)"); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ciint solo_p2m_dma(struct solo_dev *solo_dev, int wr, 298c2ecf20Sopenharmony_ci void *sys_addr, u32 ext_addr, u32 size, 308c2ecf20Sopenharmony_ci int repeat, u32 ext_size) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci dma_addr_t dma_addr; 338c2ecf20Sopenharmony_ci int ret; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci if (WARN_ON_ONCE((unsigned long)sys_addr & 0x03)) 368c2ecf20Sopenharmony_ci return -EINVAL; 378c2ecf20Sopenharmony_ci if (WARN_ON_ONCE(!size)) 388c2ecf20Sopenharmony_ci return -EINVAL; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci dma_addr = pci_map_single(solo_dev->pdev, sys_addr, size, 418c2ecf20Sopenharmony_ci wr ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); 428c2ecf20Sopenharmony_ci if (pci_dma_mapping_error(solo_dev->pdev, dma_addr)) 438c2ecf20Sopenharmony_ci return -ENOMEM; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci ret = solo_p2m_dma_t(solo_dev, wr, dma_addr, ext_addr, size, 468c2ecf20Sopenharmony_ci repeat, ext_size); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci pci_unmap_single(solo_dev->pdev, dma_addr, size, 498c2ecf20Sopenharmony_ci wr ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci return ret; 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci/* Mutex must be held for p2m_id before calling this!! */ 558c2ecf20Sopenharmony_ciint solo_p2m_dma_desc(struct solo_dev *solo_dev, 568c2ecf20Sopenharmony_ci struct solo_p2m_desc *desc, dma_addr_t desc_dma, 578c2ecf20Sopenharmony_ci int desc_cnt) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci struct solo_p2m_dev *p2m_dev; 608c2ecf20Sopenharmony_ci unsigned int timeout; 618c2ecf20Sopenharmony_ci unsigned int config = 0; 628c2ecf20Sopenharmony_ci int ret = 0; 638c2ecf20Sopenharmony_ci unsigned int p2m_id = 0; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci /* Get next ID. According to Softlogic, 6110 has problems on !=0 P2M */ 668c2ecf20Sopenharmony_ci if (solo_dev->type != SOLO_DEV_6110 && multi_p2m) 678c2ecf20Sopenharmony_ci p2m_id = atomic_inc_return(&solo_dev->p2m_count) % SOLO_NR_P2M; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci p2m_dev = &solo_dev->p2m_dev[p2m_id]; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci if (mutex_lock_interruptible(&p2m_dev->mutex)) 728c2ecf20Sopenharmony_ci return -EINTR; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci reinit_completion(&p2m_dev->completion); 758c2ecf20Sopenharmony_ci p2m_dev->error = 0; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci if (desc_cnt > 1 && solo_dev->type != SOLO_DEV_6110 && desc_mode) { 788c2ecf20Sopenharmony_ci /* For 6010 with more than one desc, we can do a one-shot */ 798c2ecf20Sopenharmony_ci p2m_dev->desc_count = p2m_dev->desc_idx = 0; 808c2ecf20Sopenharmony_ci config = solo_reg_read(solo_dev, SOLO_P2M_CONFIG(p2m_id)); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(p2m_id), desc_dma); 838c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_DESC_ID(p2m_id), desc_cnt); 848c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_CONFIG(p2m_id), config | 858c2ecf20Sopenharmony_ci SOLO_P2M_DESC_MODE); 868c2ecf20Sopenharmony_ci } else { 878c2ecf20Sopenharmony_ci /* For single descriptors and 6110, we need to run each desc */ 888c2ecf20Sopenharmony_ci p2m_dev->desc_count = desc_cnt; 898c2ecf20Sopenharmony_ci p2m_dev->desc_idx = 1; 908c2ecf20Sopenharmony_ci p2m_dev->descs = desc; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_TAR_ADR(p2m_id), 938c2ecf20Sopenharmony_ci desc[1].dma_addr); 948c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_EXT_ADR(p2m_id), 958c2ecf20Sopenharmony_ci desc[1].ext_addr); 968c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_EXT_CFG(p2m_id), 978c2ecf20Sopenharmony_ci desc[1].cfg); 988c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_CONTROL(p2m_id), 998c2ecf20Sopenharmony_ci desc[1].ctrl); 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci timeout = wait_for_completion_timeout(&p2m_dev->completion, 1038c2ecf20Sopenharmony_ci solo_dev->p2m_jiffies); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci if (WARN_ON_ONCE(p2m_dev->error)) 1068c2ecf20Sopenharmony_ci ret = -EIO; 1078c2ecf20Sopenharmony_ci else if (timeout == 0) { 1088c2ecf20Sopenharmony_ci solo_dev->p2m_timeouts++; 1098c2ecf20Sopenharmony_ci ret = -EAGAIN; 1108c2ecf20Sopenharmony_ci } 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_CONTROL(p2m_id), 0); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci /* Don't write here for the no_desc_mode case, because config is 0. 1158c2ecf20Sopenharmony_ci * We can't test no_desc_mode again, it might race. */ 1168c2ecf20Sopenharmony_ci if (desc_cnt > 1 && solo_dev->type != SOLO_DEV_6110 && config) 1178c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_CONFIG(p2m_id), config); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci mutex_unlock(&p2m_dev->mutex); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci return ret; 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_civoid solo_p2m_fill_desc(struct solo_p2m_desc *desc, int wr, 1258c2ecf20Sopenharmony_ci dma_addr_t dma_addr, u32 ext_addr, u32 size, 1268c2ecf20Sopenharmony_ci int repeat, u32 ext_size) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci WARN_ON_ONCE(dma_addr & 0x03); 1298c2ecf20Sopenharmony_ci WARN_ON_ONCE(!size); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci desc->cfg = SOLO_P2M_COPY_SIZE(size >> 2); 1328c2ecf20Sopenharmony_ci desc->ctrl = SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) | 1338c2ecf20Sopenharmony_ci (wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci if (repeat) { 1368c2ecf20Sopenharmony_ci desc->cfg |= SOLO_P2M_EXT_INC(ext_size >> 2); 1378c2ecf20Sopenharmony_ci desc->ctrl |= SOLO_P2M_PCI_INC(size >> 2) | 1388c2ecf20Sopenharmony_ci SOLO_P2M_REPEAT(repeat); 1398c2ecf20Sopenharmony_ci } 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci desc->dma_addr = dma_addr; 1428c2ecf20Sopenharmony_ci desc->ext_addr = ext_addr; 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ciint solo_p2m_dma_t(struct solo_dev *solo_dev, int wr, 1468c2ecf20Sopenharmony_ci dma_addr_t dma_addr, u32 ext_addr, u32 size, 1478c2ecf20Sopenharmony_ci int repeat, u32 ext_size) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci struct solo_p2m_desc desc[2]; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci solo_p2m_fill_desc(&desc[1], wr, dma_addr, ext_addr, size, repeat, 1528c2ecf20Sopenharmony_ci ext_size); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci /* No need for desc_dma since we know it is a single-shot */ 1558c2ecf20Sopenharmony_ci return solo_p2m_dma_desc(solo_dev, desc, 0, 1); 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_civoid solo_p2m_isr(struct solo_dev *solo_dev, int id) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci struct solo_p2m_dev *p2m_dev = &solo_dev->p2m_dev[id]; 1618c2ecf20Sopenharmony_ci struct solo_p2m_desc *desc; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci if (p2m_dev->desc_count <= p2m_dev->desc_idx) { 1648c2ecf20Sopenharmony_ci complete(&p2m_dev->completion); 1658c2ecf20Sopenharmony_ci return; 1668c2ecf20Sopenharmony_ci } 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci /* Setup next descriptor */ 1698c2ecf20Sopenharmony_ci p2m_dev->desc_idx++; 1708c2ecf20Sopenharmony_ci desc = &p2m_dev->descs[p2m_dev->desc_idx]; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0); 1738c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_TAR_ADR(id), desc->dma_addr); 1748c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_EXT_ADR(id), desc->ext_addr); 1758c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_EXT_CFG(id), desc->cfg); 1768c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), desc->ctrl); 1778c2ecf20Sopenharmony_ci} 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_civoid solo_p2m_error_isr(struct solo_dev *solo_dev) 1808c2ecf20Sopenharmony_ci{ 1818c2ecf20Sopenharmony_ci unsigned int err = solo_reg_read(solo_dev, SOLO_PCI_ERR); 1828c2ecf20Sopenharmony_ci struct solo_p2m_dev *p2m_dev; 1838c2ecf20Sopenharmony_ci int i; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci if (!(err & (SOLO_PCI_ERR_P2M | SOLO_PCI_ERR_P2M_DESC))) 1868c2ecf20Sopenharmony_ci return; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci for (i = 0; i < SOLO_NR_P2M; i++) { 1898c2ecf20Sopenharmony_ci p2m_dev = &solo_dev->p2m_dev[i]; 1908c2ecf20Sopenharmony_ci p2m_dev->error = 1; 1918c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0); 1928c2ecf20Sopenharmony_ci complete(&p2m_dev->completion); 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci} 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_civoid solo_p2m_exit(struct solo_dev *solo_dev) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci int i; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci for (i = 0; i < SOLO_NR_P2M; i++) 2018c2ecf20Sopenharmony_ci solo_irq_off(solo_dev, SOLO_IRQ_P2M(i)); 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic int solo_p2m_test(struct solo_dev *solo_dev, int base, int size) 2058c2ecf20Sopenharmony_ci{ 2068c2ecf20Sopenharmony_ci u32 *wr_buf; 2078c2ecf20Sopenharmony_ci u32 *rd_buf; 2088c2ecf20Sopenharmony_ci int i; 2098c2ecf20Sopenharmony_ci int ret = -EIO; 2108c2ecf20Sopenharmony_ci int order = get_order(size); 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci wr_buf = (u32 *)__get_free_pages(GFP_KERNEL, order); 2138c2ecf20Sopenharmony_ci if (wr_buf == NULL) 2148c2ecf20Sopenharmony_ci return -1; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci rd_buf = (u32 *)__get_free_pages(GFP_KERNEL, order); 2178c2ecf20Sopenharmony_ci if (rd_buf == NULL) { 2188c2ecf20Sopenharmony_ci free_pages((unsigned long)wr_buf, order); 2198c2ecf20Sopenharmony_ci return -1; 2208c2ecf20Sopenharmony_ci } 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci for (i = 0; i < (size >> 3); i++) 2238c2ecf20Sopenharmony_ci *(wr_buf + i) = (i << 16) | (i + 1); 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci for (i = (size >> 3); i < (size >> 2); i++) 2268c2ecf20Sopenharmony_ci *(wr_buf + i) = ~((i << 16) | (i + 1)); 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci memset(rd_buf, 0x55, size); 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci if (solo_p2m_dma(solo_dev, 1, wr_buf, base, size, 0, 0)) 2318c2ecf20Sopenharmony_ci goto test_fail; 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci if (solo_p2m_dma(solo_dev, 0, rd_buf, base, size, 0, 0)) 2348c2ecf20Sopenharmony_ci goto test_fail; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci for (i = 0; i < (size >> 2); i++) { 2378c2ecf20Sopenharmony_ci if (*(wr_buf + i) != *(rd_buf + i)) 2388c2ecf20Sopenharmony_ci goto test_fail; 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci ret = 0; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_citest_fail: 2448c2ecf20Sopenharmony_ci free_pages((unsigned long)wr_buf, order); 2458c2ecf20Sopenharmony_ci free_pages((unsigned long)rd_buf, order); 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci return ret; 2488c2ecf20Sopenharmony_ci} 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ciint solo_p2m_init(struct solo_dev *solo_dev) 2518c2ecf20Sopenharmony_ci{ 2528c2ecf20Sopenharmony_ci struct solo_p2m_dev *p2m_dev; 2538c2ecf20Sopenharmony_ci int i; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci for (i = 0; i < SOLO_NR_P2M; i++) { 2568c2ecf20Sopenharmony_ci p2m_dev = &solo_dev->p2m_dev[i]; 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci mutex_init(&p2m_dev->mutex); 2598c2ecf20Sopenharmony_ci init_completion(&p2m_dev->completion); 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0); 2628c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_P2M_CONFIG(i), 2638c2ecf20Sopenharmony_ci SOLO_P2M_CSC_16BIT_565 | 2648c2ecf20Sopenharmony_ci SOLO_P2M_DESC_INTR_OPT | 2658c2ecf20Sopenharmony_ci SOLO_P2M_DMA_INTERVAL(0) | 2668c2ecf20Sopenharmony_ci SOLO_P2M_PCI_MASTER_MODE); 2678c2ecf20Sopenharmony_ci solo_irq_on(solo_dev, SOLO_IRQ_P2M(i)); 2688c2ecf20Sopenharmony_ci } 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci /* Find correct SDRAM size */ 2718c2ecf20Sopenharmony_ci for (solo_dev->sdram_size = 0, i = 2; i >= 0; i--) { 2728c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_DMA_CTRL, 2738c2ecf20Sopenharmony_ci SOLO_DMA_CTRL_REFRESH_CYCLE(1) | 2748c2ecf20Sopenharmony_ci SOLO_DMA_CTRL_SDRAM_SIZE(i) | 2758c2ecf20Sopenharmony_ci SOLO_DMA_CTRL_SDRAM_CLK_INVERT | 2768c2ecf20Sopenharmony_ci SOLO_DMA_CTRL_READ_CLK_SELECT | 2778c2ecf20Sopenharmony_ci SOLO_DMA_CTRL_LATENCY(1)); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_SYS_CFG, solo_dev->sys_config | 2808c2ecf20Sopenharmony_ci SOLO_SYS_CFG_RESET); 2818c2ecf20Sopenharmony_ci solo_reg_write(solo_dev, SOLO_SYS_CFG, solo_dev->sys_config); 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci switch (i) { 2848c2ecf20Sopenharmony_ci case 2: 2858c2ecf20Sopenharmony_ci if (solo_p2m_test(solo_dev, 0x07ff0000, 0x00010000) || 2868c2ecf20Sopenharmony_ci solo_p2m_test(solo_dev, 0x05ff0000, 0x00010000)) 2878c2ecf20Sopenharmony_ci continue; 2888c2ecf20Sopenharmony_ci break; 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci case 1: 2918c2ecf20Sopenharmony_ci if (solo_p2m_test(solo_dev, 0x03ff0000, 0x00010000)) 2928c2ecf20Sopenharmony_ci continue; 2938c2ecf20Sopenharmony_ci break; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci default: 2968c2ecf20Sopenharmony_ci if (solo_p2m_test(solo_dev, 0x01ff0000, 0x00010000)) 2978c2ecf20Sopenharmony_ci continue; 2988c2ecf20Sopenharmony_ci } 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci solo_dev->sdram_size = (32 << 20) << i; 3018c2ecf20Sopenharmony_ci break; 3028c2ecf20Sopenharmony_ci } 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci if (!solo_dev->sdram_size) { 3058c2ecf20Sopenharmony_ci dev_err(&solo_dev->pdev->dev, "Error detecting SDRAM size\n"); 3068c2ecf20Sopenharmony_ci return -EIO; 3078c2ecf20Sopenharmony_ci } 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci if (SOLO_SDRAM_END(solo_dev) > solo_dev->sdram_size) { 3108c2ecf20Sopenharmony_ci dev_err(&solo_dev->pdev->dev, 3118c2ecf20Sopenharmony_ci "SDRAM is not large enough (%u < %u)\n", 3128c2ecf20Sopenharmony_ci solo_dev->sdram_size, SOLO_SDRAM_END(solo_dev)); 3138c2ecf20Sopenharmony_ci return -EIO; 3148c2ecf20Sopenharmony_ci } 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci return 0; 3178c2ecf20Sopenharmony_ci} 318