You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'staging-3.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging fixes from Greg Kroah-Hartman: "Here are a number of small fixes to staging drivers for your 3.8-rc3 tree. Well, the omapdrm fixes aren't really "small" but they were waiting on a number of other drm patches to go in through the drm tree, and got delayed by my vacation over the holidays. They are totally self-contained, everyone involved have acked them, and they fix issues that people have been having with the driver. Other than that one, it's a bunch of tiny bugfixes for a number of reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'staging-3.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (36 commits) staging: zram: fix invalid memory references during disk write staging: tidspbridge: use prepare/unprepare on dsp clocks staging: tidspbridge: Fix build breakage due to splitting CM functions. staging: comedi: comedi_test: fix race when cancelling command staging: comedi: Kconfig: COMEDI_NI_AT_A2150 should select COMEDI_FC staging: comedi: prevent auto-unconfig of manually configured devices staging: comedi: fix minimum AO period for NI 625x and NI 628x staging: vme_pio2: fix oops on module unloading staging: speakup: avoid out-of-range access in synth_add() staging: speakup: avoid out-of-range access in synth_init() staging: rtl8192e: Fix failure to check pci_map_single() staging: rtl8187se: Fix failure to check pci_map_single() staging: drm/imx: fix double free bug in error path staging: drm/imx: several bug fixes staging: drm/imx: check return value of ipu_reset() staging: drm/omap: fix flags in dma buf exporting staging: drm/omap: use omapdss low level API staging/fwserial: Update TODO file per reviewer comments staging/fwserial: Limit tx/rx to 1394-2008 spec maximum staging/fwserial: Refine Kconfig help text ...
This commit is contained in:
@@ -444,6 +444,7 @@ config COMEDI_ADQ12B
|
||||
|
||||
config COMEDI_NI_AT_A2150
|
||||
tristate "NI AT-A2150 ISA card support"
|
||||
select COMEDI_FC
|
||||
depends on VIRT_TO_BUS
|
||||
---help---
|
||||
Enable support for National Instruments AT-A2150 cards
|
||||
|
||||
@@ -1549,6 +1549,9 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
|
||||
if (cmd == COMEDI_DEVCONFIG) {
|
||||
rc = do_devconfig_ioctl(dev,
|
||||
(struct comedi_devconfig __user *)arg);
|
||||
if (rc == 0)
|
||||
/* Evade comedi_auto_unconfig(). */
|
||||
dev_file_info->hardware_device = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
@@ -345,7 +345,7 @@ static int waveform_ai_cancel(struct comedi_device *dev,
|
||||
struct waveform_private *devpriv = dev->private;
|
||||
|
||||
devpriv->timer_running = 0;
|
||||
del_timer(&devpriv->timer);
|
||||
del_timer_sync(&devpriv->timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -963,7 +963,7 @@ static const struct ni_board_struct ni_boards[] = {
|
||||
.ao_range_table = &range_ni_M_625x_ao,
|
||||
.reg_type = ni_reg_625x,
|
||||
.ao_unipolar = 0,
|
||||
.ao_speed = 357,
|
||||
.ao_speed = 350,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {caldac_none},
|
||||
.has_8255 = 0,
|
||||
@@ -982,7 +982,7 @@ static const struct ni_board_struct ni_boards[] = {
|
||||
.ao_range_table = &range_ni_M_625x_ao,
|
||||
.reg_type = ni_reg_625x,
|
||||
.ao_unipolar = 0,
|
||||
.ao_speed = 357,
|
||||
.ao_speed = 350,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {caldac_none},
|
||||
.has_8255 = 0,
|
||||
@@ -1001,7 +1001,7 @@ static const struct ni_board_struct ni_boards[] = {
|
||||
.ao_range_table = &range_ni_M_625x_ao,
|
||||
.reg_type = ni_reg_625x,
|
||||
.ao_unipolar = 0,
|
||||
.ao_speed = 357,
|
||||
.ao_speed = 350,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {caldac_none},
|
||||
.has_8255 = 0,
|
||||
@@ -1037,7 +1037,7 @@ static const struct ni_board_struct ni_boards[] = {
|
||||
.ao_range_table = &range_ni_M_625x_ao,
|
||||
.reg_type = ni_reg_625x,
|
||||
.ao_unipolar = 0,
|
||||
.ao_speed = 357,
|
||||
.ao_speed = 350,
|
||||
.num_p0_dio_channels = 32,
|
||||
.caldac = {caldac_none},
|
||||
.has_8255 = 0,
|
||||
@@ -1056,7 +1056,7 @@ static const struct ni_board_struct ni_boards[] = {
|
||||
.ao_range_table = &range_ni_M_625x_ao,
|
||||
.reg_type = ni_reg_625x,
|
||||
.ao_unipolar = 0,
|
||||
.ao_speed = 357,
|
||||
.ao_speed = 350,
|
||||
.num_p0_dio_channels = 32,
|
||||
.caldac = {caldac_none},
|
||||
.has_8255 = 0,
|
||||
@@ -1092,7 +1092,7 @@ static const struct ni_board_struct ni_boards[] = {
|
||||
.ao_range_table = &range_ni_M_628x_ao,
|
||||
.reg_type = ni_reg_628x,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 357,
|
||||
.ao_speed = 350,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {caldac_none},
|
||||
.has_8255 = 0,
|
||||
@@ -1111,7 +1111,7 @@ static const struct ni_board_struct ni_boards[] = {
|
||||
.ao_range_table = &range_ni_M_628x_ao,
|
||||
.reg_type = ni_reg_628x,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 357,
|
||||
.ao_speed = 350,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {caldac_none},
|
||||
.has_8255 = 0,
|
||||
@@ -1147,7 +1147,7 @@ static const struct ni_board_struct ni_boards[] = {
|
||||
.ao_range_table = &range_ni_M_628x_ao,
|
||||
.reg_type = ni_reg_628x,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 357,
|
||||
.ao_speed = 350,
|
||||
.num_p0_dio_channels = 32,
|
||||
.caldac = {caldac_none},
|
||||
.has_8255 = 0,
|
||||
|
||||
@@ -3,7 +3,9 @@ config FIREWIRE_SERIAL
|
||||
depends on FIREWIRE
|
||||
help
|
||||
This enables TTY over IEEE 1394, providing high-speed serial
|
||||
connectivity to cabled peers.
|
||||
connectivity to cabled peers. This driver implements a
|
||||
ad-hoc transport protocol and is currently limited to
|
||||
Linux-to-Linux communication.
|
||||
|
||||
To compile this driver as a module, say M here: the module will
|
||||
be called firewire-serial.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
TODOs
|
||||
-----
|
||||
TODOs prior to this driver moving out of staging
|
||||
------------------------------------------------
|
||||
1. Implement retries for RCODE_BUSY, RCODE_NO_ACK and RCODE_SEND_ERROR
|
||||
- I/O is handled asynchronously which presents some issues when error
|
||||
conditions occur.
|
||||
@@ -11,17 +11,9 @@ TODOs
|
||||
-- Issues with firewire stack --
|
||||
1. This driver uses the same unregistered vendor id that the firewire core does
|
||||
(0xd00d1e). Perhaps this could be exposed as a define in
|
||||
firewire-constants.h?
|
||||
2. MAX_ASYNC_PAYLOAD needs to be publicly exposed by core/ohci
|
||||
- otherwise how will this driver know the max size of address window to
|
||||
open for one packet write?
|
||||
firewire.h?
|
||||
3. Maybe device_max_receive() and link_speed_to_max_payload() should be
|
||||
taken up by the firewire core?
|
||||
4. To avoid dropping rx data while still limiting the maximum buffering,
|
||||
the size of the AR context must be known. How to expose this to drivers?
|
||||
5. Explore if bigger AR context will reduce RCODE_BUSY responses
|
||||
(or auto-grow to certain max size -- but this would require major surgery
|
||||
as the current AR is contiguously mapped)
|
||||
|
||||
-- Issues with TTY core --
|
||||
1. Hack for alternate device name scheme
|
||||
|
||||
@@ -179,7 +179,7 @@ static void dump_profile(struct seq_file *m, struct stats *stats)
|
||||
/* Returns the max receive packet size for the given card */
|
||||
static inline int device_max_receive(struct fw_device *fw_device)
|
||||
{
|
||||
return 1 << (clamp_t(int, fw_device->max_rec, 8U, 13U) + 1);
|
||||
return 1 << (clamp_t(int, fw_device->max_rec, 8U, 11U) + 1);
|
||||
}
|
||||
|
||||
static void fwtty_log_tx_error(struct fwtty_port *port, int rcode)
|
||||
|
||||
@@ -374,10 +374,10 @@ static inline void fwtty_bind_console(struct fwtty_port *port,
|
||||
*/
|
||||
static inline int link_speed_to_max_payload(unsigned speed)
|
||||
{
|
||||
static const int max_async[] = { 307, 614, 1229, 2458, 4916, 9832, };
|
||||
BUILD_BUG_ON(ARRAY_SIZE(max_async) - 1 != SCODE_3200);
|
||||
static const int max_async[] = { 307, 614, 1229, 2458, };
|
||||
BUILD_BUG_ON(ARRAY_SIZE(max_async) - 1 != SCODE_800);
|
||||
|
||||
speed = clamp(speed, (unsigned) SCODE_100, (unsigned) SCODE_3200);
|
||||
speed = clamp(speed, (unsigned) SCODE_100, (unsigned) SCODE_800);
|
||||
if (limit_bw)
|
||||
return max_async[speed];
|
||||
else
|
||||
|
||||
@@ -27,8 +27,8 @@ config ADIS16130
|
||||
config ADIS16260
|
||||
tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver"
|
||||
depends on SPI
|
||||
select IIO_TRIGGER if IIO_BUFFER
|
||||
select IIO_SW_RING if IIO_BUFFER
|
||||
select IIO_ADIS_LIB
|
||||
select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
|
||||
help
|
||||
Say yes here to build support for Analog Devices ADIS16260 ADIS16265
|
||||
ADIS16250 ADIS16255 and ADIS16251 programmable digital gyroscope sensors.
|
||||
|
||||
@@ -584,7 +584,6 @@ int imx_drm_add_encoder(struct drm_encoder *encoder,
|
||||
|
||||
ret = imx_drm_encoder_register(imx_drm_encoder);
|
||||
if (ret) {
|
||||
kfree(imx_drm_encoder);
|
||||
ret = -ENOMEM;
|
||||
goto err_register;
|
||||
}
|
||||
|
||||
@@ -1104,7 +1104,9 @@ static int ipu_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto out_failed_irq;
|
||||
|
||||
ipu_reset(ipu);
|
||||
ret = ipu_reset(ipu);
|
||||
if (ret)
|
||||
goto out_failed_reset;
|
||||
|
||||
/* Set MCU_T to divide MCU access window into 2 */
|
||||
ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18),
|
||||
@@ -1129,6 +1131,7 @@ failed_add_clients:
|
||||
ipu_submodules_exit(ipu);
|
||||
failed_submodules_init:
|
||||
ipu_irq_exit(ipu);
|
||||
out_failed_reset:
|
||||
out_failed_irq:
|
||||
clk_disable_unprepare(ipu->clk);
|
||||
failed_clk_get:
|
||||
|
||||
@@ -452,7 +452,7 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc,
|
||||
int ret;
|
||||
|
||||
ipu_crtc->ipu_ch = ipu_idmac_get(ipu, pdata->dma[0]);
|
||||
if (IS_ERR_OR_NULL(ipu_crtc->ipu_ch)) {
|
||||
if (IS_ERR(ipu_crtc->ipu_ch)) {
|
||||
ret = PTR_ERR(ipu_crtc->ipu_ch);
|
||||
goto err_out;
|
||||
}
|
||||
@@ -472,7 +472,7 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc,
|
||||
if (pdata->dp >= 0) {
|
||||
ipu_crtc->dp = ipu_dp_get(ipu, pdata->dp);
|
||||
if (IS_ERR(ipu_crtc->dp)) {
|
||||
ret = PTR_ERR(ipu_crtc->ipu_ch);
|
||||
ret = PTR_ERR(ipu_crtc->dp);
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
@@ -548,6 +548,8 @@ static int ipu_drm_probe(struct platform_device *pdev)
|
||||
ipu_crtc->dev = &pdev->dev;
|
||||
|
||||
ret = ipu_crtc_init(ipu_crtc, pdata);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, ipu_crtc);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
ccflags-y := -Iinclude/drm -Werror
|
||||
omapdrm-y := omap_drv.o \
|
||||
omap_irq.o \
|
||||
omap_debugfs.o \
|
||||
omap_crtc.o \
|
||||
omap_plane.o \
|
||||
|
||||
@@ -17,9 +17,6 @@ TODO
|
||||
. Revisit GEM sync object infrastructure.. TTM has some framework for this
|
||||
already. Possibly this could be refactored out and made more common?
|
||||
There should be some way to do this with less wheel-reinvention.
|
||||
. Review DSS vs KMS mismatches. The omap_dss_device is sort of part encoder,
|
||||
part connector. Which results in a bit of duct tape to fwd calls from
|
||||
encoder to connector. Possibly this could be done a bit better.
|
||||
. Solve PM sequencing on resume. DMM/TILER must be reloaded before any
|
||||
access is made from any component in the system. Which means on suspend
|
||||
CRTC's should be disabled, and on resume the LUT should be reprogrammed
|
||||
|
||||
@@ -31,9 +31,10 @@
|
||||
struct omap_connector {
|
||||
struct drm_connector base;
|
||||
struct omap_dss_device *dssdev;
|
||||
struct drm_encoder *encoder;
|
||||
};
|
||||
|
||||
static inline void copy_timings_omap_to_drm(struct drm_display_mode *mode,
|
||||
void copy_timings_omap_to_drm(struct drm_display_mode *mode,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
mode->clock = timings->pixel_clock;
|
||||
@@ -64,7 +65,7 @@ static inline void copy_timings_omap_to_drm(struct drm_display_mode *mode,
|
||||
mode->flags |= DRM_MODE_FLAG_NVSYNC;
|
||||
}
|
||||
|
||||
static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings,
|
||||
void copy_timings_drm_to_omap(struct omap_video_timings *timings,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
timings->pixel_clock = mode->clock;
|
||||
@@ -96,48 +97,7 @@ static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings,
|
||||
timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
|
||||
}
|
||||
|
||||
static void omap_connector_dpms(struct drm_connector *connector, int mode)
|
||||
{
|
||||
struct omap_connector *omap_connector = to_omap_connector(connector);
|
||||
struct omap_dss_device *dssdev = omap_connector->dssdev;
|
||||
int old_dpms;
|
||||
|
||||
DBG("%s: %d", dssdev->name, mode);
|
||||
|
||||
old_dpms = connector->dpms;
|
||||
|
||||
/* from off to on, do from crtc to connector */
|
||||
if (mode < old_dpms)
|
||||
drm_helper_connector_dpms(connector, mode);
|
||||
|
||||
if (mode == DRM_MODE_DPMS_ON) {
|
||||
/* store resume info for suspended displays */
|
||||
switch (dssdev->state) {
|
||||
case OMAP_DSS_DISPLAY_SUSPENDED:
|
||||
dssdev->activate_after_resume = true;
|
||||
break;
|
||||
case OMAP_DSS_DISPLAY_DISABLED: {
|
||||
int ret = dssdev->driver->enable(dssdev);
|
||||
if (ret) {
|
||||
DBG("%s: failed to enable: %d",
|
||||
dssdev->name, ret);
|
||||
dssdev->driver->disable(dssdev);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* from on to off, do from connector to crtc */
|
||||
if (mode > old_dpms)
|
||||
drm_helper_connector_dpms(connector, mode);
|
||||
}
|
||||
|
||||
enum drm_connector_status omap_connector_detect(
|
||||
static enum drm_connector_status omap_connector_detect(
|
||||
struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct omap_connector *omap_connector = to_omap_connector(connector);
|
||||
@@ -164,8 +124,6 @@ static void omap_connector_destroy(struct drm_connector *connector)
|
||||
struct omap_connector *omap_connector = to_omap_connector(connector);
|
||||
struct omap_dss_device *dssdev = omap_connector->dssdev;
|
||||
|
||||
dssdev->driver->disable(dssdev);
|
||||
|
||||
DBG("%s", omap_connector->dssdev->name);
|
||||
drm_sysfs_connector_remove(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
@@ -261,36 +219,12 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
|
||||
struct drm_encoder *omap_connector_attached_encoder(
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
int i;
|
||||
struct omap_connector *omap_connector = to_omap_connector(connector);
|
||||
|
||||
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
|
||||
struct drm_mode_object *obj;
|
||||
|
||||
if (connector->encoder_ids[i] == 0)
|
||||
break;
|
||||
|
||||
obj = drm_mode_object_find(connector->dev,
|
||||
connector->encoder_ids[i],
|
||||
DRM_MODE_OBJECT_ENCODER);
|
||||
|
||||
if (obj) {
|
||||
struct drm_encoder *encoder = obj_to_encoder(obj);
|
||||
struct omap_overlay_manager *mgr =
|
||||
omap_encoder_get_manager(encoder);
|
||||
DBG("%s: found %s", omap_connector->dssdev->name,
|
||||
mgr->name);
|
||||
return encoder;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%s: no encoder", omap_connector->dssdev->name);
|
||||
|
||||
return NULL;
|
||||
return omap_connector->encoder;
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs omap_connector_funcs = {
|
||||
.dpms = omap_connector_dpms,
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.detect = omap_connector_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = omap_connector_destroy,
|
||||
@@ -302,34 +236,6 @@ static const struct drm_connector_helper_funcs omap_connector_helper_funcs = {
|
||||
.best_encoder = omap_connector_attached_encoder,
|
||||
};
|
||||
|
||||
/* called from encoder when mode is set, to propagate settings to the dssdev */
|
||||
void omap_connector_mode_set(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct omap_connector *omap_connector = to_omap_connector(connector);
|
||||
struct omap_dss_device *dssdev = omap_connector->dssdev;
|
||||
struct omap_dss_driver *dssdrv = dssdev->driver;
|
||||
struct omap_video_timings timings = {0};
|
||||
|
||||
copy_timings_drm_to_omap(&timings, mode);
|
||||
|
||||
DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
|
||||
omap_connector->dssdev->name,
|
||||
mode->base.id, mode->name, mode->vrefresh, mode->clock,
|
||||
mode->hdisplay, mode->hsync_start,
|
||||
mode->hsync_end, mode->htotal,
|
||||
mode->vdisplay, mode->vsync_start,
|
||||
mode->vsync_end, mode->vtotal, mode->type, mode->flags);
|
||||
|
||||
if (dssdrv->check_timings(dssdev, &timings)) {
|
||||
dev_err(dev->dev, "could not set timings\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dssdrv->set_timings(dssdev, &timings);
|
||||
}
|
||||
|
||||
/* flush an area of the framebuffer (in case of manual update display that
|
||||
* is not automatically flushed)
|
||||
*/
|
||||
@@ -344,7 +250,8 @@ void omap_connector_flush(struct drm_connector *connector,
|
||||
|
||||
/* initialize connector */
|
||||
struct drm_connector *omap_connector_init(struct drm_device *dev,
|
||||
int connector_type, struct omap_dss_device *dssdev)
|
||||
int connector_type, struct omap_dss_device *dssdev,
|
||||
struct drm_encoder *encoder)
|
||||
{
|
||||
struct drm_connector *connector = NULL;
|
||||
struct omap_connector *omap_connector;
|
||||
@@ -360,6 +267,8 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
|
||||
}
|
||||
|
||||
omap_connector->dssdev = dssdev;
|
||||
omap_connector->encoder = encoder;
|
||||
|
||||
connector = &omap_connector->base;
|
||||
|
||||
drm_connector_init(dev, connector, &omap_connector_funcs,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,7 @@
|
||||
#include <linux/platform_data/omap_drm.h>
|
||||
#include "omap_drm.h"
|
||||
|
||||
|
||||
#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
|
||||
#define VERB(fmt, ...) if (0) DRM_DEBUG(fmt, ##__VA_ARGS__) /* verbose debug */
|
||||
|
||||
@@ -39,6 +40,51 @@
|
||||
*/
|
||||
#define MAX_MAPPERS 2
|
||||
|
||||
/* parameters which describe (unrotated) coordinates of scanout within a fb: */
|
||||
struct omap_drm_window {
|
||||
uint32_t rotation;
|
||||
int32_t crtc_x, crtc_y; /* signed because can be offscreen */
|
||||
uint32_t crtc_w, crtc_h;
|
||||
uint32_t src_x, src_y;
|
||||
uint32_t src_w, src_h;
|
||||
};
|
||||
|
||||
/* Once GO bit is set, we can't make further updates to shadowed registers
|
||||
* until the GO bit is cleared. So various parts in the kms code that need
|
||||
* to update shadowed registers queue up a pair of callbacks, pre_apply
|
||||
* which is called before setting GO bit, and post_apply that is called
|
||||
* after GO bit is cleared. The crtc manages the queuing, and everyone
|
||||
* else goes thru omap_crtc_apply() using these callbacks so that the
|
||||
* code which has to deal w/ GO bit state is centralized.
|
||||
*/
|
||||
struct omap_drm_apply {
|
||||
struct list_head pending_node, queued_node;
|
||||
bool queued;
|
||||
void (*pre_apply)(struct omap_drm_apply *apply);
|
||||
void (*post_apply)(struct omap_drm_apply *apply);
|
||||
};
|
||||
|
||||
/* For transiently registering for different DSS irqs that various parts
|
||||
* of the KMS code need during setup/configuration. We these are not
|
||||
* necessarily the same as what drm_vblank_get/put() are requesting, and
|
||||
* the hysteresis in drm_vblank_put() is not necessarily desirable for
|
||||
* internal housekeeping related irq usage.
|
||||
*/
|
||||
struct omap_drm_irq {
|
||||
struct list_head node;
|
||||
uint32_t irqmask;
|
||||
bool registered;
|
||||
void (*irq)(struct omap_drm_irq *irq, uint32_t irqstatus);
|
||||
};
|
||||
|
||||
/* For KMS code that needs to wait for a certain # of IRQs:
|
||||
*/
|
||||
struct omap_irq_wait;
|
||||
struct omap_irq_wait * omap_irq_wait_init(struct drm_device *dev,
|
||||
uint32_t irqmask, int count);
|
||||
int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait,
|
||||
unsigned long timeout);
|
||||
|
||||
struct omap_drm_private {
|
||||
uint32_t omaprev;
|
||||
|
||||
@@ -58,6 +104,7 @@ struct omap_drm_private {
|
||||
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
/* list of GEM objects: */
|
||||
struct list_head obj_list;
|
||||
|
||||
bool has_dmm;
|
||||
@@ -65,6 +112,11 @@ struct omap_drm_private {
|
||||
/* properties: */
|
||||
struct drm_property *rotation_prop;
|
||||
struct drm_property *zorder_prop;
|
||||
|
||||
/* irq handling: */
|
||||
struct list_head irq_list; /* list of omap_drm_irq */
|
||||
uint32_t vblank_mask; /* irq bits set for userspace vblank */
|
||||
struct omap_drm_irq error_handler;
|
||||
};
|
||||
|
||||
/* this should probably be in drm-core to standardize amongst drivers */
|
||||
@@ -75,15 +127,6 @@ struct omap_drm_private {
|
||||
#define DRM_REFLECT_X 4
|
||||
#define DRM_REFLECT_Y 5
|
||||
|
||||
/* parameters which describe (unrotated) coordinates of scanout within a fb: */
|
||||
struct omap_drm_window {
|
||||
uint32_t rotation;
|
||||
int32_t crtc_x, crtc_y; /* signed because can be offscreen */
|
||||
uint32_t crtc_w, crtc_h;
|
||||
uint32_t src_x, src_y;
|
||||
uint32_t src_w, src_h;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
int omap_debugfs_init(struct drm_minor *minor);
|
||||
void omap_debugfs_cleanup(struct drm_minor *minor);
|
||||
@@ -92,23 +135,36 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m);
|
||||
void omap_gem_describe_objects(struct list_head *list, struct seq_file *m);
|
||||
#endif
|
||||
|
||||
int omap_irq_enable_vblank(struct drm_device *dev, int crtc);
|
||||
void omap_irq_disable_vblank(struct drm_device *dev, int crtc);
|
||||
irqreturn_t omap_irq_handler(DRM_IRQ_ARGS);
|
||||
void omap_irq_preinstall(struct drm_device *dev);
|
||||
int omap_irq_postinstall(struct drm_device *dev);
|
||||
void omap_irq_uninstall(struct drm_device *dev);
|
||||
void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq);
|
||||
void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq);
|
||||
int omap_drm_irq_uninstall(struct drm_device *dev);
|
||||
int omap_drm_irq_install(struct drm_device *dev);
|
||||
|
||||
struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev);
|
||||
void omap_fbdev_free(struct drm_device *dev);
|
||||
|
||||
const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc);
|
||||
enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
|
||||
int omap_crtc_apply(struct drm_crtc *crtc,
|
||||
struct omap_drm_apply *apply);
|
||||
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
||||
struct omap_overlay *ovl, int id);
|
||||
struct drm_plane *plane, enum omap_channel channel, int id);
|
||||
|
||||
struct drm_plane *omap_plane_init(struct drm_device *dev,
|
||||
struct omap_overlay *ovl, unsigned int possible_crtcs,
|
||||
bool priv);
|
||||
int plane_id, bool private_plane);
|
||||
int omap_plane_dpms(struct drm_plane *plane, int mode);
|
||||
int omap_plane_mode_set(struct drm_plane *plane,
|
||||
struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
||||
int crtc_x, int crtc_y,
|
||||
unsigned int crtc_w, unsigned int crtc_h,
|
||||
uint32_t src_x, uint32_t src_y,
|
||||
uint32_t src_w, uint32_t src_h);
|
||||
void omap_plane_on_endwin(struct drm_plane *plane,
|
||||
uint32_t src_w, uint32_t src_h,
|
||||
void (*fxn)(void *), void *arg);
|
||||
void omap_plane_install_properties(struct drm_plane *plane,
|
||||
struct drm_mode_object *obj);
|
||||
@@ -116,21 +172,25 @@ int omap_plane_set_property(struct drm_plane *plane,
|
||||
struct drm_property *property, uint64_t val);
|
||||
|
||||
struct drm_encoder *omap_encoder_init(struct drm_device *dev,
|
||||
struct omap_overlay_manager *mgr);
|
||||
struct omap_overlay_manager *omap_encoder_get_manager(
|
||||
struct omap_dss_device *dssdev);
|
||||
int omap_encoder_set_enabled(struct drm_encoder *encoder, bool enabled);
|
||||
int omap_encoder_update(struct drm_encoder *encoder,
|
||||
struct omap_overlay_manager *mgr,
|
||||
struct omap_video_timings *timings);
|
||||
|
||||
struct drm_connector *omap_connector_init(struct drm_device *dev,
|
||||
int connector_type, struct omap_dss_device *dssdev,
|
||||
struct drm_encoder *encoder);
|
||||
struct drm_encoder *omap_connector_attached_encoder(
|
||||
struct drm_connector *connector);
|
||||
enum drm_connector_status omap_connector_detect(
|
||||
struct drm_connector *connector, bool force);
|
||||
|
||||
struct drm_connector *omap_connector_init(struct drm_device *dev,
|
||||
int connector_type, struct omap_dss_device *dssdev);
|
||||
void omap_connector_mode_set(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode);
|
||||
void omap_connector_flush(struct drm_connector *connector,
|
||||
int x, int y, int w, int h);
|
||||
|
||||
void copy_timings_omap_to_drm(struct drm_display_mode *mode,
|
||||
struct omap_video_timings *timings);
|
||||
void copy_timings_drm_to_omap(struct omap_video_timings *timings,
|
||||
struct drm_display_mode *mode);
|
||||
|
||||
uint32_t omap_framebuffer_get_formats(uint32_t *pixel_formats,
|
||||
uint32_t max_formats, enum omap_color_mode supported_modes);
|
||||
struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
|
||||
@@ -207,6 +267,40 @@ static inline int align_pitch(int pitch, int width, int bpp)
|
||||
return ALIGN(pitch, 8 * bytespp);
|
||||
}
|
||||
|
||||
static inline enum omap_channel pipe2chan(int pipe)
|
||||
{
|
||||
int num_mgrs = dss_feat_get_num_mgrs();
|
||||
|
||||
/*
|
||||
* We usually don't want to create a CRTC for each manager,
|
||||
* at least not until we have a way to expose private planes
|
||||
* to userspace. Otherwise there would not be enough video
|
||||
* pipes left for drm planes. The higher #'d managers tend
|
||||
* to have more features so start in reverse order.
|
||||
*/
|
||||
return num_mgrs - pipe - 1;
|
||||
}
|
||||
|
||||
/* map crtc to vblank mask */
|
||||
static inline uint32_t pipe2vbl(int crtc)
|
||||
{
|
||||
enum omap_channel channel = pipe2chan(crtc);
|
||||
return dispc_mgr_get_vsync_irq(channel);
|
||||
}
|
||||
|
||||
static inline int crtc2pipe(struct drm_device *dev, struct drm_crtc *crtc)
|
||||
{
|
||||
struct omap_drm_private *priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(priv->crtcs); i++)
|
||||
if (priv->crtcs[i] == crtc)
|
||||
return i;
|
||||
|
||||
BUG(); /* bogus CRTC ptr */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* should these be made into common util helpers?
|
||||
*/
|
||||
|
||||
|
||||
@@ -22,37 +22,56 @@
|
||||
#include "drm_crtc.h"
|
||||
#include "drm_crtc_helper.h"
|
||||
|
||||
#include <linux/list.h>
|
||||
|
||||
|
||||
/*
|
||||
* encoder funcs
|
||||
*/
|
||||
|
||||
#define to_omap_encoder(x) container_of(x, struct omap_encoder, base)
|
||||
|
||||
/* The encoder and connector both map to same dssdev.. the encoder
|
||||
* handles the 'active' parts, ie. anything the modifies the state
|
||||
* of the hw, and the connector handles the 'read-only' parts, like
|
||||
* detecting connection and reading edid.
|
||||
*/
|
||||
struct omap_encoder {
|
||||
struct drm_encoder base;
|
||||
struct omap_overlay_manager *mgr;
|
||||
struct omap_dss_device *dssdev;
|
||||
};
|
||||
|
||||
static void omap_encoder_destroy(struct drm_encoder *encoder)
|
||||
{
|
||||
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
|
||||
DBG("%s", omap_encoder->mgr->name);
|
||||
drm_encoder_cleanup(encoder);
|
||||
kfree(omap_encoder);
|
||||
}
|
||||
|
||||
static const struct drm_encoder_funcs omap_encoder_funcs = {
|
||||
.destroy = omap_encoder_destroy,
|
||||
};
|
||||
|
||||
/*
|
||||
* The CRTC drm_crtc_helper_set_mode() doesn't really give us the right
|
||||
* order.. the easiest way to work around this for now is to make all
|
||||
* the encoder-helper's no-op's and have the omap_crtc code take care
|
||||
* of the sequencing and call us in the right points.
|
||||
*
|
||||
* Eventually to handle connecting CRTCs to different encoders properly,
|
||||
* either the CRTC helpers need to change or we need to replace
|
||||
* drm_crtc_helper_set_mode(), but lets wait until atomic-modeset for
|
||||
* that.
|
||||
*/
|
||||
|
||||
static void omap_encoder_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
|
||||
DBG("%s: %d", omap_encoder->mgr->name, mode);
|
||||
}
|
||||
|
||||
static bool omap_encoder_mode_fixup(struct drm_encoder *encoder,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
|
||||
DBG("%s", omap_encoder->mgr->name);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -60,47 +79,16 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct omap_drm_private *priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
mode = adjusted_mode;
|
||||
|
||||
DBG("%s: set mode: %dx%d", omap_encoder->mgr->name,
|
||||
mode->hdisplay, mode->vdisplay);
|
||||
|
||||
for (i = 0; i < priv->num_connectors; i++) {
|
||||
struct drm_connector *connector = priv->connectors[i];
|
||||
if (connector->encoder == encoder)
|
||||
omap_connector_mode_set(connector, mode);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void omap_encoder_prepare(struct drm_encoder *encoder)
|
||||
{
|
||||
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
|
||||
struct drm_encoder_helper_funcs *encoder_funcs =
|
||||
encoder->helper_private;
|
||||
DBG("%s", omap_encoder->mgr->name);
|
||||
encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
|
||||
}
|
||||
|
||||
static void omap_encoder_commit(struct drm_encoder *encoder)
|
||||
{
|
||||
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
|
||||
struct drm_encoder_helper_funcs *encoder_funcs =
|
||||
encoder->helper_private;
|
||||
DBG("%s", omap_encoder->mgr->name);
|
||||
omap_encoder->mgr->apply(omap_encoder->mgr);
|
||||
encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
|
||||
static const struct drm_encoder_funcs omap_encoder_funcs = {
|
||||
.destroy = omap_encoder_destroy,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
|
||||
.dpms = omap_encoder_dpms,
|
||||
.mode_fixup = omap_encoder_mode_fixup,
|
||||
@@ -109,23 +97,54 @@ static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
|
||||
.commit = omap_encoder_commit,
|
||||
};
|
||||
|
||||
struct omap_overlay_manager *omap_encoder_get_manager(
|
||||
struct drm_encoder *encoder)
|
||||
/*
|
||||
* Instead of relying on the helpers for modeset, the omap_crtc code
|
||||
* calls these functions in the proper sequence.
|
||||
*/
|
||||
|
||||
int omap_encoder_set_enabled(struct drm_encoder *encoder, bool enabled)
|
||||
{
|
||||
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
|
||||
return omap_encoder->mgr;
|
||||
struct omap_dss_device *dssdev = omap_encoder->dssdev;
|
||||
struct omap_dss_driver *dssdrv = dssdev->driver;
|
||||
|
||||
if (enabled) {
|
||||
return dssdrv->enable(dssdev);
|
||||
} else {
|
||||
dssdrv->disable(dssdev);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int omap_encoder_update(struct drm_encoder *encoder,
|
||||
struct omap_overlay_manager *mgr,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
|
||||
struct omap_dss_device *dssdev = omap_encoder->dssdev;
|
||||
struct omap_dss_driver *dssdrv = dssdev->driver;
|
||||
int ret;
|
||||
|
||||
dssdev->output->manager = mgr;
|
||||
|
||||
ret = dssdrv->check_timings(dssdev, timings);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "could not set timings: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dssdrv->set_timings(dssdev, timings);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initialize encoder */
|
||||
struct drm_encoder *omap_encoder_init(struct drm_device *dev,
|
||||
struct omap_overlay_manager *mgr)
|
||||
struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct drm_encoder *encoder = NULL;
|
||||
struct omap_encoder *omap_encoder;
|
||||
struct omap_overlay_manager_info info;
|
||||
int ret;
|
||||
|
||||
DBG("%s", mgr->name);
|
||||
|
||||
omap_encoder = kzalloc(sizeof(*omap_encoder), GFP_KERNEL);
|
||||
if (!omap_encoder) {
|
||||
@@ -133,33 +152,14 @@ struct drm_encoder *omap_encoder_init(struct drm_device *dev,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
omap_encoder->mgr = mgr;
|
||||
omap_encoder->dssdev = dssdev;
|
||||
|
||||
encoder = &omap_encoder->base;
|
||||
|
||||
drm_encoder_init(dev, encoder, &omap_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
drm_encoder_helper_add(encoder, &omap_encoder_helper_funcs);
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
/* TODO: fix hard-coded setup.. */
|
||||
info.default_color = 0x00000000;
|
||||
info.trans_key = 0x00000000;
|
||||
info.trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
|
||||
info.trans_enabled = false;
|
||||
|
||||
ret = mgr->set_manager_info(mgr, &info);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "could not set manager info\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = mgr->apply(mgr);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "could not apply\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return encoder;
|
||||
|
||||
fail:
|
||||
|
||||
@@ -194,7 +194,7 @@ struct dma_buf_ops omap_dmabuf_ops = {
|
||||
struct dma_buf *omap_gem_prime_export(struct drm_device *dev,
|
||||
struct drm_gem_object *obj, int flags)
|
||||
{
|
||||
return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, 0600);
|
||||
return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, flags);
|
||||
}
|
||||
|
||||
struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user