blob: 83b5c91c27f9d224ba4dee157b2d3cc3371176d4 [file] [log] [blame]
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* spi flash driver adaptive to storage interface module
*
* Copyright (C) 2018 Amlogic Corporation
*
* Licensed under the GPL-2 or later.
*
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <linux/mtd/mtd.h>
#include <malloc.h>
#include <spi.h>
#include <spi_flash.h>
#include <amlogic/storage.h>
#include "sf_internal.h"
struct storage_t *snor_storage;
extern const struct spi_flash_info *spi_flash_read_id(struct spi_flash *flash);
extern void mtd_store_init_map(void);
extern void mtd_store_set(struct mtd_info *mtd, int dev);
extern void mtd_store_mount_ops(struct storage_t *store);
extern struct mtd_info *spi_flash_get_mtd(void);
inline void set_snor_storage(struct storage_t *snor)
{
snor_storage = snor;
}
inline struct storage_t *get_snor_storage(void)
{
return snor_storage;
}
int spi_flash_fit_storage(struct spi_flash *flash)
{
const struct spi_flash_info *info = NULL;
struct storage_t *spi_nor = NULL;
if (get_snor_storage())
return 0;
info = spi_flash_read_id(flash);
if (IS_ERR_OR_NULL(info)) {
debug("%s %d no matched flash\n", __func__, __LINE__);
return 1;
}
spi_nor = kzalloc(sizeof(*spi_nor), GFP_KERNEL);
if (!spi_nor) {
debug("%s %d no enough memory!\n", __func__, __LINE__);
return -ENOMEM;
}
spi_nor->type = BOOT_SNOR;
spi_nor->init_flag = 0;
memcpy(spi_nor->info.name, info->name,
strlen(info->name) > 32 ? 32 : strlen(info->name));
memcpy(spi_nor->info.id, info->id, info->id_len);
spi_nor->info.read_unit = flash->page_size;
spi_nor->info.write_unit = flash->page_size;
spi_nor->info.erase_unit = flash->erase_size;
spi_nor->info.caps = flash->size;
spi_nor->info.mode = 0;
set_snor_storage(spi_nor);
mtd_store_mount_ops(spi_nor);
mtd_store_set(spi_flash_get_mtd(), 0);
mtd_store_init_map();
return store_register(spi_nor);
}
int spi_nor_pre(void)
{
return 0;
}
int spi_nor_probe(u32 init_flag)
{
u32 bus = 0, cs = 0, speed = 0x40000000, mode = 0;
struct spi_flash *flash = NULL;
struct storage_t *spi_nor = get_snor_storage();
if (spi_nor) {
spi_nor->init_flag = init_flag;
return 0;
}
flash = spi_flash_probe(bus, cs, speed, mode);
if (!flash) {
debug("spi flash probe fail!\n");
return 1;
}
spi_nor = get_snor_storage();
if (!spi_nor) {
debug("can not get spi nor!\n");
return 1;
}
spi_nor->init_flag = init_flag;
return 0;
}