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 FLASH_TYPE_SFC_NOR, 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 FLASH_TYPE_SFC_NAND, 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_RKSFC, 78 0, 512, 0, &bdev); 79 if (ret) { 80 debug("Cannot create block device\n"); 81 return ret; 82 } 83 84 return 0; 85 } 86 87 static int rockchip_rksfc_ofdata_to_platdata(struct udevice *dev) 88 { 89 struct rkflash_info *priv = dev_get_priv(dev); 90 91 priv->ioaddr = dev_read_addr_ptr(dev); 92 93 return 0; 94 } 95 96 static int rockchip_rksfc_probe(struct udevice *udev) 97 { 98 int ret = 0; 99 int i; 100 struct rkflash_info *priv = dev_get_priv(udev); 101 102 debug("%s %d %p ndev = %p\n", __func__, __LINE__, udev, priv); 103 104 sfc_init(priv->ioaddr); 105 for (i = 0; i < 2; i++) { 106 if (spi_flash_op[i]->id == -1) { 107 debug("%s no optional spi flash for type %x\n", 108 __func__, i); 109 continue; 110 } 111 ret = spi_flash_op[i]->flash_init(udev); 112 if (!ret) { 113 priv->flash_con_type = FLASH_CON_TYPE_SFC; 114 priv->density = 115 spi_flash_op[i]->flash_get_capacity(udev); 116 priv->read = spi_flash_op[i]->flash_read; 117 priv->write = spi_flash_op[i]->flash_write; 118 debug("%s probe success\n", __func__); 119 break; 120 } 121 } 122 123 return ret; 124 } 125 126 UCLASS_DRIVER(rksfc) = { 127 .id = UCLASS_SPI_FLASH, 128 .name = "rksfc", 129 .flags = DM_UC_FLAG_SEQ_ALIAS, 130 }; 131 132 static const struct udevice_id rockchip_sfc_ids[] = { 133 { .compatible = "rockchip,rksfc" }, 134 { } 135 }; 136 137 U_BOOT_DRIVER(rksfc) = { 138 .name = "rksfc", 139 .id = UCLASS_SPI_FLASH, 140 .of_match = rockchip_sfc_ids, 141 .bind = rksfc_blk_bind, 142 .probe = rockchip_rksfc_probe, 143 .priv_auto_alloc_size = sizeof(struct rkflash_info), 144 .ofdata_to_platdata = rockchip_rksfc_ofdata_to_platdata, 145 }; 146 147