summaryrefslogtreecommitdiffstats
path: root/lib/benchmark.rb
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-02-08 10:22:15 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-02-08 10:22:15 +0000
commit3f8155ba7e3edf8bf49597e2ce1b6d7526a701f6 (patch)
tree70ef6b76456edcf29f093137da1a70258b4902b6 /lib/benchmark.rb
parentb14849b101a1f43e4c93bc69c4d6b31c779c5dc2 (diff)
* ext/iconv/iconv.c (rb_str_derive): uses rb_str_subseq() for byte
length. [ruby-dev:33653] git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@15405 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/benchmark.rb')
0 files changed, 0 insertions, 0 deletions
8' href='#n108'>108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
/*
 * Xilinx xps_ll_temac ethernet driver for u-boot
 *
 * MDIO bus access
 *
 * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
 * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
 * Copyright (C) 2008 - 2011 PetaLogix
 *
 * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
 * Copyright (C) 2008 Nissin Systems Co.,Ltd.
 * March 2008 created
 *
 * CREDITS: tsec driver
 *
 * SPDX-License-Identifier:	GPL-2.0+
 *
 * [0]: http://www.xilinx.com/support/documentation
 *
 * [S]:	[0]/ip_documentation/xps_ll_temac.pdf
 * [A]:	[0]/application_notes/xapp1041.pdf
 */

#include <config.h>
#include <common.h>
#include <miiphy.h>
#include <phy.h>
#include <malloc.h>
#include <asm/io.h>

#include "xilinx_ll_temac.h"
#include "xilinx_ll_temac_mdio.h"

#if !defined(CONFIG_MII)
# error "LL_TEMAC requires MII -- missing CONFIG_MII"
#endif

#if !defined(CONFIG_PHYLIB)
# error "LL_TEMAC requires PHYLIB -- missing CONFIG_PHYLIB"
#endif

/*
 * Prior to PHY access, the MDIO clock must be setup. This driver will set a
 * safe default that should work with PLB bus speeds of up to 150 MHz and keep
 * the MDIO clock below 2.5 MHz. If the user wishes faster access to the PHY
 * then the clock divisor can be set to a different value by setting the
 * correct bus speed value with CONFIG_XILINX_LL_TEMAC_CLK.
 */
#if !defined(CONFIG_XILINX_LL_TEMAC_CLK)
#define MDIO_CLOCK_DIV		MC_CLKDIV_10(150000000)
#else
#define MDIO_CLOCK_DIV		MC_CLKDIV_25(CONFIG_XILINX_LL_TEMAC_CLK)
#endif

static int ll_temac_mdio_setup(struct mii_dev *bus)
{
	struct temac_reg *regs = (struct temac_reg *)bus->priv;

	/* setup MDIO clock */
	ll_temac_indirect_set(regs, TEMAC_MC,
			MC_MDIOEN | (MDIO_CLOCK_DIV & MC_CLKDIV_MASK));

	return 0;
}

/*
 * Indirect MII PHY read via ll_temac.
 *
 * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf
 * page 67, Using the MII Management to Access PHY Registers
 */
int ll_temac_local_mdio_read(struct temac_reg *regs, int addr, int devad,
				int regnum)
{
	out_be32(&regs->lsw,
		((addr << LSW_PHYAD_POS) & LSW_PHYAD_MASK) |
		(regnum & LSW_REGAD_MASK));
	out_be32(&regs->ctl, TEMAC_MIIMAI);

	ll_temac_check_status(regs, RSE_MIIM_RR);

	return in_be32(&regs->lsw) & LSW_REGDAT_MASK;
}

/*
 * Indirect MII PHY write via ll_temac.
 *
 * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf
 * page 67, Using the MII Management to Access PHY Registers
 */
void ll_temac_local_mdio_write(struct temac_reg *regs, int addr, int devad,
				int regnum, u16 value)
{
	out_be32(&regs->lsw, (value & LSW_REGDAT_MASK));
	out_be32(&regs->ctl, CTL_WEN | TEMAC_MIIMWD);

	out_be32(&regs->lsw,
		((addr << LSW_PHYAD_POS) & LSW_PHYAD_MASK) |
		(regnum & LSW_REGAD_MASK));
	out_be32(&regs->ctl, CTL_WEN | TEMAC_MIIMAI);

	ll_temac_check_status(regs, RSE_MIIM_WR);
}

int ll_temac_phy_read(struct mii_dev *bus, int addr, int devad, int regnum)
{
	struct temac_reg *regs = (struct temac_reg *)bus->priv;

	return ll_temac_local_mdio_read(regs, addr, devad, regnum);
}

int ll_temac_phy_write(struct mii_dev *bus, int addr, int devad, int regnum,
			u16 value)
{
	struct temac_reg *regs = (struct temac_reg *)bus->priv;

	ll_temac_local_mdio_write(regs, addr, devad, regnum, value);

	return 0;
}

/*
 * Use MII register 1 (MII status register) to detect PHY
 *
 * A Mask used to verify certain PHY features (register content)
 * in the PHY detection register:
 *  Auto-negotiation support, 10Mbps half/full duplex support
 */
#define PHY_DETECT_REG		MII_BMSR
#define PHY_DETECT_MASK		(BMSR_10FULL | BMSR_10HALF | BMSR_ANEGCAPABLE)

/* Looking for a valid PHY address */
int ll_temac_phy_addr(struct mii_dev *bus)
{
	struct temac_reg *regs = (struct temac_reg *)bus->priv;
	unsigned short val;
	unsigned int phy;

	for (phy = PHY_MAX_ADDR; phy >= 0; phy--) {
		val = ll_temac_local_mdio_read(regs, phy, 0, PHY_DETECT_REG);
		if ((val != 0xFFFF) &&
		((val & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
			/* Found a valid PHY address */
			return phy;
		}
	}

	return -1;
}

int xilinx_ll_temac_mdio_initialize(bd_t *bis, struct ll_temac_mdio_info *info)
{
	struct mii_dev *bus = mdio_alloc();

	if (!bus) {
		printf("Failed to allocate LL_TEMAC MDIO bus: %s\n",
				info->name);
		return -1;
	}

	bus->read = ll_temac_phy_read;
	bus->write = ll_temac_phy_write;
	bus->reset = NULL;

	/* use given name or generate its own unique name */
	if (info->name) {
		strncpy(bus->name, info->name, MDIO_NAME_LEN);
	} else {
		snprintf(bus->name, MDIO_NAME_LEN, "lltemii.%p", info->regs);
		info->name = bus->name;
	}

	bus->priv = info->regs;

	ll_temac_mdio_setup(bus);
	return mdio_register(bus);
}