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()
60 * mapped flash memory bounds and the operation is read-only. in dw_spi_bt1_dirmap_create()
62 if (desc->info.offset + desc->info.length > dwsbt1->map_len || in dw_spi_bt1_dirmap_create()
63 desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN) in dw_spi_bt1_dirmap_create()
64 return -EOPNOTSUPP; in dw_spi_bt1_dirmap_create()
71 * That's why we have to create a dedicated read-method to copy data from there
85 chunk = min_t(size_t, 4 - shift, len); in dw_spi_bt1_dirmap_copy_from_map()
86 data = readl_relaxed(from - shift); in dw_spi_bt1_dirmap_copy_from_map()
90 len -= chunk; in dw_spi_bt1_dirmap_copy_from_map()
98 len -= 4; in dw_spi_bt1_dirmap_copy_from_map()
110 struct dw_spi_bt1 *dwsbt1 = to_dw_spi_bt1(desc->mem->spi->controller); in dw_spi_bt1_dirmap_read()
111 struct dw_spi *dws = &dwsbt1->dws; in dw_spi_bt1_dirmap_read()
112 struct spi_mem *mem = desc->mem; in dw_spi_bt1_dirmap_read()
120 if (offs >= dwsbt1->map_len || !len) in dw_spi_bt1_dirmap_read()
123 len = min_t(size_t, len, dwsbt1->map_len - offs); in dw_spi_bt1_dirmap_read()
129 cfg.freq = mem->spi->max_speed_hz; in dw_spi_bt1_dirmap_read()
131 /* Make sure the corresponding CS is de-asserted on transmission */ in dw_spi_bt1_dirmap_read()
132 dw_spi_set_cs(mem->spi, false); in dw_spi_bt1_dirmap_read()
136 dw_spi_update_config(dws, mem->spi, &cfg); in dw_spi_bt1_dirmap_read()
148 ret = mux_control_select(dwsbt1->mux, BT1_BOOT_DIRMAP); in dw_spi_bt1_dirmap_read()
152 dw_spi_bt1_dirmap_copy_from_map(buf, dwsbt1->map + offs, len); in dw_spi_bt1_dirmap_read()
154 mux_control_deselect(dwsbt1->mux); in dw_spi_bt1_dirmap_read()
156 dw_spi_set_cs(mem->spi, true); in dw_spi_bt1_dirmap_read()
168 struct dw_spi *dws = &dwsbt1->dws; in dw_spi_bt1_std_init()
170 dws->irq = platform_get_irq(pdev, 0); in dw_spi_bt1_std_init()
171 if (dws->irq < 0) in dw_spi_bt1_std_init()
172 return dws->irq; in dw_spi_bt1_std_init()
174 dws->num_cs = 4; in dw_spi_bt1_std_init()
177 * Baikal-T1 Normal SPI Controllers don't always keep up with full SPI in dw_spi_bt1_std_init()
183 dws->max_mem_freq = 20000000U; in dw_spi_bt1_std_init()
194 struct dw_spi *dws = &dwsbt1->dws; in dw_spi_bt1_sys_init()
197 * Baikal-T1 System Boot Controller is equipped with a mux, which in dw_spi_bt1_sys_init()
201 * (on idle-state). in dw_spi_bt1_sys_init()
203 dwsbt1->mux = devm_mux_control_get(&pdev->dev, NULL); in dw_spi_bt1_sys_init()
204 if (IS_ERR(dwsbt1->mux)) in dw_spi_bt1_sys_init()
205 return PTR_ERR(dwsbt1->mux); in dw_spi_bt1_sys_init()
212 * use it concurrently with time-critical tasks (like the SPI memory in dw_spi_bt1_sys_init()
218 dwsbt1->map = devm_ioremap_resource(&pdev->dev, mem); in dw_spi_bt1_sys_init()
219 if (!IS_ERR(dwsbt1->map)) { in dw_spi_bt1_sys_init()
220 dwsbt1->map_len = (mem->end - mem->start + 1); in dw_spi_bt1_sys_init()
221 dws->mem_ops.dirmap_create = dw_spi_bt1_dirmap_create; in dw_spi_bt1_sys_init()
222 dws->mem_ops.dirmap_read = dw_spi_bt1_dirmap_read; in dw_spi_bt1_sys_init()
224 dwsbt1->map = NULL; in dw_spi_bt1_sys_init()
233 dws->irq = IRQ_NOTCONNECTED; in dw_spi_bt1_sys_init()
234 dws->num_cs = 1; in dw_spi_bt1_sys_init()
237 * Baikal-T1 System Boot SPI Controller doesn't keep up with the full in dw_spi_bt1_sys_init()
245 dws->max_mem_freq = 10000000U; in dw_spi_bt1_sys_init()
247 dws->max_mem_freq = 20000000U; in dw_spi_bt1_sys_init()
260 dwsbt1 = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_bt1), GFP_KERNEL); in dw_spi_bt1_probe()
262 return -ENOMEM; in dw_spi_bt1_probe()
264 dws = &dwsbt1->dws; in dw_spi_bt1_probe()
266 dws->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); in dw_spi_bt1_probe()
267 if (IS_ERR(dws->regs)) in dw_spi_bt1_probe()
268 return PTR_ERR(dws->regs); in dw_spi_bt1_probe()
270 dws->paddr = mem->start; in dw_spi_bt1_probe()
272 dwsbt1->clk = devm_clk_get(&pdev->dev, NULL); in dw_spi_bt1_probe()
273 if (IS_ERR(dwsbt1->clk)) in dw_spi_bt1_probe()
274 return PTR_ERR(dwsbt1->clk); in dw_spi_bt1_probe()
276 ret = clk_prepare_enable(dwsbt1->clk); in dw_spi_bt1_probe()
280 dws->bus_num = pdev->id; in dw_spi_bt1_probe()
281 dws->reg_io_width = 4; in dw_spi_bt1_probe()
282 dws->max_freq = clk_get_rate(dwsbt1->clk); in dw_spi_bt1_probe()
283 if (!dws->max_freq) in dw_spi_bt1_probe()
286 init_func = device_get_match_data(&pdev->dev); in dw_spi_bt1_probe()
291 pm_runtime_enable(&pdev->dev); in dw_spi_bt1_probe()
293 ret = dw_spi_add_host(&pdev->dev, dws); in dw_spi_bt1_probe()
302 clk_disable_unprepare(dwsbt1->clk); in dw_spi_bt1_probe()
311 dw_spi_remove_host(&dwsbt1->dws); in dw_spi_bt1_remove()
313 pm_runtime_disable(&pdev->dev); in dw_spi_bt1_remove()
315 clk_disable_unprepare(dwsbt1->clk); in dw_spi_bt1_remove()
321 { .compatible = "baikal,bt1-ssi", .data = dw_spi_bt1_std_init},
322 { .compatible = "baikal,bt1-sys-ssi", .data = dw_spi_bt1_sys_init},
331 .name = "bt1-sys-ssi",
338 MODULE_DESCRIPTION("Baikal-T1 System Boot SPI Controller driver");