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(7, 0)
28
29 #define EMIF_POLL_INVL 10000 /* us */
30 #define EMIF_POLL_TIMEOUT 5000000 /* us */
31
32 /*
33 * The Capability Register replaces the Control Register (at the same
34 * offset) for EMIF feature revisions > 0. The bitmask that indicates
35 * the presence of memory channels exists in both the Capability Register
36 * and Control Register definitions. These can be thought of as a C union.
37 * The Capability Register definitions are used to check for the existence
38 * of a memory channel, and the Control Register definitions are used for
39 * managing the memory-clear functionality in revision 0.
40 */
41 #define EMIF_CAPABILITY_BASE 0x10
42 #define EMIF_CAPABILITY_CHN_MSK_V0 GENMASK_ULL(3, 0)
43 #define EMIF_CAPABILITY_CHN_MSK GENMASK_ULL(7, 0)
44
45 struct dfl_emif {
46 struct device *dev;
47 void __iomem *base;
48 spinlock_t lock; /* Serialises access to EMIF_CTRL reg */
49 };
50
51 struct emif_attr {
52 struct device_attribute attr;
53 u32 shift;
54 u32 index;
55 };
56
57 #define to_emif_attr(dev_attr) \
58 container_of(dev_attr, struct emif_attr, attr)
59
emif_state_show(struct device * dev,struct device_attribute * attr,char * buf)60 static ssize_t emif_state_show(struct device *dev,
61 struct device_attribute *attr, char *buf)
62 {
63 struct emif_attr *eattr = to_emif_attr(attr);
64 struct dfl_emif *de = dev_get_drvdata(dev);
65 u64 val;
66
67 val = readq(de->base + EMIF_STAT);
68
69 return sysfs_emit(buf, "%u\n",
70 !!(val & BIT_ULL(eattr->shift + eattr->index)));
71 }
72
emif_clear_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)73 static ssize_t emif_clear_store(struct device *dev,
74 struct device_attribute *attr,
75 const char *buf, size_t count)
76 {
77 struct emif_attr *eattr = to_emif_attr(attr);
78 struct dfl_emif *de = dev_get_drvdata(dev);
79 u64 clear_busy_msk, clear_en_msk, val;
80 void __iomem *base = de->base;
81
82 if (!sysfs_streq(buf, "1"))
83 return -EINVAL;
84
85 clear_busy_msk = BIT_ULL(EMIF_STAT_CLEAR_BUSY_SFT + eattr->index);
86 clear_en_msk = BIT_ULL(EMIF_CTRL_CLEAR_EN_SFT + eattr->index);
87
88 spin_lock(&de->lock);
89 /* The CLEAR_EN field is WO, but other fields are RW */
90 val = readq(base + EMIF_CTRL);
91 val &= ~EMIF_CTRL_CLEAR_EN_MSK;
92 val |= clear_en_msk;
93 writeq(val, base + EMIF_CTRL);
94 spin_unlock(&de->lock);
95
96 if (readq_poll_timeout(base + EMIF_STAT, val,
97 !(val & clear_busy_msk),
98 EMIF_POLL_INVL, EMIF_POLL_TIMEOUT)) {
99 dev_err(de->dev, "timeout, fail to clear\n");
100 return -ETIMEDOUT;
101 }
102
103 return count;
104 }
105
106 #define emif_state_attr(_name, _shift, _index) \
107 static struct emif_attr emif_attr_##inf##_index##_##_name = \
108 { .attr = __ATTR(inf##_index##_##_name, 0444, \
109 emif_state_show, NULL), \
110 .shift = (_shift), .index = (_index) }
111
112 #define emif_clear_attr(_index) \
113 static struct emif_attr emif_attr_##inf##_index##_clear = \
114 { .attr = __ATTR(inf##_index##_clear, 0200, \
115 NULL, emif_clear_store), \
116 .index = (_index) }
117
118 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 0);
119 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 1);
120 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 2);
121 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 3);
122 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 4);
123 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 5);
124 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 6);
125 emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 7);
126
127 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 0);
128 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 1);
129 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 2);
130 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 3);
131 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 4);
132 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 5);
133 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 6);
134 emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 7);
135
136
137 emif_clear_attr(0);
138 emif_clear_attr(1);
139 emif_clear_attr(2);
140 emif_clear_attr(3);
141 emif_clear_attr(4);
142 emif_clear_attr(5);
143 emif_clear_attr(6);
144 emif_clear_attr(7);
145
146
147 static struct attribute *dfl_emif_attrs[] = {
148 &emif_attr_inf0_init_done.attr.attr,
149 &emif_attr_inf0_cal_fail.attr.attr,
150 &emif_attr_inf0_clear.attr.attr,
151
152 &emif_attr_inf1_init_done.attr.attr,
153 &emif_attr_inf1_cal_fail.attr.attr,
154 &emif_attr_inf1_clear.attr.attr,
155
156 &emif_attr_inf2_init_done.attr.attr,
157 &emif_attr_inf2_cal_fail.attr.attr,
158 &emif_attr_inf2_clear.attr.attr,
159
160 &emif_attr_inf3_init_done.attr.attr,
161 &emif_attr_inf3_cal_fail.attr.attr,
162 &emif_attr_inf3_clear.attr.attr,
163
164 &emif_attr_inf4_init_done.attr.attr,
165 &emif_attr_inf4_cal_fail.attr.attr,
166 &emif_attr_inf4_clear.attr.attr,
167
168 &emif_attr_inf5_init_done.attr.attr,
169 &emif_attr_inf5_cal_fail.attr.attr,
170 &emif_attr_inf5_clear.attr.attr,
171
172 &emif_attr_inf6_init_done.attr.attr,
173 &emif_attr_inf6_cal_fail.attr.attr,
174 &emif_attr_inf6_clear.attr.attr,
175
176 &emif_attr_inf7_init_done.attr.attr,
177 &emif_attr_inf7_cal_fail.attr.attr,
178 &emif_attr_inf7_clear.attr.attr,
179
180 NULL,
181 };
182
dfl_emif_visible(struct kobject * kobj,struct attribute * attr,int n)183 static umode_t dfl_emif_visible(struct kobject *kobj,
184 struct attribute *attr, int n)
185 {
186 struct dfl_emif *de = dev_get_drvdata(kobj_to_dev(kobj));
187 struct emif_attr *eattr = container_of(attr, struct emif_attr,
188 attr.attr);
189 struct dfl_device *ddev = to_dfl_dev(de->dev);
190 u64 val;
191
192 /*
193 * This device supports up to 8 memory interfaces, but not all
194 * interfaces are used on different platforms. The read out value of
195 * CAPABILITY_CHN_MSK field (which is a bitmap) indicates which
196 * interfaces are available.
197 */
198 if (ddev->revision > 0 && strstr(attr->name, "_clear"))
199 return 0;
200
201 if (ddev->revision == 0)
202 val = FIELD_GET(EMIF_CAPABILITY_CHN_MSK_V0,
203 readq(de->base + EMIF_CAPABILITY_BASE));
204 else
205 val = FIELD_GET(EMIF_CAPABILITY_CHN_MSK,
206 readq(de->base + EMIF_CAPABILITY_BASE));
207
208 return (val & BIT_ULL(eattr->index)) ? attr->mode : 0;
209 }
210
211 static const struct attribute_group dfl_emif_group = {
212 .is_visible = dfl_emif_visible,
213 .attrs = dfl_emif_attrs,
214 };
215
216 static const struct attribute_group *dfl_emif_groups[] = {
217 &dfl_emif_group,
218 NULL,
219 };
220
dfl_emif_probe(struct dfl_device * ddev)221 static int dfl_emif_probe(struct dfl_device *ddev)
222 {
223 struct device *dev = &ddev->dev;
224 struct dfl_emif *de;
225
226 de = devm_kzalloc(dev, sizeof(*de), GFP_KERNEL);
227 if (!de)
228 return -ENOMEM;
229
230 de->base = devm_ioremap_resource(dev, &ddev->mmio_res);
231 if (IS_ERR(de->base))
232 return PTR_ERR(de->base);
233
234 de->dev = dev;
235 spin_lock_init(&de->lock);
236 dev_set_drvdata(dev, de);
237
238 return 0;
239 }
240
241 static const struct dfl_device_id dfl_emif_ids[] = {
242 { FME_ID, FME_FEATURE_ID_EMIF },
243 { }
244 };
245 MODULE_DEVICE_TABLE(dfl, dfl_emif_ids);
246
247 static struct dfl_driver dfl_emif_driver = {
248 .drv = {
249 .name = "dfl-emif",
250 .dev_groups = dfl_emif_groups,
251 },
252 .id_table = dfl_emif_ids,
253 .probe = dfl_emif_probe,
254 };
255 module_dfl_driver(dfl_emif_driver);
256
257 MODULE_DESCRIPTION("DFL EMIF driver");
258 MODULE_AUTHOR("Intel Corporation");
259 MODULE_LICENSE("GPL v2");
260