| .. | .. |
|---|
| 1636 | 1636 | int downstream_bw) |
|---|
| 1637 | 1637 | { |
|---|
| 1638 | 1638 | u32 val, ubw, dbw, scale; |
|---|
| 1639 | | - int ret; |
|---|
| 1639 | + int ret, max_bw; |
|---|
| 1640 | 1640 | |
|---|
| 1641 | | - /* Read the used scale, hardware default is 0 */ |
|---|
| 1642 | | - ret = tb_port_read(port, &scale, TB_CFG_PORT, |
|---|
| 1643 | | - port->cap_adap + ADP_USB3_CS_3, 1); |
|---|
| 1641 | + /* Figure out suitable scale */ |
|---|
| 1642 | + scale = 0; |
|---|
| 1643 | + max_bw = max(upstream_bw, downstream_bw); |
|---|
| 1644 | + while (scale < 64) { |
|---|
| 1645 | + if (mbps_to_usb3_bw(max_bw, scale) < 4096) |
|---|
| 1646 | + break; |
|---|
| 1647 | + scale++; |
|---|
| 1648 | + } |
|---|
| 1649 | + |
|---|
| 1650 | + if (WARN_ON(scale >= 64)) |
|---|
| 1651 | + return -EINVAL; |
|---|
| 1652 | + |
|---|
| 1653 | + ret = tb_port_write(port, &scale, TB_CFG_PORT, |
|---|
| 1654 | + port->cap_adap + ADP_USB3_CS_3, 1); |
|---|
| 1644 | 1655 | if (ret) |
|---|
| 1645 | 1656 | return ret; |
|---|
| 1646 | 1657 | |
|---|
| 1647 | | - scale &= ADP_USB3_CS_3_SCALE_MASK; |
|---|
| 1648 | 1658 | ubw = mbps_to_usb3_bw(upstream_bw, scale); |
|---|
| 1649 | 1659 | dbw = mbps_to_usb3_bw(downstream_bw, scale); |
|---|
| 1650 | 1660 | |
|---|
| 1661 | + tb_port_dbg(port, "scaled bandwidth %u/%u, scale %u\n", ubw, dbw, scale); |
|---|
| 1662 | + |
|---|
| 1651 | 1663 | ret = tb_port_read(port, &val, TB_CFG_PORT, |
|---|
| 1652 | 1664 | port->cap_adap + ADP_USB3_CS_2, 1); |
|---|
| 1653 | 1665 | if (ret) |
|---|