summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Horman <horms+renesas@verge.net.au>2015-11-20 19:29:39 (GMT)
committerDavid S. Miller <davem@davemloft.net>2015-11-20 19:52:37 (GMT)
commitb3d39a8805c5109dde960204806cf540e3be12fa (patch)
treeb52caf6ca83bbec15847e69cc97c3736cd822872
parent1777ddb84a543444d44594d437b0f3d3f8734f32 (diff)
downloadlinux-b3d39a8805c5109dde960204806cf540e3be12fa.tar.xz
ravb: use clock rate as basis for GTI.TIV
The GTI.TIV may be set to 2GHz^2 / rate, where rate is that of the clock of the device. Rather than assuming a rate of 130MHz use the actual rate of the clock. The motivation for this is to use the correct rate on the r8a7795/Salvator-X which is advertised as 133MHz but may differ depending on the extal present on the Salvator-X. Signed-off-by: Simon Horman <horms+renesas@verge.net.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/renesas/ravb.h3
-rw-r--r--drivers/net/ethernet/renesas/ravb_main.c38
2 files changed, 40 insertions, 1 deletions
diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 0623fff9..f9dee74 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -576,6 +576,9 @@ enum GTI_BIT {
GTI_TIV = 0x0FFFFFFF,
};
+#define GTI_TIV_MAX GTI_TIV
+#define GTI_TIV_MIN 0x20
+
/* GIC */
enum GIC_BIT {
GIC_PTCE = 0x00000001, /* Undocumented? */
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index ee8d1ec..990dc55 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -32,6 +32,8 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include <asm/div64.h>
+
#include "ravb.h"
#define RAVB_DEF_MSG_ENABLE \
@@ -1659,6 +1661,38 @@ static const struct of_device_id ravb_match_table[] = {
};
MODULE_DEVICE_TABLE(of, ravb_match_table);
+static int ravb_set_gti(struct net_device *ndev)
+{
+
+ struct device *dev = ndev->dev.parent;
+ struct device_node *np = dev->of_node;
+ unsigned long rate;
+ struct clk *clk;
+ uint64_t inc;
+
+ clk = of_clk_get(np, 0);
+ if (IS_ERR(clk)) {
+ dev_err(dev, "could not get clock\n");
+ return PTR_ERR(clk);
+ }
+
+ rate = clk_get_rate(clk);
+ clk_put(clk);
+
+ inc = 1000000000ULL << 20;
+ do_div(inc, rate);
+
+ if (inc < GTI_TIV_MIN || inc > GTI_TIV_MAX) {
+ dev_err(dev, "gti.tiv increment 0x%llx is outside the range 0x%x - 0x%x\n",
+ inc, GTI_TIV_MIN, GTI_TIV_MAX);
+ return -EINVAL;
+ }
+
+ ravb_write(ndev, inc, GTI);
+
+ return 0;
+}
+
static int ravb_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -1755,7 +1789,9 @@ static int ravb_probe(struct platform_device *pdev)
CCC);
/* Set GTI value */
- ravb_write(ndev, ((1000 << 20) / 130) & GTI_TIV, GTI);
+ error = ravb_set_gti(ndev);
+ if (error)
+ goto out_release;
/* Request GTI loading */
ravb_write(ndev, ravb_read(ndev, GCCR) | GCCR_LTI, GCCR);