Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
b3773301
Commit
b3773301
authored
Oct 28, 2010
by
Russell King
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/genesis-2.6 into devel-stable
Conflicts: drivers/video/sh_mobile_hdmi.c
parents
be6786ac
1a0b1eac
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1222 additions
and
613 deletions
+1222
-613
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/board-ap4evb.c
+215
-111
arch/arm/mach-shmobile/clock-sh7367.c
arch/arm/mach-shmobile/clock-sh7367.c
+1
-1
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-shmobile/clock-sh7372.c
+55
-23
arch/arm/mach-shmobile/clock-sh7377.c
arch/arm/mach-shmobile/clock-sh7377.c
+1
-1
arch/arm/mach-shmobile/include/mach/sh7372.h
arch/arm/mach-shmobile/include/mach/sh7372.h
+7
-3
arch/arm/mach-shmobile/intc-sh7372.c
arch/arm/mach-shmobile/intc-sh7372.c
+28
-0
arch/arm/mach-shmobile/pfc-sh7372.c
arch/arm/mach-shmobile/pfc-sh7372.c
+4
-4
arch/arm/mach-shmobile/setup-sh7367.c
arch/arm/mach-shmobile/setup-sh7367.c
+0
-1
arch/arm/mach-shmobile/setup-sh7372.c
arch/arm/mach-shmobile/setup-sh7372.c
+81
-13
arch/arm/mach-shmobile/setup-sh7377.c
arch/arm/mach-shmobile/setup-sh7377.c
+0
-1
arch/sh/boards/mach-ap325rxa/setup.c
arch/sh/boards/mach-ap325rxa/setup.c
+17
-12
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/boards/mach-ecovec24/setup.c
+36
-24
arch/sh/boards/mach-kfr2r09/setup.c
arch/sh/boards/mach-kfr2r09/setup.c
+17
-12
arch/sh/boards/mach-migor/setup.c
arch/sh/boards/mach-migor/setup.c
+31
-27
arch/sh/boards/mach-se/7724/setup.c
arch/sh/boards/mach-se/7724/setup.c
+34
-20
drivers/video/sh_mipi_dsi.c
drivers/video/sh_mipi_dsi.c
+18
-14
drivers/video/sh_mobile_hdmi.c
drivers/video/sh_mobile_hdmi.c
+405
-224
drivers/video/sh_mobile_lcdcfb.c
drivers/video/sh_mobile_lcdcfb.c
+227
-121
drivers/video/sh_mobile_lcdcfb.h
drivers/video/sh_mobile_lcdcfb.h
+41
-0
include/video/sh_mobile_lcdc.h
include/video/sh_mobile_lcdc.h
+4
-1
No files found.
arch/arm/mach-shmobile/board-ap4evb.c
View file @
b3773301
...
@@ -30,7 +30,6 @@
...
@@ -30,7 +30,6 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/physmap.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sh_mmcif.h>
#include <linux/mmc/sh_mmcif.h>
#include <linux/i2c.h>
#include <linux/i2c.h>
#include <linux/i2c/tsc2007.h>
#include <linux/i2c/tsc2007.h>
...
@@ -44,6 +43,10 @@
...
@@ -44,6 +43,10 @@
#include <linux/input/sh_keysc.h>
#include <linux/input/sh_keysc.h>
#include <linux/usb/r8a66597.h>
#include <linux/usb/r8a66597.h>
#include <media/sh_mobile_ceu.h>
#include <media/sh_mobile_csi2.h>
#include <media/soc_camera.h>
#include <sound/sh_fsi.h>
#include <sound/sh_fsi.h>
#include <video/sh_mobile_hdmi.h>
#include <video/sh_mobile_hdmi.h>
...
@@ -238,7 +241,7 @@ static struct platform_device smc911x_device = {
...
@@ -238,7 +241,7 @@ static struct platform_device smc911x_device = {
/* SH_MMCIF */
/* SH_MMCIF */
static
struct
resource
sh_mmcif_resources
[]
=
{
static
struct
resource
sh_mmcif_resources
[]
=
{
[
0
]
=
{
[
0
]
=
{
.
name
=
"
SH_
MMCIF"
,
.
name
=
"MMCIF"
,
.
start
=
0xE6BD0000
,
.
start
=
0xE6BD0000
,
.
end
=
0xE6BD00FF
,
.
end
=
0xE6BD00FF
,
.
flags
=
IORESOURCE_MEM
,
.
flags
=
IORESOURCE_MEM
,
...
@@ -375,10 +378,40 @@ static struct platform_device usb1_host_device = {
...
@@ -375,10 +378,40 @@ static struct platform_device usb1_host_device = {
.
resource
=
usb1_host_resources
,
.
resource
=
usb1_host_resources
,
};
};
const
static
struct
fb_videomode
ap4evb_lcdc_modes
[]
=
{
{
#ifdef CONFIG_AP4EVB_QHD
.
name
=
"R63302(QHD)"
,
.
xres
=
544
,
.
yres
=
961
,
.
left_margin
=
72
,
.
right_margin
=
600
,
.
hsync_len
=
16
,
.
upper_margin
=
8
,
.
lower_margin
=
8
,
.
vsync_len
=
2
,
.
sync
=
FB_SYNC_VERT_HIGH_ACT
|
FB_SYNC_HOR_HIGH_ACT
,
#else
.
name
=
"WVGA Panel"
,
.
xres
=
800
,
.
yres
=
480
,
.
left_margin
=
220
,
.
right_margin
=
110
,
.
hsync_len
=
70
,
.
upper_margin
=
20
,
.
lower_margin
=
5
,
.
vsync_len
=
5
,
.
sync
=
0
,
#endif
},
};
static
struct
sh_mobile_lcdc_info
lcdc_info
=
{
static
struct
sh_mobile_lcdc_info
lcdc_info
=
{
.
ch
[
0
]
=
{
.
ch
[
0
]
=
{
.
chan
=
LCDC_CHAN_MAINLCD
,
.
chan
=
LCDC_CHAN_MAINLCD
,
.
bpp
=
16
,
.
bpp
=
16
,
.
lcd_cfg
=
ap4evb_lcdc_modes
,
.
num_cfg
=
ARRAY_SIZE
(
ap4evb_lcdc_modes
),
}
}
};
};
...
@@ -517,27 +550,6 @@ static struct platform_device *qhd_devices[] __initdata = {
...
@@ -517,27 +550,6 @@ static struct platform_device *qhd_devices[] __initdata = {
/* FSI */
/* FSI */
#define IRQ_FSI evt2irq(0x1840)
#define IRQ_FSI evt2irq(0x1840)
#define FSIACKCR 0xE6150018
static
void
fsiackcr_init
(
struct
clk
*
clk
)
{
u32
status
=
__raw_readl
(
clk
->
enable_reg
);
/* use external clock */
status
&=
~
0x000000ff
;
status
|=
0x00000080
;
__raw_writel
(
status
,
clk
->
enable_reg
);
}
static
struct
clk_ops
fsiackcr_clk_ops
=
{
.
init
=
fsiackcr_init
,
};
static
struct
clk
fsiackcr_clk
=
{
.
ops
=
&
fsiackcr_clk_ops
,
.
enable_reg
=
(
void
__iomem
*
)
FSIACKCR
,
.
rate
=
0
,
/* unknown */
};
static
struct
sh_fsi_platform_info
fsi_info
=
{
static
struct
sh_fsi_platform_info
fsi_info
=
{
.
porta_flags
=
SH_FSI_BRS_INV
|
.
porta_flags
=
SH_FSI_BRS_INV
|
SH_FSI_OUT_SLAVE_MODE
|
SH_FSI_OUT_SLAVE_MODE
|
...
@@ -577,26 +589,6 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
...
@@ -577,26 +589,6 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
.
interface_type
=
RGB24
,
.
interface_type
=
RGB24
,
.
clock_divider
=
1
,
.
clock_divider
=
1
,
.
flags
=
LCDC_FLAGS_DWPOL
,
.
flags
=
LCDC_FLAGS_DWPOL
,
.
lcd_cfg
=
{
.
name
=
"HDMI"
,
/* So far only 720p is supported */
.
xres
=
1280
,
.
yres
=
720
,
/*
* If left and right margins are not multiples of 8,
* LDHAJR will be adjusted accordingly by the LCDC
* driver. Until we start using EDID, these values
* might have to be adjusted for different monitors.
*/
.
left_margin
=
200
,
.
right_margin
=
88
,
.
hsync_len
=
48
,
.
upper_margin
=
20
,
.
lower_margin
=
5
,
.
vsync_len
=
5
,
.
pixclock
=
13468
,
.
sync
=
FB_SYNC_VERT_HIGH_ACT
|
FB_SYNC_HOR_HIGH_ACT
,
},
}
}
};
};
...
@@ -608,7 +600,7 @@ static struct resource lcdc1_resources[] = {
...
@@ -608,7 +600,7 @@ static struct resource lcdc1_resources[] = {
.
flags
=
IORESOURCE_MEM
,
.
flags
=
IORESOURCE_MEM
,
},
},
[
1
]
=
{
[
1
]
=
{
.
start
=
intcs_evt2irq
(
0x17
a
0
),
.
start
=
intcs_evt2irq
(
0x17
8
0
),
.
flags
=
IORESOURCE_IRQ
,
.
flags
=
IORESOURCE_IRQ
,
},
},
};
};
...
@@ -689,6 +681,95 @@ static struct platform_device leds_device = {
...
@@ -689,6 +681,95 @@ static struct platform_device leds_device = {
},
},
};
};
static
struct
i2c_board_info
imx074_info
=
{
I2C_BOARD_INFO
(
"imx074"
,
0x1a
),
};
struct
soc_camera_link
imx074_link
=
{
.
bus_id
=
0
,
.
board_info
=
&
imx074_info
,
.
i2c_adapter_id
=
0
,
.
module_name
=
"imx074"
,
};
static
struct
platform_device
ap4evb_camera
=
{
.
name
=
"soc-camera-pdrv"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
imx074_link
,
},
};
static
struct
sh_csi2_client_config
csi2_clients
[]
=
{
{
.
phy
=
SH_CSI2_PHY_MAIN
,
.
lanes
=
3
,
.
channel
=
0
,
.
pdev
=
&
ap4evb_camera
,
},
};
static
struct
sh_csi2_pdata
csi2_info
=
{
.
type
=
SH_CSI2C
,
.
clients
=
csi2_clients
,
.
num_clients
=
ARRAY_SIZE
(
csi2_clients
),
.
flags
=
SH_CSI2_ECC
|
SH_CSI2_CRC
,
};
static
struct
resource
csi2_resources
[]
=
{
[
0
]
=
{
.
name
=
"CSI2"
,
.
start
=
0xffc90000
,
.
end
=
0xffc90fff
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
intcs_evt2irq
(
0x17a0
),
.
flags
=
IORESOURCE_IRQ
,
},
};
static
struct
platform_device
csi2_device
=
{
.
name
=
"sh-mobile-csi2"
,
.
id
=
0
,
.
num_resources
=
ARRAY_SIZE
(
csi2_resources
),
.
resource
=
csi2_resources
,
.
dev
=
{
.
platform_data
=
&
csi2_info
,
},
};
static
struct
sh_mobile_ceu_info
sh_mobile_ceu_info
=
{
.
flags
=
SH_CEU_FLAG_USE_8BIT_BUS
,
.
csi2_dev
=
&
csi2_device
.
dev
,
};
static
struct
resource
ceu_resources
[]
=
{
[
0
]
=
{
.
name
=
"CEU"
,
.
start
=
0xfe910000
,
.
end
=
0xfe91009f
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
intcs_evt2irq
(
0x880
),
.
flags
=
IORESOURCE_IRQ
,
},
[
2
]
=
{
/* place holder for contiguous memory */
},
};
static
struct
platform_device
ceu_device
=
{
.
name
=
"sh_mobile_ceu"
,
.
id
=
0
,
/* "ceu0" clock */
.
num_resources
=
ARRAY_SIZE
(
ceu_resources
),
.
resource
=
ceu_resources
,
.
dev
=
{
.
platform_data
=
&
sh_mobile_ceu_info
,
},
};
static
struct
platform_device
*
ap4evb_devices
[]
__initdata
=
{
static
struct
platform_device
*
ap4evb_devices
[]
__initdata
=
{
&
leds_device
,
&
leds_device
,
&
nor_flash_device
,
&
nor_flash_device
,
...
@@ -701,6 +782,9 @@ static struct platform_device *ap4evb_devices[] __initdata = {
...
@@ -701,6 +782,9 @@ static struct platform_device *ap4evb_devices[] __initdata = {
&
lcdc1_device
,
&
lcdc1_device
,
&
lcdc_device
,
&
lcdc_device
,
&
hdmi_device
,
&
hdmi_device
,
&
csi2_device
,
&
ceu_device
,
&
ap4evb_camera
,
};
};
static
int
__init
hdmi_init_pm_clock
(
void
)
static
int
__init
hdmi_init_pm_clock
(
void
)
...
@@ -715,22 +799,22 @@ static int __init hdmi_init_pm_clock(void)
...
@@ -715,22 +799,22 @@ static int __init hdmi_init_pm_clock(void)
goto
out
;
goto
out
;
}
}
ret
=
clk_set_parent
(
&
pllc2_clk
,
&
dv_clki_div2_clk
);
ret
=
clk_set_parent
(
&
sh7372_pllc2_clk
,
&
sh7372_
dv_clki_div2_clk
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
pr_err
(
"Cannot set PLLC2 parent: %d, %d users
\n
"
,
ret
,
pllc2_clk
.
usecount
);
pr_err
(
"Cannot set PLLC2 parent: %d, %d users
\n
"
,
ret
,
sh7372_
pllc2_clk
.
usecount
);
goto
out
;
goto
out
;
}
}
pr_debug
(
"PLLC2 initial frequency %lu
\n
"
,
clk_get_rate
(
&
pllc2_clk
));
pr_debug
(
"PLLC2 initial frequency %lu
\n
"
,
clk_get_rate
(
&
sh7372_
pllc2_clk
));
rate
=
clk_round_rate
(
&
pllc2_clk
,
594000000
);
rate
=
clk_round_rate
(
&
sh7372_
pllc2_clk
,
594000000
);
if
(
rate
<
0
)
{
if
(
rate
<
0
)
{
pr_err
(
"Cannot get suitable rate: %ld
\n
"
,
rate
);
pr_err
(
"Cannot get suitable rate: %ld
\n
"
,
rate
);
ret
=
rate
;
ret
=
rate
;
goto
out
;
goto
out
;
}
}
ret
=
clk_set_rate
(
&
pllc2_clk
,
rate
);
ret
=
clk_set_rate
(
&
sh7372_
pllc2_clk
,
rate
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
pr_err
(
"Cannot set rate %ld: %d
\n
"
,
rate
,
ret
);
pr_err
(
"Cannot set rate %ld: %d
\n
"
,
rate
,
ret
);
goto
out
;
goto
out
;
...
@@ -738,7 +822,7 @@ static int __init hdmi_init_pm_clock(void)
...
@@ -738,7 +822,7 @@ static int __init hdmi_init_pm_clock(void)
pr_debug
(
"PLLC2 set frequency %lu
\n
"
,
rate
);
pr_debug
(
"PLLC2 set frequency %lu
\n
"
,
rate
);
ret
=
clk_set_parent
(
hdmi_ick
,
&
pllc2_clk
);
ret
=
clk_set_parent
(
hdmi_ick
,
&
sh7372_
pllc2_clk
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
pr_err
(
"Cannot set HDMI parent: %d
\n
"
,
ret
);
pr_err
(
"Cannot set HDMI parent: %d
\n
"
,
ret
);
goto
out
;
goto
out
;
...
@@ -752,11 +836,51 @@ static int __init hdmi_init_pm_clock(void)
...
@@ -752,11 +836,51 @@ static int __init hdmi_init_pm_clock(void)
device_initcall
(
hdmi_init_pm_clock
);
device_initcall
(
hdmi_init_pm_clock
);
#define FSIACK_DUMMY_RATE 48000
static
int
__init
fsi_init_pm_clock
(
void
)
{
struct
clk
*
fsia_ick
;
int
ret
;
/*
* FSIACK is connected to AK4642,
* and the rate is depend on playing sound rate.
* So, set dummy rate (= 48k) here
*/
ret
=
clk_set_rate
(
&
sh7372_fsiack_clk
,
FSIACK_DUMMY_RATE
);
if
(
ret
<
0
)
{
pr_err
(
"Cannot set FSIACK dummy rate: %d
\n
"
,
ret
);
return
ret
;
}
fsia_ick
=
clk_get
(
&
fsi_device
.
dev
,
"icka"
);
if
(
IS_ERR
(
fsia_ick
))
{
ret
=
PTR_ERR
(
fsia_ick
);
pr_err
(
"Cannot get FSI ICK: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
clk_set_parent
(
fsia_ick
,
&
sh7372_fsiack_clk
);
if
(
ret
<
0
)
{
pr_err
(
"Cannot set FSI-A parent: %d
\n
"
,
ret
);
goto
out
;
}
ret
=
clk_set_rate
(
fsia_ick
,
FSIACK_DUMMY_RATE
);
if
(
ret
<
0
)
pr_err
(
"Cannot set FSI-A rate: %d
\n
"
,
ret
);
out:
clk_put
(
fsia_ick
);
return
ret
;
}
device_initcall
(
fsi_init_pm_clock
);
/*
/*
* FIXME !!
* FIXME !!
*
*
* gpio_no_direction
* gpio_no_direction
* gpio_pull_up
* are quick_hack.
* are quick_hack.
*
*
* current gpio frame work doesn't have
* current gpio frame work doesn't have
...
@@ -768,49 +892,37 @@ static void __init gpio_no_direction(u32 addr)
...
@@ -768,49 +892,37 @@ static void __init gpio_no_direction(u32 addr)
__raw_writeb
(
0x00
,
addr
);
__raw_writeb
(
0x00
,
addr
);
}
}
static
void
__init
gpio_pull_up
(
u32
addr
)
{
u8
data
=
__raw_readb
(
addr
);
data
&=
0x0F
;
data
|=
0xC0
;
__raw_writeb
(
data
,
addr
);
}
/* TouchScreen */
/* TouchScreen */
#ifdef CONFIG_AP4EVB_QHD
# define GPIO_TSC_IRQ GPIO_FN_IRQ28_123
# define GPIO_TSC_PORT GPIO_PORT123
#else
/* WVGA */
# define GPIO_TSC_IRQ GPIO_FN_IRQ7_40
# define GPIO_TSC_PORT GPIO_PORT40
#endif
#define IRQ28 evt2irq(0x3380)
/* IRQ28A */
#define IRQ28 evt2irq(0x3380)
/* IRQ28A */
#define IRQ7 evt2irq(0x02e0)
/* IRQ7A */
#define IRQ7 evt2irq(0x02e0)
/* IRQ7A */
static
int
ts_get_pendown_state
(
void
)
static
int
ts_get_pendown_state
(
void
)
{
{
int
val
1
,
val2
;
int
val
;
gpio_free
(
GPIO_FN_IRQ28_123
);
gpio_free
(
GPIO_TSC_IRQ
);
gpio_free
(
GPIO_FN_IRQ7_40
);
gpio_request
(
GPIO_PORT123
,
NULL
);
gpio_request
(
GPIO_TSC_PORT
,
NULL
);
gpio_request
(
GPIO_PORT40
,
NULL
);
gpio_direction_input
(
GPIO_PORT123
);
gpio_direction_input
(
GPIO_TSC_PORT
);
gpio_direction_input
(
GPIO_PORT40
);
val1
=
gpio_get_value
(
GPIO_PORT123
);
val
=
gpio_get_value
(
GPIO_TSC_PORT
);
val2
=
gpio_get_value
(
GPIO_PORT40
);
gpio_request
(
GPIO_FN_IRQ28_123
,
NULL
);
/* for QHD */
gpio_request
(
GPIO_TSC_IRQ
,
NULL
);
gpio_request
(
GPIO_FN_IRQ7_40
,
NULL
);
/* for WVGA */
return
val1
^
val2
;
return
!
val
;
}
}
#define PORT40CR 0xE6051028
#define PORT123CR 0xE605007B
static
int
ts_init
(
void
)
static
int
ts_init
(
void
)
{
{
gpio_request
(
GPIO_FN_IRQ28_123
,
NULL
);
/* for QHD */
gpio_request
(
GPIO_TSC_IRQ
,
NULL
);
gpio_request
(
GPIO_FN_IRQ7_40
,
NULL
);
/* for WVGA */
gpio_pull_up
(
PORT40CR
);
gpio_pull_up
(
PORT123CR
);
return
0
;
return
0
;
}
}
...
@@ -955,14 +1067,6 @@ static void __init ap4evb_init(void)
...
@@ -955,14 +1067,6 @@ static void __init ap4evb_init(void)
clk_put
(
clk
);
clk_put
(
clk
);
}
}
/* change parent of FSI A */
clk
=
clk_get
(
NULL
,
"fsia_clk"
);
if
(
!
IS_ERR
(
clk
))
{
clk_register
(
&
fsiackcr_clk
);
clk_set_parent
(
clk
,
&
fsiackcr_clk
);
clk_put
(
clk
);
}
/*
/*
* set irq priority, to avoid sound chopping
* set irq priority, to avoid sound chopping
* when NFS rootfs is used
* when NFS rootfs is used
...
@@ -977,8 +1081,10 @@ static void __init ap4evb_init(void)
...
@@ -977,8 +1081,10 @@ static void __init ap4evb_init(void)
ARRAY_SIZE
(
i2c1_devices
));
ARRAY_SIZE
(
i2c1_devices
));
#ifdef CONFIG_AP4EVB_QHD
#ifdef CONFIG_AP4EVB_QHD
/*
/*
* QHD
* For QHD Panel (MIPI-DSI, CONFIG_AP4EVB_QHD=y) and
* IRQ28 for Touch Panel, set dip switches S3, S43 as OFF, ON.
*/
*/
/* enable KEYSC */
/* enable KEYSC */
...
@@ -1004,17 +1110,6 @@ static void __init ap4evb_init(void)
...
@@ -1004,17 +1110,6 @@ static void __init ap4evb_init(void)
lcdc_info
.
ch
[
0
].
interface_type
=
RGB24
;
lcdc_info
.
ch
[
0
].
interface_type
=
RGB24
;
lcdc_info
.
ch
[
0
].
clock_divider
=
1
;
lcdc_info
.
ch
[
0
].
clock_divider
=
1
;
lcdc_info
.
ch
[
0
].
flags
=
LCDC_FLAGS_DWPOL
;
lcdc_info
.
ch
[
0
].
flags
=
LCDC_FLAGS_DWPOL
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
name
=
"R63302(QHD)"
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
xres
=
544
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
yres
=
961
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
left_margin
=
72
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
right_margin
=
600
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
hsync_len
=
16
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
upper_margin
=
8
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
lower_margin
=
8
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
vsync_len
=
2
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
sync
=
FB_SYNC_VERT_HIGH_ACT
|
FB_SYNC_HOR_HIGH_ACT
;
lcdc_info
.
ch
[
0
].
lcd_size_cfg
.
width
=
44
;
lcdc_info
.
ch
[
0
].
lcd_size_cfg
.
width
=
44
;
lcdc_info
.
ch
[
0
].
lcd_size_cfg
.
height
=
79
;
lcdc_info
.
ch
[
0
].
lcd_size_cfg
.
height
=
79
;
...
@@ -1022,8 +1117,10 @@ static void __init ap4evb_init(void)
...
@@ -1022,8 +1117,10 @@ static void __init ap4evb_init(void)
#else
#else
/*
/*
* WVGA
* For WVGA Panel (18-bit RGB, CONFIG_AP4EVB_WVGA=y) and
* IRQ7 for Touch Panel, set dip switches S3, S43 to ON, OFF.
*/
*/
gpio_request
(
GPIO_FN_LCDD17
,
NULL
);
gpio_request
(
GPIO_FN_LCDD17
,
NULL
);
gpio_request
(
GPIO_FN_LCDD16
,
NULL
);
gpio_request
(
GPIO_FN_LCDD16
,
NULL
);
gpio_request
(
GPIO_FN_LCDD15
,
NULL
);
gpio_request
(
GPIO_FN_LCDD15
,
NULL
);
...
@@ -1055,16 +1152,6 @@ static void __init ap4evb_init(void)
...
@@ -1055,16 +1152,6 @@ static void __init ap4evb_init(void)
lcdc_info
.
ch
[
0
].
interface_type
=
RGB18
;
lcdc_info
.
ch
[
0
].
interface_type
=
RGB18
;
lcdc_info
.
ch
[
0
].
clock_divider
=
2
;
lcdc_info
.
ch
[
0
].
clock_divider
=
2
;
lcdc_info
.
ch
[
0
].
flags
=
0
;
lcdc_info
.
ch
[
0
].
flags
=
0
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
name
=
"WVGA Panel"
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
xres
=
800
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
yres
=
480
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
left_margin
=
220
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
right_margin
=
110
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
hsync_len
=
70
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
upper_margin
=
20
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
lower_margin
=
5
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
vsync_len
=
5
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
sync
=
0
;
lcdc_info
.
ch
[
0
].
lcd_size_cfg
.
width
=
152
;
lcdc_info
.
ch
[
0
].
lcd_size_cfg
.
width
=
152
;
lcdc_info
.
ch
[
0
].
lcd_size_cfg
.
height
=
91
;
lcdc_info
.
ch
[
0
].
lcd_size_cfg
.
height
=
91
;
...
@@ -1075,6 +1162,23 @@ static void __init ap4evb_init(void)
...
@@ -1075,6 +1162,23 @@ static void __init ap4evb_init(void)
i2c_register_board_info
(
0
,
&
tsc_device
,
1
);
i2c_register_board_info
(
0
,
&
tsc_device
,
1
);
#endif
/* CONFIG_AP4EVB_QHD */
#endif
/* CONFIG_AP4EVB_QHD */
/* CEU */
/*
* TODO: reserve memory for V4L2 DMA buffers, when a suitable API
* becomes available
*/
/* MIPI-CSI stuff */
gpio_request
(
GPIO_FN_VIO_CKO
,
NULL
);
clk
=
clk_get
(
NULL
,
"vck1_clk"
);
if
(
!
IS_ERR
(
clk
))
{
clk_set_rate
(
clk
,
clk_round_rate
(
clk
,
13000000
));
clk_enable
(
clk
);
clk_put
(
clk
);
}
sh7372_add_standard_devices
();
sh7372_add_standard_devices
();
/* HDMI */
/* HDMI */
...
@@ -1097,7 +1201,7 @@ static void __init ap4evb_timer_init(void)
...
@@ -1097,7 +1201,7 @@ static void __init ap4evb_timer_init(void)
shmobile_timer
.
init
();
shmobile_timer
.
init
();
/* External clock source */
/* External clock source */
clk_set_rate
(
&
dv_clki_clk
,
27000000
);
clk_set_rate
(
&
sh7372_
dv_clki_clk
,
27000000
);
}
}
static
struct
sys_timer
ap4evb_timer
=
{
static
struct
sys_timer
ap4evb_timer
=
{
...
...
arch/arm/mach-shmobile/clock-sh7367.c
View file @
b3773301
...
@@ -321,7 +321,7 @@ static struct clk_lookup lookups[] = {
...
@@ -321,7 +321,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID
(
"sh-sci.3"
,
&
mstp_clks
[
SYMSTP001
]),
/* SCIFA3 */
CLKDEV_DEV_ID
(
"sh-sci.3"
,
&
mstp_clks
[
SYMSTP001
]),
/* SCIFA3 */
CLKDEV_DEV_ID
(
"sh-sci.4"
,
&
mstp_clks
[
SYMSTP000
]),
/* SCIFA4 */
CLKDEV_DEV_ID
(
"sh-sci.4"
,
&
mstp_clks
[
SYMSTP000
]),
/* SCIFA4 */
CLKDEV_DEV_ID
(
"sh_siu"
,
&
mstp_clks
[
SYMSTP231
]),
/* SIU */
CLKDEV_DEV_ID
(
"sh_siu"
,
&
mstp_clks
[
SYMSTP231
]),
/* SIU */
CLKDEV_
CON_ID
(
"cmt1
"
,
&
mstp_clks
[
SYMSTP229
]),
/* CMT10 */
CLKDEV_
DEV_ID
(
"sh_cmt.10
"
,
&
mstp_clks
[
SYMSTP229
]),
/* CMT10 */
CLKDEV_DEV_ID
(
"sh_irda"
,
&
mstp_clks
[
SYMSTP225
]),
/* IRDA */
CLKDEV_DEV_ID
(
"sh_irda"
,
&
mstp_clks
[
SYMSTP225
]),
/* IRDA */
CLKDEV_DEV_ID
(
"i2c-sh_mobile.1"
,
&
mstp_clks
[
SYMSTP223
]),
/* IIC1 */
CLKDEV_DEV_ID
(
"i2c-sh_mobile.1"
,
&
mstp_clks
[
SYMSTP223
]),
/* IIC1 */
CLKDEV_DEV_ID
(
"r8a66597_hcd.0"
,
&
mstp_clks
[
SYMSTP222
]),
/* USBHS */
CLKDEV_DEV_ID
(
"r8a66597_hcd.0"
,
&
mstp_clks
[
SYMSTP222
]),
/* USBHS */
...
...
arch/arm/mach-shmobile/clock-sh7372.c
View file @
b3773301
...
@@ -51,7 +51,7 @@
...
@@ -51,7 +51,7 @@
#define SMSTPCR4 0xe6150140
#define SMSTPCR4 0xe6150140
/* Platforms must set frequency on their DV_CLKI pin */
/* Platforms must set frequency on their DV_CLKI pin */
struct
clk
dv_clki_clk
=
{
struct
clk
sh7372_
dv_clki_clk
=
{
};
};
/* Fixed 32 KHz root clock from EXTALR pin */
/* Fixed 32 KHz root clock from EXTALR pin */
...
@@ -86,9 +86,9 @@ static struct clk_ops div2_clk_ops = {
...
@@ -86,9 +86,9 @@ static struct clk_ops div2_clk_ops = {
};
};
/* Divide dv_clki by two */
/* Divide dv_clki by two */
struct
clk
dv_clki_div2_clk
=
{
struct
clk
sh7372_
dv_clki_div2_clk
=
{
.
ops
=
&
div2_clk_ops
,
.
ops
=
&
div2_clk_ops
,
.
parent
=
&
dv_clki_clk
,
.
parent
=
&
sh7372_
dv_clki_clk
,
};
};
/* Divide extal1 by two */
/* Divide extal1 by two */
...
@@ -150,7 +150,7 @@ static struct clk pllc1_div2_clk = {
...
@@ -150,7 +150,7 @@ static struct clk pllc1_div2_clk = {
static
struct
clk
*
pllc2_parent
[]
=
{
static
struct
clk
*
pllc2_parent
[]
=
{
[
0
]
=
&
extal1_div2_clk
,
[
0
]
=
&
extal1_div2_clk
,
[
1
]
=
&
extal2_div2_clk
,
[
1
]
=
&
extal2_div2_clk
,
[
2
]
=
&
dv_clki_div2_clk
,
[
2
]
=
&
sh7372_
dv_clki_div2_clk
,
};
};
/* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
/* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
...
@@ -284,7 +284,7 @@ static struct clk_ops pllc2_clk_ops = {
...
@@ -284,7 +284,7 @@ static struct clk_ops pllc2_clk_ops = {
.
set_parent
=
pllc2_set_parent
,
.
set_parent
=
pllc2_set_parent
,
};
};
struct
clk
pllc2_clk
=
{
struct
clk
sh7372_
pllc2_clk
=
{
.
ops
=
&
pllc2_clk_ops
,
.
ops
=
&
pllc2_clk_ops
,
.
parent
=
&
extal1_div2_clk
,
.
parent
=
&
extal1_div2_clk
,
.
freq_table
=
pllc2_freq_table
,
.
freq_table
=
pllc2_freq_table
,
...
@@ -292,19 +292,28 @@ struct clk pllc2_clk = {
...
@@ -292,19 +292,28 @@ struct clk pllc2_clk = {
.
parent_num
=
ARRAY_SIZE
(
pllc2_parent
),
.
parent_num
=
ARRAY_SIZE
(
pllc2_parent
),
};
};
/* External input clock (pin name: FSIACK/FSIBCK ) */
struct
clk
sh7372_fsiack_clk
=
{
};
struct
clk
sh7372_fsibck_clk
=
{
};
static
struct
clk
*
main_clks
[]
=
{
static
struct
clk
*
main_clks
[]
=
{
&
dv_clki_clk
,
&
sh7372_
dv_clki_clk
,
&
r_clk
,
&
r_clk
,
&
sh7372_extal1_clk
,
&
sh7372_extal1_clk
,
&
sh7372_extal2_clk
,
&
sh7372_extal2_clk
,
&
dv_clki_div2_clk
,
&
sh7372_
dv_clki_div2_clk
,
&
extal1_div2_clk
,
&
extal1_div2_clk
,
&
extal2_div2_clk
,
&
extal2_div2_clk
,
&
extal2_div4_clk
,
&
extal2_div4_clk
,
&
pllc0_clk
,
&
pllc0_clk
,
&
pllc1_clk
,
&
pllc1_clk
,
&
pllc1_div2_clk
,
&
pllc1_div2_clk
,
&
pllc2_clk
,
&
sh7372_pllc2_clk
,
&
sh7372_fsiack_clk
,
&
sh7372_fsibck_clk
,
};
};
static
void
div4_kick
(
struct
clk
*
clk
)
static
void
div4_kick
(
struct
clk
*
clk
)
...
@@ -357,7 +366,7 @@ static struct clk div4_clks[DIV4_NR] = {
...
@@ -357,7 +366,7 @@ static struct clk div4_clks[DIV4_NR] = {
};
};
enum
{
DIV6_VCK1
,
DIV6_VCK2
,
DIV6_VCK3
,
DIV6_FMSI
,
DIV6_FMSO
,
enum
{
DIV6_VCK1
,
DIV6_VCK2
,
DIV6_VCK3
,
DIV6_FMSI
,
DIV6_FMSO
,
DIV6_
FSIA
,
DIV6_FSIB
,
DIV6_
SUB
,
DIV6_SPU
,
DIV6_SUB
,
DIV6_SPU
,
DIV6_VOU
,
DIV6_DSIT
,
DIV6_DSI0P
,
DIV6_DSI1P
,
DIV6_VOU
,
DIV6_DSIT
,
DIV6_DSI0P
,
DIV6_DSI1P
,
DIV6_NR
};
DIV6_NR
};
...
@@ -367,8 +376,6 @@ static struct clk div6_clks[DIV6_NR] = {
...
@@ -367,8 +376,6 @@ static struct clk div6_clks[DIV6_NR] = {
[
DIV6_VCK3
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
VCLKCR3
,
0
),
[
DIV6_VCK3
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
VCLKCR3
,
0
),
[
DIV6_FMSI
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
FMSICKCR
,
0
),
[
DIV6_FMSI
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
FMSICKCR
,
0
),
[
DIV6_FMSO
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
FMSOCKCR
,
0
),
[
DIV6_FMSO
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
FMSOCKCR
,
0
),
[
DIV6_FSIA
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
FSIACKCR
,
0
),
[
DIV6_FSIB
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
FSIBCKCR
,
0
),
[
DIV6_SUB
]
=
SH_CLK_DIV6
(
&
sh7372_extal2_clk
,
SUBCKCR
,
0
),
[
DIV6_SUB
]
=
SH_CLK_DIV6
(
&
sh7372_extal2_clk
,
SUBCKCR
,
0
),
[
DIV6_SPU
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
SPUCKCR
,
0
),
[
DIV6_SPU
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
SPUCKCR
,
0
),
[
DIV6_VOU
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
VOUCKCR
,
0
),
[
DIV6_VOU
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
VOUCKCR
,
0
),
...
@@ -377,24 +384,42 @@ static struct clk div6_clks[DIV6_NR] = {
...
@@ -377,24 +384,42 @@ static struct clk div6_clks[DIV6_NR] = {
[
DIV6_DSI1P
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
DSI1PCKCR
,
0
),
[
DIV6_DSI1P
]
=
SH_CLK_DIV6
(
&
pllc1_div2_clk
,
DSI1PCKCR
,
0
),
};
};
enum
{
DIV6_HDMI
,
DIV6_REPARENT_NR
};
enum
{
DIV6_HDMI
,
DIV6_
FSIA
,
DIV6_FSIB
,
DIV6_
REPARENT_NR
};
/* Indices are important - they are the actual src selecting values */
/* Indices are important - they are the actual src selecting values */
static
struct
clk
*
hdmi_parent
[]
=
{
static
struct
clk
*
hdmi_parent
[]
=
{
[
0
]
=
&
pllc1_div2_clk
,
[
0
]
=
&
pllc1_div2_clk
,
[
1
]
=
&
pllc2_clk
,
[
1
]
=
&
sh7372_
pllc2_clk
,
[
2
]
=
&
dv_clki_clk
,
[
2
]
=
&
sh7372_
dv_clki_clk
,
[
3
]
=
NULL
,
/* pllc2_div4 not implemented yet */
[
3
]
=
NULL
,
/* pllc2_div4 not implemented yet */
};
};
static
struct
clk
*
fsiackcr_parent
[]
=
{
[
0
]
=
&
pllc1_div2_clk
,
[
1
]
=
&
sh7372_pllc2_clk
,
[
2
]
=
&
sh7372_fsiack_clk
,
/* external input for FSI A */
[
3
]
=
NULL
,
/* setting prohibited */
};
static
struct
clk
*
fsibckcr_parent
[]
=
{
[
0
]
=
&
pllc1_div2_clk
,
[
1
]
=
&
sh7372_pllc2_clk
,
[
2
]
=
&
sh7372_fsibck_clk
,
/* external input for FSI B */
[
3
]
=
NULL
,
/* setting prohibited */
};
static
struct
clk
div6_reparent_clks
[
DIV6_REPARENT_NR
]
=
{
static
struct
clk
div6_reparent_clks
[
DIV6_REPARENT_NR
]
=
{
[
DIV6_HDMI
]
=
SH_CLK_DIV6_EXT
(
&
pllc1_div2_clk
,
HDMICKCR
,
0
,
[
DIV6_HDMI
]
=
SH_CLK_DIV6_EXT
(
&
pllc1_div2_clk
,
HDMICKCR
,
0
,
hdmi_parent
,
ARRAY_SIZE
(
hdmi_parent
),
6
,
2
),
hdmi_parent
,
ARRAY_SIZE
(
hdmi_parent
),
6
,
2
),
[
DIV6_FSIA
]
=
SH_CLK_DIV6_EXT
(
&
pllc1_div2_clk
,
FSIACKCR
,
0
,
fsiackcr_parent
,
ARRAY_SIZE
(
fsiackcr_parent
),
6
,
2
),
[
DIV6_FSIB
]
=
SH_CLK_DIV6_EXT
(
&
pllc1_div2_clk
,
FSIBCKCR
,
0
,
fsibckcr_parent
,
ARRAY_SIZE
(
fsibckcr_parent
),
6
,
2
),
};
};
enum
{
MSTP001
,
enum
{
MSTP001
,
MSTP131
,
MSTP130
,
MSTP131
,
MSTP130
,
MSTP129
,
MSTP128
,
MSTP127
,
MSTP126
,
MSTP129
,
MSTP128
,
MSTP127
,
MSTP126
,
MSTP125
,
MSTP118
,
MSTP117
,
MSTP116
,
MSTP118
,
MSTP117
,
MSTP116
,
MSTP106
,
MSTP101
,
MSTP100
,
MSTP106
,
MSTP101
,
MSTP100
,
MSTP223
,
MSTP223
,
...
@@ -414,6 +439,7 @@ static struct clk mstp_clks[MSTP_NR] = {
...
@@ -414,6 +439,7 @@ static struct clk mstp_clks[MSTP_NR] = {
[
MSTP128
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
SMSTPCR1
,
28
,
0
),
/* VEU0 */
[
MSTP128
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
SMSTPCR1
,
28
,
0
),
/* VEU0 */
[
MSTP127
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
SMSTPCR1
,
27
,
0
),
/* CEU */
[
MSTP127
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
SMSTPCR1
,
27
,
0
),
/* CEU */
[
MSTP126
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
SMSTPCR1
,
26
,
0
),
/* CSI2 */
[
MSTP126
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
SMSTPCR1
,
26
,
0
),
/* CSI2 */
[
MSTP125
]
=
MSTP
(
&
div6_clks
[
DIV6_SUB
],
SMSTPCR1
,
25
,
0
),
/* TMU0 */
[
MSTP118
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
SMSTPCR1
,
18
,
0
),
/* DSITX */
[
MSTP118
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
SMSTPCR1
,
18
,
0
),
/* DSITX */
[
MSTP117
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
SMSTPCR1
,
17
,
0
),
/* LCDC1 */
[
MSTP117
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
SMSTPCR1
,
17
,
0
),
/* LCDC1 */
[
MSTP116
]
=
MSTP
(
&
div6_clks
[
DIV6_SUB
],
SMSTPCR1
,
16
,
0
),
/* IIC0 */
[
MSTP116
]
=
MSTP
(
&
div6_clks
[
DIV6_SUB
],
SMSTPCR1
,
16
,
0
),
/* IIC0 */
...
@@ -429,7 +455,7 @@ static struct clk mstp_clks[MSTP_NR] = {
...
@@ -429,7 +455,7 @@ static struct clk mstp_clks[MSTP_NR] = {
[
MSTP201
]
=
MSTP
(
&
div6_clks
[
DIV6_SUB
],
SMSTPCR2
,
1
,
0
),
/* SCIFA3 */
[
MSTP201
]
=
MSTP
(
&
div6_clks
[
DIV6_SUB
],
SMSTPCR2
,
1
,
0
),
/* SCIFA3 */
[
MSTP200
]
=
MSTP
(
&
div6_clks
[
DIV6_SUB
],
SMSTPCR2
,
0
,
0
),
/* SCIFA4 */
[
MSTP200
]
=
MSTP
(
&
div6_clks
[
DIV6_SUB
],
SMSTPCR2
,
0
,
0
),
/* SCIFA4 */
[
MSTP329
]
=
MSTP
(
&
r_clk
,
SMSTPCR3
,
29
,
0
),
/* CMT10 */
[
MSTP329
]
=
MSTP
(
&
r_clk
,
SMSTPCR3
,
29
,
0
),
/* CMT10 */
[
MSTP328
]
=
MSTP
(
&
div6_clks
[
DIV6_SPU
],
SMSTPCR3
,
28
,
0
),
/* FSI
A
*/
[
MSTP328
]
=
MSTP
(
&
div6_clks
[
DIV6_SPU
],
SMSTPCR3
,
28
,
0
),
/* FSI
2
*/
[
MSTP323
]
=
MSTP
(
&
div6_clks
[
DIV6_SUB
],
SMSTPCR3
,
23
,
0
),
/* IIC1 */
[
MSTP323
]
=
MSTP
(
&
div6_clks
[
DIV6_SUB
],
SMSTPCR3
,
23
,
0
),
/* IIC1 */
[
MSTP322
]
=
MSTP
(
&
div6_clks
[
DIV6_SUB
],
SMSTPCR3
,
22
,
0
),
/* USB0 */
[
MSTP322
]
=
MSTP
(
&
div6_clks
[
DIV6_SUB
],
SMSTPCR3
,
22
,
0
),
/* USB0 */
[
MSTP314
]
=
MSTP
(
&
div4_clks
[
DIV4_HP
],
SMSTPCR3
,
14
,
0
),
/* SDHI0 */
[
MSTP314
]
=
MSTP
(
&
div4_clks
[
DIV4_HP
],
SMSTPCR3
,
14
,
0
),
/* SDHI0 */
...
@@ -445,10 +471,11 @@ static struct clk mstp_clks[MSTP_NR] = {
...
@@ -445,10 +471,11 @@ static struct clk mstp_clks[MSTP_NR] = {
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
/* main clocks */
CLKDEV_CON_ID
(
"dv_clki_div2_clk"
,
&
dv_clki_div2_clk
),
CLKDEV_CON_ID
(
"dv_clki_div2_clk"
,
&
sh7372_
dv_clki_div2_clk
),
CLKDEV_CON_ID
(
"r_clk"
,
&
r_clk
),
CLKDEV_CON_ID
(
"r_clk"
,
&
r_clk
),
CLKDEV_CON_ID
(
"extal1"
,
&
sh7372_extal1_clk
),
CLKDEV_CON_ID
(
"extal1"
,
&
sh7372_extal1_clk
),
CLKDEV_CON_ID
(
"extal2"
,
&
sh7372_extal2_clk
),
CLKDEV_CON_ID
(
"extal2"
,
&
sh7372_extal2_clk
),
...
@@ -458,7 +485,7 @@ static struct clk_lookup lookups[] = {
...
@@ -458,7 +485,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID
(
"pllc0_clk"
,
&
pllc0_clk
),
CLKDEV_CON_ID
(
"pllc0_clk"
,
&
pllc0_clk
),
CLKDEV_CON_ID
(
"pllc1_clk"
,
&
pllc1_clk
),
CLKDEV_CON_ID
(
"pllc1_clk"
,
&
pllc1_clk
),
CLKDEV_CON_ID
(
"pllc1_div2_clk"
,
&
pllc1_div2_clk
),
CLKDEV_CON_ID
(
"pllc1_div2_clk"
,
&
pllc1_div2_clk
),
CLKDEV_CON_ID
(
"pllc2_clk"
,
&
pllc2_clk
),
CLKDEV_CON_ID
(
"pllc2_clk"
,
&
sh7372_
pllc2_clk
),
/* DIV4 clocks */
/* DIV4 clocks */
CLKDEV_CON_ID
(
"i_clk"
,
&
div4_clks
[
DIV4_I
]),
CLKDEV_CON_ID
(
"i_clk"
,
&
div4_clks
[
DIV4_I
]),
...
@@ -483,8 +510,8 @@ static struct clk_lookup lookups[] = {
...
@@ -483,8 +510,8 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID
(
"vck3_clk"
,
&
div6_clks
[
DIV6_VCK3
]),
CLKDEV_CON_ID
(
"vck3_clk"
,
&
div6_clks
[
DIV6_VCK3
]),
CLKDEV_CON_ID
(
"fmsi_clk"
,
&
div6_clks
[
DIV6_FMSI
]),
CLKDEV_CON_ID
(
"fmsi_clk"
,
&
div6_clks
[
DIV6_FMSI
]),
CLKDEV_CON_ID
(
"fmso_clk"
,
&
div6_clks
[
DIV6_FMSO
]),
CLKDEV_CON_ID
(
"fmso_clk"
,
&
div6_clks
[
DIV6_FMSO
]),
CLKDEV_CON_ID
(
"fsia_clk"
,
&
div6_clks
[
DIV6_FSIA
]),
CLKDEV_CON_ID
(
"fsia_clk"
,
&
div6_
reparent_
clks
[
DIV6_FSIA
]),
CLKDEV_CON_ID
(
"fsib_clk"
,
&
div6_clks
[
DIV6_FSIB
]),
CLKDEV_CON_ID
(
"fsib_clk"
,
&
div6_
reparent_
clks
[
DIV6_FSIB
]),
CLKDEV_CON_ID
(
"sub_clk"
,
&
div6_clks
[
DIV6_SUB
]),
CLKDEV_CON_ID
(
"sub_clk"
,
&
div6_clks
[
DIV6_SUB
]),
CLKDEV_CON_ID
(
"spu_clk"
,
&
div6_clks
[
DIV6_SPU
]),
CLKDEV_CON_ID
(
"spu_clk"
,
&
div6_clks
[
DIV6_SPU
]),
CLKDEV_CON_ID
(
"vou_clk"
,
&
div6_clks
[
DIV6_VOU
]),
CLKDEV_CON_ID
(
"vou_clk"
,
&
div6_clks
[
DIV6_VOU
]),
...
@@ -501,6 +528,8 @@ static struct clk_lookup lookups[] = {
...
@@ -501,6 +528,8 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID
(
"uio_pdrv_genirq.1"
,
&
mstp_clks
[
MSTP128
]),
/* VEU0 */
CLKDEV_DEV_ID
(
"uio_pdrv_genirq.1"
,
&
mstp_clks
[
MSTP128
]),
/* VEU0 */
CLKDEV_DEV_ID
(
"sh_mobile_ceu.0"
,
&
mstp_clks
[
MSTP127
]),
/* CEU */
CLKDEV_DEV_ID
(
"sh_mobile_ceu.0"
,
&
mstp_clks
[
MSTP127
]),
/* CEU */
CLKDEV_DEV_ID
(
"sh-mobile-csi2.0"
,
&
mstp_clks
[
MSTP126
]),
/* CSI2 */
CLKDEV_DEV_ID
(
"sh-mobile-csi2.0"
,
&
mstp_clks
[
MSTP126
]),
/* CSI2 */
CLKDEV_DEV_ID
(
"sh_tmu.0"
,
&
mstp_clks
[
MSTP125
]),
/* TMU00 */
CLKDEV_DEV_ID
(
"sh_tmu.1"
,
&
mstp_clks
[
MSTP125
]),
/* TMU01 */
CLKDEV_DEV_ID
(
"sh-mipi-dsi.0"
,
&
mstp_clks
[
MSTP118
]),
/* DSITX */
CLKDEV_DEV_ID
(
"sh-mipi-dsi.0"
,
&
mstp_clks
[
MSTP118
]),
/* DSITX */
CLKDEV_DEV_ID
(
"sh_mobile_lcdc_fb.1"
,
&
mstp_clks
[
MSTP117
]),
/* LCDC1 */
CLKDEV_DEV_ID
(
"sh_mobile_lcdc_fb.1"
,
&
mstp_clks
[
MSTP117
]),
/* LCDC1 */
CLKDEV_DEV_ID
(
"i2c-sh_mobile.0"
,
&
mstp_clks
[
MSTP116
]),
/* IIC0 */
CLKDEV_DEV_ID
(
"i2c-sh_mobile.0"
,
&
mstp_clks
[
MSTP116
]),
/* IIC0 */
...
@@ -516,7 +545,7 @@ static struct clk_lookup lookups[] = {
...
@@ -516,7 +545,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID
(
"sh-sci.2"
,
&
mstp_clks
[
MSTP202
]),
/* SCIFA2 */
CLKDEV_DEV_ID
(
"sh-sci.2"
,
&
mstp_clks
[
MSTP202
]),
/* SCIFA2 */
CLKDEV_DEV_ID
(
"sh-sci.3"
,
&
mstp_clks
[
MSTP201
]),
/* SCIFA3 */
CLKDEV_DEV_ID
(
"sh-sci.3"
,
&
mstp_clks
[
MSTP201
]),
/* SCIFA3 */
CLKDEV_DEV_ID
(
"sh-sci.4"
,
&
mstp_clks
[
MSTP200
]),
/* SCIFA4 */
CLKDEV_DEV_ID
(
"sh-sci.4"
,
&
mstp_clks
[
MSTP200
]),
/* SCIFA4 */
CLKDEV_
CON_ID
(
"cmt1
"
,
&
mstp_clks
[
MSTP329
]),
/* CMT10 */
CLKDEV_
DEV_ID
(
"sh_cmt.10
"
,
&
mstp_clks
[
MSTP329
]),
/* CMT10 */
CLKDEV_DEV_ID
(
"sh_fsi2"
,
&
mstp_clks
[
MSTP328
]),
/* FSI2 */
CLKDEV_DEV_ID
(
"sh_fsi2"
,
&
mstp_clks
[
MSTP328
]),
/* FSI2 */
CLKDEV_DEV_ID
(
"i2c-sh_mobile.1"
,
&
mstp_clks
[
MSTP323
]),
/* IIC1 */
CLKDEV_DEV_ID
(
"i2c-sh_mobile.1"
,
&
mstp_clks
[
MSTP323
]),
/* IIC1 */
CLKDEV_DEV_ID
(
"r8a66597_hcd.0"
,
&
mstp_clks
[
MSTP323
]),
/* USB0 */
CLKDEV_DEV_ID
(
"r8a66597_hcd.0"
,
&
mstp_clks
[
MSTP323
]),
/* USB0 */
...
@@ -531,7 +560,10 @@ static struct clk_lookup lookups[] = {
...
@@ -531,7 +560,10 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID
(
"r8a66597_hcd.1"
,
&
mstp_clks
[
MSTP406
]),
/* USB1 */
CLKDEV_DEV_ID
(
"r8a66597_hcd.1"
,
&
mstp_clks
[
MSTP406
]),
/* USB1 */
CLKDEV_DEV_ID
(
"r8a66597_udc.1"
,
&
mstp_clks
[
MSTP406
]),
/* USB1 */
CLKDEV_DEV_ID
(
"r8a66597_udc.1"
,
&
mstp_clks
[
MSTP406
]),
/* USB1 */
CLKDEV_DEV_ID
(
"sh_keysc.0"
,
&
mstp_clks
[
MSTP403
]),
/* KEYSC */
CLKDEV_DEV_ID
(
"sh_keysc.0"
,
&
mstp_clks
[
MSTP403
]),
/* KEYSC */
{.
con_id
=
"ick"
,
.
dev_id
=
"sh-mobile-hdmi"
,
.
clk
=
&
div6_reparent_clks
[
DIV6_HDMI
]},
CLKDEV_ICK_ID
(
"ick"
,
"sh-mobile-hdmi"
,
&
div6_reparent_clks
[
DIV6_HDMI
]),
CLKDEV_ICK_ID
(
"icka"
,
"sh_fsi2"
,
&
div6_reparent_clks
[
DIV6_FSIA
]),
CLKDEV_ICK_ID
(
"ickb"
,
"sh_fsi2"
,
&
div6_reparent_clks
[
DIV6_FSIB
]),
};
};
void
__init
sh7372_clock_init
(
void
)
void
__init
sh7372_clock_init
(
void
)
...
@@ -548,7 +580,7 @@ void __init sh7372_clock_init(void)
...
@@ -548,7 +580,7 @@ void __init sh7372_clock_init(void)
ret
=
sh_clk_div6_register
(
div6_clks
,
DIV6_NR
);
ret
=
sh_clk_div6_register
(
div6_clks
,
DIV6_NR
);
if
(
!
ret
)
if
(
!
ret
)
ret
=
sh_clk_div6_reparent_register
(
div6_reparent_clks
,
DIV6_NR
);
ret
=
sh_clk_div6_reparent_register
(
div6_reparent_clks
,
DIV6_
REPARENT_
NR
);
if
(
!
ret
)
if
(
!
ret
)
ret
=
sh_clk_mstp32_register
(
mstp_clks
,
MSTP_NR
);
ret
=
sh_clk_mstp32_register
(
mstp_clks
,
MSTP_NR
);
...
...
arch/arm/mach-shmobile/clock-sh7377.c
View file @
b3773301
...
@@ -333,7 +333,7 @@ static struct clk_lookup lookups[] = {
...
@@ -333,7 +333,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID
(
"sh-sci.3"
,
&
mstp_clks
[
MSTP201
]),
/* SCIFA3 */
CLKDEV_DEV_ID
(
"sh-sci.3"
,
&
mstp_clks
[
MSTP201
]),
/* SCIFA3 */
CLKDEV_DEV_ID
(
"sh-sci.4"
,
&
mstp_clks
[
MSTP200
]),
/* SCIFA4 */
CLKDEV_DEV_ID
(
"sh-sci.4"
,
&
mstp_clks
[
MSTP200
]),
/* SCIFA4 */
CLKDEV_DEV_ID
(
"sh-sci.6"
,
&
mstp_clks
[
MSTP331
]),
/* SCIFA6 */
CLKDEV_DEV_ID
(
"sh-sci.6"
,
&
mstp_clks
[
MSTP331
]),
/* SCIFA6 */
CLKDEV_
CON_ID
(
"cmt1
"
,
&
mstp_clks
[
MSTP329
]),
/* CMT10 */
CLKDEV_
DEV_ID
(
"sh_cmt.10
"
,
&
mstp_clks
[
MSTP329
]),
/* CMT10 */
CLKDEV_DEV_ID
(
"sh_irda"
,
&
mstp_clks
[
MSTP325
]),
/* IRDA */
CLKDEV_DEV_ID
(
"sh_irda"
,
&
mstp_clks
[
MSTP325
]),
/* IRDA */
CLKDEV_DEV_ID
(
"i2c-sh_mobile.1"
,
&
mstp_clks
[
MSTP323
]),
/* IIC1 */
CLKDEV_DEV_ID
(
"i2c-sh_mobile.1"
,
&
mstp_clks
[
MSTP323
]),
/* IIC1 */
CLKDEV_DEV_ID
(
"r8a66597_hcd.0"
,
&
mstp_clks
[
MSTP322
]),
/* USBHS */
CLKDEV_DEV_ID
(
"r8a66597_hcd.0"
,
&
mstp_clks
[
MSTP322
]),
/* USBHS */
...
...
arch/arm/mach-shmobile/include/mach/sh7372.h
View file @
b3773301
...
@@ -457,8 +457,12 @@ enum {
...
@@ -457,8 +457,12 @@ enum {
SHDMA_SLAVE_SDHI2_TX
,
SHDMA_SLAVE_SDHI2_TX
,
};
};
extern
struct
clk
dv_clki_clk
;
extern
struct
clk
sh7372_extal1_clk
;
extern
struct
clk
dv_clki_div2_clk
;
extern
struct
clk
sh7372_extal2_clk
;
extern
struct
clk
pllc2_clk
;
extern
struct
clk
sh7372_dv_clki_clk
;
extern
struct
clk
sh7372_dv_clki_div2_clk
;
extern
struct
clk
sh7372_pllc2_clk
;
extern
struct
clk
sh7372_fsiack_clk
;
extern
struct
clk
sh7372_fsibck_clk
;
#endif
/* __ASM_SH7372_H__ */
#endif
/* __ASM_SH7372_H__ */
arch/arm/mach-shmobile/intc-sh7372.c
View file @
b3773301
...
@@ -369,9 +369,13 @@ enum {
...
@@ -369,9 +369,13 @@ enum {
INTCS
,
INTCS
,
/* interrupt sources INTCS */
/* interrupt sources INTCS */
/* IRQ0S - IRQ31S */
VEU_VEU0
,
VEU_VEU1
,
VEU_VEU2
,
VEU_VEU3
,
VEU_VEU0
,
VEU_VEU1
,
VEU_VEU2
,
VEU_VEU3
,
RTDMAC_1_DEI0
,
RTDMAC_1_DEI1
,
RTDMAC_1_DEI2
,
RTDMAC_1_DEI3
,
RTDMAC_1_DEI0
,
RTDMAC_1_DEI1
,
RTDMAC_1_DEI2
,
RTDMAC_1_DEI3
,
CEU
,
BEU_BEU0
,
BEU_BEU1
,
BEU_BEU2
,
CEU
,
BEU_BEU0
,
BEU_BEU1
,
BEU_BEU2
,
/* MFI */
/* BBIF2 */
VPU
,
VPU
,
TSIF1
,
TSIF1
,
_3DG_SGX530
,
_3DG_SGX530
,
...
@@ -379,13 +383,17 @@ enum {
...
@@ -379,13 +383,17 @@ enum {
IIC2_ALI2
,
IIC2_TACKI2
,
IIC2_WAITI2
,
IIC2_DTEI2
,
IIC2_ALI2
,
IIC2_TACKI2
,
IIC2_WAITI2
,
IIC2_DTEI2
,
IPMMU_IPMMUR
,
IPMMU_IPMMUR2
,
IPMMU_IPMMUR
,
IPMMU_IPMMUR2
,
RTDMAC_2_DEI4
,
RTDMAC_2_DEI5
,
RTDMAC_2_DADERR
,
RTDMAC_2_DEI4
,
RTDMAC_2_DEI5
,
RTDMAC_2_DADERR
,
/* KEYSC */
/* TTI20 */
MSIOF
,
MSIOF
,
IIC0_ALI0
,
IIC0_TACKI0
,
IIC0_WAITI0
,
IIC0_DTEI0
,
IIC0_ALI0
,
IIC0_TACKI0
,
IIC0_WAITI0
,
IIC0_DTEI0
,
TMU_TUNI0
,
TMU_TUNI1
,
TMU_TUNI2
,
TMU_TUNI0
,
TMU_TUNI1
,
TMU_TUNI2
,
CMT0
,
CMT0
,
TSIF0
,
TSIF0
,
/* CMT2 */
LMB
,
LMB
,
CTI
,
CTI
,
/* RWDT0 */
ICB
,
ICB
,
JPU_JPEG
,
JPU_JPEG
,
LCDC
,
LCDC
,
...
@@ -397,11 +405,17 @@ enum {
...
@@ -397,11 +405,17 @@ enum {
CSIRX
,
CSIRX
,
DSITX_DSITX0
,
DSITX_DSITX0
,
DSITX_DSITX1
,
DSITX_DSITX1
,
/* SPU2 */
/* FSI */
/* FMSI */
/* HDMI */
TMU1_TUNI0
,
TMU1_TUNI1
,
TMU1_TUNI2
,
TMU1_TUNI0
,
TMU1_TUNI1
,
TMU1_TUNI2
,
CMT4
,
CMT4
,
DSITX1_DSITX1_0
,
DSITX1_DSITX1_0
,
DSITX1_DSITX1_1
,
DSITX1_DSITX1_1
,
/* MFIS2 */
CPORTS2R
,
CPORTS2R
,
/* CEC */
JPU6E
,
JPU6E
,
/* interrupt groups INTCS */
/* interrupt groups INTCS */
...
@@ -410,12 +424,15 @@ enum {
...
@@ -410,12 +424,15 @@ enum {
};
};
static
struct
intc_vect
intcs_vectors
[]
=
{
static
struct
intc_vect
intcs_vectors
[]
=
{
/* IRQ0S - IRQ31S */
INTCS_VECT
(
VEU_VEU0
,
0x700
),
INTCS_VECT
(
VEU_VEU1
,
0x720
),
INTCS_VECT
(
VEU_VEU0
,
0x700
),
INTCS_VECT
(
VEU_VEU1
,
0x720
),
INTCS_VECT
(
VEU_VEU2
,
0x740
),
INTCS_VECT
(
VEU_VEU3
,
0x760
),
INTCS_VECT
(
VEU_VEU2
,
0x740
),
INTCS_VECT
(
VEU_VEU3
,
0x760
),
INTCS_VECT
(
RTDMAC_1_DEI0
,
0x800
),
INTCS_VECT
(
RTDMAC_1_DEI1
,
0x820
),
INTCS_VECT
(
RTDMAC_1_DEI0
,
0x800
),
INTCS_VECT
(
RTDMAC_1_DEI1
,
0x820
),
INTCS_VECT
(
RTDMAC_1_DEI2
,
0x840
),
INTCS_VECT
(
RTDMAC_1_DEI3
,
0x860
),
INTCS_VECT
(
RTDMAC_1_DEI2
,
0x840
),
INTCS_VECT
(
RTDMAC_1_DEI3
,
0x860
),
INTCS_VECT
(
CEU
,
0x880
),
INTCS_VECT
(
BEU_BEU0
,
0x8a0
),
INTCS_VECT
(
CEU
,
0x880
),
INTCS_VECT
(
BEU_BEU0
,
0x8a0
),
INTCS_VECT
(
BEU_BEU1
,
0x8c0
),
INTCS_VECT
(
BEU_BEU2
,
0x8e0
),
INTCS_VECT
(
BEU_BEU1
,
0x8c0
),
INTCS_VECT
(
BEU_BEU2
,
0x8e0
),
/* MFI */
/* BBIF2 */
INTCS_VECT
(
VPU
,
0x980
),
INTCS_VECT
(
VPU
,
0x980
),
INTCS_VECT
(
TSIF1
,
0x9a0
),
INTCS_VECT
(
TSIF1
,
0x9a0
),
INTCS_VECT
(
_3DG_SGX530
,
0x9e0
),
INTCS_VECT
(
_3DG_SGX530
,
0x9e0
),
...
@@ -425,14 +442,19 @@ static struct intc_vect intcs_vectors[] = {
...
@@ -425,14 +442,19 @@ static struct intc_vect intcs_vectors[] = {
INTCS_VECT
(
IPMMU_IPMMUR
,
0xb00
),
INTCS_VECT
(
IPMMU_IPMMUR2
,
0xb20
),
INTCS_VECT
(
IPMMU_IPMMUR
,
0xb00
),
INTCS_VECT
(
IPMMU_IPMMUR2
,
0xb20
),
INTCS_VECT
(
RTDMAC_2_DEI4
,
0xb80
),
INTCS_VECT
(
RTDMAC_2_DEI5
,
0xba0
),
INTCS_VECT
(
RTDMAC_2_DEI4
,
0xb80
),
INTCS_VECT
(
RTDMAC_2_DEI5
,
0xba0
),
INTCS_VECT
(
RTDMAC_2_DADERR
,
0xbc0
),
INTCS_VECT
(
RTDMAC_2_DADERR
,
0xbc0
),
/* KEYSC */
/* TTI20 */
INTCS_VECT
(
MSIOF
,
0x0d20
),
INTCS_VECT
(
IIC0_ALI0
,
0xe00
),
INTCS_VECT
(
IIC0_TACKI0
,
0xe20
),
INTCS_VECT
(
IIC0_ALI0
,
0xe00
),
INTCS_VECT
(
IIC0_TACKI0
,
0xe20
),
INTCS_VECT
(
IIC0_WAITI0
,
0xe40
),
INTCS_VECT
(
IIC0_DTEI0
,
0xe60
),
INTCS_VECT
(
IIC0_WAITI0
,
0xe40
),
INTCS_VECT
(
IIC0_DTEI0
,
0xe60
),
INTCS_VECT
(
TMU_TUNI0
,
0xe80
),
INTCS_VECT
(
TMU_TUNI1
,
0xea0
),
INTCS_VECT
(
TMU_TUNI0
,
0xe80
),
INTCS_VECT
(
TMU_TUNI1
,
0xea0
),
INTCS_VECT
(
TMU_TUNI2
,
0xec0
),
INTCS_VECT
(
TMU_TUNI2
,
0xec0
),
INTCS_VECT
(
CMT0
,
0xf00
),
INTCS_VECT
(
CMT0
,
0xf00
),
INTCS_VECT
(
TSIF0
,
0xf20
),
INTCS_VECT
(
TSIF0
,
0xf20
),
/* CMT2 */
INTCS_VECT
(
LMB
,
0xf60
),
INTCS_VECT
(
LMB
,
0xf60
),
INTCS_VECT
(
CTI
,
0x400
),
INTCS_VECT
(
CTI
,
0x400
),
/* RWDT0 */
INTCS_VECT
(
ICB
,
0x480
),
INTCS_VECT
(
ICB
,
0x480
),
INTCS_VECT
(
JPU_JPEG
,
0x560
),
INTCS_VECT
(
JPU_JPEG
,
0x560
),
INTCS_VECT
(
LCDC
,
0x580
),
INTCS_VECT
(
LCDC
,
0x580
),
...
@@ -446,12 +468,18 @@ static struct intc_vect intcs_vectors[] = {
...
@@ -446,12 +468,18 @@ static struct intc_vect intcs_vectors[] = {
INTCS_VECT
(
CSIRX
,
0x17a0
),
INTCS_VECT
(
CSIRX
,
0x17a0
),
INTCS_VECT
(
DSITX_DSITX0
,
0x17c0
),
INTCS_VECT
(
DSITX_DSITX0
,
0x17c0
),
INTCS_VECT
(
DSITX_DSITX1
,
0x17e0
),
INTCS_VECT
(
DSITX_DSITX1
,
0x17e0
),
/* SPU2 */
/* FSI */
/* FMSI */
/* HDMI */
INTCS_VECT
(
TMU1_TUNI0
,
0x1900
),
INTCS_VECT
(
TMU1_TUNI1
,
0x1920
),
INTCS_VECT
(
TMU1_TUNI0
,
0x1900
),
INTCS_VECT
(
TMU1_TUNI1
,
0x1920
),
INTCS_VECT
(
TMU1_TUNI2
,
0x1940
),
INTCS_VECT
(
TMU1_TUNI2
,
0x1940
),
INTCS_VECT
(
CMT4
,
0x1980
),
INTCS_VECT
(
CMT4
,
0x1980
),
INTCS_VECT
(
DSITX1_DSITX1_0
,
0x19a0
),
INTCS_VECT
(
DSITX1_DSITX1_0
,
0x19a0
),
INTCS_VECT
(
DSITX1_DSITX1_1
,
0x19c0
),
INTCS_VECT
(
DSITX1_DSITX1_1
,
0x19c0
),
/* MFIS2 */
INTCS_VECT
(
CPORTS2R
,
0x1a20
),
INTCS_VECT
(
CPORTS2R
,
0x1a20
),
/* CEC */
INTCS_VECT
(
JPU6E
,
0x1a80
),
INTCS_VECT
(
JPU6E
,
0x1a80
),
INTC_VECT
(
INTCS
,
0xf80
),
INTC_VECT
(
INTCS
,
0xf80
),
...
...
arch/arm/mach-shmobile/pfc-sh7372.c
View file @
b3773301
...
@@ -166,12 +166,12 @@ enum {
...
@@ -166,12 +166,12 @@ enum {
MSIOF2_TSYNC_MARK
,
MSIOF2_TSCK_MARK
,
MSIOF2_RXD_MARK
,
MSIOF2_TSYNC_MARK
,
MSIOF2_TSCK_MARK
,
MSIOF2_RXD_MARK
,
MSIOF2_TXD_MARK
,
MSIOF2_TXD_MARK
,
/*
MSIOF3
*/
/*
BBIF1
*/
BBIF1_RXD_MARK
,
BBIF1_TSYNC_MARK
,
BBIF1_TSCK_MARK
,
BBIF1_RXD_MARK
,
BBIF1_TSYNC_MARK
,
BBIF1_TSCK_MARK
,
BBIF1_TXD_MARK
,
BBIF1_RSCK_MARK
,
BBIF1_RSYNC_MARK
,
BBIF1_TXD_MARK
,
BBIF1_RSCK_MARK
,
BBIF1_RSYNC_MARK
,
BBIF1_FLOW_MARK
,
BB_RX_FLOW_N_MARK
,
BBIF1_FLOW_MARK
,
BB_RX_FLOW_N_MARK
,
/*
MSIOF4
*/
/*
BBIF2
*/
BBIF2_TSCK1_MARK
,
BBIF2_TSYNC1_MARK
,
BBIF2_TSCK1_MARK
,
BBIF2_TSYNC1_MARK
,
BBIF2_TXD1_MARK
,
BBIF2_RXD_MARK
,
BBIF2_TXD1_MARK
,
BBIF2_RXD_MARK
,
...
@@ -976,12 +976,12 @@ static struct pinmux_gpio pinmux_gpios[] = {
...
@@ -976,12 +976,12 @@ static struct pinmux_gpio pinmux_gpios[] = {
GPIO_FN
(
MSIOF2_TSYNC
),
GPIO_FN
(
MSIOF2_TSCK
),
GPIO_FN
(
MSIOF2_RXD
),
GPIO_FN
(
MSIOF2_TSYNC
),
GPIO_FN
(
MSIOF2_TSCK
),
GPIO_FN
(
MSIOF2_RXD
),
GPIO_FN
(
MSIOF2_TXD
),
GPIO_FN
(
MSIOF2_TXD
),
/*
MSIOF3
*/
/*
BBIF1
*/
GPIO_FN
(
BBIF1_RXD
),
GPIO_FN
(
BBIF1_TSYNC
),
GPIO_FN
(
BBIF1_TSCK
),
GPIO_FN
(
BBIF1_RXD
),
GPIO_FN
(
BBIF1_TSYNC
),
GPIO_FN
(
BBIF1_TSCK
),
GPIO_FN
(
BBIF1_TXD
),
GPIO_FN
(
BBIF1_RSCK
),
GPIO_FN
(
BBIF1_RSYNC
),
GPIO_FN
(
BBIF1_TXD
),
GPIO_FN
(
BBIF1_RSCK
),
GPIO_FN
(
BBIF1_RSYNC
),
GPIO_FN
(
BBIF1_FLOW
),
GPIO_FN
(
BB_RX_FLOW_N
),
GPIO_FN
(
BBIF1_FLOW
),
GPIO_FN
(
BB_RX_FLOW_N
),
/*
MSIOF4
*/
/*
BBIF2
*/
GPIO_FN
(
BBIF2_TSCK1
),
GPIO_FN
(
BBIF2_TSYNC1
),
GPIO_FN
(
BBIF2_TSCK1
),
GPIO_FN
(
BBIF2_TSYNC1
),
GPIO_FN
(
BBIF2_TXD1
),
GPIO_FN
(
BBIF2_RXD
),
GPIO_FN
(
BBIF2_TXD1
),
GPIO_FN
(
BBIF2_RXD
),
...
...
arch/arm/mach-shmobile/setup-sh7367.c
View file @
b3773301
...
@@ -154,7 +154,6 @@ static struct sh_timer_config cmt10_platform_data = {
...
@@ -154,7 +154,6 @@ static struct sh_timer_config cmt10_platform_data = {
.
name
=
"CMT10"
,
.
name
=
"CMT10"
,
.
channel_offset
=
0x10
,
.
channel_offset
=
0x10
,
.
timer_bit
=
0
,
.
timer_bit
=
0
,
.
clk
=
"r_clk"
,
.
clockevent_rating
=
125
,
.
clockevent_rating
=
125
,
.
clocksource_rating
=
125
,
.
clocksource_rating
=
125
,
};
};
...
...
arch/arm/mach-shmobile/setup-sh7372.c
View file @
b3773301
...
@@ -158,7 +158,6 @@ static struct sh_timer_config cmt10_platform_data = {
...
@@ -158,7 +158,6 @@ static struct sh_timer_config cmt10_platform_data = {
.
name
=
"CMT10"
,
.
name
=
"CMT10"
,
.
channel_offset
=
0x10
,
.
channel_offset
=
0x10
,
.
timer_bit
=
0
,
.
timer_bit
=
0
,
.
clk
=
"cmt1"
,
.
clockevent_rating
=
125
,
.
clockevent_rating
=
125
,
.
clocksource_rating
=
125
,
.
clocksource_rating
=
125
,
};
};
...
@@ -186,6 +185,67 @@ static struct platform_device cmt10_device = {
...
@@ -186,6 +185,67 @@ static struct platform_device cmt10_device = {
.
num_resources
=
ARRAY_SIZE
(
cmt10_resources
),
.
num_resources
=
ARRAY_SIZE
(
cmt10_resources
),
};
};
/* TMU */
static
struct
sh_timer_config
tmu00_platform_data
=
{
.
name
=
"TMU00"
,
.
channel_offset
=
0x4
,
.
timer_bit
=
0
,
.
clockevent_rating
=
200
,
};
static
struct
resource
tmu00_resources
[]
=
{
[
0
]
=
{
.
name
=
"TMU00"
,
.
start
=
0xfff60008
,
.
end
=
0xfff60013
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
intcs_evt2irq
(
0xe80
),
/* TMU_TUNI0 */
.
flags
=
IORESOURCE_IRQ
,
},
};
static
struct
platform_device
tmu00_device
=
{
.
name
=
"sh_tmu"
,
.
id
=
0
,
.
dev
=
{
.
platform_data
=
&
tmu00_platform_data
,
},
.
resource
=
tmu00_resources
,
.
num_resources
=
ARRAY_SIZE
(
tmu00_resources
),
};
static
struct
sh_timer_config
tmu01_platform_data
=
{
.
name
=
"TMU01"
,
.
channel_offset
=
0x10
,
.
timer_bit
=
1
,
.
clocksource_rating
=
200
,
};
static
struct
resource
tmu01_resources
[]
=
{
[
0
]
=
{
.
name
=
"TMU01"
,
.
start
=
0xfff60014
,
.
end
=
0xfff6001f
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
intcs_evt2irq
(
0xea0
),
/* TMU_TUNI1 */
.
flags
=
IORESOURCE_IRQ
,
},
};
static
struct
platform_device
tmu01_device
=
{
.
name
=
"sh_tmu"
,
.
id
=
1
,
.
dev
=
{
.
platform_data
=
&
tmu01_platform_data
,
},
.
resource
=
tmu01_resources
,
.
num_resources
=
ARRAY_SIZE
(
tmu01_resources
),
};
/* I2C */
/* I2C */
static
struct
resource
iic0_resources
[]
=
{
static
struct
resource
iic0_resources
[]
=
{
[
0
]
=
{
[
0
]
=
{
...
@@ -419,14 +479,14 @@ static struct resource sh7372_dmae0_resources[] = {
...
@@ -419,14 +479,14 @@ static struct resource sh7372_dmae0_resources[] = {
},
},
{
{
/* DMA error IRQ */
/* DMA error IRQ */
.
start
=
246
,
.
start
=
evt2irq
(
0x20c0
)
,
.
end
=
246
,
.
end
=
evt2irq
(
0x20c0
)
,
.
flags
=
IORESOURCE_IRQ
,
.
flags
=
IORESOURCE_IRQ
,
},
},
{
{
/* IRQ for channels 0-5 */
/* IRQ for channels 0-5 */
.
start
=
240
,
.
start
=
evt2irq
(
0x2000
)
,
.
end
=
245
,
.
end
=
evt2irq
(
0x20a0
)
,
.
flags
=
IORESOURCE_IRQ
,
.
flags
=
IORESOURCE_IRQ
,
},
},
};
};
...
@@ -447,14 +507,14 @@ static struct resource sh7372_dmae1_resources[] = {
...
@@ -447,14 +507,14 @@ static struct resource sh7372_dmae1_resources[] = {
},
},
{
{
/* DMA error IRQ */
/* DMA error IRQ */
.
start
=
254
,
.
start
=
evt2irq
(
0x21c0
)
,
.
end
=
254
,
.
end
=
evt2irq
(
0x21c0
)
,
.
flags
=
IORESOURCE_IRQ
,
.
flags
=
IORESOURCE_IRQ
,
},
},
{
{
/* IRQ for channels 0-5 */
/* IRQ for channels 0-5 */
.
start
=
248
,
.
start
=
evt2irq
(
0x2100
)
,
.
end
=
253
,
.
end
=
evt2irq
(
0x21a0
)
,
.
flags
=
IORESOURCE_IRQ
,
.
flags
=
IORESOURCE_IRQ
,
},
},
};
};
...
@@ -475,14 +535,14 @@ static struct resource sh7372_dmae2_resources[] = {
...
@@ -475,14 +535,14 @@ static struct resource sh7372_dmae2_resources[] = {
},
},
{
{
/* DMA error IRQ */
/* DMA error IRQ */
.
start
=
262
,
.
start
=
evt2irq
(
0x22c0
)
,
.
end
=
262
,
.
end
=
evt2irq
(
0x22c0
)
,
.
flags
=
IORESOURCE_IRQ
,
.
flags
=
IORESOURCE_IRQ
,
},
},
{
{
/* IRQ for channels 0-5 */
/* IRQ for channels 0-5 */
.
start
=
256
,
.
start
=
evt2irq
(
0x2200
)
,
.
end
=
261
,
.
end
=
evt2irq
(
0x22a0
)
,
.
flags
=
IORESOURCE_IRQ
,
.
flags
=
IORESOURCE_IRQ
,
},
},
};
};
...
@@ -526,6 +586,11 @@ static struct platform_device *sh7372_early_devices[] __initdata = {
...
@@ -526,6 +586,11 @@ static struct platform_device *sh7372_early_devices[] __initdata = {
&
scif5_device
,
&
scif5_device
,
&
scif6_device
,
&
scif6_device
,
&
cmt10_device
,
&
cmt10_device
,
&
tmu00_device
,
&
tmu01_device
,
};
static
struct
platform_device
*
sh7372_late_devices
[]
__initdata
=
{
&
iic0_device
,
&
iic0_device
,
&
iic1_device
,
&
iic1_device
,
&
dma0_device
,
&
dma0_device
,
...
@@ -537,6 +602,9 @@ void __init sh7372_add_standard_devices(void)
...
@@ -537,6 +602,9 @@ void __init sh7372_add_standard_devices(void)
{
{
platform_add_devices
(
sh7372_early_devices
,
platform_add_devices
(
sh7372_early_devices
,
ARRAY_SIZE
(
sh7372_early_devices
));
ARRAY_SIZE
(
sh7372_early_devices
));
platform_add_devices
(
sh7372_late_devices
,
ARRAY_SIZE
(
sh7372_late_devices
));
}
}
void
__init
sh7372_add_early_devices
(
void
)
void
__init
sh7372_add_early_devices
(
void
)
...
...
arch/arm/mach-shmobile/setup-sh7377.c
View file @
b3773301
...
@@ -172,7 +172,6 @@ static struct sh_timer_config cmt10_platform_data = {
...
@@ -172,7 +172,6 @@ static struct sh_timer_config cmt10_platform_data = {
.
name
=
"CMT10"
,
.
name
=
"CMT10"
,
.
channel_offset
=
0x10
,
.
channel_offset
=
0x10
,
.
timer_bit
=
0
,
.
timer_bit
=
0
,
.
clk
=
"r_clk"
,
.
clockevent_rating
=
125
,
.
clockevent_rating
=
125
,
.
clocksource_rating
=
125
,
.
clocksource_rating
=
125
,
};
};
...
...
arch/sh/boards/mach-ap325rxa/setup.c
View file @
b3773301
...
@@ -176,6 +176,21 @@ static void ap320_wvga_power_off(void *board_data)
...
@@ -176,6 +176,21 @@ static void ap320_wvga_power_off(void *board_data)
__raw_writew
(
0
,
FPGA_LCDREG
);
__raw_writew
(
0
,
FPGA_LCDREG
);
}
}
const
static
struct
fb_videomode
ap325rxa_lcdc_modes
[]
=
{
{
.
name
=
"LB070WV1"
,
.
xres
=
800
,
.
yres
=
480
,
.
left_margin
=
32
,
.
right_margin
=
160
,
.
hsync_len
=
8
,
.
upper_margin
=
63
,
.
lower_margin
=
80
,
.
vsync_len
=
1
,
.
sync
=
0
,
/* hsync and vsync are active low */
},
};
static
struct
sh_mobile_lcdc_info
lcdc_info
=
{
static
struct
sh_mobile_lcdc_info
lcdc_info
=
{
.
clock_source
=
LCDC_CLK_EXTERNAL
,
.
clock_source
=
LCDC_CLK_EXTERNAL
,
.
ch
[
0
]
=
{
.
ch
[
0
]
=
{
...
@@ -183,18 +198,8 @@ static struct sh_mobile_lcdc_info lcdc_info = {
...
@@ -183,18 +198,8 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.
bpp
=
16
,
.
bpp
=
16
,
.
interface_type
=
RGB18
,
.
interface_type
=
RGB18
,
.
clock_divider
=
1
,
.
clock_divider
=
1
,
.
lcd_cfg
=
{
.
lcd_cfg
=
ap325rxa_lcdc_modes
,
.
name
=
"LB070WV1"
,
.
num_cfg
=
ARRAY_SIZE
(
ap325rxa_lcdc_modes
),
.
xres
=
800
,
.
yres
=
480
,
.
left_margin
=
32
,
.
right_margin
=
160
,
.
hsync_len
=
8
,
.
upper_margin
=
63
,
.
lower_margin
=
80
,
.
vsync_len
=
1
,
.
sync
=
0
,
/* hsync and vsync are active low */
},
.
lcd_size_cfg
=
{
/* 7.0 inch */
.
lcd_size_cfg
=
{
/* 7.0 inch */
.
width
=
152
,
.
width
=
152
,
.
height
=
91
,
.
height
=
91
,
...
...
arch/sh/boards/mach-ecovec24/setup.c
View file @
b3773301
...
@@ -231,14 +231,41 @@ static struct platform_device usb1_common_device = {
...
@@ -231,14 +231,41 @@ static struct platform_device usb1_common_device = {
};
};
/* LCDC */
/* LCDC */
const
static
struct
fb_videomode
ecovec_lcd_modes
[]
=
{
{
.
name
=
"Panel"
,
.
xres
=
800
,
.
yres
=
480
,
.
left_margin
=
220
,
.
right_margin
=
110
,
.
hsync_len
=
70
,
.
upper_margin
=
20
,
.
lower_margin
=
5
,
.
vsync_len
=
5
,
.
sync
=
0
,
/* hsync and vsync are active low */
},
};
const
static
struct
fb_videomode
ecovec_dvi_modes
[]
=
{
{
.
name
=
"DVI"
,
.
xres
=
1280
,
.
yres
=
720
,
.
left_margin
=
220
,
.
right_margin
=
110
,
.
hsync_len
=
40
,
.
upper_margin
=
20
,
.
lower_margin
=
5
,
.
vsync_len
=
5
,
.
sync
=
0
,
/* hsync and vsync are active low */
},
};
static
struct
sh_mobile_lcdc_info
lcdc_info
=
{
static
struct
sh_mobile_lcdc_info
lcdc_info
=
{
.
ch
[
0
]
=
{
.
ch
[
0
]
=
{
.
interface_type
=
RGB18
,
.
interface_type
=
RGB18
,
.
chan
=
LCDC_CHAN_MAINLCD
,
.
chan
=
LCDC_CHAN_MAINLCD
,
.
bpp
=
16
,
.
bpp
=
16
,
.
lcd_cfg
=
{
.
sync
=
0
,
/* hsync and vsync are active low */
},
.
lcd_size_cfg
=
{
/* 7.0 inch */
.
lcd_size_cfg
=
{
/* 7.0 inch */
.
width
=
152
,
.
width
=
152
,
.
height
=
91
,
.
height
=
91
,
...
@@ -1079,33 +1106,18 @@ static int __init arch_setup(void)
...
@@ -1079,33 +1106,18 @@ static int __init arch_setup(void)
if
(
gpio_get_value
(
GPIO_PTE6
))
{
if
(
gpio_get_value
(
GPIO_PTE6
))
{
/* DVI */
/* DVI */
lcdc_info
.
clock_source
=
LCDC_CLK_EXTERNAL
;
lcdc_info
.
clock_source
=
LCDC_CLK_EXTERNAL
;
lcdc_info
.
ch
[
0
].
clock_divider
=
1
,
lcdc_info
.
ch
[
0
].
clock_divider
=
1
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
name
=
"DVI"
;
lcdc_info
.
ch
[
0
].
lcd_cfg
=
ecovec_dvi_modes
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
xres
=
1280
;
lcdc_info
.
ch
[
0
].
num_cfg
=
ARRAY_SIZE
(
ecovec_dvi_modes
);
lcdc_info
.
ch
[
0
].
lcd_cfg
.
yres
=
720
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
left_margin
=
220
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
right_margin
=
110
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
hsync_len
=
40
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
upper_margin
=
20
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
lower_margin
=
5
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
vsync_len
=
5
;
gpio_set_value
(
GPIO_PTA2
,
1
);
gpio_set_value
(
GPIO_PTA2
,
1
);
gpio_set_value
(
GPIO_PTU1
,
1
);
gpio_set_value
(
GPIO_PTU1
,
1
);
}
else
{
}
else
{
/* Panel */
/* Panel */
lcdc_info
.
clock_source
=
LCDC_CLK_PERIPHERAL
;
lcdc_info
.
clock_source
=
LCDC_CLK_PERIPHERAL
;
lcdc_info
.
ch
[
0
].
clock_divider
=
2
,
lcdc_info
.
ch
[
0
].
clock_divider
=
2
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
name
=
"Panel"
;
lcdc_info
.
ch
[
0
].
lcd_cfg
=
ecovec_lcd_modes
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
xres
=
800
;
lcdc_info
.
ch
[
0
].
num_cfg
=
ARRAY_SIZE
(
ecovec_lcd_modes
);
lcdc_info
.
ch
[
0
].
lcd_cfg
.
yres
=
480
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
left_margin
=
220
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
right_margin
=
110
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
hsync_len
=
70
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
upper_margin
=
20
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
lower_margin
=
5
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
vsync_len
=
5
;
gpio_set_value
(
GPIO_PTR1
,
1
);
gpio_set_value
(
GPIO_PTR1
,
1
);
...
...
arch/sh/boards/mach-kfr2r09/setup.c
View file @
b3773301
...
@@ -126,6 +126,21 @@ static struct platform_device kfr2r09_sh_keysc_device = {
...
@@ -126,6 +126,21 @@ static struct platform_device kfr2r09_sh_keysc_device = {
},
},
};
};
const
static
struct
fb_videomode
kfr2r09_lcdc_modes
[]
=
{
{
.
name
=
"TX07D34VM0AAA"
,
.
xres
=
240
,
.
yres
=
400
,
.
left_margin
=
0
,
.
right_margin
=
16
,
.
hsync_len
=
8
,
.
upper_margin
=
0
,
.
lower_margin
=
1
,
.
vsync_len
=
1
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
},
};
static
struct
sh_mobile_lcdc_info
kfr2r09_sh_lcdc_info
=
{
static
struct
sh_mobile_lcdc_info
kfr2r09_sh_lcdc_info
=
{
.
clock_source
=
LCDC_CLK_BUS
,
.
clock_source
=
LCDC_CLK_BUS
,
.
ch
[
0
]
=
{
.
ch
[
0
]
=
{
...
@@ -134,18 +149,8 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
...
@@ -134,18 +149,8 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
.
interface_type
=
SYS18
,
.
interface_type
=
SYS18
,
.
clock_divider
=
6
,
.
clock_divider
=
6
,
.
flags
=
LCDC_FLAGS_DWPOL
,
.
flags
=
LCDC_FLAGS_DWPOL
,
.
lcd_cfg
=
{
.
lcd_cfg
=
kfr2r09_lcdc_modes
,
.
name
=
"TX07D34VM0AAA"
,
.
num_cfg
=
ARRAY_SIZE
(
kfr2r09_lcdc_modes
),
.
xres
=
240
,
.
yres
=
400
,
.
left_margin
=
0
,
.
right_margin
=
16
,
.
hsync_len
=
8
,
.
upper_margin
=
0
,
.
lower_margin
=
1
,
.
vsync_len
=
1
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
},
.
lcd_size_cfg
=
{
.
lcd_size_cfg
=
{
.
width
=
35
,
.
width
=
35
,
.
height
=
58
,
.
height
=
58
,
...
...
arch/sh/boards/mach-migor/setup.c
View file @
b3773301
...
@@ -213,51 +213,55 @@ static struct platform_device migor_nand_flash_device = {
...
@@ -213,51 +213,55 @@ static struct platform_device migor_nand_flash_device = {
}
}
};
};
const
static
struct
fb_videomode
migor_lcd_modes
[]
=
{
{
#if defined(CONFIG_SH_MIGOR_RTA_WVGA)
.
name
=
"LB070WV1"
,
.
xres
=
800
,
.
yres
=
480
,
.
left_margin
=
64
,
.
right_margin
=
16
,
.
hsync_len
=
120
,
.
sync
=
0
,
#elif defined(CONFIG_SH_MIGOR_QVGA)
.
name
=
"PH240320T"
,
.
xres
=
320
,
.
yres
=
240
,
.
left_margin
=
0
,
.
right_margin
=
16
,
.
hsync_len
=
8
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
,
#endif
.
upper_margin
=
1
,
.
lower_margin
=
17
,
.
vsync_len
=
2
,
},
};
static
struct
sh_mobile_lcdc_info
sh_mobile_lcdc_info
=
{
static
struct
sh_mobile_lcdc_info
sh_mobile_lcdc_info
=
{
#if
def CONFIG_SH_MIGOR_RTA_WVGA
#if
defined(CONFIG_SH_MIGOR_RTA_WVGA)
.
clock_source
=
LCDC_CLK_BUS
,
.
clock_source
=
LCDC_CLK_BUS
,
.
ch
[
0
]
=
{
.
ch
[
0
]
=
{
.
chan
=
LCDC_CHAN_MAINLCD
,
.
chan
=
LCDC_CHAN_MAINLCD
,
.
bpp
=
16
,
.
bpp
=
16
,
.
interface_type
=
RGB16
,
.
interface_type
=
RGB16
,
.
clock_divider
=
2
,
.
clock_divider
=
2
,
.
lcd_cfg
=
{
.
lcd_cfg
=
migor_lcd_modes
,
.
name
=
"LB070WV1"
,
.
num_cfg
=
ARRAY_SIZE
(
migor_lcd_modes
),
.
xres
=
800
,
.
yres
=
480
,
.
left_margin
=
64
,
.
right_margin
=
16
,
.
hsync_len
=
120
,
.
upper_margin
=
1
,
.
lower_margin
=
17
,
.
vsync_len
=
2
,
.
sync
=
0
,
},
.
lcd_size_cfg
=
{
/* 7.0 inch */
.
lcd_size_cfg
=
{
/* 7.0 inch */
.
width
=
152
,
.
width
=
152
,
.
height
=
91
,
.
height
=
91
,
},
},
}
}
#endif
#elif defined(CONFIG_SH_MIGOR_QVGA)
#ifdef CONFIG_SH_MIGOR_QVGA
.
clock_source
=
LCDC_CLK_PERIPHERAL
,
.
clock_source
=
LCDC_CLK_PERIPHERAL
,
.
ch
[
0
]
=
{
.
ch
[
0
]
=
{
.
chan
=
LCDC_CHAN_MAINLCD
,
.
chan
=
LCDC_CHAN_MAINLCD
,
.
bpp
=
16
,
.
bpp
=
16
,
.
interface_type
=
SYS16A
,
.
interface_type
=
SYS16A
,
.
clock_divider
=
10
,
.
clock_divider
=
10
,
.
lcd_cfg
=
{
.
lcd_cfg
=
migor_lcd_modes
,
.
name
=
"PH240320T"
,
.
num_cfg
=
ARRAY_SIZE
(
migor_lcd_modes
),
.
xres
=
320
,
.
yres
=
240
,
.
left_margin
=
0
,
.
right_margin
=
16
,
.
hsync_len
=
8
,
.
upper_margin
=
1
,
.
lower_margin
=
17
,
.
vsync_len
=
2
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
,
},
.
lcd_size_cfg
=
{
/* 2.4 inch */
.
lcd_size_cfg
=
{
/* 2.4 inch */
.
width
=
49
,
.
width
=
49
,
.
height
=
37
,
.
height
=
37
,
...
...
arch/sh/boards/mach-se/7724/setup.c
View file @
b3773301
...
@@ -144,16 +144,42 @@ static struct platform_device nor_flash_device = {
...
@@ -144,16 +144,42 @@ static struct platform_device nor_flash_device = {
};
};
/* LCDC */
/* LCDC */
const
static
struct
fb_videomode
lcdc_720p_modes
[]
=
{
{
.
name
=
"LB070WV1"
,
.
sync
=
0
,
/* hsync and vsync are active low */
.
xres
=
1280
,
.
yres
=
720
,
.
left_margin
=
220
,
.
right_margin
=
110
,
.
hsync_len
=
40
,
.
upper_margin
=
20
,
.
lower_margin
=
5
,
.
vsync_len
=
5
,
},
};
const
static
struct
fb_videomode
lcdc_vga_modes
[]
=
{
{
.
name
=
"LB070WV1"
,
.
sync
=
0
,
/* hsync and vsync are active low */
.
xres
=
640
,
.
yres
=
480
,
.
left_margin
=
105
,
.
right_margin
=
50
,
.
hsync_len
=
96
,
.
upper_margin
=
33
,
.
lower_margin
=
10
,
.
vsync_len
=
2
,
},
};
static
struct
sh_mobile_lcdc_info
lcdc_info
=
{
static
struct
sh_mobile_lcdc_info
lcdc_info
=
{
.
clock_source
=
LCDC_CLK_EXTERNAL
,
.
clock_source
=
LCDC_CLK_EXTERNAL
,
.
ch
[
0
]
=
{
.
ch
[
0
]
=
{
.
chan
=
LCDC_CHAN_MAINLCD
,
.
chan
=
LCDC_CHAN_MAINLCD
,
.
bpp
=
16
,
.
bpp
=
16
,
.
clock_divider
=
1
,
.
clock_divider
=
1
,
.
lcd_cfg
=
{
.
name
=
"LB070WV1"
,
.
sync
=
0
,
/* hsync and vsync are active low */
},
.
lcd_size_cfg
=
{
/* 7.0 inch */
.
lcd_size_cfg
=
{
/* 7.0 inch */
.
width
=
152
,
.
width
=
152
,
.
height
=
91
,
.
height
=
91
,
...
@@ -909,24 +935,12 @@ static int __init devices_setup(void)
...
@@ -909,24 +935,12 @@ static int __init devices_setup(void)
if
(
sw
&
SW41_B
)
{
if
(
sw
&
SW41_B
)
{
/* 720p */
/* 720p */
lcdc_info
.
ch
[
0
].
lcd_cfg
.
xres
=
1280
;
lcdc_info
.
ch
[
0
].
lcd_cfg
=
lcdc_720p_modes
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
yres
=
720
;
lcdc_info
.
ch
[
0
].
num_cfg
=
ARRAY_SIZE
(
lcdc_720p_modes
);
lcdc_info
.
ch
[
0
].
lcd_cfg
.
left_margin
=
220
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
right_margin
=
110
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
hsync_len
=
40
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
upper_margin
=
20
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
lower_margin
=
5
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
vsync_len
=
5
;
}
else
{
}
else
{
/* VGA */
/* VGA */
lcdc_info
.
ch
[
0
].
lcd_cfg
.
xres
=
640
;
lcdc_info
.
ch
[
0
].
lcd_cfg
=
lcdc_vga_modes
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
yres
=
480
;
lcdc_info
.
ch
[
0
].
num_cfg
=
ARRAY_SIZE
(
lcdc_vga_modes
);
lcdc_info
.
ch
[
0
].
lcd_cfg
.
left_margin
=
105
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
right_margin
=
50
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
hsync_len
=
96
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
upper_margin
=
33
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
lower_margin
=
10
;
lcdc_info
.
ch
[
0
].
lcd_cfg
.
vsync_len
=
2
;
}
}
if
(
sw
&
SW41_A
)
{
if
(
sw
&
SW41_A
)
{
...
...
drivers/video/sh_mipi_dsi.c
View file @
b3773301
...
@@ -123,83 +123,87 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
...
@@ -123,83 +123,87 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
u32
linelength
;
u32
linelength
;
bool
yuv
;
bool
yuv
;
/* Select data format */
/*
* Select data format. MIPI DSI is not hot-pluggable, so, we just use
* the default videomode. If this ever becomes a problem, We'll have to
* move this to mipi_display_on() above and use info->var.xres
*/
switch
(
pdata
->
data_format
)
{
switch
(
pdata
->
data_format
)
{
case
MIPI_RGB888
:
case
MIPI_RGB888
:
pctype
=
0
;
pctype
=
0
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_24
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_24
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_24BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_24BIT
;
linelength
=
ch
->
lcd_cfg
.
xres
*
3
;
linelength
=
ch
->
lcd_cfg
[
0
]
.
xres
*
3
;
yuv
=
false
;
yuv
=
false
;
break
;
break
;
case
MIPI_RGB565
:
case
MIPI_RGB565
:
pctype
=
1
;
pctype
=
1
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_16
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_16
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_16BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_16BIT
;
linelength
=
ch
->
lcd_cfg
.
xres
*
2
;
linelength
=
ch
->
lcd_cfg
[
0
]
.
xres
*
2
;
yuv
=
false
;
yuv
=
false
;
break
;
break
;
case
MIPI_RGB666_LP
:
case
MIPI_RGB666_LP
:
pctype
=
2
;
pctype
=
2
;
datatype
=
MIPI_DSI_PIXEL_STREAM_3BYTE_18
;
datatype
=
MIPI_DSI_PIXEL_STREAM_3BYTE_18
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_24BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_24BIT
;
linelength
=
ch
->
lcd_cfg
.
xres
*
3
;
linelength
=
ch
->
lcd_cfg
[
0
]
.
xres
*
3
;
yuv
=
false
;
yuv
=
false
;
break
;
break
;
case
MIPI_RGB666
:
case
MIPI_RGB666
:
pctype
=
3
;
pctype
=
3
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_18
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_18
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_18BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_18BIT
;
linelength
=
(
ch
->
lcd_cfg
.
xres
*
18
+
7
)
/
8
;
linelength
=
(
ch
->
lcd_cfg
[
0
]
.
xres
*
18
+
7
)
/
8
;
yuv
=
false
;
yuv
=
false
;
break
;
break
;
case
MIPI_BGR888
:
case
MIPI_BGR888
:
pctype
=
8
;
pctype
=
8
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_24
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_24
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_24BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_24BIT
;
linelength
=
ch
->
lcd_cfg
.
xres
*
3
;
linelength
=
ch
->
lcd_cfg
[
0
]
.
xres
*
3
;
yuv
=
false
;
yuv
=
false
;
break
;
break
;
case
MIPI_BGR565
:
case
MIPI_BGR565
:
pctype
=
9
;
pctype
=
9
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_16
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_16
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_16BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_16BIT
;
linelength
=
ch
->
lcd_cfg
.
xres
*
2
;
linelength
=
ch
->
lcd_cfg
[
0
]
.
xres
*
2
;
yuv
=
false
;
yuv
=
false
;
break
;
break
;
case
MIPI_BGR666_LP
:
case
MIPI_BGR666_LP
:
pctype
=
0xa
;
pctype
=
0xa
;
datatype
=
MIPI_DSI_PIXEL_STREAM_3BYTE_18
;
datatype
=
MIPI_DSI_PIXEL_STREAM_3BYTE_18
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_24BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_24BIT
;
linelength
=
ch
->
lcd_cfg
.
xres
*
3
;
linelength
=
ch
->
lcd_cfg
[
0
]
.
xres
*
3
;
yuv
=
false
;
yuv
=
false
;
break
;
break
;
case
MIPI_BGR666
:
case
MIPI_BGR666
:
pctype
=
0xb
;
pctype
=
0xb
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_18
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_18
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_18BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_18BIT
;
linelength
=
(
ch
->
lcd_cfg
.
xres
*
18
+
7
)
/
8
;
linelength
=
(
ch
->
lcd_cfg
[
0
]
.
xres
*
18
+
7
)
/
8
;
yuv
=
false
;
yuv
=
false
;
break
;
break
;
case
MIPI_YUYV
:
case
MIPI_YUYV
:
pctype
=
4
;
pctype
=
4
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_16BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_16BIT
;
linelength
=
ch
->
lcd_cfg
.
xres
*
2
;
linelength
=
ch
->
lcd_cfg
[
0
]
.
xres
*
2
;
yuv
=
true
;
yuv
=
true
;
break
;
break
;
case
MIPI_UYVY
:
case
MIPI_UYVY
:
pctype
=
5
;
pctype
=
5
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_16BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_16BIT
;
linelength
=
ch
->
lcd_cfg
.
xres
*
2
;
linelength
=
ch
->
lcd_cfg
[
0
]
.
xres
*
2
;
yuv
=
true
;
yuv
=
true
;
break
;
break
;
case
MIPI_YUV420_L
:
case
MIPI_YUV420_L
:
pctype
=
6
;
pctype
=
6
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_12BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_12BIT
;
linelength
=
(
ch
->
lcd_cfg
.
xres
*
12
+
7
)
/
8
;
linelength
=
(
ch
->
lcd_cfg
[
0
]
.
xres
*
12
+
7
)
/
8
;
yuv
=
true
;
yuv
=
true
;
break
;
break
;
case
MIPI_YUV420
:
case
MIPI_YUV420
:
...
@@ -207,7 +211,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
...
@@ -207,7 +211,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12
;
datatype
=
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_12BIT
;
pixfmt
=
MIPI_DCS_PIXEL_FMT_12BIT
;
/* Length of U/V line */
/* Length of U/V line */
linelength
=
(
ch
->
lcd_cfg
.
xres
+
1
)
/
2
;
linelength
=
(
ch
->
lcd_cfg
[
0
]
.
xres
+
1
)
/
2
;
yuv
=
true
;
yuv
=
true
;
break
;
break
;
default:
default:
...
@@ -281,7 +285,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
...
@@ -281,7 +285,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
iowrite32
(
0x00e00000
,
base
+
0x8024
);
/* VMCTR2 */
iowrite32
(
0x00e00000
,
base
+
0x8024
);
/* VMCTR2 */
/*
/*
* 0x660 = 1632 bytes per line (RGB24, 544 pixels: see
* 0x660 = 1632 bytes per line (RGB24, 544 pixels: see
* sh_mobile_lcdc_info.ch[0].lcd_cfg.xres), HSALEN = 1 - default
* sh_mobile_lcdc_info.ch[0].lcd_cfg
[0]
.xres), HSALEN = 1 - default
* (unused, since VMCTR2[HSABM] = 0)
* (unused, since VMCTR2[HSABM] = 0)
*/
*/
iowrite32
(
1
|
(
linelength
<<
16
),
base
+
0x8028
);
/* VMLEN1 */
iowrite32
(
1
|
(
linelength
<<
16
),
base
+
0x8028
);
/* VMLEN1 */
...
...
drivers/video/sh_mobile_hdmi.c
View file @
b3773301
...
@@ -28,6 +28,8 @@
...
@@ -28,6 +28,8 @@
#include <video/sh_mobile_hdmi.h>
#include <video/sh_mobile_hdmi.h>
#include <video/sh_mobile_lcdc.h>
#include <video/sh_mobile_lcdc.h>
#include "sh_mobile_lcdcfb.h"
#define HDMI_SYSTEM_CTRL 0x00
/* System control */
#define HDMI_SYSTEM_CTRL 0x00
/* System control */
#define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01
/* L/R data swap control,
#define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01
/* L/R data swap control,
bits 19..16 of 20-bit N for Audio Clock Regeneration packet */
bits 19..16 of 20-bit N for Audio Clock Regeneration packet */
...
@@ -206,12 +208,15 @@ enum hotplug_state {
...
@@ -206,12 +208,15 @@ enum hotplug_state {
struct
sh_hdmi
{
struct
sh_hdmi
{
void
__iomem
*
base
;
void
__iomem
*
base
;
enum
hotplug_state
hp_state
;
enum
hotplug_state
hp_state
;
/* hot-plug status */
bool
preprogrammed_mode
;
/* use a pre-programmed VIC or the external mode */
struct
clk
*
hdmi_clk
;
struct
clk
*
hdmi_clk
;
struct
device
*
dev
;
struct
device
*
dev
;
struct
fb_info
*
info
;
struct
fb_info
*
info
;
struct
mutex
mutex
;
/* Protect the info pointer */
struct
delayed_work
edid_work
;
struct
delayed_work
edid_work
;
struct
fb_var_screeninfo
var
;
struct
fb_var_screeninfo
var
;
struct
fb_monspecs
monspec
;
};
};
static
void
hdmi_write
(
struct
sh_hdmi
*
hdmi
,
u8
data
,
u8
reg
)
static
void
hdmi_write
(
struct
sh_hdmi
*
hdmi
,
u8
data
,
u8
reg
)
...
@@ -277,7 +282,7 @@ static struct snd_soc_codec_driver soc_codec_dev_sh_hdmi = {
...
@@ -277,7 +282,7 @@ static struct snd_soc_codec_driver soc_codec_dev_sh_hdmi = {
*/
*/
/* External video parameter settings */
/* External video parameter settings */
static
void
hdmi_external_video_param
(
struct
sh_hdmi
*
hdmi
)
static
void
sh_
hdmi_external_video_param
(
struct
sh_hdmi
*
hdmi
)
{
{
struct
fb_var_screeninfo
*
var
=
&
hdmi
->
var
;
struct
fb_var_screeninfo
*
var
=
&
hdmi
->
var
;
u16
htotal
,
hblank
,
hdelay
,
vtotal
,
vblank
,
vdelay
,
voffset
;
u16
htotal
,
hblank
,
hdelay
,
vtotal
,
vblank
,
vdelay
,
voffset
;
...
@@ -309,9 +314,9 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
...
@@ -309,9 +314,9 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
if
(
var
->
sync
&
FB_SYNC_VERT_HIGH_ACT
)
if
(
var
->
sync
&
FB_SYNC_VERT_HIGH_ACT
)
sync
|=
8
;
sync
|=
8
;
pr_debug
(
"H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x
\n
"
,
dev_dbg
(
hdmi
->
dev
,
"H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x
\n
"
,
htotal
,
hblank
,
hdelay
,
var
->
hsync_len
,
htotal
,
hblank
,
hdelay
,
var
->
hsync_len
,
vtotal
,
vblank
,
vdelay
,
var
->
vsync_len
,
sync
);
vtotal
,
vblank
,
vdelay
,
var
->
vsync_len
,
sync
);
hdmi_write
(
hdmi
,
sync
|
(
voffset
<<
4
),
HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS
);
hdmi_write
(
hdmi
,
sync
|
(
voffset
<<
4
),
HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS
);
...
@@ -336,7 +341,10 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
...
@@ -336,7 +341,10 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
hdmi_write
(
hdmi
,
var
->
vsync_len
,
HDMI_EXTERNAL_V_DURATION
);
hdmi_write
(
hdmi
,
var
->
vsync_len
,
HDMI_EXTERNAL_V_DURATION
);
/* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for manual mode */
/* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */
if
(
!
hdmi
->
preprogrammed_mode
)
hdmi_write
(
hdmi
,
sync
|
1
|
(
voffset
<<
4
),
HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS
);
}
}
/**
/**
...
@@ -454,21 +462,61 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
...
@@ -454,21 +462,61 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
}
}
/**
/**
* sh_hdmi_phy_config()
* sh_hdmi_phy_config()
- configure the HDMI PHY for the used video mode
*/
*/
static
void
sh_hdmi_phy_config
(
struct
sh_hdmi
*
hdmi
)
static
void
sh_hdmi_phy_config
(
struct
sh_hdmi
*
hdmi
)
{
{
/* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */
if
(
hdmi
->
var
.
yres
>
480
)
{
hdmi_write
(
hdmi
,
0x19
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_1
);
/* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */
hdmi_write
(
hdmi
,
0x00
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_2
);
/*
hdmi_write
(
hdmi
,
0x00
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_3
);
* [1:0] Speed_A
/* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */
* [3:2] Speed_B
hdmi_write
(
hdmi
,
0x44
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_5
);
* [4] PLLA_Bypass
hdmi_write
(
hdmi
,
0x32
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_6
);
* [6] DRV_TEST_EN
hdmi_write
(
hdmi
,
0x4A
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_7
);
* [7] DRV_TEST_IN
hdmi_write
(
hdmi
,
0x0E
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_8
);
*/
hdmi_write
(
hdmi
,
0x25
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_9
);
hdmi_write
(
hdmi
,
0x0f
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_1
);
hdmi_write
(
hdmi
,
0x04
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_10
);
/* PLLB_CONFIG[17], PLLA_CONFIG[17] - not in PHY datasheet */
hdmi_write
(
hdmi
,
0x00
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_2
);
/*
* [2:0] BGR_I_OFFSET
* [6:4] BGR_V_OFFSET
*/
hdmi_write
(
hdmi
,
0x00
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_3
);
/* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */
hdmi_write
(
hdmi
,
0x44
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_5
);
/*
* PLLA_CONFIG[15:8]: regulator voltage[0], CP current,
* LPF capacitance, LPF resistance[1]
*/
hdmi_write
(
hdmi
,
0x32
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_6
);
/* PLLB_CONFIG[7:0]: LPF resistance[0], VCO offset, VCO gain */
hdmi_write
(
hdmi
,
0x4A
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_7
);
/*
* PLLB_CONFIG[15:8]: regulator voltage[0], CP current,
* LPF capacitance, LPF resistance[1]
*/
hdmi_write
(
hdmi
,
0x00
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_8
);
/* DRV_CONFIG, PE_CONFIG */
hdmi_write
(
hdmi
,
0x25
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_9
);
/*
* [2:0] AMON_SEL (4 == LPF voltage)
* [4] PLLA_CONFIG[16]
* [5] PLLB_CONFIG[16]
*/
hdmi_write
(
hdmi
,
0x04
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_10
);
}
else
{
/* for 480p8bit 27MHz */
hdmi_write
(
hdmi
,
0x19
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_1
);
hdmi_write
(
hdmi
,
0x00
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_2
);
hdmi_write
(
hdmi
,
0x00
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_3
);
hdmi_write
(
hdmi
,
0x44
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_5
);
hdmi_write
(
hdmi
,
0x32
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_6
);
hdmi_write
(
hdmi
,
0x48
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_7
);
hdmi_write
(
hdmi
,
0x0F
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_8
);
hdmi_write
(
hdmi
,
0x20
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_9
);
hdmi_write
(
hdmi
,
0x04
,
HDMI_SLIPHDMIT_PARAM_SETTINGS_10
);
}
}
}
/**
/**
...
@@ -476,6 +524,8 @@ static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
...
@@ -476,6 +524,8 @@ static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
*/
*/
static
void
sh_hdmi_avi_infoframe_setup
(
struct
sh_hdmi
*
hdmi
)
static
void
sh_hdmi_avi_infoframe_setup
(
struct
sh_hdmi
*
hdmi
)
{
{
u8
vic
;
/* AVI InfoFrame */
/* AVI InfoFrame */
hdmi_write
(
hdmi
,
0x06
,
HDMI_CTRL_PKT_BUF_INDEX
);
hdmi_write
(
hdmi
,
0x06
,
HDMI_CTRL_PKT_BUF_INDEX
);
...
@@ -500,9 +550,9 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
...
@@ -500,9 +550,9 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_PB1
);
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_PB1
);
/*
/*
*
C = No D
ata
*
[7:6] C = Colorimetry: no d
ata
*
M = 16:9
Picture Aspect Ratio
*
[5:4] M = 2: 16:9, 1: 4:3
Picture Aspect Ratio
*
R = S
ame as picture aspect ratio
*
[3:0] R = 8: Active Frame Aspect Ratio: s
ame as picture aspect ratio
*/
*/
hdmi_write
(
hdmi
,
0x28
,
HDMI_CTRL_PKT_BUF_ACCESS_PB2
);
hdmi_write
(
hdmi
,
0x28
,
HDMI_CTRL_PKT_BUF_ACCESS_PB2
);
...
@@ -516,9 +566,15 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
...
@@ -516,9 +566,15 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
/*
/*
* VIC = 1280 x 720p: ignored if external config is used
* VIC = 1280 x 720p: ignored if external config is used
* Send 2 for 720 x 480p, 16 for 1080p
* Send 2 for 720 x 480p, 16 for 1080p
, ignored in external mode
*/
*/
hdmi_write
(
hdmi
,
4
,
HDMI_CTRL_PKT_BUF_ACCESS_PB4
);
if
(
hdmi
->
var
.
yres
==
1080
&&
hdmi
->
var
.
xres
==
1920
)
vic
=
16
;
else
if
(
hdmi
->
var
.
yres
==
480
&&
hdmi
->
var
.
xres
==
720
)
vic
=
2
;
else
vic
=
4
;
hdmi_write
(
hdmi
,
vic
,
HDMI_CTRL_PKT_BUF_ACCESS_PB4
);
/* PR = No Repetition */
/* PR = No Repetition */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_PB5
);
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_PB5
);
...
@@ -591,100 +647,6 @@ static void sh_hdmi_audio_infoframe_setup(struct sh_hdmi *hdmi)
...
@@ -591,100 +647,6 @@ static void sh_hdmi_audio_infoframe_setup(struct sh_hdmi *hdmi)
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_PB10
);
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_PB10
);
}
}
/**
* sh_hdmi_gamut_metadata_setup() - Gamut Metadata Packet of CONTROL PACKET
*/
static
void
sh_hdmi_gamut_metadata_setup
(
struct
sh_hdmi
*
hdmi
)
{
int
i
;
/* Gamut Metadata Packet */
hdmi_write
(
hdmi
,
0x04
,
HDMI_CTRL_PKT_BUF_INDEX
);
/* Packet Type = 0x0A */
hdmi_write
(
hdmi
,
0x0A
,
HDMI_CTRL_PKT_BUF_ACCESS_HB0
);
/* Gamut Packet is not used, so default value */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_HB1
);
/* Gamut Packet is not used, so default value */
hdmi_write
(
hdmi
,
0x10
,
HDMI_CTRL_PKT_BUF_ACCESS_HB2
);
/* GBD bytes 0 through 27 */
for
(
i
=
0
;
i
<=
27
;
i
++
)
/* HDMI_CTRL_PKT_BUF_ACCESS_PB0_63H - PB27_7EH */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_PB0
+
i
);
}
/**
* sh_hdmi_acp_setup() - Audio Content Protection Packet (ACP)
*/
static
void
sh_hdmi_acp_setup
(
struct
sh_hdmi
*
hdmi
)
{
int
i
;
/* Audio Content Protection Packet (ACP) */
hdmi_write
(
hdmi
,
0x01
,
HDMI_CTRL_PKT_BUF_INDEX
);
/* Packet Type = 0x04 */
hdmi_write
(
hdmi
,
0x04
,
HDMI_CTRL_PKT_BUF_ACCESS_HB0
);
/* ACP_Type */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_HB1
);
/* Reserved (0) */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_HB2
);
/* GBD bytes 0 through 27 */
for
(
i
=
0
;
i
<=
27
;
i
++
)
/* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_PB0
+
i
);
}
/**
* sh_hdmi_isrc1_setup() - ISRC1 Packet
*/
static
void
sh_hdmi_isrc1_setup
(
struct
sh_hdmi
*
hdmi
)
{
int
i
;
/* ISRC1 Packet */
hdmi_write
(
hdmi
,
0x02
,
HDMI_CTRL_PKT_BUF_INDEX
);
/* Packet Type = 0x05 */
hdmi_write
(
hdmi
,
0x05
,
HDMI_CTRL_PKT_BUF_ACCESS_HB0
);
/* ISRC_Cont, ISRC_Valid, Reserved (0), ISRC_Status */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_HB1
);
/* Reserved (0) */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_HB2
);
/* PB0 UPC_EAN_ISRC_0-15 */
/* Bytes PB16-PB27 shall be set to a value of 0. */
for
(
i
=
0
;
i
<=
27
;
i
++
)
/* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_PB0
+
i
);
}
/**
* sh_hdmi_isrc2_setup() - ISRC2 Packet
*/
static
void
sh_hdmi_isrc2_setup
(
struct
sh_hdmi
*
hdmi
)
{
int
i
;
/* ISRC2 Packet */
hdmi_write
(
hdmi
,
0x03
,
HDMI_CTRL_PKT_BUF_INDEX
);
/* HB0 Packet Type = 0x06 */
hdmi_write
(
hdmi
,
0x06
,
HDMI_CTRL_PKT_BUF_ACCESS_HB0
);
/* Reserved (0) */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_HB1
);
/* Reserved (0) */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_HB2
);
/* PB0 UPC_EAN_ISRC_16-31 */
/* Bytes PB16-PB27 shall be set to a value of 0. */
for
(
i
=
0
;
i
<=
27
;
i
++
)
/* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
hdmi_write
(
hdmi
,
0x00
,
HDMI_CTRL_PKT_BUF_ACCESS_PB0
+
i
);
}
/**
/**
* sh_hdmi_configure() - Initialise HDMI for output
* sh_hdmi_configure() - Initialise HDMI for output
*/
*/
...
@@ -705,18 +667,6 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
...
@@ -705,18 +667,6 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
/* Audio InfoFrame */
/* Audio InfoFrame */
sh_hdmi_audio_infoframe_setup
(
hdmi
);
sh_hdmi_audio_infoframe_setup
(
hdmi
);
/* Gamut Metadata packet */
sh_hdmi_gamut_metadata_setup
(
hdmi
);
/* Audio Content Protection (ACP) Packet */
sh_hdmi_acp_setup
(
hdmi
);
/* ISRC1 Packet */
sh_hdmi_isrc1_setup
(
hdmi
);
/* ISRC2 Packet */
sh_hdmi_isrc2_setup
(
hdmi
);
/*
/*
* Control packet auto send with VSYNC control: auto send
* Control packet auto send with VSYNC control: auto send
* General control, Gamut metadata, ISRC, and ACP packets
* General control, Gamut metadata, ISRC, and ACP packets
...
@@ -734,17 +684,42 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
...
@@ -734,17 +684,42 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
hdmi_write
(
hdmi
,
0x40
,
HDMI_SYSTEM_CTRL
);
hdmi_write
(
hdmi
,
0x40
,
HDMI_SYSTEM_CTRL
);
}
}
static
void
sh_hdmi_read_edid
(
struct
sh_hdmi
*
hdmi
)
static
unsigned
long
sh_hdmi_rate_error
(
struct
sh_hdmi
*
hdmi
,
const
struct
fb_videomode
*
mode
)
{
{
struct
fb_var_screeninfo
*
var
=
&
hdmi
->
var
;
long
target
=
PICOS2KHZ
(
mode
->
pixclock
)
*
1000
,
struct
sh_mobile_hdmi_info
*
pdata
=
hdmi
->
dev
->
platform_data
;
rate
=
clk_round_rate
(
hdmi
->
hdmi_clk
,
target
);
struct
fb_videomode
*
lcd_cfg
=
&
pdata
->
lcd_chan
->
lcd_cfg
;
unsigned
long
rate_error
=
rate
>
0
?
abs
(
rate
-
target
)
:
ULONG_MAX
;
unsigned
long
height
=
var
->
height
,
width
=
var
->
width
;
int
i
;
dev_dbg
(
hdmi
->
dev
,
"%u-%u-%u-%u x %u-%u-%u-%u
\n
"
,
mode
->
left_margin
,
mode
->
xres
,
mode
->
right_margin
,
mode
->
hsync_len
,
mode
->
upper_margin
,
mode
->
yres
,
mode
->
lower_margin
,
mode
->
vsync_len
);
dev_dbg
(
hdmi
->
dev
,
"
\t
@%lu(+/-%lu)Hz, e=%lu / 1000, r=%uHz
\n
"
,
target
,
rate_error
,
rate_error
?
10000
/
(
10
*
target
/
rate_error
)
:
0
,
mode
->
refresh
);
return
rate_error
;
}
static
int
sh_hdmi_read_edid
(
struct
sh_hdmi
*
hdmi
)
{
struct
fb_var_screeninfo
tmpvar
;
struct
fb_var_screeninfo
*
var
=
&
tmpvar
;
const
struct
fb_videomode
*
mode
,
*
found
=
NULL
;
struct
fb_info
*
info
=
hdmi
->
info
;
struct
fb_modelist
*
modelist
=
NULL
;
unsigned
int
f_width
=
0
,
f_height
=
0
,
f_refresh
=
0
;
unsigned
long
found_rate_error
=
ULONG_MAX
;
/* silly compiler... */
bool
exact_match
=
false
;
u8
edid
[
128
];
u8
edid
[
128
];
char
*
forced
;
int
i
;
/* Read EDID */
/* Read EDID */
pr_debug
(
"Read back EDID code:"
);
dev_dbg
(
hdmi
->
dev
,
"Read back EDID code:"
);
for
(
i
=
0
;
i
<
128
;
i
++
)
{
for
(
i
=
0
;
i
<
128
;
i
++
)
{
edid
[
i
]
=
hdmi_read
(
hdmi
,
HDMI_EDID_KSV_FIFO_ACCESS_WINDOW
);
edid
[
i
]
=
hdmi_read
(
hdmi
,
HDMI_EDID_KSV_FIFO_ACCESS_WINDOW
);
#ifdef DEBUG
#ifdef DEBUG
...
@@ -759,29 +734,97 @@ static void sh_hdmi_read_edid(struct sh_hdmi *hdmi)
...
@@ -759,29 +734,97 @@ static void sh_hdmi_read_edid(struct sh_hdmi *hdmi)
#ifdef DEBUG
#ifdef DEBUG
printk
(
KERN_CONT
"
\n
"
);
printk
(
KERN_CONT
"
\n
"
);
#endif
#endif
fb_parse_edid
(
edid
,
var
);
pr_debug
(
"%u-%u-%u-%u x %u-%u-%u-%u @ %lu kHz monitor detected
\n
"
,
fb_edid_to_monspecs
(
edid
,
&
hdmi
->
monspec
);
var
->
left_margin
,
var
->
xres
,
var
->
right_margin
,
var
->
hsync_len
,
var
->
upper_margin
,
var
->
yres
,
var
->
lower_margin
,
var
->
vsync_len
,
fb_get_options
(
"sh_mobile_lcdc"
,
&
forced
);
PICOS2KHZ
(
var
->
pixclock
));
if
(
forced
&&
*
forced
)
{
/* Only primitive parsing so far */
/* FIXME: Use user-provided configuration instead of EDID */
i
=
sscanf
(
forced
,
"%ux%u@%u"
,
var
->
width
=
width
;
&
f_width
,
&
f_height
,
&
f_refresh
);
var
->
xres
=
lcd_cfg
->
xres
;
if
(
i
<
2
)
{
var
->
xres_virtual
=
lcd_cfg
->
xres
;
f_width
=
0
;
var
->
left_margin
=
lcd_cfg
->
left_margin
;
f_height
=
0
;
var
->
right_margin
=
lcd_cfg
->
right_margin
;
}
var
->
hsync_len
=
lcd_cfg
->
hsync_len
;
dev_dbg
(
hdmi
->
dev
,
"Forced mode %ux%u@%uHz
\n
"
,
var
->
height
=
height
;
f_width
,
f_height
,
f_refresh
);
var
->
yres
=
lcd_cfg
->
yres
;
}
var
->
yres_virtual
=
lcd_cfg
->
yres
*
2
;
var
->
upper_margin
=
lcd_cfg
->
upper_margin
;
/* Walk monitor modes to find the best or the exact match */
var
->
lower_margin
=
lcd_cfg
->
lower_margin
;
for
(
i
=
0
,
mode
=
hdmi
->
monspec
.
modedb
;
var
->
vsync_len
=
lcd_cfg
->
vsync_len
;
f_width
&&
f_height
&&
i
<
hdmi
->
monspec
.
modedb_len
&&
!
exact_match
;
var
->
sync
=
lcd_cfg
->
sync
;
i
++
,
mode
++
)
{
var
->
pixclock
=
lcd_cfg
->
pixclock
;
unsigned
long
rate_error
=
sh_hdmi_rate_error
(
hdmi
,
mode
);
hdmi_external_video_param
(
hdmi
);
/* No interest in unmatching modes */
if
(
f_width
!=
mode
->
xres
||
f_height
!=
mode
->
yres
)
continue
;
if
(
f_refresh
==
mode
->
refresh
||
(
!
f_refresh
&&
!
rate_error
))
/*
* Exact match if either the refresh rate matches or it
* hasn't been specified and we've found a mode, for
* which we can configure the clock precisely
*/
exact_match
=
true
;
else
if
(
found
&&
found_rate_error
<=
rate_error
)
/*
* We otherwise search for the closest matching clock
* rate - either if no refresh rate has been specified
* or we cannot find an exactly matching one
*/
continue
;
/* Check if supported: sufficient fb memory, supported clock-rate */
fb_videomode_to_var
(
var
,
mode
);
if
(
info
&&
info
->
fbops
->
fb_check_var
&&
info
->
fbops
->
fb_check_var
(
var
,
info
))
{
exact_match
=
false
;
continue
;
}
found
=
mode
;
found_rate_error
=
rate_error
;
}
/*
* TODO 1: if no ->info is present, postpone running the config until
* after ->info first gets registered.
* TODO 2: consider registering the HDMI platform device from the LCDC
* driver, and passing ->info with HDMI platform data.
*/
if
(
info
&&
!
found
)
{
modelist
=
hdmi
->
info
->
modelist
.
next
&&
!
list_empty
(
&
hdmi
->
info
->
modelist
)
?
list_entry
(
hdmi
->
info
->
modelist
.
next
,
struct
fb_modelist
,
list
)
:
NULL
;
if
(
modelist
)
{
found
=
&
modelist
->
mode
;
found_rate_error
=
sh_hdmi_rate_error
(
hdmi
,
found
);
}
}
/* No cookie today */
if
(
!
found
)
return
-
ENXIO
;
dev_info
(
hdmi
->
dev
,
"Using %s mode %ux%u@%uHz (%luHz), clock error %luHz
\n
"
,
modelist
?
"default"
:
"EDID"
,
found
->
xres
,
found
->
yres
,
found
->
refresh
,
PICOS2KHZ
(
found
->
pixclock
)
*
1000
,
found_rate_error
);
if
((
found
->
xres
==
720
&&
found
->
yres
==
480
)
||
(
found
->
xres
==
1280
&&
found
->
yres
==
720
)
||
(
found
->
xres
==
1920
&&
found
->
yres
==
1080
))
hdmi
->
preprogrammed_mode
=
true
;
else
hdmi
->
preprogrammed_mode
=
false
;
fb_videomode_to_var
(
&
hdmi
->
var
,
found
);
sh_hdmi_external_video_param
(
hdmi
);
return
0
;
}
}
static
irqreturn_t
sh_hdmi_hotplug
(
int
irq
,
void
*
dev_id
)
static
irqreturn_t
sh_hdmi_hotplug
(
int
irq
,
void
*
dev_id
)
...
@@ -809,8 +852,8 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
...
@@ -809,8 +852,8 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
hdmi_write
(
hdmi
,
0xFF
,
HDMI_INTERRUPT_STATUS_2
);
hdmi_write
(
hdmi
,
0xFF
,
HDMI_INTERRUPT_STATUS_2
);
if
(
printk_ratelimit
())
if
(
printk_ratelimit
())
pr_debug
(
"IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x
\n
"
,
dev_dbg
(
hdmi
->
dev
,
"IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x
\n
"
,
irq
,
status1
,
mask1
,
status2
,
mask2
);
irq
,
status1
,
mask1
,
status2
,
mask2
);
if
(
!
((
status1
&
mask1
)
|
(
status2
&
mask2
)))
{
if
(
!
((
status1
&
mask1
)
|
(
status2
&
mask2
)))
{
return
IRQ_NONE
;
return
IRQ_NONE
;
...
@@ -821,7 +864,7 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
...
@@ -821,7 +864,7 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
udelay
(
500
);
udelay
(
500
);
msens
=
hdmi_read
(
hdmi
,
HDMI_HOT_PLUG_MSENS_STATUS
);
msens
=
hdmi_read
(
hdmi
,
HDMI_HOT_PLUG_MSENS_STATUS
);
pr_debug
(
"MSENS 0x%x
\n
"
,
msens
);
dev_dbg
(
hdmi
->
dev
,
"MSENS 0x%x
\n
"
,
msens
);
/* Check, if hot plug & MSENS pin status are both high */
/* Check, if hot plug & MSENS pin status are both high */
if
((
msens
&
0xC0
)
==
0xC0
)
{
if
((
msens
&
0xC0
)
==
0xC0
)
{
/* Display plug in */
/* Display plug in */
...
@@ -857,83 +900,176 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
...
@@ -857,83 +900,176 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
return
IRQ_HANDLED
;
return
IRQ_HANDLED
;
}
}
static
void
hdmi_display_on
(
void
*
arg
,
struct
fb_info
*
info
)
/* locking: called with info->lock held, or before register_framebuffer() */
static
void
sh_hdmi_display_on
(
void
*
arg
,
struct
fb_info
*
info
)
{
{
/*
* info is guaranteed to be valid, when we are called, because our
* FB_EVENT_FB_UNBIND notify is also called with info->lock held
*/
struct
sh_hdmi
*
hdmi
=
arg
;
struct
sh_hdmi
*
hdmi
=
arg
;
struct
sh_mobile_hdmi_info
*
pdata
=
hdmi
->
dev
->
platform_data
;
struct
sh_mobile_hdmi_info
*
pdata
=
hdmi
->
dev
->
platform_data
;
struct
sh_mobile_lcdc_chan
*
ch
=
info
->
par
;
if
(
info
->
var
.
xres
!=
1280
||
info
->
var
.
yres
!=
720
)
{
dev_dbg
(
hdmi
->
dev
,
"%s(%p): state %x
\n
"
,
__func__
,
dev_warn
(
info
->
device
,
"Unsupported framebuffer geometry %ux%u
\n
"
,
pdata
->
lcd_dev
,
info
->
state
);
info
->
var
.
xres
,
info
->
var
.
yres
);
return
;
/* No need to lock */
}
hdmi
->
info
=
info
;
pr_debug
(
"%s(%p): state %x
\n
"
,
__func__
,
pdata
->
lcd_dev
,
info
->
state
);
/*
/*
* FIXME: not a good place to store fb_info. And we cannot nullify it
* hp_state can be set to
* even on monitor disconnect. What should the lifecycle be?
* HDMI_HOTPLUG_DISCONNECTED: on monitor unplug
* HDMI_HOTPLUG_CONNECTED: on monitor plug-in
* HDMI_HOTPLUG_EDID_DONE: on EDID read completion
*/
*/
hdmi
->
info
=
info
;
switch
(
hdmi
->
hp_state
)
{
switch
(
hdmi
->
hp_state
)
{
case
HDMI_HOTPLUG_EDID_DONE
:
case
HDMI_HOTPLUG_EDID_DONE
:
/* PS mode d->e. All functions are active */
/* PS mode d->e. All functions are active */
hdmi_write
(
hdmi
,
0x80
,
HDMI_SYSTEM_CTRL
);
hdmi_write
(
hdmi
,
0x80
,
HDMI_SYSTEM_CTRL
);
pr_debug
(
"HDMI running
\n
"
);
dev_dbg
(
hdmi
->
dev
,
"HDMI running
\n
"
);
break
;
break
;
case
HDMI_HOTPLUG_DISCONNECTED
:
case
HDMI_HOTPLUG_DISCONNECTED
:
info
->
state
=
FBINFO_STATE_SUSPENDED
;
info
->
state
=
FBINFO_STATE_SUSPENDED
;
default:
default:
hdmi
->
var
=
info
->
var
;
hdmi
->
var
=
ch
->
display_
var
;
}
}
}
}
static
void
hdmi_display_off
(
void
*
arg
)
/* locking: called with info->lock held */
static
void
sh_hdmi_display_off
(
void
*
arg
)
{
{
struct
sh_hdmi
*
hdmi
=
arg
;
struct
sh_hdmi
*
hdmi
=
arg
;
struct
sh_mobile_hdmi_info
*
pdata
=
hdmi
->
dev
->
platform_data
;
struct
sh_mobile_hdmi_info
*
pdata
=
hdmi
->
dev
->
platform_data
;
pr_debug
(
"%s(%p)
\n
"
,
__func__
,
pdata
->
lcd_dev
);
dev_dbg
(
hdmi
->
dev
,
"%s(%p)
\n
"
,
__func__
,
pdata
->
lcd_dev
);
/* PS mode e->a */
/* PS mode e->a */
hdmi_write
(
hdmi
,
0x10
,
HDMI_SYSTEM_CTRL
);
hdmi_write
(
hdmi
,
0x10
,
HDMI_SYSTEM_CTRL
);
}
}
static
bool
sh_hdmi_must_reconfigure
(
struct
sh_hdmi
*
hdmi
)
{
struct
fb_info
*
info
=
hdmi
->
info
;
struct
sh_mobile_lcdc_chan
*
ch
=
info
->
par
;
struct
fb_var_screeninfo
*
new_var
=
&
hdmi
->
var
,
*
old_var
=
&
ch
->
display_var
;
struct
fb_videomode
mode1
,
mode2
;
fb_var_to_videomode
(
&
mode1
,
old_var
);
fb_var_to_videomode
(
&
mode2
,
new_var
);
dev_dbg
(
info
->
dev
,
"Old %ux%u, new %ux%u
\n
"
,
mode1
.
xres
,
mode1
.
yres
,
mode2
.
xres
,
mode2
.
yres
);
if
(
fb_mode_is_equal
(
&
mode1
,
&
mode2
))
return
false
;
dev_dbg
(
info
->
dev
,
"Switching %u -> %u lines
\n
"
,
mode1
.
yres
,
mode2
.
yres
);
*
old_var
=
*
new_var
;
return
true
;
}
/**
* sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock
* @hdmi: driver context
* @pixclock: pixel clock period in picoseconds
* return: configured positive rate if successful
* 0 if couldn't set the rate, but managed to enable the clock
* negative error, if couldn't enable the clock
*/
static
long
sh_hdmi_clk_configure
(
struct
sh_hdmi
*
hdmi
,
unsigned
long
pixclock
)
{
long
rate
;
int
ret
;
rate
=
PICOS2KHZ
(
pixclock
)
*
1000
;
rate
=
clk_round_rate
(
hdmi
->
hdmi_clk
,
rate
);
if
(
rate
>
0
)
{
ret
=
clk_set_rate
(
hdmi
->
hdmi_clk
,
rate
);
if
(
ret
<
0
)
{
dev_warn
(
hdmi
->
dev
,
"Cannot set rate %ld: %d
\n
"
,
rate
,
ret
);
rate
=
0
;
}
else
{
dev_dbg
(
hdmi
->
dev
,
"HDMI set frequency %lu
\n
"
,
rate
);
}
}
else
{
rate
=
0
;
dev_warn
(
hdmi
->
dev
,
"Cannot get suitable rate: %ld
\n
"
,
rate
);
}
ret
=
clk_enable
(
hdmi
->
hdmi_clk
);
if
(
ret
<
0
)
{
dev_err
(
hdmi
->
dev
,
"Cannot enable clock: %d
\n
"
,
ret
);
return
ret
;
}
return
rate
;
}
/* Hotplug interrupt occurred, read EDID */
/* Hotplug interrupt occurred, read EDID */
static
void
edid_work_fn
(
struct
work_struct
*
work
)
static
void
sh_hdmi_
edid_work_fn
(
struct
work_struct
*
work
)
{
{
struct
sh_hdmi
*
hdmi
=
container_of
(
work
,
struct
sh_hdmi
,
edid_work
.
work
);
struct
sh_hdmi
*
hdmi
=
container_of
(
work
,
struct
sh_hdmi
,
edid_work
.
work
);
struct
sh_mobile_hdmi_info
*
pdata
=
hdmi
->
dev
->
platform_data
;
struct
sh_mobile_hdmi_info
*
pdata
=
hdmi
->
dev
->
platform_data
;
struct
sh_mobile_lcdc_chan
*
ch
;
int
ret
;
pr_debug
(
"%s(%p): begin, hotplug status %d
\n
"
,
__func__
,
dev_dbg
(
hdmi
->
dev
,
"%s(%p): begin, hotplug status %d
\n
"
,
__func__
,
pdata
->
lcd_dev
,
hdmi
->
hp_state
);
pdata
->
lcd_dev
,
hdmi
->
hp_state
);
if
(
!
pdata
->
lcd_dev
)
if
(
!
pdata
->
lcd_dev
)
return
;
return
;
mutex_lock
(
&
hdmi
->
mutex
);
if
(
hdmi
->
hp_state
==
HDMI_HOTPLUG_EDID_DONE
)
{
if
(
hdmi
->
hp_state
==
HDMI_HOTPLUG_EDID_DONE
)
{
pm_runtime_get_sync
(
hdmi
->
dev
);
/* A device has been plugged in */
/* A device has been plugged in */
sh_hdmi_read_edid
(
hdmi
);
pm_runtime_get_sync
(
hdmi
->
dev
);
ret
=
sh_hdmi_read_edid
(
hdmi
);
if
(
ret
<
0
)
goto
out
;
/* Reconfigure the clock */
clk_disable
(
hdmi
->
hdmi_clk
);
ret
=
sh_hdmi_clk_configure
(
hdmi
,
hdmi
->
var
.
pixclock
);
if
(
ret
<
0
)
goto
out
;
msleep
(
10
);
msleep
(
10
);
sh_hdmi_configure
(
hdmi
);
sh_hdmi_configure
(
hdmi
);
/* Switched to another (d) power-save mode */
/* Switched to another (d) power-save mode */
msleep
(
10
);
msleep
(
10
);
if
(
!
hdmi
->
info
)
if
(
!
hdmi
->
info
)
return
;
goto
out
;
ch
=
hdmi
->
info
->
par
;
acquire_console_sem
();
acquire_console_sem
();
/* HDMI plug in */
/* HDMI plug in */
hdmi
->
info
->
var
=
hdmi
->
var
;
if
(
!
sh_hdmi_must_reconfigure
(
hdmi
)
&&
if
(
hdmi
->
info
->
state
!=
FBINFO_STATE_RUNNING
)
hdmi
->
info
->
state
==
FBINFO_STATE_RUNNING
)
{
/*
* First activation with the default monitor - just turn
* on, if we run a resume here, the logo disappears
*/
if
(
lock_fb_info
(
hdmi
->
info
))
{
sh_hdmi_display_on
(
hdmi
,
hdmi
->
info
);
unlock_fb_info
(
hdmi
->
info
);
}
}
else
{
/* New monitor or have to wake up */
fb_set_suspend
(
hdmi
->
info
,
0
);
fb_set_suspend
(
hdmi
->
info
,
0
);
else
}
hdmi_display_on
(
hdmi
,
hdmi
->
info
);
release_console_sem
();
release_console_sem
();
}
else
{
}
else
{
ret
=
0
;
if
(
!
hdmi
->
info
)
if
(
!
hdmi
->
info
)
return
;
goto
out
;
acquire_console_sem
();
acquire_console_sem
();
...
@@ -942,15 +1078,67 @@ static void edid_work_fn(struct work_struct *work)
...
@@ -942,15 +1078,67 @@ static void edid_work_fn(struct work_struct *work)
release_console_sem
();
release_console_sem
();
pm_runtime_put
(
hdmi
->
dev
);
pm_runtime_put
(
hdmi
->
dev
);
fb_destroy_modedb
(
hdmi
->
monspec
.
modedb
);
}
}
pr_debug
(
"%s(%p): end
\n
"
,
__func__
,
pdata
->
lcd_dev
);
out:
if
(
ret
<
0
)
hdmi
->
hp_state
=
HDMI_HOTPLUG_DISCONNECTED
;
mutex_unlock
(
&
hdmi
->
mutex
);
dev_dbg
(
hdmi
->
dev
,
"%s(%p): end
\n
"
,
__func__
,
pdata
->
lcd_dev
);
}
static
int
sh_hdmi_notify
(
struct
notifier_block
*
nb
,
unsigned
long
action
,
void
*
data
);
static
struct
notifier_block
sh_hdmi_notifier
=
{
.
notifier_call
=
sh_hdmi_notify
,
};
static
int
sh_hdmi_notify
(
struct
notifier_block
*
nb
,
unsigned
long
action
,
void
*
data
)
{
struct
fb_event
*
event
=
data
;
struct
fb_info
*
info
=
event
->
info
;
struct
sh_mobile_lcdc_chan
*
ch
=
info
->
par
;
struct
sh_mobile_lcdc_board_cfg
*
board_cfg
=
&
ch
->
cfg
.
board_cfg
;
struct
sh_hdmi
*
hdmi
=
board_cfg
->
board_data
;
if
(
nb
!=
&
sh_hdmi_notifier
||
!
hdmi
||
hdmi
->
info
!=
info
)
return
NOTIFY_DONE
;
switch
(
action
)
{
case
FB_EVENT_FB_REGISTERED
:
/* Unneeded, activation taken care by sh_hdmi_display_on() */
break
;
case
FB_EVENT_FB_UNREGISTERED
:
/*
* We are called from unregister_framebuffer() with the
* info->lock held. This is bad for us, because we can race with
* the scheduled work, which has to call fb_set_suspend(), which
* takes info->lock internally, so, sh_hdmi_edid_work_fn()
* cannot take and hold info->lock for the whole function
* duration. Using an additional lock creates a classical AB-BA
* lock up. Therefore, we have to release the info->lock
* temporarily, synchronise with the work queue and re-acquire
* the info->lock.
*/
unlock_fb_info
(
hdmi
->
info
);
mutex_lock
(
&
hdmi
->
mutex
);
hdmi
->
info
=
NULL
;
mutex_unlock
(
&
hdmi
->
mutex
);
lock_fb_info
(
hdmi
->
info
);
return
NOTIFY_OK
;
}
return
NOTIFY_DONE
;
}
}
static
int
__init
sh_hdmi_probe
(
struct
platform_device
*
pdev
)
static
int
__init
sh_hdmi_probe
(
struct
platform_device
*
pdev
)
{
{
struct
sh_mobile_hdmi_info
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
sh_mobile_hdmi_info
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
resource
*
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
struct
resource
*
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
struct
sh_mobile_lcdc_board_cfg
*
board_cfg
;
int
irq
=
platform_get_irq
(
pdev
,
0
),
ret
;
int
irq
=
platform_get_irq
(
pdev
,
0
),
ret
;
struct
sh_hdmi
*
hdmi
;
struct
sh_hdmi
*
hdmi
;
long
rate
;
long
rate
;
...
@@ -964,10 +1152,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
...
@@ -964,10 +1152,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
ret
=
snd_soc_register_codec
(
&
pdev
->
dev
,
mutex_init
(
&
hdmi
->
mutex
);
&
soc_codec_dev_sh_hdmi
,
&
sh_hdmi_dai
,
1
);
if
(
ret
<
0
)
goto
esndreg
;
hdmi
->
dev
=
&
pdev
->
dev
;
hdmi
->
dev
=
&
pdev
->
dev
;
...
@@ -978,30 +1163,14 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
...
@@ -978,30 +1163,14 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
goto
egetclk
;
goto
egetclk
;
}
}
rate
=
PICOS2KHZ
(
pdata
->
lcd_chan
->
lcd_cfg
.
pixclock
)
*
1000
;
/* Some arbitrary relaxed pixclock just to get things started */
rate
=
sh_hdmi_clk_configure
(
hdmi
,
37037
);
rate
=
clk_round_rate
(
hdmi
->
hdmi_clk
,
rate
);
if
(
rate
<
0
)
{
if
(
rate
<
0
)
{
ret
=
rate
;
ret
=
rate
;
dev_err
(
&
pdev
->
dev
,
"Cannot get suitable rate: %ld
\n
"
,
rate
);
goto
erate
;
goto
erate
;
}
}
ret
=
clk_set_rate
(
hdmi
->
hdmi_clk
,
rate
);
dev_dbg
(
&
pdev
->
dev
,
"Enabled HDMI clock at %luHz
\n
"
,
rate
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Cannot set rate %ld: %d
\n
"
,
rate
,
ret
);
goto
erate
;
}
pr_debug
(
"HDMI set frequency %lu
\n
"
,
rate
);
ret
=
clk_enable
(
hdmi
->
hdmi_clk
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Cannot enable clock: %d
\n
"
,
ret
);
goto
eclkenable
;
}
dev_info
(
&
pdev
->
dev
,
"Enabled HDMI clock at %luHz
\n
"
,
rate
);
if
(
!
request_mem_region
(
res
->
start
,
resource_size
(
res
),
dev_name
(
&
pdev
->
dev
)))
{
if
(
!
request_mem_region
(
res
->
start
,
resource_size
(
res
),
dev_name
(
&
pdev
->
dev
)))
{
dev_err
(
&
pdev
->
dev
,
"HDMI register region already claimed
\n
"
);
dev_err
(
&
pdev
->
dev
,
"HDMI register region already claimed
\n
"
);
...
@@ -1018,18 +1187,18 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
...
@@ -1018,18 +1187,18 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
platform_set_drvdata
(
pdev
,
hdmi
);
platform_set_drvdata
(
pdev
,
hdmi
);
#if 1
/* Product and revision IDs are 0 in sh-mobile version */
/* Product and revision IDs are 0 in sh-mobile version */
dev_info
(
&
pdev
->
dev
,
"Detected HDMI controller 0x%x:0x%x
\n
"
,
dev_info
(
&
pdev
->
dev
,
"Detected HDMI controller 0x%x:0x%x
\n
"
,
hdmi_read
(
hdmi
,
HDMI_PRODUCT_ID
),
hdmi_read
(
hdmi
,
HDMI_REVISION_ID
));
hdmi_read
(
hdmi
,
HDMI_PRODUCT_ID
),
hdmi_read
(
hdmi
,
HDMI_REVISION_ID
));
#endif
/* Set up LCDC callbacks */
/* Set up LCDC callbacks */
pdata
->
lcd_chan
->
board_cfg
.
board_data
=
hdmi
;
board_cfg
=
&
pdata
->
lcd_chan
->
board_cfg
;
pdata
->
lcd_chan
->
board_cfg
.
display_on
=
hdmi_display_on
;
board_cfg
->
owner
=
THIS_MODULE
;
pdata
->
lcd_chan
->
board_cfg
.
display_off
=
hdmi_display_off
;
board_cfg
->
board_data
=
hdmi
;
board_cfg
->
display_on
=
sh_hdmi_display_on
;
board_cfg
->
display_off
=
sh_hdmi_display_off
;
INIT_DELAYED_WORK
(
&
hdmi
->
edid_work
,
edid_work_fn
);
INIT_DELAYED_WORK
(
&
hdmi
->
edid_work
,
sh_hdmi_
edid_work_fn
);
pm_runtime_enable
(
&
pdev
->
dev
);
pm_runtime_enable
(
&
pdev
->
dev
);
pm_runtime_resume
(
&
pdev
->
dev
);
pm_runtime_resume
(
&
pdev
->
dev
);
...
@@ -1041,8 +1210,17 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
...
@@ -1041,8 +1210,17 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
goto
ereqirq
;
goto
ereqirq
;
}
}
ret
=
snd_soc_register_codec
(
&
pdev
->
dev
,
&
soc_codec_dev_sh_hdmi
,
&
sh_hdmi_dai
,
1
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"codec registration failed
\n
"
);
goto
ecodec
;
}
return
0
;
return
0
;
ecodec:
free_irq
(
irq
,
hdmi
);
ereqirq:
ereqirq:
pm_runtime_disable
(
&
pdev
->
dev
);
pm_runtime_disable
(
&
pdev
->
dev
);
iounmap
(
hdmi
->
base
);
iounmap
(
hdmi
->
base
);
...
@@ -1050,12 +1228,10 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
...
@@ -1050,12 +1228,10 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
release_mem_region
(
res
->
start
,
resource_size
(
res
));
release_mem_region
(
res
->
start
,
resource_size
(
res
));
ereqreg:
ereqreg:
clk_disable
(
hdmi
->
hdmi_clk
);
clk_disable
(
hdmi
->
hdmi_clk
);
eclkenable:
erate:
erate:
clk_put
(
hdmi
->
hdmi_clk
);
clk_put
(
hdmi
->
hdmi_clk
);
egetclk:
egetclk:
snd_soc_unregister_codec
(
&
pdev
->
dev
);
mutex_destroy
(
&
hdmi
->
mutex
);
esndreg:
kfree
(
hdmi
);
kfree
(
hdmi
);
return
ret
;
return
ret
;
...
@@ -1066,21 +1242,26 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
...
@@ -1066,21 +1242,26 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
struct
sh_mobile_hdmi_info
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
sh_mobile_hdmi_info
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
sh_hdmi
*
hdmi
=
platform_get_drvdata
(
pdev
);
struct
sh_hdmi
*
hdmi
=
platform_get_drvdata
(
pdev
);
struct
resource
*
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
struct
resource
*
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
struct
sh_mobile_lcdc_board_cfg
*
board_cfg
=
&
pdata
->
lcd_chan
->
board_cfg
;
int
irq
=
platform_get_irq
(
pdev
,
0
);
int
irq
=
platform_get_irq
(
pdev
,
0
);
snd_soc_unregister_codec
(
&
pdev
->
dev
);
snd_soc_unregister_codec
(
&
pdev
->
dev
);
pdata
->
lcd_chan
->
board_cfg
.
display_on
=
NULL
;
board_cfg
->
display_on
=
NULL
;
pdata
->
lcd_chan
->
board_cfg
.
display_off
=
NULL
;
board_cfg
->
display_off
=
NULL
;
pdata
->
lcd_chan
->
board_cfg
.
board_data
=
NULL
;
board_cfg
->
board_data
=
NULL
;
board_cfg
->
owner
=
NULL
;
/* No new work will be scheduled, wait for running ISR */
free_irq
(
irq
,
hdmi
);
free_irq
(
irq
,
hdmi
);
pm_runtime_disable
(
&
pdev
->
dev
);
/* Wait for already scheduled work */
cancel_delayed_work_sync
(
&
hdmi
->
edid_work
);
cancel_delayed_work_sync
(
&
hdmi
->
edid_work
);
pm_runtime_disable
(
&
pdev
->
dev
);
clk_disable
(
hdmi
->
hdmi_clk
);
clk_disable
(
hdmi
->
hdmi_clk
);
clk_put
(
hdmi
->
hdmi_clk
);
clk_put
(
hdmi
->
hdmi_clk
);
iounmap
(
hdmi
->
base
);
iounmap
(
hdmi
->
base
);
release_mem_region
(
res
->
start
,
resource_size
(
res
));
release_mem_region
(
res
->
start
,
resource_size
(
res
));
mutex_destroy
(
&
hdmi
->
mutex
);
kfree
(
hdmi
);
kfree
(
hdmi
);
return
0
;
return
0
;
...
...
drivers/video/sh_mobile_lcdcfb.c
View file @
b3773301
...
@@ -12,7 +12,6 @@
...
@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/clk.h>
#include <linux/clk.h>
#include <linux/pm_runtime.h>
#include <linux/pm_runtime.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
...
@@ -21,10 +20,12 @@
...
@@ -21,10 +20,12 @@
#include <linux/vmalloc.h>
#include <linux/vmalloc.h>
#include <linux/ioctl.h>
#include <linux/ioctl.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/console.h>
#include <video/sh_mobile_lcdc.h>
#include <video/sh_mobile_lcdc.h>
#include <asm/atomic.h>
#include <asm/atomic.h>
#define PALETTE_NR 16
#include "sh_mobile_lcdcfb.h"
#define SIDE_B_OFFSET 0x1000
#define SIDE_B_OFFSET 0x1000
#define MIRROR_OFFSET 0x2000
#define MIRROR_OFFSET 0x2000
...
@@ -53,11 +54,8 @@ static int lcdc_shared_regs[] = {
...
@@ -53,11 +54,8 @@ static int lcdc_shared_regs[] = {
};
};
#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
/* per-channel registers */
#define DEFAULT_XRES 1280
enum
{
LDDCKPAT1R
,
LDDCKPAT2R
,
LDMT1R
,
LDMT2R
,
LDMT3R
,
LDDFR
,
LDSM1R
,
#define DEFAULT_YRES 1024
LDSM2R
,
LDSA1R
,
LDMLSR
,
LDHCNR
,
LDHSYNR
,
LDVLNR
,
LDVSYNR
,
LDPMR
,
LDHAJR
,
NR_CH_REGS
};
static
unsigned
long
lcdc_offs_mainlcd
[
NR_CH_REGS
]
=
{
static
unsigned
long
lcdc_offs_mainlcd
[
NR_CH_REGS
]
=
{
[
LDDCKPAT1R
]
=
0x400
,
[
LDDCKPAT1R
]
=
0x400
,
...
@@ -112,23 +110,21 @@ static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
...
@@ -112,23 +110,21 @@ static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
#define LDRCNTR_MRC 0x00000001
#define LDRCNTR_MRC 0x00000001
#define LDSR_MRS 0x00000100
#define LDSR_MRS 0x00000100
struct
sh_mobile_lcdc_priv
;
static
const
struct
fb_videomode
default_720p
=
{
struct
sh_mobile_lcdc_chan
{
.
name
=
"HDMI 720p"
,
struct
sh_mobile_lcdc_priv
*
lcdc
;
.
xres
=
1280
,
unsigned
long
*
reg_offs
;
.
yres
=
720
,
unsigned
long
ldmt1r_value
;
unsigned
long
enabled
;
/* ME and SE in LDCNT2R */
.
left_margin
=
200
,
struct
sh_mobile_lcdc_chan_cfg
cfg
;
.
right_margin
=
88
,
u32
pseudo_palette
[
PALETTE_NR
];
.
hsync_len
=
48
,
unsigned
long
saved_ch_regs
[
NR_CH_REGS
];
struct
fb_info
*
info
;
.
upper_margin
=
20
,
dma_addr_t
dma_handle
;
.
lower_margin
=
5
,
struct
fb_deferred_io
defio
;
.
vsync_len
=
5
,
struct
scatterlist
*
sglist
;
unsigned
long
frame_end
;
.
pixclock
=
13468
,
unsigned
long
pan_offset
;
.
sync
=
FB_SYNC_VERT_HIGH_ACT
|
FB_SYNC_HOR_HIGH_ACT
,
wait_queue_head_t
frame_end_wait
;
struct
completion
vsync_completion
;
};
};
struct
sh_mobile_lcdc_priv
{
struct
sh_mobile_lcdc_priv
{
...
@@ -409,8 +405,8 @@ static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
...
@@ -409,8 +405,8 @@ static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
static
void
sh_mobile_lcdc_geometry
(
struct
sh_mobile_lcdc_chan
*
ch
)
static
void
sh_mobile_lcdc_geometry
(
struct
sh_mobile_lcdc_chan
*
ch
)
{
{
struct
fb_var_screeninfo
*
var
=
&
ch
->
info
->
var
;
struct
fb_var_screeninfo
*
var
=
&
ch
->
info
->
var
,
*
display_var
=
&
ch
->
display_var
;
unsigned
long
h_total
,
hsync_pos
;
unsigned
long
h_total
,
hsync_pos
,
display_h_total
;
u32
tmp
;
u32
tmp
;
tmp
=
ch
->
ldmt1r_value
;
tmp
=
ch
->
ldmt1r_value
;
...
@@ -428,31 +424,33 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
...
@@ -428,31 +424,33 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
lcdc_write_chan
(
ch
,
LDMT3R
,
ch
->
cfg
.
sys_bus_cfg
.
ldmt3r
);
lcdc_write_chan
(
ch
,
LDMT3R
,
ch
->
cfg
.
sys_bus_cfg
.
ldmt3r
);
/* horizontal configuration */
/* horizontal configuration */
h_total
=
var
->
xres
+
var
->
hsync_len
+
h_total
=
display_var
->
xres
+
display_
var
->
hsync_len
+
var
->
left_margin
+
var
->
right_margin
;
display_var
->
left_margin
+
display_
var
->
right_margin
;
tmp
=
h_total
/
8
;
/* HTCN */
tmp
=
h_total
/
8
;
/* HTCN */
tmp
|=
(
var
->
xres
/
8
)
<<
16
;
/* HDCN */
tmp
|=
(
min
(
display_var
->
xres
,
var
->
xres
)
/
8
)
<<
16
;
/* HDCN */
lcdc_write_chan
(
ch
,
LDHCNR
,
tmp
);
lcdc_write_chan
(
ch
,
LDHCNR
,
tmp
);
hsync_pos
=
var
->
xres
+
var
->
right_margin
;
hsync_pos
=
display_var
->
xres
+
display_
var
->
right_margin
;
tmp
=
hsync_pos
/
8
;
/* HSYNP */
tmp
=
hsync_pos
/
8
;
/* HSYNP */
tmp
|=
(
var
->
hsync_len
/
8
)
<<
16
;
/* HSYNW */
tmp
|=
(
display_
var
->
hsync_len
/
8
)
<<
16
;
/* HSYNW */
lcdc_write_chan
(
ch
,
LDHSYNR
,
tmp
);
lcdc_write_chan
(
ch
,
LDHSYNR
,
tmp
);
/* vertical configuration */
/* vertical configuration */
tmp
=
var
->
yres
+
var
->
vsync_len
+
tmp
=
display_var
->
yres
+
display_
var
->
vsync_len
+
var
->
upper_margin
+
var
->
lower_margin
;
/* VTLN */
display_var
->
upper_margin
+
display_
var
->
lower_margin
;
/* VTLN */
tmp
|=
var
->
yres
<<
16
;
/* VDLN */
tmp
|=
min
(
display_var
->
yres
,
var
->
yres
)
<<
16
;
/* VDLN */
lcdc_write_chan
(
ch
,
LDVLNR
,
tmp
);
lcdc_write_chan
(
ch
,
LDVLNR
,
tmp
);
tmp
=
var
->
yres
+
var
->
lower_margin
;
/* VSYNP */
tmp
=
display_var
->
yres
+
display_
var
->
lower_margin
;
/* VSYNP */
tmp
|=
var
->
vsync_len
<<
16
;
/* VSYNW */
tmp
|=
display_
var
->
vsync_len
<<
16
;
/* VSYNW */
lcdc_write_chan
(
ch
,
LDVSYNR
,
tmp
);
lcdc_write_chan
(
ch
,
LDVSYNR
,
tmp
);
/* Adjust horizontal synchronisation for HDMI */
/* Adjust horizontal synchronisation for HDMI */
tmp
=
((
var
->
xres
&
7
)
<<
24
)
|
display_h_total
=
display_var
->
xres
+
display_var
->
hsync_len
+
((
h_total
&
7
)
<<
16
)
|
display_var
->
left_margin
+
display_var
->
right_margin
;
((
var
->
hsync_len
&
7
)
<<
8
)
|
tmp
=
((
display_var
->
xres
&
7
)
<<
24
)
|
((
display_h_total
&
7
)
<<
16
)
|
((
display_var
->
hsync_len
&
7
)
<<
8
)
|
hsync_pos
;
hsync_pos
;
lcdc_write_chan
(
ch
,
LDHAJR
,
tmp
);
lcdc_write_chan
(
ch
,
LDHAJR
,
tmp
);
}
}
...
@@ -460,7 +458,6 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
...
@@ -460,7 +458,6 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
static
int
sh_mobile_lcdc_start
(
struct
sh_mobile_lcdc_priv
*
priv
)
static
int
sh_mobile_lcdc_start
(
struct
sh_mobile_lcdc_priv
*
priv
)
{
{
struct
sh_mobile_lcdc_chan
*
ch
;
struct
sh_mobile_lcdc_chan
*
ch
;
struct
fb_videomode
*
lcd_cfg
;
struct
sh_mobile_lcdc_board_cfg
*
board_cfg
;
struct
sh_mobile_lcdc_board_cfg
*
board_cfg
;
unsigned
long
tmp
;
unsigned
long
tmp
;
int
k
,
m
;
int
k
,
m
;
...
@@ -503,7 +500,8 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
...
@@ -503,7 +500,8 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
m
=
1
<<
6
;
m
=
1
<<
6
;
tmp
|=
m
<<
(
lcdc_chan_is_sublcd
(
ch
)
?
8
:
0
);
tmp
|=
m
<<
(
lcdc_chan_is_sublcd
(
ch
)
?
8
:
0
);
lcdc_write_chan
(
ch
,
LDDCKPAT1R
,
0x00000000
);
/* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider denominator */
lcdc_write_chan
(
ch
,
LDDCKPAT1R
,
0
);
lcdc_write_chan
(
ch
,
LDDCKPAT2R
,
(
1
<<
(
m
/
2
))
-
1
);
lcdc_write_chan
(
ch
,
LDDCKPAT2R
,
(
1
<<
(
m
/
2
))
-
1
);
}
}
...
@@ -518,7 +516,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
...
@@ -518,7 +516,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
for
(
k
=
0
;
k
<
ARRAY_SIZE
(
priv
->
ch
);
k
++
)
{
for
(
k
=
0
;
k
<
ARRAY_SIZE
(
priv
->
ch
);
k
++
)
{
ch
=
&
priv
->
ch
[
k
];
ch
=
&
priv
->
ch
[
k
];
lcd_cfg
=
&
ch
->
cfg
.
lcd_cfg
;
if
(
!
ch
->
enabled
)
if
(
!
ch
->
enabled
)
continue
;
continue
;
...
@@ -547,7 +544,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
...
@@ -547,7 +544,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
/* set bpp format in PKF[4:0] */
/* set bpp format in PKF[4:0] */
tmp
=
lcdc_read_chan
(
ch
,
LDDFR
);
tmp
=
lcdc_read_chan
(
ch
,
LDDFR
);
tmp
&=
~
(
0x0001001f
)
;
tmp
&=
~
0x0001001f
;
tmp
|=
(
ch
->
info
->
var
.
bits_per_pixel
==
16
)
?
3
:
0
;
tmp
|=
(
ch
->
info
->
var
.
bits_per_pixel
==
16
)
?
3
:
0
;
lcdc_write_chan
(
ch
,
LDDFR
,
tmp
);
lcdc_write_chan
(
ch
,
LDDFR
,
tmp
);
...
@@ -591,8 +588,10 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
...
@@ -591,8 +588,10 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
continue
;
continue
;
board_cfg
=
&
ch
->
cfg
.
board_cfg
;
board_cfg
=
&
ch
->
cfg
.
board_cfg
;
if
(
board_cfg
->
display_on
)
if
(
try_module_get
(
board_cfg
->
owner
)
&&
board_cfg
->
display_on
)
{
board_cfg
->
display_on
(
board_cfg
->
board_data
,
ch
->
info
);
board_cfg
->
display_on
(
board_cfg
->
board_data
,
ch
->
info
);
module_put
(
board_cfg
->
owner
);
}
}
}
return
0
;
return
0
;
...
@@ -614,7 +613,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
...
@@ -614,7 +613,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
* flush frame, and wait for frame end interrupt
* flush frame, and wait for frame end interrupt
* clean up deferred io and enable clock
* clean up deferred io and enable clock
*/
*/
if
(
ch
->
info
->
fbdefio
)
{
if
(
ch
->
info
&&
ch
->
info
->
fbdefio
)
{
ch
->
frame_end
=
0
;
ch
->
frame_end
=
0
;
schedule_delayed_work
(
&
ch
->
info
->
deferred_work
,
0
);
schedule_delayed_work
(
&
ch
->
info
->
deferred_work
,
0
);
wait_event
(
ch
->
frame_end_wait
,
ch
->
frame_end
);
wait_event
(
ch
->
frame_end_wait
,
ch
->
frame_end
);
...
@@ -624,8 +623,10 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
...
@@ -624,8 +623,10 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
}
}
board_cfg
=
&
ch
->
cfg
.
board_cfg
;
board_cfg
=
&
ch
->
cfg
.
board_cfg
;
if
(
board_cfg
->
display_off
)
if
(
try_module_get
(
board_cfg
->
owner
)
&&
board_cfg
->
display_off
)
{
board_cfg
->
display_off
(
board_cfg
->
board_data
);
board_cfg
->
display_off
(
board_cfg
->
board_data
);
module_put
(
board_cfg
->
owner
);
}
}
}
/* stop the lcdc */
/* stop the lcdc */
...
@@ -704,7 +705,6 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
...
@@ -704,7 +705,6 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
return
PTR_ERR
(
priv
->
dot_clk
);
return
PTR_ERR
(
priv
->
dot_clk
);
}
}
}
}
atomic_set
(
&
priv
->
hw_usecnt
,
-
1
);
/* Runtime PM support involves two step for this driver:
/* Runtime PM support involves two step for this driver:
* 1) Enable Runtime PM
* 1) Enable Runtime PM
...
@@ -837,6 +837,102 @@ static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
...
@@ -837,6 +837,102 @@ static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
return
retval
;
return
retval
;
}
}
static
void
sh_mobile_fb_reconfig
(
struct
fb_info
*
info
)
{
struct
sh_mobile_lcdc_chan
*
ch
=
info
->
par
;
struct
fb_videomode
mode1
,
mode2
;
struct
fb_event
event
;
int
evnt
=
FB_EVENT_MODE_CHANGE_ALL
;
if
(
ch
->
use_count
>
1
||
(
ch
->
use_count
==
1
&&
!
info
->
fbcon_par
))
/* More framebuffer users are active */
return
;
fb_var_to_videomode
(
&
mode1
,
&
ch
->
display_var
);
fb_var_to_videomode
(
&
mode2
,
&
info
->
var
);
if
(
fb_mode_is_equal
(
&
mode1
,
&
mode2
))
return
;
/* Display has been re-plugged, framebuffer is free now, reconfigure */
if
(
fb_set_var
(
info
,
&
ch
->
display_var
)
<
0
)
/* Couldn't reconfigure, hopefully, can continue as before */
return
;
info
->
fix
.
line_length
=
mode2
.
xres
*
(
ch
->
cfg
.
bpp
/
8
);
/*
* fb_set_var() calls the notifier change internally, only if
* FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a
* user event, we have to call the chain ourselves.
*/
event
.
info
=
info
;
event
.
data
=
&
mode2
;
fb_notifier_call_chain
(
evnt
,
&
event
);
}
/*
* Locking: both .fb_release() and .fb_open() are called with info->lock held if
* user == 1, or with console sem held, if user == 0.
*/
static
int
sh_mobile_release
(
struct
fb_info
*
info
,
int
user
)
{
struct
sh_mobile_lcdc_chan
*
ch
=
info
->
par
;
mutex_lock
(
&
ch
->
open_lock
);
dev_dbg
(
info
->
dev
,
"%s(): %d users
\n
"
,
__func__
,
ch
->
use_count
);
ch
->
use_count
--
;
/* Nothing to reconfigure, when called from fbcon */
if
(
user
)
{
acquire_console_sem
();
sh_mobile_fb_reconfig
(
info
);
release_console_sem
();
}
mutex_unlock
(
&
ch
->
open_lock
);
return
0
;
}
static
int
sh_mobile_open
(
struct
fb_info
*
info
,
int
user
)
{
struct
sh_mobile_lcdc_chan
*
ch
=
info
->
par
;
mutex_lock
(
&
ch
->
open_lock
);
ch
->
use_count
++
;
dev_dbg
(
info
->
dev
,
"%s(): %d users
\n
"
,
__func__
,
ch
->
use_count
);
mutex_unlock
(
&
ch
->
open_lock
);
return
0
;
}
static
int
sh_mobile_check_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
{
struct
sh_mobile_lcdc_chan
*
ch
=
info
->
par
;
if
(
var
->
xres
<
160
||
var
->
xres
>
1920
||
var
->
yres
<
120
||
var
->
yres
>
1080
||
var
->
left_margin
<
32
||
var
->
left_margin
>
320
||
var
->
right_margin
<
12
||
var
->
right_margin
>
240
||
var
->
upper_margin
<
12
||
var
->
upper_margin
>
120
||
var
->
lower_margin
<
1
||
var
->
lower_margin
>
64
||
var
->
hsync_len
<
32
||
var
->
hsync_len
>
240
||
var
->
vsync_len
<
2
||
var
->
vsync_len
>
64
||
var
->
pixclock
<
6000
||
var
->
pixclock
>
40000
||
var
->
xres
*
var
->
yres
*
(
ch
->
cfg
.
bpp
/
8
)
*
2
>
info
->
fix
.
smem_len
)
{
dev_warn
(
info
->
dev
,
"Invalid info: %u %u %u %u %u %u %u %u %u!
\n
"
,
var
->
xres
,
var
->
yres
,
var
->
left_margin
,
var
->
right_margin
,
var
->
upper_margin
,
var
->
lower_margin
,
var
->
hsync_len
,
var
->
vsync_len
,
var
->
pixclock
);
return
-
EINVAL
;
}
return
0
;
}
static
struct
fb_ops
sh_mobile_lcdc_ops
=
{
static
struct
fb_ops
sh_mobile_lcdc_ops
=
{
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
...
@@ -848,6 +944,9 @@ static struct fb_ops sh_mobile_lcdc_ops = {
...
@@ -848,6 +944,9 @@ static struct fb_ops sh_mobile_lcdc_ops = {
.
fb_imageblit
=
sh_mobile_lcdc_imageblit
,
.
fb_imageblit
=
sh_mobile_lcdc_imageblit
,
.
fb_pan_display
=
sh_mobile_fb_pan_display
,
.
fb_pan_display
=
sh_mobile_fb_pan_display
,
.
fb_ioctl
=
sh_mobile_ioctl
,
.
fb_ioctl
=
sh_mobile_ioctl
,
.
fb_open
=
sh_mobile_open
,
.
fb_release
=
sh_mobile_release
,
.
fb_check_var
=
sh_mobile_check_var
,
};
};
static
int
sh_mobile_lcdc_set_bpp
(
struct
fb_var_screeninfo
*
var
,
int
bpp
)
static
int
sh_mobile_lcdc_set_bpp
(
struct
fb_var_screeninfo
*
var
,
int
bpp
)
...
@@ -958,6 +1057,7 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
...
@@ -958,6 +1057,7 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
.
runtime_resume
=
sh_mobile_lcdc_runtime_resume
,
.
runtime_resume
=
sh_mobile_lcdc_runtime_resume
,
};
};
/* locking: called with info->lock held */
static
int
sh_mobile_lcdc_notify
(
struct
notifier_block
*
nb
,
static
int
sh_mobile_lcdc_notify
(
struct
notifier_block
*
nb
,
unsigned
long
action
,
void
*
data
)
unsigned
long
action
,
void
*
data
)
{
{
...
@@ -965,53 +1065,40 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
...
@@ -965,53 +1065,40 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
struct
fb_info
*
info
=
event
->
info
;
struct
fb_info
*
info
=
event
->
info
;
struct
sh_mobile_lcdc_chan
*
ch
=
info
->
par
;
struct
sh_mobile_lcdc_chan
*
ch
=
info
->
par
;
struct
sh_mobile_lcdc_board_cfg
*
board_cfg
=
&
ch
->
cfg
.
board_cfg
;
struct
sh_mobile_lcdc_board_cfg
*
board_cfg
=
&
ch
->
cfg
.
board_cfg
;
struct
fb_var_screeninfo
*
var
;
int
ret
;
if
(
&
ch
->
lcdc
->
notifier
!=
nb
)
if
(
&
ch
->
lcdc
->
notifier
!=
nb
)
return
0
;
return
NOTIFY_DONE
;
dev_dbg
(
info
->
dev
,
"%s(): action = %lu, data = %p
\n
"
,
dev_dbg
(
info
->
dev
,
"%s(): action = %lu, data = %p
\n
"
,
__func__
,
action
,
event
->
data
);
__func__
,
action
,
event
->
data
);
switch
(
action
)
{
switch
(
action
)
{
case
FB_EVENT_SUSPEND
:
case
FB_EVENT_SUSPEND
:
if
(
board_cfg
->
display_off
)
if
(
try_module_get
(
board_cfg
->
owner
)
&&
board_cfg
->
display_off
)
{
board_cfg
->
display_off
(
board_cfg
->
board_data
);
board_cfg
->
display_off
(
board_cfg
->
board_data
);
module_put
(
board_cfg
->
owner
);
}
pm_runtime_put
(
info
->
device
);
pm_runtime_put
(
info
->
device
);
sh_mobile_lcdc_stop
(
ch
->
lcdc
);
break
;
break
;
case
FB_EVENT_RESUME
:
case
FB_EVENT_RESUME
:
var
=
&
info
->
var
;
mutex_lock
(
&
ch
->
open_lock
);
sh_mobile_fb_reconfig
(
info
);
mutex_unlock
(
&
ch
->
open_lock
);
/* HDMI must be enabled before LCDC configuration */
/* HDMI must be enabled before LCDC configuration */
if
(
board_cfg
->
display_on
)
if
(
try_module_get
(
board_cfg
->
owner
)
&&
board_cfg
->
display_on
)
{
board_cfg
->
display_on
(
board_cfg
->
board_data
,
ch
->
info
);
board_cfg
->
display_on
(
board_cfg
->
board_data
,
info
);
module_put
(
board_cfg
->
owner
);
/* Check if the new display is not in our modelist */
if
(
ch
->
info
->
modelist
.
next
&&
!
fb_match_mode
(
var
,
&
ch
->
info
->
modelist
))
{
struct
fb_videomode
mode
;
int
ret
;
/* Can we handle this display? */
if
(
var
->
xres
>
ch
->
cfg
.
lcd_cfg
.
xres
||
var
->
yres
>
ch
->
cfg
.
lcd_cfg
.
yres
)
return
-
ENOMEM
;
/* Add to the modelist */
fb_var_to_videomode
(
&
mode
,
var
);
ret
=
fb_add_videomode
(
&
mode
,
&
ch
->
info
->
modelist
);
if
(
ret
<
0
)
return
ret
;
}
}
pm_runtime_get_sync
(
info
->
device
);
ret
=
sh_mobile_lcdc_start
(
ch
->
lcdc
);
if
(
!
ret
)
sh_mobile_lcdc_geometry
(
ch
);
pm_runtime_get_sync
(
info
->
device
);
break
;
}
}
return
0
;
return
NOTIFY_OK
;
}
}
static
int
sh_mobile_lcdc_remove
(
struct
platform_device
*
pdev
);
static
int
sh_mobile_lcdc_remove
(
struct
platform_device
*
pdev
);
...
@@ -1020,14 +1107,13 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
...
@@ -1020,14 +1107,13 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
{
{
struct
fb_info
*
info
;
struct
fb_info
*
info
;
struct
sh_mobile_lcdc_priv
*
priv
;
struct
sh_mobile_lcdc_priv
*
priv
;
struct
sh_mobile_lcdc_info
*
pdata
;
struct
sh_mobile_lcdc_info
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
sh_mobile_lcdc_chan_cfg
*
cfg
;
struct
resource
*
res
;
struct
resource
*
res
;
int
error
;
int
error
;
void
*
buf
;
void
*
buf
;
int
i
,
j
;
int
i
,
j
;
if
(
!
pd
ev
->
dev
.
platform_d
ata
)
{
if
(
!
pdata
)
{
dev_err
(
&
pdev
->
dev
,
"no platform data defined
\n
"
);
dev_err
(
&
pdev
->
dev
,
"no platform data defined
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
@@ -1055,31 +1141,33 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
...
@@ -1055,31 +1141,33 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
}
}
priv
->
irq
=
i
;
priv
->
irq
=
i
;
pdata
=
pdev
->
dev
.
platform_data
;
atomic_set
(
&
priv
->
hw_usecnt
,
-
1
)
;
j
=
0
;
j
=
0
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
pdata
->
ch
);
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
pdata
->
ch
);
i
++
)
{
priv
->
ch
[
j
].
lcdc
=
priv
;
struct
sh_mobile_lcdc_chan
*
ch
=
priv
->
ch
+
j
;
memcpy
(
&
priv
->
ch
[
j
].
cfg
,
&
pdata
->
ch
[
i
],
sizeof
(
pdata
->
ch
[
i
]));
ch
->
lcdc
=
priv
;
memcpy
(
&
ch
->
cfg
,
&
pdata
->
ch
[
i
],
sizeof
(
pdata
->
ch
[
i
]));
error
=
sh_mobile_lcdc_check_interface
(
&
priv
->
ch
[
j
]
);
error
=
sh_mobile_lcdc_check_interface
(
ch
);
if
(
error
)
{
if
(
error
)
{
dev_err
(
&
pdev
->
dev
,
"unsupported interface type
\n
"
);
dev_err
(
&
pdev
->
dev
,
"unsupported interface type
\n
"
);
goto
err1
;
goto
err1
;
}
}
init_waitqueue_head
(
&
priv
->
ch
[
j
].
frame_end_wait
);
init_waitqueue_head
(
&
ch
->
frame_end_wait
);
init_completion
(
&
priv
->
ch
[
j
].
vsync_completion
);
init_completion
(
&
ch
->
vsync_completion
);
priv
->
ch
[
j
].
pan_offset
=
0
;
ch
->
pan_offset
=
0
;
switch
(
pdata
->
ch
[
i
].
chan
)
{
switch
(
pdata
->
ch
[
i
].
chan
)
{
case
LCDC_CHAN_MAINLCD
:
case
LCDC_CHAN_MAINLCD
:
priv
->
ch
[
j
].
enabled
=
1
<<
1
;
ch
->
enabled
=
1
<<
1
;
priv
->
ch
[
j
].
reg_offs
=
lcdc_offs_mainlcd
;
ch
->
reg_offs
=
lcdc_offs_mainlcd
;
j
++
;
j
++
;
break
;
break
;
case
LCDC_CHAN_SUBLCD
:
case
LCDC_CHAN_SUBLCD
:
priv
->
ch
[
j
].
enabled
=
1
<<
2
;
ch
->
enabled
=
1
<<
2
;
priv
->
ch
[
j
].
reg_offs
=
lcdc_offs_sublcd
;
ch
->
reg_offs
=
lcdc_offs_sublcd
;
j
++
;
j
++
;
break
;
break
;
}
}
...
@@ -1103,69 +1191,83 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
...
@@ -1103,69 +1191,83 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
for
(
i
=
0
;
i
<
j
;
i
++
)
{
for
(
i
=
0
;
i
<
j
;
i
++
)
{
struct
fb_var_screeninfo
*
var
;
struct
fb_var_screeninfo
*
var
;
struct
fb_videomode
*
lcd_cfg
;
const
struct
fb_videomode
*
lcd_cfg
,
*
max_cfg
=
NULL
;
cfg
=
&
priv
->
ch
[
i
].
cfg
;
struct
sh_mobile_lcdc_chan
*
ch
=
priv
->
ch
+
i
;
struct
sh_mobile_lcdc_chan_cfg
*
cfg
=
&
ch
->
cfg
;
const
struct
fb_videomode
*
mode
=
cfg
->
lcd_cfg
;
unsigned
long
max_size
=
0
;
int
k
;
priv
->
ch
[
i
].
info
=
framebuffer_alloc
(
0
,
&
pdev
->
dev
);
ch
->
info
=
framebuffer_alloc
(
0
,
&
pdev
->
dev
);
if
(
!
priv
->
ch
[
i
].
info
)
{
if
(
!
ch
->
info
)
{
dev_err
(
&
pdev
->
dev
,
"unable to allocate fb_info
\n
"
);
dev_err
(
&
pdev
->
dev
,
"unable to allocate fb_info
\n
"
);
error
=
-
ENOMEM
;
error
=
-
ENOMEM
;
break
;
break
;
}
}
info
=
priv
->
ch
[
i
].
info
;
info
=
ch
->
info
;
var
=
&
info
->
var
;
var
=
&
info
->
var
;
lcd_cfg
=
&
cfg
->
lcd_cfg
;
info
->
fbops
=
&
sh_mobile_lcdc_ops
;
info
->
fbops
=
&
sh_mobile_lcdc_ops
;
var
->
xres
=
var
->
xres_virtual
=
lcd_cfg
->
xres
;
info
->
par
=
ch
;
var
->
yres
=
lcd_cfg
->
yres
;
mutex_init
(
&
ch
->
open_lock
);
for
(
k
=
0
,
lcd_cfg
=
mode
;
k
<
cfg
->
num_cfg
&&
lcd_cfg
;
k
++
,
lcd_cfg
++
)
{
unsigned
long
size
=
lcd_cfg
->
yres
*
lcd_cfg
->
xres
;
if
(
size
>
max_size
)
{
max_cfg
=
lcd_cfg
;
max_size
=
size
;
}
}
if
(
!
mode
)
max_size
=
DEFAULT_XRES
*
DEFAULT_YRES
;
else
if
(
max_cfg
)
dev_dbg
(
&
pdev
->
dev
,
"Found largest videomode %ux%u
\n
"
,
max_cfg
->
xres
,
max_cfg
->
yres
);
info
->
fix
=
sh_mobile_lcdc_fix
;
info
->
fix
.
smem_len
=
max_size
*
(
cfg
->
bpp
/
8
)
*
2
;
if
(
!
mode
)
mode
=
&
default_720p
;
fb_videomode_to_var
(
var
,
mode
);
/* Default Y virtual resolution is 2x panel size */
/* Default Y virtual resolution is 2x panel size */
var
->
yres_virtual
=
var
->
yres
*
2
;
var
->
yres_virtual
=
var
->
yres
*
2
;
var
->
width
=
cfg
->
lcd_size_cfg
.
width
;
var
->
height
=
cfg
->
lcd_size_cfg
.
height
;
var
->
activate
=
FB_ACTIVATE_NOW
;
var
->
activate
=
FB_ACTIVATE_NOW
;
var
->
left_margin
=
lcd_cfg
->
left_margin
;
var
->
right_margin
=
lcd_cfg
->
right_margin
;
var
->
upper_margin
=
lcd_cfg
->
upper_margin
;
var
->
lower_margin
=
lcd_cfg
->
lower_margin
;
var
->
hsync_len
=
lcd_cfg
->
hsync_len
;
var
->
vsync_len
=
lcd_cfg
->
vsync_len
;
var
->
sync
=
lcd_cfg
->
sync
;
var
->
pixclock
=
lcd_cfg
->
pixclock
;
error
=
sh_mobile_lcdc_set_bpp
(
var
,
cfg
->
bpp
);
error
=
sh_mobile_lcdc_set_bpp
(
var
,
cfg
->
bpp
);
if
(
error
)
if
(
error
)
break
;
break
;
info
->
fix
=
sh_mobile_lcdc_fix
;
info
->
fix
.
line_length
=
lcd_cfg
->
xres
*
(
cfg
->
bpp
/
8
);
info
->
fix
.
smem_len
=
info
->
fix
.
line_length
*
var
->
yres_virtual
;
buf
=
dma_alloc_coherent
(
&
pdev
->
dev
,
info
->
fix
.
smem_len
,
buf
=
dma_alloc_coherent
(
&
pdev
->
dev
,
info
->
fix
.
smem_len
,
&
priv
->
ch
[
i
].
dma_handle
,
GFP_KERNEL
);
&
ch
->
dma_handle
,
GFP_KERNEL
);
if
(
!
buf
)
{
if
(
!
buf
)
{
dev_err
(
&
pdev
->
dev
,
"unable to allocate buffer
\n
"
);
dev_err
(
&
pdev
->
dev
,
"unable to allocate buffer
\n
"
);
error
=
-
ENOMEM
;
error
=
-
ENOMEM
;
break
;
break
;
}
}
info
->
pseudo_palette
=
&
priv
->
ch
[
i
].
pseudo_palette
;
info
->
pseudo_palette
=
&
ch
->
pseudo_palette
;
info
->
flags
=
FBINFO_FLAG_DEFAULT
;
info
->
flags
=
FBINFO_FLAG_DEFAULT
;
error
=
fb_alloc_cmap
(
&
info
->
cmap
,
PALETTE_NR
,
0
);
error
=
fb_alloc_cmap
(
&
info
->
cmap
,
PALETTE_NR
,
0
);
if
(
error
<
0
)
{
if
(
error
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"unable to allocate cmap
\n
"
);
dev_err
(
&
pdev
->
dev
,
"unable to allocate cmap
\n
"
);
dma_free_coherent
(
&
pdev
->
dev
,
info
->
fix
.
smem_len
,
dma_free_coherent
(
&
pdev
->
dev
,
info
->
fix
.
smem_len
,
buf
,
priv
->
ch
[
i
].
dma_handle
);
buf
,
ch
->
dma_handle
);
break
;
break
;
}
}
memset
(
buf
,
0
,
info
->
fix
.
smem_len
)
;
info
->
fix
.
smem_start
=
ch
->
dma_handle
;
info
->
fix
.
smem_start
=
priv
->
ch
[
i
].
dma_handle
;
info
->
fix
.
line_length
=
var
->
xres
*
(
cfg
->
bpp
/
8
)
;
info
->
screen_base
=
buf
;
info
->
screen_base
=
buf
;
info
->
device
=
&
pdev
->
dev
;
info
->
device
=
&
pdev
->
dev
;
info
->
par
=
&
priv
->
ch
[
i
]
;
ch
->
display_var
=
*
var
;
}
}
if
(
error
)
if
(
error
)
...
@@ -1179,6 +1281,10 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
...
@@ -1179,6 +1281,10 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
for
(
i
=
0
;
i
<
j
;
i
++
)
{
for
(
i
=
0
;
i
<
j
;
i
++
)
{
struct
sh_mobile_lcdc_chan
*
ch
=
priv
->
ch
+
i
;
struct
sh_mobile_lcdc_chan
*
ch
=
priv
->
ch
+
i
;
const
struct
fb_videomode
*
mode
=
ch
->
cfg
.
lcd_cfg
;
if
(
!
mode
)
mode
=
&
default_720p
;
info
=
ch
->
info
;
info
=
ch
->
info
;
...
@@ -1191,6 +1297,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
...
@@ -1191,6 +1297,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
}
}
}
}
fb_videomode_to_modelist
(
mode
,
ch
->
cfg
.
num_cfg
,
&
info
->
modelist
);
error
=
register_framebuffer
(
info
);
error
=
register_framebuffer
(
info
);
if
(
error
<
0
)
if
(
error
<
0
)
goto
err1
;
goto
err1
;
...
@@ -1200,8 +1307,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
...
@@ -1200,8 +1307,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
pdev
->
name
,
pdev
->
name
,
(
ch
->
cfg
.
chan
==
LCDC_CHAN_MAINLCD
)
?
(
ch
->
cfg
.
chan
==
LCDC_CHAN_MAINLCD
)
?
"mainlcd"
:
"sublcd"
,
"mainlcd"
:
"sublcd"
,
(
int
)
ch
->
cfg
.
lcd_cfg
.
xres
,
info
->
var
.
xres
,
info
->
var
.
yres
,
(
int
)
ch
->
cfg
.
lcd_cfg
.
yres
,
ch
->
cfg
.
bpp
);
ch
->
cfg
.
bpp
);
/* deferred io mode: disable clock to save power */
/* deferred io mode: disable clock to save power */
...
...
drivers/video/sh_mobile_lcdcfb.h
0 → 100644
View file @
b3773301
#ifndef SH_MOBILE_LCDCFB_H
#define SH_MOBILE_LCDCFB_H
#include <linux/completion.h>
#include <linux/fb.h>
#include <linux/mutex.h>
#include <linux/wait.h>
/* per-channel registers */
enum
{
LDDCKPAT1R
,
LDDCKPAT2R
,
LDMT1R
,
LDMT2R
,
LDMT3R
,
LDDFR
,
LDSM1R
,
LDSM2R
,
LDSA1R
,
LDMLSR
,
LDHCNR
,
LDHSYNR
,
LDVLNR
,
LDVSYNR
,
LDPMR
,
LDHAJR
,
NR_CH_REGS
};
#define PALETTE_NR 16
struct
sh_mobile_lcdc_priv
;
struct
fb_info
;
struct
sh_mobile_lcdc_chan
{
struct
sh_mobile_lcdc_priv
*
lcdc
;
unsigned
long
*
reg_offs
;
unsigned
long
ldmt1r_value
;
unsigned
long
enabled
;
/* ME and SE in LDCNT2R */
struct
sh_mobile_lcdc_chan_cfg
cfg
;
u32
pseudo_palette
[
PALETTE_NR
];
unsigned
long
saved_ch_regs
[
NR_CH_REGS
];
struct
fb_info
*
info
;
dma_addr_t
dma_handle
;
struct
fb_deferred_io
defio
;
struct
scatterlist
*
sglist
;
unsigned
long
frame_end
;
unsigned
long
pan_offset
;
wait_queue_head_t
frame_end_wait
;
struct
completion
vsync_completion
;
struct
fb_var_screeninfo
display_var
;
int
use_count
;
struct
mutex
open_lock
;
/* protects the use counter */
};
#endif
include/video/sh_mobile_lcdc.h
View file @
b3773301
...
@@ -49,7 +49,9 @@ struct sh_mobile_lcdc_sys_bus_ops {
...
@@ -49,7 +49,9 @@ struct sh_mobile_lcdc_sys_bus_ops {
unsigned
long
(
*
read_data
)(
void
*
handle
);
unsigned
long
(
*
read_data
)(
void
*
handle
);
};
};
struct
module
;
struct
sh_mobile_lcdc_board_cfg
{
struct
sh_mobile_lcdc_board_cfg
{
struct
module
*
owner
;
void
*
board_data
;
void
*
board_data
;
int
(
*
setup_sys
)(
void
*
board_data
,
void
*
sys_ops_handle
,
int
(
*
setup_sys
)(
void
*
board_data
,
void
*
sys_ops_handle
,
struct
sh_mobile_lcdc_sys_bus_ops
*
sys_ops
);
struct
sh_mobile_lcdc_sys_bus_ops
*
sys_ops
);
...
@@ -70,7 +72,8 @@ struct sh_mobile_lcdc_chan_cfg {
...
@@ -70,7 +72,8 @@ struct sh_mobile_lcdc_chan_cfg {
int
interface_type
;
/* selects RGBn or SYSn I/F, see above */
int
interface_type
;
/* selects RGBn or SYSn I/F, see above */
int
clock_divider
;
int
clock_divider
;
unsigned
long
flags
;
/* LCDC_FLAGS_... */
unsigned
long
flags
;
/* LCDC_FLAGS_... */
struct
fb_videomode
lcd_cfg
;
const
struct
fb_videomode
*
lcd_cfg
;
int
num_cfg
;
struct
sh_mobile_lcdc_lcd_size_cfg
lcd_size_cfg
;
struct
sh_mobile_lcdc_lcd_size_cfg
lcd_size_cfg
;
struct
sh_mobile_lcdc_board_cfg
board_cfg
;
struct
sh_mobile_lcdc_board_cfg
board_cfg
;
struct
sh_mobile_lcdc_sys_bus_cfg
sys_bus_cfg
;
/* only for SYSn I/F */
struct
sh_mobile_lcdc_sys_bus_cfg
sys_bus_cfg
;
/* only for SYSn I/F */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment