The SoundWire 1.2 specification adds new registers to allow for seamless clock changes while audio transfers are on-going. Program them following the specification. Note that dynamic clock changes are not supported for now, this only adds the register initialization.
Unified · Split
| @@ -1070,12 +1070,119 @@ int sdw_configure_dpn_intr(struct sdw_slave *slave, · 1069 unmodified lines | ||
| 1070 | 1070 | return ret; |
| 1071 | 1071 | } |
| 1072 | 1072 | |
| 1073 | +static int sdw_slave_set_frequency(struct sdw_slave *slave) | |
| 1074 | +{ | |
| 1075 | + u32 mclk_freq = slave->bus->prop.mclk_freq; | |
| 1076 | + u32 curr_freq = slave->bus->params.curr_dr_freq >> 1; | |
| 1077 | + unsigned int scale; | |
| 1078 | + u8 scale_index; | |
| 1079 | + u8 base; | |
| 1080 | + int ret; | |
| 1081 | + | |
| 1082 | + /* | |
| 1083 | + * frequency base and scale registers are required for SDCA | |
| 1084 | + * devices. They may also be used for 1.2+/non-SDCA devices, | |
| 1085 | + * but we will need a DisCo property to cover this case | |
| 1086 | + */ | |
| 1087 | + if (!slave->id.class_id) | |
| 1088 | + return 0; | |
| 1089 | + | |
| 1090 | + if (!mclk_freq) { | |
| 1091 | + dev_err(&slave->dev, | |
| 1092 | + "no bus MCLK, cannot set SDW_SCP_BUS_CLOCK_BASE\n"); | |
| 1093 | + return -EINVAL; | |
| 1094 | + } | |
| 1095 | + | |
| 1096 | + /* | |
| 1097 | + * map base frequency using Table 89 of SoundWire 1.2 spec. | |
| 1098 | + * The order of the tests just follows the specification, this | |
| 1099 | + * is not a selection between possible values or a search for | |
| 1100 | + * the best value but just a mapping. Only one case per platform | |
| 1101 | + * is relevant. | |
| 1102 | + * Some BIOS have inconsistent values for mclk_freq but a | |
| 1103 | + * correct root so we force the mclk_freq to avoid variations. | |
| 1104 | + */ | |
| 1105 | + if (!(19200000 % mclk_freq)) { | |
| 1106 | + mclk_freq = 19200000; | |
| 1107 | + base = SDW_SCP_BASE_CLOCK_19200000_HZ; | |
| 1108 | + } else if (!(24000000 % mclk_freq)) { | |
| 1109 | + mclk_freq = 24000000; | |
| 1110 | + base = SDW_SCP_BASE_CLOCK_24000000_HZ; | |
| 1111 | + } else if (!(24576000 % mclk_freq)) { | |
| 1112 | + mclk_freq = 24576000; | |
| 1113 | + base = SDW_SCP_BASE_CLOCK_24576000_HZ; | |
| 1114 | + } else if (!(22579200 % mclk_freq)) { | |
| 1115 | + mclk_freq = 22579200; | |
| 1116 | + base = SDW_SCP_BASE_CLOCK_22579200_HZ; | |
| 1117 | + } else if (!(32000000 % mclk_freq)) { | |
| 1118 | + mclk_freq = 32000000; | |
| 1119 | + base = SDW_SCP_BASE_CLOCK_32000000_HZ; | |
| 1120 | + } else { | |
| 1121 | + dev_err(&slave->dev, | |
| 1122 | + "Unsupported clock base, mclk %d\n", | |
| 1123 | + mclk_freq); | |
| 1124 | + return -EINVAL; | |
| 1125 | + } | |
| 1126 | + | |
| 1127 | + if (mclk_freq % curr_freq) { | |
| 1128 | + dev_err(&slave->dev, | |
| 1129 | + "mclk %d is not multiple of bus curr_freq %d\n", | |
| 1130 | + mclk_freq, curr_freq); | |
| 1131 | + return -EINVAL; | |
| 1132 | + } | |
| 1133 | + | |
| 1134 | + scale = mclk_freq / curr_freq; | |
| 1135 | + | |
| 1136 | + /* | |
| 1137 | + * map scale to Table 90 of SoundWire 1.2 spec - and check | |
| 1138 | + * that the scale is a power of two and maximum 64 | |
| 1139 | + */ | |
| 1140 | + scale_index = ilog2(scale); | |
| 1141 | + | |
| 1142 | + if (BIT(scale_index) != scale || scale_index > 6) { | |
| 1143 | + dev_err(&slave->dev, | |
| 1144 | + "No match found for scale %d, bus mclk %d curr_freq %d\n", | |
| 1145 | + scale, mclk_freq, curr_freq); | |
| 1146 | + return -EINVAL; | |
| 1147 | + } | |
| 1148 | + scale_index++; | |
| 1149 | + | |
| 1150 | + ret = sdw_write(slave, SDW_SCP_BUS_CLOCK_BASE, base); | |
| 1151 | + if (ret < 0) { | |
| 1152 | + dev_err(&slave->dev, | |
| 1153 | + "SDW_SCP_BUS_CLOCK_BASE write failed:%d\n", ret); | |
| 1154 | + return ret; | |
| 1155 | + } | |
| 1156 | + | |
| 1157 | + /* initialize scale for both banks */ | |
| 1158 | + ret = sdw_write(slave, SDW_SCP_BUSCLOCK_SCALE_B0, scale_index); | |
| 1159 | + if (ret < 0) { | |
| 1160 | + dev_err(&slave->dev, | |
| 1161 | + "SDW_SCP_BUSCLOCK_SCALE_B0 write failed:%d\n", ret); | |
| 1162 | + return ret; | |
| 1163 | + } | |
| 1164 | + ret = sdw_write(slave, SDW_SCP_BUSCLOCK_SCALE_B1, scale_index); | |
| 1165 | + if (ret < 0) | |
| 1166 | + dev_err(&slave->dev, | |
| 1167 | + "SDW_SCP_BUSCLOCK_SCALE_B1 write failed:%d\n", ret); | |
| 1168 | + | |
| 1169 | + dev_dbg(&slave->dev, | |
| 1170 | + "Configured bus base %d, scale %d, mclk %d, curr_freq %d\n", | |
| 1171 | + base, scale_index, mclk_freq, curr_freq); | |
| 1172 | + | |
| 1173 | + return ret; | |
| 1174 | +} | |
| 1175 | + | |
| 1073 | 1176 | static int sdw_initialize_slave(struct sdw_slave *slave) |
| 1074 | 1177 | { |
| 1075 | 1178 | struct sdw_slave_prop *prop = &slave->prop; |
| 1076 | 1179 | int ret; |
| 1077 | 1180 | u8 val; |
| 1078 | 1181 | |
| 1182 | + ret = sdw_slave_set_frequency(slave); | |
| 1183 | + if (ret < 0) | |
| 1184 | + return ret; | |
| 1185 | + | |
| 1079 | 1186 | /* |
| 1080 | 1187 | * Set bus clash, parity and SCP implementation |
| 1081 | 1188 | * defined interrupt mask |
| @@ -109,8 +109,18 @@ · 108 unmodified lines | ||
| 109 | 109 | #define SDW_SCP_KEEPEREN 0x4A |
| 110 | 110 | #define SDW_SCP_BANKDELAY 0x4B |
| 111 | 111 | #define SDW_SCP_COMMIT 0x4C |
| 112 | + | |
| 112 | 113 | #define SDW_SCP_BUS_CLOCK_BASE 0x4D |
| 113 | 114 | #define SDW_SCP_BASE_CLOCK_FREQ GENMASK(2, 0) |
| 115 | +#define SDW_SCP_BASE_CLOCK_UNKNOWN 0x0 | |
| 116 | +#define SDW_SCP_BASE_CLOCK_19200000_HZ 0x1 | |
| 117 | +#define SDW_SCP_BASE_CLOCK_24000000_HZ 0x2 | |
| 118 | +#define SDW_SCP_BASE_CLOCK_24576000_HZ 0x3 | |
| 119 | +#define SDW_SCP_BASE_CLOCK_22579200_HZ 0x4 | |
| 120 | +#define SDW_SCP_BASE_CLOCK_32000000_HZ 0x5 | |
| 121 | +#define SDW_SCP_BASE_CLOCK_RESERVED 0x6 | |
| 122 | +#define SDW_SCP_BASE_CLOCK_IMP_DEF 0x7 | |
| 123 | + | |
| 114 | 124 | /* 0x4E is not allocated in SoundWire specification 1.2 */ |
| 115 | 125 | #define SDW_SCP_TESTMODE 0x4F |
| 116 | 126 | #define SDW_SCP_DEVID_0 0x50 |