~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/board/sandisk/sansa_fuze_plus/sfp.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * SanDisk Sansa Fuze Plus board
 
3
 *
 
4
 * Copyright (C) 2013 Marek Vasut <marex@denx.de>
 
5
 *
 
6
 * Hardware investigation done by:
 
7
 *
 
8
 * Amaury Pouly <amaury.pouly@gmail.com>
 
9
 *
 
10
 * SPDX-License-Identifier:     GPL-2.0+
 
11
 */
 
12
 
 
13
#include <common.h>
 
14
#include <errno.h>
 
15
#include <asm/gpio.h>
 
16
#include <asm/io.h>
 
17
#include <asm/arch/iomux-mx23.h>
 
18
#include <asm/arch/imx-regs.h>
 
19
#include <asm/arch/clock.h>
 
20
#include <asm/arch/sys_proto.h>
 
21
 
 
22
DECLARE_GLOBAL_DATA_PTR;
 
23
 
 
24
/*
 
25
 * Functions
 
26
 */
 
27
int board_early_init_f(void)
 
28
{
 
29
        /* IO0 clock at 480MHz */
 
30
        mxs_set_ioclk(MXC_IOCLK0, 480000);
 
31
 
 
32
        /* SSP0 clock at 96MHz */
 
33
        mxs_set_sspclk(MXC_SSPCLK0, 96000, 0);
 
34
 
 
35
        return 0;
 
36
}
 
37
 
 
38
int dram_init(void)
 
39
{
 
40
        return mxs_dram_init();
 
41
}
 
42
 
 
43
#ifdef  CONFIG_CMD_MMC
 
44
static int xfi3_mmc_cd(int id)
 
45
{
 
46
        switch (id) {
 
47
        case 0:
 
48
                /* The SSP_DETECT is inverted on this board. */
 
49
                return gpio_get_value(MX23_PAD_SSP1_DETECT__GPIO_2_1);
 
50
        case 1:
 
51
                /* Internal eMMC always present */
 
52
                return 1;
 
53
        default:
 
54
                return 0;
 
55
        }
 
56
}
 
57
 
 
58
int board_mmc_init(bd_t *bis)
 
59
{
 
60
        int ret;
 
61
 
 
62
        /* MicroSD slot */
 
63
        gpio_direction_input(MX23_PAD_SSP1_DETECT__GPIO_2_1);
 
64
        gpio_direction_output(MX23_PAD_GPMI_D08__GPIO_0_8, 0);
 
65
        ret = mxsmmc_initialize(bis, 0, NULL, xfi3_mmc_cd);
 
66
        if (ret)
 
67
                return ret;
 
68
 
 
69
        /* Internal eMMC */
 
70
        gpio_direction_output(MX23_PAD_PWM3__GPIO_1_29, 0);
 
71
        ret = mxsmmc_initialize(bis, 1, NULL, xfi3_mmc_cd);
 
72
 
 
73
        return ret;
 
74
}
 
75
#endif
 
76
 
 
77
#ifdef CONFIG_VIDEO_MXS
 
78
#define MUX_CONFIG_LCD  (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
 
79
const iomux_cfg_t iomux_lcd_gpio[] = {
 
80
        MX23_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_LCD,
 
81
        MX23_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_LCD,
 
82
        MX23_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_LCD,
 
83
        MX23_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_LCD,
 
84
        MX23_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_LCD,
 
85
        MX23_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_LCD,
 
86
        MX23_PAD_LCD_D06__GPIO_1_6 | MUX_CONFIG_LCD,
 
87
        MX23_PAD_LCD_D07__GPIO_1_7 | MUX_CONFIG_LCD,
 
88
        MX23_PAD_LCD_D08__GPIO_1_8 | MUX_CONFIG_LCD,
 
89
        MX23_PAD_LCD_D09__GPIO_1_9 | MUX_CONFIG_LCD,
 
90
        MX23_PAD_LCD_D10__GPIO_1_10 | MUX_CONFIG_LCD,
 
91
        MX23_PAD_LCD_D11__GPIO_1_11 | MUX_CONFIG_LCD,
 
92
        MX23_PAD_LCD_D12__GPIO_1_12 | MUX_CONFIG_LCD,
 
93
        MX23_PAD_LCD_D13__GPIO_1_13 | MUX_CONFIG_LCD,
 
94
        MX23_PAD_LCD_D14__GPIO_1_14 | MUX_CONFIG_LCD,
 
95
        MX23_PAD_LCD_D15__GPIO_1_15 | MUX_CONFIG_LCD,
 
96
        MX23_PAD_LCD_D16__GPIO_1_16 | MUX_CONFIG_LCD,
 
97
        MX23_PAD_LCD_D17__GPIO_1_17 | MUX_CONFIG_LCD,
 
98
        MX23_PAD_LCD_RESET__GPIO_1_18 | MUX_CONFIG_LCD,
 
99
        MX23_PAD_LCD_RS__GPIO_1_19 | MUX_CONFIG_LCD,
 
100
        MX23_PAD_LCD_WR__GPIO_1_20 | MUX_CONFIG_LCD,
 
101
        MX23_PAD_LCD_CS__GPIO_1_21 | MUX_CONFIG_LCD,
 
102
        MX23_PAD_LCD_ENABLE__GPIO_1_23 | MUX_CONFIG_LCD,
 
103
};
 
