Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 //
0003 // Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
0004 //
0005 // Authors:
0006 //   Ramil Zaripov <Ramil.Zaripov@baikalelectronics.ru>
0007 //   Serge Semin <Sergey.Semin@baikalelectronics.ru>
0008 //
0009 // Baikal-T1 DW APB SPI and System Boot SPI driver
0010 //
0011 
0012 #include <linux/clk.h>
0013 #include <linux/cpumask.h>
0014 #include <linux/err.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/module.h>
0017 #include <linux/mux/consumer.h>
0018 #include <linux/of.h>
0019 #include <linux/of_platform.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/pm_runtime.h>
0022 #include <linux/property.h>
0023 #include <linux/slab.h>
0024 #include <linux/spi/spi-mem.h>
0025 #include <linux/spi/spi.h>
0026 
0027 #include "spi-dw.h"
0028 
0029 #define BT1_BOOT_DIRMAP     0
0030 #define BT1_BOOT_REGS       1
0031 
0032 struct dw_spi_bt1 {
0033     struct dw_spi       dws;
0034     struct clk      *clk;
0035     struct mux_control  *mux;
0036 
0037 #ifdef CONFIG_SPI_DW_BT1_DIRMAP
0038     void __iomem        *map;
0039     resource_size_t     map_len;
0040 #endif
0041 };
0042 #define to_dw_spi_bt1(_ctlr) \
0043     container_of(spi_controller_get_devdata(_ctlr), struct dw_spi_bt1, dws)
0044 
0045 typedef int (*dw_spi_bt1_init_cb)(struct platform_device *pdev,
0046                     struct dw_spi_bt1 *dwsbt1);
0047 
0048 #ifdef CONFIG_SPI_DW_BT1_DIRMAP
0049 
0050 static int dw_spi_bt1_dirmap_create(struct spi_mem_dirmap_desc *desc)
0051 {
0052     struct dw_spi_bt1 *dwsbt1 = to_dw_spi_bt1(desc->mem->spi->controller);
0053 
0054     if (!dwsbt1->map ||
0055         !dwsbt1->dws.mem_ops.supports_op(desc->mem, &desc->info.op_tmpl))
0056         return -EOPNOTSUPP;
0057 
0058     /*
0059      * Make sure the requested region doesn't go out of the physically
0060      * mapped flash memory bounds and the operation is read-only.
0061      */
0062     if (desc->info.offset + desc->info.length > dwsbt1->map_len ||
0063         desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN)
0064         return -EOPNOTSUPP;
0065 
0066     return 0;
0067 }
0068 
0069 /*
0070  * Directly mapped SPI memory region is only accessible in the dword chunks.
0071  * That's why we have to create a dedicated read-method to copy data from there
0072  * to the passed buffer.
0073  */
0074 static void dw_spi_bt1_dirmap_copy_from_map(void *to, void __iomem *from, size_t len)
0075 {
0076     size_t shift, chunk;
0077     u32 data;
0078 
0079     /*
0080      * We split the copying up into the next three stages: unaligned head,
0081      * aligned body, unaligned tail.
0082      */
0083     shift = (size_t)from & 0x3;
0084     if (shift) {
0085         chunk = min_t(size_t, 4 - shift, len);
0086         data = readl_relaxed(from - shift);
0087         memcpy(to, (char *)&data + shift, chunk);
0088         from += chunk;
0089         to += chunk;
0090         len -= chunk;
0091     }
0092 
0093     while (len >= 4) {
0094         data = readl_relaxed(from);
0095         memcpy(to, &data, 4);
0096         from += 4;
0097         to += 4;
0098         len -= 4;
0099     }
0100 
0101     if (len) {
0102         data = readl_relaxed(from);
0103         memcpy(to, &data, len);
0104     }
0105 }
0106 
0107 static ssize_t dw_spi_bt1_dirmap_read(struct spi_mem_dirmap_desc *desc,
0108                       u64 offs, size_t len, void *buf)
0109 {
0110     struct dw_spi_bt1 *dwsbt1 = to_dw_spi_bt1(desc->mem->spi->controller);
0111     struct dw_spi *dws = &dwsbt1->dws;
0112     struct spi_mem *mem = desc->mem;
0113     struct dw_spi_cfg cfg;
0114     int ret;
0115 
0116     /*
0117      * Make sure the requested operation length is valid. Truncate the
0118      * length if it's greater than the length of the MMIO region.
0119      */
0120     if (offs >= dwsbt1->map_len || !len)
0121         return 0;
0122 
0123     len = min_t(size_t, len, dwsbt1->map_len - offs);
0124 
0125     /* Collect the controller configuration required by the operation */
0126     cfg.tmode = DW_SPI_CTRLR0_TMOD_EPROMREAD;
0127     cfg.dfs = 8;
0128     cfg.ndf = 4;
0129     cfg.freq = mem->spi->max_speed_hz;
0130 
0131     /* Make sure the corresponding CS is de-asserted on transmission */
0132     dw_spi_set_cs(mem->spi, false);
0133 
0134     dw_spi_enable_chip(dws, 0);
0135 
0136     dw_spi_update_config(dws, mem->spi, &cfg);
0137 
0138     dw_spi_umask_intr(dws, DW_SPI_INT_RXFI);
0139 
0140     dw_spi_enable_chip(dws, 1);
0141 
0142     /*
0143      * Enable the transparent mode of the System Boot Controller.
0144      * The SPI core IO should have been locked before calling this method
0145      * so noone would be touching the controller' registers during the
0146      * dirmap operation.
0147      */
0148     ret = mux_control_select(dwsbt1->mux, BT1_BOOT_DIRMAP);
0149     if (ret)
0150         return ret;
0151 
0152     dw_spi_bt1_dirmap_copy_from_map(buf, dwsbt1->map + offs, len);
0153 
0154     mux_control_deselect(dwsbt1->mux);
0155 
0156     dw_spi_set_cs(mem->spi, true);
0157 
0158     ret = dw_spi_check_status(dws, true);
0159 
0160     return ret ?: len;
0161 }
0162 
0163 #endif /* CONFIG_SPI_DW_BT1_DIRMAP */
0164 
0165 static int dw_spi_bt1_std_init(struct platform_device *pdev,
0166                    struct dw_spi_bt1 *dwsbt1)
0167 {
0168     struct dw_spi *dws = &dwsbt1->dws;
0169 
0170     dws->irq = platform_get_irq(pdev, 0);
0171     if (dws->irq < 0)
0172         return dws->irq;
0173 
0174     dws->num_cs = 4;
0175 
0176     /*
0177      * Baikal-T1 Normal SPI Controllers don't always keep up with full SPI
0178      * bus speed especially when it comes to the concurrent access to the
0179      * APB bus resources. Thus we have no choice but to set a constraint on
0180      * the SPI bus frequency for the memory operations which require to
0181      * read/write data as fast as possible.
0182      */
0183     dws->max_mem_freq = 20000000U;
0184 
0185     dw_spi_dma_setup_generic(dws);
0186 
0187     return 0;
0188 }
0189 
0190 static int dw_spi_bt1_sys_init(struct platform_device *pdev,
0191                    struct dw_spi_bt1 *dwsbt1)
0192 {
0193     struct resource *mem __maybe_unused;
0194     struct dw_spi *dws = &dwsbt1->dws;
0195 
0196     /*
0197      * Baikal-T1 System Boot Controller is equipped with a mux, which
0198      * switches between the directly mapped SPI flash access mode and
0199      * IO access to the DW APB SSI registers. Note the mux controller
0200      * must be setup to preserve the registers being accessible by default
0201      * (on idle-state).
0202      */
0203     dwsbt1->mux = devm_mux_control_get(&pdev->dev, NULL);
0204     if (IS_ERR(dwsbt1->mux))
0205         return PTR_ERR(dwsbt1->mux);
0206 
0207     /*
0208      * Directly mapped SPI flash memory is a 16MB MMIO region, which can be
0209      * used to access a peripheral memory device just by reading/writing
0210      * data from/to it. Note the system APB bus will stall during each IO
0211      * from/to the dirmap region until the operation is finished. So don't
0212      * use it concurrently with time-critical tasks (like the SPI memory
0213      * operations implemented in the DW APB SSI driver).
0214      */
0215 #ifdef CONFIG_SPI_DW_BT1_DIRMAP
0216     mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
0217     if (mem) {
0218         dwsbt1->map = devm_ioremap_resource(&pdev->dev, mem);
0219         if (!IS_ERR(dwsbt1->map)) {
0220             dwsbt1->map_len = resource_size(mem);
0221             dws->mem_ops.dirmap_create = dw_spi_bt1_dirmap_create;
0222             dws->mem_ops.dirmap_read = dw_spi_bt1_dirmap_read;
0223         } else {
0224             dwsbt1->map = NULL;
0225         }
0226     }
0227 #endif /* CONFIG_SPI_DW_BT1_DIRMAP */
0228 
0229     /*
0230      * There is no IRQ, no DMA and just one CS available on the System Boot
0231      * SPI controller.
0232      */
0233     dws->irq = IRQ_NOTCONNECTED;
0234     dws->num_cs = 1;
0235 
0236     /*
0237      * Baikal-T1 System Boot SPI Controller doesn't keep up with the full
0238      * SPI bus speed due to relatively slow APB bus and races for it'
0239      * resources from different CPUs. The situation is worsen by a small
0240      * FIFOs depth (just 8 words). It works better in a single CPU mode
0241      * though, but still tends to be not fast enough at low CPU
0242      * frequencies.
0243      */
0244     if (num_possible_cpus() > 1)
0245         dws->max_mem_freq = 10000000U;
0246     else
0247         dws->max_mem_freq = 20000000U;
0248 
0249     return 0;
0250 }
0251 
0252 static int dw_spi_bt1_probe(struct platform_device *pdev)
0253 {
0254     dw_spi_bt1_init_cb init_func;
0255     struct dw_spi_bt1 *dwsbt1;
0256     struct resource *mem;
0257     struct dw_spi *dws;
0258     int ret;
0259 
0260     dwsbt1 = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_bt1), GFP_KERNEL);
0261     if (!dwsbt1)
0262         return -ENOMEM;
0263 
0264     dws = &dwsbt1->dws;
0265 
0266     dws->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
0267     if (IS_ERR(dws->regs))
0268         return PTR_ERR(dws->regs);
0269 
0270     dws->paddr = mem->start;
0271 
0272     dwsbt1->clk = devm_clk_get(&pdev->dev, NULL);
0273     if (IS_ERR(dwsbt1->clk))
0274         return PTR_ERR(dwsbt1->clk);
0275 
0276     ret = clk_prepare_enable(dwsbt1->clk);
0277     if (ret)
0278         return ret;
0279 
0280     dws->bus_num = pdev->id;
0281     dws->reg_io_width = 4;
0282     dws->max_freq = clk_get_rate(dwsbt1->clk);
0283     if (!dws->max_freq) {
0284         ret = -EINVAL;
0285         goto err_disable_clk;
0286     }
0287 
0288     init_func = device_get_match_data(&pdev->dev);
0289     ret = init_func(pdev, dwsbt1);
0290     if (ret)
0291         goto err_disable_clk;
0292 
0293     pm_runtime_enable(&pdev->dev);
0294 
0295     ret = dw_spi_add_host(&pdev->dev, dws);
0296     if (ret)
0297         goto err_disable_clk;
0298 
0299     platform_set_drvdata(pdev, dwsbt1);
0300 
0301     return 0;
0302 
0303 err_disable_clk:
0304     clk_disable_unprepare(dwsbt1->clk);
0305 
0306     return ret;
0307 }
0308 
0309 static int dw_spi_bt1_remove(struct platform_device *pdev)
0310 {
0311     struct dw_spi_bt1 *dwsbt1 = platform_get_drvdata(pdev);
0312 
0313     dw_spi_remove_host(&dwsbt1->dws);
0314 
0315     pm_runtime_disable(&pdev->dev);
0316 
0317     clk_disable_unprepare(dwsbt1->clk);
0318 
0319     return 0;
0320 }
0321 
0322 static const struct of_device_id dw_spi_bt1_of_match[] = {
0323     { .compatible = "baikal,bt1-ssi", .data = dw_spi_bt1_std_init},
0324     { .compatible = "baikal,bt1-sys-ssi", .data = dw_spi_bt1_sys_init},
0325     { }
0326 };
0327 MODULE_DEVICE_TABLE(of, dw_spi_bt1_of_match);
0328 
0329 static struct platform_driver dw_spi_bt1_driver = {
0330     .probe  = dw_spi_bt1_probe,
0331     .remove = dw_spi_bt1_remove,
0332     .driver = {
0333         .name       = "bt1-sys-ssi",
0334         .of_match_table = dw_spi_bt1_of_match,
0335     },
0336 };
0337 module_platform_driver(dw_spi_bt1_driver);
0338 
0339 MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>");
0340 MODULE_DESCRIPTION("Baikal-T1 System Boot SPI Controller driver");
0341 MODULE_LICENSE("GPL v2");
0342 MODULE_IMPORT_NS(SPI_DW_CORE);