static void bcm_sf2_gphy_enable_set(struct dsa_switch *ds, bool enable) { struct bcm_sf2_priv *priv = ds_to_priv(ds); u32 reg; reg = reg_readl(priv, REG_SPHY_CNTRL); if (enable) { reg |= PHY_RESET; reg &= ~(EXT_PWR_DOWN | IDDQ_BIAS | CK25_DIS); reg_writel(priv, reg, REG_SPHY_CNTRL); udelay(21); reg = reg_readl(priv, REG_SPHY_CNTRL); reg &= ~PHY_RESET; } else { reg |= EXT_PWR_DOWN | IDDQ_BIAS | PHY_RESET; reg_writel(priv, reg, REG_SPHY_CNTRL); mdelay(1); reg |= CK25_DIS; } reg_writel(priv, reg, REG_SPHY_CNTRL); /* Use PHY-driven LED signaling */ if (!enable) { reg = reg_readl(priv, REG_LED_CNTRL(0)); reg |= SPDLNK_SRC_SEL; reg_writel(priv, reg, REG_LED_CNTRL(0)); } }
static int bcm_sf2_sw_indir_rw(struct bcm_sf2_priv *priv, int op, int addr, int regnum, u16 val) { int ret = 0; u32 reg; reg = reg_readl(priv, REG_SWITCH_CNTRL); reg |= MDIO_MASTER_SEL; reg_writel(priv, reg, REG_SWITCH_CNTRL); /* Page << 8 | offset */ reg = 0x70; reg <<= 2; core_writel(priv, addr, reg); /* Page << 8 | offset */ reg = 0x80 << 8 | regnum << 1; reg <<= 2; if (op) ret = core_readl(priv, reg); else core_writel(priv, val, reg); reg = reg_readl(priv, REG_SWITCH_CNTRL); reg &= ~MDIO_MASTER_SEL; reg_writel(priv, reg, REG_SWITCH_CNTRL); return ret & 0xffff; }
static int bcm_sf2_sw_resume(struct dsa_switch *ds) { struct bcm_sf2_priv *priv = ds_to_priv(ds); unsigned int port; u32 reg; int ret; ret = bcm_sf2_sw_rst(priv); if (ret) { pr_err("%s: failed to software reset switch\n", __func__); return ret; } /* Reinitialize the single GPHY */ if (priv->hw_params.num_gphy == 1) { reg = reg_readl(priv, REG_SPHY_CNTRL); reg |= PHY_RESET; reg &= ~(EXT_PWR_DOWN | IDDQ_BIAS); reg_writel(priv, reg, REG_SPHY_CNTRL); udelay(21); reg = reg_readl(priv, REG_SPHY_CNTRL); reg &= ~PHY_RESET; reg_writel(priv, reg, REG_SPHY_CNTRL); } for (port = 0; port < DSA_MAX_PORTS; port++) { if ((1 << port) & ds->phys_port_mask) bcm_sf2_port_setup(ds, port, NULL); else if (dsa_is_cpu_port(ds, port)) bcm_sf2_imp_setup(ds, port); } return 0; }
static int __init sprd_dma_init(void) { int ret; /* enable DMAC */ sci_glb_set(REG_AHB_AHB_CTL0, BIT_DMA_EB); /* reset the DMAC */ __raw_writel(0, DMA_CHx_EN); __raw_writel(0, DMA_LINKLIST_EN); __raw_writel(0, DMA_SOFT_REQ); __raw_writel(0, DMA_PRI_REG0); __raw_writel(0, DMA_PRI_REG1); __raw_writel(0xffffffff, DMA_LISTDONE_INT_CLR); __raw_writel(0xffffffff, DMA_TRANSF_INT_CLR); __raw_writel(0xffffffff, DMA_BURST_INT_CLR); __raw_writel(0, DMA_LISTDONE_INT_EN); __raw_writel(0, DMA_TRANSF_INT_EN); __raw_writel(0, DMA_BURST_INT_EN); /*set hard/soft burst wait time*/ reg_writel(DMA_CFG, 0, DMA_HARD_WAITTIME, 0xff); reg_writel(DMA_CFG,16, DMA_SOFT_WAITTIME, 0xffff); /*register dma irq handle*/ ret = request_irq(IRQ_DMA_INT, sprd_dma_irq, 0, "sprd-dma", NULL); if (ret == 0) { printk(KERN_INFO "request dma irq ok\n"); } else { printk(KERN_ERR "request dma irq failed %d\n", ret); goto request_irq_err; } return ret; request_irq_err: /* disable DMAC */ sci_glb_clr(REG_AHB_AHB_CTL0, BIT_DMA_EB); return ret; }
static void bcm_sf2_sw_mac_link_set(struct dsa_switch *ds, int port, phy_interface_t interface, bool link) { struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); u32 reg; if (!phy_interface_mode_is_rgmii(interface) && interface != PHY_INTERFACE_MODE_MII && interface != PHY_INTERFACE_MODE_REVMII) return; /* If the link is down, just disable the interface to conserve power */ reg = reg_readl(priv, REG_RGMII_CNTRL_P(port)); if (link) reg |= RGMII_MODE_EN; else reg &= ~RGMII_MODE_EN; reg_writel(priv, reg, REG_RGMII_CNTRL_P(port)); }
static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port, struct phy_device *phydev) { struct bcm_sf2_priv *priv = ds_to_priv(ds); u32 id_mode_dis = 0, port_mode; const char *str = NULL; u32 reg; switch (phydev->interface) { case PHY_INTERFACE_MODE_RGMII: str = "RGMII (no delay)"; id_mode_dis = 1; case PHY_INTERFACE_MODE_RGMII_TXID: if (!str) str = "RGMII (TX delay)"; port_mode = EXT_GPHY; break; case PHY_INTERFACE_MODE_MII: str = "MII"; port_mode = EXT_EPHY; break; case PHY_INTERFACE_MODE_REVMII: str = "Reverse MII"; port_mode = EXT_REVMII; break; default: /* All other PHYs: internal and MoCA */ goto force_link; } /* If the link is down, just disable the interface to conserve power */ if (!phydev->link) { reg = reg_readl(priv, REG_RGMII_CNTRL_P(port)); reg &= ~RGMII_MODE_EN; reg_writel(priv, reg, REG_RGMII_CNTRL_P(port)); goto force_link; } /* Clear id_mode_dis bit, and the existing port mode, but * make sure we enable the RGMII block for data to pass */ reg = reg_readl(priv, REG_RGMII_CNTRL_P(port)); reg &= ~ID_MODE_DIS; reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT); reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN); reg |= port_mode | RGMII_MODE_EN; if (id_mode_dis) reg |= ID_MODE_DIS; if (phydev->pause) { if (phydev->asym_pause) reg |= TX_PAUSE_EN; reg |= RX_PAUSE_EN; } reg_writel(priv, reg, REG_RGMII_CNTRL_P(port)); pr_info("Port %d configured for %s\n", port, str); force_link: /* Force link settings detected from the PHY */ reg = SW_OVERRIDE; switch (phydev->speed) { case SPEED_1000: reg |= SPDSTS_1000 << SPEED_SHIFT; break; case SPEED_100: reg |= SPDSTS_100 << SPEED_SHIFT; break; } if (phydev->link) reg |= LINK_STS; if (phydev->duplex == DUPLEX_FULL) reg |= DUPLX_MODE; core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port)); }
static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port, unsigned int mode, const struct phylink_link_state *state) { struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); u32 id_mode_dis = 0, port_mode; u32 reg, offset; if (priv->type == BCM7445_DEVICE_ID) offset = CORE_STS_OVERRIDE_GMIIP_PORT(port); else offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port); switch (state->interface) { case PHY_INTERFACE_MODE_RGMII: id_mode_dis = 1; /* fallthrough */ case PHY_INTERFACE_MODE_RGMII_TXID: port_mode = EXT_GPHY; break; case PHY_INTERFACE_MODE_MII: port_mode = EXT_EPHY; break; case PHY_INTERFACE_MODE_REVMII: port_mode = EXT_REVMII; break; default: /* all other PHYs: internal and MoCA */ goto force_link; } /* Clear id_mode_dis bit, and the existing port mode, let * RGMII_MODE_EN bet set by mac_link_{up,down} */ reg = reg_readl(priv, REG_RGMII_CNTRL_P(port)); reg &= ~ID_MODE_DIS; reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT); reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN); reg |= port_mode; if (id_mode_dis) reg |= ID_MODE_DIS; if (state->pause & MLO_PAUSE_TXRX_MASK) { if (state->pause & MLO_PAUSE_TX) reg |= TX_PAUSE_EN; reg |= RX_PAUSE_EN; } reg_writel(priv, reg, REG_RGMII_CNTRL_P(port)); force_link: /* Force link settings detected from the PHY */ reg = SW_OVERRIDE; switch (state->speed) { case SPEED_1000: reg |= SPDSTS_1000 << SPEED_SHIFT; break; case SPEED_100: reg |= SPDSTS_100 << SPEED_SHIFT; break; } if (state->link) reg |= LINK_STS; if (state->duplex == DUPLEX_FULL) reg |= DUPLX_MODE; core_writel(priv, reg, offset); }