+static void mv_enable_leds5(struct mv_host_priv *hpriv, void __iomem *mmio)
+{
+ /* FIXME */
+}
+
+static void mv_enable_leds6(struct mv_host_priv *hpriv, void __iomem *mmio)
+{
+ if (hpriv->hp_flags & MV_HP_ERRATA_60X1A1)
+ writel(0x00020060, mmio + MV_GPIO_PORT_CTL);
+
+ else if (hpriv->hp_flags & MV_HP_ERRATA_60X1B0)
+ writel(0x00000060, mmio + MV_GPIO_PORT_CTL);
+}
+
+static void mv_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio)
+{
+ if (IS_50XX(hpriv))
+ mv_enable_leds5(hpriv, mmio);
+ else
+ mv_enable_leds6(hpriv, mmio);
+}
+
+static void mv_cfg_signal5(struct mv_host_priv *hpriv, int idx,
+ void __iomem *mmio)
+{
+ /* FIXME */
+}
+
+static void mv_cfg_signal6(struct mv_host_priv *hpriv, int idx,
+ void __iomem *mmio)
+{
+ void __iomem *port_mmio;
+ u32 tmp;
+
+ if (hpriv->hp_flags & MV_HP_ERRATA_60X1A1) {
+ hpriv->signal[idx].amps = 0x5 << 8;
+ hpriv->signal[idx].pre = 0x3 << 5;
+ return;
+ }
+
+ assert (hpriv->hp_flags & MV_HP_ERRATA_60X1B0);
+
+ tmp = readl(mmio + MV_RESET_CFG);
+ if ((tmp & (1 << 0)) == 0) {
+ hpriv->signal[idx].amps = 0x4 << 8;
+ hpriv->signal[idx].pre = 0x1 << 5;
+ return;
+ }
+
+ port_mmio = mv_port_base(mmio, idx);
+ tmp = readl(port_mmio + PHY_MODE2);
+
+ hpriv->signal[idx].amps = tmp & 0x700; /* bits 10:8 */
+ hpriv->signal[idx].pre = tmp & 0xe0; /* bits 7:5 */
+}
+
+static int mv_cfg_errata(struct pci_dev *pdev, struct mv_host_priv *hpriv,
+ unsigned int board_idx)
+{
+ u8 rev_id;
+ u32 hp_flags = hpriv->hp_flags;
+
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
+
+ switch(board_idx) {
+ case chip_504x:
+ case chip_508x:
+ hp_flags |= MV_HP_50XX;
+
+ if (pdev->device == 0x5080) {
+ switch (rev_id) {
+ case 0x0:
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "Applying B0 workarounds to unknown rev 0\n");
+ /* fall through */
+ case 0x1:
+ hp_flags |= MV_HP_ERRATA_50XXB0;
+ break;
+ case 0x2:
+ hp_flags |= MV_HP_ERRATA_50XXB1;
+ break;
+ case 0x3:
+ hp_flags |= MV_HP_ERRATA_50XXB2;
+ break;
+ default:
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "Applying B2 workarounds to future rev\n");
+ hp_flags |= MV_HP_ERRATA_50XXB2;
+ break;
+ }
+ } else {
+ switch (rev_id) {
+ case 0x0:
+ hp_flags |= MV_HP_ERRATA_50XXB0;
+ break;
+ case 0x1:
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "Applying B1 workarounds to unknown rev 1\n");
+ /* fall through */
+ case 0x2:
+ hp_flags |= MV_HP_ERRATA_50XXB1;
+ break;
+ default:
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "Applying B2 workarounds to future rev\n");
+ /* fall through */
+ case 0x3:
+ hp_flags |= MV_HP_ERRATA_50XXB2;
+ break;
+ }
+ }
+ break;
+
+ case chip_604x:
+ case chip_608x:
+ switch (rev_id) {
+ case 0x0:
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "Applying A1 workarounds to unknown rev 0\n");
+ /* fall through */
+ case 0x1:
+ hp_flags |= MV_HP_ERRATA_60X1A1;
+ break;
+ default:
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "Applying B0 workarounds to future rev\n");
+ /* fall through */
+ case 0x2:
+ hp_flags |= MV_HP_ERRATA_60X1B0;
+ break;
+ }
+ break;
+
+ default:
+ printk(KERN_ERR DRV_NAME ": BUG: invalid board index %u\n", board_idx);
+ return 1;
+ }
+
+ hpriv->hp_flags = hp_flags;
+
+ return 0;
+}
+