Browse Source

[dm][clk][rockchip] fixup rockchip clk

Signed-off-by: GuEe-GUI <2991707448@qq.com>
GuEe-GUI 15 hours ago
parent
commit
e41c7ccf88

+ 14 - 0
bsp/rockchip/dm/clk/clk-rk-gate.h

@@ -27,6 +27,20 @@
     .gate_flags = gf,                           \
 }
 
+#define GATE_NO_SET_RATE(_id, cname, pname, f, o, b, gf) \
+(void *)&(struct rockchip_clk_cell)             \
+{                                               \
+    .cell.name = cname,                         \
+    .cell.ops = &rockchip_gate_clk_ops,         \
+    .cell.parent_name = pname,                  \
+    .cell.parents_nr = 1,                       \
+    .cell.flags = f | RT_CLK_F_SET_RATE_PARENT, \
+    .id = _id,                                  \
+    .gate_offset = o,                           \
+    .gate_shift = b,                            \
+    .gate_flags = gf,                           \
+}
+
 extern const struct rt_clk_ops rockchip_gate_clk_ops;
 
 #endif /* __CLK_RK_GATE_H__ */

+ 3 - 2
bsp/rockchip/dm/clk/clk-rk-half-divider.h

@@ -63,7 +63,7 @@ struct rockchip_half_divider_clk_cell
     .rk_cell.init = rockchip_half_divider_clk_cell_init,\
 }
 
-#define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df)                            \
+#define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df) \
 (void *)&(struct rockchip_half_divider_clk_cell)        \
 {                                                       \
     .rk_cell.cell.name = cname,                         \
@@ -82,7 +82,8 @@ struct rockchip_half_divider_clk_cell
     .rk_cell.init = rockchip_half_divider_clk_cell_init,\
 }
 
-#define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df, go, gs, gf)                             \
+#define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df, go, gs, gf) \
+(void *)&(struct rockchip_half_divider_clk_cell)        \
 {                                                       \
     .rk_cell.cell.name = cname,                         \
     .rk_cell.cell.parent_name = pname,                  \

+ 32 - 5
components/drivers/clk/clk-scmi.c

@@ -230,7 +230,7 @@ static rt_err_t scmi_clk_probe(struct rt_scmi_device *sdev)
     for (int id = 0; id < cell_count; ++id)
     {
         const char *clk_name;
-        rt_uint32_t flags, rates_nr, rate_discrete;
+        rt_uint32_t flags, rate_discrete;
 
         in.id = rt_cpu_to_le32(id);
         in.rate_index = rt_cpu_to_le32(0);
@@ -242,7 +242,6 @@ static rt_err_t scmi_clk_probe(struct rt_scmi_device *sdev)
         }
 
         flags = rt_le32_to_cpu(out->num_rates_flags);
-        rates_nr = SCMI_NUM_REMAINING(flags);
         rate_discrete = SCMI_RATE_DISCRETE(flags);
 
         if (rate_discrete)
@@ -263,12 +262,40 @@ static rt_err_t scmi_clk_probe(struct rt_scmi_device *sdev)
 
         if (rate_discrete)
         {
-            for (int i = 0; i < rates_nr; ++i)
+            /*
+             * SCMI: [11:0] = rates in this message, [31:16] = remaining to query.
+             * Using REMAINING as the copy count overflows rates[] and corrupts heap.
+             */
+            int idx = 0;
+
+            for (;;)
             {
-                clk_data->info.list.rates[i] = SCMI_RATE_TO_U64(out->rate[i]);
+                rt_uint32_t nr = SCMI_NUM_RETURNED(flags);
+                rt_uint32_t remaining = SCMI_NUM_REMAINING(flags);
+
+                for (rt_uint32_t i = 0; i < nr && idx < SCMI_MAX_NUM_RATES; ++i, ++idx)
+                {
+                    clk_data->info.list.rates[idx] = SCMI_RATE_TO_U64(out->rate[i]);
+                }
+
+                if (remaining == 0 || idx >= SCMI_MAX_NUM_RATES)
+                {
+                    break;
+                }
+
+                in.rate_index = rt_cpu_to_le32(idx);
+                msg = RT_SCMI_MSG_RAW(SCMI_CLOCK_DESCRIBE_RATES, &in, sizeof(in), out, out_size);
+
+                if ((err = rt_scmi_process_msg(sclk->sdev, &msg)))
+                {
+                    rt_free(clk_data);
+                    goto _fail;
+                }
+
+                flags = rt_le32_to_cpu(out->num_rates_flags);
             }
 
-            clk_data->info.list.rates_nr = rates_nr;
+            clk_data->info.list.rates_nr = idx;
         }
         else
         {