diff --git a/arch/ppc/boards/pcm030/Makefile b/arch/ppc/boards/pcm030/Makefile index e7d744b..4e5dc4f 100644 --- a/arch/ppc/boards/pcm030/Makefile +++ b/arch/ppc/boards/pcm030/Makefile @@ -1,2 +1,2 @@ -obj-y += pcm030.o +obj-y += pcm030.o eeprom.o extra-y += barebox.lds diff --git a/arch/ppc/boards/pcm030/config.h b/arch/ppc/boards/pcm030/config.h index 6e74964..3fe1f28 100644 --- a/arch/ppc/boards/pcm030/config.h +++ b/arch/ppc/boards/pcm030/config.h @@ -25,18 +25,9 @@ #include -#define CFG_MPC5XXX_CLKIN 33333333 /* ... running at 33.333333MHz */ - -#define CFG_GPS_PORT_CONFIG 0x00558c10 /* PSC6=UART, PSC3=UART ; Ether=100MBit with MD */ +#define CFG_MPC5XXX_CLKIN 33333000 /* ... running at 33.333MHz */ #define CFG_HID0_INIT HID0_ICE | HID0_ICFI #define CFG_HID0_FINAL HID0_ICE - -#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ - -#define OF_CPU "PowerPC,5200@0" -#define OF_TBCLK CFG_MPC5XXX_CLKIN -#define OF_SOC "soc5200@f0000000" - #endif /* __CONFIG_H */ diff --git a/arch/ppc/boards/pcm030/eeprom.c b/arch/ppc/boards/pcm030/eeprom.c new file mode 100644 index 0000000..aa00f36 --- /dev/null +++ b/arch/ppc/boards/pcm030/eeprom.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2015 Juergen Borleis + * + * Based on code from: + * Copyright (C) 2013 Jan Luebbe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#define PCM030_EEPROM_DEVICE "/dev/eeprom0" + +/* + * The first 2048 bytes contain the U-Boot environment shipped with the boards. + * After that an area begins where some board specific and partially unique data + * is stored. All of this data is plain test, string delimiter is the semicolon. + * the last string terminates with a '\0'. + * One example found in the 'product' area: PCM-030-02REI;017822;0050C2875974\0 + * The first string seems to be the product type, the second string some kind + * of serial number and the last string the boards unique MAC. + */ +struct pcm030_eeprom { + char env[0x800]; /* u-boot environment */ + char product[0x80]; /* ;;\0 */ +} __attribute__((packed)); + +static void pcm030_read_factory_data(const struct pcm030_eeprom *buf) +{ + unsigned u, l; + char *board, *serial; + char *full_mac = "xx:xx:xx:xx:xx:xx"; + u8 enetaddr[6]; + + u = 0; + + for (l = 0; (l + u) < sizeof(buf->product); l++) { + if (buf->product[u + l] != ';') + continue; + board = xstrndup(&buf->product[u], l); + u += l + 1; + globalvar_add_simple("model.type", board); + free(board); + } + + for (l = 0; (l + u) < sizeof(buf->product); l++) { + if (buf->product[u + l] != ';') + continue; + serial = xstrndup(&buf->product[u], l); + u += l + 1; + globalvar_add_simple("model.serial", serial); + free(serial); + } + + /* for the MAC do a simple duck test */ + if (buf->product[u] != ';' && buf->product[u + 12] == '\0') { + full_mac[0] = buf->product[u + 0]; + full_mac[1] = buf->product[u + 1]; + full_mac[3] = buf->product[u + 2]; + full_mac[4] = buf->product[u + 3]; + full_mac[6] = buf->product[u + 4]; + full_mac[7] = buf->product[u + 5]; + full_mac[9] = buf->product[u + 6]; + full_mac[10] = buf->product[u + 7]; + full_mac[12] = buf->product[u + 8]; + full_mac[13] = buf->product[u + 9]; + full_mac[15] = buf->product[u + 10]; + full_mac[16] = buf->product[u + 11]; + string_to_ethaddr(full_mac, enetaddr); + eth_register_ethaddr(0, enetaddr); + return; + } + + printf("EEPROM contains no ethernet MAC\n"); +} + +static int pcm030_eeprom_read(void) +{ + int fd, ret; + struct pcm030_eeprom *buf; + + fd = open(PCM030_EEPROM_DEVICE, O_RDONLY); + if (fd < 0) { + perror("failed to open " PCM030_EEPROM_DEVICE); + return fd; + } + + buf = xmalloc(sizeof(struct pcm030_eeprom)); + + ret = pread(fd, buf, sizeof(struct pcm030_eeprom), 0); + if (ret < sizeof(struct pcm030_eeprom)) { + perror("failed to read " PCM030_EEPROM_DEVICE); + goto out; + } + + pcm030_read_factory_data(buf); + ret = 0; +out: + free(buf); + close(fd); + + return ret; +} +late_initcall(pcm030_eeprom_read); diff --git a/arch/ppc/boards/pcm030/pcm030.c b/arch/ppc/boards/pcm030/pcm030.c index a7fa21d..11b3beb 100644 --- a/arch/ppc/boards/pcm030/pcm030.c +++ b/arch/ppc/boards/pcm030/pcm030.c @@ -32,12 +32,23 @@ #include #include #include +#include #include +#include static struct fec_platform_data fec_info = { .xcv_type = PHY_INTERFACE_MODE_MII, }; +static struct i2c_board_info pcm030_i2c_devices[] = { + { I2C_BOARD_INFO("pcf8563", 0x51), }, + { I2C_BOARD_INFO("24c32", 0x52), }, +}; + +struct i2c_platform_data pcm030_i2c_plat = { + .bitrate = 100000, +}; + static int devices_init (void) { struct stat s; @@ -52,6 +63,9 @@ add_generic_device("fec_mpc5xxx", DEVICE_ID_DYNAMIC, NULL, MPC5XXX_FEC, 0x200, IORESOURCE_MEM, &fec_info); + i2c_register_board_info(0, pcm030_i2c_devices, ARRAY_SIZE(pcm030_i2c_devices)); + add_generic_device("i2c-fsl", DEVICE_ID_DYNAMIC, NULL, MPC5XXX_I2C2, 0x100, + IORESOURCE_MEM, &pcm030_i2c_plat); ret = stat("/dev/nor0", &s); if (ret) @@ -141,10 +155,16 @@ /* Setup pin multiplexing */ /* PSC6=UART, PSC3=UART ; Ether=100MBit with MD */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG = 0x00558c10; + *(vu_long *)MPC5XXX_GPS_PORT_CONFIG = 0x00559c10; *(vu_long *)MPC5XXX_CS_BURST = 0x00000000; *(vu_long *)MPC5XXX_CS_DEADCYCLE = 0x33333333; + /* + * Make USB work due to the special base crystal frequency: + * 33,3330MHz * 16 = 533,328MHz main clock, but should be 528 MHz Clock + */ + out_be32((void *)MPC5XXX_CDM_48_FDC, 0x00015555); + mpc5200_setup_bus_clocks(1, 4); if (get_pc() > SZ_128M) { diff --git a/arch/ppc/configs/pcm030_defconfig b/arch/ppc/configs/pcm030_defconfig index 7b84e2f..61380ac 100644 --- a/arch/ppc/configs/pcm030_defconfig +++ b/arch/ppc/configs/pcm030_defconfig @@ -35,8 +35,11 @@ CONFIG_CMD_TIME=y CONFIG_NET=y CONFIG_DRIVER_NET_MPC5200=y +CONFIG_I2C=y +CONFIG_I2C_IMX=y CONFIG_MTD=y CONFIG_DRIVER_CFI=y CONFIG_CFI_BUFFER_WRITE=y +CONFIG_EEPROM_AT24=y CONFIG_FS_TFTP=y CONFIG_ZLIB=y diff --git a/arch/ppc/mach-mpc5xxx/cpu.c b/arch/ppc/mach-mpc5xxx/cpu.c index a53af63..3f826e4 100644 --- a/arch/ppc/mach-mpc5xxx/cpu.c +++ b/arch/ppc/mach-mpc5xxx/cpu.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include int checkcpu (void) { diff --git a/arch/ppc/mach-mpc5xxx/include/mach/clock.h b/arch/ppc/mach-mpc5xxx/include/mach/clock.h new file mode 100644 index 0000000..b19686f --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/include/mach/clock.h @@ -0,0 +1,14 @@ +#ifndef __ASM_ARCH_CLOCKS_H +#define __ASM_ARCH_CLOCKS_H + +unsigned long get_bus_clock(void); +unsigned long get_cpu_clock(void); +unsigned long get_ipb_clock(void); +unsigned long get_pci_clock(void); +unsigned long get_timebase_clock(void); +static inline unsigned long fsl_get_i2c_freq(void) +{ + return get_ipb_clock(); +} + +#endif /* __ASM_ARCH_CLOCKS_H */ diff --git a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h b/arch/ppc/mach-mpc5xxx/include/mach/clocks.h deleted file mode 100644 index 4e1a903..0000000 --- a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __ASM_ARCH_CLOCKS_H -#define __ASM_ARCH_CLOCKS_H - -unsigned long get_bus_clock(void); -unsigned long get_cpu_clock(void); -unsigned long get_ipb_clock(void); -unsigned long get_pci_clock(void); -unsigned long get_timebase_clock(void); - -#endif /* __ASM_ARCH_CLOCKS_H */ diff --git a/arch/ppc/mach-mpc5xxx/time.c b/arch/ppc/mach-mpc5xxx/time.c index 699a66d..aaa4573 100644 --- a/arch/ppc/mach-mpc5xxx/time.c +++ b/arch/ppc/mach-mpc5xxx/time.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include uint64_t ppc_clocksource_read(void) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 3962286..181321b 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -17,8 +17,13 @@ depends on ARCH_AT91 config I2C_IMX - bool "MPC85xx/i.MX I2C Master driver" - depends on (ARCH_IMX && !ARCH_IMX1) || ARCH_MPC85XX + bool "MPC85xx/MPC5200/i.MX I2C Master driver" + depends on (ARCH_IMX && !ARCH_IMX1) || ARCH_MPC85XX || ARCH_MPC5200 + help + If you say yes to this option, support will be included for many + built-in I2C master controllers found in Freescale SoCs. This is true + for many i.MX ARM based SoCs, for MPC85xx and MPC5200 PowerPC based + SoCs. config I2C_MV64XXX bool "Marvell mv64xxx I2C Controller" diff --git a/drivers/net/fec_mpc5200.c b/drivers/net/fec_mpc5200.c index 14ef872..30be8f7 100644 --- a/drivers/net/fec_mpc5200.c +++ b/drivers/net/fec_mpc5200.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include "fec_mpc5200.h" diff --git a/drivers/serial/serial_mpc5xxx.c b/drivers/serial/serial_mpc5xxx.c index f48255b..711163c 100644 --- a/drivers/serial/serial_mpc5xxx.c +++ b/drivers/serial/serial_mpc5xxx.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate)