Преглед на файлове

waterDataDiscreteRateMining dataMonitoring.c 康雷 commit at 2020-10-26

康雷 преди 4 години
родител
ревизия
94725d0047
променени са 1 файла, в които са добавени 145 реда и са изтрити 0 реда
  1. 145 0
      waterDataDiscreteRateMining/externalListeningThread/dataMonitoring.c

+ 145 - 0
waterDataDiscreteRateMining/externalListeningThread/dataMonitoring.c

@@ -195,3 +195,148 @@ static struct clk pllc1_div2_clk = {
  * USBCKCR is controlling usb24 clock
  * bit[7] : parent clock
  * bit[6] : clock divide rate
+ * And this bit[7] is used as a "usb24s" from other devices.
+ * (Video clock / Sub clock / SPU clock)
+ * You can controll this clock as a below.
+ *
+ * struct clk *usb24	= clk_get(dev,  "usb24");
+ * struct clk *usb24s	= clk_get(NULL, "usb24s");
+ * struct clk *system	= clk_get(NULL, "system_clk");
+ * int rate = clk_get_rate(system);
+ *
+ * clk_set_parent(usb24s, system);  // for bit[7]
+ * clk_set_rate(usb24, rate / 2);   // for bit[6]
+ */
+static struct clk *usb24s_parents[] = {
+	[0] = &system_clk,
+	[1] = &extal2_clk
+};
+
+static int usb24s_enable(struct clk *clk)
+{
+	__raw_writel(__raw_readl(USBCKCR) & ~(1 << 8), USBCKCR);
+
+	return 0;
+}
+
+static void usb24s_disable(struct clk *clk)
+{
+	__raw_writel(__raw_readl(USBCKCR) | (1 << 8), USBCKCR);
+}
+
+static int usb24s_set_parent(struct clk *clk, struct clk *parent)
+{
+	int i, ret;
+	u32 val;
+
+	if (!clk->parent_table || !clk->parent_num)
+		return -EINVAL;
+
+	/* Search the parent */
+	for (i = 0; i < clk->parent_num; i++)
+		if (clk->parent_table[i] == parent)
+			break;
+
+	if (i == clk->parent_num)
+		return -ENODEV;
+
+	ret = clk_reparent(clk, parent);
+	if (ret < 0)
+		return ret;
+
+	val = __raw_readl(USBCKCR);
+	val &= ~(1 << 7);
+	val |= i << 7;
+	__raw_writel(val, USBCKCR);
+
+	return 0;
+}
+
+static struct sh_clk_ops usb24s_clk_ops = {
+	.recalc		= followparent_recalc,
+	.enable		= usb24s_enable,
+	.disable	= usb24s_disable,
+	.set_parent	= usb24s_set_parent,
+};
+
+static struct clk usb24s_clk = {
+	.ops		= &usb24s_clk_ops,
+	.parent_table	= usb24s_parents,
+	.parent_num	= ARRAY_SIZE(usb24s_parents),
+	.parent		= &system_clk,
+};
+
+static unsigned long usb24_recalc(struct clk *clk)
+{
+	return clk->parent->rate /
+		((__raw_readl(USBCKCR) & (1 << 6)) ? 1 : 2);
+};
+
+static int usb24_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 val;
+
+	/* closer to which ? parent->rate or parent->rate/2 */
+	val = __raw_readl(USBCKCR);
+	val &= ~(1 << 6);
+	val |= (rate > (clk->parent->rate / 4) * 3) << 6;
+	__raw_writel(val, USBCKCR);
+
+	return 0;
+}
+
+static struct sh_clk_ops usb24_clk_ops = {
+	.recalc		= usb24_recalc,
+	.set_rate	= usb24_set_rate,
+};
+
+static struct clk usb24_clk = {
+	.ops		= &usb24_clk_ops,
+	.parent		= &usb24s_clk,
+};
+
+/* External FSIACK/FSIBCK clock */
+static struct clk fsiack_clk = {
+};
+
+static struct clk fsibck_clk = {
+};
+
+struct clk *main_clks[] = {
+	&extalr_clk,
+	&extal1_clk,
+	&extal2_clk,
+	&extal1_div2_clk,
+	&extal1_div1024_clk,
+	&extal1_div2048_clk,
+	&extal2_div2_clk,
+	&dv_clk,
+	&system_clk,
+	&system_div2_clk,
+	&r_clk,
+	&pllc0_clk,
+	&pllc1_clk,
+	&pllc1_div2_clk,
+	&usb24s_clk,
+	&usb24_clk,
+	&fsiack_clk,
+	&fsibck_clk,
+};
+
+static void div4_kick(struct clk *clk)
+{
+	unsigned long value;
+
+	/* set KICK bit in FRQCRB to update hardware setting */
+	value = __raw_readl(FRQCRB);
+	value |= (1 << 31);
+	__raw_writel(value, FRQCRB);
+}
+
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
+			  24, 32, 36, 48, 0, 72, 96, 0 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+	.divisors = divisors,
+	.nr_divisors = ARRAY_SIZE(divisors),
+};