1ad309a88SDingqiang Lin /* 2ad309a88SDingqiang Lin * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd 3ad309a88SDingqiang Lin * 4ba0501acSDingqiang Lin * SPDX-License-Identifier: GPL-2.0 5ad309a88SDingqiang Lin */ 6ba0501acSDingqiang Lin 7ad309a88SDingqiang Lin #include <common.h> 8ad309a88SDingqiang Lin #include <dm.h> 9ad309a88SDingqiang Lin 10ad309a88SDingqiang Lin #include "rkflash_api.h" 11ad309a88SDingqiang Lin #include "rkflash_blk.h" 12ad309a88SDingqiang Lin 13ad309a88SDingqiang Lin #ifdef CONFIG_RKSFC_NOR 14ba0501acSDingqiang Lin int rksfc_nor_init(struct udevice *udev) 15ad309a88SDingqiang Lin { 16ad309a88SDingqiang Lin struct rkflash_info *priv = dev_get_priv(udev); 17ad309a88SDingqiang Lin struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 18ad309a88SDingqiang Lin 19ad309a88SDingqiang Lin return snor_init(p_dev); 20ad309a88SDingqiang Lin } 21ad309a88SDingqiang Lin 22ba0501acSDingqiang Lin u32 rksfc_nor_get_capacity(struct udevice *udev) 23ad309a88SDingqiang Lin { 24ad309a88SDingqiang Lin struct rkflash_info *priv = dev_get_priv(udev); 25ad309a88SDingqiang Lin struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 26ad309a88SDingqiang Lin 27ad309a88SDingqiang Lin return snor_get_capacity(p_dev); 28ad309a88SDingqiang Lin } 29ad309a88SDingqiang Lin 30ba0501acSDingqiang Lin int rksfc_nor_read(struct udevice *udev, u32 sec, u32 n_sec, void *p_data) 31ad309a88SDingqiang Lin { 32ba0501acSDingqiang Lin u32 ret; 33ba0501acSDingqiang Lin u32 offset, count = 0; 34ba0501acSDingqiang Lin char *buf = (char *)p_data; 35ad309a88SDingqiang Lin struct rkflash_info *priv = dev_get_priv(udev); 36ad309a88SDingqiang Lin struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 37ad309a88SDingqiang Lin 38ba0501acSDingqiang Lin if (sec + n_sec - 1 < FLASH_VENDOR_PART_START || 39ba0501acSDingqiang Lin sec > FLASH_VENDOR_PART_END) { 40ba0501acSDingqiang Lin ret = snor_read(p_dev, sec, n_sec, p_data); 41ba0501acSDingqiang Lin if (ret != n_sec) 42ba0501acSDingqiang Lin return ret; 43ba0501acSDingqiang Lin } else { 44ba0501acSDingqiang Lin memset(p_data, 0, 512 * n_sec); 45ba0501acSDingqiang Lin if (sec < FLASH_VENDOR_PART_START) { 46ba0501acSDingqiang Lin count = FLASH_VENDOR_PART_START - sec; 47ba0501acSDingqiang Lin buf = (char *)p_data; 48ba0501acSDingqiang Lin ret = snor_read(p_dev, sec, count, buf); 49ba0501acSDingqiang Lin if (ret != count) 50ba0501acSDingqiang Lin return ret; 51ba0501acSDingqiang Lin } 52ba0501acSDingqiang Lin if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) { 53ba0501acSDingqiang Lin count = sec + n_sec - 1 - FLASH_VENDOR_PART_END; 54ba0501acSDingqiang Lin offset = FLASH_VENDOR_PART_END - sec + 1; 55ba0501acSDingqiang Lin buf = (char *)p_data + offset * 512; 56ba0501acSDingqiang Lin ret = snor_read(p_dev, 57ba0501acSDingqiang Lin FLASH_VENDOR_PART_END + 1, 58ba0501acSDingqiang Lin count, buf); 59ba0501acSDingqiang Lin if (ret != count) 60ba0501acSDingqiang Lin return ret; 61ba0501acSDingqiang Lin } 62ba0501acSDingqiang Lin } 63ba0501acSDingqiang Lin 64ba0501acSDingqiang Lin return n_sec; 65ba0501acSDingqiang Lin } 66ba0501acSDingqiang Lin 67ba0501acSDingqiang Lin int rksfc_nor_write(struct udevice *udev, 68ba0501acSDingqiang Lin u32 sec, 69ba0501acSDingqiang Lin u32 n_sec, 70ba0501acSDingqiang Lin const void *p_data) 71ba0501acSDingqiang Lin { 72ba0501acSDingqiang Lin u32 ret; 73ba0501acSDingqiang Lin u32 offset, count = 0; 74ba0501acSDingqiang Lin char *buf = (char *)p_data; 75ba0501acSDingqiang Lin struct rkflash_info *priv = dev_get_priv(udev); 76ba0501acSDingqiang Lin struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 77ba0501acSDingqiang Lin 78ba0501acSDingqiang Lin if (sec + n_sec - 1 < FLASH_VENDOR_PART_START || 79ba0501acSDingqiang Lin sec > FLASH_VENDOR_PART_END) { 80*c84f0ed8SJon Lin ret = snor_write(p_dev, sec, n_sec, (void *)p_data); 81ba0501acSDingqiang Lin if (ret != n_sec) 82ba0501acSDingqiang Lin return ret; 83ba0501acSDingqiang Lin } else { 84ba0501acSDingqiang Lin if (sec < FLASH_VENDOR_PART_START) { 85ba0501acSDingqiang Lin count = FLASH_VENDOR_PART_START - sec; 86ba0501acSDingqiang Lin buf = (char *)p_data; 87ba0501acSDingqiang Lin ret = snor_write(p_dev, sec, count, buf); 88ba0501acSDingqiang Lin if (ret != count) 89ba0501acSDingqiang Lin return ret; 90ba0501acSDingqiang Lin } 91ba0501acSDingqiang Lin if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) { 92ba0501acSDingqiang Lin count = sec + n_sec - 1 - FLASH_VENDOR_PART_END; 93ba0501acSDingqiang Lin offset = FLASH_VENDOR_PART_END - sec + 1; 94ba0501acSDingqiang Lin buf = (char *)p_data + offset * 512; 95ba0501acSDingqiang Lin ret = snor_write(p_dev, 96ba0501acSDingqiang Lin FLASH_VENDOR_PART_END + 1, 97ba0501acSDingqiang Lin count, buf); 98ba0501acSDingqiang Lin if (ret != count) 99ba0501acSDingqiang Lin return ret; 100ba0501acSDingqiang Lin } 101ba0501acSDingqiang Lin } 102ba0501acSDingqiang Lin 103ba0501acSDingqiang Lin return n_sec; 104ba0501acSDingqiang Lin } 105ba0501acSDingqiang Lin 106ba0501acSDingqiang Lin int rksfc_nor_vendor_read(struct blk_desc *dev_desc, 107ba0501acSDingqiang Lin u32 sec, 108ba0501acSDingqiang Lin u32 n_sec, 109ba0501acSDingqiang Lin void *p_data) 110ba0501acSDingqiang Lin { 111ba0501acSDingqiang Lin struct rkflash_info *priv = dev_get_priv(dev_desc->bdev->parent); 112ba0501acSDingqiang Lin struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 113ba0501acSDingqiang Lin 114ad309a88SDingqiang Lin return snor_read(p_dev, sec, n_sec, p_data); 115ad309a88SDingqiang Lin } 116ad309a88SDingqiang Lin 117ba0501acSDingqiang Lin int rksfc_nor_vendor_write(struct blk_desc *dev_desc, 118ba0501acSDingqiang Lin u32 sec, 119ba0501acSDingqiang Lin u32 n_sec, 120ba0501acSDingqiang Lin void *p_data) 121ad309a88SDingqiang Lin { 122ba0501acSDingqiang Lin struct rkflash_info *priv = dev_get_priv(dev_desc->bdev->parent); 123ad309a88SDingqiang Lin struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info; 124ad309a88SDingqiang Lin 125ad309a88SDingqiang Lin return snor_write(p_dev, sec, n_sec, p_data); 126ad309a88SDingqiang Lin } 127ba0501acSDingqiang Lin 128ad309a88SDingqiang Lin #endif 129ad309a88SDingqiang Lin 130ba0501acSDingqiang Lin #ifdef CONFIG_RKSFC_NAND 131ba0501acSDingqiang Lin int rksfc_nand_init(struct udevice *udev) 132ba0501acSDingqiang Lin { 133ba0501acSDingqiang Lin int ret; 134ba0501acSDingqiang Lin 135ba0501acSDingqiang Lin ret = sfc_nand_init(); 136*c84f0ed8SJon Lin if (ret) { 137ba0501acSDingqiang Lin return ret; 138*c84f0ed8SJon Lin } else { 139*c84f0ed8SJon Lin sfc_nand_ftl_ops_init(); 140*c84f0ed8SJon Lin 141ba0501acSDingqiang Lin return sftl_init(); 142ba0501acSDingqiang Lin } 143*c84f0ed8SJon Lin } 144ba0501acSDingqiang Lin 145ba0501acSDingqiang Lin int rksfc_nand_read(struct udevice *udev, u32 index, u32 count, void *buf) 146ba0501acSDingqiang Lin { 147ba0501acSDingqiang Lin int ret; 148ba0501acSDingqiang Lin 149ba0501acSDingqiang Lin ret = sftl_read(index, count, (u8 *)buf); 150ba0501acSDingqiang Lin if (!ret) 151ba0501acSDingqiang Lin return count; 152ba0501acSDingqiang Lin else 153ba0501acSDingqiang Lin return -EIO; 154ba0501acSDingqiang Lin } 155ba0501acSDingqiang Lin 156ba0501acSDingqiang Lin int rksfc_nand_write(struct udevice *udev, 157ba0501acSDingqiang Lin u32 index, 158ba0501acSDingqiang Lin u32 count, 159ba0501acSDingqiang Lin const void *buf) 160ba0501acSDingqiang Lin { 161ba0501acSDingqiang Lin int ret; 162ba0501acSDingqiang Lin 163ba0501acSDingqiang Lin ret = sftl_write(index, count, (u8 *)buf); 164ba0501acSDingqiang Lin if (!ret) 165ba0501acSDingqiang Lin return count; 166ba0501acSDingqiang Lin else 167ba0501acSDingqiang Lin return -EIO; 168ba0501acSDingqiang Lin } 169ba0501acSDingqiang Lin 170ba0501acSDingqiang Lin u32 rksfc_nand_get_density(struct udevice *udev) 171ba0501acSDingqiang Lin { 172ba0501acSDingqiang Lin return sftl_get_density(); 173ba0501acSDingqiang Lin } 17440bd3f86SDingqiang Lin 17540bd3f86SDingqiang Lin int rksfc_nand_vendor_read(struct blk_desc *dev_desc, 17640bd3f86SDingqiang Lin u32 sec, 17740bd3f86SDingqiang Lin u32 n_sec, 17840bd3f86SDingqiang Lin void *p_data) 17940bd3f86SDingqiang Lin { 18040bd3f86SDingqiang Lin int ret; 18140bd3f86SDingqiang Lin 18240bd3f86SDingqiang Lin ret = sftl_vendor_read(sec, n_sec, (u8 *)p_data); 18340bd3f86SDingqiang Lin if (!ret) 18440bd3f86SDingqiang Lin return n_sec; 18540bd3f86SDingqiang Lin else 18640bd3f86SDingqiang Lin return -EIO; 18740bd3f86SDingqiang Lin } 18840bd3f86SDingqiang Lin 18940bd3f86SDingqiang Lin int rksfc_nand_vendor_write(struct blk_desc *dev_desc, 19040bd3f86SDingqiang Lin u32 sec, 19140bd3f86SDingqiang Lin u32 n_sec, 19240bd3f86SDingqiang Lin void *p_data) 19340bd3f86SDingqiang Lin { 19440bd3f86SDingqiang Lin int ret; 19540bd3f86SDingqiang Lin 19640bd3f86SDingqiang Lin ret = sftl_vendor_write(sec, n_sec, (u8 *)p_data); 19740bd3f86SDingqiang Lin if (!ret) 19840bd3f86SDingqiang Lin return n_sec; 19940bd3f86SDingqiang Lin else 20040bd3f86SDingqiang Lin return -EIO; 20140bd3f86SDingqiang Lin } 20240bd3f86SDingqiang Lin 203ba0501acSDingqiang Lin #endif 204ba0501acSDingqiang Lin 205ba0501acSDingqiang Lin #ifdef CONFIG_RKNANDC_NAND 206ba0501acSDingqiang Lin int rknand_flash_init(struct udevice *udev) 207ba0501acSDingqiang Lin { 208ba0501acSDingqiang Lin return sftl_init(); 209ba0501acSDingqiang Lin } 210ba0501acSDingqiang Lin 211ba0501acSDingqiang Lin int rknand_flash_read(struct udevice *udev, u32 index, u32 count, void *buf) 212ba0501acSDingqiang Lin { 213ba0501acSDingqiang Lin int ret; 214ba0501acSDingqiang Lin 215ba0501acSDingqiang Lin ret = sftl_read(index, count, (u8 *)buf); 216ba0501acSDingqiang Lin if (!ret) 217ba0501acSDingqiang Lin return count; 218ba0501acSDingqiang Lin else 219ba0501acSDingqiang Lin return -EIO; 220ba0501acSDingqiang Lin } 221ba0501acSDingqiang Lin 222ba0501acSDingqiang Lin int rknand_flash_write(struct udevice *udev, 223ba0501acSDingqiang Lin u32 index, 224ba0501acSDingqiang Lin u32 count, 225ba0501acSDingqiang Lin const void *buf) 226ba0501acSDingqiang Lin { 227ba0501acSDingqiang Lin int ret; 228ba0501acSDingqiang Lin 229ba0501acSDingqiang Lin ret = sftl_write(index, count, (u8 *)buf); 230ba0501acSDingqiang Lin if (!ret) 231ba0501acSDingqiang Lin return count; 232ba0501acSDingqiang Lin else 233ba0501acSDingqiang Lin return -EIO; 234ba0501acSDingqiang Lin } 235ba0501acSDingqiang Lin 236ba0501acSDingqiang Lin u32 rknand_flash_get_density(struct udevice *udev) 237ba0501acSDingqiang Lin { 238ba0501acSDingqiang Lin return sftl_get_density(); 239ba0501acSDingqiang Lin } 24040bd3f86SDingqiang Lin 24140bd3f86SDingqiang Lin int rknand_flash_vendor_read(struct blk_desc *dev_desc, 24240bd3f86SDingqiang Lin u32 sec, 24340bd3f86SDingqiang Lin u32 n_sec, 24440bd3f86SDingqiang Lin void *p_data) 24540bd3f86SDingqiang Lin { 24640bd3f86SDingqiang Lin int ret; 24740bd3f86SDingqiang Lin 24840bd3f86SDingqiang Lin ret = sftl_vendor_read(sec, n_sec, (u8 *)p_data); 24940bd3f86SDingqiang Lin if (!ret) 25040bd3f86SDingqiang Lin return n_sec; 25140bd3f86SDingqiang Lin else 25240bd3f86SDingqiang Lin return -EIO; 25340bd3f86SDingqiang Lin } 25440bd3f86SDingqiang Lin 25540bd3f86SDingqiang Lin int rknand_flash_vendor_write(struct blk_desc *dev_desc, 25640bd3f86SDingqiang Lin u32 sec, 25740bd3f86SDingqiang Lin u32 n_sec, 25840bd3f86SDingqiang Lin void *p_data) 25940bd3f86SDingqiang Lin { 26040bd3f86SDingqiang Lin int ret; 26140bd3f86SDingqiang Lin 26240bd3f86SDingqiang Lin ret = sftl_vendor_write(sec, n_sec, (u8 *)p_data); 26340bd3f86SDingqiang Lin if (!ret) 26440bd3f86SDingqiang Lin return n_sec; 26540bd3f86SDingqiang Lin else 26640bd3f86SDingqiang Lin return -EIO; 26740bd3f86SDingqiang Lin } 26840bd3f86SDingqiang Lin 269ba0501acSDingqiang Lin #endif 270