linux/arch/powerpc/platforms/85xx/p1022_rdk.c
<<
>>
Prefs
   1/*
   2 * P1022 RDK board specific routines
   3 *
   4 * Copyright 2012 Freescale Semiconductor, Inc.
   5 *
   6 * Author: Timur Tabi <timur@freescale.com>
   7 *
   8 * Based on p1022_ds.c
   9 *
  10 * This file is licensed under the terms of the GNU General Public License
  11 * version 2.  This program is licensed "as is" without any warranty of any
  12 * kind, whether express or implied.
  13 */
  14
  15#include <linux/fsl/guts.h>
  16#include <linux/pci.h>
  17#include <linux/of_platform.h>
  18#include <asm/div64.h>
  19#include <asm/mpic.h>
  20#include <asm/swiotlb.h>
  21
  22#include <sysdev/fsl_soc.h>
  23#include <sysdev/fsl_pci.h>
  24#include <asm/udbg.h>
  25#include "smp.h"
  26
  27#include "mpc85xx.h"
  28
  29#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
  30
  31/* DIU Pixel Clock bits of the CLKDVDR Global Utilities register */
  32#define CLKDVDR_PXCKEN          0x80000000
  33#define CLKDVDR_PXCKINV         0x10000000
  34#define CLKDVDR_PXCKDLY         0x06000000
  35#define CLKDVDR_PXCLK_MASK      0x00FF0000
  36
  37/**
  38 * p1022rdk_set_pixel_clock: program the DIU's clock
  39 *
  40 * @pixclock: the wavelength, in picoseconds, of the clock
  41 */
  42void p1022rdk_set_pixel_clock(unsigned int pixclock)
  43{
  44        struct device_node *guts_np = NULL;
  45        struct ccsr_guts __iomem *guts;
  46        unsigned long freq;
  47        u64 temp;
  48        u32 pxclk;
  49
  50        /* Map the global utilities registers. */
  51        guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
  52        if (!guts_np) {
  53                pr_err("p1022rdk: missing global utilities device node\n");
  54                return;
  55        }
  56
  57        guts = of_iomap(guts_np, 0);
  58        of_node_put(guts_np);
  59        if (!guts) {
  60                pr_err("p1022rdk: could not map global utilities device\n");
  61                return;
  62        }
  63
  64        /* Convert pixclock from a wavelength to a frequency */
  65        temp = 1000000000000ULL;
  66        do_div(temp, pixclock);
  67        freq = temp;
  68
  69        /*
  70         * 'pxclk' is the ratio of the platform clock to the pixel clock.
  71         * This number is programmed into the CLKDVDR register, and the valid
  72         * range of values is 2-255.
  73         */
  74        pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq);
  75        pxclk = clamp_t(u32, pxclk, 2, 255);
  76
  77        /* Disable the pixel clock, and set it to non-inverted and no delay */
  78        clrbits32(&guts->clkdvdr,
  79                  CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
  80
  81        /* Enable the clock and set the pxclk */
  82        setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
  83
  84        iounmap(guts);
  85}
  86
  87/**
  88 * p1022rdk_valid_monitor_port: set the monitor port for sysfs
  89 */
  90enum fsl_diu_monitor_port
  91p1022rdk_valid_monitor_port(enum fsl_diu_monitor_port port)
  92{
  93        return FSL_DIU_PORT_DVI;
  94}
  95
  96#endif
  97
  98void __init p1022_rdk_pic_init(void)
  99{
 100        struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
 101                MPIC_SINGLE_DEST_CPU,
 102                0, 256, " OpenPIC  ");
 103        BUG_ON(mpic == NULL);
 104        mpic_init(mpic);
 105}
 106
 107/*
 108 * Setup the architecture
 109 */
 110static void __init p1022_rdk_setup_arch(void)
 111{
 112        if (ppc_md.progress)
 113                ppc_md.progress("p1022_rdk_setup_arch()", 0);
 114
 115#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
 116        diu_ops.set_pixel_clock         = p1022rdk_set_pixel_clock;
 117        diu_ops.valid_monitor_port      = p1022rdk_valid_monitor_port;
 118#endif
 119
 120        mpc85xx_smp_init();
 121
 122        fsl_pci_assign_primary();
 123
 124        swiotlb_detect_4g();
 125
 126        pr_info("Freescale / iVeia P1022 RDK reference board\n");
 127}
 128
 129machine_arch_initcall(p1022_rdk, mpc85xx_common_publish_devices);
 130
 131/*
 132 * Called very early, device-tree isn't unflattened
 133 */
 134static int __init p1022_rdk_probe(void)
 135{
 136        return of_machine_is_compatible("fsl,p1022rdk");
 137}
 138
 139define_machine(p1022_rdk) {
 140        .name                   = "P1022 RDK",
 141        .probe                  = p1022_rdk_probe,
 142        .setup_arch             = p1022_rdk_setup_arch,
 143        .init_IRQ               = p1022_rdk_pic_init,
 144#ifdef CONFIG_PCI
 145        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 146        .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 147#endif
 148        .get_irq                = mpic_get_irq,
 149        .calibrate_decr         = generic_calibrate_decr,
 150        .progress               = udbg_progress,
 151};
 152