gpio: npcm: Add persist feature to sgpio module
[J-u-boot.git] / drivers / mtd / hbmc-am654.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/
4 // Author: Vignesh Raghavendra <vigneshr@ti.com>
5
6 #include <asm/io.h>
7 #include <dm.h>
8 #include <mux.h>
9 #include <regmap.h>
10 #include <dm/device_compat.h>
11
12 #define FSS_SYSC_REG    0x4
13
14 #define HYPERBUS_CALIB_COUNT 25
15
16 struct am654_hbmc_priv {
17         void __iomem *mmiobase;
18         bool calibrated;
19 };
20
21 /* Calibrate by looking for "QRY" string within the CFI space */
22 static int am654_hyperbus_calibrate(struct udevice *dev)
23 {
24         struct am654_hbmc_priv *priv = dev_get_priv(dev);
25         int count = HYPERBUS_CALIB_COUNT;
26         int pass_count = 0;
27         u16 qry[3];
28
29         if (priv->calibrated)
30                 return 0;
31
32         writew(0xF0, priv->mmiobase);
33         writew(0x98, priv->mmiobase + 0xaa);
34
35         while (count--) {
36                 qry[0] = readw(priv->mmiobase + 0x20);
37                 qry[1] = readw(priv->mmiobase + 0x22);
38                 qry[2] = readw(priv->mmiobase + 0x24);
39
40                 if (qry[0] == 'Q' && qry[1] == 'R' && qry[2] == 'Y')
41                         pass_count++;
42                 else
43                         pass_count = 0;
44                 if (pass_count == 5)
45                         break;
46         }
47         writew(0xF0, priv->mmiobase);
48         writew(0xFF, priv->mmiobase);
49
50         return pass_count == 5;
51 }
52
53 static int am654_select_hbmc(struct udevice *dev)
54 {
55         struct mux_control *mux_ctl;
56         int ret;
57
58         ret = mux_get_by_index(dev, 0, &mux_ctl);
59         if (!ret)
60                 ret = mux_control_select(mux_ctl, 1);
61         return ret;
62 }
63
64 static int am654_hbmc_bind(struct udevice *dev)
65 {
66         return dm_scan_fdt_dev(dev);
67 }
68
69 static int am654_hbmc_probe(struct udevice *dev)
70 {
71         struct am654_hbmc_priv *priv = dev_get_priv(dev);
72         int ret;
73
74         priv->mmiobase = devfdt_remap_addr_index(dev, 1);
75         if (dev_read_bool(dev, "mux-controls")) {
76                 ret = am654_select_hbmc(dev);
77                 if (ret) {
78                         dev_err(dev, "Failed to select HBMC mux\n");
79                         return ret;
80                 }
81         }
82
83         if (!priv->calibrated) {
84                 ret = am654_hyperbus_calibrate(dev);
85                 if (!ret) {
86                         dev_err(dev, "Calibration Failed\n");
87                         return -EIO;
88                 }
89         }
90         priv->calibrated = true;
91
92         return 0;
93 }
94
95 static const struct udevice_id am654_hbmc_dt_ids[] = {
96         {
97                 .compatible = "ti,am654-hbmc",
98         },
99         { /* end of table */ }
100 };
101
102 U_BOOT_DRIVER(hbmc_am654) = {
103         .name   = "hbmc-am654",
104         .id     = UCLASS_MTD,
105         .of_match = am654_hbmc_dt_ids,
106         .probe = am654_hbmc_probe,
107         .bind = am654_hbmc_bind,
108         .priv_auto      = sizeof(struct am654_hbmc_priv),
109 };
This page took 0.030984 seconds and 4 git commands to generate.