| /* |
| * Copyright 2019 Google LLC |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License |
| * version 2 as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * General Public License for more details. |
| */ |
| |
| #include "board_id.h" |
| |
| #include <asm/arch/imx8mq_pins.h> |
| #include <asm/arch/imx-regs.h> |
| #include <asm/mach-imx/iomux-v3.h> |
| #include <asm/mach-imx/gpio.h> |
| #include <asm/gpio.h> |
| #include <asm/io.h> |
| |
| #define BOARD_ID_GPIOS_PORT 3 |
| #define BOARD_ID_GPIOS_BASE GPIO3_BASE_ADDR |
| #define BOARD_ID_GPIO1_INDEX 22 |
| #define BOARD_ID_GPIO2_INDEX 24 |
| #define BOARD_ID_GPIO3_INDEX 19 |
| #define BOARD_ID_GPIO1 IMX_GPIO_NR(BOARD_ID_GPIOS_PORT, BOARD_ID_GPIO1_INDEX) |
| #define BOARD_ID_GPIO2 IMX_GPIO_NR(BOARD_ID_GPIOS_PORT, BOARD_ID_GPIO2_INDEX) |
| #define BOARD_ID_GPIO3 IMX_GPIO_NR(BOARD_ID_GPIOS_PORT, BOARD_ID_GPIO3_INDEX) |
| |
| #define BASEBOARD_ID_GPIOS_PORT 3 |
| #define BASEBOARD_ID_GPIOS_BASE GPIO3_BASE_ADDR |
| #define BASEBOARD_ID_GPIO1_INDEX 25 |
| #define BASEBOARD_ID_GPIO2_INDEX 23 |
| #define BASEBOARD_ID_GPIO3_INDEX 20 |
| #define BASEBOARD_ID_GPIO4_INDEX 21 |
| #define BASEBOARD_ID_GPIO1 IMX_GPIO_NR(BASEBOARD_ID_GPIOS_PORT, BASEBOARD_ID_GPIO1_INDEX) |
| #define BASEBOARD_ID_GPIO2 IMX_GPIO_NR(BASEBOARD_ID_GPIOS_PORT, BASEBOARD_ID_GPIO2_INDEX) |
| #define BASEBOARD_ID_GPIO3 IMX_GPIO_NR(BASEBOARD_ID_GPIOS_PORT, BASEBOARD_ID_GPIO3_INDEX) |
| #define BASEBOARD_ID_GPIO4 IMX_GPIO_NR(BASEBOARD_ID_GPIOS_PORT, BASEBOARD_ID_GPIO4_INDEX) |
| |
| static iomux_v3_cfg_t const board_id_pads[] = { |
| IMX8MQ_PAD_SAI5_RXD1__GPIO3_IO22 | MUX_PAD_CTRL(PAD_CTL_DSE0), |
| IMX8MQ_PAD_SAI5_RXD3__GPIO3_IO24 | MUX_PAD_CTRL(PAD_CTL_DSE0), |
| IMX8MQ_PAD_SAI5_RXFS__GPIO3_IO19 | MUX_PAD_CTRL(PAD_CTL_DSE0), |
| }; |
| |
| static iomux_v3_cfg_t const board_id_default_pads[] = { |
| IMX8MQ_PAD_SAI5_RXD1__SAI5_RX_DATA1 | MUX_PAD_CTRL(0x1816), |
| IMX8MQ_PAD_SAI5_RXD3__SAI5_RX_DATA3 | MUX_PAD_CTRL(0x16), |
| IMX8MQ_PAD_SAI5_RXFS__SAI5_RX_SYNC | MUX_PAD_CTRL(0x16), |
| }; |
| |
| static iomux_v3_cfg_t const baseboard_id_pads[] = { |
| IMX8MQ_PAD_SAI5_MCLK__GPIO3_IO25 | MUX_PAD_CTRL(PAD_CTL_DSE0), |
| IMX8MQ_PAD_SAI5_RXD2__GPIO3_IO23 | MUX_PAD_CTRL(PAD_CTL_DSE0), |
| IMX8MQ_PAD_SAI5_RXC__GPIO3_IO20 | MUX_PAD_CTRL(PAD_CTL_DSE0), |
| IMX8MQ_PAD_SAI5_RXD0__GPIO3_IO21 | MUX_PAD_CTRL(PAD_CTL_DSE0), |
| }; |
| |
| static iomux_v3_cfg_t const baseboard_id_default_pads[] = { |
| IMX8MQ_PAD_SAI5_MCLK__SAI5_MCLK | MUX_PAD_CTRL(0x16), |
| IMX8MQ_PAD_SAI5_RXD2__SAI5_RX_DATA2 | MUX_PAD_CTRL(0x16), |
| IMX8MQ_PAD_SAI5_RXC__SAI5_RX_BCLK | MUX_PAD_CTRL(0x16), |
| IMX8MQ_PAD_SAI5_RXD0__SAI5_RX_DATA0 | MUX_PAD_CTRL(0x16), |
| }; |
| |
| int get_board_id() { |
| int board_id = 0; |
| |
| imx_iomux_v3_setup_multiple_pads(board_id_pads, |
| ARRAY_SIZE(board_id_pads)); |
| |
| #ifdef CONFIG_SPL_BUILD |
| gpio_request(BOARD_ID_GPIO1, "board_id_1"); |
| gpio_direction_input(BOARD_ID_GPIO1); |
| gpio_request(BOARD_ID_GPIO2, "board_id_2"); |
| gpio_direction_input(BOARD_ID_GPIO2); |
| gpio_request(BOARD_ID_GPIO3, "board_id_3"); |
| gpio_direction_input(BOARD_ID_GPIO3); |
| |
| board_id = gpio_get_value(BOARD_ID_GPIO1); |
| board_id |= gpio_get_value(BOARD_ID_GPIO2) << 1; |
| board_id |= gpio_get_value(BOARD_ID_GPIO3) << 2; |
| |
| gpio_free(BOARD_ID_GPIO1); |
| gpio_free(BOARD_ID_GPIO2); |
| gpio_free(BOARD_ID_GPIO3); |
| #else |
| struct gpio_regs *regs = (struct gpio_regs *)BOARD_ID_GPIOS_BASE; |
| board_id = (readl(®s->gpio_dr) >> BOARD_ID_GPIO1_INDEX) & 0x01; |
| board_id |= (readl(®s->gpio_dr) >> (BOARD_ID_GPIO2_INDEX - 1)) & 0x02; |
| board_id |= (readl(®s->gpio_dr) >> (BOARD_ID_GPIO3_INDEX - 2)) & 0x04; |
| #endif |
| |
| imx_iomux_v3_setup_multiple_pads(board_id_default_pads, |
| ARRAY_SIZE(board_id_default_pads)); |
| |
| return board_id; |
| } |
| |
| int get_baseboard_id() { |
| int baseboard_id = -1; |
| |
| imx_iomux_v3_setup_multiple_pads(baseboard_id_pads, ARRAY_SIZE(baseboard_id_pads)); |
| |
| #ifdef CONFIG_SPL_BUILD |
| gpio_request(BASEBOARD_ID_GPIO1, "baseboard_id_1"); |
| gpio_direction_input(BASEBOARD_ID_GPIO1); |
| gpio_request(BASEBOARD_ID_GPIO2, "baseboard_id_2"); |
| gpio_direction_input(BASEBOARD_ID_GPIO2); |
| gpio_request(BASEBOARD_ID_GPIO3, "baseboard_id_3"); |
| gpio_direction_input(BASEBOARD_ID_GPIO3); |
| gpio_request(BASEBOARD_ID_GPIO4, "baseboard_id_4"); |
| gpio_direction_input(BASEBOARD_ID_GPIO4); |
| |
| baseboard_id = gpio_get_value(BASEBOARD_ID_GPIO1); |
| baseboard_id |= gpio_get_value(BASEBOARD_ID_GPIO2) << 1; |
| baseboard_id |= gpio_get_value(BASEBOARD_ID_GPIO3) << 2; |
| baseboard_id |= gpio_get_value(BASEBOARD_ID_GPIO4) << 3; |
| |
| gpio_free(BASEBOARD_ID_GPIO1); |
| gpio_free(BASEBOARD_ID_GPIO2); |
| gpio_free(BASEBOARD_ID_GPIO3); |
| gpio_free(BASEBOARD_ID_GPIO4); |
| #else |
| |
| struct gpio_regs *regs = (struct gpio_regs *)BASEBOARD_ID_GPIOS_BASE; |
| baseboard_id = (readl(®s->gpio_dr) >> BASEBOARD_ID_GPIO1_INDEX) & 0x01; |
| baseboard_id |= (readl(®s->gpio_dr) >> (BASEBOARD_ID_GPIO2_INDEX - 1)) & 0x02; |
| baseboard_id |= (readl(®s->gpio_dr) >> (BASEBOARD_ID_GPIO3_INDEX - 2)) & 0x04; |
| baseboard_id |= (readl(®s->gpio_dr) >> (BASEBOARD_ID_GPIO4_INDEX - 3)) & 0x08; |
| #endif |
| |
| imx_iomux_v3_setup_multiple_pads(baseboard_id_default_pads, |
| ARRAY_SIZE(baseboard_id_default_pads)); |
| |
| return baseboard_id; |
| } |
| |
| phys_size_t get_ddr_size(void) { |
| const phys_size_t k1Gb = 0x40000000; |
| const phys_size_t k2Gb = 0x80000000; |
| const phys_size_t k3Gb = 0xC0000000; |
| const phys_size_t k4Gb = 0x100000000; |
| phys_size_t ram_size = 0; |
| const int board_id = get_board_id(); |
| |
| switch (board_id) { |
| case 0: |
| // Todo(pnordstrom) Board id 0 should be 4 Gb but currently |
| // only 3Gb works due to 32 bit checks all over u-boot and SDRAM |
| // starting at 1 Gb |
| ram_size = k4Gb; |
| break; |
| case 1: |
| case 2: |
| case 5: |
| case 6: |
| ram_size = k1Gb; |
| break; |
| case 3: |
| ram_size = k2Gb; |
| break; |
| case 4: |
| case 7: |
| ram_size = k3Gb; |
| break; |
| default: |
| break; |
| } |
| |
| return ram_size; |
| } |