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
nexedi
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