mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
ipq807x : Enabling MDIO C45 and Uniphy3 support
Change-Id: I9236aa2861a004a030e7e88403302d5e09949ad7 Signed-off-by: Ramesh Muthusamy <rmuthusa@codeaurora.org>
This commit is contained in:
parent
9dc890a648
commit
0afdc8209b
5 changed files with 148 additions and 28 deletions
52
drivers/net/ipq807x/ipq807x_uniphy.c
Normal file
52
drivers/net/ipq807x/ipq807x_uniphy.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 <common.h>
|
||||
#include <net.h>
|
||||
#include <asm-generic/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <malloc.h>
|
||||
#include <phy.h>
|
||||
#include <net.h>
|
||||
#include <miiphy.h>
|
||||
#include <asm/arch-ipq807x/edma_regs.h>
|
||||
#include "ipq807x_edma.h"
|
||||
|
||||
extern int ipq_mdio_write(int mii_id,
|
||||
int regnum, u16 value);
|
||||
extern int ipq_mdio_read(int mii_id,
|
||||
int regnum, ushort *data);
|
||||
|
||||
void csr1_write(int phy_id, int addr, int value)
|
||||
{
|
||||
int addr_h, addr_l, ahb_h, ahb_l, phy;
|
||||
phy=phy_id<<(0x10);
|
||||
addr_h=(addr&0xffffff)>>8;
|
||||
addr_l=((addr&0xff)<<2)|(0x20<<(0xa));
|
||||
ahb_l=(addr_l&0xffff)|(0x7A00000|phy);
|
||||
ahb_h=(0x7A083FC|phy);
|
||||
writel(addr_h,ahb_h);
|
||||
writel(value,ahb_l);
|
||||
}
|
||||
|
||||
int csr1_read(int phy_id, int addr )
|
||||
{
|
||||
int addr_h ,addr_l,ahb_h, ahb_l, phy;
|
||||
phy=phy_id<<(0x10);
|
||||
addr_h=(addr&0xffffff)>>8;
|
||||
addr_l=((addr&0xff)<<2)|(0x20<<(0xa));
|
||||
ahb_l=(addr_l&0xffff)|(0x7A00000|phy);
|
||||
ahb_h=(0x7A083FC|phy);
|
||||
writel(addr_h, ahb_h);
|
||||
return readl(ahb_l);
|
||||
}
|
||||
|
|
@ -44,20 +44,50 @@ static int ipq_mdio_wait_busy(void)
|
|||
|
||||
int ipq_mdio_write(int mii_id, int regnum, u16 value)
|
||||
{
|
||||
u32 cmd;
|
||||
if (ipq_mdio_wait_busy())
|
||||
return -ETIMEDOUT;
|
||||
/* Issue the phy addreass and reg */
|
||||
writel((mii_id << 8 | regnum),
|
||||
IPQ_MDIO_BASE + MDIO_CTRL_1_REG);
|
||||
|
||||
|
||||
if (regnum & MII_ADDR_C45) {
|
||||
unsigned int mmd = (regnum >> 16) & 0x1F;
|
||||
unsigned int reg = regnum & 0xFFFF;
|
||||
|
||||
writel(CTRL_0_REG_C45_DEFAULT_VALUE,
|
||||
IPQ_MDIO_BASE + MDIO_CTRL_0_REG);
|
||||
|
||||
/* Issue the phy address and reg */
|
||||
writel((mii_id << 8) | mmd,
|
||||
IPQ_MDIO_BASE + MDIO_CTRL_1_REG);
|
||||
|
||||
writel(reg, IPQ_MDIO_BASE + MDIO_CTRL_2_REG);
|
||||
|
||||
/* issue read command */
|
||||
cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_ADDR;
|
||||
|
||||
writel(cmd, IPQ_MDIO_BASE + MDIO_CTRL_4_REG);
|
||||
|
||||
if (ipq_mdio_wait_busy())
|
||||
return -ETIMEDOUT;
|
||||
} else {
|
||||
writel(CTRL_0_REG_DEFAULT_VALUE,
|
||||
IPQ_MDIO_BASE + MDIO_CTRL_0_REG);
|
||||
|
||||
/* Issue the phy addreass and reg */
|
||||
writel((mii_id << 8 | regnum),
|
||||
IPQ_MDIO_BASE + MDIO_CTRL_1_REG);
|
||||
}
|
||||
|
||||
/* Issue a write data */
|
||||
writel(value, IPQ_MDIO_BASE + MDIO_CTRL_2_REG);
|
||||
|
||||
/* Issue write command */
|
||||
writel((MDIO_CTRL_4_ACCESS_START |
|
||||
MDIO_CTRL_4_ACCESS_CODE_WRITE),
|
||||
(IPQ_MDIO_BASE + MDIO_CTRL_4_REG));
|
||||
if (regnum & MII_ADDR_C45) {
|
||||
cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_WRITE ;
|
||||
} else {
|
||||
cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_WRITE ;
|
||||
}
|
||||
|
||||
writel(cmd, IPQ_MDIO_BASE + MDIO_CTRL_4_REG);
|
||||
/* Wait for write complete */
|
||||
|
||||
if (ipq_mdio_wait_busy())
|
||||
|
|
@ -68,22 +98,55 @@ int ipq_mdio_write(int mii_id, int regnum, u16 value)
|
|||
|
||||
int ipq_mdio_read(int mii_id, int regnum, ushort *data)
|
||||
{
|
||||
u32 val;
|
||||
u32 val,cmd;
|
||||
if (ipq_mdio_wait_busy())
|
||||
return -ETIMEDOUT;
|
||||
|
||||
/* Issue the phy address and reg */
|
||||
writel((mii_id << 8) | regnum,
|
||||
IPQ_MDIO_BASE + MDIO_CTRL_1_REG);
|
||||
if (regnum & MII_ADDR_C45) {
|
||||
|
||||
unsigned int mmd = (regnum >> 16) & 0x1F;
|
||||
unsigned int reg = regnum & 0xFFFF;
|
||||
|
||||
writel(CTRL_0_REG_C45_DEFAULT_VALUE,
|
||||
IPQ_MDIO_BASE + MDIO_CTRL_0_REG);
|
||||
|
||||
/* Issue the phy address and reg */
|
||||
writel((mii_id << 8) | mmd,
|
||||
IPQ_MDIO_BASE + MDIO_CTRL_1_REG);
|
||||
|
||||
|
||||
writel(reg, IPQ_MDIO_BASE + MDIO_CTRL_2_REG);
|
||||
|
||||
/* issue read command */
|
||||
cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_ADDR;
|
||||
} else {
|
||||
|
||||
writel(CTRL_0_REG_DEFAULT_VALUE,
|
||||
IPQ_MDIO_BASE + MDIO_CTRL_0_REG);
|
||||
|
||||
/* Issue the phy address and reg */
|
||||
writel((mii_id << 8 | regnum ) ,
|
||||
IPQ_MDIO_BASE + MDIO_CTRL_1_REG);
|
||||
|
||||
/* issue read command */
|
||||
cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_READ ;
|
||||
}
|
||||
|
||||
/* issue read command */
|
||||
writel((MDIO_CTRL_4_ACCESS_START |
|
||||
MDIO_CTRL_4_ACCESS_CODE_READ),
|
||||
(IPQ_MDIO_BASE + MDIO_CTRL_4_REG));
|
||||
writel(cmd, IPQ_MDIO_BASE + MDIO_CTRL_4_REG);
|
||||
|
||||
if (ipq_mdio_wait_busy())
|
||||
return -ETIMEDOUT;
|
||||
|
||||
|
||||
if (regnum & MII_ADDR_C45) {
|
||||
cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_READ;
|
||||
writel(cmd, IPQ_MDIO_BASE + MDIO_CTRL_4_REG);
|
||||
|
||||
if (ipq_mdio_wait_busy())
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Read data */
|
||||
val = readl(IPQ_MDIO_BASE + MDIO_CTRL_3_REG);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,17 +13,22 @@
|
|||
#ifndef _IPQ_MDIO_H
|
||||
#define _IPQ_MDIO_H
|
||||
|
||||
#define IPQ_MDIO_BASE 0x90000
|
||||
#define MDIO_CTRL_0_REG 0x40
|
||||
#define MDIO_CTRL_1_REG 0x44
|
||||
#define MDIO_CTRL_2_REG 0x48
|
||||
#define MDIO_CTRL_3_REG 0x4c
|
||||
#define MDIO_CTRL_4_REG 0x50
|
||||
#define MDIO_CTRL_4_ACCESS_BUSY (1 << 16)
|
||||
#define MDIO_CTRL_4_ACCESS_START (1 << 8)
|
||||
#define MDIO_CTRL_4_ACCESS_CODE_READ 0
|
||||
#define MDIO_CTRL_4_ACCESS_CODE_WRITE 1
|
||||
#define IPQ_MDIO_BASE 0x90000
|
||||
#define MDIO_CTRL_0_REG 0x40
|
||||
#define MDIO_CTRL_1_REG 0x44
|
||||
#define MDIO_CTRL_2_REG 0x48
|
||||
#define MDIO_CTRL_3_REG 0x4c
|
||||
#define MDIO_CTRL_4_REG 0x50
|
||||
#define MDIO_CTRL_4_ACCESS_BUSY (1 << 16)
|
||||
#define MDIO_CTRL_4_ACCESS_START (1 << 8)
|
||||
#define MDIO_CTRL_4_ACCESS_CODE_READ 0
|
||||
#define MDIO_CTRL_4_ACCESS_CODE_WRITE 1
|
||||
#define MDIO_CTRL_4_ACCESS_CODE_C45_ADDR 0
|
||||
#define MDIO_CTRL_4_ACCESS_CODE_C45_WRITE 1
|
||||
#define MDIO_CTRL_4_ACCESS_CODE_C45_READ 2
|
||||
#define CTRL_0_REG_DEFAULT_VALUE 0x1500F
|
||||
#define CTRL_0_REG_C45_DEFAULT_VALUE 0x1510F
|
||||
|
||||
#define IPQ_MDIO_RETRY 1000
|
||||
#define IPQ_MDIO_DELAY 5
|
||||
#define IPQ_MDIO_RETRY 1000
|
||||
#define IPQ_MDIO_DELAY 5
|
||||
#endif /* End _IPQ_MDIO_H */
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#include <common.h>
|
||||
#include <net.h>
|
||||
|
||||
#define PHY_MAX 5
|
||||
#define PHY_MAX 6
|
||||
#define MDIO_CTRL_0_REG 0x00090040
|
||||
#define MDIO_CTRL_0_DIV(x) (x << 0)
|
||||
#define MDIO_CTRL_0_MODE (1 << 8)
|
||||
|
|
|
|||
|
|
@ -270,5 +270,5 @@ int phy_get_interface_by_name(const char *str);
|
|||
/* PHY UIDs for various PHYs that are referenced in external code */
|
||||
#define PHY_UID_CS4340 0x13e51002
|
||||
#define PHY_UID_TN2020 0x00a19410
|
||||
|
||||
#define MII_ADDR_C45 (1<<30)
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue