1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 #include "hal_otp.h"
20 #include "drv_osal_lib.h"
21 #include "drv_ioctl_otp.h"
22
23 static hi_u8 *g_otp_base_vir_addr = HI_NULL;
24 static hi_bool g_otp_init = HI_FALSE;
25
26 #define otp_read(addr) readl(addr)
27 #define otp_write(addr, data) writel(data, addr)
28 #define hal_otp_read(offset) otp_read((volatile hi_u8 *)(g_otp_base_vir_addr + (offset)))
29 #define hal_otp_write(offset, data) otp_write((volatile hi_u8 *)(g_otp_base_vir_addr + (offset)), data)
30
31 #define hal_check_init_fail_return() \
32 do { \
33 if (g_otp_init != HI_TRUE || g_otp_base_vir_addr == HI_NULL) { \
34 hi_otp_err("device isn't init\n"); \
35 return HI_ERR_OTP_NOT_INIT; \
36 } \
37 } while (0) \
38
hal_otp_init(hi_void)39 hi_s32 hal_otp_init(hi_void)
40 {
41 hi_u32 crg_value;
42 hi_u32 *sys_addr = HI_NULL;
43
44 if (g_otp_init == HI_TRUE) {
45 return HI_SUCCESS;
46 }
47
48 /* otp clock configure */
49 sys_addr = otp_ioremap_nocache(REG_SYS_OTP_CLK_ADDR_PHY, 0x100);
50 hi_otp_func_fail_return(otp_ioremap_nocache, sys_addr == HI_NULL, HI_ERR_OTP_FAILED_MEM);
51
52 crg_value = otp_read(sys_addr);
53 crg_value |= OTP_CRG_CLOCK_BIT; /* set the bit 0, clock opened */
54 otp_write(sys_addr, crg_value);
55
56 otp_iounmap(sys_addr, 0x100);
57
58 /* otp reg addr map */
59 g_otp_base_vir_addr = otp_ioremap_nocache(OTP_REG_BASE_ADDR_PHY, 0x1000);
60 hi_otp_func_fail_return(otp_ioremap_nocache, g_otp_base_vir_addr == HI_NULL, HI_ERR_OTP_FAILED_MEM);
61
62 g_otp_init = HI_TRUE;
63
64 return HI_SUCCESS;
65 }
66
hal_otp_deinit(hi_void)67 hi_void hal_otp_deinit(hi_void)
68 {
69 if (g_otp_init == HI_FALSE) {
70 return;
71 }
72
73 if (g_otp_base_vir_addr != HI_NULL) {
74 otp_iounmap(g_otp_base_vir_addr, 0x1000);
75 g_otp_base_vir_addr = HI_NULL;
76 }
77 g_otp_init = HI_FALSE;
78 }
79
hal_otp_read_word(hi_u32 offset,hi_u32 * value)80 hi_s32 hal_otp_read_word(hi_u32 offset, hi_u32 *value)
81 {
82 hi_otp_check_formula_fail(value == HI_NULL, HI_ERR_OTP_NULL_PTR);
83 hal_check_init_fail_return();
84
85 *value = hal_otp_read(offset);
86 hi_otp_info(" read offset %04X value %x\n", offset, *value);
87 return HI_SUCCESS;
88 }
89
hal_otp_write_word(hi_u32 offset,hi_u32 value)90 hi_s32 hal_otp_write_word(hi_u32 offset, hi_u32 value)
91 {
92 hal_check_init_fail_return();
93
94 hal_otp_write(offset, value);
95 hi_otp_info("write offset %04X value %x\n", offset, value);
96 return HI_SUCCESS;
97 }
98
99
100