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