u32 cflcr;
 
+       /* static max sizes either from platform data or default */
+       int max_width;
+       int max_height;
+
        enum v4l2_field field;
        int sequence;
 
                if (ret < 0)
                        return ret;
 
-               while ((mf.width > 2560 || mf.height > 1920) && shift < 4) {
+               /*
+                * All currently existing CEU implementations support 2560x1920
+                * or larger frames. If the sensor is proposing too big a frame,
+                * don't bother with possibly supportred by the CEU larger
+                * sizes, just try VGA multiples. If needed, this can be
+                * adjusted in the future.
+                */
+               while ((mf.width > pcdev->max_width ||
+                       mf.height > pcdev->max_height) && shift < 4) {
                        /* Try 2560x1920, 1280x960, 640x480, 320x240 */
                        mf.width        = 2560 >> shift;
                        mf.height       = 1920 >> shift;
 static int client_s_fmt(struct soc_camera_device *icd,
                        struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
 {
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+       struct sh_mobile_ceu_dev *pcdev = ici->priv;
        struct sh_mobile_ceu_cam *cam = icd->host_priv;
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct device *dev = icd->parent;
        if (ret < 0)
                return ret;
 
-       max_width = min(cap.bounds.width, 2560);
-       max_height = min(cap.bounds.height, 1920);
+       max_width = min(cap.bounds.width, pcdev->max_width);
+       max_height = min(cap.bounds.height, pcdev->max_height);
 
        /* Camera set a format, but geometry is not precise, try to improve */
        tmp_w = mf->width;
        if (ret < 0)
                return ret;
 
-       if (mf.width > 2560 || mf.height > 1920)
+       if (mf.width > pcdev->max_width || mf.height > pcdev->max_height)
                return -EINVAL;
 
        /* 4. Calculate camera scales */
 static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
                                 struct v4l2_format *f)
 {
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+       struct sh_mobile_ceu_dev *pcdev = ici->priv;
        const struct soc_camera_format_xlate *xlate;
        struct v4l2_pix_format *pix = &f->fmt.pix;
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        /* FIXME: calculate using depth and bus width */
 
        /* CFSZR requires height and width to be 4-pixel aligned */
-       v4l_bound_align_image(&pix->width, 2, 2560, 2,
-                             &pix->height, 4, 1920, 2, 0);
+       v4l_bound_align_image(&pix->width, 2, pcdev->max_width, 2,
+                             &pix->height, 4, pcdev->max_height, 2, 0);
 
        width = pix->width;
        height = pix->height;
                         * requested a bigger rectangle, it will not return a
                         * smaller one.
                         */
-                       mf.width = 2560;
-                       mf.height = 1920;
+                       mf.width = pcdev->max_width;
+                       mf.height = pcdev->max_height;
                        ret = v4l2_device_call_until_err(sd->v4l2_dev,
                                        soc_camera_grp_id(icd), video,
                                        try_mbus_fmt, &mf);
                goto exit_kfree;
        }
 
+       pcdev->max_width = pcdev->pdata->max_width ? : 2560;
+       pcdev->max_height = pcdev->pdata->max_height ? : 1920;
+
        base = ioremap_nocache(res->start, resource_size(res));
        if (!base) {
                err = -ENXIO;