aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index d92e30371d8a..9f31314a9cd7 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -1046,13 +1046,20 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
1046 * sunxi_divs_clk_setup() helper data 1046 * sunxi_divs_clk_setup() helper data
1047 */ 1047 */
1048 1048
1049#define SUNXI_DIVS_MAX_QTY 2 1049#define SUNXI_DIVS_MAX_QTY 4
1050#define SUNXI_DIVISOR_WIDTH 2 1050#define SUNXI_DIVISOR_WIDTH 2
1051 1051
1052struct divs_data { 1052struct divs_data {
1053 const struct factors_data *factors; /* data for the factor clock */ 1053 const struct factors_data *factors; /* data for the factor clock */
1054 int ndivs; /* number of children */ 1054 int ndivs; /* number of outputs */
1055 /*
1056 * List of outputs. Refer to the diagram for sunxi_divs_clk_setup():
1057 * self or base factor clock refers to the output from the pll
1058 * itself. The remaining refer to fixed or configurable divider
1059 * outputs.
1060 */
1055 struct { 1061 struct {
1062 u8 self; /* is it the base factor clock? (only one) */
1056 u8 fixed; /* is it a fixed divisor? if not... */ 1063 u8 fixed; /* is it a fixed divisor? if not... */
1057 struct clk_div_table *table; /* is it a table based divisor? */ 1064 struct clk_div_table *table; /* is it a table based divisor? */
1058 u8 shift; /* otherwise it's a normal divisor with this shift */ 1065 u8 shift; /* otherwise it's a normal divisor with this shift */
@@ -1075,23 +1082,26 @@ static const struct divs_data pll5_divs_data __initconst = {
1075 .div = { 1082 .div = {
1076 { .shift = 0, .pow = 0, }, /* M, DDR */ 1083 { .shift = 0, .pow = 0, }, /* M, DDR */
1077 { .shift = 16, .pow = 1, }, /* P, other */ 1084 { .shift = 16, .pow = 1, }, /* P, other */
1085 /* No output for the base factor clock */
1078 } 1086 }
1079}; 1087};
1080 1088
1081static const struct divs_data pll6_divs_data __initconst = { 1089static const struct divs_data pll6_divs_data __initconst = {
1082 .factors = &sun4i_pll6_data, 1090 .factors = &sun4i_pll6_data,
1083 .ndivs = 2, 1091 .ndivs = 3,
1084 .div = { 1092 .div = {
1085 { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ 1093 { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
1086 { .fixed = 2 }, /* P, other */ 1094 { .fixed = 2 }, /* P, other */
1095 { .self = 1 }, /* base factor clock, 2x */
1087 } 1096 }
1088}; 1097};
1089 1098
1090static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { 1099static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
1091 .factors = &sun6i_a31_pll6_data, 1100 .factors = &sun6i_a31_pll6_data,
1092 .ndivs = 1, 1101 .ndivs = 2,
1093 .div = { 1102 .div = {
1094 { .fixed = 2 }, /* normal output */ 1103 { .fixed = 2 }, /* normal output */
1104 { .self = 1 }, /* base factor clock, 2x */
1095 } 1105 }
1096}; 1106};
1097 1107
@@ -1122,6 +1132,10 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
1122 int ndivs = SUNXI_DIVS_MAX_QTY, i = 0; 1132 int ndivs = SUNXI_DIVS_MAX_QTY, i = 0;
1123 int flags, clkflags; 1133 int flags, clkflags;
1124 1134
1135 /* if number of children known, use it */
1136 if (data->ndivs)
1137 ndivs = data->ndivs;
1138
1125 /* Set up factor clock that we will be dividing */ 1139 /* Set up factor clock that we will be dividing */
1126 pclk = sunxi_factors_clk_setup(node, data->factors); 1140 pclk = sunxi_factors_clk_setup(node, data->factors);
1127 parent = __clk_get_name(pclk); 1141 parent = __clk_get_name(pclk);
@@ -1132,7 +1146,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
1132 if (!clk_data) 1146 if (!clk_data)
1133 return; 1147 return;
1134 1148
1135 clks = kzalloc((SUNXI_DIVS_MAX_QTY+1) * sizeof(*clks), GFP_KERNEL); 1149 clks = kcalloc(ndivs, sizeof(*clks), GFP_KERNEL);
1136 if (!clks) 1150 if (!clks)
1137 goto free_clkdata; 1151 goto free_clkdata;
1138 1152
@@ -1142,15 +1156,17 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
1142 * our RAM clock! */ 1156 * our RAM clock! */
1143 clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT; 1157 clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT;
1144 1158
1145 /* if number of children known, use it */
1146 if (data->ndivs)
1147 ndivs = data->ndivs;
1148
1149 for (i = 0; i < ndivs; i++) { 1159 for (i = 0; i < ndivs; i++) {
1150 if (of_property_read_string_index(node, "clock-output-names", 1160 if (of_property_read_string_index(node, "clock-output-names",
1151 i, &clk_name) != 0) 1161 i, &clk_name) != 0)
1152 break; 1162 break;
1153 1163
1164 /* If this is the base factor clock, only update clks */
1165 if (data->div[i].self) {
1166 clk_data->clks[i] = pclk;
1167 continue;
1168 }
1169
1154 gate_hw = NULL; 1170 gate_hw = NULL;
1155 rate_hw = NULL; 1171 rate_hw = NULL;
1156 rate_ops = NULL; 1172 rate_ops = NULL;
@@ -1209,9 +1225,6 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
1209 clk_register_clkdev(clks[i], clk_name, NULL); 1225 clk_register_clkdev(clks[i], clk_name, NULL);
1210 } 1226 }
1211 1227
1212 /* The last clock available on the getter is the parent */
1213 clks[i++] = pclk;
1214
1215 /* Adjust to the real max */ 1228 /* Adjust to the real max */
1216 clk_data->clk_num = i; 1229 clk_data->clk_num = i;
1217 1230