aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoff Levand <geoffrey.levand@am.sony.com>2006-12-08 21:27:47 -0500
committerPaul Mackerras <paulus@samba.org>2006-12-10 21:49:53 -0500
commit74e95d5de9d8eb243cda68b546bdb29f6ef0f01c (patch)
treec1f3a14628510af3ca134da5db409dcc8d428e99
parent0204568a088fecd5478153504f9476ee2c46d5bf (diff)
[POWERPC] ps3: Add vuart support
Adds support for the PS3 virtual UART (vuart). The vuart provides a bi-directional byte stream data link between logical partitions. This is needed for the ps3 graphics driver and the ps3 power control support to be able to communicate with the lv1 policy module. Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/configs/ps3_defconfig1
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig11
-rw-r--r--drivers/ps3/Makefile1
-rw-r--r--drivers/ps3/vuart.c965
-rw-r--r--drivers/ps3/vuart.h94
5 files changed, 1072 insertions, 0 deletions
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index f2d888e014..70ed61337f 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -157,6 +157,7 @@ CONFIG_SPU_BASE=y
157CONFIG_PS3_HTAB_SIZE=20 157CONFIG_PS3_HTAB_SIZE=20
158CONFIG_PS3_DYNAMIC_DMA=y 158CONFIG_PS3_DYNAMIC_DMA=y
159CONFIG_PS3_USE_LPAR_ADDR=y 159CONFIG_PS3_USE_LPAR_ADDR=y
160CONFIG_PS3_VUART=y
160 161
161# 162#
162# Kernel options 163# Kernel options
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 451bfcd550..de52ec4e9e 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -40,4 +40,15 @@ config PS3_USE_LPAR_ADDR
40 40
41 If you have any doubt, choose the default y. 41 If you have any doubt, choose the default y.
42 42
43config PS3_VUART
44 depends on PPC_PS3
45 bool "PS3 Virtual UART support"
46 default y
47 help
48 Include support for the PS3 Virtual UART.
49
50 This support is required for several system services
51 including the System Manager and AV Settings. In
52 general, all users will say Y.
53
43endmenu 54endmenu
diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile
index b52d547b7a..8433eb7562 100644
--- a/drivers/ps3/Makefile
+++ b/drivers/ps3/Makefile
@@ -1 +1,2 @@
1obj-y += system-bus.o 1obj-y += system-bus.o
2obj-$(CONFIG_PS3_VUART) += vuart.o
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
new file mode 100644
index 0000000000..6974f65bcd
--- /dev/null
+++ b/drivers/ps3/vuart.c
@@ -0,0 +1,965 @@
1/*
2 * PS3 virtual uart
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/interrupt.h>
24#include <asm/ps3.h>
25
26#include <asm/lv1call.h>
27#include <asm/bitops.h>
28
29#include "vuart.h"
30
31MODULE_AUTHOR("Sony Corporation");
32MODULE_LICENSE("GPL v2");
33MODULE_DESCRIPTION("ps3 vuart");
34
35/**
36 * vuart - An inter-partition data link service.
37 * port 0: PS3 AV Settings.
38 * port 2: PS3 System Manager.
39 *
40 * The vuart provides a bi-directional byte stream data link between logical
41 * partitions. Its primary role is as a communications link between the guest
42 * OS and the system policy module. The current HV does not support any
43 * connections other than those listed.
44 */
45
46enum {PORT_COUNT = 3,};
47
48enum vuart_param {
49 PARAM_TX_TRIGGER = 0,
50 PARAM_RX_TRIGGER = 1,
51 PARAM_INTERRUPT_MASK = 2,
52 PARAM_RX_BUF_SIZE = 3, /* read only */
53 PARAM_RX_BYTES = 4, /* read only */
54 PARAM_TX_BUF_SIZE = 5, /* read only */
55 PARAM_TX_BYTES = 6, /* read only */
56 PARAM_INTERRUPT_STATUS = 7, /* read only */
57};
58
59enum vuart_interrupt_bit {
60 INTERRUPT_BIT_TX = 0,
61 INTERRUPT_BIT_RX = 1,
62 INTERRUPT_BIT_DISCONNECT = 2,
63};
64
65enum vuart_interrupt_mask {
66 INTERRUPT_MASK_TX = 1,
67 INTERRUPT_MASK_RX = 2,
68 INTERRUPT_MASK_DISCONNECT = 4,
69};
70
71/**
72 * struct ports_bmp - bitmap indicating ports needing service.
73 *
74 * A 256 bit read only bitmap indicating ports needing service. Do not write
75 * to these bits. Must not cross a page boundary.
76 */
77
78struct ports_bmp {
79 u64 status;
80 u64 unused[3];
81} __attribute__ ((aligned (32)));
82
83/* redefine dev_dbg to do a syntax check */
84
85#if !defined(DEBUG)
86#undef dev_dbg
87static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg(
88 const struct device *_dev, const char *fmt, ...) {return 0;}
89#endif
90
91#define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__)
92static void __attribute__ ((unused)) _dump_ports_bmp(
93 const struct ports_bmp* bmp, const char* func, int line)
94{
95 pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status);
96}
97
98static int ps3_vuart_match_id_to_port(enum ps3_match_id match_id,
99 unsigned int *port_number)
100{
101 switch(match_id) {
102 case PS3_MATCH_ID_AV_SETTINGS:
103 *port_number = 0;
104 return 0;
105 case PS3_MATCH_ID_SYSTEM_MANAGER:
106 *port_number = 2;
107 return 0;
108 default:
109 WARN_ON(1);
110 *port_number = UINT_MAX;
111 return -EINVAL;
112 };
113}
114
115#define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__)
116static void __attribute__ ((unused)) _dump_port_params(unsigned int port_number,
117 const char* func, int line)
118{
119#if defined(DEBUG)
120 static const char *strings[] = {
121 "tx_trigger ",
122 "rx_trigger ",
123 "interrupt_mask ",
124 "rx_buf_size ",
125 "rx_bytes ",
126 "tx_buf_size ",
127 "tx_bytes ",
128 "interrupt_status",
129 };
130 int result;
131 unsigned int i;
132 u64 value;
133
134 for (i = 0; i < ARRAY_SIZE(strings); i++) {
135 result = lv1_get_virtual_uart_param(port_number, i, &value);
136
137 if (result) {
138 pr_debug("%s:%d: port_%u: %s failed: %s\n", func, line,
139 port_number, strings[i], ps3_result(result));
140 continue;
141 }
142 pr_debug("%s:%d: port_%u: %s = %lxh\n",
143 func, line, port_number, strings[i], value);
144 }
145#endif
146}
147
148struct vuart_triggers {
149 unsigned long rx;
150 unsigned long tx;
151};
152
153int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
154 struct vuart_triggers *trig)
155{
156 int result;
157 unsigned long size;
158 unsigned long val;
159
160 result = lv1_get_virtual_uart_param(dev->port_number,
161 PARAM_TX_TRIGGER, &trig->tx);
162
163 if (result) {
164 dev_dbg(&dev->core, "%s:%d: tx_trigger failed: %s\n",
165 __func__, __LINE__, ps3_result(result));
166 return result;
167 }
168
169 result = lv1_get_virtual_uart_param(dev->port_number,
170 PARAM_RX_BUF_SIZE, &size);
171
172 if (result) {
173 dev_dbg(&dev->core, "%s:%d: tx_buf_size failed: %s\n",
174 __func__, __LINE__, ps3_result(result));
175 return result;
176 }
177
178 result = lv1_get_virtual_uart_param(dev->port_number,
179 PARAM_RX_TRIGGER, &val);
180
181 if (result) {
182 dev_dbg(&dev->core, "%s:%d: rx_trigger failed: %s\n",