104
 
 
105
const iomux_cfg_t iomux_lcd_lcd[] = {
 
106
        MX23_PAD_LCD_D00__LCD_D00 | MUX_CONFIG_LCD,
 
107
        MX23_PAD_LCD_D01__LCD_D01 | MUX_CONFIG_LCD,
 
108
        MX23_PAD_LCD_D02__LCD_D02 | MUX_CONFIG_LCD,
 
109
        MX23_PAD_LCD_D03__LCD_D03 | MUX_CONFIG_LCD,
 
110
        MX23_PAD_LCD_D04__LCD_D04 | MUX_CONFIG_LCD,
 
111
        MX23_PAD_LCD_D05__LCD_D05 | MUX_CONFIG_LCD,
 
112
        MX23_PAD_LCD_D06__LCD_D06 | MUX_CONFIG_LCD,
 
113
        MX23_PAD_LCD_D07__LCD_D07 | MUX_CONFIG_LCD,
 
114
        MX23_PAD_LCD_D08__LCD_D08 | MUX_CONFIG_LCD,
 
115
        MX23_PAD_LCD_D09__LCD_D09 | MUX_CONFIG_LCD,
 
116
        MX23_PAD_LCD_D10__LCD_D10 | MUX_CONFIG_LCD,
 
117
        MX23_PAD_LCD_D11__LCD_D11 | MUX_CONFIG_LCD,
 
118
        MX23_PAD_LCD_D12__LCD_D12 | MUX_CONFIG_LCD,
 
119
        MX23_PAD_LCD_D13__LCD_D13 | MUX_CONFIG_LCD,
 
120
        MX23_PAD_LCD_D14__LCD_D14 | MUX_CONFIG_LCD,
 
121
        MX23_PAD_LCD_D15__LCD_D15 | MUX_CONFIG_LCD,
 
122
        MX23_PAD_LCD_D16__LCD_D16 | MUX_CONFIG_LCD,
 
123
        MX23_PAD_LCD_D17__LCD_D17 | MUX_CONFIG_LCD,
 
124
        MX23_PAD_LCD_RESET__LCD_RESET | MUX_CONFIG_LCD,
 
125
        MX23_PAD_LCD_RS__LCD_RS | MUX_CONFIG_LCD,
 
126
        MX23_PAD_LCD_WR__LCD_WR | MUX_CONFIG_LCD,
 
127
        MX23_PAD_LCD_CS__LCD_CS | MUX_CONFIG_LCD,
 
128
        MX23_PAD_LCD_ENABLE__LCD_ENABLE | MUX_CONFIG_LCD,
 
129
        MX23_PAD_LCD_VSYNC__LCD_VSYNC | MUX_CONFIG_LCD,
 
130
};
 
131
 
 
132
static int mxsfb_read_register(uint32_t reg, uint32_t *value)
 
