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