Lines Matching +full:baikal +full:- +full:t1

1 // SPDX-License-Identifier: GPL-2.0-only
3 // Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
9 // Baikal-T1 DW APB SPI and System Boot SPI driver
24 #include <linux/spi/spi-mem.h>
27 #include "spi-dw.h"
52 struct dw_spi_bt1 *dwsbt1 = to_dw_spi_bt1(desc->mem->spi->controller); in dw_spi_bt1_dirmap_create()
54 if (!dwsbt1->map || in dw_spi_bt1_dirmap_create()
55 !dwsbt1->dws.mem_ops.supports_op(desc->mem, &desc->info.op_tmpl)) in dw_spi_bt1_dirmap_create()
56 return -EOPNOTSUPP; in dw_spi_bt1_dirmap_create()
58 if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN) in dw_spi_bt1_dirmap_create()
59 return -EOPNOTSUPP; in dw_spi_bt1_dirmap_create()
65 if (desc->info.offset + desc->info.length > dwsbt1->map_len) in dw_spi_bt1_dirmap_create()
66 return -EINVAL; in dw_spi_bt1_dirmap_create()
73 * That's why we have to create a dedicated read-method to copy data from there
87 chunk = min_t(size_t, 4 - shift, len); in dw_spi_bt1_dirmap_copy_from_map()
88 data = readl_relaxed(from - shift); in dw_spi_bt1_dirmap_copy_from_map()
92 len -= chunk; in dw_spi_bt1_dirmap_copy_from_map()
100 len -= 4; in dw_spi_bt1_dirmap_copy_from_map()
112 struct dw_spi_bt1 *dwsbt1 = to_dw_spi_bt1(desc->mem->spi->controller); in dw_spi_bt1_dirmap_read()
113 struct dw_spi *dws = &dwsbt1->dws; in dw_spi_bt1_dirmap_read()
114 struct spi_mem *mem = desc->mem; in dw_spi_bt1_dirmap_read()
122 if (offs >= dwsbt1->map_len || !len) in dw_spi_bt1_dirmap_read()
125 len = min_t(size_t, len, dwsbt1->map_len - offs); in dw_spi_bt1_dirmap_read()
131 cfg.freq = mem->spi->max_speed_hz; in dw_spi_bt1_dirmap_read()
133 /* Make sure the corresponding CS is de-asserted on transmission */ in dw_spi_bt1_dirmap_read()
134 dw_spi_set_cs(mem->spi, false); in dw_spi_bt1_dirmap_read()
138 dw_spi_update_config(dws, mem->spi, &cfg); in dw_spi_bt1_dirmap_read()
150 ret = mux_control_select(dwsbt1->mux, BT1_BOOT_DIRMAP); in dw_spi_bt1_dirmap_read()
154 dw_spi_bt1_dirmap_copy_from_map(buf, dwsbt1->map + offs, len); in dw_spi_bt1_dirmap_read()
156 mux_control_deselect(dwsbt1->mux); in dw_spi_bt1_dirmap_read()
158 dw_spi_set_cs(mem->spi, true); in dw_spi_bt1_dirmap_read()
170 struct dw_spi *dws = &dwsbt1->dws; in dw_spi_bt1_std_init()
172 dws->irq = platform_get_irq(pdev, 0); in dw_spi_bt1_std_init()
173 if (dws->irq < 0) in dw_spi_bt1_std_init()
174 return dws->irq; in dw_spi_bt1_std_init()
176 dws->num_cs = 4; in dw_spi_bt1_std_init()
179 * Baikal-T1 Normal SPI Controllers don't always keep up with full SPI in dw_spi_bt1_std_init()
185 dws->max_mem_freq = 20000000U; in dw_spi_bt1_std_init()
196 struct dw_spi *dws = &dwsbt1->dws; in dw_spi_bt1_sys_init()
199 * Baikal-T1 System Boot Controller is equipped with a mux, which in dw_spi_bt1_sys_init()
203 * (on idle-state). in dw_spi_bt1_sys_init()
205 dwsbt1->mux = devm_mux_control_get(&pdev->dev, NULL); in dw_spi_bt1_sys_init()
206 if (IS_ERR(dwsbt1->mux)) in dw_spi_bt1_sys_init()
207 return PTR_ERR(dwsbt1->mux); in dw_spi_bt1_sys_init()
214 * use it concurrently with time-critical tasks (like the SPI memory in dw_spi_bt1_sys_init()
220 dwsbt1->map = devm_ioremap_resource(&pdev->dev, mem); in dw_spi_bt1_sys_init()
221 if (!IS_ERR(dwsbt1->map)) { in dw_spi_bt1_sys_init()
222 dwsbt1->map_len = resource_size(mem); in dw_spi_bt1_sys_init()
223 dws->mem_ops.dirmap_create = dw_spi_bt1_dirmap_create; in dw_spi_bt1_sys_init()
224 dws->mem_ops.dirmap_read = dw_spi_bt1_dirmap_read; in dw_spi_bt1_sys_init()
226 dwsbt1->map = NULL; in dw_spi_bt1_sys_init()
235 dws->irq = IRQ_NOTCONNECTED; in dw_spi_bt1_sys_init()
236 dws->num_cs = 1; in dw_spi_bt1_sys_init()
239 * Baikal-T1 System Boot SPI Controller doesn't keep up with the full in dw_spi_bt1_sys_init()
247 dws->max_mem_freq = 10000000U; in dw_spi_bt1_sys_init()
249 dws->max_mem_freq = 20000000U; in dw_spi_bt1_sys_init()
262 dwsbt1 = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_bt1), GFP_KERNEL); in dw_spi_bt1_probe()
264 return -ENOMEM; in dw_spi_bt1_probe()
266 dws = &dwsbt1->dws; in dw_spi_bt1_probe()
268 dws->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); in dw_spi_bt1_probe()
269 if (IS_ERR(dws->regs)) in dw_spi_bt1_probe()
270 return PTR_ERR(dws->regs); in dw_spi_bt1_probe()
272 dws->paddr = mem->start; in dw_spi_bt1_probe()
274 dwsbt1->clk = devm_clk_get_enabled(&pdev->dev, NULL); in dw_spi_bt1_probe()
275 if (IS_ERR(dwsbt1->clk)) in dw_spi_bt1_probe()
276 return PTR_ERR(dwsbt1->clk); in dw_spi_bt1_probe()
278 dws->bus_num = pdev->id; in dw_spi_bt1_probe()
279 dws->reg_io_width = 4; in dw_spi_bt1_probe()
280 dws->max_freq = clk_get_rate(dwsbt1->clk); in dw_spi_bt1_probe()
281 if (!dws->max_freq) in dw_spi_bt1_probe()
282 return -EINVAL; in dw_spi_bt1_probe()
284 init_func = device_get_match_data(&pdev->dev); in dw_spi_bt1_probe()
289 pm_runtime_enable(&pdev->dev); in dw_spi_bt1_probe()
291 ret = dw_spi_add_host(&pdev->dev, dws); in dw_spi_bt1_probe()
293 pm_runtime_disable(&pdev->dev); in dw_spi_bt1_probe()
306 dw_spi_remove_host(&dwsbt1->dws); in dw_spi_bt1_remove()
308 pm_runtime_disable(&pdev->dev); in dw_spi_bt1_remove()
312 { .compatible = "baikal,bt1-ssi", .data = dw_spi_bt1_std_init},
313 { .compatible = "baikal,bt1-sys-ssi", .data = dw_spi_bt1_sys_init},
322 .name = "bt1-sys-ssi",
329 MODULE_DESCRIPTION("Baikal-T1 System Boot SPI Controller driver");