blob: b392f34825db0b22e64774434f4f52e118efd7de [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
4 *
5 * Author: Weijie Gao <weijie.gao@mediatek.com>
6 */
7
8#ifndef _MTK_SNAND_OS_H_
9#define _MTK_SNAND_OS_H_
10
11#include <linux/slab.h>
12#include <linux/kernel.h>
13#include <linux/limits.h>
14#include <linux/types.h>
15#include <linux/bitops.h>
16#include <linux/sizes.h>
17#include <linux/iopoll.h>
18#include <linux/hrtimer.h>
19#include <linux/device.h>
20#include <linux/dma-mapping.h>
21#include <linux/io.h>
22#include <asm/div64.h>
23
24struct mtk_snand_plat_dev {
25 struct device *dev;
26 struct completion done;
developer8c414ee2023-06-20 19:08:04 +080027 bool poll_mode;
developerfd40db22021-04-29 10:08:25 +080028};
29
30/* Polling helpers */
31#define read16_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
32 readw_poll_timeout((addr), (val), (cond), (sleep_us), (timeout_us))
33
34#define read32_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
35 readl_poll_timeout((addr), (val), (cond), (sleep_us), (timeout_us))
36
37/* Timer helpers */
38#define mtk_snand_time_t ktime_t
39
40static inline mtk_snand_time_t timer_get_ticks(void)
41{
42 return ktime_get();
43}
44
45static inline mtk_snand_time_t timer_time_to_tick(uint32_t timeout_us)
46{
47 return ktime_add_us(ktime_set(0, 0), timeout_us);
48}
49
50static inline bool timer_is_timeout(mtk_snand_time_t start_tick,
51 mtk_snand_time_t timeout_tick)
52{
53 ktime_t tmo = ktime_add(start_tick, timeout_tick);
54
55 return ktime_compare(ktime_get(), tmo) > 0;
56}
57
58/* Memory helpers */
59static inline void *generic_mem_alloc(struct mtk_snand_plat_dev *pdev,
60 size_t size)
61{
62 return devm_kzalloc(pdev->dev, size, GFP_KERNEL);
63}
64static inline void generic_mem_free(struct mtk_snand_plat_dev *pdev, void *ptr)
65{
66 devm_kfree(pdev->dev, ptr);
67}
68
69static inline void *dma_mem_alloc(struct mtk_snand_plat_dev *pdev, size_t size)
70{
71 return kzalloc(size, GFP_KERNEL);
72}
73static inline void dma_mem_free(struct mtk_snand_plat_dev *pdev, void *ptr)
74{
75 kfree(ptr);
76}
77
78static inline int dma_mem_map(struct mtk_snand_plat_dev *pdev, void *vaddr,
79 uintptr_t *dma_addr, size_t size, bool to_device)
80{
81 dma_addr_t addr;
82 int ret;
83
84 addr = dma_map_single(pdev->dev, vaddr, size,
85 to_device ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
86 ret = dma_mapping_error(pdev->dev, addr);
87 if (ret)
88 return ret;
89
90 *dma_addr = (uintptr_t)addr;
91
92 return 0;
93}
94
95static inline void dma_mem_unmap(struct mtk_snand_plat_dev *pdev,
96 uintptr_t dma_addr, size_t size,
97 bool to_device)
98{
99 dma_unmap_single(pdev->dev, dma_addr, size,
100 to_device ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
101}
102
103/* Interrupt helpers */
104static inline void irq_completion_done(struct mtk_snand_plat_dev *pdev)
105{
developer8c414ee2023-06-20 19:08:04 +0800106 if (!pdev->poll_mode)
107 complete(&pdev->done);
developerfd40db22021-04-29 10:08:25 +0800108}
109
110static inline void irq_completion_init(struct mtk_snand_plat_dev *pdev)
111{
developer8c414ee2023-06-20 19:08:04 +0800112 if (!pdev->poll_mode)
113 init_completion(&pdev->done);
developerfd40db22021-04-29 10:08:25 +0800114}
115
116static inline int irq_completion_wait(struct mtk_snand_plat_dev *pdev,
117 void __iomem *reg, uint32_t bit,
118 uint32_t timeout_us)
119{
developerfd40db22021-04-29 10:08:25 +0800120 uint32_t val;
developerfd40db22021-04-29 10:08:25 +0800121 int ret;
122
developer8c414ee2023-06-20 19:08:04 +0800123 if (pdev->poll_mode)
124 return read32_poll_timeout(reg, val, val & bit, 0, timeout_us);
125
developerfd40db22021-04-29 10:08:25 +0800126 ret = wait_for_completion_timeout(&pdev->done,
127 usecs_to_jiffies(timeout_us));
128 if (!ret)
129 return -ETIMEDOUT;
130
131 return 0;
developerfd40db22021-04-29 10:08:25 +0800132}
133
developer8c414ee2023-06-20 19:08:04 +0800134void mtk_snand_control_poll_mode(struct mtk_snand_plat_dev *pdev, bool enable);
135
developerfd40db22021-04-29 10:08:25 +0800136#endif /* _MTK_SNAND_OS_H_ */