blob: e6e650ef8c09d6d5d63f67ba257a50fc7645d91a [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glassd6eedf72014-10-13 23:42:06 -06002/*
3 * Copyright (c) 2014 Google, Inc
Simon Glassd6eedf72014-10-13 23:42:06 -06004 */
5
Patrick Delaunay81313352021-04-27 11:02:19 +02006#define LOG_CATEGORY UCLASS_SPI_FLASH
7
Simon Glassd6eedf72014-10-13 23:42:06 -06008#include <common.h>
9#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -060010#include <log.h>
Simon Glass9bc15642020-02-03 07:36:16 -070011#include <malloc.h>
Simon Glassd6eedf72014-10-13 23:42:06 -060012#include <spi.h>
13#include <spi_flash.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060014#include <asm/global_data.h>
Simon Glassd6eedf72014-10-13 23:42:06 -060015#include <dm/device-internal.h>
16#include "sf_internal.h"
17
Michal Simekc790ede2015-10-27 13:52:47 +010018DECLARE_GLOBAL_DATA_PTR;
19
Simon Glass1c369232015-03-26 09:29:25 -060020int spi_flash_read_dm(struct udevice *dev, u32 offset, size_t len, void *buf)
21{
Simon Glass00d99902018-10-01 12:22:24 -060022 return log_ret(sf_get_ops(dev)->read(dev, offset, len, buf));
Simon Glass1c369232015-03-26 09:29:25 -060023}
24
25int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len,
26 const void *buf)
27{
Simon Glass00d99902018-10-01 12:22:24 -060028 return log_ret(sf_get_ops(dev)->write(dev, offset, len, buf));
Simon Glass1c369232015-03-26 09:29:25 -060029}
30
31int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len)
32{
Simon Glass00d99902018-10-01 12:22:24 -060033 return log_ret(sf_get_ops(dev)->erase(dev, offset, len));
Simon Glass1c369232015-03-26 09:29:25 -060034}
35
Simon Glass61d04642021-03-15 18:11:17 +130036int spl_flash_get_sw_write_prot(struct udevice *dev)
37{
38 struct dm_spi_flash_ops *ops = sf_get_ops(dev);
39
40 if (!ops->get_sw_write_prot)
41 return -ENOSYS;
42 return log_ret(ops->get_sw_write_prot(dev));
43}
44
Simon Glassd6eedf72014-10-13 23:42:06 -060045/*
46 * TODO(sjg@chromium.org): This is an old-style function. We should remove
47 * it when all SPI flash drivers use dm
48 */
Patrice Chotard05b1aa62022-03-30 09:33:14 +020049struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
Simon Glassd6eedf72014-10-13 23:42:06 -060050 unsigned int max_hz, unsigned int spi_mode)
51{
Simon Glassd6eedf72014-10-13 23:42:06 -060052 struct spi_slave *slave;
53 struct udevice *bus;
Simon Glass30d435e2015-12-29 05:22:47 -070054 char *str;
Simon Glassd6eedf72014-10-13 23:42:06 -060055
Simon Glass7611ac62019-09-25 08:56:27 -060056#if defined(CONFIG_SPL_BUILD) && CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glass30d435e2015-12-29 05:22:47 -070057 str = "spi_flash";
58#else
59 char name[30];
60
Haikun.Wang@freescale.com16b7ddd2015-05-06 10:37:43 +080061 snprintf(name, sizeof(name), "spi_flash@%d:%d", busnum, cs);
Simon Glassd6eedf72014-10-13 23:42:06 -060062 str = strdup(name);
Simon Glass30d435e2015-12-29 05:22:47 -070063#endif
Patrice Chotard05b1aa62022-03-30 09:33:14 +020064
65 if (_spi_get_bus_and_cs(busnum, cs, max_hz, spi_mode,
66 "jedec_spi_nor", str, &bus, &slave))
67 return NULL;
68
69 return dev_get_uclass_priv(slave->dev);
70}
71
72int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
73 struct udevice **devp)
74{
75 struct spi_slave *slave;
76 struct udevice *bus;
77 int ret;
78
79 ret = spi_get_bus_and_cs(busnum, cs, &bus, &slave);
Simon Glassd6eedf72014-10-13 23:42:06 -060080 if (ret)
81 return ret;
82
83 *devp = slave->dev;
84 return 0;
85}
86
Michal Simekc790ede2015-10-27 13:52:47 +010087static int spi_flash_post_bind(struct udevice *dev)
88{
89#if defined(CONFIG_NEEDS_MANUAL_RELOC)
90 struct dm_spi_flash_ops *ops = sf_get_ops(dev);
91 static int reloc_done;
92
93 if (!reloc_done) {
94 if (ops->read)
95 ops->read += gd->reloc_off;
96 if (ops->write)
97 ops->write += gd->reloc_off;
98 if (ops->erase)
99 ops->erase += gd->reloc_off;
100
101 reloc_done++;
102 }
103#endif
104 return 0;
105}
106
Simon Glassd6eedf72014-10-13 23:42:06 -0600107UCLASS_DRIVER(spi_flash) = {
108 .id = UCLASS_SPI_FLASH,
109 .name = "spi_flash",
Michal Simekc790ede2015-10-27 13:52:47 +0100110 .post_bind = spi_flash_post_bind,
Simon Glassb33cd252020-12-19 10:40:01 -0700111 .per_device_auto = sizeof(struct spi_nor),
Simon Glassd6eedf72014-10-13 23:42:06 -0600112};