1// SPDX-License-Identifier: GPL-2.0+ 2/* (C) Copyright 2019 CompuLab, Ltd. <www.compulab.co.il> */ 3 4#include <common.h> 5#include <i2c.h> 6#include <linux/kernel.h> 7#include <asm/arch/imx8mq_pins.h> 8#include <asm/mach-imx/gpio.h> 9#include <asm-generic/gpio.h> 10#include <asm/setup.h> 11#include <linux/delay.h> 12 13#ifdef CONFIG_SPL_BUILD 14 15#define CFG_SYS_I2C_EEPROM_ADDR_P1 0x51 16 17static iomux_v3_cfg_t const eeprom_pads[] = { 18 IMX8MQ_PAD_GPIO1_IO13__GPIO1_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL), 19}; 20 21#define EEPROM_WP_GPIO IMX_GPIO_NR(1, 13) 22 23static void cl_eeprom_we(int enable) 24{ 25 static int done; 26 27 if (done) { 28 gpio_direction_output(EEPROM_WP_GPIO, enable); 29 return; 30 } 31 32 imx_iomux_v3_setup_multiple_pads(eeprom_pads, ARRAY_SIZE(eeprom_pads)); 33 gpio_request(EEPROM_WP_GPIO, "eeprom_wp"); 34 gpio_direction_output(EEPROM_WP_GPIO, enable); 35 done = 1; 36} 37 38static int cl_eeprom_read(uint offset, uchar *buf, int len) 39{ 40 struct udevice *dev; 41 int ret; 42 43 ret = i2c_get_chip_for_busnum(1, CFG_SYS_I2C_EEPROM_ADDR_P1, 44 CONFIG_SYS_I2C_EEPROM_ADDR_LEN, &dev); 45 if (ret) { 46 printf("%s: Cannot find EEPROM: %d\n", __func__, ret); 47 return ret; 48 } 49 50 return dm_i2c_read(dev, offset, buf, len); 51} 52 53static int cl_eeprom_write(uint offset, uchar *buf, int len) 54{ 55 struct udevice *dev; 56 int ret; 57 58 cl_eeprom_we(1); 59 60 ret = i2c_get_chip_for_busnum(1, CFG_SYS_I2C_EEPROM_ADDR_P1, 61 CONFIG_SYS_I2C_EEPROM_ADDR_LEN, &dev); 62 if (ret) { 63 printf("%s: Cannot find EEPROM: %d\n", __func__, ret); 64 return ret; 65 } 66 67 return dm_i2c_write(dev, offset, buf, len); 68} 69 70/* Reserved for fututre use area */ 71#define BOARD_DDRINFO_OFFSET 0x40 72#define BOARD_DDR_SIZE 4 73static u32 board_ddrinfo = 0xdeadbeef; 74 75#define BOARD_DDRSUBIND_OFFSET 0x44 76#define BOARD_DDRSUBIND_SIZE 1 77static u8 board_ddrsubind = 0xff; 78 79#define BOARD_OSIZE_OFFSET 0x80 80#define BOARD_OSIZE_SIZE 4 81static u32 board_osize = 0xdeadbeef; 82 83#define BOARD_DDRINFO_VALID(A) ((A) != 0xdeadbeef) 84 85u32 cl_eeprom_get_ddrinfo(void) 86{ 87 if (!BOARD_DDRINFO_VALID(board_ddrinfo)) { 88 if (cl_eeprom_read(BOARD_DDRINFO_OFFSET, (uchar *)&board_ddrinfo, BOARD_DDR_SIZE)) 89 return 0; 90 } 91 return board_ddrinfo; 92}; 93 94u32 cl_eeprom_set_ddrinfo(u32 ddrinfo) 95{ 96 if (cl_eeprom_write(BOARD_DDRINFO_OFFSET, (uchar *)&ddrinfo, BOARD_DDR_SIZE)) 97 return 0; 98 99 board_ddrinfo = ddrinfo; 100 101 return board_ddrinfo; 102}; 103 104u8 cl_eeprom_get_subind(void) 105{ 106 if (cl_eeprom_read(BOARD_DDRSUBIND_OFFSET, (uchar *)&board_ddrsubind, BOARD_DDRSUBIND_SIZE)) 107 return 0xff; 108 109 return board_ddrsubind; 110}; 111 112u8 cl_eeprom_set_subind(u8 ddrsubind) 113{ 114 if (cl_eeprom_write(BOARD_DDRSUBIND_OFFSET, (uchar *)&ddrsubind, BOARD_DDRSUBIND_SIZE)) 115 return 0xff; 116 board_ddrsubind = ddrsubind; 117 118 return board_ddrsubind; 119}; 120 121/* override-size ifaces */ 122u32 cl_eeprom_get_osize(void) 123{ 124 if (cl_eeprom_read(BOARD_OSIZE_OFFSET, (uchar *)&board_osize, BOARD_OSIZE_SIZE)) 125 return 0; 126 127 return board_osize; 128}; 129#endif 130