blob: 4afd679a04b2c9eeb559d3e22ed65b09513979ec [file] [log] [blame]
Masahiro Yamada9c5a5dd2017-08-26 01:12:31 +09001/*
2 * Copyright (C) 2017 Socionext Inc.
3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <common.h>
9#include <dm.h>
10#include <linux/io.h>
11#include <linux/ioport.h>
12
13#include "denali.h"
14
Masahiro Yamada54fde8e2017-09-15 21:43:19 +090015struct denali_dt_data {
16 unsigned int revision;
17 unsigned int caps;
18};
19
20static const struct denali_dt_data denali_socfpga_data = {
21 .caps = DENALI_CAP_HW_ECC_FIXUP,
22};
23
24static const struct denali_dt_data denali_uniphier_v5a_data = {
25 .caps = DENALI_CAP_HW_ECC_FIXUP |
26 DENALI_CAP_DMA_64BIT,
27};
28
29static const struct denali_dt_data denali_uniphier_v5b_data = {
30 .revision = 0x0501,
31 .caps = DENALI_CAP_HW_ECC_FIXUP |
32 DENALI_CAP_DMA_64BIT,
33};
34
Masahiro Yamada9c5a5dd2017-08-26 01:12:31 +090035static const struct udevice_id denali_nand_dt_ids[] = {
36 {
37 .compatible = "altr,socfpga-denali-nand",
Masahiro Yamada54fde8e2017-09-15 21:43:19 +090038 .data = (unsigned long)&denali_socfpga_data,
Masahiro Yamada9c5a5dd2017-08-26 01:12:31 +090039 },
40 {
41 .compatible = "socionext,uniphier-denali-nand-v5a",
Masahiro Yamada54fde8e2017-09-15 21:43:19 +090042 .data = (unsigned long)&denali_uniphier_v5a_data,
Masahiro Yamada9c5a5dd2017-08-26 01:12:31 +090043 },
44 {
45 .compatible = "socionext,uniphier-denali-nand-v5b",
Masahiro Yamada54fde8e2017-09-15 21:43:19 +090046 .data = (unsigned long)&denali_uniphier_v5b_data,
Masahiro Yamada9c5a5dd2017-08-26 01:12:31 +090047 },
48 { /* sentinel */ }
49};
50
51static int denali_dt_probe(struct udevice *dev)
52{
53 struct denali_nand_info *denali = dev_get_priv(dev);
Masahiro Yamada54fde8e2017-09-15 21:43:19 +090054 const struct denali_dt_data *data;
Masahiro Yamada9c5a5dd2017-08-26 01:12:31 +090055 struct resource res;
56 int ret;
57
Masahiro Yamada54fde8e2017-09-15 21:43:19 +090058 data = (void *)dev_get_driver_data(dev);
59 if (data) {
60 denali->revision = data->revision;
61 denali->caps = data->caps;
62 }
63
Masahiro Yamada9c5a5dd2017-08-26 01:12:31 +090064 ret = dev_read_resource_byname(dev, "denali_reg", &res);
65 if (ret)
66 return ret;
67
68 denali->flash_reg = devm_ioremap(dev, res.start, resource_size(&res));
69
70 ret = dev_read_resource_byname(dev, "nand_data", &res);
71 if (ret)
72 return ret;
73
74 denali->flash_mem = devm_ioremap(dev, res.start, resource_size(&res));
75
76 return denali_init(denali);
77}
78
79U_BOOT_DRIVER(denali_nand_dt) = {
80 .name = "denali-nand-dt",
81 .id = UCLASS_MISC,
82 .of_match = denali_nand_dt_ids,
83 .probe = denali_dt_probe,
84 .priv_auto_alloc_size = sizeof(struct denali_nand_info),
85};
86
87void board_nand_init(void)
88{
89 struct udevice *dev;
90 int ret;
91
92 ret = uclass_get_device_by_driver(UCLASS_MISC,
93 DM_GET_DRIVER(denali_nand_dt),
94 &dev);
95 if (ret && ret != -ENODEV)
96 printf("Failed to initialize Denali NAND controller. (error %d)\n",
97 ret);
98}