summaryrefslogtreecommitdiff
path: root/minix/lib/libclkconf/clkconf.c
blob: cf634dce3e640ee8fb4a62bb93c44f9f9b6d066e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* kernel headers */
#include <minix/syslib.h>
#include <minix/drvlib.h>
#include <minix/log.h>
#include <minix/mmio.h>
#include <minix/clkconf.h>
#include <minix/type.h>
#include <minix/board.h>

/* system headers */
#include <sys/mman.h>
#include <sys/types.h>

/* usr headers */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <assert.h>

/* used for logging */
static struct log clk_log = {
	.name = "omap_clkconf",
	.log_level = LEVEL_INFO,
	.log_func = default_log
};

#define DM37XX_CM_BASE 0x48004000
#define AM335X_CM_BASE 0x44E00000

static u32_t base = 0;
static u32_t use_count = 0;

int
clkconf_init()
{
	use_count++;
	struct machine machine;
	sys_getmachine(&machine);
	u32_t cm_base = 0;


	if (base != 0) {
		/* when used in a library we can't guaranty we only call this
		 * method once */
		log_trace(&clk_log, "Called %d times\n", use_count);
		return OK;
	}

	if (BOARD_IS_BBXM(machine.board_id)){
		cm_base = DM37XX_CM_BASE;
	} else if (BOARD_IS_BB(machine.board_id)){
		cm_base = AM335X_CM_BASE;
	}
	struct minix_mem_range mr;
	mr.mr_base = cm_base;
	mr.mr_limit = cm_base + 0x1000;

	if (sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mr) != 0) {
		log_warn(&clk_log,
		    "Unable to request permission to map memory\n");
		return EPERM;
	}

	base = (uint32_t) vm_map_phys(SELF, (void *) cm_base, 0x1000);

	if (base == (uint32_t) MAP_FAILED) {
		log_warn(&clk_log, "Unable to map GPIO memory\n");
		return EPERM;
	}
	return OK;
}

int
clkconf_set(u32_t clk, u32_t mask, u32_t value)
{
	set32(base + clk, mask, value);
	return OK;
}

int
clkconf_release()
{
	assert(use_count > 0);
	use_count--;
	if (use_count == 0) {
		vm_unmap_phys(SELF, (void *) base, 0x1000);
	}
	return OK;
}