root/arch/unicore32/kernel/puv3-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sched_clock
  2. puv3_cpu_pm_save
  3. puv3_cpu_pm_restore
  4. puv3_cpu_pm_prepare
  5. puv3_cpu_pm_enter
  6. puv3_cpu_pm_valid
  7. puv3_cpu_pm_finish
  8. puv3_init_pm
  9. puv3_init_pm
  10. puv3_ps2_init
  11. puv3_core_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  linux/arch/unicore32/kernel/puv3-core.c
   4  *
   5  * Code specific to PKUnity SoC and UniCore ISA
   6  *
   7  *      Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
   8  *      Copyright (C) 2001-2010 Guan Xuetao
   9  */
  10 
  11 #include <linux/init.h>
  12 #include <linux/device.h>
  13 #include <linux/amba/bus.h>
  14 #include <linux/platform_device.h>
  15 #include <linux/io.h>
  16 #include <linux/cnt32_to_63.h>
  17 #include <linux/usb/musb.h>
  18 
  19 #include <asm/irq.h>
  20 #include <mach/hardware.h>
  21 #include <mach/pm.h>
  22 
  23 /*
  24  * This is the PKUnity sched_clock implementation.  This has
  25  * a resolution of 271ns, and a maximum value of 32025597s (370 days).
  26  *
  27  * The return value is guaranteed to be monotonic in that range as
  28  * long as there is always less than 582 seconds between successive
  29  * calls to this function.
  30  *
  31  *  ( * 1E9 / CLOCK_TICK_RATE ) -> about 2235/32
  32  */
  33 unsigned long long sched_clock(void)
  34 {
  35         unsigned long long v = cnt32_to_63(readl(OST_OSCR));
  36 
  37         /* original conservative method, but overflow frequently
  38          * v *= NSEC_PER_SEC >> 12;
  39          * do_div(v, CLOCK_TICK_RATE >> 12);
  40          */
  41         v = ((v & 0x7fffffffffffffffULL) * 2235) >> 5;
  42 
  43         return v;
  44 }
  45 
  46 static struct resource puv3_usb_resources[] = {
  47         /* order is significant! */
  48         {
  49                 .start          = io_v2p(PKUNITY_USB_BASE),
  50                 .end            = io_v2p(PKUNITY_USB_BASE) + 0x3ff,
  51                 .flags          = IORESOURCE_MEM,
  52         }, {
  53                 .start          = IRQ_USB,
  54                 .flags          = IORESOURCE_IRQ,
  55         }, {
  56                 .start          = IRQ_USB,
  57                 .flags          = IORESOURCE_IRQ,
  58         },
  59 };
  60 
  61 static struct musb_hdrc_config  puv3_usb_config[] = {
  62         {
  63                 .num_eps = 16,
  64                 .multipoint = 1,
  65 #ifdef CONFIG_USB_INVENTRA_DMA
  66                 .dma = 1,
  67                 .dma_channels = 8,
  68 #endif
  69         },
  70 };
  71 
  72 static struct musb_hdrc_platform_data puv3_usb_plat = {
  73         .mode           = MUSB_HOST,
  74         .min_power      = 100,
  75         .clock          = 0,
  76         .config         = puv3_usb_config,
  77 };
  78 
  79 static struct resource puv3_mmc_resources[] = {
  80         [0] = {
  81                 .start  = io_v2p(PKUNITY_SDC_BASE),
  82                 .end    = io_v2p(PKUNITY_SDC_BASE) + 0xfff,
  83                 .flags  = IORESOURCE_MEM,
  84         },
  85         [1] = {
  86                 .start  = IRQ_SDC,
  87                 .end    = IRQ_SDC,
  88                 .flags  = IORESOURCE_IRQ,
  89         },
  90 };
  91 
  92 static struct resource puv3_unigfx_resources[] = {
  93         [0] = {
  94                 .start  = io_v2p(PKUNITY_UNIGFX_BASE),
  95                 .end    = io_v2p(PKUNITY_UNIGFX_BASE) + 0xfff,
  96                 .flags  = IORESOURCE_MEM,
  97         },
  98 };
  99 
 100 static struct resource puv3_rtc_resources[] = {
 101         [0] = {
 102                 .start = io_v2p(PKUNITY_RTC_BASE),
 103                 .end   = io_v2p(PKUNITY_RTC_BASE) + 0xff,
 104                 .flags = IORESOURCE_MEM,
 105         },
 106         [1] = {
 107                 .start = IRQ_RTCAlarm,
 108                 .end   = IRQ_RTCAlarm,
 109                 .flags = IORESOURCE_IRQ,
 110         },
 111         [2] = {
 112                 .start = IRQ_RTC,
 113                 .end   = IRQ_RTC,
 114                 .flags = IORESOURCE_IRQ
 115         }
 116 };
 117 
 118 static struct resource puv3_pwm_resources[] = {
 119         [0] = {
 120                 .start  = io_v2p(PKUNITY_OST_BASE) + 0x80,
 121                 .end    = io_v2p(PKUNITY_OST_BASE) + 0xff,
 122                 .flags  = IORESOURCE_MEM,
 123         },
 124 };
 125 
 126 static struct resource puv3_uart0_resources[] = {
 127         [0] = {
 128                 .start = io_v2p(PKUNITY_UART0_BASE),
 129                 .end   = io_v2p(PKUNITY_UART0_BASE) + 0xff,
 130                 .flags = IORESOURCE_MEM,
 131         },
 132         [1] = {
 133                 .start = IRQ_UART0,
 134                 .end   = IRQ_UART0,
 135                 .flags = IORESOURCE_IRQ
 136         }
 137 };
 138 
 139 static struct resource puv3_uart1_resources[] = {
 140         [0] = {
 141                 .start = io_v2p(PKUNITY_UART1_BASE),
 142                 .end   = io_v2p(PKUNITY_UART1_BASE) + 0xff,
 143                 .flags = IORESOURCE_MEM,
 144         },
 145         [1] = {
 146                 .start = IRQ_UART1,
 147                 .end   = IRQ_UART1,
 148                 .flags = IORESOURCE_IRQ
 149         }
 150 };
 151 
 152 static struct resource puv3_umal_resources[] = {
 153         [0] = {
 154                 .start = io_v2p(PKUNITY_UMAL_BASE),
 155                 .end   = io_v2p(PKUNITY_UMAL_BASE) + 0x1fff,
 156                 .flags = IORESOURCE_MEM,
 157         },
 158         [1] = {
 159                 .start = IRQ_UMAL,
 160                 .end   = IRQ_UMAL,
 161                 .flags = IORESOURCE_IRQ
 162         }
 163 };
 164 
 165 #ifdef CONFIG_PUV3_PM
 166 
 167 #define SAVE(x)         sleep_save[SLEEP_SAVE_##x] = x
 168 #define RESTORE(x)      x = sleep_save[SLEEP_SAVE_##x]
 169 
 170 /*
 171  * List of global PXA peripheral registers to preserve.
 172  * More ones like CP and general purpose register values are preserved
 173  * with the stack pointer in sleep.S.
 174  */
 175 enum {
 176         SLEEP_SAVE_PM_PLLDDRCFG,
 177         SLEEP_SAVE_COUNT
 178 };
 179 
 180 
 181 static void puv3_cpu_pm_save(unsigned long *sleep_save)
 182 {
 183 /*      SAVE(PM_PLLDDRCFG); */
 184 }
 185 
 186 static void puv3_cpu_pm_restore(unsigned long *sleep_save)
 187 {
 188 /*      RESTORE(PM_PLLDDRCFG); */
 189 }
 190 
 191 static int puv3_cpu_pm_prepare(void)
 192 {
 193         /* set resume return address */
 194         writel(virt_to_phys(puv3_cpu_resume), PM_DIVCFG);
 195         return 0;
 196 }
 197 
 198 static void puv3_cpu_pm_enter(suspend_state_t state)
 199 {
 200         /* Clear reset status */
 201         writel(RESETC_RSSR_HWR | RESETC_RSSR_WDR
 202                         | RESETC_RSSR_SMR | RESETC_RSSR_SWR, RESETC_RSSR);
 203 
 204         switch (state) {
 205 /*      case PM_SUSPEND_ON:
 206                 puv3_cpu_idle();
 207                 break; */
 208         case PM_SUSPEND_MEM:
 209                 puv3_cpu_pm_prepare();
 210                 puv3_cpu_suspend(PM_PMCR_SFB);
 211                 break;
 212         }
 213 }
 214 
 215 static int puv3_cpu_pm_valid(suspend_state_t state)
 216 {
 217         return state == PM_SUSPEND_MEM;
 218 }
 219 
 220 static void puv3_cpu_pm_finish(void)
 221 {
 222         /* ensure not to come back here if it wasn't intended */
 223         /* PSPR = 0; */
 224 }
 225 
 226 static struct puv3_cpu_pm_fns puv3_cpu_pm_fnss = {
 227         .save_count     = SLEEP_SAVE_COUNT,
 228         .valid          = puv3_cpu_pm_valid,
 229         .save           = puv3_cpu_pm_save,
 230         .restore        = puv3_cpu_pm_restore,
 231         .enter          = puv3_cpu_pm_enter,
 232         .prepare        = puv3_cpu_pm_prepare,
 233         .finish         = puv3_cpu_pm_finish,
 234 };
 235 
 236 static void __init puv3_init_pm(void)
 237 {
 238         puv3_cpu_pm_fns = &puv3_cpu_pm_fnss;
 239 }
 240 #else
 241 static inline void puv3_init_pm(void) {}
 242 #endif
 243 
 244 void puv3_ps2_init(void)
 245 {
 246         struct clk *bclk32;
 247 
 248         bclk32 = clk_get(NULL, "BUS32_CLK");
 249         writel(clk_get_rate(bclk32) / 200000, PS2_CNT); /* should > 5us */
 250 }
 251 
 252 void __init puv3_core_init(void)
 253 {
 254         puv3_init_pm();
 255         puv3_ps2_init();
 256 
 257         platform_device_register_simple("PKUnity-v3-RTC", -1,
 258                         puv3_rtc_resources, ARRAY_SIZE(puv3_rtc_resources));
 259         platform_device_register_simple("PKUnity-v3-UMAL", -1,
 260                         puv3_umal_resources, ARRAY_SIZE(puv3_umal_resources));
 261         platform_device_register_simple("PKUnity-v3-MMC", -1,
 262                         puv3_mmc_resources, ARRAY_SIZE(puv3_mmc_resources));
 263         platform_device_register_simple("PKUnity-v3-UNIGFX", -1,
 264                         puv3_unigfx_resources, ARRAY_SIZE(puv3_unigfx_resources));
 265         platform_device_register_simple("PKUnity-v3-PWM", -1,
 266                         puv3_pwm_resources, ARRAY_SIZE(puv3_pwm_resources));
 267         platform_device_register_simple("PKUnity-v3-UART", 0,
 268                         puv3_uart0_resources, ARRAY_SIZE(puv3_uart0_resources));
 269         platform_device_register_simple("PKUnity-v3-UART", 1,
 270                         puv3_uart1_resources, ARRAY_SIZE(puv3_uart1_resources));
 271         platform_device_register_simple("PKUnity-v3-AC97", -1, NULL, 0);
 272         platform_device_register_resndata(NULL, "musb_hdrc", -1,
 273                         puv3_usb_resources, ARRAY_SIZE(puv3_usb_resources),
 274                         &puv3_usb_plat, sizeof(puv3_usb_plat));
 275 }
 276 

/* [<][>][^][v][top][bottom][index][help] */