blob: 223f73f736efc6650722d07dd46d676b295db701 [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;
27};
28
29/* Polling helpers */
30#define read16_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
31 readw_poll_timeout((addr), (val), (cond), (sleep_us), (timeout_us))
32
33#define read32_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
34 readl_poll_timeout((addr), (val), (cond), (sleep_us), (timeout_us))
35
36/* Timer helpers */
37#define mtk_snand_time_t ktime_t
38
39static inline mtk_snand_time_t timer_get_ticks(void)
40{
41 return ktime_get();
42}
43
44static inline mtk_snand_time_t timer_time_to_tick(uint32_t timeout_us)
45{
46 return ktime_add_us(ktime_set(0, 0), timeout_us);
47}
48
49static inline bool timer_is_timeout(mtk_snand_time_t start_tick,
50 mtk_snand_time_t timeout_tick)
51{
52 ktime_t tmo = ktime_add(start_tick, timeout_tick);
53
54 return ktime_compare(ktime_get(), tmo) > 0;
55}
56
57/* Memory helpers */
58static inline void *generic_mem_alloc(struct mtk_snand_plat_dev *pdev,
59 size_t size)
60{
61 return devm_kzalloc(pdev->dev, size, GFP_KERNEL);
62}
63static inline void generic_mem_free(struct mtk_snand_plat_dev *pdev, void *ptr)
64{
65 devm_kfree(pdev->dev, ptr);
66}
67
68static inline void *dma_mem_alloc(struct mtk_snand_plat_dev *pdev, size_t size)
69{
70 return kzalloc(size, GFP_KERNEL);
71}
72static inline void dma_mem_free(struct mtk_snand_plat_dev *pdev, void *ptr)
73{
74 kfree(ptr);
75}
76
77static inline int dma_mem_map(struct mtk_snand_plat_dev *pdev, void *vaddr,
78 uintptr_t *dma_addr, size_t size, bool to_device)
79{
80 dma_addr_t addr;
81 int ret;
82
83 addr = dma_map_single(pdev->dev, vaddr, size,
84 to_device ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
85 ret = dma_mapping_error(pdev->dev, addr);
86 if (ret)
87 return ret;
88
89 *dma_addr = (uintptr_t)addr;
90
91 return 0;
92}
93
94static inline void dma_mem_unmap(struct mtk_snand_plat_dev *pdev,
95 uintptr_t dma_addr, size_t size,
96 bool to_device)
97{
98 dma_unmap_single(pdev->dev, dma_addr, size,
99 to_device ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
100}
101
102/* Interrupt helpers */
103static inline void irq_completion_done(struct mtk_snand_plat_dev *pdev)
104{
105 complete(&pdev->done);
106}
107
108static inline void irq_completion_init(struct mtk_snand_plat_dev *pdev)
109{
110 init_completion(&pdev->done);
111}
112
113static inline int irq_completion_wait(struct mtk_snand_plat_dev *pdev,
114 void __iomem *reg, uint32_t bit,
115 uint32_t timeout_us)
116{
117#if 0
118 uint32_t val;
119
120 return read32_poll_timeout(reg, val, val & bit, 0, timeout_us);
121#else
122 int ret;
123
124 ret = wait_for_completion_timeout(&pdev->done,
125 usecs_to_jiffies(timeout_us));
126 if (!ret)
127 return -ETIMEDOUT;
128
129 return 0;
130#endif
131}
132
133#endif /* _MTK_SNAND_OS_H_ */