blob: d97bd1027850a3005e5e88514d464124857361e8 [file] [log] [blame]
Norman James6a58a272015-10-07 14:34:16 -05001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <fcntl.h>
5#include <sys/mman.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <unistd.h>
9#include <byteswap.h>
10#include <stdint.h>
11#include <stdbool.h>
12#include <getopt.h>
13#include <limits.h>
14#include <arpa/inet.h>
15#include <assert.h>
16
17#include "io.h"
18
19void *ahb_reg_map;
20void *ahb_flash_map;
21uint32_t ahb_flash_base, ahb_flash_size;
22void *gpio_ctrl;
23
24int ast_copy_to_ahb(uint32_t reg, const void *src, uint32_t len)
25{
26 if (reg < ahb_flash_base ||
27 (reg + len) > (ahb_flash_base + ahb_flash_size))
28 return -1;
29 reg -= ahb_flash_base;
30
31 if (((reg | (unsigned long)src | len) & 3) == 0) {
32 while(len > 3) {
33 uint32_t val = *(uint32_t *)src;
34 writel(val, ahb_flash_map + reg);
35 src += 4;
36 reg += 4;
37 len -= 4;
38 }
39 }
40
41 while(len--) {
42 uint8_t val = *(uint8_t *)src;
43 writeb(val, ahb_flash_map + reg++);
44 src += 1;
45 }
46 return 0;
47}
48
49
50int ast_copy_from_ahb(void *dst, uint32_t reg, uint32_t len)
51{
52 if (reg < ahb_flash_base ||
53 (reg + len) > (ahb_flash_base + ahb_flash_size))
54 return -1;
55 reg -= ahb_flash_base;
56
57 if (((reg | (unsigned long)dst | len) & 3) == 0) {
58 while(len > 3) {
59 *(uint32_t *)dst = readl(ahb_flash_map + reg);
60 dst += 4;
61 reg += 4;
62 len -= 4;
63 }
64 }
65
66 while(len--) {
67 *(uint8_t *)dst = readb(ahb_flash_map + reg++);
68 dst += 1;
69 }
70 return 0;
71}
72
73/*
74 * GPIO stuff to be replaced by higher level accessors for
75 * controlling the flash write lock via sysfs
76 */
77
78static inline uint32_t gpio_ctl_readl(uint32_t offset)
79{
80 return readl(gpio_ctrl + offset);
81}
82
83static inline void gpio_ctl_writel(uint32_t val, uint32_t offset)
84{
85 writel(val, gpio_ctrl + offset);
86}
87
88
89bool set_wrprotect(bool protect)
90{
91 uint32_t reg;
92 bool was_protected;
93
94 reg = gpio_ctl_readl(0x20);
95 was_protected = !!(reg & 0x00004000);
96 if (protect)
97 reg |= 0x00004000; /* GPIOF[6] value */
98 else
99 reg &= ~0x00004000; /* GPIOF[6] value */
100 gpio_ctl_writel(reg, 0x20);
101 reg = gpio_ctl_readl(0x24);
102 reg |= 0x00004000; /* GPIOF[6] direction */
103 gpio_ctl_writel(reg, 0x24);
104
105 return was_protected;
106}
107
108void open_devs(bool use_lpc, bool bmc_flash)
109{
110 int fd;
111
112 (void)use_lpc;
113
114 fd = open("/dev/mem", O_RDWR | O_SYNC);
115 if (fd < 0) {
116 perror("can't open /dev/mem");
117 exit(1);
118 }
119 ahb_reg_map = mmap(0, AHB_REGS_SIZE, PROT_READ | PROT_WRITE,
120 MAP_SHARED, fd, AHB_REGS_BASE);
121 if (ahb_reg_map == MAP_FAILED) {
122 perror("can't map AHB registers /dev/mem");
123 exit(1);
124 }
125 gpio_ctrl = mmap(0, GPIO_CTRL_SIZE, PROT_READ | PROT_WRITE,
126 MAP_SHARED, fd, GPIO_CTRL_BASE);
127 if (gpio_ctrl == MAP_FAILED) {
128 perror("can't map GPIO control via /dev/mem");
129 exit(1);
130 }
131 ahb_flash_base = bmc_flash ? BMC_FLASH_BASE : PNOR_FLASH_BASE;
132 ahb_flash_size = bmc_flash ? BMC_FLASH_SIZE : PNOR_FLASH_SIZE;
133 ahb_flash_map = mmap(0, ahb_flash_size, PROT_READ | PROT_WRITE,
134 MAP_SHARED, fd, ahb_flash_base);
135 if (ahb_flash_map == MAP_FAILED) {
136 perror("can't map flash via /dev/mem");
137 exit(1);
138 }
139}