Merge tag 'mailbox-v5.15' of git://git.linaro.org/landing-teams/working/fujitsu/integ...
[linux-2.6-microblaze.git] / drivers / memory / dfl-emif.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * DFL device driver for EMIF private feature
4  *
5  * Copyright (C) 2020 Intel Corporation, Inc.
6  *
7  */
8 #include <linux/bitfield.h>
9 #include <linux/dfl.h>
10 #include <linux/errno.h>
11 #include <linux/io.h>
12 #include <linux/iopoll.h>
13 #include <linux/io-64-nonatomic-lo-hi.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/spinlock.h>
17 #include <linux/types.h>
18
19 #define FME_FEATURE_ID_EMIF             0x9
20
21 #define EMIF_STAT                       0x8
22 #define EMIF_STAT_INIT_DONE_SFT         0
23 #define EMIF_STAT_CALC_FAIL_SFT         8
24 #define EMIF_STAT_CLEAR_BUSY_SFT        16
25 #define EMIF_CTRL                       0x10
26 #define EMIF_CTRL_CLEAR_EN_SFT          0
27 #define EMIF_CTRL_CLEAR_EN_MSK          GENMASK_ULL(3, 0)
28
29 #define EMIF_POLL_INVL                  10000 /* us */
30 #define EMIF_POLL_TIMEOUT               5000000 /* us */
31
32 struct dfl_emif {
33         struct device *dev;
34         void __iomem *base;
35         spinlock_t lock;        /* Serialises access to EMIF_CTRL reg */
36 };
37
38 struct emif_attr {
39         struct device_attribute attr;
40         u32 shift;
41         u32 index;
42 };
43
44 #define to_emif_attr(dev_attr) \
45         container_of(dev_attr, struct emif_attr, attr)
46
47 static ssize_t emif_state_show(struct device *dev,
48                                struct device_attribute *attr, char *buf)
49 {
50         struct emif_attr *eattr = to_emif_attr(attr);
51         struct dfl_emif *de = dev_get_drvdata(dev);
52         u64 val;
53
54         val = readq(de->base + EMIF_STAT);
55
56         return sysfs_emit(buf, "%u\n",
57                           !!(val & BIT_ULL(eattr->shift + eattr->index)));
58 }
59
60 static ssize_t emif_clear_store(struct device *dev,
61                                 struct device_attribute *attr,
62                                 const char *buf, size_t count)
63 {
64         struct emif_attr *eattr = to_emif_attr(attr);
65         struct dfl_emif *de = dev_get_drvdata(dev);
66         u64 clear_busy_msk, clear_en_msk, val;
67         void __iomem *base = de->base;
68
69         if (!sysfs_streq(buf, "1"))
70                 return -EINVAL;
71
72         clear_busy_msk = BIT_ULL(EMIF_STAT_CLEAR_BUSY_SFT + eattr->index);
73         clear_en_msk = BIT_ULL(EMIF_CTRL_CLEAR_EN_SFT + eattr->index);
74
75         spin_lock(&de->lock);
76         /* The CLEAR_EN field is WO, but other fields are RW */
77         val = readq(base + EMIF_CTRL);
78         val &= ~EMIF_CTRL_CLEAR_EN_MSK;
79         val |= clear_en_msk;
80         writeq(val, base + EMIF_CTRL);
81         spin_unlock(&de->lock);
82
83         if (readq_poll_timeout(base + EMIF_STAT, val,
84                                !(val & clear_busy_msk),
85                                EMIF_POLL_INVL, EMIF_POLL_TIMEOUT)) {
86                 dev_err(de->dev, "timeout, fail to clear\n");
87                 return -ETIMEDOUT;
88         }
89
90         return count;
91 }
92
93 #define emif_state_attr(_name, _shift, _index)                          \
94         static struct emif_attr emif_attr_##inf##_index##_##_name =     \
95                 { .attr = __ATTR(inf##_index##_##_name, 0444,           \
96                                  emif_state_show, NULL),                \
97                   .shift = (_shift), .index = (_index) }
98
99 #define emif_clear_attr(_index)                                         \
100         static struct emif_attr emif_attr_##inf##_index##_clear =       \
101                 { .attr = __ATTR(inf##_index##_clear, 0200,             \
102                                  NULL, emif_clear_store),               \
103                   .index = (_index) }
104
105 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 0);
106 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 1);
107 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 2);
108 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 3);
109
110 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 0);
111 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 1);
112 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 2);
113 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 3);
114
115 emif_clear_attr(0);
116 emif_clear_attr(1);
117 emif_clear_attr(2);
118 emif_clear_attr(3);
119
120 static struct attribute *dfl_emif_attrs[] = {
121         &emif_attr_inf0_init_done.attr.attr,
122         &emif_attr_inf0_cal_fail.attr.attr,
123         &emif_attr_inf0_clear.attr.attr,
124
125         &emif_attr_inf1_init_done.attr.attr,
126         &emif_attr_inf1_cal_fail.attr.attr,
127         &emif_attr_inf1_clear.attr.attr,
128
129         &emif_attr_inf2_init_done.attr.attr,
130         &emif_attr_inf2_cal_fail.attr.attr,
131         &emif_attr_inf2_clear.attr.attr,
132
133         &emif_attr_inf3_init_done.attr.attr,
134         &emif_attr_inf3_cal_fail.attr.attr,
135         &emif_attr_inf3_clear.attr.attr,
136
137         NULL,
138 };
139
140 static umode_t dfl_emif_visible(struct kobject *kobj,
141                                 struct attribute *attr, int n)
142 {
143         struct dfl_emif *de = dev_get_drvdata(kobj_to_dev(kobj));
144         struct emif_attr *eattr = container_of(attr, struct emif_attr,
145                                                attr.attr);
146         u64 val;
147
148         /*
149          * This device supports upto 4 memory interfaces, but not all
150          * interfaces are used on different platforms. The read out value of
151          * CLEAN_EN field (which is a bitmap) could tell how many interfaces
152          * are available.
153          */
154         val = FIELD_GET(EMIF_CTRL_CLEAR_EN_MSK, readq(de->base + EMIF_CTRL));
155
156         return (val & BIT_ULL(eattr->index)) ? attr->mode : 0;
157 }
158
159 static const struct attribute_group dfl_emif_group = {
160         .is_visible = dfl_emif_visible,
161         .attrs = dfl_emif_attrs,
162 };
163
164 static const struct attribute_group *dfl_emif_groups[] = {
165         &dfl_emif_group,
166         NULL,
167 };
168
169 static int dfl_emif_probe(struct dfl_device *ddev)
170 {
171         struct device *dev = &ddev->dev;
172         struct dfl_emif *de;
173
174         de = devm_kzalloc(dev, sizeof(*de), GFP_KERNEL);
175         if (!de)
176                 return -ENOMEM;
177
178         de->base = devm_ioremap_resource(dev, &ddev->mmio_res);
179         if (IS_ERR(de->base))
180                 return PTR_ERR(de->base);
181
182         de->dev = dev;
183         spin_lock_init(&de->lock);
184         dev_set_drvdata(dev, de);
185
186         return 0;
187 }
188
189 static const struct dfl_device_id dfl_emif_ids[] = {
190         { FME_ID, FME_FEATURE_ID_EMIF },
191         { }
192 };
193 MODULE_DEVICE_TABLE(dfl, dfl_emif_ids);
194
195 static struct dfl_driver dfl_emif_driver = {
196         .drv    = {
197                 .name       = "dfl-emif",
198                 .dev_groups = dfl_emif_groups,
199         },
200         .id_table = dfl_emif_ids,
201         .probe   = dfl_emif_probe,
202 };
203 module_dfl_driver(dfl_emif_driver);
204
205 MODULE_DESCRIPTION("DFL EMIF driver");
206 MODULE_AUTHOR("Intel Corporation");
207 MODULE_LICENSE("GPL v2");