Loading drivers/scsi/ufs/ufs-qcom.c +70 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,19 @@ static int ufs_qcom_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes) return err; } static int ufs_qcom_get_connected_rx_lanes(struct ufs_hba *hba, u32 *rx_lanes) { int err = 0; err = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDRXDATALANES), rx_lanes); if (err) dev_err(hba->dev, "%s: couldn't read PA_CONNECTEDRXDATALANES %d\n", __func__, err); return err; } static int ufs_qcom_host_clk_get(struct device *dev, const char *name, struct clk **clk_out, bool optional) { Loading Loading @@ -900,6 +913,62 @@ static int ufs_qcom_bypass_cfgready_signal(struct ufs_hba *hba) return err; } static void ufs_qcom_dump_attribs(struct ufs_hba *hba) { int ret; int attrs[] = {0x15a0, 0x1552, 0x1553, 0x1554, 0x1555, 0x1556, 0x1557, 0x155a, 0x155b, 0x155c, 0x155d, 0x155e, 0x155f, 0x1560, 0x1561, 0x1568, 0x1569, 0x156a, 0x1571, 0x1580, 0x1581, 0x1583, 0x1584, 0x1585, 0x1586, 0x1587, 0x1590, 0x1591, 0x15a1, 0x15a2, 0x15a3, 0x15a4, 0x15a5, 0x15a6, 0x15a7, 0x15a8, 0x15a9, 0x15aa, 0x15ab, 0x15c0, 0x15c1, 0x15c2, 0x15d0, 0x15d1, 0x15d2, 0x15d3, 0x15d4, 0x15d5, }; int cnt = ARRAY_SIZE(attrs); int i = 0, val; for (; i < cnt; i++) { ret = ufshcd_dme_get(hba, UIC_ARG_MIB(attrs[i]), &val); if (ret) { dev_err(hba->dev, "Failed reading: 0x%04x, ret:%d\n", attrs[i], ret); continue; } dev_err(hba->dev, "0x%04x: %d\n", attrs[i], val); } } static void ufs_qcom_validate_link_params(struct ufs_hba *hba) { int val = 0; bool err = false; WARN_ON(ufs_qcom_get_connected_tx_lanes(hba, &val)); if (val != hba->lanes_per_direction) { dev_err(hba->dev, "%s: Tx lane mismatch [config,reported] [%d,%d]\n", __func__, hba->lanes_per_direction, val); WARN_ON(1); err = true; } val = 0; WARN_ON(ufs_qcom_get_connected_rx_lanes(hba, &val)); if (val != hba->lanes_per_direction) { dev_err(hba->dev, "%s: Rx lane mismatch [config,reported] [%d,%d]\n", __func__, hba->lanes_per_direction, val); WARN_ON(1); err = true; } if (err) ufs_qcom_dump_attribs(hba); } static int ufs_qcom_link_startup_notify(struct ufs_hba *hba, enum ufs_notify_change_status status) { Loading Loading @@ -946,6 +1015,7 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba, break; case POST_CHANGE: ufs_qcom_link_startup_post_change(hba); ufs_qcom_validate_link_params(hba); break; default: break; Loading Loading
drivers/scsi/ufs/ufs-qcom.c +70 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,19 @@ static int ufs_qcom_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes) return err; } static int ufs_qcom_get_connected_rx_lanes(struct ufs_hba *hba, u32 *rx_lanes) { int err = 0; err = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDRXDATALANES), rx_lanes); if (err) dev_err(hba->dev, "%s: couldn't read PA_CONNECTEDRXDATALANES %d\n", __func__, err); return err; } static int ufs_qcom_host_clk_get(struct device *dev, const char *name, struct clk **clk_out, bool optional) { Loading Loading @@ -900,6 +913,62 @@ static int ufs_qcom_bypass_cfgready_signal(struct ufs_hba *hba) return err; } static void ufs_qcom_dump_attribs(struct ufs_hba *hba) { int ret; int attrs[] = {0x15a0, 0x1552, 0x1553, 0x1554, 0x1555, 0x1556, 0x1557, 0x155a, 0x155b, 0x155c, 0x155d, 0x155e, 0x155f, 0x1560, 0x1561, 0x1568, 0x1569, 0x156a, 0x1571, 0x1580, 0x1581, 0x1583, 0x1584, 0x1585, 0x1586, 0x1587, 0x1590, 0x1591, 0x15a1, 0x15a2, 0x15a3, 0x15a4, 0x15a5, 0x15a6, 0x15a7, 0x15a8, 0x15a9, 0x15aa, 0x15ab, 0x15c0, 0x15c1, 0x15c2, 0x15d0, 0x15d1, 0x15d2, 0x15d3, 0x15d4, 0x15d5, }; int cnt = ARRAY_SIZE(attrs); int i = 0, val; for (; i < cnt; i++) { ret = ufshcd_dme_get(hba, UIC_ARG_MIB(attrs[i]), &val); if (ret) { dev_err(hba->dev, "Failed reading: 0x%04x, ret:%d\n", attrs[i], ret); continue; } dev_err(hba->dev, "0x%04x: %d\n", attrs[i], val); } } static void ufs_qcom_validate_link_params(struct ufs_hba *hba) { int val = 0; bool err = false; WARN_ON(ufs_qcom_get_connected_tx_lanes(hba, &val)); if (val != hba->lanes_per_direction) { dev_err(hba->dev, "%s: Tx lane mismatch [config,reported] [%d,%d]\n", __func__, hba->lanes_per_direction, val); WARN_ON(1); err = true; } val = 0; WARN_ON(ufs_qcom_get_connected_rx_lanes(hba, &val)); if (val != hba->lanes_per_direction) { dev_err(hba->dev, "%s: Rx lane mismatch [config,reported] [%d,%d]\n", __func__, hba->lanes_per_direction, val); WARN_ON(1); err = true; } if (err) ufs_qcom_dump_attribs(hba); } static int ufs_qcom_link_startup_notify(struct ufs_hba *hba, enum ufs_notify_change_status status) { Loading Loading @@ -946,6 +1015,7 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba, break; case POST_CHANGE: ufs_qcom_link_startup_post_change(hba); ufs_qcom_validate_link_params(hba); break; default: break; Loading