Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1411479

[PATCH v3 3/4] clk: bcm2835: Mark the CM SDRAM clock's parent as critical

From Eric Anholt <eric@anholt.net>
Newsgroups linux.kernel
Subject [PATCH v3 3/4] clk: bcm2835: Mark the CM SDRAM clock's parent as critical
Date 2016-06-01 21:10 +0200
Message-ID <rFjGG-41O-23@gated-at.bofh.it> (permalink)
References <rFjGF-41O-9@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


While the SDRAM is being driven by its dedicated PLL most of the time,
there is a little loop running in the firmware that periodically turns
on the CM SDRAM clock (using its pre-initialized parent) and switches
SDRAM to using the CM clock to do PVT recalibration.

This avoids system hangs if we choose SDRAM's parent for some other
clock, then disable that clock.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/clk/bcm/clk-bcm2835.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 400615baea97..c6420b36cbcb 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -36,6 +36,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
+#include <linux/clk.h>
 #include <linux/clk/bcm2835.h>
 #include <linux/debugfs.h>
 #include <linux/module.h>
@@ -1801,6 +1802,25 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.ctl_reg = CM_PERIICTL),
 };
 
+/*
+ * Permanently take a reference on the parent of the SDRAM clock.
+ *
+ * While the SDRAM is being driven by its dedicated PLL most of the
+ * time, there is a little loop running in the firmware that
+ * periodically switches the SDRAM to using our CM clock to do PVT
+ * recalibration, with the assumption that the previously configured
+ * SDRAM parent is still enabled and running.
+ */
+static int bcm2835_mark_sdc_parent_critical(struct clk *sdc)
+{
+	struct clk *parent = clk_get_parent(sdc);
+
+	if (IS_ERR(parent))
+		return PTR_ERR(parent);
+
+	return clk_prepare_enable(parent);
+}
+
 static int bcm2835_clk_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1810,6 +1830,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
 	const struct bcm2835_clk_desc *desc;
 	const size_t asize = ARRAY_SIZE(clk_desc_array);
 	size_t i;
+	int ret;
 
 	cprman = devm_kzalloc(dev,
 			      sizeof(*cprman) + asize * sizeof(*clks),
@@ -1840,6 +1861,10 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
 			clks[i] = desc->clk_register(cprman, desc->data);
 	}
 
+	ret = bcm2835_mark_sdc_parent_critical(clks[BCM2835_CLOCK_SDRAM]);
+	if (ret)
+		return ret;
+
 	return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
 				   &cprman->onecell);
 }
-- 
2.8.0.rc3

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH v3 0/4] clk: bcm2835: critical clocks and parent selection Eric Anholt <eric@anholt.net> - 2016-06-01 21:10 +0200
  [PATCH v3 4/4] clk: bcm2835: Skip PLLC clocks when deciding on a new clock parent Eric Anholt <eric@anholt.net> - 2016-06-01 21:10 +0200
  [PATCH v3 3/4] clk: bcm2835: Mark the CM SDRAM clock's parent as critical Eric Anholt <eric@anholt.net> - 2016-06-01 21:10 +0200
  [PATCH v3 2/4] clk: bcm2835: Mark GPIO clocks enabled at boot as critical Eric Anholt <eric@anholt.net> - 2016-06-01 21:10 +0200
  [PATCH v3 1/4] clk: bcm2835: Mark the VPU clock as critical Eric Anholt <eric@anholt.net> - 2016-06-01 21:10 +0200

csiph-web