Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* Board-specific reboot/shutdown routines
0003  *
0004  * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
0005  *
0006  * Copyright (C) 2009 Lemote Inc.
0007  * Author: Wu Zhangjin, wuzhangjin@gmail.com
0008  */
0009 
0010 #include <linux/io.h>
0011 #include <linux/delay.h>
0012 #include <linux/types.h>
0013 
0014 #include <asm/bootinfo.h>
0015 
0016 #include <loongson.h>
0017 
0018 #include <cs5536/cs5536.h>
0019 #include "ec_kb3310b.h"
0020 
0021 static void reset_cpu(void)
0022 {
0023     /*
0024      * reset cpu to full speed, this is needed when enabling cpu frequency
0025      * scalling
0026      */
0027     writel(readl(LOONGSON_CHIPCFG) | 0x7, LOONGSON_CHIPCFG);
0028 }
0029 
0030 /* reset support for fuloong2f */
0031 
0032 static void fl2f_reboot(void)
0033 {
0034     reset_cpu();
0035 
0036     /* send a reset signal to south bridge.
0037      *
0038      * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset
0039      * normally with this reset operation and it will not work in PMON, but
0040      * you can type halt command and then reboot, seems the hardware reset
0041      * logic not work normally.
0042      */
0043     {
0044         u32 hi, lo;
0045         _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo);
0046         lo |= 0x00000001;
0047         _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo);
0048     }
0049 }
0050 
0051 static void fl2f_shutdown(void)
0052 {
0053     u32 hi, lo, val;
0054     int gpio_base;
0055 
0056     /* get gpio base */
0057     _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
0058     gpio_base = lo & 0xff00;
0059 
0060     /* make cs5536 gpio13 output enable */
0061     val = inl(gpio_base + GPIOL_OUT_EN);
0062     val &= ~(1 << (16 + 13));
0063     val |= (1 << 13);
0064     outl(val, gpio_base + GPIOL_OUT_EN);
0065     mmiowb();
0066     /* make cs5536 gpio13 output low level voltage. */
0067     val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13));
0068     val |= (1 << (16 + 13));
0069     outl(val, gpio_base + GPIOL_OUT_VAL);
0070     mmiowb();
0071 }
0072 
0073 /* reset support for yeeloong2f and mengloong2f notebook */
0074 
0075 static void ml2f_reboot(void)
0076 {
0077     reset_cpu();
0078 
0079     /* sending an reset signal to EC(embedded controller) */
0080     ec_write(REG_RESET, BIT_RESET_ON);
0081 }
0082 
0083 #define yl2f89_reboot ml2f_reboot
0084 
0085 /* menglong(7inches) laptop has different shutdown logic from 8.9inches */
0086 #define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d
0087 #define EC_SHUTDOWN_IO_PORT_LOW  0xff2e
0088 #define EC_SHUTDOWN_IO_PORT_DATA 0xff2f
0089 #define REG_SHUTDOWN_HIGH    0xFC
0090 #define REG_SHUTDOWN_LOW     0x29
0091 #define BIT_SHUTDOWN_ON      (1 << 1)
0092 
0093 static void ml2f_shutdown(void)
0094 {
0095     u8 val;
0096     u64 i;
0097 
0098     outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH);
0099     outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW);
0100     mmiowb();
0101     val = inb(EC_SHUTDOWN_IO_PORT_DATA);
0102     outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA);
0103     mmiowb();
0104     /* need enough wait here... how many microseconds needs? */
0105     for (i = 0; i < 0x10000; i++)
0106         delay();
0107     outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA);
0108     mmiowb();
0109 }
0110 
0111 static void yl2f89_shutdown(void)
0112 {
0113     /* cpu-gpio0 output low */
0114     LOONGSON_GPIODATA &= ~0x00000001;
0115     /* cpu-gpio0 as output */
0116     LOONGSON_GPIOIE &= ~0x00000001;
0117 }
0118 
0119 void mach_prepare_reboot(void)
0120 {
0121     switch (mips_machtype) {
0122     case MACH_LEMOTE_FL2F:
0123     case MACH_LEMOTE_NAS:
0124     case MACH_LEMOTE_LL2F:
0125         fl2f_reboot();
0126         break;
0127     case MACH_LEMOTE_ML2F7:
0128         ml2f_reboot();
0129         break;
0130     case MACH_LEMOTE_YL2F89:
0131         yl2f89_reboot();
0132         break;
0133     default:
0134         break;
0135     }
0136 }
0137 
0138 void mach_prepare_shutdown(void)
0139 {
0140     switch (mips_machtype) {
0141     case MACH_LEMOTE_FL2F:
0142     case MACH_LEMOTE_NAS:
0143     case MACH_LEMOTE_LL2F:
0144         fl2f_shutdown();
0145         break;
0146     case MACH_LEMOTE_ML2F7:
0147         ml2f_shutdown();
0148         break;
0149     case MACH_LEMOTE_YL2F89:
0150         yl2f89_shutdown();
0151         break;
0152     default:
0153         break;
0154     }
0155 }