Home | History | Annotate | Download | only in fm
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright 2009-2011 Freescale Semiconductor, Inc.
      4  */
      5 
      6 #include <common.h>
      7 #include <asm/types.h>
      8 #include <asm/io.h>
      9 #include <fsl_dtsec.h>
     10 #include <fsl_mdio.h>
     11 #include <phy.h>
     12 
     13 #include "fm.h"
     14 
     15 #define RCTRL_INIT	(RCTRL_GRS | RCTRL_UPROM)
     16 #define TCTRL_INIT	TCTRL_GTS
     17 #define MACCFG1_INIT	MACCFG1_SOFT_RST
     18 
     19 #define MACCFG2_INIT	(MACCFG2_PRE_LEN(0x7) | MACCFG2_LEN_CHECK | \
     20 			 MACCFG2_PAD_CRC | MACCFG2_FULL_DUPLEX | \
     21 			 MACCFG2_IF_MODE_NIBBLE)
     22 
     23 /* MAXFRM - maximum frame length register */
     24 #define MAXFRM_MASK		0x00003fff
     25 
     26 static void dtsec_init_mac(struct fsl_enet_mac *mac)
     27 {
     28 	struct dtsec *regs = mac->base;
     29 
     30 	/* soft reset */
     31 	out_be32(&regs->maccfg1, MACCFG1_SOFT_RST);
     32 	udelay(1000);
     33 
     34 	/* clear soft reset, Rx/Tx MAC disable */
     35 	out_be32(&regs->maccfg1, 0);
     36 
     37 	/* graceful stop rx */
     38 	out_be32(&regs->rctrl, RCTRL_INIT);
     39 	udelay(1000);
     40 
     41 	/* graceful stop tx */
     42 	out_be32(&regs->tctrl, TCTRL_INIT);
     43 	udelay(1000);
     44 
     45 	/* disable all interrupts */
     46 	out_be32(&regs->imask, IMASK_MASK_ALL);
     47 
     48 	/* clear all events */
     49 	out_be32(&regs->ievent, IEVENT_CLEAR_ALL);
     50 
     51 	/* set the max Rx length */
     52 	out_be32(&regs->maxfrm, mac->max_rx_len & MAXFRM_MASK);
     53 
     54 	/* set the ecntrl to reset value */
     55 	out_be32(&regs->ecntrl, ECNTRL_DEFAULT);
     56 
     57 	/*
     58 	 * Rx length check, no strip CRC for Rx, pad and append CRC for Tx,
     59 	 * full duplex
     60 	 */
     61 	out_be32(&regs->maccfg2, MACCFG2_INIT);
     62 }
     63 
     64 static void dtsec_enable_mac(struct fsl_enet_mac *mac)
     65 {
     66 	struct dtsec *regs = mac->base;
     67 
     68 	/* enable Rx/Tx MAC */
     69 	setbits_be32(&regs->maccfg1, MACCFG1_RXTX_EN);
     70 
     71 	/* clear the graceful Rx stop */
     72 	clrbits_be32(&regs->rctrl, RCTRL_GRS);
     73 
     74 	/* clear the graceful Tx stop */
     75 	clrbits_be32(&regs->tctrl, TCTRL_GTS);
     76 }
     77 
     78 static void dtsec_disable_mac(struct fsl_enet_mac *mac)
     79 {
     80 	struct dtsec *regs = mac->base;
     81 
     82 	/* graceful Rx stop */
     83 	setbits_be32(&regs->rctrl, RCTRL_GRS);
     84 
     85 	/* graceful Tx stop */
     86 	setbits_be32(&regs->tctrl, TCTRL_GTS);
     87 
     88 	/* disable Rx/Tx MAC */
     89 	clrbits_be32(&regs->maccfg1, MACCFG1_RXTX_EN);
     90 }
     91 
     92 static void dtsec_set_mac_addr(struct fsl_enet_mac *mac, u8 *mac_addr)
     93 {
     94 	struct dtsec *regs = mac->base;
     95 	u32 mac_addr1, mac_addr2;
     96 
     97 	/*
     98 	 * if a station address of 0x12345678ABCD, perform a write to
     99 	 * MACSTNADDR1 of 0xCDAB7856, MACSTNADDR2 of 0x34120000
    100 	 */
    101 	mac_addr1 = (mac_addr[5] << 24) | (mac_addr[4] << 16) | \
    102 			(mac_addr[3] << 8)  | (mac_addr[2]);
    103 	out_be32(&regs->macstnaddr1, mac_addr1);
    104 
    105 	mac_addr2 = ((mac_addr[1] << 24) | (mac_addr[0] << 16)) & 0xffff0000;
    106 	out_be32(&regs->macstnaddr2, mac_addr2);
    107 }
    108 
    109 static void dtsec_set_interface_mode(struct fsl_enet_mac *mac,
    110 		phy_interface_t type, int speed)
    111 {
    112 	struct dtsec *regs = mac->base;
    113 	u32 ecntrl, maccfg2;
    114 
    115 	/* clear all bits relative with interface mode */
    116 	ecntrl = in_be32(&regs->ecntrl);
    117 	ecntrl &= ~(ECNTRL_TBIM | ECNTRL_GMIIM | ECNTRL_RPM |
    118 				  ECNTRL_R100M | ECNTRL_SGMIIM);
    119 
    120 	maccfg2 = in_be32(&regs->maccfg2);
    121 	maccfg2 &= ~MACCFG2_IF_MODE_MASK;
    122 
    123 	if (speed == SPEED_1000)
    124 		maccfg2 |= MACCFG2_IF_MODE_BYTE;
    125 	else
    126 		maccfg2 |= MACCFG2_IF_MODE_NIBBLE;
    127 
    128 	/* set interface mode */
    129 	switch (type) {
    130 	case PHY_INTERFACE_MODE_GMII:
    131 		ecntrl |= ECNTRL_GMIIM;
    132 		break;
    133 	case PHY_INTERFACE_MODE_RGMII:
    134 		ecntrl |= (ECNTRL_GMIIM | ECNTRL_RPM);
    135 		if (speed == SPEED_100)
    136 			ecntrl |= ECNTRL_R100M;
    137 		break;
    138 	case PHY_INTERFACE_MODE_RMII:
    139 		if (speed == SPEED_100)
    140 			ecntrl |= ECNTRL_R100M;
    141 		break;
    142 	case PHY_INTERFACE_MODE_SGMII:
    143 		ecntrl |= (ECNTRL_SGMIIM | ECNTRL_TBIM);
    144 		if (speed == SPEED_100)
    145 			ecntrl |= ECNTRL_R100M;
    146 		break;
    147 	default:
    148 		break;
    149 	}
    150 
    151 	out_be32(&regs->ecntrl, ecntrl);
    152 	out_be32(&regs->maccfg2, maccfg2);
    153 }
    154 
    155 void init_dtsec(struct fsl_enet_mac *mac, void *base,
    156 		void *phyregs, int max_rx_len)
    157 {
    158 	mac->base = base;
    159 	mac->phyregs = phyregs;
    160 	mac->max_rx_len = max_rx_len;
    161 	mac->init_mac = dtsec_init_mac;
    162 	mac->enable_mac = dtsec_enable_mac;
    163 	mac->disable_mac = dtsec_disable_mac;
    164 	mac->set_mac_addr = dtsec_set_mac_addr;
    165 	mac->set_if_mode = dtsec_set_interface_mode;
    166 }
    167