133
{
 
134
        iomux_cfg_t mux;
 
135
        uint32_t val = 0;
 
136
        int i;
 
137
 
 
138
        /* Mangle the register offset. */
 
139
        reg = ((reg & 0xff) << 1) | (((reg >> 8) & 0xff) << 10);
 
140
 
 
141
        /*
 
142
         * The SmartLCD interface on MX233 can only do WRITE operation
 
143
         * via the LCDIF controller. Implement the READ operation by
 
144
         * fiddling with bits.
 
145
         */
 
146
        mxs_iomux_setup_multiple_pads(iomux_lcd_gpio,
 
147
                ARRAY_SIZE(iomux_lcd_gpio));
 
148
 
 
149
        gpio_direction_output(MX23_PAD_LCD_RS__GPIO_1_19, 1);
 
150
        gpio_direction_output(MX23_PAD_LCD_CS__GPIO_1_21, 1);
 
151
        gpio_direction_output(MX23_PAD_LCD_WR__GPIO_1_20, 1);
 
152
        gpio_direction_output(MX23_PAD_LCD_ENABLE__GPIO_1_23, 1);
 
153
 
 
154
        for (i = 0; i < 18; i++) {
 
155
                mux = MXS_IOMUX_PAD_NAKED(1, i, PAD_MUXSEL_GPIO);
 
156
                gpio_direction_output(mux, 0);
 
157
        }
 
158
 
 
159
        udelay(2);
 
160
        gpio_direction_output(MX23_PAD_LCD_RS__GPIO_1_19, 0);
 
161
        udelay(1);
 
162
        gpio_direction_output(MX23_PAD_LCD_CS__GPIO_1_21, 0);
 
163
        udelay(1);
 
164
        gpio_direction_output(MX23_PAD_LCD_WR__GPIO_1_20, 0);
 
165
        udelay(1);
 
166
 
 
167
        for (i = 0; i < 18; i++) {
 
168
                mux = MXS_IOMUX_PAD_NAKED(1, i, PAD_MUXSEL_GPIO);
 
169
                gpio_direction_output(mux, (reg >> i) & 1);
 
170
        }
 
171
        udelay(1);
 
172
 
 
173
        gpio_direction_output(MX23_PAD_LCD_WR__GPIO_1_20, 1);
 
174
        udelay(3);
 
175
 
 
176
        for (i = 0; i < 18; i++) {
 
177
                mux = MXS_IOMUX_PAD_NAKED(1, i, PAD_MUXSEL_GPIO);
 
178
                gpio_direction_input(mux);
 
179
        }
 
180
        udelay(2);
 
181
 
 
182
        gpio_direction_output(MX23_PAD_LCD_ENABLE__GPIO_1_23, 0);
 
183
        udelay(1);
 
184
        gpio_direction_output(MX23_PAD_LCD_RS__GPIO_1_19, 1);
 
185
        udelay(1);
 
186
        gpio_direction_output(MX23_PAD_LCD_ENABLE__GPIO_1_23, 1);
 
187
        udelay(3);
 
188
        gpio_direction_output(MX23_PAD_LCD_ENABLE__GPIO_1_23, 0);
 
189
        udelay(2);
 
190
 
 
191
        for (i = 0; i < 18; i++) {
 
192
                mux = MXS_IOMUX_PAD_NAKED(1, i, PAD_MUXSEL_GPIO);
 
193
                val |= !!gpio_get_value(mux) << i;
 
194
        }
 
195
        udelay(1);
 
196
 
 
197
        gpio_direction_output(MX23_PAD_LCD_ENABLE__GPIO_1_23, 1);
 
198
        udelay(1);
 
199
        gpio_direction_output(MX23_PAD_LCD_CS__GPIO_1_21, 1);
 
200
        udelay(1);
 
201
 
 
202
        mxs_iomux_setup_multiple_pads(iomux_lcd_lcd,
 
203
                ARRAY_SIZE(iomux_lcd_lcd));
 
204
 
 
205
        /* Demangle the register value. */
 
206
        *value = ((val >> 1) & 0xff) | ((val >> 2) & 0xff00);
 
207
 
 
208
        writel(val, 0x2000);
 
209
        return 0;
 
210
}
 
211
 
 
212
static int mxsfb_write_byte(uint32_t payload, const unsigned int data)
 
213
{
 
214
        struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
 
215
        const unsigned int timeout = 0x10000;
 
216
 
 
217
        /* What is going on here I do not know. FIXME */
 
218
        payload = ((payload & 0xff) << 1) | (((payload >> 8) & 0xff) << 10);
 
219
 
 
220
        if (mxs_wait_mask_clr(&regs->hw_lcdif_ctrl_reg, LCDIF_CTRL_RUN,
 
221
                              timeout))
 
222
                return -ETIMEDOUT;
 
223
 
 
224
        writel((1 << LCDIF_TRANSFER_COUNT_V_COUNT_OFFSET) |
 
225
                (1 << LCDIF_TRANSFER_COUNT_H_COUNT_OFFSET),
 
226
                &regs->hw_lcdif_transfer_count);
 
227
 
 
228
        writel(LCDIF_CTRL_DATA_SELECT | LCDIF_CTRL_RUN,
 
229
                &regs->hw_lcdif_ctrl_clr);
 
230
 
 
231
        if (data)
 
232
                writel(LCDIF_CTRL_DATA_SELECT, &regs->hw_lcdif_ctrl_set);
 
233
 
 
234
        writel(LCDIF_CTRL_RUN, &regs->hw_lcdif_ctrl_set);
 
235
 
 
236
        if (mxs_wait_mask_clr(&regs->hw_lcdif_lcdif_stat_reg, 1 << 29,
 
237
                              timeout))
 
238
                return -ETIMEDOUT;
 
239
 
 
240
        writel(payload, &regs->hw_lcdif_data);
 
241
        return mxs_wait_mask_clr(&regs->hw_lcdif_ctrl_reg, LCDIF_CTRL_RUN,
 
242
                                 timeout);
 
243
}
 
244
 
 
245
static void mxsfb_write_register(uint32_t reg, uint32_t data)
 
246
{
 
247
        mxsfb_write_byte(reg, 0);
 
248
        mxsfb_write_byte(data, 1);
 
249
}
 
250
 
 
251
static const struct {
 
252
        uint8_t         reg;
 
253
        uint8_t         delay;
 
254
        uint16_t        val;
 
255
} lcd_regs[] = {
 
256
        { 0xe5, 0  , 0x78f0 },
 
257
        { 0xe3, 0  , 0x3008 },
 
258
        { 0xe7, 0  , 0x0012 },
 
259
        { 0xef, 0  , 0x1231 },
 
260
        { 0x00, 0  , 0x0001 },
 
261
        { 0x01, 0  , 0x0100 },
 
262
        { 0x02, 0  , 0x0700 },
 
263
        { 0x03, 0  , 0x1030 },
 
264
        { 0x04, 0  , 0x0000 },
 
265
        { 0x08, 0  , 0x0207 },
 
266
        { 0x09, 0  , 0x0000 },
 
267
        { 0x0a, 0  , 0x0000 },
 
268
        { 0x0c, 0  , 0x0000 },
 
269
        { 0x0d, 0  , 0x0000 },
 
270
        { 0x0f, 0  , 0x0000 },
 
271
        { 0x10, 0  , 0x0000 },
 
272
        { 0x11, 0  , 0x0007 },
 
273
        { 0x12, 0  , 0x0000 },
 
274
        { 0x13, 20 , 0x0000 },
 
275
        /* Wait 20 mS here. */
 
276
        { 0x10, 0  , 0x1290 },
 
277
        { 0x11, 50 , 0x0007 },
 
278
        /* Wait 50 mS here. */
 
279
        { 0x12, 50 , 0x0019 },
 
280
        /* Wait 50 mS here. */
 
281
        { 0x13, 0  , 0x1700 },
 
282
        { 0x29, 50 , 0x0014 },
 
283
        /* Wait 50 mS here. */
 
284
        { 0x20, 0  , 0x0000 },
 
285
        { 0x21, 0  , 0x0000 },
 
286
        { 0x30, 0  , 0x0504 },
 
287
        { 0x31, 0  , 0x0007 },
 
288
        { 0x32, 0  , 0x0006 },
 
289
        { 0x35, 0  , 0x0106 },
 
290
        { 0x36, 0  , 0x0202 },
 
291
        { 0x37, 0  , 0x0504 },
 
292
        { 0x38, 0  , 0x0500 },
 
293
        { 0x39, 0  , 0x0706 },
 
294
        { 0x3c, 0  , 0x0204 },
 
295
        { 0x3d, 0  , 0x0202 },
 
296
        { 0x50, 0  , 0x0000 },
 
297
        { 0x51, 0  , 0x00ef },
 
298
        { 0x52, 0  , 0x0000 },
 
299
        { 0x53, 0  , 0x013f },
 
300
        { 0x60, 0  , 0xa700 },
 
301
        { 0x61, 0  , 0x0001 },
 
302
        { 0x6a, 0  , 0x0000 },
 
303
        { 0x2b, 50 , 0x000d },
 
304
        /* Wait 50 mS here. */
 
305
        { 0x90, 0  , 0x0011 },
 
306
        { 0x92, 0  , 0x0600 },
 
307
        { 0x93, 0  , 0x0003 },
 
308
        { 0x95, 0  , 0x0110 },
 
309
        { 0x97, 0  , 0x0000 },
 
310
        { 0x98, 0  , 0x0000 },
 
311
        { 0x07, 0  , 0x0173 },
 
312
};
 
313
 
 
314
void board_mxsfb_system_setup(void)
 
315
{
 
316
        struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
 
317
        uint32_t id;
 
318
        int i;
 
319
 
 
320
        /* Switch the LCDIF into System-Mode */
 
321
        writel(LCDIF_CTRL_LCDIF_MASTER | LCDIF_CTRL_DOTCLK_MODE |
 
322
                LCDIF_CTRL_BYPASS_COUNT, &regs->hw_lcdif_ctrl_clr);
 
323
 
 
324
        /* To program the LCD, switch to 18bit bus + 18bit data. */
 
325
        clrsetbits_le32(&regs->hw_lcdif_ctrl,
 
326
                LCDIF_CTRL_WORD_LENGTH_MASK | LCDIF_CTRL_LCD_DATABUS_WIDTH_MASK,
 
327
                LCDIF_CTRL_WORD_LENGTH_18BIT |
 
328
                LCDIF_CTRL_LCD_DATABUS_WIDTH_18BIT);
 
329
 
 
330
        mxsfb_read_register(0, &id);
 
331
        writel(id, 0x2004);
 
332
 
 
333
        /* Restart the SmartLCD controller */
 
334
        mdelay(50);
 
335
        writel(1, &regs->hw_lcdif_ctrl1_set);
 
336
        mdelay(50);
 
337
        writel(1, &regs->hw_lcdif_ctrl1_clr);
 
338
        mdelay(50);
 
339
        writel(1, &regs->hw_lcdif_ctrl1_set);
 
340
        mdelay(50);
 
341
 
 
342
        /* Program the SmartLCD controller */
 
343
        writel(LCDIF_CTRL1_RECOVER_ON_UNDERFLOW, &regs->hw_lcdif_ctrl1_set);
 
344
 
 
345
        writel((0x02 << LCDIF_TIMING_CMD_HOLD_OFFSET) |
 
346
               (0x02 << LCDIF_TIMING_CMD_SETUP_OFFSET) |
 
347
               (0x02 << LCDIF_TIMING_DATA_HOLD_OFFSET) |
 
348
               (0x01 << LCDIF_TIMING_DATA_SETUP_OFFSET),
 
349
               &regs->hw_lcdif_timing);
 
350
 
 
351
        /*
 
352
         * ILI9325 init and configuration sequence.
 
353
         */
 
354
        for (i = 0; i < ARRAY_SIZE(lcd_regs); i++) {
 
355
                mxsfb_write_register(lcd_regs[i].reg, lcd_regs[i].val);
 
356
                if (lcd_regs[i].delay)
 
357
                        mdelay(lcd_regs[i].delay);
 
358
        }
 
359
        /* Turn on Framebuffer Upload Mode */
 
360
        mxsfb_write_byte(0x22, 0);
 
361
 
 
362
        writel(LCDIF_CTRL_LCDIF_MASTER | LCDIF_CTRL_DATA_SELECT,
 
363
                &regs->hw_lcdif_ctrl_set);
 
364
 
 
365
        /* Operate the framebuffer in 16bit mode. */
 
366
        clrsetbits_le32(&regs->hw_lcdif_ctrl,
 
367
                LCDIF_CTRL_WORD_LENGTH_MASK | LCDIF_CTRL_LCD_DATABUS_WIDTH_MASK,
 
368
                LCDIF_CTRL_WORD_LENGTH_16BIT |
 
369
                LCDIF_CTRL_LCD_DATABUS_WIDTH_18BIT);
 
370
}
 
371
#endif
 
372
 
 
373
int board_init(void)
 
374
{
 
375
        /* Adress of boot parameters */
 
376
        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
377
 
 
378
        /* Turn on PWM backlight */
 
379
        gpio_direction_output(MX23_PAD_PWM2__GPIO_1_28, 1);
 
380
 
 
381
        return 0;
 
382
}
 
383
 
 
384
int board_eth_init(bd_t *bis)
 
385
{
 
386
        usb_eth_initialize(bis);
 
387
        return 0;
 
388
}