1921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa/*
2921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * SBE 2T3E3 synchronous serial card driver for Linux
3921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa *
4921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
5921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa *
6921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * This program is free software; you can redistribute it and/or modify it
7921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * under the terms of version 2 of the GNU General Public License
8921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * as published by the Free Software Foundation.
9921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa *
10921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * This code is based on a driver written by SBE Inc.
11921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa */
12921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
13921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#include <linux/ip.h>
14921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#include "2t3e3.h"
15921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#include "ctrl.h"
16921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
17921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa/* All access to registers done via the 21143 on port 0 must be
18921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * protected via the card->bootrom_lock. */
19921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
20921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa/* priviate define to be used here only - must be protected by card->bootrom_lock */
21921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#define cpld_write_nolock(channel, reg, val)			\
22921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	bootrom_write((channel), CPLD_MAP_REG(reg, channel), val)
23921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
24921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasau32 cpld_read(struct channel *channel, u32 reg)
25921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
26921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned long flags;
27921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 val;
28921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
29921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_lock_irqsave(&channel->card->bootrom_lock, flags);
30921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	val = bootrom_read((channel), CPLD_MAP_REG(reg, channel));
31921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
32921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	return val;
33921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
34921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
35921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa/****************************************
36921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * Access via BootROM port
37921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa ****************************************/
38921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
39921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasau32 bootrom_read(struct channel *channel, u32 reg)
40921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
41921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned long addr = channel->card->bootrom_addr;
42921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 result;
43921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
44921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select BootROM address */
45921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS, reg & 0x3FFFF);
46921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
47921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select reading from BootROM */
48921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
49921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_READ_OPERATION |
50921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT);
51921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
52921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	udelay(2); /* 20 PCI cycles */
53921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
54921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* read from BootROM */
55921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	result = dc_read(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT) & 0xff;
56921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
57921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* reset CSR9 */
58921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
59921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
60921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	return result;
61921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
62921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
63921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasavoid bootrom_write(struct channel *channel, u32 reg, u32 val)
64921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
65921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned long addr = channel->card->bootrom_addr;
66921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
67921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select BootROM address */
68921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS, reg & 0x3FFFF);
69921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
70921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select writting to BootROM */
71921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
72921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_WRITE_OPERATION |
73921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT |
74921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 (val & 0xff));
75921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
76921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	udelay(2); /* 20 PCI cycles */
77921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
78921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* reset CSR9 */
79921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
80921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
81921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
82921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
83921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa/****************************************
84921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * Access via Serial I/O port
85921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa ****************************************/
86921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
87921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasastatic u32 serialrom_read_bit(struct channel *channel)
88921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
89921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned long addr = channel->card->bootrom_addr;
90921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 bit;
91921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
92921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
93921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_READ_OPERATION |
94921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
95921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK |
96921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT);	/* clock high */
97921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
98921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	bit = (dc_read(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT) &
99921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	       SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_OUT) > 0 ? 1 : 0;
100921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
101921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
102921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_READ_OPERATION |
103921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
104921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT);	/* clock low */
105921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
106921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	return bit;
107921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
108921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
109921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasastatic void serialrom_write_bit(struct channel *channel, u32 bit)
110921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
111921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned long addr = channel->card->bootrom_addr;
112921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 lastbit = -1;
113921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
114921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	bit &= 1;
115921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
116921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	if (bit != lastbit) {
117921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
118921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			 SBE_2T3E3_21143_VAL_WRITE_OPERATION |
119921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			 SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
120921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			 SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
121921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			 (bit << 2)); /* clock low */
122921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
123921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		lastbit = bit;
124921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
125921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
126921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
127921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_WRITE_OPERATION |
128921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
129921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK |
130921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
131921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 (bit << 2)); /* clock high */
132921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
133921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
134921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_WRITE_OPERATION |
135921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
136921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
137921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 (bit << 2)); /* clock low */
138921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
139921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
140921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa/****************************************
141921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * Access to SerialROM (eeprom)
142921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa ****************************************/
143921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
144921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasau32 t3e3_eeprom_read_word(struct channel *channel, u32 address)
145921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
146921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned long addr = channel->card->bootrom_addr;
147921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 i, val;
148921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned long flags;
149921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
150921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	address &= 0x3f;
151921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
152921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_lock_irqsave(&channel->card->bootrom_lock, flags);
153921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
154921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select correct Serial Chip */
155921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
156921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			  SBE_2T3E3_CPLD_VAL_EEPROM_SELECT);
157921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
158921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select reading from Serial I/O Bus */
159921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
160921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_READ_OPERATION |
161921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
162921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT);        /* clock low */
163921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
164921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select read operation */
165921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	serialrom_write_bit(channel, 0);
166921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	serialrom_write_bit(channel, 1);
167921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	serialrom_write_bit(channel, 1);
168921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	serialrom_write_bit(channel, 0);
169921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
170921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	for (i = 0x20; i; i >>= 1)
171921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		serialrom_write_bit(channel, address & i ? 1 : 0);
172921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
173921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	val = 0;
174921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	for (i = 0x8000; i; i >>= 1)
175921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		val |= (serialrom_read_bit(channel) ? i : 0);
176921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
177921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* Reset 21143's CSR9 */
178921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
179921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_READ_OPERATION |
180921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
181921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT);        /* clock low */
182921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
183921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
184921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* Unselect Serial Chip */
185921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
186921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
187921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
188921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
189921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	return ntohs(val);
190921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
191921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
192921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
193921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa/****************************************
194921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * Access to Framer
195921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa ****************************************/
196921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
197921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasau32 exar7250_read(struct channel *channel, u32 reg)
198921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
199921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 result;
200921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned long flags;
201921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
202921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#if 0
203921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	switch (reg) {
204921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_FRAMER_REG_OPERATING_MODE:
205921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		return channel->framer_regs[reg];
206921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		break;
207921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	default:
208921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
209921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#endif
210921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
211921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_lock_irqsave(&channel->card->bootrom_lock, flags);
212921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
213921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	result = bootrom_read(channel, cpld_reg_map[SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS]
214921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			      [channel->h.slot] + (t3e3_framer_reg_map[reg] << 2));
215921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
216921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
217921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
218921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	return result;
219921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
220921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
221921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasavoid exar7250_write(struct channel *channel, u32 reg, u32 val)
222921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
223921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned long flags;
224921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
225921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	val &= 0xff;
226921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	channel->framer_regs[reg] = val;
227921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
228921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_lock_irqsave(&channel->card->bootrom_lock, flags);
229921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
230921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	bootrom_write(channel, cpld_reg_map[SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS]
231921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		      [channel->h.slot] + (t3e3_framer_reg_map[reg] << 2), val);
232921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
233921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
234921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
235921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
236921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
237921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa/****************************************
238921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa * Access to LIU
239921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa ****************************************/
240921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
241921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasau32 exar7300_read(struct channel *channel, u32 reg)
242921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
243921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned long addr = channel->card->bootrom_addr, flags;
244921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 i, val;
245921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
246921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#if 0
247921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	switch (reg) {
248921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_LIU_REG_REG1:
249921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_LIU_REG_REG2:
250921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_LIU_REG_REG3:
251921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	case SBE_2T3E3_LIU_REG_REG4:
252921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		return channel->liu_regs[reg];
253921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		break;
254921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	default:
255921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
256921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa#endif
257921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
258921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select correct Serial Chip */
259921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
260921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_lock_irqsave(&channel->card->bootrom_lock, flags);
261921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
262921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
263921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			  cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_SELECT][channel->h.slot]);
264921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
265921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select reading from Serial I/O Bus */
266921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
267921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_READ_OPERATION |
268921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
269921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT);	/* clock low */
270921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
271921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select read operation */
272921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	serialrom_write_bit(channel, 1);
273921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
274921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* Exar7300 register address is 4 bit long */
275921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	reg = t3e3_liu_reg_map[reg];
276921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	for (i = 0; i < 4; i++, reg >>= 1) /* 4 bits of SerialROM address */
277921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		serialrom_write_bit(channel, reg & 1);
278921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	for (i = 0; i < 3; i++)	/* remaining 3 bits of SerialROM address */
279921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		serialrom_write_bit(channel, 0);
280921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
281921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	val = 0; /* Exar7300 register value is 5 bit long */
282921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	for (i = 0; i < 8; i++)	/* 8 bits of SerialROM value */
283921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		val += (serialrom_read_bit(channel) << i);
284921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
285921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* Reset 21143's CSR9 */
286921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
287921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_READ_OPERATION |
288921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
289921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT);	/* clock low */
290921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
291921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
292921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* Unselect Serial Chip */
293921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
294921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
295921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
296921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
297921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	return val;
298921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
299921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
300921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasavoid exar7300_write(struct channel *channel, u32 reg, u32 val)
301921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa{
302921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	unsigned long addr = channel->card->bootrom_addr, flags;
303921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	u32 i;
304921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
305921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	channel->liu_regs[reg] = val;
306921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
307921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select correct Serial Chip */
308921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
309921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_lock_irqsave(&channel->card->bootrom_lock, flags);
310921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
311921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
312921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa			  cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_SELECT][channel->h.slot]);
313921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
314921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select writting to Serial I/O Bus */
315921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
316921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_WRITE_OPERATION |
317921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
318921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT);	/* clock low */
319921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
320921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* select write operation */
321921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	serialrom_write_bit(channel, 0);
322921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
323921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* Exar7300 register address is 4 bit long */
324921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	reg = t3e3_liu_reg_map[reg];
325921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	for (i = 0; i < 4; i++) {	/* 4 bits */
326921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		serialrom_write_bit(channel, reg & 1);
327921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		reg >>= 1;
328921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
329921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	for (i = 0; i < 3; i++)	/* remaining 3 bits of SerialROM address */
330921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		serialrom_write_bit(channel, 0);
331921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
332921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* Exar7300 register value is 5 bit long */
333921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	for (i = 0; i < 5; i++) {
334921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		serialrom_write_bit(channel, val & 1);
335921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		val >>= 1;
336921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	}
337921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	for (i = 0; i < 3; i++)	/* remaining 3 bits of SerialROM value */
338921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		serialrom_write_bit(channel, 0);
339921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
340921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* Reset 21143_CSR9 */
341921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
342921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_WRITE_OPERATION |
343921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
344921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa		 SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT);	/* clock low */
345921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
346921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
347921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	/* Unselect Serial Chip */
348921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
349921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa
350921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa	spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
351921a86e0e306e42452e16894f2cc792659ede16bKrzysztof Halasa}
352