Commit aa4e8b78 authored by Alexander Potashev's avatar Alexander Potashev

RT74765. twr-k60n512: reuse the `mcffec` Ethernet driver for TWR-K60N512

Also add the code for:
1. Enabling the clock gate for the Ethernet module of the MCU,
2. Pin configuration for RMII.
3. Disabling the MPU (the Ethernet module will be unable to work with
     the SRAM otherwise.)

The pull-down resistor for the RXER pin is enabled, because this input
pin is not connected to the PHY on the TWR-K60N512 board by default.
parent e066e32e
......@@ -24,15 +24,62 @@
*/
#include <common.h>
#include <netdev.h>
#include <asm/arch/kinetis_gpio.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* GPIO pin configuration table for TWR-K60N512
*
* This table does not list all GPIO pins that will be configured. See also
* the code in `gpio_init()` and in the drivers (for example, the UART driver).
*/
static const struct kinetis_gpio_pin_config twr_k60n512_gpio[] = {
#ifdef CONFIG_MCFFEC
/* A.5 = RMII0_RXER */
{{KINETIS_GPIO_PORT_A, 5}, KINETIS_GPIO_CONFIG_PULLDOWN(4)},
/* A.12 = RMII0_RXD1 */
{{KINETIS_GPIO_PORT_A, 12}, KINETIS_GPIO_CONFIG_MUX(4)},
/* A.13 = RMII0_RXD0 */
{{KINETIS_GPIO_PORT_A, 13}, KINETIS_GPIO_CONFIG_MUX(4)},
/* A.14 = RMII0_CRS_DV */
{{KINETIS_GPIO_PORT_A, 14}, KINETIS_GPIO_CONFIG_MUX(4)},
/* A.15 = RMII0_TXEN */
{{KINETIS_GPIO_PORT_A, 15}, KINETIS_GPIO_CONFIG_MUX(4)},
/* A.16 = RMII0_TXD0 */
{{KINETIS_GPIO_PORT_A, 16}, KINETIS_GPIO_CONFIG_MUX(4)},
/* A.17 = RMII0_TXD1 */
{{KINETIS_GPIO_PORT_A, 17}, KINETIS_GPIO_CONFIG_MUX(4)},
/* B.0 = RMII0_MDIO */
{{KINETIS_GPIO_PORT_B, 0}, KINETIS_GPIO_CONFIG_MUX(4)},
/* B.1 = RMII0_MDC */
{{KINETIS_GPIO_PORT_B, 1}, KINETIS_GPIO_CONFIG_MUX(4)},
#endif /* CONFIG_MCFFEC */
};
/*
* Configure all necessary GPIO pins
*/
static void gpio_init(void)
{
/*
* Configure GPIO pins using the `twr_k60n512_gpio[]` table
*/
kinetis_gpio_config_table(twr_k60n512_gpio, ARRAY_SIZE(twr_k60n512_gpio));
}
/*
* Early hardware init.
*/
int board_init(void)
{
/* TBD */
/*
* Enable GPIO pins
*/
gpio_init();
return 0;
}
......@@ -65,3 +112,13 @@ int dram_init(void)
return 0;
}
#ifdef CONFIG_MCFFEC
/*
* Register the Ethernet driver
*/
int board_eth_init(bd_t *bis)
{
return mcffec_initialize(bis);
}
#endif
......@@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
COBJS := clock.o cpu.o envm.o wdt.o
COBJS := clock.o cpu.o envm.o eth.o soc.o wdt.o
SOBJS :=
SRCS := $(COBJS:.o=.c)
......
......@@ -510,6 +510,11 @@ void clock_init(void)
* Set the bus clock rate (used for many peripherals)
*/
clock_val[CLOCK_PCLK] = KINETIS_PCLK_RATE;
/*
* The MAC internal module clock is OSC0ERCLK
*/
clock_val[CLOCK_MACCLK] = KINETIS_EXTAL_RATE;
}
/*
......
/*
* (C) Copyright 2011
*
* Alexander Potashev, Emcraft Systems, aspotashev@emcraft.com
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/kinetis.h>
#if defined(CONFIG_CMD_NET)
/*
* This function is called by the `mcffec.c` driver with setclear=1
* on FEC initialization, and with setclear=0 on FEC halt.
*
* Someone might think that we could put the clock gate enable/disable code
* for Ethernet here. But this thought is wrong, because the Ethernet module
* clocking must be enabled even when resetting the Ethernet module (otherwise
* we get an exception.) In the `fec_halt()` function, a MAC reset may be
* attempted before calling `fecpin_setclear(dev, 1)`, therefore the clock for
* the Ethernet module must be enabled somewhere else.
* We do this in `cortex_m3_soc_init()`.
*/
int fecpin_setclear(struct eth_device *dev, int setclear)
{
return 0;
}
#endif /* CONFIG_CMD_NET */
/*
* (C) Copyright 2011
*
* Alexander Potashev, Emcraft Systems, aspotashev@emcraft.com
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include "soc.h"
/*
* Memory Protection Unit (MPU) register map
*
* See Chapter 18 of the K60 Reference Manual (page 409)
*/
struct kinetis_mpu_regs {
u32 cesr; /* Control/Error Status Register */
};
/*
* MPU registers base
*/
#define KINETIS_MPU_BASE (KINETIS_AIPS0PERIPH_BASE + 0x0000D000)
#define KINETIS_MPU ((volatile struct kinetis_mpu_regs *) \
KINETIS_MPU_BASE)
/*
* SoC configuration code that cannot be put into drivers
*/
#ifdef CONFIG_ARMCORTEXM3_SOC_INIT
void cortex_m3_soc_init(void)
{
#ifdef CONFIG_MCFFEC
/*
* Enable the clock on the Ethernet module of the MCU
*/
kinetis_periph_enable(KINETIS_CG_ENET, 1);
#endif /* CONFIG_MCFFEC */
/*
* Disable the MPU to let the Ethernet module access the SRAM
*/
KINETIS_MPU->cesr = 0;
}
#endif
......@@ -119,3 +119,23 @@ out:
return rv;
}
/*
* Configure a set of GPIO pins using the given configuration table.
* Returns 0 on success.
*/
int kinetis_gpio_config_table(
const struct kinetis_gpio_pin_config *table, unsigned int len)
{
unsigned int i;
int rv;
for (i = 0; i < len; i ++) {
rv = kinetis_gpio_config(&table[i].dsc, table[i].regval);
if (rv != 0)
goto out;
}
rv = 0;
out:
return rv;
}
......@@ -86,6 +86,8 @@ typedef u32 kinetis_clock_gate_t;
#define KINETIS_CG_PORTC KINETIS_MKCG(4, 11) /* SIM_SCGC5[11] */
#define KINETIS_CG_PORTD KINETIS_MKCG(4, 12) /* SIM_SCGC5[12] */
#define KINETIS_CG_PORTE KINETIS_MKCG(4, 13) /* SIM_SCGC5[13] */
/* ENET */
#define KINETIS_CG_ENET KINETIS_MKCG(1, 0) /* SIM_SCGC2[0] */
/*
* Enable or disable the clock on a peripheral device (timers, UARTs, USB, etc)
......@@ -99,6 +101,7 @@ enum clock {
CLOCK_SYSTICK, /* Systimer clock frequency expressed in Hz */
CLOCK_CCLK, /* Core clock frequency expressed in Hz */
CLOCK_PCLK, /* Bus clock frequency expressed in Hz */
CLOCK_MACCLK, /* MAC module clock frequency expressed in Hz */
CLOCK_END /* for internal usage */
};
......
......@@ -27,6 +27,9 @@
*/
/* Pin Mux Control (selects pin function) */
#define KINETIS_GPIO_CONFIG_MUX_BITS 8
/* Pull Enable (pull-down by default) */
#define LPC178X_GPIO_CONFIG_PE_BIT 1
#define LPC178X_GPIO_CONFIG_PE_MSK (1 << LPC178X_GPIO_CONFIG_PE_BIT)
/*
* These macros should be used to compute the value for the second argument of
......@@ -36,6 +39,8 @@
/* The simplest macro that only allow to configure the MUX bits */
#define KINETIS_GPIO_CONFIG_MUX(mux) \
(mux << KINETIS_GPIO_CONFIG_MUX_BITS)
#define KINETIS_GPIO_CONFIG_PULLDOWN(mux) \
((mux << KINETIS_GPIO_CONFIG_MUX_BITS) | LPC178X_GPIO_CONFIG_PE_MSK)
/*
* TBD: similar macros with more options
*/
......@@ -70,10 +75,22 @@ struct kinetis_gpio_dsc {
unsigned int pin; /* GPIO pin */
};
struct kinetis_gpio_pin_config {
struct kinetis_gpio_dsc dsc;
u32 regval; /* Value for writing into the PCR register */
};
/*
* Configure the specified GPIO pin.
* Returns 0 on success, -EINVAL otherwise.
*/
int kinetis_gpio_config(const struct kinetis_gpio_dsc *dsc, u32 regval);
/*
* Configure a set of GPIO pins using the given configuration table.
* Returns 0 on success.
*/
extern int kinetis_gpio_config_table(
const struct kinetis_gpio_pin_config *table, unsigned int len);
#endif /* _KINETIS_GPIO_H_ */
......@@ -66,6 +66,11 @@
*/
#define CONFIG_ARCH_CPU_INIT
/*
* This ensures that the SoC-specific cortex_m3_soc_init() gets invoked.
*/
#define CONFIG_ARMCORTEXM3_SOC_INIT
/*
* Clock configuration (see cpu/arm_cortexm3/kinetis/clock.c for details)
*/
......@@ -188,7 +193,36 @@
/*
* Ethernet configuration
*/
/* TBD */
#define CONFIG_MCFFEC
/* Only the RMII mode is possible on the TWR-K60N512 board */
#undef CONFIG_MCFFEC_MII
#define CONFIG_NET_MULTI
#define CONFIG_MII
#define CONFIG_MII_INIT
/*
* The value of CONFIG_SYS_FEC0_PINMUX does not matter.
* This configuration option is required by the `mcffec.c` driver.
*/
#define CONFIG_SYS_FEC0_PINMUX 0
#define CONFIG_SYS_FEC0_IOBASE 0x400C0000
#define CONFIG_SYS_FEC0_MIIBASE CONFIG_SYS_FEC0_IOBASE
/*
* Ethernet buffer descriptor tables should be aligned on 512-byte boundaries
*/
#define CONFIG_SYS_CACHELINE_SIZE 512
#define MCFFEC_TOUT_LOOP 1000000
#define CONFIG_SYS_DISCOVER_PHY
#define CONFIG_SYS_RX_ETH_BUFFER 8
/*
* Options for the MDC clock
*/
/* Internal MAC clock rate */
#define CONFIG_MCFFEC_MAC_CLK clock_get(CLOCK_MACCLK)
/*
* We limit the MDC rate to 800 kHz, because the rate of 2.5 MHz leads to data
* corruption when reading the PHY registers.
*/
#define CONFIG_MCFFEC_MII_SPEED_LIMIT 800000
/*
* Console I/O buffer size
......@@ -236,7 +270,7 @@
#undef CONFIG_CMD_IMLS
#undef CONFIG_CMD_LOADS
#undef CONFIG_CMD_MISC
#undef CONFIG_CMD_NET
#define CONFIG_CMD_NET
#undef CONFIG_CMD_NFS
#undef CONFIG_CMD_SOURCE
#undef CONFIG_CMD_XIMG
......@@ -274,8 +308,8 @@
"addip=setenv bootargs ${bootargs} " \
"ip=${ipaddr}:${serverip}:${gatewayip}:" \
"${netmask}:${hostname}:eth0:off\0" \
"ethaddr=C0:B1:3C:88:88:88\0" \
"ipaddr=172.17.4.206\0" \
"ethaddr=C0:B1:3C:77:88:99\0" \
"ipaddr=172.17.6.35\0" \
"serverip=172.17.0.1\0" \
"image=k60/uImage\0" \
"netboot=tftp ${image};run addip;bootm\0"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment