1 /* 2 * PowerMac G5 SMU driver 3 * 4 * Copyright 2004 J. Mayer <l_indien@magic.fr> 5 * Copyright 2005 Benjamin Herrenschmidt, IBM Corp. 6 * 7 * Released under the term of the GNU GPL v2. 8 */ 9 10 /* 11 * For now, this driver includes: 12 * - RTC get & set 13 * - reboot & shutdown commands 14 * all synchronous with IRQ disabled (ugh) 15 * 16 * TODO: 17 * rework in a way the PMU driver works, that is asynchronous 18 * with a queue of commands. I'll do that as soon as I have an 19 * SMU based machine at hand. Some more cleanup is needed too, 20 * like maybe fitting it into a platform device, etc... 21 * Also check what's up with cache coherency, and if we really 22 * can't do better than flushing the cache, maybe build a table 23 * of command len/reply len like the PMU driver to only flush 24 * what is actually necessary. 25 * --BenH. 26 */ 27 28 #include <linux/config.h> 29 #include <linux/types.h> 30 #include <linux/kernel.h> 31 #include <linux/device.h> 32 #include <linux/dmapool.h> 33 #include <linux/bootmem.h> 34 #include <linux/vmalloc.h> 35 #include <linux/highmem.h> 36 #include <linux/jiffies.h> 37 #include <linux/interrupt.h> 38 #include <linux/rtc.h> 39 40 #include <asm/byteorder.h> 41 #include <asm/io.h> 42 #include <asm/prom.h> 43 #include <asm/machdep.h> 44 #include <asm/pmac_feature.h> 45 #include <asm/smu.h> 46 #include <asm/sections.h> 47 #include <asm/abs_addr.h> 48 49 #define DEBUG_SMU 1 50 51 #ifdef DEBUG_SMU 52 #define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0) 53 #else 54 #define DPRINTK(fmt, args...) do { } while (0) 55 #endif 56 57 /* 58 * This is the command buffer passed to the SMU hardware 59 */ 60 struct smu_cmd_buf { 61 u8 cmd; 62 u8 length; 63 u8 data[0x0FFE]; 64 }; 65 66 struct smu_device { 67 spinlock_t lock; 68 struct device_node *of_node; 69 int db_ack; /* doorbell ack GPIO */ 70 int db_req; /* doorbell req GPIO */ 71 u32 __iomem *db_buf; /* doorbell buffer */ 72 struct smu_cmd_buf *cmd_buf; /* command buffer virtual */ 73 u32 cmd_buf_abs; /* command buffer absolute */ 74 }; 75 76 /* 77 * I don't think there will ever be more than one SMU, so 78 * for now, just hard code that 79 */ 80 static struct smu_device *smu; 81 82 /* 83 * SMU low level communication stuff 84 */ 85 static inline int smu_cmd_stat(struct smu_cmd_buf *cmd_buf, u8 cmd_ack) 86 { 87 rmb(); 88 return cmd_buf->cmd == cmd_ack && cmd_buf->length != 0; 89 } 90 91 static inline u8 smu_save_ack_cmd(struct smu_cmd_buf *cmd_buf) 92 { 93 return (~cmd_buf->cmd) & 0xff; 94 } 95 96 static void smu_send_cmd(struct smu_device *dev) 97 { 98 /* SMU command buf is currently cacheable, we need a physical 99 * address. This isn't exactly a DMA mapping here, I suspect 100 * the SMU is actually communicating with us via i2c to the 101 * northbridge or the CPU to access RAM. 102 */ 103 writel(dev->cmd_buf_abs, dev->db_buf); 104 105 /* Ring the SMU doorbell */ 106 pmac_do_feature_call(PMAC_FTR_WRITE_GPIO, NULL, dev->db_req, 4); 107 pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, dev->db_req, 4); 108 } 109 110 static int smu_cmd_done(struct smu_device *dev) 111 { 112 unsigned long wait = 0; 113 int gpio; 114 115 /* Check the SMU doorbell */ 116 do { 117 gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, 118 NULL, dev->db_ack); 119 if ((gpio & 7) == 7) 120 return 0; 121 udelay(100); 122 } while(++wait < 10000); 123 124 printk(KERN_ERR "SMU timeout !\n"); 125 return -ENXIO; 126 } 127 128 static int smu_do_cmd(struct smu_device *dev) 129 { 130 int rc; 131 u8 cmd_ack; 132 133 DPRINTK("SMU do_cmd %02x len=%d %02x\n", 134 dev->cmd_buf->cmd, dev->cmd_buf->length, 135 dev->cmd_buf->data[0]); 136 137 cmd_ack = smu_save_ack_cmd(dev->cmd_buf); 138 139 /* Clear cmd_buf cache lines */ 140 flush_inval_dcache_range((unsigned long)dev->cmd_buf, 141 ((unsigned long)dev->cmd_buf) + 142 sizeof(struct smu_cmd_buf)); 143 smu_send_cmd(dev); 144 rc = smu_cmd_done(dev); 145 if (rc == 0) 146 rc = smu_cmd_stat(dev->cmd_buf, cmd_ack) ? 0 : -1; 147 148 DPRINTK("SMU do_cmd %02x len=%d %02x => %d (%02x)\n", 149 dev->cmd_buf->cmd, dev->cmd_buf->length, 150 dev->cmd_buf->data[0], rc, cmd_ack); 151 152 return rc; 153 } 154 155 /* RTC low level commands */ 156 static inline int bcd2hex (int n) 157 { 158 return (((n & 0xf0) >> 4) * 10) + (n & 0xf); 159 } 160 161 static inline int hex2bcd (int n) 162 { 163 return ((n / 10) << 4) + (n % 10); 164 } 165 166 #if 0 167 static inline void smu_fill_set_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf) 168 { 169 cmd_buf->cmd = 0x8e; 170 cmd_buf->length = 8; 171 cmd_buf->data[0] = 0x00; 172 memset(cmd_buf->data + 1, 0, 7); 173 } 174 175 static inline void smu_fill_get_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf) 176 { 177 cmd_buf->cmd = 0x8e; 178 cmd_buf->length = 1; 179 cmd_buf->data[0] = 0x01; 180 } 181 182 static inline void smu_fill_dis_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf) 183 { 184 cmd_buf->cmd = 0x8e; 185 cmd_buf->length = 1; 186 cmd_buf->data[0] = 0x02; 187 } 188 #endif 189 190 static inline void smu_fill_set_rtc_cmd(struct smu_cmd_buf *cmd_buf, 191 struct rtc_time *time) 192 { 193 cmd_buf->cmd = 0x8e; 194 cmd_buf->length = 8; 195 cmd_buf->data[0] = 0x80; 196 cmd_buf->data[1] = hex2bcd(time->tm_sec); 197 cmd_buf->data[2] = hex2bcd(time->tm_min); 198 cmd_buf->data[3] = hex2bcd(time->tm_hour); 199 cmd_buf->data[4] = time->tm_wday; 200 cmd_buf->data[5] = hex2bcd(time->tm_mday); 201 cmd_buf->data[6] = hex2bcd(time->tm_mon) + 1; 202 cmd_buf->data[7] = hex2bcd(time->tm_year - 100); 203 } 204 205 static inline void smu_fill_get_rtc_cmd(struct smu_cmd_buf *cmd_buf) 206 { 207 cmd_buf->cmd = 0x8e; 208 cmd_buf->length = 1; 209 cmd_buf->data[0] = 0x81; 210 } 211 212 static void smu_parse_get_rtc_reply(struct smu_cmd_buf *cmd_buf, 213 struct rtc_time *time) 214 { 215 time->tm_sec = bcd2hex(cmd_buf->data[0]); 216 time->tm_min = bcd2hex(cmd_buf->data[1]); 217 time->tm_hour = bcd2hex(cmd_buf->data[2]); 218 time->tm_wday = bcd2hex(cmd_buf->data[3]); 219 time->tm_mday = bcd2hex(cmd_buf->data[4]); 220 time->tm_mon = bcd2hex(cmd_buf->data[5]) - 1; 221 time->tm_year = bcd2hex(cmd_buf->data[6]) + 100; 222 } 223 224 int smu_get_rtc_time(struct rtc_time *time) 225 { 226 unsigned long flags; 227 int rc; 228 229 if (smu == NULL) 230 return -ENODEV; 231 232 memset(time, 0, sizeof(struct rtc_time)); 233 spin_lock_irqsave(&smu->lock, flags); 234 smu_fill_get_rtc_cmd(smu->cmd_buf); 235 rc = smu_do_cmd(smu); 236 if (rc == 0) 237 smu_parse_get_rtc_reply(smu->cmd_buf, time); 238 spin_unlock_irqrestore(&smu->lock, flags); 239 240 return rc; 241 } 242 243 int smu_set_rtc_time(struct rtc_time *time) 244 { 245 unsigned long flags; 246 int rc; 247 248 if (smu == NULL) 249 return -ENODEV; 250 251 spin_lock_irqsave(&smu->lock, flags); 252 smu_fill_set_rtc_cmd(smu->cmd_buf, time); 253 rc = smu_do_cmd(smu); 254 spin_unlock_irqrestore(&smu->lock, flags); 255 256 return rc; 257 } 258 259 void smu_shutdown(void) 260 { 261 const unsigned char *command = "SHUTDOWN"; 262 unsigned long flags; 263 264 if (smu == NULL) 265 return; 266 267 spin_lock_irqsave(&smu->lock, flags); 268 smu->cmd_buf->cmd = 0xaa; 269 smu->cmd_buf->length = strlen(command); 270 strcpy(smu->cmd_buf->data, command); 271 smu_do_cmd(smu); 272 for (;;) 273 ; 274 spin_unlock_irqrestore(&smu->lock, flags); 275 } 276 277 void smu_restart(void) 278 { 279 const unsigned char *command = "RESTART"; 280 unsigned long flags; 281 282 if (smu == NULL) 283 return; 284 285 spin_lock_irqsave(&smu->lock, flags); 286 smu->cmd_buf->cmd = 0xaa; 287 smu->cmd_buf->length = strlen(command); 288 strcpy(smu->cmd_buf->data, command); 289 smu_do_cmd(smu); 290 for (;;) 291 ; 292 spin_unlock_irqrestore(&smu->lock, flags); 293 } 294 295 int smu_present(void) 296 { 297 return smu != NULL; 298 } 299 300 301 int smu_init (void) 302 { 303 struct device_node *np; 304 u32 *data; 305 306 np = of_find_node_by_type(NULL, "smu"); 307 if (np == NULL) 308 return -ENODEV; 309 310 if (smu_cmdbuf_abs == 0) { 311 printk(KERN_ERR "SMU: Command buffer not allocated !\n"); 312 return -EINVAL; 313 } 314 315 smu = alloc_bootmem(sizeof(struct smu_device)); 316 if (smu == NULL) 317 return -ENOMEM; 318 memset(smu, 0, sizeof(*smu)); 319 320 spin_lock_init(&smu->lock); 321 smu->of_node = np; 322 /* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a 323 * 32 bits value safely 324 */ 325 smu->cmd_buf_abs = (u32)smu_cmdbuf_abs; 326 smu->cmd_buf = (struct smu_cmd_buf *)abs_to_virt(smu_cmdbuf_abs); 327 328 np = of_find_node_by_name(NULL, "smu-doorbell"); 329 if (np == NULL) { 330 printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); 331 goto fail; 332 } 333 data = (u32 *)get_property(np, "reg", NULL); 334 of_node_put(np); 335 if (data == NULL) { 336 printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); 337 goto fail; 338 } 339 340 /* Current setup has one doorbell GPIO that does both doorbell 341 * and ack. GPIOs are at 0x50, best would be to find that out 342 * in the device-tree though. 343 */ 344 smu->db_req = 0x50 + *data; 345 smu->db_ack = 0x50 + *data; 346 347 /* Doorbell buffer is currently hard-coded, I didn't find a proper 348 * device-tree entry giving the address. Best would probably to use 349 * an offset for K2 base though, but let's do it that way for now. 350 */ 351 smu->db_buf = ioremap(0x8000860c, 0x1000); 352 if (smu->db_buf == NULL) { 353 printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n"); 354 goto fail; 355 } 356 357 sys_ctrler = SYS_CTRLER_SMU; 358 return 0; 359 360 fail: 361 smu = NULL; 362 return -ENXIO; 363 364 } 365