Commit fa7499ef77db8d535e3c609c8064e9ee50c0693c

Authored by GuanXuetao
1 parent 70fac51fea

unicore32 machine related files: core files

This patch adds machine related core files, also including build infrastructure.

Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>

Showing 3 changed files with 440 additions and 0 deletions Side-by-side Diff

arch/unicore32/Kconfig
... ... @@ -231,6 +231,31 @@
231 231 tristate "PKUnity v3 RTC Support"
232 232 depends on !ARCH_FPGA
233 233  
  234 +if PUV3_NB0916
  235 +
  236 +menu "PKUnity NetBook-0916 Features"
  237 +
  238 +config I2C_BATTERY_BQ27200
  239 + tristate "I2C Battery BQ27200 Support"
  240 + select PUV3_I2C
  241 + select POWER_SUPPLY
  242 + select BATTERY_BQ27x00
  243 +
  244 +config I2C_EEPROM_AT24
  245 + tristate "I2C EEPROMs AT24 support"
  246 + select PUV3_I2C
  247 + select MISC_DEVICES
  248 + select EEPROM_AT24
  249 +
  250 +config LCD_BACKLIGHT
  251 + tristate "LCD Backlight support"
  252 + select BACKLIGHT_LCD_SUPPORT
  253 + select BACKLIGHT_PWM
  254 +
  255 +endmenu
  256 +
  257 +endif
  258 +
