Skip to content

Commit 7e9b5f8

Browse files
author
deooi
committedMar 11, 2025·
pl35x-nand-controller: Enable dynamic clk rate setting
Bluefin devices require different clk frequencies to be set at different timing modes. Enable the memclk rate to be set according to the specifications in the device tree. If the device tree does not have this memclk-timing-frequency property specified, the driver proceeds as usual. Signed-off-by: deooi <deborah.ooi@ni.com>
1 parent 76c9aec commit 7e9b5f8

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed
 

‎arch/arm/boot/dts/xilinx/ni-zynq.dtsi

+10
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,16 @@
140140

141141
&smcc {
142142
status = "okay";
143+
/*
144+
* Bluefin devices require different memclk frequency
145+
* for different timing modes
146+
*/
147+
memclk-timing-frequency = <0 83333333>,
148+
<1 166666666>,
149+
<2 166666666>,
150+
<3 166666666>,
151+
<4 166666666>,
152+
<5 166666666>;
143153
};
144154

145155
&nfc0 {

‎drivers/mtd/nand/raw/pl35x-nand-controller.c

+38
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,25 @@ static int pl35x_nfc_exec_op(struct nand_chip *chip,
795795
op, check_only);
796796
}
797797

798+
static unsigned long of_get_memclk_freq(const struct device_node *np, const int timing_mode)
799+
{
800+
struct property *prop;
801+
const __be32 *cur;
802+
int memclk_frequency = 0;
803+
u32 memclk_mode;
804+
805+
of_property_for_each_u32(np, "memclk-timing-frequency", prop, cur, memclk_mode) {
806+
if (timing_mode != memclk_mode)
807+
continue;
808+
809+
of_property_read_u32_index(np, "memclk-timing-frequency",
810+
(cur - (__be32 *)prop->value) / sizeof(u32) + 1,
811+
&memclk_frequency);
812+
return memclk_frequency;
813+
}
814+
return 0;
815+
}
816+
798817
static int pl35x_nfc_setup_interface(struct nand_chip *chip, int cs,
799818
const struct nand_interface_config *conf)
800819
{
@@ -804,6 +823,8 @@ static int pl35x_nfc_setup_interface(struct nand_chip *chip, int cs,
804823
const struct nand_sdr_timings *sdr;
805824
unsigned int period_ns, val;
806825
struct clk *mclk;
826+
unsigned long memclk_of_timing_freq;
827+
int ret = 0;
807828

808829
sdr = nand_get_sdr_timings(conf);
809830
if (IS_ERR(sdr))
@@ -815,6 +836,23 @@ static int pl35x_nfc_setup_interface(struct nand_chip *chip, int cs,
815836
return PTR_ERR(mclk);
816837
}
817838

839+
/*
840+
* Bluefin devices require different rates for different timing modes
841+
* so we need to set the rate according to the timing modes
842+
*/
843+
memclk_of_timing_freq = of_get_memclk_freq(
844+
nfc->dev->parent->of_node,
845+
conf->timings.mode);
846+
847+
if (memclk_of_timing_freq) {
848+
ret = clk_set_rate(mclk, memclk_of_timing_freq);
849+
if (ret) {
850+
pr_err("Failed to set memclk timing frequency to %lu\n",
851+
memclk_of_timing_freq);
852+
return ret;
853+
}
854+
}
855+
818856
/*
819857
* SDR timings are given in pico-seconds while NFC timings must be
820858
* expressed in NAND controller clock cycles. We use the TO_CYCLE()

0 commit comments

Comments
 (0)