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