1 /* 2 * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <clk.h> 9 #include <dm.h> 10 #include <dm/device-internal.h> 11 #include <asm/arch/clock.h> 12 #include <rksfc.h> 13 #include <asm/arch/vendor.h> 14 15 #include "rkflash_blk.h" 16 #include "rkflash_api.h" 17 18 static struct flash_operation sfc_nor_op = { 19 #ifdef CONFIG_RKSFC_NOR 20 IF_TYPE_SPINOR, 21 rksfc_nor_init, 22 rksfc_nor_get_capacity, 23 rksfc_nor_read, 24 rksfc_nor_write, 25 NULL, 26 rksfc_nor_vendor_read, 27 rksfc_nor_vendor_write, 28 #else 29 -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 30 #endif 31 }; 32 33 static struct flash_operation sfc_nand_op = { 34 #ifdef CONFIG_RKSFC_NAND 35 IF_TYPE_SPINAND, 36 rksfc_nand_init, 37 rksfc_nand_get_density, 38 rksfc_nand_read, 39 rksfc_nand_write, 40 NULL, 41 rksfc_nand_vendor_read, 42 rksfc_nand_vendor_write, 43 #else 44 -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 45 #endif 46 }; 47 48 static struct flash_operation *spi_flash_op[2] = { 49 &sfc_nor_op, 50 &sfc_nand_op, 51 }; 52 53 int rksfc_scan_namespace(void) 54 { 55 struct uclass *uc; 56 struct udevice *dev; 57 int ret; 58 59 ret = uclass_get(UCLASS_SPI_FLASH, &uc); 60 if (ret) 61 return ret; 62 63 uclass_foreach_dev(dev, uc) { 64 debug("%s %d %p\n", __func__, __LINE__, dev); 65 ret = device_probe(dev); 66 if (ret) 67 return ret; 68 } 69 70 return 0; 71 } 72 73 static int rksfc_blk_bind(struct udevice *udev) 74 { 75 struct udevice *bdev; 76 int ret; 77 78 ret = blk_create_devicef(udev, "rkflash_blk", "spinand.blk", 79 IF_TYPE_SPINAND, 80 0, 512, 0, &bdev); 81 ret = blk_create_devicef(udev, "rkflash_blk", "spinor.blk", 82 IF_TYPE_SPINOR, 83 1, 512, 0, &bdev); 84 85 if (ret) { 86 debug("Cannot create block device\n"); 87 return ret; 88 } 89 90 return 0; 91 } 92 93 static int rockchip_rksfc_ofdata_to_platdata(struct udevice *dev) 94 { 95 struct rkflash_info *priv = dev_get_priv(dev); 96 97 priv->ioaddr = dev_read_addr_ptr(dev); 98 99 return 0; 100 } 101 102 static int rockchip_rksfc_probe(struct udevice *udev) 103 { 104 int ret = 0; 105 int i; 106 struct rkflash_info *priv = dev_get_priv(udev); 107 108 debug("%s %d %p ndev = %p\n", __func__, __LINE__, udev, priv); 109 110 sfc_init(priv->ioaddr); 111 for (i = 0; i < 2; i++) { 112 if (spi_flash_op[i]->id <= 0) { 113 debug("%s no optional spi flash for type %x\n", 114 __func__, i); 115 continue; 116 } 117 ret = spi_flash_op[i]->flash_init(udev); 118 if (!ret) { 119 priv->flash_con_type = spi_flash_op[i]->id; 120 priv->density = 121 spi_flash_op[i]->flash_get_capacity(udev); 122 priv->read = spi_flash_op[i]->flash_read; 123 priv->write = spi_flash_op[i]->flash_write; 124 #ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION 125 flash_vendor_dev_ops_register(spi_flash_op[i]->vendor_read, 126 spi_flash_op[i]->vendor_write); 127 #endif 128 debug("%s probe success\n", __func__); 129 break; 130 } else { 131 pr_err("ret %d\n", ret); 132 } 133 } 134 135 return ret; 136 } 137 138 UCLASS_DRIVER(rksfc) = { 139 .id = UCLASS_SPI_FLASH, 140 .name = "rksfc", 141 .flags = DM_UC_FLAG_SEQ_ALIAS, 142 }; 143 144 static const struct udevice_id rockchip_sfc_ids[] = { 145 { .compatible = "rockchip,rksfc" }, 146 { } 147 }; 148 149 U_BOOT_DRIVER(rksfc) = { 150 .name = "rksfc", 151 .id = UCLASS_SPI_FLASH, 152 .of_match = rockchip_sfc_ids, 153 .bind = rksfc_blk_bind, 154 .probe = rockchip_rksfc_probe, 155 .priv_auto_alloc_size = sizeof(struct rkflash_info), 156 .ofdata_to_platdata = rockchip_rksfc_ofdata_to_platdata, 157 }; 158 159