xref: /minix3/minix/lib/libclkconf/clkconf.c (revision 7c48de6cc4c6d56f2277d378dba01dbac8a8c3b9)
1433d6423SLionel Sambuc /* kernel headers */
2433d6423SLionel Sambuc #include <minix/syslib.h>
3433d6423SLionel Sambuc #include <minix/drvlib.h>
4433d6423SLionel Sambuc #include <minix/log.h>
5433d6423SLionel Sambuc #include <minix/mmio.h>
6433d6423SLionel Sambuc #include <minix/clkconf.h>
7433d6423SLionel Sambuc #include <minix/type.h>
8433d6423SLionel Sambuc #include <minix/board.h>
9433d6423SLionel Sambuc 
10433d6423SLionel Sambuc /* system headers */
11433d6423SLionel Sambuc #include <sys/mman.h>
12433d6423SLionel Sambuc #include <sys/types.h>
13433d6423SLionel Sambuc 
14433d6423SLionel Sambuc /* usr headers */
15433d6423SLionel Sambuc #include <stdio.h>
16433d6423SLionel Sambuc #include <stdlib.h>
17433d6423SLionel Sambuc #include <stdarg.h>
18433d6423SLionel Sambuc #include <string.h>
19433d6423SLionel Sambuc #include <errno.h>
20433d6423SLionel Sambuc #include <assert.h>
21433d6423SLionel Sambuc 
22433d6423SLionel Sambuc /* used for logging */
23*7c48de6cSDavid van Moolenbroek static struct log clk_log = {
24433d6423SLionel Sambuc 	.name = "omap_clkconf",
25433d6423SLionel Sambuc 	.log_level = LEVEL_INFO,
26433d6423SLionel Sambuc 	.log_func = default_log
27433d6423SLionel Sambuc };
28433d6423SLionel Sambuc 
29433d6423SLionel Sambuc #define DM37XX_CM_BASE 0x48004000
30433d6423SLionel Sambuc #define AM335X_CM_BASE 0x44E00000
31433d6423SLionel Sambuc 
32433d6423SLionel Sambuc static u32_t base = 0;
33433d6423SLionel Sambuc static u32_t use_count = 0;
34433d6423SLionel Sambuc 
35433d6423SLionel Sambuc int
clkconf_init()36433d6423SLionel Sambuc clkconf_init()
37433d6423SLionel Sambuc {
38433d6423SLionel Sambuc 	use_count++;
39433d6423SLionel Sambuc 	struct machine machine;
40433d6423SLionel Sambuc 	sys_getmachine(&machine);
41433d6423SLionel Sambuc 	u32_t cm_base = 0;
42433d6423SLionel Sambuc 
43433d6423SLionel Sambuc 
44433d6423SLionel Sambuc 	if (base != 0) {
45433d6423SLionel Sambuc 		/* when used in a library we can't guaranty we only call this
46433d6423SLionel Sambuc 		 * method once */
47*7c48de6cSDavid van Moolenbroek 		log_trace(&clk_log, "Called %d times\n", use_count);
48433d6423SLionel Sambuc 		return OK;
49433d6423SLionel Sambuc 	}
50433d6423SLionel Sambuc 
51433d6423SLionel Sambuc 	if (BOARD_IS_BBXM(machine.board_id)){
52433d6423SLionel Sambuc 		cm_base = DM37XX_CM_BASE;
53433d6423SLionel Sambuc 	} else if (BOARD_IS_BB(machine.board_id)){
54433d6423SLionel Sambuc 		cm_base = AM335X_CM_BASE;
55433d6423SLionel Sambuc 	}
56433d6423SLionel Sambuc 	struct minix_mem_range mr;
57433d6423SLionel Sambuc 	mr.mr_base = cm_base;
58433d6423SLionel Sambuc 	mr.mr_limit = cm_base + 0x1000;
59433d6423SLionel Sambuc 
60433d6423SLionel Sambuc 	if (sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mr) != 0) {
61*7c48de6cSDavid van Moolenbroek 		log_warn(&clk_log,
62*7c48de6cSDavid van Moolenbroek 		    "Unable to request permission to map memory\n");
63433d6423SLionel Sambuc 		return EPERM;
64433d6423SLionel Sambuc 	}
65433d6423SLionel Sambuc 
66433d6423SLionel Sambuc 	base = (uint32_t) vm_map_phys(SELF, (void *) cm_base, 0x1000);
67433d6423SLionel Sambuc 
68433d6423SLionel Sambuc 	if (base == (uint32_t) MAP_FAILED) {
69*7c48de6cSDavid van Moolenbroek 		log_warn(&clk_log, "Unable to map GPIO memory\n");
70433d6423SLionel Sambuc 		return EPERM;
71433d6423SLionel Sambuc 	}
72433d6423SLionel Sambuc 	return OK;
73433d6423SLionel Sambuc }
74433d6423SLionel Sambuc 
75433d6423SLionel Sambuc int
clkconf_set(u32_t clk,u32_t mask,u32_t value)76433d6423SLionel Sambuc clkconf_set(u32_t clk, u32_t mask, u32_t value)
77433d6423SLionel Sambuc {
78433d6423SLionel Sambuc 	set32(base + clk, mask, value);
79433d6423SLionel Sambuc 	return OK;
80433d6423SLionel Sambuc }
81433d6423SLionel Sambuc 
82433d6423SLionel Sambuc int
clkconf_release()83433d6423SLionel Sambuc clkconf_release()
84433d6423SLionel Sambuc {
85433d6423SLionel Sambuc 	assert(use_count > 0);
86433d6423SLionel Sambuc 	use_count--;
87433d6423SLionel Sambuc 	if (use_count == 0) {
88433d6423SLionel Sambuc 		vm_unmap_phys(SELF, (void *) base, 0x1000);
89433d6423SLionel Sambuc 	}
90433d6423SLionel Sambuc 	return OK;
91433d6423SLionel Sambuc }
92