Commit 1f80769ffd36e74357fe896dc43dddf1af1510f3
Committed by
Linus Torvalds
1 parent
a50b0aa4bd
Exists in
master
and in
4 other branches
synclink_gt: add clock options
Add support for x8 asynchronous sample rate and ability to specify base clock frequency. Signed-off-by: Paul Fulghum <paulkf@microgate.com> Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 39 additions and 20 deletions Side-by-side Diff
drivers/char/synclink_gt.c
... | ... | @@ -298,6 +298,7 @@ |
298 | 298 | |
299 | 299 | unsigned int rbuf_fill_level; |
300 | 300 | unsigned int if_mode; |
301 | + unsigned int base_clock; | |
301 | 302 | |
302 | 303 | /* device status */ |
303 | 304 | |
304 | 305 | |
... | ... | @@ -1156,22 +1157,26 @@ |
1156 | 1157 | return -EFAULT; |
1157 | 1158 | |
1158 | 1159 | spin_lock(&info->lock); |
1159 | - info->params.mode = tmp_params.mode; | |
1160 | - info->params.loopback = tmp_params.loopback; | |
1161 | - info->params.flags = tmp_params.flags; | |
1162 | - info->params.encoding = tmp_params.encoding; | |
1163 | - info->params.clock_speed = tmp_params.clock_speed; | |
1164 | - info->params.addr_filter = tmp_params.addr_filter; | |
1165 | - info->params.crc_type = tmp_params.crc_type; | |
1166 | - info->params.preamble_length = tmp_params.preamble_length; | |
1167 | - info->params.preamble = tmp_params.preamble; | |
1168 | - info->params.data_rate = tmp_params.data_rate; | |
1169 | - info->params.data_bits = tmp_params.data_bits; | |
1170 | - info->params.stop_bits = tmp_params.stop_bits; | |
1171 | - info->params.parity = tmp_params.parity; | |
1160 | + if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) { | |
1161 | + info->base_clock = tmp_params.clock_speed; | |
1162 | + } else { | |
1163 | + info->params.mode = tmp_params.mode; | |
1164 | + info->params.loopback = tmp_params.loopback; | |
1165 | + info->params.flags = tmp_params.flags; | |
1166 | + info->params.encoding = tmp_params.encoding; | |
1167 | + info->params.clock_speed = tmp_params.clock_speed; | |
1168 | + info->params.addr_filter = tmp_params.addr_filter; | |
1169 | + info->params.crc_type = tmp_params.crc_type; | |
1170 | + info->params.preamble_length = tmp_params.preamble_length; | |
1171 | + info->params.preamble = tmp_params.preamble; | |
1172 | + info->params.data_rate = tmp_params.data_rate; | |
1173 | + info->params.data_bits = tmp_params.data_bits; | |
1174 | + info->params.stop_bits = tmp_params.stop_bits; | |
1175 | + info->params.parity = tmp_params.parity; | |
1176 | + } | |
1172 | 1177 | spin_unlock(&info->lock); |
1173 | 1178 | |
1174 | - change_params(info); | |
1179 | + program_hw(info); | |
1175 | 1180 | |
1176 | 1181 | return 0; |
1177 | 1182 | } |
1178 | 1183 | |
... | ... | @@ -2559,10 +2564,13 @@ |
2559 | 2564 | return -EFAULT; |
2560 | 2565 | |
2561 | 2566 | spin_lock_irqsave(&info->lock, flags); |
2562 | - memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS)); | |
2567 | + if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) | |
2568 | + info->base_clock = tmp_params.clock_speed; | |
2569 | + else | |
2570 | + memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS)); | |
2563 | 2571 | spin_unlock_irqrestore(&info->lock, flags); |
2564 | 2572 | |
2565 | - change_params(info); | |
2573 | + program_hw(info); | |
2566 | 2574 | |
2567 | 2575 | return 0; |
2568 | 2576 | } |
... | ... | @@ -3432,6 +3440,7 @@ |
3432 | 3440 | info->magic = MGSL_MAGIC; |
3433 | 3441 | INIT_WORK(&info->task, bh_handler); |
3434 | 3442 | info->max_frame_size = 4096; |
3443 | + info->base_clock = 14745600; | |
3435 | 3444 | info->rbuf_fill_level = DMABUFSIZE; |
3436 | 3445 | info->port.close_delay = 5*HZ/10; |
3437 | 3446 | info->port.closing_wait = 30*HZ; |
... | ... | @@ -3779,7 +3788,7 @@ |
3779 | 3788 | static void set_rate(struct slgt_info *info, u32 rate) |
3780 | 3789 | { |
3781 | 3790 | unsigned int div; |
3782 | - static unsigned int osc = 14745600; | |
3791 | + unsigned int osc = info->base_clock; | |
3783 | 3792 | |
3784 | 3793 | /* div = osc/rate - 1 |
3785 | 3794 | * |
3786 | 3795 | |
3787 | 3796 | |
... | ... | @@ -4083,17 +4092,26 @@ |
4083 | 4092 | * 06 CTS IRQ enable |
4084 | 4093 | * 05 DCD IRQ enable |
4085 | 4094 | * 04 RI IRQ enable |
4086 | - * 03 reserved, must be zero | |
4095 | + * 03 0=16x sampling, 1=8x sampling | |
4087 | 4096 | * 02 1=txd->rxd internal loopback enable |
4088 | 4097 | * 01 reserved, must be zero |
4089 | 4098 | * 00 1=master IRQ enable |
4090 | 4099 | */ |
4091 | 4100 | val = BIT15 + BIT14 + BIT0; |
4101 | + /* JCR[8] : 1 = x8 async mode feature available */ | |
4102 | + if ((rd_reg32(info, JCR) & BIT8) && info->params.data_rate && | |
4103 | + ((info->base_clock < (info->params.data_rate * 16)) || | |
4104 | + (info->base_clock % (info->params.data_rate * 16)))) { | |
4105 | + /* use 8x sampling */ | |
4106 | + val |= BIT3; | |
4107 | + set_rate(info, info->params.data_rate * 8); | |
4108 | + } else { | |
4109 | + /* use 16x sampling */ | |
4110 | + set_rate(info, info->params.data_rate * 16); | |
4111 | + } | |
4092 | 4112 | wr_reg16(info, SCR, val); |
4093 | 4113 | |
4094 | 4114 | slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER); |
4095 | - | |
4096 | - set_rate(info, info->params.data_rate * 16); | |
4097 | 4115 | |
4098 | 4116 | if (info->params.loopback) |
4099 | 4117 | enable_loopback(info); |
include/linux/synclink.h