env: Move env_set() to env.h
[oweals/u-boot.git] / board / kosagi / novena / novena.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Novena board support
4  *
5  * Copyright (C) 2014 Marek Vasut <marex@denx.de>
6  */
7
8 #include <common.h>
9 #include <dm.h>
10 #include <dm/device-internal.h>
11 #include <ahci.h>
12 #include <env.h>
13 #include <linux/errno.h>
14 #include <asm/gpio.h>
15 #include <asm/io.h>
16 #include <asm/arch/clock.h>
17 #include <asm/arch/crm_regs.h>
18 #include <asm/arch/imx-regs.h>
19 #include <asm/arch/iomux.h>
20 #include <asm/arch/mxc_hdmi.h>
21 #include <asm/arch/sys_proto.h>
22 #include <asm/mach-imx/boot_mode.h>
23 #include <asm/mach-imx/iomux-v3.h>
24 #include <asm/mach-imx/mxc_i2c.h>
25 #include <asm/mach-imx/sata.h>
26 #include <asm/mach-imx/video.h>
27 #include <dwc_ahsata.h>
28 #include <environment.h>
29 #include <fsl_esdhc_imx.h>
30 #include <i2c.h>
31 #include <input.h>
32 #include <ipu_pixfmt.h>
33 #include <linux/fb.h>
34 #include <linux/input.h>
35 #include <malloc.h>
36 #include <micrel.h>
37 #include <miiphy.h>
38 #include <mmc.h>
39 #include <netdev.h>
40 #include <power/pmic.h>
41 #include <power/pfuze100_pmic.h>
42 #include <stdio_dev.h>
43 #include <video_console.h>
44
45 #include "novena.h"
46
47 DECLARE_GLOBAL_DATA_PTR;
48
49 /*
50  * GPIO button
51  */
52 #ifdef CONFIG_KEYBOARD
53 static struct input_config button_input;
54
55 static int novena_gpio_button_read_keys(struct input_config *input)
56 {
57         int key = KEY_ENTER;
58         if (gpio_get_value(NOVENA_BUTTON_GPIO))
59                 return 0;
60         input_send_keycodes(&button_input, &key, 1);
61         return 1;
62 }
63
64 static int novena_gpio_button_getc(struct stdio_dev *dev)
65 {
66         return input_getc(&button_input);
67 }
68
69 static int novena_gpio_button_tstc(struct stdio_dev *dev)
70 {
71         return input_tstc(&button_input);
72 }
73
74 static int novena_gpio_button_init(struct stdio_dev *dev)
75 {
76         gpio_direction_input(NOVENA_BUTTON_GPIO);
77         input_set_delays(&button_input, 250, 250);
78         return 0;
79 }
80
81 int drv_keyboard_init(void)
82 {
83         int error;
84         struct stdio_dev dev = {
85                 .name   = "button",
86                 .flags  = DEV_FLAGS_INPUT,
87                 .start  = novena_gpio_button_init,
88                 .getc   = novena_gpio_button_getc,
89                 .tstc   = novena_gpio_button_tstc,
90         };
91
92         gpio_request(NOVENA_BUTTON_GPIO, "button");
93
94         error = input_init(&button_input, 0);
95         if (error) {
96                 debug("%s: Cannot set up input\n", __func__);
97                 return -1;
98         }
99         input_add_tables(&button_input, false);
100         button_input.read_keys = novena_gpio_button_read_keys;
101
102         error = input_stdio_register(&dev);
103         if (error)
104                 return error;
105
106         return 0;
107 }
108 #endif
109
110 int board_early_init_f(void)
111 {
112 #if defined(CONFIG_VIDEO_IPUV3)
113         setup_display_clock();
114 #endif
115
116         return 0;
117 }
118
119 int board_init(void)
120 {
121         /* address of boot parameters */
122         gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
123
124         return 0;
125 }
126
127 int board_late_init(void)
128 {
129 #if defined(CONFIG_VIDEO_IPUV3)
130         struct udevice *con;
131         char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
132         int ret;
133
134         setup_display_lvds();
135
136         ret = uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con);
137         if (ret)
138                 return ret;
139
140         display_options_get_banner(false, buf, sizeof(buf));
141         vidconsole_position_cursor(con, 0, 0);
142         vidconsole_put_string(con, buf);
143 #endif
144         return 0;
145 }
146
147 int checkboard(void)
148 {
149         puts("Board: Novena 4x\n");
150         return 0;
151 }
152
153 int dram_init(void)
154 {
155         gd->ram_size = imx_ddr_size();
156         return 0;
157 }
158
159 /* setup board specific PMIC */
160 int power_init_board(void)
161 {
162         struct pmic *p;
163         u32 reg;
164         int ret;
165
166         power_pfuze100_init(1);
167         p = pmic_get("PFUZE100");
168         if (!p)
169                 return -EINVAL;
170
171         ret = pmic_probe(p);
172         if (ret)
173                 return ret;
174
175         pmic_reg_read(p, PFUZE100_DEVICEID, &reg);
176         printf("PMIC:  PFUZE100 ID=0x%02x\n", reg);
177
178         /* Set SWBST to 5.0V and enable (for USB) */
179         pmic_reg_read(p, PFUZE100_SWBSTCON1, &reg);
180         reg &= ~(SWBST_MODE_MASK | SWBST_VOL_MASK);
181         reg |= (SWBST_5_00V | (SWBST_MODE_AUTO << SWBST_MODE_SHIFT));
182         pmic_reg_write(p, PFUZE100_SWBSTCON1, reg);
183
184         return 0;
185 }
186
187 /* EEPROM configuration data */
188 struct novena_eeprom_data {
189         uint8_t         signature[6];
190         uint8_t         version;
191         uint8_t         reserved;
192         uint32_t        serial;
193         uint8_t         mac[6];
194         uint16_t        features;
195 };
196
197 int misc_init_r(void)
198 {
199         struct novena_eeprom_data data;
200         uchar *datap = (uchar *)&data;
201         const char *signature = "Novena";
202         int ret;
203
204         /* If 'ethaddr' is already set, do nothing. */
205         if (env_get("ethaddr"))
206                 return 0;
207
208         /* EEPROM is at bus 2. */
209         ret = i2c_set_bus_num(2);
210         if (ret) {
211                 puts("Cannot select EEPROM I2C bus.\n");
212                 return 0;
213         }
214
215         /* EEPROM is at address 0x56. */
216         ret = eeprom_read(0x56, 0, datap, sizeof(data));
217         if (ret) {
218                 puts("Cannot read I2C EEPROM.\n");
219                 return 0;
220         }
221
222         /* Check EEPROM signature. */
223         if (memcmp(data.signature, signature, 6)) {
224                 puts("Invalid I2C EEPROM signature.\n");
225                 return 0;
226         }
227
228         /* Set ethernet address from EEPROM. */
229         eth_env_set_enetaddr("ethaddr", data.mac);
230
231         return ret;
232 }