123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- // SPDX-License-Identifier: GPL-2.0
- //
- // Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
- // Author: Vignesh Raghavendra <vigneshr@ti.com>
- #include <common.h>
- #include <asm/io.h>
- #include <dm.h>
- #include <regmap.h>
- #include <syscon.h>
- #include <dm/device_compat.h>
- #define FSS_SYSC_REG 0x4
- #define HYPERBUS_CALIB_COUNT 25
- struct am654_hbmc_priv {
- void __iomem *mmiobase;
- bool calibrated;
- };
- /* Calibrate by looking for "QRY" string within the CFI space */
- static int am654_hyperbus_calibrate(struct udevice *dev)
- {
- struct am654_hbmc_priv *priv = dev_get_priv(dev);
- int count = HYPERBUS_CALIB_COUNT;
- int pass_count = 0;
- u16 qry[3];
- if (priv->calibrated)
- return 0;
- writew(0xF0, priv->mmiobase);
- writew(0x98, priv->mmiobase + 0xaa);
- while (count--) {
- qry[0] = readw(priv->mmiobase + 0x20);
- qry[1] = readw(priv->mmiobase + 0x22);
- qry[2] = readw(priv->mmiobase + 0x24);
- if (qry[0] == 'Q' && qry[1] == 'R' && qry[2] == 'Y')
- pass_count++;
- else
- pass_count = 0;
- if (pass_count == 5)
- break;
- }
- writew(0xF0, priv->mmiobase);
- writew(0xFF, priv->mmiobase);
- return pass_count == 5;
- }
- static int am654_select_hbmc(struct udevice *dev)
- {
- struct regmap *regmap = syscon_get_regmap(dev_get_parent(dev));
- return regmap_update_bits(regmap, FSS_SYSC_REG, 0x2, 0x2);
- }
- static int am654_hbmc_bind(struct udevice *dev)
- {
- return dm_scan_fdt_dev(dev);
- }
- static int am654_hbmc_probe(struct udevice *dev)
- {
- struct am654_hbmc_priv *priv = dev_get_priv(dev);
- int ret;
- priv->mmiobase = devfdt_remap_addr_index(dev, 1);
- if (dev_read_bool(dev, "mux-controls")) {
- ret = am654_select_hbmc(dev);
- if (ret) {
- dev_err(dev, "Failed to select HBMC mux\n");
- return ret;
- }
- }
- if (!priv->calibrated) {
- ret = am654_hyperbus_calibrate(dev);
- if (!ret) {
- dev_err(dev, "Calibration Failed\n");
- return -EIO;
- }
- }
- priv->calibrated = true;
- return 0;
- }
- static const struct udevice_id am654_hbmc_dt_ids[] = {
- {
- .compatible = "ti,am654-hbmc",
- },
- { /* end of table */ }
- };
- U_BOOT_DRIVER(hbmc_am654) = {
- .name = "hbmc-am654",
- .id = UCLASS_MTD,
- .of_match = am654_hbmc_dt_ids,
- .probe = am654_hbmc_probe,
- .bind = am654_hbmc_bind,
- .priv_auto = sizeof(struct am654_hbmc_priv),
- };
|