From ea08eeccae9297f7aabd2ef7f0c2517ac4549acc Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 20 Feb 2024 01:18:26 +0000
Subject: [PATCH] write in 30M
---
kernel/drivers/clk/clk-fractional-divider.c | 50 +++++++++++++++++++++++++++++++++++---------------
1 files changed, 35 insertions(+), 15 deletions(-)
diff --git a/kernel/drivers/clk/clk-fractional-divider.c b/kernel/drivers/clk/clk-fractional-divider.c
index bf62cb1..2d7fdf1 100644
--- a/kernel/drivers/clk/clk-fractional-divider.c
+++ b/kernel/drivers/clk/clk-fractional-divider.c
@@ -1,9 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2014 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*
* Adjustable fractional divider clock implementation.
* Output rate = (m / n) * parent_rate.
@@ -11,10 +8,27 @@
*/
#include <linux/clk-provider.h>
+#include <linux/io.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/rational.h>
+
+static inline u32 clk_fd_readl(struct clk_fractional_divider *fd)
+{
+ if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
+ return ioread32be(fd->reg);
+
+ return readl(fd->reg);
+}
+
+static inline void clk_fd_writel(struct clk_fractional_divider *fd, u32 val)
+{
+ if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
+ iowrite32be(val, fd->reg);
+ else
+ writel(val, fd->reg);
+}
static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
@@ -30,7 +44,7 @@
else
__acquire(fd->lock);
- val = clk_readl(fd->reg);
+ val = clk_fd_readl(fd);
if (fd->lock)
spin_unlock_irqrestore(fd->lock, flags);
@@ -39,6 +53,11 @@
m = (val & fd->mmask) >> fd->mshift;
n = (val & fd->nmask) >> fd->nshift;
+
+ if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
+ m++;
+ n++;
+ }
if (!n || !m)
return parent_rate;
@@ -77,16 +96,13 @@
unsigned long m, n;
u64 ret;
- if (!rate)
+ if (!rate && rate >= *parent_rate)
return *parent_rate;
- if (fd->approximation) {
+ if (fd->approximation)
fd->approximation(hw, rate, parent_rate, &m, &n);
- } else {
- if (rate >= *parent_rate)
- return *parent_rate;
+ else
clk_fd_general_approximation(hw, rate, parent_rate, &m, &n);
- }
ret = (u64)*parent_rate * m;
do_div(ret, n);
@@ -106,6 +122,10 @@
GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
&m, &n);
+ if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
+ m--;
+ n--;
+ }
/*
* When compensation the fractional divider,
* the [1:0] bits of the numerator register are omitted,
@@ -138,10 +158,10 @@
else
__acquire(fd->lock);
- val = clk_readl(fd->reg);
+ val = clk_fd_readl(fd);
val &= ~(fd->mmask | fd->nmask);
val |= (m << fd->mshift) | (n << fd->nshift);
- clk_writel(val, fd->reg);
+ clk_fd_writel(fd, val);
if (fd->lock)
spin_unlock_irqrestore(fd->lock, flags);
@@ -164,7 +184,7 @@
u8 clk_divider_flags, spinlock_t *lock)
{
struct clk_fractional_divider *fd;
- struct clk_init_data init = {};
+ struct clk_init_data init;
struct clk_hw *hw;
int ret;
@@ -174,7 +194,7 @@
init.name = name;
init.ops = &clk_fractional_divider_ops;
- init.flags = flags | CLK_IS_BASIC;
+ init.flags = flags;
init.parent_names = parent_name ? &parent_name : NULL;
init.num_parents = parent_name ? 1 : 0;
--
Gitblit v1.6.2