Merge tag 'reset-for-v5.3' of git://git.pengutronix.de/git/pza/linux into arm/drivers
[sfrench/cifs-2.6.git] / drivers / memory / brcmstb_dpfe.c
1 /*
2  * DDR PHY Front End (DPFE) driver for Broadcom set top box SoCs
3  *
4  * Copyright (c) 2017 Broadcom
5  *
6  * Released under the GPLv2 only.
7  * SPDX-License-Identifier: GPL-2.0
8  */
9
10 /*
11  * This driver provides access to the DPFE interface of Broadcom STB SoCs.
12  * The firmware running on the DCPU inside the DDR PHY can provide current
13  * information about the system's RAM, for instance the DRAM refresh rate.
14  * This can be used as an indirect indicator for the DRAM's temperature.
15  * Slower refresh rate means cooler RAM, higher refresh rate means hotter
16  * RAM.
17  *
18  * Throughout the driver, we use readl_relaxed() and writel_relaxed(), which
19  * already contain the appropriate le32_to_cpu()/cpu_to_le32() calls.
20  *
21  * Note regarding the loading of the firmware image: we use be32_to_cpu()
22  * and le_32_to_cpu(), so we can support the following four cases:
23  *     - LE kernel + LE firmware image (the most common case)
24  *     - LE kernel + BE firmware image
25  *     - BE kernel + LE firmware image
26  *     - BE kernel + BE firmware image
27  *
28  * The DPCU always runs in big endian mode. The firwmare image, however, can
29  * be in either format. Also, communication between host CPU and DCPU is
30  * always in little endian.
31  */
32
33 #include <linux/delay.h>
34 #include <linux/firmware.h>
35 #include <linux/io.h>
36 #include <linux/module.h>
37 #include <linux/of_address.h>
38 #include <linux/of_device.h>
39 #include <linux/platform_device.h>
40
41 #define DRVNAME                 "brcmstb-dpfe"
42
43 /* DCPU register offsets */
44 #define REG_DCPU_RESET          0x0
45 #define REG_TO_DCPU_MBOX        0x10
46 #define REG_TO_HOST_MBOX        0x14
47
48 /* Macros to process offsets returned by the DCPU */
49 #define DRAM_MSG_ADDR_OFFSET    0x0
50 #define DRAM_MSG_TYPE_OFFSET    0x1c
51 #define DRAM_MSG_ADDR_MASK      ((1UL << DRAM_MSG_TYPE_OFFSET) - 1)
52 #define DRAM_MSG_TYPE_MASK      ((1UL << \
53                                  (BITS_PER_LONG - DRAM_MSG_TYPE_OFFSET)) - 1)
54
55 /* Message RAM */
56 #define DCPU_MSG_RAM_START      0x100
57 #define DCPU_MSG_RAM(x)         (DCPU_MSG_RAM_START + (x) * sizeof(u32))
58
59 /* DRAM Info Offsets & Masks */
60 #define DRAM_INFO_INTERVAL      0x0
61 #define DRAM_INFO_MR4           0x4
62 #define DRAM_INFO_ERROR         0x8
63 #define DRAM_INFO_MR4_MASK      0xff
64 #define DRAM_INFO_MR4_SHIFT     24      /* We need to look at byte 3 */
65
66 /* DRAM MR4 Offsets & Masks */
67 #define DRAM_MR4_REFRESH        0x0     /* Refresh rate */
68 #define DRAM_MR4_SR_ABORT       0x3     /* Self Refresh Abort */
69 #define DRAM_MR4_PPRE           0x4     /* Post-package repair entry/exit */
70 #define DRAM_MR4_TH_OFFS        0x5     /* Thermal Offset; vendor specific */
71 #define DRAM_MR4_TUF            0x7     /* Temperature Update Flag */
72
73 #define DRAM_MR4_REFRESH_MASK   0x7
74 #define DRAM_MR4_SR_ABORT_MASK  0x1
75 #define DRAM_MR4_PPRE_MASK      0x1
76 #define DRAM_MR4_TH_OFFS_MASK   0x3
77 #define DRAM_MR4_TUF_MASK       0x1
78
79 /* DRAM Vendor Offsets & Masks (API v2) */
80 #define DRAM_VENDOR_MR5         0x0
81 #define DRAM_VENDOR_MR6         0x4
82 #define DRAM_VENDOR_MR7         0x8
83 #define DRAM_VENDOR_MR8         0xc
84 #define DRAM_VENDOR_ERROR       0x10
85 #define DRAM_VENDOR_MASK        0xff
86 #define DRAM_VENDOR_SHIFT       24      /* We need to look at byte 3 */
87
88 /* DRAM Information Offsets & Masks (API v3) */
89 #define DRAM_DDR_INFO_MR4       0x0
90 #define DRAM_DDR_INFO_MR5       0x4
91 #define DRAM_DDR_INFO_MR6       0x8
92 #define DRAM_DDR_INFO_MR7       0xc
93 #define DRAM_DDR_INFO_MR8       0x10
94 #define DRAM_DDR_INFO_ERROR     0x14
95 #define DRAM_DDR_INFO_MASK      0xff
96
97 /* Reset register bits & masks */
98 #define DCPU_RESET_SHIFT        0x0
99 #define DCPU_RESET_MASK         0x1
100 #define DCPU_CLK_DISABLE_SHIFT  0x2
101
102 /* DCPU return codes */
103 #define DCPU_RET_ERROR_BIT      BIT(31)
104 #define DCPU_RET_SUCCESS        0x1
105 #define DCPU_RET_ERR_HEADER     (DCPU_RET_ERROR_BIT | BIT(0))
106 #define DCPU_RET_ERR_INVAL      (DCPU_RET_ERROR_BIT | BIT(1))
107 #define DCPU_RET_ERR_CHKSUM     (DCPU_RET_ERROR_BIT | BIT(2))
108 #define DCPU_RET_ERR_COMMAND    (DCPU_RET_ERROR_BIT | BIT(3))
109 /* This error code is not firmware defined and only used in the driver. */
110 #define DCPU_RET_ERR_TIMEDOUT   (DCPU_RET_ERROR_BIT | BIT(4))
111
112 /* Firmware magic */
113 #define DPFE_BE_MAGIC           0xfe1010fe
114 #define DPFE_LE_MAGIC           0xfe0101fe
115
116 /* Error codes */
117 #define ERR_INVALID_MAGIC       -1
118 #define ERR_INVALID_SIZE        -2
119 #define ERR_INVALID_CHKSUM      -3
120
121 /* Message types */
122 #define DPFE_MSG_TYPE_COMMAND   1
123 #define DPFE_MSG_TYPE_RESPONSE  2
124
125 #define DELAY_LOOP_MAX          1000
126
127 enum dpfe_msg_fields {
128         MSG_HEADER,
129         MSG_COMMAND,
130         MSG_ARG_COUNT,
131         MSG_ARG0,
132         MSG_CHKSUM,
133         MSG_FIELD_MAX   = 16 /* Max number of arguments */
134 };
135
136 enum dpfe_commands {
137         DPFE_CMD_GET_INFO,
138         DPFE_CMD_GET_REFRESH,
139         DPFE_CMD_GET_VENDOR,
140         DPFE_CMD_MAX /* Last entry */
141 };
142
143 /*
144  * Format of the binary firmware file:
145  *
146  *   entry
147  *      0    header
148  *              value:  0xfe0101fe  <== little endian
149  *                      0xfe1010fe  <== big endian
150  *      1    sequence:
151  *              [31:16] total segments on this build
152  *              [15:0]  this segment sequence.
153  *      2    FW version
154  *      3    IMEM byte size
155  *      4    DMEM byte size
156  *           IMEM
157  *           DMEM
158  *      last checksum ==> sum of everything
159  */
160 struct dpfe_firmware_header {
161         u32 magic;
162         u32 sequence;
163         u32 version;
164         u32 imem_size;
165         u32 dmem_size;
166 };
167
168 /* Things we only need during initialization. */
169 struct init_data {
170         unsigned int dmem_len;
171         unsigned int imem_len;
172         unsigned int chksum;
173         bool is_big_endian;
174 };
175
176 /* API version and corresponding commands */
177 struct dpfe_api {
178         int version;
179         const char *fw_name;
180         const struct attribute_group **sysfs_attrs;
181         u32 command[DPFE_CMD_MAX][MSG_FIELD_MAX];
182 };
183
184 /* Things we need for as long as we are active. */
185 struct private_data {
186         void __iomem *regs;
187         void __iomem *dmem;
188         void __iomem *imem;
189         struct device *dev;
190         const struct dpfe_api *dpfe_api;
191         struct mutex lock;
192 };
193
194 static const char *error_text[] = {
195         "Success", "Header code incorrect", "Unknown command or argument",
196         "Incorrect checksum", "Malformed command", "Timed out",
197 };
198
199 /*
200  * Forward declaration of our sysfs attribute functions, so we can declare the
201  * attribute data structures early.
202  */
203 static ssize_t show_info(struct device *, struct device_attribute *, char *);
204 static ssize_t show_refresh(struct device *, struct device_attribute *, char *);
205 static ssize_t store_refresh(struct device *, struct device_attribute *,
206                           const char *, size_t);
207 static ssize_t show_vendor(struct device *, struct device_attribute *, char *);
208 static ssize_t show_dram(struct device *, struct device_attribute *, char *);
209
210 /*
211  * Declare our attributes early, so they can be referenced in the API data
212  * structure. We need to do this, because the attributes depend on the API
213  * version.
214  */
215 static DEVICE_ATTR(dpfe_info, 0444, show_info, NULL);
216 static DEVICE_ATTR(dpfe_refresh, 0644, show_refresh, store_refresh);
217 static DEVICE_ATTR(dpfe_vendor, 0444, show_vendor, NULL);
218 static DEVICE_ATTR(dpfe_dram, 0444, show_dram, NULL);
219
220 /* API v2 sysfs attributes */
221 static struct attribute *dpfe_v2_attrs[] = {
222         &dev_attr_dpfe_info.attr,
223         &dev_attr_dpfe_refresh.attr,
224         &dev_attr_dpfe_vendor.attr,
225         NULL
226 };
227 ATTRIBUTE_GROUPS(dpfe_v2);
228
229 /* API v3 sysfs attributes */
230 static struct attribute *dpfe_v3_attrs[] = {
231         &dev_attr_dpfe_info.attr,
232         &dev_attr_dpfe_dram.attr,
233         NULL
234 };
235 ATTRIBUTE_GROUPS(dpfe_v3);
236
237 /* API v2 firmware commands */
238 static const struct dpfe_api dpfe_api_v2 = {
239         .version = 2,
240         .fw_name = "dpfe.bin",
241         .sysfs_attrs = dpfe_v2_groups,
242         .command = {
243                 [DPFE_CMD_GET_INFO] = {
244                         [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
245                         [MSG_COMMAND] = 1,
246                         [MSG_ARG_COUNT] = 1,
247                         [MSG_ARG0] = 1,
248                         [MSG_CHKSUM] = 4,
249                 },
250                 [DPFE_CMD_GET_REFRESH] = {
251                         [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
252                         [MSG_COMMAND] = 2,
253                         [MSG_ARG_COUNT] = 1,
254                         [MSG_ARG0] = 1,
255                         [MSG_CHKSUM] = 5,
256                 },
257                 [DPFE_CMD_GET_VENDOR] = {
258                         [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
259                         [MSG_COMMAND] = 2,
260                         [MSG_ARG_COUNT] = 1,
261                         [MSG_ARG0] = 2,
262                         [MSG_CHKSUM] = 6,
263                 },
264         }
265 };
266
267 /* API v3 firmware commands */
268 static const struct dpfe_api dpfe_api_v3 = {
269         .version = 3,
270         .fw_name = NULL, /* We expect the firmware to have been downloaded! */
271         .sysfs_attrs = dpfe_v3_groups,
272         .command = {
273                 [DPFE_CMD_GET_INFO] = {
274                         [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
275                         [MSG_COMMAND] = 0x0101,
276                         [MSG_ARG_COUNT] = 1,
277                         [MSG_ARG0] = 1,
278                         [MSG_CHKSUM] = 0x104,
279                 },
280                 [DPFE_CMD_GET_REFRESH] = {
281                         [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
282                         [MSG_COMMAND] = 0x0202,
283                         [MSG_ARG_COUNT] = 0,
284                         /*
285                          * This is a bit ugly. Without arguments, the checksum
286                          * follows right after the argument count and not at
287                          * offset MSG_CHKSUM.
288                          */
289                         [MSG_ARG0] = 0x203,
290                 },
291                 /* There's no GET_VENDOR command in API v3. */
292         },
293 };
294
295 static bool is_dcpu_enabled(void __iomem *regs)
296 {
297         u32 val;
298
299         val = readl_relaxed(regs + REG_DCPU_RESET);
300
301         return !(val & DCPU_RESET_MASK);
302 }
303
304 static void __disable_dcpu(void __iomem *regs)
305 {
306         u32 val;
307
308         if (!is_dcpu_enabled(regs))
309                 return;
310
311         /* Put DCPU in reset if it's running. */
312         val = readl_relaxed(regs + REG_DCPU_RESET);
313         val |= (1 << DCPU_RESET_SHIFT);
314         writel_relaxed(val, regs + REG_DCPU_RESET);
315 }
316
317 static void __enable_dcpu(void __iomem *regs)
318 {
319         u32 val;
320
321         /* Clear mailbox registers. */
322         writel_relaxed(0, regs + REG_TO_DCPU_MBOX);
323         writel_relaxed(0, regs + REG_TO_HOST_MBOX);
324
325         /* Disable DCPU clock gating */
326         val = readl_relaxed(regs + REG_DCPU_RESET);
327         val &= ~(1 << DCPU_CLK_DISABLE_SHIFT);
328         writel_relaxed(val, regs + REG_DCPU_RESET);
329
330         /* Take DCPU out of reset */
331         val = readl_relaxed(regs + REG_DCPU_RESET);
332         val &= ~(1 << DCPU_RESET_SHIFT);
333         writel_relaxed(val, regs + REG_DCPU_RESET);
334 }
335
336 static unsigned int get_msg_chksum(const u32 msg[], unsigned int max)
337 {
338         unsigned int sum = 0;
339         unsigned int i;
340
341         /* Don't include the last field in the checksum. */
342         for (i = 0; i < max; i++)
343                 sum += msg[i];
344
345         return sum;
346 }
347
348 static void __iomem *get_msg_ptr(struct private_data *priv, u32 response,
349                                  char *buf, ssize_t *size)
350 {
351         unsigned int msg_type;
352         unsigned int offset;
353         void __iomem *ptr = NULL;
354
355         /* There is no need to use this function for API v3 or later. */
356         if (unlikely(priv->dpfe_api->version >= 3)) {
357                 return NULL;
358         }
359
360         msg_type = (response >> DRAM_MSG_TYPE_OFFSET) & DRAM_MSG_TYPE_MASK;
361         offset = (response >> DRAM_MSG_ADDR_OFFSET) & DRAM_MSG_ADDR_MASK;
362
363         /*
364          * msg_type == 1: the offset is relative to the message RAM
365          * msg_type == 0: the offset is relative to the data RAM (this is the
366          *                previous way of passing data)
367          * msg_type is anything else: there's critical hardware problem
368          */
369         switch (msg_type) {
370         case 1:
371                 ptr = priv->regs + DCPU_MSG_RAM_START + offset;
372                 break;
373         case 0:
374                 ptr = priv->dmem + offset;
375                 break;
376         default:
377                 dev_emerg(priv->dev, "invalid message reply from DCPU: %#x\n",
378                         response);
379                 if (buf && size)
380                         *size = sprintf(buf,
381                                 "FATAL: communication error with DCPU\n");
382         }
383
384         return ptr;
385 }
386
387 static void __finalize_command(struct private_data *priv)
388 {
389         unsigned int release_mbox;
390
391         /*
392          * It depends on the API version which MBOX register we have to write to
393          * to signal we are done.
394          */
395         release_mbox = (priv->dpfe_api->version < 3)
396                         ? REG_TO_HOST_MBOX : REG_TO_DCPU_MBOX;
397         writel_relaxed(0, priv->regs + release_mbox);
398 }
399
400 static int __send_command(struct private_data *priv, unsigned int cmd,
401                           u32 result[])
402 {
403         const u32 *msg = priv->dpfe_api->command[cmd];
404         void __iomem *regs = priv->regs;
405         unsigned int i, chksum, chksum_idx;
406         int ret = 0;
407         u32 resp;
408
409         if (cmd >= DPFE_CMD_MAX)
410                 return -1;
411
412         mutex_lock(&priv->lock);
413
414         /* Wait for DCPU to become ready */
415         for (i = 0; i < DELAY_LOOP_MAX; i++) {
416                 resp = readl_relaxed(regs + REG_TO_HOST_MBOX);
417                 if (resp == 0)
418                         break;
419                 msleep(1);
420         }
421         if (resp != 0) {
422                 mutex_unlock(&priv->lock);
423                 return -ETIMEDOUT;
424         }
425
426         /* Write command and arguments to message area */
427         for (i = 0; i < MSG_FIELD_MAX; i++)
428                 writel_relaxed(msg[i], regs + DCPU_MSG_RAM(i));
429
430         /* Tell DCPU there is a command waiting */
431         writel_relaxed(1, regs + REG_TO_DCPU_MBOX);
432
433         /* Wait for DCPU to process the command */
434         for (i = 0; i < DELAY_LOOP_MAX; i++) {
435                 /* Read response code */
436                 resp = readl_relaxed(regs + REG_TO_HOST_MBOX);
437                 if (resp > 0)
438                         break;
439                 msleep(1);
440         }
441
442         if (i == DELAY_LOOP_MAX) {
443                 resp = (DCPU_RET_ERR_TIMEDOUT & ~DCPU_RET_ERROR_BIT);
444                 ret = -ffs(resp);
445         } else {
446                 /* Read response data */
447                 for (i = 0; i < MSG_FIELD_MAX; i++)
448                         result[i] = readl_relaxed(regs + DCPU_MSG_RAM(i));
449                 chksum_idx = result[MSG_ARG_COUNT] + MSG_ARG_COUNT + 1;
450         }
451
452         /* Tell DCPU we are done */
453         __finalize_command(priv);
454
455         mutex_unlock(&priv->lock);
456
457         if (ret)
458                 return ret;
459
460         /* Verify response */
461         chksum = get_msg_chksum(result, chksum_idx);
462         if (chksum != result[chksum_idx])
463                 resp = DCPU_RET_ERR_CHKSUM;
464
465         if (resp != DCPU_RET_SUCCESS) {
466                 resp &= ~DCPU_RET_ERROR_BIT;
467                 ret = -ffs(resp);
468         }
469
470         return ret;
471 }
472
473 /* Ensure that the firmware file loaded meets all the requirements. */
474 static int __verify_firmware(struct init_data *init,
475                              const struct firmware *fw)
476 {
477         const struct dpfe_firmware_header *header = (void *)fw->data;
478         unsigned int dmem_size, imem_size, total_size;
479         bool is_big_endian = false;
480         const u32 *chksum_ptr;
481
482         if (header->magic == DPFE_BE_MAGIC)
483                 is_big_endian = true;
484         else if (header->magic != DPFE_LE_MAGIC)
485                 return ERR_INVALID_MAGIC;
486
487         if (is_big_endian) {
488                 dmem_size = be32_to_cpu(header->dmem_size);
489                 imem_size = be32_to_cpu(header->imem_size);
490         } else {
491                 dmem_size = le32_to_cpu(header->dmem_size);
492                 imem_size = le32_to_cpu(header->imem_size);
493         }
494
495         /* Data and instruction sections are 32 bit words. */
496         if ((dmem_size % sizeof(u32)) != 0 || (imem_size % sizeof(u32)) != 0)
497                 return ERR_INVALID_SIZE;
498
499         /*
500          * The header + the data section + the instruction section + the
501          * checksum must be equal to the total firmware size.
502          */
503         total_size = dmem_size + imem_size + sizeof(*header) +
504                 sizeof(*chksum_ptr);
505         if (total_size != fw->size)
506                 return ERR_INVALID_SIZE;
507
508         /* The checksum comes at the very end. */
509         chksum_ptr = (void *)fw->data + sizeof(*header) + dmem_size + imem_size;
510
511         init->is_big_endian = is_big_endian;
512         init->dmem_len = dmem_size;
513         init->imem_len = imem_size;
514         init->chksum = (is_big_endian)
515                 ? be32_to_cpu(*chksum_ptr) : le32_to_cpu(*chksum_ptr);
516
517         return 0;
518 }
519
520 /* Verify checksum by reading back the firmware from co-processor RAM. */
521 static int __verify_fw_checksum(struct init_data *init,
522                                 struct private_data *priv,
523                                 const struct dpfe_firmware_header *header,
524                                 u32 checksum)
525 {
526         u32 magic, sequence, version, sum;
527         u32 __iomem *dmem = priv->dmem;
528         u32 __iomem *imem = priv->imem;
529         unsigned int i;
530
531         if (init->is_big_endian) {
532                 magic = be32_to_cpu(header->magic);
533                 sequence = be32_to_cpu(header->sequence);
534                 version = be32_to_cpu(header->version);
535         } else {
536                 magic = le32_to_cpu(header->magic);
537                 sequence = le32_to_cpu(header->sequence);
538                 version = le32_to_cpu(header->version);
539         }
540
541         sum = magic + sequence + version + init->dmem_len + init->imem_len;
542
543         for (i = 0; i < init->dmem_len / sizeof(u32); i++)
544                 sum += readl_relaxed(dmem + i);
545
546         for (i = 0; i < init->imem_len / sizeof(u32); i++)
547                 sum += readl_relaxed(imem + i);
548
549         return (sum == checksum) ? 0 : -1;
550 }
551
552 static int __write_firmware(u32 __iomem *mem, const u32 *fw,
553                             unsigned int size, bool is_big_endian)
554 {
555         unsigned int i;
556
557         /* Convert size to 32-bit words. */
558         size /= sizeof(u32);
559
560         /* It is recommended to clear the firmware area first. */
561         for (i = 0; i < size; i++)
562                 writel_relaxed(0, mem + i);
563
564         /* Now copy it. */
565         if (is_big_endian) {
566                 for (i = 0; i < size; i++)
567                         writel_relaxed(be32_to_cpu(fw[i]), mem + i);
568         } else {
569                 for (i = 0; i < size; i++)
570                         writel_relaxed(le32_to_cpu(fw[i]), mem + i);
571         }
572
573         return 0;
574 }
575
576 static int brcmstb_dpfe_download_firmware(struct platform_device *pdev,
577                                           struct init_data *init)
578 {
579         const struct dpfe_firmware_header *header;
580         unsigned int dmem_size, imem_size;
581         struct device *dev = &pdev->dev;
582         bool is_big_endian = false;
583         struct private_data *priv;
584         const struct firmware *fw;
585         const u32 *dmem, *imem;
586         const void *fw_blob;
587         int ret;
588
589         priv = platform_get_drvdata(pdev);
590
591         /*
592          * Skip downloading the firmware if the DCPU is already running and
593          * responding to commands.
594          */
595         if (is_dcpu_enabled(priv->regs)) {
596                 u32 response[MSG_FIELD_MAX];
597
598                 ret = __send_command(priv, DPFE_CMD_GET_INFO, response);
599                 if (!ret)
600                         return 0;
601         }
602
603         /*
604          * If the firmware filename is NULL it means the boot firmware has to
605          * download the DCPU firmware for us. If that didn't work, we have to
606          * bail, since downloading it ourselves wouldn't work either.
607          */
608         if (!priv->dpfe_api->fw_name)
609                 return -ENODEV;
610
611         ret = request_firmware(&fw, priv->dpfe_api->fw_name, dev);
612         /* request_firmware() prints its own error messages. */
613         if (ret)
614                 return ret;
615
616         ret = __verify_firmware(init, fw);
617         if (ret)
618                 return -EFAULT;
619
620         __disable_dcpu(priv->regs);
621
622         is_big_endian = init->is_big_endian;
623         dmem_size = init->dmem_len;
624         imem_size = init->imem_len;
625
626         /* At the beginning of the firmware blob is a header. */
627         header = (struct dpfe_firmware_header *)fw->data;
628         /* Void pointer to the beginning of the actual firmware. */
629         fw_blob = fw->data + sizeof(*header);
630         /* IMEM comes right after the header. */
631         imem = fw_blob;
632         /* DMEM follows after IMEM. */
633         dmem = fw_blob + imem_size;
634
635         ret = __write_firmware(priv->dmem, dmem, dmem_size, is_big_endian);
636         if (ret)
637                 return ret;
638         ret = __write_firmware(priv->imem, imem, imem_size, is_big_endian);
639         if (ret)
640                 return ret;
641
642         ret = __verify_fw_checksum(init, priv, header, init->chksum);
643         if (ret)
644                 return ret;
645
646         __enable_dcpu(priv->regs);
647
648         return 0;
649 }
650
651 static ssize_t generic_show(unsigned int command, u32 response[],
652                             struct private_data *priv, char *buf)
653 {
654         int ret;
655
656         if (!priv)
657                 return sprintf(buf, "ERROR: driver private data not set\n");
658
659         ret = __send_command(priv, command, response);
660         if (ret < 0)
661                 return sprintf(buf, "ERROR: %s\n", error_text[-ret]);
662
663         return 0;
664 }
665
666 static ssize_t show_info(struct device *dev, struct device_attribute *devattr,
667                          char *buf)
668 {
669         u32 response[MSG_FIELD_MAX];
670         struct private_data *priv;
671         unsigned int info;
672         ssize_t ret;
673
674         priv = dev_get_drvdata(dev);
675         ret = generic_show(DPFE_CMD_GET_INFO, response, priv, buf);
676         if (ret)
677                 return ret;
678
679         info = response[MSG_ARG0];
680
681         return sprintf(buf, "%u.%u.%u.%u\n",
682                        (info >> 24) & 0xff,
683                        (info >> 16) & 0xff,
684                        (info >> 8) & 0xff,
685                        info & 0xff);
686 }
687
688 static ssize_t show_refresh(struct device *dev,
689                             struct device_attribute *devattr, char *buf)
690 {
691         u32 response[MSG_FIELD_MAX];
692         void __iomem *info;
693         struct private_data *priv;
694         u8 refresh, sr_abort, ppre, thermal_offs, tuf;
695         u32 mr4;
696         ssize_t ret;
697
698         priv = dev_get_drvdata(dev);
699         ret = generic_show(DPFE_CMD_GET_REFRESH, response, priv, buf);
700         if (ret)
701                 return ret;
702
703         info = get_msg_ptr(priv, response[MSG_ARG0], buf, &ret);
704         if (!info)
705                 return ret;
706
707         mr4 = (readl_relaxed(info + DRAM_INFO_MR4) >> DRAM_INFO_MR4_SHIFT) &
708                DRAM_INFO_MR4_MASK;
709
710         refresh = (mr4 >> DRAM_MR4_REFRESH) & DRAM_MR4_REFRESH_MASK;
711         sr_abort = (mr4 >> DRAM_MR4_SR_ABORT) & DRAM_MR4_SR_ABORT_MASK;
712         ppre = (mr4 >> DRAM_MR4_PPRE) & DRAM_MR4_PPRE_MASK;
713         thermal_offs = (mr4 >> DRAM_MR4_TH_OFFS) & DRAM_MR4_TH_OFFS_MASK;
714         tuf = (mr4 >> DRAM_MR4_TUF) & DRAM_MR4_TUF_MASK;
715
716         return sprintf(buf, "%#x %#x %#x %#x %#x %#x %#x\n",
717                        readl_relaxed(info + DRAM_INFO_INTERVAL),
718                        refresh, sr_abort, ppre, thermal_offs, tuf,
719                        readl_relaxed(info + DRAM_INFO_ERROR));
720 }
721
722 static ssize_t store_refresh(struct device *dev, struct device_attribute *attr,
723                           const char *buf, size_t count)
724 {
725         u32 response[MSG_FIELD_MAX];
726         struct private_data *priv;
727         void __iomem *info;
728         unsigned long val;
729         int ret;
730
731         if (kstrtoul(buf, 0, &val) < 0)
732                 return -EINVAL;
733
734         priv = dev_get_drvdata(dev);
735         ret = __send_command(priv, DPFE_CMD_GET_REFRESH, response);
736         if (ret)
737                 return ret;
738
739         info = get_msg_ptr(priv, response[MSG_ARG0], NULL, NULL);
740         if (!info)
741                 return -EIO;
742
743         writel_relaxed(val, info + DRAM_INFO_INTERVAL);
744
745         return count;
746 }
747
748 static ssize_t show_vendor(struct device *dev, struct device_attribute *devattr,
749                            char *buf)
750 {
751         u32 response[MSG_FIELD_MAX];
752         struct private_data *priv;
753         void __iomem *info;
754         ssize_t ret;
755         u32 mr5, mr6, mr7, mr8, err;
756
757         priv = dev_get_drvdata(dev);
758         ret = generic_show(DPFE_CMD_GET_VENDOR, response, priv, buf);
759         if (ret)
760                 return ret;
761
762         info = get_msg_ptr(priv, response[MSG_ARG0], buf, &ret);
763         if (!info)
764                 return ret;
765
766         mr5 = (readl_relaxed(info + DRAM_VENDOR_MR5) >> DRAM_VENDOR_SHIFT) &
767                 DRAM_VENDOR_MASK;
768         mr6 = (readl_relaxed(info + DRAM_VENDOR_MR6) >> DRAM_VENDOR_SHIFT) &
769                 DRAM_VENDOR_MASK;
770         mr7 = (readl_relaxed(info + DRAM_VENDOR_MR7) >> DRAM_VENDOR_SHIFT) &
771                 DRAM_VENDOR_MASK;
772         mr8 = (readl_relaxed(info + DRAM_VENDOR_MR8) >> DRAM_VENDOR_SHIFT) &
773                 DRAM_VENDOR_MASK;
774         err = readl_relaxed(info + DRAM_VENDOR_ERROR) & DRAM_VENDOR_MASK;
775
776         return sprintf(buf, "%#x %#x %#x %#x %#x\n", mr5, mr6, mr7, mr8, err);
777 }
778
779 static ssize_t show_dram(struct device *dev, struct device_attribute *devattr,
780                          char *buf)
781 {
782         u32 response[MSG_FIELD_MAX];
783         struct private_data *priv;
784         ssize_t ret;
785         u32 mr4, mr5, mr6, mr7, mr8, err;
786
787         priv = dev_get_drvdata(dev);
788         ret = generic_show(DPFE_CMD_GET_REFRESH, response, priv, buf);
789         if (ret)
790                 return ret;
791
792         mr4 = response[MSG_ARG0 + 0] & DRAM_INFO_MR4_MASK;
793         mr5 = response[MSG_ARG0 + 1] & DRAM_DDR_INFO_MASK;
794         mr6 = response[MSG_ARG0 + 2] & DRAM_DDR_INFO_MASK;
795         mr7 = response[MSG_ARG0 + 3] & DRAM_DDR_INFO_MASK;
796         mr8 = response[MSG_ARG0 + 4] & DRAM_DDR_INFO_MASK;
797         err = response[MSG_ARG0 + 5] & DRAM_DDR_INFO_MASK;
798
799         return sprintf(buf, "%#x %#x %#x %#x %#x %#x\n", mr4, mr5, mr6, mr7,
800                         mr8, err);
801 }
802
803 static int brcmstb_dpfe_resume(struct platform_device *pdev)
804 {
805         struct init_data init;
806
807         return brcmstb_dpfe_download_firmware(pdev, &init);
808 }
809
810 static int brcmstb_dpfe_probe(struct platform_device *pdev)
811 {
812         struct device *dev = &pdev->dev;
813         struct private_data *priv;
814         struct init_data init;
815         struct resource *res;
816         int ret;
817
818         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
819         if (!priv)
820                 return -ENOMEM;
821
822         mutex_init(&priv->lock);
823         platform_set_drvdata(pdev, priv);
824
825         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dpfe-cpu");
826         priv->regs = devm_ioremap_resource(dev, res);
827         if (IS_ERR(priv->regs)) {
828                 dev_err(dev, "couldn't map DCPU registers\n");
829                 return -ENODEV;
830         }
831
832         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dpfe-dmem");
833         priv->dmem = devm_ioremap_resource(dev, res);
834         if (IS_ERR(priv->dmem)) {
835                 dev_err(dev, "Couldn't map DCPU data memory\n");
836                 return -ENOENT;
837         }
838
839         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dpfe-imem");
840         priv->imem = devm_ioremap_resource(dev, res);
841         if (IS_ERR(priv->imem)) {
842                 dev_err(dev, "Couldn't map DCPU instruction memory\n");
843                 return -ENOENT;
844         }
845
846         priv->dpfe_api = of_device_get_match_data(dev);
847         if (unlikely(!priv->dpfe_api)) {
848                 /*
849                  * It should be impossible to end up here, but to be safe we
850                  * check anyway.
851                  */
852                 dev_err(dev, "Couldn't determine API\n");
853                 return -ENOENT;
854         }
855
856         ret = brcmstb_dpfe_download_firmware(pdev, &init);
857         if (ret) {
858                 dev_err(dev, "Couldn't download firmware -- %d\n", ret);
859                 return ret;
860         }
861
862         ret = sysfs_create_groups(&pdev->dev.kobj, priv->dpfe_api->sysfs_attrs);
863         if (!ret)
864                 dev_info(dev, "registered with API v%d.\n",
865                          priv->dpfe_api->version);
866
867         return ret;
868 }
869
870 static int brcmstb_dpfe_remove(struct platform_device *pdev)
871 {
872         struct private_data *priv = dev_get_drvdata(&pdev->dev);
873
874         sysfs_remove_groups(&pdev->dev.kobj, priv->dpfe_api->sysfs_attrs);
875
876         return 0;
877 }
878
879 static const struct of_device_id brcmstb_dpfe_of_match[] = {
880         /* Use legacy API v2 for a select number of chips */
881         { .compatible = "brcm,bcm7268-dpfe-cpu", .data = &dpfe_api_v2 },
882         { .compatible = "brcm,bcm7271-dpfe-cpu", .data = &dpfe_api_v2 },
883         { .compatible = "brcm,bcm7278-dpfe-cpu", .data = &dpfe_api_v2 },
884         { .compatible = "brcm,bcm7211-dpfe-cpu", .data = &dpfe_api_v2 },
885         /* API v3 is the default going forward */
886         { .compatible = "brcm,dpfe-cpu", .data = &dpfe_api_v3 },
887         {}
888 };
889 MODULE_DEVICE_TABLE(of, brcmstb_dpfe_of_match);
890
891 static struct platform_driver brcmstb_dpfe_driver = {
892         .driver = {
893                 .name = DRVNAME,
894                 .of_match_table = brcmstb_dpfe_of_match,
895         },
896         .probe = brcmstb_dpfe_probe,
897         .remove = brcmstb_dpfe_remove,
898         .resume = brcmstb_dpfe_resume,
899 };
900
901 module_platform_driver(brcmstb_dpfe_driver);
902
903 MODULE_AUTHOR("Markus Mayer <mmayer@broadcom.com>");
904 MODULE_DESCRIPTION("BRCMSTB DDR PHY Front End Driver");
905 MODULE_LICENSE("GPL");