Commit dc917ea7 authored by Ladislav Michl's avatar Ladislav Michl Committed by Thomas Bogendoerfer

MIPS: OCTEON: octeon-usb: cleanup divider calculation

Simple self-contained function is easier to review.
Signed-off-by: default avatarLadislav Michl <ladis@linux-mips.org>
Signed-off-by: default avatarThomas Bogendoerfer <tsbogend@alpha.franken.de>
parent 2257c6c9
...@@ -187,12 +187,7 @@ ...@@ -187,12 +187,7 @@
#define USBDRD_UCTL_ECC 0xf0 #define USBDRD_UCTL_ECC 0xf0
#define USBDRD_UCTL_SPARE1 0xf8 #define USBDRD_UCTL_SPARE1 0xf8
#define OCTEON_H_CLKDIV_SEL 8
#define OCTEON_MIN_H_CLK_RATE 150000000
#define OCTEON_MAX_H_CLK_RATE 300000000
static DEFINE_MUTEX(dwc3_octeon_clocks_mutex); static DEFINE_MUTEX(dwc3_octeon_clocks_mutex);
static uint8_t clk_div[OCTEON_H_CLKDIV_SEL] = {1, 2, 4, 6, 8, 16, 24, 32};
#ifdef CONFIG_CAVIUM_OCTEON_SOC #ifdef CONFIG_CAVIUM_OCTEON_SOC
#include <asm/octeon/octeon.h> #include <asm/octeon/octeon.h>
...@@ -240,6 +235,21 @@ static inline void dwc3_octeon_writeq(void __iomem *base, uint64_t val) { } ...@@ -240,6 +235,21 @@ static inline void dwc3_octeon_writeq(void __iomem *base, uint64_t val) { }
static inline void dwc3_octeon_config_gpio(int index, int gpio) { } static inline void dwc3_octeon_config_gpio(int index, int gpio) { }
#endif #endif
static int dwc3_octeon_get_divider(void)
{
static const uint8_t clk_div[] = { 1, 2, 4, 6, 8, 16, 24, 32 };
int div = 0;
while (div < ARRAY_SIZE(clk_div)) {
uint64_t rate = octeon_get_io_clock_rate() / clk_div[div];
if (rate <= 300000000 && rate >= 150000000)
break;
div++;
}
return div;
}
static int dwc3_octeon_config_power(struct device *dev, void __iomem *base) static int dwc3_octeon_config_power(struct device *dev, void __iomem *base)
{ {
uint32_t gpio_pwr[3]; uint32_t gpio_pwr[3];
...@@ -284,9 +294,9 @@ static int dwc3_octeon_config_power(struct device *dev, void __iomem *base) ...@@ -284,9 +294,9 @@ static int dwc3_octeon_config_power(struct device *dev, void __iomem *base)
static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base) static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base)
{ {
int i, mpll_mul, ref_clk_fsel, ref_clk_sel = 2; int i, div, mpll_mul, ref_clk_fsel, ref_clk_sel = 2;
u32 clock_rate; u32 clock_rate;
u64 div, h_clk_rate, val; u64 val;
void __iomem *uctl_ctl_reg = base + USBDRD_UCTL_CTL; void __iomem *uctl_ctl_reg = base + USBDRD_UCTL_CTL;
if (dev->of_node) { if (dev->of_node) {
...@@ -363,12 +373,7 @@ static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base) ...@@ -363,12 +373,7 @@ static int dwc3_octeon_clocks_start(struct device *dev, void __iomem *base)
dwc3_octeon_writeq(uctl_ctl_reg, val); dwc3_octeon_writeq(uctl_ctl_reg, val);
/* Step 4b: Select controller clock frequency. */ /* Step 4b: Select controller clock frequency. */
for (div = 0; div < OCTEON_H_CLKDIV_SEL; div++) { div = dwc3_octeon_get_divider();
h_clk_rate = octeon_get_io_clock_rate() / clk_div[div];
if (h_clk_rate <= OCTEON_MAX_H_CLK_RATE &&
h_clk_rate >= OCTEON_MIN_H_CLK_RATE)
break;
}
val = dwc3_octeon_readq(uctl_ctl_reg); val = dwc3_octeon_readq(uctl_ctl_reg);
val &= ~USBDRD_UCTL_CTL_H_CLKDIV_SEL; val &= ~USBDRD_UCTL_CTL_H_CLKDIV_SEL;
val |= FIELD_PREP(USBDRD_UCTL_CTL_H_CLKDIV_SEL, div); val |= FIELD_PREP(USBDRD_UCTL_CTL_H_CLKDIV_SEL, div);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment