xref: /minix/minix/lib/libclkconf/clkconf.c (revision 0a6a1f1d)
1 /* kernel headers */
2 #include <minix/syslib.h>
3 #include <minix/drvlib.h>
4 #include <minix/log.h>
5 #include <minix/mmio.h>
6 #include <minix/clkconf.h>
7 #include <minix/type.h>
8 #include <minix/board.h>
9 
10 /* system headers */
11 #include <sys/mman.h>
12 #include <sys/types.h>
13 
14 /* usr headers */
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <stdarg.h>
18 #include <string.h>
19 #include <errno.h>
20 #include <assert.h>
21 
22 /* used for logging */
23 static struct log clk_log = {
24 	.name = "omap_clkconf",
25 	.log_level = LEVEL_INFO,
26 	.log_func = default_log
27 };
28 
29 #define DM37XX_CM_BASE 0x48004000
30 #define AM335X_CM_BASE 0x44E00000
31 
32 static u32_t base = 0;
33 static u32_t use_count = 0;
34 
35 int
36 clkconf_init()
37 {
38 	use_count++;
39 	struct machine machine;
40 	sys_getmachine(&machine);
41 	u32_t cm_base = 0;
42 
43 
44 	if (base != 0) {
45 		/* when used in a library we can't guaranty we only call this
46 		 * method once */
47 		log_trace(&clk_log, "Called %d times\n", use_count);
48 		return OK;
49 	}
50 
51 	if (BOARD_IS_BBXM(machine.board_id)){
52 		cm_base = DM37XX_CM_BASE;
53 	} else if (BOARD_IS_BB(machine.board_id)){
54 		cm_base = AM335X_CM_BASE;
55 	}
56 	struct minix_mem_range mr;
57 	mr.mr_base = cm_base;
58 	mr.mr_limit = cm_base + 0x1000;
59 
60 	if (sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mr) != 0) {
61 		log_warn(&clk_log,
62 		    "Unable to request permission to map memory\n");
63 		return EPERM;
64 	}
65 
66 	base = (uint32_t) vm_map_phys(SELF, (void *) cm_base, 0x1000);
67 
68 	if (base == (uint32_t) MAP_FAILED) {
69 		log_warn(&clk_log, "Unable to map GPIO memory\n");
70 		return EPERM;
71 	}
72 	return OK;
73 }
74 
75 int
76 clkconf_set(u32_t clk, u32_t mask, u32_t value)
77 {
78 	set32(base + clk, mask, value);
79 	return OK;
80 }
81 
82 int
83 clkconf_release()
84 {
85 	assert(use_count > 0);
86 	use_count--;
87 	if (use_count == 0) {
88 		vm_unmap_phys(SELF, (void *) base, 0x1000);
89 	}
90 	return OK;
91 }
92