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