234 259 endif
235 260  
236 261 source "drivers/Kconfig"
arch/unicore32/kernel/puv3-core.c
  1 +/*
  2 + * linux/arch/unicore32/kernel/puv3-core.c
  3 + *
  4 + * Code specific to PKUnity SoC and UniCore ISA
  5 + *
  6 + * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
  7 + * Copyright (C) 2001-2010 Guan Xuetao
  8 + *
  9 + * This program is free software; you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License version 2 as
  11 + * published by the Free Software Foundation.
  12 + */
  13 +
  14 +#include <linux/init.h>
  15 +#include <linux/device.h>
  16 +#include <linux/sysdev.h>
  17 +#include <linux/amba/bus.h>
  18 +#include <linux/platform_device.h>
  19 +#include <linux/io.h>
  20 +#include <linux/cnt32_to_63.h>
  21 +#include <linux/usb/musb.h>
  22 +
  23 +#include <asm/irq.h>
  24 +#include <mach/hardware.h>
  25 +#include <mach/pm.h>
  26 +
  27 +/*
  28 + * This is the PKUnity sched_clock implementation. This has
  29 + * a resolution of 271ns, and a maximum value of 32025597s (370 days).
  30 + *
  31 + * The return value is guaranteed to be monotonic in that range as
  32 + * long as there is always less than 582 seconds between successive
  33 + * calls to this function.
  34 + *
  35 + * ( * 1E9 / CLOCK_TICK_RATE ) -> about 2235/32
  36 + */
  37 +unsigned long long sched_clock(void)
  38 +{
  39 + unsigned long long v = cnt32_to_63(OST_OSCR);
  40 +
  41 + /* original conservative method, but overflow frequently
  42 + * v *= NSEC_PER_SEC >> 12;
  43 + * do_div(v, CLOCK_TICK_RATE >> 12);
  44 + */
  45 + v = ((v & 0x7fffffffffffffffULL) * 2235) >> 5;
  46 +
  47 + return v;
  48 +}
  49 +
  50 +static struct resource puv3_usb_resources[] = {
  51 + /* order is significant! */
  52 + {
  53 + .start = PKUNITY_USB_BASE,
  54 + .end = PKUNITY_USB_BASE + 0x3ff,
  55 + .flags = IORESOURCE_MEM,
  56 + }, {
  57 + .start = IRQ_USB,
  58 + .flags = IORESOURCE_IRQ,
  59 + }, {
  60 + .start = IRQ_USB,
  61 + .flags = IORESOURCE_IRQ,
  62 + },
  63 +};
  64 +
  65 +static struct musb_hdrc_config puv3_usb_config[] = {
  66 + {
  67 + .num_eps = 16,
  68 + .multipoint = 1,
  69 +#ifdef CONFIG_USB_INVENTRA_DMA
  70 + .dma = 1,
  71 + .dma_channels = 8,
  72 +#endif
  73 + },
  74 +};
  75 +
  76 +static struct musb_hdrc_platform_data puv3_usb_plat = {
  77 + .mode = MUSB_HOST,
  78 + .min_power = 100,
  79 + .clock = 0,
  80 + .config = puv3_usb_config,
  81 +};
  82 +
  83 +static struct resource puv3_mmc_resources[] = {
  84 + [0] = {
  85 + .start = PKUNITY_SDC_BASE,
  86 + .end = PKUNITY_SDC_BASE + 0xfff,
  87 + .flags = IORESOURCE_MEM,
  88 + },
  89 + [1] = {
  90 + .start = IRQ_SDC,
  91 + .end = IRQ_SDC,
  92 + .flags = IORESOURCE_IRQ,
  93 + },
  94 +};
  95 +
  96 +static struct resource puv3_rtc_resources[] = {
  97 + [0] = {
  98 + .start = PKUNITY_RTC_BASE,
  99 + .end = PKUNITY_RTC_BASE + 0xff,
  100 + .flags = IORESOURCE_MEM,
  101 + },
  102 + [1] = {
  103 + .start = IRQ_RTCAlarm,
  104 + .end = IRQ_RTCAlarm,
  105 + .flags = IORESOURCE_IRQ,
  106 + },
  107 + [2] = {
  108 + .start = IRQ_RTC,
  109 + .end = IRQ_RTC,
  110 + .flags = IORESOURCE_IRQ
  111 + }
  112 +};
  113 +
  114 +static struct resource puv3_pwm_resources[] = {
  115 + [0] = {
  116 + .start = PKUNITY_OST_BASE + 0x80,
  117 + .end = PKUNITY_OST_BASE + 0xff,
  118 + .flags = IORESOURCE_MEM,
  119 + },
  120 +};
  121 +
  122 +static struct resource puv3_uart0_resources[] = {
  123 + [0] = {
  124 + .start = PKUNITY_UART0_BASE,
  125 + .end = PKUNITY_UART0_BASE + 0xff,
  126 + .flags = IORESOURCE_MEM,
  127 + },
  128 + [1] = {
  129 + .start = IRQ_UART0,
  130 + .end = IRQ_UART0,
  131 + .flags = IORESOURCE_IRQ
  132 + }
  133 +};
  134 +
  135 +static struct resource puv3_uart1_resources[] = {
  136 + [0] = {
  137 + .start = PKUNITY_UART1_BASE,
  138 + .end = PKUNITY_UART1_BASE + 0xff,
  139 + .flags = IORESOURCE_MEM,
  140 + },
  141 + [1] = {
  142 + .start = IRQ_UART1,
  143 + .end = IRQ_UART1,
  144 + .flags = IORESOURCE_IRQ
  145 + }
  146 +};
  147 +
  148 +static struct resource puv3_umal_resources[] = {
  149 + [0] = {
  150 + .start = PKUNITY_UMAL_BASE,
  151 + .end = PKUNITY_UMAL_BASE + 0x1fff,
  152 + .flags = IORESOURCE_MEM,
  153 + },
  154 + [1] = {
  155 + .start = IRQ_UMAL,
  156 + .end = IRQ_UMAL,
  157 + .flags = IORESOURCE_IRQ
  158 + }
  159 +};
  160 +
  161 +#ifdef CONFIG_PUV3_PM
  162 +
  163 +#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
  164 +#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
  165 +
  166 +/*
  167 + * List of global PXA peripheral registers to preserve.
  168 + * More ones like CP and general purpose register values are preserved
  169 + * with the stack pointer in sleep.S.
  170 + */
  171 +enum {
  172 + SLEEP_SAVE_PM_PLLDDRCFG,
  173 + SLEEP_SAVE_COUNT
  174 +};
  175 +
  176 +
  177 +static void puv3_cpu_pm_save(unsigned long *sleep_save)
  178 +{
  179 +/* SAVE(PM_PLLDDRCFG); */
  180 +}
  181 +
  182 +static void puv3_cpu_pm_restore(unsigned long *sleep_save)
  183 +{
  184 +/* RESTORE(PM_PLLDDRCFG); */
  185 +}
  186 +
  187 +static int puv3_cpu_pm_prepare(void)
  188 +{
  189 + /* set resume return address */
  190 + PM_DIVCFG = virt_to_phys(puv3_cpu_resume);
  191 + return 0;
  192 +}
  193 +
  194 +static void puv3_cpu_pm_enter(suspend_state_t state)
  195 +{
  196 + /* Clear reset status */
  197 + RESETC_RSSR = RESETC_RSSR_HWR | RESETC_RSSR_WDR
  198 + | RESETC_RSSR_SMR | RESETC_RSSR_SWR;
  199 +
  200 + switch (state) {
  201 +/* case PM_SUSPEND_ON:
  202 + puv3_cpu_idle();
  203 + break; */
  204 + case PM_SUSPEND_MEM:
  205 + puv3_cpu_pm_prepare();
  206 + puv3_cpu_suspend(PM_PMCR_SFB);
  207 + break;
  208 + }
  209 +}
  210 +
  211 +static int puv3_cpu_pm_valid(suspend_state_t state)
  212 +{
  213 + return state == PM_SUSPEND_MEM;
  214 +}
  215 +
  216 +static void puv3_cpu_pm_finish(void)
  217 +{
  218 + /* ensure not to come back here if it wasn't intended */
  219 + /* PSPR = 0; */
  220 +}
  221 +
  222 +static struct puv3_cpu_pm_fns puv3_cpu_pm_fnss = {
  223 + .save_count = SLEEP_SAVE_COUNT,
  224 + .valid = puv3_cpu_pm_valid,
  225 + .save = puv3_cpu_pm_save,
  226 + .restore = puv3_cpu_pm_restore,
  227 + .enter = puv3_cpu_pm_enter,
  228 + .prepare = puv3_cpu_pm_prepare,
  229 + .finish = puv3_cpu_pm_finish,
  230 +};
  231 +
  232 +static void __init puv3_init_pm(void)
  233 +{
  234 + puv3_cpu_pm_fns = &puv3_cpu_pm_fnss;
  235 +}
  236 +#else
  237 +static inline void puv3_init_pm(void) {}
  238 +#endif
  239 +
  240 +void puv3_ps2_init(void)
  241 +{
  242 + struct clk *bclk32;
  243 +
  244 + bclk32 = clk_get(NULL, "BUS32_CLK");
  245 + PS2_CNT = clk_get_rate(bclk32) / 200000; /* should > 5us */
  246 +}
  247 +
  248 +void __init puv3_core_init(void)
  249 +{
  250 + puv3_init_pm();
  251 + puv3_ps2_init();
  252 +
  253 + platform_device_register_simple("PKUnity-v3-RTC", -1,
  254 + puv3_rtc_resources, ARRAY_SIZE(puv3_rtc_resources));
  255 + platform_device_register_simple("PKUnity-v3-UMAL", -1,
  256 + puv3_umal_resources, ARRAY_SIZE(puv3_umal_resources));
  257 + platform_device_register_simple("PKUnity-v3-MMC", -1,
  258 + puv3_mmc_resources, ARRAY_SIZE(puv3_mmc_resources));
  259 + platform_device_register_simple("PKUnity-v3-PWM", -1,
  260 + puv3_pwm_resources, ARRAY_SIZE(puv3_pwm_resources));
  261 + platform_device_register_simple("PKUnity-v3-UART", 0,
  262 + puv3_uart0_resources, ARRAY_SIZE(puv3_uart0_resources));
  263 + platform_device_register_simple("PKUnity-v3-UART", 1,
  264 + puv3_uart1_resources, ARRAY_SIZE(puv3_uart1_resources));
  265 + platform_device_register_simple("PKUnity-v3-AC97", -1, NULL, 0);
  266 + platform_device_register_resndata(&platform_bus, "musb_hdrc", -1,
  267 + puv3_usb_resources, ARRAY_SIZE(puv3_usb_resources),
  268 + &puv3_usb_plat, sizeof(puv3_usb_plat));
  269 +}
arch/unicore32/kernel/puv3-nb0916.c
  1 +/*
  2 + * linux/arch/unicore32/kernel/puv3-nb0916.c
  3 + *
  4 + * Code specific to PKUnity SoC and UniCore ISA
  5 + *
  6 + * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
  7 + * Copyright (C) 2001-2010 Guan Xuetao
  8 + *
  9 + * This program is free software; you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License version 2 as
  11 + * published by the Free Software Foundation.
  12 + */
  13 +
  14 +#include <linux/init.h>
  15 +#include <linux/device.h>
  16 +#include <linux/sysdev.h>
  17 +#include <linux/platform_device.h>
  18 +#include <linux/mtd/physmap.h>
  19 +#include <linux/io.h>
  20 +#include <linux/reboot.h>
  21 +#include <linux/interrupt.h>
  22 +#include <linux/i2c.h>
  23 +#include <linux/pwm_backlight.h>
  24 +#include <linux/gpio.h>
  25 +#include <linux/gpio_keys.h>
  26 +#include <linux/input.h>
  27 +
  28 +#include <mach/hardware.h>
  29 +
  30 +static struct physmap_flash_data physmap_flash_data = {
  31 + .width = 1,
  32 +};
  33 +
  34 +static struct resource physmap_flash_resource = {
  35 + .start = 0xFFF80000,
  36 + .end = 0xFFFFFFFF,
  37 + .flags = IORESOURCE_MEM,
  38 +};
  39 +
  40 +static struct resource puv3_i2c_resources[] = {
  41 + [0] = {
  42 + .start = PKUNITY_I2C_BASE,
  43 + .end = PKUNITY_I2C_BASE + 0xff,
  44 + .flags = IORESOURCE_MEM,
  45 + },
  46 + [1] = {
  47 + .start = IRQ_I2C,
  48 + .end = IRQ_I2C,
  49 + .flags = IORESOURCE_IRQ,
  50 + }
  51 +};
  52 +
  53 +static struct platform_pwm_backlight_data nb0916_backlight_data = {
  54 + .pwm_id = 0,
  55 + .max_brightness = 100,
  56 + .dft_brightness = 100,
  57 + .pwm_period_ns = 70 * 1024,
  58 +};
  59 +
  60 +static struct gpio_keys_button nb0916_gpio_keys[] = {
  61 + {
  62 + .type = EV_KEY,
  63 + .code = KEY_POWER,
  64 + .gpio = GPI_SOFF_REQ,
  65 + .desc = "Power Button",
  66 + .wakeup = 1,
  67 + .active_low = 1,
  68 + },
  69 + {
  70 + .type = EV_KEY,
  71 + .code = BTN_TOUCH,
  72 + .gpio = GPI_BTN_TOUCH,
  73 + .desc = "Touchpad Button",
  74 + .wakeup = 1,
  75 + .active_low = 1,
  76 + },
  77 +};
  78 +
  79 +static struct gpio_keys_platform_data nb0916_gpio_button_data = {
  80 + .buttons = nb0916_gpio_keys,
  81 + .nbuttons = ARRAY_SIZE(nb0916_gpio_keys),
  82 +};
  83 +
  84 +static irqreturn_t nb0916_lcdcaseoff_handler(int irq, void *dev_id)
  85 +{
  86 + if (gpio_get_value(GPI_LCD_CASE_OFF))
  87 + gpio_set_value(GPO_LCD_EN, 1);
  88 + else
  89 + gpio_set_value(GPO_LCD_EN, 0);
  90 +
  91 + return IRQ_HANDLED;
  92 +}
  93 +
  94 +static irqreturn_t nb0916_overheat_handler(int irq, void *dev_id)
  95 +{
  96 + machine_halt();
  97 + /* SYSTEM HALT, NO RETURN */
  98 + return IRQ_HANDLED;
  99 +}
  100 +
  101 +static struct i2c_board_info __initdata puv3_i2c_devices[] = {
  102 + { I2C_BOARD_INFO("lm75", I2C_TAR_THERMAL), },
  103 + { I2C_BOARD_INFO("bq27200", I2C_TAR_PWIC), },
  104 + { I2C_BOARD_INFO("24c02", I2C_TAR_EEPROM), },
  105 +};
  106 +
  107 +int __init mach_nb0916_init(void)
  108 +{
  109 + i2c_register_board_info(0, puv3_i2c_devices,
  110 + ARRAY_SIZE(puv3_i2c_devices));
  111 +
  112 + platform_device_register_simple("PKUnity-v3-I2C", -1,
  113 + puv3_i2c_resources, ARRAY_SIZE(puv3_i2c_resources));
  114 +
  115 + platform_device_register_data(&platform_bus, "pwm-backlight", -1,
  116 + &nb0916_backlight_data, sizeof(nb0916_backlight_data));
  117 +
  118 + platform_device_register_data(&platform_bus, "gpio-keys", -1,
  119 + &nb0916_gpio_button_data, sizeof(nb0916_gpio_button_data));
  120 +
  121 + platform_device_register_resndata(&platform_bus, "physmap-flash", -1,
  122 + &physmap_flash_resource, 1,
  123 + &physmap_flash_data, sizeof(physmap_flash_data));
  124 +
  125 + if (request_irq(gpio_to_irq(GPI_LCD_CASE_OFF),
  126 + &nb0916_lcdcaseoff_handler,
  127 + IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  128 + "NB0916 lcd case off", NULL) < 0) {
  129 +
  130 + printk(KERN_DEBUG "LCD-Case-OFF IRQ %d not available\n",
  131 + gpio_to_irq(GPI_LCD_CASE_OFF));
  132 + }
  133 +
  134 + if (request_irq(gpio_to_irq(GPI_OTP_INT), &nb0916_overheat_handler,
  135 + IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  136 + "NB0916 overheating protection", NULL) < 0) {
  137 +
  138 + printk(KERN_DEBUG "Overheating Protection IRQ %d not available\n",
  139 + gpio_to_irq(GPI_OTP_INT));
  140 + }
  141 +
  142 + return 0;
  143 +}
  144 +
  145 +subsys_initcall_sync(mach_nb0916_init);