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