ipq807x : Enabling MDIO C45 and Uniphy3 support

Change-Id: I9236aa2861a004a030e7e88403302d5e09949ad7
Signed-off-by: Ramesh Muthusamy <rmuthusa@codeaurora.org>
This commit is contained in:
Ramesh Muthusamy 2017-08-21 18:11:38 +05:30
parent 9dc890a648
commit 0afdc8209b
5 changed files with 148 additions and 28 deletions

View 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);
}

View file

@ -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);

View file

@ -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 */

View file

@ -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)

View file

@ -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