|
303 | 303 | #define ERR_CNT_INVLD_DW (PORT_BASE + 0x390)
|
304 | 304 | #define ERR_CNT_CODE_ERR (PORT_BASE + 0x394)
|
305 | 305 | #define ERR_CNT_DISP_ERR (PORT_BASE + 0x398)
|
| 306 | +#define DFX_FIFO_CTRL (PORT_BASE + 0x3a0) |
| 307 | +#define DFX_FIFO_CTRL_TRIGGER_MODE_OFF 0 |
| 308 | +#define DFX_FIFO_CTRL_TRIGGER_MODE_MSK (0x7 << DFX_FIFO_CTRL_TRIGGER_MODE_OFF) |
| 309 | +#define DFX_FIFO_CTRL_DUMP_MODE_OFF 3 |
| 310 | +#define DFX_FIFO_CTRL_DUMP_MODE_MSK (0x7 << DFX_FIFO_CTRL_DUMP_MODE_OFF) |
| 311 | +#define DFX_FIFO_CTRL_SIGNAL_SEL_OFF 6 |
| 312 | +#define DFX_FIFO_CTRL_SIGNAL_SEL_MSK (0xF << DFX_FIFO_CTRL_SIGNAL_SEL_OFF) |
| 313 | +#define DFX_FIFO_CTRL_DUMP_DISABLE_OFF 10 |
| 314 | +#define DFX_FIFO_CTRL_DUMP_DISABLE_MSK (0x1 << DFX_FIFO_CTRL_DUMP_DISABLE_OFF) |
| 315 | +#define DFX_FIFO_TRIGGER (PORT_BASE + 0x3a4) |
| 316 | +#define DFX_FIFO_TRIGGER_MSK (PORT_BASE + 0x3a8) |
| 317 | +#define DFX_FIFO_DUMP_MSK (PORT_BASE + 0x3aC) |
| 318 | +#define DFX_FIFO_RD_DATA (PORT_BASE + 0x3b0) |
306 | 319 |
|
307 | 320 | #define DEFAULT_ITCT_HW 2048 /* reset value, not reprogrammed */
|
308 | 321 | #if (HISI_SAS_MAX_DEVICES > DEFAULT_ITCT_HW)
|
@@ -4153,6 +4166,243 @@ static const struct file_operations debugfs_phy_down_cnt_v3_hw_fops = {
|
4153 | 4166 | .owner = THIS_MODULE,
|
4154 | 4167 | };
|
4155 | 4168 |
|
| 4169 | +enum fifo_dump_mode_v3_hw { |
| 4170 | + FIFO_DUMP_FORVER = (1U << 0), |
| 4171 | + FIFO_DUMP_AFTER_TRIGGER = (1U << 1), |
| 4172 | + FIFO_DUMP_UNTILL_TRIGGER = (1U << 2), |
| 4173 | +}; |
| 4174 | + |
| 4175 | +enum fifo_trigger_mode_v3_hw { |
| 4176 | + FIFO_TRIGGER_EDGE = (1U << 0), |
| 4177 | + FIFO_TRIGGER_SAME_LEVEL = (1U << 1), |
| 4178 | + FIFO_TRIGGER_DIFF_LEVEL = (1U << 2), |
| 4179 | +}; |
| 4180 | + |
| 4181 | +static int debugfs_is_fifo_config_valid_v3_hw(struct hisi_sas_phy *phy) |
| 4182 | +{ |
| 4183 | + struct hisi_hba *hisi_hba = phy->hisi_hba; |
| 4184 | + |
| 4185 | + if (phy->fifo.signal_sel > 0xf) { |
| 4186 | + dev_info(hisi_hba->dev, "Invalid signal select: %u\n", |
| 4187 | + phy->fifo.signal_sel); |
| 4188 | + return -EINVAL; |
| 4189 | + } |
| 4190 | + |
| 4191 | + switch (phy->fifo.dump_mode) { |
| 4192 | + case FIFO_DUMP_FORVER: |
| 4193 | + case FIFO_DUMP_AFTER_TRIGGER: |
| 4194 | + case FIFO_DUMP_UNTILL_TRIGGER: |
| 4195 | + break; |
| 4196 | + default: |
| 4197 | + dev_info(hisi_hba->dev, "Invalid dump mode: %u\n", |
| 4198 | + phy->fifo.dump_mode); |
| 4199 | + return -EINVAL; |
| 4200 | + } |
| 4201 | + |
| 4202 | + /* when FIFO_DUMP_FORVER, no need to check trigger_mode */ |
| 4203 | + if (phy->fifo.dump_mode == FIFO_DUMP_FORVER) |
| 4204 | + return 0; |
| 4205 | + |
| 4206 | + switch (phy->fifo.trigger_mode) { |
| 4207 | + case FIFO_TRIGGER_EDGE: |
| 4208 | + case FIFO_TRIGGER_SAME_LEVEL: |
| 4209 | + case FIFO_TRIGGER_DIFF_LEVEL: |
| 4210 | + break; |
| 4211 | + default: |
| 4212 | + dev_info(hisi_hba->dev, "Invalid trigger mode: %u\n", |
| 4213 | + phy->fifo.trigger_mode); |
| 4214 | + return -EINVAL; |
| 4215 | + } |
| 4216 | + return 0; |
| 4217 | +} |
| 4218 | + |
| 4219 | +static int debugfs_update_fifo_config_v3_hw(struct hisi_sas_phy *phy) |
| 4220 | +{ |
| 4221 | + u32 trigger_mode = phy->fifo.trigger_mode; |
| 4222 | + u32 signal_sel = phy->fifo.signal_sel; |
| 4223 | + u32 dump_mode = phy->fifo.dump_mode; |
| 4224 | + struct hisi_hba *hisi_hba = phy->hisi_hba; |
| 4225 | + int phy_no = phy->sas_phy.id; |
| 4226 | + u32 reg_val; |
| 4227 | + int res; |
| 4228 | + |
| 4229 | + /* Check the validity of trace FIFO configuration */ |
| 4230 | + res = debugfs_is_fifo_config_valid_v3_hw(phy); |
| 4231 | + if (res) |
| 4232 | + return res; |
| 4233 | + |
| 4234 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); |
| 4235 | + /* Disable trace FIFO before update configuration */ |
| 4236 | + reg_val |= DFX_FIFO_CTRL_DUMP_DISABLE_MSK; |
| 4237 | + |
| 4238 | + /* Update trace FIFO configuration */ |
| 4239 | + reg_val &= ~(DFX_FIFO_CTRL_DUMP_MODE_MSK | |
| 4240 | + DFX_FIFO_CTRL_SIGNAL_SEL_MSK | |
| 4241 | + DFX_FIFO_CTRL_TRIGGER_MODE_MSK); |
| 4242 | + |
| 4243 | + reg_val |= ((trigger_mode << DFX_FIFO_CTRL_TRIGGER_MODE_OFF) | |
| 4244 | + (dump_mode << DFX_FIFO_CTRL_DUMP_MODE_OFF) | |
| 4245 | + (signal_sel << DFX_FIFO_CTRL_SIGNAL_SEL_OFF)); |
| 4246 | + hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, reg_val); |
| 4247 | + |
| 4248 | + hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_DUMP_MSK, |
| 4249 | + phy->fifo.dump_msk); |
| 4250 | + |
| 4251 | + hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_TRIGGER, |
| 4252 | + phy->fifo.trigger); |
| 4253 | + |
| 4254 | + hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_TRIGGER_MSK, |
| 4255 | + phy->fifo.trigger_msk); |
| 4256 | + |
| 4257 | + /* Enable trace FIFO after updated configuration */ |
| 4258 | + reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); |
| 4259 | + reg_val &= ~DFX_FIFO_CTRL_DUMP_DISABLE_MSK; |
| 4260 | + hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, reg_val); |
| 4261 | + |
| 4262 | + return 0; |
| 4263 | +} |
| 4264 | + |
| 4265 | +static ssize_t debugfs_fifo_update_cfg_v3_hw_write(struct file *filp, |
| 4266 | + const char __user *buf, |
| 4267 | + size_t count, loff_t *ppos) |
| 4268 | +{ |
| 4269 | + struct hisi_sas_phy *phy = filp->private_data; |
| 4270 | + bool update; |
| 4271 | + int val; |
| 4272 | + |
| 4273 | + val = kstrtobool_from_user(buf, count, &update); |
| 4274 | + if (val) |
| 4275 | + return val; |
| 4276 | + |
| 4277 | + if (update != 1) |
| 4278 | + return -EINVAL; |
| 4279 | + |
| 4280 | + val = debugfs_update_fifo_config_v3_hw(phy); |
| 4281 | + if (val) |
| 4282 | + return val; |
| 4283 | + |
| 4284 | + return count; |
| 4285 | +} |
| 4286 | + |
| 4287 | +static const struct file_operations debugfs_fifo_update_cfg_v3_hw_fops = { |
| 4288 | + .open = simple_open, |
| 4289 | + .write = debugfs_fifo_update_cfg_v3_hw_write, |
| 4290 | + .owner = THIS_MODULE, |
| 4291 | +}; |
| 4292 | + |
| 4293 | +static void debugfs_read_fifo_data_v3_hw(struct hisi_sas_phy *phy) |
| 4294 | +{ |
| 4295 | + struct hisi_hba *hisi_hba = phy->hisi_hba; |
| 4296 | + u32 *buf = phy->fifo.rd_data; |
| 4297 | + int phy_no = phy->sas_phy.id; |
| 4298 | + u32 val; |
| 4299 | + int i; |
| 4300 | + |
| 4301 | + memset(buf, 0, sizeof(phy->fifo.rd_data)); |
| 4302 | + |
| 4303 | + /* Disable trace FIFO before read data */ |
| 4304 | + val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); |
| 4305 | + val |= DFX_FIFO_CTRL_DUMP_DISABLE_MSK; |
| 4306 | + hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, val); |
| 4307 | + |
| 4308 | + for (i = 0; i < HISI_SAS_FIFO_DATA_DW_SIZE; i++) { |
| 4309 | + val = hisi_sas_phy_read32(hisi_hba, phy_no, |
| 4310 | + DFX_FIFO_RD_DATA); |
| 4311 | + buf[i] = val; |
| 4312 | + } |
| 4313 | + |
| 4314 | + /* Enable trace FIFO after read data */ |
| 4315 | + val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); |
| 4316 | + val &= ~DFX_FIFO_CTRL_DUMP_DISABLE_MSK; |
| 4317 | + hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, val); |
| 4318 | +} |
| 4319 | + |
| 4320 | +static int debugfs_fifo_data_v3_hw_show(struct seq_file *s, void *p) |
| 4321 | +{ |
| 4322 | + struct hisi_sas_phy *phy = s->private; |
| 4323 | + |
| 4324 | + debugfs_read_fifo_data_v3_hw(phy); |
| 4325 | + |
| 4326 | + debugfs_show_row_32_v3_hw(s, 0, HISI_SAS_FIFO_DATA_DW_SIZE * 4, |
| 4327 | + phy->fifo.rd_data); |
| 4328 | + |
| 4329 | + return 0; |
| 4330 | +} |
| 4331 | +DEFINE_SHOW_ATTRIBUTE(debugfs_fifo_data_v3_hw); |
| 4332 | + |
| 4333 | +static void debugfs_fifo_init_v3_hw(struct hisi_hba *hisi_hba) |
| 4334 | +{ |
| 4335 | + int phy_no; |
| 4336 | + |
| 4337 | + hisi_hba->debugfs_fifo_dentry = |
| 4338 | + debugfs_create_dir("fifo", hisi_hba->debugfs_dir); |
| 4339 | + |
| 4340 | + for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { |
| 4341 | + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
| 4342 | + struct dentry *port_dentry; |
| 4343 | + char name[256]; |
| 4344 | + u32 val; |
| 4345 | + |
| 4346 | + /* get default configuration for trace FIFO */ |
| 4347 | + val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); |
| 4348 | + val &= DFX_FIFO_CTRL_DUMP_MODE_MSK; |
| 4349 | + val >>= DFX_FIFO_CTRL_DUMP_MODE_OFF; |
| 4350 | + phy->fifo.dump_mode = val; |
| 4351 | + |
| 4352 | + val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); |
| 4353 | + val &= DFX_FIFO_CTRL_TRIGGER_MODE_MSK; |
| 4354 | + val >>= DFX_FIFO_CTRL_TRIGGER_MODE_OFF; |
| 4355 | + phy->fifo.trigger_mode = val; |
| 4356 | + |
| 4357 | + val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL); |
| 4358 | + val &= DFX_FIFO_CTRL_SIGNAL_SEL_MSK; |
| 4359 | + val >>= DFX_FIFO_CTRL_SIGNAL_SEL_OFF; |
| 4360 | + phy->fifo.signal_sel = val; |
| 4361 | + |
| 4362 | + val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_DUMP_MSK); |
| 4363 | + phy->fifo.dump_msk = val; |
| 4364 | + |
| 4365 | + val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_TRIGGER); |
| 4366 | + phy->fifo.trigger = val; |
| 4367 | + val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_TRIGGER_MSK); |
| 4368 | + phy->fifo.trigger_msk = val; |
| 4369 | + |
| 4370 | + snprintf(name, 256, "%d", phy_no); |
| 4371 | + port_dentry = debugfs_create_dir(name, |
| 4372 | + hisi_hba->debugfs_fifo_dentry); |
| 4373 | + |
| 4374 | + debugfs_create_file("update_config", 0200, port_dentry, phy, |
| 4375 | + &debugfs_fifo_update_cfg_v3_hw_fops); |
| 4376 | + |
| 4377 | + debugfs_create_file("signal_sel", 0600, port_dentry, |
| 4378 | + &phy->fifo.signal_sel, |
| 4379 | + &debugfs_v3_hw_fops); |
| 4380 | + |
| 4381 | + debugfs_create_file("dump_msk", 0600, port_dentry, |
| 4382 | + &phy->fifo.dump_msk, |
| 4383 | + &debugfs_v3_hw_fops); |
| 4384 | + |
| 4385 | + debugfs_create_file("dump_mode", 0600, port_dentry, |
| 4386 | + &phy->fifo.dump_mode, |
| 4387 | + &debugfs_v3_hw_fops); |
| 4388 | + |
| 4389 | + debugfs_create_file("trigger_mode", 0600, port_dentry, |
| 4390 | + &phy->fifo.trigger_mode, |
| 4391 | + &debugfs_v3_hw_fops); |
| 4392 | + |
| 4393 | + debugfs_create_file("trigger", 0600, port_dentry, |
| 4394 | + &phy->fifo.trigger, |
| 4395 | + &debugfs_v3_hw_fops); |
| 4396 | + |
| 4397 | + debugfs_create_file("trigger_msk", 0600, port_dentry, |
| 4398 | + &phy->fifo.trigger_msk, |
| 4399 | + &debugfs_v3_hw_fops); |
| 4400 | + |
| 4401 | + debugfs_create_file("fifo_data", 0400, port_dentry, phy, |
| 4402 | + &debugfs_fifo_data_v3_hw_fops); |
| 4403 | + } |
| 4404 | +} |
| 4405 | + |
4156 | 4406 | static void debugfs_work_handler_v3_hw(struct work_struct *work)
|
4157 | 4407 | {
|
4158 | 4408 | struct hisi_hba *hisi_hba =
|
@@ -4388,6 +4638,7 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
|
4388 | 4638 | debugfs_create_dir("dump", hisi_hba->debugfs_dir);
|
4389 | 4639 |
|
4390 | 4640 | debugfs_phy_down_cnt_init_v3_hw(hisi_hba);
|
| 4641 | + debugfs_fifo_init_v3_hw(hisi_hba); |
4391 | 4642 |
|
4392 | 4643 | for (i = 0; i < hisi_sas_debugfs_dump_count; i++) {
|
4393 | 4644 | if (debugfs_alloc_v3_hw(hisi_hba, i)) {
|
|
0 commit comments